@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,204 @@
1
+ import { lookupField, lookupOwn, lookupResource, } from "../contracts/contract-lookup.js";
2
+ import { planOperationArgumentsPath } from "../runtime/error-boundary.js";
3
+ import { isPlainRecord, referenceOperandShape, } from "../runtime/scalar-runtime.js";
4
+ import { routeTransactionReferenceCandidate, } from "./transaction-reference.js";
5
+ function isObject(value) {
6
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7
+ }
8
+ function at(position, ...segments) {
9
+ return { ...position, path: [...position.path, ...segments] };
10
+ }
11
+ function collectValue(field, shape, value, path, candidates, written = false) {
12
+ const route = routeTransactionReferenceCandidate(value);
13
+ if (route.kind === "ordinary") {
14
+ return false;
15
+ }
16
+ candidates.push({
17
+ path,
18
+ field,
19
+ shape,
20
+ written,
21
+ candidate: route.candidate,
22
+ });
23
+ return true;
24
+ }
25
+ function collectKey(position, selector, candidates) {
26
+ if (!isObject(selector)) {
27
+ return;
28
+ }
29
+ const resource = lookupResource(position.contract, position.resource);
30
+ for (const [fieldName, value] of Object.entries(selector)) {
31
+ const field = lookupField(resource, fieldName);
32
+ if (field?.kind === "scalar") {
33
+ collectValue(field, "nonNullValue", value, [...position.path, fieldName], candidates);
34
+ }
35
+ }
36
+ }
37
+ function collectKeys(position, selectors, candidates) {
38
+ if (Array.isArray(selectors)) {
39
+ selectors.forEach((selector, index) => {
40
+ collectKey(at(position, index), selector, candidates);
41
+ });
42
+ return;
43
+ }
44
+ collectKey(position, selectors, candidates);
45
+ }
46
+ function collectScalarFilter(field, filter, path, candidates) {
47
+ if (collectValue(field, "value", filter, path, candidates) ||
48
+ !isPlainRecord(filter)) {
49
+ return;
50
+ }
51
+ for (const [operator, operand] of Object.entries(filter)) {
52
+ const operandPath = [...path, operator];
53
+ if (operator === "not") {
54
+ collectScalarFilter(field, operand, operandPath, candidates);
55
+ continue;
56
+ }
57
+ const shape = referenceOperandShape(operator);
58
+ if (shape !== undefined) {
59
+ collectValue(field, shape, operand, operandPath, candidates);
60
+ }
61
+ }
62
+ }
63
+ function collectWhere(position, where, candidates) {
64
+ if (!isObject(where)) {
65
+ return;
66
+ }
67
+ const resource = lookupResource(position.contract, position.resource);
68
+ for (const [key, value] of Object.entries(where)) {
69
+ if (key === "AND" || key === "OR") {
70
+ if (Array.isArray(value)) {
71
+ value.forEach((entry, index) => {
72
+ collectWhere(at(position, key, index), entry, candidates);
73
+ });
74
+ }
75
+ continue;
76
+ }
77
+ if (key === "NOT") {
78
+ collectWhere(at(position, key), value, candidates);
79
+ continue;
80
+ }
81
+ const field = lookupField(resource, key);
82
+ if (field?.kind === "scalar") {
83
+ collectScalarFilter(field, value, [...position.path, key], candidates);
84
+ }
85
+ else if (field?.kind === "relation") {
86
+ const target = { ...at(position, key), resource: field.target };
87
+ if (field.cardinality === "one") {
88
+ collectWhere(target, value, candidates);
89
+ }
90
+ else if (isObject(value)) {
91
+ for (const operator of ["some", "every", "none"]) {
92
+ if (Object.hasOwn(value, operator)) {
93
+ collectWhere(at(target, operator), value[operator], candidates);
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
100
+ function eachEntry(position, operand, visit) {
101
+ if (Array.isArray(operand)) {
102
+ operand.forEach((entry, index) => {
103
+ visit(at(position, index), entry);
104
+ });
105
+ return;
106
+ }
107
+ visit(position, operand);
108
+ }
109
+ function collectRelationDirectives(position, edge, value, candidates) {
110
+ if (!isObject(value)) {
111
+ return;
112
+ }
113
+ const target = { ...position, resource: edge.target };
114
+ for (const [directive, operand] of Object.entries(value)) {
115
+ const directivePosition = at(target, directive);
116
+ switch (directive) {
117
+ case "$connect":
118
+ case "$disconnect":
119
+ case "$set":
120
+ collectKeys(directivePosition, operand, candidates);
121
+ break;
122
+ case "$create":
123
+ eachEntry(directivePosition, operand, (entryPosition, entry) => {
124
+ collectData(entryPosition, entry, candidates);
125
+ });
126
+ break;
127
+ case "$connectOrCreate":
128
+ case "$update":
129
+ case "$delete":
130
+ case "$upsert":
131
+ eachEntry(directivePosition, operand, (entryPosition, entry) => {
132
+ if (!isObject(entry)) {
133
+ return;
134
+ }
135
+ const where = at(entryPosition, "where");
136
+ if (directive === "$update" || directive === "$delete") {
137
+ collectWhere(where, entry.where, candidates);
138
+ }
139
+ else {
140
+ collectKey(where, entry.where, candidates);
141
+ }
142
+ for (const branch of ["create", "update", "data"]) {
143
+ if (Object.hasOwn(entry, branch)) {
144
+ collectData(at(entryPosition, branch), entry[branch], candidates);
145
+ }
146
+ }
147
+ });
148
+ break;
149
+ }
150
+ }
151
+ }
152
+ function collectData(position, data, candidates) {
153
+ if (!isObject(data)) {
154
+ return;
155
+ }
156
+ const resource = lookupResource(position.contract, position.resource);
157
+ for (const [fieldName, value] of Object.entries(data)) {
158
+ const field = lookupField(resource, fieldName);
159
+ if (field?.kind === "scalar") {
160
+ collectValue(field, "value", value, [...position.path, fieldName], candidates, true);
161
+ }
162
+ else if (field?.kind === "relation") {
163
+ collectRelationDirectives(at(position, fieldName), field, value, candidates);
164
+ }
165
+ }
166
+ }
167
+ export function collectTransactionReferenceCandidates(contract, request, index, args) {
168
+ const candidates = [];
169
+ const root = {
170
+ contract,
171
+ resource: request.resource,
172
+ path: planOperationArgumentsPath(index),
173
+ };
174
+ const where = lookupOwn(args, "where");
175
+ if (request.variant === "unique") {
176
+ collectKey(at(root, "where"), where, candidates);
177
+ }
178
+ else {
179
+ collectWhere(at(root, "where"), where, candidates);
180
+ }
181
+ collectKey(at(root, "cursor"), lookupOwn(args, "cursor"), candidates);
182
+ if (request.family === "create") {
183
+ const data = lookupOwn(args, "data");
184
+ if (request.variant === "many" || request.variant === "count") {
185
+ if (Array.isArray(data)) {
186
+ data.forEach((entry, dataIndex) => {
187
+ collectData(at(root, "data", dataIndex), entry, candidates);
188
+ });
189
+ }
190
+ }
191
+ else {
192
+ collectData(at(root, "data"), data, candidates);
193
+ }
194
+ }
195
+ else if (request.family === "update") {
196
+ collectData(at(root, "data"), lookupOwn(args, "data"), candidates);
197
+ }
198
+ else if (request.family === "upsert") {
199
+ for (const stage of ["create", "update"]) {
200
+ collectData(at(root, stage), lookupOwn(args, stage), candidates);
201
+ }
202
+ }
203
+ return candidates;
204
+ }
@@ -1,13 +1,30 @@
1
+ import type { AvAdapterSqlStatement } from "../adapters/adapter-sql-statement.js";
1
2
  import type { SemanticOperationArguments } from "../operations/operation-validator.js";
2
- import type { ValidationIssue } from "../operations/validation-code.js";
3
+ import type { AvValidationIssue } from "../operations/validation-code.js";
4
+ import type { ValidatedSqlStatement } from "./sql-statement.js";
3
5
  import type { ValidatedTransactionOperation } from "./transaction-plan-validator.js";
4
6
  export type ResolvedTransactionArguments = {
5
7
  readonly ok: true;
6
8
  readonly arguments: SemanticOperationArguments;
7
9
  } | {
8
10
  readonly ok: false;
9
- readonly issues: readonly ValidationIssue[];
11
+ readonly issues: readonly AvValidationIssue[];
10
12
  };
13
+ export type ResolvedSqlStatement = {
14
+ readonly ok: true;
15
+ readonly statement: AvAdapterSqlStatement;
16
+ } | {
17
+ readonly ok: false;
18
+ readonly issues: readonly AvValidationIssue[];
19
+ };
20
+ /**
21
+ * The statement a validated SQL step hands the Adapter: every `$ref` value read from
22
+ * the results ledger, exactly as an operation's slot is — the source's final data,
23
+ * copied by the source field's own codec — and then bound like any other value. A
24
+ * source row lacking the field is `V1018` at the value, before the statement runs.
25
+ * Issue paths are relative to the step (`["values", k, "$ref", "path"]`).
26
+ */
27
+ export declare function resolveSqlStatement(statement: ValidatedSqlStatement, results: readonly unknown[]): ResolvedSqlStatement;
11
28
  /**
12
29
  * Substitutes every validated `$ref` placeholder of one operation from the results
13
30
  * ledger: each earlier operation's final `data`, exactly the value at its index in the
@@ -4,23 +4,40 @@ import { replaceTransactionSlotValues } from "./transaction-slot-writer.js";
4
4
  function isRecord(value) {
5
5
  return typeof value === "object" && value !== null && !Array.isArray(value);
6
6
  }
7
+ function unresolvedIssue(path) {
8
+ return validationIssue("V1018", [...path, "$ref", "path"], "Transaction reference resolved to no value.");
9
+ }
10
+ export function resolveSqlStatement(statement, results) {
11
+ const values = [];
12
+ for (const [position, value] of statement.values.entries()) {
13
+ if (value.kind === "value") {
14
+ values.push(value.value);
15
+ continue;
16
+ }
17
+ const row = results[value.operation];
18
+ if (!isRecord(row) || !Object.hasOwn(row, value.field)) {
19
+ return { ok: false, issues: [unresolvedIssue(["values", position])] };
20
+ }
21
+ values.push(copyScalarFieldValue(value.source, row[value.field]));
22
+ }
23
+ return {
24
+ ok: true,
25
+ statement: Object.freeze({
26
+ strings: statement.strings,
27
+ values: Object.freeze(values),
28
+ }),
29
+ };
30
+ }
7
31
  export function resolveTransactionReferences(operation, results) {
8
32
  const substitutions = [];
9
33
  for (const slot of operation.references) {
10
34
  const { operation: source, path: [segment], } = slot.reference.$ref;
11
35
  const row = results[source];
12
36
  if (!isRecord(row) || !Object.hasOwn(row, segment)) {
13
- return {
14
- ok: false,
15
- issues: [
16
- validationIssue("V1018", [...slot.path, "$ref", "path"], "Transaction reference resolved to no value."),
17
- ],
18
- };
37
+ return { ok: false, issues: [unresolvedIssue(slot.path)] };
19
38
  }
20
- substitutions.push({
21
- path: slot.path,
22
- value: copyScalarFieldValue(slot.field, row[segment]),
23
- });
39
+ const value = copyScalarFieldValue(slot.source, row[segment]);
40
+ substitutions.push({ path: slot.path, value });
24
41
  }
25
42
  return {
26
43
  ok: true,
@@ -1,5 +1,9 @@
1
- import type { OperationFailureResponse } from "../runtime/operation-response.js";
2
- import type { CandidateTransactionOperation, TransactionReferenceSlot, ValidatedTransactionOperation } from "./transaction-plan-validator.js";
1
+ import type { AvContract } from "../contracts/contract.js";
2
+ import type { AvField } from "../contracts/field.js";
3
+ import type { AvValidationIssue } from "../operations/validation-code.js";
4
+ import type { AvOperationFailureResponse } from "../runtime/operation-response.js";
5
+ import type { CandidateTransactionOperation, TransactionReferenceSlot, ValidatedTransactionStep } from "./transaction-plan-validator.js";
6
+ type Path = readonly (string | number)[];
3
7
  type ReferenceValidationResult = {
4
8
  readonly ok: true;
5
9
  readonly references: readonly TransactionReferenceSlot[];
@@ -7,8 +11,34 @@ type ReferenceValidationResult = {
7
11
  readonly requestArguments: unknown;
8
12
  } | {
9
13
  readonly ok: false;
10
- readonly response: OperationFailureResponse;
14
+ readonly response: AvOperationFailureResponse;
11
15
  };
16
+ /** The `V1016` refusal of a reference's source index, at its `operation` member. */
17
+ export declare function invalidSourceIndexIssue(operationPath: Path): AvValidationIssue;
18
+ /**
19
+ * The validated step a reference names, or `undefined` when its index is no
20
+ * integer naming a step before the referencing one (`V1016`).
21
+ */
22
+ export declare function referenceSourceAt(earlier: readonly ValidatedTransactionStep[], sourceIndex: unknown, referencingIndex: number): ValidatedTransactionStep | undefined;
23
+ /** The `V1010` refusal of a reference whose source is an `appTx.$sql` step. */
24
+ export declare function sqlSourceIssue(pathPath: Path): AvValidationIssue;
25
+ /** The field a reference reads from its source step, or why it cannot read one. */
26
+ export type ReferenceSourceRead = {
27
+ readonly ok: true;
28
+ readonly field: AvField<AvContract>;
29
+ } | {
30
+ readonly ok: false;
31
+ readonly issue: AvValidationIssue;
32
+ };
33
+ /**
34
+ * Reads the field a reference's one path segment names from its source step,
35
+ * holding the source to what a reference may read: one row (not a `many` or
36
+ * `count` result, not a SQL step's rows), and a field in its actual projection,
37
+ * never a reducer. The field is read under the source's own Contract: in a plan
38
+ * that mixes origins, a source field the referencing step's layer hides is still
39
+ * the source's to read. Assignability to a destination is the caller's.
40
+ */
41
+ export declare function referenceSourceField(source: ValidatedTransactionStep, segment: string, pathPath: Path): ReferenceSourceRead;
12
42
  /** Validates every passive reference candidate before operation fingerprinting. */
13
- export declare function validateTransactionReferences(operation: CandidateTransactionOperation, earlier: readonly ValidatedTransactionOperation[]): ReferenceValidationResult;
43
+ export declare function validateTransactionReferences(operation: CandidateTransactionOperation, earlier: readonly ValidatedTransactionStep[]): ReferenceValidationResult;
14
44
  export {};
@@ -141,25 +141,74 @@ function containsUnpairedSurrogate(value) {
141
141
  }
142
142
  return false;
143
143
  }
144
- function sameType(source, destination) {
144
+ function sameScalar(source, destination) {
145
145
  if ("scalar" in source.type) {
146
- if (!("scalar" in destination.type)) {
147
- return false;
148
- }
149
- if (source.type.scalar !== destination.type.scalar) {
150
- return false;
151
- }
146
+ return ("scalar" in destination.type &&
147
+ source.type.scalar === destination.type.scalar);
152
148
  }
153
- else {
154
- if (!("enum" in destination.type)) {
155
- return false;
156
- }
157
- if (source.type.enum !== destination.type.enum) {
158
- return false;
159
- }
149
+ return ("enum" in destination.type && source.type.enum === destination.type.enum);
150
+ }
151
+ function isAssignable(source, destination, shape) {
152
+ if (!sameScalar(source, destination)) {
153
+ return false;
154
+ }
155
+ switch (shape) {
156
+ case "value":
157
+ return (source.list === destination.list &&
158
+ !(source.nullable && !destination.nullable));
159
+ case "nonNullValue":
160
+ return source.list === destination.list && !source.nullable;
161
+ case "entry":
162
+ return !source.list && !source.nullable;
163
+ case "entries":
164
+ return source.list && !source.nullable;
160
165
  }
161
- return (source.list === destination.list &&
162
- !(source.nullable && !destination.nullable));
166
+ }
167
+ export function invalidSourceIndexIssue(operationPath) {
168
+ return validationIssue("V1016", operationPath, "Transaction reference operation index is invalid.");
169
+ }
170
+ export function referenceSourceAt(earlier, sourceIndex, referencingIndex) {
171
+ if (typeof sourceIndex !== "number" ||
172
+ !Number.isInteger(sourceIndex) ||
173
+ sourceIndex < 0 ||
174
+ sourceIndex >= referencingIndex) {
175
+ return undefined;
176
+ }
177
+ const source = earlier[sourceIndex];
178
+ return source !== undefined && source.index === sourceIndex
179
+ ? source
180
+ : undefined;
181
+ }
182
+ export function sqlSourceIssue(pathPath) {
183
+ return validationIssue("V1010", pathPath, "Transaction reference source is a SQL step, whose rows cannot be referenced.");
184
+ }
185
+ export function referenceSourceField(source, segment, pathPath) {
186
+ if (source.kind === "sql") {
187
+ return { ok: false, issue: sqlSourceIssue(pathPath) };
188
+ }
189
+ if (source.request.variant === "many" || source.request.variant === "count") {
190
+ return {
191
+ ok: false,
192
+ issue: validationIssue("V1010", pathPath, "Transaction reference source has no addressable single-row projection."),
193
+ };
194
+ }
195
+ const projection = source.projection;
196
+ if (projection?.reducers.some((reducer) => reducer === segment)) {
197
+ return {
198
+ ok: false,
199
+ issue: validationIssue("V1011", pathPath, "Transaction reference source is not a scalar field."),
200
+ };
201
+ }
202
+ const field = projection === undefined || !projection.requested.includes(segment)
203
+ ? undefined
204
+ : lookupField(lookupResource(source.contract, projection.resource), segment);
205
+ if (field === undefined) {
206
+ return {
207
+ ok: false,
208
+ issue: validationIssue("V1010", pathPath, "Transaction reference path is not present in the source projection."),
209
+ };
210
+ }
211
+ return { ok: true, field };
163
212
  }
164
213
  const CANDIDATE_KEYS = new Set(["$ref"]);
165
214
  const REFERENCE_KEYS = new Set(["operation", "fingerprint", "path"]);
@@ -185,19 +234,15 @@ export function validateTransactionReferences(operation, earlier) {
185
234
  return failure(sourceIndexProperty.issue, operation.index);
186
235
  }
187
236
  const sourceIndex = sourceIndexProperty.value;
188
- const source = typeof sourceIndex === "number" && Number.isInteger(sourceIndex)
189
- ? earlier[sourceIndex]
190
- : undefined;
191
- if (typeof sourceIndex !== "number" ||
192
- !Number.isInteger(sourceIndex) ||
193
- sourceIndex < 0 ||
194
- sourceIndex >= operation.index ||
195
- source === undefined ||
196
- source.index !== sourceIndex) {
197
- return failure(validationIssue("V1016", operationPath, "Transaction reference operation index is invalid."), operation.index);
237
+ const source = referenceSourceAt(earlier, sourceIndex, operation.index);
238
+ if (source === undefined) {
239
+ return failure(invalidSourceIndexIssue(operationPath), operation.index);
240
+ }
241
+ if (source.kind === "sql") {
242
+ return failure(sqlSourceIssue([...refPath, "path"]), operation.index);
198
243
  }
199
244
  const fingerprintPath = [...refPath, "fingerprint"];
200
- const fingerprintProperty = inspectOwnDataProperty(referenceInspection.value, "fingerprint", fingerprintPath, "V1017", refPath);
245
+ const fingerprintProperty = inspectOwnDataProperty(referenceInspection.value, "fingerprint", fingerprintPath, "V1000", refPath);
201
246
  if (!fingerprintProperty.ok) {
202
247
  return failure(fingerprintProperty.issue, operation.index);
203
248
  }
@@ -219,27 +264,18 @@ export function validateTransactionReferences(operation, earlier) {
219
264
  if (containsUnpairedSurrogate(segment)) {
220
265
  return failure(validationIssue("V1010", pathPath, "Transaction reference path contains invalid Unicode."), operation.index);
221
266
  }
222
- if (source.request.variant === "many" ||
223
- source.request.variant === "count") {
224
- return failure(validationIssue("V1010", pathPath, "Transaction reference source has no addressable single-row projection."), operation.index);
225
- }
226
- const projection = source.projection;
227
- if (projection?.reducers.some((reducer) => reducer === segment)) {
228
- return failure(validationIssue("V1011", pathPath, "Transaction reference source is not a scalar field."), operation.index);
229
- }
230
- if (projection === undefined || !projection.requested.includes(segment)) {
231
- return failure(validationIssue("V1010", pathPath, "Transaction reference path is not present in the source projection."), operation.index);
232
- }
233
- const sourceField = lookupField(lookupResource(source.contract, projection.resource), segment);
234
- if (sourceField === undefined) {
235
- return failure(validationIssue("V1010", pathPath, "Transaction reference path is not present in the source projection."), operation.index);
267
+ const sourceRead = referenceSourceField(source, segment, pathPath);
268
+ if (!sourceRead.ok) {
269
+ return failure(sourceRead.issue, operation.index);
236
270
  }
237
- if (sourceField.kind !== "scalar" || !sameType(sourceField, slot.field)) {
271
+ const sourceField = sourceRead.field;
272
+ if (sourceField.kind !== "scalar" ||
273
+ !isAssignable(sourceField, slot.field, slot.shape)) {
238
274
  return failure(validationIssue("V1011", pathPath, "Transaction reference source type is not assignable to its destination."), operation.index);
239
275
  }
240
276
  const reference = Object.freeze({
241
277
  $ref: Object.freeze({
242
- operation: sourceIndex,
278
+ operation: source.index,
243
279
  fingerprint,
244
280
  path: Object.freeze([segment]),
245
281
  }),
@@ -247,6 +283,9 @@ export function validateTransactionReferences(operation, earlier) {
247
283
  references.push({
248
284
  path: Object.freeze([...slot.path]),
249
285
  field: slot.field,
286
+ shape: slot.shape,
287
+ written: slot.written,
288
+ source: sourceField,
250
289
  reference,
251
290
  });
252
291
  }
@@ -1,8 +1,8 @@
1
- import type { WriteScope } from "../contracts/capability.js";
2
- import type { Contract } from "../contracts/contract.js";
1
+ import type { AvWriteScope } from "../contracts/capability.js";
2
+ import type { AvContract } from "../contracts/contract.js";
3
3
  import type { ScalarForms } from "../contracts/scalar-value-type.js";
4
- import type { CreateDataInput, OperationArgumentsFor, ResourceKey, UpdateDataInput, WritableRelationKey } from "../operations/operation-arguments.js";
5
- import type { OperationIdentity } from "../operations/operation-identity.js";
4
+ import type { AvCreateDataInput, AvOperationArgumentsFor, AvResourceKey, AvUpdateDataInput } from "../operations/operation-arguments.js";
5
+ import type { AvOperationIdentity } from "../operations/operation-identity.js";
6
6
  import type { OperationFingerprint } from "./deferred-operation.js";
7
7
  declare const REFERENCE_VALUE: unique symbol;
8
8
  /** Any object with a `$ref` key, before it is validated as a reference. */
@@ -13,7 +13,7 @@ export type TransactionReferenceCandidate = {
13
13
  * A reference to a field of an earlier operation's result in the same
14
14
  * transaction plan: `{ $ref: { operation, fingerprint, path } }`.
15
15
  */
16
- export type TransactionReference<Value = unknown> = {
16
+ export type AvTransactionReference<Value = unknown> = {
17
17
  readonly $ref: {
18
18
  readonly operation: number;
19
19
  readonly fingerprint: OperationFingerprint;
@@ -38,68 +38,40 @@ export declare function routeTransactionReferenceCandidate(value: unknown): Tran
38
38
  /** Whether `value` is an object with a `$ref` key; it is not validated here. */
39
39
  export declare function isTransactionReferenceCandidate(value: unknown): value is TransactionReferenceCandidate;
40
40
  /** Whether `value` is a complete `$ref` object. */
41
- export declare function isTransactionReferenceObject(value: unknown): value is TransactionReference;
41
+ export declare function isTransactionReferenceObject(value: unknown): value is AvTransactionReference;
42
42
  /**
43
43
  * A scalar mutation value inside a plan: the value itself, or a reference to an
44
44
  * earlier operation's field of that same type.
45
45
  */
46
- export type TransactionScalarValue<Value> = Value | TransactionReference<Value>;
46
+ export type TransactionScalarValue<Value> = Value | AvTransactionReference<Value>;
47
47
  /**
48
- * A scalar value inside a plan, or a `$ref` to a field of the same type. A
49
- * reference is typed by the application form of its source field, because a
50
- * source's final data is always in application forms.
48
+ * What a Transaction Slot holds of its destination field, which decides the source
49
+ * fields a reference there accepts — always the same scalar or enum, no coercion:
50
+ *
51
+ * - `"value"` — the field's whole value, where a `null` means something: a mutation
52
+ * value, or an equality filter (`null` matches the rows the field is unset on). A
53
+ * nullable source only into a nullable field.
54
+ * - `"nonNullValue"` — the field's whole value, where a `null` identifies or orders
55
+ * nothing: a unique key, a `cursor`, an ordering or text comparison. The source is
56
+ * never nullable.
57
+ * - `"entry"` — one entry of a list field (`has`): a non-null, non-list source.
58
+ * - `"entries"` — a list of entries (`in`, `notIn`, `hasEvery`, `hasSome`): a
59
+ * non-null list source.
51
60
  */
52
- type ReferenceableValue<Value, ReferenceValue> = Value | TransactionReference<ReferenceValue>;
53
- /** `Data`'s member `Key`, or `never` when it has none. */
54
- type MemberOf<Data, Key> = Key extends keyof Data ? Data[Key] : never;
61
+ export type TransactionSlotShape = "value" | "nonNullValue" | "entry" | "entries";
55
62
  /**
56
- * Create data whose top-level scalar fields may hold a `$ref`, under stated
57
- * scalar forms.
63
+ * Create data inside a transaction plan, at one write position: its scalar values
64
+ * and the unique keys its relation directives name may hold a `$ref`. The default
65
+ * is the unrestricted position, as on `AvCreateDataInput`.
58
66
  */
59
- export type ReferenceableCreateData<C extends Contract, K extends ResourceKey<C>, Scope extends WriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
60
- [F in keyof CreateDataInput<C, K, Scope, Forms>]: F extends WritableRelationKey<C, K, "create", Scope> ? CreateDataInput<C, K, Scope, Forms>[F] : ReferenceableValue<CreateDataInput<C, K, Scope, Forms>[F], MemberOf<CreateDataInput<C, K, Scope, ReferenceForms>, F>>;
61
- }>;
67
+ export type TransactionCreateDataInput<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope = "nested"> = AvCreateDataInput<C, K, Scope, ScalarForms, ScalarForms>;
68
+ /** Update data inside a transaction plan. See {@link TransactionCreateDataInput}. */
69
+ export type TransactionUpdateDataInput<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope = "nested"> = AvUpdateDataInput<C, K, Scope, ScalarForms, ScalarForms>;
62
70
  /**
63
- * Update data whose top-level scalar fields may hold a `$ref`, under stated
64
- * scalar forms.
71
+ * Operation arguments inside a transaction plan, under one value form and one
72
+ * reference form: `AvOperationArgumentsFor` with its reference positions opened.
65
73
  */
66
- export type ReferenceableUpdateData<C extends Contract, K extends ResourceKey<C>, Scope extends WriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
67
- [F in keyof UpdateDataInput<C, K, Scope, Forms>]: F extends WritableRelationKey<C, K, "update", Scope> ? UpdateDataInput<C, K, Scope, Forms>[F] : ReferenceableValue<UpdateDataInput<C, K, Scope, Forms>[F], MemberOf<UpdateDataInput<C, K, Scope, ReferenceForms>, F>>;
68
- }>;
69
- /**
70
- * Only top-level scalar fields accept a `$ref`; a relation field keeps its relation
71
- * mutation action, where a `$ref` is an ordinary invalid value.
72
- */
73
- export type TransactionCreateDataInput<C extends Contract, K extends ResourceKey<C>, Scope extends WriteScope = "nested"> = ReferenceableCreateData<C, K, Scope, ScalarForms, ScalarForms>;
74
- /** See {@link TransactionCreateDataInput}. */
75
- export type TransactionUpdateDataInput<C extends Contract, K extends ResourceKey<C>, Scope extends WriteScope = "nested"> = ReferenceableUpdateData<C, K, Scope, ScalarForms, ScalarForms>;
76
- /** Operation arguments inside a transaction plan, under stated scalar forms. */
77
- export type ReferenceableArgumentsFor<C extends Contract, K extends ResourceKey<C>, I extends OperationIdentity, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = I extends {
78
- family: "create";
79
- variant: "one";
80
- } ? Omit<OperationArgumentsFor<C, K, I, Forms>, "data"> & {
81
- data: ReferenceableCreateData<C, K, "nested", Forms, ReferenceForms>;
82
- } : I extends {
83
- family: "create";
84
- variant: "many" | "count";
85
- } ? Omit<OperationArgumentsFor<C, K, I, Forms>, "data"> & {
86
- data: readonly ReferenceableCreateData<C, K, "bulkWrite", Forms, ReferenceForms>[];
87
- } : I extends {
88
- family: "update";
89
- variant: "first" | "unique";
90
- } ? Omit<OperationArgumentsFor<C, K, I, Forms>, "data"> & {
91
- data: ReferenceableUpdateData<C, K, "nested", Forms, ReferenceForms>;
92
- } : I extends {
93
- family: "update";
94
- variant: "many" | "count";
95
- } ? Omit<OperationArgumentsFor<C, K, I, Forms>, "data"> & {
96
- data: ReferenceableUpdateData<C, K, "bulkWrite", Forms, ReferenceForms>;
97
- } : I extends {
98
- family: "upsert";
99
- } ? Omit<OperationArgumentsFor<C, K, I, Forms>, "create" | "update"> & {
100
- create: ReferenceableCreateData<C, K, "nested", Forms, ReferenceForms>;
101
- update: ReferenceableUpdateData<C, K, "nested", Forms, ReferenceForms>;
102
- } : OperationArgumentsFor<C, K, I, Forms>;
74
+ export type ReferenceableArgumentsFor<C extends AvContract, K extends AvResourceKey<C>, I extends AvOperationIdentity, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = AvOperationArgumentsFor<C, K, I, Forms, ReferenceForms>;
103
75
  /** Operation arguments inside a transaction plan, no scalar form stated. */
104
- export type TransactionOperationArgumentsFor<C extends Contract, K extends ResourceKey<C>, I extends OperationIdentity> = ReferenceableArgumentsFor<C, K, I, ScalarForms, ScalarForms>;
76
+ export type TransactionOperationArgumentsFor<C extends AvContract, K extends AvResourceKey<C>, I extends AvOperationIdentity> = ReferenceableArgumentsFor<C, K, I, ScalarForms, ScalarForms>;
105
77
  export {};