@aventara/core 1.0.0-rc.0 → 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 (242) hide show
  1. package/CHANGELOG.md +1140 -0
  2. package/README.md +224 -57
  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 +9 -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 -29
  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/{json → avz}/avz.js +150 -8
  19. package/dist/{json → avz}/index.d.ts +2 -1
  20. package/dist/{json → avz}/json-shape.registry.d.ts +7 -7
  21. package/dist/{json → avz}/zod-issue.translator.d.ts +8 -2
  22. package/dist/{json → avz}/zod-issue.translator.js +7 -0
  23. package/dist/compiler/contract-compiler-diagnostic.d.ts +31 -5
  24. package/dist/compiler/contract.compiler.d.ts +18 -18
  25. package/dist/compiler/contract.compiler.js +548 -441
  26. package/dist/compiler/create-requirements.projector.d.ts +49 -0
  27. package/dist/compiler/create-requirements.projector.js +423 -0
  28. package/dist/compiler/field-validator.compiler.d.ts +47 -0
  29. package/dist/compiler/field-validator.compiler.js +238 -0
  30. package/dist/config/any-framework-config.d.ts +19 -12
  31. package/dist/config/config-diagnostic.d.ts +11 -4
  32. package/dist/config/config-layer.d.ts +15 -6
  33. package/dist/config/config.resolver.d.ts +74 -31
  34. package/dist/config/config.resolver.js +108 -44
  35. package/dist/config/config.validator.d.ts +7 -7
  36. package/dist/config/config.validator.js +581 -72
  37. package/dist/config/define-resource.d.ts +57 -0
  38. package/dist/config/define-resource.js +14 -0
  39. package/dist/config/effective-fields.d.ts +19 -23
  40. package/dist/config/entrypoint.normalizer.d.ts +1 -1
  41. package/dist/config/exact-framework-config.d.ts +280 -0
  42. package/dist/config/field-compute.resolver.d.ts +19 -0
  43. package/dist/config/field-compute.resolver.js +115 -0
  44. package/dist/config/field-pipeline-config.d.ts +47 -0
  45. package/dist/config/forced-operation.validator.d.ts +10 -0
  46. package/dist/config/forced-operation.validator.js +66 -0
  47. package/dist/config/framework-config.d.ts +110 -39
  48. package/dist/config/framework-exemptions-config.d.ts +91 -0
  49. package/dist/config/framework-exemptions-config.js +1 -0
  50. package/dist/config/framework-field-definition.d.ts +78 -0
  51. package/dist/config/framework-field-definition.js +28 -0
  52. package/dist/config/framework-resources-config.d.ts +116 -0
  53. package/dist/config/framework-resources-config.js +1 -0
  54. package/dist/config/pipeline-config.d.ts +56 -20
  55. package/dist/config/pipeline-tree.resolver.d.ts +79 -0
  56. package/dist/config/pipeline-tree.resolver.js +220 -0
  57. package/dist/config/stage-type.eraser.d.ts +65 -0
  58. package/dist/config/stage-type.eraser.js +1 -0
  59. package/dist/contracts/capability.d.ts +11 -11
  60. package/dist/contracts/client-contract-structure.validator.d.ts +323 -28
  61. package/dist/contracts/client-contract-structure.validator.js +152 -8
  62. package/dist/contracts/contract-canonicalizer.d.ts +19 -3
  63. package/dist/contracts/contract-canonicalizer.js +141 -28
  64. package/dist/contracts/contract-hash.d.ts +12 -7
  65. package/dist/contracts/contract-hash.js +3 -2
  66. package/dist/contracts/contract-limits.d.ts +4 -1
  67. package/dist/contracts/contract-limits.js +1 -0
  68. package/dist/contracts/contract-lookup.d.ts +5 -5
  69. package/dist/contracts/contract-protocol.d.ts +4 -4
  70. package/dist/contracts/contract.d.ts +24 -16
  71. package/dist/contracts/create-requirements.d.ts +35 -0
  72. package/dist/contracts/create-requirements.js +1 -0
  73. package/dist/contracts/enum-definition.d.ts +1 -1
  74. package/dist/contracts/field-check.d.ts +101 -0
  75. package/dist/contracts/field-check.js +1 -0
  76. package/dist/contracts/field.d.ts +52 -42
  77. package/dist/contracts/identifier.d.ts +4 -4
  78. package/dist/contracts/json-shape.d.ts +12 -1
  79. package/dist/contracts/lifecycle-trait.d.ts +2 -2
  80. package/dist/contracts/resource-operations.d.ts +28 -28
  81. package/dist/contracts/resource.d.ts +15 -9
  82. package/dist/contracts/scalar-value-type.d.ts +15 -15
  83. package/dist/contracts/scalar.d.ts +3 -3
  84. package/dist/contracts/transaction-capability.d.ts +1 -1
  85. package/dist/contracts/wire-scalar-format.d.ts +4 -4
  86. package/dist/framework/contract-view.d.ts +213 -147
  87. package/dist/framework/framework-construction.error.d.ts +10 -10
  88. package/dist/framework/framework-construction.error.js +2 -2
  89. package/dist/framework/framework.d.ts +47 -23
  90. package/dist/framework/framework.factory.d.ts +8 -6
  91. package/dist/framework/framework.factory.js +40 -20
  92. package/dist/framework/operation-facade.d.ts +123 -52
  93. package/dist/framework/operation-facade.js +9 -1
  94. package/dist/index.d.ts +55 -50
  95. package/dist/index.js +6 -6
  96. package/dist/internal.d.ts +15 -10
  97. package/dist/internal.js +3 -1
  98. package/dist/operations/operation-arguments.d.ts +267 -202
  99. package/dist/operations/operation-call.d.ts +27 -28
  100. package/dist/operations/operation-identity.d.ts +10 -10
  101. package/dist/operations/operation-result.d.ts +21 -21
  102. package/dist/operations/operation-validator-core.d.ts +6 -6
  103. package/dist/operations/operation-validator-core.js +13 -2
  104. package/dist/operations/operation-validator.d.ts +9 -9
  105. package/dist/operations/projection-scope.resolver.d.ts +6 -6
  106. package/dist/operations/structural-limits.walker.d.ts +6 -6
  107. package/dist/operations/structural-limits.walker.js +145 -0
  108. package/dist/operations/validation-code.d.ts +11 -6
  109. package/dist/operations/validation-code.js +4 -0
  110. package/dist/operations/write-scope.resolver.d.ts +6 -6
  111. package/dist/protocol/absent-route.responder.d.ts +13 -12
  112. package/dist/protocol/absent-route.responder.js +19 -19
  113. package/dist/protocol/contract-document.responder.d.ts +3 -3
  114. package/dist/protocol/contract-document.responder.js +2 -2
  115. package/dist/protocol/http-request.decoder.d.ts +17 -13
  116. package/dist/protocol/http-request.decoder.js +10 -10
  117. package/dist/protocol/http-request.reader.d.ts +3 -3
  118. package/dist/protocol/http-response.encoder.d.ts +4 -4
  119. package/dist/protocol/http-response.encoder.js +94 -55
  120. package/dist/protocol/http-status.table.d.ts +2 -2
  121. package/dist/protocol/operation-response.guard.d.ts +2 -2
  122. package/dist/protocol/protocol-surface.d.ts +4 -4
  123. package/dist/protocol/protocol.binder.d.ts +50 -27
  124. package/dist/protocol/protocol.binder.js +12 -9
  125. package/dist/protocol/protocol.handler.d.ts +22 -13
  126. package/dist/protocol/protocol.handler.js +44 -9
  127. package/dist/protocol/unmounted-route.error.d.ts +4 -4
  128. package/dist/protocol/unmounted-route.error.js +2 -2
  129. package/dist/runtime/caller-data.copier.d.ts +5 -5
  130. package/dist/runtime/caller-data.copier.js +13 -13
  131. package/dist/runtime/caller-data.door.d.ts +6 -6
  132. package/dist/runtime/caller-data.door.js +6 -4
  133. package/dist/runtime/computed-read-runtime.d.ts +7 -6
  134. package/dist/runtime/computed-read-runtime.js +61 -48
  135. package/dist/runtime/computed-value.error.d.ts +6 -6
  136. package/dist/runtime/computed-value.error.js +3 -3
  137. package/dist/runtime/context-executor.runtime.d.ts +59 -0
  138. package/dist/runtime/context-executor.runtime.js +275 -0
  139. package/dist/runtime/create-requirement.d.ts +10 -81
  140. package/dist/runtime/create-requirement.js +80 -57
  141. package/dist/runtime/decimal.d.ts +2 -2
  142. package/dist/runtime/decimal.js +1 -1
  143. package/dist/runtime/diagnostics-reporter.d.ts +53 -27
  144. package/dist/runtime/diagnostics-reporter.js +24 -0
  145. package/dist/runtime/error-boundary.d.ts +65 -8
  146. package/dist/runtime/error-boundary.js +45 -19
  147. package/dist/runtime/execution-options.d.ts +10 -2
  148. package/dist/runtime/field-check.evaluator.d.ts +29 -0
  149. package/dist/runtime/field-check.evaluator.js +521 -0
  150. package/dist/runtime/field-compute.d.ts +64 -0
  151. package/dist/runtime/field-compute.js +1 -0
  152. package/dist/runtime/field-stage.plan.d.ts +15 -0
  153. package/dist/runtime/field-stage.plan.js +27 -0
  154. package/dist/runtime/field-stage.runtime.d.ts +35 -0
  155. package/dist/runtime/field-stage.runtime.js +143 -0
  156. package/dist/runtime/field-validator.runtime.d.ts +11 -0
  157. package/dist/runtime/field-validator.runtime.js +87 -0
  158. package/dist/runtime/framework-error-class.table.d.ts +33 -0
  159. package/dist/runtime/framework-error-class.table.js +25 -0
  160. package/dist/runtime/framework-error.d.ts +68 -8
  161. package/dist/runtime/framework-error.factory.d.ts +4 -0
  162. package/dist/runtime/framework-error.factory.js +15 -0
  163. package/dist/runtime/framework-error.js +23 -2
  164. package/dist/runtime/interceptor-next.error.d.ts +5 -0
  165. package/dist/runtime/interceptor-next.error.js +6 -0
  166. package/dist/runtime/json-value.d.ts +3 -3
  167. package/dist/runtime/level-lifecycle.runtime.d.ts +25 -0
  168. package/dist/runtime/level-lifecycle.runtime.js +42 -0
  169. package/dist/runtime/misuse-reporter.d.ts +12 -12
  170. package/dist/runtime/mutation-planner.d.ts +19 -10
  171. package/dist/runtime/mutation-planner.js +54 -30
  172. package/dist/runtime/nested-write.walker.d.ts +32 -0
  173. package/dist/runtime/nested-write.walker.js +73 -0
  174. package/dist/runtime/operation-request.d.ts +33 -6
  175. package/dist/runtime/operation-response.d.ts +17 -17
  176. package/dist/runtime/operation-runtime.d.ts +113 -25
  177. package/dist/runtime/operation-runtime.js +395 -74
  178. package/dist/runtime/outcome-mapper.d.ts +16 -5
  179. package/dist/runtime/outcome-mapper.js +23 -6
  180. package/dist/runtime/output-validator.d.ts +10 -10
  181. package/dist/runtime/output-validator.js +3 -3
  182. package/dist/runtime/owned-execution.registry.d.ts +6 -6
  183. package/dist/runtime/pipe-output.validator.d.ts +33 -18
  184. package/dist/runtime/pipe-output.validator.js +12 -12
  185. package/dist/runtime/pipeline.d.ts +196 -34
  186. package/dist/runtime/readonly-value.d.ts +32 -0
  187. package/dist/runtime/readonly-value.js +141 -0
  188. package/dist/runtime/request-envelope.validator.d.ts +3 -3
  189. package/dist/runtime/request-envelope.validator.js +12 -7
  190. package/dist/runtime/request-id.d.ts +1 -1
  191. package/dist/runtime/request-state.d.ts +14 -0
  192. package/dist/runtime/request-state.js +1 -0
  193. package/dist/runtime/request-state.resolver.d.ts +12 -0
  194. package/dist/runtime/request-state.resolver.js +20 -0
  195. package/dist/runtime/scalar-runtime.d.ts +31 -16
  196. package/dist/runtime/scalar-runtime.js +16 -18
  197. package/dist/transactions/deferred-operation.d.ts +35 -20
  198. package/dist/transactions/operation-arguments-encoder.d.ts +3 -3
  199. package/dist/transactions/operation-arguments-encoder.js +2 -2
  200. package/dist/transactions/sql-statement.d.ts +77 -0
  201. package/dist/transactions/sql-statement.js +47 -0
  202. package/dist/transactions/sql-statement.validator.d.ts +44 -0
  203. package/dist/transactions/sql-statement.validator.js +134 -0
  204. package/dist/transactions/transaction-envelope.d.ts +4 -4
  205. package/dist/transactions/transaction-integrity-error.d.ts +6 -6
  206. package/dist/transactions/transaction-integrity-error.js +5 -2
  207. package/dist/transactions/transaction-plan-assembler.d.ts +21 -11
  208. package/dist/transactions/transaction-plan-assembler.js +148 -34
  209. package/dist/transactions/transaction-plan-validator.d.ts +29 -20
  210. package/dist/transactions/transaction-plan-validator.js +70 -38
  211. package/dist/transactions/transaction-reference-collector.d.ts +5 -5
  212. package/dist/transactions/transaction-reference-resolver.d.ts +19 -2
  213. package/dist/transactions/transaction-reference-resolver.js +26 -14
  214. package/dist/transactions/transaction-reference-validator.d.ts +34 -4
  215. package/dist/transactions/transaction-reference-validator.js +58 -26
  216. package/dist/transactions/transaction-reference.d.ts +13 -13
  217. package/dist/transactions/transaction-request.d.ts +18 -5
  218. package/dist/transactions/transaction-response.d.ts +6 -6
  219. package/dist/transactions/transaction-runtime.d.ts +8 -7
  220. package/dist/transactions/transaction-runtime.js +166 -50
  221. package/dist/transactions/transaction-settlement.runtime.d.ts +51 -0
  222. package/dist/transactions/transaction-settlement.runtime.js +120 -0
  223. package/dist/transactions/transaction-slot-path-error.d.ts +4 -4
  224. package/dist/transactions/transaction-slot-path-error.js +2 -2
  225. package/dist/transactions/transaction-slot-writer.js +2 -2
  226. package/dist/transactions/transaction-stage.runtime.d.ts +81 -0
  227. package/dist/transactions/transaction-stage.runtime.js +123 -0
  228. package/package.json +6 -5
  229. package/src/runtime/field-check.evaluator.ts +720 -0
  230. package/dist/config/define-fields.d.ts +0 -42
  231. package/dist/config/define-fields.js +0 -3
  232. package/dist/config/framework-behaviors-config.d.ts +0 -30
  233. package/dist/config/framework-fields-config.d.ts +0 -42
  234. package/dist/config/framework-restrictions-config.d.ts +0 -142
  235. package/dist/json/avz.d.ts +0 -96
  236. package/dist/runtime/field-behavior.d.ts +0 -48
  237. /package/dist/{config/framework-behaviors-config.js → adapters/adapter-sql-statement.js} +0 -0
  238. /package/dist/{config/framework-fields-config.js → adapters/adapter-transaction-executor.interface.js} +0 -0
  239. /package/dist/{json → avz}/index.js +0 -0
  240. /package/dist/{json → avz}/json-shape.registry.js +0 -0
  241. /package/dist/config/{framework-restrictions-config.js → exact-framework-config.js} +0 -0
  242. /package/dist/{runtime/field-behavior.js → config/field-pipeline-config.js} +0 -0
@@ -10,13 +10,16 @@ function literal(values) {
10
10
  return { is: "literal", values };
11
11
  }
12
12
  function list(item) {
13
- return { is: "list", item, nonEmpty: false, unique: false };
13
+ return { is: "list", item, minimum: 0, unique: false };
14
14
  }
15
15
  function nonEmptyList(item) {
16
- return { is: "list", item, nonEmpty: true, unique: false };
16
+ return { is: "list", item, minimum: 1, unique: false };
17
+ }
18
+ function pairOrMoreList(item) {
19
+ return { is: "list", item, minimum: 2, unique: false };
17
20
  }
18
21
  function uniqueList(item) {
19
- return { is: "list", item, nonEmpty: false, unique: true };
22
+ return { is: "list", item, minimum: 0, unique: true };
20
23
  }
21
24
  function registry(entry) {
22
25
  return { is: "registry", entry };
@@ -93,6 +96,127 @@ const RELATION_MUTATION = union(list(literal(RELATION_MUTATION_DIRECTIVES)), obj
93
96
  directives: list(literal(RELATION_MUTATION_DIRECTIVES)),
94
97
  scopes: WRITE_SCOPE_LIST,
95
98
  }));
99
+ const NAMED_FORMATS = [
100
+ "lowercase",
101
+ "uppercase",
102
+ "email",
103
+ "url",
104
+ "emoji",
105
+ "uuid",
106
+ "guid",
107
+ "nanoid",
108
+ "cuid",
109
+ "cuid2",
110
+ "ulid",
111
+ "xid",
112
+ "ksuid",
113
+ "datetime",
114
+ "date",
115
+ "time",
116
+ "duration",
117
+ "ipv4",
118
+ "ipv6",
119
+ "cidrv4",
120
+ "cidrv6",
121
+ "base64",
122
+ "base64url",
123
+ "json_string",
124
+ "e164",
125
+ "credit_card",
126
+ "iban",
127
+ "jwt",
128
+ ];
129
+ const STRING_FORMAT_CHECK = union(object({
130
+ check: literal(["string_format"]),
131
+ format: literal(["regex"]),
132
+ pattern: object({ source: STRING, flags: STRING }),
133
+ }), object({
134
+ check: literal(["string_format"]),
135
+ format: literal(["includes"]),
136
+ includes: STRING,
137
+ }), object({
138
+ check: literal(["string_format"]),
139
+ format: literal(["starts_with"]),
140
+ prefix: STRING,
141
+ }), object({
142
+ check: literal(["string_format"]),
143
+ format: literal(["ends_with"]),
144
+ suffix: STRING,
145
+ }), object({
146
+ check: literal(["string_format"]),
147
+ format: literal(NAMED_FORMATS),
148
+ }));
149
+ const STRING_LENGTH_CHECKS = {
150
+ max_length: object({ check: literal(["max_length"]), maximum: NUMBER }),
151
+ min_length: object({ check: literal(["min_length"]), minimum: NUMBER }),
152
+ length_equals: object({ check: literal(["length_equals"]), length: NUMBER }),
153
+ string_format: STRING_FORMAT_CHECK,
154
+ };
155
+ const FIELD_CHECK = {
156
+ is: "variants",
157
+ key: "check",
158
+ arms: {
159
+ less_than: object({
160
+ check: literal(["less_than"]),
161
+ value: union(NUMBER, STRING),
162
+ inclusive: BOOLEAN,
163
+ }),
164
+ greater_than: object({
165
+ check: literal(["greater_than"]),
166
+ value: union(NUMBER, STRING),
167
+ inclusive: BOOLEAN,
168
+ }),
169
+ multiple_of: object({
170
+ check: literal(["multiple_of"]),
171
+ value: union(NUMBER, STRING),
172
+ }),
173
+ max_length: object({ check: literal(["max_length"]), maximum: NUMBER }, { list: literal([true]) }),
174
+ min_length: object({ check: literal(["min_length"]), minimum: NUMBER }, { list: literal([true]) }),
175
+ length_equals: STRING_LENGTH_CHECKS.length_equals,
176
+ string_format: STRING_FORMAT_CHECK,
177
+ max_size: object({ check: literal(["max_size"]), maximum: NUMBER }),
178
+ min_size: object({ check: literal(["min_size"]), minimum: NUMBER }),
179
+ size_equals: object({ check: literal(["size_equals"]), size: NUMBER }),
180
+ },
181
+ };
182
+ const JSON_STRING_CHECK = {
183
+ is: "variants",
184
+ key: "check",
185
+ arms: STRING_LENGTH_CHECKS,
186
+ };
187
+ const JSON_NUMBER_CHECK = {
188
+ is: "variants",
189
+ key: "check",
190
+ arms: {
191
+ less_than: object({
192
+ check: literal(["less_than"]),
193
+ value: NUMBER,
194
+ inclusive: BOOLEAN,
195
+ }),
196
+ greater_than: object({
197
+ check: literal(["greater_than"]),
198
+ value: NUMBER,
199
+ inclusive: BOOLEAN,
200
+ }),
201
+ multiple_of: object({ check: literal(["multiple_of"]), value: NUMBER }),
202
+ },
203
+ };
204
+ const JSON_LIST_CHECK = {
205
+ is: "variants",
206
+ key: "check",
207
+ arms: {
208
+ max_length: object({
209
+ check: literal(["max_length"]),
210
+ maximum: NUMBER,
211
+ list: literal([true]),
212
+ }),
213
+ min_length: object({
214
+ check: literal(["min_length"]),
215
+ minimum: NUMBER,
216
+ list: literal([true]),
217
+ }),
218
+ },
219
+ };
96
220
  const SCALAR_FIELD = object({
97
221
  kind: literal(["scalar"]),
98
222
  type: union(object({ scalar: STRING }), object({ enum: STRING })),
@@ -107,7 +231,11 @@ const SCALAR_FIELD = object({
107
231
  create: list(literal(SCALAR_MUTATION_DIRECTIVES)),
108
232
  update: list(literal(SCALAR_MUTATION_DIRECTIVES)),
109
233
  }),
110
- }, { format: STRING, json: { is: "jsonSchema" } });
234
+ }, {
235
+ format: STRING,
236
+ json: { is: "jsonSchema" },
237
+ validators: list(FIELD_CHECK),
238
+ });
111
239
  const RELATION_FIELD = object({
112
240
  kind: literal(["relation"]),
113
241
  target: STRING,
@@ -162,6 +290,12 @@ const RESOURCE = object({
162
290
  }),
163
291
  upsert: object({}, { unique: OPERATION_AVAILABILITY }),
164
292
  }),
293
+ }, {
294
+ createRequirements: object({}, {
295
+ required: nonEmptyList(STRING),
296
+ oneOf: nonEmptyList(pairOrMoreList(STRING)),
297
+ parentSupplies: registry(registry(nonEmptyList(STRING))),
298
+ }),
165
299
  });
166
300
  export const CLIENT_CONTRACT_STRUCTURE = object({
167
301
  scalars: registry(object({ builtin: literal([true]) })),
@@ -173,6 +307,7 @@ export const CLIENT_CONTRACT_STRUCTURE = object({
173
307
  maxListLimit: NUMBER,
174
308
  maxTransactionOperations: NUMBER,
175
309
  maxBooleanNodes: NUMBER,
310
+ maxJsonDepth: NUMBER,
176
311
  }),
177
312
  transactions: literal(TRANSACTION_CAPABILITIES),
178
313
  protocol: object({
@@ -272,13 +407,20 @@ function jsonSchemaDefect(value, path, depth) {
272
407
  switch (keys) {
273
408
  case "type":
274
409
  return literalDefect(JSON_SCHEMA_SCALAR_TYPES, schema.type, `${path}.type`, depth + 1);
410
+ case "checks,type":
411
+ return (literalDefect(["string", "number", "integer"], schema.type, `${path}.type`, depth + 1) ??
412
+ defectOf(list(schema.type === "string" ? JSON_STRING_CHECK : JSON_NUMBER_CHECK), schema.checks, `${path}.checks`, depth + 1));
413
+ case "checks,items,type":
414
+ return (literalDefect(["array"], schema.type, `${path}.type`, depth + 1) ??
415
+ child("items", schema.items) ??
416
+ defectOf(list(JSON_LIST_CHECK), schema.checks, `${path}.checks`, depth + 1));
275
417
  case "const":
276
418
  return Object.is(schema.const, null)
277
419
  ? undefined
278
420
  : defectOf(JSON_PRIMITIVE, schema.const, `${path}.const`, depth + 1);
279
421
  case "enum,type":
280
422
  return (literalDefect(["string"], schema.type, `${path}.type`, depth + 1) ??
281
- defectOf({ is: "list", item: STRING, nonEmpty: true, unique: true }, schema.enum, `${path}.enum`, depth + 1));
423
+ defectOf({ is: "list", item: STRING, minimum: 1, unique: true }, schema.enum, `${path}.enum`, depth + 1));
282
424
  case "additionalProperties,properties,type":
283
425
  case "additionalProperties,properties,required,type": {
284
426
  const typeDefect = literalDefect(["object"], schema.type, `${path}.type`, depth + 1) ??
@@ -296,7 +438,7 @@ function jsonSchemaDefect(value, path, depth) {
296
438
  }
297
439
  if (!Object.hasOwn(schema, "required"))
298
440
  return undefined;
299
- const requiredDefect = defectOf({ is: "list", item: STRING, nonEmpty: false, unique: true }, schema.required, `${path}.required`, depth + 1);
441
+ const requiredDefect = defectOf({ is: "list", item: STRING, minimum: 0, unique: true }, schema.required, `${path}.required`, depth + 1);
300
442
  if (requiredDefect !== undefined)
301
443
  return requiredDefect;
302
444
  const undeclared = schema.required.findIndex((name) => !Object.hasOwn(properties, name));
@@ -348,8 +490,10 @@ function listDefect(node, value, path, depth) {
348
490
  if (kind !== undefined)
349
491
  return kind;
350
492
  const entries = value;
351
- if (node.nonEmpty && entries.length === 0) {
352
- return at(path, depth, "is an empty JSON array, and needs at least one entry");
493
+ if (entries.length < node.minimum) {
494
+ return at(path, depth, entries.length === 0
495
+ ? `is an empty JSON array, and needs at least ${node.minimum === 1 ? "one entry" : "two entries"}`
496
+ : "is a JSON array of one entry, and needs at least two");
353
497
  }
354
498
  const firstIndexOf = new Map();
355
499
  for (let index = 0; index < entries.length; index += 1) {
@@ -1,11 +1,27 @@
1
- import type { Contract } from "./contract.js";
1
+ import type { AvContract } from "./contract.js";
2
2
  /**
3
3
  * Thrown when a value cannot be written as canonical JSON (RFC 8785). It is a
4
4
  * `TypeError`.
5
5
  */
6
- export declare class CanonicalJsonError extends TypeError {
6
+ export declare class AvCanonicalJsonError extends TypeError {
7
7
  }
8
8
  /** Canonical JSON (RFC 8785) for a JSON-safe value. */
9
9
  export declare function canonicalizeJson(value: unknown): string;
10
+ /** One top-level member of a canonical Contract: its key and its value's canonical text. */
11
+ export type CanonicalContractMember = {
12
+ readonly key: string;
13
+ readonly text: string;
14
+ };
15
+ /** The Contract as canonical JSON (RFC 8785), one top-level member at a time, in order. */
16
+ export declare function canonicalizeContractMembers<C extends AvContract>(contract: C): readonly CanonicalContractMember[];
17
+ /** The canonical object text the members write: `{"key":text,…}`, in their order. */
18
+ export declare function joinCanonicalContractMembers(members: readonly CanonicalContractMember[]): string;
10
19
  /** The Contract as canonical JSON (RFC 8785): the same bytes for the same Contract. */
11
- export declare function canonicalizeContract<C extends Contract>(contract: C): string;
20
+ export declare function canonicalizeContract<C extends AvContract>(contract: C): string;
21
+ /** Records `text` as the canonical text `contract` was parsed from. */
22
+ export declare function recordCanonicalContractText(contract: AvContract, text: string): void;
23
+ /**
24
+ * The Contract's canonical text: the text it was identified from, when the compiler
25
+ * recorded one, else written now. Both are the same bytes for the same Contract.
26
+ */
27
+ export declare function canonicalContractTextOf<C extends AvContract>(contract: C): string;
@@ -3,7 +3,7 @@ import { LIFECYCLE_TRAITS } from "./lifecycle-trait.js";
3
3
  import { projectionScopeOf, writeScopeOf } from "./resource-operations.js";
4
4
  const PAGINATION_ORDER = ["limit", "offset", "cursor"];
5
5
  const REDUCER_ORDER = ["$count"];
6
- export class CanonicalJsonError extends TypeError {
6
+ export class AvCanonicalJsonError extends TypeError {
7
7
  }
8
8
  function compareCodeUnits(left, right) {
9
9
  if (left === right) {
@@ -103,7 +103,7 @@ function normalizeJsonSchema(schema) {
103
103
  normalizeJsonSchema(child),
104
104
  ]));
105
105
  }
106
- else if (key === "const" || key === "enum") {
106
+ else if (key === "const" || key === "enum" || key === "checks") {
107
107
  normalized[key] = value;
108
108
  }
109
109
  else {
@@ -173,8 +173,46 @@ function normalizeResource(resource) {
173
173
  fields,
174
174
  identifiers,
175
175
  operations: normalizeOperations(resource.operations),
176
+ ...(resource.createRequirements === undefined
177
+ ? {}
178
+ : {
179
+ createRequirements: normalizeCreateRequirements(resource.createRequirements),
180
+ }),
176
181
  };
177
182
  }
183
+ function isJsonObject(value) {
184
+ return typeof value === "object" && value !== null && !Array.isArray(value);
185
+ }
186
+ function normalizeCreateRequirements(requirements) {
187
+ if (!isJsonObject(requirements)) {
188
+ return requirements;
189
+ }
190
+ const normalized = { ...requirements };
191
+ if (Array.isArray(requirements.required)) {
192
+ normalized.required = normalizeStringSet(requirements.required);
193
+ }
194
+ if (Array.isArray(requirements.oneOf)) {
195
+ normalized.oneOf = requirements.oneOf
196
+ .map((group) => Array.isArray(group) && group.length > 0
197
+ ? [group[0], ...normalizeStringSet(group.slice(1))]
198
+ : group)
199
+ .sort((left, right) => compareCodeUnits(canonicalizeJson(left), canonicalizeJson(right)));
200
+ }
201
+ if (isJsonObject(requirements.parentSupplies)) {
202
+ normalized.parentSupplies = Object.fromEntries(Object.entries(requirements.parentSupplies).map(([parent, byRelation]) => [
203
+ parent,
204
+ isJsonObject(byRelation)
205
+ ? Object.fromEntries(Object.entries(byRelation).map(([relation, members]) => [
206
+ relation,
207
+ Array.isArray(members)
208
+ ? normalizeStringSet(members)
209
+ : members,
210
+ ]))
211
+ : byRelation,
212
+ ]));
213
+ }
214
+ return normalized;
215
+ }
178
216
  function normalizeContract(contract) {
179
217
  const scalars = Object.fromEntries(Object.keys(contract.scalars)
180
218
  .sort(compareCodeUnits)
@@ -201,17 +239,24 @@ function assertValidUnicode(value, path) {
201
239
  if (code >= 0xd800 && code <= 0xdbff) {
202
240
  const next = value.charCodeAt(index + 1);
203
241
  if (!(next >= 0xdc00 && next <= 0xdfff)) {
204
- throw new CanonicalJsonError(`invalid Unicode surrogate at ${path}`);
242
+ throw new AvCanonicalJsonError(`invalid Unicode surrogate at ${path()}`);
205
243
  }
206
244
  index += 1;
207
245
  continue;
208
246
  }
209
247
  if (code >= 0xdc00 && code <= 0xdfff) {
210
- throw new CanonicalJsonError(`invalid Unicode surrogate at ${path}`);
248
+ throw new AvCanonicalJsonError(`invalid Unicode surrogate at ${path()}`);
211
249
  }
212
250
  }
213
251
  }
214
- function canonicalizeValue(value, path) {
252
+ function pathOf(link) {
253
+ const segments = [];
254
+ for (let current = link; current !== undefined; current = current.parent) {
255
+ segments.push(current.segment);
256
+ }
257
+ return `$${segments.reverse().join("")}`;
258
+ }
259
+ function canonicalizePrimitive(value, link) {
215
260
  if (value === null) {
216
261
  return "null";
217
262
  }
@@ -220,47 +265,115 @@ function canonicalizeValue(value, path) {
220
265
  return value ? "true" : "false";
221
266
  case "number": {
222
267
  if (!Number.isFinite(value)) {
223
- throw new CanonicalJsonError(`non-finite number at ${path}`);
268
+ throw new AvCanonicalJsonError(`non-finite number at ${pathOf(link)}`);
224
269
  }
225
270
  const serialized = JSON.stringify(value);
226
271
  if (serialized === undefined) {
227
- throw new CanonicalJsonError(`number at ${path} is not JSON serializable`);
272
+ throw new AvCanonicalJsonError(`number at ${pathOf(link)} is not JSON serializable`);
228
273
  }
229
274
  return serialized;
230
275
  }
231
276
  case "string":
232
- assertValidUnicode(value, path);
277
+ assertValidUnicode(value, () => pathOf(link));
233
278
  return JSON.stringify(value);
234
279
  case "undefined":
235
- throw new CanonicalJsonError(`undefined value at ${path}`);
280
+ throw new AvCanonicalJsonError(`undefined value at ${pathOf(link)}`);
236
281
  case "bigint":
237
282
  case "function":
238
283
  case "symbol":
239
- throw new CanonicalJsonError(`${typeof value} value at ${path} is not JSON serializable`);
240
- case "object":
241
- break;
284
+ throw new AvCanonicalJsonError(`${typeof value} value at ${pathOf(link)} is not JSON serializable`);
285
+ default:
286
+ return undefined;
242
287
  }
243
- if (Array.isArray(value)) {
244
- return `[${Array.prototype.map
245
- .call(value, (entry, index) => canonicalizeValue(entry, `${path}[${index}]`))
246
- .join(",")}]`;
247
- }
248
- const prototype = Object.getPrototypeOf(value);
249
- if (prototype !== Object.prototype && prototype !== null) {
250
- throw new CanonicalJsonError(`non-plain object at ${path} is not canonical JSON`);
288
+ }
289
+ function canonicalizeValue(value, link = undefined) {
290
+ const output = [];
291
+ const stack = [{ kind: "value", value, link }];
292
+ while (stack.length > 0) {
293
+ const task = stack.pop();
294
+ if (task.kind === "text") {
295
+ output.push(task.text);
296
+ continue;
297
+ }
298
+ if (task.kind === "key") {
299
+ assertValidUnicode(task.key, () => `${pathOf(task.link)} key`);
300
+ output.push(`${JSON.stringify(task.key)}:`);
301
+ continue;
302
+ }
303
+ const { value: current, link } = task;
304
+ const primitive = canonicalizePrimitive(current, link);
305
+ if (primitive !== undefined) {
306
+ output.push(primitive);
307
+ continue;
308
+ }
309
+ if (Array.isArray(current)) {
310
+ output.push("[");
311
+ stack.push({ kind: "text", text: "]" });
312
+ for (let index = current.length - 1; index >= 0; index -= 1) {
313
+ if (index in current) {
314
+ stack.push({
315
+ kind: "value",
316
+ value: current[index],
317
+ link: { parent: link, segment: `[${index}]` },
318
+ });
319
+ }
320
+ if (index > 0) {
321
+ stack.push({ kind: "text", text: "," });
322
+ }
323
+ }
324
+ continue;
325
+ }
326
+ const prototype = Object.getPrototypeOf(current);
327
+ if (prototype !== Object.prototype && prototype !== null) {
328
+ throw new AvCanonicalJsonError(`non-plain object at ${pathOf(link)} is not canonical JSON`);
329
+ }
330
+ const record = current;
331
+ const keys = Object.keys(record).sort(compareCodeUnits);
332
+ output.push("{");
333
+ stack.push({ kind: "text", text: "}" });
334
+ for (let index = keys.length - 1; index >= 0; index -= 1) {
335
+ const key = keys[index];
336
+ stack.push({
337
+ kind: "value",
338
+ value: record[key],
339
+ link: { parent: link, segment: `.${key}` },
340
+ });
341
+ stack.push({ kind: "key", key, link });
342
+ if (index > 0) {
343
+ stack.push({ kind: "text", text: "," });
344
+ }
345
+ }
251
346
  }
252
- const record = value;
253
- const entries = Object.keys(record)
347
+ return output.join("");
348
+ }
349
+ export function canonicalizeJson(value) {
350
+ return canonicalizeValue(value);
351
+ }
352
+ export function canonicalizeContractMembers(contract) {
353
+ const record = normalizeContract(contract);
354
+ return Object.keys(record)
254
355
  .sort(compareCodeUnits)
255
356
  .map((key) => {
256
- assertValidUnicode(key, `${path} key`);
257
- return `${JSON.stringify(key)}:${canonicalizeValue(record[key], `${path}.${key}`)}`;
357
+ assertValidUnicode(key, () => "$ key");
358
+ return {
359
+ key,
360
+ text: canonicalizeValue(record[key], {
361
+ parent: undefined,
362
+ segment: `.${key}`,
363
+ }),
364
+ };
258
365
  });
259
- return `{${entries.join(",")}}`;
260
366
  }
261
- export function canonicalizeJson(value) {
262
- return canonicalizeValue(value, "$");
367
+ export function joinCanonicalContractMembers(members) {
368
+ return `{${members.map(({ key, text }) => `${JSON.stringify(key)}:${text}`).join(",")}}`;
263
369
  }
264
370
  export function canonicalizeContract(contract) {
265
- return canonicalizeJson(normalizeContract(contract));
371
+ return joinCanonicalContractMembers(canonicalizeContractMembers(contract));
372
+ }
373
+ const canonicalTexts = new WeakMap();
374
+ export function recordCanonicalContractText(contract, text) {
375
+ canonicalTexts.set(contract, text);
376
+ }
377
+ export function canonicalContractTextOf(contract) {
378
+ return canonicalTexts.get(contract) ?? canonicalizeContract(contract);
266
379
  }
@@ -1,11 +1,16 @@
1
- import type { ClientContract } from "./contract.js";
2
- import type { ContractHash, ContractProtocol } from "./contract-protocol.js";
1
+ import type { AvContractClient } from "./contract.js";
2
+ import type { AvContractHash, AvContractProtocol } from "./contract-protocol.js";
3
3
  /** A ClientContract whose `protocol` does not carry the hash yet. */
4
- export type ClientContractHashInput = Omit<ClientContract, "protocol"> & {
5
- readonly protocol: ContractProtocol;
4
+ export type AvContractClientHashInput = Omit<AvContractClient, "protocol"> & {
5
+ readonly protocol: AvContractProtocol;
6
6
  };
7
- export declare function createClientContractHashInput(contract: ClientContract | ClientContractHashInput): ClientContractHashInput;
7
+ export declare function createClientContractHashInput(contract: AvContractClient | AvContractClientHashInput): AvContractClientHashInput;
8
8
  /** Computes a ClientContract's `sha256:` hash, ignoring `protocol.hash` itself. */
9
- export declare function computeClientContractHash(contract: ClientContract | ClientContractHashInput): Promise<ContractHash>;
9
+ export declare function computeClientContractHash(contract: AvContractClient | AvContractClientHashInput): Promise<AvContractHash>;
10
+ /**
11
+ * The `sha256:` hash of a hash input's canonical text, already written: what
12
+ * {@link computeClientContractHash} answers for the input that text is of.
13
+ */
14
+ export declare function hashCanonicalContractText(canonical: string): Promise<AvContractHash>;
10
15
  /** Whether a ClientContract's `protocol.hash` matches its content. */
11
- export declare function verifyClientContractHash(contract: ClientContract): Promise<boolean>;
16
+ export declare function verifyClientContractHash(contract: AvContractClient): Promise<boolean>;
@@ -10,8 +10,9 @@ function digestHex(digest) {
10
10
  return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
11
11
  }
12
12
  export async function computeClientContractHash(contract) {
13
- const input = createClientContractHashInput(contract);
14
- const canonical = canonicalizeContract(input);
13
+ return hashCanonicalContractText(canonicalizeContract(createClientContractHashInput(contract)));
14
+ }
15
+ export async function hashCanonicalContractText(canonical) {
15
16
  const bytes = new TextEncoder().encode(canonical);
16
17
  const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
17
18
  return `sha256:${digestHex(digest)}`;
@@ -1,5 +1,5 @@
1
1
  /** The request limits a Contract enforces. */
2
- export type ContractLimits = {
2
+ export type AvContractLimits = {
3
3
  /** The largest request body accepted, in bytes. */
4
4
  readonly maxRequestBytes: number;
5
5
  /** How deeply arguments may nest. */
@@ -10,6 +10,8 @@ export type ContractLimits = {
10
10
  readonly maxTransactionOperations: number;
11
11
  /** The most boolean and filter nodes one request may hold. */
12
12
  readonly maxBooleanNodes: number;
13
+ /** How deeply a `json` field's value may nest: its arrays and objects, counted from the value. */
14
+ readonly maxJsonDepth: number;
13
15
  };
14
16
  /** The limits in force when the configuration sets none. */
15
17
  export declare const DEFAULT_CONTRACT_LIMITS: {
@@ -18,4 +20,5 @@ export declare const DEFAULT_CONTRACT_LIMITS: {
18
20
  readonly maxListLimit: 250;
19
21
  readonly maxTransactionOperations: 20;
20
22
  readonly maxBooleanNodes: 50;
23
+ readonly maxJsonDepth: 64;
21
24
  };
@@ -4,4 +4,5 @@ export const DEFAULT_CONTRACT_LIMITS = {
4
4
  maxListLimit: 250,
5
5
  maxTransactionOperations: 20,
6
6
  maxBooleanNodes: 50,
7
+ maxJsonDepth: 64,
7
8
  };
@@ -1,6 +1,6 @@
1
- import type { Contract } from "./contract.js";
2
- import type { Field } from "./field.js";
3
- import type { Resource } from "./resource.js";
1
+ import type { AvContract } from "./contract.js";
2
+ import type { AvField } from "./field.js";
3
+ import type { AvResource } from "./resource.js";
4
4
  /**
5
5
  * Own-property lookups over Contract registries.
6
6
  *
@@ -12,5 +12,5 @@ import type { Resource } from "./resource.js";
12
12
  * must go through here so an unknown key is unknown, whatever its name.
13
13
  */
14
14
  export declare function lookupOwn<T>(registry: Readonly<Record<string, T>> | undefined, key: string): T | undefined;
15
- export declare function lookupResource<C extends Contract>(contract: C, resourceName: string): Resource<C> | undefined;
16
- export declare function lookupField<C extends Contract>(resource: Resource<C> | undefined, fieldName: string): Field<C> | undefined;
15
+ export declare function lookupResource<C extends AvContract>(contract: C, resourceName: string): AvResource<C> | undefined;
16
+ export declare function lookupField<C extends AvContract>(resource: AvResource<C> | undefined, fieldName: string): AvField<C> | undefined;
@@ -5,13 +5,13 @@
5
5
  */
6
6
  export declare const AVENTARA_PROTOCOL_VERSION: 1;
7
7
  /** A Contract hash: `sha256:` followed by the hex digest. */
8
- export type ContractHash = `sha256:${string}`;
8
+ export type AvContractHash = `sha256:${string}`;
9
9
  /** The protocol a Contract is written for. */
10
- export type ContractProtocol = {
10
+ export type AvContractProtocol = {
11
11
  /** The protocol version; see {@link AVENTARA_PROTOCOL_VERSION}. */
12
12
  readonly version: typeof AVENTARA_PROTOCOL_VERSION;
13
13
  };
14
14
  /** A ClientContract's `protocol`: the protocol version and the Contract hash. */
15
- export type ClientContractProtocol = ContractProtocol & {
16
- readonly hash: ContractHash;
15
+ export type AvContractClientProtocol = AvContractProtocol & {
16
+ readonly hash: AvContractHash;
17
17
  };
@@ -1,22 +1,22 @@
1
- import type { ContractLimits } from "./contract-limits.js";
2
- import type { ClientContractProtocol } from "./contract-protocol.js";
3
- import type { EnumDefinition } from "./enum-definition.js";
1
+ import type { AvContractLimits } from "./contract-limits.js";
2
+ import type { AvContractClientProtocol } from "./contract-protocol.js";
3
+ import type { AvEnumDefinition } from "./enum-definition.js";
4
4
  import type { ReferenceWriteLimit } from "./reference-write-limit.js";
5
- import type { Resource } from "./resource.js";
6
- import type { ScalarRegistry } from "./scalar.js";
7
- import type { TransactionCapability } from "./transaction-capability.js";
5
+ import type { AvResource } from "./resource.js";
6
+ import type { AvScalarRegistry } from "./scalar.js";
7
+ import type { AvTransactionCapability } from "./transaction-capability.js";
8
8
  /** What every Contract describes: scalars, enums, Resources, limits and transactions. */
9
- export interface Contract {
9
+ export interface AvContract {
10
10
  /** The scalar types available. */
11
- readonly scalars: ScalarRegistry;
11
+ readonly scalars: AvScalarRegistry;
12
12
  /** The enums, by name. */
13
- readonly enums: Readonly<Record<string, EnumDefinition>>;
13
+ readonly enums: Readonly<Record<string, AvEnumDefinition>>;
14
14
  /** The Resources, by name. */
15
- readonly resources: Readonly<Record<string, Resource<this>>>;
15
+ readonly resources: Readonly<Record<string, AvResource<this>>>;
16
16
  /** The request limits in force. */
17
- readonly limits: ContractLimits;
17
+ readonly limits: AvContractLimits;
18
18
  /** Whether interactive transactions are available. */
19
- readonly transactions: TransactionCapability;
19
+ readonly transactions: AvTransactionCapability;
20
20
  /**
21
21
  * `"uniform"` when one record must write the relations that hold a reference
22
22
  * either all as relations or all through their reference fields; a record
@@ -25,16 +25,24 @@ export interface Contract {
25
25
  readonly referenceWrites?: ReferenceWriteLimit;
26
26
  }
27
27
  /** The Contract compiled from the root configuration. */
28
- export interface CoreContract extends Contract {
28
+ export interface AvContractCore extends AvContract {
29
29
  }
30
30
  /** The Contract in-process calls run under (`framework.application`). */
31
- export interface ApplicationContract extends Contract {
31
+ export interface AvContractApplication extends AvContract {
32
32
  }
33
33
  /**
34
34
  * The Contract remote clients run under, published at `GET /_contract` and
35
35
  * identified by its hash.
36
36
  */
37
- export interface ClientContract extends Contract {
37
+ export interface AvContractClient extends AvContract {
38
38
  /** The protocol version and this Contract's hash. */
39
- readonly protocol: ClientContractProtocol;
39
+ readonly protocol: AvContractClientProtocol;
40
+ }
41
+ /**
42
+ * The Contract an AI agent's calls run under (the `agent` layer), identified by
43
+ * its hash. MCP tools are built from it.
44
+ */
45
+ export interface AvContractAgent extends AvContract {
46
+ /** The protocol version and this Contract's hash. */
47
+ readonly protocol: AvContractClientProtocol;
40
48
  }