@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,9 +1,12 @@
1
- import { validationIssue } from "../operations/validation-code.js";
1
+ import { VALIDATION_CODE_MESSAGES, validationIssue, } from "../operations/validation-code.js";
2
+ import { copyAtDoor, refuseCallerData } from "../runtime/caller-data.door.js";
2
3
  import { operationFailure } from "../runtime/operation-response.js";
3
4
  import { mapValidationOutcome } from "../runtime/outcome-mapper.js";
4
5
  import { encodeOperationArgumentsForWire } from "./operation-arguments-encoder.js";
5
6
  import { computeOperationFingerprint } from "./operation-fingerprint.js";
7
+ import { readSqlTemplate } from "./sql-statement.js";
6
8
  import { transactionOperationFailure } from "./transaction-response.js";
9
+ const SQL_STEP_NODE = Object.freeze({ fingerprint: null });
7
10
  function isPlainRecord(value) {
8
11
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
9
12
  return false;
@@ -11,64 +14,111 @@ function isPlainRecord(value) {
11
14
  const prototype = Object.getPrototypeOf(value);
12
15
  return prototype === Object.prototype || prototype === null;
13
16
  }
14
- function referenceKeys(identity) {
15
- switch (identity.family) {
16
- case "create":
17
- case "update":
18
- return ["data"];
19
- case "upsert":
20
- return ["create", "update"];
21
- default:
22
- return [];
23
- }
24
- }
25
- function referenceContainers(identity, args) {
26
- if (!isPlainRecord(args)) {
27
- return [];
28
- }
29
- return referenceKeys(identity).flatMap((key) => {
30
- const value = args[key];
31
- if (Array.isArray(value)) {
32
- return value.flatMap((entry, index) => isPlainRecord(entry) ? [{ path: [key, index], record: entry }] : []);
17
+ const KEEP = Symbol("keep");
18
+ function rebuildArguments(root, leaf) {
19
+ const pathOf = (parent, key) => () => {
20
+ const segments = [];
21
+ if (key !== undefined) {
22
+ segments.push(key);
33
23
  }
34
- return isPlainRecord(value) ? [{ path: [key], record: value }] : [];
35
- });
36
- }
37
- function replaceContainers(identity, args, rebuild) {
38
- if (!isPlainRecord(args)) {
39
- return args;
24
+ for (let frame = parent; frame?.key !== undefined; frame = frame.parent) {
25
+ segments.push(frame.key);
26
+ }
27
+ return segments.reverse();
28
+ };
29
+ const ancestors = new Set();
30
+ const finish = (frame) => {
31
+ ancestors.delete(frame.source);
32
+ if (!Array.isArray(frame.source)) {
33
+ return Object.fromEntries(frame.built);
34
+ }
35
+ const rebuilt = new Array(frame.source.length);
36
+ for (const [index, value] of frame.built) {
37
+ rebuilt[index] = value;
38
+ }
39
+ return rebuilt;
40
+ };
41
+ const enter = (value, parent, key) => {
42
+ const replaced = leaf(value, pathOf(parent, key));
43
+ if (replaced !== KEEP) {
44
+ return { value: replaced };
45
+ }
46
+ if (!Array.isArray(value) && !isPlainRecord(value)) {
47
+ return { value };
48
+ }
49
+ if (ancestors.has(value)) {
50
+ return { value };
51
+ }
52
+ ancestors.add(value);
53
+ const keys = Array.isArray(value)
54
+ ? Object.keys(value).map(Number)
55
+ : Object.keys(value);
56
+ return { source: value, keys, built: [], parent, key, next: 0 };
57
+ };
58
+ const first = enter(root, undefined, undefined);
59
+ if (!("source" in first)) {
60
+ return first.value;
40
61
  }
41
- const result = { ...args };
42
- for (const key of referenceKeys(identity)) {
43
- const value = args[key];
44
- if (Array.isArray(value)) {
45
- result[key] = value.map((entry, index) => isPlainRecord(entry)
46
- ? rebuild({ path: [key, index], record: entry })
47
- : entry);
62
+ let frame = first;
63
+ for (;;) {
64
+ if (frame.next < frame.keys.length) {
65
+ const key = frame.keys[frame.next];
66
+ frame.next += 1;
67
+ const entry = frame.source[key];
68
+ const child = enter(entry, frame, key);
69
+ if ("source" in child) {
70
+ frame = child;
71
+ }
72
+ else {
73
+ frame.built.push([key, child.value]);
74
+ }
75
+ continue;
48
76
  }
49
- else if (isPlainRecord(value)) {
50
- result[key] = rebuild({ path: [key], record: value });
77
+ const rebuilt = finish(frame);
78
+ const parent = frame.parent;
79
+ if (parent === undefined) {
80
+ return rebuilt;
51
81
  }
82
+ parent.built.push([frame.key, rebuilt]);
83
+ frame = parent;
52
84
  }
53
- return result;
54
85
  }
55
86
  function operationEntryFailure(operation, message) {
56
87
  return transactionOperationFailure(operationFailure("A2004", {
57
88
  message: "Transaction plan failed framework validation.",
58
- issues: [validationIssue("V1001", ["operation"], message)],
89
+ issues: [validationIssue("V1001", [], message)],
59
90
  }), operation);
60
91
  }
61
92
  function referenceFailure(issue, operation) {
62
93
  return transactionOperationFailure(mapValidationOutcome([issue]), operation);
63
94
  }
64
- export function createTransactionPlanAssembler(contracts, protocol) {
95
+ export function createTransactionPlanAssembler(contracts, protocol, misuse) {
65
96
  const handles = new WeakMap();
66
97
  const placeholders = new WeakMap();
67
98
  const originOf = (origin) => origin === "application"
68
- ? { scope: "application" }
69
- : { scope: "client", protocol };
70
- const snapshot = (identity, args) => replaceContainers(identity, args, ({ record }) => ({ ...record }));
71
- const defer = (origin, resource, identity, args) => {
99
+ ? { origin: "application" }
100
+ : { origin: "client", protocol };
101
+ const snapshot = (args) => {
102
+ const copy = copyAtDoor(args, {
103
+ keep: (value) => placeholders.has(value),
104
+ });
105
+ return copy.ok ? { args: copy.value } : { args: {}, refused: copy.error };
106
+ };
107
+ const placeholderSites = (args) => {
108
+ const sites = [];
109
+ rebuildArguments(args, (value, pathOf) => {
110
+ const placeholder = typeof value === "object" && value !== null
111
+ ? placeholders.get(value)
112
+ : undefined;
113
+ if (placeholder === undefined) {
114
+ return KEEP;
115
+ }
116
+ sites.push({ path: pathOf(), object: value, placeholder });
117
+ return value;
118
+ });
119
+ return sites;
120
+ };
121
+ const createHandle = (record) => {
72
122
  const handle = Object.freeze({
73
123
  $ref: (field) => {
74
124
  const placeholder = Object.freeze({
@@ -78,15 +128,60 @@ export function createTransactionPlanAssembler(contracts, protocol) {
78
128
  return placeholder;
79
129
  },
80
130
  });
81
- handles.set(handle, {
82
- origin,
83
- resource,
84
- identity,
85
- args: snapshot(identity, args),
86
- });
131
+ handles.set(handle, record);
87
132
  return handle;
88
133
  };
89
- const assemble = async (operations) => {
134
+ const defer = (origin, resource, identity, args) => createHandle({
135
+ kind: "operation",
136
+ origin,
137
+ resource,
138
+ identity,
139
+ ...snapshot(args),
140
+ });
141
+ const deferSql = (strings, values) => {
142
+ const copy = snapshot(values);
143
+ return createHandle({
144
+ kind: "sql",
145
+ strings: readSqlTemplate(strings, values.length),
146
+ values: Array.isArray(copy.args) ? copy.args : [],
147
+ ...(copy.refused === undefined ? {} : { refused: copy.refused }),
148
+ });
149
+ };
150
+ const recordPlaceholderSites = (record) => placeholderSites(record.kind === "sql" ? record.values : record.args);
151
+ const planSqlStatement = (record, positions) => {
152
+ const values = record.values.map((value) => {
153
+ const sites = placeholderSites(value);
154
+ const [site] = sites;
155
+ if (site === undefined) {
156
+ return { kind: "value", value };
157
+ }
158
+ if (site.path.length > 0) {
159
+ return { kind: "misplaced-reference", path: site.path };
160
+ }
161
+ return {
162
+ kind: "reference",
163
+ operation: positions.get(site.placeholder.source),
164
+ field: site.placeholder.field,
165
+ };
166
+ });
167
+ return {
168
+ strings: record.strings,
169
+ values,
170
+ ...(record.refused === undefined ? {} : { refused: record.refused }),
171
+ };
172
+ };
173
+ const assemble = async (input) => {
174
+ const list = copyAtDoor(input, { keep: (value) => value !== input });
175
+ if (!list.ok) {
176
+ return {
177
+ ok: false,
178
+ response: operationFailure("A2004", {
179
+ message: "Transaction plan failed framework validation.",
180
+ issues: [refuseCallerData(list.error, ["operations"], {}, misuse)],
181
+ }),
182
+ };
183
+ }
184
+ const operations = list.value;
90
185
  if (!Array.isArray(operations)) {
91
186
  return {
92
187
  ok: false,
@@ -119,18 +214,36 @@ export function createTransactionPlanAssembler(contracts, protocol) {
119
214
  positions.set(entry, index);
120
215
  records.push(record);
121
216
  }
217
+ const originOfRecord = (record) => record.kind === "sql" ? "application" : record.origin;
218
+ const [first] = records;
219
+ if (first !== undefined) {
220
+ const planOrigin = originOfRecord(first);
221
+ const other = records.findIndex((record) => originOfRecord(record) !== planOrigin);
222
+ if (other !== -1) {
223
+ return {
224
+ ok: false,
225
+ response: transactionOperationFailure(operationFailure("A2004", {
226
+ message: "Transaction plan failed framework validation.",
227
+ issues: [
228
+ validationIssue("V1020", [], VALIDATION_CODE_MESSAGES.V1020),
229
+ ],
230
+ }), other),
231
+ };
232
+ }
233
+ }
122
234
  for (const [index, record] of records.entries()) {
123
- for (const { path, record: container } of referenceContainers(record.identity, record.args)) {
124
- for (const [field, value] of Object.entries(container)) {
125
- const placeholder = typeof value === "object" && value !== null
126
- ? placeholders.get(value)
127
- : undefined;
128
- if (placeholder !== undefined && !positions.has(placeholder.source)) {
129
- return {
130
- ok: false,
131
- response: referenceFailure(validationIssue("V1010", ["operations", index, "args", ...path, field, "$ref"], "Transaction reference names an operation that is not in this transaction."), index),
132
- };
133
- }
235
+ for (const { path, placeholder } of recordPlaceholderSites(record)) {
236
+ if (!positions.has(placeholder.source)) {
237
+ return {
238
+ ok: false,
239
+ response: referenceFailure(validationIssue("V1010", [
240
+ "operations",
241
+ index,
242
+ record.kind === "sql" ? "values" : "args",
243
+ ...path,
244
+ "$ref",
245
+ ], "Transaction reference names an operation that is not in this transaction."), index),
246
+ };
134
247
  }
135
248
  }
136
249
  }
@@ -145,26 +258,20 @@ export function createTransactionPlanAssembler(contracts, protocol) {
145
258
  };
146
259
  const materialize = async (index) => {
147
260
  const record = records[index];
148
- const references = [];
149
- const args = replaceContainers(record.identity, record.args, ({ record: container }) => {
150
- const bound = { ...container };
151
- for (const [field, value] of Object.entries(container)) {
152
- const placeholder = typeof value === "object" && value !== null
153
- ? placeholders.get(value)
154
- : undefined;
155
- if (placeholder === undefined) {
156
- continue;
157
- }
158
- const operation = positions.get(placeholder.source);
159
- references.push(nodeAt(operation).then(({ fingerprint }) => {
160
- bound[field] = {
161
- $ref: { operation, fingerprint, path: [placeholder.field] },
162
- };
163
- }));
164
- }
165
- return bound;
166
- });
167
- await Promise.all(references);
261
+ if (record.kind === "sql") {
262
+ return SQL_STEP_NODE;
263
+ }
264
+ const bound = new Map();
265
+ await Promise.all(placeholderSites(record.args).map(async ({ object, placeholder }) => {
266
+ const operation = positions.get(placeholder.source);
267
+ const { fingerprint } = await nodeAt(operation);
268
+ bound.set(object, {
269
+ $ref: { operation, fingerprint, path: [placeholder.field] },
270
+ });
271
+ }));
272
+ const args = rebuildArguments(record.args, (value) => typeof value === "object" && value !== null && bound.has(value)
273
+ ? bound.get(value)
274
+ : KEEP);
168
275
  return {
169
276
  resource: record.resource,
170
277
  family: record.identity.family,
@@ -194,8 +301,14 @@ export function createTransactionPlanAssembler(contracts, protocol) {
194
301
  plan: {
195
302
  operations: await Promise.all(records.map((_, index) => nodeAt(index))),
196
303
  },
197
- origins: records.map((record) => originOf(record.origin)),
304
+ origins: records.map((record) => originOf(record.kind === "sql" ? "application" : record.origin)),
305
+ refused: new Map(records.flatMap((record, index) => record.kind === "sql" || record.refused === undefined
306
+ ? []
307
+ : [[index, record.refused]])),
308
+ statements: new Map(records.flatMap((record, index) => record.kind === "sql"
309
+ ? [[index, planSqlStatement(record, positions)]]
310
+ : [])),
198
311
  };
199
312
  };
200
- return { defer, assemble };
313
+ return { defer, deferSql, assemble };
201
314
  }
@@ -1,24 +1,51 @@
1
- import type { AdapterModel } from "../adapters/adapter-model.js";
2
- import type { Contract } from "../contracts/contract.js";
3
- import type { ScalarField } from "../contracts/field.js";
1
+ import type { AvAdapterModel } from "../adapters/adapter-model.js";
2
+ import type { AvContract } from "../contracts/contract.js";
3
+ import type { AvScalarField } from "../contracts/field.js";
4
4
  import type { SemanticOperationArguments } from "../operations/operation-validator.js";
5
+ import { AvCallerDataError } from "../runtime/caller-data.copier.js";
5
6
  import { type ReadProjectionPlan } from "../runtime/computed-read-runtime.js";
6
7
  import type { FrameworkOperationRequest } from "../runtime/operation-request.js";
7
- import type { OperationFailureResponse } from "../runtime/operation-response.js";
8
+ import type { AvOperationFailureResponse } from "../runtime/operation-response.js";
8
9
  import type { OperationPipelineDependencies } from "../runtime/operation-runtime.js";
9
10
  import type { CascadeClosure } from "../runtime/referential-action.js";
10
11
  import type { OperationFingerprint } from "./deferred-operation.js";
11
- import type { TransactionReference } from "./transaction-reference.js";
12
+ import type { PlannedSqlStatement, ValidatedSqlStatement } from "./sql-statement.js";
13
+ import type { AvTransactionReference } from "./transaction-reference.js";
14
+ import { type TransactionSlotShape } from "./transaction-reference.js";
15
+ import { type TransactionReferenceCandidateSlot } from "./transaction-reference-collector.js";
12
16
  import type { FrameworkTransactionRequest, TransactionOperationOrigin } from "./transaction-request.js";
13
- export type TransactionReferenceCandidateSlot = {
14
- readonly path: readonly (string | number)[];
15
- readonly field: ScalarField<Contract>;
16
- readonly candidate: unknown;
17
+ /**
18
+ * Where a plan's step arguments came from, so the validator knows whether to copy
19
+ * them at the door (see `ArgumentsSource`):
20
+ *
21
+ * - `"caller"` — `framework.executeTransaction`'s caller's own objects: every step's
22
+ * arguments are copied when the plan is handed in, before the validator's first
23
+ * await, so a step revoked or changed after the call is never read again;
24
+ * - `"owned"` — a plan the protocol decoder parsed, or the typed runner assembled
25
+ * from its builders' copies; `refused` names the steps whose arguments a builder
26
+ * could not copy, answered at their turn, and `statements` the steps that are
27
+ * `appTx.$sql` statements, which only the typed runner builds: they have no wire
28
+ * form, so no plan a caller or a remote client hands in can hold one.
29
+ */
30
+ export type PlanArguments = {
31
+ readonly source: "caller";
32
+ } | {
33
+ readonly source: "owned";
34
+ readonly refused?: ReadonlyMap<number, AvCallerDataError>;
35
+ readonly statements?: ReadonlyMap<number, PlannedSqlStatement>;
17
36
  };
37
+ export type { TransactionReferenceCandidateSlot } from "./transaction-reference-collector.js";
38
+ /** One validated Transaction Slot: where it is, what it holds, and its reference. */
18
39
  export type TransactionReferenceSlot = {
19
40
  readonly path: readonly (string | number)[];
20
- readonly field: ScalarField<Contract>;
21
- readonly reference: TransactionReference;
41
+ /** The destination field. */
42
+ readonly field: AvScalarField<AvContract>;
43
+ readonly shape: TransactionSlotShape;
44
+ /** The slot is a scalar value of mutation data: what it resolves to is written. */
45
+ readonly written: boolean;
46
+ /** The source field, under its own step's Contract: what the slot receives. */
47
+ readonly source: AvScalarField<AvContract>;
48
+ readonly reference: AvTransactionReference;
22
49
  };
23
50
  export type CandidateTransactionOperation = {
24
51
  readonly index: number;
@@ -29,45 +56,50 @@ export type CandidateTransactionOperation = {
29
56
  readonly candidates: readonly TransactionReferenceCandidateSlot[];
30
57
  };
31
58
  export type ValidatedTransactionOperation = {
59
+ readonly kind: "operation";
32
60
  readonly index: number;
33
61
  readonly request: FrameworkOperationRequest;
34
62
  /**
35
- * The Contract of this operation's own origin: the one it was validated
36
- * against, the one it runs under, and the one a later `$ref` reads its source
37
- * field from. One plan may carry steps of both origins.
63
+ * The Contract of this operation's origin, which is the plan's: the one it was
64
+ * validated against, the one it runs under, and the one a later `$ref` reads its
65
+ * source field from.
38
66
  */
39
- readonly contract: Contract;
67
+ readonly contract: AvContract;
40
68
  readonly arguments: SemanticOperationArguments;
41
69
  readonly projection: ReadProjectionPlan | undefined;
42
70
  readonly fingerprint: OperationFingerprint;
43
71
  readonly references: readonly TransactionReferenceSlot[];
44
72
  };
73
+ /** One validated plan step: a standard operation, or an `appTx.$sql` statement. */
74
+ export type ValidatedTransactionStep = ValidatedTransactionOperation | ValidatedSqlStatement;
45
75
  export type ValidatedTransactionPlan = {
46
- readonly operations: readonly ValidatedTransactionOperation[];
76
+ readonly operations: readonly ValidatedTransactionStep[];
47
77
  };
48
78
  /**
49
79
  * What validating a plan needs beyond one operation's pipeline: the cascade
50
80
  * closure over the Adapter's referential actions, resolved once when the
51
- * Framework is constructed. The create requirements are not among them: they
81
+ * Framework is constructed. The record-write facts are not among them: they
52
82
  * are checked when each operation runs, after its pipes.
53
83
  */
54
- export type TransactionPlanDependencies<M extends AdapterModel> = Omit<OperationPipelineDependencies<M>, "createRequirements"> & {
84
+ export type TransactionPlanDependencies<M extends AvAdapterModel> = Omit<OperationPipelineDependencies<M>, "recordWrites" | "contexts" | "fieldStages"> & {
55
85
  readonly cascades: CascadeClosure;
86
+ /** Whether the Adapter declares `sqlStatements`: read once, at construction. */
87
+ readonly sqlStatements: boolean;
56
88
  };
57
89
  export type TransactionPlanValidationResult = {
58
90
  readonly ok: true;
59
91
  readonly plan: ValidatedTransactionPlan;
60
92
  } | {
61
93
  readonly ok: false;
62
- readonly response: OperationFailureResponse;
94
+ readonly response: AvOperationFailureResponse;
63
95
  };
64
96
  /**
65
97
  * The refusal of a plan on a Contract without transaction plans (`A2002`, one `V1006`
66
98
  * at `["operations"]`). The one spelling — the protocol's absence answer for
67
99
  * `/_transactions` is this envelope too.
68
100
  */
69
- export declare function transactionsUnavailableFailure(): OperationFailureResponse;
101
+ export declare function transactionsUnavailableFailure(): AvOperationFailureResponse;
70
102
  /**
71
103
  * Whole-plan Framework Validation Layer for transaction structure and identity.
72
104
  */
73
- export declare function validateTransactionPlan<M extends AdapterModel>(dependencies: TransactionPlanDependencies<M>, request: FrameworkTransactionRequest, origins?: readonly TransactionOperationOrigin[]): Promise<TransactionPlanValidationResult>;
105
+ export declare function validateTransactionPlan<M extends AvAdapterModel>(dependencies: TransactionPlanDependencies<M>, request: FrameworkTransactionRequest, origins?: readonly TransactionOperationOrigin[], planArguments?: PlanArguments): Promise<TransactionPlanValidationResult>;