@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.
Files changed (79) hide show
  1. package/README.md +33 -20
  2. package/dist/discovery/artifact.loader.d.ts +6 -2
  3. package/dist/discovery/artifact.loader.js +12 -57
  4. package/dist/discovery/capability-surface.interface.d.ts +29 -40
  5. package/dist/discovery/capability-surface.interface.js +0 -12
  6. package/dist/discovery/capability.deriver.d.ts +10 -40
  7. package/dist/discovery/capability.deriver.js +0 -179
  8. package/dist/discovery/client-shape.verifier.d.ts +13 -0
  9. package/dist/discovery/client-shape.verifier.js +93 -0
  10. package/dist/discovery/discovery-artifact.interface.d.ts +55 -30
  11. package/dist/discovery/enum.mapper.d.ts +6 -14
  12. package/dist/discovery/enum.mapper.js +1 -2
  13. package/dist/discovery/field.mapper.d.ts +49 -63
  14. package/dist/discovery/field.mapper.js +0 -161
  15. package/dist/discovery/identifier.mapper.d.ts +38 -77
  16. package/dist/discovery/identifier.mapper.js +0 -64
  17. package/dist/discovery/model.discoverer.d.ts +18 -35
  18. package/dist/discovery/model.discoverer.js +66 -141
  19. package/dist/discovery/operations.deriver.d.ts +10 -38
  20. package/dist/discovery/operations.deriver.js +0 -40
  21. package/dist/discovery/scalar.mapper.d.ts +12 -35
  22. package/dist/discovery/scalar.mapper.js +0 -8
  23. package/dist/discovery/schema-facts.interface.d.ts +26 -25
  24. package/dist/discovery/schema-facts.interface.js +0 -10
  25. package/dist/discovery/schema.reader.d.ts +53 -64
  26. package/dist/discovery/schema.reader.js +0 -174
  27. package/dist/discovery/types.reader.d.ts +0 -4
  28. package/dist/discovery/types.reader.js +2 -177
  29. package/dist/discovery/vocabulary.dictionary.d.ts +36 -75
  30. package/dist/discovery/vocabulary.dictionary.js +2 -152
  31. package/dist/errors/error.normalizer.d.ts +85 -135
  32. package/dist/errors/error.normalizer.js +1 -70
  33. package/dist/errors/prisma-error.reader.d.ts +53 -68
  34. package/dist/errors/prisma-error.reader.js +0 -91
  35. package/dist/execution/first-variant.emulator.d.ts +11 -22
  36. package/dist/execution/first-variant.emulator.js +0 -142
  37. package/dist/execution/operation.executor.d.ts +12 -19
  38. package/dist/execution/operation.executor.js +0 -92
  39. package/dist/execution/result.shaper.d.ts +22 -31
  40. package/dist/execution/result.shaper.js +0 -24
  41. package/dist/execution/transaction.executor.d.ts +36 -73
  42. package/dist/generate/artifact.emitter.d.ts +27 -27
  43. package/dist/generate/artifact.emitter.js +30 -13
  44. package/dist/generate/declared-support.reader.d.ts +11 -11
  45. package/dist/generate/declared-support.reader.js +0 -12
  46. package/dist/generate/discovery.bin.js +0 -10
  47. package/dist/generate/discovery.cli.js +0 -55
  48. package/dist/generate/existence.gate.d.ts +26 -32
  49. package/dist/generate/existence.gate.js +0 -6
  50. package/dist/generate/index.d.ts +10 -12
  51. package/dist/generate/index.js +0 -42
  52. package/dist/generate/node-version.guard.js +0 -12
  53. package/dist/generate/prisma-cli.resolver.d.ts +9 -11
  54. package/dist/generate/prisma-cli.resolver.js +0 -13
  55. package/dist/generate/prisma.generate.d.ts +49 -65
  56. package/dist/generate/prisma.generate.js +13 -123
  57. package/dist/generate/reader-crosscheck.d.ts +36 -60
  58. package/dist/generate/reader-crosscheck.js +5 -41
  59. package/dist/prisma-client.interface.d.ts +14 -19
  60. package/dist/prisma-client.interface.js +0 -6
  61. package/dist/prisma.adapter.d.ts +9 -17
  62. package/dist/prisma.adapter.js +11 -53
  63. package/dist/provider/provider-profile.d.ts +6 -23
  64. package/dist/provider/provider-profile.js +0 -64
  65. package/dist/translation/identifier.addressing.d.ts +15 -22
  66. package/dist/translation/identifier.addressing.js +0 -10
  67. package/dist/translation/mutation.translator.d.ts +19 -43
  68. package/dist/translation/mutation.translator.js +1 -209
  69. package/dist/translation/operation.translator.d.ts +36 -63
  70. package/dist/translation/operation.translator.js +1 -51
  71. package/dist/translation/order-pagination.translator.d.ts +24 -31
  72. package/dist/translation/order-pagination.translator.js +0 -43
  73. package/dist/translation/projection.translator.d.ts +25 -58
  74. package/dist/translation/projection.translator.js +0 -27
  75. package/dist/translation/scalar.conversion.d.ts +15 -26
  76. package/dist/translation/scalar.conversion.js +1 -129
  77. package/dist/translation/where.translator.d.ts +17 -28
  78. package/dist/translation/where.translator.js +0 -83
  79. package/package.json +3 -3
@@ -1,17 +1,8 @@
1
1
  import { loadDiscoveryArtifact } from "./discovery/artifact.loader.js";
2
+ import { assertClientMatchesArtifact } from "./discovery/client-shape.verifier.js";
2
3
  import { createPrismaOperationExecutor } from "./execution/operation.executor.js";
3
4
  import { createPrismaTransactionExecutor } from "./execution/transaction.executor.js";
4
5
  import { resolveProviderProfile, } from "./provider/provider-profile.js";
5
- /**
6
- * Each Prisma referential action as core's word for it (F-806). Keyed by the
7
- * closed {@link PrismaReferentialAction} union with `satisfies`, so a sixth
8
- * Prisma action is a compile error here rather than an edge core never follows,
9
- * and valued by core's own union, so a word core does not have is one too. The
10
- * mapping is one to one (the architect's five words, 2026-10-04): `no-action`
11
- * stays `noAction` although, measured on both engines (Phase 9 S0, U4), it is not
12
- * `DEFERRABLE` and answers one delete exactly as `restrict` does; `set-default`
13
- * stays `setDefault` although, like `setNull`, it keeps the rows.
14
- */
15
6
  const DELETE_EFFECTS = {
16
7
  cascade: "cascade",
17
8
  restrict: "restrict",
@@ -19,14 +10,6 @@ const DELETE_EFFECTS = {
19
10
  "set-null": "setNull",
20
11
  "set-default": "setDefault",
21
12
  };
22
- /**
23
- * The artifact's referential actions, translated into core's vocabulary.
24
- *
25
- * The direction is carried over unchanged, because it is the same sentence on
26
- * both sides of the seam: an edge listed under Resource `R` says **deleting a
27
- * `target` row does `onDelete` to rows of `R`**. Only owning edges exist in the
28
- * artifact, and `onUpdate` is not carried: core plans the delete closure only.
29
- */
30
13
  function translateReferentialActions(table) {
31
14
  return Object.fromEntries(Object.entries(table).map(([resource, { owningEdges }]) => [
32
15
  resource,
@@ -37,44 +20,19 @@ function translateReferentialActions(table) {
37
20
  })),
38
21
  ]));
39
22
  }
40
- /**
41
- * Construction is `async` because core's `Adapter.model` is a settled fact read
42
- * synchronously at framework construction, while *verifying* the artifact is
43
- * asynchronous: `computeModelHash` digests through `globalThis.crypto.subtle`,
44
- * which is a promise-returning API. The artifact itself is already a value in
45
- * hand (`options.discovery`); only its verification has to
46
- * await, so it happens here, once, before an adapter exists — every fence is
47
- * the same fence, moved from the first `discover()` call to construction.
48
- */
49
23
  export async function createPrismaAdapter(options) {
50
24
  const profile = resolveProviderProfile({
51
25
  provider: options.provider,
52
26
  driver: options.driver,
53
27
  });
54
- // The loader is a *verifier*, and its return is deliberately discarded. It
55
- // takes `unknown` because it guards the runtime boundary, so its answer is
56
- // the general `PrismaAdapterModel`; the literal `M` is already in hand on
57
- // `options.discovery.model`, which is the very object the loader would have
58
- // handed back. Reading it from the argument keeps the literal without a
59
- // cast, and keeps the loader honest about validating untrusted input.
60
28
  await loadDiscoveryArtifact({
61
29
  artifact: options.discovery,
62
30
  installedPrismaVersion: options.installedPrismaVersion ?? options.discovery.prismaVersion,
63
31
  });
32
+ assertClientMatchesArtifact(options.discovery.client, options.client);
64
33
  const model = options.discovery.model;
65
- // Read once, like the model: a settled fact of the constructed adapter.
66
34
  const referentialActions = translateReferentialActions(options.discovery.referentialActions);
67
- // Task 10: `execute` is real. The executor is built once, at construction, and
68
- // closes over the client, the discovered model and the generate-time
69
- // translation table — the three facts every call needs and none of which can
70
- // change afterwards.
71
- //
72
- // `translation` is widened by one deliberate cast. `PrismaTranslationTable<M>`
73
- // is a mapped type over `M`'s own resource keys, which is exactly what makes a
74
- // missing Resource a compile error at the generate step; a mapped type over a
75
- // literal union carries no index signature, so the executor — which looks a
76
- // Resource up by a name core validated — takes the widened view. The narrow
77
- // type has already done its work by the time this line runs.
35
+ const createRequirements = options.discovery.createRequirements;
78
36
  const { execute } = createPrismaOperationExecutor({
79
37
  client: options.client,
80
38
  model: options.discovery.model,
@@ -84,14 +42,8 @@ export async function createPrismaAdapter(options) {
84
42
  ? {}
85
43
  : { transactionOptions: options.transactionOptions }),
86
44
  });
87
- // DA-12: `transaction` is mounted exactly when the declared driver supports
88
- // an interactive one. For `@prisma/adapter-d1` the profile says `"none"`
89
- // [PKG], so core never calls it and the `_transactions` route is never
90
- // mounted. The declaration is Task 10's (D-805) and the body is Task 11's:
91
- // one interactive transaction per plan, with the transaction-scoped executor
92
- // as the only thing the callback hands core (C-803, C-804).
93
45
  if (profile.transactions === "none") {
94
- return { model, referentialActions, execute };
46
+ return { model, referentialActions, createRequirements, execute };
95
47
  }
96
48
  const transaction = createPrismaTransactionExecutor({
97
49
  client: options.client,
@@ -101,5 +53,11 @@ export async function createPrismaAdapter(options) {
101
53
  ? {}
102
54
  : { transactionOptions: options.transactionOptions }),
103
55
  });
104
- return { model, referentialActions, execute, transaction };
56
+ return {
57
+ model,
58
+ referentialActions,
59
+ createRequirements,
60
+ execute,
61
+ transaction,
62
+ };
105
63
  }
@@ -1,38 +1,21 @@
1
1
  import type { TransactionCapability } from "@aventara/core";
2
2
  /**
3
- * T-2 / D-824 — the one closed table of provider and driver facts, carrying
4
- * **only** the facts no reader can supply.
3
+ * A stored copy of either class would be a second source of truth, which is
4
+ * dictionary invariant 6.
5
5
  *
6
- * What is deliberately absent: `supportsScalarLists`, `supportsOrderNulls`,
7
- * `supportsCreateManyAndReturn` and `supportsUpdateManyAndReturn` are
8
- * *discovered* from the generated client's own types at generate time and
9
- * recorded in `PrismaDiscoveryArtifact` (T-3, T-3.2); `supportsEmulatedFirst
10
- * Variants` is *derived* — it is exactly `transactions !== "none"` — and is
11
- * computed where the §8.3 gate lives. A stored copy of either class would be a
12
- * second source of truth, which is dictionary invariant 6.
13
- *
14
- * Nothing here is inferred at runtime, because nothing here is derived at
15
- * runtime at all.
16
- */
17
- /**
18
- * The two engines Phase 8 runs — a value, so the bin's `--provider` check and
19
- * the manifest's declaration drift guard (`declaration-drift.gate.spec.ts`)
20
- * read the same list the type is derived from.
6
+ * Nothing here is inferred at runtime, because nothing here is derived at runtime
7
+ * at all.
21
8
  */
22
9
  export declare const PRISMA_PROVIDERS: readonly ["sqlite", "postgresql"];
23
10
  export type PrismaProvider = (typeof PRISMA_PROVIDERS)[number];
24
11
  /**
25
- * The closed driver set. Neon-HTTP and PlanetScale-HTTP are **absent**, not
26
- * `false`: their interactive-transaction support is genuinely UNVERIFIED for
27
- * Prisma 7 (C-825 — no adapter package is installed, neither driver is in
28
- * Phase 8's engine split, and all three v7 driver-adapter documentation pages
29
- * returned HTTP 404), and an entry with no evidence is a guess.
12
+ * The closed driver set.
30
13
  */
31
14
  export declare const PRISMA_DRIVERS: readonly ["@prisma/adapter-better-sqlite3", "@prisma/adapter-pg", "@prisma/adapter-d1"];
32
15
  export type PrismaDriver = (typeof PRISMA_DRIVERS)[number];
33
16
  /** The five levels `Prisma.IsolationLevel` admits **[PKG, `runtime/client.d.ts`]**. */
34
17
  export type PrismaIsolationLevel = "ReadUncommitted" | "ReadCommitted" | "RepeatableRead" | "Snapshot" | "Serializable";
35
- /** The caller's explicit declaration; never sniffed from client internals (D-804). */
18
+ /** The caller's explicit declaration; never sniffed from client internals. */
36
19
  export type PrismaProviderDeclaration = {
37
20
  readonly provider: PrismaProvider;
38
21
  readonly driver: PrismaDriver;
@@ -1,74 +1,14 @@
1
- /**
2
- * T-2 / D-824 — the one closed table of provider and driver facts, carrying
3
- * **only** the facts no reader can supply.
4
- *
5
- * What is deliberately absent: `supportsScalarLists`, `supportsOrderNulls`,
6
- * `supportsCreateManyAndReturn` and `supportsUpdateManyAndReturn` are
7
- * *discovered* from the generated client's own types at generate time and
8
- * recorded in `PrismaDiscoveryArtifact` (T-3, T-3.2); `supportsEmulatedFirst
9
- * Variants` is *derived* — it is exactly `transactions !== "none"` — and is
10
- * computed where the §8.3 gate lives. A stored copy of either class would be a
11
- * second source of truth, which is dictionary invariant 6.
12
- *
13
- * Nothing here is inferred at runtime, because nothing here is derived at
14
- * runtime at all.
15
- */
16
- /**
17
- * The two engines Phase 8 runs — a value, so the bin's `--provider` check and
18
- * the manifest's declaration drift guard (`declaration-drift.gate.spec.ts`)
19
- * read the same list the type is derived from.
20
- */
21
1
  export const PRISMA_PROVIDERS = ["sqlite", "postgresql"];
22
- /**
23
- * The closed driver set. Neon-HTTP and PlanetScale-HTTP are **absent**, not
24
- * `false`: their interactive-transaction support is genuinely UNVERIFIED for
25
- * Prisma 7 (C-825 — no adapter package is installed, neither driver is in
26
- * Phase 8's engine split, and all three v7 driver-adapter documentation pages
27
- * returned HTTP 404), and an entry with no evidence is a guess.
28
- */
29
2
  export const PRISMA_DRIVERS = [
30
3
  "@prisma/adapter-better-sqlite3",
31
4
  "@prisma/adapter-pg",
32
5
  "@prisma/adapter-d1",
33
6
  ];
34
- /**
35
- * `transactions` is a **DRIVER** fact, and each row carries its evidence.
36
- *
37
- * - `@prisma/adapter-d1` → `"none"` **[PKG]**: `runtime/client.js` of
38
- * `@prisma/client` 7.10.0 branches on
39
- * `this._engineConfig.adapter?.adapterName === "@prisma/adapter-d1"` and
40
- * throws `"Cloudflare D1 does not support interactive transactions. …"`.
41
- * Read from the installed package on 2026-09-23 (C-824, F-703).
42
- * - `@prisma/adapter-better-sqlite3` and `@prisma/adapter-pg` →
43
- * `"interactive"` **[RUN8]**: observed, not assumed. D-805 conditions this
44
- * value on an interactive transaction having been *proved to run* on each
45
- * driver, and `src/provider/interactive-transaction.spec.ts` runs one — a
46
- * write and a read issued through the callback's `tx`, with the write
47
- * visible afterwards — on both. Produced by
48
- * `AVENTARA_TEST_POSTGRES_URL=postgresql://aventara:aventara_dev@127.0.0.1:5432/aventara
49
- * npx vitest run --config ../../vitest.config.mts --root .
50
- * src/provider/interactive-transaction.spec.ts --reporter=verbose`
51
- * from `packages/prisma7-adapter`, which is what the relative `--config` path
52
- * and `--root .` are relative to. Run on 2026-09-23 against `@prisma/client`
53
- * 7.10.0, Node v24.20.0, SQLite through better-sqlite3 12.11.1 and
54
- * PostgreSQL 18.6: 4 passed, and 2 of those 4 skip when the URL is absent, so
55
- * the PostgreSQL half is not a silent pass. Re-run as written on 2026-10-02
56
- * after the config's `.mts` rename (`aba66a2`): 4 passed, and 2 passed with
57
- * 2 skipped without the URL.
58
- */
59
7
  const DRIVER_TRANSACTIONS = {
60
8
  "@prisma/adapter-better-sqlite3": "interactive",
61
9
  "@prisma/adapter-pg": "interactive",
62
10
  "@prisma/adapter-d1": "none",
63
11
  };
64
- /**
65
- * `isolationLevels` is a **PROVIDER** fact **[DOC7]**, fetched 2026-09-23 from
66
- * the version-pinned `prisma.io/docs/orm/v7/…/queries/transactions` page:
67
- * PostgreSQL supports ReadUncommitted, ReadCommitted, RepeatableRead and
68
- * Serializable; SQLite supports Serializable only. `Snapshot` is a SQL Server
69
- * level and belongs to neither Phase 8 engine, so it appears in the level
70
- * union (it is one of the five Prisma admits) and in no row.
71
- */
72
12
  const PROVIDER_ISOLATION_LEVELS = {
73
13
  sqlite: ["Serializable"],
74
14
  postgresql: [
@@ -78,10 +18,6 @@ const PROVIDER_ISOLATION_LEVELS = {
78
18
  "Serializable",
79
19
  ],
80
20
  };
81
- /**
82
- * Resolves the profile for a declaration. Pure, total over the closed sets,
83
- * and the only place provider truth is read.
84
- */
85
21
  export function resolveProviderProfile(declaration) {
86
22
  return {
87
23
  provider: declaration.provider,
@@ -7,17 +7,13 @@ import type { PrismaIdentifierAddress } from "../discovery/discovery-artifact.in
7
7
  *
8
8
  * The rule is three facts, every one of them measured at 7.10.0 and recorded in
9
9
  * {@link PrismaIdentifierAddress}: the generate-time `key` is matched and never
10
- * re-derived (`members.join("_")` is wrong for every `name:`-renamed criterion),
11
- * a key wraps its members iff `members.length > 1`, and the identifier chosen is
12
- * the first recorded criterion the caller's values complete.
10
+ * re-derived (`members.join("_")` is wrong for every `name:`-renamed criterion), a
11
+ * key wraps its members iff `members.length > 1`, and the identifier chosen is the
12
+ * first recorded criterion the caller's values complete.
13
13
  *
14
- * Task 9 flagged that the rule had landed twice — `addressCursor` in
15
- * `order-pagination.translator.ts` and `addressUnique` in
16
- * `mutation.translator.ts` — and Task 10 needed it a third time, for the
17
- * top-level where-unique of `find.unique`, `update.unique`, `delete.unique` and
18
- * `upsert.unique`. Three copies of a measured rule is three places a later
19
- * maintainer can fix two of, so the rule moved here and the three call sites
20
- * became three *configurations* of it.
14
+ * Three copies of a measured rule is three places a later maintainer can fix two
15
+ * of, so the rule moved here and the three call sites became three
16
+ * *configurations* of it.
21
17
  *
22
18
  * # What the call sites still own, and why that is not a leak
23
19
  *
@@ -26,23 +22,20 @@ import type { PrismaIdentifierAddress } from "../discovery/discovery-artifact.in
26
22
  * - **How complete the values must be.** A unique selector is `"exact"`: core's
27
23
  * selector carries one identifier and nothing else, so a selector with a spare
28
24
  * key is not that identifier. A cursor is `"subset"`: `validateCursor` requires
29
- * the cursor's keys to equal the *active ordered scalar fields*, which include
30
- * a complete identifier **plus** every other ordered key, so the identifier is
31
- * a proper subset of what arrives.
32
- * - **How a member's value is emitted.** `mutation.translator.ts` runs each
33
- * member through C-834's outbound scalar conversion (a core `Decimal` must
34
- * leave as a base-10 string); a cursor's values are already Prisma-shaped.
35
- * Passing the conversion in as `emit` keeps the scalar table in the module that
25
+ * the cursor's keys to equal the *active ordered scalar fields*, which include a
26
+ * complete identifier **plus** every other ordered key, so the identifier is a
27
+ * proper subset of what arrives.
28
+ * - Passing the conversion in as `emit` keeps the scalar table in the module that
36
29
  * owns it rather than importing it here.
37
30
  *
38
31
  * # No spec file of its own, deliberately
39
32
  *
40
33
  * Every branch is exercised through its three callers' specs —
41
- * `order-pagination.translator.spec.ts` (subset, compound wrapping, the
42
- * "addresses no row" refusal), `mutation.translator.spec.ts` (exact, renamed
43
- * keys, Decimal members) and `operation.translator.spec.ts` (exact, at the top
44
- * level). A fourth spec restating them would test this module's three lines
45
- * twice and the measured facts not at all.
34
+ * `order-pagination.translator.spec.ts` (subset, compound wrapping, the "addresses
35
+ * no row" refusal), `mutation.translator.spec.ts` (exact, renamed keys, Decimal
36
+ * members) and `operation.translator.spec.ts` (exact, at the top level). A fourth
37
+ * spec restating them would test this module's three lines twice and the measured
38
+ * facts not at all.
46
39
  */
47
40
  /**
48
41
  * How completely the supplied values must cover a criterion.
@@ -1,10 +1,3 @@
1
- /**
2
- * Addresses one row by the first recorded criterion the values complete.
3
- *
4
- * @returns the addressing, or `undefined` when no criterion is complete — which
5
- * is a caller-specific refusal (each call site raises its own error type with
6
- * its own path), never a silently unaddressed write.
7
- */
8
1
  export function addressIdentifier(input) {
9
2
  const keyCount = Object.keys(input.values).length;
10
3
  for (const address of input.addresses) {
@@ -16,9 +9,6 @@ export function addressIdentifier(input) {
16
9
  }
17
10
  const members = address.members.map((member) => [member, input.emit(member, input.values[member])]);
18
11
  const [single] = members;
19
- // A single-column criterion does NOT wrap, and a compound one does. The
20
- // difference is `members.length`, read off the recorded criterion rather
21
- // than guessed from the shape of the value.
22
12
  return {
23
13
  address,
24
14
  where: members.length === 1 && single !== undefined
@@ -1,58 +1,40 @@
1
1
  import { type AdapterModel, type OperationIdentity } from "@aventara/core";
2
2
  import type { PrismaIdentifierAddress } from "../discovery/discovery-artifact.interface.js";
3
3
  /**
4
- * T-7's mutation half — one validated Aventara `data` in, one Prisma write
5
- * argument out.
6
- *
7
4
  * # Pure, and the tables are the module
8
5
  *
9
- * No client, no database, no provider name. Three tables carry everything this
10
- * module knows, each one TOTAL over a core union by `satisfies`, so a member
11
- * added to core with no row here is a compile error rather than a silently
12
- * dropped argument (C-855's emission half, C-837's translator table — the one
13
- * `vocabulary.dictionary.ts` explicitly left to this task):
6
+ * No client, no database, no provider name.
14
7
  *
15
8
  * - {@link SCALAR_DIRECTIVE_TOKENS} over `ScalarMutationDirective`;
16
9
  * - {@link RELATION_DIRECTIVE_EMISSIONS} over `RelationMutationDirective`;
17
- * - {@link MUTATION_DATA_SITES} over every standard operation key, which is
18
- * C-818's enforcement point.
19
10
  *
20
- * C-834's own table is NOT one of them any more: the scalar value conversion was
21
- * born here, and `where.translator.ts` and `execution/result.shaper.ts` need the
22
- * same answers, so it moved to `scalar.conversion.ts` and all three read it
23
- * (Task 10's `identifier.addressing.ts` is the precedent). This module's
24
- * emission site is {@link emitValue}, which is now a call rather than a copy.
11
+ * This module's emission site is {@link emitValue}, which is now a call rather
12
+ * than a copy.
25
13
  *
26
- * Phase 7's `RELATION_MUTATION_RECORD_SITES` is the pattern
27
- * (`packages/core/src/runtime/mutation-planner.ts`): `as const satisfies
28
- * Readonly<Record<Union, …>>` keeps every cell a literal while making the union
29
- * coverage a compile-time obligation. Two of core's passes are already keyed
30
- * that way; this is the third, and the only one that names Prisma.
14
+ * Two of core's passes are already keyed that way; this is the third, and the only
15
+ * one that names Prisma.
31
16
  *
32
17
  * # Refusing is part of honouring (the `where.translator.ts` stance)
33
18
  *
34
- * The adapter assumes validated input (C-845). It still refuses to EMIT a
35
- * directive the discovered model does not advertise for that field and stage,
36
- * and refuses one for which Prisma's nested input at that stage and cardinality
37
- * has no key at all. Both refusals are C-855 seen from the emission side: an
38
- * argument is honoured or it is not sent. A directive quietly dropped here would
39
- * surface as a write that silently did less than it was asked to.
40
- *
41
- * # C-818 cannot reach the Contract, so it is enforced here
19
+ * The adapter assumes validated input. It still refuses to EMIT a directive the
20
+ * discovered model does not advertise for that field and stage, and refuses one
21
+ * for which Prisma's nested input at that stage and cardinality has no key at all.
22
+ * A directive quietly dropped here would surface as a write that silently did less
23
+ * than it was asked to.
42
24
  *
43
25
  * `RelationFieldCapabilities` is one record per field with a single `create`
44
- * member **[CORE, adapters/adapter-field.ts]**, so "relation create directives
45
- * for `create.one` and none for `create.many`" is unrepresentable in the model;
26
+ * member **[CORE, adapters/adapter-field.ts]**, so "relation create directives for
27
+ * `create.one` and none for `create.many`" is unrepresentable in the model;
46
28
  * `model.discoverer.ts` composes the permissive `create.one` answer and says so.
47
29
  * The restriction therefore lives in {@link MUTATION_DATA_SITES}, which is keyed
48
30
  * by the operation the data belongs to. Measured at 7.10.0 on both engines
49
31
  * (2026-10-02), a nested relation key in a bulk write is a hard failure, not a
50
32
  * no-op:
51
33
  *
52
- * - `post.createMany({ data: [{ title, author: { connect: … } }] })` →
53
- * *"Argument `authorId` is missing."*
54
- * - `post.updateMany({ where, data: { category: { connect: … } } })` →
55
- * *"Unknown argument `category`. Available options are marked with ?."*
34
+ * - `post.createMany({ data: [{ title, author: { connect: … } }] })` → *"Argument
35
+ * `authorId` is missing."*
36
+ * - `post.updateMany({ where, data: { category: { connect: … } } })` → *"Unknown
37
+ * argument `category`. Available options are marked with ?."*
56
38
  *
57
39
  * # Nothing in the caller's arguments is touched
58
40
  *
@@ -73,11 +55,6 @@ export declare class PrismaMutationTranslationError extends Error {
73
55
  export type PrismaMutationData = Readonly<Record<string, unknown>>;
74
56
  /** The two write stages core distinguishes. */
75
57
  export type PrismaWriteStage = "create" | "update";
76
- /**
77
- * Task 7's `where` translator, injected rather than imported so this module
78
- * stays a pure function of its inputs and the filter grammar keeps one owner
79
- * (the same shape `projection.translator.ts` uses for the same reason).
80
- */
81
58
  export type PrismaNestedWhereTranslator = (resource: string, where: unknown, path: string) => Readonly<Record<string, unknown>>;
82
59
  export type PrismaMutationDependencies = {
83
60
  readonly translateWhere: PrismaNestedWhereTranslator;
@@ -97,7 +74,6 @@ export type MutationTranslation = {
97
74
  readonly model: AdapterModel;
98
75
  /** The Aventara Resource key the data is written against. */
99
76
  readonly resource: string;
100
- /** The operation whose argument this data becomes; it decides C-818 admission. */
101
77
  readonly operation: OperationIdentity;
102
78
  /** Which of that operation's write stages this data is (`upsert.unique` has two). */
103
79
  readonly stage: PrismaWriteStage;
@@ -105,11 +81,11 @@ export type MutationTranslation = {
105
81
  readonly data: unknown;
106
82
  };
107
83
  /**
108
- * Translates one validated Aventara mutation `data` into the Prisma write
109
- * argument for the named operation and stage.
84
+ * Translates one validated Aventara mutation `data` into the Prisma write argument
85
+ * for the named operation and stage.
110
86
  *
111
87
  * @throws {PrismaMutationTranslationError} rather than emitting a directive the
112
88
  * model does not advertise, one Prisma has no key for at this stage and
113
- * cardinality, or a nested relation write inside a bulk argument (C-818).
89
+ * cardinality, or a nested relation write inside a bulk argument.
114
90
  */
115
91
  export declare function translateMutationData(input: MutationTranslation, dependencies: PrismaMutationDependencies): PrismaMutationData;