@aventara/prisma7-adapter 0.1.0-pilot.0

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 (86) hide show
  1. package/LICENSE +91 -0
  2. package/LICENSE-ADDITIONAL-PERMISSION.md +9 -0
  3. package/README.md +564 -0
  4. package/dist/discovery/artifact.loader.d.ts +26 -0
  5. package/dist/discovery/artifact.loader.js +124 -0
  6. package/dist/discovery/capability-surface.interface.d.ts +191 -0
  7. package/dist/discovery/capability-surface.interface.js +13 -0
  8. package/dist/discovery/capability.deriver.d.ts +92 -0
  9. package/dist/discovery/capability.deriver.js +350 -0
  10. package/dist/discovery/discovery-artifact.interface.d.ts +210 -0
  11. package/dist/discovery/discovery-artifact.interface.js +1 -0
  12. package/dist/discovery/enum.mapper.d.ts +59 -0
  13. package/dist/discovery/enum.mapper.js +32 -0
  14. package/dist/discovery/field.mapper.d.ts +244 -0
  15. package/dist/discovery/field.mapper.js +387 -0
  16. package/dist/discovery/identifier.mapper.d.ts +188 -0
  17. package/dist/discovery/identifier.mapper.js +132 -0
  18. package/dist/discovery/model.discoverer.d.ts +108 -0
  19. package/dist/discovery/model.discoverer.js +341 -0
  20. package/dist/discovery/operations.deriver.d.ts +75 -0
  21. package/dist/discovery/operations.deriver.js +92 -0
  22. package/dist/discovery/scalar.mapper.d.ts +81 -0
  23. package/dist/discovery/scalar.mapper.js +51 -0
  24. package/dist/discovery/schema-facts.interface.d.ts +174 -0
  25. package/dist/discovery/schema-facts.interface.js +11 -0
  26. package/dist/discovery/schema.reader.d.ts +162 -0
  27. package/dist/discovery/schema.reader.js +692 -0
  28. package/dist/discovery/types.reader.d.ts +24 -0
  29. package/dist/discovery/types.reader.js +617 -0
  30. package/dist/discovery/vocabulary.dictionary.d.ts +258 -0
  31. package/dist/discovery/vocabulary.dictionary.js +429 -0
  32. package/dist/errors/error.normalizer.d.ts +250 -0
  33. package/dist/errors/error.normalizer.js +135 -0
  34. package/dist/errors/prisma-error.reader.d.ts +144 -0
  35. package/dist/errors/prisma-error.reader.js +167 -0
  36. package/dist/execution/first-variant.emulator.d.ts +64 -0
  37. package/dist/execution/first-variant.emulator.js +205 -0
  38. package/dist/execution/operation.executor.d.ts +87 -0
  39. package/dist/execution/operation.executor.js +210 -0
  40. package/dist/execution/result.shaper.d.ts +103 -0
  41. package/dist/execution/result.shaper.js +141 -0
  42. package/dist/execution/transaction.executor.d.ts +147 -0
  43. package/dist/execution/transaction.executor.js +13 -0
  44. package/dist/generate/artifact.emitter.d.ts +50 -0
  45. package/dist/generate/artifact.emitter.js +105 -0
  46. package/dist/generate/declared-support.reader.d.ts +33 -0
  47. package/dist/generate/declared-support.reader.js +74 -0
  48. package/dist/generate/discovery.bin.d.ts +2 -0
  49. package/dist/generate/discovery.bin.js +15 -0
  50. package/dist/generate/discovery.cli.d.ts +24 -0
  51. package/dist/generate/discovery.cli.js +163 -0
  52. package/dist/generate/existence.gate.d.ts +73 -0
  53. package/dist/generate/existence.gate.js +91 -0
  54. package/dist/generate/index.d.ts +81 -0
  55. package/dist/generate/index.js +65 -0
  56. package/dist/generate/node-version.guard.d.ts +8 -0
  57. package/dist/generate/node-version.guard.js +59 -0
  58. package/dist/generate/prisma-cli.resolver.d.ts +48 -0
  59. package/dist/generate/prisma-cli.resolver.js +95 -0
  60. package/dist/generate/prisma.generate.d.ts +164 -0
  61. package/dist/generate/prisma.generate.js +278 -0
  62. package/dist/generate/reader-crosscheck.d.ts +156 -0
  63. package/dist/generate/reader-crosscheck.js +202 -0
  64. package/dist/index.d.ts +5 -0
  65. package/dist/index.js +1 -0
  66. package/dist/prisma-client.interface.d.ts +48 -0
  67. package/dist/prisma-client.interface.js +9 -0
  68. package/dist/prisma.adapter.d.ts +55 -0
  69. package/dist/prisma.adapter.js +105 -0
  70. package/dist/provider/provider-profile.d.ts +53 -0
  71. package/dist/provider/provider-profile.js +91 -0
  72. package/dist/translation/identifier.addressing.d.ts +80 -0
  73. package/dist/translation/identifier.addressing.js +30 -0
  74. package/dist/translation/mutation.translator.d.ts +115 -0
  75. package/dist/translation/mutation.translator.js +580 -0
  76. package/dist/translation/operation.translator.d.ts +273 -0
  77. package/dist/translation/operation.translator.js +377 -0
  78. package/dist/translation/order-pagination.translator.d.ts +86 -0
  79. package/dist/translation/order-pagination.translator.js +159 -0
  80. package/dist/translation/projection.translator.d.ts +115 -0
  81. package/dist/translation/projection.translator.js +151 -0
  82. package/dist/translation/scalar.conversion.d.ts +101 -0
  83. package/dist/translation/scalar.conversion.js +221 -0
  84. package/dist/translation/where.translator.d.ts +79 -0
  85. package/dist/translation/where.translator.js +254 -0
  86. package/package.json +102 -0
@@ -0,0 +1,258 @@
1
+ import type { AdapterLifecycleTrait, BuiltInScalar, PaginationCapability, RelationFilterCapability, RelationMutationDirective, ScalarFilterOperator, ScalarFormat, ScalarMutationDirective } from "@aventara/core";
2
+ /**
3
+ * T-3.1 — the vocabulary dictionary: where PSL, the 🟢 generated types and the
4
+ * observed runtime meet Aventara's own words.
5
+ *
6
+ * # It is data, not conditionals
7
+ *
8
+ * Every table below is a value a reader can hold beside T-3.1's table and check
9
+ * row by row. Nothing here branches on a provider, a field name or a schema: a
10
+ * module that learns a fact by asking `if (provider === "sqlite")` is tabulating
11
+ * what the sources already state, which is the cover-up C-854 forbids
12
+ * (T-3.1 invariant 6).
13
+ *
14
+ * # Every entry names its source class (invariant 1)
15
+ *
16
+ * `VOCABULARY` carries one row per Aventara fact with its source code — `PSL`,
17
+ * `TYPE`, `RUN`, `DRIVER` or `CFG`. `VocabularyEntry.sources` is a **non-empty**
18
+ * tuple, so "an entry with no source" is a compile error rather than a silent
19
+ * default.
20
+ *
21
+ * # `@default` is matched, never parsed (invariant 5)
22
+ *
23
+ * `PRISMA_DEFAULT_TABLE` is looked up with the raw text the PSL reader carried
24
+ * across unchanged. `dbgenerated("gen_random_uuid()")` is a **key**, not an
25
+ * expression: the day this module evaluates one, the reader behind it has become
26
+ * a parser and needs a different decision (T-3). An unmatched form falls back to
27
+ * `PRISMA_UNMATCHED_DEFAULT_TRAITS` **plus** a recorded unknown that fails the
28
+ * generate step — never an inferred trait.
29
+ *
30
+ * `@db.*` is matched the same way, by its **exact written spelling**
31
+ * (`PRISMA_NATIVE_FORMATS`). `@db.Decimal(10, 2)` matches no key and therefore
32
+ * proves no format, which is the right answer arrived at without splitting an
33
+ * argument list.
34
+ *
35
+ * # This dictionary proposes no `CONTEXT.md` term
36
+ *
37
+ * It is adapter-internal data, not framework vocabulary. Its job is the opposite:
38
+ * no Prisma term reaches `AdapterModel` (invariant 2) — `AtLeast`,
39
+ * `WhereUniqueInput`, `FieldRef`, `@@map`, `take`/`skip` all die here.
40
+ */
41
+ /**
42
+ * `PSL` — `schema.prisma` · `TYPE` — the 🟢 generated types ·
43
+ * `RUN` — observed runtime behaviour · `DRIVER` — the configured Prisma driver
44
+ * adapter · `CFG` — framework configuration, which is policy and not discovery.
45
+ */
46
+ export type VocabularySource = "PSL" | "TYPE" | "RUN" | "DRIVER" | "CFG";
47
+ export type VocabularyEntry = {
48
+ /** The Aventara fact, spelled as T-3.1's left column spells it. */
49
+ readonly fact: string;
50
+ /** Non-empty by construction: invariant 1 is enforced by the type, not by a comment. */
51
+ readonly sources: readonly [VocabularySource, ...VocabularySource[]];
52
+ readonly rule: string;
53
+ };
54
+ /**
55
+ * T-3.1's table, row for row, so a reader can audit one against the other.
56
+ *
57
+ * **`format?` diverges from T-3.1's table deliberately, and the plan row is the
58
+ * one that is wrong.** T-3.1 says `format?` is `CFG` — "PSL's `@db.*` is a hint
59
+ * only … policy, not discovery". Spec §6.1 says the opposite in as many words:
60
+ * UUID "is a string scalar plus passive format metadata **when the adapter can
61
+ * prove the format**", §18.3's discovery mapping reads "scalar type → stable
62
+ * framework scalar + optional format", C-809 restates both, T-5 restates them
63
+ * again, and `AdapterScalarField.format?` exists **[CORE]** — a member with no
64
+ * producer if discovery never emits one. So the source is `PSL` **and** `CFG`:
65
+ * discovery emits what the provider's own column type proves, configuration owns
66
+ * everything else. `scalar.mapper.ts`'s header carries the full argument.
67
+ */
68
+ export declare const VOCABULARY: readonly VocabularyEntry[];
69
+ /**
70
+ * The closed set of ways a mapper refuses. It is dictionary data because a
71
+ * refusal is the dictionary's own answer: a construct it has no word for.
72
+ */
73
+ export type PrismaDiscoveryDiagnosticCode =
74
+ /** A Prisma type name in neither PRISMA_SCALAR_TABLE nor `enums.ts` (C-809). */
75
+ "unmapped-prisma-type"
76
+ /** PSL declares it, the 🟢 types do not expose it: omitted, with the reason said out loud (C-808). */
77
+ | "not-exposed"
78
+ /** PSL and `enums.ts` disagree about an enum's members or their order (§19.2). */
79
+ | "enum-diverged";
80
+ export type PrismaDiscoveryDiagnostic = {
81
+ readonly code: PrismaDiscoveryDiagnosticCode;
82
+ /** Written for the engineer who has to fix the schema, naming the entity it is about. */
83
+ readonly message: string;
84
+ };
85
+ /** T-5 — a proven scalar identity, plus a format only where something proves it. */
86
+ export type PrismaScalarMapping = {
87
+ readonly scalar: BuiltInScalar;
88
+ readonly format?: ScalarFormat;
89
+ };
90
+ export type PrismaScalarTable = Readonly<Record<string, PrismaScalarMapping>>;
91
+ /**
92
+ * Total and 1:1 over `BUILT_IN_SCALARS` **[CORE]**. There is no default arm: a
93
+ * Prisma type name absent from this table is a diagnostic, not a guess (C-809).
94
+ *
95
+ * **No row carries a `format`**, and that is the point: a format is a property of
96
+ * a *column*, not of a Prisma *type name*. `String` alone proves nothing, so the
97
+ * one thing that can prove something — the native column type — is a separate
98
+ * lookup (`PRISMA_NATIVE_FORMATS`).
99
+ */
100
+ export declare const PRISMA_SCALAR_TABLE: PrismaScalarTable;
101
+ /**
102
+ * The only `@db.*` spellings that **prove** a format, matched by exact written
103
+ * spelling and never parsed.
104
+ *
105
+ * The bar for a row here is not "the name suggests a format". It is: **the column
106
+ * type itself rejects the values `format` would later reject.** `format` is
107
+ * enforced, not decorative — `normalizeScalarFieldValue` turns `format: "uuid"`
108
+ * into a `V1003` rejection of request input **[CORE,
109
+ * `runtime/scalar-runtime.ts`]** — so a row that is merely probable would have
110
+ * Aventara refuse writes the database accepts.
111
+ *
112
+ * `@db.Uuid` clears that bar: PostgreSQL's `uuid` column rejects
113
+ * `'not-a-uuid'` (`ERROR: invalid input syntax for type uuid`) where a `text`
114
+ * column takes it **[RUN8 — 2026-09-28, `aventara-postgres`, postgres:18]**.
115
+ *
116
+ * `@default(uuid())` does **not** clear it, which is where T-5's wording is
117
+ * narrowed: on a `String` column with no `@db.Uuid` the column is `text`, only
118
+ * *generated* values are UUIDs, and a client may legally supply any string. That
119
+ * intent belongs in `FrameworkScalarFieldConfig.format` **[CORE]**, which the
120
+ * Contract compiler already applies over the adapter's value.
121
+ *
122
+ * `@db.Decimal(10, 2)` and `@db.VarChar(255)` are absent because they prove no
123
+ * *format*; they carry precision and width, which Aventara has no word for.
124
+ */
125
+ export declare const PRISMA_NATIVE_FORMATS: Readonly<Record<string, ScalarFormat>>;
126
+ /** Whether a row was exercised against 7.10.0 or is carried forward unproven (§12). */
127
+ export type PrismaEvidence = "RUN8" | "UNVERIFIED";
128
+ export type PrismaDefaultRow = {
129
+ /**
130
+ * Matched against `PrismaSchemaField.defaultArgument` exactly as the PSL
131
+ * reader carried it. A `literal` is compared with `===`; a `pattern` is
132
+ * tested. Neither reads *inside* the argument.
133
+ */
134
+ readonly match: {
135
+ readonly literal: string;
136
+ } | {
137
+ readonly pattern: RegExp;
138
+ };
139
+ readonly traits: readonly AdapterLifecycleTrait[];
140
+ readonly evidence: PrismaEvidence;
141
+ };
142
+ /**
143
+ * T-3.1's `@default` table.
144
+ *
145
+ * **`traits` is the whole trait set, where T-3.1's table lists only the trait the
146
+ * *argument* adds.** The two are consistent, not contradictory: `DEFAULTED` comes
147
+ * from `@default`'s **presence** (C-808: "`@default` → `DEFAULTED` and, when
148
+ * generator-owned, `GENERATED_ON_CREATE`"), and C-811's acceptance criteria spell
149
+ * the full sets out — `@default(autoincrement())` → `["DEFAULTED",
150
+ * "GENERATED_ON_CREATE"]`, `@default("x")` → `["DEFAULTED"]`. This table states
151
+ * the answer rather than half of it, so no consumer has to remember to add the
152
+ * other half.
153
+ *
154
+ * The lookup that walks this table lives with the lifecycle projection (Task 4),
155
+ * where it can be driven red; this pass owns the data only.
156
+ */
157
+ export declare const PRISMA_DEFAULT_TABLE: readonly PrismaDefaultRow[];
158
+ /**
159
+ * Any other text — `"BRONZE"`, `"x"`, `sequence()`, `nanoid()`, a spelling added
160
+ * after 7.10.0. The value is still `DEFAULTED`, because `@default` is present;
161
+ * the *unknown* is what fails the generate step, so an unrecognised generator
162
+ * function is a build stop rather than a column Aventara quietly thinks the
163
+ * client must supply.
164
+ */
165
+ export declare const PRISMA_UNMATCHED_DEFAULT_TRAITS: readonly AdapterLifecycleTrait[];
166
+ /**
167
+ * The dictionary's other half: the point at which Prisma's spelling stops and
168
+ * Aventara's begins.
169
+ *
170
+ * **One untyped `PRISMA_RENAMES` became six typed tables (2026-10-02, T-6).** The
171
+ * single `Record<string, string>` could not make a mistake a compile error: a
172
+ * rename to a word core does not have, or a Prisma key nobody decided about,
173
+ * both typechecked. Each table below is keyed on the Prisma spelling and valued in
174
+ * the ONE Aventara vocabulary that spelling can land in, so `"arrayContains"`
175
+ * misspelt fails to compile. The table had no consumer, so nothing was broken by
176
+ * splitting it.
177
+ *
178
+ * `null` is a value, not an omission: it means **recognised, and Aventara has no
179
+ * word for it** — the nested bulk writes, `distinct`, Prisma's `set` assignment.
180
+ * A key absent from a table is a different thing entirely, and the deriver that
181
+ * reads these refuses rather than dropping it silently, because a silently dropped
182
+ * capability key is how C-855's failure mode begins.
183
+ *
184
+ * C-837's relation *translator* table — which Prisma argument each directive emits
185
+ * — is still Task 9's. This is the vocabulary half only.
186
+ */
187
+ /**
188
+ * `<Kind>Filter` / `<Kind>NullableFilter` / `Json[Nullable]Filter` keys.
189
+ *
190
+ * Total and 1:1 over `ScalarFilterOperator` **[CORE]** at 7.10.0, measured over
191
+ * both generated clients: 23 Prisma keys, 23 Aventara operators, no survivor on
192
+ * either side.
193
+ */
194
+ export declare const PRISMA_FILTER_OPERATORS: Readonly<Record<string, ScalarFilterOperator>>;
195
+ /**
196
+ * `[Nullable]ScalarRelationFilter` and `ListRelationFilter` keys.
197
+ *
198
+ * `is` and `isNot` both answer `match`: §18.5 has one to-one matching capability
199
+ * and no `is`/`isNot` wrapper, so the two Prisma keys collapse into it. `nested`
200
+ * and `null` are **not** keys of any filter input — they are read off the edge's
201
+ * own `where` argument and off the edge's nullability — so they are absent here by
202
+ * construction rather than by omission.
203
+ */
204
+ export declare const PRISMA_RELATION_FILTERS: Readonly<Record<string, RelationFilterCapability>>;
205
+ /**
206
+ * `<Kind>FieldUpdateOperationsInput` and `<M><Stage><field>Input` keys.
207
+ *
208
+ * `set` is `null` because plain assignment is not a directive in Aventara: the
209
+ * value is written directly, and `ScalarMutationDirective` has no `$set`
210
+ * **[CORE]**. `unset` is carried although neither Phase 8 engine emits it — it is
211
+ * Mongo's, and a key the dictionary recognises and never advertises is better than
212
+ * one that makes the deriver throw the day a third provider is added.
213
+ */
214
+ export declare const PRISMA_SCALAR_DIRECTIVES: Readonly<Record<string, ScalarMutationDirective | null>>;
215
+ /**
216
+ * `<M>Update<edge>Without<M>NestedInput` / `<M>Create<edge>…NestedInput` keys.
217
+ *
218
+ * `createMany`, `updateMany` and `deleteMany` are `null`: they are nested BULK
219
+ * writes, and `RelationMutationDirective` models per-row intent only **[CORE]**.
220
+ * Aventara expresses the same effect by addressing the target Resource, so
221
+ * advertising them would promise an argument no directive could carry.
222
+ */
223
+ export declare const PRISMA_RELATION_DIRECTIVES: Readonly<Record<string, RelationMutationDirective | null>>;
224
+ /**
225
+ * `<M>$<edge>Args` keys, valued in `PaginationCapability`.
226
+ *
227
+ * `null` means the argument is read for something else, or for nothing:
228
+ * `orderBy` answers `order`, `where` answers the `nested` filter capability,
229
+ * `select`/`omit`/`include` answer projection, and `distinct` is a Prisma concept
230
+ * Aventara has no word for. The table is total over the keys both clients write,
231
+ * so a new edge argument at 7.11 is an unrecognised key rather than a silent drop.
232
+ */
233
+ export declare const PRISMA_EDGE_ARGUMENTS: Readonly<Record<string, PaginationCapability | null>>;
234
+ /** `_count` on `<M>Include` / `<M>CountOutputType`. */
235
+ export declare const PRISMA_REDUCERS: Readonly<Record<string, "$count">>;
236
+ export type ObservedValueShape = {
237
+ /** The Prisma type name, as PSL writes it. */
238
+ readonly prismaType: string;
239
+ /** The JavaScript value the client hands back, stated exactly. */
240
+ readonly shape: string;
241
+ /** The driver adapters it was observed through — inlined, never generalised. */
242
+ readonly engines: readonly string[];
243
+ readonly evidence: PrismaEvidence;
244
+ };
245
+ /**
246
+ * Task 1's observations, inlined with the engines they were made on
247
+ * **[RUN8, `src/environment.spec.ts`]**. Identical through both driver adapters,
248
+ * so the representation is not driver-dependent *between these two engines* —
249
+ * which is a narrower claim than "not driver-dependent", and the narrower one is
250
+ * what was measured.
251
+ *
252
+ * A row is `RUN8` only where a read-back value was actually asserted. `String`,
253
+ * `Boolean`, `Int` and `Float` were written into a row and never read back under
254
+ * assertion, so they stay `[UNVERIFIED]` (§12): a plausible value shape is not an
255
+ * observed one, and this table exists precisely so that nobody has to guess which
256
+ * is which.
257
+ */
258
+ export declare const OBSERVED_VALUE_SHAPES: readonly ObservedValueShape[];
@@ -0,0 +1,429 @@
1
+ /**
2
+ * T-3.1's table, row for row, so a reader can audit one against the other.
3
+ *
4
+ * **`format?` diverges from T-3.1's table deliberately, and the plan row is the
5
+ * one that is wrong.** T-3.1 says `format?` is `CFG` — "PSL's `@db.*` is a hint
6
+ * only … policy, not discovery". Spec §6.1 says the opposite in as many words:
7
+ * UUID "is a string scalar plus passive format metadata **when the adapter can
8
+ * prove the format**", §18.3's discovery mapping reads "scalar type → stable
9
+ * framework scalar + optional format", C-809 restates both, T-5 restates them
10
+ * again, and `AdapterScalarField.format?` exists **[CORE]** — a member with no
11
+ * producer if discovery never emits one. So the source is `PSL` **and** `CFG`:
12
+ * discovery emits what the provider's own column type proves, configuration owns
13
+ * everything else. `scalar.mapper.ts`'s header carries the full argument.
14
+ */
15
+ export const VOCABULARY = [
16
+ {
17
+ fact: 'kind: "scalar" / "relation"',
18
+ sources: ["PSL", "TYPE"],
19
+ rule: "PSL decides by whether the written type name is a model name; TYPE gates existence.",
20
+ },
21
+ {
22
+ fact: "nullable",
23
+ sources: ["PSL"],
24
+ rule: "Never TYPE (invariant 4): `JsonValue` contains `null` because JSON null is a value, so a types-derived nullable is wrong for every Json field.",
25
+ },
26
+ {
27
+ fact: "list",
28
+ sources: ["PSL", "TYPE"],
29
+ rule: "PSL states it; TYPE states whether this provider exposes it. A list in PSL that the types drop is a generate-time error.",
30
+ },
31
+ {
32
+ fact: "type.scalar / type.enum",
33
+ sources: ["PSL", "TYPE"],
34
+ rule: "PRISMA_SCALAR_TABLE is total and 1:1 over the nine built-ins; an enum name is confirmed against `enums.ts`.",
35
+ },
36
+ {
37
+ fact: "format?",
38
+ sources: ["PSL", "CFG"],
39
+ rule: "PSL supplies it only through PRISMA_NATIVE_FORMATS — a native column type that itself rejects the values `format` would later reject. Every other format is CFG. See this constant's doc comment.",
40
+ },
41
+ {
42
+ fact: "relation target / cardinality / nullable",
43
+ sources: ["PSL", "TYPE"],
44
+ rule: "—",
45
+ },
46
+ {
47
+ fact: "relation pairing",
48
+ sources: ["PSL"],
49
+ rule: '`@relation("Mentorship")` on both sides is the only pairing evidence; the name appears nowhere on the 🟢 surface.',
50
+ },
51
+ {
52
+ fact: "lifecycle traits",
53
+ sources: ["PSL"],
54
+ rule: "PRISMA_DEFAULT_TABLE plus `@updatedAt`; TYPE is a cross-check only, because the create-optional marker is one bit over four causes.",
55
+ },
56
+ {
57
+ fact: "identifiers",
58
+ sources: ["PSL"],
59
+ rule: "`@id`/`@@id`/`@unique`/`@@unique`, member order as written; cross-checked against TYPE's key set as a subset with one closed explanation.",
60
+ },
61
+ {
62
+ fact: "enum values",
63
+ sources: ["PSL"],
64
+ rule: "Declaration order is semantic (§19.2) and is never sorted; cross-checked against `enums.ts`.",
65
+ },
66
+ {
67
+ fact: "field & operation capabilities",
68
+ sources: ["TYPE"],
69
+ rule: "Per-kind filter sets, mutation directives, edge pagination, `_count`, and `<M>Delegate`'s own method set — read, never tabulated.",
70
+ },
71
+ {
72
+ fact: "JS value shapes",
73
+ sources: ["RUN"],
74
+ rule: "OBSERVED_VALUE_SHAPES; anything not observed stays [UNVERIFIED] and is never promoted.",
75
+ },
76
+ {
77
+ fact: "transactions",
78
+ sources: ["DRIVER"],
79
+ rule: "F-801 — the configured driver adapter, not the provider name.",
80
+ },
81
+ {
82
+ fact: "COMPUTED_* / VIRTUAL",
83
+ sources: ["CFG"],
84
+ rule: "Outside `AdapterLifecycleTrait` by construction [CORE]; the adapter cannot emit them.",
85
+ },
86
+ ];
87
+ /**
88
+ * Total and 1:1 over `BUILT_IN_SCALARS` **[CORE]**. There is no default arm: a
89
+ * Prisma type name absent from this table is a diagnostic, not a guess (C-809).
90
+ *
91
+ * **No row carries a `format`**, and that is the point: a format is a property of
92
+ * a *column*, not of a Prisma *type name*. `String` alone proves nothing, so the
93
+ * one thing that can prove something — the native column type — is a separate
94
+ * lookup (`PRISMA_NATIVE_FORMATS`).
95
+ */
96
+ export const PRISMA_SCALAR_TABLE = {
97
+ String: { scalar: "string" },
98
+ Boolean: { scalar: "boolean" },
99
+ Int: { scalar: "int" },
100
+ Float: { scalar: "float" },
101
+ BigInt: { scalar: "bigint" },
102
+ Decimal: { scalar: "decimal" },
103
+ DateTime: { scalar: "datetime" },
104
+ Bytes: { scalar: "bytes" },
105
+ Json: { scalar: "json" },
106
+ };
107
+ /**
108
+ * The only `@db.*` spellings that **prove** a format, matched by exact written
109
+ * spelling and never parsed.
110
+ *
111
+ * The bar for a row here is not "the name suggests a format". It is: **the column
112
+ * type itself rejects the values `format` would later reject.** `format` is
113
+ * enforced, not decorative — `normalizeScalarFieldValue` turns `format: "uuid"`
114
+ * into a `V1003` rejection of request input **[CORE,
115
+ * `runtime/scalar-runtime.ts`]** — so a row that is merely probable would have
116
+ * Aventara refuse writes the database accepts.
117
+ *
118
+ * `@db.Uuid` clears that bar: PostgreSQL's `uuid` column rejects
119
+ * `'not-a-uuid'` (`ERROR: invalid input syntax for type uuid`) where a `text`
120
+ * column takes it **[RUN8 — 2026-09-28, `aventara-postgres`, postgres:18]**.
121
+ *
122
+ * `@default(uuid())` does **not** clear it, which is where T-5's wording is
123
+ * narrowed: on a `String` column with no `@db.Uuid` the column is `text`, only
124
+ * *generated* values are UUIDs, and a client may legally supply any string. That
125
+ * intent belongs in `FrameworkScalarFieldConfig.format` **[CORE]**, which the
126
+ * Contract compiler already applies over the adapter's value.
127
+ *
128
+ * `@db.Decimal(10, 2)` and `@db.VarChar(255)` are absent because they prove no
129
+ * *format*; they carry precision and width, which Aventara has no word for.
130
+ */
131
+ export const PRISMA_NATIVE_FORMATS = {
132
+ "@db.Uuid": "uuid",
133
+ };
134
+ /**
135
+ * T-3.1's `@default` table.
136
+ *
137
+ * **`traits` is the whole trait set, where T-3.1's table lists only the trait the
138
+ * *argument* adds.** The two are consistent, not contradictory: `DEFAULTED` comes
139
+ * from `@default`'s **presence** (C-808: "`@default` → `DEFAULTED` and, when
140
+ * generator-owned, `GENERATED_ON_CREATE`"), and C-811's acceptance criteria spell
141
+ * the full sets out — `@default(autoincrement())` → `["DEFAULTED",
142
+ * "GENERATED_ON_CREATE"]`, `@default("x")` → `["DEFAULTED"]`. This table states
143
+ * the answer rather than half of it, so no consumer has to remember to add the
144
+ * other half.
145
+ *
146
+ * The lookup that walks this table lives with the lifecycle projection (Task 4),
147
+ * where it can be driven red; this pass owns the data only.
148
+ */
149
+ export const PRISMA_DEFAULT_TABLE = [
150
+ {
151
+ match: { literal: "uuid()" },
152
+ traits: ["DEFAULTED", "GENERATED_ON_CREATE"],
153
+ evidence: "RUN8",
154
+ },
155
+ {
156
+ match: { literal: "uuid(4)" },
157
+ traits: ["DEFAULTED", "GENERATED_ON_CREATE"],
158
+ evidence: "UNVERIFIED",
159
+ },
160
+ {
161
+ match: { literal: "uuid(7)" },
162
+ traits: ["DEFAULTED", "GENERATED_ON_CREATE"],
163
+ evidence: "UNVERIFIED",
164
+ },
165
+ {
166
+ match: { literal: "cuid()" },
167
+ traits: ["DEFAULTED", "GENERATED_ON_CREATE"],
168
+ evidence: "RUN8",
169
+ },
170
+ {
171
+ match: { literal: "cuid(1)" },
172
+ traits: ["DEFAULTED", "GENERATED_ON_CREATE"],
173
+ evidence: "UNVERIFIED",
174
+ },
175
+ {
176
+ match: { literal: "cuid(2)" },
177
+ traits: ["DEFAULTED", "GENERATED_ON_CREATE"],
178
+ evidence: "UNVERIFIED",
179
+ },
180
+ {
181
+ match: { literal: "autoincrement()" },
182
+ traits: ["DEFAULTED", "GENERATED_ON_CREATE"],
183
+ evidence: "RUN8",
184
+ },
185
+ {
186
+ match: { literal: "now()" },
187
+ traits: ["DEFAULTED", "GENERATED_ON_CREATE"],
188
+ evidence: "RUN8",
189
+ },
190
+ {
191
+ match: { pattern: /^dbgenerated\(/ },
192
+ traits: ["DEFAULTED", "GENERATED_ON_CREATE"],
193
+ evidence: "RUN8",
194
+ },
195
+ {
196
+ // Mongo; unreachable for the SQL providers Phase 8 supports.
197
+ match: { pattern: /^auto\(\)$/ },
198
+ traits: ["DEFAULTED", "GENERATED_ON_CREATE"],
199
+ evidence: "UNVERIFIED",
200
+ },
201
+ ];
202
+ /**
203
+ * Any other text — `"BRONZE"`, `"x"`, `sequence()`, `nanoid()`, a spelling added
204
+ * after 7.10.0. The value is still `DEFAULTED`, because `@default` is present;
205
+ * the *unknown* is what fails the generate step, so an unrecognised generator
206
+ * function is a build stop rather than a column Aventara quietly thinks the
207
+ * client must supply.
208
+ */
209
+ export const PRISMA_UNMATCHED_DEFAULT_TRAITS = ["DEFAULTED"];
210
+ /* ------------------------------------------------------------------ *
211
+ * Prisma → Aventara renames (invariant 2) *
212
+ * ------------------------------------------------------------------ */
213
+ /**
214
+ * The dictionary's other half: the point at which Prisma's spelling stops and
215
+ * Aventara's begins.
216
+ *
217
+ * **One untyped `PRISMA_RENAMES` became six typed tables (2026-10-02, T-6).** The
218
+ * single `Record<string, string>` could not make a mistake a compile error: a
219
+ * rename to a word core does not have, or a Prisma key nobody decided about,
220
+ * both typechecked. Each table below is keyed on the Prisma spelling and valued in
221
+ * the ONE Aventara vocabulary that spelling can land in, so `"arrayContains"`
222
+ * misspelt fails to compile. The table had no consumer, so nothing was broken by
223
+ * splitting it.
224
+ *
225
+ * `null` is a value, not an omission: it means **recognised, and Aventara has no
226
+ * word for it** — the nested bulk writes, `distinct`, Prisma's `set` assignment.
227
+ * A key absent from a table is a different thing entirely, and the deriver that
228
+ * reads these refuses rather than dropping it silently, because a silently dropped
229
+ * capability key is how C-855's failure mode begins.
230
+ *
231
+ * C-837's relation *translator* table — which Prisma argument each directive emits
232
+ * — is still Task 9's. This is the vocabulary half only.
233
+ */
234
+ /**
235
+ * `<Kind>Filter` / `<Kind>NullableFilter` / `Json[Nullable]Filter` keys.
236
+ *
237
+ * Total and 1:1 over `ScalarFilterOperator` **[CORE]** at 7.10.0, measured over
238
+ * both generated clients: 23 Prisma keys, 23 Aventara operators, no survivor on
239
+ * either side.
240
+ */
241
+ export const PRISMA_FILTER_OPERATORS = {
242
+ equals: "equals",
243
+ not: "not",
244
+ in: "in",
245
+ notIn: "notIn",
246
+ lt: "lt",
247
+ lte: "lte",
248
+ gt: "gt",
249
+ gte: "gte",
250
+ contains: "contains",
251
+ startsWith: "startsWith",
252
+ endsWith: "endsWith",
253
+ mode: "mode",
254
+ has: "has",
255
+ hasEvery: "hasEvery",
256
+ hasSome: "hasSome",
257
+ isEmpty: "isEmpty",
258
+ path: "path",
259
+ string_contains: "stringContains",
260
+ string_starts_with: "stringStartsWith",
261
+ string_ends_with: "stringEndsWith",
262
+ array_contains: "arrayContains",
263
+ array_starts_with: "arrayStartsWith",
264
+ array_ends_with: "arrayEndsWith",
265
+ };
266
+ /**
267
+ * `[Nullable]ScalarRelationFilter` and `ListRelationFilter` keys.
268
+ *
269
+ * `is` and `isNot` both answer `match`: §18.5 has one to-one matching capability
270
+ * and no `is`/`isNot` wrapper, so the two Prisma keys collapse into it. `nested`
271
+ * and `null` are **not** keys of any filter input — they are read off the edge's
272
+ * own `where` argument and off the edge's nullability — so they are absent here by
273
+ * construction rather than by omission.
274
+ */
275
+ export const PRISMA_RELATION_FILTERS = {
276
+ is: "match",
277
+ isNot: "match",
278
+ some: "some",
279
+ every: "every",
280
+ none: "none",
281
+ };
282
+ /**
283
+ * `<Kind>FieldUpdateOperationsInput` and `<M><Stage><field>Input` keys.
284
+ *
285
+ * `set` is `null` because plain assignment is not a directive in Aventara: the
286
+ * value is written directly, and `ScalarMutationDirective` has no `$set`
287
+ * **[CORE]**. `unset` is carried although neither Phase 8 engine emits it — it is
288
+ * Mongo's, and a key the dictionary recognises and never advertises is better than
289
+ * one that makes the deriver throw the day a third provider is added.
290
+ */
291
+ export const PRISMA_SCALAR_DIRECTIVES = {
292
+ set: null,
293
+ increment: "$increment",
294
+ decrement: "$decrement",
295
+ multiply: "$multiply",
296
+ divide: "$divide",
297
+ push: "$push",
298
+ unset: "$unset",
299
+ };
300
+ /**
301
+ * `<M>Update<edge>Without<M>NestedInput` / `<M>Create<edge>…NestedInput` keys.
302
+ *
303
+ * `createMany`, `updateMany` and `deleteMany` are `null`: they are nested BULK
304
+ * writes, and `RelationMutationDirective` models per-row intent only **[CORE]**.
305
+ * Aventara expresses the same effect by addressing the target Resource, so
306
+ * advertising them would promise an argument no directive could carry.
307
+ */
308
+ export const PRISMA_RELATION_DIRECTIVES = {
309
+ create: "$create",
310
+ connect: "$connect",
311
+ connectOrCreate: "$connectOrCreate",
312
+ disconnect: "$disconnect",
313
+ set: "$set",
314
+ update: "$update",
315
+ delete: "$delete",
316
+ upsert: "$upsert",
317
+ createMany: null,
318
+ updateMany: null,
319
+ deleteMany: null,
320
+ };
321
+ /**
322
+ * `<M>$<edge>Args` keys, valued in `PaginationCapability`.
323
+ *
324
+ * `null` means the argument is read for something else, or for nothing:
325
+ * `orderBy` answers `order`, `where` answers the `nested` filter capability,
326
+ * `select`/`omit`/`include` answer projection, and `distinct` is a Prisma concept
327
+ * Aventara has no word for. The table is total over the keys both clients write,
328
+ * so a new edge argument at 7.11 is an unrecognised key rather than a silent drop.
329
+ */
330
+ export const PRISMA_EDGE_ARGUMENTS = {
331
+ take: "limit",
332
+ skip: "offset",
333
+ cursor: "cursor",
334
+ orderBy: null,
335
+ distinct: null,
336
+ select: null,
337
+ omit: null,
338
+ include: null,
339
+ where: null,
340
+ };
341
+ /** `_count` on `<M>Include` / `<M>CountOutputType`. */
342
+ export const PRISMA_REDUCERS = {
343
+ _count: "$count",
344
+ };
345
+ const BOTH_ENGINES = [
346
+ "@prisma/adapter-better-sqlite3",
347
+ "@prisma/adapter-pg",
348
+ ];
349
+ /**
350
+ * Task 1's observations, inlined with the engines they were made on
351
+ * **[RUN8, `src/environment.spec.ts`]**. Identical through both driver adapters,
352
+ * so the representation is not driver-dependent *between these two engines* —
353
+ * which is a narrower claim than "not driver-dependent", and the narrower one is
354
+ * what was measured.
355
+ *
356
+ * A row is `RUN8` only where a read-back value was actually asserted. `String`,
357
+ * `Boolean`, `Int` and `Float` were written into a row and never read back under
358
+ * assertion, so they stay `[UNVERIFIED]` (§12): a plausible value shape is not an
359
+ * observed one, and this table exists precisely so that nobody has to guess which
360
+ * is which.
361
+ */
362
+ export const OBSERVED_VALUE_SHAPES = [
363
+ {
364
+ prismaType: "Decimal",
365
+ shape: 'an object whose constructor is `Decimal2` (Prisma\'s bundled decimal.js), carrying `toFixed`, whose `JSON.stringify` is a string ("1.25") and which is never a number',
366
+ engines: BOTH_ENGINES,
367
+ evidence: "RUN8",
368
+ },
369
+ {
370
+ prismaType: "BigInt",
371
+ shape: "a `bigint` primitive; 9007199254740993n round-tripped exactly, beyond Number.MAX_SAFE_INTEGER",
372
+ engines: BOTH_ENGINES,
373
+ evidence: "RUN8",
374
+ },
375
+ {
376
+ prismaType: "DateTime",
377
+ shape: "a `Date`",
378
+ engines: BOTH_ENGINES,
379
+ evidence: "RUN8",
380
+ },
381
+ {
382
+ prismaType: "Bytes",
383
+ shape: "a `Uint8Array` with `Buffer.isBuffer(v) === false`",
384
+ engines: BOTH_ENGINES,
385
+ evidence: "RUN8",
386
+ },
387
+ {
388
+ prismaType: "Json",
389
+ shape: "a plain object",
390
+ engines: BOTH_ENGINES,
391
+ evidence: "RUN8",
392
+ },
393
+ {
394
+ prismaType: "<enum>",
395
+ shape: "a plain string — the PSL member name, never the `@map`ped database name",
396
+ engines: BOTH_ENGINES,
397
+ evidence: "RUN8",
398
+ },
399
+ {
400
+ prismaType: "<absent nullable>",
401
+ shape: "`null`",
402
+ engines: BOTH_ENGINES,
403
+ evidence: "RUN8",
404
+ },
405
+ {
406
+ prismaType: "String",
407
+ shape: "[UNVERIFIED]",
408
+ engines: BOTH_ENGINES,
409
+ evidence: "UNVERIFIED",
410
+ },
411
+ {
412
+ prismaType: "Boolean",
413
+ shape: "[UNVERIFIED]",
414
+ engines: BOTH_ENGINES,
415
+ evidence: "UNVERIFIED",
416
+ },
417
+ {
418
+ prismaType: "Int",
419
+ shape: "[UNVERIFIED]",
420
+ engines: BOTH_ENGINES,
421
+ evidence: "UNVERIFIED",
422
+ },
423
+ {
424
+ prismaType: "Float",
425
+ shape: "[UNVERIFIED]",
426
+ engines: BOTH_ENGINES,
427
+ evidence: "UNVERIFIED",
428
+ },
429
+ ];