@aventara/core 1.0.0-rc.0 → 1.0.0-rc.2

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