@aventara/prisma7-adapter 0.1.0-pilot.1 → 0.1.0-pilot.2
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 +33 -20
- package/dist/discovery/artifact.loader.d.ts +6 -2
- package/dist/discovery/artifact.loader.js +12 -57
- package/dist/discovery/capability-surface.interface.d.ts +29 -40
- package/dist/discovery/capability-surface.interface.js +0 -12
- package/dist/discovery/capability.deriver.d.ts +10 -40
- package/dist/discovery/capability.deriver.js +0 -179
- package/dist/discovery/client-shape.verifier.d.ts +13 -0
- package/dist/discovery/client-shape.verifier.js +93 -0
- package/dist/discovery/discovery-artifact.interface.d.ts +55 -30
- package/dist/discovery/enum.mapper.d.ts +6 -14
- package/dist/discovery/enum.mapper.js +1 -2
- package/dist/discovery/field.mapper.d.ts +49 -63
- package/dist/discovery/field.mapper.js +0 -161
- package/dist/discovery/identifier.mapper.d.ts +38 -77
- package/dist/discovery/identifier.mapper.js +0 -64
- package/dist/discovery/model.discoverer.d.ts +18 -35
- package/dist/discovery/model.discoverer.js +66 -141
- package/dist/discovery/operations.deriver.d.ts +10 -38
- package/dist/discovery/operations.deriver.js +0 -40
- package/dist/discovery/scalar.mapper.d.ts +12 -35
- package/dist/discovery/scalar.mapper.js +0 -8
- package/dist/discovery/schema-facts.interface.d.ts +26 -25
- package/dist/discovery/schema-facts.interface.js +0 -10
- package/dist/discovery/schema.reader.d.ts +53 -64
- package/dist/discovery/schema.reader.js +0 -174
- package/dist/discovery/types.reader.d.ts +0 -4
- package/dist/discovery/types.reader.js +2 -177
- package/dist/discovery/vocabulary.dictionary.d.ts +36 -75
- package/dist/discovery/vocabulary.dictionary.js +2 -152
- package/dist/errors/error.normalizer.d.ts +85 -135
- package/dist/errors/error.normalizer.js +1 -70
- package/dist/errors/prisma-error.reader.d.ts +53 -68
- package/dist/errors/prisma-error.reader.js +0 -91
- package/dist/execution/first-variant.emulator.d.ts +11 -22
- package/dist/execution/first-variant.emulator.js +0 -142
- package/dist/execution/operation.executor.d.ts +12 -19
- package/dist/execution/operation.executor.js +0 -92
- package/dist/execution/result.shaper.d.ts +22 -31
- package/dist/execution/result.shaper.js +0 -24
- package/dist/execution/transaction.executor.d.ts +36 -73
- package/dist/generate/artifact.emitter.d.ts +27 -27
- package/dist/generate/artifact.emitter.js +30 -13
- package/dist/generate/declared-support.reader.d.ts +11 -11
- package/dist/generate/declared-support.reader.js +0 -12
- package/dist/generate/discovery.bin.js +0 -10
- package/dist/generate/discovery.cli.js +0 -55
- package/dist/generate/existence.gate.d.ts +26 -32
- package/dist/generate/existence.gate.js +0 -6
- package/dist/generate/index.d.ts +10 -12
- package/dist/generate/index.js +0 -42
- package/dist/generate/node-version.guard.js +0 -12
- package/dist/generate/prisma-cli.resolver.d.ts +9 -11
- package/dist/generate/prisma-cli.resolver.js +0 -13
- package/dist/generate/prisma.generate.d.ts +49 -65
- package/dist/generate/prisma.generate.js +13 -123
- package/dist/generate/reader-crosscheck.d.ts +36 -60
- package/dist/generate/reader-crosscheck.js +5 -41
- package/dist/prisma-client.interface.d.ts +14 -19
- package/dist/prisma-client.interface.js +0 -6
- package/dist/prisma.adapter.d.ts +9 -17
- package/dist/prisma.adapter.js +11 -53
- package/dist/provider/provider-profile.d.ts +6 -23
- package/dist/provider/provider-profile.js +0 -64
- package/dist/translation/identifier.addressing.d.ts +15 -22
- package/dist/translation/identifier.addressing.js +0 -10
- package/dist/translation/mutation.translator.d.ts +19 -43
- package/dist/translation/mutation.translator.js +1 -209
- package/dist/translation/operation.translator.d.ts +36 -63
- package/dist/translation/operation.translator.js +1 -51
- package/dist/translation/order-pagination.translator.d.ts +24 -31
- package/dist/translation/order-pagination.translator.js +0 -43
- package/dist/translation/projection.translator.d.ts +25 -58
- package/dist/translation/projection.translator.js +0 -27
- package/dist/translation/scalar.conversion.d.ts +15 -26
- package/dist/translation/scalar.conversion.js +1 -129
- package/dist/translation/where.translator.d.ts +17 -28
- package/dist/translation/where.translator.js +0 -83
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -126,35 +126,48 @@ project's `devDependencies` — if you are generating a Prisma client at all, yo
|
|
|
126
126
|
|
|
127
127
|
The step reads two sources in the same instant — the `schema.prisma` text and the generated client's
|
|
128
128
|
own public types — and cross-checks them against each other. What it emits is a TypeScript module
|
|
129
|
-
exporting one `discovery` value with
|
|
129
|
+
exporting one `discovery` value with eight members: the canonical `AdapterModel` (scalars, enums,
|
|
130
130
|
Resources with fields, identifiers and available operations, plus the `transactions` capability), the
|
|
131
|
-
Prisma addressing each Resource is reached by, the resolved referential actions per Resource, a
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
Prisma addressing each Resource is reached by, the resolved referential actions per Resource, a record
|
|
132
|
+
of the generated client it was read from (each model and its field references), the create
|
|
133
|
+
requirements per Resource, a `modelHash`, and the `prismaVersion` it was generated against.
|
|
134
|
+
|
|
135
|
+
The create requirements are what a create cannot do without — a column with no default, or a required
|
|
136
|
+
relation, which may be written instead through the scalar fields that hold its reference — read off the
|
|
137
|
+
question marks of the generated create inputs. The framework checks every create against them after
|
|
138
|
+
your pipes and computed behaviours have run, and answers a missing value as `A2004` with a `V1000`
|
|
139
|
+
issue at its path (`["arguments", "data", "title"]`, or `["arguments", "data", "author"]` for a
|
|
140
|
+
required relation) instead of letting the database refuse it. A nested create does not need the
|
|
141
|
+
relation it is created through.
|
|
142
|
+
|
|
143
|
+
`modelHash` digests the **model** and nothing else. The addressing table, the referential actions, the
|
|
144
|
+
client record and the create requirements sit beside it and outside the hash: a database-side rename or a foreign-key action carries no semantic
|
|
136
145
|
content, and inside the hash either would move the Contract identity and force every generated client
|
|
137
146
|
to be regenerated for nothing.
|
|
138
147
|
|
|
139
148
|
On the runtime path there is **no** TypeScript program, **no** PSL parser and **no** Prisma tooling.
|
|
140
149
|
The loader reads no file: the artifact arrives as a value you import.
|
|
141
150
|
|
|
142
|
-
At construction the adapter checks
|
|
143
|
-
regenerate if
|
|
151
|
+
At construction — before the application listens — the adapter checks three things, and fails hard
|
|
152
|
+
with an instruction to regenerate if any is wrong:
|
|
144
153
|
|
|
145
154
|
1. the artifact matches **itself** — the `modelHash` over its own canonicalized model;
|
|
146
|
-
2. the installed `@prisma/client` **major** is the one the artifact was generated against
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
2. the installed `@prisma/client` **major** is the one the artifact was generated against;
|
|
156
|
+
3. the Prisma client you pass is the one the artifact was **generated from**: the same models, and the
|
|
157
|
+
same field references (`prisma.<model>.fields`) on each. A schema change followed by
|
|
158
|
+
`prisma generate` but not by the generate step — a model or field added, removed or renamed — is
|
|
159
|
+
refused in one sentence naming what differs:
|
|
160
|
+
|
|
161
|
+
```text
|
|
162
|
+
PrismaDiscoveryArtifactError: The Prisma client has changed since the discovery artifact was generated (model `Comment` is in the client and not in the artifact): run `npm run aventara:prepare` (the adapter's `aventara-prisma7-generate`) to regenerate it, then restart.
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
A value with no recognisable model delegate (a test double, a deep mock) is not compared.
|
|
166
|
+
|
|
167
|
+
What the client check does not see: a change that leaves every model and field name in place — a type,
|
|
168
|
+
a default, an attribute. Run the generate step in the same build that runs `prisma generate` (a project
|
|
169
|
+
set up by `aventara` does, from `postinstall` and `aventara:prepare`), and deploy the artifact with the
|
|
170
|
+
schema and client it came from.
|
|
158
171
|
|
|
159
172
|
---
|
|
160
173
|
|
|
@@ -1,7 +1,11 @@
|
|
|
1
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
|
+
/**
|
|
5
|
+
* `instruction` replaces the general regeneration sentence where the reason
|
|
6
|
+
* reads as the first half of one sentence with it.
|
|
7
|
+
*/
|
|
8
|
+
constructor(reason: string, instruction?: string);
|
|
5
9
|
}
|
|
6
10
|
export type PrismaDiscoveryArtifactLoad = {
|
|
7
11
|
readonly artifact: unknown;
|
|
@@ -21,6 +25,6 @@ export declare function computeModelHash(model: PrismaAdapterModel): Promise<str
|
|
|
21
25
|
* Validates an artifact and hands back its model **unchanged**.
|
|
22
26
|
*
|
|
23
27
|
* Three checks, in the order that makes each one's failure legible: shape, then
|
|
24
|
-
* the `prismaVersion` major fence
|
|
28
|
+
* the `prismaVersion` major fence, then `modelHash`.
|
|
25
29
|
*/
|
|
26
30
|
export declare function loadDiscoveryArtifact(load: PrismaDiscoveryArtifactLoad): Promise<PrismaAdapterModel>;
|
|
@@ -1,37 +1,12 @@
|
|
|
1
1
|
import { canonicalizeJson } from "@aventara/core";
|
|
2
|
-
/**
|
|
3
|
-
* T-3.2 — `discover()`'s whole runtime half.
|
|
4
|
-
*
|
|
5
|
-
* This module builds no TypeScript program, parses no PSL and calls no Prisma
|
|
6
|
-
* tooling, and that is guaranteed by construction rather than by assertion:
|
|
7
|
-
* its transitive import graph is this file, `discovery-artifact.interface.ts`
|
|
8
|
-
* and `@aventara/core`. Nothing under `generate/` is reachable from here, and
|
|
9
|
-
* neither is `typescript`, `prisma`, `@prisma/*`, `node:child_process` or
|
|
10
|
-
* `node:fs`. `artifact.loader.spec.ts` walks that graph from source and fails
|
|
11
|
-
* if a specifier appears that should not.
|
|
12
|
-
*
|
|
13
|
-
* The loader reads no file at all: the artifact arrives as a value, and hashing
|
|
14
|
-
* uses `globalThis.crypto.subtle`, so it needs no import either. It checks the
|
|
15
|
-
* two facts the runtime can still get wrong — that the artifact matches itself
|
|
16
|
-
* (`modelHash`) and that the installed `@prisma/client` major is the one it was
|
|
17
|
-
* generated against (C-846) — and nothing else. The model is derived at
|
|
18
|
-
* generate time from the schema and the generated client read in the same
|
|
19
|
-
* instant and cross-checked there, so the runtime never sees the schema and
|
|
20
|
-
* never asks after it.
|
|
21
|
-
*/
|
|
22
|
-
/** The `sha256:<hex>` convention core already uses for Contract identity. */
|
|
23
2
|
const HASH_PREFIX = "sha256:";
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
*/
|
|
28
|
-
const REGENERATION_INSTRUCTION = "Regenerate the discovery artifact with the adapter's generate step " +
|
|
29
|
-
"(`aventara-prisma7-generate`) and redeploy it " +
|
|
3
|
+
const REGENERATION_INSTRUCTION = "Regenerate the discovery artifact — `npm run aventara:prepare` in a project " +
|
|
4
|
+
"set up by `aventara`, or the adapter's generate step " +
|
|
5
|
+
"(`aventara-prisma7-generate`) — and redeploy it " +
|
|
30
6
|
"alongside the schema and client it was generated from.";
|
|
31
|
-
/** Every artifact failure is this class, and every one of them says how to fix it. */
|
|
32
7
|
export class PrismaDiscoveryArtifactError extends Error {
|
|
33
|
-
constructor(reason) {
|
|
34
|
-
super(`${reason} ${
|
|
8
|
+
constructor(reason, instruction = REGENERATION_INSTRUCTION) {
|
|
9
|
+
super(`${reason} ${instruction}`);
|
|
35
10
|
this.name = "PrismaDiscoveryArtifactError";
|
|
36
11
|
}
|
|
37
12
|
}
|
|
@@ -43,14 +18,6 @@ async function sha256(text) {
|
|
|
43
18
|
const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
|
|
44
19
|
return `${HASH_PREFIX}${hex(digest)}`;
|
|
45
20
|
}
|
|
46
|
-
/**
|
|
47
|
-
* The identity of a discovered model: one canonicalization, one digest — over
|
|
48
|
-
* the model and **nothing else**. The artifact's `translation` half is Prisma
|
|
49
|
-
* addressing, and hashing it would put a DB-side rename into the Contract
|
|
50
|
-
* identity; its `referentialActions` half is what a delete does below the ORM
|
|
51
|
-
* entrypoint, and hashing it would put a foreign-key action into the Contract
|
|
52
|
-
* identity and into every generated client.
|
|
53
|
-
*/
|
|
54
21
|
export async function computeModelHash(model) {
|
|
55
22
|
return sha256(canonicalizeJson(model));
|
|
56
23
|
}
|
|
@@ -61,7 +28,6 @@ function majorOf(version) {
|
|
|
61
28
|
const major = /^(\d+)\./.exec(version)?.[1];
|
|
62
29
|
return major;
|
|
63
30
|
}
|
|
64
|
-
/** Shape validation, before any hash is computed over a value that may not have one. */
|
|
65
31
|
function assertArtifactShape(artifact) {
|
|
66
32
|
if (!isRecord(artifact)) {
|
|
67
33
|
throw new PrismaDiscoveryArtifactError("The discovery artifact is not a JSON object.");
|
|
@@ -74,17 +40,12 @@ function assertArtifactShape(artifact) {
|
|
|
74
40
|
if (!isRecord(artifact.model)) {
|
|
75
41
|
throw new PrismaDiscoveryArtifactError("The discovery artifact's `model` is not a JSON object.");
|
|
76
42
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
//
|
|
84
|
-
// `referentialActions` is checked for the same reason as `translation` and with
|
|
85
|
-
// the same consequence: an artifact emitted before the key existed is refused
|
|
86
|
-
// here and regenerated, rather than reaching a planner as `undefined`.
|
|
87
|
-
for (const key of ["translation", "referentialActions"]) {
|
|
43
|
+
for (const key of [
|
|
44
|
+
"translation",
|
|
45
|
+
"referentialActions",
|
|
46
|
+
"client",
|
|
47
|
+
"createRequirements",
|
|
48
|
+
]) {
|
|
88
49
|
if (!isRecord(artifact[key])) {
|
|
89
50
|
throw new PrismaDiscoveryArtifactError(`The discovery artifact's \`${key}\` is not a JSON object.`);
|
|
90
51
|
}
|
|
@@ -99,12 +60,6 @@ function assertArtifactShape(artifact) {
|
|
|
99
60
|
throw new PrismaDiscoveryArtifactError("The discovery artifact's `model.transactions` is not a transaction capability.");
|
|
100
61
|
}
|
|
101
62
|
}
|
|
102
|
-
/**
|
|
103
|
-
* Validates an artifact and hands back its model **unchanged**.
|
|
104
|
-
*
|
|
105
|
-
* Three checks, in the order that makes each one's failure legible: shape, then
|
|
106
|
-
* the `prismaVersion` major fence (C-846), then `modelHash`.
|
|
107
|
-
*/
|
|
108
63
|
export async function loadDiscoveryArtifact(load) {
|
|
109
64
|
const { artifact, installedPrismaVersion } = load;
|
|
110
65
|
assertArtifactShape(artifact);
|
|
@@ -114,7 +69,7 @@ export async function loadDiscoveryArtifact(load) {
|
|
|
114
69
|
throw new PrismaDiscoveryArtifactError(`A Prisma version is not a major.minor.patch version: the artifact declares \`${artifact.prismaVersion}\` and the installed client reports \`${installedPrismaVersion}\`.`);
|
|
115
70
|
}
|
|
116
71
|
if (artifactMajor !== installedMajor) {
|
|
117
|
-
throw new PrismaDiscoveryArtifactError(`The discovery artifact was generated against Prisma major ${artifactMajor}, and the installed client is major ${installedMajor}. The P-code surface and the generated-client grammar are version-bound
|
|
72
|
+
throw new PrismaDiscoveryArtifactError(`The discovery artifact was generated against Prisma major ${artifactMajor}, and the installed client is major ${installedMajor}. The P-code surface and the generated-client grammar are version-bound.`);
|
|
118
73
|
}
|
|
119
74
|
const modelHash = await computeModelHash(artifact.model);
|
|
120
75
|
if (modelHash !== artifact.modelHash) {
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* T-3, source **TYPE** — the output of the reader over the generated client's
|
|
3
|
-
* 🟢 public types.
|
|
4
|
-
*
|
|
5
2
|
* Nothing here is imported from `@prisma/client`: these are this adapter's own
|
|
6
|
-
* facts over public generated types, which is what keeps discovery a pure
|
|
7
|
-
*
|
|
3
|
+
* facts over public generated types, which is what keeps discovery a pure function
|
|
4
|
+
* of plain data and unit-testable without a client.
|
|
8
5
|
*
|
|
9
6
|
* Read `types.reader.ts`'s header for the two rules that give these facts their
|
|
10
7
|
* meaning: only the 🟢 files are opened, and token-shaped facts come from the
|
|
11
8
|
* **written** type arguments rather than from the instantiated reference.
|
|
12
9
|
*/
|
|
13
10
|
export type PrismaCapabilitySurface = {
|
|
14
|
-
/** The EXISTENCE GATE: an entity is discoverable iff it appears here
|
|
11
|
+
/** The EXISTENCE GATE: an entity is discoverable iff it appears here. */
|
|
15
12
|
readonly resources: Readonly<Record<string, PrismaResourceSurface>>;
|
|
16
13
|
/** `enums.ts`'s `as const` objects, in property order. */
|
|
17
14
|
readonly enums: Readonly<Record<string, readonly string[]>>;
|
|
@@ -33,11 +30,10 @@ export type PrismaScalarSurface = {
|
|
|
33
30
|
/** `<Kind>Filter` keys, in Prisma's spelling — NAMES ONLY. */
|
|
34
31
|
readonly filters: readonly string[];
|
|
35
32
|
/**
|
|
36
|
-
* The operand SHAPE per filter key, as written in the generated type — because
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* only. Read, not tabulated — T-3.1 invariant 6.
|
|
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.
|
|
41
37
|
*/
|
|
42
38
|
readonly filterOperands: Readonly<Record<string, string>>;
|
|
43
39
|
/**
|
|
@@ -103,14 +99,18 @@ export type PrismaRelationSurface = {
|
|
|
103
99
|
* `<T>CreateNested{One,Many}Without<M>Input` keys — the **create** stage's own
|
|
104
100
|
* nested-write input, read off `<M>CreateInput`'s entry for this edge.
|
|
105
101
|
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* `createMany` (to-many only) and `connect` and nothing else, where the
|
|
109
|
-
* update-stage input carries eight more. Reusing one list for both stages
|
|
110
|
-
* advertises five directives per to-many edge, and two per to-one edge, that
|
|
111
|
-
* Prisma has no key for at the create stage.
|
|
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.
|
|
112
104
|
*/
|
|
113
105
|
readonly createMutations: readonly string[];
|
|
106
|
+
/**
|
|
107
|
+
* Whether `<M>CreateInput` — the CHECKED create input, the only one that carries
|
|
108
|
+
* relation edges — writes this edge without a `?`: a create through the checked
|
|
109
|
+
* input cannot leave it out. Read as presence of the question mark, the way
|
|
110
|
+
* {@link PrismaScalarSurface.createOptional} is; `false` where the input has no
|
|
111
|
+
* entry for the edge at all.
|
|
112
|
+
*/
|
|
113
|
+
readonly createRequired: boolean;
|
|
114
114
|
/** `<T>Update*Without<M>NestedInput` keys — the **update** stage's own input. */
|
|
115
115
|
readonly updateMutations: readonly string[];
|
|
116
116
|
/**
|
|
@@ -137,24 +137,18 @@ export type PrismaRelationSurface = {
|
|
|
137
137
|
* # Presence, read. Not foreign-key ownership, computed
|
|
138
138
|
*
|
|
139
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
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* Deriving FK ownership here instead would be a tabulated provider-dependent
|
|
146
|
-
* fact — the shape §18.4 forbids and D-802 exists to prevent — and it would be
|
|
147
|
-
* wrong the first time Prisma changes which relations it admits into the
|
|
148
|
-
* projection, while a presence read simply tells the truth again.
|
|
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.
|
|
149
144
|
*
|
|
150
145
|
* **Every**, not *any*: one {@link ProjectionScope} covers both bulk-returning
|
|
151
|
-
* variants, so a scope the adapter advertises must hold in both. At 7.10.0 the
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
* nothing there.
|
|
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.
|
|
158
152
|
*/
|
|
159
153
|
readonly bulkSelect: boolean;
|
|
160
154
|
/** The {@link bulkSelect} question asked of `<M>Include{Create,Update}ManyAndReturn`. */
|
|
@@ -170,13 +164,8 @@ export type PrismaRelationSurface = {
|
|
|
170
164
|
*/
|
|
171
165
|
readonly bulkReducers: boolean;
|
|
172
166
|
/**
|
|
173
|
-
* Whether `<M>CreateManyInput` — the data argument of the bulk create — exposes
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
* The write-side mirror of {@link bulkSelect}, and read the same way: C-818's
|
|
177
|
-
* rule (*no nested `create`/`connect` inside a top-level `createMany()` or
|
|
178
|
-
* `createManyAndReturn()`*) is a **consequence** of the bulk input carrying no
|
|
179
|
-
* relation member, never a row this adapter keeps.
|
|
167
|
+
* Whether `<M>CreateManyInput` — the data argument of the bulk create — exposes an
|
|
168
|
+
* entry for this edge.
|
|
180
169
|
*/
|
|
181
170
|
readonly bulkCreatable: boolean;
|
|
182
171
|
/**
|
|
@@ -1,13 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* T-3, source **TYPE** — the output of the reader over the generated client's
|
|
3
|
-
* 🟢 public types.
|
|
4
|
-
*
|
|
5
|
-
* Nothing here is imported from `@prisma/client`: these are this adapter's own
|
|
6
|
-
* facts over public generated types, which is what keeps discovery a pure
|
|
7
|
-
* function of plain data and unit-testable without a client (T-3).
|
|
8
|
-
*
|
|
9
|
-
* Read `types.reader.ts`'s header for the two rules that give these facts their
|
|
10
|
-
* meaning: only the 🟢 files are opened, and token-shaped facts come from the
|
|
11
|
-
* **written** type arguments rather than from the instantiated reference.
|
|
12
|
-
*/
|
|
13
1
|
export {};
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import type { RelationFieldCapabilities, ScalarFieldCapabilities, ScalarFilterOperator } from "@aventara/core";
|
|
2
2
|
import type { PrismaRelationSurface, PrismaScalarSurface } from "./capability-surface.interface.js";
|
|
3
3
|
/**
|
|
4
|
-
* T-6 — field capabilities, derived from the generated client's own types.
|
|
5
|
-
*
|
|
6
|
-
* # The input is narrower than T-6 writes it, and the narrowing IS the invariant
|
|
7
|
-
*
|
|
8
|
-
* T-6 spells `ScalarCapabilityInput` as `{ field, surface, mapping, profile }`.
|
|
9
4
|
* This module accepts `surface` alone, and that is deliberate: dictionary
|
|
10
5
|
* invariant 6 says a capability is read from the client's own types and never
|
|
11
6
|
* tabulated from a provider row, and the strongest available mechanism for that is
|
|
@@ -13,27 +8,20 @@ import type { PrismaRelationSurface, PrismaScalarSurface } from "./capability-su
|
|
|
13
8
|
* `PrismaProviderProfile` in this input is a `provider` member one keystroke from
|
|
14
9
|
* a branch; with no such member, `if (provider === …)` is a compile error, and the
|
|
15
10
|
* three per-engine differences this pass exists to prove — `mode`, `JsonFilter`'s
|
|
16
|
-
* ordering operators, and the `path` / `in` / `notIn` operand shapes — have to
|
|
17
|
-
* from the surface because nothing else is in scope.
|
|
11
|
+
* ordering operators, and the `path` / `in` / `notIn` operand shapes — have to
|
|
12
|
+
* come from the surface because nothing else is in scope.
|
|
18
13
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* nothing here reads an Aventara scalar identity to answer a capability question.
|
|
14
|
+
* `mapping` went with them because nothing here reads an Aventara scalar identity
|
|
15
|
+
* to answer a capability question.
|
|
22
16
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* {@link translatable}. The answer is read off the recorded operand shape, which
|
|
27
|
-
* is already on the surface; the Aventara scalar identity would have been a
|
|
28
|
-
* second, weaker source for the same fact. `mapping` stays out.
|
|
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.
|
|
29
20
|
*
|
|
30
21
|
* # Order is canonical, not incidental
|
|
31
22
|
*
|
|
32
23
|
* Every list is emitted in **core's own union declaration order**, held below as a
|
|
33
|
-
* closed ordered array.
|
|
34
|
-
* fact, and C-843 wants two generate runs byte-identical; ordering by the Aventara
|
|
35
|
-
* union makes the output independent of how a generator happens to write a member
|
|
36
|
-
* list, while keeping the array reviewable against `contracts/capability.ts`.
|
|
24
|
+
* closed ordered array.
|
|
37
25
|
*
|
|
38
26
|
* # Absent and empty are different answers
|
|
39
27
|
*
|
|
@@ -49,12 +37,6 @@ import type { PrismaRelationSurface, PrismaScalarSurface } from "./capability-su
|
|
|
49
37
|
export declare class PrismaCapabilityDerivationError extends Error {
|
|
50
38
|
readonly name = "PrismaCapabilityDerivationError";
|
|
51
39
|
}
|
|
52
|
-
/**
|
|
53
|
-
* T-6's `ScalarCapabilityInput`, narrowed — see this module's header.
|
|
54
|
-
*
|
|
55
|
-
* An object rather than a bare parameter because T-6 names an input type and
|
|
56
|
-
* because a later pass may legitimately add `mapping` back.
|
|
57
|
-
*/
|
|
58
40
|
export type ScalarCapabilityInput = {
|
|
59
41
|
readonly surface: PrismaScalarSurface;
|
|
60
42
|
};
|
|
@@ -62,12 +44,8 @@ export type ScalarCapabilityInput = {
|
|
|
62
44
|
* A relation's capabilities are answered for the field, not for an operation.
|
|
63
45
|
*
|
|
64
46
|
* The `operation: "create.one" | "create.many"` parameter this input used to carry
|
|
65
|
-
* is **gone**.
|
|
66
|
-
*
|
|
67
|
-
* composition had to pick one variant's answer and the other was unrepresentable —
|
|
68
|
-
* `model.discoverer.ts` recorded that as an open conflict. The scope-qualified
|
|
69
|
-
* members hold both answers at once, so there is nothing left to pick and no caller
|
|
70
|
-
* left to pick it.
|
|
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.
|
|
71
49
|
*/
|
|
72
50
|
export type RelationCapabilityInput = {
|
|
73
51
|
readonly surface: PrismaRelationSurface;
|
|
@@ -76,17 +54,9 @@ export declare function deriveScalarCapabilities(input: ScalarCapabilityInput):
|
|
|
76
54
|
/**
|
|
77
55
|
* The Prisma operand for each ADVERTISED operator, keyed by the Aventara name.
|
|
78
56
|
*
|
|
79
|
-
* T-6's three signatures return core types unchanged, and `ScalarFieldCapabilities`
|
|
80
|
-
* has nowhere to put an operand shape — yet the shape is exactly where two engines
|
|
81
|
-
* differ on keys they both carry (`JsonFilter.path` is `string[]` on one and
|
|
82
|
-
* `string` on the other; `in`/`notIn` admit `List<Kind>FieldRefInput` on one only).
|
|
83
57
|
* A deriver that answered operator NAMES alone would report the two engines
|
|
84
58
|
* identical where they are not, so the shape is carried beside the capability
|
|
85
59
|
* rather than discarded.
|
|
86
|
-
*
|
|
87
|
-
* Keyed by the Aventara operator so Task 7 reads a shape without re-running the
|
|
88
|
-
* rename — and so a provider branch has nothing to be for (§Open question,
|
|
89
|
-
* "How the `path` filter operator is emitted per provider").
|
|
90
60
|
*/
|
|
91
61
|
export declare function deriveScalarFilterOperands(input: ScalarCapabilityInput): Readonly<Partial<Record<ScalarFilterOperator, string>>>;
|
|
92
62
|
export declare function deriveRelationCapabilities(input: RelationCapabilityInput): RelationFieldCapabilities;
|