@aventara/core 0.1.0-pilot.0 → 0.1.0-pilot.2
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/README.md +3 -3
- 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 +13 -57
- 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 +26 -23
- package/dist/protocol/protocol-failure.js +6 -6
- package/dist/protocol/protocol-headers.d.ts +30 -27
- package/dist/protocol/protocol-headers.js +3 -61
- 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
|
@@ -5,16 +5,13 @@ import type { Contract } from "../contracts/contract.js";
|
|
|
5
5
|
import type { OperationFamily } from "../operations/operation-identity.js";
|
|
6
6
|
import type { FrameworkError } from "./framework-error.js";
|
|
7
7
|
/**
|
|
8
|
-
* What a pipeline is told about the HTTP request a client-origin operation
|
|
9
|
-
*
|
|
10
|
-
* (F-609; the architect, Phase 10 Q7; ADR 0010). Specification §17.2 states
|
|
11
|
-
* this shape, and developers may read it in their pipelines: the verb, always
|
|
12
|
-
* `POST` on a framework route, and the request's headers.
|
|
8
|
+
* What a pipeline is told about the HTTP request a client-origin operation arrived
|
|
9
|
+
* on — a **deliberate exception** to core's transport-agnosticism.
|
|
13
10
|
*
|
|
14
|
-
* Core never parses HTTP to fill it. `@aventara/core/protocol`'s decoders do,
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
11
|
+
* Core never parses HTTP to fill it. `@aventara/core/protocol`'s decoders do, with
|
|
12
|
+
* header names **lower-cased** and a repeated header's values joined with `", "`
|
|
13
|
+
* (RFC 9110 §5.3), so a pipeline reads one spelling. An application-scope request
|
|
14
|
+
* carries none (`ClientOperationRequest.transport` is optional).
|
|
18
15
|
*/
|
|
19
16
|
export type PipelineTransportContext = {
|
|
20
17
|
readonly method: "POST";
|
|
@@ -23,27 +20,24 @@ export type PipelineTransportContext = {
|
|
|
23
20
|
/**
|
|
24
21
|
* What a pipeline callback is told about the operation it is wrapping.
|
|
25
22
|
*
|
|
26
|
-
* `resource` reads its key set from the **AdapterModel**, not from a
|
|
27
|
-
* `Contract
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
23
|
+
* `resource` reads its key set from the **AdapterModel**, not from a `Contract`:
|
|
24
|
+
* `Contract["resources"]` is an open `Record<string, …>`, so the `C extends
|
|
25
|
+
* Contract` parameter this type used to take could never name the Resources an
|
|
26
|
+
* author actually has — it erased to `string`. `M` can name them, and
|
|
27
|
+
* configuration cannot add Resources, so `M` is the whole answer.
|
|
31
28
|
*
|
|
32
|
-
*
|
|
33
|
-
* and this type has none: `contract` is passive compiled data, `args` is
|
|
34
|
-
* `unknown` until Phase 9 (F-701), and `resource` comes from `M` alone. A
|
|
35
|
-
* `Cfg` parameter here would be referenced nowhere — `biome` flags it
|
|
29
|
+
* A `Cfg` parameter here would be referenced nowhere — `biome` flags it
|
|
36
30
|
* (`lint/correctness/noUnusedVariables`) and it would encode no semantic
|
|
37
|
-
* dependency. `FrameworkScopeConfig` already has the precedent one line
|
|
38
|
-
*
|
|
31
|
+
* dependency. `FrameworkScopeConfig` already has the precedent one line above
|
|
32
|
+
* `pipelines`: `fields` takes `M` only.
|
|
39
33
|
*
|
|
40
|
-
* `contract` stays the erased {@link Contract} deliberately: a compiled
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
34
|
+
* `contract` stays the erased {@link Contract} deliberately: a compiled Contract
|
|
35
|
+
* is passive semantic data whose result "stays untyped by design". Threading
|
|
36
|
+
* configuration into it would rebuild the authoring-config-to-compiled-contract
|
|
37
|
+
* bridge this work bypasses.
|
|
44
38
|
*
|
|
45
|
-
* Under the default `M` the key set degenerates to `string`, so an
|
|
46
|
-
*
|
|
39
|
+
* Under the default `M` the key set degenerates to `string`, so an unannotated
|
|
40
|
+
* `PipelineContext` is what it was before.
|
|
47
41
|
*/
|
|
48
42
|
export type PipelineContext<M extends AdapterModel = AdapterModel> = {
|
|
49
43
|
readonly contract: Contract;
|
|
@@ -1,35 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core's referential-action vocabulary, and the transitive cascade closure the
|
|
3
|
-
* transaction planner reads
|
|
3
|
+
* transaction planner reads.
|
|
4
4
|
*
|
|
5
5
|
* The facts are an Adapter's: which relation edges exist, and what deleting a
|
|
6
|
-
* referenced row does to the rows that reference it.
|
|
7
|
-
* core's — the architect rejected keeping it below the seam on 2026-10-02,
|
|
8
|
-
* because every Adapter would then re-implement it. So the words here are
|
|
6
|
+
* referenced row does to the rows that reference it. So the words here are
|
|
9
7
|
* Aventara's, stated as the effect on the referencing rows, and an Adapter
|
|
10
8
|
* translates its own provider's vocabulary into them.
|
|
11
9
|
*
|
|
12
|
-
* None of this enters a Contract. It is not part of the semantic model a
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* None of this enters a Contract. It is not part of the semantic model a Contract
|
|
11
|
+
* is compiled from, so it moves no Contract value and no hash; it is a planning
|
|
12
|
+
* fact, read once when the Framework is constructed.
|
|
15
13
|
*/
|
|
16
14
|
/**
|
|
17
|
-
* What deleting a referenced row does to the rows that reference it.
|
|
18
|
-
* words are the architect's (binding, 2026-10-04), and mirror SQL's
|
|
19
|
-
* referential actions one to one, so no adapter has to choose between two of
|
|
20
|
-
* them:
|
|
15
|
+
* What deleting a referenced row does to the rows that reference it.
|
|
21
16
|
*
|
|
22
|
-
* - `cascade` — they are deleted with it, and their own referencing rows in
|
|
23
|
-
*
|
|
17
|
+
* - `cascade` — they are deleted with it, and their own referencing rows in turn
|
|
18
|
+
* (SQL `ON DELETE CASCADE`).
|
|
24
19
|
* - `restrict` — the delete is refused while they reference it (`RESTRICT`).
|
|
25
20
|
* - `noAction` — the delete is refused while they reference it (`NO ACTION`).
|
|
26
|
-
* Measured identical to `restrict` on both pilot engines
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
21
|
+
* Measured identical to `restrict` on both pilot engines: neither declares the
|
|
22
|
+
* constraint `DEFERRABLE`, so the end-of-statement check answers one delete
|
|
23
|
+
* exactly as `RESTRICT` does. It stays a distinct word because it is a distinct
|
|
24
|
+
* schema fact.
|
|
30
25
|
* - `setNull` — they are kept, the reference set to null (`SET NULL`).
|
|
31
|
-
* - `setDefault` — they are kept, the reference set to its column default
|
|
32
|
-
*
|
|
26
|
+
* - `setDefault` — they are kept, the reference set to its column default (`SET
|
|
27
|
+
* DEFAULT`).
|
|
33
28
|
*
|
|
34
29
|
* Only `cascade` takes rows away, so only `cascade` is followed by the closure.
|
|
35
30
|
*/
|
|
@@ -1,26 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core's referential-action vocabulary, and the transitive cascade closure the
|
|
3
|
-
* transaction planner reads (F-806, Phase 9 S10).
|
|
4
|
-
*
|
|
5
|
-
* The facts are an Adapter's: which relation edges exist, and what deleting a
|
|
6
|
-
* referenced row does to the rows that reference it. The reasoning over them is
|
|
7
|
-
* core's — the architect rejected keeping it below the seam on 2026-10-02,
|
|
8
|
-
* because every Adapter would then re-implement it. So the words here are
|
|
9
|
-
* Aventara's, stated as the effect on the referencing rows, and an Adapter
|
|
10
|
-
* translates its own provider's vocabulary into them.
|
|
11
|
-
*
|
|
12
|
-
* None of this enters a Contract. It is not part of the semantic model a
|
|
13
|
-
* Contract is compiled from, so it moves no Contract value and no hash; it is a
|
|
14
|
-
* planning fact, read once when the Framework is constructed.
|
|
15
|
-
*/
|
|
16
1
|
const NO_CASCADE = new Set();
|
|
17
|
-
/**
|
|
18
|
-
* Builds the closure over an Adapter's table, once. An absent table is the
|
|
19
|
-
* answer of an Adapter that cannot state its referential actions; it is
|
|
20
|
-
* believed, so nothing cascades.
|
|
21
|
-
*/
|
|
22
2
|
export function resolveCascadeClosure(table) {
|
|
23
|
-
// target → the Resources a delete of it cascades into, one hop.
|
|
24
3
|
const removedBy = new Map();
|
|
25
4
|
for (const [resource, edges] of Object.entries(table ?? {})) {
|
|
26
5
|
for (const edge of edges) {
|
|
@@ -41,8 +20,6 @@ export function resolveCascadeClosure(table) {
|
|
|
41
20
|
const closure = new Set();
|
|
42
21
|
const frontier = [...(removedBy.get(resource) ?? [])];
|
|
43
22
|
for (let next = frontier.pop(); next !== undefined; next = frontier.pop()) {
|
|
44
|
-
// The visited set is what makes a self-referential or cyclic cascade
|
|
45
|
-
// terminate: each Resource is expanded at most once.
|
|
46
23
|
if (closure.has(next)) {
|
|
47
24
|
continue;
|
|
48
25
|
}
|
|
@@ -1,27 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The one place core mints a request id (Q10 = B; F-833). The typed façades and
|
|
3
|
-
* the typed transaction runner call it when the caller supplies no usable id.
|
|
4
|
-
* It is internal: neither the main entry nor `@aventara/core/protocol` exports
|
|
5
|
-
* a minting helper. A host's correlation id reaches core as data —
|
|
6
|
-
* `ExecutionOptions.requestId` in process, or the `requestId` of a request the
|
|
7
|
-
* protocol decoders build from an adopted `Aventara-Request-Id` (Phase 10 S7,
|
|
8
|
-
* which mints through this module when none was adopted).
|
|
9
|
-
*/
|
|
10
1
|
function createRequestId() {
|
|
11
2
|
return globalThis.crypto.randomUUID();
|
|
12
3
|
}
|
|
13
|
-
/**
|
|
14
|
-
* The request id of one façade call or transaction run: the caller's
|
|
15
|
-
* `ExecutionOptions.requestId` when it is a non-empty string, otherwise a minted
|
|
16
|
-
* one. Nothing is refused (the call runs either way); the empty string is read
|
|
17
|
-
* as absent, because it names nothing a log line or a diagnostic could be
|
|
18
|
-
* correlated by.
|
|
19
|
-
*
|
|
20
|
-
* Read as `unknown` because the façades are total for untyped callers too: a
|
|
21
|
-
* value the type refuses — a non-string id, a non-object options argument, a
|
|
22
|
-
* getter that throws — is ignored rather than carried into a `string` slot or
|
|
23
|
-
* thrown out of a call that must resolve.
|
|
24
|
-
*/
|
|
25
4
|
export function requestIdOf(options) {
|
|
26
5
|
if (typeof options === "object" && options !== null) {
|
|
27
6
|
let requestId;
|
|
@@ -20,14 +20,13 @@ export type ScalarValueNormalizationResult = {
|
|
|
20
20
|
};
|
|
21
21
|
type Path = readonly (string | number)[];
|
|
22
22
|
/**
|
|
23
|
-
* The one discriminant between an argument OBJECT and a VALUE wherever a
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* another.
|
|
23
|
+
* The one discriminant between an argument OBJECT and a VALUE wherever a position
|
|
24
|
+
* admits both — a filter position above all: a **plain** record is an operator
|
|
25
|
+
* object, and anything else — a `Date`, a core `Decimal`, a `Uint8Array` — is a
|
|
26
|
+
* value, which equality shorthand then holds to the field's scalar. The validator
|
|
27
|
+
* (`operation-validator-core.ts`) reads a filter position through this same
|
|
28
|
+
* answer, and an adapter's filter translation is expected to, so a position cannot
|
|
29
|
+
* be operators to one reader and a value to another.
|
|
31
30
|
*/
|
|
32
31
|
export declare function isPlainRecord(value: unknown): value is Readonly<Record<string, unknown>>;
|
|
33
32
|
/**
|
|
@@ -36,14 +35,13 @@ export declare function isPlainRecord(value: unknown): value is Readonly<Record<
|
|
|
36
35
|
*/
|
|
37
36
|
export declare function normalizeScalarFieldValue(contract: Contract, field: ScalarField<Contract>, value: unknown, scope: RequestOrigin | "runtime", path: Path): ScalarValueNormalizationResult;
|
|
38
37
|
/**
|
|
39
|
-
* Copies one validated runtime value of a scalar field into a value the
|
|
40
|
-
*
|
|
41
|
-
* `
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* declaring its copy.
|
|
38
|
+
* Copies one validated runtime value of a scalar field into a value the framework
|
|
39
|
+
* owns, per scalar codec: `datetime` → a new `Date`, `bytes` → a sliced
|
|
40
|
+
* `Uint8Array`, `json` → a structured deep copy, and a list → a new array of
|
|
41
|
+
* copied items. `decimal` keeps its identity, and strings, numbers, booleans,
|
|
42
|
+
* bigints, enum members and `null` are immutable and returned unchanged. {@link
|
|
43
|
+
* SCALAR_ATOM_COPIERS} is exhaustive over {@link BuiltInScalar}, so a new codec
|
|
44
|
+
* cannot reach this function without declaring its copy.
|
|
47
45
|
*/
|
|
48
46
|
export declare function copyScalarFieldValue(field: ScalarField<Contract>, value: unknown): unknown;
|
|
49
47
|
/**
|
|
@@ -4,20 +4,12 @@ import { routeTransactionReferenceCandidate } from "../transactions/transaction-
|
|
|
4
4
|
import { Decimal } from "./decimal.js";
|
|
5
5
|
const INT_MIN = -(2 ** 31);
|
|
6
6
|
const INT_MAX = 2 ** 31 - 1;
|
|
7
|
+
const BIGINT_MIN = -(2n ** 63n);
|
|
8
|
+
const BIGINT_MAX = 2n ** 63n - 1n;
|
|
7
9
|
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
8
10
|
function isRecord(value) {
|
|
9
11
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
10
12
|
}
|
|
11
|
-
/**
|
|
12
|
-
* The one discriminant between an argument OBJECT and a VALUE wherever a
|
|
13
|
-
* position admits both — a filter position above all: a **plain** record is an
|
|
14
|
-
* operator object, and anything else — a `Date`, a core `Decimal`, a
|
|
15
|
-
* `Uint8Array` — is a value, which equality shorthand then holds to the field's
|
|
16
|
-
* scalar (spec §9.1). The validator (`operation-validator-core.ts`) reads a
|
|
17
|
-
* filter position through this same answer, and an adapter's filter translation
|
|
18
|
-
* is expected to, so a position cannot be operators to one reader and a value to
|
|
19
|
-
* another.
|
|
20
|
-
*/
|
|
21
13
|
export function isPlainRecord(value) {
|
|
22
14
|
if (!isRecord(value)) {
|
|
23
15
|
return false;
|
|
@@ -45,20 +37,6 @@ function materializeJsonPath(root, link) {
|
|
|
45
37
|
segments.reverse();
|
|
46
38
|
return [...root, ...segments];
|
|
47
39
|
}
|
|
48
|
-
/**
|
|
49
|
-
* A JSON scalar's interior is opaque to the Contract, so no semantic limit
|
|
50
|
-
* bounds its depth - `maxNestingDepth` counts Contract nesting and
|
|
51
|
-
* `maxRequestBytes` is a transport concern. The traversal therefore carries
|
|
52
|
-
* its own stack on the heap: a payload deep enough to exhaust the call stack
|
|
53
|
-
* must still normalize rather than become an internal failure.
|
|
54
|
-
*
|
|
55
|
-
* `seen` holds the ancestors of the value being visited, so a repeated
|
|
56
|
-
* sibling reference is legal and only a genuine cycle is rejected.
|
|
57
|
-
*
|
|
58
|
-
* Every node it emits is typed {@link JsonValue}, so the public type and what
|
|
59
|
-
* this traversal produces are one fact: a branch that emitted anything else
|
|
60
|
-
* would not compile.
|
|
61
|
-
*/
|
|
62
40
|
function normalizeJsonValue(value, path, seen) {
|
|
63
41
|
const issues = [];
|
|
64
42
|
let root;
|
|
@@ -238,6 +216,16 @@ function normalizeScalarAtom(contract, field, value, scope, path, allowNull) {
|
|
|
238
216
|
else {
|
|
239
217
|
normalized = { ok: true, value: BigInt(value) };
|
|
240
218
|
}
|
|
219
|
+
if (normalized.ok &&
|
|
220
|
+
typeof normalized.value === "bigint" &&
|
|
221
|
+
(normalized.value < BIGINT_MIN || normalized.value > BIGINT_MAX)) {
|
|
222
|
+
normalized = {
|
|
223
|
+
ok: false,
|
|
224
|
+
issues: [
|
|
225
|
+
issue("V1004", path, "BigInt value is outside signed 64-bit range."),
|
|
226
|
+
],
|
|
227
|
+
};
|
|
228
|
+
}
|
|
241
229
|
break;
|
|
242
230
|
case "decimal":
|
|
243
231
|
if (scope === "application") {
|
|
@@ -346,10 +334,6 @@ function normalizeScalarAtom(contract, field, value, scope, path, allowNull) {
|
|
|
346
334
|
}
|
|
347
335
|
return normalized;
|
|
348
336
|
}
|
|
349
|
-
/**
|
|
350
|
-
* Normalizes one field value to Aventara's provider-neutral runtime form.
|
|
351
|
-
* `runtime` is used for framework-produced values regardless of request origin.
|
|
352
|
-
*/
|
|
353
337
|
export function normalizeScalarFieldValue(contract, field, value, scope, path) {
|
|
354
338
|
if (value === null) {
|
|
355
339
|
return field.nullable
|
|
@@ -377,32 +361,17 @@ export function normalizeScalarFieldValue(contract, field, value, scope, path) {
|
|
|
377
361
|
}
|
|
378
362
|
return normalizeScalarAtom(contract, field, value, scope === "runtime" ? "application" : scope, path, field.nullable);
|
|
379
363
|
}
|
|
380
|
-
/**
|
|
381
|
-
* One copier per built-in scalar codec, keyed by a mapped type over
|
|
382
|
-
* {@link BuiltInScalar}: a codec added to the protocol is a compile error
|
|
383
|
-
* here until it declares how a framework-owned copy of its runtime form is
|
|
384
|
-
* made, so DA-25 cannot silently degrade to identity sharing for it. The
|
|
385
|
-
* immutable codecs name themselves rather than sharing a `default` branch.
|
|
386
|
-
*/
|
|
387
364
|
const SCALAR_ATOM_COPIERS = {
|
|
388
365
|
string: (value) => value,
|
|
389
366
|
boolean: (value) => value,
|
|
390
367
|
int: (value) => value,
|
|
391
368
|
float: (value) => value,
|
|
392
369
|
bigint: (value) => value,
|
|
393
|
-
// `Decimal` holds its digits in a `readonly` ES private field assigned once
|
|
394
|
-
// by its constructor and exposes no mutator, so one instance cannot connect
|
|
395
|
-
// two views of it.
|
|
396
370
|
decimal: (value) => value,
|
|
397
371
|
datetime: (value) => value instanceof Date ? new Date(value.getTime()) : value,
|
|
398
372
|
bytes: (value) => (value instanceof Uint8Array ? value.slice() : value),
|
|
399
373
|
json: (value) => structuredClone(value),
|
|
400
374
|
};
|
|
401
|
-
/**
|
|
402
|
-
* The same table for a runtime lookup: a Contract's scalar name is a `string`
|
|
403
|
-
* in the type system, so an unknown name yields no copier and the value is
|
|
404
|
-
* returned as it is.
|
|
405
|
-
*/
|
|
406
375
|
const SCALAR_ATOM_COPIER_LOOKUP = SCALAR_ATOM_COPIERS;
|
|
407
376
|
function copyScalarAtom(field, value) {
|
|
408
377
|
if (value === null || "enum" in field.type) {
|
|
@@ -411,16 +380,6 @@ function copyScalarAtom(field, value) {
|
|
|
411
380
|
const copier = SCALAR_ATOM_COPIER_LOOKUP[field.type.scalar];
|
|
412
381
|
return copier === undefined ? value : copier(value);
|
|
413
382
|
}
|
|
414
|
-
/**
|
|
415
|
-
* Copies one validated runtime value of a scalar field into a value the
|
|
416
|
-
* framework owns, per scalar codec (DA-25): `datetime` → a new `Date`,
|
|
417
|
-
* `bytes` → a sliced `Uint8Array`, `json` → a structured deep copy, and a list
|
|
418
|
-
* → a new array of copied items. `decimal` keeps its identity, and strings,
|
|
419
|
-
* numbers, booleans, bigints, enum members and `null` are immutable and
|
|
420
|
-
* returned unchanged. {@link SCALAR_ATOM_COPIERS} is exhaustive over
|
|
421
|
-
* {@link BuiltInScalar}, so a new codec cannot reach this function without
|
|
422
|
-
* declaring its copy.
|
|
423
|
-
*/
|
|
424
383
|
export function copyScalarFieldValue(field, value) {
|
|
425
384
|
if (!field.list || !Array.isArray(value)) {
|
|
426
385
|
return copyScalarAtom(field, value);
|
|
@@ -780,10 +739,6 @@ function isUniqueOperation(request) {
|
|
|
780
739
|
request.family === "delete" ||
|
|
781
740
|
request.family === "upsert"));
|
|
782
741
|
}
|
|
783
|
-
/**
|
|
784
|
-
* Normalizes every scalar leaf in one structurally valid standard operation.
|
|
785
|
-
* Client wire values are decoded; application values are validated in runtime form.
|
|
786
|
-
*/
|
|
787
742
|
export function normalizeOperationScalarValues(contract, request, scope, options) {
|
|
788
743
|
const issues = [];
|
|
789
744
|
const args = cloneRecord(request.arguments);
|
|
@@ -17,9 +17,9 @@ declare const OPERATION_RESULT: unique symbol;
|
|
|
17
17
|
declare const OPERATION_HANDLE: unique symbol;
|
|
18
18
|
/**
|
|
19
19
|
* Standard-library shapes that are objects but never a projected result row.
|
|
20
|
-
* `ArrayBufferView` is TypeScript's shared structural base for every typed
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* `ArrayBufferView` is TypeScript's shared structural base for every typed array
|
|
21
|
+
* and `DataView`, so no constructor is enumerated and the declaration stays
|
|
22
|
+
* portable ES2022 with no runtime dependency.
|
|
23
23
|
*/
|
|
24
24
|
export type BuiltinNonRow = Date | RegExp | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown> | PromiseLike<unknown> | ArrayBufferView;
|
|
25
25
|
/**
|
|
@@ -32,18 +32,13 @@ export type BuiltinNonRow = Date | RegExp | ReadonlyMap<unknown, unknown> | Read
|
|
|
32
32
|
export type SingleRowResult<T> = NonNullable<T> extends readonly unknown[] ? never : NonNullable<T> extends (...args: never[]) => unknown ? never : NonNullable<T> extends BuiltinNonRow ? never : NonNullable<T> extends object ? Extract<keyof NonNullable<T>, string> extends never ? never : NonNullable<T> : never;
|
|
33
33
|
/** The field names a result row can be referenced by. */
|
|
34
34
|
export type ReferenceableField<T> = Extract<keyof SingleRowResult<T>, string>;
|
|
35
|
-
/** Builds a §14.2 `$ref` carrying the source field's own value type. */
|
|
36
35
|
export type ReferenceBuilder<T> = <F extends ReferenceableField<T>>(field: F) => TransactionReference<SingleRowResult<T>[F]>;
|
|
37
36
|
/** Contributes `$ref` only where the result is a referenceable single row. */
|
|
38
37
|
export type OperationReferenceSurface<T> = [SingleRowResult<T>] extends [never] ? {} : {
|
|
39
38
|
readonly $ref: ReferenceBuilder<T>;
|
|
40
39
|
};
|
|
41
40
|
/**
|
|
42
|
-
* An opaque deferred-operation handle.
|
|
43
|
-
* it exposes no `resource`, `family`, `variant`, `args` or `fingerprint`, and
|
|
44
|
-
* is never intersected with `DeferredOperation`. Phase 9 and the generated
|
|
45
|
-
* Phase 12 builders construct handles; `T` is supplied by the caller until
|
|
46
|
-
* Phase 9 derives it from a Contract as `OperationResultFor` (DA-11).
|
|
41
|
+
* An opaque deferred-operation handle.
|
|
47
42
|
*/
|
|
48
43
|
export type Operation<T> = {
|
|
49
44
|
readonly [OPERATION_HANDLE]: true;
|
|
@@ -54,13 +49,13 @@ export type TransactionResults<Ops extends readonly Operation<unknown>[]> = {
|
|
|
54
49
|
readonly [I in keyof Ops]: Ops[I] extends Operation<infer R> ? R : never;
|
|
55
50
|
};
|
|
56
51
|
/**
|
|
57
|
-
* The one typed transaction runner — `framework.transaction`'s own type. It
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
52
|
+
* The one typed transaction runner — `framework.transaction`'s own type. It infers
|
|
53
|
+
* the handle tuple without `as const` at the call site, and resolves what the
|
|
54
|
+
* runtime answers: the committed envelope (`A1009`) with each handle's result in
|
|
55
|
+
* plan order, or the failure response. Never the bare result tuple.
|
|
61
56
|
*
|
|
62
57
|
* The second argument is the run's `ExecutionOptions`: its `requestId` is every
|
|
63
|
-
* step's, under either origin
|
|
58
|
+
* step's, under either origin. A handle takes none.
|
|
64
59
|
*/
|
|
65
60
|
export type TransactionRunner = <const Ops extends readonly Operation<unknown>[]>(operations: Ops, options?: ExecutionOptions) => Promise<TransactionCommittedResponse<TransactionResults<Ops>> | OperationFailureResponse>;
|
|
66
61
|
export {};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Contract } from "../contracts/contract.js";
|
|
2
2
|
import type { OperationIdentity } from "../operations/operation-identity.js";
|
|
3
3
|
import type { SemanticOperationArguments } from "../operations/operation-validator.js";
|
|
4
|
-
/** Encodes validated application arguments into the §6.2 wire scalar form. */
|
|
5
4
|
export declare function encodeOperationArgumentsForWire(contract: Contract, operation: OperationIdentity & {
|
|
6
5
|
readonly resource: string;
|
|
7
6
|
}, args: SemanticOperationArguments): unknown;
|
|
@@ -204,14 +204,6 @@ function encodeScalarMutation(field, value) {
|
|
|
204
204
|
}
|
|
205
205
|
return encoded;
|
|
206
206
|
}
|
|
207
|
-
/**
|
|
208
|
-
* The identifier half of the relation-mutation grammar, and the companion of
|
|
209
|
-
* `RELATION_MUTATION_RECORD_SITES`, which owns the record operands and leaves
|
|
210
|
-
* identifier operands empty because the write planner never encodes them. This
|
|
211
|
-
* pass does, so it describes them here rather than hand-walking the grammar a
|
|
212
|
-
* second time. Both tables are keyed by `RelationMutationDirective`, so a new
|
|
213
|
-
* directive cannot be added without this file failing to compile.
|
|
214
|
-
*/
|
|
215
207
|
const RELATION_MUTATION_SELECTOR_SITES = {
|
|
216
208
|
$create: [],
|
|
217
209
|
$connect: [{ key: undefined, form: "unique" }],
|
|
@@ -222,11 +214,6 @@ const RELATION_MUTATION_SELECTOR_SITES = {
|
|
|
222
214
|
$delete: [{ key: "where", form: "filter" }],
|
|
223
215
|
$upsert: [{ key: "where", form: "unique" }],
|
|
224
216
|
};
|
|
225
|
-
/**
|
|
226
|
-
* Encodes one site of a directive operand. A site with no key names the whole
|
|
227
|
-
* operand; a keyed site names one own member of it and leaves an operand that
|
|
228
|
-
* is not a plain record, or that does not carry the member, alone.
|
|
229
|
-
*/
|
|
230
217
|
function encodeRelationSite(entry, key, encode) {
|
|
231
218
|
if (key === undefined) {
|
|
232
219
|
return encode(entry);
|
|
@@ -294,7 +281,6 @@ function isUniqueOperation(operation) {
|
|
|
294
281
|
operation.family === "delete" ||
|
|
295
282
|
operation.family === "upsert"));
|
|
296
283
|
}
|
|
297
|
-
/** Encodes validated application arguments into the §6.2 wire scalar form. */
|
|
298
284
|
export function encodeOperationArgumentsForWire(contract, operation, args) {
|
|
299
285
|
const encoded = cloneRecord(args);
|
|
300
286
|
if (hasOwnWireProperty(args, "where")) {
|
|
@@ -13,7 +13,6 @@ function encodeBase64Url(bytes) {
|
|
|
13
13
|
export function isOperationFingerprint(value) {
|
|
14
14
|
return typeof value === "string" && OPERATION_FINGERPRINT_PATTERN.test(value);
|
|
15
15
|
}
|
|
16
|
-
/** Computes the v1 operation fingerprint from an already wire-form node. */
|
|
17
16
|
export async function computeOperationFingerprint(node) {
|
|
18
17
|
const canonical = canonicalizeJson({
|
|
19
18
|
resource: node.resource,
|
|
@@ -13,9 +13,6 @@ function inspectArrayDataProperty(value, key) {
|
|
|
13
13
|
if (!("value" in descriptor)) {
|
|
14
14
|
return { ok: false };
|
|
15
15
|
}
|
|
16
|
-
// This can invoke a transparent proxy trap, but never an accessor: the
|
|
17
|
-
// descriptor above proved that the property is data-backed. The value
|
|
18
|
-
// consumed below remains the descriptor value.
|
|
19
16
|
Reflect.get(value, key);
|
|
20
17
|
return { ok: true, present: true, value: descriptor.value };
|
|
21
18
|
}
|
|
@@ -23,12 +20,6 @@ function inspectArrayDataProperty(value, key) {
|
|
|
23
20
|
return { ok: false };
|
|
24
21
|
}
|
|
25
22
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Inspects the plan's operations tuple without dereferencing untrusted array
|
|
28
|
-
* properties outside a reflection boundary. The caller uses the returned
|
|
29
|
-
* length and per-index inspector rather than `operations.length` or
|
|
30
|
-
* `operations[index]` directly.
|
|
31
|
-
*/
|
|
32
23
|
export function inspectTransactionOperations(value) {
|
|
33
24
|
try {
|
|
34
25
|
if (!Array.isArray(value)) {
|
|
@@ -55,7 +46,6 @@ export function inspectTransactionOperations(value) {
|
|
|
55
46
|
return operationsReflectionFailure("Transaction operations array reflection failed.");
|
|
56
47
|
}
|
|
57
48
|
}
|
|
58
|
-
/** Reads one operations entry through its own data descriptor. */
|
|
59
49
|
export function inspectTransactionOperationEntry(operations, index) {
|
|
60
50
|
const entry = inspectArrayDataProperty(operations, String(index));
|
|
61
51
|
if (!entry.ok) {
|
|
@@ -70,10 +60,6 @@ export function inspectTransactionOperationEntry(operations, index) {
|
|
|
70
60
|
}
|
|
71
61
|
return { ok: true, value: entry.value };
|
|
72
62
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Inspects an untrusted transaction envelope without reading any property value.
|
|
75
|
-
* Proxies are unsupported; reflection failures are contained as envelope issues.
|
|
76
|
-
*/
|
|
77
63
|
export function inspectTransactionEnvelope(value, schema) {
|
|
78
64
|
if (typeof value !== "object" || value === null) {
|
|
79
65
|
return issue(schema.invalidContainerPath, schema.invalidContainerMessage);
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The ways an Adapter transaction can break the contract the framework's plan
|
|
3
|
-
* executor depends on
|
|
4
|
-
*
|
|
5
|
-
* than message text (ADR 0006: never infer an outcome from error text).
|
|
3
|
+
* executor depends on. Each is answered `A3002`; the violation is the only thing
|
|
4
|
+
* that tells them apart, so it is structured data rather than message text.
|
|
6
5
|
*
|
|
7
|
-
* - `transaction-unavailable`: the Adapter's `transaction` function is gone
|
|
8
|
-
*
|
|
9
|
-
* - `resolved-after-abort`: the Adapter resolved although the framework threw
|
|
10
|
-
*
|
|
11
|
-
* - `resolved-incomplete`: the Adapter resolved before every plan operation
|
|
12
|
-
*
|
|
13
|
-
* - `foreign-abort`: the Adapter rejected with the framework's rollback
|
|
14
|
-
*
|
|
6
|
+
* - `transaction-unavailable`: the Adapter's `transaction` function is gone at
|
|
7
|
+
* execution time.
|
|
8
|
+
* - `resolved-after-abort`: the Adapter resolved although the framework threw its
|
|
9
|
+
* rollback request.
|
|
10
|
+
* - `resolved-incomplete`: the Adapter resolved before every plan operation ran,
|
|
11
|
+
* so no committed `A1009` array exists.
|
|
12
|
+
* - `foreign-abort`: the Adapter rejected with the framework's rollback request
|
|
13
|
+
* although this plan never made one.
|
|
15
14
|
*/
|
|
16
15
|
export type TransactionIntegrityViolation = "transaction-unavailable" | "resolved-after-abort" | "resolved-incomplete" | "foreign-abort";
|
|
17
16
|
/**
|
|
@@ -4,11 +4,6 @@ const TRANSACTION_INTEGRITY_MESSAGES = {
|
|
|
4
4
|
"resolved-incomplete": "Adapter transaction resolved before the plan completed.",
|
|
5
5
|
"foreign-abort": "Adapter transaction rejected with a rollback request this plan never made.",
|
|
6
6
|
};
|
|
7
|
-
/**
|
|
8
|
-
* The framework-owned failure reported to diagnostics when an Adapter
|
|
9
|
-
* transaction violates its contract. It never reaches the wire: the response
|
|
10
|
-
* is always the constant `A3002` envelope.
|
|
11
|
-
*/
|
|
12
7
|
export class TransactionIntegrityError extends Error {
|
|
13
8
|
violation;
|
|
14
9
|
constructor(violation) {
|
|
@@ -5,7 +5,6 @@ import type { ClientProtocolIdentity } from "../runtime/operation-request.js";
|
|
|
5
5
|
import type { OperationFailureResponse } from "../runtime/operation-response.js";
|
|
6
6
|
import type { Operation, OperationFingerprint } from "./deferred-operation.js";
|
|
7
7
|
import type { TransactionOperationOrigin } from "./transaction-request.js";
|
|
8
|
-
/** One §14.2 wire node, exactly as the transaction runtime receives it. */
|
|
9
8
|
type WireOperationNode = {
|
|
10
9
|
readonly resource: string;
|
|
11
10
|
readonly family: string;
|
|
@@ -11,11 +11,6 @@ function isPlainRecord(value) {
|
|
|
11
11
|
const prototype = Object.getPrototypeOf(value);
|
|
12
12
|
return prototype === Object.prototype || prototype === null;
|
|
13
13
|
}
|
|
14
|
-
/**
|
|
15
|
-
* The argument keys whose value holds DA-3 positions for `identity`: the
|
|
16
|
-
* top-level mutation data. `create.many`/`create.count` hold a list of records
|
|
17
|
-
* there; every other one holds one record.
|
|
18
|
-
*/
|
|
19
14
|
function referenceKeys(identity) {
|
|
20
15
|
switch (identity.family) {
|
|
21
16
|
case "create":
|
|
@@ -27,11 +22,6 @@ function referenceKeys(identity) {
|
|
|
27
22
|
return [];
|
|
28
23
|
}
|
|
29
24
|
}
|
|
30
|
-
/**
|
|
31
|
-
* Every DA-3 container `args` holds. A value that is not a plain record (or, for
|
|
32
|
-
* a bulk create, a list of them) holds none: it reaches the validation layer as
|
|
33
|
-
* it is, which answers it.
|
|
34
|
-
*/
|
|
35
25
|
function referenceContainers(identity, args) {
|
|
36
26
|
if (!isPlainRecord(args)) {
|
|
37
27
|
return [];
|
|
@@ -44,10 +34,6 @@ function referenceContainers(identity, args) {
|
|
|
44
34
|
return isPlainRecord(value) ? [{ path: [key], record: value }] : [];
|
|
45
35
|
});
|
|
46
36
|
}
|
|
47
|
-
/**
|
|
48
|
-
* Rebuilds `args` with each DA-3 container replaced by `rebuild(container)`,
|
|
49
|
-
* cloning only the containing path; every other value is the caller's own.
|
|
50
|
-
*/
|
|
51
37
|
function replaceContainers(identity, args, rebuild) {
|
|
52
38
|
if (!isPlainRecord(args)) {
|
|
53
39
|
return args;
|
|
@@ -66,34 +52,21 @@ function replaceContainers(identity, args, rebuild) {
|
|
|
66
52
|
}
|
|
67
53
|
return result;
|
|
68
54
|
}
|
|
69
|
-
/** A per-operation framework-validation refusal (`A2004`/`V1001`), at `["operation"]`. */
|
|
70
55
|
function operationEntryFailure(operation, message) {
|
|
71
56
|
return transactionOperationFailure(operationFailure("A2004", {
|
|
72
57
|
message: "Transaction plan failed framework validation.",
|
|
73
58
|
issues: [validationIssue("V1001", ["operation"], message)],
|
|
74
59
|
}), operation);
|
|
75
60
|
}
|
|
76
|
-
/** A reference refusal, routed like every other reference issue (DA-4). */
|
|
77
61
|
function referenceFailure(issue, operation) {
|
|
78
62
|
return transactionOperationFailure(mapValidationOutcome([issue]), operation);
|
|
79
63
|
}
|
|
80
|
-
/**
|
|
81
|
-
* One assembler per Framework: a handle is this Framework's or it is not a
|
|
82
|
-
* handle, so a handle another instance built — typed against another model,
|
|
83
|
-
* bound to other Contracts — is refused rather than run.
|
|
84
|
-
*/
|
|
85
64
|
export function createTransactionPlanAssembler(contracts, protocol) {
|
|
86
65
|
const handles = new WeakMap();
|
|
87
66
|
const placeholders = new WeakMap();
|
|
88
67
|
const originOf = (origin) => origin === "application"
|
|
89
68
|
? { scope: "application" }
|
|
90
69
|
: { scope: "client", protocol };
|
|
91
|
-
/**
|
|
92
|
-
* Fixes the handle's DA-3 positions when it is built: each container is
|
|
93
|
-
* copied, so a later mutation of the caller's data object cannot move a
|
|
94
|
-
* reference — and, since a handle can only reference handles built before it,
|
|
95
|
-
* the references between handles are acyclic.
|
|
96
|
-
*/
|
|
97
70
|
const snapshot = (identity, args) => replaceContainers(identity, args, ({ record }) => ({ ...record }));
|
|
98
71
|
const defer = (origin, resource, identity, args) => {
|
|
99
72
|
const handle = Object.freeze({
|
|
@@ -146,7 +119,6 @@ export function createTransactionPlanAssembler(contracts, protocol) {
|
|
|
146
119
|
positions.set(entry, index);
|
|
147
120
|
records.push(record);
|
|
148
121
|
}
|
|
149
|
-
// Every reference must name a handle in this list; the earliest refusal wins.
|
|
150
122
|
for (const [index, record] of records.entries()) {
|
|
151
123
|
for (const { path, record: container } of referenceContainers(record.identity, record.args)) {
|
|
152
124
|
for (const [field, value] of Object.entries(container)) {
|
|
@@ -201,13 +173,6 @@ export function createTransactionPlanAssembler(contracts, protocol) {
|
|
|
201
173
|
fingerprint: await fingerprintOf(record, args),
|
|
202
174
|
};
|
|
203
175
|
};
|
|
204
|
-
/**
|
|
205
|
-
* The DA-17 fingerprint the validation layer recomputes. When it cannot be
|
|
206
|
-
* computed here, the validation layer cannot compute it either and answers
|
|
207
|
-
* the operation itself first — an invalid argument before the fingerprint
|
|
208
|
-
* step, a value JCS cannot encode as `V1001` at it — so the declared value
|
|
209
|
-
* is never compared and is left `null`.
|
|
210
|
-
*/
|
|
211
176
|
const fingerprintOf = async (record, args) => {
|
|
212
177
|
const operation = { resource: record.resource, ...record.identity };
|
|
213
178
|
try {
|