@aventara/core 1.0.0-rc.1 → 1.0.0-rc.10
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 +943 -16
- package/ERRORS.md +142 -0
- package/README.md +274 -16
- package/dist/adapters/adapter-discovery-diagnostic.guidance.d.ts +6 -0
- package/dist/adapters/adapter-discovery-diagnostic.guidance.js +7 -0
- package/dist/adapters/adapter-field.d.ts +22 -0
- package/dist/adapters/adapter-identifier.d.ts +9 -0
- package/dist/adapters/adapter-identifier.js +6 -1
- package/dist/adapters/adapter-model.d.ts +9 -0
- package/dist/adapters/adapter-operation.d.ts +18 -3
- package/dist/adapters/adapter-resource.d.ts +5 -0
- package/dist/adapters/adapter.interface.d.ts +10 -0
- package/dist/avz/avz.d.ts +1 -1
- package/dist/avz/json-shape.registry.d.ts +2 -1
- package/dist/compiler/contract-compiler-diagnostic.guidance.d.ts +6 -0
- package/dist/compiler/contract-compiler-diagnostic.guidance.js +97 -0
- package/dist/compiler/contract.compiler.d.ts +6 -0
- package/dist/compiler/contract.compiler.js +227 -24
- package/dist/compiler/managed-elsewhere.projector.d.ts +52 -0
- package/dist/compiler/managed-elsewhere.projector.js +179 -0
- package/dist/compiler/managed-elsewhere.validator.d.ts +9 -0
- package/dist/compiler/managed-elsewhere.validator.js +74 -0
- package/dist/config/computed-fields.d.ts +62 -0
- package/dist/config/computed-fields.js +73 -0
- package/dist/config/config-diagnostic.guidance.d.ts +6 -0
- package/dist/config/config-diagnostic.guidance.js +32 -0
- package/dist/config/config.resolver.d.ts +24 -0
- package/dist/config/config.resolver.js +65 -0
- package/dist/config/config.validator.js +222 -8
- package/dist/config/define-resource.d.ts +1 -5
- package/dist/config/entrypoint.normalizer.d.ts +3 -2
- package/dist/config/exact-framework-config.d.ts +67 -22
- package/dist/config/field-compute.resolver.d.ts +2 -0
- package/dist/config/field-compute.resolver.js +8 -0
- package/dist/config/framework-config.d.ts +53 -15
- package/dist/config/framework-resources-config.d.ts +25 -14
- package/dist/config/pipeline-config.d.ts +4 -4
- package/dist/config/pipeline-tree.resolver.d.ts +2 -2
- package/dist/contracts/access-route.rules.d.ts +10 -0
- package/dist/contracts/access-route.rules.js +45 -0
- package/dist/contracts/capability.d.ts +26 -1
- package/dist/contracts/capability.js +20 -0
- package/dist/contracts/client-contract-structure.validator.d.ts +301 -89
- package/dist/contracts/client-contract-structure.validator.js +37 -2
- package/dist/contracts/contract-access.d.ts +29 -0
- package/dist/contracts/contract-access.js +1 -0
- package/dist/contracts/contract-canonicalizer.d.ts +9 -1
- package/dist/contracts/contract-canonicalizer.js +30 -4
- package/dist/contracts/contract-hash.d.ts +0 -1
- package/dist/contracts/contract-hash.js +1 -1
- package/dist/contracts/contract.d.ts +27 -1
- package/dist/contracts/field.d.ts +58 -1
- package/dist/contracts/json-schema.projector.d.ts +11 -0
- package/dist/contracts/json-schema.projector.js +78 -0
- package/dist/contracts/scalar-value-type.d.ts +3 -1
- package/dist/framework/access-facade.d.ts +116 -0
- package/dist/framework/access-facade.js +120 -0
- package/dist/framework/contract-view.d.ts +120 -16
- package/dist/framework/framework-construction.error.d.ts +14 -4
- package/dist/framework/framework-construction.error.js +18 -2
- package/dist/framework/framework.d.ts +26 -5
- package/dist/framework/framework.factory.d.ts +1 -1
- package/dist/framework/framework.factory.js +115 -23
- package/dist/framework/operation-facade.d.ts +80 -13
- package/dist/framework/operation-facade.js +2 -1
- package/dist/index.d.ts +17 -5
- package/dist/index.js +1 -0
- package/dist/internal.d.ts +7 -2
- package/dist/internal.js +6 -0
- package/dist/operations/database-refusal.d.ts +51 -0
- package/dist/operations/database-refusal.js +45 -0
- package/dist/operations/operation-arguments.d.ts +148 -60
- package/dist/operations/operation-call.d.ts +9 -5
- package/dist/operations/operation-result.d.ts +6 -4
- package/dist/operations/operation-validator-core.js +159 -36
- package/dist/operations/operation-validator.d.ts +1 -1
- package/dist/operations/structural-limits.walker.d.ts +1 -1
- package/dist/operations/validation-code.guidance.d.ts +6 -0
- package/dist/operations/validation-code.guidance.js +90 -0
- package/dist/operations/write-scope.resolver.d.ts +4 -0
- package/dist/operations/write-scope.resolver.js +2 -0
- package/dist/policy/access-provider.interface.d.ts +91 -0
- package/dist/policy/access-provider.interface.js +1 -0
- package/dist/policy/access-provider.registry.d.ts +17 -0
- package/dist/policy/access-provider.registry.js +15 -0
- package/dist/policy/access-question.d.ts +20 -0
- package/dist/policy/access-question.js +1 -0
- package/dist/policy/access-question.registry.d.ts +5 -0
- package/dist/policy/access-question.registry.js +19 -0
- package/dist/policy/access-question.runtime.d.ts +36 -0
- package/dist/policy/access-question.runtime.js +297 -0
- package/dist/policy/access-verb.table.d.ts +56 -0
- package/dist/policy/access-verb.table.js +21 -0
- package/dist/policy/access-verbs.d.ts +46 -0
- package/dist/policy/access-verbs.js +1 -0
- package/dist/policy/policy-admission.d.ts +20 -0
- package/dist/policy/policy-admission.js +409 -0
- package/dist/policy/policy-after-update.runtime.d.ts +79 -0
- package/dist/policy/policy-after-update.runtime.js +208 -0
- package/dist/policy/policy-condition.d.ts +15 -0
- package/dist/policy/policy-condition.js +36 -0
- package/dist/policy/policy-engine.d.ts +205 -0
- package/dist/policy/policy-engine.js +1 -0
- package/dist/policy/policy-named-rows.d.ts +18 -0
- package/dist/policy/policy-named-rows.js +51 -0
- package/dist/policy/policy-nested-write.runtime.d.ts +44 -0
- package/dist/policy/policy-nested-write.runtime.js +545 -0
- package/dist/policy/policy-read.runtime.d.ts +81 -0
- package/dist/policy/policy-read.runtime.js +503 -0
- package/dist/policy/policy-reference-write.runtime.d.ts +51 -0
- package/dist/policy/policy-reference-write.runtime.js +345 -0
- package/dist/policy/policy-request.d.ts +41 -0
- package/dist/policy/policy-request.js +63 -0
- package/dist/policy/policy-session.d.ts +106 -0
- package/dist/policy/policy-session.js +295 -0
- package/dist/policy/policy-startup.validator.d.ts +10 -0
- package/dist/policy/policy-startup.validator.js +112 -0
- package/dist/policy/policy-write.runtime.d.ts +39 -0
- package/dist/policy/policy-write.runtime.js +532 -0
- package/dist/prebuilt/core-version.generated.d.ts +2 -0
- package/dist/prebuilt/core-version.generated.js +1 -0
- package/dist/prebuilt/prebuilt-changes.d.ts +29 -0
- package/dist/prebuilt/prebuilt-changes.js +65 -0
- package/dist/prebuilt/prebuilt-contracts.d.ts +40 -0
- package/dist/prebuilt/prebuilt-contracts.emitter.d.ts +16 -0
- package/dist/prebuilt/prebuilt-contracts.emitter.js +50 -0
- package/dist/prebuilt/prebuilt-contracts.js +1 -0
- package/dist/prebuilt/prebuilt-contracts.loader.d.ts +19 -0
- package/dist/prebuilt/prebuilt-contracts.loader.js +77 -0
- package/dist/prebuilt/prebuilt-inputs.fingerprint.d.ts +16 -0
- package/dist/prebuilt/prebuilt-inputs.fingerprint.js +229 -0
- package/dist/protocol/absent-route.responder.d.ts +9 -27
- package/dist/protocol/absent-route.responder.js +36 -3
- package/dist/protocol/contract-document.responder.d.ts +2 -1
- package/dist/protocol/http-request.decoder.d.ts +19 -3
- package/dist/protocol/http-request.decoder.js +24 -1
- package/dist/protocol/http-request.reader.d.ts +6 -3
- package/dist/protocol/http-request.reader.js +1 -0
- package/dist/protocol/http-response.encoder.js +2 -2
- package/dist/protocol/protocol-headers.d.ts +3 -3
- package/dist/protocol/protocol-surface.d.ts +6 -1
- package/dist/protocol/protocol-surface.js +7 -0
- package/dist/protocol/protocol.binder.d.ts +16 -1
- package/dist/protocol/protocol.binder.js +4 -1
- package/dist/protocol/protocol.handler.d.ts +12 -1
- package/dist/protocol/protocol.handler.js +86 -17
- package/dist/runtime/caller-data.copier.d.ts +18 -3
- package/dist/runtime/caller-data.copier.js +21 -8
- package/dist/runtime/caller-data.door.d.ts +13 -6
- package/dist/runtime/computed-read-runtime.d.ts +6 -1
- package/dist/runtime/computed-read-runtime.js +232 -45
- package/dist/runtime/computed-value.error.d.ts +3 -2
- package/dist/runtime/computed-value.error.js +3 -2
- package/dist/runtime/context-executor.runtime.d.ts +4 -3
- package/dist/runtime/context-executor.runtime.js +4 -2
- package/dist/runtime/core-class.brand.d.ts +10 -0
- package/dist/runtime/core-class.brand.js +21 -0
- package/dist/runtime/create-requirement.d.ts +31 -5
- package/dist/runtime/create-requirement.js +129 -21
- package/dist/runtime/decimal.d.ts +14 -0
- package/dist/runtime/decimal.js +21 -0
- package/dist/runtime/diagnostics-reporter.d.ts +44 -9
- package/dist/runtime/diagnostics-reporter.js +13 -1
- package/dist/runtime/error-boundary.d.ts +9 -2
- package/dist/runtime/error-boundary.js +12 -0
- package/dist/runtime/error-guidance.d.ts +12 -0
- package/dist/runtime/error-guidance.js +1 -0
- package/dist/runtime/error.catalog.d.ts +49 -0
- package/dist/runtime/error.catalog.js +49 -0
- package/dist/runtime/execution-options.d.ts +8 -0
- package/dist/runtime/field-check.evaluator.d.ts +0 -2
- package/dist/runtime/field-check.evaluator.js +1 -1
- package/dist/runtime/field-compute.d.ts +11 -10
- package/dist/runtime/field-stage.runtime.d.ts +3 -1
- package/dist/runtime/field-stage.runtime.js +8 -4
- package/dist/runtime/field-validator.runtime.d.ts +19 -1
- package/dist/runtime/field-validator.runtime.js +47 -8
- package/dist/runtime/framework-error.js +9 -0
- package/dist/runtime/framework-warning.emitter.d.ts +6 -0
- package/dist/runtime/framework-warning.emitter.js +8 -0
- package/dist/runtime/json-value.d.ts +10 -5
- package/dist/runtime/level-lifecycle.runtime.d.ts +4 -3
- package/dist/runtime/level-lifecycle.runtime.js +3 -5
- package/dist/runtime/mutation-planner.d.ts +1 -6
- package/dist/runtime/mutation-planner.js +3 -14
- package/dist/runtime/operation-code.guidance.d.ts +6 -0
- package/dist/runtime/operation-code.guidance.js +167 -0
- package/dist/runtime/operation-request.d.ts +16 -9
- package/dist/runtime/operation-runtime.d.ts +35 -17
- package/dist/runtime/operation-runtime.js +220 -49
- package/dist/runtime/outcome-mapper.d.ts +2 -1
- package/dist/runtime/output-validator.d.ts +1 -1
- package/dist/runtime/owned-execution.registry.d.ts +13 -3
- package/dist/runtime/pipe-output.validator.d.ts +10 -0
- package/dist/runtime/pipe-output.validator.js +4 -2
- package/dist/runtime/pipeline.d.ts +47 -22
- package/dist/runtime/readonly-value.d.ts +20 -5
- package/dist/runtime/readonly-value.js +74 -26
- package/dist/runtime/referential-action.d.ts +1 -1
- package/dist/runtime/scalar-runtime.d.ts +4 -11
- package/dist/runtime/scalar-runtime.js +91 -22
- package/dist/runtime/unsent-value.normalizer.d.ts +15 -0
- package/dist/runtime/unsent-value.normalizer.js +128 -0
- package/dist/transactions/operation-arguments-encoder.js +8 -3
- package/dist/transactions/operation-fingerprint.js +2 -2
- package/dist/transactions/sql-statement.d.ts +10 -2
- package/dist/transactions/sql-statement.validator.d.ts +2 -2
- package/dist/transactions/sql-statement.validator.js +38 -5
- package/dist/transactions/transaction-envelope.d.ts +5 -4
- package/dist/transactions/transaction-integrity-error.js +2 -0
- package/dist/transactions/transaction-plan-assembler.d.ts +12 -5
- package/dist/transactions/transaction-plan-assembler.js +48 -10
- package/dist/transactions/transaction-plan-validator.d.ts +23 -7
- package/dist/transactions/transaction-plan-validator.js +27 -1
- package/dist/transactions/transaction-reference-resolver.d.ts +3 -2
- package/dist/transactions/transaction-reference-validator.d.ts +43 -3
- package/dist/transactions/transaction-reference-validator.js +83 -57
- package/dist/transactions/transaction-reference.d.ts +1 -1
- package/dist/transactions/transaction-reference.js +5 -0
- package/dist/transactions/transaction-request.d.ts +8 -8
- package/dist/transactions/transaction-runtime.d.ts +5 -2
- package/dist/transactions/transaction-runtime.js +79 -27
- package/dist/transactions/transaction-settlement.runtime.d.ts +4 -3
- package/dist/transactions/transaction-slot-path-error.js +2 -0
- package/dist/transactions/transaction-stage.runtime.d.ts +5 -3
- package/dist/transactions/transaction-stage.runtime.js +7 -4
- package/package.json +6 -5
- package/src/runtime/field-check.evaluator.ts +1 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export const DATABASE_REFUSALS = {
|
|
2
|
+
tooLong: {
|
|
3
|
+
code: "V1004",
|
|
4
|
+
message: "The database refused this value: it is longer than the database can hold for its column.",
|
|
5
|
+
},
|
|
6
|
+
outOfRange: {
|
|
7
|
+
code: "V1004",
|
|
8
|
+
message: "The database refused this value: it is outside the range its column can hold.",
|
|
9
|
+
},
|
|
10
|
+
datetimeOutOfRange: {
|
|
11
|
+
code: "V1004",
|
|
12
|
+
message: "The database refused this value: the date and time is outside the range the database can hold.",
|
|
13
|
+
},
|
|
14
|
+
divisionByZero: {
|
|
15
|
+
code: "V1004",
|
|
16
|
+
message: "The database refused this value: it divides by zero.",
|
|
17
|
+
},
|
|
18
|
+
computedNull: {
|
|
19
|
+
code: "V1004",
|
|
20
|
+
message: "The database refused this value: the write computes no value for a column that requires one, as a division by zero does.",
|
|
21
|
+
},
|
|
22
|
+
invalidInput: {
|
|
23
|
+
code: "V1001",
|
|
24
|
+
message: "The database refused this value: it is not valid input for its column's type.",
|
|
25
|
+
},
|
|
26
|
+
nulInText: {
|
|
27
|
+
code: "V1001",
|
|
28
|
+
message: "The database refused this value: its text cannot contain the NUL character (U+0000).",
|
|
29
|
+
},
|
|
30
|
+
nulInJson: {
|
|
31
|
+
code: "V1001",
|
|
32
|
+
message: "The database refused this value: its JSON cannot contain the NUL character (U+0000).",
|
|
33
|
+
},
|
|
34
|
+
trailingEscape: {
|
|
35
|
+
code: "V1001",
|
|
36
|
+
message: "The database refused this value: a text match cannot end with the escape character \\.",
|
|
37
|
+
},
|
|
38
|
+
backReference: {
|
|
39
|
+
code: "V1012",
|
|
40
|
+
message: "The data source refused this nested write: a record written through a relation cannot write that relation or its reference fields back.",
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
export function isDatabaseRefusalMessage(code, message) {
|
|
44
|
+
return Object.values(DATABASE_REFUSALS).some((refusal) => refusal.code === code && refusal.message === message);
|
|
45
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AvProjectionScope, AvRelationMutationDirective, AvScalarFilterOperator, AvScalarMutationDirective, AvWriteScope } from "../contracts/capability.js";
|
|
1
|
+
import type { AvProjectionScope, AvRelationMutationDirective, AvScalarFilterOperator, AvScalarMutationDirective, AvWriteScope, ScalarFilterMode, ToOneRelinkDirective, ToOneRewriteDirective } from "../contracts/capability.js";
|
|
2
2
|
import type { AvContract } from "../contracts/contract.js";
|
|
3
3
|
import type { AvProjectionScopes, AvScalarField } from "../contracts/field.js";
|
|
4
4
|
import type { AvScalarValueType, FieldAtom, ScalarForms } from "../contracts/scalar-value-type.js";
|
|
@@ -82,13 +82,8 @@ type SlotReference<C extends AvContract, K extends AvResourceKey<C>, F extends A
|
|
|
82
82
|
* read a JSON object as the operators, so their value forms leave it out.
|
|
83
83
|
*/
|
|
84
84
|
type JsonObject = Extract<AvJsonValue, {
|
|
85
|
-
readonly [key: string]: AvJsonValue;
|
|
85
|
+
readonly [key: string]: AvJsonValue | undefined;
|
|
86
86
|
}>;
|
|
87
|
-
/**
|
|
88
|
-
* The field-independent shape of one scalar filter: any value, or an object of the
|
|
89
|
-
* operator vocabulary.
|
|
90
|
-
*/
|
|
91
|
-
export type ScalarFilterInput = unknown | Readonly<Partial<Record<AvScalarFilterOperator, unknown>>>;
|
|
92
87
|
/**
|
|
93
88
|
* A scalar filter's shorthand equality value: the field's value, minus a JSON
|
|
94
89
|
* object.
|
|
@@ -106,14 +101,17 @@ type FieldSlotReferences<C extends AvContract, K extends AvResourceKey<C>, F ext
|
|
|
106
101
|
* whole value; `in`, `notIn`, `hasEvery` and `hasSome` take a list of entries;
|
|
107
102
|
* `has` one entry; a `json` field's `string*`/`array*` operand a
|
|
108
103
|
* {@link AvJsonValue}; `not` a nested operator object of the same operators, or
|
|
109
|
-
* a value where `equals` is one of them. `mode
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
104
|
+
* a value where `equals` is one of them. `mode` takes one of the modes the
|
|
105
|
+
* field offers at this level (`LevelMode`), `isEmpty` a boolean, `path` a list of
|
|
106
|
+
* JSON keys and a `json` field's `string*` operand a string: none of these is a
|
|
107
|
+
* value of the field. Only `equals`, `not` and the `json` `array*` operands take
|
|
108
|
+
* `null`. Inside a transaction plan every
|
|
109
|
+
* operand but `mode`, `isEmpty`, `path` and the `json` ones may be a `$ref` of
|
|
110
|
+
* the shape it holds (`References`).
|
|
113
111
|
*/
|
|
114
|
-
type
|
|
112
|
+
export type AvScalarFilterOperands<Value, Atom, Json, References extends Readonly<Record<TransactionSlotShape, unknown>>, Operator extends AvScalarFilterOperator, Mode extends ScalarFilterMode, PathMode extends ScalarFilterMode, LevelMode extends ScalarFilterMode> = {
|
|
115
113
|
equals: Value | References["value"];
|
|
116
|
-
not:
|
|
114
|
+
not: NegatedValue<Value, References, Operator> | ScalarFilterOperators<Value, Atom, Json, References, Operator, Mode, PathMode>;
|
|
117
115
|
in: readonly Atom[] | References["entries"];
|
|
118
116
|
notIn: readonly Atom[] | References["entries"];
|
|
119
117
|
lt: Exclude<Value, null> | References["nonNullValue"];
|
|
@@ -123,26 +121,67 @@ type ScalarFilterOperands<Value, Atom, Json, References extends Readonly<Record<
|
|
|
123
121
|
contains: Exclude<Value, null> | References["nonNullValue"];
|
|
124
122
|
startsWith: Exclude<Value, null> | References["nonNullValue"];
|
|
125
123
|
endsWith: Exclude<Value, null> | References["nonNullValue"];
|
|
126
|
-
mode:
|
|
124
|
+
mode: LevelMode;
|
|
127
125
|
has: Atom | References["entry"];
|
|
128
126
|
hasEvery: readonly Atom[] | References["entries"];
|
|
129
127
|
hasSome: readonly Atom[] | References["entries"];
|
|
130
|
-
isEmpty:
|
|
131
|
-
path:
|
|
132
|
-
stringContains:
|
|
133
|
-
stringStartsWith:
|
|
134
|
-
stringEndsWith:
|
|
128
|
+
isEmpty: boolean;
|
|
129
|
+
path: readonly string[];
|
|
130
|
+
stringContains: string;
|
|
131
|
+
stringStartsWith: string;
|
|
132
|
+
stringEndsWith: string;
|
|
135
133
|
arrayContains: Json;
|
|
136
134
|
arrayStartsWith: Json;
|
|
137
135
|
arrayEndsWith: Json;
|
|
138
136
|
};
|
|
139
137
|
/**
|
|
140
138
|
* A scalar filter's operator object: the operators `Operator` names — the ones
|
|
141
|
-
* the field's `filter` member advertises — each with its operand.
|
|
139
|
+
* the field's `filter` member advertises — each with its operand. Where `path`
|
|
140
|
+
* is one of them, an object that names it takes `PathMode`, and one that does
|
|
141
|
+
* not takes `Mode`. An object that names `mode` or `path` names a comparing
|
|
142
|
+
* operator beside it.
|
|
143
|
+
*/
|
|
144
|
+
type ScalarFilterOperators<Value, Atom, Json, References extends Readonly<Record<TransactionSlotShape, unknown>>, Operator extends AvScalarFilterOperator, Mode extends ScalarFilterMode, PathMode extends ScalarFilterMode> = ScalarFilterLevel<ReadonlyOperands<Value, Atom, Json, References, Operator, Mode, PathMode, Mode>, Operator, Mode, NegatedValue<Value, References, Operator>, "path" extends Operator ? {
|
|
145
|
+
readonly path?: never;
|
|
146
|
+
} : unknown> | ("path" extends Operator ? ScalarFilterOperatorsAtPath<ReadonlyOperands<Value, Atom, Json, References, Operator, Mode, PathMode, PathMode>, Operator, PathMode, NegatedValue<Value, References, Operator>> : never);
|
|
147
|
+
/** {@link AvScalarFilterOperands}, each operand read-only. */
|
|
148
|
+
type ReadonlyOperands<Value, Atom, Json, References extends Readonly<Record<TransactionSlotShape, unknown>>, Operator extends AvScalarFilterOperator, Mode extends ScalarFilterMode, PathMode extends ScalarFilterMode, LevelMode extends ScalarFilterMode> = Readonly<AvScalarFilterOperands<Value, Atom, Json, References, Operator, Mode, PathMode, LevelMode>>;
|
|
149
|
+
/** The operators of a level that compare something: all but `mode` and `path`. */
|
|
150
|
+
type ComparingOperator<Operator extends AvScalarFilterOperator> = Exclude<Operator, "mode" | "path">;
|
|
151
|
+
/** `not`'s value arm: equality negated, offered only where `equals` is. */
|
|
152
|
+
type NegatedValue<Value, References extends Readonly<Record<TransactionSlotShape, unknown>>, Operator extends AvScalarFilterOperator> = "equals" extends Operator ? Exclude<Value, JsonObject> | References["value"] : never;
|
|
153
|
+
/** A level's comparing operators, each optional. */
|
|
154
|
+
type ComparingOperators<Operands extends Readonly<Record<AvScalarFilterOperator, unknown>>, Operator extends AvScalarFilterOperator> = Partial<Pick<Operands, ComparingOperator<Operator>>>;
|
|
155
|
+
/**
|
|
156
|
+
* A level's comparing operators with at least one of them present; `not` is
|
|
157
|
+
* one only with a value (an object under `not` compares at its own level).
|
|
158
|
+
*/
|
|
159
|
+
type SomeComparingOperator<Operands extends Readonly<Record<AvScalarFilterOperator, unknown>>, Operator extends AvScalarFilterOperator, Negated> = ({
|
|
160
|
+
[Key in Exclude<ComparingOperator<Operator>, "not">]-?: Pick<Operands, Key>;
|
|
161
|
+
}[Exclude<ComparingOperator<Operator>, "not">] & ComparingOperators<Operands, Operator>) | ("not" extends Operator ? {
|
|
162
|
+
readonly not: Negated;
|
|
163
|
+
} & Partial<Pick<Operands, Exclude<ComparingOperator<Operator>, "not">>> : never);
|
|
164
|
+
/**
|
|
165
|
+
* One operator object that names no `path`: without `mode`, any of its comparing
|
|
166
|
+
* operators; with `mode` (one of `Mode`), at least one of them.
|
|
142
167
|
*/
|
|
143
|
-
type
|
|
168
|
+
type ScalarFilterLevel<Operands extends Readonly<Record<AvScalarFilterOperator, unknown>>, Operator extends AvScalarFilterOperator, Mode extends ScalarFilterMode, Negated, PathKey> = ("mode" extends Operator ? (ComparingOperators<Operands, Operator> & {
|
|
169
|
+
readonly mode?: never;
|
|
170
|
+
}) | (SomeComparingOperator<Operands, Operator, Negated> & {
|
|
171
|
+
readonly mode?: Mode;
|
|
172
|
+
}) : ComparingOperators<Operands, Operator>) & PathKey;
|
|
173
|
+
/** An operator object that names `path`: `PathMode`, and a comparing operator. */
|
|
174
|
+
type ScalarFilterOperatorsAtPath<Operands extends Readonly<Record<AvScalarFilterOperator, unknown>>, Operator extends AvScalarFilterOperator, PathMode extends ScalarFilterMode, Negated> = SomeComparingOperator<Operands, Operator, Negated> & {
|
|
175
|
+
readonly path: readonly string[];
|
|
176
|
+
} & ("mode" extends Operator ? {
|
|
177
|
+
readonly mode?: PathMode;
|
|
178
|
+
} : unknown);
|
|
144
179
|
/** The filter operators field `F` advertises: `never` when it advertises none. */
|
|
145
180
|
type ScalarFilterOperatorAt<C extends AvContract, K extends AvResourceKey<C>, F extends AvFieldKey<C, K>> = Extract<CapabilityTokens<C, K, F, "filter", UnrestrictedProjection>, AvScalarFilterOperator>;
|
|
181
|
+
/** The `mode` operands field `F` takes in an operator object without `path`. */
|
|
182
|
+
type ScalarFilterModeAt<C extends AvContract, K extends AvResourceKey<C>, F extends AvFieldKey<C, K>> = "default" | Extract<CapabilityTokens<C, K, F, "filterModes", UnrestrictedProjection>, ScalarFilterMode>;
|
|
183
|
+
/** The `mode` operands field `F` takes in an operator object that names `path`. */
|
|
184
|
+
type ScalarPathFilterModeAt<C extends AvContract, K extends AvResourceKey<C>, F extends AvFieldKey<C, K>> = "pathFilterModes" extends keyof CapabilitiesOf<C, K, F> ? "default" | Extract<CapabilityTokens<C, K, F, "pathFilterModes", UnrestrictedProjection>, ScalarFilterMode> : ScalarFilterModeAt<C, K, F>;
|
|
146
185
|
/**
|
|
147
186
|
* One scalar field's filter under `Forms`: a shorthand value where the field
|
|
148
187
|
* advertises `equals`, or an object of the operators it advertises. Inside a
|
|
@@ -153,7 +192,7 @@ type ScalarFilterOperatorAt<C extends AvContract, K extends AvResourceKey<C>, F
|
|
|
153
192
|
*/
|
|
154
193
|
type ScalarFilterFor<C extends AvContract, K extends AvResourceKey<C>, F extends AvFieldKey<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = ("equals" extends ScalarFilterOperatorAt<C, K, F> ? ScalarFilterShorthand<ScalarValueAt<C, K, F, Forms>> | SlotReference<C, K, F, ReferenceForms, "value"> : never) | ScalarFilterOperators<ScalarValueAt<C, K, F, Forms>, ScalarAtomAt<C, K, F, Forms>, ScalarFieldAt<C, K, F>["type"] extends {
|
|
155
194
|
readonly scalar: "json";
|
|
156
|
-
} ? AvJsonValue : ScalarValueAt<C, K, F, Forms>, FieldSlotReferences<C, K, F, ReferenceForms>, ScalarFilterOperatorAt<C, K, F>>;
|
|
195
|
+
} ? AvJsonValue : ScalarValueAt<C, K, F, Forms>, FieldSlotReferences<C, K, F, ReferenceForms>, ScalarFilterOperatorAt<C, K, F>, ScalarFilterModeAt<C, K, F>, ScalarPathFilterModeAt<C, K, F>>;
|
|
157
196
|
/** The scalar fields of `K` a `where` can name: those advertising an operator. */
|
|
158
197
|
type ScalarFilterableKey<C extends AvContract, K extends AvResourceKey<C>> = {
|
|
159
198
|
[F in ScalarFieldKeyOf<C, K>]: [ScalarFilterOperatorAt<C, K, F>] extends [
|
|
@@ -180,7 +219,7 @@ export type AvWhereInput<C extends AvContract, K extends AvResourceKey<C>, Forms
|
|
|
180
219
|
AND?: readonly AvWhereInput<C, K, Forms, ReferenceForms>[];
|
|
181
220
|
OR?: readonly AvWhereInput<C, K, Forms, ReferenceForms>[];
|
|
182
221
|
NOT?: AvWhereInput<C, K, Forms, ReferenceForms>;
|
|
183
|
-
} & ScalarWhereFields<C, K, Forms, ReferenceForms> & RelationWhereFields<C, K, Forms, ReferenceForms
|
|
222
|
+
}> & ScalarWhereFields<C, K, Forms, ReferenceForms> & RelationWhereFields<C, K, Forms, ReferenceForms>;
|
|
184
223
|
type ActiveIdentifier<C extends AvContract, K extends AvResourceKey<C>> = C["resources"][K]["identifiers"][number];
|
|
185
224
|
type IdentifierObject<C extends AvContract, K extends AvResourceKey<C>, I extends readonly string[], Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
|
|
186
225
|
[F in Extract<I[number], AvFieldKey<C, K>>]: ScalarValueAt<C, K, F, Forms> | SlotReference<C, K, F, ReferenceForms, "nonNullValue">;
|
|
@@ -291,15 +330,11 @@ type IncludeRelationProjectionEntry<C extends AvContract, K extends AvResourceKe
|
|
|
291
330
|
* One entry of a `select` argument, at one projection position. The default is
|
|
292
331
|
* the unrestricted position.
|
|
293
332
|
*/
|
|
294
|
-
export type AvProjectionEntry<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvProjectionScope = 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);
|
|
333
|
+
export type AvProjectionEntry<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvProjectionScope = UnrestrictedProjection, AllowCount extends boolean = false, Forms extends ScalarForms = UnstatedForms> = SelectableScalarKey<C, K, Scope> | SelectableRelationKey<C, K, Scope> | SelectRelationProjectionEntry<C, K, Scope, Forms> | "$defaults" | (AllowCount extends true ? "$count" : never);
|
|
295
334
|
/** A `select` argument: the fields to return. */
|
|
296
335
|
export type AvSelectInput<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvProjectionScope = UnrestrictedProjection, AllowCount extends boolean = false, Forms extends ScalarForms = UnstatedForms> = readonly AvProjectionEntry<C, K, Scope, AllowCount, Forms>[];
|
|
297
336
|
/** An `include` argument: the relations to return with each row. */
|
|
298
337
|
export type AvIncludeInput<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvProjectionScope = UnrestrictedProjection, Forms extends ScalarForms = UnstatedForms> = readonly (IncludeRelationKey<C, K, Scope> | IncludeRelationProjectionEntry<C, K, Scope, Forms>)[];
|
|
299
|
-
/** A scalar update directive and its operand, such as `{ $increment: 1 }`. */
|
|
300
|
-
export type ScalarMutationAction = Readonly<Partial<Record<AvScalarMutationDirective, unknown>>>;
|
|
301
|
-
/** A relation write: one or more relation directives and their payloads. */
|
|
302
|
-
export type RelationMutationAction = Readonly<Partial<Record<AvRelationMutationDirective, unknown>>>;
|
|
303
338
|
/** The scalar fields writable at one stage and write position. */
|
|
304
339
|
type WritableScalarKey<C extends AvContract, K extends AvResourceKey<C>, Stage extends "create" | "update", Scope extends AvWriteScope> = KeysWithCapability<C, K, ScalarFieldKeyOf<C, K>, Stage, Scope>;
|
|
305
340
|
/**
|
|
@@ -312,29 +347,29 @@ type ManyOrOne<C extends AvContract, K extends AvResourceKey<C>, F extends Relat
|
|
|
312
347
|
* A `where` of plain fields: each scalar field's filter, combined with
|
|
313
348
|
* `AND`/`OR`/`NOT`, and no relation filter at any depth.
|
|
314
349
|
*/
|
|
315
|
-
type
|
|
316
|
-
AND?: readonly
|
|
317
|
-
OR?: readonly
|
|
318
|
-
NOT?:
|
|
319
|
-
} & ScalarWhereFields<C, K, Forms, ReferenceForms
|
|
350
|
+
export type AvScalarWhereInput<C extends AvContract, K extends AvResourceKey<C>, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never> = Readonly<{
|
|
351
|
+
AND?: readonly AvScalarWhereInput<C, K, Forms, ReferenceForms>[];
|
|
352
|
+
OR?: readonly AvScalarWhereInput<C, K, Forms, ReferenceForms>[];
|
|
353
|
+
NOT?: AvScalarWhereInput<C, K, Forms, ReferenceForms>;
|
|
354
|
+
}> & ScalarWhereFields<C, K, Forms, ReferenceForms>;
|
|
320
355
|
/**
|
|
321
356
|
* The `where` of a nested `$update` or `$delete` through relation `F`: plain fields
|
|
322
357
|
* only where the relation states `nestedWriteFilter: "scalar"`, any filter otherwise.
|
|
323
358
|
*/
|
|
324
359
|
type NestedWriteWhereInput<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = CapabilitiesOf<C, K, F> extends {
|
|
325
360
|
readonly nestedWriteFilter: "scalar";
|
|
326
|
-
} ?
|
|
361
|
+
} ? AvScalarWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms> : AvWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>;
|
|
327
362
|
type ConnectOrCreateEntry<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
|
|
328
363
|
where: AvUniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>;
|
|
329
364
|
create: AvCreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms, readonly [K, F]>;
|
|
330
365
|
}>;
|
|
331
366
|
type ToOneUpdateEntry<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
|
|
332
367
|
where?: NestedWriteWhereInput<C, K, F, Forms, ReferenceForms>;
|
|
333
|
-
data: AvUpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms>;
|
|
368
|
+
data: AvUpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms, readonly [K, F]>;
|
|
334
369
|
}>;
|
|
335
370
|
type ToManyUpdateEntry<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
|
|
336
371
|
where: NestedWriteWhereInput<C, K, F, Forms, ReferenceForms>;
|
|
337
|
-
data: AvUpdateDataInput<C, RelationTarget<C, K, F>,
|
|
372
|
+
data: AvUpdateDataInput<C, RelationTarget<C, K, F>, "bulkWrite", Forms, ReferenceForms, readonly [K, F]>;
|
|
338
373
|
}>;
|
|
339
374
|
type ToOneDeleteEntry<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = true | Readonly<{
|
|
340
375
|
where?: NestedWriteWhereInput<C, K, F, Forms, ReferenceForms>;
|
|
@@ -345,26 +380,35 @@ type ToManyDeleteEntry<C extends AvContract, K extends AvResourceKey<C>, F exten
|
|
|
345
380
|
type ToOneUpsertEntry<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
|
|
346
381
|
where?: AvUniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>;
|
|
347
382
|
create: AvCreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms, readonly [K, F]>;
|
|
348
|
-
update: AvUpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms>;
|
|
383
|
+
update: AvUpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms, readonly [K, F]>;
|
|
349
384
|
}>;
|
|
350
385
|
type ToManyUpsertEntry<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
|
|
351
386
|
where: AvUniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>;
|
|
352
387
|
create: AvCreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms, readonly [K, F]>;
|
|
353
|
-
update: AvUpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms>;
|
|
388
|
+
update: AvUpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms, readonly [K, F]>;
|
|
354
389
|
}>;
|
|
355
390
|
type RelationDirectiveValue<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Directive extends AvRelationMutationDirective, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Directive extends "$create" ? ManyOrOne<C, K, F, AvCreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms, readonly [K, F]>> : Directive extends "$connect" ? ManyOrOne<C, K, F, AvUniqueWhereInput<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 : AvUniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms> | readonly AvUniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>[] : Directive extends "$set" ? RelationCardinality<C, K, F> extends "one" ? AvUniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms> | null : readonly AvUniqueWhereInput<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;
|
|
356
|
-
declare const NO_ADVERTISED_MEMBER: unique symbol;
|
|
357
391
|
/**
|
|
358
392
|
* A write member that advertises nothing: it accepts `{}` and refuses every key.
|
|
359
393
|
*/
|
|
360
|
-
|
|
361
|
-
readonly [
|
|
362
|
-
}
|
|
363
|
-
/** `Write`, or {@link
|
|
364
|
-
type RefuseEveryKeyWhenEmpty<Write> = [keyof Write] extends [never] ?
|
|
365
|
-
type RelationMutationActionFor<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Stage extends "create" | "update", Scope extends AvWriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = RefuseEveryKeyWhenEmpty<Readonly<Partial<{
|
|
394
|
+
export interface AvNoAdvertisedMember {
|
|
395
|
+
readonly [Symbol.unscopables]?: never;
|
|
396
|
+
}
|
|
397
|
+
/** `Write`, or {@link AvNoAdvertisedMember} when `Write` has no keys at all. */
|
|
398
|
+
type RefuseEveryKeyWhenEmpty<Write> = [keyof Write] extends [never] ? AvNoAdvertisedMember : Write;
|
|
399
|
+
type RelationMutationActionFor<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Stage extends "create" | "update", Scope extends AvWriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = RefuseEveryKeyWhenEmpty<RelinkOrRewrite<RelationCardinality<C, K, F>, Readonly<Partial<{
|
|
366
400
|
[Directive in Extract<CapabilityTokens<C, K, F, Stage, Scope>, AvRelationMutationDirective>]: RelationDirectiveValue<C, K, F, Directive, Forms, ReferenceForms>;
|
|
367
|
-
}
|
|
401
|
+
}>>>>;
|
|
402
|
+
/**
|
|
403
|
+
* A to-one relation's directive object, which either relinks the relation
|
|
404
|
+
* (`$connect`, `$create`, …) or writes the linked row (`$update`, `$upsert`),
|
|
405
|
+
* never both: the ORM would write the newly linked row.
|
|
406
|
+
*/
|
|
407
|
+
type RelinkOrRewrite<Cardinality, Directives> = [Cardinality] extends ["one"] ? [Extract<keyof Directives, ToOneRewriteDirective>] extends [never] ? Directives : [Extract<keyof Directives, ToOneRelinkDirective>] extends [never] ? Directives : (Directives & {
|
|
408
|
+
readonly [D in Extract<keyof Directives, ToOneRewriteDirective>]?: never;
|
|
409
|
+
}) | (Directives & {
|
|
410
|
+
readonly [D in Extract<keyof Directives, ToOneRelinkDirective>]?: never;
|
|
411
|
+
}) : Directives;
|
|
368
412
|
/**
|
|
369
413
|
* One scalar mutation directive's operand: one entry of the field (`$push` on a
|
|
370
414
|
* list also takes a list of them). `$unset`'s operand is passed to the adapter as
|
|
@@ -377,22 +421,55 @@ type ScalarDirectiveOperand<C extends AvContract, K extends AvResourceKey<C>, F
|
|
|
377
421
|
*/
|
|
378
422
|
type ScalarMutationActionFor<C extends AvContract, K extends AvResourceKey<C>, F extends AvFieldKey<C, K>, Stage extends "create" | "update", Scope extends AvWriteScope, Forms extends ScalarForms> = [
|
|
379
423
|
Extract<CapabilityTokens<C, K, F, Stage, Scope>, AvScalarMutationDirective>
|
|
380
|
-
] extends [never] ? never :
|
|
381
|
-
|
|
382
|
-
|
|
424
|
+
] extends [never] ? never : OneDirective<Extract<CapabilityTokens<C, K, F, Stage, Scope>, AvScalarMutationDirective>, C, K, F, Forms>;
|
|
425
|
+
type OneDirective<Tokens extends AvScalarMutationDirective, C extends AvContract, K extends AvResourceKey<C>, F extends AvFieldKey<C, K>, Forms extends ScalarForms> = {
|
|
426
|
+
[Directive in Tokens]: Readonly<{
|
|
427
|
+
[Key in Directive]: ScalarDirectiveOperand<C, K, F, Key, Forms>;
|
|
428
|
+
} & {
|
|
429
|
+
[Other in Exclude<Tokens, Directive>]?: never;
|
|
430
|
+
}>;
|
|
431
|
+
}[Tokens];
|
|
383
432
|
/**
|
|
384
433
|
* Each writable scalar takes its value under `Forms`, or a directive object of
|
|
385
434
|
* the directives it advertises at this stage — or, in a transaction plan's
|
|
386
|
-
* top-level data, a `$ref` to a source of the same type.
|
|
435
|
+
* top-level data, a `$ref` to a source of the same type. A field a create must
|
|
436
|
+
* write (`RequiredWriteKey`) is required.
|
|
387
437
|
*/
|
|
388
|
-
type ScalarMutationFields<C extends AvContract, K extends AvResourceKey<C>, Stage extends "create" | "update", Scope extends AvWriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
|
|
389
|
-
[F in
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
438
|
+
type ScalarMutationFields<C extends AvContract, K extends AvResourceKey<C>, Stage extends "create" | "update", Scope extends AvWriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms, Via extends ParentEdge = never, Keys extends AvFieldKey<C, K> = Exclude<WritableScalarKey<C, K, Stage, Scope>, LoopbackRefused<C, K, Stage, Via>>, Required extends Keys = Extract<Keys, RequiredWriteKey<C, K, Stage, Scope, Via>>> = Readonly<([Required] extends [never] ? unknown : {
|
|
439
|
+
[F in Required]: ScalarValueAt<C, K, F, Forms> | ScalarMutationActionFor<C, K, F, Stage, Scope, Forms> | SlotReference<C, K, F, ReferenceForms, "value">;
|
|
440
|
+
}) & ([Exclude<Keys, Required>] extends [never] ? unknown : {
|
|
441
|
+
[F in Exclude<Keys, Required>]?: ScalarValueAt<C, K, F, Forms> | ScalarMutationActionFor<C, K, F, Stage, Scope, Forms> | SlotReference<C, K, F, ReferenceForms, "value">;
|
|
442
|
+
})>;
|
|
443
|
+
/**
|
|
444
|
+
* Each writable relation takes the directive object it advertises at this
|
|
445
|
+
* stage. A relation a create must write (`RequiredWriteKey`) is required.
|
|
446
|
+
*/
|
|
447
|
+
type RelationMutationFields<C extends AvContract, K extends AvResourceKey<C>, Stage extends "create" | "update", Scope extends AvWriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms, Via extends ParentEdge = never, Keys extends AvFieldKey<C, K> = Exclude<WritableRelationKey<C, K, Stage, Scope>, LoopbackRefused<C, K, Stage, Via>>, Required extends Keys = Extract<Keys, RequiredWriteKey<C, K, Stage, Scope, Via>>> = Readonly<([Required] extends [never] ? unknown : {
|
|
448
|
+
[F in Required]: RelationMutationActionFor<C, K, F & RelationFieldKeyOf<C, K>, Stage, Scope, Forms, ReferenceForms>;
|
|
449
|
+
}) & ([Exclude<Keys, Required>] extends [never] ? unknown : {
|
|
450
|
+
[F in Exclude<Keys, Required>]?: RelationMutationActionFor<C, K, F & RelationFieldKeyOf<C, K>, Stage, Scope, Forms, ReferenceForms>;
|
|
451
|
+
})>;
|
|
394
452
|
/** A relation edge a nested create is reached through: `[parent, relation]`. */
|
|
395
453
|
type ParentEdge = readonly [string, string];
|
|
454
|
+
/** The other end of `Via`'s relation, as the Contract pairs it; `never` when it does not. */
|
|
455
|
+
type LoopbackOf<C extends AvContract, Via> = Via extends readonly [
|
|
456
|
+
infer Parent,
|
|
457
|
+
infer Relation
|
|
458
|
+
] ? Parent extends AvResourceKey<C> ? Relation extends keyof C["resources"][Parent]["fields"] ? C["resources"][Parent]["fields"][Relation] extends {
|
|
459
|
+
readonly inverse: infer Inverse extends string;
|
|
460
|
+
} ? Inverse : never : never : never : never;
|
|
461
|
+
/** The fields `K`'s relation `Relation` states hold its reference; `never` when it states none. */
|
|
462
|
+
type ReferenceFieldsOf<C extends AvContract, K extends AvResourceKey<C>, Relation extends string> = Relation extends keyof C["resources"][K]["fields"] ? C["resources"][K]["fields"][Relation] extends {
|
|
463
|
+
readonly referenceFields: readonly (infer Field extends string)[];
|
|
464
|
+
} ? Field : never : never;
|
|
465
|
+
/**
|
|
466
|
+
* The members a record of `K` reached through `Via` cannot write at `Stage`:
|
|
467
|
+
* the other end of `Via`'s relation and the fields that hold its reference,
|
|
468
|
+
* unless the Contract admits that relation at the `"loopback"` position.
|
|
469
|
+
*/
|
|
470
|
+
type LoopbackRefused<C extends AvContract, K extends AvResourceKey<C>, Stage extends "create" | "update", Via> = [Via] extends [never] ? never : LoopbackOf<C, Via> extends infer Loopback extends string ? [
|
|
471
|
+
Extract<Loopback, WritableRelationKey<C, K, Stage, "loopback">>
|
|
472
|
+
] extends [never] ? Loopback | ReferenceFieldsOf<C, K, Loopback> : never : never;
|
|
396
473
|
/** The names a requirement list holds; `never` when the member is absent. */
|
|
397
474
|
type RequirementNames<Requirements, Member extends PropertyKey> = Requirements extends {
|
|
398
475
|
readonly [P in Member]?: infer List;
|
|
@@ -429,13 +506,21 @@ type GroupPresence<Group, Scalars, Relations, Supplied> = Group extends readonly
|
|
|
429
506
|
}) : Present<Relation> : Present<References[number]> : unknown : unknown;
|
|
430
507
|
/** Every group of a `oneOf` tuple, each one's presence intersected. */
|
|
431
508
|
type GroupsPresence<Groups, Scalars, Relations, Supplied> = Groups extends readonly [infer Group, ...infer Rest] ? GroupPresence<Group, Scalars, Relations, Supplied> & GroupsPresence<Rest, Scalars, Relations, Supplied> : unknown;
|
|
509
|
+
/**
|
|
510
|
+
* The names a create of `K` at `Scope` must write: every `required` name it can
|
|
511
|
+
* write there, less what the parent supplies through `Via`. `never` for an
|
|
512
|
+
* update, and where the Contract states nothing.
|
|
513
|
+
*/
|
|
514
|
+
type RequiredWriteKey<C extends AvContract, K extends AvResourceKey<C>, Stage extends "create" | "update", Scope extends AvWriteScope, Via> = Stage extends "create" ? [CreateRequirementsAt<C, K>] extends [never] ? never : CreateRequirementsAt<C, K> extends infer Requirements ? string extends RequirementNames<Requirements, "required"> ? never : Exclude<Extract<RequirementNames<Requirements, "required">, WritableScalarKey<C, K, "create", Scope> | WritableRelationKey<C, K, "create", Scope>>, SuppliedThrough<Requirements, Via>> : never : never;
|
|
515
|
+
/** The members a create's two halves hold at `Scope`, reached through `Via`. */
|
|
516
|
+
type HeldCreateKey<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope, Via> = Exclude<WritableScalarKey<C, K, "create", Scope> | WritableRelationKey<C, K, "create", Scope>, LoopbackRefused<C, K, "create", Via>>;
|
|
432
517
|
/**
|
|
433
518
|
* What a create of Resource `K` at write position `Scope` must and must not
|
|
434
519
|
* write: every `required` name it can write, and one side of every `oneOf`
|
|
435
520
|
* group — less what the parent supplies when the create is nested through
|
|
436
521
|
* `Via`. `unknown` (no constraint) when the Contract states nothing.
|
|
437
522
|
*/
|
|
438
|
-
type CreateRequirementPresence<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope, Via> = [CreateRequirementsAt<C, K>] extends [never] ? unknown : CreateRequirementsAt<C, K> extends infer Requirements ? string extends RequirementNames<Requirements, "required"> ? unknown : Present<Exclude<
|
|
523
|
+
type CreateRequirementPresence<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope, Via> = [CreateRequirementsAt<C, K>] extends [never] ? unknown : CreateRequirementsAt<C, K> extends infer Requirements ? string extends RequirementNames<Requirements, "required"> ? unknown : Present<Exclude<RequiredWriteKey<C, K, "create", Scope, Via>, HeldCreateKey<C, K, Scope, Via>>> & (Requirements extends {
|
|
439
524
|
readonly oneOf?: infer Groups;
|
|
440
525
|
} ? GroupsPresence<Groups, WritableScalarKey<C, K, "create", Scope>, WritableRelationKey<C, K, "create", Scope>, SuppliedThrough<Requirements, Via>> : unknown) : unknown;
|
|
441
526
|
/**
|
|
@@ -450,9 +535,12 @@ type CreateRequirementPresence<C extends AvContract, K extends AvResourceKey<C>,
|
|
|
450
535
|
* reference fields — never both. `Via` is the `[parent, relation]` a nested
|
|
451
536
|
* create is reached through: what that parent supplies is not required.
|
|
452
537
|
*/
|
|
453
|
-
export type AvCreateDataInput<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope = UnrestrictedWrite, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never, Via extends ParentEdge = never> = RefuseEveryKeyWhenEmpty<
|
|
454
|
-
/**
|
|
455
|
-
|
|
538
|
+
export type AvCreateDataInput<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope = UnrestrictedWrite, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never, Via extends ParentEdge = never> = RefuseEveryKeyWhenEmpty<ScalarMutationFields<C, K, "create", Scope, Forms, ReferenceForms, Via>> & RefuseEveryKeyWhenEmpty<RelationMutationFields<C, K, "create", Scope, Forms, ReferenceForms, Via>> & CreateRequirementPresence<C, K, Scope, Via>;
|
|
539
|
+
/**
|
|
540
|
+
* An `update` data argument, at one write position. See {@link AvCreateDataInput};
|
|
541
|
+
* `Via` is the `[parent, relation]` a nested update is reached through.
|
|
542
|
+
*/
|
|
543
|
+
export type AvUpdateDataInput<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope = UnrestrictedWrite, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never, Via extends ParentEdge = never> = RefuseEveryKeyWhenEmpty<ScalarMutationFields<C, K, "update", Scope, Forms, ReferenceForms, Via>> & RefuseEveryKeyWhenEmpty<RelationMutationFields<C, K, "update", Scope, Forms, ReferenceForms, Via>>;
|
|
456
544
|
type QueryProjectionArgs<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvProjectionScope, Forms extends ScalarForms> = ProjectionChoice<C, K, Scope, false, Forms>;
|
|
457
545
|
/**
|
|
458
546
|
* Every standard operation's argument object, with each argument at its
|
|
@@ -55,8 +55,10 @@ export type AvOperationGrammar<C extends AvContract> = {
|
|
|
55
55
|
export type AvOperationSlot<I extends AvOperationIdentity, Result> = I["variant"] extends "first" ? Result | null : Result;
|
|
56
56
|
/** What a direct call resolves: the slot, every failure thrown. */
|
|
57
57
|
type Settled<I extends AvOperationIdentity, Result> = AvOperationSlot<I, Result>;
|
|
58
|
-
|
|
59
|
-
type
|
|
58
|
+
/** A direct call that projects: generic in its `select`/`include` literal. */
|
|
59
|
+
export type ProjectingCall<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Args, ResultForms extends ScalarForms, Options> = <const Select extends SelectOf<Args> = never, const Include extends IncludeOf<Args> = never>(...args: CallArgumentList<Omit<Args, ProjectionKey>, NoInfer<Omit<Args, ProjectionKey>> & ProjectionArgument<Select, Include>, Options>) => Promise<Settled<I, AdmittedOperationResult<C, R, I, InferredProjection<Select, Include>, ResultForms>>>;
|
|
60
|
+
/** A direct call that does not project. */
|
|
61
|
+
export type PlainCall<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Args, ResultForms extends ScalarForms, Options> = (...args: CallArgumentList<Args, Args, Options>) => Promise<Settled<I, AdmittedOperationResult<C, R, I, unknown, ResultForms>>>;
|
|
60
62
|
/**
|
|
61
63
|
* One direct call: its arguments in `Forms`, its result in `ResultForms`,
|
|
62
64
|
* resolving the slot and throwing every failure, taking `Options` per call. It is generic in its
|
|
@@ -68,9 +70,11 @@ export type AvOperationCall<C extends AvContract, R extends AvResourceKey<C>, I
|
|
|
68
70
|
* `$ref` typed in `ResultForms` — the forms the source's final data is read in, so a
|
|
69
71
|
* reference carries what its source resolves.
|
|
70
72
|
*/
|
|
71
|
-
type DeferredArguments<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Forms extends ScalarForms, ResultForms extends ScalarForms> = ReferenceableArgumentsFor<C, R, I, Forms, ResultForms>;
|
|
72
|
-
|
|
73
|
-
type
|
|
73
|
+
export type DeferredArguments<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Forms extends ScalarForms, ResultForms extends ScalarForms> = ReferenceableArgumentsFor<C, R, I, Forms, ResultForms>;
|
|
74
|
+
/** A deferred operation that projects: generic in its `select`/`include` literal. */
|
|
75
|
+
export type DeferredProjectingCall<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Args, ResultForms extends ScalarForms, Origin extends HandleOrigin> = <const Select extends SelectOf<Args> = never, const Include extends IncludeOf<Args> = never>(...args: ArgumentList<Omit<Args, ProjectionKey>, NoInfer<Omit<Args, ProjectionKey>> & ProjectionArgument<Select, Include>>) => AvOperation<AvOperationSlot<I, AdmittedOperationResult<C, R, I, InferredProjection<Select, Include>, ResultForms>>, Origin>;
|
|
76
|
+
/** A deferred operation that does not project. */
|
|
77
|
+
export type DeferredPlainCall<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Args, ResultForms extends ScalarForms, Origin extends HandleOrigin> = (...args: ArgumentList<Args, Args>) => AvOperation<AvOperationSlot<I, AdmittedOperationResult<C, R, I, unknown, ResultForms>>, Origin>;
|
|
74
78
|
/**
|
|
75
79
|
* One deferred operation: a handle typed `AvOperation<AvOperationSlot<…>, Origin>`,
|
|
76
80
|
* with `$ref` present exactly where the result is one row. A handle is not a
|
|
@@ -6,7 +6,8 @@ import type { AvOperationIdentity } from "./operation-identity.js";
|
|
|
6
6
|
type FieldOf<C extends AvContract, K extends AvResourceKey<C>, F extends AvFieldKey<C, K>> = C["resources"][K]["fields"][F];
|
|
7
7
|
/**
|
|
8
8
|
* The fields returned when no projection is given: the scalars whose `select`
|
|
9
|
-
* is exactly `true
|
|
9
|
+
* is exactly `true` and that the policy does not govern. A write-only field never
|
|
10
|
+
* appears, and a governed one appears only where a projection names it.
|
|
10
11
|
*/
|
|
11
12
|
type DefaultKey<C extends AvContract, K extends AvResourceKey<C>> = {
|
|
12
13
|
[F in AvFieldKey<C, K>]: FieldOf<C, K, F> extends {
|
|
@@ -14,6 +15,7 @@ type DefaultKey<C extends AvContract, K extends AvResourceKey<C>> = {
|
|
|
14
15
|
readonly capabilities: {
|
|
15
16
|
readonly select: true;
|
|
16
17
|
};
|
|
18
|
+
readonly governed?: never;
|
|
17
19
|
} ? F : never;
|
|
18
20
|
}[AvFieldKey<C, K>];
|
|
19
21
|
/** The field one projection entry names: a bare key, or a relation entry's key. */
|
|
@@ -33,14 +35,14 @@ type EntryArguments<Entry, F extends string> = Entry extends object ? Entry exte
|
|
|
33
35
|
*/
|
|
34
36
|
type ProjectedFields<C extends AvContract, K extends AvResourceKey<C>, Keys extends AvFieldKey<C, K>, Entries, Forms extends ScalarForms> = {
|
|
35
37
|
readonly [F in Keys]: FieldOf<C, K, F> extends AvScalarField<C> ? AvScalarValueType<C, FieldOf<C, K, F>, Forms> : FieldOf<C, K, F> extends AvRelationField<C> ? RelationResult<C, Extract<FieldOf<C, K, F>["target"], AvResourceKey<C>>, FieldOf<C, K, F>, EntryArguments<Entries, F>, Forms> : never;
|
|
36
|
-
};
|
|
38
|
+
} extends infer Fields ? Fields : never;
|
|
37
39
|
/**
|
|
38
40
|
* One projection level: `select` returns exactly its entries, `include` the
|
|
39
41
|
* default fields plus the named relations, and no projection the default fields.
|
|
40
42
|
*/
|
|
41
43
|
type ProjectedRecord<C extends AvContract, K extends AvResourceKey<C>, Arguments, Forms extends ScalarForms> = [Arguments] extends [never] ? ProjectedFields<C, K, DefaultKey<C, K>, never, Forms> : [Arguments] extends [{
|
|
42
44
|
readonly select: readonly (infer Entry)[];
|
|
43
|
-
}] ? ProjectedFields<C, K, Extract<EntryKey<Entry>, AvFieldKey<C, K
|
|
45
|
+
}] ? ProjectedFields<C, K, Extract<EntryKey<Entry>, AvFieldKey<C, K>> | (Entry extends "$defaults" ? DefaultKey<C, K> : never), Entry, Forms> : [Arguments] extends [{
|
|
44
46
|
readonly include: readonly (infer Entry)[];
|
|
45
47
|
}] ? ProjectedFields<C, K, DefaultKey<C, K> | Extract<EntryKey<Entry>, AvFieldKey<C, K>>, Entry, Forms> : ProjectedFields<C, K, DefaultKey<C, K>, never, Forms>;
|
|
46
48
|
/**
|
|
@@ -50,7 +52,7 @@ type ProjectedRecord<C extends AvContract, K extends AvResourceKey<C>, Arguments
|
|
|
50
52
|
type CountEnvelope<C extends AvContract, Target extends AvResourceKey<C>, Entry, Forms extends ScalarForms> = [Exclude<Entry, "$count">] extends [never] ? {
|
|
51
53
|
readonly count: number;
|
|
52
54
|
} : {
|
|
53
|
-
readonly data: readonly ProjectedFields<C, Target, Extract<EntryKey<Entry>, AvFieldKey<C, Target
|
|
55
|
+
readonly data: readonly ProjectedFields<C, Target, Extract<EntryKey<Entry>, AvFieldKey<C, Target>> | (Entry extends "$defaults" ? DefaultKey<C, Target> : never), Exclude<Entry, "$count">, Forms>[];
|
|
54
56
|
readonly count: number;
|
|
55
57
|
};
|
|
56
58
|
/** The entries of an argument's own `select`, or `never` when it has none. */
|