@aventara/core 0.1.0-pilot.2 → 0.1.0-pilot.4
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/dist/adapters/adapter-discovery-diagnostic.d.ts +2 -0
- package/dist/adapters/adapter-field.d.ts +3 -26
- package/dist/adapters/adapter-identifier.d.ts +1 -11
- package/dist/adapters/adapter-model.d.ts +4 -0
- package/dist/adapters/adapter-operation-executor.interface.d.ts +5 -1
- package/dist/adapters/adapter-resource.d.ts +7 -28
- package/dist/adapters/adapter.interface.d.ts +21 -26
- package/dist/compiler/contract-compiler-diagnostic.d.ts +2 -0
- package/dist/compiler/contract.compiler.d.ts +11 -22
- package/dist/config/any-framework-config.d.ts +5 -26
- package/dist/config/config-diagnostic.d.ts +2 -0
- package/dist/config/config-layer.d.ts +6 -19
- package/dist/config/config.resolver.d.ts +6 -14
- package/dist/config/config.validator.d.ts +6 -3
- package/dist/config/define-fields.d.ts +6 -46
- package/dist/config/effective-fields.d.ts +6 -29
- package/dist/config/entrypoint.normalizer.d.ts +6 -18
- package/dist/config/framework-behaviors-config.d.ts +11 -10
- package/dist/config/framework-config.d.ts +15 -15
- package/dist/config/framework-fields-config.d.ts +14 -7
- package/dist/config/framework-restrictions-config.d.ts +41 -61
- package/dist/config/pipeline-config.d.ts +7 -17
- package/dist/contracts/capability.d.ts +13 -49
- package/dist/contracts/client-contract-structure.validator.d.ts +7 -53
- package/dist/contracts/contract-canonicalizer.d.ts +4 -6
- package/dist/contracts/contract-hash.d.ts +3 -2
- package/dist/contracts/contract-limits.d.ts +7 -1
- package/dist/contracts/contract-protocol.d.ts +7 -8
- package/dist/contracts/contract.d.ts +13 -4
- package/dist/contracts/enum-definition.d.ts +2 -0
- package/dist/contracts/field.d.ts +30 -167
- package/dist/contracts/identifier.d.ts +1 -16
- package/dist/contracts/lifecycle-trait.d.ts +4 -3
- package/dist/contracts/resource-operations.d.ts +2 -62
- package/dist/contracts/resource.d.ts +2 -0
- package/dist/contracts/scalar-value-type.d.ts +16 -47
- package/dist/contracts/scalar.d.ts +4 -3
- package/dist/contracts/transaction-capability.d.ts +2 -0
- package/dist/contracts/wire-scalar-format.d.ts +6 -21
- package/dist/framework/contract-view.d.ts +30 -113
- package/dist/framework/framework-construction.error.d.ts +6 -1
- package/dist/framework/framework.d.ts +31 -46
- package/dist/framework/framework.factory.d.ts +3 -17
- package/dist/framework/operation-facade.d.ts +3 -7
- package/dist/operations/operation-arguments.d.ts +52 -207
- package/dist/operations/operation-call.d.ts +13 -15
- package/dist/operations/operation-identity.d.ts +4 -2
- package/dist/operations/operation-result.d.ts +15 -61
- package/dist/operations/operation-validator-core.d.ts +5 -4
- package/dist/operations/operation-validator.d.ts +5 -7
- package/dist/operations/projection-scope.resolver.d.ts +0 -10
- package/dist/operations/validation-code.d.ts +5 -17
- package/dist/operations/write-scope.resolver.d.ts +3 -28
- package/dist/protocol/absent-route.responder.d.ts +23 -38
- package/dist/protocol/av-protocol.d.ts +2 -8
- package/dist/protocol/contract-document.responder.d.ts +5 -18
- package/dist/protocol/http-request.decoder.d.ts +12 -59
- package/dist/protocol/http-request.reader.d.ts +5 -5
- package/dist/protocol/http-response.encoder.d.ts +14 -20
- package/dist/protocol/http-status.table.d.ts +0 -8
- package/dist/protocol/index.d.ts +2 -7
- package/dist/protocol/operation-response.guard.d.ts +0 -15
- package/dist/protocol/protocol-failure.d.ts +8 -27
- package/dist/protocol/protocol-headers.d.ts +15 -42
- package/dist/protocol/protocol-surface.d.ts +0 -22
- package/dist/protocol/protocol.binder.d.ts +16 -26
- package/dist/protocol/protocol.handler.d.ts +15 -23
- package/dist/runtime/decimal.d.ts +5 -3
- package/dist/runtime/diagnostics-reporter.d.ts +14 -34
- package/dist/runtime/error-boundary.d.ts +6 -10
- package/dist/runtime/execution-options.d.ts +3 -7
- package/dist/runtime/field-behavior.d.ts +12 -19
- package/dist/runtime/framework-error.d.ts +2 -2
- package/dist/runtime/json-value.d.ts +7 -15
- package/dist/runtime/mutation-planner.d.ts +6 -12
- package/dist/runtime/operation-request.d.ts +7 -0
- package/dist/runtime/operation-response.d.ts +18 -23
- package/dist/runtime/operation-runtime.d.ts +12 -27
- package/dist/runtime/pipeline.d.ts +14 -29
- package/dist/runtime/referential-action.d.ts +1 -26
- package/dist/runtime/request-id.d.ts +3 -10
- package/dist/runtime/scalar-runtime.d.ts +12 -12
- package/dist/transactions/deferred-operation.d.ts +10 -21
- package/dist/transactions/operation-arguments-encoder.d.ts +1 -0
- package/dist/transactions/operation-fingerprint.d.ts +3 -1
- package/dist/transactions/transaction-envelope.d.ts +2 -4
- package/dist/transactions/transaction-integrity-error.d.ts +4 -15
- package/dist/transactions/transaction-plan-assembler.d.ts +1 -0
- package/dist/transactions/transaction-plan-validator.d.ts +3 -17
- package/dist/transactions/transaction-reference-resolver.d.ts +9 -12
- package/dist/transactions/transaction-reference.d.ts +23 -28
- package/dist/transactions/transaction-request.d.ts +3 -5
- package/dist/transactions/transaction-response.d.ts +5 -7
- package/dist/transactions/transaction-runtime.d.ts +3 -3
- package/dist/transactions/transaction-slot-path-error.d.ts +5 -15
- package/dist/transactions/transaction-slot-writer.d.ts +3 -13
- package/package.json +1 -1
|
@@ -1,49 +1,18 @@
|
|
|
1
1
|
import type { PaginationCapability, ProjectionScope, RelationFilterCapability, RelationMutationDirective, RelationReducer, ScalarFilterOperator, ScalarMutationDirective, WriteScope } from "./capability.js";
|
|
2
2
|
import type { Contract } from "./contract.js";
|
|
3
3
|
import type { LifecycleTrait } from "./lifecycle-trait.js";
|
|
4
|
-
/**
|
|
4
|
+
/** A format name that refines a scalar type, carried in the Contract as data. */
|
|
5
5
|
export type ScalarFormat = string;
|
|
6
|
-
/**
|
|
7
|
-
* The projection positions a field is projectable in: at least one, because an
|
|
8
|
-
* EMPTY list is not a third answer.
|
|
9
|
-
*
|
|
10
|
-
* `absent ≠ empty` is this repository's established rule and the validation layer
|
|
11
|
-
* already acts on the difference, so the empty list has to be unrepresentable
|
|
12
|
-
* rather than merely discouraged. An absent capability member is "not available at
|
|
13
|
-
* all"; an empty list would say the same thing in a second encoding, which is one
|
|
14
|
-
* semantic fact with two hashes.
|
|
15
|
-
*
|
|
16
|
-
* **A scope list qualifies the TOP LEVEL of a projection only. It does not narrow
|
|
17
|
-
* recursively** — see {@link ProjectionScope}, where the runtime measurement and
|
|
18
|
-
* the reason are recorded.
|
|
19
|
-
*/
|
|
6
|
+
/** The projection positions a field can be selected in (at least one). */
|
|
20
7
|
export type ProjectionScopes = readonly [ProjectionScope, ...ProjectionScope[]];
|
|
21
8
|
/**
|
|
22
|
-
* The write positions a field
|
|
23
|
-
*
|
|
24
|
-
* the directive list beside it is separately allowed to be empty and already
|
|
25
|
-
* means something: on a relation mutation member, absent answers `V1006` *"is not
|
|
26
|
-
* writable during <stage>"* while `[]` answers *"writable with no directive"*. A
|
|
27
|
-
* scope list that could also be empty would put a third, unreachable answer next
|
|
28
|
-
* to those two.
|
|
29
|
-
*
|
|
30
|
-
* **A scope list qualifies the TOP LEVEL of a write argument only. It does not
|
|
31
|
-
* narrow recursively** — see {@link WriteScope}.
|
|
9
|
+
* The write positions a field can be written in (at least one). A scope list
|
|
10
|
+
* applies to the top level of a write argument only; see {@link WriteScope}.
|
|
32
11
|
*/
|
|
33
12
|
export type WriteScopes = readonly [WriteScope, ...WriteScope[]];
|
|
34
13
|
/**
|
|
35
|
-
* Whether a relation
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* `true`/`false` is the unqualified answer: available, or not, in every projection
|
|
39
|
-
* position. A {@link ProjectionScopes} list is the qualified answer, and it exists
|
|
40
|
-
* because both pilot engines measurably narrow the top level of a BULK write's
|
|
41
|
-
* returned-row projection to the relations the written row itself resolves, while
|
|
42
|
-
* advertising the full surface on every read.
|
|
43
|
-
*
|
|
44
|
-
* The unqualified arm is retained deliberately: an adapter that has not measured
|
|
45
|
-
* the axis must be able to say so, and a Contract that predates the measurement
|
|
46
|
-
* must keep its meaning.
|
|
14
|
+
* Whether a relation can be selected or included: `true`, or the projection
|
|
15
|
+
* positions it can be used in.
|
|
47
16
|
*/
|
|
48
17
|
export type RelationProjectionCapability = boolean | ProjectionScopes;
|
|
49
18
|
/**
|
|
@@ -57,36 +26,25 @@ export type ScopedRelationReducers = {
|
|
|
57
26
|
readonly scopes: ProjectionScopes;
|
|
58
27
|
};
|
|
59
28
|
/**
|
|
60
|
-
* A relation's
|
|
61
|
-
*
|
|
62
|
-
* unqualified arm is an array, the qualified arm an object.
|
|
29
|
+
* A relation's reducers: a reducer list, or an object with the reducers and
|
|
30
|
+
* the projection positions they apply in.
|
|
63
31
|
*/
|
|
64
32
|
export type RelationReducerCapability = readonly RelationReducer[] | ScopedRelationReducers;
|
|
65
33
|
/**
|
|
66
|
-
* The mutation directives a relation admits at one write stage,
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* `directives: []` stays meaningful and stays distinct from an absent member —
|
|
70
|
-
* "writable with no directive" against "not writable during this stage" — so the
|
|
71
|
-
* scoped form carries the directive list rather than replacing it.
|
|
34
|
+
* The mutation directives a relation admits at one write stage, and the write
|
|
35
|
+
* positions they are admitted in. `directives: []` means writable with no
|
|
36
|
+
* directive.
|
|
72
37
|
*/
|
|
73
38
|
export type ScopedRelationMutations = {
|
|
74
39
|
readonly directives: readonly RelationMutationDirective[];
|
|
75
40
|
readonly scopes: WriteScopes;
|
|
76
41
|
};
|
|
77
42
|
/**
|
|
78
|
-
* A relation's write capability
|
|
79
|
-
*
|
|
80
|
-
* — the unqualified arm is an array, the qualified arm an object.
|
|
43
|
+
* A relation's write capability for `create` or `update`: a directive list, or
|
|
44
|
+
* an object with the directives and the write positions they apply in.
|
|
81
45
|
*/
|
|
82
46
|
export type RelationMutationCapability = readonly RelationMutationDirective[] | ScopedRelationMutations;
|
|
83
|
-
/**
|
|
84
|
-
* Scalar capabilities carry no scope qualifier. Measured on both pilot engines,
|
|
85
|
-
* 2026-10-03: all six members are uniform across every operation variant on the
|
|
86
|
-
* axis — the same scalar members, the same operands, the same declared input
|
|
87
|
-
* symbols in the singular and the bulk forms. Qualifying them would encode a
|
|
88
|
-
* variation that does not exist.
|
|
89
|
-
*/
|
|
47
|
+
/** What can be done with a scalar field. Scalar capabilities apply in every position. */
|
|
90
48
|
export type ScalarFieldCapabilities = {
|
|
91
49
|
readonly select?: boolean;
|
|
92
50
|
readonly filter?: readonly ScalarFilterOperator[];
|
|
@@ -95,18 +53,7 @@ export type ScalarFieldCapabilities = {
|
|
|
95
53
|
readonly create?: readonly ScalarMutationDirective[];
|
|
96
54
|
readonly update?: readonly ScalarMutationDirective[];
|
|
97
55
|
};
|
|
98
|
-
/**
|
|
99
|
-
* Relation capabilities. Five of the eight members are scope-qualified, which is
|
|
100
|
-
* exactly the five the survey measured as varying by operation variant, by two
|
|
101
|
-
* independent mechanisms: the bulk-returning projection ceiling (`select`,
|
|
102
|
-
* `include`, `reducers`) and the flat bulk write stage (`create`, `update`).
|
|
103
|
-
*
|
|
104
|
-
* The other three are left alone on the same evidence. `filter` is uniform
|
|
105
|
-
* (`<M>WhereInput` and `<M>WhereUniqueInput` agree member-for-member on relation
|
|
106
|
-
* members), `order` is uniform (one orderBy input type across every orderBy-carrying
|
|
107
|
-
* variant), and `pagination` is read off the edge's own arguments, the same symbol
|
|
108
|
-
* under every projection that admits the edge at all.
|
|
109
|
-
*/
|
|
56
|
+
/** What can be done with a relation field. */
|
|
110
57
|
export type RelationFieldCapabilities = {
|
|
111
58
|
readonly select?: RelationProjectionCapability;
|
|
112
59
|
readonly include?: RelationProjectionCapability;
|
|
@@ -118,119 +65,34 @@ export type RelationFieldCapabilities = {
|
|
|
118
65
|
readonly update?: RelationMutationCapability;
|
|
119
66
|
};
|
|
120
67
|
/**
|
|
121
|
-
* The reducers a relation advertises,
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* Scope-blind on purpose, and only for a reader on an axis the scope does not
|
|
125
|
-
* qualify. `orderBy: { <to-many>: { $count: … } }` is the one such reader: ordering
|
|
126
|
-
* was measured uniform across every variant that carries an `orderBy` argument, so
|
|
127
|
-
* there is no projection position to ask about and asking would invent one.
|
|
128
|
-
*
|
|
129
|
-
* Every reader on the projection axis wants {@link advertisedReducersAt} instead.
|
|
68
|
+
* The reducers a relation advertises, in any projection position. Use
|
|
69
|
+
* {@link advertisedReducersAt} for one position.
|
|
130
70
|
*/
|
|
131
71
|
export declare function advertisedReducers(capability: RelationReducerCapability | undefined): readonly RelationReducer[] | undefined;
|
|
132
|
-
/**
|
|
133
|
-
* Whether a projection capability holds at one projection scope — **the one home
|
|
134
|
-
* of the scope-aware capability read.**
|
|
135
|
-
*
|
|
136
|
-
* Every reader that has a scope asks this, and no reader compares a capability
|
|
137
|
-
* member to `true` any more. That is not tidiness: a qualified member is an
|
|
138
|
-
* object/array, so `member === true` is `false` for *every* scope, and the six
|
|
139
|
-
* `select`/`include` comparisons this function replaces read a measured
|
|
140
|
-
* `["record"]` as **unavailable everywhere** — a to-many projection refused on
|
|
141
|
-
* `update.first`, which is the single-record scope the adapter advertises it in.
|
|
142
|
-
*
|
|
143
|
-
* The parameter admits `boolean` as well as {@link ProjectionScopes} because the
|
|
144
|
-
* unqualified arm means *holds in every scope*: an adapter that has not measured
|
|
145
|
-
* the axis, and every Contract that predates the measurement, must keep answering
|
|
146
|
-
* what they answered before. So `true` holds at every scope and `false`/absent at
|
|
147
|
-
* none, and the qualified arm is consulted only where one exists.
|
|
148
|
-
*
|
|
149
|
-
* **A scope qualifies the TOP LEVEL of a projection only** — see {@link
|
|
150
|
-
* ProjectionScope}, where the runtime measurement is recorded. A caller that
|
|
151
|
-
* recurses must ask about the nested position with the unrestricted scope, not
|
|
152
|
-
* with its own.
|
|
153
|
-
*/
|
|
72
|
+
/** Whether a projection capability holds at one projection position. */
|
|
154
73
|
export declare function holdsAt(capability: RelationProjectionCapability | undefined, scope: ProjectionScope): boolean;
|
|
155
74
|
/**
|
|
156
|
-
* Whether a projection capability holds in **any**
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* It exists so that reader does not hand-roll `=== true` either. The Contract
|
|
160
|
-
* compiler's VIRTUAL lifecycle check asks whether a field is selectable *at all*
|
|
161
|
-
* before requiring an effective read behavior; a field selectable in one scope
|
|
162
|
-
* needs that behavior exactly as much as one selectable in every scope.
|
|
163
|
-
*
|
|
164
|
-
* A reader with a scope must use {@link holdsAt}. This one answers a strictly
|
|
165
|
-
* weaker question and will over-advertise if used in its place.
|
|
75
|
+
* Whether a projection capability holds in **any** projection position. Use
|
|
76
|
+
* {@link holdsAt} when the position is known.
|
|
166
77
|
*/
|
|
167
78
|
export declare function holdsInAnyScope(capability: RelationProjectionCapability | undefined): boolean;
|
|
168
79
|
/**
|
|
169
|
-
* The reducers a relation advertises
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
* One call rather than two, because the two-call form is the defect. A reader that
|
|
173
|
-
* asks {@link advertisedReducers} for the tokens and then has to remember a second
|
|
174
|
-
* {@link holdsAt} call will forget it, and a forgotten scope check is a silent
|
|
175
|
-
* over-advertisement. Here the scope cannot be forgotten: there is no way to get
|
|
176
|
-
* the tokens without naming the position they are wanted in.
|
|
177
|
-
*
|
|
178
|
-
* `undefined` is the same answer an absent member gives, which is correct — a
|
|
179
|
-
* reducer that does not hold at this scope is not advertised at this scope — and
|
|
180
|
-
* it keeps `[]` meaning what it means everywhere else: advertised, with no
|
|
181
|
-
* reducer.
|
|
80
|
+
* The reducers a relation advertises at one projection position, or
|
|
81
|
+
* `undefined` where it has none there.
|
|
182
82
|
*/
|
|
183
83
|
export declare function advertisedReducersAt(capability: RelationReducerCapability | undefined, scope: ProjectionScope): readonly RelationReducer[] | undefined;
|
|
184
84
|
/**
|
|
185
|
-
* The mutation directives a relation advertises at one write stage,
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* Scope-blind on purpose, and only for a reader that has no write position to ask
|
|
190
|
-
* about or whose answer may only be WIDER than the validator's. Two readers
|
|
191
|
-
* qualify. `operation-boolean-nodes.ts`'s `maxBooleanNodes` walk descends a
|
|
192
|
-
* relation mutation to count the filter nodes inside it; reading scope-blind makes
|
|
193
|
-
* that walk a superset of what the grammar walk admits, which is the harmless
|
|
194
|
-
* direction — it counts inside a write that is about to be refused, and it can
|
|
195
|
-
* never stop counting inside one that is admitted. An adapter's own write
|
|
196
|
-
* translator is the other: it is handed the write site's verdict by whoever
|
|
197
|
-
* dispatched it and holds no advertised variant to resolve a scope from.
|
|
198
|
-
*
|
|
199
|
-
* Every reader on the write axis that HAS a position wants {@link
|
|
200
|
-
* advertisedDirectivesAt} instead.
|
|
201
|
-
*
|
|
202
|
-
* See {@link advertisedReducers} for why the scopes are not returned beside them.
|
|
85
|
+
* The mutation directives a relation advertises at one write stage, in any
|
|
86
|
+
* write position. `undefined` means the stage is unavailable; `[]` means
|
|
87
|
+
* available with no directive.
|
|
203
88
|
*/
|
|
204
89
|
export declare function advertisedDirectives(capability: RelationMutationCapability | undefined): readonly RelationMutationDirective[] | undefined;
|
|
205
90
|
/**
|
|
206
|
-
* The mutation directives a relation advertises
|
|
207
|
-
*
|
|
208
|
-
* **the one home of the scope-aware write read**, and the write mirror of {@link
|
|
209
|
-
* advertisedReducersAt}.
|
|
210
|
-
*
|
|
211
|
-
* One call rather than two, for the reason {@link advertisedReducersAt} gives: a
|
|
212
|
-
* reader that fetches the directives and then has to remember a separate scope
|
|
213
|
-
* check will forget it, and a forgotten scope check is a silent
|
|
214
|
-
* over-advertisement. Here the position cannot be forgotten, because there is no
|
|
215
|
-
* way to reach the directives without naming it.
|
|
216
|
-
*
|
|
217
|
-
* `undefined` for a stage that does not hold at this scope is the same answer an
|
|
218
|
-
* absent member gives, which is what the caller must say: a relation that is not
|
|
219
|
-
* writable in this write position is *"not writable during <stage>"* there. That
|
|
220
|
-
* keeps `[]` meaning what it means everywhere else — advertised, with no directive
|
|
221
|
-
* — so the two live answers `V1006` already distinguishes stay two, and the scope
|
|
222
|
-
* does not invent a third.
|
|
223
|
-
*
|
|
224
|
-
* The unqualified arm is an array and means *holds in every write position*: an
|
|
225
|
-
* adapter that has not measured the axis, and every Contract that predates the
|
|
226
|
-
* measurement, keep the write surface they had.
|
|
227
|
-
*
|
|
228
|
-
* **A scope qualifies the TOP LEVEL of a write argument only** — see {@link
|
|
229
|
-
* WriteScope}. A caller that recurses into a nested write must ask about the
|
|
230
|
-
* nested position with the unrestricted scope, not with its own.
|
|
91
|
+
* The mutation directives a relation advertises at one write position, or
|
|
92
|
+
* `undefined` where it is not writable there.
|
|
231
93
|
*/
|
|
232
94
|
export declare function advertisedDirectivesAt(capability: RelationMutationCapability | undefined, scope: WriteScope): readonly RelationMutationDirective[] | undefined;
|
|
233
|
-
/**
|
|
95
|
+
/** A scalar field, including an enum-backed one. */
|
|
234
96
|
export type ScalarField<C extends Contract> = {
|
|
235
97
|
readonly kind: "scalar";
|
|
236
98
|
readonly type: {
|
|
@@ -244,7 +106,7 @@ export type ScalarField<C extends Contract> = {
|
|
|
244
106
|
readonly lifecycle: readonly LifecycleTrait[];
|
|
245
107
|
readonly capabilities: ScalarFieldCapabilities;
|
|
246
108
|
};
|
|
247
|
-
/**
|
|
109
|
+
/** A relation field; the `target` Resource describes the related row. */
|
|
248
110
|
export type RelationField<C extends Contract> = {
|
|
249
111
|
readonly kind: "relation";
|
|
250
112
|
readonly target: Extract<keyof C["resources"], string>;
|
|
@@ -252,4 +114,5 @@ export type RelationField<C extends Contract> = {
|
|
|
252
114
|
readonly nullable: boolean;
|
|
253
115
|
readonly capabilities: RelationFieldCapabilities;
|
|
254
116
|
};
|
|
117
|
+
/** One field of a Resource: a scalar or a relation. */
|
|
255
118
|
export type Field<C extends Contract> = ScalarField<C> | RelationField<C>;
|
|
@@ -1,21 +1,6 @@
|
|
|
1
1
|
import type { Contract } from "./contract.js";
|
|
2
2
|
import type { Field } from "./field.js";
|
|
3
|
-
/**
|
|
4
|
-
* Keys of `TFields` whose Field can be scalar-shaped.
|
|
5
|
-
*
|
|
6
|
-
* `TFields[K]` is an indexed access, not a naked type parameter, so a bare
|
|
7
|
-
* conditional would not distribute over a union-valued field. With the
|
|
8
|
-
* abstract `ResourceFieldMap` default every key maps to the whole `Field`
|
|
9
|
-
* union, which is not a subtype of the scalar branch, so the bare form
|
|
10
|
-
* collapses to `never` and makes `Identifier` uninhabitable. `Extract` selects
|
|
11
|
-
* the scalar branch out of the union instead, so a key is kept unless it is
|
|
12
|
-
* provably relation-only.
|
|
13
|
-
*
|
|
14
|
-
* The branch is selected by its `kind` discriminant rather than by
|
|
15
|
-
* `ScalarField<Contract>`: `Field<C>` measures as invariant in `C`, so a
|
|
16
|
-
* `Field<ClientContract>` is not assignable to a `Field<Contract>` and the
|
|
17
|
-
* `Extract` would collapse again. This mirrors `AdapterScalarFieldKey`.
|
|
18
|
-
*/
|
|
3
|
+
/** Keys of `TFields` whose field can be scalar-shaped. */
|
|
19
4
|
export type ScalarFieldKey<TFields extends Readonly<Record<string, Field<Contract>>>> = Extract<{
|
|
20
5
|
[K in keyof TFields]: [
|
|
21
6
|
Extract<TFields[K], {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* framework
|
|
2
|
+
* Where a field's value comes from, without saying whether it is writable:
|
|
3
|
+
* `DEFAULTED` and `GENERATED_ON_*` by the data source, `COMPUTED_ON_*` by a
|
|
4
|
+
* framework behavior; `VIRTUAL` marks a field that is not stored.
|
|
5
5
|
*/
|
|
6
6
|
export declare const LIFECYCLE_TRAITS: readonly ["DEFAULTED", "GENERATED_ON_CREATE", "GENERATED_ON_UPDATE", "COMPUTED_ON_CREATE", "COMPUTED_ON_UPDATE", "COMPUTED_ON_READ", "VIRTUAL"];
|
|
7
|
+
/** One of {@link LIFECYCLE_TRAITS}. */
|
|
7
8
|
export type LifecycleTrait = (typeof LIFECYCLE_TRAITS)[number];
|
|
@@ -3,19 +3,6 @@ import type { ProjectionScope, WriteScope } from "./capability.js";
|
|
|
3
3
|
* The argument scopes one advertised operation variant qualifies its arguments
|
|
4
4
|
* with: which projection position its projection arguments sit in, and which write
|
|
5
5
|
* position its data argument sits in.
|
|
6
|
-
*
|
|
7
|
-
* The variant-to-scope map is an ADAPTER fact, not a protocol constant — a
|
|
8
|
-
* variant's projection position depends on which ORM call the adapter routes it to
|
|
9
|
-
* — so the advertised variant carries the answer rather than core tabulating it.
|
|
10
|
-
*
|
|
11
|
-
* At least one scope must be stated. A descriptor stating neither says exactly
|
|
12
|
-
* what `true` says, and one semantic fact with two encodings is one fact with two
|
|
13
|
-
* hashes.
|
|
14
|
-
*
|
|
15
|
-
* Named for the variant it qualifies, and deliberately not `OperationScopes`:
|
|
16
|
-
* `OperationScope` is a public (now deprecated) alias of `RequestOrigin`, meaning
|
|
17
|
-
* `"application" | "client"`, and two public names one character apart with
|
|
18
|
-
* nothing in common is a vocabulary collision, not a near-miss.
|
|
19
6
|
*/
|
|
20
7
|
export type OperationVariantScopes = {
|
|
21
8
|
readonly projection: ProjectionScope;
|
|
@@ -60,63 +47,16 @@ export type ResourceOperations = {
|
|
|
60
47
|
};
|
|
61
48
|
};
|
|
62
49
|
/**
|
|
63
|
-
* Whether one `ResourceOperations`
|
|
64
|
-
*
|
|
65
|
-
* Availability is **presence**: the leaf is `true`, or it is the descriptor that
|
|
66
|
-
* qualifies the variant's arguments. A descriptor states how the variant's
|
|
67
|
-
* arguments are scoped — it never retracts the variant — so `leaf === true` is
|
|
68
|
-
* the wrong question wherever availability is read, and the leaf's widening to
|
|
69
|
-
* `true | OperationVariantScopes` made every hand-rolled copy of that question
|
|
70
|
-
* silently wrong. The question has one home so the next widening of
|
|
71
|
-
* `OperationAvailability` reaches every reader at once.
|
|
72
|
-
*
|
|
73
|
-
* The parameter is `unknown` because the readers are the request validator and
|
|
74
|
-
* the Contract compiler, which hold the leaf as a Contract value keyed by an
|
|
75
|
-
* untrusted or mid-compilation string. Descriptor *shape* is not judged here: a
|
|
76
|
-
* present leaf is an available variant, and validating what the descriptor says
|
|
77
|
-
* belongs to whoever owns the descriptor's own invariants.
|
|
50
|
+
* Whether one `ResourceOperations` entry marks its variant available: it is
|
|
51
|
+
* `true` or an argument-position descriptor.
|
|
78
52
|
*/
|
|
79
53
|
export declare function isOperationVariantAvailable(availability: unknown): availability is OperationAvailability;
|
|
80
54
|
/**
|
|
81
55
|
* The projection position one advertised variant's projection arguments sit in.
|
|
82
|
-
*
|
|
83
|
-
* `"record"` — the unrestricted position — is the answer for `true`, for an absent
|
|
84
|
-
* leaf and for a descriptor that qualifies only its write argument, because the
|
|
85
|
-
* unqualified arm means *nothing is narrowed here*. A Contract written before the
|
|
86
|
-
* axis existed therefore keeps validating exactly as it did, which is what makes
|
|
87
|
-
* the widening in {@link OperationAvailability} non-breaking for a producer that
|
|
88
|
-
* has not measured it.
|
|
89
|
-
*
|
|
90
|
-
* The map from variant to scope is **not** here and must never be:
|
|
91
|
-
* `update.first`'s projection position is the single-record one only because an
|
|
92
|
-
* adapter chose to route that variant to a single-record provider call, and an
|
|
93
|
-
* adapter that routes it to a bulk one moves the answer. Core reads what the
|
|
94
|
-
* advertised variant carries rather than tabulating one scope per variant name.
|
|
95
|
-
*
|
|
96
|
-
* `unknown` for the same reason {@link isOperationVariantAvailable} takes it: the
|
|
97
|
-
* caller holds the leaf keyed by an untrusted request string.
|
|
98
56
|
*/
|
|
99
57
|
export declare function projectionScopeOf(availability: unknown): ProjectionScope;
|
|
100
58
|
/**
|
|
101
59
|
* The write position one advertised variant's data argument sits in, and the write
|
|
102
60
|
* mirror of {@link projectionScopeOf}.
|
|
103
|
-
*
|
|
104
|
-
* `"nested"` — the unrestricted position — is the answer for `true`, for an absent
|
|
105
|
-
* leaf and for a descriptor that qualifies only its projection argument, for the
|
|
106
|
-
* same reason `"record"` is on the projection axis: the unqualified arm means
|
|
107
|
-
* *nothing is narrowed here*, so a Contract written before the axis existed keeps
|
|
108
|
-
* the write surface it had.
|
|
109
|
-
*
|
|
110
|
-
* The two axes are read by two functions, not one that returns a pair, because
|
|
111
|
-
* they are measured and consulted separately — `WRITE_SCOPES` is a separate array
|
|
112
|
-
* from `PROJECTION_SCOPES` for that reason — and a caller that needs only one
|
|
113
|
-
* position should not be handed the other to discard.
|
|
114
|
-
*
|
|
115
|
-
* The mirror exists so that *"what does this descriptor mean?"* has one answer per
|
|
116
|
-
* axis rather than one answer and one convention. The canonicalizer's collapse of
|
|
117
|
-
* a redundant descriptor is keyed on these two functions' answer for `true`: a
|
|
118
|
-
* descriptor says nothing beyond `true` exactly when every reader answers for it
|
|
119
|
-
* what it answers for `true`, and that test is only as honest as the readers being
|
|
120
|
-
* the single statement of each axis's unqualified scope.
|
|
121
61
|
*/
|
|
122
62
|
export declare function writeScopeOf(availability: unknown): WriteScope;
|
|
@@ -2,7 +2,9 @@ import type { Contract } from "./contract.js";
|
|
|
2
2
|
import type { Field } from "./field.js";
|
|
3
3
|
import type { Identifier } from "./identifier.js";
|
|
4
4
|
import type { ResourceOperations } from "./resource-operations.js";
|
|
5
|
+
/** A Resource's fields, by name. */
|
|
5
6
|
export type ResourceFieldMap<C extends Contract> = Readonly<Record<string, Field<C>>>;
|
|
7
|
+
/** One Resource: its fields, identifiers and available operations. */
|
|
6
8
|
export type Resource<C extends Contract, TFields extends ResourceFieldMap<C> = ResourceFieldMap<C>> = {
|
|
7
9
|
readonly fields: TFields;
|
|
8
10
|
readonly identifiers: readonly Identifier<TFields>[];
|
|
@@ -4,31 +4,16 @@ import type { Contract } from "./contract.js";
|
|
|
4
4
|
import type { ScalarField } from "./field.js";
|
|
5
5
|
import type { BuiltInScalar } from "./scalar.js";
|
|
6
6
|
/**
|
|
7
|
-
* A scalar-form map: the TypeScript type each built-in scalar takes on one side
|
|
8
|
-
* a boundary. Every built-in must be
|
|
9
|
-
* compile where it is passed rather than typing that scalar as `unknown`.
|
|
10
|
-
*
|
|
11
|
-
* It is a parameter rather than a fixed table because one derivation serves more
|
|
12
|
-
* than one side: the application forms below for an in-process caller, and the
|
|
13
|
-
* wire forms for a transport or a generated client.
|
|
14
|
-
*
|
|
15
|
-
* This constraint is not exported: a map is checked for completeness where it is
|
|
16
|
-
* passed, so a consumer never has to name it.
|
|
7
|
+
* A scalar-form map: the TypeScript type each built-in scalar takes on one side
|
|
8
|
+
* of a boundary. Every built-in must be listed.
|
|
17
9
|
*/
|
|
18
10
|
export type ScalarForms = {
|
|
19
11
|
readonly [Scalar in BuiltInScalar]: unknown;
|
|
20
12
|
};
|
|
21
13
|
/**
|
|
22
|
-
* The
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* which maps to the application branch of `normalizeScalarAtom`, and the adapter
|
|
26
|
-
* is held to it (`runtime/scalar-runtime.ts`, `runtime/output-validator.ts`). So
|
|
27
|
-
* a client-scope caller receives these forms too, in process; the wire encoding
|
|
28
|
-
* happens on a transport's way out.
|
|
29
|
-
*
|
|
30
|
-
* `decimal` is core's own {@link Decimal} — never a provider's decimal class —
|
|
31
|
-
* which is what `normalizeScalarAtom`'s `instanceof Decimal` check enforces.
|
|
14
|
+
* The TypeScript form each built-in scalar takes in process: in results of
|
|
15
|
+
* either origin, and in `framework.application` arguments. `decimal` is
|
|
16
|
+
* Aventara's own {@link Decimal}.
|
|
32
17
|
*/
|
|
33
18
|
export type ApplicationScalarForms = {
|
|
34
19
|
readonly string: string;
|
|
@@ -40,17 +25,15 @@ export type ApplicationScalarForms = {
|
|
|
40
25
|
readonly datetime: Date;
|
|
41
26
|
readonly bytes: Uint8Array;
|
|
42
27
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* the `| null` comes from the Contract's `nullable` like every other scalar's. A
|
|
46
|
-
* `null` INSIDE the value is JSON's.
|
|
28
|
+
* Any JSON value. A field-level `null` is the field's absence and is allowed
|
|
29
|
+
* only where the field is nullable; a `null` inside the value is JSON's own.
|
|
47
30
|
*/
|
|
48
31
|
readonly json: Exclude<JsonValue, null>;
|
|
49
32
|
};
|
|
50
33
|
/**
|
|
51
|
-
* The encoded forms the
|
|
52
|
-
*
|
|
53
|
-
*
|
|
34
|
+
* The encoded forms of the built-in scalars: base-10 bigint strings, decimal strings,
|
|
35
|
+
* canonical ISO-8601 UTC datetimes and RFC 4648 base64 bytes. For a transport or a
|
|
36
|
+
* generated client to pass as `Forms`.
|
|
54
37
|
*/
|
|
55
38
|
export type WireScalarForms = {
|
|
56
39
|
readonly string: string;
|
|
@@ -61,20 +44,10 @@ export type WireScalarForms = {
|
|
|
61
44
|
readonly decimal: string;
|
|
62
45
|
readonly datetime: string;
|
|
63
46
|
readonly bytes: string;
|
|
64
|
-
/**
|
|
65
|
-
* The same form as the application's: `normalizeJsonValue` has no client
|
|
66
|
-
* branch, and a JSON value needs no encoding to cross a JSON wire.
|
|
67
|
-
*/
|
|
47
|
+
/** The same as in process: a JSON value needs no encoding to cross a JSON wire. */
|
|
68
48
|
readonly json: Exclude<JsonValue, null>;
|
|
69
49
|
};
|
|
70
|
-
/**
|
|
71
|
-
* One value of a scalar field, before `list` and `nullable` apply.
|
|
72
|
-
*
|
|
73
|
-
* Exported to the argument surface only, never from the package: a filter's
|
|
74
|
-
* `in`, a list's `has` and a mutation directive's operand each take one entry of
|
|
75
|
-
* a list field, which is exactly this, and a second spelling of it would be a
|
|
76
|
-
* second derivation of one rule.
|
|
77
|
-
*/
|
|
50
|
+
/** One value of a scalar field, before `list` and `nullable` apply. */
|
|
78
51
|
export type ScalarAtom<C extends Contract, Type, Forms extends ScalarForms> = Type extends {
|
|
79
52
|
readonly enum: infer Enum extends keyof C["enums"];
|
|
80
53
|
} ? C["enums"][Enum]["values"][number] : Type extends {
|
|
@@ -86,17 +59,13 @@ export type ScalarAtom<C extends Contract, Type, Forms extends ScalarForms> = Ty
|
|
|
86
59
|
*/
|
|
87
60
|
type ListValue<List, Atom> = [List] extends [false] ? Atom : [List] extends [true] ? readonly Atom[] : Atom | readonly Atom[];
|
|
88
61
|
/**
|
|
89
|
-
* The value type of one scalar field, under one scalar-form map
|
|
62
|
+
* The value type of one scalar field, under one scalar-form map:
|
|
90
63
|
*
|
|
91
|
-
* - enum-backed → the
|
|
92
|
-
*
|
|
64
|
+
* - enum-backed → the union of its values (literal only while the model is
|
|
65
|
+
* `as const`; otherwise `string`);
|
|
93
66
|
* - built-in scalar → `Forms[scalar]`;
|
|
94
|
-
* - `list: true` → `readonly T[]`, whose entries are never `null
|
|
95
|
-
* (`normalizeScalarFieldValue` refuses a null entry);
|
|
67
|
+
* - `list: true` → `readonly T[]`, whose entries are never `null`;
|
|
96
68
|
* - `nullable: true` → `| null`, on the whole value, list or not.
|
|
97
|
-
*
|
|
98
|
-
* Nullability is read as "can it be `true`", so a Contract that widened the flag
|
|
99
|
-
* to `boolean` is typed nullable rather than promised non-null.
|
|
100
69
|
*/
|
|
101
70
|
export type ScalarValueType<C extends Contract, Field extends ScalarField<C>, Forms extends ScalarForms = ApplicationScalarForms> = ListValue<Field["list"], ScalarAtom<C, Field["type"], Forms>> | (true extends Field["nullable"] ? null : never);
|
|
102
71
|
export {};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** The built-in scalar types of the Aventara protocol. */
|
|
2
2
|
export declare const BUILT_IN_SCALARS: readonly ["string", "boolean", "int", "float", "bigint", "decimal", "datetime", "bytes", "json"];
|
|
3
|
+
/** One of {@link BUILT_IN_SCALARS}. */
|
|
3
4
|
export type BuiltInScalar = (typeof BUILT_IN_SCALARS)[number];
|
|
4
|
-
/**
|
|
5
|
+
/** One entry of a scalar registry. */
|
|
5
6
|
export type ScalarDefinition = {
|
|
6
7
|
readonly builtin: true;
|
|
7
8
|
};
|
|
8
|
-
/**
|
|
9
|
+
/** The scalar types an adapter model or Contract supports, by name. */
|
|
9
10
|
export type ScalarRegistry = Readonly<Record<string, ScalarDefinition>>;
|
|
@@ -2,9 +2,9 @@ import type { BuiltInScalar } from "./scalar.js";
|
|
|
2
2
|
import type { ApplicationScalarForms, WireScalarForms } from "./scalar-value-type.js";
|
|
3
3
|
/**
|
|
4
4
|
* The built-in scalars whose wire form is not their runtime form — the ones a JSON
|
|
5
|
-
* wire carries as a string with a grammar of its own. Derived from the two form
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* wire carries as a string with a grammar of its own. Derived from the two form maps
|
|
6
|
+
* rather than listed, so a built-in scalar added with a string wire form fails to
|
|
7
|
+
* compile below until its grammar is written.
|
|
8
8
|
*/
|
|
9
9
|
type WireEncodedScalar = {
|
|
10
10
|
readonly [S in BuiltInScalar]: WireScalarForms[S] extends ApplicationScalarForms[S] ? never : S;
|
|
@@ -13,18 +13,6 @@ type WireEncodedScalar = {
|
|
|
13
13
|
* `AvProtocol.scalarFormats` — the wire grammars of protocol version 1, as passive
|
|
14
14
|
* data: one anchored pattern SOURCE string per wire-encoded scalar, in
|
|
15
15
|
* `BUILT_IN_SCALARS` order.
|
|
16
|
-
*
|
|
17
|
-
* The one source: execution decodes client-scope arguments with these
|
|
18
|
-
* (`runtime/scalar-runtime.ts`, `runtime/decimal.ts`), `@aventara/core/protocol`
|
|
19
|
-
* re-exports this object, and the client generator emits each source by value into
|
|
20
|
-
* the generated runtime as a regular-expression literal. Strings, not `RegExp`s,
|
|
21
|
-
* so it survives JSON and can be emitted; frozen, so no consumer can rewrite a
|
|
22
|
-
* grammar in place.
|
|
23
|
-
*
|
|
24
|
-
* A grammar is the SHAPE only. Two scalars carry one more rule each, applied where
|
|
25
|
-
* they decode: a `datetime` must also round-trip `toISOString()` exactly, and a
|
|
26
|
-
* `bytes` string's padded group must leave its unused bits zero ({@link
|
|
27
|
-
* decodeBase64}).
|
|
28
16
|
*/
|
|
29
17
|
export declare const scalarFormats: Readonly<{
|
|
30
18
|
readonly bigint: "^-?(?:0|[1-9]\\d*)$";
|
|
@@ -32,18 +20,15 @@ export declare const scalarFormats: Readonly<{
|
|
|
32
20
|
readonly datetime: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$";
|
|
33
21
|
readonly bytes: "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$";
|
|
34
22
|
}>;
|
|
35
|
-
/** {@link scalarFormats}, compiled
|
|
23
|
+
/** {@link scalarFormats}, compiled to regular expressions. */
|
|
36
24
|
export declare const WIRE_SCALAR_PATTERNS: {
|
|
37
25
|
readonly [S in WireEncodedScalar]: RegExp;
|
|
38
26
|
};
|
|
39
27
|
/** RFC 4648 base64, standard alphabet, padded: the canonical spelling of `bytes`. */
|
|
40
28
|
export declare function encodeBase64(bytes: Uint8Array): string;
|
|
41
29
|
/**
|
|
42
|
-
* The bytes of a
|
|
43
|
-
* string
|
|
44
|
-
* bits a padded final group does not carry must be zero, or two wire strings would
|
|
45
|
-
* name one byte sequence (`"AB=="` and `"AA=="` both `[0]`). The generated
|
|
46
|
-
* client's decoder applies the same rule.
|
|
30
|
+
* The bytes of a canonical RFC 4648 base64 string; `undefined` for any other
|
|
31
|
+
* string, including one whose unused padding bits are not zero.
|
|
47
32
|
*/
|
|
48
33
|
export declare function decodeBase64(wire: string): Uint8Array | undefined;
|
|
49
34
|
export {};
|