@aventara/core 1.0.0-rc.0 → 1.0.0-rc.10

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 (338) hide show
  1. package/CHANGELOG.md +2068 -1
  2. package/ERRORS.md +142 -0
  3. package/README.md +485 -60
  4. package/dist/adapters/adapter-discovery-diagnostic.d.ts +4 -4
  5. package/dist/adapters/adapter-discovery-diagnostic.guidance.d.ts +6 -0
  6. package/dist/adapters/adapter-discovery-diagnostic.guidance.js +7 -0
  7. package/dist/adapters/adapter-field.d.ts +33 -11
  8. package/dist/adapters/adapter-identifier.d.ts +15 -6
  9. package/dist/adapters/adapter-identifier.js +6 -1
  10. package/dist/adapters/adapter-model.d.ts +18 -9
  11. package/dist/adapters/adapter-operation-executor.interface.d.ts +4 -4
  12. package/dist/adapters/adapter-operation.d.ts +21 -6
  13. package/dist/adapters/adapter-resource.d.ts +23 -9
  14. package/dist/adapters/adapter-sql-statement.d.ts +19 -0
  15. package/dist/adapters/adapter-transaction-executor.interface.d.ts +19 -0
  16. package/dist/adapters/adapter.interface.d.ts +59 -29
  17. package/dist/avz/avz-check.factory.d.ts +83 -0
  18. package/dist/avz/avz-check.factory.js +116 -0
  19. package/dist/avz/avz-check.registry.d.ts +35 -0
  20. package/dist/avz/avz-check.registry.js +9 -0
  21. package/dist/avz/avz.d.ts +203 -0
  22. package/dist/{json → avz}/avz.js +150 -8
  23. package/dist/{json → avz}/index.d.ts +2 -1
  24. package/dist/{json → avz}/json-shape.registry.d.ts +9 -8
  25. package/dist/{json → avz}/zod-issue.translator.d.ts +8 -2
  26. package/dist/{json → avz}/zod-issue.translator.js +7 -0
  27. package/dist/compiler/contract-compiler-diagnostic.d.ts +31 -5
  28. package/dist/compiler/contract-compiler-diagnostic.guidance.d.ts +6 -0
  29. package/dist/compiler/contract-compiler-diagnostic.guidance.js +97 -0
  30. package/dist/compiler/contract.compiler.d.ts +23 -17
  31. package/dist/compiler/contract.compiler.js +753 -443
  32. package/dist/compiler/create-requirements.projector.d.ts +49 -0
  33. package/dist/compiler/create-requirements.projector.js +423 -0
  34. package/dist/compiler/field-validator.compiler.d.ts +47 -0
  35. package/dist/compiler/field-validator.compiler.js +238 -0
  36. package/dist/compiler/managed-elsewhere.projector.d.ts +52 -0
  37. package/dist/compiler/managed-elsewhere.projector.js +179 -0
  38. package/dist/compiler/managed-elsewhere.validator.d.ts +9 -0
  39. package/dist/compiler/managed-elsewhere.validator.js +74 -0
  40. package/dist/config/any-framework-config.d.ts +19 -12
  41. package/dist/config/computed-fields.d.ts +62 -0
  42. package/dist/config/computed-fields.js +73 -0
  43. package/dist/config/config-diagnostic.d.ts +11 -4
  44. package/dist/config/config-diagnostic.guidance.d.ts +6 -0
  45. package/dist/config/config-diagnostic.guidance.js +32 -0
  46. package/dist/config/config-layer.d.ts +15 -6
  47. package/dist/config/config.resolver.d.ts +98 -31
  48. package/dist/config/config.resolver.js +173 -44
  49. package/dist/config/config.validator.d.ts +7 -7
  50. package/dist/config/config.validator.js +792 -69
  51. package/dist/config/define-resource.d.ts +53 -0
  52. package/dist/config/define-resource.js +14 -0
  53. package/dist/config/effective-fields.d.ts +19 -23
  54. package/dist/config/entrypoint.normalizer.d.ts +4 -3
  55. package/dist/config/exact-framework-config.d.ts +325 -0
  56. package/dist/config/field-compute.resolver.d.ts +21 -0
  57. package/dist/config/field-compute.resolver.js +123 -0
  58. package/dist/config/field-pipeline-config.d.ts +47 -0
  59. package/dist/config/forced-operation.validator.d.ts +10 -0
  60. package/dist/config/forced-operation.validator.js +66 -0
  61. package/dist/config/framework-config.d.ts +148 -39
  62. package/dist/config/framework-exemptions-config.d.ts +91 -0
  63. package/dist/config/framework-exemptions-config.js +1 -0
  64. package/dist/config/framework-field-definition.d.ts +78 -0
  65. package/dist/config/framework-field-definition.js +28 -0
  66. package/dist/config/framework-resources-config.d.ts +127 -0
  67. package/dist/config/framework-resources-config.js +1 -0
  68. package/dist/config/pipeline-config.d.ts +56 -20
  69. package/dist/config/pipeline-tree.resolver.d.ts +79 -0
  70. package/dist/config/pipeline-tree.resolver.js +220 -0
  71. package/dist/config/stage-type.eraser.d.ts +65 -0
  72. package/dist/config/stage-type.eraser.js +1 -0
  73. package/dist/contracts/access-route.rules.d.ts +10 -0
  74. package/dist/contracts/access-route.rules.js +45 -0
  75. package/dist/contracts/capability.d.ts +37 -12
  76. package/dist/contracts/capability.js +20 -0
  77. package/dist/contracts/client-contract-structure.validator.d.ts +621 -114
  78. package/dist/contracts/client-contract-structure.validator.js +189 -10
  79. package/dist/contracts/contract-access.d.ts +29 -0
  80. package/dist/contracts/contract-access.js +1 -0
  81. package/dist/contracts/contract-canonicalizer.d.ts +27 -3
  82. package/dist/contracts/contract-canonicalizer.js +168 -29
  83. package/dist/contracts/contract-hash.d.ts +11 -7
  84. package/dist/contracts/contract-hash.js +4 -3
  85. package/dist/contracts/contract-limits.d.ts +4 -1
  86. package/dist/contracts/contract-limits.js +1 -0
  87. package/dist/contracts/contract-lookup.d.ts +5 -5
  88. package/dist/contracts/contract-protocol.d.ts +4 -4
  89. package/dist/contracts/contract.d.ts +51 -17
  90. package/dist/contracts/create-requirements.d.ts +35 -0
  91. package/dist/contracts/create-requirements.js +1 -0
  92. package/dist/contracts/enum-definition.d.ts +1 -1
  93. package/dist/contracts/field-check.d.ts +101 -0
  94. package/dist/contracts/field-check.js +1 -0
  95. package/dist/contracts/field.d.ts +109 -42
  96. package/dist/contracts/identifier.d.ts +4 -4
  97. package/dist/contracts/json-schema.projector.d.ts +11 -0
  98. package/dist/contracts/json-schema.projector.js +78 -0
  99. package/dist/contracts/json-shape.d.ts +12 -1
  100. package/dist/contracts/lifecycle-trait.d.ts +2 -2
  101. package/dist/contracts/resource-operations.d.ts +28 -28
  102. package/dist/contracts/resource.d.ts +15 -9
  103. package/dist/contracts/scalar-value-type.d.ts +17 -15
  104. package/dist/contracts/scalar.d.ts +3 -3
  105. package/dist/contracts/transaction-capability.d.ts +1 -1
  106. package/dist/contracts/wire-scalar-format.d.ts +4 -4
  107. package/dist/framework/access-facade.d.ts +116 -0
  108. package/dist/framework/access-facade.js +120 -0
  109. package/dist/framework/contract-view.d.ts +315 -145
  110. package/dist/framework/framework-construction.error.d.ts +21 -11
  111. package/dist/framework/framework-construction.error.js +20 -4
  112. package/dist/framework/framework.d.ts +71 -26
  113. package/dist/framework/framework.factory.d.ts +8 -6
  114. package/dist/framework/framework.factory.js +150 -38
  115. package/dist/framework/operation-facade.d.ts +192 -54
  116. package/dist/framework/operation-facade.js +10 -1
  117. package/dist/index.d.ts +67 -50
  118. package/dist/index.js +7 -6
  119. package/dist/internal.d.ts +20 -10
  120. package/dist/internal.js +9 -1
  121. package/dist/operations/database-refusal.d.ts +51 -0
  122. package/dist/operations/database-refusal.js +45 -0
  123. package/dist/operations/operation-arguments.d.ts +381 -228
  124. package/dist/operations/operation-call.d.ts +31 -28
  125. package/dist/operations/operation-identity.d.ts +10 -10
  126. package/dist/operations/operation-result.d.ts +25 -23
  127. package/dist/operations/operation-validator-core.d.ts +6 -6
  128. package/dist/operations/operation-validator-core.js +172 -38
  129. package/dist/operations/operation-validator.d.ts +10 -10
  130. package/dist/operations/projection-scope.resolver.d.ts +6 -6
  131. package/dist/operations/structural-limits.walker.d.ts +7 -7
  132. package/dist/operations/structural-limits.walker.js +145 -0
  133. package/dist/operations/validation-code.d.ts +11 -6
  134. package/dist/operations/validation-code.guidance.d.ts +6 -0
  135. package/dist/operations/validation-code.guidance.js +90 -0
  136. package/dist/operations/validation-code.js +4 -0
  137. package/dist/operations/write-scope.resolver.d.ts +10 -6
  138. package/dist/operations/write-scope.resolver.js +2 -0
  139. package/dist/policy/access-provider.interface.d.ts +91 -0
  140. package/dist/policy/access-provider.interface.js +1 -0
  141. package/dist/policy/access-provider.registry.d.ts +17 -0
  142. package/dist/policy/access-provider.registry.js +15 -0
  143. package/dist/policy/access-question.d.ts +20 -0
  144. package/dist/policy/access-question.js +1 -0
  145. package/dist/policy/access-question.registry.d.ts +5 -0
  146. package/dist/policy/access-question.registry.js +19 -0
  147. package/dist/policy/access-question.runtime.d.ts +36 -0
  148. package/dist/policy/access-question.runtime.js +297 -0
  149. package/dist/policy/access-verb.table.d.ts +56 -0
  150. package/dist/policy/access-verb.table.js +21 -0
  151. package/dist/policy/access-verbs.d.ts +46 -0
  152. package/dist/policy/access-verbs.js +1 -0
  153. package/dist/policy/policy-admission.d.ts +20 -0
  154. package/dist/policy/policy-admission.js +409 -0
  155. package/dist/policy/policy-after-update.runtime.d.ts +79 -0
  156. package/dist/policy/policy-after-update.runtime.js +208 -0
  157. package/dist/policy/policy-condition.d.ts +15 -0
  158. package/dist/policy/policy-condition.js +36 -0
  159. package/dist/policy/policy-engine.d.ts +205 -0
  160. package/dist/policy/policy-engine.js +1 -0
  161. package/dist/policy/policy-named-rows.d.ts +18 -0
  162. package/dist/policy/policy-named-rows.js +51 -0
  163. package/dist/policy/policy-nested-write.runtime.d.ts +44 -0
  164. package/dist/policy/policy-nested-write.runtime.js +545 -0
  165. package/dist/policy/policy-read.runtime.d.ts +81 -0
  166. package/dist/policy/policy-read.runtime.js +503 -0
  167. package/dist/policy/policy-reference-write.runtime.d.ts +51 -0
  168. package/dist/policy/policy-reference-write.runtime.js +345 -0
  169. package/dist/policy/policy-request.d.ts +41 -0
  170. package/dist/policy/policy-request.js +63 -0
  171. package/dist/policy/policy-session.d.ts +106 -0
  172. package/dist/policy/policy-session.js +295 -0
  173. package/dist/policy/policy-startup.validator.d.ts +10 -0
  174. package/dist/policy/policy-startup.validator.js +112 -0
  175. package/dist/policy/policy-write.runtime.d.ts +39 -0
  176. package/dist/policy/policy-write.runtime.js +532 -0
  177. package/dist/prebuilt/core-version.generated.d.ts +2 -0
  178. package/dist/prebuilt/core-version.generated.js +1 -0
  179. package/dist/prebuilt/prebuilt-changes.d.ts +29 -0
  180. package/dist/prebuilt/prebuilt-changes.js +65 -0
  181. package/dist/prebuilt/prebuilt-contracts.d.ts +40 -0
  182. package/dist/prebuilt/prebuilt-contracts.emitter.d.ts +16 -0
  183. package/dist/prebuilt/prebuilt-contracts.emitter.js +50 -0
  184. package/dist/prebuilt/prebuilt-contracts.js +1 -0
  185. package/dist/prebuilt/prebuilt-contracts.loader.d.ts +19 -0
  186. package/dist/prebuilt/prebuilt-contracts.loader.js +77 -0
  187. package/dist/prebuilt/prebuilt-inputs.fingerprint.d.ts +16 -0
  188. package/dist/prebuilt/prebuilt-inputs.fingerprint.js +229 -0
  189. package/dist/protocol/absent-route.responder.d.ts +17 -34
  190. package/dist/protocol/absent-route.responder.js +53 -20
  191. package/dist/protocol/contract-document.responder.d.ts +5 -4
  192. package/dist/protocol/contract-document.responder.js +2 -2
  193. package/dist/protocol/http-request.decoder.d.ts +33 -13
  194. package/dist/protocol/http-request.decoder.js +34 -11
  195. package/dist/protocol/http-request.reader.d.ts +9 -6
  196. package/dist/protocol/http-request.reader.js +1 -0
  197. package/dist/protocol/http-response.encoder.d.ts +4 -4
  198. package/dist/protocol/http-response.encoder.js +94 -55
  199. package/dist/protocol/http-status.table.d.ts +2 -2
  200. package/dist/protocol/operation-response.guard.d.ts +2 -2
  201. package/dist/protocol/protocol-headers.d.ts +3 -3
  202. package/dist/protocol/protocol-surface.d.ts +10 -5
  203. package/dist/protocol/protocol-surface.js +7 -0
  204. package/dist/protocol/protocol.binder.d.ts +66 -28
  205. package/dist/protocol/protocol.binder.js +16 -10
  206. package/dist/protocol/protocol.handler.d.ts +34 -14
  207. package/dist/protocol/protocol.handler.js +122 -18
  208. package/dist/protocol/unmounted-route.error.d.ts +4 -4
  209. package/dist/protocol/unmounted-route.error.js +2 -2
  210. package/dist/runtime/caller-data.copier.d.ts +22 -7
  211. package/dist/runtime/caller-data.copier.js +30 -17
  212. package/dist/runtime/caller-data.door.d.ts +18 -11
  213. package/dist/runtime/caller-data.door.js +6 -4
  214. package/dist/runtime/computed-read-runtime.d.ts +12 -6
  215. package/dist/runtime/computed-read-runtime.js +271 -71
  216. package/dist/runtime/computed-value.error.d.ts +7 -6
  217. package/dist/runtime/computed-value.error.js +5 -4
  218. package/dist/runtime/context-executor.runtime.d.ts +60 -0
  219. package/dist/runtime/context-executor.runtime.js +277 -0
  220. package/dist/runtime/core-class.brand.d.ts +10 -0
  221. package/dist/runtime/core-class.brand.js +21 -0
  222. package/dist/runtime/create-requirement.d.ts +34 -79
  223. package/dist/runtime/create-requirement.js +205 -74
  224. package/dist/runtime/decimal.d.ts +16 -2
  225. package/dist/runtime/decimal.js +22 -1
  226. package/dist/runtime/diagnostics-reporter.d.ts +91 -30
  227. package/dist/runtime/diagnostics-reporter.js +37 -1
  228. package/dist/runtime/error-boundary.d.ts +73 -9
  229. package/dist/runtime/error-boundary.js +57 -19
  230. package/dist/runtime/error-guidance.d.ts +12 -0
  231. package/dist/runtime/error-guidance.js +1 -0
  232. package/dist/runtime/error.catalog.d.ts +49 -0
  233. package/dist/runtime/error.catalog.js +49 -0
  234. package/dist/runtime/execution-options.d.ts +18 -2
  235. package/dist/runtime/field-check.evaluator.d.ts +27 -0
  236. package/dist/runtime/field-check.evaluator.js +521 -0
  237. package/dist/runtime/field-compute.d.ts +65 -0
  238. package/dist/runtime/field-compute.js +1 -0
  239. package/dist/runtime/field-stage.plan.d.ts +15 -0
  240. package/dist/runtime/field-stage.plan.js +27 -0
  241. package/dist/runtime/field-stage.runtime.d.ts +37 -0
  242. package/dist/runtime/field-stage.runtime.js +147 -0
  243. package/dist/runtime/field-validator.runtime.d.ts +29 -0
  244. package/dist/runtime/field-validator.runtime.js +126 -0
  245. package/dist/runtime/framework-error-class.table.d.ts +33 -0
  246. package/dist/runtime/framework-error-class.table.js +25 -0
  247. package/dist/runtime/framework-error.d.ts +68 -8
  248. package/dist/runtime/framework-error.factory.d.ts +4 -0
  249. package/dist/runtime/framework-error.factory.js +15 -0
  250. package/dist/runtime/framework-error.js +32 -2
  251. package/dist/runtime/framework-warning.emitter.d.ts +6 -0
  252. package/dist/runtime/framework-warning.emitter.js +8 -0
  253. package/dist/runtime/interceptor-next.error.d.ts +5 -0
  254. package/dist/runtime/interceptor-next.error.js +6 -0
  255. package/dist/runtime/json-value.d.ts +11 -6
  256. package/dist/runtime/level-lifecycle.runtime.d.ts +26 -0
  257. package/dist/runtime/level-lifecycle.runtime.js +40 -0
  258. package/dist/runtime/misuse-reporter.d.ts +12 -12
  259. package/dist/runtime/mutation-planner.d.ts +20 -16
  260. package/dist/runtime/mutation-planner.js +48 -35
  261. package/dist/runtime/nested-write.walker.d.ts +32 -0
  262. package/dist/runtime/nested-write.walker.js +73 -0
  263. package/dist/runtime/operation-code.guidance.d.ts +6 -0
  264. package/dist/runtime/operation-code.guidance.js +167 -0
  265. package/dist/runtime/operation-request.d.ts +45 -11
  266. package/dist/runtime/operation-response.d.ts +17 -17
  267. package/dist/runtime/operation-runtime.d.ts +133 -27
  268. package/dist/runtime/operation-runtime.js +576 -84
  269. package/dist/runtime/outcome-mapper.d.ts +17 -5
  270. package/dist/runtime/outcome-mapper.js +23 -6
  271. package/dist/runtime/output-validator.d.ts +11 -11
  272. package/dist/runtime/output-validator.js +3 -3
  273. package/dist/runtime/owned-execution.registry.d.ts +16 -6
  274. package/dist/runtime/pipe-output.validator.d.ts +43 -18
  275. package/dist/runtime/pipe-output.validator.js +15 -13
  276. package/dist/runtime/pipeline.d.ts +221 -34
  277. package/dist/runtime/readonly-value.d.ts +47 -0
  278. package/dist/runtime/readonly-value.js +189 -0
  279. package/dist/runtime/referential-action.d.ts +1 -1
  280. package/dist/runtime/request-envelope.validator.d.ts +3 -3
  281. package/dist/runtime/request-envelope.validator.js +12 -7
  282. package/dist/runtime/request-id.d.ts +1 -1
  283. package/dist/runtime/request-state.d.ts +14 -0
  284. package/dist/runtime/request-state.js +1 -0
  285. package/dist/runtime/request-state.resolver.d.ts +12 -0
  286. package/dist/runtime/request-state.resolver.js +20 -0
  287. package/dist/runtime/scalar-runtime.d.ts +33 -25
  288. package/dist/runtime/scalar-runtime.js +105 -38
  289. package/dist/runtime/unsent-value.normalizer.d.ts +15 -0
  290. package/dist/runtime/unsent-value.normalizer.js +128 -0
  291. package/dist/transactions/deferred-operation.d.ts +35 -20
  292. package/dist/transactions/operation-arguments-encoder.d.ts +3 -3
  293. package/dist/transactions/operation-arguments-encoder.js +8 -3
  294. package/dist/transactions/operation-fingerprint.js +2 -2
  295. package/dist/transactions/sql-statement.d.ts +85 -0
  296. package/dist/transactions/sql-statement.js +47 -0
  297. package/dist/transactions/sql-statement.validator.d.ts +44 -0
  298. package/dist/transactions/sql-statement.validator.js +167 -0
  299. package/dist/transactions/transaction-envelope.d.ts +9 -8
  300. package/dist/transactions/transaction-integrity-error.d.ts +6 -6
  301. package/dist/transactions/transaction-integrity-error.js +7 -2
  302. package/dist/transactions/transaction-plan-assembler.d.ts +30 -13
  303. package/dist/transactions/transaction-plan-assembler.js +184 -32
  304. package/dist/transactions/transaction-plan-validator.d.ts +50 -25
  305. package/dist/transactions/transaction-plan-validator.js +96 -38
  306. package/dist/transactions/transaction-reference-collector.d.ts +5 -5
  307. package/dist/transactions/transaction-reference-resolver.d.ts +21 -3
  308. package/dist/transactions/transaction-reference-resolver.js +26 -14
  309. package/dist/transactions/transaction-reference-validator.d.ts +74 -4
  310. package/dist/transactions/transaction-reference-validator.js +129 -71
  311. package/dist/transactions/transaction-reference.d.ts +14 -14
  312. package/dist/transactions/transaction-reference.js +5 -0
  313. package/dist/transactions/transaction-request.d.ts +22 -9
  314. package/dist/transactions/transaction-response.d.ts +6 -6
  315. package/dist/transactions/transaction-runtime.d.ts +12 -8
  316. package/dist/transactions/transaction-runtime.js +218 -50
  317. package/dist/transactions/transaction-settlement.runtime.d.ts +52 -0
  318. package/dist/transactions/transaction-settlement.runtime.js +120 -0
  319. package/dist/transactions/transaction-slot-path-error.d.ts +4 -4
  320. package/dist/transactions/transaction-slot-path-error.js +4 -2
  321. package/dist/transactions/transaction-slot-writer.js +2 -2
  322. package/dist/transactions/transaction-stage.runtime.d.ts +83 -0
  323. package/dist/transactions/transaction-stage.runtime.js +126 -0
  324. package/package.json +11 -9
  325. package/src/runtime/field-check.evaluator.ts +720 -0
  326. package/dist/config/define-fields.d.ts +0 -42
  327. package/dist/config/define-fields.js +0 -3
  328. package/dist/config/framework-behaviors-config.d.ts +0 -30
  329. package/dist/config/framework-fields-config.d.ts +0 -42
  330. package/dist/config/framework-restrictions-config.d.ts +0 -142
  331. package/dist/json/avz.d.ts +0 -96
  332. package/dist/runtime/field-behavior.d.ts +0 -48
  333. /package/dist/{config/framework-behaviors-config.js → adapters/adapter-sql-statement.js} +0 -0
  334. /package/dist/{config/framework-fields-config.js → adapters/adapter-transaction-executor.interface.js} +0 -0
  335. /package/dist/{json → avz}/index.js +0 -0
  336. /package/dist/{json → avz}/json-shape.registry.js +0 -0
  337. /package/dist/config/{framework-restrictions-config.js → exact-framework-config.js} +0 -0
  338. /package/dist/{runtime/field-behavior.js → config/field-pipeline-config.js} +0 -0
@@ -0,0 +1,532 @@
1
+ import { adapterPrimaryIdentifier } from "../adapters/adapter-identifier.js";
2
+ import { lookupField, lookupResource } from "../contracts/contract-lookup.js";
3
+ import { uniqueMissFailure } from "../runtime/outcome-mapper.js";
4
+ import { frozenCopy } from "../runtime/readonly-value.js";
5
+ import { policyRefusal } from "./policy-admission.js";
6
+ import { afterCheckFields, afterUpdate, beforeFields, beforeUnreadable, checkChanged, coveredBefore, rowsBefore, unchangedSince, } from "./policy-after-update.runtime.js";
7
+ import { allOf, everyOf, noneOf, someOf, whereOf, } from "./policy-condition.js";
8
+ import { planNestedWrites, writesNested, } from "./policy-nested-write.runtime.js";
9
+ import { enforceReadPolicy, identifiedRows, returnedRowChecks, } from "./policy-read.runtime.js";
10
+ import { heldReferences, } from "./policy-reference-write.runtime.js";
11
+ function heldUnchanged(core, model, resource, checks, run, before) {
12
+ if (!checks.before || before.length === 0) {
13
+ return run;
14
+ }
15
+ const condition = unchangedSince(core, model, resource, before);
16
+ if (typeof condition === "boolean") {
17
+ return run;
18
+ }
19
+ const args = isRecord(run.arguments) ? run.arguments : {};
20
+ const where = isRecord(args.where) ? args.where : {};
21
+ const and = where.AND === undefined
22
+ ? []
23
+ : Array.isArray(where.AND)
24
+ ? where.AND
25
+ : [where.AND];
26
+ return {
27
+ ...run,
28
+ arguments: { ...args, where: { ...where, AND: [...and, condition] } },
29
+ };
30
+ }
31
+ function whereOfRun(run) {
32
+ const where = isRecord(run.arguments) ? run.arguments.where : undefined;
33
+ return isRecord(where) ? where : true;
34
+ }
35
+ function fewerChanged(resource, checks, before, changed) {
36
+ return checks.before && changed < before.rows.length
37
+ ? policyRefusal(`The policy checks this update on Resource "${resource}" against the rows as they were before it, and ${before.rows.length - changed} of the ${before.rows.length} rows it read changed before it ran (a concurrent write), so it was not applied.`)
38
+ : undefined;
39
+ }
40
+ const UNVERIFIABLE = "cannot be verified on this database: it has no interactive transaction to roll the write back in";
41
+ function isRecord(value) {
42
+ return value !== null && typeof value === "object" && !Array.isArray(value);
43
+ }
44
+ function refused(message) {
45
+ return { kind: "refused", response: policyRefusal(message) };
46
+ }
47
+ function rowOf(core, resource, record) {
48
+ const owner = lookupResource(core, resource);
49
+ const row = {};
50
+ if (isRecord(record)) {
51
+ for (const [field, value] of Object.entries(record)) {
52
+ if (value !== undefined &&
53
+ lookupField(owner, field)?.kind !== "relation") {
54
+ row[field] = value;
55
+ }
56
+ }
57
+ }
58
+ return frozenCopy(row);
59
+ }
60
+ function rowsOf(data) {
61
+ if (Array.isArray(data)) {
62
+ return data.filter(isRecord);
63
+ }
64
+ return isRecord(data) ? [data] : [];
65
+ }
66
+ function offers(core, resource, family, variant) {
67
+ const operations = lookupResource(core, resource)?.operations;
68
+ return operations?.[family]?.[variant] !== undefined;
69
+ }
70
+ function missOf(session, request, selector) {
71
+ return async () => {
72
+ const read = await session.scope(request.resource, "read");
73
+ const reach = allOf(isRecord(selector) ? selector : true, read);
74
+ if (reach !== false &&
75
+ (await session.renewed().exists(request.resource, whereOf(reach)))) {
76
+ return policyRefusal(`The policy does not allow ${request.family} on this row of Resource "${request.resource}".`);
77
+ }
78
+ return (uniqueMissFailure(request, null) ??
79
+ policyRefusal(`The policy does not allow ${request.family} on this row of Resource "${request.resource}".`));
80
+ };
81
+ }
82
+ async function checkCreated(session, core, model, resource, grants, created) {
83
+ if (created.length === 0) {
84
+ return undefined;
85
+ }
86
+ const these = identifiedRows(core, adapterPrimaryIdentifier(model, resource), resource, created);
87
+ const missed = allOf(these, someOf([...grants.values()].map(noneOf)));
88
+ if (missed !== false &&
89
+ (await session.renewed().exists(resource, whereOf(missed)))) {
90
+ return policyRefusal(`The policy does not allow writing ${fieldNames(grants)} of Resource "${resource}" on the row this request creates.`);
91
+ }
92
+ return undefined;
93
+ }
94
+ function fieldNames(grants) {
95
+ return [...grants.keys()].map((field) => `"${field}"`).join(", ");
96
+ }
97
+ function uncheckableCreate(model, request, grants, inTransaction) {
98
+ if (grants.size === 0) {
99
+ return undefined;
100
+ }
101
+ const what = `The policy allows writing ${fieldNames(grants)} of Resource "${request.resource}" on some rows only, and checks the row this request creates against them after the insert`;
102
+ if (!inTransaction) {
103
+ return refused(`${what}, which ${UNVERIFIABLE}.`);
104
+ }
105
+ if (request.variant === "count" ||
106
+ adapterPrimaryIdentifier(model, request.resource).length === 0) {
107
+ return refused(`${what}, and this create does not return the rows it creates to check by.`);
108
+ }
109
+ return undefined;
110
+ }
111
+ function unverifiable(read, request, inTransaction) {
112
+ if (inTransaction || read.kind !== "run") {
113
+ return undefined;
114
+ }
115
+ const rootChecked = request.family !== "delete" && read.checks.root.length > 0;
116
+ return rootChecked || read.checks.nested
117
+ ? refused(`The policy checks the rows this ${request.family} on Resource "${request.resource}" returns after it runs, which ${UNVERIFIABLE}. Select fewer fields or relations, or read them in a request of their own.`)
118
+ : undefined;
119
+ }
120
+ async function nestedWritesOf(session, core, model, request, record, parent, inTransaction) {
121
+ if (!isRecord(record) || !writesNested(core, request.resource, record)) {
122
+ return undefined;
123
+ }
124
+ if (!inTransaction) {
125
+ return {
126
+ kind: "refused",
127
+ response: policyRefusal(`The policy checks the nested writes of this ${request.family} on Resource "${request.resource}" inside its transaction, which ${UNVERIFIABLE}. Write the related rows in their own operations.`),
128
+ };
129
+ }
130
+ return planNestedWrites(session, core, model, request.resource, record, parent);
131
+ }
132
+ function withNestedWrites(run, key, nested) {
133
+ const runArguments = isRecord(run.arguments) ? run.arguments : {};
134
+ const narrowed = runArguments[key] === nested.record
135
+ ? run
136
+ : { ...run, arguments: { ...runArguments, [key]: nested.record } };
137
+ return withChangedRows(narrowed, (data) => nested.after(rowsOf(data)));
138
+ }
139
+ function linkRefused(held) {
140
+ if (held?.kind !== "held" || !held.linked) {
141
+ return undefined;
142
+ }
143
+ return async (error) => isRecord(error) && error.code === "A4002"
144
+ ? policyRefusal("The policy does not allow this write to link a row outside what the caller may read.")
145
+ : undefined;
146
+ }
147
+ function withHeldReferences(run, held, keys) {
148
+ if (!held.linked) {
149
+ return run;
150
+ }
151
+ const runArguments = isRecord(run.arguments) ? run.arguments : {};
152
+ const linked = { ...runArguments };
153
+ for (const [key, stage] of keys) {
154
+ if (Object.hasOwn(runArguments, key)) {
155
+ linked[key] = held.apply(runArguments[key], stage);
156
+ }
157
+ }
158
+ return { ...run, arguments: linked };
159
+ }
160
+ function countOf(run) {
161
+ return {
162
+ ...run,
163
+ settle: async (data) => {
164
+ const settled = await run.settle(data);
165
+ return settled.ok ? { ok: true, data: rowsOf(data).length } : settled;
166
+ },
167
+ };
168
+ }
169
+ function withoutCarried(run, asked, carried) {
170
+ if (carried === undefined || !Array.isArray(asked.select)) {
171
+ return run;
172
+ }
173
+ const kept = asked.select;
174
+ const dropped = carried.filter((field) => !kept.includes(field));
175
+ if (dropped.length === 0) {
176
+ return run;
177
+ }
178
+ const trimmed = (row) => {
179
+ if (!isRecord(row)) {
180
+ return row;
181
+ }
182
+ const answer = {};
183
+ for (const key of Object.keys(row)) {
184
+ if (!dropped.includes(key)) {
185
+ answer[key] = row[key];
186
+ }
187
+ }
188
+ return answer;
189
+ };
190
+ return {
191
+ ...run,
192
+ settle: async (data) => {
193
+ const settled = await run.settle(data);
194
+ if (!settled.ok) {
195
+ return settled;
196
+ }
197
+ return {
198
+ ok: true,
199
+ data: Array.isArray(settled.data)
200
+ ? settled.data.map(trimmed)
201
+ : trimmed(settled.data),
202
+ };
203
+ },
204
+ };
205
+ }
206
+ function withChangedRows(read, check) {
207
+ return {
208
+ ...read,
209
+ settle: async (data) => {
210
+ const settled = await read.settle(data);
211
+ if (!settled.ok) {
212
+ return settled;
213
+ }
214
+ const response = await check(data);
215
+ return response === undefined ? settled : { ok: false, response };
216
+ },
217
+ };
218
+ }
219
+ export async function writeNeedsTransaction(session, core, request, planned, adapterArguments) {
220
+ switch (request.family) {
221
+ case "find":
222
+ return false;
223
+ case "update":
224
+ case "upsert":
225
+ return true;
226
+ case "create": {
227
+ const args = isRecord(adapterArguments) ? adapterArguments : {};
228
+ if (session.createGrants().size > 0 ||
229
+ (isRecord(args.data) && writesNested(core, request.resource, args.data))) {
230
+ return true;
231
+ }
232
+ break;
233
+ }
234
+ case "delete":
235
+ break;
236
+ }
237
+ const plan = planned();
238
+ const checks = await returnedRowChecks(session, core, plan);
239
+ return [...checks.keys()].some((level) => level !== plan.projection || request.family !== "delete");
240
+ }
241
+ export async function enforceWritePolicy(session, core, model, request, plan, adapterArguments, inTransaction) {
242
+ const args = isRecord(adapterArguments) ? adapterArguments : {};
243
+ switch (request.family) {
244
+ case "create":
245
+ return enforceCreate(session, core, model, request, plan, adapterArguments, args, inTransaction);
246
+ case "update":
247
+ case "delete":
248
+ return enforceScopedWrite(session, core, model, request, plan, adapterArguments, args, inTransaction);
249
+ case "upsert":
250
+ return enforceUpsert(session, core, model, request, plan, adapterArguments, args, inTransaction);
251
+ case "find":
252
+ return enforceReadPolicy(session, core, model, request, plan, adapterArguments);
253
+ }
254
+ }
255
+ async function enforceCreate(session, core, model, request, plan, adapterArguments, args, inTransaction) {
256
+ const resource = request.resource;
257
+ const records = Array.isArray(args.data) ? args.data : [args.data];
258
+ const nested = await nestedWritesOf(session, core, model, request, args.data, { kind: "new" }, inTransaction);
259
+ if (nested?.kind === "refused") {
260
+ return nested;
261
+ }
262
+ if (nested === undefined) {
263
+ const answers = await Promise.all(records
264
+ .filter(isRecord)
265
+ .map((record) => session.can(resource, "create", rowOf(core, resource, record))));
266
+ if (answers.includes(false)) {
267
+ return refused(`The policy does not allow creating this row of Resource "${resource}".`);
268
+ }
269
+ }
270
+ const grants = session.createGrants();
271
+ const uncheckable = uncheckableCreate(model, request, grants, inTransaction);
272
+ if (uncheckable !== undefined) {
273
+ return uncheckable;
274
+ }
275
+ const held = await heldReferences(session, core, model, request, [
276
+ { stage: "create", records },
277
+ ]);
278
+ if (held.kind === "refused") {
279
+ return held;
280
+ }
281
+ const read = await enforceReadPolicy(session, core, model, request, plan, adapterArguments, { scope: undefined, identified: grants.size > 0 || nested !== undefined });
282
+ const blocked = unverifiable(read, request, inTransaction);
283
+ if (blocked !== undefined || read.kind !== "run") {
284
+ return blocked ?? read;
285
+ }
286
+ let run = read;
287
+ if (grants.size > 0) {
288
+ run = withChangedRows(run, (data) => checkCreated(session, core, model, resource, grants, rowsOf(data)));
289
+ }
290
+ if (nested !== undefined) {
291
+ run = withNestedWrites(run, "data", nested);
292
+ }
293
+ run = withHeldReferences(run, held, [["data", "create"]]);
294
+ const failed = linkRefused(held);
295
+ return failed === undefined ? run : { ...run, failed };
296
+ }
297
+ async function enforceScopedWrite(session, core, model, request, plan, adapterArguments, args, inTransaction) {
298
+ const resource = request.resource;
299
+ const action = request.family === "delete" ? "delete" : "update";
300
+ const scope = allOf(await session.scope(resource, action), await session.scope(resource, "read"));
301
+ const changes = action === "update"
302
+ ? await afterUpdate(session, core, model, resource, args.data, inTransaction)
303
+ : undefined;
304
+ if (changes !== undefined && !inTransaction) {
305
+ return refused(`The policy checks this update on Resource "${resource}" after it runs (${changes.after ? "its grant's after condition" : "whether it moves a row out of what the caller may read"}), which ${UNVERIFIABLE}.`);
306
+ }
307
+ if (changes !== undefined &&
308
+ adapterPrimaryIdentifier(model, resource).length === 0) {
309
+ return refused(`The policy checks this update on Resource "${resource}" after it runs, and the Resource has no identifier to find the changed rows by.`);
310
+ }
311
+ const unreadable = beforeUnreadable(core, resource, changes);
312
+ if (unreadable !== undefined) {
313
+ return { kind: "refused", response: unreadable };
314
+ }
315
+ const held = action === "update"
316
+ ? await heldReferences(session, core, model, request, [
317
+ { stage: "update", records: [args.data] },
318
+ ])
319
+ : undefined;
320
+ if (held?.kind === "refused") {
321
+ return held;
322
+ }
323
+ const nested = action === "update"
324
+ ? await nestedWritesOf(session, core, model, request, args.data, {
325
+ kind: "existing",
326
+ reach: allOf(isRecord(args.where) ? args.where : true, scope),
327
+ }, inTransaction)
328
+ : undefined;
329
+ if (nested?.kind === "refused") {
330
+ return nested;
331
+ }
332
+ const miss = request.variant === "unique"
333
+ ? missOf(session, request, args.where)
334
+ : undefined;
335
+ const linked = held?.kind === "held" && held.linked;
336
+ const failedMiss = miss !== undefined && (nested !== undefined || linked)
337
+ ? async () => {
338
+ const reach = allOf(isRecord(args.where) ? args.where : true, scope);
339
+ return reach !== false &&
340
+ (await session.renewed().exists(resource, whereOf(reach)))
341
+ ? undefined
342
+ : miss();
343
+ }
344
+ : undefined;
345
+ const failedLink = linkRefused(held);
346
+ const failed = nested === undefined && failedLink === undefined
347
+ ? failedMiss
348
+ : async (error) => (await failedMiss?.()) ??
349
+ (await failedLink?.(error)) ??
350
+ (await nested?.failed());
351
+ const misses = {
352
+ ...(miss === undefined ? {} : { miss }),
353
+ ...(failed === undefined ? {} : { failed }),
354
+ };
355
+ const carried = changes?.after === true
356
+ ? afterCheckFields(core, model, resource)
357
+ : undefined;
358
+ const read = await enforceReadPolicy(session, core, model, request, plan, adapterArguments, {
359
+ scope,
360
+ identified: changes !== undefined || nested !== undefined,
361
+ ...(carried === undefined ? {} : { carried }),
362
+ });
363
+ const blocked = unverifiable(read, request, inTransaction);
364
+ if (blocked !== undefined) {
365
+ return blocked;
366
+ }
367
+ if (read.kind !== "run") {
368
+ return { ...read, ...misses };
369
+ }
370
+ let run = read;
371
+ if (action === "delete" && run.checks.root.length > 0) {
372
+ const where = isRecord(run.arguments) ? run.arguments.where : undefined;
373
+ const reach = allOf(isRecord(where) ? where : true, someOf(run.checks.root));
374
+ if (reach !== false && (await session.exists(resource, whereOf(reach)))) {
375
+ return refused("The policy does not allow reading every row or field this request returns.");
376
+ }
377
+ }
378
+ if (changes !== undefined) {
379
+ const reach = allOf(isRecord(args.where) ? args.where : true, scope);
380
+ let changed;
381
+ const counted = request.variant === "count";
382
+ if (counted && offers(core, resource, "update", "many")) {
383
+ const runArgs = isRecord(run.arguments) ? run.arguments : {};
384
+ const asMany = {
385
+ ...run,
386
+ identity: { family: "update", variant: "many" },
387
+ arguments: {
388
+ ...runArgs,
389
+ select: changes.after
390
+ ? [...afterCheckFields(core, model, resource)]
391
+ : [...adapterPrimaryIdentifier(model, resource)],
392
+ },
393
+ };
394
+ const before = await rowsBefore(session, core, model, resource, changes, whereOfRun(run));
395
+ run = withChangedRows(heldUnchanged(core, model, resource, changes, asMany, before.rows), async (data) => fewerChanged(resource, changes, before, rowsOf(data).length) ??
396
+ checkChanged(session, core, model, resource, changes, rowsOf(data), changes.after, before));
397
+ if (nested !== undefined) {
398
+ run = withNestedWrites(run, "data", nested);
399
+ }
400
+ if (held?.kind === "held") {
401
+ run = withHeldReferences(run, held, [["data", "update"]]);
402
+ }
403
+ return countOf(run);
404
+ }
405
+ if (counted) {
406
+ const runArgs = isRecord(run.arguments) ? run.arguments : {};
407
+ const identifier = adapterPrimaryIdentifier(model, resource);
408
+ changed = await session.rows(resource, isRecord(runArgs.where) ? runArgs.where : {}, beforeFields(core, model, resource, changes));
409
+ if (changed.length === 0) {
410
+ return { kind: "empty", data: 0 };
411
+ }
412
+ const these = identifiedRows(core, identifier, resource, changed);
413
+ run = {
414
+ ...run,
415
+ arguments: {
416
+ ...runArgs,
417
+ where: everyOf([
418
+ these,
419
+ isRecord(runArgs.where) ? runArgs.where : true,
420
+ ]),
421
+ },
422
+ };
423
+ }
424
+ const known = changed;
425
+ const before = known === undefined
426
+ ? await rowsBefore(session, core, model, resource, changes, request.variant === "unique" ? reach : whereOfRun(run))
427
+ : await coveredBefore(session, core, model, resource, changes, known);
428
+ const several = request.variant === "many" || request.variant === "count";
429
+ run = heldUnchanged(core, model, resource, changes, run, before.rows);
430
+ run = withChangedRows(run, async (data) => (several
431
+ ? fewerChanged(resource, changes, before, known === undefined
432
+ ? rowsOf(data).length
433
+ : typeof data === "number"
434
+ ? data
435
+ : known.length)
436
+ : undefined) ??
437
+ checkChanged(session, core, model, resource, changes, known ?? rowsOf(data), known === undefined && changes.after, before));
438
+ }
439
+ if (nested !== undefined) {
440
+ run = withNestedWrites(run, "data", nested);
441
+ }
442
+ if (held?.kind === "held") {
443
+ run = withHeldReferences(run, held, [["data", "update"]]);
444
+ }
445
+ run = withoutCarried(run, args, carried);
446
+ return { ...run, ...misses };
447
+ }
448
+ async function enforceUpsert(session, core, model, request, plan, adapterArguments, args, inTransaction) {
449
+ const resource = request.resource;
450
+ const selector = isRecord(args.where) ? args.where : true;
451
+ const scope = allOf(await session.scope(resource, "update"), await session.scope(resource, "read"));
452
+ const within = allOf(selector, scope);
453
+ const updates = within !== false && (await session.exists(resource, whereOf(within)));
454
+ let changes;
455
+ let grants = new Map();
456
+ const exists = !updates && (await session.exists(resource, whereOf(selector)));
457
+ const nested = exists
458
+ ? undefined
459
+ : await nestedWritesOf(session, core, model, request, updates ? args.update : args.create, updates ? { kind: "existing", reach: within } : { kind: "new" }, inTransaction);
460
+ if (nested?.kind === "refused") {
461
+ return nested;
462
+ }
463
+ if (updates) {
464
+ changes = await afterUpdate(session, core, model, resource, args.update, inTransaction);
465
+ const unreadable = beforeUnreadable(core, resource, changes);
466
+ if (unreadable !== undefined) {
467
+ return { kind: "refused", response: unreadable };
468
+ }
469
+ if (changes !== undefined && !inTransaction) {
470
+ return refused(`The policy checks this upsert's update on Resource "${resource}" after it runs (${changes.after ? "its grant's after condition" : "whether it moves a row out of what the caller may read"}), which ${UNVERIFIABLE}.`);
471
+ }
472
+ }
473
+ else if (exists) {
474
+ return refused(`The policy does not allow update on this row of Resource "${resource}".`);
475
+ }
476
+ else if (nested === undefined &&
477
+ !(await session.can(resource, "create", rowOf(core, resource, args.create)))) {
478
+ return refused(`The policy does not allow creating this row of Resource "${resource}".`);
479
+ }
480
+ else {
481
+ grants = session.createGrants();
482
+ const uncheckable = uncheckableCreate(model, request, grants, inTransaction);
483
+ if (uncheckable !== undefined) {
484
+ return uncheckable;
485
+ }
486
+ }
487
+ const held = await heldReferences(session, core, model, request, [
488
+ { stage: "create", records: [args.create] },
489
+ { stage: "update", records: [args.update] },
490
+ ]);
491
+ if (held.kind === "refused") {
492
+ return held;
493
+ }
494
+ const carried = changes?.after === true
495
+ ? afterCheckFields(core, model, resource)
496
+ : undefined;
497
+ const read = await enforceReadPolicy(session, core, model, request, plan, adapterArguments, {
498
+ scope: undefined,
499
+ identified: changes !== undefined || grants.size > 0 || nested !== undefined,
500
+ ...(carried === undefined ? {} : { carried }),
501
+ });
502
+ const blocked = unverifiable(read, request, inTransaction);
503
+ if (blocked !== undefined || read.kind !== "run") {
504
+ return blocked ?? read;
505
+ }
506
+ let run = read;
507
+ const checks = changes;
508
+ if (checks !== undefined) {
509
+ const before = await rowsBefore(session, core, model, resource, checks, within);
510
+ run = withChangedRows(run, (data) => checkChanged(session, core, model, resource, checks, rowsOf(data), checks.after, before));
511
+ }
512
+ const created = grants;
513
+ if (created.size > 0) {
514
+ run = withChangedRows(run, (data) => checkCreated(session, core, model, resource, created, rowsOf(data)));
515
+ }
516
+ if (nested !== undefined) {
517
+ run = withNestedWrites(run, updates ? "update" : "create", nested);
518
+ }
519
+ run = withHeldReferences(run, held, [
520
+ ["create", "create"],
521
+ ["update", "update"],
522
+ ]);
523
+ run = withoutCarried(run, args, carried);
524
+ const failedLink = linkRefused(held);
525
+ if (nested === undefined && failedLink === undefined) {
526
+ return run;
527
+ }
528
+ return {
529
+ ...run,
530
+ failed: async (error) => (await failedLink?.(error)) ?? (await nested?.failed()),
531
+ };
532
+ }
@@ -0,0 +1,2 @@
1
+ /** The version of this `@aventara/core`. */
2
+ export declare const CORE_VERSION = "1.0.0-rc.10";
@@ -0,0 +1 @@
1
+ export const CORE_VERSION = "1.0.0-rc.10";
@@ -0,0 +1,29 @@
1
+ import type { PrebuiltPartFingerprints } from "./prebuilt-inputs.fingerprint.js";
2
+ /** `a`, `a and b`, `a, b and c`. */
3
+ export declare function listedNames(names: readonly string[]): string;
4
+ /** What a prebuilt file was written in, by and for. */
5
+ type PrebuiltHeader = {
6
+ readonly format: number;
7
+ readonly core: string;
8
+ readonly protocol: number;
9
+ };
10
+ /**
11
+ * Each way a stored file's header differs from `current`, in the order the
12
+ * runtime checks them: the file format, the core version, the protocol.
13
+ */
14
+ export declare function prebuiltHeaderChanges(stored: unknown, current: PrebuiltHeader): readonly string[];
15
+ /**
16
+ * Each way a stored file's part fingerprints differ from `current`: the
17
+ * Resources whose inputs changed, the new ones, the gone ones, and, when
18
+ * `sameHeader`, the inputs that belong to no single Resource.
19
+ */
20
+ export declare function prebuiltInputChanges(stored: unknown, current: PrebuiltPartFingerprints, sameHeader?: boolean): readonly string[];
21
+ /**
22
+ * What differs between a stored prebuilt file and `current`, one clause per
23
+ * difference: its header's, then its inputs' (`… since it was written`).
24
+ * Empty when the two record the same header and inputs.
25
+ */
26
+ export declare function prebuiltFileChanges(stored: unknown, current: PrebuiltHeader & {
27
+ readonly fingerprints: PrebuiltPartFingerprints;
28
+ }): readonly string[];
29
+ export {};
@@ -0,0 +1,65 @@
1
+ function isRecord(value) {
2
+ return value !== null && typeof value === "object" && !Array.isArray(value);
3
+ }
4
+ export function listedNames(names) {
5
+ return names.length < 2
6
+ ? names.join("")
7
+ : `${names.slice(0, -1).join(", ")} and ${names.at(-1)}`;
8
+ }
9
+ export function prebuiltHeaderChanges(stored, current) {
10
+ const header = isRecord(stored) ? stored : {};
11
+ const changes = [];
12
+ if (header.format !== current.format) {
13
+ changes.push(`it is written in file format ${String(header.format)}, and this @aventara/core reads format ${current.format}`);
14
+ }
15
+ if (header.core !== current.core) {
16
+ changes.push(`it was built by @aventara/core ${String(header.core)}, and this is ${current.core}`);
17
+ }
18
+ if (header.protocol !== current.protocol) {
19
+ changes.push(`it was built for protocol version ${String(header.protocol)}, and this @aventara/core speaks version ${current.protocol}`);
20
+ }
21
+ return changes;
22
+ }
23
+ export function prebuiltInputChanges(stored, current, sameHeader = true) {
24
+ const storedResources = isRecord(stored) ? stored.resources : undefined;
25
+ const before = isRecord(storedResources) ? storedResources : {};
26
+ const changed = [];
27
+ const added = [];
28
+ const removed = [];
29
+ for (const [name, fingerprint] of Object.entries(current.resources)) {
30
+ if (!Object.hasOwn(before, name)) {
31
+ added.push(name);
32
+ }
33
+ else if (before[name] !== fingerprint) {
34
+ changed.push(name);
35
+ }
36
+ }
37
+ for (const name of Object.keys(before)) {
38
+ if (!Object.hasOwn(current.resources, name)) {
39
+ removed.push(name);
40
+ }
41
+ }
42
+ const resources = (names) => `${names.length === 1 ? "Resource" : "Resources"} ${listedNames(names)}`;
43
+ const be = (names) => (names.length === 1 ? "is" : "are");
44
+ const changes = [];
45
+ if (changed.length > 0) {
46
+ changes.push(`${resources(changed)} changed`);
47
+ }
48
+ if (added.length > 0) {
49
+ changes.push(`${resources(added)} ${be(added)} new`);
50
+ }
51
+ if (removed.length > 0) {
52
+ changes.push(`${resources(removed)} ${be(removed)} gone`);
53
+ }
54
+ if (sameHeader && (!isRecord(stored) || stored.shared !== current.shared)) {
55
+ changes.push("the configuration or model outside the Resources changed");
56
+ }
57
+ return changes;
58
+ }
59
+ export function prebuiltFileChanges(stored, current) {
60
+ const header = prebuiltHeaderChanges(stored, current);
61
+ const inputs = prebuiltInputChanges(isRecord(stored) ? stored.fingerprints : undefined, current.fingerprints, header.length === 0);
62
+ return inputs.length === 0
63
+ ? header
64
+ : [...header, `${listedNames(inputs)} since it was written`];
65
+ }
@@ -0,0 +1,40 @@
1
+ /** The file format this core writes and reads. */
2
+ export declare const PREBUILT_FORMAT = 1;
3
+ /**
4
+ * Contracts compiled ahead of time: the value of a generated
5
+ * `contracts.generated.ts`, passed to `createFramework` as `prebuilt`. The
6
+ * framework uses them only when they were compiled by the same core, for the
7
+ * same protocol, from the same configuration and model; otherwise it compiles
8
+ * live and warns (`AVENTARA_PREBUILT_STALE`). Generated, never written by hand.
9
+ */
10
+ export type AvPrebuiltContracts = {
11
+ /** The file format's version. */
12
+ readonly format: number;
13
+ /** The version of `@aventara/core` that compiled the Contracts. */
14
+ readonly core: string;
15
+ /** The protocol version the Contracts were compiled for. */
16
+ readonly protocol: number;
17
+ /**
18
+ * `sha256:` over every input: the configuration (without `adapter` and
19
+ * `prebuilt`), the adapter's model, the core version, the protocol version
20
+ * and the file format.
21
+ */
22
+ readonly fingerprint: string;
23
+ /** The same inputs, fingerprinted in parts, so a stale file can say what changed. */
24
+ readonly fingerprints: {
25
+ /** The inputs that belong to no single Resource. */
26
+ readonly shared: string;
27
+ /** Each Resource's inputs: its model, and its entries in every layer. */
28
+ readonly resources: Readonly<Record<string, string>>;
29
+ };
30
+ /**
31
+ * Each Contract's canonical JSON text. The Client and Agent texts carry
32
+ * their hash and are the bytes `/_contract` serves.
33
+ */
34
+ readonly contracts: {
35
+ readonly core: string;
36
+ readonly application: string;
37
+ readonly client: string;
38
+ readonly agent: string;
39
+ };
40
+ };