@aventara/core 1.0.0-rc.0 → 1.0.0-rc.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2068 -1
- package/ERRORS.md +142 -0
- package/README.md +485 -60
- package/dist/adapters/adapter-discovery-diagnostic.d.ts +4 -4
- package/dist/adapters/adapter-discovery-diagnostic.guidance.d.ts +6 -0
- package/dist/adapters/adapter-discovery-diagnostic.guidance.js +7 -0
- package/dist/adapters/adapter-field.d.ts +33 -11
- package/dist/adapters/adapter-identifier.d.ts +15 -6
- package/dist/adapters/adapter-identifier.js +6 -1
- package/dist/adapters/adapter-model.d.ts +18 -9
- package/dist/adapters/adapter-operation-executor.interface.d.ts +4 -4
- package/dist/adapters/adapter-operation.d.ts +21 -6
- package/dist/adapters/adapter-resource.d.ts +23 -9
- package/dist/adapters/adapter-sql-statement.d.ts +19 -0
- package/dist/adapters/adapter-transaction-executor.interface.d.ts +19 -0
- package/dist/adapters/adapter.interface.d.ts +59 -29
- package/dist/avz/avz-check.factory.d.ts +83 -0
- package/dist/avz/avz-check.factory.js +116 -0
- package/dist/avz/avz-check.registry.d.ts +35 -0
- package/dist/avz/avz-check.registry.js +9 -0
- package/dist/avz/avz.d.ts +203 -0
- package/dist/{json → avz}/avz.js +150 -8
- package/dist/{json → avz}/index.d.ts +2 -1
- package/dist/{json → avz}/json-shape.registry.d.ts +9 -8
- package/dist/{json → avz}/zod-issue.translator.d.ts +8 -2
- package/dist/{json → avz}/zod-issue.translator.js +7 -0
- package/dist/compiler/contract-compiler-diagnostic.d.ts +31 -5
- package/dist/compiler/contract-compiler-diagnostic.guidance.d.ts +6 -0
- package/dist/compiler/contract-compiler-diagnostic.guidance.js +97 -0
- package/dist/compiler/contract.compiler.d.ts +23 -17
- package/dist/compiler/contract.compiler.js +753 -443
- package/dist/compiler/create-requirements.projector.d.ts +49 -0
- package/dist/compiler/create-requirements.projector.js +423 -0
- package/dist/compiler/field-validator.compiler.d.ts +47 -0
- package/dist/compiler/field-validator.compiler.js +238 -0
- package/dist/compiler/managed-elsewhere.projector.d.ts +52 -0
- package/dist/compiler/managed-elsewhere.projector.js +179 -0
- package/dist/compiler/managed-elsewhere.validator.d.ts +9 -0
- package/dist/compiler/managed-elsewhere.validator.js +74 -0
- package/dist/config/any-framework-config.d.ts +19 -12
- package/dist/config/computed-fields.d.ts +62 -0
- package/dist/config/computed-fields.js +73 -0
- package/dist/config/config-diagnostic.d.ts +11 -4
- package/dist/config/config-diagnostic.guidance.d.ts +6 -0
- package/dist/config/config-diagnostic.guidance.js +32 -0
- package/dist/config/config-layer.d.ts +15 -6
- package/dist/config/config.resolver.d.ts +98 -31
- package/dist/config/config.resolver.js +173 -44
- package/dist/config/config.validator.d.ts +7 -7
- package/dist/config/config.validator.js +792 -69
- package/dist/config/define-resource.d.ts +53 -0
- package/dist/config/define-resource.js +14 -0
- package/dist/config/effective-fields.d.ts +19 -23
- package/dist/config/entrypoint.normalizer.d.ts +4 -3
- package/dist/config/exact-framework-config.d.ts +325 -0
- package/dist/config/field-compute.resolver.d.ts +21 -0
- package/dist/config/field-compute.resolver.js +123 -0
- package/dist/config/field-pipeline-config.d.ts +47 -0
- package/dist/config/forced-operation.validator.d.ts +10 -0
- package/dist/config/forced-operation.validator.js +66 -0
- package/dist/config/framework-config.d.ts +148 -39
- package/dist/config/framework-exemptions-config.d.ts +91 -0
- package/dist/config/framework-exemptions-config.js +1 -0
- package/dist/config/framework-field-definition.d.ts +78 -0
- package/dist/config/framework-field-definition.js +28 -0
- package/dist/config/framework-resources-config.d.ts +127 -0
- package/dist/config/framework-resources-config.js +1 -0
- package/dist/config/pipeline-config.d.ts +56 -20
- package/dist/config/pipeline-tree.resolver.d.ts +79 -0
- package/dist/config/pipeline-tree.resolver.js +220 -0
- package/dist/config/stage-type.eraser.d.ts +65 -0
- package/dist/config/stage-type.eraser.js +1 -0
- package/dist/contracts/access-route.rules.d.ts +10 -0
- package/dist/contracts/access-route.rules.js +45 -0
- package/dist/contracts/capability.d.ts +37 -12
- package/dist/contracts/capability.js +20 -0
- package/dist/contracts/client-contract-structure.validator.d.ts +621 -114
- package/dist/contracts/client-contract-structure.validator.js +189 -10
- package/dist/contracts/contract-access.d.ts +29 -0
- package/dist/contracts/contract-access.js +1 -0
- package/dist/contracts/contract-canonicalizer.d.ts +27 -3
- package/dist/contracts/contract-canonicalizer.js +168 -29
- package/dist/contracts/contract-hash.d.ts +11 -7
- package/dist/contracts/contract-hash.js +4 -3
- package/dist/contracts/contract-limits.d.ts +4 -1
- package/dist/contracts/contract-limits.js +1 -0
- package/dist/contracts/contract-lookup.d.ts +5 -5
- package/dist/contracts/contract-protocol.d.ts +4 -4
- package/dist/contracts/contract.d.ts +51 -17
- package/dist/contracts/create-requirements.d.ts +35 -0
- package/dist/contracts/create-requirements.js +1 -0
- package/dist/contracts/enum-definition.d.ts +1 -1
- package/dist/contracts/field-check.d.ts +101 -0
- package/dist/contracts/field-check.js +1 -0
- package/dist/contracts/field.d.ts +109 -42
- package/dist/contracts/identifier.d.ts +4 -4
- package/dist/contracts/json-schema.projector.d.ts +11 -0
- package/dist/contracts/json-schema.projector.js +78 -0
- package/dist/contracts/json-shape.d.ts +12 -1
- package/dist/contracts/lifecycle-trait.d.ts +2 -2
- package/dist/contracts/resource-operations.d.ts +28 -28
- package/dist/contracts/resource.d.ts +15 -9
- package/dist/contracts/scalar-value-type.d.ts +17 -15
- package/dist/contracts/scalar.d.ts +3 -3
- package/dist/contracts/transaction-capability.d.ts +1 -1
- package/dist/contracts/wire-scalar-format.d.ts +4 -4
- package/dist/framework/access-facade.d.ts +116 -0
- package/dist/framework/access-facade.js +120 -0
- package/dist/framework/contract-view.d.ts +315 -145
- package/dist/framework/framework-construction.error.d.ts +21 -11
- package/dist/framework/framework-construction.error.js +20 -4
- package/dist/framework/framework.d.ts +71 -26
- package/dist/framework/framework.factory.d.ts +8 -6
- package/dist/framework/framework.factory.js +150 -38
- package/dist/framework/operation-facade.d.ts +192 -54
- package/dist/framework/operation-facade.js +10 -1
- package/dist/index.d.ts +67 -50
- package/dist/index.js +7 -6
- package/dist/internal.d.ts +20 -10
- package/dist/internal.js +9 -1
- package/dist/operations/database-refusal.d.ts +51 -0
- package/dist/operations/database-refusal.js +45 -0
- package/dist/operations/operation-arguments.d.ts +381 -228
- package/dist/operations/operation-call.d.ts +31 -28
- package/dist/operations/operation-identity.d.ts +10 -10
- package/dist/operations/operation-result.d.ts +25 -23
- package/dist/operations/operation-validator-core.d.ts +6 -6
- package/dist/operations/operation-validator-core.js +172 -38
- package/dist/operations/operation-validator.d.ts +10 -10
- package/dist/operations/projection-scope.resolver.d.ts +6 -6
- package/dist/operations/structural-limits.walker.d.ts +7 -7
- package/dist/operations/structural-limits.walker.js +145 -0
- package/dist/operations/validation-code.d.ts +11 -6
- package/dist/operations/validation-code.guidance.d.ts +6 -0
- package/dist/operations/validation-code.guidance.js +90 -0
- package/dist/operations/validation-code.js +4 -0
- package/dist/operations/write-scope.resolver.d.ts +10 -6
- package/dist/operations/write-scope.resolver.js +2 -0
- package/dist/policy/access-provider.interface.d.ts +91 -0
- package/dist/policy/access-provider.interface.js +1 -0
- package/dist/policy/access-provider.registry.d.ts +17 -0
- package/dist/policy/access-provider.registry.js +15 -0
- package/dist/policy/access-question.d.ts +20 -0
- package/dist/policy/access-question.js +1 -0
- package/dist/policy/access-question.registry.d.ts +5 -0
- package/dist/policy/access-question.registry.js +19 -0
- package/dist/policy/access-question.runtime.d.ts +36 -0
- package/dist/policy/access-question.runtime.js +297 -0
- package/dist/policy/access-verb.table.d.ts +56 -0
- package/dist/policy/access-verb.table.js +21 -0
- package/dist/policy/access-verbs.d.ts +46 -0
- package/dist/policy/access-verbs.js +1 -0
- package/dist/policy/policy-admission.d.ts +20 -0
- package/dist/policy/policy-admission.js +409 -0
- package/dist/policy/policy-after-update.runtime.d.ts +79 -0
- package/dist/policy/policy-after-update.runtime.js +208 -0
- package/dist/policy/policy-condition.d.ts +15 -0
- package/dist/policy/policy-condition.js +36 -0
- package/dist/policy/policy-engine.d.ts +205 -0
- package/dist/policy/policy-engine.js +1 -0
- package/dist/policy/policy-named-rows.d.ts +18 -0
- package/dist/policy/policy-named-rows.js +51 -0
- package/dist/policy/policy-nested-write.runtime.d.ts +44 -0
- package/dist/policy/policy-nested-write.runtime.js +545 -0
- package/dist/policy/policy-read.runtime.d.ts +81 -0
- package/dist/policy/policy-read.runtime.js +503 -0
- package/dist/policy/policy-reference-write.runtime.d.ts +51 -0
- package/dist/policy/policy-reference-write.runtime.js +345 -0
- package/dist/policy/policy-request.d.ts +41 -0
- package/dist/policy/policy-request.js +63 -0
- package/dist/policy/policy-session.d.ts +106 -0
- package/dist/policy/policy-session.js +295 -0
- package/dist/policy/policy-startup.validator.d.ts +10 -0
- package/dist/policy/policy-startup.validator.js +112 -0
- package/dist/policy/policy-write.runtime.d.ts +39 -0
- package/dist/policy/policy-write.runtime.js +532 -0
- package/dist/prebuilt/core-version.generated.d.ts +2 -0
- package/dist/prebuilt/core-version.generated.js +1 -0
- package/dist/prebuilt/prebuilt-changes.d.ts +29 -0
- package/dist/prebuilt/prebuilt-changes.js +65 -0
- package/dist/prebuilt/prebuilt-contracts.d.ts +40 -0
- package/dist/prebuilt/prebuilt-contracts.emitter.d.ts +16 -0
- package/dist/prebuilt/prebuilt-contracts.emitter.js +50 -0
- package/dist/prebuilt/prebuilt-contracts.js +1 -0
- package/dist/prebuilt/prebuilt-contracts.loader.d.ts +19 -0
- package/dist/prebuilt/prebuilt-contracts.loader.js +77 -0
- package/dist/prebuilt/prebuilt-inputs.fingerprint.d.ts +16 -0
- package/dist/prebuilt/prebuilt-inputs.fingerprint.js +229 -0
- package/dist/protocol/absent-route.responder.d.ts +17 -34
- package/dist/protocol/absent-route.responder.js +53 -20
- package/dist/protocol/contract-document.responder.d.ts +5 -4
- package/dist/protocol/contract-document.responder.js +2 -2
- package/dist/protocol/http-request.decoder.d.ts +33 -13
- package/dist/protocol/http-request.decoder.js +34 -11
- package/dist/protocol/http-request.reader.d.ts +9 -6
- package/dist/protocol/http-request.reader.js +1 -0
- package/dist/protocol/http-response.encoder.d.ts +4 -4
- package/dist/protocol/http-response.encoder.js +94 -55
- package/dist/protocol/http-status.table.d.ts +2 -2
- package/dist/protocol/operation-response.guard.d.ts +2 -2
- package/dist/protocol/protocol-headers.d.ts +3 -3
- package/dist/protocol/protocol-surface.d.ts +10 -5
- package/dist/protocol/protocol-surface.js +7 -0
- package/dist/protocol/protocol.binder.d.ts +66 -28
- package/dist/protocol/protocol.binder.js +16 -10
- package/dist/protocol/protocol.handler.d.ts +34 -14
- package/dist/protocol/protocol.handler.js +122 -18
- package/dist/protocol/unmounted-route.error.d.ts +4 -4
- package/dist/protocol/unmounted-route.error.js +2 -2
- package/dist/runtime/caller-data.copier.d.ts +22 -7
- package/dist/runtime/caller-data.copier.js +30 -17
- package/dist/runtime/caller-data.door.d.ts +18 -11
- package/dist/runtime/caller-data.door.js +6 -4
- package/dist/runtime/computed-read-runtime.d.ts +12 -6
- package/dist/runtime/computed-read-runtime.js +271 -71
- package/dist/runtime/computed-value.error.d.ts +7 -6
- package/dist/runtime/computed-value.error.js +5 -4
- package/dist/runtime/context-executor.runtime.d.ts +60 -0
- package/dist/runtime/context-executor.runtime.js +277 -0
- package/dist/runtime/core-class.brand.d.ts +10 -0
- package/dist/runtime/core-class.brand.js +21 -0
- package/dist/runtime/create-requirement.d.ts +34 -79
- package/dist/runtime/create-requirement.js +205 -74
- package/dist/runtime/decimal.d.ts +16 -2
- package/dist/runtime/decimal.js +22 -1
- package/dist/runtime/diagnostics-reporter.d.ts +91 -30
- package/dist/runtime/diagnostics-reporter.js +37 -1
- package/dist/runtime/error-boundary.d.ts +73 -9
- package/dist/runtime/error-boundary.js +57 -19
- package/dist/runtime/error-guidance.d.ts +12 -0
- package/dist/runtime/error-guidance.js +1 -0
- package/dist/runtime/error.catalog.d.ts +49 -0
- package/dist/runtime/error.catalog.js +49 -0
- package/dist/runtime/execution-options.d.ts +18 -2
- package/dist/runtime/field-check.evaluator.d.ts +27 -0
- package/dist/runtime/field-check.evaluator.js +521 -0
- package/dist/runtime/field-compute.d.ts +65 -0
- package/dist/runtime/field-compute.js +1 -0
- package/dist/runtime/field-stage.plan.d.ts +15 -0
- package/dist/runtime/field-stage.plan.js +27 -0
- package/dist/runtime/field-stage.runtime.d.ts +37 -0
- package/dist/runtime/field-stage.runtime.js +147 -0
- package/dist/runtime/field-validator.runtime.d.ts +29 -0
- package/dist/runtime/field-validator.runtime.js +126 -0
- package/dist/runtime/framework-error-class.table.d.ts +33 -0
- package/dist/runtime/framework-error-class.table.js +25 -0
- package/dist/runtime/framework-error.d.ts +68 -8
- package/dist/runtime/framework-error.factory.d.ts +4 -0
- package/dist/runtime/framework-error.factory.js +15 -0
- package/dist/runtime/framework-error.js +32 -2
- package/dist/runtime/framework-warning.emitter.d.ts +6 -0
- package/dist/runtime/framework-warning.emitter.js +8 -0
- package/dist/runtime/interceptor-next.error.d.ts +5 -0
- package/dist/runtime/interceptor-next.error.js +6 -0
- package/dist/runtime/json-value.d.ts +11 -6
- package/dist/runtime/level-lifecycle.runtime.d.ts +26 -0
- package/dist/runtime/level-lifecycle.runtime.js +40 -0
- package/dist/runtime/misuse-reporter.d.ts +12 -12
- package/dist/runtime/mutation-planner.d.ts +20 -16
- package/dist/runtime/mutation-planner.js +48 -35
- package/dist/runtime/nested-write.walker.d.ts +32 -0
- package/dist/runtime/nested-write.walker.js +73 -0
- package/dist/runtime/operation-code.guidance.d.ts +6 -0
- package/dist/runtime/operation-code.guidance.js +167 -0
- package/dist/runtime/operation-request.d.ts +45 -11
- package/dist/runtime/operation-response.d.ts +17 -17
- package/dist/runtime/operation-runtime.d.ts +133 -27
- package/dist/runtime/operation-runtime.js +576 -84
- package/dist/runtime/outcome-mapper.d.ts +17 -5
- package/dist/runtime/outcome-mapper.js +23 -6
- package/dist/runtime/output-validator.d.ts +11 -11
- package/dist/runtime/output-validator.js +3 -3
- package/dist/runtime/owned-execution.registry.d.ts +16 -6
- package/dist/runtime/pipe-output.validator.d.ts +43 -18
- package/dist/runtime/pipe-output.validator.js +15 -13
- package/dist/runtime/pipeline.d.ts +221 -34
- package/dist/runtime/readonly-value.d.ts +47 -0
- package/dist/runtime/readonly-value.js +189 -0
- package/dist/runtime/referential-action.d.ts +1 -1
- package/dist/runtime/request-envelope.validator.d.ts +3 -3
- package/dist/runtime/request-envelope.validator.js +12 -7
- package/dist/runtime/request-id.d.ts +1 -1
- package/dist/runtime/request-state.d.ts +14 -0
- package/dist/runtime/request-state.js +1 -0
- package/dist/runtime/request-state.resolver.d.ts +12 -0
- package/dist/runtime/request-state.resolver.js +20 -0
- package/dist/runtime/scalar-runtime.d.ts +33 -25
- package/dist/runtime/scalar-runtime.js +105 -38
- package/dist/runtime/unsent-value.normalizer.d.ts +15 -0
- package/dist/runtime/unsent-value.normalizer.js +128 -0
- package/dist/transactions/deferred-operation.d.ts +35 -20
- package/dist/transactions/operation-arguments-encoder.d.ts +3 -3
- package/dist/transactions/operation-arguments-encoder.js +8 -3
- package/dist/transactions/operation-fingerprint.js +2 -2
- package/dist/transactions/sql-statement.d.ts +85 -0
- package/dist/transactions/sql-statement.js +47 -0
- package/dist/transactions/sql-statement.validator.d.ts +44 -0
- package/dist/transactions/sql-statement.validator.js +167 -0
- package/dist/transactions/transaction-envelope.d.ts +9 -8
- package/dist/transactions/transaction-integrity-error.d.ts +6 -6
- package/dist/transactions/transaction-integrity-error.js +7 -2
- package/dist/transactions/transaction-plan-assembler.d.ts +30 -13
- package/dist/transactions/transaction-plan-assembler.js +184 -32
- package/dist/transactions/transaction-plan-validator.d.ts +50 -25
- package/dist/transactions/transaction-plan-validator.js +96 -38
- package/dist/transactions/transaction-reference-collector.d.ts +5 -5
- package/dist/transactions/transaction-reference-resolver.d.ts +21 -3
- package/dist/transactions/transaction-reference-resolver.js +26 -14
- package/dist/transactions/transaction-reference-validator.d.ts +74 -4
- package/dist/transactions/transaction-reference-validator.js +129 -71
- package/dist/transactions/transaction-reference.d.ts +14 -14
- package/dist/transactions/transaction-reference.js +5 -0
- package/dist/transactions/transaction-request.d.ts +22 -9
- package/dist/transactions/transaction-response.d.ts +6 -6
- package/dist/transactions/transaction-runtime.d.ts +12 -8
- package/dist/transactions/transaction-runtime.js +218 -50
- package/dist/transactions/transaction-settlement.runtime.d.ts +52 -0
- package/dist/transactions/transaction-settlement.runtime.js +120 -0
- package/dist/transactions/transaction-slot-path-error.d.ts +4 -4
- package/dist/transactions/transaction-slot-path-error.js +4 -2
- package/dist/transactions/transaction-slot-writer.js +2 -2
- package/dist/transactions/transaction-stage.runtime.d.ts +83 -0
- package/dist/transactions/transaction-stage.runtime.js +126 -0
- package/package.json +11 -9
- package/src/runtime/field-check.evaluator.ts +720 -0
- package/dist/config/define-fields.d.ts +0 -42
- package/dist/config/define-fields.js +0 -3
- package/dist/config/framework-behaviors-config.d.ts +0 -30
- package/dist/config/framework-fields-config.d.ts +0 -42
- package/dist/config/framework-restrictions-config.d.ts +0 -142
- package/dist/json/avz.d.ts +0 -96
- package/dist/runtime/field-behavior.d.ts +0 -48
- /package/dist/{config/framework-behaviors-config.js → adapters/adapter-sql-statement.js} +0 -0
- /package/dist/{config/framework-fields-config.js → adapters/adapter-transaction-executor.interface.js} +0 -0
- /package/dist/{json → avz}/index.js +0 -0
- /package/dist/{json → avz}/json-shape.registry.js +0 -0
- /package/dist/config/{framework-restrictions-config.js → exact-framework-config.js} +0 -0
- /package/dist/{runtime/field-behavior.js → config/field-pipeline-config.js} +0 -0
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { AvRequestOrigin } from "../config/config-layer.js";
|
|
2
|
+
import type { AvOperationFamily } from "../operations/operation-identity.js";
|
|
3
3
|
/**
|
|
4
4
|
* One caller value the framework refused because it could not be read
|
|
5
5
|
* (`"unreadable-value"`: a revoked Proxy, a throwing getter or trap) or is not plain
|
|
6
|
-
* data (`"non-plain-value"`: a class instance other than `Date`, `
|
|
6
|
+
* data (`"non-plain-value"`: a class instance other than `Date`, `AvDecimal` or
|
|
7
7
|
* `Uint8Array`). The caller received `A2004` with one `V1001` at `path`.
|
|
8
8
|
*
|
|
9
|
-
* The operation's identity is present when the framework could read it
|
|
10
|
-
* a request whose own envelope could not be read
|
|
9
|
+
* The operation's identity is present when the framework could read it (absent for
|
|
10
|
+
* a request whose own envelope could not be read), and `operation` is the step's
|
|
11
11
|
* index in a transaction plan.
|
|
12
12
|
*/
|
|
13
|
-
export type
|
|
13
|
+
export type AvMisuseEvent = {
|
|
14
14
|
readonly kind: "unreadable-value" | "non-plain-value";
|
|
15
15
|
/** The issue path the caller received. */
|
|
16
16
|
readonly path: readonly (string | number)[];
|
|
17
|
-
readonly origin?:
|
|
17
|
+
readonly origin?: AvRequestOrigin;
|
|
18
18
|
readonly resource?: string;
|
|
19
|
-
readonly family?:
|
|
19
|
+
readonly family?: AvOperationFamily;
|
|
20
20
|
readonly variant?: string;
|
|
21
21
|
readonly operation?: number;
|
|
22
22
|
};
|
|
23
23
|
/**
|
|
24
|
-
* Receives a {@link
|
|
24
|
+
* Receives a {@link AvMisuseEvent} for every caller value the framework
|
|
25
25
|
* refused as unreadable or not plain data. Set once, as the root configuration's
|
|
26
26
|
* `misuse`. What it returns, throws or rejects with never reaches the response.
|
|
27
27
|
*/
|
|
28
|
-
export type
|
|
28
|
+
export type AvMisuseSink = (event: AvMisuseEvent) => void | Promise<void>;
|
|
29
29
|
/** The channel as the runtime holds it: total, never awaited. */
|
|
30
|
-
export type MisuseReporter = (event:
|
|
30
|
+
export type MisuseReporter = (event: AvMisuseEvent) => void;
|
|
31
31
|
/** Binds the configured sink; without one, nothing is observed. */
|
|
32
|
-
export declare function createMisuseReporter(sink:
|
|
32
|
+
export declare function createMisuseReporter(sink: AvMisuseSink | undefined): MisuseReporter;
|
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import type { ResolvedComputeConfig } from "../config/field-compute.resolver.js";
|
|
2
|
+
import type { AvRelationMutationDirective } from "../contracts/capability.js";
|
|
3
|
+
import type { AvContract, AvContractCore } from "../contracts/contract.js";
|
|
4
|
+
import type { AvComputeContext } from "./field-compute.js";
|
|
5
|
+
import type { NestedWriteTarget } from "./nested-write.walker.js";
|
|
4
6
|
import type { OperationExecutionRequest } from "./operation-request.js";
|
|
5
|
-
import type { PipelineContext } from "./pipeline.js";
|
|
6
7
|
/**
|
|
7
8
|
* The two Contracts a write reads. The Core Contract decides what the Adapter is asked
|
|
8
9
|
* to store; the active Contract adds the fields its scope declared under
|
|
9
10
|
* `application.fields` / `client.fields`, which Core does not carry. Such a field is
|
|
10
11
|
* virtual: its behaviours run and its value is stripped before the Adapter call.
|
|
11
12
|
*/
|
|
12
|
-
|
|
13
|
-
readonly core:
|
|
14
|
-
readonly active:
|
|
15
|
-
};
|
|
16
|
-
type WriteStage = "create" | "update";
|
|
17
|
-
type ContextFactory = (args: unknown) => PipelineContext;
|
|
18
|
-
export type RelationRecordSite = {
|
|
19
|
-
readonly key: string | undefined;
|
|
20
|
-
readonly stage: WriteStage;
|
|
13
|
+
type WriteContracts = {
|
|
14
|
+
readonly core: AvContractCore;
|
|
15
|
+
readonly active: AvContract;
|
|
21
16
|
};
|
|
17
|
+
type ContextFactory = (args: unknown) => AvComputeContext;
|
|
22
18
|
/**
|
|
23
19
|
* The sole grammar for relation-mutation record operands. Every write pass maps these
|
|
24
20
|
* sites with its own record leaf, leaving identifier-only directives untouched.
|
|
@@ -53,9 +49,17 @@ export declare const RELATION_MUTATION_RECORD_SITES: {
|
|
|
53
49
|
* membership, not an assertion: `Object.prototype` members resolve through the
|
|
54
50
|
* prototype chain and would otherwise reach a site loop with a non-iterable.
|
|
55
51
|
*/
|
|
56
|
-
export declare function isRelationMutationDirective(key: string): key is
|
|
57
|
-
/** Apply effective
|
|
58
|
-
export declare function
|
|
52
|
+
export declare function isRelationMutationDirective(key: string): key is AvRelationMutationDirective;
|
|
53
|
+
/** Apply the effective create/update compute stages to the post-pipe logical args. */
|
|
54
|
+
export declare function applyWriteCompute(contracts: WriteContracts, compute: ResolvedComputeConfig | undefined, request: OperationExecutionRequest, args: unknown, contextFactory: ContextFactory): Promise<unknown>;
|
|
55
|
+
/**
|
|
56
|
+
* Applies each nested target's write compute, in the targets' order, to its
|
|
57
|
+
* records: `compute.create` on a created row (an `$upsert`'s `create` branch
|
|
58
|
+
* too), `compute.update` on an updated one. Each target's stages are told
|
|
59
|
+
* `context(target, payload)`, the nested target's own context. The arguments
|
|
60
|
+
* are copied where a record changes, never written.
|
|
61
|
+
*/
|
|
62
|
+
export declare function applyNestedWriteCompute(contracts: WriteContracts, compute: ResolvedComputeConfig | undefined, args: unknown, targets: readonly NestedWriteTarget[], context: (target: NestedWriteTarget, payload: unknown) => AvComputeContext): Promise<unknown>;
|
|
59
63
|
/** Strip VIRTUAL scalar input only at the persistence boundary. */
|
|
60
64
|
export declare function stripVirtualMutationInput(contracts: WriteContracts, request: OperationExecutionRequest, args: unknown): Promise<unknown>;
|
|
61
65
|
export {};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { lookupField, lookupResource } from "../contracts/contract-lookup.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { AvComputedValueError } from "./computed-value.error.js";
|
|
3
|
+
import { replaceAt, valueAt } from "./field-stage.runtime.js";
|
|
4
|
+
import { frozenCopy } from "./readonly-value.js";
|
|
5
|
+
import { normalizeScalarFieldValue } from "./scalar-runtime.js";
|
|
4
6
|
function writeScalarField(contracts, resourceName, fieldName) {
|
|
5
7
|
const field = lookupField(lookupResource(contracts.core, resourceName), fieldName) ??
|
|
6
8
|
lookupField(lookupResource(contracts.active, resourceName), fieldName);
|
|
@@ -33,7 +35,7 @@ function cloneRecord(value) {
|
|
|
33
35
|
function relationEntries(value) {
|
|
34
36
|
return Array.isArray(value) ? value : [value];
|
|
35
37
|
}
|
|
36
|
-
async function computeRecord(contracts,
|
|
38
|
+
async function computeRecord(contracts, compute, resourceName, stage, data, contextFactory) {
|
|
37
39
|
if (!isRecord(data)) {
|
|
38
40
|
return data;
|
|
39
41
|
}
|
|
@@ -42,13 +44,13 @@ async function computeRecord(contracts, behaviors, request, resourceName, stage,
|
|
|
42
44
|
return data;
|
|
43
45
|
}
|
|
44
46
|
const logicalData = cloneRecord(data);
|
|
45
|
-
const
|
|
46
|
-
if (
|
|
47
|
-
for (const [fieldName,
|
|
48
|
-
if (
|
|
47
|
+
const resourceCompute = compute[resourceName];
|
|
48
|
+
if (resourceCompute !== undefined) {
|
|
49
|
+
for (const [fieldName, fieldCompute] of Object.entries(resourceCompute)) {
|
|
50
|
+
if (fieldCompute === undefined) {
|
|
49
51
|
continue;
|
|
50
52
|
}
|
|
51
|
-
const callback =
|
|
53
|
+
const callback = fieldCompute[stage];
|
|
52
54
|
if (typeof callback !== "function") {
|
|
53
55
|
continue;
|
|
54
56
|
}
|
|
@@ -56,40 +58,31 @@ async function computeRecord(contracts, behaviors, request, resourceName, stage,
|
|
|
56
58
|
if (field === undefined) {
|
|
57
59
|
continue;
|
|
58
60
|
}
|
|
61
|
+
const snapshot = frozenCopy(logicalData);
|
|
59
62
|
const computed = await callback({
|
|
60
|
-
origin: request.origin,
|
|
61
|
-
resource: resourceName,
|
|
62
63
|
field: fieldName,
|
|
63
|
-
value:
|
|
64
|
-
data:
|
|
65
|
-
|
|
64
|
+
value: snapshot[fieldName],
|
|
65
|
+
data: snapshot,
|
|
66
|
+
ctx: contextFactory(snapshot),
|
|
66
67
|
});
|
|
67
68
|
if (computed === undefined) {
|
|
68
69
|
continue;
|
|
69
70
|
}
|
|
70
|
-
const validation = normalizeScalarFieldValue(contracts.core, field, computed, "runtime", [
|
|
71
|
-
|
|
72
|
-
throw new ComputedValueError(resourceName, fieldName, stage, validation.issues);
|
|
73
|
-
}
|
|
74
|
-
const shapeIssues = jsonShapeIssues(field, validation.value, [
|
|
75
|
-
"behaviors",
|
|
71
|
+
const validation = normalizeScalarFieldValue(contracts.core, field, computed, "runtime", [
|
|
72
|
+
"resources",
|
|
76
73
|
resourceName,
|
|
74
|
+
"fields",
|
|
77
75
|
fieldName,
|
|
76
|
+
"pipelines",
|
|
77
|
+
"compute",
|
|
78
78
|
stage,
|
|
79
79
|
]);
|
|
80
|
-
if (
|
|
81
|
-
throw new
|
|
80
|
+
if (!validation.ok) {
|
|
81
|
+
throw new AvComputedValueError(resourceName, fieldName, stage, validation.issues);
|
|
82
82
|
}
|
|
83
83
|
logicalData[fieldName] = validation.value;
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
-
for (const [fieldName, value] of Object.entries(logicalData)) {
|
|
87
|
-
const field = lookupField(resource, fieldName);
|
|
88
|
-
if (field?.kind !== "relation") {
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
logicalData[fieldName] = await mapRelationMutationRecords(field, value, (targetResource, nestedStage, record) => computeRecord(contracts, behaviors, request, targetResource, nestedStage, record, contextFactory));
|
|
92
|
-
}
|
|
93
86
|
return logicalData;
|
|
94
87
|
}
|
|
95
88
|
async function mapRelationMutationRecords(relation, value, leaf) {
|
|
@@ -125,29 +118,49 @@ async function mapRelationMutationRecords(relation, value, leaf) {
|
|
|
125
118
|
}
|
|
126
119
|
return normalized;
|
|
127
120
|
}
|
|
128
|
-
export async function
|
|
129
|
-
if (
|
|
121
|
+
export async function applyWriteCompute(contracts, compute, request, args, contextFactory) {
|
|
122
|
+
if (compute === undefined || !isRecord(args)) {
|
|
130
123
|
return args;
|
|
131
124
|
}
|
|
132
125
|
const logicalArgs = cloneRecord(args);
|
|
133
126
|
if (request.family === "create" && "data" in logicalArgs) {
|
|
134
127
|
logicalArgs.data = Array.isArray(logicalArgs.data)
|
|
135
|
-
? await Promise.all(logicalArgs.data.map((entry) => computeRecord(contracts,
|
|
136
|
-
: await computeRecord(contracts,
|
|
128
|
+
? await Promise.all(logicalArgs.data.map((entry) => computeRecord(contracts, compute, request.resource, "create", entry, contextFactory)))
|
|
129
|
+
: await computeRecord(contracts, compute, request.resource, "create", logicalArgs.data, contextFactory);
|
|
137
130
|
}
|
|
138
131
|
if (request.family === "update" && "data" in logicalArgs) {
|
|
139
|
-
logicalArgs.data = await computeRecord(contracts,
|
|
132
|
+
logicalArgs.data = await computeRecord(contracts, compute, request.resource, "update", logicalArgs.data, contextFactory);
|
|
140
133
|
}
|
|
141
134
|
if (request.family === "upsert") {
|
|
142
135
|
if ("create" in logicalArgs) {
|
|
143
|
-
logicalArgs.create = await computeRecord(contracts,
|
|
136
|
+
logicalArgs.create = await computeRecord(contracts, compute, request.resource, "create", logicalArgs.create, contextFactory);
|
|
144
137
|
}
|
|
145
138
|
if ("update" in logicalArgs) {
|
|
146
|
-
logicalArgs.update = await computeRecord(contracts,
|
|
139
|
+
logicalArgs.update = await computeRecord(contracts, compute, request.resource, "update", logicalArgs.update, contextFactory);
|
|
147
140
|
}
|
|
148
141
|
}
|
|
149
142
|
return logicalArgs;
|
|
150
143
|
}
|
|
144
|
+
export async function applyNestedWriteCompute(contracts, compute, args, targets, context) {
|
|
145
|
+
if (compute === undefined) {
|
|
146
|
+
return args;
|
|
147
|
+
}
|
|
148
|
+
let current = args;
|
|
149
|
+
for (const target of targets) {
|
|
150
|
+
if (!Object.hasOwn(compute, target.resource)) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
for (const site of target.records) {
|
|
154
|
+
const record = valueAt(current, site.path);
|
|
155
|
+
if (!isRecord(record)) {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
const computed = await computeRecord(contracts, compute, target.resource, site.stage, record, () => context(target, valueAt(current, target.path)));
|
|
159
|
+
current = replaceAt(current, site.path, computed);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return current;
|
|
163
|
+
}
|
|
151
164
|
async function stripVirtualRecord(contracts, resourceName, data) {
|
|
152
165
|
if (!isRecord(data)) {
|
|
153
166
|
return data;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AvContract } from "../contracts/contract.js";
|
|
2
|
+
import type { AvOperationIdentity } from "../operations/operation-identity.js";
|
|
3
|
+
import { type Path } from "./field-stage.runtime.js";
|
|
4
|
+
import type { ReferentialActionTable } from "./referential-action.js";
|
|
5
|
+
/** The family a nested target's stages are told, and its guards are drawn from. */
|
|
6
|
+
export type NestedTargetFamily = "create" | "update" | "delete";
|
|
7
|
+
/** One record of a nested target's data, and the write phase it is. */
|
|
8
|
+
export type NestedRecordSite = {
|
|
9
|
+
/** Where the record sits in the operation's arguments. */
|
|
10
|
+
readonly path: Path;
|
|
11
|
+
/** `create` for a created row (an `$upsert`'s `create` branch too), `update` otherwise. */
|
|
12
|
+
readonly stage: "create" | "update";
|
|
13
|
+
};
|
|
14
|
+
/** One nested write's target, in data order. */
|
|
15
|
+
export type NestedWriteTarget = {
|
|
16
|
+
/** The target Resource. */
|
|
17
|
+
readonly resource: string;
|
|
18
|
+
readonly family: NestedTargetFamily;
|
|
19
|
+
/** Where the directive's entry — the nested payload — sits in the arguments. */
|
|
20
|
+
readonly path: Path;
|
|
21
|
+
/** The entry's data records the target's field stages run on. */
|
|
22
|
+
readonly records: readonly NestedRecordSite[];
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Every nested write target in an operation's arguments, depth first in data
|
|
26
|
+
* order: a target comes before the targets inside its own data, and before the
|
|
27
|
+
* next directive's. Empty for an operation with no write data. Total over
|
|
28
|
+
* malformed input.
|
|
29
|
+
*/
|
|
30
|
+
export declare function nestedWriteTargetsOf(contract: AvContract, references: ReferentialActionTable, request: AvOperationIdentity & {
|
|
31
|
+
readonly resource: string;
|
|
32
|
+
}, args: unknown): readonly NestedWriteTarget[];
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { lookupField, lookupResource } from "../contracts/contract-lookup.js";
|
|
2
|
+
import { isPlainRecord, valueAt, writeRecordPathsOf, } from "./field-stage.runtime.js";
|
|
3
|
+
import { isRelationMutationDirective, RELATION_MUTATION_RECORD_SITES, } from "./mutation-planner.js";
|
|
4
|
+
const DIRECTIVE_FAMILY = {
|
|
5
|
+
$create: "create",
|
|
6
|
+
$connectOrCreate: "create",
|
|
7
|
+
$update: "update",
|
|
8
|
+
$upsert: "update",
|
|
9
|
+
$delete: "delete",
|
|
10
|
+
$connect: "relation",
|
|
11
|
+
$disconnect: "relation",
|
|
12
|
+
$set: "relation",
|
|
13
|
+
};
|
|
14
|
+
function holdsReference(references, resource, relation) {
|
|
15
|
+
const edges = Object.hasOwn(references, resource)
|
|
16
|
+
? references[resource]
|
|
17
|
+
: undefined;
|
|
18
|
+
return (Array.isArray(edges) &&
|
|
19
|
+
edges.some((edge) => edge.field === relation));
|
|
20
|
+
}
|
|
21
|
+
function walkRecord(context, resource, path, record) {
|
|
22
|
+
if (!isPlainRecord(record)) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const owner = lookupResource(context.contract, resource);
|
|
26
|
+
for (const [key, value] of Object.entries(record)) {
|
|
27
|
+
const field = lookupField(owner, key);
|
|
28
|
+
if (field?.kind !== "relation" || !isPlainRecord(value)) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
for (const [directive, operand] of Object.entries(value)) {
|
|
32
|
+
if (!isRelationMutationDirective(directive)) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const mapped = DIRECTIVE_FAMILY[directive];
|
|
36
|
+
if (mapped === "relation" &&
|
|
37
|
+
field.cardinality === "one" &&
|
|
38
|
+
holdsReference(context.references, resource, key)) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const family = mapped === "relation" ? "update" : mapped;
|
|
42
|
+
const entries = directive !== "$set" && Array.isArray(operand)
|
|
43
|
+
? operand.map((_entry, index) => [index])
|
|
44
|
+
: [[]];
|
|
45
|
+
for (const at of entries) {
|
|
46
|
+
const entryPath = [...path, key, directive, ...at];
|
|
47
|
+
const records = [];
|
|
48
|
+
for (const site of RELATION_MUTATION_RECORD_SITES[directive]) {
|
|
49
|
+
const sitePath = site.key === undefined ? entryPath : [...entryPath, site.key];
|
|
50
|
+
if (isPlainRecord(valueAt(record, sitePath.slice(path.length)))) {
|
|
51
|
+
records.push({ path: sitePath, stage: site.stage });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
context.targets.push({
|
|
55
|
+
resource: field.target,
|
|
56
|
+
family,
|
|
57
|
+
path: entryPath,
|
|
58
|
+
records,
|
|
59
|
+
});
|
|
60
|
+
for (const site of records) {
|
|
61
|
+
walkRecord(context, field.target, site.path, valueAt(record, site.path.slice(path.length)));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export function nestedWriteTargetsOf(contract, references, request, args) {
|
|
68
|
+
const context = { contract, references, targets: [] };
|
|
69
|
+
for (const path of writeRecordPathsOf(request.family, args)) {
|
|
70
|
+
walkRecord(context, request.resource, path, valueAt(args, path));
|
|
71
|
+
}
|
|
72
|
+
return context.targets;
|
|
73
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ErrorCodeDescription } from "./error-guidance.js";
|
|
2
|
+
import type { AvOperationCode } from "./operation-response.js";
|
|
3
|
+
/** Meaning, cause and fix of every outcome code. */
|
|
4
|
+
export declare const OPERATION_CODE_GUIDANCE: {
|
|
5
|
+
readonly [C in AvOperationCode]: ErrorCodeDescription;
|
|
6
|
+
};
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
export const OPERATION_CODE_GUIDANCE = {
|
|
2
|
+
A1000: {
|
|
3
|
+
message: "Success.",
|
|
4
|
+
cause: "A read, a count or another operation without a more specific success code succeeded.",
|
|
5
|
+
fix: "Nothing: the call succeeded.",
|
|
6
|
+
},
|
|
7
|
+
A1001: {
|
|
8
|
+
message: "No match.",
|
|
9
|
+
cause: "A first-style operation (find.first, update.first, delete.first) matched no row; data is null and the generated client resolves null.",
|
|
10
|
+
fix: "Nothing: handle the null result. A unique operation answers A2003 instead.",
|
|
11
|
+
},
|
|
12
|
+
A1002: {
|
|
13
|
+
message: "Created.",
|
|
14
|
+
cause: "create.one created a row.",
|
|
15
|
+
fix: "Nothing: the call succeeded.",
|
|
16
|
+
},
|
|
17
|
+
A1003: {
|
|
18
|
+
message: "Created many.",
|
|
19
|
+
cause: "create.many or create.count created rows.",
|
|
20
|
+
fix: "Nothing: the call succeeded.",
|
|
21
|
+
},
|
|
22
|
+
A1004: {
|
|
23
|
+
message: "Updated.",
|
|
24
|
+
cause: "update.first or update.unique updated a row.",
|
|
25
|
+
fix: "Nothing: the call succeeded.",
|
|
26
|
+
},
|
|
27
|
+
A1005: {
|
|
28
|
+
message: "Updated many.",
|
|
29
|
+
cause: "update.many or update.count updated rows.",
|
|
30
|
+
fix: "Nothing: the call succeeded.",
|
|
31
|
+
},
|
|
32
|
+
A1006: {
|
|
33
|
+
message: "Deleted.",
|
|
34
|
+
cause: "delete.first or delete.unique deleted a row.",
|
|
35
|
+
fix: "Nothing: the call succeeded.",
|
|
36
|
+
},
|
|
37
|
+
A1007: {
|
|
38
|
+
message: "Deleted many.",
|
|
39
|
+
cause: "delete.count deleted rows.",
|
|
40
|
+
fix: "Nothing: the call succeeded.",
|
|
41
|
+
},
|
|
42
|
+
A1008: {
|
|
43
|
+
message: "Upserted.",
|
|
44
|
+
cause: "upsert.unique created or updated a row.",
|
|
45
|
+
fix: "Nothing: the call succeeded.",
|
|
46
|
+
},
|
|
47
|
+
A1009: {
|
|
48
|
+
message: "Transaction committed.",
|
|
49
|
+
cause: "A whole transaction plan committed; data holds one result per step.",
|
|
50
|
+
fix: "Nothing: the plan committed.",
|
|
51
|
+
},
|
|
52
|
+
A2000: {
|
|
53
|
+
message: "Invalid request.",
|
|
54
|
+
cause: "The HTTP request cannot be interpreted: malformed JSON, a body that is not a JSON object, an unknown `/_*` path, a body that does not decode in its Content-Encoding, or a missing Aventara-Protocol-Version or Aventara-Contract-Hash header (the message names it).",
|
|
55
|
+
fix: "Send a JSON object with both identity headers. The generated client does this for you.",
|
|
56
|
+
},
|
|
57
|
+
A2001: {
|
|
58
|
+
message: "Unknown Resource.",
|
|
59
|
+
cause: 'The Resource is not in the caller\'s contract: misspelt, hidden by exposure, or added to the schema after aventara:prepare last ran. cause.message is "The requested Resource is not available." and the issue is V1005 at `["resource"]`.',
|
|
60
|
+
fix: "Use the model's exact name. After a schema change run the adapter's generate step (`npm run aventara:prepare` in a scaffolded project), restart, and regenerate the client. A Resource hidden on purpose is reached from server code (framework.application).",
|
|
61
|
+
},
|
|
62
|
+
A2002: {
|
|
63
|
+
message: "Unknown operation.",
|
|
64
|
+
cause: 'The operation is not available on that Resource: a typo, removed by exposure, an operation the adapter does not offer (such as delete.many), or a ctx.$sql, appTx.$sql or ctx.$transaction the adapter or the layer cannot run. The issue is V1006 at `["family"]` or `["variant"]`.',
|
|
65
|
+
fix: "Call an operation the contract lists (`GET <api>/_contract`), regenerate a stale client, and check the layer's exemptions and transactionsStyle.",
|
|
66
|
+
},
|
|
67
|
+
A2003: {
|
|
68
|
+
message: "Not found.",
|
|
69
|
+
cause: "A unique operation (find.unique, update.unique, delete.unique) matched no row, or a $connect names a record that does not exist. The operation fails, so no after hook runs. Under a policy, a row outside the caller's read scope is a miss too, and so is a single-row update or delete of a row the caller cannot read, so the answer does not reveal that the row exists. A row the caller can read but not change answers A4002.",
|
|
70
|
+
fix: "Catch AvNotFoundError, or use a first-style operation, which answers A1001 with null. Check the $connect identifier.",
|
|
71
|
+
},
|
|
72
|
+
A2004: {
|
|
73
|
+
message: "Validation failed.",
|
|
74
|
+
cause: 'The arguments break a contract rule or a field validator. cause.issues lists each problem by V-code and path; a validator\'s issue also has check and params. The validators judge the values after the pipes and write compute, so a computed value they refuse is here too, at its field. A required create field left out is here (V1000). So is a value the database itself refused: too long for its column or its index, or out of its range (V1004), or holding a character it cannot store or a pattern it cannot read (V1001), with the issue at `["arguments"]`, or at the value where the adapter can place it (a bigint its driver cannot bind), and its message saying what the database refused. So is a record written through a relation that writes that relation, or a field holding its reference, back (V1012, at that field), where the adapter admits no such write.',
|
|
75
|
+
fix: "Fix the argument each issue's path points at, as its V-code says. A field the server must fill takes a compute.create stage. For a value the database refused, send one its column holds. For a nested write that writes its relation back, leave that field out: the parent supplies it.",
|
|
76
|
+
},
|
|
77
|
+
A2005: {
|
|
78
|
+
message: "Contract mismatch.",
|
|
79
|
+
cause: "The caller's Aventara-Contract-Hash is not the server's current one: the schema, the configuration, the limits or the exposure changed, or the client targets another deployment.",
|
|
80
|
+
fix: "Regenerate the client against the running server: `npm run avclient:generate`.",
|
|
81
|
+
},
|
|
82
|
+
A2006: {
|
|
83
|
+
message: "Protocol mismatch.",
|
|
84
|
+
cause: "Aventara-Protocol-Version is not 1.",
|
|
85
|
+
fix: "Send `Aventara-Protocol-Version: 1`, or upgrade the client.",
|
|
86
|
+
},
|
|
87
|
+
A2007: {
|
|
88
|
+
message: "Invalid transaction reference.",
|
|
89
|
+
cause: "A transaction $ref or fingerprint is invalid: the issues are V1010, V1011, V1016, V1017 or V1018, and cause.operation is the step. A $ref with no fingerprint is A2004 / V1000.",
|
|
90
|
+
fix: "Let the generated client or framework.appTx build plans; check the $ref path and that the referenced step comes earlier.",
|
|
91
|
+
},
|
|
92
|
+
A2008: {
|
|
93
|
+
message: "Conflict.",
|
|
94
|
+
cause: "A uniqueness or reference constraint failed: a duplicate value, a missing parent, or a $disconnect or $set that would orphan a required child (also through update.first or a developer SQL statement). Sending it again unchanged fails the same way.",
|
|
95
|
+
fix: "Change the data. For a duplicate, update the existing row or use upsert.unique.",
|
|
96
|
+
},
|
|
97
|
+
A2009: {
|
|
98
|
+
message: "Limit exceeded.",
|
|
99
|
+
cause: "A contract limit was crossed: nesting depth (V1013), list or plan size (V1014), boolean nodes (V1015) or Json value depth (V1021).",
|
|
100
|
+
fix: "Ask for less (paginate, split the plan), or raise the limit under `limits`.",
|
|
101
|
+
},
|
|
102
|
+
A2010: {
|
|
103
|
+
message: "Payload too large.",
|
|
104
|
+
cause: "The decoded request body exceeds maxRequestBytes (default 1048576).",
|
|
105
|
+
fix: "Send less, or raise limits.maxRequestBytes.",
|
|
106
|
+
},
|
|
107
|
+
A2011: {
|
|
108
|
+
message: "Unsupported media type.",
|
|
109
|
+
cause: "The body is not application/json, or its Content-Encoding is not gzip, deflate or br.",
|
|
110
|
+
fix: "Send `Content-Type: application/json`.",
|
|
111
|
+
},
|
|
112
|
+
A2012: {
|
|
113
|
+
message: "Method not allowed.",
|
|
114
|
+
cause: "The HTTP method does not fit the route; the Allow header names the right one (`POST` on operations and `/_transactions`, `GET` on `/_contract`).",
|
|
115
|
+
fix: "Use the method the Allow header names.",
|
|
116
|
+
},
|
|
117
|
+
A2013: {
|
|
118
|
+
message: "Concurrent modification.",
|
|
119
|
+
cause: "A competing writer reached the state first; nothing was written.",
|
|
120
|
+
fix: "Retry. No retry is automatic.",
|
|
121
|
+
},
|
|
122
|
+
A2014: {
|
|
123
|
+
message: "Stale selection.",
|
|
124
|
+
cause: "The selected state changed before the write; nothing was written.",
|
|
125
|
+
fix: "Read again, then retry.",
|
|
126
|
+
},
|
|
127
|
+
A3000: {
|
|
128
|
+
message: "Internal error.",
|
|
129
|
+
cause: 'An unexpected failure on the server: a stage threw an error that is not an AvError, an interceptor called next() twice, a compute stage reached a write through its read-only ctx, a compute stage returned a value of the wrong type, or a compute.create returned undefined for a required field. cause.message is always "Internal framework error."',
|
|
130
|
+
fix: "Read the real error in the diagnostics sink (the root `diagnostics` key) or the server log line for the request id, and fix that stage. To answer with a code of your choice, throw an AvError.",
|
|
131
|
+
},
|
|
132
|
+
A3001: {
|
|
133
|
+
message: "Adapter error.",
|
|
134
|
+
cause: 'A database or ORM failure that is not something the caller can fix. cause.message is always "Adapter execution failed."',
|
|
135
|
+
fix: "Read the raw error in the diagnostics sink; check the database, its connection and the migration state.",
|
|
136
|
+
},
|
|
137
|
+
A3002: {
|
|
138
|
+
message: "Transaction error.",
|
|
139
|
+
cause: "Transaction infrastructure failed (commit or rollback, or the transaction expired or was closed under a step), or a Resource transaction interceptor called next() twice or resolved without calling it.",
|
|
140
|
+
fix: "Read the diagnostics sink. Call next() exactly once in a transaction interceptor; retry an infrastructure failure.",
|
|
141
|
+
},
|
|
142
|
+
A3003: {
|
|
143
|
+
message: "Serialization error.",
|
|
144
|
+
cause: "A result could not be encoded for transport.",
|
|
145
|
+
fix: "Read the diagnostics sink; make compute.read stages and Json values return plain data of the field's type.",
|
|
146
|
+
},
|
|
147
|
+
A3004: {
|
|
148
|
+
message: "Pipe output invalid.",
|
|
149
|
+
cause: 'A server pipe, field pipe or transaction pipe (or write compute) returned arguments the server\'s own contract refuses: a field the Resource does not have, a wrong type, a dropped required field, a reference written together with its relation (V1012), or a changed plan. cause.message is always "A server pipeline produced invalid arguments."',
|
|
150
|
+
fix: "Read the server log line, which names the pipe, the operation and the path, and fix the pipe. A pipe returns a new object of the same shape, or undefined to keep the arguments.",
|
|
151
|
+
},
|
|
152
|
+
A4000: {
|
|
153
|
+
message: "Unauthenticated.",
|
|
154
|
+
cause: 'A guard threw new AvError("A4000", ...): authentication is required or failed. The framework never authenticates by itself.',
|
|
155
|
+
fix: "Send the credentials your guards expect, such as the Authorization header.",
|
|
156
|
+
},
|
|
157
|
+
A4001: {
|
|
158
|
+
message: "Forbidden.",
|
|
159
|
+
cause: 'A guard returned false ("Operation denied by a framework guard."), a field write guard or a nested write\'s target guard included, or a stage threw A4001.',
|
|
160
|
+
fix: "Call as a caller the guard admits, or stop sending the guarded field. To answer another code, throw an AvError from the guard.",
|
|
161
|
+
},
|
|
162
|
+
A4002: {
|
|
163
|
+
message: "Policy denied.",
|
|
164
|
+
cause: "The configuration's policy refused the request: its engine does not allow the operation, a field the request names, writes or returns, a row it reaches, a row it creates, or the row a change leaves (moved out of what the caller reads, or failing its grant's after condition, which rolls the write back); on a database without interactive transactions, a write the policy can only check after it runs; or a stage threw new AvError(\"A4002\", ...).",
|
|
165
|
+
fix: "Read cause.message, which names what the policy refused. Call as a principal the policy allows, leave the refused field or relation out (a governed one is named only where every row grants it), or change only rows the caller may change and still read afterwards.",
|
|
166
|
+
},
|
|
167
|
+
};
|
|
@@ -1,17 +1,27 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type { AvOperationIdentity } from "../operations/operation-identity.js";
|
|
2
|
+
import type { PolicySession } from "../policy/policy-session.js";
|
|
3
|
+
import type { AvTransportContext } from "./pipeline.js";
|
|
4
|
+
import type { AvState } from "./request-state.js";
|
|
5
|
+
/**
|
|
6
|
+
* The protocol version and Contract hash a remote caller says it was built for:
|
|
7
|
+
* the Client Contract's for a client, the Agent Contract's for an agent.
|
|
8
|
+
*/
|
|
9
|
+
export type AvRequestProtocol = {
|
|
5
10
|
readonly version: number;
|
|
6
11
|
readonly hash: string;
|
|
7
12
|
};
|
|
8
|
-
type RuntimeOperationBase =
|
|
13
|
+
type RuntimeOperationBase = AvOperationIdentity & {
|
|
9
14
|
readonly resource: string;
|
|
10
15
|
readonly arguments: unknown;
|
|
11
16
|
readonly requestId: string;
|
|
17
|
+
/**
|
|
18
|
+
* The request's `ctx.$state`: every stage of it, and every ctx call they make,
|
|
19
|
+
* shares this one object. Omitted, it is a fresh `{}`.
|
|
20
|
+
*/
|
|
21
|
+
readonly state?: AvState;
|
|
12
22
|
};
|
|
13
23
|
/** An in-process request, run under the Application Contract. */
|
|
14
|
-
export type
|
|
24
|
+
export type AvApplicationOperationRequest = RuntimeOperationBase & {
|
|
15
25
|
readonly origin: "application";
|
|
16
26
|
readonly protocol?: never;
|
|
17
27
|
readonly transport?: never;
|
|
@@ -20,13 +30,24 @@ export type ApplicationOperationRequest = RuntimeOperationBase & {
|
|
|
20
30
|
* A remote request, run under the Client Contract; `protocol` is the identity
|
|
21
31
|
* the client sent.
|
|
22
32
|
*/
|
|
23
|
-
export type
|
|
33
|
+
export type AvClientOperationRequest = RuntimeOperationBase & {
|
|
24
34
|
readonly origin: "client";
|
|
25
|
-
readonly protocol:
|
|
26
|
-
readonly transport?:
|
|
35
|
+
readonly protocol: AvRequestProtocol;
|
|
36
|
+
readonly transport?: AvTransportContext;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* An AI agent's request, run under the Agent Contract; `protocol` is the
|
|
40
|
+
* identity of the Agent Contract the caller (an MCP server) was built from.
|
|
41
|
+
*/
|
|
42
|
+
export type AvAgentOperationRequest = RuntimeOperationBase & {
|
|
43
|
+
readonly origin: "agent";
|
|
44
|
+
readonly protocol: AvRequestProtocol;
|
|
45
|
+
readonly transport?: AvTransportContext;
|
|
27
46
|
};
|
|
47
|
+
/** A request from outside the server: a client's or an agent's. */
|
|
48
|
+
export type RemoteOperationRequest = AvClientOperationRequest | AvAgentOperationRequest;
|
|
28
49
|
/** One operation request, as `framework.execute` takes it. */
|
|
29
|
-
export type
|
|
50
|
+
export type AvOperationRequest = AvApplicationOperationRequest | AvClientOperationRequest | AvAgentOperationRequest;
|
|
30
51
|
type WithoutArguments<Request> = Request extends unknown ? Omit<Request, "arguments"> : never;
|
|
31
52
|
/**
|
|
32
53
|
* A request as every stage after the Framework Validation Layer sees it:
|
|
@@ -36,5 +57,18 @@ type WithoutArguments<Request> = Request extends unknown ? Omit<Request, "argume
|
|
|
36
57
|
* unreachable by type. Distributive, so the origin and family/variant
|
|
37
58
|
* correlations survive the omission.
|
|
38
59
|
*/
|
|
39
|
-
export type OperationExecutionRequest = WithoutArguments<
|
|
60
|
+
export type OperationExecutionRequest = WithoutArguments<AvOperationRequest>;
|
|
61
|
+
/**
|
|
62
|
+
* A request whose stages run: its `state` settled once, the seed or the `{}`
|
|
63
|
+
* the runtime made for it, so every stage is told the same object.
|
|
64
|
+
*/
|
|
65
|
+
export type StatefulOperationRequest = OperationExecutionRequest & {
|
|
66
|
+
readonly state: AvState;
|
|
67
|
+
/**
|
|
68
|
+
* The request's policy session, when the policy checks it: a client's or an
|
|
69
|
+
* agent's request, or an application call made `as` a principal. Absent, nothing
|
|
70
|
+
* is checked: an application call, or a call a stage made through `ctx`.
|
|
71
|
+
*/
|
|
72
|
+
readonly policy?: PolicySession;
|
|
73
|
+
};
|
|
40
74
|
export {};
|