@aventara/prisma7-adapter 1.0.0-rc.14 → 1.0.0-rc.15
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/CHANGELOG.md +25 -0
- package/dist/discovery/artifact.loader.js +3 -0
- package/dist/discovery/discovery-artifact.interface.d.ts +12 -2
- package/dist/discovery/discovery-artifact.interface.js +1 -1
- package/dist/generate/artifact.emitter.d.ts +10 -0
- package/dist/generate/artifact.emitter.js +66 -5
- package/dist/generate/computed-fields.import.d.ts +5 -0
- package/dist/generate/computed-fields.import.js +3 -0
- package/dist/generate/prisma.generate.js +4 -1
- package/dist/prisma-adapter.description.d.ts +1 -1
- package/dist/prisma-adapter.description.js +2 -0
- package/dist/prisma.adapter.js +10 -5
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @aventara/prisma7-adapter
|
|
2
2
|
|
|
3
|
+
## 1.0.0-rc.15
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- aab6d72: The client `avclient generate` writes now passes a default `biome check` as written, on Biome 2.4.0 and later (Biome's default rules; an opt-in rule or assist such as `useSortedKeys` is not covered): every generated file opens with `biome-ignore-all` lines for formatting, lint and import order (`organizeImports`), core's copied declarations have a blank line after their imports, the copied field-check evaluator carries no line suppression that the file-wide one makes unused, and each file ends without a final line break, which Biome 2.4.0 to 2.4.10 reported on every file under `biome-ignore-all format`. `aventara-build`'s own files pass too, in NestJS and Next.js projects: `resources.generated.ts`, `computed-fields.generated.ts` and `contracts.generated.ts` now open with the same suppressions and end without a final line break, and `--client`'s `src/aventara/client.ts` and `src/aventara/universal.ts` are written the same way. The discovery artifact `aventara-prisma7-generate` writes passes too. A file an earlier version wrote is reported stale by `aventara-build --check` and replaced by the next run. A client `avclient generate` wrote before is replaced on its next run. The client skill now says the generated files need no exclusion under Biome's default rules, and how to skip them in another linter or formatter.
|
|
8
|
+
- bf98da7: A pipeline stage's types now know the root's field definitions. `aventara-build` writes `src/generated/aventara/config-facts.generated.ts` after it compiles the Contracts, and the discovery artifact puts it on the model's type:
|
|
9
|
+
|
|
10
|
+
- A Json field the root shapes reads as its shape in a stage's `ctx` calls, in `tx` and in compute's read-only `ctx`: `ctx.Product.find.many({ select: ["name"] })` types `name` as `{ ar: string; en: string }`. A read gives the shape's own type, the same as `framework.application`'s.
|
|
11
|
+
- A `VIRTUAL` field the root adds is in a variant's typed `ctx.$args` (`ctx.$args.data.tenderedMinor`), and a `ctx` create must write a non-null added input it can create.
|
|
12
|
+
- A variant's hooks and interceptors are told resolved arguments: their `ctx.$args` holds no `$ref` (an `AvTransactionReference`), since references are resolved before they run. Guards, pipes and filters still may see one.
|
|
13
|
+
- A write takes a shaped Json value read-only, deep, on every surface (`framework.application`, `ctx`, the generated client too), so a frozen value, such as a stage's `ctx.$args`, fits as well as a mutable one.
|
|
14
|
+
- A compute stage on a shaped Json field returns the shape's type. A compute stage on an added field returns the type its generated fact states, read from the model instead of the configuration. Without the generated file, its return is not typed.
|
|
15
|
+
|
|
16
|
+
The server warns at startup (`AVENTARA_STALE_GENERATED_TYPES`) when the configuration's definitions differ from the ones the generated types were written with, naming each field. It is the same one warning as for stale computed fields: one stale build gives one warning, with a paragraph for each part that is stale, including a facts file it cannot read. `aventara-build --check` also fails on a stale file. Run `aventara:prepare` after you change a `definition`.
|
|
17
|
+
|
|
18
|
+
The discovery artifact's format is now 5: regenerate it with `aventara:prepare` (an artifact of format 4 is refused, as before). The Json Shape type emitter the client generator uses now lives in `@aventara/core`; the generated clients are unchanged. The CLI's agent skill says this in `SKILL.md` and `reference/stages.md`.
|
|
19
|
+
|
|
20
|
+
- Updated dependencies [aab6d72]
|
|
21
|
+
- Updated dependencies [bf98da7]
|
|
22
|
+
- Updated dependencies [f8cd860]
|
|
23
|
+
- Updated dependencies [8a64af2]
|
|
24
|
+
- Updated dependencies [548881c]
|
|
25
|
+
- Updated dependencies [62fa91f]
|
|
26
|
+
- @aventara/core@1.0.0-rc.15
|
|
27
|
+
|
|
3
28
|
## 1.0.0-rc.14
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
|
@@ -50,6 +50,9 @@ function assertArtifactShape(artifact) {
|
|
|
50
50
|
if (artifact.computedFields !== null && !isRecord(artifact.computedFields)) {
|
|
51
51
|
throw new AvPrismaDiscoveryArtifactError("The discovery artifact's `computedFields` is neither a JSON object nor null.");
|
|
52
52
|
}
|
|
53
|
+
if (artifact.configFacts !== null && !isRecord(artifact.configFacts)) {
|
|
54
|
+
throw new AvPrismaDiscoveryArtifactError("The discovery artifact's `configFacts` is neither a JSON object nor null.");
|
|
55
|
+
}
|
|
53
56
|
for (const key of ["scalars", "enums", "resources"]) {
|
|
54
57
|
if (!isRecord(artifact.model[key])) {
|
|
55
58
|
throw new AvPrismaDiscoveryArtifactError(`The discovery artifact's \`model.${key}\` is not a JSON object.`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AvAdapterModel, AvConfigComputedFields, AvEnumDefinition, AvScalarRegistry, AvTransactionCapability } from "@aventara/core";
|
|
1
|
+
import type { AvAdapter, AvAdapterModel, AvConfigComputedFields, AvEnumDefinition, AvScalarRegistry, AvTransactionCapability } from "@aventara/core";
|
|
2
2
|
import type { AvAdapterResource } from "@aventara/core/internal";
|
|
3
3
|
import type { AvPrismaProvider } from "../provider/provider-profile.js";
|
|
4
4
|
/** The adapter model a discovery artifact carries, in Aventara's vocabulary. */
|
|
@@ -75,7 +75,7 @@ export type AvPrismaReferentialActionTable<M extends AvPrismaAdapterModel = AvPr
|
|
|
75
75
|
*/
|
|
76
76
|
export type PrismaClientShape = Readonly<Record<string, readonly string[]>>;
|
|
77
77
|
/** The current discovery artifact format. */
|
|
78
|
-
export declare const DISCOVERY_ARTIFACT_FORMAT =
|
|
78
|
+
export declare const DISCOVERY_ARTIFACT_FORMAT = 5;
|
|
79
79
|
/**
|
|
80
80
|
* The discovery artifact: the module `aventara-prisma7-generate` writes from
|
|
81
81
|
* your schema and generated client. Import its `discovery` export and pass it
|
|
@@ -118,4 +118,14 @@ export type AvPrismaDiscoveryArtifact<M extends AvPrismaAdapterModel = AvPrismaA
|
|
|
118
118
|
* `modelHash`.
|
|
119
119
|
*/
|
|
120
120
|
readonly computedFields: AvConfigComputedFields | null;
|
|
121
|
+
/**
|
|
122
|
+
* The Json shapes and the fields the configuration's definitions add, per
|
|
123
|
+
* Resource, as `aventara-build` read them off the Contracts it compiled (the
|
|
124
|
+
* artifact imports them when the step was given `--config`); `null` when it
|
|
125
|
+
* was given none, or the build has not compiled the Contracts yet. The
|
|
126
|
+
* model's type carries the same statement for the pipeline stages' types;
|
|
127
|
+
* this value is compared with the compiled Core Contract when the framework
|
|
128
|
+
* starts. Not part of `modelHash`.
|
|
129
|
+
*/
|
|
130
|
+
readonly configFacts: NonNullable<AvAdapter["configFacts"]> | null;
|
|
121
131
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const DISCOVERY_ARTIFACT_FORMAT =
|
|
1
|
+
export const DISCOVERY_ARTIFACT_FORMAT = 5;
|
|
@@ -20,6 +20,16 @@ type PrismaArtifactEmission = {
|
|
|
20
20
|
readonly computedFields: {
|
|
21
21
|
readonly specifier: string;
|
|
22
22
|
} | null;
|
|
23
|
+
/**
|
|
24
|
+
* The specifier the module imports the configuration facts by (CORE-06
|
|
25
|
+
* step 2): the Json shapes and added fields `aventara-build` read off the
|
|
26
|
+
* Contracts it compiled (`config-facts.generated.ts`, beside the computed
|
|
27
|
+
* fields). `null` when the step was given no configuration: the module then
|
|
28
|
+
* states none. Beside `model`, outside the hash.
|
|
29
|
+
*/
|
|
30
|
+
readonly configFacts: {
|
|
31
|
+
readonly specifier: string;
|
|
32
|
+
} | null;
|
|
23
33
|
};
|
|
24
34
|
export declare function emitDiscoveryArtifactModule(emission: PrismaArtifactEmission): Promise<string>;
|
|
25
35
|
export {};
|
|
@@ -4,6 +4,7 @@ import { DISCOVERY_ARTIFACT_FORMAT, } from "../discovery/discovery-artifact.inte
|
|
|
4
4
|
const BANNER = [
|
|
5
5
|
"// biome-ignore-all format: generated output",
|
|
6
6
|
"// biome-ignore-all lint: generated output",
|
|
7
|
+
"// biome-ignore-all assist/source/organizeImports: generated output",
|
|
7
8
|
"/* !!! Generated by @aventara/prisma7-adapter's generate step. Do not edit. !!! */",
|
|
8
9
|
"/* Regenerate with `aventara-prisma7-generate`. */",
|
|
9
10
|
];
|
|
@@ -74,6 +75,22 @@ const NO_COMPUTED_FIELDS_DOC = [
|
|
|
74
75
|
" * `modelHash`.",
|
|
75
76
|
" */",
|
|
76
77
|
];
|
|
78
|
+
const CONFIG_FACTS_DOC = [
|
|
79
|
+
"/**",
|
|
80
|
+
" * The Json shapes and the fields the configuration's definitions add, per",
|
|
81
|
+
" * Resource, as aventara-build read them off the Contracts it compiled. A",
|
|
82
|
+
" * pipeline stage's `ctx` and its arguments are typed with them. The framework",
|
|
83
|
+
" * warns at startup when the configuration says otherwise: run",
|
|
84
|
+
" * `aventara:prepare` again. Not part of `modelHash`.",
|
|
85
|
+
" */",
|
|
86
|
+
];
|
|
87
|
+
const NO_CONFIG_FACTS_DOC = [
|
|
88
|
+
"/**",
|
|
89
|
+
" * `null`: the generate step was given no configuration (`--config`), so",
|
|
90
|
+
" * pipeline stages see the model's own fields, Json unshaped. Not part of",
|
|
91
|
+
" * `modelHash`.",
|
|
92
|
+
" */",
|
|
93
|
+
];
|
|
77
94
|
const DISCOVERY_DOC = [
|
|
78
95
|
"/** Pass this to `createPrismaAdapter({ discovery })`. */",
|
|
79
96
|
];
|
|
@@ -94,6 +111,46 @@ function computedFieldsLines(computedFields) {
|
|
|
94
111
|
"",
|
|
95
112
|
];
|
|
96
113
|
}
|
|
114
|
+
function configFactsLines(configFacts) {
|
|
115
|
+
if (configFacts === null) {
|
|
116
|
+
return [...NO_CONFIG_FACTS_DOC, "export const configFacts = null;", ""];
|
|
117
|
+
}
|
|
118
|
+
return [
|
|
119
|
+
...CONFIG_FACTS_DOC,
|
|
120
|
+
"export { type AvConfigFacts, configFacts };",
|
|
121
|
+
"",
|
|
122
|
+
];
|
|
123
|
+
}
|
|
124
|
+
function generatedStatementLines(emission) {
|
|
125
|
+
if (emission.computedFields !== null && emission.configFacts !== null) {
|
|
126
|
+
return [
|
|
127
|
+
...COMPUTED_FIELDS_DOC,
|
|
128
|
+
...CONFIG_FACTS_DOC,
|
|
129
|
+
"export {",
|
|
130
|
+
"\ttype AvComputedFields,",
|
|
131
|
+
"\ttype AvConfigFacts,",
|
|
132
|
+
"\tcomputedFields,",
|
|
133
|
+
"\tconfigFacts,",
|
|
134
|
+
"};",
|
|
135
|
+
"",
|
|
136
|
+
];
|
|
137
|
+
}
|
|
138
|
+
return [
|
|
139
|
+
...computedFieldsLines(emission.computedFields),
|
|
140
|
+
...configFactsLines(emission.configFacts),
|
|
141
|
+
];
|
|
142
|
+
}
|
|
143
|
+
function modelTypeMembers(emission) {
|
|
144
|
+
const members = [
|
|
145
|
+
...(emission.computedFields === null
|
|
146
|
+
? []
|
|
147
|
+
: ['readonly "~computedFields"?: AvComputedFields']),
|
|
148
|
+
...(emission.configFacts === null
|
|
149
|
+
? []
|
|
150
|
+
: ['readonly "~configFacts"?: AvConfigFacts']),
|
|
151
|
+
];
|
|
152
|
+
return members.length === 0 ? "};" : `} & { ${members.join("; ")} };`;
|
|
153
|
+
}
|
|
97
154
|
export async function emitDiscoveryArtifactModule(emission) {
|
|
98
155
|
const modelHash = await computeModelHash(emission.model);
|
|
99
156
|
return `${[
|
|
@@ -105,16 +162,19 @@ export async function emitDiscoveryArtifactModule(emission) {
|
|
|
105
162
|
: [
|
|
106
163
|
`import { type AvComputedFields, computedFields } from ${JSON.stringify(emission.computedFields.specifier)};`,
|
|
107
164
|
]),
|
|
165
|
+
...(emission.configFacts === null
|
|
166
|
+
? []
|
|
167
|
+
: [
|
|
168
|
+
`import { type AvConfigFacts, configFacts } from ${JSON.stringify(emission.configFacts.specifier)};`,
|
|
169
|
+
]),
|
|
108
170
|
"",
|
|
109
171
|
`const discoveredModel = ${canonicalLiteral(emission.model)} as const satisfies AvAdapterModel;`,
|
|
110
172
|
"",
|
|
111
|
-
...
|
|
173
|
+
...generatedStatementLines(emission),
|
|
112
174
|
...MODEL_TYPE_DOC,
|
|
113
175
|
"export type AvModel = {",
|
|
114
176
|
"\treadonly [K in keyof typeof discoveredModel]: (typeof discoveredModel)[K];",
|
|
115
|
-
emission
|
|
116
|
-
? "};"
|
|
117
|
-
: '} & { readonly "~computedFields"?: AvComputedFields };',
|
|
177
|
+
modelTypeMembers(emission),
|
|
118
178
|
"",
|
|
119
179
|
...MODEL_DOC,
|
|
120
180
|
"export const model: AvModel = discoveredModel;",
|
|
@@ -143,6 +203,7 @@ export async function emitDiscoveryArtifactModule(emission) {
|
|
|
143
203
|
"\treferentialActions,",
|
|
144
204
|
"\tclient,",
|
|
145
205
|
"\tcomputedFields,",
|
|
206
|
+
"\tconfigFacts,",
|
|
146
207
|
"} as const;",
|
|
147
|
-
].join("\n")}
|
|
208
|
+
].join("\n")}`;
|
|
148
209
|
}
|
|
@@ -3,3 +3,8 @@
|
|
|
3
3
|
* the sibling `computed-fields.generated` module.
|
|
4
4
|
*/
|
|
5
5
|
export declare function computedFieldsSpecifier(artifactFile: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* The specifier the artifact at `artifactFile` imports the configuration
|
|
8
|
+
* facts by: the sibling `config-facts.generated` module.
|
|
9
|
+
*/
|
|
10
|
+
export declare function configFactsSpecifier(artifactFile: string): string;
|
|
@@ -50,3 +50,6 @@ function importSuffix(directory) {
|
|
|
50
50
|
export function computedFieldsSpecifier(artifactFile) {
|
|
51
51
|
return `./computed-fields.generated${importSuffix(path.dirname(path.resolve(artifactFile)))}`;
|
|
52
52
|
}
|
|
53
|
+
export function configFactsSpecifier(artifactFile) {
|
|
54
|
+
return `./config-facts.generated${importSuffix(path.dirname(path.resolve(artifactFile)))}`;
|
|
55
|
+
}
|
|
@@ -7,7 +7,7 @@ import { computeModelHash } from "../discovery/artifact.loader.js";
|
|
|
7
7
|
import { AvPrismaSchemaReaderError, readPrismaSchema, } from "../discovery/schema.reader.js";
|
|
8
8
|
import { readPrismaCapabilitySurface } from "../discovery/types.reader.js";
|
|
9
9
|
import { emitDiscoveryArtifactModule } from "./artifact.emitter.js";
|
|
10
|
-
import { computedFieldsSpecifier } from "./computed-fields.import.js";
|
|
10
|
+
import { computedFieldsSpecifier, configFactsSpecifier, } from "./computed-fields.import.js";
|
|
11
11
|
import { readDeclaredSupport } from "./declared-support.reader.js";
|
|
12
12
|
import { applyExistenceGate } from "./existence.gate.js";
|
|
13
13
|
import { resolvePrismaCli } from "./prisma-cli.resolver.js";
|
|
@@ -230,6 +230,9 @@ export async function runPrismaGenerateStep(request) {
|
|
|
230
230
|
: {
|
|
231
231
|
specifier: computedFieldsSpecifier(request.artifactFile),
|
|
232
232
|
},
|
|
233
|
+
configFacts: request.config === undefined
|
|
234
|
+
? null
|
|
235
|
+
: { specifier: configFactsSpecifier(request.artifactFile) },
|
|
233
236
|
});
|
|
234
237
|
await toolchain.writeArtifact(request.artifactFile, source);
|
|
235
238
|
return {
|
|
@@ -11,7 +11,7 @@ type PrismaAdapterDescriptionInput<M extends AvPrismaAdapterModel> = {
|
|
|
11
11
|
readonly driver: AvPrismaDriver;
|
|
12
12
|
};
|
|
13
13
|
/** The adapter's passive facts, as {@link describePrismaAdapter} states them. */
|
|
14
|
-
type PrismaAdapterDescription<M extends AvPrismaAdapterModel> = PrismaAdapterDescriptionInput<M> & Required<Pick<AvAdapter<M>, "model" | "referentialActions">> & Pick<AvAdapter<M>, "computedFields"> & {
|
|
14
|
+
type PrismaAdapterDescription<M extends AvPrismaAdapterModel> = PrismaAdapterDescriptionInput<M> & Required<Pick<AvAdapter<M>, "model" | "referentialActions">> & Pick<AvAdapter<M>, "computedFields" | "configFacts"> & {
|
|
15
15
|
/**
|
|
16
16
|
* The driver's transaction capability: `"interactive"` when the
|
|
17
17
|
* constructed Adapter runs transactions, `"none"` when it carries no
|
|
@@ -23,6 +23,7 @@ export function describePrismaAdapter(input) {
|
|
|
23
23
|
driver: input.driver,
|
|
24
24
|
});
|
|
25
25
|
const computedFields = input.discovery.computedFields;
|
|
26
|
+
const configFacts = input.discovery.configFacts;
|
|
26
27
|
return Object.freeze({
|
|
27
28
|
discovery: input.discovery,
|
|
28
29
|
provider: input.provider,
|
|
@@ -31,6 +32,7 @@ export function describePrismaAdapter(input) {
|
|
|
31
32
|
transactions: profile.transactions,
|
|
32
33
|
referentialActions: translateReferentialActions(input.discovery.referentialActions),
|
|
33
34
|
...(computedFields === null ? {} : { computedFields }),
|
|
35
|
+
...(configFacts === null ? {} : { configFacts }),
|
|
34
36
|
sqlStatements: true,
|
|
35
37
|
});
|
|
36
38
|
}
|
package/dist/prisma.adapter.js
CHANGED
|
@@ -34,9 +34,14 @@ export async function createPrismaAdapter(options) {
|
|
|
34
34
|
const referentialActions = description.referentialActions;
|
|
35
35
|
const backReferences = derivePrismaBackReferences(options.discovery.model);
|
|
36
36
|
const bigintBinding = resolveBigintBinding(options.driver);
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
const generatedTypeFacts = {
|
|
38
|
+
...(description.computedFields === undefined
|
|
39
|
+
? {}
|
|
40
|
+
: { computedFields: description.computedFields }),
|
|
41
|
+
...(description.configFacts === undefined
|
|
42
|
+
? {}
|
|
43
|
+
: { configFacts: description.configFacts }),
|
|
44
|
+
};
|
|
40
45
|
const translation = options.discovery.translation;
|
|
41
46
|
const transactionOptions = options.transactionOptions === undefined
|
|
42
47
|
? {}
|
|
@@ -73,7 +78,7 @@ export async function createPrismaAdapter(options) {
|
|
|
73
78
|
return {
|
|
74
79
|
model,
|
|
75
80
|
referentialActions,
|
|
76
|
-
...
|
|
81
|
+
...generatedTypeFacts,
|
|
77
82
|
execute,
|
|
78
83
|
sqlStatements: description.sqlStatements,
|
|
79
84
|
executeSql,
|
|
@@ -91,7 +96,7 @@ export async function createPrismaAdapter(options) {
|
|
|
91
96
|
return {
|
|
92
97
|
model,
|
|
93
98
|
referentialActions,
|
|
94
|
-
...
|
|
99
|
+
...generatedTypeFacts,
|
|
95
100
|
execute,
|
|
96
101
|
transaction,
|
|
97
102
|
sqlStatements: description.sqlStatements,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aventara/prisma7-adapter",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.15",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"description": "The Prisma 7 adapter for Aventara.",
|
|
6
6
|
"type": "module",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"CHANGELOG.md"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@aventara/core": "1.0.0-rc.
|
|
33
|
+
"@aventara/core": "1.0.0-rc.15"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"@prisma/adapter-better-sqlite3": "^7.10.1",
|