@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.
Files changed (255) hide show
  1. package/CHANGELOG.md +1478 -0
  2. package/README.md +275 -11
  3. package/dist/adapters/adapter-discovery-diagnostic.d.ts +4 -4
  4. package/dist/adapters/adapter-field.d.ts +11 -11
  5. package/dist/adapters/adapter-identifier.d.ts +6 -6
  6. package/dist/adapters/adapter-model.d.ts +17 -9
  7. package/dist/adapters/adapter-operation-executor.interface.d.ts +4 -4
  8. package/dist/adapters/adapter-operation.d.ts +3 -3
  9. package/dist/adapters/adapter-resource.d.ts +18 -9
  10. package/dist/adapters/adapter-sql-statement.d.ts +19 -0
  11. package/dist/adapters/adapter-transaction-executor.interface.d.ts +19 -0
  12. package/dist/adapters/adapter.interface.d.ts +49 -25
  13. package/dist/avz/avz-check.factory.d.ts +83 -0
  14. package/dist/avz/avz-check.factory.js +116 -0
  15. package/dist/avz/avz-check.registry.d.ts +35 -0
  16. package/dist/avz/avz-check.registry.js +9 -0
  17. package/dist/avz/avz.d.ts +203 -0
  18. package/dist/avz/avz.js +354 -0
  19. package/dist/avz/index.d.ts +7 -0
  20. package/dist/avz/index.js +1 -0
  21. package/dist/avz/json-shape.registry.d.ts +22 -0
  22. package/dist/avz/json-shape.registry.js +16 -0
  23. package/dist/avz/zod-issue.translator.d.ts +57 -0
  24. package/dist/avz/zod-issue.translator.js +149 -0
  25. package/dist/compiler/contract-compiler-diagnostic.d.ts +37 -5
  26. package/dist/compiler/contract.compiler.d.ts +18 -18
  27. package/dist/compiler/contract.compiler.js +595 -421
  28. package/dist/compiler/create-requirements.projector.d.ts +49 -0
  29. package/dist/compiler/create-requirements.projector.js +423 -0
  30. package/dist/compiler/field-validator.compiler.d.ts +47 -0
  31. package/dist/compiler/field-validator.compiler.js +238 -0
  32. package/dist/config/any-framework-config.d.ts +19 -12
  33. package/dist/config/config-diagnostic.d.ts +11 -4
  34. package/dist/config/config-layer.d.ts +15 -6
  35. package/dist/config/config.resolver.d.ts +75 -29
  36. package/dist/config/config.resolver.js +109 -44
  37. package/dist/config/config.validator.d.ts +7 -7
  38. package/dist/config/config.validator.js +586 -71
  39. package/dist/config/define-resource.d.ts +57 -0
  40. package/dist/config/define-resource.js +14 -0
  41. package/dist/config/effective-fields.d.ts +19 -23
  42. package/dist/config/entrypoint.normalizer.d.ts +1 -1
  43. package/dist/config/exact-framework-config.d.ts +280 -0
  44. package/dist/config/field-compute.resolver.d.ts +19 -0
  45. package/dist/config/field-compute.resolver.js +115 -0
  46. package/dist/config/field-pipeline-config.d.ts +47 -0
  47. package/dist/config/forced-operation.validator.d.ts +10 -0
  48. package/dist/config/forced-operation.validator.js +66 -0
  49. package/dist/config/framework-config.d.ts +111 -37
  50. package/dist/config/framework-exemptions-config.d.ts +91 -0
  51. package/dist/config/framework-exemptions-config.js +1 -0
  52. package/dist/config/framework-field-definition.d.ts +78 -0
  53. package/dist/config/framework-field-definition.js +28 -0
  54. package/dist/config/framework-resources-config.d.ts +116 -0
  55. package/dist/config/framework-resources-config.js +1 -0
  56. package/dist/config/pipeline-config.d.ts +56 -20
  57. package/dist/config/pipeline-tree.resolver.d.ts +79 -0
  58. package/dist/config/pipeline-tree.resolver.js +220 -0
  59. package/dist/config/stage-type.eraser.d.ts +65 -0
  60. package/dist/config/stage-type.eraser.js +1 -0
  61. package/dist/contracts/capability.d.ts +11 -11
  62. package/dist/contracts/client-contract-structure.validator.d.ts +344 -29
  63. package/dist/contracts/client-contract-structure.validator.js +248 -7
  64. package/dist/contracts/contract-canonicalizer.d.ts +19 -3
  65. package/dist/contracts/contract-canonicalizer.js +172 -27
  66. package/dist/contracts/contract-hash.d.ts +12 -7
  67. package/dist/contracts/contract-hash.js +3 -2
  68. package/dist/contracts/contract-limits.d.ts +4 -1
  69. package/dist/contracts/contract-limits.js +1 -0
  70. package/dist/contracts/contract-lookup.d.ts +5 -5
  71. package/dist/contracts/contract-protocol.d.ts +4 -4
  72. package/dist/contracts/contract.d.ts +31 -16
  73. package/dist/contracts/create-requirements.d.ts +35 -0
  74. package/dist/contracts/create-requirements.js +1 -0
  75. package/dist/contracts/enum-definition.d.ts +1 -1
  76. package/dist/contracts/field-check.d.ts +101 -0
  77. package/dist/contracts/field-check.js +1 -0
  78. package/dist/contracts/field.d.ts +61 -41
  79. package/dist/contracts/identifier.d.ts +4 -4
  80. package/dist/contracts/json-shape.d.ts +76 -0
  81. package/dist/contracts/json-shape.js +1 -0
  82. package/dist/contracts/lifecycle-trait.d.ts +2 -2
  83. package/dist/contracts/reference-write-limit.d.ts +7 -0
  84. package/dist/contracts/reference-write-limit.js +1 -0
  85. package/dist/contracts/resource-operations.d.ts +28 -28
  86. package/dist/contracts/resource.d.ts +15 -9
  87. package/dist/contracts/scalar-value-type.d.ts +25 -14
  88. package/dist/contracts/scalar.d.ts +3 -3
  89. package/dist/contracts/transaction-capability.d.ts +1 -1
  90. package/dist/contracts/wire-scalar-format.d.ts +4 -4
  91. package/dist/framework/contract-view.d.ts +234 -63
  92. package/dist/framework/framework-construction.error.d.ts +10 -10
  93. package/dist/framework/framework-construction.error.js +2 -2
  94. package/dist/framework/framework.d.ts +50 -24
  95. package/dist/framework/framework.factory.d.ts +8 -6
  96. package/dist/framework/framework.factory.js +95 -32
  97. package/dist/framework/operation-facade.d.ts +123 -52
  98. package/dist/framework/operation-facade.js +9 -1
  99. package/dist/index.d.ts +55 -82
  100. package/dist/index.js +6 -26
  101. package/dist/internal.d.ts +40 -0
  102. package/dist/internal.js +18 -0
  103. package/dist/operations/operation-arguments.d.ts +316 -201
  104. package/dist/operations/operation-call.d.ts +27 -28
  105. package/dist/operations/operation-identity.d.ts +12 -10
  106. package/dist/operations/operation-identity.js +3 -0
  107. package/dist/operations/operation-result.d.ts +21 -21
  108. package/dist/operations/operation-validator-core.d.ts +6 -6
  109. package/dist/operations/operation-validator-core.js +41 -12
  110. package/dist/operations/operation-validator.d.ts +24 -9
  111. package/dist/operations/operation-validator.js +26 -10
  112. package/dist/operations/projection-scope.resolver.d.ts +7 -7
  113. package/dist/operations/structural-limits.walker.d.ts +19 -0
  114. package/dist/operations/structural-limits.walker.js +489 -0
  115. package/dist/operations/validation-code.d.ts +11 -6
  116. package/dist/operations/validation-code.js +4 -0
  117. package/dist/operations/write-scope.resolver.d.ts +6 -6
  118. package/dist/protocol/absent-route.responder.d.ts +13 -11
  119. package/dist/protocol/absent-route.responder.js +42 -16
  120. package/dist/protocol/contract-document.responder.d.ts +3 -3
  121. package/dist/protocol/contract-document.responder.js +2 -2
  122. package/dist/protocol/http-request.decoder.d.ts +23 -13
  123. package/dist/protocol/http-request.decoder.js +19 -11
  124. package/dist/protocol/http-request.reader.d.ts +3 -3
  125. package/dist/protocol/http-response.encoder.d.ts +4 -4
  126. package/dist/protocol/http-response.encoder.js +94 -55
  127. package/dist/protocol/http-status.table.d.ts +2 -2
  128. package/dist/protocol/operation-response.guard.d.ts +2 -2
  129. package/dist/protocol/protocol-surface.d.ts +4 -4
  130. package/dist/protocol/protocol.binder.d.ts +52 -27
  131. package/dist/protocol/protocol.binder.js +14 -9
  132. package/dist/protocol/protocol.handler.d.ts +28 -15
  133. package/dist/protocol/protocol.handler.js +55 -10
  134. package/dist/protocol/unmounted-route.error.d.ts +19 -0
  135. package/dist/protocol/unmounted-route.error.js +10 -0
  136. package/dist/runtime/caller-data.copier.d.ts +59 -0
  137. package/dist/runtime/caller-data.copier.js +470 -0
  138. package/dist/runtime/caller-data.door.d.ts +56 -0
  139. package/dist/runtime/caller-data.door.js +67 -0
  140. package/dist/runtime/computed-read-runtime.d.ts +7 -6
  141. package/dist/runtime/computed-read-runtime.js +61 -55
  142. package/dist/runtime/computed-value.error.d.ts +13 -0
  143. package/dist/runtime/computed-value.error.js +9 -0
  144. package/dist/runtime/context-executor.runtime.d.ts +59 -0
  145. package/dist/runtime/context-executor.runtime.js +275 -0
  146. package/dist/runtime/create-requirement.d.ts +22 -57
  147. package/dist/runtime/create-requirement.js +140 -37
  148. package/dist/runtime/decimal.d.ts +2 -2
  149. package/dist/runtime/decimal.js +1 -1
  150. package/dist/runtime/diagnostics-reporter.d.ts +64 -22
  151. package/dist/runtime/diagnostics-reporter.js +35 -4
  152. package/dist/runtime/error-boundary.d.ts +73 -8
  153. package/dist/runtime/error-boundary.js +104 -48
  154. package/dist/runtime/execution-options.d.ts +10 -2
  155. package/dist/runtime/field-check.evaluator.d.ts +29 -0
  156. package/dist/runtime/field-check.evaluator.js +521 -0
  157. package/dist/runtime/field-compute.d.ts +64 -0
  158. package/dist/runtime/field-compute.js +1 -0
  159. package/dist/runtime/field-stage.plan.d.ts +15 -0
  160. package/dist/runtime/field-stage.plan.js +27 -0
  161. package/dist/runtime/field-stage.runtime.d.ts +35 -0
  162. package/dist/runtime/field-stage.runtime.js +143 -0
  163. package/dist/runtime/field-validator.runtime.d.ts +11 -0
  164. package/dist/runtime/field-validator.runtime.js +87 -0
  165. package/dist/runtime/framework-error-class.table.d.ts +33 -0
  166. package/dist/runtime/framework-error-class.table.js +25 -0
  167. package/dist/runtime/framework-error.d.ts +79 -7
  168. package/dist/runtime/framework-error.factory.d.ts +4 -0
  169. package/dist/runtime/framework-error.factory.js +15 -0
  170. package/dist/runtime/framework-error.js +23 -2
  171. package/dist/runtime/interceptor-next.error.d.ts +5 -0
  172. package/dist/runtime/interceptor-next.error.js +6 -0
  173. package/dist/runtime/json-value.d.ts +3 -3
  174. package/dist/runtime/level-lifecycle.runtime.d.ts +25 -0
  175. package/dist/runtime/level-lifecycle.runtime.js +42 -0
  176. package/dist/runtime/misuse-reporter.d.ts +32 -0
  177. package/dist/runtime/misuse-reporter.js +19 -0
  178. package/dist/runtime/mutation-planner.d.ts +19 -10
  179. package/dist/runtime/mutation-planner.js +62 -36
  180. package/dist/runtime/nested-write.walker.d.ts +32 -0
  181. package/dist/runtime/nested-write.walker.js +73 -0
  182. package/dist/runtime/operation-request.d.ts +35 -15
  183. package/dist/runtime/operation-response.d.ts +17 -17
  184. package/dist/runtime/operation-runtime.d.ts +125 -30
  185. package/dist/runtime/operation-runtime.js +423 -83
  186. package/dist/runtime/outcome-mapper.d.ts +16 -5
  187. package/dist/runtime/outcome-mapper.js +35 -8
  188. package/dist/runtime/output-validator.d.ts +16 -6
  189. package/dist/runtime/output-validator.js +12 -1
  190. package/dist/runtime/owned-execution.registry.d.ts +13 -0
  191. package/dist/runtime/owned-execution.registry.js +7 -0
  192. package/dist/runtime/pipe-output.validator.d.ts +33 -18
  193. package/dist/runtime/pipe-output.validator.js +12 -12
  194. package/dist/runtime/pipeline.d.ts +202 -28
  195. package/dist/runtime/readonly-value.d.ts +32 -0
  196. package/dist/runtime/readonly-value.js +141 -0
  197. package/dist/runtime/referential-action.d.ts +7 -0
  198. package/dist/runtime/request-envelope.validator.d.ts +5 -0
  199. package/dist/runtime/request-envelope.validator.js +123 -0
  200. package/dist/runtime/request-id.d.ts +1 -1
  201. package/dist/runtime/request-state.d.ts +14 -0
  202. package/dist/runtime/request-state.js +1 -0
  203. package/dist/runtime/request-state.resolver.d.ts +12 -0
  204. package/dist/runtime/request-state.resolver.js +20 -0
  205. package/dist/runtime/scalar-runtime.d.ts +56 -13
  206. package/dist/runtime/scalar-runtime.js +167 -86
  207. package/dist/transactions/deferred-operation.d.ts +35 -20
  208. package/dist/transactions/operation-arguments-encoder.d.ts +3 -3
  209. package/dist/transactions/operation-arguments-encoder.js +2 -2
  210. package/dist/transactions/sql-statement.d.ts +77 -0
  211. package/dist/transactions/sql-statement.js +47 -0
  212. package/dist/transactions/sql-statement.validator.d.ts +44 -0
  213. package/dist/transactions/sql-statement.validator.js +134 -0
  214. package/dist/transactions/transaction-envelope.d.ts +4 -4
  215. package/dist/transactions/transaction-integrity-error.d.ts +6 -6
  216. package/dist/transactions/transaction-integrity-error.js +5 -2
  217. package/dist/transactions/transaction-plan-assembler.d.ts +23 -9
  218. package/dist/transactions/transaction-plan-assembler.js +195 -82
  219. package/dist/transactions/transaction-plan-validator.d.ts +53 -21
  220. package/dist/transactions/transaction-plan-validator.js +246 -163
  221. package/dist/transactions/transaction-reference-collector.d.ts +30 -0
  222. package/dist/transactions/transaction-reference-collector.js +204 -0
  223. package/dist/transactions/transaction-reference-resolver.d.ts +19 -2
  224. package/dist/transactions/transaction-reference-resolver.js +27 -10
  225. package/dist/transactions/transaction-reference-validator.d.ts +34 -4
  226. package/dist/transactions/transaction-reference-validator.js +82 -43
  227. package/dist/transactions/transaction-reference.d.ts +30 -58
  228. package/dist/transactions/transaction-request.d.ts +20 -7
  229. package/dist/transactions/transaction-response.d.ts +12 -7
  230. package/dist/transactions/transaction-response.js +24 -1
  231. package/dist/transactions/transaction-runtime.d.ts +11 -8
  232. package/dist/transactions/transaction-runtime.js +167 -50
  233. package/dist/transactions/transaction-settlement.runtime.d.ts +51 -0
  234. package/dist/transactions/transaction-settlement.runtime.js +120 -0
  235. package/dist/transactions/transaction-slot-path-error.d.ts +4 -4
  236. package/dist/transactions/transaction-slot-path-error.js +2 -2
  237. package/dist/transactions/transaction-slot-writer.js +2 -2
  238. package/dist/transactions/transaction-stage.runtime.d.ts +81 -0
  239. package/dist/transactions/transaction-stage.runtime.js +123 -0
  240. package/package.json +18 -3
  241. package/src/runtime/field-check.evaluator.ts +720 -0
  242. package/dist/config/define-fields.d.ts +0 -35
  243. package/dist/config/define-fields.js +0 -3
  244. package/dist/config/framework-behaviors-config.d.ts +0 -30
  245. package/dist/config/framework-fields-config.d.ts +0 -36
  246. package/dist/config/framework-restrictions-config.d.ts +0 -142
  247. package/dist/operations/operation-boolean-nodes.d.ts +0 -11
  248. package/dist/operations/operation-boolean-nodes.js +0 -283
  249. package/dist/operations/operation-nesting.d.ts +0 -8
  250. package/dist/operations/operation-nesting.js +0 -307
  251. package/dist/runtime/field-behavior.d.ts +0 -48
  252. /package/dist/{config/framework-behaviors-config.js → adapters/adapter-sql-statement.js} +0 -0
  253. /package/dist/{config/framework-fields-config.js → adapters/adapter-transaction-executor.interface.js} +0 -0
  254. /package/dist/config/{framework-restrictions-config.js → exact-framework-config.js} +0 -0
  255. /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 { missingCreateValues, } from "./create-requirement.js";
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 { applyWriteFieldBehaviors, stripVirtualMutationInput, } from "./mutation-planner.js";
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 { normalizeOperationScalarValues } from "./scalar-runtime.js";
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.scope === "application"
14
- ? contracts.application
15
- : contracts.client;
112
+ return contracts[request.origin];
16
113
  }
17
114
  function activeScopeConfig(config, request) {
18
- return request.scope === "application" ? config.application : config.client;
115
+ return config[request.origin];
19
116
  }
20
- function pipelineContext(contract, request, args) {
117
+ function operationFacts(contract, request, args) {
21
118
  return {
22
- contract,
23
- scope: request.scope,
24
- resource: request.resource,
25
- family: request.family,
26
- variant: request.variant,
27
- args,
28
- requestId: request.requestId,
29
- ...(request.scope === "client" && request.transport !== undefined
30
- ? { transport: request.transport }
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
- return validateOperationOutput(contract, request, projection, data).ok;
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 pipelineDependencies = {
50
- contracts: dependencies.contracts,
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
- return executeValidatedOperation(pipelineDependencies, request, validated.contract, validated.arguments, OPERATION_ARGUMENTS_PATH, dependencies.adapter, report);
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
- const validation = validateOperationRequest(contract, request);
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.scope === "client"
85
- ? protocolIdentityFailure(contracts, request.protocol)
86
- : undefined;
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.client.protocol.hash) {
228
+ if (protocol.hash !== contracts[origin].protocol.hash) {
95
229
  return operationFailure("A2005", {
96
- message: "Generated client contract does not match the server. Regenerate the client.",
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.scope, options);
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
- export async function executeValidatedOperation(dependencies, request, contract, validatedArguments, argumentsPath, executor, report) {
118
- const scopeConfig = activeScopeConfig(dependencies.config, request);
119
- const pipelines = scopeConfig.pipelines;
120
- const adapterBoundary = new AdapterBoundary();
121
- let args = validatedArguments;
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 runLifecycle();
326
+ return await admit();
124
327
  }
125
328
  catch (error) {
126
- return resolveOperationFailure(error, pipelines.filters, pipelineContext(contract, request, args), adapterBoundary, report, { path: argumentsPath, arguments: args });
329
+ return {
330
+ ok: false,
331
+ response: await resolveOperationFailure(error, filtersOf(levels), context(), new AdapterBoundary(), report, { path: argumentsPath, arguments: current }),
332
+ };
127
333
  }
128
- async function runLifecycle() {
129
- for (const guard of pipelines.guards) {
130
- const allowed = await guard(pipelineContext(contract, request, args));
131
- if (allowed === false) {
132
- return forbidden();
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
- for (const [index, pipe] of pipelines.pipes.entries()) {
136
- const nextArgs = await pipe(args, pipelineContext(contract, request, args));
137
- if (nextArgs !== undefined) {
138
- args = nextArgs;
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
- const refused = refusePipeOutput({ core: dependencies.contracts.core, active: contract }, request, args, pipe, index);
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
- args = await applyWriteFieldBehaviors({ core: dependencies.contracts.core, active: contract }, scopeConfig.behaviors, request, args, () => pipelineContext(contract, request, args));
147
- const missing = missingCreateValues(contract, dependencies.createRequirements, request, args, argumentsPath);
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
- for (const hook of pipelines.hooks.before) {
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.behaviors, request, plan, data, () => pipelineContext(contract, request, args));
506
+ return materializeReadOperation(contract, scopeConfig.compute, request, plan, data, computeContext);
160
507
  };
161
- let invoke = async () => {
162
- const readPlan = planReadOperation(dependencies.contracts.core, contract, scopeConfig.behaviors, request, args);
163
- const adapterArguments = await stripVirtualMutationInput({ core: dependencies.contracts.core, active: contract }, request, readPlan.arguments);
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
- for (let index = pipelines.interceptors.length - 1; index >= 0; index -= 1) {
173
- const interceptor = pipelines.interceptors[index];
174
- if (interceptor === undefined) {
175
- continue;
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 { 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;