@aventara/core 0.1.0-pilot.4 → 1.0.0-rc.1
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 +1478 -0
- package/README.md +275 -11
- package/dist/adapters/adapter-discovery-diagnostic.d.ts +4 -4
- package/dist/adapters/adapter-field.d.ts +11 -11
- package/dist/adapters/adapter-identifier.d.ts +6 -6
- package/dist/adapters/adapter-model.d.ts +17 -9
- package/dist/adapters/adapter-operation-executor.interface.d.ts +4 -4
- package/dist/adapters/adapter-operation.d.ts +3 -3
- package/dist/adapters/adapter-resource.d.ts +18 -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 +49 -25
- 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/avz/avz.js +354 -0
- package/dist/avz/index.d.ts +7 -0
- package/dist/avz/index.js +1 -0
- package/dist/avz/json-shape.registry.d.ts +22 -0
- package/dist/avz/json-shape.registry.js +16 -0
- package/dist/avz/zod-issue.translator.d.ts +57 -0
- package/dist/avz/zod-issue.translator.js +149 -0
- package/dist/compiler/contract-compiler-diagnostic.d.ts +37 -5
- package/dist/compiler/contract.compiler.d.ts +18 -18
- package/dist/compiler/contract.compiler.js +595 -421
- 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/config/any-framework-config.d.ts +19 -12
- package/dist/config/config-diagnostic.d.ts +11 -4
- package/dist/config/config-layer.d.ts +15 -6
- package/dist/config/config.resolver.d.ts +75 -29
- package/dist/config/config.resolver.js +109 -44
- package/dist/config/config.validator.d.ts +7 -7
- package/dist/config/config.validator.js +586 -71
- package/dist/config/define-resource.d.ts +57 -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 +1 -1
- package/dist/config/exact-framework-config.d.ts +280 -0
- package/dist/config/field-compute.resolver.d.ts +19 -0
- package/dist/config/field-compute.resolver.js +115 -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 +111 -37
- 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 +116 -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/capability.d.ts +11 -11
- package/dist/contracts/client-contract-structure.validator.d.ts +344 -29
- package/dist/contracts/client-contract-structure.validator.js +248 -7
- package/dist/contracts/contract-canonicalizer.d.ts +19 -3
- package/dist/contracts/contract-canonicalizer.js +172 -27
- package/dist/contracts/contract-hash.d.ts +12 -7
- package/dist/contracts/contract-hash.js +3 -2
- 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 +31 -16
- 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 +61 -41
- package/dist/contracts/identifier.d.ts +4 -4
- package/dist/contracts/json-shape.d.ts +76 -0
- package/dist/contracts/json-shape.js +1 -0
- package/dist/contracts/lifecycle-trait.d.ts +2 -2
- package/dist/contracts/reference-write-limit.d.ts +7 -0
- package/dist/contracts/reference-write-limit.js +1 -0
- 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 +25 -14
- 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/contract-view.d.ts +234 -63
- package/dist/framework/framework-construction.error.d.ts +10 -10
- package/dist/framework/framework-construction.error.js +2 -2
- package/dist/framework/framework.d.ts +50 -24
- package/dist/framework/framework.factory.d.ts +8 -6
- package/dist/framework/framework.factory.js +95 -32
- package/dist/framework/operation-facade.d.ts +123 -52
- package/dist/framework/operation-facade.js +9 -1
- package/dist/index.d.ts +55 -82
- package/dist/index.js +6 -26
- package/dist/internal.d.ts +40 -0
- package/dist/internal.js +18 -0
- package/dist/operations/operation-arguments.d.ts +316 -201
- package/dist/operations/operation-call.d.ts +27 -28
- package/dist/operations/operation-identity.d.ts +12 -10
- package/dist/operations/operation-identity.js +3 -0
- package/dist/operations/operation-result.d.ts +21 -21
- package/dist/operations/operation-validator-core.d.ts +6 -6
- package/dist/operations/operation-validator-core.js +41 -12
- package/dist/operations/operation-validator.d.ts +24 -9
- package/dist/operations/operation-validator.js +26 -10
- package/dist/operations/projection-scope.resolver.d.ts +7 -7
- package/dist/operations/structural-limits.walker.d.ts +19 -0
- package/dist/operations/structural-limits.walker.js +489 -0
- package/dist/operations/validation-code.d.ts +11 -6
- package/dist/operations/validation-code.js +4 -0
- package/dist/operations/write-scope.resolver.d.ts +6 -6
- package/dist/protocol/absent-route.responder.d.ts +13 -11
- package/dist/protocol/absent-route.responder.js +42 -16
- package/dist/protocol/contract-document.responder.d.ts +3 -3
- package/dist/protocol/contract-document.responder.js +2 -2
- package/dist/protocol/http-request.decoder.d.ts +23 -13
- package/dist/protocol/http-request.decoder.js +19 -11
- package/dist/protocol/http-request.reader.d.ts +3 -3
- 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-surface.d.ts +4 -4
- package/dist/protocol/protocol.binder.d.ts +52 -27
- package/dist/protocol/protocol.binder.js +14 -9
- package/dist/protocol/protocol.handler.d.ts +28 -15
- package/dist/protocol/protocol.handler.js +55 -10
- package/dist/protocol/unmounted-route.error.d.ts +19 -0
- package/dist/protocol/unmounted-route.error.js +10 -0
- package/dist/runtime/caller-data.copier.d.ts +59 -0
- package/dist/runtime/caller-data.copier.js +470 -0
- package/dist/runtime/caller-data.door.d.ts +56 -0
- package/dist/runtime/caller-data.door.js +67 -0
- package/dist/runtime/computed-read-runtime.d.ts +7 -6
- package/dist/runtime/computed-read-runtime.js +61 -55
- package/dist/runtime/computed-value.error.d.ts +13 -0
- package/dist/runtime/computed-value.error.js +9 -0
- package/dist/runtime/context-executor.runtime.d.ts +59 -0
- package/dist/runtime/context-executor.runtime.js +275 -0
- package/dist/runtime/create-requirement.d.ts +22 -57
- package/dist/runtime/create-requirement.js +140 -37
- package/dist/runtime/decimal.d.ts +2 -2
- package/dist/runtime/decimal.js +1 -1
- package/dist/runtime/diagnostics-reporter.d.ts +64 -22
- package/dist/runtime/diagnostics-reporter.js +35 -4
- package/dist/runtime/error-boundary.d.ts +73 -8
- package/dist/runtime/error-boundary.js +104 -48
- package/dist/runtime/execution-options.d.ts +10 -2
- package/dist/runtime/field-check.evaluator.d.ts +29 -0
- package/dist/runtime/field-check.evaluator.js +521 -0
- package/dist/runtime/field-compute.d.ts +64 -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 +35 -0
- package/dist/runtime/field-stage.runtime.js +143 -0
- package/dist/runtime/field-validator.runtime.d.ts +11 -0
- package/dist/runtime/field-validator.runtime.js +87 -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 +79 -7
- 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 +23 -2
- 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 +3 -3
- package/dist/runtime/level-lifecycle.runtime.d.ts +25 -0
- package/dist/runtime/level-lifecycle.runtime.js +42 -0
- package/dist/runtime/misuse-reporter.d.ts +32 -0
- package/dist/runtime/misuse-reporter.js +19 -0
- package/dist/runtime/mutation-planner.d.ts +19 -10
- package/dist/runtime/mutation-planner.js +62 -36
- package/dist/runtime/nested-write.walker.d.ts +32 -0
- package/dist/runtime/nested-write.walker.js +73 -0
- package/dist/runtime/operation-request.d.ts +35 -15
- package/dist/runtime/operation-response.d.ts +17 -17
- package/dist/runtime/operation-runtime.d.ts +125 -30
- package/dist/runtime/operation-runtime.js +423 -83
- package/dist/runtime/outcome-mapper.d.ts +16 -5
- package/dist/runtime/outcome-mapper.js +35 -8
- package/dist/runtime/output-validator.d.ts +16 -6
- package/dist/runtime/output-validator.js +12 -1
- package/dist/runtime/owned-execution.registry.d.ts +13 -0
- package/dist/runtime/owned-execution.registry.js +7 -0
- package/dist/runtime/pipe-output.validator.d.ts +33 -18
- package/dist/runtime/pipe-output.validator.js +12 -12
- package/dist/runtime/pipeline.d.ts +202 -28
- package/dist/runtime/readonly-value.d.ts +32 -0
- package/dist/runtime/readonly-value.js +141 -0
- package/dist/runtime/referential-action.d.ts +7 -0
- package/dist/runtime/request-envelope.validator.d.ts +5 -0
- package/dist/runtime/request-envelope.validator.js +123 -0
- 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 +56 -13
- package/dist/runtime/scalar-runtime.js +167 -86
- 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 +2 -2
- package/dist/transactions/sql-statement.d.ts +77 -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 +134 -0
- package/dist/transactions/transaction-envelope.d.ts +4 -4
- package/dist/transactions/transaction-integrity-error.d.ts +6 -6
- package/dist/transactions/transaction-integrity-error.js +5 -2
- package/dist/transactions/transaction-plan-assembler.d.ts +23 -9
- package/dist/transactions/transaction-plan-assembler.js +195 -82
- package/dist/transactions/transaction-plan-validator.d.ts +53 -21
- package/dist/transactions/transaction-plan-validator.js +246 -163
- package/dist/transactions/transaction-reference-collector.d.ts +30 -0
- package/dist/transactions/transaction-reference-collector.js +204 -0
- package/dist/transactions/transaction-reference-resolver.d.ts +19 -2
- package/dist/transactions/transaction-reference-resolver.js +27 -10
- package/dist/transactions/transaction-reference-validator.d.ts +34 -4
- package/dist/transactions/transaction-reference-validator.js +82 -43
- package/dist/transactions/transaction-reference.d.ts +30 -58
- package/dist/transactions/transaction-request.d.ts +20 -7
- package/dist/transactions/transaction-response.d.ts +12 -7
- package/dist/transactions/transaction-response.js +24 -1
- package/dist/transactions/transaction-runtime.d.ts +11 -8
- package/dist/transactions/transaction-runtime.js +167 -50
- package/dist/transactions/transaction-settlement.runtime.d.ts +51 -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 +2 -2
- package/dist/transactions/transaction-slot-writer.js +2 -2
- package/dist/transactions/transaction-stage.runtime.d.ts +81 -0
- package/dist/transactions/transaction-stage.runtime.js +123 -0
- package/package.json +18 -3
- package/src/runtime/field-check.evaluator.ts +720 -0
- package/dist/config/define-fields.d.ts +0 -35
- 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 -36
- package/dist/config/framework-restrictions-config.d.ts +0 -142
- package/dist/operations/operation-boolean-nodes.d.ts +0 -11
- package/dist/operations/operation-boolean-nodes.js +0 -283
- package/dist/operations/operation-nesting.d.ts +0 -8
- package/dist/operations/operation-nesting.js +0 -307
- 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/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,60 +1,171 @@
|
|
|
1
|
+
import { hasFieldValidators } from "../compiler/field-validator.compiler.js";
|
|
2
|
+
import { fieldStagesOf, isForcedOperation, nestedTargetLevels, operationLevels, rawPipelineTree, transactionLevelsOf, } from "../config/pipeline-tree.resolver.js";
|
|
1
3
|
import { AVENTARA_PROTOCOL_VERSION } from "../contracts/contract-protocol.js";
|
|
2
|
-
import { validateOperationArguments } from "../operations/operation-validator.js";
|
|
4
|
+
import { findOperationAvailabilityIssue, validateOperationArguments, } from "../operations/operation-validator.js";
|
|
5
|
+
import { transactionInfrastructureFailure } from "../transactions/transaction-response.js";
|
|
6
|
+
import { settleTransaction } from "../transactions/transaction-settlement.runtime.js";
|
|
7
|
+
import { TRANSACTION_PIPES, transactionFacts, } from "../transactions/transaction-stage.runtime.js";
|
|
8
|
+
import { copyAtDoor, misuseIdentityOf, refuseCallerData, } from "./caller-data.door.js";
|
|
3
9
|
import { materializeReadOperation, planReadOperation, } from "./computed-read-runtime.js";
|
|
4
|
-
import {
|
|
10
|
+
import { createContextExecutor, } from "./context-executor.runtime.js";
|
|
11
|
+
import { createRequirementIssues, recordWriteFactsOf, } from "./create-requirement.js";
|
|
12
|
+
import { createDiagnosticsReporter, } from "./diagnostics-reporter.js";
|
|
5
13
|
import { AdapterBoundary, OPERATION_ARGUMENTS_PATH, resolveOperationFailure, sanitizeOperationFailure, } from "./error-boundary.js";
|
|
6
|
-
import {
|
|
14
|
+
import { planFieldStages } from "./field-stage.plan.js";
|
|
15
|
+
import { guardSentFields, pipeSentFields, valueAt, writeRecordPathsOf, } from "./field-stage.runtime.js";
|
|
16
|
+
import { fieldValidatorIssues } from "./field-validator.runtime.js";
|
|
17
|
+
import { thrownFailure } from "./framework-error.factory.js";
|
|
18
|
+
import { AvInterceptorNextError } from "./interceptor-next.error.js";
|
|
19
|
+
import { runLevelLifecycle, } from "./level-lifecycle.runtime.js";
|
|
20
|
+
import { createMisuseReporter, } from "./misuse-reporter.js";
|
|
21
|
+
import { applyNestedWriteCompute, applyWriteCompute, stripVirtualMutationInput, } from "./mutation-planner.js";
|
|
22
|
+
import { nestedWriteTargetsOf, } from "./nested-write.walker.js";
|
|
7
23
|
import { internalFailure, operationFailure } from "./operation-response.js";
|
|
8
|
-
import { mapOperationOutcome, mapValidationOutcome } from "./outcome-mapper.js";
|
|
9
|
-
import { validateOperationOutput } from "./output-validator.js";
|
|
10
|
-
import { refusePipeOutput } from "./pipe-output.validator.js";
|
|
11
|
-
import {
|
|
24
|
+
import { mapOperationOutcome, mapValidationOutcome, uniqueMissFailure, } from "./outcome-mapper.js";
|
|
25
|
+
import { AvOutputValidationError, validateOperationOutput, } from "./output-validator.js";
|
|
26
|
+
import { refusePipeOutput, refuseStageOutput, } from "./pipe-output.validator.js";
|
|
27
|
+
import { deepFreeze, frozenCopy } from "./readonly-value.js";
|
|
28
|
+
import { requestStateOf } from "./request-state.resolver.js";
|
|
29
|
+
import { normalizeOperationScalarValues, } from "./scalar-runtime.js";
|
|
30
|
+
function scopeOf(request, binding) {
|
|
31
|
+
return {
|
|
32
|
+
requestId: request.requestId,
|
|
33
|
+
transaction: binding?.kind === "transaction" ? binding.executor : undefined,
|
|
34
|
+
state: request.state,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function withRequestState(request) {
|
|
38
|
+
return { ...request, state: requestStateOf(request.state) };
|
|
39
|
+
}
|
|
40
|
+
export function createPipelineDependencies(dependencies, model) {
|
|
41
|
+
const misuse = createMisuseReporter(dependencies.config.misuse);
|
|
42
|
+
const recordWrites = recordWriteFactsOf(dependencies.adapter);
|
|
43
|
+
const contexts = createContextExecutor({
|
|
44
|
+
model,
|
|
45
|
+
adapter: dependencies.adapter,
|
|
46
|
+
application: dependencies.contracts.application,
|
|
47
|
+
diagnostics: dependencies.config.diagnostics,
|
|
48
|
+
misuse,
|
|
49
|
+
run: (request, transaction) => executeContextCall(raw, dependencies, request, transaction, misuse),
|
|
50
|
+
});
|
|
51
|
+
const { contracts, config } = dependencies;
|
|
52
|
+
const pipeline = {
|
|
53
|
+
contracts,
|
|
54
|
+
config,
|
|
55
|
+
recordWrites,
|
|
56
|
+
contexts,
|
|
57
|
+
fieldStages: {
|
|
58
|
+
application: planFieldStages(config.application.pipelines, contracts.application),
|
|
59
|
+
client: planFieldStages(config.client.pipelines, contracts.client),
|
|
60
|
+
agent: planFieldStages(config.agent.pipelines, contracts.agent),
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
const rawTree = rawPipelineTree(config.application.pipelines);
|
|
64
|
+
const raw = {
|
|
65
|
+
...pipeline,
|
|
66
|
+
config: {
|
|
67
|
+
...config,
|
|
68
|
+
application: { ...config.application, pipelines: rawTree },
|
|
69
|
+
},
|
|
70
|
+
fieldStages: {
|
|
71
|
+
...pipeline.fieldStages,
|
|
72
|
+
application: planFieldStages(rawTree, contracts.application),
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
return pipeline;
|
|
76
|
+
}
|
|
77
|
+
async function executeContextCall(raw, dependencies, request, transaction, misuse) {
|
|
78
|
+
const report = createDiagnosticsReporter(dependencies.config.diagnostics, request);
|
|
79
|
+
try {
|
|
80
|
+
let validated;
|
|
81
|
+
try {
|
|
82
|
+
validated = validateOperation(dependencies, request, "caller", misuse);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
return sanitizeOperationFailure(error, "runtime", report, {
|
|
86
|
+
path: OPERATION_ARGUMENTS_PATH,
|
|
87
|
+
arguments: request.arguments,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (!validated.ok) {
|
|
91
|
+
return validated.response;
|
|
92
|
+
}
|
|
93
|
+
const stateful = withRequestState(request);
|
|
94
|
+
const admitted = await admitOperation(raw, stateful, validated.contract, validated.arguments, OPERATION_ARGUMENTS_PATH, report, {
|
|
95
|
+
requestId: request.requestId,
|
|
96
|
+
transaction,
|
|
97
|
+
state: stateful.state,
|
|
98
|
+
});
|
|
99
|
+
if (!admitted.ok) {
|
|
100
|
+
return admitted.response;
|
|
101
|
+
}
|
|
102
|
+
return await executeAdmittedOperation(raw, stateful, validated.contract, admitted.args, OPERATION_ARGUMENTS_PATH, transaction === undefined
|
|
103
|
+
? { kind: "standalone", executor: dependencies.adapter }
|
|
104
|
+
: { kind: "transaction", executor: transaction }, report);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
report(error, "A3000");
|
|
108
|
+
return internalFailure();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
12
111
|
export function activeContract(contracts, request) {
|
|
13
|
-
return request.
|
|
14
|
-
? contracts.application
|
|
15
|
-
: contracts.client;
|
|
112
|
+
return contracts[request.origin];
|
|
16
113
|
}
|
|
17
114
|
function activeScopeConfig(config, request) {
|
|
18
|
-
return request.
|
|
115
|
+
return config[request.origin];
|
|
19
116
|
}
|
|
20
|
-
function
|
|
117
|
+
function operationFacts(contract, request, args) {
|
|
21
118
|
return {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
args,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
119
|
+
$operation: {
|
|
120
|
+
resource: request.resource,
|
|
121
|
+
family: request.family,
|
|
122
|
+
variant: request.variant,
|
|
123
|
+
},
|
|
124
|
+
$args: args,
|
|
125
|
+
$origin: request.origin,
|
|
126
|
+
$requestId: request.requestId,
|
|
127
|
+
$contract: contract,
|
|
128
|
+
...(request.origin !== "application" && request.transport !== undefined
|
|
129
|
+
? { $transport: request.transport }
|
|
31
130
|
: {}),
|
|
32
131
|
};
|
|
33
132
|
}
|
|
133
|
+
function nestedFacts(contract, request, target, payload) {
|
|
134
|
+
return {
|
|
135
|
+
...operationFacts(contract, request, payload),
|
|
136
|
+
$operation: {
|
|
137
|
+
resource: target.resource,
|
|
138
|
+
family: target.family,
|
|
139
|
+
variant: "one",
|
|
140
|
+
nested: true,
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
34
144
|
function forbidden() {
|
|
35
145
|
return operationFailure("A4001", {
|
|
36
146
|
message: "Operation denied by a framework guard.",
|
|
37
147
|
});
|
|
38
148
|
}
|
|
39
149
|
function outputAccepted(contract, request, projection, data, report) {
|
|
150
|
+
let validation;
|
|
40
151
|
try {
|
|
41
|
-
|
|
152
|
+
validation = validateOperationOutput(contract, request, projection, data);
|
|
42
153
|
}
|
|
43
154
|
catch (error) {
|
|
44
155
|
report(error, "A3000");
|
|
45
156
|
return false;
|
|
46
157
|
}
|
|
158
|
+
if (!validation.ok) {
|
|
159
|
+
report(new AvOutputValidationError(request, validation.issues), "A3000");
|
|
160
|
+
}
|
|
161
|
+
return validation.ok;
|
|
47
162
|
}
|
|
48
|
-
export function createOperationRuntime(dependencies) {
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
config: dependencies.config,
|
|
52
|
-
createRequirements: dependencies.adapter.createRequirements ?? {},
|
|
53
|
-
};
|
|
54
|
-
return async (request, report) => {
|
|
163
|
+
export function createOperationRuntime(dependencies, pipelineDependencies) {
|
|
164
|
+
const misuse = createMisuseReporter(dependencies.config.misuse);
|
|
165
|
+
return async (request, report, source) => {
|
|
55
166
|
let validated;
|
|
56
167
|
try {
|
|
57
|
-
validated = validateOperation(dependencies, request);
|
|
168
|
+
validated = validateOperation(dependencies, request, source, misuse);
|
|
58
169
|
}
|
|
59
170
|
catch (error) {
|
|
60
171
|
return sanitizeOperationFailure(error, "runtime", report, {
|
|
@@ -65,45 +176,70 @@ export function createOperationRuntime(dependencies) {
|
|
|
65
176
|
if (!validated.ok) {
|
|
66
177
|
return validated.response;
|
|
67
178
|
}
|
|
68
|
-
|
|
179
|
+
const stateful = withRequestState(request);
|
|
180
|
+
const admitted = await admitOperation(pipelineDependencies, stateful, validated.contract, validated.arguments, OPERATION_ARGUMENTS_PATH, report, {
|
|
181
|
+
requestId: request.requestId,
|
|
182
|
+
transaction: undefined,
|
|
183
|
+
state: stateful.state,
|
|
184
|
+
});
|
|
185
|
+
if (!admitted.ok) {
|
|
186
|
+
return admitted.response;
|
|
187
|
+
}
|
|
188
|
+
if (isForcedOperation(activeScopeConfig(dependencies.config, request).pipelines, request)) {
|
|
189
|
+
return executeForcedOperation(pipelineDependencies, dependencies.adapter, stateful, validated.contract, admitted.args, report);
|
|
190
|
+
}
|
|
191
|
+
return executeAdmittedOperation(pipelineDependencies, stateful, validated.contract, admitted.args, OPERATION_ARGUMENTS_PATH, { kind: "standalone", executor: dependencies.adapter }, report);
|
|
69
192
|
};
|
|
70
193
|
}
|
|
71
|
-
function validateOperation(dependencies, request) {
|
|
194
|
+
function validateOperation(dependencies, request, source, misuse) {
|
|
72
195
|
const protocolFailure = validateProtocolIdentity(dependencies.contracts, request);
|
|
73
196
|
if (protocolFailure !== undefined) {
|
|
74
197
|
return rejected(protocolFailure);
|
|
75
198
|
}
|
|
76
199
|
const contract = activeContract(dependencies.contracts, request);
|
|
77
|
-
|
|
200
|
+
let owned = request;
|
|
201
|
+
if (source === "caller" &&
|
|
202
|
+
findOperationAvailabilityIssue(contract, request) === undefined) {
|
|
203
|
+
const copy = copyAtDoor(request.arguments);
|
|
204
|
+
if (!copy.ok) {
|
|
205
|
+
return rejected(mapValidationOutcome([
|
|
206
|
+
refuseCallerData(copy.error, OPERATION_ARGUMENTS_PATH, misuseIdentityOf(request), misuse),
|
|
207
|
+
]));
|
|
208
|
+
}
|
|
209
|
+
owned = { ...request, arguments: copy.value };
|
|
210
|
+
}
|
|
211
|
+
const validation = validateOperationRequest(contract, owned, undefined, "in-place");
|
|
78
212
|
if (!validation.ok) {
|
|
79
213
|
return rejected(validation.response);
|
|
80
214
|
}
|
|
81
215
|
return { ok: true, contract, arguments: validation.arguments };
|
|
82
216
|
}
|
|
83
217
|
export function validateProtocolIdentity(contracts, request) {
|
|
84
|
-
return request.
|
|
85
|
-
?
|
|
86
|
-
:
|
|
218
|
+
return request.origin === "application"
|
|
219
|
+
? undefined
|
|
220
|
+
: protocolIdentityFailure(contracts, request.protocol, request.origin);
|
|
87
221
|
}
|
|
88
|
-
export function protocolIdentityFailure(contracts, protocol) {
|
|
222
|
+
export function protocolIdentityFailure(contracts, protocol, origin) {
|
|
89
223
|
if (protocol.version !== AVENTARA_PROTOCOL_VERSION) {
|
|
90
224
|
return operationFailure("A2006", {
|
|
91
225
|
message: "Aventara protocol version does not match the server.",
|
|
92
226
|
});
|
|
93
227
|
}
|
|
94
|
-
if (protocol.hash !== contracts.
|
|
228
|
+
if (protocol.hash !== contracts[origin].protocol.hash) {
|
|
95
229
|
return operationFailure("A2005", {
|
|
96
|
-
message:
|
|
230
|
+
message: origin === "client"
|
|
231
|
+
? "Generated client contract does not match the server. Regenerate the client."
|
|
232
|
+
: "Agent contract does not match the server. Rebuild the agent's tools from the current Agent Contract.",
|
|
97
233
|
});
|
|
98
234
|
}
|
|
99
235
|
return undefined;
|
|
100
236
|
}
|
|
101
|
-
export function validateOperationRequest(contract, request, options) {
|
|
237
|
+
export function validateOperationRequest(contract, request, options, write = "copy") {
|
|
102
238
|
const validation = validateOperationArguments(contract, request, options);
|
|
103
239
|
if (!validation.ok) {
|
|
104
240
|
return { ok: false, response: mapValidationOutcome(validation.issues) };
|
|
105
241
|
}
|
|
106
|
-
const scalarNormalization = normalizeOperationScalarValues(contract, { ...request, arguments: validation.arguments }, request.
|
|
242
|
+
const scalarNormalization = normalizeOperationScalarValues(contract, { ...request, arguments: validation.arguments }, request.origin, options, write);
|
|
107
243
|
return scalarNormalization.ok
|
|
108
244
|
? { ok: true, arguments: scalarNormalization.arguments }
|
|
109
245
|
: {
|
|
@@ -114,76 +250,280 @@ export function validateOperationRequest(contract, request, options) {
|
|
|
114
250
|
function rejected(response) {
|
|
115
251
|
return { ok: false, response };
|
|
116
252
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
253
|
+
const FIELD_PIPES = "Field pipes";
|
|
254
|
+
const STEP_PIPES = "Pipes";
|
|
255
|
+
export const EVERY_FIELD = () => true;
|
|
256
|
+
function filtersOf(levels) {
|
|
257
|
+
return levels.flatMap((level) => level.filters);
|
|
258
|
+
}
|
|
259
|
+
const SINGLE_CALL = { select: EVERY_FIELD };
|
|
260
|
+
export async function admitOperation(dependencies, request, contract, args, argumentsPath, report, scope, admission = SINGLE_CALL) {
|
|
261
|
+
const contexts = dependencies.contexts;
|
|
262
|
+
const tree = activeScopeConfig(dependencies.config, request).pipelines;
|
|
263
|
+
const levels = operationLevels(tree, request);
|
|
264
|
+
const planned = dependencies.fieldStages[request.origin];
|
|
265
|
+
const guarded = planned.guarded(request.resource);
|
|
266
|
+
const contracts = { core: dependencies.contracts.core, active: contract };
|
|
267
|
+
let current = deepFreeze(args);
|
|
268
|
+
const context = () => contexts.operation(scope, operationFacts(contract, request, current));
|
|
269
|
+
const admit = async () => {
|
|
270
|
+
for (const level of levels) {
|
|
271
|
+
for (const guard of level.guards) {
|
|
272
|
+
if ((await guard(context())) === false) {
|
|
273
|
+
return { ok: false, response: forbidden() };
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (guarded.length > 0 &&
|
|
278
|
+
!(await guardSentFields(fieldStagesOf(tree, request.resource), guarded, writeRecordPathsOf(request.family, current), current, context))) {
|
|
279
|
+
return { ok: false, response: forbidden() };
|
|
280
|
+
}
|
|
281
|
+
for (const target of planned.nestedGuards
|
|
282
|
+
? nestedWriteTargetsOf(contract, dependencies.recordWrites.references, request, current)
|
|
283
|
+
: []) {
|
|
284
|
+
const told = () => contexts.operation(scope, nestedFacts(contract, request, target, valueAt(current, target.path)));
|
|
285
|
+
for (const level of nestedTargetLevels(tree, target.resource, target.family)) {
|
|
286
|
+
for (const guard of level.guards) {
|
|
287
|
+
if ((await guard(told())) === false) {
|
|
288
|
+
return { ok: false, response: forbidden() };
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const targetGuarded = planned.guarded(target.resource);
|
|
293
|
+
if (targetGuarded.length > 0 &&
|
|
294
|
+
!(await guardSentFields(fieldStagesOf(tree, target.resource), targetGuarded, target.records.map((site) => site.path), current, told))) {
|
|
295
|
+
return { ok: false, response: forbidden() };
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
let piped = false;
|
|
299
|
+
let pipeIndex = 0;
|
|
300
|
+
for (const level of levels) {
|
|
301
|
+
for (const pipe of level.pipes) {
|
|
302
|
+
const returned = await pipe(current, context());
|
|
303
|
+
if (returned !== undefined && returned !== current) {
|
|
304
|
+
const refused = refusePipeOutput(contracts, request, returned, pipe, pipeIndex, admission.validation);
|
|
305
|
+
if (refused !== undefined) {
|
|
306
|
+
report(refused.error, "A3004");
|
|
307
|
+
return { ok: false, response: refused.response };
|
|
308
|
+
}
|
|
309
|
+
current = deepFreeze(returned);
|
|
310
|
+
piped = true;
|
|
311
|
+
}
|
|
312
|
+
pipeIndex += 1;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
const fields = await runFieldInputStages(dependencies, request, contract, current, argumentsPath, report, admission);
|
|
316
|
+
if (!fields.ok) {
|
|
317
|
+
return fields;
|
|
318
|
+
}
|
|
319
|
+
return {
|
|
320
|
+
ok: true,
|
|
321
|
+
args: deepFreeze(fields.args),
|
|
322
|
+
piped: piped || fields.piped,
|
|
323
|
+
};
|
|
324
|
+
};
|
|
122
325
|
try {
|
|
123
|
-
return await
|
|
326
|
+
return await admit();
|
|
124
327
|
}
|
|
125
328
|
catch (error) {
|
|
126
|
-
return
|
|
329
|
+
return {
|
|
330
|
+
ok: false,
|
|
331
|
+
response: await resolveOperationFailure(error, filtersOf(levels), context(), new AdapterBoundary(), report, { path: argumentsPath, arguments: current }),
|
|
332
|
+
};
|
|
127
333
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
334
|
+
}
|
|
335
|
+
async function runFieldInputStages(dependencies, request, contract, args, argumentsPath, report, admission) {
|
|
336
|
+
const tree = activeScopeConfig(dependencies.config, request).pipelines;
|
|
337
|
+
const planned = dependencies.fieldStages[request.origin];
|
|
338
|
+
const pipes = planned.anyPipes;
|
|
339
|
+
if (!pipes && !hasFieldValidators(contract)) {
|
|
340
|
+
return { ok: true, args, piped: false };
|
|
341
|
+
}
|
|
342
|
+
let current = args;
|
|
343
|
+
let changed = false;
|
|
344
|
+
if (pipes) {
|
|
345
|
+
const pipedFields = planned.piped(request.resource);
|
|
346
|
+
let piped = pipedFields.length === 0
|
|
347
|
+
? { args: current, changed: false }
|
|
348
|
+
: await pipeSentFields(fieldStagesOf(tree, request.resource), pipedFields, writeRecordPathsOf(request.family, current), current, admission.select);
|
|
349
|
+
changed = piped.changed;
|
|
350
|
+
for (const target of nestedWriteTargetsOf(contract, dependencies.recordWrites.references, request, piped.args)) {
|
|
351
|
+
const targetPiped = planned.piped(target.resource);
|
|
352
|
+
if (targetPiped.length === 0) {
|
|
353
|
+
continue;
|
|
133
354
|
}
|
|
355
|
+
piped = await pipeSentFields(fieldStagesOf(tree, target.resource), targetPiped, target.records.map((site) => site.path), piped.args, admission.select);
|
|
356
|
+
changed ||= piped.changed;
|
|
134
357
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
358
|
+
current = piped.args;
|
|
359
|
+
if (changed) {
|
|
360
|
+
const refused = refuseStageOutput({ core: dependencies.contracts.core, active: contract }, request, current, FIELD_PIPES, admission.validation);
|
|
361
|
+
if (refused !== undefined) {
|
|
362
|
+
report(refused.error, "A3004");
|
|
363
|
+
return { ok: false, response: refused.response };
|
|
139
364
|
}
|
|
140
|
-
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const broken = fieldValidatorIssues(contract, dependencies.recordWrites.references, request, current, argumentsPath, admission.select);
|
|
368
|
+
if (broken.length > 0) {
|
|
369
|
+
return { ok: false, response: mapValidationOutcome(broken) };
|
|
370
|
+
}
|
|
371
|
+
return { ok: true, args: current, piped: changed };
|
|
372
|
+
}
|
|
373
|
+
export async function prepareStep(dependencies, request, contract, args, argumentsPath, report, executor, changes, outer) {
|
|
374
|
+
let current = deepFreeze(args);
|
|
375
|
+
const scope = {
|
|
376
|
+
requestId: request.requestId,
|
|
377
|
+
transaction: executor,
|
|
378
|
+
state: request.state,
|
|
379
|
+
};
|
|
380
|
+
try {
|
|
381
|
+
const resolved = await runFieldInputStages(dependencies, request, contract, current, argumentsPath, report, { select: changes.written });
|
|
382
|
+
if (!resolved.ok) {
|
|
383
|
+
return resolved;
|
|
384
|
+
}
|
|
385
|
+
current = resolved.args;
|
|
386
|
+
const subject = changes.transactionPiped
|
|
387
|
+
? TRANSACTION_PIPES
|
|
388
|
+
: changes.pipedAroundReferences
|
|
389
|
+
? STEP_PIPES
|
|
390
|
+
: undefined;
|
|
391
|
+
if (subject !== undefined) {
|
|
392
|
+
const refused = refuseStageOutput({ core: dependencies.contracts.core, active: contract }, request, current, subject);
|
|
141
393
|
if (refused !== undefined) {
|
|
142
394
|
report(refused.error, "A3004");
|
|
143
|
-
return refused.response;
|
|
395
|
+
return { ok: false, response: refused.response };
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
if (changes.transactionPiped) {
|
|
399
|
+
const broken = fieldValidatorIssues(contract, dependencies.recordWrites.references, request, current, argumentsPath, EVERY_FIELD);
|
|
400
|
+
if (broken.length > 0) {
|
|
401
|
+
return { ok: false, response: mapValidationOutcome(broken) };
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return { ok: true, args: deepFreeze(current), piped: resolved.piped };
|
|
405
|
+
}
|
|
406
|
+
catch (error) {
|
|
407
|
+
return {
|
|
408
|
+
ok: false,
|
|
409
|
+
response: await resolveOperationFailure(error, filtersOf(operationLevels(activeScopeConfig(dependencies.config, request).pipelines, request)), dependencies.contexts.operation(scope, operationFacts(contract, request, current)), new AdapterBoundary(), report, { path: argumentsPath, arguments: current }, outer),
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
async function executeForcedOperation(dependencies, adapter, request, contract, args, report) {
|
|
414
|
+
const plan = [
|
|
415
|
+
{
|
|
416
|
+
resource: request.resource,
|
|
417
|
+
family: request.family,
|
|
418
|
+
variant: request.variant,
|
|
419
|
+
args,
|
|
420
|
+
},
|
|
421
|
+
];
|
|
422
|
+
const settled = await settleTransaction({
|
|
423
|
+
adapter,
|
|
424
|
+
levels: transactionLevelsOf(activeScopeConfig(dependencies.config, request).pipelines, request.resource),
|
|
425
|
+
plan,
|
|
426
|
+
contextOf: (current, executor) => dependencies.contexts.transaction({
|
|
427
|
+
requestId: request.requestId,
|
|
428
|
+
transaction: executor,
|
|
429
|
+
state: request.state,
|
|
430
|
+
}, transactionFacts(contract, request, current)),
|
|
431
|
+
failureView: { path: OPERATION_ARGUMENTS_PATH, arguments: args },
|
|
432
|
+
report,
|
|
433
|
+
runStep: async (_index, step, piped, executor, _results, outer) => {
|
|
434
|
+
let stepArguments = step.args;
|
|
435
|
+
if (piped) {
|
|
436
|
+
const prepared = await prepareStep(dependencies, request, contract, stepArguments, OPERATION_ARGUMENTS_PATH, report, executor, {
|
|
437
|
+
written: () => false,
|
|
438
|
+
transactionPiped: true,
|
|
439
|
+
pipedAroundReferences: false,
|
|
440
|
+
}, outer);
|
|
441
|
+
if (!prepared.ok) {
|
|
442
|
+
return prepared.response;
|
|
443
|
+
}
|
|
444
|
+
stepArguments = prepared.args;
|
|
144
445
|
}
|
|
446
|
+
return executeAdmittedOperation(dependencies, request, contract, stepArguments, OPERATION_ARGUMENTS_PATH, { kind: "transaction", executor, outer }, report);
|
|
447
|
+
},
|
|
448
|
+
});
|
|
449
|
+
switch (settled.kind) {
|
|
450
|
+
case "committed":
|
|
451
|
+
return settled.responses[0] ?? internalFailure();
|
|
452
|
+
case "rolled-back":
|
|
453
|
+
return settled.response;
|
|
454
|
+
case "broken":
|
|
455
|
+
report(settled.error, "A3002");
|
|
456
|
+
return transactionInfrastructureFailure();
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
export async function executeAdmittedOperation(dependencies, request, contract, admittedArguments, argumentsPath, binding, report) {
|
|
460
|
+
const { executor } = binding;
|
|
461
|
+
const scope = scopeOf(request, binding);
|
|
462
|
+
const contexts = dependencies.contexts;
|
|
463
|
+
const scopeConfig = activeScopeConfig(dependencies.config, request);
|
|
464
|
+
const levels = operationLevels(scopeConfig.pipelines, request);
|
|
465
|
+
const adapterBoundary = new AdapterBoundary();
|
|
466
|
+
const contracts = { core: dependencies.contracts.core, active: contract };
|
|
467
|
+
let args = deepFreeze(admittedArguments);
|
|
468
|
+
let told;
|
|
469
|
+
const view = () => {
|
|
470
|
+
if (told === undefined || told.of !== args) {
|
|
471
|
+
told = { of: args, view: frozenCopy(args) };
|
|
145
472
|
}
|
|
146
|
-
|
|
147
|
-
|
|
473
|
+
return told.view;
|
|
474
|
+
};
|
|
475
|
+
const context = () => contexts.operation(scope, operationFacts(contract, request, view()));
|
|
476
|
+
const computeContext = () => contexts.compute(scope, operationFacts(contract, request, view()));
|
|
477
|
+
const reuse = { refusal: undefined };
|
|
478
|
+
const refusedReuse = (refusal) => {
|
|
479
|
+
report(refusal, "A3000");
|
|
480
|
+
return internalFailure();
|
|
481
|
+
};
|
|
482
|
+
let response;
|
|
483
|
+
try {
|
|
484
|
+
response = await runLifecycle();
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
if (reuse.refusal !== undefined) {
|
|
488
|
+
return refusedReuse(reuse.refusal);
|
|
489
|
+
}
|
|
490
|
+
return resolveOperationFailure(error, filtersOf(levels), context(), adapterBoundary, report, { path: argumentsPath, arguments: args }, binding.kind === "transaction" ? binding.outer : undefined);
|
|
491
|
+
}
|
|
492
|
+
return reuse.refusal === undefined ? response : refusedReuse(reuse.refusal);
|
|
493
|
+
async function runLifecycle() {
|
|
494
|
+
let computed = await applyWriteCompute(contracts, scopeConfig.compute, request, args, computeContext);
|
|
495
|
+
computed = await applyNestedWriteCompute(contracts, scopeConfig.compute, computed, nestedWriteTargetsOf(contract, dependencies.recordWrites.references, request, computed), (target, payload) => contexts.compute(scope, nestedFacts(contract, request, target, payload)));
|
|
496
|
+
const missing = createRequirementIssues(contract, dependencies.recordWrites, request, computed, argumentsPath);
|
|
148
497
|
if (missing.length > 0) {
|
|
149
498
|
return mapValidationOutcome(missing);
|
|
150
499
|
}
|
|
151
|
-
|
|
152
|
-
await hook(pipelineContext(contract, request, args));
|
|
153
|
-
}
|
|
500
|
+
args = deepFreeze(computed);
|
|
154
501
|
let readMaterialized = false;
|
|
155
502
|
let executedReadPlan;
|
|
156
503
|
const materialize = async (data, plan) => {
|
|
157
504
|
readMaterialized = true;
|
|
158
505
|
executedReadPlan = plan;
|
|
159
|
-
return materializeReadOperation(contract, scopeConfig.
|
|
506
|
+
return materializeReadOperation(contract, scopeConfig.compute, request, plan, data, computeContext);
|
|
160
507
|
};
|
|
161
|
-
|
|
162
|
-
const readPlan = planReadOperation(dependencies.contracts.core, contract, scopeConfig.
|
|
163
|
-
const adapterArguments = await stripVirtualMutationInput(
|
|
508
|
+
const invoke = async () => {
|
|
509
|
+
const readPlan = planReadOperation(dependencies.contracts.core, dependencies.config.adapter.model, contract, scopeConfig.compute, request, args);
|
|
510
|
+
const adapterArguments = await stripVirtualMutationInput(contracts, request, readPlan.arguments);
|
|
164
511
|
const identity = request;
|
|
165
512
|
const adapterData = await adapterBoundary.execute(() => executor.execute({
|
|
166
513
|
...identity,
|
|
167
514
|
resource: request.resource,
|
|
168
515
|
arguments: adapterArguments,
|
|
169
516
|
}));
|
|
517
|
+
const miss = uniqueMissFailure(request, adapterData);
|
|
518
|
+
if (miss !== undefined) {
|
|
519
|
+
throw thrownFailure(miss);
|
|
520
|
+
}
|
|
170
521
|
return materialize(adapterData, readPlan);
|
|
171
522
|
};
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
const next = invoke;
|
|
178
|
-
invoke = () => interceptor(pipelineContext(contract, request, args), next);
|
|
179
|
-
}
|
|
180
|
-
let data = await invoke();
|
|
181
|
-
if (!readMaterialized) {
|
|
182
|
-
data = await materialize(data, planReadOperation(dependencies.contracts.core, contract, scopeConfig.behaviors, request, args));
|
|
183
|
-
}
|
|
184
|
-
for (const hook of pipelines.hooks.after) {
|
|
185
|
-
await hook(data, pipelineContext(contract, request, args));
|
|
186
|
-
}
|
|
523
|
+
const materialized = async (data) => readMaterialized
|
|
524
|
+
? data
|
|
525
|
+
: materialize(data, planReadOperation(dependencies.contracts.core, dependencies.config.adapter.model, contract, scopeConfig.compute, request, args));
|
|
526
|
+
const data = await materialized(await runLevelLifecycle(levels, context, invoke, materialized, reuse, () => new AvInterceptorNextError()));
|
|
187
527
|
if (!outputAccepted(contract, request, executedReadPlan?.projection, data, report)) {
|
|
188
528
|
return internalFailure();
|
|
189
529
|
}
|
|
@@ -1,11 +1,22 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import type { AvOperationIdentity } from "../operations/operation-identity.js";
|
|
2
|
+
import type { AvValidationIssue } from "../operations/validation-code.js";
|
|
3
|
+
import type { AvOperationFailureResponse, AvOperationResponse } from "./operation-response.js";
|
|
4
|
+
/**
|
|
5
|
+
* The failure a strict unique operation's miss raises inside the pipeline, or
|
|
6
|
+
* `undefined` when `data` is a row, or the variant answers a miss with `null`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function uniqueMissFailure(operation: AvOperationIdentity, data: unknown): AvOperationFailureResponse | undefined;
|
|
4
9
|
/**
|
|
5
10
|
* Maps one validated operation result to its stable outcome envelope. The
|
|
6
11
|
* result must already have passed output validation, so `null` can only
|
|
7
12
|
* reach a variant whose cardinality admits it.
|
|
8
13
|
*/
|
|
9
|
-
export declare function mapOperationOutcome(operation:
|
|
14
|
+
export declare function mapOperationOutcome(operation: AvOperationIdentity, data: unknown): AvOperationResponse;
|
|
15
|
+
/** The A-codes a set of Framework Validation Layer issues can roll up to. */
|
|
16
|
+
export type ValidationOutcomeCode = "A2001" | "A2002" | "A2004" | "A2007" | "A2009";
|
|
17
|
+
/** The framework's top-level `cause.message` for each validation outcome code. */
|
|
18
|
+
export declare const VALIDATION_OUTCOME_MESSAGES: {
|
|
19
|
+
readonly [K in ValidationOutcomeCode]: string;
|
|
20
|
+
};
|
|
10
21
|
/** Maps framework validation issues to their stable failure envelope. */
|
|
11
|
-
export declare function mapValidationOutcome(issues: readonly
|
|
22
|
+
export declare function mapValidationOutcome(issues: readonly AvValidationIssue[]): AvOperationFailureResponse;
|