@aventara/core 0.1.0-pilot.3 → 1.0.0-rc.0

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 (167) hide show
  1. package/CHANGELOG.md +338 -0
  2. package/README.md +100 -3
  3. package/dist/adapters/adapter-discovery-diagnostic.d.ts +2 -0
  4. package/dist/adapters/adapter-field.d.ts +3 -26
  5. package/dist/adapters/adapter-identifier.d.ts +1 -11
  6. package/dist/adapters/adapter-model.d.ts +12 -0
  7. package/dist/adapters/adapter-operation-executor.interface.d.ts +5 -1
  8. package/dist/adapters/adapter-resource.d.ts +7 -28
  9. package/dist/adapters/adapter.interface.d.ts +25 -26
  10. package/dist/compiler/contract-compiler-diagnostic.d.ts +8 -0
  11. package/dist/compiler/contract.compiler.d.ts +11 -22
  12. package/dist/compiler/contract.compiler.js +67 -0
  13. package/dist/config/any-framework-config.d.ts +5 -26
  14. package/dist/config/config-diagnostic.d.ts +2 -0
  15. package/dist/config/config-layer.d.ts +6 -19
  16. package/dist/config/config.resolver.d.ts +9 -14
  17. package/dist/config/config.resolver.js +1 -0
  18. package/dist/config/config.validator.d.ts +6 -3
  19. package/dist/config/config.validator.js +6 -0
  20. package/dist/config/define-fields.d.ts +15 -48
  21. package/dist/config/effective-fields.d.ts +6 -29
  22. package/dist/config/entrypoint.normalizer.d.ts +6 -18
  23. package/dist/config/framework-behaviors-config.d.ts +11 -10
  24. package/dist/config/framework-config.d.ts +19 -16
  25. package/dist/config/framework-fields-config.d.ts +20 -7
  26. package/dist/config/framework-restrictions-config.d.ts +41 -61
  27. package/dist/config/pipeline-config.d.ts +7 -17
  28. package/dist/contracts/capability.d.ts +13 -49
  29. package/dist/contracts/client-contract-structure.validator.d.ts +28 -54
  30. package/dist/contracts/client-contract-structure.validator.js +99 -2
  31. package/dist/contracts/contract-canonicalizer.d.ts +4 -6
  32. package/dist/contracts/contract-canonicalizer.js +32 -0
  33. package/dist/contracts/contract-hash.d.ts +3 -2
  34. package/dist/contracts/contract-limits.d.ts +7 -1
  35. package/dist/contracts/contract-protocol.d.ts +7 -8
  36. package/dist/contracts/contract.d.ts +20 -4
  37. package/dist/contracts/enum-definition.d.ts +2 -0
  38. package/dist/contracts/field.d.ts +40 -167
  39. package/dist/contracts/identifier.d.ts +1 -16
  40. package/dist/contracts/json-shape.d.ts +65 -0
  41. package/dist/contracts/json-shape.js +1 -0
  42. package/dist/contracts/lifecycle-trait.d.ts +4 -3
  43. package/dist/contracts/reference-write-limit.d.ts +7 -0
  44. package/dist/contracts/reference-write-limit.js +1 -0
  45. package/dist/contracts/resource-operations.d.ts +2 -62
  46. package/dist/contracts/resource.d.ts +2 -0
  47. package/dist/contracts/scalar-value-type.d.ts +28 -48
  48. package/dist/contracts/scalar.d.ts +4 -3
  49. package/dist/contracts/transaction-capability.d.ts +2 -0
  50. package/dist/contracts/wire-scalar-format.d.ts +6 -21
  51. package/dist/framework/contract-view.d.ts +152 -130
  52. package/dist/framework/framework-construction.error.d.ts +6 -1
  53. package/dist/framework/framework.d.ts +33 -46
  54. package/dist/framework/framework.factory.d.ts +3 -17
  55. package/dist/framework/framework.factory.js +56 -13
  56. package/dist/framework/operation-facade.d.ts +3 -7
  57. package/dist/index.d.ts +8 -40
  58. package/dist/index.js +0 -20
  59. package/dist/internal.d.ts +35 -0
  60. package/dist/internal.js +16 -0
  61. package/dist/json/avz.d.ts +96 -0
  62. package/dist/json/avz.js +212 -0
  63. package/dist/json/index.d.ts +6 -0
  64. package/dist/json/index.js +1 -0
  65. package/dist/json/json-shape.registry.d.ts +22 -0
  66. package/dist/json/json-shape.registry.js +16 -0
  67. package/dist/json/zod-issue.translator.d.ts +51 -0
  68. package/dist/json/zod-issue.translator.js +142 -0
  69. package/dist/operations/operation-arguments.d.ts +198 -303
  70. package/dist/operations/operation-call.d.ts +13 -15
  71. package/dist/operations/operation-identity.d.ts +6 -2
  72. package/dist/operations/operation-identity.js +3 -0
  73. package/dist/operations/operation-result.d.ts +15 -61
  74. package/dist/operations/operation-validator-core.d.ts +6 -5
  75. package/dist/operations/operation-validator-core.js +28 -10
  76. package/dist/operations/operation-validator.d.ts +22 -9
  77. package/dist/operations/operation-validator.js +26 -10
  78. package/dist/operations/projection-scope.resolver.d.ts +1 -11
  79. package/dist/operations/structural-limits.walker.d.ts +19 -0
  80. package/dist/operations/structural-limits.walker.js +344 -0
  81. package/dist/operations/validation-code.d.ts +5 -17
  82. package/dist/operations/write-scope.resolver.d.ts +3 -28
  83. package/dist/protocol/absent-route.responder.d.ts +25 -39
  84. package/dist/protocol/absent-route.responder.js +32 -6
  85. package/dist/protocol/av-protocol.d.ts +2 -8
  86. package/dist/protocol/contract-document.responder.d.ts +5 -18
  87. package/dist/protocol/http-request.decoder.d.ts +18 -59
  88. package/dist/protocol/http-request.decoder.js +11 -3
  89. package/dist/protocol/http-request.reader.d.ts +5 -5
  90. package/dist/protocol/http-response.encoder.d.ts +14 -20
  91. package/dist/protocol/http-status.table.d.ts +0 -8
  92. package/dist/protocol/index.d.ts +2 -7
  93. package/dist/protocol/operation-response.guard.d.ts +0 -15
  94. package/dist/protocol/protocol-failure.d.ts +8 -27
  95. package/dist/protocol/protocol-headers.d.ts +15 -42
  96. package/dist/protocol/protocol-surface.d.ts +0 -22
  97. package/dist/protocol/protocol.binder.d.ts +19 -27
  98. package/dist/protocol/protocol.binder.js +3 -1
  99. package/dist/protocol/protocol.handler.d.ts +19 -23
  100. package/dist/protocol/protocol.handler.js +14 -4
  101. package/dist/protocol/unmounted-route.error.d.ts +19 -0
  102. package/dist/protocol/unmounted-route.error.js +10 -0
  103. package/dist/runtime/caller-data.copier.d.ts +59 -0
  104. package/dist/runtime/caller-data.copier.js +470 -0
  105. package/dist/runtime/caller-data.door.d.ts +56 -0
  106. package/dist/runtime/caller-data.door.js +65 -0
  107. package/dist/runtime/computed-read-runtime.js +3 -10
  108. package/dist/runtime/computed-value.error.d.ts +13 -0
  109. package/dist/runtime/computed-value.error.js +9 -0
  110. package/dist/runtime/create-requirement.d.ts +43 -7
  111. package/dist/runtime/create-requirement.js +89 -9
  112. package/dist/runtime/decimal.d.ts +5 -3
  113. package/dist/runtime/diagnostics-reporter.d.ts +33 -37
  114. package/dist/runtime/diagnostics-reporter.js +11 -4
  115. package/dist/runtime/error-boundary.d.ts +14 -10
  116. package/dist/runtime/error-boundary.js +65 -35
  117. package/dist/runtime/execution-options.d.ts +3 -7
  118. package/dist/runtime/field-behavior.d.ts +14 -21
  119. package/dist/runtime/framework-error.d.ts +14 -2
  120. package/dist/runtime/json-value.d.ts +7 -15
  121. package/dist/runtime/misuse-reporter.d.ts +32 -0
  122. package/dist/runtime/misuse-reporter.js +19 -0
  123. package/dist/runtime/mutation-planner.d.ts +6 -12
  124. package/dist/runtime/mutation-planner.js +13 -11
  125. package/dist/runtime/operation-request.d.ts +11 -11
  126. package/dist/runtime/operation-response.d.ts +18 -23
  127. package/dist/runtime/operation-runtime.d.ts +25 -33
  128. package/dist/runtime/operation-runtime.js +37 -18
  129. package/dist/runtime/outcome-mapper.js +12 -2
  130. package/dist/runtime/output-validator.d.ts +10 -0
  131. package/dist/runtime/output-validator.js +11 -0
  132. package/dist/runtime/owned-execution.registry.d.ts +13 -0
  133. package/dist/runtime/owned-execution.registry.js +7 -0
  134. package/dist/runtime/pipeline.d.ts +33 -36
  135. package/dist/runtime/referential-action.d.ts +8 -26
  136. package/dist/runtime/request-envelope.validator.d.ts +5 -0
  137. package/dist/runtime/request-envelope.validator.js +118 -0
  138. package/dist/runtime/request-id.d.ts +3 -10
  139. package/dist/runtime/scalar-runtime.d.ts +42 -14
  140. package/dist/runtime/scalar-runtime.js +162 -79
  141. package/dist/transactions/deferred-operation.d.ts +10 -21
  142. package/dist/transactions/operation-arguments-encoder.d.ts +1 -0
  143. package/dist/transactions/operation-fingerprint.d.ts +3 -1
  144. package/dist/transactions/transaction-envelope.d.ts +2 -4
  145. package/dist/transactions/transaction-integrity-error.d.ts +4 -15
  146. package/dist/transactions/transaction-plan-assembler.d.ts +6 -1
  147. package/dist/transactions/transaction-plan-assembler.js +74 -75
  148. package/dist/transactions/transaction-plan-validator.d.ts +33 -24
  149. package/dist/transactions/transaction-plan-validator.js +204 -153
  150. package/dist/transactions/transaction-reference-collector.d.ts +30 -0
  151. package/dist/transactions/transaction-reference-collector.js +204 -0
  152. package/dist/transactions/transaction-reference-resolver.d.ts +9 -12
  153. package/dist/transactions/transaction-reference-resolver.js +10 -5
  154. package/dist/transactions/transaction-reference-validator.js +24 -17
  155. package/dist/transactions/transaction-reference.d.ts +31 -64
  156. package/dist/transactions/transaction-request.d.ts +6 -8
  157. package/dist/transactions/transaction-response.d.ts +10 -7
  158. package/dist/transactions/transaction-response.js +24 -1
  159. package/dist/transactions/transaction-runtime.d.ts +7 -5
  160. package/dist/transactions/transaction-runtime.js +4 -3
  161. package/dist/transactions/transaction-slot-path-error.d.ts +5 -15
  162. package/dist/transactions/transaction-slot-writer.d.ts +3 -13
  163. package/package.json +17 -3
  164. package/dist/operations/operation-boolean-nodes.d.ts +0 -11
  165. package/dist/operations/operation-boolean-nodes.js +0 -283
  166. package/dist/operations/operation-nesting.d.ts +0 -8
  167. package/dist/operations/operation-nesting.js +0 -307
@@ -1,10 +1,13 @@
1
1
  import type { ProjectionScope, RelationMutationDirective, ScalarFilterOperator, ScalarMutationDirective, WriteScope } from "../contracts/capability.js";
2
2
  import type { Contract } from "../contracts/contract.js";
3
3
  import type { ProjectionScopes, ScalarField } from "../contracts/field.js";
4
- import type { ScalarAtom, ScalarForms, ScalarValueType } from "../contracts/scalar-value-type.js";
4
+ import type { FieldAtom, ScalarForms, ScalarValueType } from "../contracts/scalar-value-type.js";
5
5
  import type { JsonValue } from "../runtime/json-value.js";
6
+ import type { TransactionReference, TransactionSlotShape } from "../transactions/transaction-reference.js";
6
7
  import type { OperationIdentity } from "./operation-identity.js";
8
+ /** The Resource names of Contract `C`. */
7
9
  export type ResourceKey<C extends Contract> = Extract<keyof C["resources"], string>;
10
+ /** The field names of Resource `K` in Contract `C`. */
8
11
  export type FieldKey<C extends Contract, K extends ResourceKey<C>> = Extract<keyof C["resources"][K]["fields"], string>;
9
12
  type FieldAt<C extends Contract, K extends ResourceKey<C>, F extends FieldKey<C, K>> = C["resources"][K]["fields"][F];
10
13
  type ScalarFieldAt<C extends Contract, K extends ResourceKey<C>, F extends FieldKey<C, K>> = Extract<FieldAt<C, K, F>, {
@@ -22,49 +25,15 @@ type RelationFieldKeyOf<C extends Contract, K extends ResourceKey<C>> = {
22
25
  type CapabilitiesOf<C extends Contract, K extends ResourceKey<C>, F extends FieldKey<C, K>> = FieldAt<C, K, F> extends {
23
26
  readonly capabilities: infer Capabilities;
24
27
  } ? Capabilities : never;
25
- /**
26
- * The argument scope a reader with no scope to thread reads a projection
27
- * capability at.
28
- *
29
- * `filter`, `order`, `orderNulls` and `pagination` were measured uniform across
30
- * every operation variant, so their readers have no scope to be given; and every
31
- * variant that carries a filter, an order, a cursor or a pagination argument
32
- * carries it in the unrestricted position — the bulk cells carry none of them.
33
- * Named rather than inlined so that a member which stops being uniform is found
34
- * by grepping one word instead of auditing `"record"` string literals.
35
- */
28
+ /** The projection position read when no position applies: `"record"`. */
36
29
  type UnrestrictedProjection = "record";
37
- /**
38
- * The write mirror of {@link UnrestrictedProjection}, and the default for the
39
- * public write surfaces: a write argument reached through a relation is the
40
- * unrestricted position, because a scope qualifies the TOP LEVEL of an argument
41
- * only and does not narrow recursively (see {@link WriteScope}).
42
- */
30
+ /** The write position read when no position applies, and the one nested writes use: `"nested"`. */
43
31
  type UnrestrictedWrite = "nested";
44
- /**
45
- * Whether a capability member's answer holds at one argument scope.
46
- *
47
- * The qualified arms state where they hold: a scope list on `select`/`include`,
48
- * a `scopes` member beside the tokens on `reducers`, `create` and `update`. The
49
- * unqualified arms state no scope and therefore hold in every one of them —
50
- * which is what keeps a Contract written before the axis existed meaning exactly
51
- * what it meant, and what lets an adapter that has not measured the axis say so
52
- * without losing a capability.
53
- *
54
- * Presence is deliberately NOT answered here: `false` and an absent member
55
- * arrive as unqualified values and would be reported as holding.
56
- * {@link HasCapability} owns the presence question and asks this one second.
57
- */
32
+ /** Whether a capability member's answer holds at one argument scope. */
58
33
  type HoldsAtScope<Value, Scope extends ProjectionScope | WriteScope> = Value extends {
59
34
  readonly scopes: readonly (infer Stated)[];
60
35
  } ? Scope extends Stated ? true : false : Value extends ProjectionScopes ? Scope extends Value[number] ? true : false : true;
61
- /**
62
- * The tokens a capability member advertises, whichever arm it is written in — the
63
- * type-level mirror of `advertisedDirectives` and `advertisedReducers`, and
64
- * scope-blind for the same reason they are: reading the tokens and deciding where
65
- * they hold are two questions, and a reader handed both in one answer answers the
66
- * second by forgetting it. {@link CapabilityTokens} asks both.
67
- */
36
+ /** The tokens a capability member advertises, in any argument position. */
68
37
  type AdvertisedTokens<Value> = Value extends {
69
38
  readonly scopes: readonly WriteScope[];
70
39
  readonly directives: readonly (infer Directive)[];
@@ -93,127 +62,129 @@ type KeysWithCapability<C extends Contract, K extends ResourceKey<C>, Keys exten
93
62
  [F in Keys]: HasCapability<C, K, F, Capability, Scope> extends true ? F : never;
94
63
  }[Keys];
95
64
  /**
96
- * The scalar-form map an argument surface reads its scalar VALUES through when
97
- * the caller names no side of a boundary: every built-in form `unknown`.
98
- *
99
- * It is `ScalarForms` itself — the constraint every map satisfies — so it tells a
100
- * reader nothing about a built-in value, which is the surface every caller had
101
- * before values were typed. An authoring mirror shared by both request origins (a
102
- * transaction plan, a hand-written request) cannot know whether its `Date`
103
- * travels as a `Date` or as an ISO string; a caller that does know passes
104
- * `ApplicationScalarForms` or `WireScalarForms` and is held to it.
105
- *
106
- * Enum members are not a form: they are the same strings on both sides, so an
107
- * enum-backed value is its member union under every map, this one included.
65
+ * The scalar-form map used when no side of a boundary is named: every built-in
66
+ * value is `unknown`. Pass `ApplicationScalarForms` or `WireScalarForms` to type
67
+ * values. Enum values are their member union under every map.
108
68
  */
109
69
  type UnstatedForms = ScalarForms;
110
- /**
111
- * Field `F`'s value under `Forms`: the one derivation a result reads
112
- * (`ScalarValueType`), read here for arguments, so an argument and a result
113
- * cannot disagree about what a field's value is.
114
- */
70
+ /** Field `F`'s value under `Forms`, the same as in results. */
115
71
  type ScalarValueAt<C extends Contract, K extends ResourceKey<C>, F extends FieldKey<C, K>, Forms extends ScalarForms> = ScalarFieldAt<C, K, F> extends infer Field extends ScalarField<C> ? ScalarValueType<C, Field, Forms> : never;
116
72
  /** One entry of field `F`'s value — the whole value when `F` is not a list. */
117
- type ScalarAtomAt<C extends Contract, K extends ResourceKey<C>, F extends FieldKey<C, K>, Forms extends ScalarForms> = ScalarAtom<C, ScalarFieldAt<C, K, F>["type"], Forms>;
73
+ type ScalarAtomAt<C extends Contract, K extends ResourceKey<C>, F extends FieldKey<C, K>, Forms extends ScalarForms> = FieldAtom<C, ScalarFieldAt<C, K, F>, Forms>;
74
+ /**
75
+ * A `$ref` to a source whose value fits slot shape `Shape` of field `F`, typed in
76
+ * `ReferenceForms` — the forms a source's final data is read in. `never` when
77
+ * `ReferenceForms` is `never`: no position takes one outside a transaction plan.
78
+ */
79
+ type SlotReference<C extends Contract, K extends ResourceKey<C>, F extends FieldKey<C, K>, ReferenceForms extends ScalarForms, Shape extends TransactionSlotShape> = [ReferenceForms] extends [never] ? never : TransactionReference<Shape extends "value" ? ScalarValueAt<C, K, F, ReferenceForms> : Shape extends "nonNullValue" ? Exclude<ScalarValueAt<C, K, F, ReferenceForms>, null> : Shape extends "entry" ? ScalarAtomAt<C, K, F, ReferenceForms> : readonly ScalarAtomAt<C, K, F, ReferenceForms>[]>;
118
80
  /**
119
- * A JSON object: the value the runtime reads as an argument OBJECT rather than as
120
- * a value wherever a position admits both (`runtime/scalar-runtime.ts`
121
- * `isPlainRecord`), so those positions' value arms leave it out.
81
+ * A JSON object. Positions that accept both a value and an object of operators
82
+ * read a JSON object as the operators, so their value forms leave it out.
122
83
  */
123
84
  type JsonObject = Extract<JsonValue, {
124
85
  readonly [key: string]: JsonValue;
125
86
  }>;
126
87
  /**
127
- * The field-independent shape of one scalar filter: any value, or an object of
128
- * the operator vocabulary. `WhereInput` no longer reads it — it types each
129
- * field's operands through a scalar-form map (see `ScalarFilterFor`) — and it
130
- * stays exported as the vocabulary's own shape for a caller that holds no
131
- * Contract.
88
+ * The field-independent shape of one scalar filter: any value, or an object of the
89
+ * operator vocabulary.
132
90
  */
133
91
  export type ScalarFilterInput = unknown | Readonly<Partial<Record<ScalarFilterOperator, unknown>>>;
134
92
  /**
135
93
  * A scalar filter's shorthand equality value: the field's value, minus a JSON
136
94
  * object.
137
- *
138
- * Every reader of a filter position — the validation layer, the scalar runtime and
139
- * the adapter — reads it through one discriminant (`runtime/scalar-runtime.ts`
140
- * `isPlainRecord`): a plain record is an operator object, anything else is a
141
- * value. So a `Date`, a `Decimal` and a `Uint8Array` are shorthand for their
142
- * field, and a JSON object is an operator object by construction — `{ equals:
143
- * document }` carries it. The same exclusion as `not`'s value arm below.
144
95
  */
145
96
  type ScalarFilterShorthand<Value> = Exclude<Value, JsonObject>;
146
97
  /**
147
- * A scalar filter's operator object, each operand read the way
148
- * `normalizeScalarFilter` reads it: a comparison operand is the field's whole
149
- * value; `in`, `notIn`, `hasEvery` and `hasSome` a list of entries; `has` one
150
- * entry; a `json` field's `string*`/`array*` operand a {@link JsonValue}; `not` a
151
- * value or a nested operator object. `mode`, `isEmpty` and `path` reach the
152
- * adapter un-normalized, so core states nothing about them.
153
- *
154
- * Which operators a field advertises stays the validation layer's question
155
- * (`V1006`), exactly as before values were typed: this answers only what each
156
- * operand is.
98
+ * The `$ref` each slot shape of field `F` takes, by shape: every member `never`
99
+ * outside a transaction plan.
100
+ */
101
+ type FieldSlotReferences<C extends Contract, K extends ResourceKey<C>, F extends FieldKey<C, K>, ReferenceForms extends ScalarForms> = {
102
+ readonly [Shape in TransactionSlotShape]: SlotReference<C, K, F, ReferenceForms, Shape>;
103
+ };
104
+ /**
105
+ * A scalar filter's operator object: a comparison operand is the field's whole
106
+ * value; `in`, `notIn`, `hasEvery` and `hasSome` take a list of entries; `has`
107
+ * one entry; a `json` field's `string*`/`array*` operand a {@link JsonValue};
108
+ * `not` a value or a nested operator object. `mode`, `isEmpty` and `path` are
109
+ * passed to the adapter as given. Only `equals`, `not` and the `json` `array*`
110
+ * operands take `null`. Inside a transaction plan every operand but `mode`,
111
+ * `isEmpty`, `path` and the `json` ones may be a `$ref` of the shape it holds
112
+ * (`References`).
157
113
  */
158
- type ScalarFilterOperators<Value, Atom, Json> = Readonly<{
159
- equals?: Value;
160
- not?: Exclude<Value, JsonObject> | ScalarFilterOperators<Value, Atom, Json>;
161
- in?: readonly Atom[];
162
- notIn?: readonly Atom[];
163
- lt?: Value;
164
- lte?: Value;
165
- gt?: Value;
166
- gte?: Value;
167
- contains?: Value;
168
- startsWith?: Value;
169
- endsWith?: Value;
114
+ type ScalarFilterOperators<Value, Atom, Json, References extends Readonly<Record<TransactionSlotShape, unknown>>> = Readonly<{
115
+ equals?: Value | References["value"];
116
+ not?: Exclude<Value, JsonObject> | References["value"] | ScalarFilterOperators<Value, Atom, Json, References>;
117
+ in?: readonly Atom[] | References["entries"];
118
+ notIn?: readonly Atom[] | References["entries"];
119
+ lt?: Exclude<Value, null> | References["nonNullValue"];
120
+ lte?: Exclude<Value, null> | References["nonNullValue"];
121
+ gt?: Exclude<Value, null> | References["nonNullValue"];
122
+ gte?: Exclude<Value, null> | References["nonNullValue"];
123
+ contains?: Exclude<Value, null> | References["nonNullValue"];
124
+ startsWith?: Exclude<Value, null> | References["nonNullValue"];
125
+ endsWith?: Exclude<Value, null> | References["nonNullValue"];
170
126
  mode?: unknown;
171
- has?: Atom;
172
- hasEvery?: readonly Atom[];
173
- hasSome?: readonly Atom[];
127
+ has?: Atom | References["entry"];
128
+ hasEvery?: readonly Atom[] | References["entries"];
129
+ hasSome?: readonly Atom[] | References["entries"];
174
130
  isEmpty?: unknown;
175
131
  path?: unknown;
176
- stringContains?: Json;
177
- stringStartsWith?: Json;
178
- stringEndsWith?: Json;
132
+ stringContains?: Exclude<Json, null>;
133
+ stringStartsWith?: Exclude<Json, null>;
134
+ stringEndsWith?: Exclude<Json, null>;
179
135
  arrayContains?: Json;
180
136
  arrayStartsWith?: Json;
181
137
  arrayEndsWith?: Json;
182
138
  }>;
183
- /** One scalar field's filter under `Forms`: a shorthand value or an operator object. */
184
- type ScalarFilterFor<C extends Contract, K extends ResourceKey<C>, F extends FieldKey<C, K>, Forms extends ScalarForms> = ScalarFilterShorthand<ScalarValueAt<C, K, F, Forms>> | ScalarFilterOperators<ScalarValueAt<C, K, F, Forms>, ScalarAtomAt<C, K, F, Forms>, ScalarFieldAt<C, K, F>["type"] extends {
139
+ /**
140
+ * One scalar field's filter under `Forms`: a shorthand value or an operator object.
141
+ * Inside a transaction plan the value and every operand that holds a field value may
142
+ * be a `$ref` (see {@link TransactionSlotShape}): equality to a source nullable only
143
+ * where the field is, a comparison to a non-null source, `in` and the list operators
144
+ * to a list source, `has` to one entry.
145
+ */
146
+ type ScalarFilterFor<C extends Contract, K extends ResourceKey<C>, F extends FieldKey<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = ScalarFilterShorthand<ScalarValueAt<C, K, F, Forms>> | SlotReference<C, K, F, ReferenceForms, "value"> | ScalarFilterOperators<ScalarValueAt<C, K, F, Forms>, ScalarAtomAt<C, K, F, Forms>, ScalarFieldAt<C, K, F>["type"] extends {
185
147
  readonly scalar: "json";
186
- } ? JsonValue : ScalarValueAt<C, K, F, Forms>>;
148
+ } ? JsonValue : ScalarValueAt<C, K, F, Forms>, FieldSlotReferences<C, K, F, ReferenceForms>>;
187
149
  type ScalarFilterableKey<C extends Contract, K extends ResourceKey<C>> = KeysWithCapability<C, K, ScalarFieldKeyOf<C, K>, "filter", UnrestrictedProjection>;
188
150
  type RelationParentFilterKey<C extends Contract, K extends ResourceKey<C>> = {
189
151
  [F in RelationFieldKeyOf<C, K>]: RelationCardinality<C, K, F> extends "one" ? HasCapabilityToken<C, K, F, "filter", UnrestrictedProjection, "match"> extends true ? F : HasCapabilityToken<C, K, F, "filter", UnrestrictedProjection, "null"> extends true ? F : never : Extract<CapabilityTokens<C, K, F, "filter", UnrestrictedProjection>, "some" | "every" | "none"> extends never ? never : F;
190
152
  }[RelationFieldKeyOf<C, K>];
191
- type ToManyRelationWhereInput<C extends Contract, K extends ResourceKey<C>, F extends RelationParentFilterKey<C, K> & RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = Readonly<Partial<Record<Extract<CapabilityTokens<C, K, F, "filter", UnrestrictedProjection>, "some" | "every" | "none">, WhereInput<C, RelationTarget<C, K, F>, Forms>>>>;
192
- type RelationWhereInput<C extends Contract, K extends ResourceKey<C>, F extends RelationParentFilterKey<C, K> & RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = RelationCardinality<C, K, F> extends "one" ? (HasCapabilityToken<C, K, F, "filter", UnrestrictedProjection, "match"> extends true ? WhereInput<C, RelationTarget<C, K, F>, Forms> : never) | (RelationNullable<C, K, F> extends true ? HasCapabilityToken<C, K, F, "filter", UnrestrictedProjection, "null"> extends true ? null : never : never) : ToManyRelationWhereInput<C, K, F, Forms>;
193
- type ScalarWhereFields<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms> = Readonly<{
194
- [F in ScalarFilterableKey<C, K>]?: ScalarFilterFor<C, K, F, Forms>;
153
+ type ToManyRelationWhereInput<C extends Contract, K extends ResourceKey<C>, F extends RelationParentFilterKey<C, K> & RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<Partial<Record<Extract<CapabilityTokens<C, K, F, "filter", UnrestrictedProjection>, "some" | "every" | "none">, WhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>>>>;
154
+ type RelationWhereInput<C extends Contract, K extends ResourceKey<C>, F extends RelationParentFilterKey<C, K> & RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = RelationCardinality<C, K, F> extends "one" ? (HasCapabilityToken<C, K, F, "filter", UnrestrictedProjection, "match"> extends true ? WhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms> : never) | (RelationNullable<C, K, F> extends true ? HasCapabilityToken<C, K, F, "filter", UnrestrictedProjection, "null"> extends true ? null : never : never) : ToManyRelationWhereInput<C, K, F, Forms, ReferenceForms>;
155
+ type ScalarWhereFields<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
156
+ [F in ScalarFilterableKey<C, K>]?: ScalarFilterFor<C, K, F, Forms, ReferenceForms>;
195
157
  }>;
196
- type RelationWhereFields<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms> = Readonly<{
197
- [F in RelationParentFilterKey<C, K>]?: RelationWhereInput<C, K, F & RelationFieldKeyOf<C, K>, Forms>;
158
+ type RelationWhereFields<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
159
+ [F in RelationParentFilterKey<C, K>]?: RelationWhereInput<C, K, F & RelationFieldKeyOf<C, K>, Forms, ReferenceForms>;
198
160
  }>;
199
161
  /**
200
162
  * A `where` argument. `Forms` is the scalar-form map its scalar values are read
201
- * through; see {@link UnstatedForms} for the default.
163
+ * through; see {@link UnstatedForms} for the default. `ReferenceForms` opens a
164
+ * transaction step's own `where` to `$ref`s, at every depth of it.
202
165
  */
203
- export type WhereInput<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms = UnstatedForms> = Readonly<{
204
- AND?: readonly WhereInput<C, K, Forms>[];
205
- OR?: readonly WhereInput<C, K, Forms>[];
206
- NOT?: WhereInput<C, K, Forms>;
207
- } & ScalarWhereFields<C, K, Forms> & RelationWhereFields<C, K, Forms>>;
166
+ export type WhereInput<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never> = Readonly<{
167
+ AND?: readonly WhereInput<C, K, Forms, ReferenceForms>[];
168
+ OR?: readonly WhereInput<C, K, Forms, ReferenceForms>[];
169
+ NOT?: WhereInput<C, K, Forms, ReferenceForms>;
170
+ } & ScalarWhereFields<C, K, Forms, ReferenceForms> & RelationWhereFields<C, K, Forms, ReferenceForms>>;
208
171
  type ActiveIdentifier<C extends Contract, K extends ResourceKey<C>> = C["resources"][K]["identifiers"][number];
209
- type IdentifierObject<C extends Contract, K extends ResourceKey<C>, I extends readonly string[], Forms extends ScalarForms> = Readonly<{
210
- [F in Extract<I[number], FieldKey<C, K>>]: ScalarValueAt<C, K, F, Forms>;
172
+ type IdentifierObject<C extends Contract, K extends ResourceKey<C>, I extends readonly string[], Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
173
+ [F in Extract<I[number], FieldKey<C, K>>]: ScalarValueAt<C, K, F, Forms> | SlotReference<C, K, F, ReferenceForms, "nonNullValue">;
211
174
  } & {
212
175
  [F in Exclude<FieldKey<C, K>, I[number]>]?: never;
213
176
  }>;
214
- export type UniqueWhereInput<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms = UnstatedForms> = ActiveIdentifier<C, K> extends infer I ? I extends readonly string[] ? IdentifierObject<C, K, I, Forms> : never : never;
177
+ /**
178
+ * A `where` argument for a unique operation: the values of one identifier. Inside a
179
+ * transaction plan (`ReferenceForms` stated) each value may be a `$ref` to a non-null
180
+ * source of the same type.
181
+ */
182
+ export type UniqueWhereInput<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never> = ActiveIdentifier<C, K> extends infer I ? I extends readonly string[] ? IdentifierObject<C, K, I, Forms, ReferenceForms> : never : never;
183
+ /** `"asc"` or `"desc"`. */
215
184
  export type SortDirection = "asc" | "desc";
185
+ /** Where `null`s sort: `"first"` or `"last"`. */
216
186
  export type NullsOrder = "first" | "last";
187
+ /** How one scalar field sorts: a direction, or a direction and a `nulls` order. */
217
188
  export type ScalarOrderInput = SortDirection | Readonly<{
218
189
  sort: SortDirection;
219
190
  nulls: NullsOrder;
@@ -223,40 +194,15 @@ type OrderableRelationKey<C extends Contract, K extends ResourceKey<C>> = KeysWi
223
194
  type OrderableFieldKey<C extends Contract, K extends ResourceKey<C>> = OrderableScalarKey<C, K> | OrderableRelationKey<C, K>;
224
195
  type ScalarOrderForField<C extends Contract, K extends ResourceKey<C>, F extends OrderableScalarKey<C, K>> = ScalarFieldAt<C, K, F>["nullable"] extends true ? HasCapability<C, K, F, "orderNulls", UnrestrictedProjection> extends true ? ScalarOrderInput : SortDirection : SortDirection;
225
196
  /**
226
- * An `orderBy` reducer is not a PROJECTION position, so the projection scopes
227
- * beside the reducer list do not qualify it; and every variant that carries an
228
- * `orderBy` argument carries it in the unrestricted position, which is why this
229
- * reader does not thread a scope.
230
- *
231
- * A to-one value is **one** target entry, not an {@link OrderByInput}: the
232
- * runtime refuses a precedence list there (`validateOrderBy` requires a record
233
- * at a relation position, V1001), so admitting one would advertise what the
234
- * validation layer refuses.
197
+ * The `orderBy` value of a relation field: a to-many relation orders by
198
+ * `$count`; a to-one relation takes one entry of the related Resource's
199
+ * `orderBy`, not a list.
235
200
  */
236
201
  type RelationOrderForField<C extends Contract, K extends ResourceKey<C>, F extends OrderableRelationKey<C, K> & RelationFieldKeyOf<C, K>> = RelationCardinality<C, K, F> extends "many" ? HasCapabilityToken<C, K, F, "reducers", UnrestrictedProjection, "$count"> extends true ? Readonly<{
237
202
  $count: SortDirection;
238
203
  }> : never : OrderByEntry<C, RelationTarget<C, K, F>>;
239
204
  type OrderValue<C extends Contract, K extends ResourceKey<C>, F extends OrderableFieldKey<C, K>> = F extends OrderableScalarKey<C, K> ? ScalarOrderForField<C, K, F> : F extends OrderableRelationKey<C, K> & RelationFieldKeyOf<C, K> ? RelationOrderForField<C, K, F> : never;
240
- /**
241
- * One `orderBy` precedence entry: exactly one orderable field and its value.
242
- *
243
- * A to-one relation's value is the target's entry, so a self-relation
244
- * (`Author.mentor → Author`) or a one-to-one pair makes this type recursive. A
245
- * type argument is instantiated eagerly, so resolving `OrderByEntry<C, "Author">`
246
- * needed `OrderValue<…, "mentor">`, which IS `OrderByEntry<C, "Author">`: TS2615,
247
- * after which the entry degraded to `any` and refused nothing. A mapped property
248
- * is resolved only when read, by which time the entry it recurses into exists. The
249
- * projection walk never hit this because its recursion already sits behind an
250
- * object property (`{ select?: … }`).
251
- *
252
- * **No type-level depth cap, deliberately.** The runtime bound is the Contract's
253
- * `limits.maxNestingDepth` — each to-one hop counts one level, and one past it is
254
- * V1013 (`operation-nesting.ts` `walkOrderBy`). That limit is a `number` in the
255
- * Contract, resolved per scope at construction, so no literal exists for a type to
256
- * count against; a fixed cap would refuse what a Contract with a larger limit
257
- * accepts. `where` and `select` recurse uncapped for the same reason, and the
258
- * validation layer refuses past the limit for all three.
259
- */
205
+ /** One `orderBy` precedence entry: exactly one orderable field and its value. */
260
206
  export type OrderByEntry<C extends Contract, K extends ResourceKey<C>> = {
261
207
  [F in OrderableFieldKey<C, K>]: {
262
208
  readonly [Only in F]: OrderValue<C, K, Only>;
@@ -264,15 +210,16 @@ export type OrderByEntry<C extends Contract, K extends ResourceKey<C>> = {
264
210
  readonly [Other in Exclude<OrderableFieldKey<C, K>, F>]?: never;
265
211
  };
266
212
  }[OrderableFieldKey<C, K>];
213
+ /** An `orderBy` argument: one entry, or a list in order of precedence. */
267
214
  export type OrderByInput<C extends Contract, K extends ResourceKey<C>> = OrderByEntry<C, K> | readonly OrderByEntry<C, K>[];
268
- export type CursorInput<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms = UnstatedForms> = Readonly<{
269
- [F in ScalarFieldKeyOf<C, K>]?: ScalarValueAt<C, K, F, Forms>;
270
- }>;
271
215
  /**
272
- * Scalar `select` carries no scope qualifier — the six scalar members were
273
- * measured uniform — so the scope reaches this reader only to keep one projection
274
- * walk asking one question.
216
+ * A `cursor` argument: scalar field values of the row the page starts from. Inside
217
+ * a transaction plan each may be a `$ref` to a non-null source of the same type.
275
218
  */
219
+ export type CursorInput<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never> = Readonly<{
220
+ [F in ScalarFieldKeyOf<C, K>]?: ScalarValueAt<C, K, F, Forms> | SlotReference<C, K, F, ReferenceForms, "nonNullValue">;
221
+ }>;
222
+ /** The scalar fields selectable at one projection position. */
276
223
  type SelectableScalarKey<C extends Contract, K extends ResourceKey<C>, Scope extends ProjectionScope> = KeysWithCapability<C, K, ScalarFieldKeyOf<C, K>, "select", Scope>;
277
224
  type SelectableRelationKey<C extends Contract, K extends ResourceKey<C>, Scope extends ProjectionScope> = KeysWithCapability<C, K, RelationFieldKeyOf<C, K>, "select", Scope>;
278
225
  type IncludeRelationKey<C extends Contract, K extends ResourceKey<C>, Scope extends ProjectionScope> = KeysWithCapability<C, K, RelationFieldKeyOf<C, K>, "include", Scope>;
@@ -307,28 +254,14 @@ type ProjectionChoice<C extends Contract, K extends ResourceKey<C>, Scope extend
307
254
  select?: never;
308
255
  }>;
309
256
  /**
310
- * The argument object one relation entry carries inside a projection.
311
- *
312
- * `Scope` is the scope of the projection this entry sits in. It qualifies the
313
- * entry's own reducer question and nothing deeper: the target's projection is
314
- * taken at {@link UnrestrictedProjection}, because a scope qualifies the top
315
- * level of a projection only and the measurement is explicit that the full
316
- * surface returns one level in (see {@link ProjectionScope}). A reader who
317
- * narrowed it recursively would refuse what the ORM accepts.
257
+ * The argument object one relation entry carries inside a projection. `Scope`
258
+ * applies to this entry only; the related rows' own projection is
259
+ * unrestricted.
318
260
  */
319
261
  export type RelationProjectionInput<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K> = RelationFieldKeyOf<C, K>, Scope extends ProjectionScope = UnrestrictedProjection, Forms extends ScalarForms = UnstatedForms> = F extends RelationFieldKeyOf<C, K> ? Readonly<NestedWhereArgument<C, K, F, Forms> & NestedOrderArgument<C, K, F> & NestedPaginationArgument<C, K, F, "limit", Forms> & NestedPaginationArgument<C, K, F, "offset", Forms> & NestedPaginationArgument<C, K, F, "cursor", Forms> & ProjectionChoice<C, RelationTarget<C, K, F>, UnrestrictedProjection, RelationAllowsCount<C, K, F, Scope>, Forms>> : never;
320
262
  /**
321
263
  * One relation entry of a projection: exactly relation `F` of `Keys`, with its
322
264
  * argument object, and every other key of `Keys` absent.
323
- *
324
- * A projection's entry union is formed whenever its `select`/`include` constraint
325
- * is — at every call, including one that passes no projection — and a type
326
- * argument is instantiated when the union is: every relation's {@link
327
- * RelationProjectionInput} (its nested `where`, `orderBy`, pagination and
328
- * projection choice) for every relation the Resource has. A mapped property is
329
- * resolved only when an entry names it, so a call pays for the relations it
330
- * projects. Measured on the six-resource artifact shape: ≈4,500–6,700
331
- * instantiations per call whose projection names no relation.
332
265
  */
333
266
  type RelationProjectionEntry<C extends Contract, K extends ResourceKey<C>, Keys extends RelationFieldKeyOf<C, K>, F extends Keys, Scope extends ProjectionScope, Forms extends ScalarForms> = {
334
267
  readonly [Only in F]: RelationProjectionInput<C, K, Only & RelationFieldKeyOf<C, K>, Scope, Forms>;
@@ -342,93 +275,92 @@ type IncludeRelationProjectionEntry<C extends Contract, K extends ResourceKey<C>
342
275
  [F in IncludeRelationKey<C, K, Scope>]: RelationProjectionEntry<C, K, IncludeRelationKey<C, K, Scope>, F, Scope, Forms>;
343
276
  }[IncludeRelationKey<C, K, Scope>];
344
277
  /**
345
- * One entry of a `select` argument, at one projection scope.
346
- *
347
- * The scope precedes `AllowCount` because it qualifies which fields exist at
348
- * this position at all, while `AllowCount` only says whether the carrying entry
349
- * admits its parent's reducer. The default is the unrestricted position, so a
350
- * reader that states no scope keeps today's surface exactly.
278
+ * One entry of a `select` argument, at one projection position. The default is
279
+ * the unrestricted position.
351
280
  */
352
281
  export type ProjectionEntry<C extends Contract, K extends ResourceKey<C>, Scope extends ProjectionScope = UnrestrictedProjection, AllowCount extends boolean = false, Forms extends ScalarForms = UnstatedForms> = SelectableScalarKey<C, K, Scope> | SelectableRelationKey<C, K, Scope> | SelectRelationProjectionEntry<C, K, Scope, Forms> | (AllowCount extends true ? "$count" : never);
282
+ /** A `select` argument: the fields to return. */
353
283
  export type SelectInput<C extends Contract, K extends ResourceKey<C>, Scope extends ProjectionScope = UnrestrictedProjection, AllowCount extends boolean = false, Forms extends ScalarForms = UnstatedForms> = readonly ProjectionEntry<C, K, Scope, AllowCount, Forms>[];
284
+ /** An `include` argument: the relations to return with each row. */
354
285
  export type IncludeInput<C extends Contract, K extends ResourceKey<C>, Scope extends ProjectionScope = UnrestrictedProjection, Forms extends ScalarForms = UnstatedForms> = readonly (IncludeRelationKey<C, K, Scope> | IncludeRelationProjectionEntry<C, K, Scope, Forms>)[];
286
+ /** A scalar update directive and its operand, such as `{ $increment: 1 }`. */
355
287
  export type ScalarMutationAction = Readonly<Partial<Record<ScalarMutationDirective, unknown>>>;
288
+ /** A relation write: one or more relation directives and their payloads. */
356
289
  export type RelationMutationAction = Readonly<Partial<Record<RelationMutationDirective, unknown>>>;
357
- /**
358
- * Scalar write members carry no scope qualifier — all six scalar members were
359
- * measured uniform — so the scope reaches this reader only to keep one mutation
360
- * walk asking one question.
361
- */
290
+ /** The scalar fields writable at one stage and write position. */
362
291
  type WritableScalarKey<C extends Contract, K extends ResourceKey<C>, Stage extends "create" | "update", Scope extends WriteScope> = KeysWithCapability<C, K, ScalarFieldKeyOf<C, K>, Stage, Scope>;
363
292
  /**
364
- * The relations writable at one stage **in one write position**. The default is
365
- * the unrestricted position, which is what every nested write argument is and
366
- * what a caller that states no scope means.
293
+ * The relations writable at one stage in one write position. The default is
294
+ * the unrestricted position.
367
295
  */
368
296
  export type WritableRelationKey<C extends Contract, K extends ResourceKey<C>, Stage extends "create" | "update", Scope extends WriteScope = UnrestrictedWrite> = KeysWithCapability<C, K, RelationFieldKeyOf<C, K>, Stage, Scope>;
369
297
  type ManyOrOne<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Value> = RelationCardinality<C, K, F> extends "many" ? Value | readonly Value[] : Value;
370
- type ConnectOrCreateEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = Readonly<{
371
- where: UniqueWhereInput<C, RelationTarget<C, K, F>, Forms>;
372
- create: CreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms>;
298
+ /**
299
+ * A `where` of plain fields: each scalar field's filter, combined with
300
+ * `AND`/`OR`/`NOT`, and no relation filter at any depth.
301
+ */
302
+ type ScalarOnlyWhereInput<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
303
+ AND?: readonly ScalarOnlyWhereInput<C, K, Forms, ReferenceForms>[];
304
+ OR?: readonly ScalarOnlyWhereInput<C, K, Forms, ReferenceForms>[];
305
+ NOT?: ScalarOnlyWhereInput<C, K, Forms, ReferenceForms>;
306
+ } & ScalarWhereFields<C, K, Forms, ReferenceForms>>;
307
+ /**
308
+ * The `where` of a nested `$update` or `$delete` through relation `F`: plain fields
309
+ * only where the relation states `nestedWriteFilter: "scalar"`, any filter otherwise.
310
+ */
311
+ type NestedWriteWhereInput<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = CapabilitiesOf<C, K, F> extends {
312
+ readonly nestedWriteFilter: "scalar";
313
+ } ? ScalarOnlyWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms> : WhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>;
314
+ type ConnectOrCreateEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
315
+ where: UniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>;
316
+ create: CreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms>;
373
317
  }>;
374
- type ToOneUpdateEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = Readonly<{
375
- where?: WhereInput<C, RelationTarget<C, K, F>, Forms>;
376
- data: UpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms>;
318
+ type ToOneUpdateEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
319
+ where?: NestedWriteWhereInput<C, K, F, Forms, ReferenceForms>;
320
+ data: UpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms>;
377
321
  }>;
378
- type ToManyUpdateEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = Readonly<{
379
- where: WhereInput<C, RelationTarget<C, K, F>, Forms>;
380
- data: UpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms>;
322
+ type ToManyUpdateEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
323
+ where: NestedWriteWhereInput<C, K, F, Forms, ReferenceForms>;
324
+ data: UpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms>;
381
325
  }>;
382
- type ToOneDeleteEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = true | Readonly<{
383
- where?: WhereInput<C, RelationTarget<C, K, F>, Forms>;
326
+ type ToOneDeleteEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = true | Readonly<{
327
+ where?: NestedWriteWhereInput<C, K, F, Forms, ReferenceForms>;
384
328
  }>;
385
- type ToManyDeleteEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = Readonly<{
386
- where: WhereInput<C, RelationTarget<C, K, F>, Forms>;
329
+ type ToManyDeleteEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
330
+ where: NestedWriteWhereInput<C, K, F, Forms, ReferenceForms>;
387
331
  }>;
388
- type ToOneUpsertEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = Readonly<{
389
- where?: UniqueWhereInput<C, RelationTarget<C, K, F>, Forms>;
390
- create: CreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms>;
391
- update: UpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms>;
332
+ type ToOneUpsertEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
333
+ where?: UniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>;
334
+ create: CreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms>;
335
+ update: UpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms>;
392
336
  }>;
393
- type ToManyUpsertEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = Readonly<{
394
- where: UniqueWhereInput<C, RelationTarget<C, K, F>, Forms>;
395
- create: CreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms>;
396
- update: UpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms>;
337
+ type ToManyUpsertEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
338
+ where: UniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>;
339
+ create: CreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms>;
340
+ update: UpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms>;
397
341
  }>;
398
- type RelationDirectiveValue<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Directive extends RelationMutationDirective, Forms extends ScalarForms> = Directive extends "$create" ? ManyOrOne<C, K, F, CreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms>> : Directive extends "$connect" ? ManyOrOne<C, K, F, UniqueWhereInput<C, RelationTarget<C, K, F>, Forms>> : Directive extends "$connectOrCreate" ? ManyOrOne<C, K, F, ConnectOrCreateEntry<C, K, F, Forms>> : Directive extends "$disconnect" ? RelationCardinality<C, K, F> extends "one" ? true : UniqueWhereInput<C, RelationTarget<C, K, F>, Forms> | readonly UniqueWhereInput<C, RelationTarget<C, K, F>, Forms>[] : Directive extends "$set" ? RelationCardinality<C, K, F> extends "one" ? UniqueWhereInput<C, RelationTarget<C, K, F>, Forms> | null : readonly UniqueWhereInput<C, RelationTarget<C, K, F>, Forms>[] : Directive extends "$update" ? RelationCardinality<C, K, F> extends "one" ? ToOneUpdateEntry<C, K, F, Forms> : ManyOrOne<C, K, F, ToManyUpdateEntry<C, K, F, Forms>> : Directive extends "$delete" ? RelationCardinality<C, K, F> extends "one" ? ToOneDeleteEntry<C, K, F, Forms> : ManyOrOne<C, K, F, ToManyDeleteEntry<C, K, F, Forms>> : Directive extends "$upsert" ? RelationCardinality<C, K, F> extends "one" ? ToOneUpsertEntry<C, K, F, Forms> : ManyOrOne<C, K, F, ToManyUpsertEntry<C, K, F, Forms>> : never;
342
+ type RelationDirectiveValue<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Directive extends RelationMutationDirective, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Directive extends "$create" ? ManyOrOne<C, K, F, CreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms>> : Directive extends "$connect" ? ManyOrOne<C, K, F, UniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>> : Directive extends "$connectOrCreate" ? ManyOrOne<C, K, F, ConnectOrCreateEntry<C, K, F, Forms, ReferenceForms>> : Directive extends "$disconnect" ? RelationCardinality<C, K, F> extends "one" ? true : UniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms> | readonly UniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>[] : Directive extends "$set" ? RelationCardinality<C, K, F> extends "one" ? UniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms> | null : readonly UniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>[] : Directive extends "$update" ? RelationCardinality<C, K, F> extends "one" ? ToOneUpdateEntry<C, K, F, Forms, ReferenceForms> : ManyOrOne<C, K, F, ToManyUpdateEntry<C, K, F, Forms, ReferenceForms>> : Directive extends "$delete" ? RelationCardinality<C, K, F> extends "one" ? ToOneDeleteEntry<C, K, F, Forms, ReferenceForms> : ManyOrOne<C, K, F, ToManyDeleteEntry<C, K, F, Forms, ReferenceForms>> : Directive extends "$upsert" ? RelationCardinality<C, K, F> extends "one" ? ToOneUpsertEntry<C, K, F, Forms, ReferenceForms> : ManyOrOne<C, K, F, ToManyUpsertEntry<C, K, F, Forms, ReferenceForms>> : never;
399
343
  declare const NO_ADVERTISED_MEMBER: unique symbol;
400
344
  /**
401
345
  * A write member that advertises nothing: it accepts `{}` and refuses every key.
402
- *
403
- * TypeScript runs no excess-property check against an object type with no known
404
- * properties, so an empty mapped member would type as `{}` and accept any key
405
- * silently, leaving it to `V1006` at runtime. One optional member on a
406
- * module-private symbol keeps the type weak — `{}` still assigns — while giving
407
- * the excess-property check something to measure against, so the diagnostic names
408
- * the offending key.
409
- *
410
- * The empty case is reachable by design: `directives: []` means "writable, with no
411
- * directive", distinct from an absent member (see `contracts/field.ts`).
412
346
  */
413
347
  type NoAdvertisedMember = {
414
348
  readonly [NO_ADVERTISED_MEMBER]?: never;
415
349
  };
416
350
  /** `Write`, or {@link NoAdvertisedMember} when `Write` has no keys at all. */
417
351
  type RefuseEveryKeyWhenEmpty<Write> = [keyof Write] extends [never] ? NoAdvertisedMember : Write;
418
- type RelationMutationActionFor<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Stage extends "create" | "update", Scope extends WriteScope, Forms extends ScalarForms> = RefuseEveryKeyWhenEmpty<Readonly<Partial<{
419
- [Directive in Extract<CapabilityTokens<C, K, F, Stage, Scope>, RelationMutationDirective>]: RelationDirectiveValue<C, K, F, Directive, Forms>;
352
+ type RelationMutationActionFor<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Stage extends "create" | "update", Scope extends WriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = RefuseEveryKeyWhenEmpty<Readonly<Partial<{
353
+ [Directive in Extract<CapabilityTokens<C, K, F, Stage, Scope>, RelationMutationDirective>]: RelationDirectiveValue<C, K, F, Directive, Forms, ReferenceForms>;
420
354
  }>>>;
421
355
  /**
422
- * One scalar mutation directive's operand, as `normalizeScalarMutation` reads
423
- * it: one entry of the field (`$push` on a list also takes a list of them), and
424
- * `$unset`'s operand reaches the adapter un-normalized, so core states nothing
425
- * about it.
356
+ * One scalar mutation directive's operand: one entry of the field (`$push` on a
357
+ * list also takes a list of them). `$unset`'s operand is passed to the adapter as
358
+ * given.
426
359
  */
427
360
  type ScalarDirectiveOperand<C extends Contract, K extends ResourceKey<C>, F extends FieldKey<C, K>, Directive extends ScalarMutationDirective, Forms extends ScalarForms> = Directive extends "$unset" ? unknown : Directive extends "$push" ? [ScalarFieldAt<C, K, F>["list"]] extends [false] ? ScalarAtomAt<C, K, F, Forms> : ScalarAtomAt<C, K, F, Forms> | readonly ScalarAtomAt<C, K, F, Forms>[] : ScalarAtomAt<C, K, F, Forms>;
428
361
  /**
429
362
  * The directive object a scalar field accepts at one stage, or `never` when it
430
- * advertises no directive — never an empty object type, which every non-nullish
431
- * value would satisfy and so would let any value through beside the typed one.
363
+ * advertises no directive.
432
364
  */
433
365
  type ScalarMutationActionFor<C extends Contract, K extends ResourceKey<C>, F extends FieldKey<C, K>, Stage extends "create" | "update", Scope extends WriteScope, Forms extends ScalarForms> = [
434
366
  Extract<CapabilityTokens<C, K, F, Stage, Scope>, ScalarMutationDirective>
@@ -437,143 +369,106 @@ type ScalarMutationActionFor<C extends Contract, K extends ResourceKey<C>, F ext
437
369
  }>;
438
370
  /**
439
371
  * Each writable scalar takes its value under `Forms`, or a directive object of
440
- * the directives it advertises at this stage.
372
+ * the directives it advertises at this stage — or, in a transaction plan's
373
+ * top-level data, a `$ref` to a source of the same type.
441
374
  */
442
- type ScalarMutationFields<C extends Contract, K extends ResourceKey<C>, Stage extends "create" | "update", Scope extends WriteScope, Forms extends ScalarForms> = Readonly<{
443
- [F in WritableScalarKey<C, K, Stage, Scope>]?: ScalarValueAt<C, K, F, Forms> | ScalarMutationActionFor<C, K, F, Stage, Scope, Forms>;
375
+ type ScalarMutationFields<C extends Contract, K extends ResourceKey<C>, Stage extends "create" | "update", Scope extends WriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
376
+ [F in WritableScalarKey<C, K, Stage, Scope>]?: ScalarValueAt<C, K, F, Forms> | ScalarMutationActionFor<C, K, F, Stage, Scope, Forms> | SlotReference<C, K, F, ReferenceForms, "value">;
444
377
  }>;
445
- type RelationMutationFields<C extends Contract, K extends ResourceKey<C>, Stage extends "create" | "update", Scope extends WriteScope, Forms extends ScalarForms> = Readonly<{
446
- [F in WritableRelationKey<C, K, Stage, Scope>]?: RelationMutationActionFor<C, K, F & RelationFieldKeyOf<C, K>, Stage, Scope, Forms>;
378
+ type RelationMutationFields<C extends Contract, K extends ResourceKey<C>, Stage extends "create" | "update", Scope extends WriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
379
+ [F in WritableRelationKey<C, K, Stage, Scope>]?: RelationMutationActionFor<C, K, F & RelationFieldKeyOf<C, K>, Stage, Scope, Forms, ReferenceForms>;
447
380
  }>;
448
381
  /**
449
- * A `create` data argument, at one write position.
450
- *
451
- * The default is the unrestricted position: every nested occurrence of this type
452
- * — a `$create` payload, a `$connectOrCreate`'s `create`, an upsert branch — is a
453
- * write reached through a relation, and a scope qualifies the top level of a
454
- * write argument only (see {@link WriteScope}).
382
+ * A `create` data argument, at one write position. A write position applies
383
+ * to the top level only; nested writes use the unrestricted position (see
384
+ * {@link WriteScope}). `ReferenceForms` opens a transaction plan's reference
385
+ * positions — its scalar values and the unique keys its relation directives name
386
+ * — and is never passed to nested data, which holds none.
455
387
  */
456
- export type CreateDataInput<C extends Contract, K extends ResourceKey<C>, Scope extends WriteScope = UnrestrictedWrite, Forms extends ScalarForms = UnstatedForms> = RefuseEveryKeyWhenEmpty<Readonly<ScalarMutationFields<C, K, "create", Scope, Forms> & RelationMutationFields<C, K, "create", Scope, Forms>>>;
388
+ export type CreateDataInput<C extends Contract, K extends ResourceKey<C>, Scope extends WriteScope = UnrestrictedWrite, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never> = RefuseEveryKeyWhenEmpty<Readonly<ScalarMutationFields<C, K, "create", Scope, Forms, ReferenceForms> & RelationMutationFields<C, K, "create", Scope, Forms, ReferenceForms>>>;
457
389
  /** An `update` data argument, at one write position. See {@link CreateDataInput}. */
458
- export type UpdateDataInput<C extends Contract, K extends ResourceKey<C>, Scope extends WriteScope = UnrestrictedWrite, Forms extends ScalarForms = UnstatedForms> = RefuseEveryKeyWhenEmpty<Readonly<ScalarMutationFields<C, K, "update", Scope, Forms> & RelationMutationFields<C, K, "update", Scope, Forms>>>;
390
+ export type UpdateDataInput<C extends Contract, K extends ResourceKey<C>, Scope extends WriteScope = UnrestrictedWrite, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never> = RefuseEveryKeyWhenEmpty<Readonly<ScalarMutationFields<C, K, "update", Scope, Forms, ReferenceForms> & RelationMutationFields<C, K, "update", Scope, Forms, ReferenceForms>>>;
459
391
  type QueryProjectionArgs<C extends Contract, K extends ResourceKey<C>, Scope extends ProjectionScope, Forms extends ScalarForms> = ProjectionChoice<C, K, Scope, false, Forms>;
460
392
  /**
461
- * Every standard operation's argument object, with each argument position bound to
462
- * the argument SCOPE it is.
463
- *
464
- * The map is already keyed by `family.variant`, so binding the scope here is what
465
- * makes an over-advertised projection or nested write **unrepresentable** at the
466
- * authoring boundary rather than merely refused at runtime: twelve projection
467
- * cells and eight data cells, and `create.many`/`update.many` no longer share
468
- * their projection with `find.many` nor their data with `create.one`.
469
- *
470
- * **Two bulk-returning projections** — `create.many` and `update.many` are the
471
- * row-returning bulk writes, so their projection sits in `"bulkWrite"`. Every
472
- * other projection-carrying variant reads or writes one addressed record and sits
473
- * in `"record"`, including a multi-row READ: the axis is the write being bulk, not
474
- * the row count. `delete.many` is the one cell where that is a judgement rather
475
- * than a measurement — it is a bulk write that core's grammar gives a projection,
476
- * and no pilot engine answers it at all, so it keeps the surface it has today
477
- * instead of being narrowed on a supposition.
478
- *
479
- * **Four flat bulk writes** — `create.many`, `create.count`, `update.many` and
480
- * `update.count` carry a data argument of own columns and own reference fields;
481
- * the rest admit nested writes. `upsert.unique`'s two branches are both nested.
482
- *
483
- * **This binding is core's grammar, not the adapter's routing.** A variant's real
484
- * scope is an adapter fact and the adapter states it on the advertised variant
485
- * (`OperationVariantScopes`); a host that routed, say, `update.first` through a
486
- * bulk-returning call would make this map's `"record"` too generous.
487
- *
488
- * An unqualified capability holds in every scope, so a Contract whose adapter has
489
- * not measured the axis is bound to the same surface it had before the axis
490
- * existed.
393
+ * Every standard operation's argument object, with each argument at its
394
+ * projection or write position.
491
395
  */
492
- export type OperationArgumentMap<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms = UnstatedForms> = {
396
+ export type OperationArgumentMap<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never> = {
493
397
  find: {
494
398
  first: QueryProjectionArgs<C, K, "record", Forms> & {
495
- where?: WhereInput<C, K, Forms>;
399
+ where?: WhereInput<C, K, Forms, ReferenceForms>;
496
400
  orderBy?: OrderByInput<C, K>;
497
401
  };
498
402
  unique: QueryProjectionArgs<C, K, "record", Forms> & {
499
- where: UniqueWhereInput<C, K, Forms>;
403
+ where: UniqueWhereInput<C, K, Forms, ReferenceForms>;
500
404
  };
501
405
  many: QueryProjectionArgs<C, K, "record", Forms> & {
502
- where?: WhereInput<C, K, Forms>;
406
+ where?: WhereInput<C, K, Forms, ReferenceForms>;
503
407
  orderBy?: OrderByInput<C, K>;
504
408
  limit?: number;
505
409
  offset?: number;
506
- cursor?: CursorInput<C, K, Forms>;
410
+ cursor?: CursorInput<C, K, Forms, ReferenceForms>;
507
411
  };
508
412
  count: {
509
- where?: WhereInput<C, K, Forms>;
413
+ where?: WhereInput<C, K, Forms, ReferenceForms>;
510
414
  };
511
415
  };
512
416
  create: {
513
417
  one: QueryProjectionArgs<C, K, "record", Forms> & {
514
- data: CreateDataInput<C, K, "nested", Forms>;
418
+ data: CreateDataInput<C, K, "nested", Forms, ReferenceForms>;
515
419
  };
516
420
  many: QueryProjectionArgs<C, K, "bulkWrite", Forms> & {
517
- data: readonly CreateDataInput<C, K, "bulkWrite", Forms>[];
421
+ data: readonly CreateDataInput<C, K, "bulkWrite", Forms, ReferenceForms>[];
518
422
  };
519
423
  count: {
520
- data: readonly CreateDataInput<C, K, "bulkWrite", Forms>[];
424
+ data: readonly CreateDataInput<C, K, "bulkWrite", Forms, ReferenceForms>[];
521
425
  };
522
426
  };
523
427
  update: {
524
428
  first: QueryProjectionArgs<C, K, "record", Forms> & {
525
- where?: WhereInput<C, K, Forms>;
429
+ where?: WhereInput<C, K, Forms, ReferenceForms>;
526
430
  orderBy?: OrderByInput<C, K>;
527
- data: UpdateDataInput<C, K, "nested", Forms>;
431
+ data: UpdateDataInput<C, K, "nested", Forms, ReferenceForms>;
528
432
  };
529
433
  unique: QueryProjectionArgs<C, K, "record", Forms> & {
530
- where: UniqueWhereInput<C, K, Forms>;
531
- data: UpdateDataInput<C, K, "nested", Forms>;
434
+ where: UniqueWhereInput<C, K, Forms, ReferenceForms>;
435
+ data: UpdateDataInput<C, K, "nested", Forms, ReferenceForms>;
532
436
  };
533
437
  many: QueryProjectionArgs<C, K, "bulkWrite", Forms> & {
534
- where?: WhereInput<C, K, Forms>;
535
- data: UpdateDataInput<C, K, "bulkWrite", Forms>;
438
+ where?: WhereInput<C, K, Forms, ReferenceForms>;
439
+ data: UpdateDataInput<C, K, "bulkWrite", Forms, ReferenceForms>;
536
440
  };
537
441
  count: {
538
- where?: WhereInput<C, K, Forms>;
539
- data: UpdateDataInput<C, K, "bulkWrite", Forms>;
442
+ where?: WhereInput<C, K, Forms, ReferenceForms>;
443
+ data: UpdateDataInput<C, K, "bulkWrite", Forms, ReferenceForms>;
540
444
  };
541
445
  };
542
446
  delete: {
543
447
  first: QueryProjectionArgs<C, K, "record", Forms> & {
544
- where?: WhereInput<C, K, Forms>;
448
+ where?: WhereInput<C, K, Forms, ReferenceForms>;
545
449
  orderBy?: OrderByInput<C, K>;
546
450
  };
547
451
  unique: QueryProjectionArgs<C, K, "record", Forms> & {
548
- where: UniqueWhereInput<C, K, Forms>;
452
+ where: UniqueWhereInput<C, K, Forms, ReferenceForms>;
549
453
  };
550
454
  many: QueryProjectionArgs<C, K, "record", Forms> & {
551
- where?: WhereInput<C, K, Forms>;
455
+ where?: WhereInput<C, K, Forms, ReferenceForms>;
552
456
  };
553
457
  count: {
554
- where?: WhereInput<C, K, Forms>;
458
+ where?: WhereInput<C, K, Forms, ReferenceForms>;
555
459
  };
556
460
  };
557
461
  upsert: {
558
462
  unique: QueryProjectionArgs<C, K, "record", Forms> & {
559
- where: UniqueWhereInput<C, K, Forms>;
560
- create: CreateDataInput<C, K, "nested", Forms>;
561
- update: UpdateDataInput<C, K, "nested", Forms>;
463
+ where: UniqueWhereInput<C, K, Forms, ReferenceForms>;
464
+ create: CreateDataInput<C, K, "nested", Forms, ReferenceForms>;
465
+ update: UpdateDataInput<C, K, "nested", Forms, ReferenceForms>;
562
466
  };
563
467
  };
564
468
  };
565
- /**
566
- * One standard operation's argument object.
567
- *
568
- * `Forms` is the scalar-form map its scalar VALUES are read through — data,
569
- * filters, unique selectors and cursors, at every depth. Unstated, every built-in
570
- * value is `unknown` ({@link UnstatedForms}); the application façade passes
571
- * `ApplicationScalarForms`, so a `Date` handed to a `json` field or a number to a
572
- * `string` one is refused where it is written rather than by `V1001` at runtime.
573
- * The validation layer stays the guard either way.
574
- */
575
- export type OperationArgumentsFor<C extends Contract, K extends ResourceKey<C>, I extends OperationIdentity, Forms extends ScalarForms = UnstatedForms> = I extends {
469
+ /** One standard operation's argument object. */
470
+ export type OperationArgumentsFor<C extends Contract, K extends ResourceKey<C>, I extends OperationIdentity, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never> = I extends {
576
471
  family: infer F;
577
472
  variant: infer V;
578
- } ? F extends keyof OperationArgumentMap<C, K, Forms> ? V extends keyof OperationArgumentMap<C, K, Forms>[F] ? OperationArgumentMap<C, K, Forms>[F][V] : never : never : never;
473
+ } ? F extends keyof OperationArgumentMap<C, K, Forms, ReferenceForms> ? V extends keyof OperationArgumentMap<C, K, Forms, ReferenceForms>[F] ? OperationArgumentMap<C, K, Forms, ReferenceForms>[F][V] : never : never : never;
579
474
  export {};