@aventara/core 0.1.0-pilot.1 → 0.1.0-pilot.3
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-field.d.ts +4 -4
- package/dist/adapters/adapter-resource.d.ts +10 -12
- package/dist/adapters/adapter.interface.d.ts +20 -10
- package/dist/compiler/contract-compiler-diagnostic.d.ts +3 -4
- package/dist/compiler/contract.compiler.d.ts +5 -4
- package/dist/compiler/contract.compiler.js +0 -132
- package/dist/config/config.resolver.d.ts +2 -2
- package/dist/config/config.resolver.js +0 -5
- package/dist/config/config.validator.d.ts +3 -3
- package/dist/config/config.validator.js +0 -8
- package/dist/config/define-fields.d.ts +2 -7
- package/dist/config/define-fields.js +0 -15
- package/dist/config/effective-fields.d.ts +4 -8
- package/dist/config/entrypoint.normalizer.d.ts +7 -7
- package/dist/config/entrypoint.normalizer.js +0 -22
- package/dist/config/framework-behaviors-config.d.ts +6 -6
- package/dist/config/framework-config.d.ts +3 -5
- package/dist/config/framework-restrictions-config.d.ts +19 -29
- package/dist/config/pipeline-config.d.ts +8 -18
- package/dist/contracts/capability.d.ts +18 -21
- package/dist/contracts/capability.js +0 -75
- package/dist/contracts/client-contract-structure.validator.d.ts +15 -22
- package/dist/contracts/client-contract-structure.validator.js +0 -27
- package/dist/contracts/contract-canonicalizer.js +0 -96
- package/dist/contracts/contract-hash.js +0 -2
- package/dist/contracts/contract-limits.js +0 -1
- package/dist/contracts/contract-lookup.js +0 -10
- package/dist/contracts/contract-protocol.js +0 -10
- package/dist/contracts/field.d.ts +23 -26
- package/dist/contracts/field.js +0 -107
- package/dist/contracts/lifecycle-trait.js +0 -5
- package/dist/contracts/resource-operations.d.ts +17 -18
- package/dist/contracts/resource-operations.js +0 -63
- package/dist/contracts/scalar-value-type.d.ts +12 -22
- package/dist/contracts/scalar.js +0 -1
- package/dist/contracts/wire-scalar-format.d.ts +20 -20
- package/dist/contracts/wire-scalar-format.js +0 -26
- package/dist/framework/contract-view.d.ts +7 -8
- package/dist/framework/framework-construction.error.js +0 -1
- package/dist/framework/framework.d.ts +26 -27
- package/dist/framework/framework.factory.js +0 -49
- package/dist/framework/operation-facade.js +0 -17
- package/dist/operations/operation-arguments.d.ts +36 -46
- package/dist/operations/operation-boolean-nodes.js +0 -16
- package/dist/operations/operation-call.d.ts +4 -9
- package/dist/operations/operation-identity.js +0 -1
- package/dist/operations/operation-nesting.js +0 -5
- package/dist/operations/operation-result.d.ts +4 -4
- package/dist/operations/operation-validator-core.d.ts +2 -2
- package/dist/operations/operation-validator-core.js +6 -71
- package/dist/operations/operation-validator.d.ts +4 -4
- package/dist/operations/operation-validator.js +0 -12
- package/dist/operations/projection-scope.resolver.d.ts +8 -10
- package/dist/operations/projection-scope.resolver.js +0 -35
- package/dist/operations/validation-code.d.ts +11 -18
- package/dist/operations/validation-code.js +0 -24
- package/dist/operations/write-scope.resolver.d.ts +4 -7
- package/dist/operations/write-scope.resolver.js +0 -37
- package/dist/protocol/absent-route.responder.d.ts +33 -48
- package/dist/protocol/absent-route.responder.js +0 -55
- package/dist/protocol/av-protocol.d.ts +6 -6
- package/dist/protocol/av-protocol.js +0 -10
- package/dist/protocol/contract-document.responder.d.ts +15 -18
- package/dist/protocol/contract-document.responder.js +0 -33
- package/dist/protocol/http-request.decoder.d.ts +55 -61
- package/dist/protocol/http-request.decoder.js +0 -62
- package/dist/protocol/http-request.reader.d.ts +12 -13
- package/dist/protocol/http-request.reader.js +0 -45
- package/dist/protocol/http-response.encoder.d.ts +17 -18
- package/dist/protocol/http-response.encoder.js +0 -59
- package/dist/protocol/http-status.table.d.ts +7 -11
- package/dist/protocol/http-status.table.js +1 -15
- package/dist/protocol/index.d.ts +5 -5
- package/dist/protocol/index.js +0 -9
- package/dist/protocol/operation-response.guard.d.ts +12 -19
- package/dist/protocol/operation-response.guard.js +0 -29
- package/dist/protocol/protocol-failure.d.ts +21 -26
- package/dist/protocol/protocol-failure.js +0 -12
- package/dist/protocol/protocol-headers.d.ts +25 -30
- package/dist/protocol/protocol-headers.js +0 -66
- package/dist/protocol/protocol-surface.d.ts +25 -29
- package/dist/protocol/protocol-surface.js +0 -19
- package/dist/protocol/protocol.binder.d.ts +58 -71
- package/dist/protocol/protocol.binder.js +0 -8
- package/dist/protocol/protocol.handler.d.ts +28 -32
- package/dist/protocol/protocol.handler.js +0 -43
- package/dist/runtime/computed-read-runtime.js +0 -29
- package/dist/runtime/create-requirement.d.ts +65 -0
- package/dist/runtime/create-requirement.js +141 -0
- package/dist/runtime/decimal.d.ts +2 -2
- package/dist/runtime/decimal.js +0 -8
- package/dist/runtime/diagnostics-reporter.d.ts +6 -6
- package/dist/runtime/diagnostics-reporter.js +0 -35
- package/dist/runtime/error-boundary.d.ts +3 -3
- package/dist/runtime/error-boundary.js +2 -167
- package/dist/runtime/execution-options.d.ts +4 -4
- package/dist/runtime/field-behavior.d.ts +6 -9
- package/dist/runtime/framework-error.js +0 -4
- package/dist/runtime/mutation-planner.d.ts +5 -6
- package/dist/runtime/mutation-planner.js +0 -23
- package/dist/runtime/operation-response.d.ts +1 -1
- package/dist/runtime/operation-response.js +1 -17
- package/dist/runtime/operation-runtime.d.ts +24 -22
- package/dist/runtime/operation-runtime.js +18 -52
- package/dist/runtime/outcome-mapper.js +0 -22
- package/dist/runtime/output-validator.js +0 -1
- package/dist/runtime/pipe-output.validator.d.ts +48 -0
- package/dist/runtime/pipe-output.validator.js +79 -0
- package/dist/runtime/pipeline.d.ts +20 -26
- package/dist/runtime/referential-action.d.ts +14 -19
- package/dist/runtime/referential-action.js +0 -23
- package/dist/runtime/request-id.js +0 -21
- package/dist/runtime/scalar-runtime.d.ts +14 -16
- package/dist/runtime/scalar-runtime.js +12 -57
- package/dist/transactions/deferred-operation.d.ts +9 -14
- package/dist/transactions/operation-arguments-encoder.d.ts +0 -1
- package/dist/transactions/operation-arguments-encoder.js +0 -14
- package/dist/transactions/operation-fingerprint.js +0 -1
- package/dist/transactions/transaction-envelope.js +0 -14
- package/dist/transactions/transaction-integrity-error.d.ts +10 -11
- package/dist/transactions/transaction-integrity-error.js +0 -5
- package/dist/transactions/transaction-plan-assembler.d.ts +0 -1
- package/dist/transactions/transaction-plan-assembler.js +0 -35
- package/dist/transactions/transaction-plan-validator.d.ts +5 -5
- package/dist/transactions/transaction-plan-validator.js +0 -63
- package/dist/transactions/transaction-reference-resolver.d.ts +12 -13
- package/dist/transactions/transaction-reference-resolver.js +0 -16
- package/dist/transactions/transaction-reference-validator.js +0 -8
- package/dist/transactions/transaction-reference.d.ts +19 -43
- package/dist/transactions/transaction-reference.js +0 -11
- package/dist/transactions/transaction-request.d.ts +4 -5
- package/dist/transactions/transaction-response.d.ts +1 -1
- package/dist/transactions/transaction-runtime.d.ts +2 -3
- package/dist/transactions/transaction-runtime.js +5 -44
- package/dist/transactions/transaction-slot-path-error.d.ts +10 -11
- package/dist/transactions/transaction-slot-path-error.js +0 -7
- package/dist/transactions/transaction-slot-writer.d.ts +12 -12
- package/dist/transactions/transaction-slot-writer.js +0 -34
- package/package.json +2 -2
|
@@ -4,11 +4,11 @@ import { type OperationValidationOptions, type OperationValidationResult } from
|
|
|
4
4
|
import type { ValidationIssue } from "./validation-code.js";
|
|
5
5
|
export type { OperationValidationOptions, OperationValidationResult, SemanticOperationArguments, } from "./operation-validator-core.js";
|
|
6
6
|
/**
|
|
7
|
-
* The Framework Validation Layer's issue for a `(resource, family, variant)`
|
|
8
|
-
*
|
|
7
|
+
* The Framework Validation Layer's issue for a `(resource, family, variant)` the
|
|
8
|
+
* active Contract does not advertise on a Resource it has (`V1006` at
|
|
9
9
|
* `["operation"]`, rolling up to `A2002`). The one spelling — the protocol's
|
|
10
|
-
* absence answers
|
|
11
|
-
*
|
|
10
|
+
* absence answers build theirs with it, so a caller cannot tell which layer
|
|
11
|
+
* answered.
|
|
12
12
|
*/
|
|
13
13
|
export declare function operationUnavailableIssue(request: {
|
|
14
14
|
readonly resource: string;
|
|
@@ -15,13 +15,6 @@ function isOperationAvailable(contract, request) {
|
|
|
15
15
|
const family = lookupOwn(advertised, request.family);
|
|
16
16
|
return isOperationVariantAvailable(lookupOwn(family, request.variant));
|
|
17
17
|
}
|
|
18
|
-
/**
|
|
19
|
-
* The Framework Validation Layer's issue for a `(resource, family, variant)`
|
|
20
|
-
* the active Contract does not advertise on a Resource it has (`V1006` at
|
|
21
|
-
* `["operation"]`, rolling up to `A2002`). The one spelling — the protocol's
|
|
22
|
-
* absence answers (`@aventara/core/protocol`, Q2's O3) build theirs with it, so
|
|
23
|
-
* a caller cannot tell which layer answered.
|
|
24
|
-
*/
|
|
25
18
|
export function operationUnavailableIssue(request) {
|
|
26
19
|
return {
|
|
27
20
|
path: ["operation"],
|
|
@@ -39,11 +32,6 @@ function hasGeneralRootWhere(request) {
|
|
|
39
32
|
request.family === "delete" ||
|
|
40
33
|
request.family === "upsert"));
|
|
41
34
|
}
|
|
42
|
-
/**
|
|
43
|
-
* Validates one standard operation's semantic arguments against the active
|
|
44
|
-
* Contract. Operation availability and request-wide structural limits are
|
|
45
|
-
* enforced before deeper grammar validation.
|
|
46
|
-
*/
|
|
47
35
|
export function validateOperationArguments(contract, request, options) {
|
|
48
36
|
if (!isOperationAvailable(contract, request)) {
|
|
49
37
|
return { ok: false, issues: [operationUnavailableIssue(request)] };
|
|
@@ -26,16 +26,14 @@ export declare function resolveProjectionScope(resource: Resource<Contract> | un
|
|
|
26
26
|
* The position a projection NESTED beneath an admitted relation sits in: the
|
|
27
27
|
* unrestricted one, at every depth, under every top-level scope.
|
|
28
28
|
*
|
|
29
|
-
* **Measured at runtime on both pilot engines, 2026-10-03** — not inferred from
|
|
30
|
-
* types, which permit more than they accept. A bulk-returning write accepted
|
|
31
|
-
* `include: { <owned to-one>: { include: { <to-many>: true } } }` and populated
|
|
32
|
-
* rows, while the same to-many asked for at the top level was refused
|
|
33
|
-
* generated types say why: a bulk projection types an admitted
|
|
34
|
-
* *unrestricted* projection argument, so the full surface returns
|
|
29
|
+
* **Measured at runtime on both pilot engines, 2026-10-03** — not inferred from
|
|
30
|
+
* the types, which permit more than they accept. A bulk-returning write accepted
|
|
31
|
+
* `include: { <owned to-one>: { include: { <to-many>: true } } }` and populated
|
|
32
|
+
* the rows, while the same to-many asked for at the top level was refused
|
|
33
|
+
* outright. The generated types say why: a bulk projection types an admitted
|
|
34
|
+
* relation as the *unrestricted* projection argument, so the full surface returns
|
|
35
|
+
* one level in.
|
|
35
36
|
*
|
|
36
|
-
* Naming it is the point.
|
|
37
|
-
* refuse what the ORM accepts, which is C-855 with the sign flipped and the same
|
|
38
|
-
* defect; this constant is the single place that decision is written, and S7's
|
|
39
|
-
* `bulkDoesNotNarrowRecursively` pins the identical rule at the type level.
|
|
37
|
+
* Naming it is the point.
|
|
40
38
|
*/
|
|
41
39
|
export declare const NESTED_PROJECTION_SCOPE: ProjectionScope;
|
|
@@ -1,42 +1,7 @@
|
|
|
1
1
|
import { lookupOwn } from "../contracts/contract-lookup.js";
|
|
2
2
|
import { projectionScopeOf, } from "../contracts/resource-operations.js";
|
|
3
|
-
/**
|
|
4
|
-
* Which projection position one request's **top-level** projection arguments sit
|
|
5
|
-
* in, read off the variant the Resource advertises.
|
|
6
|
-
*
|
|
7
|
-
* Two readers need the answer and they run one after the other over the same
|
|
8
|
-
* request — the `maxBooleanNodes` walk in `operation-boolean-nodes.ts`, then the
|
|
9
|
-
* grammar walk in `operation-validator-core.ts`. They must agree: a walk that
|
|
10
|
-
* resolved a wider scope than the validator would count nodes inside a projection
|
|
11
|
-
* the validator then refuses (harmless), and a walk that resolved a narrower one
|
|
12
|
-
* would stop counting inside a projection the validator admits, which is a limit
|
|
13
|
-
* silently not enforced. So the resolution has one home.
|
|
14
|
-
*
|
|
15
|
-
* `"record"` is the answer wherever nothing narrower is stated — an absent
|
|
16
|
-
* Resource, an unadvertised variant, `true`, or a descriptor that qualifies only
|
|
17
|
-
* its write argument. Availability is **not** decided here: an unadvertised
|
|
18
|
-
* operation is refused by `operation-validator.ts` before either walk runs, and
|
|
19
|
-
* answering `"record"` for one keeps this function a projection question rather
|
|
20
|
-
* than a second, weaker copy of the availability gate.
|
|
21
|
-
*/
|
|
22
3
|
export function resolveProjectionScope(resource, request) {
|
|
23
4
|
const advertised = lookupOwn(resource?.operations, request.family);
|
|
24
5
|
return projectionScopeOf(lookupOwn(advertised, request.variant));
|
|
25
6
|
}
|
|
26
|
-
/**
|
|
27
|
-
* The position a projection NESTED beneath an admitted relation sits in: the
|
|
28
|
-
* unrestricted one, at every depth, under every top-level scope.
|
|
29
|
-
*
|
|
30
|
-
* **Measured at runtime on both pilot engines, 2026-10-03** — not inferred from the
|
|
31
|
-
* types, which permit more than they accept. A bulk-returning write accepted
|
|
32
|
-
* `include: { <owned to-one>: { include: { <to-many>: true } } }` and populated the
|
|
33
|
-
* rows, while the same to-many asked for at the top level was refused outright. The
|
|
34
|
-
* generated types say why: a bulk projection types an admitted relation as the
|
|
35
|
-
* *unrestricted* projection argument, so the full surface returns one level in.
|
|
36
|
-
*
|
|
37
|
-
* Naming it is the point. A recursive walk that passed its own scope down would
|
|
38
|
-
* refuse what the ORM accepts, which is C-855 with the sign flipped and the same
|
|
39
|
-
* defect; this constant is the single place that decision is written, and S7's
|
|
40
|
-
* `bulkDoesNotNarrowRecursively` pins the identical rule at the type level.
|
|
41
|
-
*/
|
|
42
7
|
export const NESTED_PROJECTION_SCOPE = "record";
|
|
@@ -1,27 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* array for the same reason `OPERATION_CODES` is one: the union below is the
|
|
6
|
-
* compiler's view of the set, and the response boundary needs the set itself
|
|
7
|
-
* to test a thrower-supplied code by identity before emitting it (ADR 0005
|
|
8
|
-
* applied to the V axis, ADR 0008 decision 4).
|
|
2
|
+
* It is a runtime array for the same reason `OPERATION_CODES` is one: the union
|
|
3
|
+
* below is the compiler's view of the set, and the response boundary needs the set
|
|
4
|
+
* itself to test a thrower-supplied code by identity before emitting it.
|
|
9
5
|
*/
|
|
10
6
|
export declare const VALIDATION_CODES: readonly ["V1000", "V1001", "V1002", "V1003", "V1004", "V1005", "V1006", "V1007", "V1008", "V1009", "V1010", "V1011", "V1012", "V1013", "V1014", "V1015", "V1016", "V1017", "V1018", "V1019"];
|
|
11
7
|
export type ValidationCode = (typeof VALIDATION_CODES)[number];
|
|
12
8
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* thrower-supplied issue message, which is untrusted and may carry provider
|
|
17
|
-
* text that specification 13.5 forbids in `cause`.
|
|
9
|
+
* This is the text the response boundary emits in place of a thrower-supplied
|
|
10
|
+
* issue message, which is untrusted and may carry provider text that specification
|
|
11
|
+
* 13.5 forbids in `cause`.
|
|
18
12
|
*
|
|
19
|
-
* It is deliberately not the only message a `V` code may ever carry. A
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* the ones it did.
|
|
13
|
+
* It is deliberately not the only message a `V` code may ever carry. A framework
|
|
14
|
+
* producer knows the offending field, limit or reference and says so; those issues
|
|
15
|
+
* are built here and mapped straight to their envelope by `mapValidationOutcome`,
|
|
16
|
+
* never through the sanitization boundary. This table is the floor for an issue
|
|
17
|
+
* the framework did not author, not a ceiling on the ones it did.
|
|
25
18
|
*/
|
|
26
19
|
export declare const VALIDATION_CODE_MESSAGES: Readonly<Record<ValidationCode, string>>;
|
|
27
20
|
export type ValidationIssue = {
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The closed Validation-code vocabulary, allocated by specification 13.3 as
|
|
3
|
-
* `V1000`-`V1015`, amended to `V1018` by ADR 0006 DA-4 and to `V1019` by the
|
|
4
|
-
* Phase 9 cascade refusal (§13.3, ADR 0008 decision 4). It is a runtime
|
|
5
|
-
* array for the same reason `OPERATION_CODES` is one: the union below is the
|
|
6
|
-
* compiler's view of the set, and the response boundary needs the set itself
|
|
7
|
-
* to test a thrower-supplied code by identity before emitting it (ADR 0005
|
|
8
|
-
* applied to the V axis, ADR 0008 decision 4).
|
|
9
|
-
*/
|
|
10
1
|
export const VALIDATION_CODES = [
|
|
11
2
|
"V1000",
|
|
12
3
|
"V1001",
|
|
@@ -29,20 +20,6 @@ export const VALIDATION_CODES = [
|
|
|
29
20
|
"V1018",
|
|
30
21
|
"V1019",
|
|
31
22
|
];
|
|
32
|
-
/**
|
|
33
|
-
* The framework's own text for each Validation code: the published meaning
|
|
34
|
-
* from specification 13.3, and from ADR 0006 DA-4 for the three codes it
|
|
35
|
-
* amended in. `V1019` is the architect's wording, verbatim (2026-10-04). This is the text the response boundary emits in place of a
|
|
36
|
-
* thrower-supplied issue message, which is untrusted and may carry provider
|
|
37
|
-
* text that specification 13.5 forbids in `cause`.
|
|
38
|
-
*
|
|
39
|
-
* It is deliberately not the only message a `V` code may ever carry. A
|
|
40
|
-
* framework producer knows the offending field, limit or reference and says
|
|
41
|
-
* so; those issues are built here and mapped straight to their envelope by
|
|
42
|
-
* `mapValidationOutcome`, never through the sanitization boundary. This table
|
|
43
|
-
* is the floor for an issue the framework did not author, not a ceiling on
|
|
44
|
-
* the ones it did.
|
|
45
|
-
*/
|
|
46
23
|
export const VALIDATION_CODE_MESSAGES = {
|
|
47
24
|
V1000: "Required value missing.",
|
|
48
25
|
V1001: "Invalid runtime/wire type.",
|
|
@@ -65,7 +42,6 @@ export const VALIDATION_CODE_MESSAGES = {
|
|
|
65
42
|
V1018: "Transaction reference resolved to no value.",
|
|
66
43
|
V1019: "Transaction step depends on a row removed by an earlier step's cascade",
|
|
67
44
|
};
|
|
68
|
-
/** Builds one Framework Validation Layer issue at its path. */
|
|
69
45
|
export function validationIssue(code, path, message) {
|
|
70
46
|
return { code, path, message };
|
|
71
47
|
}
|
|
@@ -30,14 +30,11 @@ export declare function resolveWriteScope(resource: Resource<Contract> | undefin
|
|
|
30
30
|
* `$connectOrCreate.create`, `$update.data` or `$upsert`'s two branches lands in
|
|
31
31
|
* the unrestricted write input on both pilot engines, whatever the top-level
|
|
32
32
|
* argument was. The measurement behind that is the flat bulk write inputs carrying
|
|
33
|
-
* **no relation member at all**, so a nested write is only ever reachable
|
|
34
|
-
* a relation the top-level scope already admitted — and past that point
|
|
35
|
-
* write surface returns.
|
|
33
|
+
* **no relation member at all**, so a nested write is only ever reachable
|
|
34
|
+
* *through* a relation the top-level scope already admitted — and past that point
|
|
35
|
+
* the full write surface returns.
|
|
36
36
|
*
|
|
37
37
|
* Naming it is the point, exactly as `NESTED_PROJECTION_SCOPE` names the same
|
|
38
|
-
* decision on the read axis.
|
|
39
|
-
* refuse what the ORM accepts, which is C-855 with the sign flipped and the same
|
|
40
|
-
* defect; this constant is the single place that decision is written, and S7's
|
|
41
|
-
* non-recursion rows pin the identical rule at the type level.
|
|
38
|
+
* decision on the read axis.
|
|
42
39
|
*/
|
|
43
40
|
export declare const NESTED_WRITE_SCOPE: WriteScope;
|
|
@@ -1,44 +1,7 @@
|
|
|
1
1
|
import { lookupOwn } from "../contracts/contract-lookup.js";
|
|
2
2
|
import { writeScopeOf, } from "../contracts/resource-operations.js";
|
|
3
|
-
/**
|
|
4
|
-
* Which write position one request's **top-level** `data` (or `create`/`update`)
|
|
5
|
-
* argument sits in, read off the variant the Resource advertises.
|
|
6
|
-
*
|
|
7
|
-
* The write mirror of `resolveProjectionScope`, and a separate function for the
|
|
8
|
-
* reason `resource-operations.ts` gives for `projectionScopeOf`/`writeScopeOf`
|
|
9
|
-
* being two: the axes are measured and consulted independently — the flat-bulk
|
|
10
|
-
* write scope covers four variants where the bulk-returning projection scope
|
|
11
|
-
* covers two — and a caller that needs one position should not be handed the other
|
|
12
|
-
* to discard.
|
|
13
|
-
*
|
|
14
|
-
* `"nested"` is the answer wherever nothing narrower is stated — an absent
|
|
15
|
-
* Resource, an unadvertised variant, `true`, or a descriptor that qualifies only
|
|
16
|
-
* its projection argument. Availability is **not** decided here: an unadvertised
|
|
17
|
-
* operation is refused by `operation-validator.ts` before the mutation walk runs,
|
|
18
|
-
* and answering `"nested"` for one keeps this function a write question rather than
|
|
19
|
-
* a second, weaker copy of the availability gate.
|
|
20
|
-
*/
|
|
21
3
|
export function resolveWriteScope(resource, request) {
|
|
22
4
|
const advertised = lookupOwn(resource?.operations, request.family);
|
|
23
5
|
return writeScopeOf(lookupOwn(advertised, request.variant));
|
|
24
6
|
}
|
|
25
|
-
/**
|
|
26
|
-
* The position a write NESTED beneath an admitted relation directive sits in: the
|
|
27
|
-
* unrestricted one, at every depth, under every top-level scope.
|
|
28
|
-
*
|
|
29
|
-
* It is a constant and not a parameter the recursion threads, because there is no
|
|
30
|
-
* depth at which the answer differs. A relation write reached through `$create`,
|
|
31
|
-
* `$connectOrCreate.create`, `$update.data` or `$upsert`'s two branches lands in
|
|
32
|
-
* the unrestricted write input on both pilot engines, whatever the top-level
|
|
33
|
-
* argument was. The measurement behind that is the flat bulk write inputs carrying
|
|
34
|
-
* **no relation member at all**, so a nested write is only ever reachable *through*
|
|
35
|
-
* a relation the top-level scope already admitted — and past that point the full
|
|
36
|
-
* write surface returns.
|
|
37
|
-
*
|
|
38
|
-
* Naming it is the point, exactly as `NESTED_PROJECTION_SCOPE` names the same
|
|
39
|
-
* decision on the read axis. A recursive walk that passed its own scope down would
|
|
40
|
-
* refuse what the ORM accepts, which is C-855 with the sign flipped and the same
|
|
41
|
-
* defect; this constant is the single place that decision is written, and S7's
|
|
42
|
-
* non-recursion rows pin the identical rule at the type level.
|
|
43
|
-
*/
|
|
44
7
|
export const NESTED_WRITE_SCOPE = "nested";
|
|
@@ -6,23 +6,11 @@ import type { AvProtocolRequest } from "./http-request.decoder.js";
|
|
|
6
6
|
import { type ReadRequest } from "./http-request.reader.js";
|
|
7
7
|
import { type AvProtocolResponse } from "./http-response.encoder.js";
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* reaches an Adapter: the protocol version (`A2006`), the ClientContract hash
|
|
12
|
-
* (`A2005`), then whether the ClientContract advertises the route at all
|
|
13
|
-
* (`A2001`, `A2002`). One implementation, for both route styles Q12 permits:
|
|
14
|
-
* the decoders answer a catch-all host's unadvertised path with it, and
|
|
15
|
-
* `protocol.answerAbsent` (S10) is the fallback a per-operation host mounts.
|
|
9
|
+
* "Removed" and "never existed" are not distinguished; a stale client hears
|
|
10
|
+
* `A2005` first.
|
|
16
11
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* `resourceUnavailableIssue`, `operationUnavailableIssue`,
|
|
20
|
-
* `mapValidationOutcome`, `transactionsUnavailableFailure`) — so a caller
|
|
21
|
-
* cannot tell which layer answered [M4, M5, M17]. "Removed" and "never
|
|
22
|
-
* existed" are not distinguished; a stale client hears `A2005` first (Q3).
|
|
23
|
-
*
|
|
24
|
-
* It reads the compiled Contracts only — passive data — so nothing it depends
|
|
25
|
-
* on can execute an operation.
|
|
12
|
+
* It reads the compiled Contracts only — passive data — so nothing it depends on
|
|
13
|
+
* can execute an operation.
|
|
26
14
|
*/
|
|
27
15
|
/** A route's three decoded segments, still untrusted strings. */
|
|
28
16
|
export type OperationRouteSegments = {
|
|
@@ -39,20 +27,19 @@ export type OperationRouteResolution = {
|
|
|
39
27
|
readonly failure: OperationFailureResponse;
|
|
40
28
|
};
|
|
41
29
|
/**
|
|
42
|
-
* An operation route `/_resources/<resource>/<family>/<variant>` under one
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
30
|
+
* An operation route `/_resources/<resource>/<family>/<variant>` under one client
|
|
31
|
+
* protocol identity: version → hash → Resource → operation. A Resource key is
|
|
32
|
+
* matched exactly and only as the ClientContract's own key; a family/variant pair
|
|
33
|
+
* only when it is a standard operation the Resource advertises, read through
|
|
34
|
+
* `isOperationVariantAvailable` alone.
|
|
47
35
|
*/
|
|
48
36
|
export declare function resolveOperationRoute(contracts: FrameworkContracts, protocol: ClientProtocolIdentity, route: OperationRouteSegments): OperationRouteResolution;
|
|
49
37
|
/**
|
|
50
|
-
* The `/_transactions` route under one client protocol identity: version →
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* `undefined` when the route is there.
|
|
38
|
+
* The `/_transactions` route under one client protocol identity: version → hash →
|
|
39
|
+
* the ClientContract's transaction capability. The route exists only when that
|
|
40
|
+
* capability is `"interactive"` — tested against the value itself, as
|
|
41
|
+
* `protocol.surface()` tests it — and is otherwise absent with core's own refusal
|
|
42
|
+
* of a plan. `undefined` when the route is there.
|
|
56
43
|
*/
|
|
57
44
|
export declare function transactionsRouteFailure(contracts: FrameworkContracts, protocol: ClientProtocolIdentity): OperationFailureResponse | undefined;
|
|
58
45
|
/**
|
|
@@ -69,10 +56,10 @@ type RouteCheck<Route> = ({
|
|
|
69
56
|
/**
|
|
70
57
|
* An operation route's checks before its body (decoder steps 2–4): the path
|
|
71
58
|
* (`A2000` unless `/_resources/<r>/<f>/<v>`, each segment decodable and none
|
|
72
|
-
* empty), the identity headers' presence (`A2000`), then
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
59
|
+
* empty), the identity headers' presence (`A2000`), then {@link
|
|
60
|
+
* resolveOperationRoute} — version, hash, Resource, operation — and the method
|
|
61
|
+
* (`A2012`, `Allow: POST`). One sequence for both route styles: `decodeOperation`
|
|
62
|
+
* reads the body only after it passes, `answerAbsent` never.
|
|
76
63
|
*/
|
|
77
64
|
export declare function checkOperationRoute(contracts: FrameworkContracts, read: ReadRequest): RouteCheck<{
|
|
78
65
|
readonly resource: string;
|
|
@@ -86,28 +73,26 @@ export declare function checkOperationRoute(contracts: FrameworkContracts, read:
|
|
|
86
73
|
*/
|
|
87
74
|
export declare function checkTransactionsRoute(contracts: FrameworkContracts, read: ReadRequest): RouteCheck<object>;
|
|
88
75
|
/**
|
|
89
|
-
* `protocol.answerAbsent(request)`
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* In order:
|
|
76
|
+
* `protocol.answerAbsent(request)` — the fallback a host that mounts one route per
|
|
77
|
+
* `protocol.surface()` entry mounts for every path it did not. Never a catch-all
|
|
78
|
+
* into framework handling: it reads no body, runs no pipeline, calls no Adapter,
|
|
79
|
+
* and takes only the compiled Contracts. In order:
|
|
94
80
|
*
|
|
95
81
|
* 1. a value that is not an `AvProtocolRequest` → `400 A2000`, minted id;
|
|
96
|
-
* 2. a path outside the protocol's underscore namespace
|
|
97
|
-
*
|
|
98
|
-
* framework's (the architect, 2026-10-05);
|
|
82
|
+
* 2. a path outside the protocol's underscore namespace → `undefined`: the host
|
|
83
|
+
* answers it itself — `/favicon.ico` is not the framework's;
|
|
99
84
|
* 3. `/_contract`: any method but `GET` → `405 A2012` with `Allow: GET`; no
|
|
100
|
-
* identity header is read
|
|
85
|
+
* identity header is read;
|
|
101
86
|
* 4. `/_transactions`, or else an operation route: exactly what the catch-all
|
|
102
|
-
* host's decoder answers before its body — path syntax and identity
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* 5. a route that EXISTS, reached with its own method — the host mounted
|
|
107
|
-
*
|
|
108
|
-
*
|
|
87
|
+
* host's decoder answers before its body — path syntax and identity presence
|
|
88
|
+
* (`A2000`), version (`A2006`), hash (`A2005`), Resource (`A2001`), operation
|
|
89
|
+
* or the `"none"` capability (`A2002`), method (`A2012`, `Allow: POST`) — each
|
|
90
|
+
* core's own envelope;
|
|
91
|
+
* 5. a route that EXISTS, reached with its own method — the host mounted only part
|
|
92
|
+
* of the surface — → `500 A3000`: a host wiring bug made visible, never a
|
|
93
|
+
* silent 404.
|
|
109
94
|
*
|
|
110
|
-
* Every framework answer echoes `Aventara-Request-Id
|
|
95
|
+
* Every framework answer echoes `Aventara-Request-Id`.
|
|
111
96
|
*/
|
|
112
97
|
export declare function answerAbsentRequest(contracts: FrameworkContracts, received: AvProtocolRequest): AvProtocolResponse | undefined;
|
|
113
98
|
export {};
|
|
@@ -11,13 +11,6 @@ import { CONTRACT_ROUTE, GET_ONLY, isProtocolPath, operationRouteSegments, POST_
|
|
|
11
11
|
import { encodeOperationResponse, } from "./http-response.encoder.js";
|
|
12
12
|
import { identityHeadersMissing, transportFailure, } from "./protocol-failure.js";
|
|
13
13
|
import { missingIdentityHeaders } from "./protocol-headers.js";
|
|
14
|
-
/**
|
|
15
|
-
* An operation route `/_resources/<resource>/<family>/<variant>` under one
|
|
16
|
-
* client protocol identity: version → hash → Resource → operation. A Resource
|
|
17
|
-
* key is matched exactly (§12.6) and only as the ClientContract's own key; a
|
|
18
|
-
* family/variant pair only when it is a standard operation the Resource
|
|
19
|
-
* advertises, read through `isOperationVariantAvailable` alone (§4).
|
|
20
|
-
*/
|
|
21
14
|
export function resolveOperationRoute(contracts, protocol, route) {
|
|
22
15
|
const identityFailure = protocolIdentityFailure(contracts, protocol);
|
|
23
16
|
if (identityFailure !== undefined) {
|
|
@@ -41,28 +34,12 @@ export function resolveOperationRoute(contracts, protocol, route) {
|
|
|
41
34
|
}
|
|
42
35
|
return { ok: true, operation };
|
|
43
36
|
}
|
|
44
|
-
/**
|
|
45
|
-
* The `/_transactions` route under one client protocol identity: version →
|
|
46
|
-
* hash → the ClientContract's transaction capability. The route exists only
|
|
47
|
-
* when that capability is `"interactive"` (A4) — tested against the value
|
|
48
|
-
* itself, as `protocol.surface()` tests it — and is otherwise absent with
|
|
49
|
-
* core's own refusal of a plan (`A2002`, `V1006` at `["operations"]`, M17).
|
|
50
|
-
* `undefined` when the route is there.
|
|
51
|
-
*/
|
|
52
37
|
export function transactionsRouteFailure(contracts, protocol) {
|
|
53
38
|
return (protocolIdentityFailure(contracts, protocol) ??
|
|
54
39
|
(contracts.client.transactions === "interactive"
|
|
55
40
|
? undefined
|
|
56
41
|
: transactionsUnavailableFailure()));
|
|
57
42
|
}
|
|
58
|
-
/**
|
|
59
|
-
* An operation route's checks before its body (decoder steps 2–4): the path
|
|
60
|
-
* (`A2000` unless `/_resources/<r>/<f>/<v>`, each segment decodable and none
|
|
61
|
-
* empty), the identity headers' presence (`A2000`), then
|
|
62
|
-
* {@link resolveOperationRoute} — version, hash, Resource, operation — and the
|
|
63
|
-
* method (`A2012`, `Allow: POST`). One sequence for both route styles (Q12):
|
|
64
|
-
* `decodeOperation` reads the body only after it passes, `answerAbsent` never.
|
|
65
|
-
*/
|
|
66
43
|
export function checkOperationRoute(contracts, read) {
|
|
67
44
|
const segments = operationRouteSegments(read.request.path);
|
|
68
45
|
if (segments === undefined) {
|
|
@@ -84,12 +61,6 @@ export function checkOperationRoute(contracts, read) {
|
|
|
84
61
|
}
|
|
85
62
|
: refusedWith(transportFailure("A2012", read.requestId, POST_ONLY));
|
|
86
63
|
}
|
|
87
|
-
/**
|
|
88
|
-
* `/_transactions`' checks before its body: the path (`A2000` unless exactly
|
|
89
|
-
* `/_transactions`), the identity headers' presence (`A2000`), then
|
|
90
|
-
* {@link transactionsRouteFailure} — version, hash, `"interactive"` — and the
|
|
91
|
-
* method (`A2012`, `Allow: POST`).
|
|
92
|
-
*/
|
|
93
64
|
export function checkTransactionsRoute(contracts, read) {
|
|
94
65
|
if (read.request.path !== TRANSACTIONS_ROUTE) {
|
|
95
66
|
return refusedWith(transportFailure("A2000", read.requestId));
|
|
@@ -105,37 +76,12 @@ export function checkTransactionsRoute(contracts, read) {
|
|
|
105
76
|
? { ok: true, protocol: read.protocol }
|
|
106
77
|
: refusedWith(transportFailure("A2012", read.requestId, POST_ONLY));
|
|
107
78
|
}
|
|
108
|
-
/** The `A2000` for a request whose identity headers are not all there, naming the missing ones (pilot.1). */
|
|
109
79
|
function identityFailureOf(read) {
|
|
110
80
|
return identityHeadersMissing(missingIdentityHeaders(read.headers), read.requestId);
|
|
111
81
|
}
|
|
112
82
|
function refusedWith(response) {
|
|
113
83
|
return { ok: false, response };
|
|
114
84
|
}
|
|
115
|
-
/**
|
|
116
|
-
* `protocol.answerAbsent(request)` (§5.9, Q2's O3; S10) — the fallback a host
|
|
117
|
-
* that mounts one route per `protocol.surface()` entry mounts for every path
|
|
118
|
-
* it did not. Never a catch-all into framework handling: it reads no body,
|
|
119
|
-
* runs no pipeline, calls no Adapter, and takes only the compiled Contracts.
|
|
120
|
-
* In order:
|
|
121
|
-
*
|
|
122
|
-
* 1. a value that is not an `AvProtocolRequest` → `400 A2000`, minted id;
|
|
123
|
-
* 2. a path outside the protocol's underscore namespace (§12.1) →
|
|
124
|
-
* `undefined`: the host answers it itself — `/favicon.ico` is not the
|
|
125
|
-
* framework's (the architect, 2026-10-05);
|
|
126
|
-
* 3. `/_contract`: any method but `GET` → `405 A2012` with `Allow: GET`; no
|
|
127
|
-
* identity header is read (§12.4);
|
|
128
|
-
* 4. `/_transactions`, or else an operation route: exactly what the catch-all
|
|
129
|
-
* host's decoder answers before its body — path syntax and identity
|
|
130
|
-
* presence (`A2000`), version (`A2006`), hash (`A2005`), Resource
|
|
131
|
-
* (`A2001`), operation or the `"none"` capability (`A2002`), method
|
|
132
|
-
* (`A2012`, `Allow: POST`) — each core's own envelope;
|
|
133
|
-
* 5. a route that EXISTS, reached with its own method — the host mounted
|
|
134
|
-
* only part of the surface — → `500 A3000`: a host wiring bug made
|
|
135
|
-
* visible, never a silent 404 (the architect, 2026-10-05).
|
|
136
|
-
*
|
|
137
|
-
* Every framework answer echoes `Aventara-Request-Id` (Q13).
|
|
138
|
-
*/
|
|
139
85
|
export function answerAbsentRequest(contracts, received) {
|
|
140
86
|
const read = readRequest(received);
|
|
141
87
|
if (!read.ok) {
|
|
@@ -155,7 +101,6 @@ export function answerAbsentRequest(contracts, received) {
|
|
|
155
101
|
: checkOperationRoute(contracts, read);
|
|
156
102
|
return route.ok ? unmounted(read.requestId) : route.response;
|
|
157
103
|
}
|
|
158
|
-
/** A mounted route's request at the fallback: the framework failed to route it. */
|
|
159
104
|
function unmounted(requestId) {
|
|
160
105
|
return encodeOperationResponse(operationFailure("A3000", { message: INTERNAL_FAILURE_MESSAGE }), requestId);
|
|
161
106
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The members of `AvProtocol`, as this module's own named exports. The entry
|
|
3
|
-
* (`./index.ts`) publishes this module whole as the namespace `AvProtocol
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* (`./index.ts`) publishes this module whole as the namespace `AvProtocol`: the
|
|
4
|
+
* language freezes a module namespace, and a bundler drops the members a consumer
|
|
5
|
+
* does not read.
|
|
6
6
|
*
|
|
7
|
-
* Re-exports only — no logic lives here. Every member is pinned, by name and
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* Re-exports only — no logic lives here. Every member is pinned, by name and by
|
|
8
|
+
* type, in `./index.test-d.ts`, whose exact `keyof` set fails when a member is
|
|
9
|
+
* added or removed without a row.
|
|
10
10
|
*/
|
|
11
11
|
export { normalizeEntrypoint } from "../config/entrypoint.normalizer.js";
|
|
12
12
|
export { scalarFormats } from "../contracts/wire-scalar-format.js";
|
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The members of `AvProtocol`, as this module's own named exports. The entry
|
|
3
|
-
* (`./index.ts`) publishes this module whole as the namespace `AvProtocol`
|
|
4
|
-
* (P5): the language freezes a module namespace, and a bundler drops the
|
|
5
|
-
* members a consumer does not read.
|
|
6
|
-
*
|
|
7
|
-
* Re-exports only — no logic lives here. Every member is pinned, by name and
|
|
8
|
-
* by type, in `./index.test-d.ts`, whose exact `keyof` set fails when a member
|
|
9
|
-
* is added or removed without a row.
|
|
10
|
-
*/
|
|
11
1
|
export { normalizeEntrypoint } from "../config/entrypoint.normalizer.js";
|
|
12
2
|
export { scalarFormats } from "../contracts/wire-scalar-format.js";
|
|
13
3
|
export { httpStatus } from "./http-status.table.js";
|
|
@@ -2,10 +2,9 @@ import type { ClientContract } from "../contracts/contract.js";
|
|
|
2
2
|
import type { AvProtocolRequest } from "./http-request.decoder.js";
|
|
3
3
|
import type { AvProtocolResponse } from "./http-response.encoder.js";
|
|
4
4
|
/**
|
|
5
|
-
* The served ClientContract, written once per binding: its JCS-canonical
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* it (M22).
|
|
5
|
+
* The served ClientContract, written once per binding: its JCS-canonical bytes and
|
|
6
|
+
* its entity tag, the quoted contract hash. The bytes include `protocol.hash`,
|
|
7
|
+
* although the hash's own input excludes it.
|
|
9
8
|
*/
|
|
10
9
|
export type ContractDocument = {
|
|
11
10
|
readonly body: string;
|
|
@@ -14,22 +13,20 @@ export type ContractDocument = {
|
|
|
14
13
|
/** The bound ClientContract as the document `_contract` serves. */
|
|
15
14
|
export declare function contractDocumentOf(client: ClientContract): ContractDocument;
|
|
16
15
|
/**
|
|
17
|
-
* `protocol.encodeContract(request)
|
|
18
|
-
*
|
|
16
|
+
* `protocol.encodeContract(request)`: the `GET <entrypoint>/_contract` responder.
|
|
17
|
+
* In order:
|
|
19
18
|
*
|
|
20
|
-
* 1. a value that is not an `AvProtocolRequest` → `400 A2000` under a minted
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* cannot read, as a decoder answers one);
|
|
19
|
+
* 1. a value that is not an `AvProtocolRequest` → `400 A2000` under a minted id
|
|
20
|
+
* (as the decoders answer it);
|
|
21
|
+
* 3. a path other than `/_contract` → `400 A2000` (path syntax this route cannot
|
|
22
|
+
* read, as a decoder answers one);
|
|
25
23
|
* 4. a method other than `GET` → `405 A2012` with `Allow: GET`;
|
|
26
|
-
* 5. `If-None-Match` matching the document's entity tag — RFC 9110 §13.1.2's
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
24
|
+
* 5. `If-None-Match` matching the document's entity tag — RFC 9110 §13.1.2's weak
|
|
25
|
+
* comparison, over a comma-separated list, or `*` — → `304 Not Modified`, no
|
|
26
|
+
* body, still carrying `ETag` and `Cache-Control`; otherwise `200` with the
|
|
27
|
+
* canonical bytes, `ETag`, `Cache-Control: no-cache` and `Content-Type:
|
|
28
|
+
* application/json`.
|
|
31
29
|
*
|
|
32
|
-
* No identity header is required or read
|
|
33
|
-
* discovery mechanism), and the body is never read.
|
|
30
|
+
* No identity header is required or read, and the body is never read.
|
|
34
31
|
*/
|
|
35
32
|
export declare function encodeContractRequest(document: ContractDocument, received: AvProtocolRequest): AvProtocolResponse;
|
|
@@ -2,32 +2,12 @@ import { canonicalizeContract } from "../contracts/contract-canonicalizer.js";
|
|
|
2
2
|
import { CONTRACT_ROUTE, GET_ONLY, readRequest, } from "./http-request.reader.js";
|
|
3
3
|
import { transportFailure } from "./protocol-failure.js";
|
|
4
4
|
import { headers, headerValue } from "./protocol-headers.js";
|
|
5
|
-
/** The bound ClientContract as the document `_contract` serves. */
|
|
6
5
|
export function contractDocumentOf(client) {
|
|
7
6
|
return Object.freeze({
|
|
8
7
|
body: canonicalizeContract(client),
|
|
9
8
|
etag: `"${client.protocol.hash}"`,
|
|
10
9
|
});
|
|
11
10
|
}
|
|
12
|
-
/**
|
|
13
|
-
* `protocol.encodeContract(request)` (§5.9, Q8; S11): the `GET
|
|
14
|
-
* <entrypoint>/_contract` responder. In order:
|
|
15
|
-
*
|
|
16
|
-
* 1. a value that is not an `AvProtocolRequest` → `400 A2000` under a minted
|
|
17
|
-
* id (as the decoders answer it);
|
|
18
|
-
* 2. the request id: `Aventara-Request-Id` adopted per Q13, else minted;
|
|
19
|
-
* 3. a path other than `/_contract` → `400 A2000` (path syntax this route
|
|
20
|
-
* cannot read, as a decoder answers one);
|
|
21
|
-
* 4. a method other than `GET` → `405 A2012` with `Allow: GET`;
|
|
22
|
-
* 5. `If-None-Match` matching the document's entity tag — RFC 9110 §13.1.2's
|
|
23
|
-
* weak comparison, over a comma-separated list, or `*` — → `304 Not
|
|
24
|
-
* Modified`, no body, still carrying `ETag` and `Cache-Control` (§15.4.5);
|
|
25
|
-
* otherwise `200` with the canonical bytes, `ETag`, `Cache-Control:
|
|
26
|
-
* no-cache` and `Content-Type: application/json`.
|
|
27
|
-
*
|
|
28
|
-
* No identity header is required or read (§12.4: the contract GET is the
|
|
29
|
-
* discovery mechanism), and the body is never read.
|
|
30
|
-
*/
|
|
31
11
|
export function encodeContractRequest(document, received) {
|
|
32
12
|
const read = readRequest(received);
|
|
33
13
|
if (!read.ok) {
|
|
@@ -53,20 +33,7 @@ export function encodeContractRequest(document, received) {
|
|
|
53
33
|
body: document.body,
|
|
54
34
|
};
|
|
55
35
|
}
|
|
56
|
-
/**
|
|
57
|
-
* One member of an `If-None-Match` list (RFC 9110 §5.6.1, §8.8.3): optional
|
|
58
|
-
* whitespace, an optional entity tag — `W/` optional, then an opaque tag of
|
|
59
|
-
* `etagc` between quotes — optional whitespace, then a comma or the end. An
|
|
60
|
-
* empty member is allowed, as the list rule allows it.
|
|
61
|
-
*/
|
|
62
36
|
const IF_NONE_MATCH_MEMBER = /[ \t]*(?:(?:W\/)?("[\x21\x23-\x7e\x80-\xff]*"))?[ \t]*(,|$)/y;
|
|
63
|
-
/**
|
|
64
|
-
* Whether `If-None-Match` names the current representation: `*`, or a list
|
|
65
|
-
* holding an entity tag whose opaque tag equals `etag`'s — the WEAK
|
|
66
|
-
* comparison (RFC 9110 §8.8.3.2), which `If-None-Match` uses (§13.1.2), so a
|
|
67
|
-
* `W/` prefix does not matter. A value that is not a well-formed list matches
|
|
68
|
-
* nothing; an absent header matches nothing.
|
|
69
|
-
*/
|
|
70
37
|
function noneMatchHolds(value, etag) {
|
|
71
38
|
if (value === undefined) {
|
|
72
39
|
return false;
|