@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
@@ -0,0 +1,489 @@
1
+ import { lookupField, lookupResource } from "../contracts/contract-lookup.js";
2
+ import { advertisedDirectives, holdsAt, } from "../contracts/field.js";
3
+ import { NESTED_PROJECTION_SCOPE, resolveProjectionScope, } from "./projection-scope.resolver.js";
4
+ const UNTRACKED = [];
5
+ const RELATION_FILTER_OPERATORS = ["some", "every", "none"];
6
+ const DIRECTIVE_PAYLOADS = new Map([
7
+ ["$connectOrCreate", [["create", "create"]]],
8
+ ["$update", [["data", "update"]]],
9
+ [
10
+ "$upsert",
11
+ [
12
+ ["create", "create"],
13
+ ["update", "update"],
14
+ ],
15
+ ],
16
+ ]);
17
+ const NO_PAYLOADS = [];
18
+ function isRecord(value) {
19
+ return typeof value === "object" && value !== null && !Array.isArray(value);
20
+ }
21
+ function extend(state, path, segment) {
22
+ return state.tracking ? [...path, segment] : UNTRACKED;
23
+ }
24
+ function nestingExceeded(state) {
25
+ state.nesting = {
26
+ path: ["arguments", state.rootKey],
27
+ code: "V1013",
28
+ message: `Request nesting exceeds maxNestingDepth (${state.nestingLimit}).`,
29
+ };
30
+ }
31
+ function jsonDepthExceeded(state, fieldPath) {
32
+ state.nestingAtField = true;
33
+ state.nesting = {
34
+ path: state.tracking ? fieldPath : ["arguments", state.rootKey],
35
+ code: "V1021",
36
+ message: `Json value depth exceeds maxJsonDepth (${state.jsonDepthLimit}).`,
37
+ };
38
+ }
39
+ function isJsonField(field) {
40
+ return "scalar" in field.type && field.type.scalar === "json";
41
+ }
42
+ function jsonValueExceeds(state, value) {
43
+ const deepest = new Map();
44
+ const ancestors = new Set();
45
+ const stack = [{ leave: false, value, level: 0 }];
46
+ while (stack.length > 0) {
47
+ const task = stack.pop();
48
+ if (task.leave) {
49
+ ancestors.delete(task.container);
50
+ continue;
51
+ }
52
+ const current = task.value;
53
+ if (typeof current !== "object" ||
54
+ current === null ||
55
+ ancestors.has(current)) {
56
+ continue;
57
+ }
58
+ const inner = task.level + 1;
59
+ if (inner > state.jsonDepthLimit) {
60
+ return true;
61
+ }
62
+ const seen = deepest.get(current);
63
+ if (seen !== undefined && seen >= inner) {
64
+ continue;
65
+ }
66
+ deepest.set(current, inner);
67
+ ancestors.add(current);
68
+ stack.push({ leave: true, container: current });
69
+ const entries = Array.isArray(current)
70
+ ? current
71
+ : Object.values(current);
72
+ for (const entry of entries) {
73
+ stack.push({ leave: false, value: entry, level: inner });
74
+ }
75
+ }
76
+ return false;
77
+ }
78
+ function walkJsonWrite(state, field, value, path) {
79
+ const operands = isRecord(value) && Object.keys(value).some((key) => key.startsWith("$"))
80
+ ? Object.entries(value)
81
+ .filter(([key]) => key !== "$unset" && key !== "$ref")
82
+ .map(([, operand]) => operand)
83
+ : [value];
84
+ for (const operand of operands) {
85
+ const values = field.list && Array.isArray(operand) ? operand : [operand];
86
+ for (const entry of values) {
87
+ if (jsonValueExceeds(state, entry)) {
88
+ jsonDepthExceeded(state, path);
89
+ return;
90
+ }
91
+ }
92
+ }
93
+ }
94
+ const JSON_LIST_OPERATORS = new Set(["in", "notIn", "hasEvery", "hasSome"]);
95
+ const JSON_VALUELESS_OPERATORS = new Set(["mode", "isEmpty", "path"]);
96
+ function walkJsonFilter(state, filter, depth, path) {
97
+ let level = depth;
98
+ let current = filter;
99
+ while (isRecord(current)) {
100
+ let next;
101
+ for (const operator of Object.keys(current)) {
102
+ const operand = current[operator];
103
+ if (operator === "not" && isRecord(operand)) {
104
+ next = operand;
105
+ continue;
106
+ }
107
+ if (JSON_VALUELESS_OPERATORS.has(operator)) {
108
+ continue;
109
+ }
110
+ const values = JSON_LIST_OPERATORS.has(operator) && Array.isArray(operand)
111
+ ? operand
112
+ : [operand];
113
+ for (const entry of values) {
114
+ if (jsonValueExceeds(state, entry)) {
115
+ jsonDepthExceeded(state, path);
116
+ return;
117
+ }
118
+ }
119
+ }
120
+ if (next === undefined) {
121
+ return;
122
+ }
123
+ level += 1;
124
+ if (level > state.nestingLimit) {
125
+ nestingExceeded(state);
126
+ return;
127
+ }
128
+ current = next;
129
+ }
130
+ if (jsonValueExceeds(state, current)) {
131
+ jsonDepthExceeded(state, path);
132
+ }
133
+ }
134
+ function countBooleanNode(state, path, key) {
135
+ if (state.booleanExceeded) {
136
+ return;
137
+ }
138
+ state.booleanCount += 1;
139
+ if (state.booleanCount > state.booleanLimit) {
140
+ state.booleanExceeded = true;
141
+ if (state.tracking) {
142
+ state.booleanNodes = {
143
+ path: [...path, key],
144
+ code: "V1015",
145
+ message: `Boolean/filter node count exceeds maxBooleanNodes (${state.booleanLimit}).`,
146
+ };
147
+ }
148
+ }
149
+ }
150
+ function walkWhere(state, resourceName, value, depth, path, counting) {
151
+ if (depth > state.nestingLimit) {
152
+ nestingExceeded(state);
153
+ return;
154
+ }
155
+ const resource = lookupResource(state.contract, resourceName);
156
+ if (!isRecord(value) || resource === undefined) {
157
+ return;
158
+ }
159
+ for (const key of Object.keys(value)) {
160
+ if (counting) {
161
+ countBooleanNode(state, path, key);
162
+ }
163
+ const child = value[key];
164
+ if (key === "AND" || key === "OR") {
165
+ if (Array.isArray(child)) {
166
+ for (let index = 0; index < child.length; index += 1) {
167
+ walkWhere(state, resourceName, child[index], depth + 1, state.tracking ? [...path, key, index] : UNTRACKED, counting);
168
+ if (state.nesting !== undefined) {
169
+ return;
170
+ }
171
+ }
172
+ }
173
+ continue;
174
+ }
175
+ if (key === "NOT") {
176
+ walkWhere(state, resourceName, child, depth + 1, extend(state, path, key), counting);
177
+ }
178
+ else {
179
+ const field = lookupField(resource, key);
180
+ if (field?.kind === "scalar") {
181
+ if (isJsonField(field)) {
182
+ walkJsonFilter(state, child, depth, extend(state, path, key));
183
+ }
184
+ else {
185
+ walkScalarNot(state, child, depth);
186
+ }
187
+ }
188
+ if (field?.kind !== "relation") {
189
+ if (state.nesting !== undefined) {
190
+ return;
191
+ }
192
+ continue;
193
+ }
194
+ if (field.cardinality === "one") {
195
+ walkWhere(state, field.target, child, depth + 1, extend(state, path, key), counting);
196
+ }
197
+ else if (isRecord(child)) {
198
+ for (const operator of RELATION_FILTER_OPERATORS) {
199
+ if (!(operator in child)) {
200
+ continue;
201
+ }
202
+ walkWhere(state, field.target, child[operator], depth + 1, state.tracking ? [...path, key, operator] : UNTRACKED, counting);
203
+ if (state.nesting !== undefined) {
204
+ return;
205
+ }
206
+ }
207
+ }
208
+ }
209
+ if (state.nesting !== undefined) {
210
+ return;
211
+ }
212
+ }
213
+ }
214
+ function walkScalarNot(state, filter, depth) {
215
+ let level = depth;
216
+ let current = filter;
217
+ while (isRecord(current) && Object.hasOwn(current, "not")) {
218
+ const operand = current.not;
219
+ if (!isRecord(operand)) {
220
+ return;
221
+ }
222
+ level += 1;
223
+ if (level > state.nestingLimit) {
224
+ nestingExceeded(state);
225
+ return;
226
+ }
227
+ current = operand;
228
+ }
229
+ }
230
+ function walkOrderBy(state, resourceName, value, depth) {
231
+ const resource = lookupResource(state.contract, resourceName);
232
+ if (resource === undefined) {
233
+ return;
234
+ }
235
+ const entries = Array.isArray(value) ? value : [value];
236
+ for (let index = 0; index < entries.length; index += 1) {
237
+ const entry = entries[index];
238
+ if (!isRecord(entry)) {
239
+ continue;
240
+ }
241
+ for (const fieldName of Object.keys(entry)) {
242
+ const field = lookupField(resource, fieldName);
243
+ if (field?.kind !== "relation" || field.cardinality === "many") {
244
+ continue;
245
+ }
246
+ const relationDepth = depth + 1;
247
+ if (relationDepth > state.nestingLimit) {
248
+ nestingExceeded(state);
249
+ return;
250
+ }
251
+ walkOrderBy(state, field.target, entry[fieldName], relationDepth);
252
+ if (state.nesting !== undefined) {
253
+ return;
254
+ }
255
+ }
256
+ }
257
+ }
258
+ function soleKey(record) {
259
+ const keys = Object.keys(record);
260
+ return keys.length === 1 ? keys[0] : undefined;
261
+ }
262
+ function walkProjection(state, resourceName, value, depth, path, mode, scope) {
263
+ const resource = lookupResource(state.contract, resourceName);
264
+ if (!Array.isArray(value) || resource === undefined) {
265
+ return;
266
+ }
267
+ for (let index = 0; index < value.length; index += 1) {
268
+ const entry = value[index];
269
+ const relationName = isRecord(entry) ? soleKey(entry) : undefined;
270
+ const edge = relationName === undefined
271
+ ? undefined
272
+ : lookupField(resource, relationName);
273
+ if (relationName === undefined || edge?.kind !== "relation") {
274
+ continue;
275
+ }
276
+ const relationDepth = depth + 1;
277
+ if (relationDepth > state.nestingLimit) {
278
+ nestingExceeded(state);
279
+ return;
280
+ }
281
+ const projection = entry[relationName];
282
+ if (!isRecord(projection)) {
283
+ continue;
284
+ }
285
+ const relationPath = state.tracking
286
+ ? [...path, index, relationName]
287
+ : UNTRACKED;
288
+ const counted = scope !== undefined &&
289
+ holdsAt(mode === "select"
290
+ ? edge.capabilities.select
291
+ : edge.capabilities.include, scope);
292
+ if ("where" in projection) {
293
+ walkWhere(state, edge.target, projection.where, relationDepth, extend(state, relationPath, "where"), counted && edge.capabilities.filter?.includes("nested") === true);
294
+ if (state.nesting !== undefined) {
295
+ return;
296
+ }
297
+ }
298
+ if ("orderBy" in projection) {
299
+ walkOrderBy(state, edge.target, projection.orderBy, relationDepth);
300
+ if (state.nesting !== undefined) {
301
+ return;
302
+ }
303
+ }
304
+ for (const nestedMode of ["select", "include"]) {
305
+ if (!(nestedMode in projection)) {
306
+ continue;
307
+ }
308
+ walkProjection(state, edge.target, projection[nestedMode], relationDepth, extend(state, relationPath, nestedMode), nestedMode, counted ? NESTED_PROJECTION_SCOPE : undefined);
309
+ if (state.nesting !== undefined) {
310
+ return;
311
+ }
312
+ }
313
+ }
314
+ }
315
+ function walkMutationData(state, resourceName, value, depth, path, stage, counting) {
316
+ if (depth > state.nestingLimit) {
317
+ nestingExceeded(state);
318
+ return;
319
+ }
320
+ const resource = lookupResource(state.contract, resourceName);
321
+ if (!isRecord(value) || resource === undefined) {
322
+ return;
323
+ }
324
+ for (const fieldName of Object.keys(value)) {
325
+ const edge = lookupField(resource, fieldName);
326
+ const directives = value[fieldName];
327
+ if (edge?.kind === "scalar" && isJsonField(edge)) {
328
+ walkJsonWrite(state, edge, directives, extend(state, path, fieldName));
329
+ if (state.nesting !== undefined) {
330
+ return;
331
+ }
332
+ continue;
333
+ }
334
+ if (edge?.kind !== "relation" || !isRecord(directives)) {
335
+ continue;
336
+ }
337
+ walkRelationDirectives(state, edge, directives, depth + 1, extend(state, path, fieldName), stage, counting);
338
+ if (state.nesting !== undefined) {
339
+ return;
340
+ }
341
+ }
342
+ }
343
+ function walkRelationDirectives(state, edge, directives, relationDepth, path, stage, counting) {
344
+ const supported = advertisedDirectives(edge.capabilities[stage]);
345
+ for (const directive of Object.keys(directives)) {
346
+ if (relationDepth > state.nestingLimit) {
347
+ nestingExceeded(state);
348
+ return;
349
+ }
350
+ const directivePath = extend(state, path, directive);
351
+ const directiveCounting = counting && supported?.includes(directive) === true;
352
+ const directiveValue = directives[directive];
353
+ if (Array.isArray(directiveValue)) {
354
+ for (let index = 0; index < directiveValue.length; index += 1) {
355
+ walkDirectiveEntry(state, edge.target, directive, directiveValue[index], relationDepth, extend(state, directivePath, index), directiveCounting);
356
+ if (state.nesting !== undefined) {
357
+ return;
358
+ }
359
+ }
360
+ }
361
+ else {
362
+ walkDirectiveEntry(state, edge.target, directive, directiveValue, relationDepth, directivePath, directiveCounting);
363
+ if (state.nesting !== undefined) {
364
+ return;
365
+ }
366
+ }
367
+ }
368
+ }
369
+ function walkDirectiveEntry(state, target, directive, entry, relationDepth, path, counting) {
370
+ if (directive === "$create") {
371
+ walkMutationData(state, target, entry, relationDepth, path, "create", counting);
372
+ return;
373
+ }
374
+ if (!isRecord(entry)) {
375
+ return;
376
+ }
377
+ if ((directive === "$update" || directive === "$delete") &&
378
+ "where" in entry) {
379
+ walkWhere(state, target, entry.where, relationDepth, extend(state, path, "where"), counting);
380
+ if (state.nesting !== undefined) {
381
+ return;
382
+ }
383
+ }
384
+ for (const [key, stage] of DIRECTIVE_PAYLOADS.get(directive) ?? NO_PAYLOADS) {
385
+ if (!(key in entry)) {
386
+ continue;
387
+ }
388
+ walkMutationData(state, target, entry[key], relationDepth, extend(state, path, key), stage, counting);
389
+ if (state.nesting !== undefined) {
390
+ return;
391
+ }
392
+ }
393
+ }
394
+ function isUniqueOperation(request) {
395
+ return (request.variant === "unique" &&
396
+ (request.family === "find" ||
397
+ request.family === "update" ||
398
+ request.family === "delete" ||
399
+ request.family === "upsert"));
400
+ }
401
+ function walkArguments(state, request, args) {
402
+ const resource = request.resource;
403
+ const rootPath = (key) => {
404
+ state.rootKey = key;
405
+ return state.tracking ? ["arguments", key] : UNTRACKED;
406
+ };
407
+ if ("where" in args) {
408
+ walkWhere(state, resource, args.where, 1, rootPath("where"), !isUniqueOperation(request));
409
+ if (state.nesting !== undefined) {
410
+ return;
411
+ }
412
+ }
413
+ if ("orderBy" in args) {
414
+ rootPath("orderBy");
415
+ walkOrderBy(state, resource, args.orderBy, 0);
416
+ if (state.nesting !== undefined) {
417
+ return;
418
+ }
419
+ }
420
+ for (const mode of ["select", "include"]) {
421
+ if (!(mode in args)) {
422
+ continue;
423
+ }
424
+ walkProjection(state, resource, args[mode], 0, rootPath(mode), mode, resolveProjectionScope(lookupResource(state.contract, resource), request));
425
+ if (state.nesting !== undefined) {
426
+ return;
427
+ }
428
+ }
429
+ if ("data" in args) {
430
+ const path = rootPath("data");
431
+ const data = args.data;
432
+ if (Array.isArray(data)) {
433
+ for (let index = 0; index < data.length; index += 1) {
434
+ walkMutationData(state, resource, data[index], 0, extend(state, path, index), "create", request.family === "create");
435
+ if (state.nesting !== undefined) {
436
+ return;
437
+ }
438
+ }
439
+ }
440
+ else {
441
+ walkMutationData(state, resource, data, 0, path, request.family === "update" ? "update" : "create", request.family === "create" || request.family === "update");
442
+ if (state.nesting !== undefined) {
443
+ return;
444
+ }
445
+ }
446
+ }
447
+ for (const branch of ["create", "update"]) {
448
+ if (!(branch in args)) {
449
+ continue;
450
+ }
451
+ walkMutationData(state, resource, args[branch], 0, rootPath(branch), branch, request.family === "upsert");
452
+ if (state.nesting !== undefined) {
453
+ return;
454
+ }
455
+ }
456
+ }
457
+ function walk(contract, request, args, tracking) {
458
+ const state = {
459
+ contract,
460
+ nestingLimit: contract.limits.maxNestingDepth,
461
+ jsonDepthLimit: contract.limits.maxJsonDepth,
462
+ booleanLimit: contract.limits.maxBooleanNodes,
463
+ tracking,
464
+ rootKey: "",
465
+ booleanCount: 0,
466
+ nesting: undefined,
467
+ nestingAtField: false,
468
+ booleanNodes: undefined,
469
+ booleanExceeded: false,
470
+ };
471
+ walkArguments(state, request, args);
472
+ return state;
473
+ }
474
+ export function findStructuralLimitIssues(contract, request, args) {
475
+ const untracked = walk(contract, request, args, false);
476
+ if (untracked.nestingAtField) {
477
+ return {
478
+ nesting: walk(contract, request, args, true).nesting,
479
+ booleanNodes: undefined,
480
+ };
481
+ }
482
+ if (untracked.nesting !== undefined || !untracked.booleanExceeded) {
483
+ return { nesting: untracked.nesting, booleanNodes: undefined };
484
+ }
485
+ return {
486
+ nesting: undefined,
487
+ booleanNodes: walk(contract, request, args, true).booleanNodes,
488
+ };
489
+ }
@@ -1,14 +1,19 @@
1
+ import type { AvFieldCheck } from "../contracts/field-check.js";
1
2
  /** The set of allocated Validation codes, as a runtime array. */
2
- export declare const VALIDATION_CODES: readonly ["V1000", "V1001", "V1002", "V1003", "V1004", "V1005", "V1006", "V1007", "V1008", "V1009", "V1010", "V1011", "V1012", "V1013", "V1014", "V1015", "V1016", "V1017", "V1018", "V1019"];
3
+ export declare const VALIDATION_CODES: readonly ["V1000", "V1001", "V1002", "V1003", "V1004", "V1005", "V1006", "V1007", "V1008", "V1009", "V1010", "V1011", "V1012", "V1013", "V1014", "V1015", "V1016", "V1017", "V1018", "V1019", "V1020", "V1021"];
3
4
  /** A validation code (`V1000` and up), one per kind of argument problem. */
4
- export type ValidationCode = (typeof VALIDATION_CODES)[number];
5
+ export type AvValidationCode = (typeof VALIDATION_CODES)[number];
5
6
  /** The framework's message for each validation code. */
6
- export declare const VALIDATION_CODE_MESSAGES: Readonly<Record<ValidationCode, string>>;
7
+ export declare const VALIDATION_CODE_MESSAGES: Readonly<Record<AvValidationCode, string>>;
7
8
  /** One validation problem: its code, message and the argument path it is at. */
8
- export type ValidationIssue = {
9
+ export type AvValidationIssue = {
9
10
  readonly path?: readonly (string | number)[];
10
- readonly code: ValidationCode;
11
+ readonly code: AvValidationCode;
11
12
  readonly message: string;
13
+ /** The failed field validator's check name (`max_length`, `string_format`, …). */
14
+ readonly check?: AvFieldCheck["check"];
15
+ /** That check's parameters, as the Contract stores them (`{ maximum: 80 }`). */
16
+ readonly params?: Readonly<Record<string, unknown>>;
12
17
  };
13
18
  /** Builds one validation issue at its path. */
14
- export declare function validationIssue(code: ValidationCode, path: readonly (string | number)[], message: string): ValidationIssue;
19
+ export declare function validationIssue(code: AvValidationCode, path: readonly (string | number)[], message: string): AvValidationIssue;
@@ -19,6 +19,8 @@ export const VALIDATION_CODES = [
19
19
  "V1017",
20
20
  "V1018",
21
21
  "V1019",
22
+ "V1020",
23
+ "V1021",
22
24
  ];
23
25
  export const VALIDATION_CODE_MESSAGES = {
24
26
  V1000: "Required value missing.",
@@ -41,6 +43,8 @@ export const VALIDATION_CODE_MESSAGES = {
41
43
  V1017: "Transaction fingerprint mismatch.",
42
44
  V1018: "Transaction reference resolved to no value.",
43
45
  V1019: "Transaction step depends on a row removed by an earlier step's cascade",
46
+ V1020: "Transaction mixes application and client steps.",
47
+ V1021: "Json value depth limit exceeded.",
44
48
  };
45
49
  export function validationIssue(code, path, message) {
46
50
  return { code, path, message };
@@ -1,15 +1,15 @@
1
- import type { WriteScope } from "../contracts/capability.js";
2
- import type { Contract } from "../contracts/contract.js";
3
- import type { Resource } from "../contracts/resource.js";
4
- import type { OperationIdentity } from "./operation-identity.js";
1
+ import type { AvWriteScope } from "../contracts/capability.js";
2
+ import type { AvContract } from "../contracts/contract.js";
3
+ import type { AvResource } from "../contracts/resource.js";
4
+ import type { AvOperationIdentity } from "./operation-identity.js";
5
5
  /**
6
6
  * Which write position one request's top-level `data` (or `create`/`update`)
7
7
  * argument sits in, read off the variant the Resource advertises. `"nested"`
8
8
  * wherever nothing narrower is stated.
9
9
  */
10
- export declare function resolveWriteScope(resource: Resource<Contract> | undefined, request: OperationIdentity): WriteScope;
10
+ export declare function resolveWriteScope(resource: AvResource<AvContract> | undefined, request: AvOperationIdentity): AvWriteScope;
11
11
  /**
12
12
  * The position a write NESTED beneath an admitted relation directive sits in: the
13
13
  * unrestricted one, at every depth, under every top-level scope.
14
14
  */
15
- export declare const NESTED_WRITE_SCOPE: WriteScope;
15
+ export declare const NESTED_WRITE_SCOPE: AvWriteScope;
@@ -1,7 +1,9 @@
1
- import type { FrameworkContracts } from "../compiler/contract.compiler.js";
2
- import { type OperationIdentity } from "../operations/operation-identity.js";
1
+ import type { AvContracts } from "../compiler/contract.compiler.js";
2
+ import type { RemoteRequestOrigin } from "../config/config-layer.js";
3
+ import { type AvOperationIdentity } from "../operations/operation-identity.js";
4
+ import { type AvDiagnosticsSink } from "../runtime/diagnostics-reporter.js";
3
5
  import type { ClientProtocolIdentity } from "../runtime/operation-request.js";
4
- import { type OperationFailureResponse } from "../runtime/operation-response.js";
6
+ import { type AvOperationFailureResponse } from "../runtime/operation-response.js";
5
7
  import type { AvProtocolRequest } from "./http-request.decoder.js";
6
8
  import { type ReadRequest } from "./http-request.reader.js";
7
9
  import { type AvProtocolResponse } from "./http-response.encoder.js";
@@ -22,10 +24,10 @@ export type OperationRouteSegments = {
22
24
  /** What a route check resolves to: the operation it names, or the answer that refuses it. */
23
25
  export type OperationRouteResolution = {
24
26
  readonly ok: true;
25
- readonly operation: OperationIdentity;
27
+ readonly operation: AvOperationIdentity;
26
28
  } | {
27
29
  readonly ok: false;
28
- readonly failure: OperationFailureResponse;
30
+ readonly failure: AvOperationFailureResponse;
29
31
  };
30
32
  /**
31
33
  * An operation route `/_resources/<resource>/<family>/<variant>` under one client
@@ -34,7 +36,7 @@ export type OperationRouteResolution = {
34
36
  * is a standard operation the Resource advertises, read through
35
37
  * `isOperationVariantAvailable` alone.
36
38
  */
37
- export declare function resolveOperationRoute(contracts: FrameworkContracts, protocol: ClientProtocolIdentity, route: OperationRouteSegments): OperationRouteResolution;
39
+ export declare function resolveOperationRoute(contracts: AvContracts, protocol: ClientProtocolIdentity, route: OperationRouteSegments, origin?: RemoteRequestOrigin): OperationRouteResolution;
38
40
  /**
39
41
  * The `/_transactions` route under one client protocol identity: version → hash → the
40
42
  * ClientContract's transaction capability. The route exists only when that capability
@@ -42,7 +44,7 @@ export declare function resolveOperationRoute(contracts: FrameworkContracts, pro
42
44
  * it — and is otherwise absent with core's own refusal of a plan. `undefined` when the
43
45
  * route is there.
44
46
  */
45
- export declare function transactionsRouteFailure(contracts: FrameworkContracts, protocol: ClientProtocolIdentity): OperationFailureResponse | undefined;
47
+ export declare function transactionsRouteFailure(contracts: AvContracts, protocol: ClientProtocolIdentity, origin?: RemoteRequestOrigin): AvOperationFailureResponse | undefined;
46
48
  /**
47
49
  * What a route's checks before its body resolve to: the route a request
48
50
  * reaches, or the framework response that answers it instead.
@@ -62,9 +64,9 @@ type RouteCheck<Route> = ({
62
64
  * for both route styles: `decodeOperation` reads the body only after it passes,
63
65
  * `answerAbsent` never.
64
66
  */
65
- export declare function checkOperationRoute(contracts: FrameworkContracts, read: ReadRequest): RouteCheck<{
67
+ export declare function checkOperationRoute(contracts: AvContracts, read: ReadRequest, origin?: RemoteRequestOrigin): RouteCheck<{
66
68
  readonly resource: string;
67
- readonly operation: OperationIdentity;
69
+ readonly operation: AvOperationIdentity;
68
70
  }>;
69
71
  /**
70
72
  * `/_transactions`' checks before its body: the path (`A2000` unless exactly
@@ -72,12 +74,12 @@ export declare function checkOperationRoute(contracts: FrameworkContracts, read:
72
74
  * {@link transactionsRouteFailure} — version, hash, `"interactive"` — and the
73
75
  * method (`A2012`, `Allow: POST`).
74
76
  */
75
- export declare function checkTransactionsRoute(contracts: FrameworkContracts, read: ReadRequest): RouteCheck<object>;
77
+ export declare function checkTransactionsRoute(contracts: AvContracts, read: ReadRequest, origin?: RemoteRequestOrigin): RouteCheck<object>;
76
78
  /**
77
79
  * `protocol.answerAbsent(request)` — the fallback a host that mounts one route per
78
80
  * `protocol.surface()` entry mounts for every path it did not. Never a catch-all into
79
81
  * framework handling: it reads no body, runs no pipeline, calls no Adapter, and takes
80
82
  * only the compiled Contracts. In order:
81
83
  */
82
- export declare function answerAbsentRequest(contracts: FrameworkContracts, received: AvProtocolRequest): AvProtocolResponse | undefined;
84
+ export declare function answerAbsentRequest(contracts: AvContracts, received: AvProtocolRequest, sink?: AvDiagnosticsSink, origin?: RemoteRequestOrigin): AvProtocolResponse | undefined;
83
85
  export {};