@aventara/prisma7-adapter 0.1.0-pilot.3 → 0.1.0-pilot.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -22
- package/dist/discovery/artifact.loader.d.ts +2 -7
- package/dist/discovery/artifact.loader.js +4 -0
- package/dist/discovery/capability-surface.interface.d.ts +2 -66
- package/dist/discovery/capability.deriver.d.ts +2 -47
- package/dist/discovery/discovery-artifact.interface.d.ts +34 -155
- package/dist/discovery/discovery-artifact.interface.js +1 -1
- package/dist/discovery/enum.mapper.d.ts +0 -24
- package/dist/discovery/field.mapper.d.ts +3 -114
- package/dist/discovery/field.mapper.js +6 -6
- package/dist/discovery/identifier.mapper.d.ts +4 -84
- package/dist/discovery/model.discoverer.d.ts +2 -69
- package/dist/discovery/operations.deriver.d.ts +0 -36
- package/dist/discovery/scalar.mapper.d.ts +1 -32
- package/dist/discovery/scalar.mapper.js +2 -2
- package/dist/discovery/schema-facts.interface.d.ts +3 -83
- package/dist/discovery/schema.reader.d.ts +0 -133
- package/dist/discovery/types.reader.d.ts +1 -9
- package/dist/discovery/types.reader.js +7 -7
- package/dist/discovery/vocabulary.dictionary.d.ts +6 -133
- package/dist/discovery/vocabulary.dictionary.js +2 -2
- package/dist/errors/error.normalizer.d.ts +5 -168
- package/dist/errors/prisma-error.reader.d.ts +1 -93
- package/dist/execution/first-variant.emulator.d.ts +5 -28
- package/dist/execution/operation.executor.d.ts +1 -62
- package/dist/execution/result.shaper.d.ts +0 -56
- package/dist/execution/transaction.executor.d.ts +0 -98
- package/dist/generate/artifact.emitter.d.ts +1 -35
- package/dist/generate/artifact.emitter.js +26 -43
- package/dist/generate/declared-support.reader.d.ts +0 -20
- package/dist/generate/discovery.cli.d.ts +0 -4
- package/dist/generate/existence.gate.d.ts +3 -37
- package/dist/generate/index.d.ts +4 -57
- package/dist/generate/prisma-cli.resolver.d.ts +0 -22
- package/dist/generate/prisma.generate.d.ts +14 -83
- package/dist/generate/reader-crosscheck.d.ts +3 -88
- package/dist/generate/reader-crosscheck.js +4 -4
- package/dist/prisma-client.interface.d.ts +5 -25
- package/dist/prisma.adapter.d.ts +21 -22
- package/dist/provider/provider-profile.d.ts +6 -14
- package/dist/translation/identifier.addressing.d.ts +0 -38
- package/dist/translation/mutation.translator.d.ts +5 -51
- package/dist/translation/operation.translator.d.ts +1 -102
- package/dist/translation/order-pagination.translator.d.ts +1 -47
- package/dist/translation/projection.translator.d.ts +1 -46
- package/dist/translation/scalar.conversion.d.ts +0 -64
- package/dist/translation/where.translator.d.ts +0 -52
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ The Prisma 7 Adapter for Aventara. It discovers what a Prisma schema and its gen
|
|
|
4
4
|
compiles that into an Aventara `AdapterModel`, and executes validated Aventara operations against a
|
|
5
5
|
Prisma client the application owns.
|
|
6
6
|
|
|
7
|
-
This document is written for the person
|
|
7
|
+
This document is written for the person setting it up in an application. It states what the adapter
|
|
8
8
|
does, what it deliberately does **not** offer, and the two places where a correct Aventara operation
|
|
9
9
|
has a weaker guarantee than its name suggests. Everything a consumer has to know is in the body of
|
|
10
10
|
this file; nothing load-bearing is in a footnote.
|
|
@@ -13,7 +13,7 @@ this file; nothing load-bearing is in a footnote.
|
|
|
13
13
|
unmeasured, and this file says so where it matters.
|
|
14
14
|
- **Peer dependencies:** `@prisma/client` `^7.10.0` (required); `prisma`, `@prisma/adapter-better-sqlite3`
|
|
15
15
|
and `@prisma/adapter-pg` `^7.10.0` and `typescript` `>=5.5.0 <7` (optional). 7.10.0 is the version the
|
|
16
|
-
error map
|
|
16
|
+
error map targets; the adapter is bound to Prisma **7**'s error surface; see
|
|
17
17
|
[Prisma 7 only](#prisma-7-only).
|
|
18
18
|
|
|
19
19
|
---
|
|
@@ -59,8 +59,8 @@ checks is a `crypto.subtle` promise — so every fence fires once, here, before
|
|
|
59
59
|
|
|
60
60
|
### `maxWait`, `timeout` and `isolationLevel` are adapter-owned
|
|
61
61
|
|
|
62
|
-
They are provider concepts. Core's `Adapter.transaction(work)`
|
|
63
|
-
grow any, so these live on `createPrismaAdapter({ transactionOptions })` and are not Aventara public
|
|
62
|
+
They are provider concepts. Core's `Adapter.transaction(work)` interface carries no options and will
|
|
63
|
+
not grow any, so these live on `createPrismaAdapter({ transactionOptions })` and are not Aventara public
|
|
64
64
|
configuration. Prisma's own defaults stand when they are absent: `maxWait` 2000 ms, `timeout` 5000 ms.
|
|
65
65
|
|
|
66
66
|
Supported isolation levels come from the declared provider: PostgreSQL admits `ReadUncommitted`,
|
|
@@ -177,7 +177,7 @@ Operation availability is **derived**, never assumed. Every omission is decided
|
|
|
177
177
|
three facts: the generated delegate's own method set, the Resource's identifiers, and the driver's
|
|
178
178
|
transaction capability.
|
|
179
179
|
|
|
180
|
-
|
|
180
|
+
For a typical schema the compiled Contracts advertise **fifteen** distinct
|
|
181
181
|
`family.variant` operations, identically on all three Contract scopes. `delete.many` is **not** one of
|
|
182
182
|
them.
|
|
183
183
|
|
|
@@ -198,7 +198,7 @@ are derived — so `if (provider === …)` is a compile error rather than a code
|
|
|
198
198
|
the rule because a provider table is a second source of truth that drifts, silently, one Prisma
|
|
199
199
|
release at a time.
|
|
200
200
|
|
|
201
|
-
|
|
201
|
+
Consequences on PostgreSQL and SQLite, all of them read from generated types rather than
|
|
202
202
|
tabulated:
|
|
203
203
|
|
|
204
204
|
| Capability | PostgreSQL | SQLite | Read from |
|
|
@@ -213,7 +213,7 @@ tabulated:
|
|
|
213
213
|
**Beyond PostgreSQL and SQLite nothing here is measured.** MySQL, SQL Server, MongoDB, CockroachDB
|
|
214
214
|
and D1 were not generated against. Because every capability is read from the client you actually
|
|
215
215
|
generated, a provider that lacks something advertises less rather than failing at runtime — but the
|
|
216
|
-
|
|
216
|
+
this release makes no claim about them.
|
|
217
217
|
|
|
218
218
|
### `update.many` and `create.many` cannot project a to-many relation
|
|
219
219
|
|
|
@@ -277,7 +277,7 @@ no re-assertion can, because the missing fact is about a record that was never r
|
|
|
277
277
|
|
|
278
278
|
This is a **documented, permitted property** of a framework-manufactured variant, published as
|
|
279
279
|
policy rather than discovered in practice. Serializable isolation is not the remedy: core's
|
|
280
|
-
`Adapter.transaction(work)`
|
|
280
|
+
`Adapter.transaction(work)` interface carries no isolation parameter, so an adapter cannot set a level for
|
|
281
281
|
a manufactured variant or for a plan, and a provider transaction's level is fixed before its first
|
|
282
282
|
statement, so a per-operation escalation is not expressible at all. SQLite admits `Serializable`
|
|
283
283
|
only, and the residual persists there regardless.
|
|
@@ -293,7 +293,7 @@ closed" without naming one is wrong.
|
|
|
293
293
|
### Why the write is by identifier and not by Prisma's `limit`
|
|
294
294
|
|
|
295
295
|
Prisma **does** offer a top-level `limit` on `updateMany`, `deleteMany` and `updateManyAndReturn` in
|
|
296
|
-
7.10.0 —
|
|
296
|
+
7.10.0 — present on every model on PostgreSQL and SQLite. The adapter does not use it, and the
|
|
297
297
|
reason is not concealment: Aventara's doctrine is to **expose** what the ORM offers, not to hide it.
|
|
298
298
|
|
|
299
299
|
The reason is that `limit` **cannot express this operation**. None of those three argument types
|
|
@@ -321,13 +321,13 @@ prose, may change, and deliberately says less than the provider did.
|
|
|
321
321
|
|
|
322
322
|
### The three conflict codes
|
|
323
323
|
|
|
324
|
-
Three situations
|
|
324
|
+
Three different situations each have their own code.
|
|
325
325
|
|
|
326
326
|
| Code | Means | Retry? |
|
|
327
327
|
|---|---|---|
|
|
328
328
|
| `A2008 CONFLICT` | The operation would violate a **uniqueness or reference constraint** the Resource declares. Raised from Prisma's `P2002` and `P2003`. | No — re-running the same request unchanged fails the same way. |
|
|
329
329
|
| `A2013 CONCURRENT_MODIFICATION` | Another operation **modified the same state concurrently**, so this operation was not applied and nothing was written. Raised from Prisma's `P2034`. | Yes, the same request may succeed. The framework performs **no** automatic retry. |
|
|
330
|
-
| `A2014 STALE_SELECTION` | The state this operation had **selected changed** before its effect could be applied, so nothing was written. Raised by the
|
|
330
|
+
| `A2014 STALE_SELECTION` | The state this operation had **selected changed** before its effect could be applied, so nothing was written. Raised by the adapter's `update.first` and `delete.first`. | Yes, the same request may succeed. No automatic retry. |
|
|
331
331
|
|
|
332
332
|
`A2008` **narrowed** to the constraint case; it was not repurposed. If you previously treated `A2008`
|
|
333
333
|
as "any conflict", the two situations that left it now have their own codes.
|
|
@@ -342,7 +342,7 @@ Two consequences worth stating explicitly:
|
|
|
342
342
|
constraint; the envelope does **not** say so, and nothing should be parsed out of it.
|
|
343
343
|
- **A write conflict and a deadlock share `A2013` deliberately.** Both arrive as `P2034` with
|
|
344
344
|
identical `meta` keys, differing only in a provider-owned code (`40001` versus `40P01`) that never
|
|
345
|
-
crosses the boundary. They
|
|
345
|
+
crosses the boundary. They cannot be told apart here, so one outcome is the honest answer.
|
|
346
346
|
|
|
347
347
|
### None of the three carries `cause.issues`
|
|
348
348
|
|
|
@@ -380,13 +380,13 @@ hook.
|
|
|
380
380
|
answers `A3002 TRANSACTION_ERROR` for the failure that *ends* the transaction, and never reads the
|
|
381
381
|
message text to decide anything.
|
|
382
382
|
|
|
383
|
-
What is separable **structurally** (
|
|
383
|
+
What is separable **structurally** (on PostgreSQL and SQLite, never inferred from docs):
|
|
384
384
|
|
|
385
385
|
| Situation | Code | `meta` |
|
|
386
386
|
|---|---|---|
|
|
387
387
|
| Transaction-timeout expiry | `P2028` | `{ operation, timeout, timeTaken }` — the expiry is identifiable |
|
|
388
388
|
| `maxWait` acquisition timeout | `P2028` | **empty** — identifiable *by* that emptiness, and by nothing finer |
|
|
389
|
-
| Valid-but-unsupported isolation level (e.g. `Snapshot` on either
|
|
389
|
+
| Valid-but-unsupported isolation level (e.g. `Snapshot` on either engine) | `P2028` | `{ isolationLevel }` |
|
|
390
390
|
| An isolation level outside Prisma's own set (e.g. `"Bogus"`) | **`P2023`** | `{ providedIsolationLevel }` — a different code entirely |
|
|
391
391
|
|
|
392
392
|
The remaining **four** classes — transaction not found, already committed, already rolled back, and
|
|
@@ -431,7 +431,7 @@ transaction**. It is one `client.$transaction(async (tx) => …)` per Aventara t
|
|
|
431
431
|
- the **root client is unreachable** from inside the callback: the executor core is handed closes over
|
|
432
432
|
the transaction client and nothing else;
|
|
433
433
|
- the value the callback threw is rethrown **by identity**. The adapter adds no `try`, no `catch` and
|
|
434
|
-
no wrapper, because that is what
|
|
434
|
+
no wrapper, because that is what core's transaction interface requires and wrapping would turn every plan failure into
|
|
435
435
|
an integrity failure.
|
|
436
436
|
|
|
437
437
|
A first-style variant inside a plan **reuses the plan's transaction** rather than opening a nested
|
|
@@ -495,8 +495,8 @@ the inverted reading produces no error at all, only a plan that reasons backward
|
|
|
495
495
|
Only **owning** edges appear: PSL forbids the non-owning side of a relation from declaring an action,
|
|
496
496
|
so a back-reference's answer is its partner's and carries no entry of its own. Both actions are
|
|
497
497
|
*resolved* — an absent PSL argument is not a third state but Prisma's effective default (`set-null`
|
|
498
|
-
where every foreign-key scalar is optional, `restrict` otherwise, `cascade` on update),
|
|
499
|
-
|
|
498
|
+
where every foreign-key scalar is optional, `restrict` otherwise, `cascade` on update), on both
|
|
499
|
+
PostgreSQL and SQLite. An action spelling the reader cannot name stops the generate step rather than reaching
|
|
500
500
|
the artifact.
|
|
501
501
|
|
|
502
502
|
Neither the model nor the compiled Contracts carry a referential action — the actions are beside the
|
|
@@ -508,7 +508,7 @@ five words (mirroring Prisma's and SQL's actions; direction unchanged):
|
|
|
508
508
|
|---|---|---|
|
|
509
509
|
| `cascade` | `cascade` | deletes them, and the closure recurses into them |
|
|
510
510
|
| `restrict` | `restrict` | refuses the delete while they reference it |
|
|
511
|
-
| `no-action` | `noAction` | refuses the delete while they reference it —
|
|
511
|
+
| `no-action` | `noAction` | refuses the delete while they reference it — identical to `restrict` on both engines, because `NoAction` is not `DEFERRABLE` on either |
|
|
512
512
|
| `set-null` | `setNull` | keeps them, the reference set to null |
|
|
513
513
|
| `set-default` | `setDefault` | keeps them, the reference set to its column default |
|
|
514
514
|
|
|
@@ -522,8 +522,8 @@ what the schema says rather than collapsing it into what core currently reads.
|
|
|
522
522
|
once, at framework construction, and the transaction planner refuses a step that depends on rows an
|
|
523
523
|
earlier step's cascade removed — its own Resource, or one its arguments reach through a relation — with
|
|
524
524
|
`A2004`/`V1019` *"Transaction step depends on a row removed by an earlier step's cascade"*, before any
|
|
525
|
-
provider statement is issued.
|
|
526
|
-
(`onDelete: Cascade`)
|
|
525
|
+
provider statement is issued. For example, with `Metric.author`
|
|
526
|
+
(`onDelete: Cascade`) as the one cascade edge: deleting an `Author` and then reading its
|
|
527
527
|
`Metric` rows is refused; deleting an `Author` and then reading `Post` (`Restrict`), or a `Category` and
|
|
528
528
|
then `Post` (`SetNull`), is not. The refusal is per Resource — a plan cannot know which rows a delete
|
|
529
529
|
will match — and plan-scoped: a single delete that cascades runs.
|
|
@@ -544,7 +544,7 @@ Prisma's typed delegate surface.
|
|
|
544
544
|
|
|
545
545
|
## Also worth knowing
|
|
546
546
|
|
|
547
|
-
- **`$count` on a paginated relation reports the pre-pagination count.**
|
|
547
|
+
- **`$count` on a paginated relation reports the pre-pagination count.** On both engines, a
|
|
548
548
|
relation's `_count` is unaffected by `take`/`skip`/`cursor` applied to the same relation in the same
|
|
549
549
|
query. A filter on the relation *does* affect it.
|
|
550
550
|
- **`limit`/`offset`/`cursor` are the public names.** Prisma's `take`/`skip` never surface.
|
|
@@ -555,7 +555,7 @@ Prisma's typed delegate surface.
|
|
|
555
555
|
`find.first`, `update.first` and `delete.first` answer `A1001 NO_MATCH` with `null` data. The
|
|
556
556
|
distinction is deliberate and is core's, not the adapter's.
|
|
557
557
|
|
|
558
|
-
## Not covered
|
|
558
|
+
## Not covered
|
|
559
559
|
|
|
560
560
|
Stated so nothing here reads as a claim it is not:
|
|
561
561
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type PrismaAdapterModel } from "./discovery-artifact.interface.js";
|
|
2
2
|
/** Every artifact failure is this class, and every one of them says how to fix it. */
|
|
3
3
|
export declare class PrismaDiscoveryArtifactError extends Error {
|
|
4
4
|
/**
|
|
@@ -21,10 +21,5 @@ export type PrismaDiscoveryArtifactLoad = {
|
|
|
21
21
|
* identity and into every generated client.
|
|
22
22
|
*/
|
|
23
23
|
export declare function computeModelHash(model: PrismaAdapterModel): Promise<string>;
|
|
24
|
-
/**
|
|
25
|
-
* Validates an artifact and hands back its model **unchanged**.
|
|
26
|
-
*
|
|
27
|
-
* Three checks, in the order that makes each one's failure legible: shape, then
|
|
28
|
-
* the `prismaVersion` major fence, then `modelHash`.
|
|
29
|
-
*/
|
|
24
|
+
/** Validates an artifact and hands back its model **unchanged**. */
|
|
30
25
|
export declare function loadDiscoveryArtifact(load: PrismaDiscoveryArtifactLoad): Promise<PrismaAdapterModel>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { canonicalizeJson } from "@aventara/core";
|
|
2
|
+
import { DISCOVERY_ARTIFACT_FORMAT, } from "./discovery-artifact.interface.js";
|
|
2
3
|
const HASH_PREFIX = "sha256:";
|
|
3
4
|
const REGENERATION_INSTRUCTION = "Regenerate the discovery artifact — `npm run aventara:prepare` in a project " +
|
|
4
5
|
"set up by `aventara`, or the adapter's generate step " +
|
|
@@ -32,6 +33,9 @@ function assertArtifactShape(artifact) {
|
|
|
32
33
|
if (!isRecord(artifact)) {
|
|
33
34
|
throw new PrismaDiscoveryArtifactError("The discovery artifact is not a JSON object.");
|
|
34
35
|
}
|
|
36
|
+
if (artifact.regenerate_with_aventara_prepare !== DISCOVERY_ARTIFACT_FORMAT) {
|
|
37
|
+
throw new PrismaDiscoveryArtifactError("The discovery artifact was written by another version of @aventara/prisma7-adapter.");
|
|
38
|
+
}
|
|
35
39
|
for (const key of ["prismaVersion", "provider", "modelHash"]) {
|
|
36
40
|
if (typeof artifact[key] !== "string") {
|
|
37
41
|
throw new PrismaDiscoveryArtifactError(`The discovery artifact's \`${key}\` is not a string.`);
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Nothing here is imported from `@prisma/client`: these are this adapter's own
|
|
3
|
-
* facts over public generated types, which is what keeps discovery a pure function
|
|
4
|
-
* of plain data and unit-testable without a client.
|
|
5
|
-
*
|
|
6
|
-
* Read `types.reader.ts`'s header for the two rules that give these facts their
|
|
7
|
-
* meaning: only the 🟢 files are opened, and token-shaped facts come from the
|
|
8
|
-
* **written** type arguments rather than from the instantiated reference.
|
|
9
|
-
*/
|
|
10
1
|
export type PrismaCapabilitySurface = {
|
|
11
|
-
/** The EXISTENCE GATE: an entity is discoverable iff it appears here. */
|
|
12
2
|
readonly resources: Readonly<Record<string, PrismaResourceSurface>>;
|
|
13
3
|
/** `enums.ts`'s `as const` objects, in property order. */
|
|
14
4
|
readonly enums: Readonly<Record<string, readonly string[]>>;
|
|
@@ -19,7 +9,6 @@ export type PrismaResourceSurface = {
|
|
|
19
9
|
readonly relationFields: Readonly<Record<string, PrismaRelationSurface>>;
|
|
20
10
|
/** `AtLeast<…, K>`'s key union — cross-check only; order unused. */
|
|
21
11
|
readonly uniqueKeys: readonly string[];
|
|
22
|
-
/** `<M>Delegate`'s own methods → `ResourceOperations`. */
|
|
23
12
|
readonly operations: readonly string[];
|
|
24
13
|
/** e.g. `updateMany` → `["data", "where", "limit"]`. */
|
|
25
14
|
readonly manyWriteArguments: Readonly<Record<string, readonly string[]>>;
|
|
@@ -29,24 +18,12 @@ export type PrismaScalarSurface = {
|
|
|
29
18
|
readonly token: string;
|
|
30
19
|
/** `<Kind>Filter` keys, in Prisma's spelling — NAMES ONLY. */
|
|
31
20
|
readonly filters: readonly string[];
|
|
32
|
-
/**
|
|
33
|
-
* The operand SHAPE per filter key, as written in the generated type — because two
|
|
34
|
-
* engines can carry the same key with different operands, and a name set cannot
|
|
35
|
-
* express that: `path` is `string[]` on PostgreSQL and `string` on SQLite, and
|
|
36
|
-
* `in`/`notIn` admit `List<Kind>FieldRefInput` on PostgreSQL only.
|
|
37
|
-
*/
|
|
38
21
|
readonly filterOperands: Readonly<Record<string, string>>;
|
|
39
22
|
/**
|
|
40
23
|
* `<M>UncheckedCreateInput`'s entry for this field, read as the keys of the
|
|
41
24
|
* `…Input` it references: `[]` for a plain value, and **`null` where the client
|
|
42
25
|
* exposes no entry at all**, which is the only evidence that a column is not
|
|
43
26
|
* creatable.
|
|
44
|
-
*
|
|
45
|
-
* The UNCHECKED input is the source because it is what the delegate accepts:
|
|
46
|
-
* `create`'s argument is `XOR<<M>CreateInput, <M>UncheckedCreateInput>`, and the
|
|
47
|
-
* checked half omits every foreign-key scalar (the relation owns it there). Read
|
|
48
|
-
* from the checked half, `Post.authorId` and `Post.categoryId` come back absent
|
|
49
|
-
* and Aventara would refuse writes Prisma accepts.
|
|
50
27
|
*/
|
|
51
28
|
readonly createOperations: readonly string[] | null;
|
|
52
29
|
/**
|
|
@@ -77,11 +54,6 @@ export type PrismaScalarSurface = {
|
|
|
77
54
|
* `<Kind>FieldUpdateOperationsInput`, or of `<M>Update<field>Input` for a scalar
|
|
78
55
|
* list (`set`, `push`), or `[]` for a plain value (`Json`), or `null` where the
|
|
79
56
|
* client exposes no entry.
|
|
80
|
-
*
|
|
81
|
-
* Measured at 7.10.0 (2026-10-02): reading `<M>UpdateInput` instead under-reports
|
|
82
|
-
* six of the twenty-five scalar columns per engine — `Author.mentorId`,
|
|
83
|
-
* `Metric.authorId`, `Post.authorId`, `Post.categoryId`, `Category.id` and
|
|
84
|
-
* `Post.id` — every one of which `<M>UncheckedUpdateInput` admits.
|
|
85
57
|
*/
|
|
86
58
|
readonly updateOperations: readonly string[] | null;
|
|
87
59
|
readonly orderable: boolean;
|
|
@@ -89,19 +61,11 @@ export type PrismaScalarSurface = {
|
|
|
89
61
|
readonly nullsOrderable: boolean;
|
|
90
62
|
};
|
|
91
63
|
export type PrismaRelationSurface = {
|
|
92
|
-
/** Read off `$<Target>Payload`'s own `name` literal, never off the alias's spelling. */
|
|
93
64
|
readonly target: string;
|
|
94
65
|
readonly many: boolean;
|
|
95
66
|
readonly nullable: boolean;
|
|
96
67
|
/** `ListRelationFilter` vs `[Nullable]ScalarRelationFilter`. */
|
|
97
68
|
readonly filters: readonly string[];
|
|
98
|
-
/**
|
|
99
|
-
* `<T>CreateNested{One,Many}Without<M>Input` keys — the **create** stage's own
|
|
100
|
-
* nested-write input, read off `<M>CreateInput`'s entry for this edge.
|
|
101
|
-
*
|
|
102
|
-
* Reusing one list for both stages advertises five directives per to-many edge,
|
|
103
|
-
* and two per to-one edge, that Prisma has no key for at the create stage.
|
|
104
|
-
*/
|
|
105
69
|
readonly createMutations: readonly string[];
|
|
106
70
|
/**
|
|
107
71
|
* Whether `<M>CreateInput` — the CHECKED create input, the only one that carries
|
|
@@ -111,20 +75,8 @@ export type PrismaRelationSurface = {
|
|
|
111
75
|
* entry for the edge at all.
|
|
112
76
|
*/
|
|
113
77
|
readonly createRequired: boolean;
|
|
114
|
-
/** `<T>Update*Without<M>NestedInput` keys — the **update** stage's own input. */
|
|
115
78
|
readonly updateMutations: readonly string[];
|
|
116
|
-
/**
|
|
117
|
-
* `<M>$<edge>Args`'s own member names, as written. The edge's whole argument
|
|
118
|
-
* surface, because four separate capabilities are read off it — pagination,
|
|
119
|
-
* ordering, nested filtering of the returned edge, and projection — and a
|
|
120
|
-
* residual cannot answer the other three.
|
|
121
|
-
*/
|
|
122
79
|
readonly edgeArguments: readonly string[];
|
|
123
|
-
/**
|
|
124
|
-
* {@link edgeArguments} minus what projection and predicate already own — a
|
|
125
|
-
* derived projection kept because it is the one a to-one/to-many split reads at
|
|
126
|
-
* a glance: a to-one edge leaves nothing.
|
|
127
|
-
*/
|
|
128
80
|
readonly pagination: readonly string[];
|
|
129
81
|
/** The edge is admitted by `<M>OrderByWithRelationInput`. */
|
|
130
82
|
readonly orderable: boolean;
|
|
@@ -133,22 +85,6 @@ export type PrismaRelationSurface = {
|
|
|
133
85
|
/**
|
|
134
86
|
* Whether **every** `<M>Select{Create,Update}ManyAndReturn` the client declares
|
|
135
87
|
* lists this edge.
|
|
136
|
-
*
|
|
137
|
-
* # Presence, read. Not foreign-key ownership, computed
|
|
138
|
-
*
|
|
139
|
-
* The *explanation* for which edges survive into a bulk-returning write's
|
|
140
|
-
* projection is foreign-key ownership rather than cardinality — a to-one that does
|
|
141
|
-
* not hold its own FK is absent, which is what the `User`/`Profile` fixture exists
|
|
142
|
-
* to prove. That explanation is **not** the mechanism. The mechanism is this
|
|
143
|
-
* member: the edge is in the type, or it is not.
|
|
144
|
-
*
|
|
145
|
-
* **Every**, not *any*: one {@link ProjectionScope} covers both bulk-returning
|
|
146
|
-
* variants, so a scope the adapter advertises must hold in both. At 7.10.0 the two
|
|
147
|
-
* types agree member-for-member on both pilot engines, so the conjunction is
|
|
148
|
-
* currently indistinguishable from either half — `types.reader.spec.ts` asserts
|
|
149
|
-
* that agreement, so the day it stops holding is the day a reader reports it
|
|
150
|
-
* instead of silently picking a side. **Zero declared types answer `false`**,
|
|
151
|
-
* never vacuously `true`: a client with no `*AndReturn` type admits nothing there.
|
|
152
88
|
*/
|
|
153
89
|
readonly bulkSelect: boolean;
|
|
154
90
|
/** The {@link bulkSelect} question asked of `<M>Include{Create,Update}ManyAndReturn`. */
|
|
@@ -164,8 +100,8 @@ export type PrismaRelationSurface = {
|
|
|
164
100
|
*/
|
|
165
101
|
readonly bulkReducers: boolean;
|
|
166
102
|
/**
|
|
167
|
-
* Whether `<M>CreateManyInput` — the data argument of the bulk create — exposes
|
|
168
|
-
* entry for this edge.
|
|
103
|
+
* Whether `<M>CreateManyInput` — the data argument of the bulk create — exposes
|
|
104
|
+
* an entry for this edge.
|
|
169
105
|
*/
|
|
170
106
|
readonly bulkCreatable: boolean;
|
|
171
107
|
/**
|
|
@@ -1,38 +1,5 @@
|
|
|
1
1
|
import type { RelationFieldCapabilities, ScalarFieldCapabilities, ScalarFilterOperator } from "@aventara/core";
|
|
2
2
|
import type { PrismaRelationSurface, PrismaScalarSurface } from "./capability-surface.interface.js";
|
|
3
|
-
/**
|
|
4
|
-
* This module accepts `surface` alone, and that is deliberate: dictionary
|
|
5
|
-
* invariant 6 says a capability is read from the client's own types and never
|
|
6
|
-
* tabulated from a provider row, and the strongest available mechanism for that is
|
|
7
|
-
* to make the provider **unrepresentable** rather than merely unread. A
|
|
8
|
-
* `PrismaProviderProfile` in this input is a `provider` member one keystroke from
|
|
9
|
-
* a branch; with no such member, `if (provider === …)` is a compile error, and the
|
|
10
|
-
* three per-engine differences this pass exists to prove — `mode`, `JsonFilter`'s
|
|
11
|
-
* ordering operators, and the `path` / `in` / `notIn` operand shapes — have to
|
|
12
|
-
* come from the surface because nothing else is in scope.
|
|
13
|
-
*
|
|
14
|
-
* `mapping` went with them because nothing here reads an Aventara scalar identity
|
|
15
|
-
* to answer a capability question.
|
|
16
|
-
*
|
|
17
|
-
* The answer is read off the recorded operand shape, which is already on the
|
|
18
|
-
* surface; the Aventara scalar identity would have been a second, weaker source
|
|
19
|
-
* for the same fact. `mapping` stays out.
|
|
20
|
-
*
|
|
21
|
-
* # Order is canonical, not incidental
|
|
22
|
-
*
|
|
23
|
-
* Every list is emitted in **core's own union declaration order**, held below as a
|
|
24
|
-
* closed ordered array.
|
|
25
|
-
*
|
|
26
|
-
* # Absent and empty are different answers
|
|
27
|
-
*
|
|
28
|
-
* `create: []` / `update: []` mean **writable with no directive** — plain
|
|
29
|
-
* assignment, which is what `set` alone is. An absent `create` / `update` means
|
|
30
|
-
* **not writable**, and core enforces exactly that: `validateScalarMutation`
|
|
31
|
-
* answers `V1006` *"is not writable during <stage>"* when the member is
|
|
32
|
-
* `undefined` **[CORE, operations/operation-validator-core.ts]**. So the two must
|
|
33
|
-
* not be conflated, and the surface's `null` (the client exposes no entry for this
|
|
34
|
-
* column at this stage) is the only thing that produces the absent form.
|
|
35
|
-
*/
|
|
36
3
|
/** A Prisma spelling that no dictionary table recognises: a build stop, never a drop. */
|
|
37
4
|
export declare class PrismaCapabilityDerivationError extends Error {
|
|
38
5
|
readonly name = "PrismaCapabilityDerivationError";
|
|
@@ -40,23 +7,11 @@ export declare class PrismaCapabilityDerivationError extends Error {
|
|
|
40
7
|
export type ScalarCapabilityInput = {
|
|
41
8
|
readonly surface: PrismaScalarSurface;
|
|
42
9
|
};
|
|
43
|
-
/**
|
|
44
|
-
* A relation's capabilities are answered for the field, not for an operation.
|
|
45
|
-
*
|
|
46
|
-
* The `operation: "create.one" | "create.many"` parameter this input used to carry
|
|
47
|
-
* is **gone**. The scope-qualified members hold both answers at once, so there is
|
|
48
|
-
* nothing left to pick and no caller left to pick it.
|
|
49
|
-
*/
|
|
10
|
+
/** A relation's capabilities are answered for the field, not for an operation. */
|
|
50
11
|
export type RelationCapabilityInput = {
|
|
51
12
|
readonly surface: PrismaRelationSurface;
|
|
52
13
|
};
|
|
53
14
|
export declare function deriveScalarCapabilities(input: ScalarCapabilityInput): ScalarFieldCapabilities;
|
|
54
|
-
/**
|
|
55
|
-
* The Prisma operand for each ADVERTISED operator, keyed by the Aventara name.
|
|
56
|
-
*
|
|
57
|
-
* A deriver that answered operator NAMES alone would report the two engines
|
|
58
|
-
* identical where they are not, so the shape is carried beside the capability
|
|
59
|
-
* rather than discarded.
|
|
60
|
-
*/
|
|
15
|
+
/** The Prisma operand for each ADVERTISED operator, keyed by the Aventara name. */
|
|
61
16
|
export declare function deriveScalarFilterOperands(input: ScalarCapabilityInput): Readonly<Partial<Record<ScalarFilterOperator, string>>>;
|
|
62
17
|
export declare function deriveRelationCapabilities(input: RelationCapabilityInput): RelationFieldCapabilities;
|