@aventara/core 0.1.0-pilot.4 → 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.
- package/CHANGELOG.md +338 -0
- package/README.md +100 -3
- package/dist/adapters/adapter-model.d.ts +8 -0
- package/dist/adapters/adapter.interface.d.ts +6 -2
- package/dist/compiler/contract-compiler-diagnostic.d.ts +6 -0
- package/dist/compiler/contract.compiler.js +67 -0
- package/dist/config/config.resolver.d.ts +3 -0
- package/dist/config/config.resolver.js +1 -0
- package/dist/config/config.validator.js +6 -0
- package/dist/config/define-fields.d.ts +10 -3
- package/dist/config/framework-config.d.ts +4 -1
- package/dist/config/framework-fields-config.d.ts +6 -0
- package/dist/contracts/client-contract-structure.validator.d.ts +21 -1
- package/dist/contracts/client-contract-structure.validator.js +99 -2
- package/dist/contracts/contract-canonicalizer.js +32 -0
- package/dist/contracts/contract.d.ts +7 -0
- package/dist/contracts/field.d.ts +10 -0
- package/dist/contracts/json-shape.d.ts +65 -0
- package/dist/contracts/json-shape.js +1 -0
- package/dist/contracts/reference-write-limit.d.ts +7 -0
- package/dist/contracts/reference-write-limit.js +1 -0
- package/dist/contracts/scalar-value-type.d.ts +12 -1
- package/dist/framework/contract-view.d.ts +126 -21
- package/dist/framework/framework.d.ts +5 -3
- package/dist/framework/framework.factory.js +56 -13
- package/dist/index.d.ts +8 -40
- package/dist/index.js +0 -20
- package/dist/internal.d.ts +35 -0
- package/dist/internal.js +16 -0
- package/dist/json/avz.d.ts +96 -0
- package/dist/json/avz.js +212 -0
- package/dist/json/index.d.ts +6 -0
- package/dist/json/index.js +1 -0
- package/dist/json/json-shape.registry.d.ts +22 -0
- package/dist/json/json-shape.registry.js +16 -0
- package/dist/json/zod-issue.translator.d.ts +51 -0
- package/dist/json/zod-issue.translator.js +142 -0
- package/dist/operations/operation-arguments.d.ts +151 -101
- package/dist/operations/operation-identity.d.ts +2 -0
- package/dist/operations/operation-identity.js +3 -0
- package/dist/operations/operation-validator-core.d.ts +1 -1
- package/dist/operations/operation-validator-core.js +28 -10
- package/dist/operations/operation-validator.d.ts +20 -5
- package/dist/operations/operation-validator.js +26 -10
- package/dist/operations/projection-scope.resolver.d.ts +1 -1
- package/dist/operations/structural-limits.walker.d.ts +19 -0
- package/dist/operations/structural-limits.walker.js +344 -0
- package/dist/protocol/absent-route.responder.d.ts +2 -1
- package/dist/protocol/absent-route.responder.js +32 -6
- package/dist/protocol/http-request.decoder.d.ts +6 -0
- package/dist/protocol/http-request.decoder.js +11 -3
- package/dist/protocol/protocol.binder.d.ts +4 -2
- package/dist/protocol/protocol.binder.js +3 -1
- package/dist/protocol/protocol.handler.d.ts +6 -2
- package/dist/protocol/protocol.handler.js +14 -4
- package/dist/protocol/unmounted-route.error.d.ts +19 -0
- package/dist/protocol/unmounted-route.error.js +10 -0
- package/dist/runtime/caller-data.copier.d.ts +59 -0
- package/dist/runtime/caller-data.copier.js +470 -0
- package/dist/runtime/caller-data.door.d.ts +56 -0
- package/dist/runtime/caller-data.door.js +65 -0
- package/dist/runtime/computed-read-runtime.js +3 -10
- package/dist/runtime/computed-value.error.d.ts +13 -0
- package/dist/runtime/computed-value.error.js +9 -0
- package/dist/runtime/create-requirement.d.ts +43 -7
- package/dist/runtime/create-requirement.js +89 -9
- package/dist/runtime/diagnostics-reporter.d.ts +20 -4
- package/dist/runtime/diagnostics-reporter.js +11 -4
- package/dist/runtime/error-boundary.d.ts +8 -0
- package/dist/runtime/error-boundary.js +65 -35
- package/dist/runtime/field-behavior.d.ts +2 -2
- package/dist/runtime/framework-error.d.ts +12 -0
- package/dist/runtime/misuse-reporter.d.ts +32 -0
- package/dist/runtime/misuse-reporter.js +19 -0
- package/dist/runtime/mutation-planner.js +13 -11
- package/dist/runtime/operation-request.d.ts +4 -11
- package/dist/runtime/operation-runtime.d.ts +14 -7
- package/dist/runtime/operation-runtime.js +37 -18
- package/dist/runtime/outcome-mapper.js +12 -2
- package/dist/runtime/output-validator.d.ts +10 -0
- package/dist/runtime/output-validator.js +11 -0
- package/dist/runtime/owned-execution.registry.d.ts +13 -0
- package/dist/runtime/owned-execution.registry.js +7 -0
- package/dist/runtime/pipeline.d.ts +19 -7
- package/dist/runtime/referential-action.d.ts +7 -0
- package/dist/runtime/request-envelope.validator.d.ts +5 -0
- package/dist/runtime/request-envelope.validator.js +118 -0
- package/dist/runtime/scalar-runtime.d.ts +30 -2
- package/dist/runtime/scalar-runtime.js +162 -79
- package/dist/transactions/transaction-plan-assembler.d.ts +5 -1
- package/dist/transactions/transaction-plan-assembler.js +74 -75
- package/dist/transactions/transaction-plan-validator.d.ts +30 -7
- package/dist/transactions/transaction-plan-validator.js +204 -153
- package/dist/transactions/transaction-reference-collector.d.ts +30 -0
- package/dist/transactions/transaction-reference-collector.js +204 -0
- package/dist/transactions/transaction-reference-resolver.js +10 -5
- package/dist/transactions/transaction-reference-validator.js +24 -17
- package/dist/transactions/transaction-reference.d.ts +23 -51
- package/dist/transactions/transaction-request.d.ts +3 -3
- package/dist/transactions/transaction-response.d.ts +6 -1
- package/dist/transactions/transaction-response.js +24 -1
- package/dist/transactions/transaction-runtime.d.ts +4 -2
- package/dist/transactions/transaction-runtime.js +4 -3
- package/package.json +17 -3
- package/dist/operations/operation-boolean-nodes.d.ts +0 -11
- package/dist/operations/operation-boolean-nodes.js +0 -283
- package/dist/operations/operation-nesting.d.ts +0 -8
- package/dist/operations/operation-nesting.js +0 -307
|
@@ -1,8 +1,9 @@
|
|
|
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 {
|
|
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";
|
|
7
8
|
/** The Resource names of Contract `C`. */
|
|
8
9
|
export type ResourceKey<C extends Contract> = Extract<keyof C["resources"], string>;
|
|
@@ -69,7 +70,13 @@ type UnstatedForms = ScalarForms;
|
|
|
69
70
|
/** Field `F`'s value under `Forms`, the same as in results. */
|
|
70
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;
|
|
71
72
|
/** One entry of field `F`'s value — the whole value when `F` is not a list. */
|
|
72
|
-
type ScalarAtomAt<C extends Contract, K extends ResourceKey<C>, F extends FieldKey<C, K>, Forms extends ScalarForms> =
|
|
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>[]>;
|
|
73
80
|
/**
|
|
74
81
|
* A JSON object. Positions that accept both a value and an object of operators
|
|
75
82
|
* read a JSON object as the operators, so their value forms leave it out.
|
|
@@ -87,71 +94,92 @@ export type ScalarFilterInput = unknown | Readonly<Partial<Record<ScalarFilterOp
|
|
|
87
94
|
* object.
|
|
88
95
|
*/
|
|
89
96
|
type ScalarFilterShorthand<Value> = Exclude<Value, JsonObject>;
|
|
97
|
+
/**
|
|
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
|
+
};
|
|
90
104
|
/**
|
|
91
105
|
* A scalar filter's operator object: a comparison operand is the field's whole
|
|
92
106
|
* value; `in`, `notIn`, `hasEvery` and `hasSome` take a list of entries; `has`
|
|
93
107
|
* one entry; a `json` field's `string*`/`array*` operand a {@link JsonValue};
|
|
94
108
|
* `not` a value or a nested operator object. `mode`, `isEmpty` and `path` are
|
|
95
|
-
* passed to the adapter as given.
|
|
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`).
|
|
96
113
|
*/
|
|
97
|
-
type ScalarFilterOperators<Value, Atom, Json
|
|
98
|
-
equals?: Value;
|
|
99
|
-
not?: Exclude<Value, JsonObject> | ScalarFilterOperators<Value, Atom, Json>;
|
|
100
|
-
in?: readonly Atom[];
|
|
101
|
-
notIn?: readonly Atom[];
|
|
102
|
-
lt?: Value;
|
|
103
|
-
lte?: Value;
|
|
104
|
-
gt?: Value;
|
|
105
|
-
gte?: Value;
|
|
106
|
-
contains?: Value;
|
|
107
|
-
startsWith?: Value;
|
|
108
|
-
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"];
|
|
109
126
|
mode?: unknown;
|
|
110
|
-
has?: Atom;
|
|
111
|
-
hasEvery?: readonly Atom[];
|
|
112
|
-
hasSome?: readonly Atom[];
|
|
127
|
+
has?: Atom | References["entry"];
|
|
128
|
+
hasEvery?: readonly Atom[] | References["entries"];
|
|
129
|
+
hasSome?: readonly Atom[] | References["entries"];
|
|
113
130
|
isEmpty?: unknown;
|
|
114
131
|
path?: unknown;
|
|
115
|
-
stringContains?: Json
|
|
116
|
-
stringStartsWith?: Json
|
|
117
|
-
stringEndsWith?: Json
|
|
132
|
+
stringContains?: Exclude<Json, null>;
|
|
133
|
+
stringStartsWith?: Exclude<Json, null>;
|
|
134
|
+
stringEndsWith?: Exclude<Json, null>;
|
|
118
135
|
arrayContains?: Json;
|
|
119
136
|
arrayStartsWith?: Json;
|
|
120
137
|
arrayEndsWith?: Json;
|
|
121
138
|
}>;
|
|
122
|
-
/**
|
|
123
|
-
|
|
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 {
|
|
124
147
|
readonly scalar: "json";
|
|
125
|
-
} ? JsonValue : ScalarValueAt<C, K, F, Forms>>;
|
|
148
|
+
} ? JsonValue : ScalarValueAt<C, K, F, Forms>, FieldSlotReferences<C, K, F, ReferenceForms>>;
|
|
126
149
|
type ScalarFilterableKey<C extends Contract, K extends ResourceKey<C>> = KeysWithCapability<C, K, ScalarFieldKeyOf<C, K>, "filter", UnrestrictedProjection>;
|
|
127
150
|
type RelationParentFilterKey<C extends Contract, K extends ResourceKey<C>> = {
|
|
128
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;
|
|
129
152
|
}[RelationFieldKeyOf<C, K>];
|
|
130
|
-
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>>>>;
|
|
131
|
-
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>;
|
|
132
|
-
type ScalarWhereFields<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms> = Readonly<{
|
|
133
|
-
[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>;
|
|
134
157
|
}>;
|
|
135
|
-
type RelationWhereFields<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms> = Readonly<{
|
|
136
|
-
[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>;
|
|
137
160
|
}>;
|
|
138
161
|
/**
|
|
139
162
|
* A `where` argument. `Forms` is the scalar-form map its scalar values are read
|
|
140
|
-
* 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.
|
|
141
165
|
*/
|
|
142
|
-
export type WhereInput<C extends Contract, K extends ResourceKey<C>, Forms extends ScalarForms = UnstatedForms> = Readonly<{
|
|
143
|
-
AND?: readonly WhereInput<C, K, Forms>[];
|
|
144
|
-
OR?: readonly WhereInput<C, K, Forms>[];
|
|
145
|
-
NOT?: WhereInput<C, K, Forms>;
|
|
146
|
-
} & 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>>;
|
|
147
171
|
type ActiveIdentifier<C extends Contract, K extends ResourceKey<C>> = C["resources"][K]["identifiers"][number];
|
|
148
|
-
type IdentifierObject<C extends Contract, K extends ResourceKey<C>, I extends readonly string[], Forms extends ScalarForms> = Readonly<{
|
|
149
|
-
[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">;
|
|
150
174
|
} & {
|
|
151
175
|
[F in Exclude<FieldKey<C, K>, I[number]>]?: never;
|
|
152
176
|
}>;
|
|
153
|
-
/**
|
|
154
|
-
|
|
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;
|
|
155
183
|
/** `"asc"` or `"desc"`. */
|
|
156
184
|
export type SortDirection = "asc" | "desc";
|
|
157
185
|
/** Where `null`s sort: `"first"` or `"last"`. */
|
|
@@ -184,9 +212,12 @@ export type OrderByEntry<C extends Contract, K extends ResourceKey<C>> = {
|
|
|
184
212
|
}[OrderableFieldKey<C, K>];
|
|
185
213
|
/** An `orderBy` argument: one entry, or a list in order of precedence. */
|
|
186
214
|
export type OrderByInput<C extends Contract, K extends ResourceKey<C>> = OrderByEntry<C, K> | readonly OrderByEntry<C, K>[];
|
|
187
|
-
/**
|
|
188
|
-
|
|
189
|
-
|
|
215
|
+
/**
|
|
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.
|
|
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">;
|
|
190
221
|
}>;
|
|
191
222
|
/** The scalar fields selectable at one projection position. */
|
|
192
223
|
type SelectableScalarKey<C extends Contract, K extends ResourceKey<C>, Scope extends ProjectionScope> = KeysWithCapability<C, K, ScalarFieldKeyOf<C, K>, "select", Scope>;
|
|
@@ -264,35 +295,51 @@ type WritableScalarKey<C extends Contract, K extends ResourceKey<C>, Stage exten
|
|
|
264
295
|
*/
|
|
265
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>;
|
|
266
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;
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
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>;
|
|
270
317
|
}>;
|
|
271
|
-
type ToOneUpdateEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = Readonly<{
|
|
272
|
-
where?:
|
|
273
|
-
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>;
|
|
274
321
|
}>;
|
|
275
|
-
type ToManyUpdateEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = Readonly<{
|
|
276
|
-
where:
|
|
277
|
-
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>;
|
|
278
325
|
}>;
|
|
279
|
-
type ToOneDeleteEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = true | Readonly<{
|
|
280
|
-
where?:
|
|
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>;
|
|
281
328
|
}>;
|
|
282
|
-
type ToManyDeleteEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = Readonly<{
|
|
283
|
-
where:
|
|
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>;
|
|
284
331
|
}>;
|
|
285
|
-
type ToOneUpsertEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = Readonly<{
|
|
286
|
-
where?: UniqueWhereInput<C, RelationTarget<C, K, F>, Forms>;
|
|
287
|
-
create: CreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms>;
|
|
288
|
-
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>;
|
|
289
336
|
}>;
|
|
290
|
-
type ToManyUpsertEntry<C extends Contract, K extends ResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms> = Readonly<{
|
|
291
|
-
where: UniqueWhereInput<C, RelationTarget<C, K, F>, Forms>;
|
|
292
|
-
create: CreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms>;
|
|
293
|
-
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>;
|
|
294
341
|
}>;
|
|
295
|
-
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;
|
|
296
343
|
declare const NO_ADVERTISED_MEMBER: unique symbol;
|
|
297
344
|
/**
|
|
298
345
|
* A write member that advertises nothing: it accepts `{}` and refuses every key.
|
|
@@ -302,8 +349,8 @@ type NoAdvertisedMember = {
|
|
|
302
349
|
};
|
|
303
350
|
/** `Write`, or {@link NoAdvertisedMember} when `Write` has no keys at all. */
|
|
304
351
|
type RefuseEveryKeyWhenEmpty<Write> = [keyof Write] extends [never] ? NoAdvertisedMember : Write;
|
|
305
|
-
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<{
|
|
306
|
-
[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>;
|
|
307
354
|
}>>>;
|
|
308
355
|
/**
|
|
309
356
|
* One scalar mutation directive's operand: one entry of the field (`$push` on a
|
|
@@ -322,103 +369,106 @@ type ScalarMutationActionFor<C extends Contract, K extends ResourceKey<C>, F ext
|
|
|
322
369
|
}>;
|
|
323
370
|
/**
|
|
324
371
|
* Each writable scalar takes its value under `Forms`, or a directive object of
|
|
325
|
-
* 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.
|
|
326
374
|
*/
|
|
327
|
-
type ScalarMutationFields<C extends Contract, K extends ResourceKey<C>, Stage extends "create" | "update", Scope extends WriteScope, Forms extends ScalarForms> = Readonly<{
|
|
328
|
-
[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">;
|
|
329
377
|
}>;
|
|
330
|
-
type RelationMutationFields<C extends Contract, K extends ResourceKey<C>, Stage extends "create" | "update", Scope extends WriteScope, Forms extends ScalarForms> = Readonly<{
|
|
331
|
-
[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>;
|
|
332
380
|
}>;
|
|
333
381
|
/**
|
|
334
382
|
* A `create` data argument, at one write position. A write position applies
|
|
335
383
|
* to the top level only; nested writes use the unrestricted position (see
|
|
336
|
-
* {@link WriteScope}).
|
|
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.
|
|
337
387
|
*/
|
|
338
|
-
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>>>;
|
|
339
389
|
/** An `update` data argument, at one write position. See {@link CreateDataInput}. */
|
|
340
|
-
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>>>;
|
|
341
391
|
type QueryProjectionArgs<C extends Contract, K extends ResourceKey<C>, Scope extends ProjectionScope, Forms extends ScalarForms> = ProjectionChoice<C, K, Scope, false, Forms>;
|
|
342
392
|
/**
|
|
343
393
|
* Every standard operation's argument object, with each argument at its
|
|
344
394
|
* projection or write position.
|
|
345
395
|
*/
|
|
346
|
-
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> = {
|
|
347
397
|
find: {
|
|
348
398
|
first: QueryProjectionArgs<C, K, "record", Forms> & {
|
|
349
|
-
where?: WhereInput<C, K, Forms>;
|
|
399
|
+
where?: WhereInput<C, K, Forms, ReferenceForms>;
|
|
350
400
|
orderBy?: OrderByInput<C, K>;
|
|
351
401
|
};
|
|
352
402
|
unique: QueryProjectionArgs<C, K, "record", Forms> & {
|
|
353
|
-
where: UniqueWhereInput<C, K, Forms>;
|
|
403
|
+
where: UniqueWhereInput<C, K, Forms, ReferenceForms>;
|
|
354
404
|
};
|
|
355
405
|
many: QueryProjectionArgs<C, K, "record", Forms> & {
|
|
356
|
-
where?: WhereInput<C, K, Forms>;
|
|
406
|
+
where?: WhereInput<C, K, Forms, ReferenceForms>;
|
|
357
407
|
orderBy?: OrderByInput<C, K>;
|
|
358
408
|
limit?: number;
|
|
359
409
|
offset?: number;
|
|
360
|
-
cursor?: CursorInput<C, K, Forms>;
|
|
410
|
+
cursor?: CursorInput<C, K, Forms, ReferenceForms>;
|
|
361
411
|
};
|
|
362
412
|
count: {
|
|
363
|
-
where?: WhereInput<C, K, Forms>;
|
|
413
|
+
where?: WhereInput<C, K, Forms, ReferenceForms>;
|
|
364
414
|
};
|
|
365
415
|
};
|
|
366
416
|
create: {
|
|
367
417
|
one: QueryProjectionArgs<C, K, "record", Forms> & {
|
|
368
|
-
data: CreateDataInput<C, K, "nested", Forms>;
|
|
418
|
+
data: CreateDataInput<C, K, "nested", Forms, ReferenceForms>;
|
|
369
419
|
};
|
|
370
420
|
many: QueryProjectionArgs<C, K, "bulkWrite", Forms> & {
|
|
371
|
-
data: readonly CreateDataInput<C, K, "bulkWrite", Forms>[];
|
|
421
|
+
data: readonly CreateDataInput<C, K, "bulkWrite", Forms, ReferenceForms>[];
|
|
372
422
|
};
|
|
373
423
|
count: {
|
|
374
|
-
data: readonly CreateDataInput<C, K, "bulkWrite", Forms>[];
|
|
424
|
+
data: readonly CreateDataInput<C, K, "bulkWrite", Forms, ReferenceForms>[];
|
|
375
425
|
};
|
|
376
426
|
};
|
|
377
427
|
update: {
|
|
378
428
|
first: QueryProjectionArgs<C, K, "record", Forms> & {
|
|
379
|
-
where?: WhereInput<C, K, Forms>;
|
|
429
|
+
where?: WhereInput<C, K, Forms, ReferenceForms>;
|
|
380
430
|
orderBy?: OrderByInput<C, K>;
|
|
381
|
-
data: UpdateDataInput<C, K, "nested", Forms>;
|
|
431
|
+
data: UpdateDataInput<C, K, "nested", Forms, ReferenceForms>;
|
|
382
432
|
};
|
|
383
433
|
unique: QueryProjectionArgs<C, K, "record", Forms> & {
|
|
384
|
-
where: UniqueWhereInput<C, K, Forms>;
|
|
385
|
-
data: UpdateDataInput<C, K, "nested", Forms>;
|
|
434
|
+
where: UniqueWhereInput<C, K, Forms, ReferenceForms>;
|
|
435
|
+
data: UpdateDataInput<C, K, "nested", Forms, ReferenceForms>;
|
|
386
436
|
};
|
|
387
437
|
many: QueryProjectionArgs<C, K, "bulkWrite", Forms> & {
|
|
388
|
-
where?: WhereInput<C, K, Forms>;
|
|
389
|
-
data: UpdateDataInput<C, K, "bulkWrite", Forms>;
|
|
438
|
+
where?: WhereInput<C, K, Forms, ReferenceForms>;
|
|
439
|
+
data: UpdateDataInput<C, K, "bulkWrite", Forms, ReferenceForms>;
|
|
390
440
|
};
|
|
391
441
|
count: {
|
|
392
|
-
where?: WhereInput<C, K, Forms>;
|
|
393
|
-
data: UpdateDataInput<C, K, "bulkWrite", Forms>;
|
|
442
|
+
where?: WhereInput<C, K, Forms, ReferenceForms>;
|
|
443
|
+
data: UpdateDataInput<C, K, "bulkWrite", Forms, ReferenceForms>;
|
|
394
444
|
};
|
|
395
445
|
};
|
|
396
446
|
delete: {
|
|
397
447
|
first: QueryProjectionArgs<C, K, "record", Forms> & {
|
|
398
|
-
where?: WhereInput<C, K, Forms>;
|
|
448
|
+
where?: WhereInput<C, K, Forms, ReferenceForms>;
|
|
399
449
|
orderBy?: OrderByInput<C, K>;
|
|
400
450
|
};
|
|
401
451
|
unique: QueryProjectionArgs<C, K, "record", Forms> & {
|
|
402
|
-
where: UniqueWhereInput<C, K, Forms>;
|
|
452
|
+
where: UniqueWhereInput<C, K, Forms, ReferenceForms>;
|
|
403
453
|
};
|
|
404
454
|
many: QueryProjectionArgs<C, K, "record", Forms> & {
|
|
405
|
-
where?: WhereInput<C, K, Forms>;
|
|
455
|
+
where?: WhereInput<C, K, Forms, ReferenceForms>;
|
|
406
456
|
};
|
|
407
457
|
count: {
|
|
408
|
-
where?: WhereInput<C, K, Forms>;
|
|
458
|
+
where?: WhereInput<C, K, Forms, ReferenceForms>;
|
|
409
459
|
};
|
|
410
460
|
};
|
|
411
461
|
upsert: {
|
|
412
462
|
unique: QueryProjectionArgs<C, K, "record", Forms> & {
|
|
413
|
-
where: UniqueWhereInput<C, K, Forms>;
|
|
414
|
-
create: CreateDataInput<C, K, "nested", Forms>;
|
|
415
|
-
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>;
|
|
416
466
|
};
|
|
417
467
|
};
|
|
418
468
|
};
|
|
419
469
|
/** One standard operation's argument object. */
|
|
420
|
-
export type OperationArgumentsFor<C extends Contract, K extends ResourceKey<C>, I extends OperationIdentity, Forms extends ScalarForms = UnstatedForms> = I extends {
|
|
470
|
+
export type OperationArgumentsFor<C extends Contract, K extends ResourceKey<C>, I extends OperationIdentity, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never> = I extends {
|
|
421
471
|
family: infer F;
|
|
422
472
|
variant: infer V;
|
|
423
|
-
} ? 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;
|
|
424
474
|
export {};
|
|
@@ -14,3 +14,5 @@ export type OperationIdentity = {
|
|
|
14
14
|
}[OperationFamily];
|
|
15
15
|
/** Parses a family and variant into an {@link OperationIdentity}, or `undefined` when they name no standard operation. */
|
|
16
16
|
export declare function parseOperationIdentity(family: string, variant: string): OperationIdentity | undefined;
|
|
17
|
+
/** Whether `family` names one of the standard operation families. */
|
|
18
|
+
export declare function isOperationFamily(family: string): boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Contract } from "../contracts/contract.js";
|
|
2
|
-
import type
|
|
2
|
+
import { type OperationIdentity } from "./operation-identity.js";
|
|
3
3
|
import type { ValidationIssue } from "./validation-code.js";
|
|
4
4
|
/** An operation's arguments as an object, before validation. */
|
|
5
5
|
export type SemanticOperationArguments = Readonly<Record<string, unknown>>;
|
|
@@ -2,6 +2,7 @@ import { lookupField, lookupResource } from "../contracts/contract-lookup.js";
|
|
|
2
2
|
import { advertisedDirectivesAt, advertisedReducers, advertisedReducersAt, holdsAt, } from "../contracts/field.js";
|
|
3
3
|
import { isPlainRecord } from "../runtime/scalar-runtime.js";
|
|
4
4
|
import { routeTransactionReferenceCandidate } from "../transactions/transaction-reference.js";
|
|
5
|
+
import { isOperationFamily, } from "./operation-identity.js";
|
|
5
6
|
import { NESTED_PROJECTION_SCOPE, resolveProjectionScope, } from "./projection-scope.resolver.js";
|
|
6
7
|
import { NESTED_WRITE_SCOPE, resolveWriteScope, } from "./write-scope.resolver.js";
|
|
7
8
|
const OPERATION_ARGUMENT_RULES = {
|
|
@@ -111,7 +112,7 @@ function validateTopLevelArguments(request, args) {
|
|
|
111
112
|
const rule = OPERATION_ARGUMENT_RULES[key];
|
|
112
113
|
const issues = [];
|
|
113
114
|
if (rule === undefined) {
|
|
114
|
-
addIssue(issues, "V1001", ["
|
|
115
|
+
addIssue(issues, "V1001", [isOperationFamily(request.family) ? "variant" : "family"], `Operation "${key}" is not part of the standard operation grammar.`);
|
|
115
116
|
return issues;
|
|
116
117
|
}
|
|
117
118
|
for (const required of rule.required) {
|
|
@@ -168,6 +169,13 @@ function validateScalarFilter(fieldName, field, value, path, state) {
|
|
|
168
169
|
}
|
|
169
170
|
return;
|
|
170
171
|
}
|
|
172
|
+
if (state.transactionReferences === true &&
|
|
173
|
+
routeTransactionReferenceCandidate(value).kind !== "ordinary") {
|
|
174
|
+
if (!includes(supported, "equals")) {
|
|
175
|
+
addIssue(state.issues, "V1006", path, `Equality filtering is not available on field "${fieldName}".`);
|
|
176
|
+
}
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
171
179
|
if (!isPlainRecord(value)) {
|
|
172
180
|
if (!includes(supported, "equals")) {
|
|
173
181
|
addIssue(state.issues, "V1006", path, `Equality filtering is not available on field "${fieldName}".`);
|
|
@@ -270,6 +278,9 @@ function validateWhere(contract, resourceName, where, path, state, depth) {
|
|
|
270
278
|
if (field.kind === "scalar") {
|
|
271
279
|
validateScalarFilter(key, field, value, fieldPath, state);
|
|
272
280
|
}
|
|
281
|
+
else if (state.scalarOnly === true) {
|
|
282
|
+
addIssue(state.issues, "V1006", fieldPath, `Relation filter "${key}" is not available here: a nested $update or $delete filter on this relation takes scalar fields only.`);
|
|
283
|
+
}
|
|
273
284
|
else {
|
|
274
285
|
validateRelationFilter(contract, key, field, value, fieldPath, state, depth);
|
|
275
286
|
}
|
|
@@ -570,7 +581,7 @@ function validateScalarMutation(fieldName, field, value, stage, path, issues, tr
|
|
|
570
581
|
}
|
|
571
582
|
}
|
|
572
583
|
}
|
|
573
|
-
function validateRelationMutationEntry(contract, edge, directive, value, path, issues) {
|
|
584
|
+
function validateRelationMutationEntry(contract, edge, directive, value, path, issues, transactionReferences) {
|
|
574
585
|
const target = edge.target;
|
|
575
586
|
if (edge.cardinality === "one" && Array.isArray(value)) {
|
|
576
587
|
addIssue(issues, "V1012", path, `To-one relation directive "${directive}" does not accept arrays.`);
|
|
@@ -619,7 +630,7 @@ function validateRelationMutationEntry(contract, edge, directive, value, path, i
|
|
|
619
630
|
if (directive === "$create") {
|
|
620
631
|
const entries = edge.cardinality === "many" && Array.isArray(value) ? value : [value];
|
|
621
632
|
for (const entry of entries) {
|
|
622
|
-
validateMutationData(contract, target, entry, "create", NESTED_WRITE_SCOPE, path, issues);
|
|
633
|
+
validateMutationData(contract, target, entry, "create", NESTED_WRITE_SCOPE, path, issues, transactionReferences);
|
|
623
634
|
}
|
|
624
635
|
return;
|
|
625
636
|
}
|
|
@@ -631,7 +642,7 @@ function validateRelationMutationEntry(contract, edge, directive, value, path, i
|
|
|
631
642
|
continue;
|
|
632
643
|
}
|
|
633
644
|
validateUniqueSelector(contract, target, entry.where, [...path, "where"], issues);
|
|
634
|
-
validateMutationData(contract, target, entry.create, "create", NESTED_WRITE_SCOPE, [...path, "create"], issues);
|
|
645
|
+
validateMutationData(contract, target, entry.create, "create", NESTED_WRITE_SCOPE, [...path, "create"], issues, transactionReferences);
|
|
635
646
|
}
|
|
636
647
|
return;
|
|
637
648
|
}
|
|
@@ -650,13 +661,15 @@ function validateRelationMutationEntry(contract, edge, directive, value, path, i
|
|
|
650
661
|
const state = {
|
|
651
662
|
issues,
|
|
652
663
|
structuralRoot: [...path, "where"],
|
|
664
|
+
transactionReferences,
|
|
665
|
+
scalarOnly: edge.capabilities.nestedWriteFilter === "scalar",
|
|
653
666
|
booleanFilterNodes: 0,
|
|
654
667
|
nestingExceeded: false,
|
|
655
668
|
booleanNodesExceeded: false,
|
|
656
669
|
};
|
|
657
670
|
validateWhere(contract, target, entry.where, [...path, "where"], state, 1);
|
|
658
671
|
}
|
|
659
|
-
validateMutationData(contract, target, entry.data, "update", NESTED_WRITE_SCOPE, [...path, "data"], issues);
|
|
672
|
+
validateMutationData(contract, target, entry.data, "update", NESTED_WRITE_SCOPE, [...path, "data"], issues, transactionReferences);
|
|
660
673
|
}
|
|
661
674
|
return;
|
|
662
675
|
}
|
|
@@ -671,6 +684,8 @@ function validateRelationMutationEntry(contract, edge, directive, value, path, i
|
|
|
671
684
|
const state = {
|
|
672
685
|
issues,
|
|
673
686
|
structuralRoot: [...path, "where"],
|
|
687
|
+
transactionReferences,
|
|
688
|
+
scalarOnly: edge.capabilities.nestedWriteFilter === "scalar",
|
|
674
689
|
booleanFilterNodes: 0,
|
|
675
690
|
nestingExceeded: false,
|
|
676
691
|
booleanNodesExceeded: false,
|
|
@@ -685,6 +700,8 @@ function validateRelationMutationEntry(contract, edge, directive, value, path, i
|
|
|
685
700
|
const state = {
|
|
686
701
|
issues,
|
|
687
702
|
structuralRoot: [...path, "where"],
|
|
703
|
+
transactionReferences,
|
|
704
|
+
scalarOnly: edge.capabilities.nestedWriteFilter === "scalar",
|
|
688
705
|
booleanFilterNodes: 0,
|
|
689
706
|
nestingExceeded: false,
|
|
690
707
|
booleanNodesExceeded: false,
|
|
@@ -707,12 +724,12 @@ function validateRelationMutationEntry(contract, edge, directive, value, path, i
|
|
|
707
724
|
if ("where" in entry) {
|
|
708
725
|
validateUniqueSelector(contract, target, entry.where, [...path, "where"], issues);
|
|
709
726
|
}
|
|
710
|
-
validateMutationData(contract, target, entry.create, "create", NESTED_WRITE_SCOPE, [...path, "create"], issues);
|
|
711
|
-
validateMutationData(contract, target, entry.update, "update", NESTED_WRITE_SCOPE, [...path, "update"], issues);
|
|
727
|
+
validateMutationData(contract, target, entry.create, "create", NESTED_WRITE_SCOPE, [...path, "create"], issues, transactionReferences);
|
|
728
|
+
validateMutationData(contract, target, entry.update, "update", NESTED_WRITE_SCOPE, [...path, "update"], issues, transactionReferences);
|
|
712
729
|
}
|
|
713
730
|
}
|
|
714
731
|
}
|
|
715
|
-
function validateRelationMutation(contract, fieldName, field, value, stage, scope, path, issues) {
|
|
732
|
+
function validateRelationMutation(contract, fieldName, field, value, stage, scope, path, issues, transactionReferences) {
|
|
716
733
|
const directives = advertisedDirectivesAt(field.capabilities[stage], scope);
|
|
717
734
|
if (directives === undefined) {
|
|
718
735
|
addIssue(issues, "V1006", path, `Relation "${fieldName}" is not writable during ${stage}.`);
|
|
@@ -728,7 +745,7 @@ function validateRelationMutation(contract, fieldName, field, value, stage, scop
|
|
|
728
745
|
addIssue(issues, "V1006", directivePath, `Relation mutation directive "${directive}" is not available on relation "${fieldName}".`);
|
|
729
746
|
continue;
|
|
730
747
|
}
|
|
731
|
-
validateRelationMutationEntry(contract, field, directive, directiveValue, directivePath, issues);
|
|
748
|
+
validateRelationMutationEntry(contract, field, directive, directiveValue, directivePath, issues, transactionReferences);
|
|
732
749
|
}
|
|
733
750
|
}
|
|
734
751
|
function validateMutationData(contract, resourceName, data, stage, scope, path, issues, transactionReferences = false) {
|
|
@@ -752,7 +769,7 @@ function validateMutationData(contract, resourceName, data, stage, scope, path,
|
|
|
752
769
|
validateScalarMutation(fieldName, field, value, stage, fieldPath, issues, transactionReferences);
|
|
753
770
|
}
|
|
754
771
|
else {
|
|
755
|
-
validateRelationMutation(contract, fieldName, field, value, stage, scope, fieldPath, issues);
|
|
772
|
+
validateRelationMutation(contract, fieldName, field, value, stage, scope, fieldPath, issues, transactionReferences);
|
|
756
773
|
}
|
|
757
774
|
}
|
|
758
775
|
}
|
|
@@ -830,6 +847,7 @@ export function validateOperationArguments(contract, request, options) {
|
|
|
830
847
|
const state = {
|
|
831
848
|
issues,
|
|
832
849
|
structuralRoot: ["arguments", "where"],
|
|
850
|
+
transactionReferences: options?.transactionReferences === true,
|
|
833
851
|
booleanFilterNodes: 0,
|
|
834
852
|
nestingExceeded: false,
|
|
835
853
|
booleanNodesExceeded: false,
|