@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,12 +1,10 @@
1
- import type { OperationIdentity } from "../operations/operation-identity.js";
2
- import type { ExecutionOptions } from "../runtime/execution-options.js";
3
- import type { OperationFailureResponse } from "../runtime/operation-response.js";
4
- import type { TransactionReference } from "./transaction-reference.js";
5
- import type { TransactionCommittedResponse } from "./transaction-response.js";
1
+ import type { AvOperationIdentity } from "../operations/operation-identity.js";
2
+ import type { AvExecutionOptions } from "../runtime/execution-options.js";
3
+ import type { AvTransactionReference } from "./transaction-reference.js";
6
4
  /** An operation fingerprint: `fp1:` and a hash of the operation and its arguments. */
7
5
  export type OperationFingerprint = `fp1:${string}`;
8
6
  /** One serializable transaction-plan operation node. */
9
- export type DeferredOperation = OperationIdentity & {
7
+ export type DeferredOperation = AvOperationIdentity & {
10
8
  readonly resource: string;
11
9
  readonly args: unknown;
12
10
  readonly fingerprint: OperationFingerprint;
@@ -17,34 +15,51 @@ export type TransactionPlan = {
17
15
  };
18
16
  declare const OPERATION_RESULT: unique symbol;
19
17
  declare const OPERATION_HANDLE: unique symbol;
18
+ /** The origin a handle's builder gives it: `appTx`'s or `clientTx`'s. */
19
+ type HandleOrigin = "application" | "client";
20
+ type AnyOrigin = any;
20
21
  /** Standard-library shapes that are objects but never a projected result row. */
21
22
  export type BuiltinNonRow = Date | RegExp | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown> | PromiseLike<unknown> | ArrayBufferView;
22
23
  /**
23
24
  * The single row behind a result type, or `never` when the result is not one
24
25
  * referenceable row.
25
26
  */
26
- export type SingleRowResult<T> = NonNullable<T> extends readonly unknown[] ? never : NonNullable<T> extends (...args: never[]) => unknown ? never : NonNullable<T> extends BuiltinNonRow ? never : NonNullable<T> extends object ? Extract<keyof NonNullable<T>, string> extends never ? never : NonNullable<T> : never;
27
+ export type AvSingleRowResult<T> = NonNullable<T> extends readonly unknown[] ? never : NonNullable<T> extends (...args: never[]) => unknown ? never : NonNullable<T> extends BuiltinNonRow ? never : NonNullable<T> extends object ? Extract<keyof NonNullable<T>, string> extends never ? never : NonNullable<T> : never;
27
28
  /** The field names a result row can be referenced by. */
28
- export type ReferenceableField<T> = Extract<keyof SingleRowResult<T>, string>;
29
+ export type AvReferenceableField<T> = Extract<keyof AvSingleRowResult<T>, string>;
29
30
  /** Builds a `$ref` to one field of this handle's row, typed as that field. */
30
- export type ReferenceBuilder<T> = <F extends ReferenceableField<T>>(field: F) => TransactionReference<SingleRowResult<T>[F]>;
31
+ export type AvReferenceBuilder<T> = <F extends AvReferenceableField<T>>(field: F) => AvTransactionReference<AvSingleRowResult<T>[F]>;
31
32
  /** Contributes `$ref` only where the result is a referenceable single row. */
32
- export type OperationReferenceSurface<T> = [SingleRowResult<T>] extends [never] ? {} : {
33
- readonly $ref: ReferenceBuilder<T>;
33
+ export type AvOperationReferenceSurface<T> = [AvSingleRowResult<T>] extends [
34
+ never
35
+ ] ? {} : {
36
+ readonly $ref: AvReferenceBuilder<T>;
34
37
  };
35
- /** An opaque deferred-operation handle. */
36
- export type Operation<T> = {
37
- readonly [OPERATION_HANDLE]: true;
38
+ /**
39
+ * The opaque part of every deferred-operation handle: the result type `T` its
40
+ * transaction slot resolves to, and the origin of the builder that made it
41
+ * (`appTx` is `"application"`, `clientTx` is `"client"`; left out, either).
42
+ * Type-level only: a handle holds neither at runtime.
43
+ */
44
+ export interface AvOperationHandle<T, Origin extends HandleOrigin = AnyOrigin> {
45
+ readonly [OPERATION_HANDLE]: Origin;
38
46
  readonly [OPERATION_RESULT]?: T;
39
- } & OperationReferenceSurface<T>;
47
+ }
48
+ /**
49
+ * An opaque deferred-operation handle: its result type and origin
50
+ * ({@link AvOperationHandle}), and `$ref` where the result is one row.
51
+ */
52
+ export type AvOperation<T, Origin extends HandleOrigin = AnyOrigin> = AvOperationHandle<T, Origin> & AvOperationReferenceSurface<T>;
40
53
  /** Ordered results of a tuple of handles, positionally typed. */
41
- export type TransactionResults<Ops extends readonly Operation<unknown>[]> = {
42
- readonly [I in keyof Ops]: Ops[I] extends Operation<infer R> ? R : never;
54
+ export type AvTransactionResults<Ops extends readonly AvOperation<unknown>[]> = {
55
+ readonly [I in keyof Ops]: Ops[I] extends AvOperation<infer R> ? R : never;
43
56
  };
44
57
  /**
45
58
  * `framework.transaction`'s type. It infers the handle tuple without `as const`
46
- * and resolves the committed response (`A1009`) with each handle's result in
47
- * plan order, or the failure response.
59
+ * and resolves each handle's result in plan order once the transaction
60
+ * committed, or throws its failure as the `AvError` subclass of the code's class
61
+ * (`cause.operation` names the failing step). The handles are all `appTx`
62
+ * handles or all `clientTx` handles: a list that mixes them is a type error.
48
63
  */
49
- export type TransactionRunner = <const Ops extends readonly Operation<unknown>[]>(operations: Ops, options?: ExecutionOptions) => Promise<TransactionCommittedResponse<TransactionResults<Ops>> | OperationFailureResponse>;
64
+ export type AvTransactionRunner = <const Ops extends readonly AvOperation<unknown, "application">[] | readonly AvOperation<unknown, "client">[]>(operations: Ops, options?: AvExecutionOptions) => Promise<AvTransactionResults<Ops>>;
50
65
  export {};
@@ -1,7 +1,7 @@
1
- import type { Contract } from "../contracts/contract.js";
2
- import type { OperationIdentity } from "../operations/operation-identity.js";
1
+ import type { AvContract } from "../contracts/contract.js";
2
+ import type { AvOperationIdentity } from "../operations/operation-identity.js";
3
3
  import type { SemanticOperationArguments } from "../operations/operation-validator.js";
4
4
  /** Encodes validated application arguments into the wire scalar form. */
5
- export declare function encodeOperationArgumentsForWire(contract: Contract, operation: OperationIdentity & {
5
+ export declare function encodeOperationArgumentsForWire(contract: AvContract, operation: AvOperationIdentity & {
6
6
  readonly resource: string;
7
7
  }, args: SemanticOperationArguments): unknown;
@@ -1,6 +1,6 @@
1
1
  import { lookupField, lookupResource } from "../contracts/contract-lookup.js";
2
2
  import { encodeBase64 } from "../contracts/wire-scalar-format.js";
3
- import { Decimal } from "../runtime/decimal.js";
3
+ import { AvDecimal } from "../runtime/decimal.js";
4
4
  import { isRelationMutationDirective, RELATION_MUTATION_RECORD_SITES, } from "../runtime/mutation-planner.js";
5
5
  import { isTransactionReferenceCandidate } from "./transaction-reference.js";
6
6
  function isPlainRecord(value) {
@@ -27,7 +27,7 @@ function encodeScalarAtom(field, value) {
27
27
  case "bigint":
28
28
  return typeof value === "bigint" ? value.toString(10) : value;
29
29
  case "decimal":
30
- return value instanceof Decimal ? value.toString() : value;
30
+ return value instanceof AvDecimal ? value.toString() : value;
31
31
  case "datetime":
32
32
  return value instanceof Date ? value.toISOString() : value;
33
33
  case "bytes":
@@ -0,0 +1,77 @@
1
+ import type { AvAdapterSqlValue } from "../adapters/adapter-sql-statement.js";
2
+ import type { AvContract } from "../contracts/contract.js";
3
+ import type { AvScalarField } from "../contracts/field.js";
4
+ import type { AvCallerDataError } from "../runtime/caller-data.copier.js";
5
+ import type { AvOperation } from "./deferred-operation.js";
6
+ import type { AvTransactionReference } from "./transaction-reference.js";
7
+ /**
8
+ * One value an `appTx.$sql` template binds: a primitive, a `Date`, an `AvDecimal`, a
9
+ * `Uint8Array`, a JSON value (a plain object or array, bound as JSON text — cast it,
10
+ * `${value}::jsonb`), or a `$ref` to an earlier step's field, resolved when the
11
+ * earlier steps have run and then bound like any other value.
12
+ */
13
+ export type SqlStatementValue = AvAdapterSqlValue | AvTransactionReference;
14
+ /**
15
+ * `framework.appTx.$sql`: a developer SQL step, written only as a tagged template —
16
+ * ``framework.appTx.$sql`select pgmq.send('jobs', jsonb_build_object('id', ${ref}))` ``.
17
+ * Every interpolated value is bound as a parameter, never spliced into the text, so
18
+ * the text is static: a table or column name cannot come from a value.
19
+ *
20
+ * The step runs in plan order inside the same database transaction as the other
21
+ * steps; its entry in the committed `data` is the rows the statement returned,
22
+ * typed `Row[]` (`unknown[]` unless `Row` is given). A later step cannot `$ref` a
23
+ * SQL step's rows. No guard, pipe, hook, interceptor or filter runs around it: it
24
+ * has no Resource or operation for one to wrap.
25
+ */
26
+ export type SqlStatementBuilder = <Row = unknown>(strings: TemplateStringsArray, ...values: readonly SqlStatementValue[]) => AvOperation<Row[], "application">;
27
+ /** One value of a planned SQL step, as the typed runner bound it. */
28
+ export type PlannedSqlValue = {
29
+ readonly kind: "value";
30
+ readonly value: unknown;
31
+ }
32
+ /** A `$ref` placeholder standing as the whole value: the source's position and field. */
33
+ | {
34
+ readonly kind: "reference";
35
+ readonly operation: number;
36
+ readonly field: string;
37
+ }
38
+ /** A `$ref` placeholder found inside a value, at `path` within it: refused. */
39
+ | {
40
+ readonly kind: "misplaced-reference";
41
+ readonly path: readonly (string | number)[];
42
+ };
43
+ /**
44
+ * A SQL step as the typed runner hands it to the validator, unvalidated: the
45
+ * template's static text (`undefined` when the call was no genuine tagged
46
+ * template), its values with each `$ref` bound to its source's position, or why the
47
+ * builder could not copy the values.
48
+ */
49
+ export type PlannedSqlStatement = {
50
+ readonly strings: readonly string[] | undefined;
51
+ readonly values: readonly PlannedSqlValue[];
52
+ readonly refused?: AvCallerDataError;
53
+ };
54
+ /** One validated value of a SQL step: bound as it is, or resolved from a `$ref`. */
55
+ export type ValidatedSqlValue = {
56
+ readonly kind: "value";
57
+ readonly value: AvAdapterSqlValue;
58
+ } | {
59
+ readonly kind: "reference";
60
+ readonly operation: number;
61
+ readonly field: string;
62
+ /** The source field, under its own step's Contract: what the value is read as. */
63
+ readonly source: AvScalarField<AvContract>;
64
+ };
65
+ /** A SQL step the Framework Validation Layer accepted. */
66
+ export type ValidatedSqlStatement = {
67
+ readonly kind: "sql";
68
+ readonly index: number;
69
+ readonly strings: readonly string[];
70
+ readonly values: readonly ValidatedSqlValue[];
71
+ };
72
+ /**
73
+ * The static text of a genuine tagged template, read once and copied, or
74
+ * `undefined` when `strings` is not one or does not fit `valueCount` values.
75
+ * Total: a hostile value is `undefined`, never a throw.
76
+ */
77
+ export declare function readSqlTemplate(strings: unknown, valueCount: number): readonly string[] | undefined;
@@ -0,0 +1,47 @@
1
+ function ownData(target, key) {
2
+ const descriptor = Object.getOwnPropertyDescriptor(target, key);
3
+ return descriptor !== undefined && "value" in descriptor
4
+ ? descriptor.value
5
+ : undefined;
6
+ }
7
+ function frozenStrings(value, length) {
8
+ if (!Array.isArray(value) || !Object.isFrozen(value)) {
9
+ return undefined;
10
+ }
11
+ const size = ownData(value, "length");
12
+ if (typeof size !== "number" ||
13
+ size < 1 ||
14
+ (length !== undefined && size !== length)) {
15
+ return undefined;
16
+ }
17
+ const strings = [];
18
+ for (let index = 0; index < size; index += 1) {
19
+ const entry = ownData(value, String(index));
20
+ if (typeof entry !== "string") {
21
+ return undefined;
22
+ }
23
+ strings.push(entry);
24
+ }
25
+ return strings;
26
+ }
27
+ export function readSqlTemplate(strings, valueCount) {
28
+ try {
29
+ if (typeof strings !== "object" || strings === null) {
30
+ return undefined;
31
+ }
32
+ const raw = Object.getOwnPropertyDescriptor(strings, "raw");
33
+ if (raw === undefined || raw.enumerable || !("value" in raw)) {
34
+ return undefined;
35
+ }
36
+ const cooked = frozenStrings(strings, valueCount + 1);
37
+ if (cooked === undefined) {
38
+ return undefined;
39
+ }
40
+ return frozenStrings(raw.value, cooked.length) === undefined
41
+ ? undefined
42
+ : Object.freeze(cooked);
43
+ }
44
+ catch {
45
+ return undefined;
46
+ }
47
+ }
@@ -0,0 +1,44 @@
1
+ import type { AvAdapterSqlValue } from "../adapters/adapter-sql-statement.js";
2
+ import type { AvValidationIssue } from "../operations/validation-code.js";
3
+ import type { MisuseReporter } from "../runtime/misuse-reporter.js";
4
+ import type { AvOperationFailureResponse } from "../runtime/operation-response.js";
5
+ import type { PlannedSqlStatement, ValidatedSqlStatement } from "./sql-statement.js";
6
+ import type { ValidatedTransactionStep } from "./transaction-plan-validator.js";
7
+ type Path = readonly (string | number)[];
8
+ export type SqlStatementValidation = {
9
+ readonly ok: true;
10
+ readonly statement: ValidatedSqlStatement;
11
+ } | {
12
+ readonly ok: false;
13
+ readonly response: AvOperationFailureResponse;
14
+ };
15
+ /** What validating a SQL step needs from the plan around it. */
16
+ export type SqlStatementValidationContext = {
17
+ /** The step's position in the plan. */
18
+ readonly index: number;
19
+ /** The steps validated before it, by position. */
20
+ readonly earlier: readonly ValidatedTransactionStep[];
21
+ /** Whether the Adapter declares `sqlStatements`. */
22
+ readonly available: boolean;
23
+ readonly misuse: MisuseReporter;
24
+ };
25
+ /**
26
+ * One bindable value of a SQL step, in its runtime form, or the issues that refuse
27
+ * it: a primitive (a `number` only when finite), a valid `Date`, an `AvDecimal`, a
28
+ * `Uint8Array`, or a JSON value — a plain object or array, held to the same rules
29
+ * as a `json` field's value. `undefined` and anything else are no value to bind.
30
+ */
31
+ export declare function normalizeSqlValue(value: unknown, path: Path): {
32
+ readonly ok: true;
33
+ readonly value: AvAdapterSqlValue;
34
+ } | {
35
+ readonly ok: false;
36
+ readonly issues: readonly AvValidationIssue[];
37
+ };
38
+ /**
39
+ * Validates one SQL step: the Adapter runs SQL statements, the call was a genuine
40
+ * tagged template, its values could be copied, every value is bindable, and every
41
+ * `$ref` stands as a whole value and reads one field of an earlier single-row step.
42
+ */
43
+ export declare function validateSqlStatement(statement: PlannedSqlStatement, context: SqlStatementValidationContext): SqlStatementValidation;
44
+ export {};
@@ -0,0 +1,134 @@
1
+ import { validationIssue } from "../operations/validation-code.js";
2
+ import { refuseCallerData } from "../runtime/caller-data.door.js";
3
+ import { AvDecimal } from "../runtime/decimal.js";
4
+ import { planStepPath } from "../runtime/error-boundary.js";
5
+ import { operationFailure } from "../runtime/operation-response.js";
6
+ import { mapValidationOutcome } from "../runtime/outcome-mapper.js";
7
+ import { isPlainRecord, normalizeJsonValue, } from "../runtime/scalar-runtime.js";
8
+ import { invalidSourceIndexIssue, referenceSourceAt, referenceSourceField, } from "./transaction-reference-validator.js";
9
+ import { transactionOperationFailure } from "./transaction-response.js";
10
+ function refused(issue, index) {
11
+ return {
12
+ ok: false,
13
+ response: transactionOperationFailure(mapValidationOutcome([issue]), index),
14
+ };
15
+ }
16
+ export function normalizeSqlValue(value, path) {
17
+ if (value === null ||
18
+ typeof value === "string" ||
19
+ typeof value === "boolean" ||
20
+ typeof value === "bigint" ||
21
+ value instanceof AvDecimal ||
22
+ value instanceof Uint8Array) {
23
+ return { ok: true, value };
24
+ }
25
+ if (typeof value === "number") {
26
+ return Number.isFinite(value)
27
+ ? { ok: true, value }
28
+ : {
29
+ ok: false,
30
+ issues: [
31
+ validationIssue("V1004", path, "Value must be a finite number."),
32
+ ],
33
+ };
34
+ }
35
+ if (value instanceof Date) {
36
+ return Number.isNaN(value.getTime())
37
+ ? {
38
+ ok: false,
39
+ issues: [
40
+ validationIssue("V1003", path, "Value must use a valid Date value."),
41
+ ],
42
+ }
43
+ : { ok: true, value };
44
+ }
45
+ if (Array.isArray(value) || isPlainRecord(value)) {
46
+ const json = normalizeJsonValue(value, path, new Set());
47
+ return json.ok
48
+ ? { ok: true, value: json.value }
49
+ : { ok: false, issues: json.issues };
50
+ }
51
+ return {
52
+ ok: false,
53
+ issues: [
54
+ validationIssue("V1001", path, "Value must be a string, number, boolean, bigint, null, Date, Decimal, Uint8Array or JSON value."),
55
+ ],
56
+ };
57
+ }
58
+ export function validateSqlStatement(statement, context) {
59
+ const { index, earlier } = context;
60
+ if (!context.available) {
61
+ const message = "SQL statements are not available on this Adapter.";
62
+ return {
63
+ ok: false,
64
+ response: transactionOperationFailure(operationFailure("A2002", {
65
+ message,
66
+ issues: [validationIssue("V1006", [], message)],
67
+ }), index),
68
+ };
69
+ }
70
+ if (statement.strings === undefined) {
71
+ return refused(validationIssue("V1001", ["strings"], "SQL must be written as a tagged template: framework.appTx.$sql`…`."), index);
72
+ }
73
+ if (statement.refused !== undefined) {
74
+ return refused(refuseCallerData(statement.refused, [...planStepPath(index), "values"], { origin: "application", operation: index }, context.misuse), index);
75
+ }
76
+ const values = [];
77
+ const issues = [];
78
+ for (const [position, planned] of statement.values.entries()) {
79
+ const path = ["values", position];
80
+ switch (planned.kind) {
81
+ case "misplaced-reference":
82
+ return refused(validationIssue("V1010", [...path, ...planned.path, "$ref"], "A transaction reference in a SQL step must be a whole value."), index);
83
+ case "reference": {
84
+ const source = referenceSourceAt(earlier, planned.operation, index);
85
+ if (source === undefined) {
86
+ return refused(invalidSourceIndexIssue([...path, "$ref", "operation"]), index);
87
+ }
88
+ const read = referenceSourceField(source, planned.field, [
89
+ ...path,
90
+ "$ref",
91
+ "path",
92
+ ]);
93
+ if (!read.ok) {
94
+ return refused(read.issue, index);
95
+ }
96
+ if (read.field.kind !== "scalar" || read.field.list) {
97
+ return refused(validationIssue("V1011", [...path, "$ref", "path"], "Transaction reference source is not a single scalar field."), index);
98
+ }
99
+ values.push({
100
+ kind: "reference",
101
+ operation: planned.operation,
102
+ field: planned.field,
103
+ source: read.field,
104
+ });
105
+ break;
106
+ }
107
+ case "value": {
108
+ const normalized = normalizeSqlValue(planned.value, path);
109
+ if (normalized.ok) {
110
+ values.push({ kind: "value", value: normalized.value });
111
+ }
112
+ else {
113
+ issues.push(...normalized.issues);
114
+ }
115
+ break;
116
+ }
117
+ }
118
+ }
119
+ if (issues.length > 0) {
120
+ return {
121
+ ok: false,
122
+ response: transactionOperationFailure(mapValidationOutcome(issues), index),
123
+ };
124
+ }
125
+ return {
126
+ ok: true,
127
+ statement: {
128
+ kind: "sql",
129
+ index,
130
+ strings: statement.strings,
131
+ values,
132
+ },
133
+ };
134
+ }
@@ -1,4 +1,4 @@
1
- import type { ValidationIssue } from "../operations/validation-code.js";
1
+ import type { AvValidationIssue } from "../operations/validation-code.js";
2
2
  export type TransactionEnvelopeSchema = {
3
3
  readonly required: readonly string[];
4
4
  readonly optional?: readonly string[];
@@ -10,7 +10,7 @@ export type TransactionEnvelopeInspection = {
10
10
  readonly values: ReadonlyMap<string, unknown>;
11
11
  } | {
12
12
  readonly ok: false;
13
- readonly issue: ValidationIssue;
13
+ readonly issue: AvValidationIssue;
14
14
  };
15
15
  export type TransactionOperationsInspection = {
16
16
  readonly ok: true;
@@ -18,14 +18,14 @@ export type TransactionOperationsInspection = {
18
18
  readonly length: number;
19
19
  } | {
20
20
  readonly ok: false;
21
- readonly issue: ValidationIssue;
21
+ readonly issue: AvValidationIssue;
22
22
  };
23
23
  export type TransactionOperationEntryInspection = {
24
24
  readonly ok: true;
25
25
  readonly value: unknown;
26
26
  } | {
27
27
  readonly ok: false;
28
- readonly issue: ValidationIssue;
28
+ readonly issue: AvValidationIssue;
29
29
  };
30
30
  /**
31
31
  * The caller uses the returned length and per-index inspector rather than
@@ -1,13 +1,13 @@
1
1
  /**
2
- * The ways an Adapter transaction can break the framework's transaction
3
- * contract. Each is answered `A3002`.
2
+ * The ways an Adapter transaction, or a stage running inside it, can break the
3
+ * framework's transaction contract. Each is answered `A3002` and rolls back.
4
4
  */
5
- export type TransactionIntegrityViolation = "transaction-unavailable" | "resolved-after-abort" | "resolved-incomplete" | "foreign-abort";
5
+ export type AvTransactionIntegrityViolation = "transaction-unavailable" | "resolved-after-abort" | "resolved-incomplete" | "foreign-abort" | "statement-unavailable" | "next-called-twice" | "steps-not-run";
6
6
  /**
7
7
  * Reported to diagnostics when an Adapter transaction breaks the framework's
8
8
  * transaction contract. The caller receives `A3002`.
9
9
  */
10
- export declare class TransactionIntegrityError extends Error {
11
- readonly violation: TransactionIntegrityViolation;
12
- constructor(violation: TransactionIntegrityViolation);
10
+ export declare class AvTransactionIntegrityError extends Error {
11
+ readonly violation: AvTransactionIntegrityViolation;
12
+ constructor(violation: AvTransactionIntegrityViolation);
13
13
  }
@@ -3,12 +3,15 @@ const TRANSACTION_INTEGRITY_MESSAGES = {
3
3
  "resolved-after-abort": "Adapter transaction resolved after the framework requested rollback.",
4
4
  "resolved-incomplete": "Adapter transaction resolved before the plan completed.",
5
5
  "foreign-abort": "Adapter transaction rejected with a rollback request this plan never made.",
6
+ "statement-unavailable": "Adapter declares sqlStatements but its transaction executor has no executeSql.",
7
+ "next-called-twice": "A transaction interceptor called next() more than once; next() runs the plan's steps once.",
8
+ "steps-not-run": "A transaction interceptor resolved without calling next(); the plan's steps never ran.",
6
9
  };
7
- export class TransactionIntegrityError extends Error {
10
+ export class AvTransactionIntegrityError extends Error {
8
11
  violation;
9
12
  constructor(violation) {
10
13
  super(TRANSACTION_INTEGRITY_MESSAGES[violation]);
11
- this.name = "TransactionIntegrityError";
14
+ this.name = "AvTransactionIntegrityError";
12
15
  this.violation = violation;
13
16
  }
14
17
  }
@@ -1,10 +1,14 @@
1
- import type { FrameworkContracts } from "../compiler/contract.compiler.js";
2
- import type { RequestOrigin } from "../config/config-layer.js";
3
- import type { OperationIdentity } from "../operations/operation-identity.js";
1
+ import type { AvContracts } from "../compiler/contract.compiler.js";
2
+ import type { AvOperationIdentity } from "../operations/operation-identity.js";
3
+ import type { AvCallerDataError } from "../runtime/caller-data.copier.js";
4
+ import type { MisuseReporter } from "../runtime/misuse-reporter.js";
4
5
  import type { ClientProtocolIdentity } from "../runtime/operation-request.js";
5
- import type { OperationFailureResponse } from "../runtime/operation-response.js";
6
- import type { Operation, OperationFingerprint } from "./deferred-operation.js";
6
+ import type { AvOperationFailureResponse } from "../runtime/operation-response.js";
7
+ import type { AvOperation, OperationFingerprint } from "./deferred-operation.js";
8
+ import type { PlannedSqlStatement } from "./sql-statement.js";
7
9
  import type { TransactionOperationOrigin } from "./transaction-request.js";
10
+ /** The origin a handle's builder gives it. */
11
+ type HandleOrigin = "application" | "client";
8
12
  /** One wire node, exactly as the transaction runtime receives it. */
9
13
  type WireOperationNode = {
10
14
  readonly resource: string;
@@ -13,20 +17,30 @@ type WireOperationNode = {
13
17
  readonly args: unknown;
14
18
  readonly fingerprint: OperationFingerprint | null;
15
19
  };
20
+ declare const SQL_STEP_NODE: Readonly<{
21
+ fingerprint: null;
22
+ }>;
23
+ type PlanNode = WireOperationNode | typeof SQL_STEP_NODE;
16
24
  export type AssembledTransactionPlan = {
17
25
  readonly ok: true;
18
26
  readonly plan: {
19
- readonly operations: readonly WireOperationNode[];
27
+ readonly operations: readonly PlanNode[];
20
28
  };
21
29
  /** Each operation's own origin, by index (mixed plans). */
22
30
  readonly origins: readonly TransactionOperationOrigin[];
31
+ /** The steps whose arguments their builder could not copy, by index. */
32
+ readonly refused: ReadonlyMap<number, AvCallerDataError>;
33
+ /** The `appTx.$sql` steps, by index, with each `$ref` bound to its source's position. */
34
+ readonly statements: ReadonlyMap<number, PlannedSqlStatement>;
23
35
  } | {
24
36
  readonly ok: false;
25
- readonly response: OperationFailureResponse;
37
+ readonly response: AvOperationFailureResponse;
26
38
  };
27
39
  export type TransactionPlanAssembler = {
28
40
  /** Defers one operation into a handle; nothing runs. */
29
- defer(origin: RequestOrigin, resource: string, identity: OperationIdentity, args: unknown): Operation<unknown>;
41
+ defer(origin: HandleOrigin, resource: string, identity: AvOperationIdentity, args: unknown): AvOperation<unknown>;
42
+ /** Defers one `appTx.$sql` statement into a handle; nothing runs. */
43
+ deferSql(strings: unknown, values: readonly unknown[]): AvOperation<unknown>;
30
44
  /** Binds a list of handles into the passive plan, or refuses it. */
31
45
  assemble(operations: unknown): Promise<AssembledTransactionPlan>;
32
46
  };
@@ -35,5 +49,5 @@ export type TransactionPlanAssembler = {
35
49
  * handle, so a handle another instance built — typed against another model,
36
50
  * bound to other Contracts — is refused rather than run.
37
51
  */
38
- export declare function createTransactionPlanAssembler(contracts: FrameworkContracts, protocol: ClientProtocolIdentity): TransactionPlanAssembler;
52
+ export declare function createTransactionPlanAssembler(contracts: AvContracts, protocol: ClientProtocolIdentity, misuse: MisuseReporter): TransactionPlanAssembler;
39
53
  export {};