@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
|
@@ -20,16 +20,6 @@ function compare(left, right) {
|
|
|
20
20
|
}
|
|
21
21
|
return 0;
|
|
22
22
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Whether `version` satisfies `range`, for the range forms a peer declaration
|
|
25
|
-
* here uses: space-separated comparators (`>=5.5.0 <7`), each `^`, `>=`, `>`,
|
|
26
|
-
* `<=`, `<`, `=` or bare, with missing minor and patch read as `0`.
|
|
27
|
-
*
|
|
28
|
-
* Only a plain release can satisfy: a pre-release (`8.0.0-rc.20`) never does,
|
|
29
|
-
* which is semver's own rule for a range whose comparators carry no pre-release
|
|
30
|
-
* tag. A range in any other form is a defect in this package's manifest, so it
|
|
31
|
-
* throws rather than answering a guess.
|
|
32
|
-
*/
|
|
33
23
|
export function satisfiesDeclaredRange(version, range) {
|
|
34
24
|
const release = RELEASE.exec(version);
|
|
35
25
|
if (release === null) {
|
|
@@ -45,8 +35,6 @@ export function satisfiesDeclaredRange(version, range) {
|
|
|
45
35
|
.split(/\s+/)
|
|
46
36
|
.every((comparator) => {
|
|
47
37
|
const parsed = COMPARATOR.exec(comparator);
|
|
48
|
-
// `^0.x` means something narrower than "same major", and no peer here
|
|
49
|
-
// declares one, so it is refused with the forms this does not read.
|
|
50
38
|
if (parsed === null || (parsed[1] === "^" && parsed[2] === "0")) {
|
|
51
39
|
throw new Error(`the declared range \`${range}\` has a comparator, \`${comparator}\`, that the generate step does not read`);
|
|
52
40
|
}
|
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { refuseUnsupportedNode } from "./node-version.guard.js";
|
|
3
|
-
/**
|
|
4
|
-
* `aventara-prisma7-generate`'s entry, what the manifest's `bin` names (F-855). It always runs — no
|
|
5
|
-
* `import.meta.main` — and checks this Node against the package's
|
|
6
|
-
* `engines.node` before it loads anything else: the program is imported only
|
|
7
|
-
* once the guard admits this Node, so an older Node meets one sentence and exit
|
|
8
|
-
* 1, never a silent exit 0 or a parse error from a module it cannot run.
|
|
9
|
-
*
|
|
10
|
-
* A promise chain rather than a top-level `await`, which Node 12 cannot parse:
|
|
11
|
-
* this file is read by the Nodes the package does not support.
|
|
12
|
-
*/
|
|
13
3
|
if (!refuseUnsupportedNode("aventara-prisma7-generate", new URL("../../package.json", import.meta.url))) {
|
|
14
4
|
void import("./discovery.cli.js").then((program) => program.runFromProcess());
|
|
15
5
|
}
|
|
@@ -1,40 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { PRISMA_DRIVERS, PRISMA_PROVIDERS, } from "../provider/provider-profile.js";
|
|
3
3
|
import { generatePrismaDiscoveryArtifact } from "./index.js";
|
|
4
|
-
/**
|
|
5
|
-
* F-805 — `aventara-prisma7-generate`: the published binary that produces the
|
|
6
|
-
* discovery artifact `createPrismaAdapter({ discovery })` requires.
|
|
7
|
-
*
|
|
8
|
-
* Before this existed, `package.json` declared no `bin`, one `"."` export and
|
|
9
|
-
* `files: ["dist"]` over a build that excluded `src/generate/**` — so a consumer
|
|
10
|
-
* of the published package could not produce an artifact for their own schema at
|
|
11
|
-
* all, and the only artifacts in existence were the two this repository generates
|
|
12
|
-
* for its own tests. The package was unusable as published.
|
|
13
|
-
*
|
|
14
|
-
* # It reads nothing it was not told
|
|
15
|
-
*
|
|
16
|
-
* Every input is an argument. There is no repository path, no fixture schema, no
|
|
17
|
-
* convention-over-configuration search and no tsconfig of this package's: the
|
|
18
|
-
* types reader builds its own program over the client directory it is given. That
|
|
19
|
-
* is the whole reason this file is a flag parser and `discovery.generate.ts` — the
|
|
20
|
-
* repository's own two-engine script — is a separate file that happens to call the
|
|
21
|
-
* same function.
|
|
22
|
-
*
|
|
23
|
-
* `--provider` and `--driver` are required rather than sniffed. The provider is
|
|
24
|
-
* stamped into the artifact as a recorded fact, and the driver decides
|
|
25
|
-
* `AdapterModel.transactions`, which is a **driver** fact the schema cannot state:
|
|
26
|
-
* a `datasource` block names `postgresql`, not whether the application will drive
|
|
27
|
-
* it through `@prisma/adapter-pg`. Guessing either would put a guess in the
|
|
28
|
-
* artifact; D-804's rule is that the caller declares.
|
|
29
|
-
*
|
|
30
|
-
* # Failure is a message and an exit code, never a stack
|
|
31
|
-
*
|
|
32
|
-
* The step's refusals are deliberate, legible and aimed at the person running the
|
|
33
|
-
* build — a `prisma` major this reader has never seen, a generated tree whose
|
|
34
|
-
* runtime does not resolve, a schema construct the reader does not model. Printing
|
|
35
|
-
* a V8 stack trace over them would bury the sentence that says what to do. An
|
|
36
|
-
* unexpected error keeps its stack, because that one is a defect.
|
|
37
|
-
*/
|
|
38
4
|
const USAGE = `aventara-prisma7-generate — emit a @aventara/prisma7-adapter discovery artifact.
|
|
39
5
|
|
|
40
6
|
Usage:
|
|
@@ -69,14 +35,6 @@ const FLAGS = {
|
|
|
69
35
|
"--driver": "driver",
|
|
70
36
|
"--out": "artifactFile",
|
|
71
37
|
};
|
|
72
|
-
/**
|
|
73
|
-
* The flags, parsed. Exported so a case can drive it without a child process:
|
|
74
|
-
* the parse is the only judgement this file makes, and the rest is the step's.
|
|
75
|
-
*
|
|
76
|
-
* `--flag value` only. `--flag=value` is deliberately not accepted, because
|
|
77
|
-
* accepting both spellings means two code paths over one fact for a binary whose
|
|
78
|
-
* entire surface is five required flags.
|
|
79
|
-
*/
|
|
80
38
|
export function parsePrismaGenerateArguments(argv) {
|
|
81
39
|
const seen = {};
|
|
82
40
|
for (let index = 0; index < argv.length; index += 1) {
|
|
@@ -107,8 +65,6 @@ export function parsePrismaGenerateArguments(argv) {
|
|
|
107
65
|
if (!PRISMA_DRIVERS.includes(driver)) {
|
|
108
66
|
throw new PrismaGenerateCliError(`\`--driver ${seen.driver}\` is not one of ${PRISMA_DRIVERS.join(", ")}.`);
|
|
109
67
|
}
|
|
110
|
-
// Resolved against the process's own directory, so every path in the output
|
|
111
|
-
// names one place and a relative `--out` lands where the caller meant.
|
|
112
68
|
return {
|
|
113
69
|
schema: path.resolve(seen.schema),
|
|
114
70
|
clientDirectory: path.resolve(seen.clientDirectory),
|
|
@@ -129,27 +85,16 @@ async function main(argv) {
|
|
|
129
85
|
for (const absence of result.excluded) {
|
|
130
86
|
process.stdout.write(`excluded: ${absence.message}\n`);
|
|
131
87
|
}
|
|
132
|
-
// Printed every run, because a cross-check whose exemptions are invisible is a
|
|
133
|
-
// cross-check nobody can audit.
|
|
134
88
|
for (const exemption of result.exemptions) {
|
|
135
89
|
process.stdout.write(`exempt (${exemption.kind}) ${exemption.entity}: ${exemption.reason}\n`);
|
|
136
90
|
}
|
|
137
91
|
return 0;
|
|
138
92
|
}
|
|
139
|
-
/**
|
|
140
|
-
* Runs `aventara-prisma7-generate` over this process — its arguments, its
|
|
141
|
-
* output, its exit code. Called by the bin's entry (`discovery.bin.ts`) once the
|
|
142
|
-
* Node guard has admitted this Node; importing this module runs nothing, which
|
|
143
|
-
* is what lets the parse be tested without the process exiting.
|
|
144
|
-
*/
|
|
145
93
|
export async function runFromProcess() {
|
|
146
94
|
try {
|
|
147
95
|
process.exitCode = await main(process.argv.slice(2));
|
|
148
96
|
}
|
|
149
97
|
catch (error) {
|
|
150
|
-
// A refusal from the step or this parser is a sentence the person running the
|
|
151
|
-
// build has to read; a stack trace in front of it is noise. Anything else is
|
|
152
|
-
// a defect and keeps its stack.
|
|
153
98
|
const named = error instanceof PrismaGenerateCliError ||
|
|
154
99
|
(error instanceof Error &&
|
|
155
100
|
(error.name === "PrismaGenerateStepError" ||
|
|
@@ -1,45 +1,39 @@
|
|
|
1
1
|
import type { PrismaCapabilitySurface } from "../discovery/capability-surface.interface.js";
|
|
2
2
|
import type { PrismaSchemaFacts, PrismaSchemaSite } from "../discovery/schema-facts.interface.js";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* An entity enters the `AdapterModel` iff the 🟢 generated types expose it.
|
|
8
|
-
* The gate is strictly stronger than any attribute list: it catches `@ignore`,
|
|
4
|
+
* An entity enters the `AdapterModel` iff the 🟢 generated types expose it. The
|
|
5
|
+
* gate is strictly stronger than any attribute list: it catches `@ignore`,
|
|
9
6
|
* `@@ignore`, preview-feature exclusions, provider drops and `Unsupported(…)`
|
|
10
7
|
* columns with no special case for any of them, because all of them show up the
|
|
11
8
|
* same way — as a name PSL declares and the client does not carry
|
|
12
|
-
* (`Unsupported(…)` confirmed absent from `$Payload.scalars` and from
|
|
13
|
-
*
|
|
9
|
+
* (`Unsupported(…)` confirmed absent from `$Payload.scalars` and from `FieldRefs`
|
|
10
|
+
* at 7.10.0 **[RUN8]**).
|
|
14
11
|
*
|
|
15
|
-
* `@ignore` and `@@ignore` are parsed **anyway**, and that is this module's
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
12
|
+
* `@ignore` and `@@ignore` are parsed **anyway**, and that is this module's whole
|
|
13
|
+
* subtlety. They do not drive the gate — the types do. They exist so the gate's
|
|
14
|
+
* report can say *why* an entity is absent rather than emitting the useless
|
|
15
|
+
* "present in schema, absent from client", and so the two outcomes can be told
|
|
16
|
+
* apart:
|
|
20
17
|
*
|
|
21
|
-
* - **Explained** — PSL itself instructed the exclusion. Recorded, reported,
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* - **Unexplained** — nothing in the schema accounts for the absence.
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
18
|
+
* - **Explained** — PSL itself instructed the exclusion. Recorded, reported, and
|
|
19
|
+
* **not fatal**. `@ignore` is a documented Prisma instruction with a deliberate
|
|
20
|
+
* author behind it; stopping the build on it would leave the developer no remedy
|
|
21
|
+
* but to delete the instruction, and an error with no remedy is a defect rather
|
|
22
|
+
* than a fence.
|
|
23
|
+
* - **Unexplained** — nothing in the schema accounts for the absence. **Fatal.**
|
|
24
|
+
* Emitting the entity would hand the framework a Resource the adapter can never
|
|
25
|
+
* execute against; omitting it silently would ship a model that is quietly
|
|
26
|
+
* missing something the developer wrote.
|
|
30
27
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* the
|
|
36
|
-
* never execute against" — survives: once the entity is excluded, no such
|
|
37
|
-
* Resource is handed over, and what remains to decide is only whether to stop
|
|
38
|
-
* the build. It is worth stopping for the absence nobody asked for.)
|
|
28
|
+
* This module implements the split above, which is the only reading under which
|
|
29
|
+
* the stated *reason* for the error — "otherwise the adapter hands the framework a
|
|
30
|
+
* Resource it can never execute against" — survives: once the entity is excluded,
|
|
31
|
+
* no such Resource is handed over, and what remains to decide is only whether to
|
|
32
|
+
* stop the build. It is worth stopping for the absence nobody asked for.)
|
|
39
33
|
*
|
|
40
|
-
* The reverse direction — a resource the types expose and PSL does not declare
|
|
41
|
-
*
|
|
42
|
-
* `reader-crosscheck.ts
|
|
34
|
+
* The reverse direction — a resource the types expose and PSL does not declare —
|
|
35
|
+
* is a reader inconsistency rather than an existence question, and belongs to
|
|
36
|
+
* `reader-crosscheck.ts`. This module does not answer it.
|
|
43
37
|
*/
|
|
44
38
|
export type PrismaAbsenceKind = "model" | "field";
|
|
45
39
|
/** What PSL said, when PSL said anything. */
|
|
@@ -28,12 +28,6 @@ function unexplainedMessage(entity, kind, site) {
|
|
|
28
28
|
: "Admitting it would put a field in the Contract that no query, filter or write can ever name";
|
|
29
29
|
return `\`${entity}\` is declared at ${where(site)} but ${surfaceSays(entity, kind)}, and nothing in the schema explains the absence — there is no ${instruction} on it. ${cost}, and dropping it silently would ship a model quietly missing something the schema declares. ${CAUSES}.`;
|
|
30
30
|
}
|
|
31
|
-
/**
|
|
32
|
-
* Runs the gate. Returns what was admitted and what PSL explained away; throws
|
|
33
|
-
* {@link PrismaExistenceGateError} listing every unexplained absence at once,
|
|
34
|
-
* because fixing them one build at a time is how a schema migration becomes a
|
|
35
|
-
* week.
|
|
36
|
-
*/
|
|
37
31
|
export function applyExistenceGate(facts, surface) {
|
|
38
32
|
const admitted = [];
|
|
39
33
|
const explained = [];
|
package/dist/generate/index.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import type { PrismaDriver, PrismaProvider } from "../provider/provider-profile.js";
|
|
2
2
|
import type { PrismaGenerateResult, PrismaGenerateToolchain } from "./prisma.generate.js";
|
|
3
3
|
/**
|
|
4
|
-
* F-805 — the package's **second published entry**: `@aventara/prisma7-adapter/generate`.
|
|
5
|
-
*
|
|
6
4
|
* # Why a second entry rather than a second package or a wider `"."`
|
|
7
5
|
*
|
|
8
6
|
* The runtime entry (`"."`) depends on `@aventara/core` and the caller's own
|
|
9
|
-
* generated client, and on nothing else. The generate path needs `typescript`
|
|
10
|
-
*
|
|
7
|
+
* generated client, and on nothing else. The generate path needs `typescript` (the
|
|
8
|
+
* types reader builds a real TypeScript program over the generated tree) and
|
|
11
9
|
* `prisma` (the step runs `prisma generate` itself, so that both sources describe
|
|
12
10
|
* one instant). Those two are declared as **optional peer dependencies**, not as
|
|
13
11
|
* dependencies, and the split is what keeps the plan's guarantee that *no
|
|
@@ -16,9 +14,9 @@ import type { PrismaGenerateResult, PrismaGenerateToolchain } from "./prisma.gen
|
|
|
16
14
|
* optional peer is not installed on their behalf.
|
|
17
15
|
*
|
|
18
16
|
* The published build therefore carries both halves and the `exports` map is what
|
|
19
|
-
* separates them. Nothing reachable from `"."` imports anything under
|
|
20
|
-
* `
|
|
21
|
-
*
|
|
17
|
+
* separates them. Nothing reachable from `"."` imports anything under `generate/`;
|
|
18
|
+
* `artifact.loader.spec.ts` asserts that from the import graph rather than from
|
|
19
|
+
* this paragraph.
|
|
22
20
|
*
|
|
23
21
|
* # What this entry is for
|
|
24
22
|
*
|
|
@@ -29,9 +27,9 @@ import type { PrismaGenerateResult, PrismaGenerateToolchain } from "./prisma.gen
|
|
|
29
27
|
* already has a build script and would rather call it.
|
|
30
28
|
*
|
|
31
29
|
* Everything the step itself exposes is re-exported, because the seams are the
|
|
32
|
-
* point: a consumer with an unusual toolchain can supply their own
|
|
33
|
-
*
|
|
34
|
-
*
|
|
30
|
+
* point: a consumer with an unusual toolchain can supply their own {@link
|
|
31
|
+
* PrismaGenerateToolchain}, and one with their own composition rules can call
|
|
32
|
+
* {@link runPrismaGenerateStep} directly.
|
|
35
33
|
*/
|
|
36
34
|
export { createPrismaModelComposer, PrismaModelCompositionError, } from "../discovery/model.discoverer.js";
|
|
37
35
|
export type { PrismaEntityAbsence } from "./existence.gate.js";
|
|
@@ -42,8 +40,8 @@ export type { PrismaReaderExemption } from "./reader-crosscheck.js";
|
|
|
42
40
|
* One engine's generate request, as a consumer states it.
|
|
43
41
|
*
|
|
44
42
|
* `driver` is here and is not on {@link PrismaGenerateRequest} for a reason the
|
|
45
|
-
* step's own header gives: `AdapterModel.transactions` is a **driver** fact
|
|
46
|
-
*
|
|
43
|
+
* step's own header gives: `AdapterModel.transactions` is a **driver** fact that
|
|
44
|
+
* is stamped into the artifact at generate time, while the step itself is
|
|
47
45
|
* forbidden to know a provider or a driver at all — composition is created with a
|
|
48
46
|
* transaction capability and nothing else, so `if (provider === …)` inside
|
|
49
47
|
* discovery is a compile error rather than a convention. This function is the one
|
package/dist/generate/index.js
CHANGED
|
@@ -1,50 +1,8 @@
|
|
|
1
1
|
import { createPrismaModelComposer } from "../discovery/model.discoverer.js";
|
|
2
2
|
import { resolveProviderProfile } from "../provider/provider-profile.js";
|
|
3
3
|
import { runPrismaGenerateStep } from "./prisma.generate.js";
|
|
4
|
-
/**
|
|
5
|
-
* F-805 — the package's **second published entry**: `@aventara/prisma7-adapter/generate`.
|
|
6
|
-
*
|
|
7
|
-
* # Why a second entry rather than a second package or a wider `"."`
|
|
8
|
-
*
|
|
9
|
-
* The runtime entry (`"."`) depends on `@aventara/core` and the caller's own
|
|
10
|
-
* generated client, and on nothing else. The generate path needs `typescript`
|
|
11
|
-
* (the types reader builds a real TypeScript program over the generated tree) and
|
|
12
|
-
* `prisma` (the step runs `prisma generate` itself, so that both sources describe
|
|
13
|
-
* one instant). Those two are declared as **optional peer dependencies**, not as
|
|
14
|
-
* dependencies, and the split is what keeps the plan's guarantee that *no
|
|
15
|
-
* compiler, no parser and no Prisma tooling enters the deployed runtime*: a
|
|
16
|
-
* consumer who imports only `"."` never loads a module that names either, and an
|
|
17
|
-
* optional peer is not installed on their behalf.
|
|
18
|
-
*
|
|
19
|
-
* The published build therefore carries both halves and the `exports` map is what
|
|
20
|
-
* separates them. Nothing reachable from `"."` imports anything under
|
|
21
|
-
* `generate/`; `artifact.loader.spec.ts` asserts that from the import graph
|
|
22
|
-
* rather than from this paragraph.
|
|
23
|
-
*
|
|
24
|
-
* # What this entry is for
|
|
25
|
-
*
|
|
26
|
-
* Producing the discovery artifact `createPrismaAdapter({ discovery })` requires,
|
|
27
|
-
* from the consumer's own `schema.prisma` and their own generated client. The
|
|
28
|
-
* `aventara-prisma7-generate` binary (`discovery.cli.ts`) is this function with an
|
|
29
|
-
* argument parser in front of it; this module is the same thing for a consumer who
|
|
30
|
-
* already has a build script and would rather call it.
|
|
31
|
-
*
|
|
32
|
-
* Everything the step itself exposes is re-exported, because the seams are the
|
|
33
|
-
* point: a consumer with an unusual toolchain can supply their own
|
|
34
|
-
* {@link PrismaGenerateToolchain}, and one with their own composition rules can
|
|
35
|
-
* call {@link runPrismaGenerateStep} directly.
|
|
36
|
-
*/
|
|
37
4
|
export { createPrismaModelComposer, PrismaModelCompositionError, } from "../discovery/model.discoverer.js";
|
|
38
5
|
export { createPrismaGenerateToolchain, PINNED_PRISMA_MAJOR, PrismaGenerateStepError, runPrismaGenerateStep, } from "./prisma.generate.js";
|
|
39
|
-
/**
|
|
40
|
-
* The generate step, wired: provider profile → transaction capability →
|
|
41
|
-
* composition → the step.
|
|
42
|
-
*
|
|
43
|
-
* Every decision stays where it already lived. This function resolves the profile
|
|
44
|
-
* and builds the composer; it makes no judgement of its own, which is why there is
|
|
45
|
-
* nothing here to test beyond that it is the wiring the CLI and the repository's
|
|
46
|
-
* own `generate` script both use.
|
|
47
|
-
*/
|
|
48
6
|
export async function generatePrismaDiscoveryArtifact(request) {
|
|
49
7
|
const profile = resolveProviderProfile({
|
|
50
8
|
provider: request.provider,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// biome-ignore lint/style/useNodejsImportProtocol: Node 14.0–14.13.0 resolves no "node:" specifier in an ES module, and this module runs on the Nodes the packages do not support.
|
|
2
1
|
import { readFileSync } from "fs";
|
|
3
2
|
function versionOf(text) {
|
|
4
3
|
const match = /^v?(\d+)\.(\d+)\.(\d+)/.exec(text);
|
|
@@ -16,11 +15,6 @@ function compareVersions(left, right) {
|
|
|
16
15
|
}
|
|
17
16
|
return 0;
|
|
18
17
|
}
|
|
19
|
-
/**
|
|
20
|
-
* Whether `range` admits `version`. Reads `^x.y.z` (the same major, from the
|
|
21
|
-
* floor; majors ≥ 1) and `>=x.y.z`, joined by `||`; anything else throws rather
|
|
22
|
-
* than admit or refuse by guess.
|
|
23
|
-
*/
|
|
24
18
|
function admits(range, version) {
|
|
25
19
|
return range.split("||").some((part) => {
|
|
26
20
|
const comparator = /^\s*(\^|>=)(\d+\.\d+\.\d+)\s*$/.exec(part);
|
|
@@ -32,17 +26,11 @@ function admits(range, version) {
|
|
|
32
26
|
(comparator[1] === ">=" || version[0] === floor[0]));
|
|
33
27
|
});
|
|
34
28
|
}
|
|
35
|
-
/** The sentence a bin answers on `version`, or `undefined` when `range` admits it. */
|
|
36
29
|
export function nodeVersionRefusal(bin, packageName, range, version) {
|
|
37
30
|
return admits(range, versionOf(version))
|
|
38
31
|
? undefined
|
|
39
32
|
: `${bin}: Node ${version} is not supported; ${packageName} needs Node ${range}.`;
|
|
40
33
|
}
|
|
41
|
-
/**
|
|
42
|
-
* Reads the manifest at `manifestUrl`; on a Node its `engines.node` does not
|
|
43
|
-
* admit, writes the sentence to stderr, sets exit code 1 and answers `true` —
|
|
44
|
-
* the bin then loads nothing else.
|
|
45
|
-
*/
|
|
46
34
|
export function refuseUnsupportedNode(bin, manifestUrl) {
|
|
47
35
|
const manifest = JSON.parse(readFileSync(manifestUrl, "utf8"));
|
|
48
36
|
const range = manifest.engines === undefined ? undefined : manifest.engines.node;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* prisma
|
|
6
|
-
*
|
|
7
|
-
* side as **`@prisma/prisma7`**, bin `prisma7` — the same CLI under a
|
|
8
|
-
* version-specific name. So, in this order:
|
|
2
|
+
* `prisma`'s `latest` is a Prisma 8 release candidate, so `npm i prisma` in a
|
|
3
|
+
* Prisma 7 project now installs a CLI this adapter's readers were never written
|
|
4
|
+
* against. Prisma's own upgrade path keeps the Prisma 7 CLI side by side as
|
|
5
|
+
* **`@prisma/prisma7`**, bin `prisma7` — the same CLI under a version-specific
|
|
6
|
+
* name. So, in this order:
|
|
9
7
|
*
|
|
10
8
|
* 1. `@prisma/prisma7` installed → its `prisma7` bin runs, provided the `prisma`
|
|
11
9
|
* it wraps is in the declared range;
|
|
@@ -17,10 +15,10 @@
|
|
|
17
15
|
*
|
|
18
16
|
* Each package is looked up first from this module — the adapter's own install,
|
|
19
17
|
* where an optional peer is linked — and then from the project the step runs in
|
|
20
|
-
* (its working directory), where a strict installer such as pnpm leaves a
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
18
|
+
* (its working directory), where a strict installer such as pnpm leaves a package
|
|
19
|
+
* the adapter does not declare. A found package is followed to its real path, so
|
|
20
|
+
* the `prisma` that `@prisma/prisma7` wraps is the one beside it and not a
|
|
21
|
+
* `prisma` 8 hoisted next to the link.
|
|
24
22
|
*/
|
|
25
23
|
export type PrismaCli = {
|
|
26
24
|
/** The package whose bin runs: `@prisma/prisma7` or `prisma`. */
|
|
@@ -2,13 +2,6 @@ import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { satisfiesDeclaredRange } from "./declared-support.reader.js";
|
|
5
|
-
/**
|
|
6
|
-
* The first `node_modules/<name>/package.json` on the way up from each place in
|
|
7
|
-
* turn — Node's own lookup order, walked by hand because the manifest is all
|
|
8
|
-
* that is wanted: no `exports` map can hide it, and no `NODE_PATH` can answer
|
|
9
|
-
* from outside the install (a test runner sets one, and a resolution answered
|
|
10
|
-
* through it has produced a false green in this package before).
|
|
11
|
-
*/
|
|
12
5
|
function locate(name, searchFrom) {
|
|
13
6
|
for (const base of searchFrom) {
|
|
14
7
|
let directory = path.dirname(base.startsWith("file:") ? fileURLToPath(base) : base);
|
|
@@ -48,16 +41,10 @@ function binEntry(located, bin) {
|
|
|
48
41
|
? path.join(located.directory, relative)
|
|
49
42
|
: undefined;
|
|
50
43
|
}
|
|
51
|
-
/**
|
|
52
|
-
* The Prisma CLI to run, or why there is none. `searchFrom` holds the places to
|
|
53
|
-
* resolve from, in order — a module URL or a path of a file in the directory to
|
|
54
|
-
* start from; `range` is the adapter's declared `prisma` range.
|
|
55
|
-
*/
|
|
56
44
|
export function resolvePrismaCli(input) {
|
|
57
45
|
const install = `\`npm i -D "@prisma/prisma7@${input.range}"\``;
|
|
58
46
|
const prisma7 = locate("@prisma/prisma7", input.searchFrom);
|
|
59
47
|
if (prisma7 !== undefined) {
|
|
60
|
-
// The version is the wrapped CLI's, looked up from beside the wrapper.
|
|
61
48
|
const wrapped = locate("prisma", [
|
|
62
49
|
path.join(prisma7.directory, "package.json"),
|
|
63
50
|
]);
|
|
@@ -1,62 +1,52 @@
|
|
|
1
1
|
import type { PrismaCapabilitySurface } from "../discovery/capability-surface.interface.js";
|
|
2
|
-
import type { PrismaAdapterModel, PrismaReferentialActionTable, PrismaTranslationTable } from "../discovery/discovery-artifact.interface.js";
|
|
2
|
+
import type { PrismaAdapterModel, PrismaCreateRequirementTable, PrismaReferentialActionTable, PrismaTranslationTable } from "../discovery/discovery-artifact.interface.js";
|
|
3
3
|
import type { PrismaSchemaFacts } from "../discovery/schema-facts.interface.js";
|
|
4
4
|
import type { PrismaProvider } from "../provider/provider-profile.js";
|
|
5
5
|
import type { PrismaEntityAbsence } from "./existence.gate.js";
|
|
6
6
|
import { type PrismaCli } from "./prisma-cli.resolver.js";
|
|
7
7
|
import type { PrismaReaderExemption } from "./reader-crosscheck.js";
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* a deployed application never carries `typescript`, a PSL reader or a child
|
|
14
|
-
* process.
|
|
9
|
+
* Nothing under `execution/`, and nothing in `discovery/artifact.loader.ts`,
|
|
10
|
+
* imports it; the package's build `exclude` keeps `src/generate/**` out of `dist`
|
|
11
|
+
* entirely, so a deployed application never carries `typescript`, a PSL reader or
|
|
12
|
+
* a child process.
|
|
15
13
|
*
|
|
16
14
|
* **The order is fixed, and each step earns its place:**
|
|
17
15
|
*
|
|
18
|
-
* 1. **The pinned `prisma` major
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* `
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* on the result.
|
|
43
|
-
* 6. **Emit** one TypeScript module (ADR 0009).
|
|
16
|
+
* 1. **The pinned `prisma` major**. PSL's grammar and the generated client's shape
|
|
17
|
+
* are version-bound; a major this reader has never seen must stop the build
|
|
18
|
+
* rather than produce a wrong `AdapterModel` from a grammar nobody read.
|
|
19
|
+
* 2. **`@prisma/client/runtime/client` resolves**. This one is first among equals,
|
|
20
|
+
* because its failure is *silent*: every generated file opens `// @ts-nocheck`,
|
|
21
|
+
* so with the runtime unresolvable a TypeScript program over the generated tree
|
|
22
|
+
* reports **zero** diagnostics while `FieldRef` degrades to its uninstantiated
|
|
23
|
+
* form and `JsonValue` stops being a union — flipping a types-derived
|
|
24
|
+
* nullability from `true` to `false` with nothing anywhere to say so
|
|
25
|
+
* **[RUN8]**. The guard is therefore a module *resolution*, never a diagnostic
|
|
26
|
+
* count: a diagnostic count is exactly the instrument that reads clean in this
|
|
27
|
+
* failure.
|
|
28
|
+
* 3. **`prisma generate`**, run by this step itself. The two sources must describe
|
|
29
|
+
* one instant; a client generated by some earlier command may describe an older
|
|
30
|
+
* schema, and nothing downstream could tell.
|
|
31
|
+
* 4. **Both sources read in that same run** — PSL for the semantic model, the 🟢
|
|
32
|
+
* generated types for the capability surface and for existence.
|
|
33
|
+
* 5. **The structural checks, in that order.** The existence gate first, because
|
|
34
|
+
* it decides *which* entities exist and a cross-check of an entity nobody
|
|
35
|
+
* admitted is noise; then the reader-versus-reader cross-check
|
|
36
|
+
* (`reader-crosscheck.ts`), which answers the reverse direction the gate hands
|
|
37
|
+
* it and every other fact both sources carry. Its findings stop the step; its
|
|
38
|
+
* two documented exemptions are reported and carried out on the result.
|
|
39
|
+
* 6. **Emit** one TypeScript module.
|
|
44
40
|
*
|
|
45
|
-
* The
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* PSL `unhandled` entry means *I located a token I do not model*: there is a
|
|
53
|
-
* construct, a spelling and a site to report, so they are aggregated and
|
|
54
|
-
* reported together. A types-reader failure means *I cannot read the surface at
|
|
55
|
-
* all*: there is nothing to record, so it throws. Inventing an `unhandled`
|
|
56
|
-
* vocabulary for the type surface would be a second parallel representation of
|
|
57
|
-
* "something went wrong" for no gain.
|
|
41
|
+
* **The two readers fail differently, and the step keeps them different.** A PSL
|
|
42
|
+
* `unhandled` entry means *I located a token I do not model*: there is a
|
|
43
|
+
* construct, a spelling and a site to report, so they are aggregated and reported
|
|
44
|
+
* together. A types-reader failure means *I cannot read the surface at all*: there
|
|
45
|
+
* is nothing to record, so it throws. Inventing an `unhandled` vocabulary for the
|
|
46
|
+
* type surface would be a second parallel representation of "something went wrong"
|
|
47
|
+
* for no gain.
|
|
58
48
|
*/
|
|
59
|
-
/** The `prisma` major this reader's grammar was written against
|
|
49
|
+
/** The `prisma` major this reader's grammar was written against. */
|
|
60
50
|
export declare const PINNED_PRISMA_MAJOR = 7;
|
|
61
51
|
export declare class PrismaGenerateStepError extends Error {
|
|
62
52
|
readonly name = "PrismaGenerateStepError";
|
|
@@ -77,14 +67,15 @@ export type PrismaComposedArtifact = {
|
|
|
77
67
|
readonly model: PrismaAdapterModel;
|
|
78
68
|
readonly translation: PrismaTranslationTable;
|
|
79
69
|
readonly referentialActions: PrismaReferentialActionTable;
|
|
70
|
+
readonly createRequirements: PrismaCreateRequirementTable;
|
|
80
71
|
};
|
|
81
72
|
/**
|
|
82
73
|
* Composition of the two readers' facts into the artifact's two halves.
|
|
83
74
|
*
|
|
84
75
|
* It is a parameter rather than a call, because composition is
|
|
85
|
-
* `discovery/model.discoverer.ts`'s
|
|
86
|
-
*
|
|
87
|
-
*
|
|
76
|
+
* `discovery/model.discoverer.ts`'s and this step's job is order and refusal over
|
|
77
|
+
* external effects. The step hands over only what it has verified: both readers'
|
|
78
|
+
* output, and the resource names the existence gate admitted.
|
|
88
79
|
*/
|
|
89
80
|
export type PrismaModelComposer = (input: {
|
|
90
81
|
readonly facts: PrismaSchemaFacts;
|
|
@@ -129,18 +120,14 @@ export type PrismaGenerateResult = {
|
|
|
129
120
|
/** PSL-only entities the schema itself explained away. */
|
|
130
121
|
readonly excluded: readonly PrismaEntityAbsence[];
|
|
131
122
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* caller can print them and a spec can assert them by name and reason.
|
|
123
|
+
* Carried out rather than swallowed, so a caller can print them and a spec can
|
|
124
|
+
* assert them by name and reason.
|
|
135
125
|
*/
|
|
136
126
|
readonly exemptions: readonly PrismaReaderExemption[];
|
|
137
127
|
};
|
|
138
128
|
/**
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* version is in the adapter's declared range, else a refusal naming both. Looked
|
|
142
|
-
* up from this package — where an optional peer is linked — and then from the
|
|
143
|
-
* project the step runs in.
|
|
129
|
+
* Looked up from this package — where an optional peer is linked — and then from
|
|
130
|
+
* the project the step runs in.
|
|
144
131
|
*/
|
|
145
132
|
export declare function resolveInstalledPrismaCli(): PrismaCli;
|
|
146
133
|
/**
|
|
@@ -151,13 +138,10 @@ export declare function resolveInstalledPrismaCli(): PrismaCli;
|
|
|
151
138
|
*/
|
|
152
139
|
export declare function readInstalledPrismaVersion(): Promise<string>;
|
|
153
140
|
/**
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
* file path *inside* `clientDirectory` because resolution walks `node_modules`
|
|
159
|
-
* upward from the importer. The directory need not exist yet: resolution is a
|
|
160
|
-
* path question, which is what lets this fence run before `prisma generate`.
|
|
141
|
+
* Asked as a module resolution, never as a diagnostic count, and asked from a file
|
|
142
|
+
* path *inside* `clientDirectory` because resolution walks `node_modules` upward
|
|
143
|
+
* from the importer. The directory need not exist yet: resolution is a path
|
|
144
|
+
* question, which is what lets this fence run before `prisma generate`.
|
|
161
145
|
*/
|
|
162
146
|
export declare function clientRuntimeResolves(clientDirectory: string): boolean;
|
|
163
147
|
export declare function createPrismaGenerateToolchain(): PrismaGenerateToolchain;
|