@aventara/core 1.0.0-rc.1 → 1.0.0-rc.11

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 (261) hide show
  1. package/CHANGELOG.md +1022 -16
  2. package/ERRORS.md +142 -0
  3. package/README.md +330 -16
  4. package/dist/adapters/adapter-discovery-diagnostic.guidance.d.ts +6 -0
  5. package/dist/adapters/adapter-discovery-diagnostic.guidance.js +7 -0
  6. package/dist/adapters/adapter-field.d.ts +22 -0
  7. package/dist/adapters/adapter-identifier.d.ts +9 -0
  8. package/dist/adapters/adapter-identifier.js +6 -1
  9. package/dist/adapters/adapter-model.d.ts +9 -0
  10. package/dist/adapters/adapter-operation.d.ts +18 -3
  11. package/dist/adapters/adapter-resource.d.ts +5 -0
  12. package/dist/adapters/adapter.interface.d.ts +10 -0
  13. package/dist/avz/avz.d.ts +1 -1
  14. package/dist/avz/json-shape.registry.d.ts +2 -1
  15. package/dist/compiler/contract-compiler-diagnostic.guidance.d.ts +6 -0
  16. package/dist/compiler/contract-compiler-diagnostic.guidance.js +97 -0
  17. package/dist/compiler/contract.compiler.d.ts +6 -0
  18. package/dist/compiler/contract.compiler.js +281 -31
  19. package/dist/compiler/create-requirements.projector.js +1 -3
  20. package/dist/compiler/field-validator.compiler.js +1 -3
  21. package/dist/compiler/managed-elsewhere.projector.d.ts +52 -0
  22. package/dist/compiler/managed-elsewhere.projector.js +179 -0
  23. package/dist/compiler/managed-elsewhere.validator.d.ts +9 -0
  24. package/dist/compiler/managed-elsewhere.validator.js +74 -0
  25. package/dist/config/cache-stage.factory.d.ts +24 -0
  26. package/dist/config/cache-stage.factory.js +3 -0
  27. package/dist/config/computed-fields.d.ts +62 -0
  28. package/dist/config/computed-fields.js +73 -0
  29. package/dist/config/config-diagnostic.guidance.d.ts +6 -0
  30. package/dist/config/config-diagnostic.guidance.js +32 -0
  31. package/dist/config/config.resolver.d.ts +24 -0
  32. package/dist/config/config.resolver.js +66 -7
  33. package/dist/config/config.validator.js +283 -21
  34. package/dist/config/define-resource.d.ts +1 -5
  35. package/dist/config/entrypoint.normalizer.d.ts +3 -2
  36. package/dist/config/exact-framework-config.d.ts +73 -22
  37. package/dist/config/field-compute.resolver.d.ts +2 -0
  38. package/dist/config/field-compute.resolver.js +9 -3
  39. package/dist/config/framework-config.d.ts +53 -15
  40. package/dist/config/framework-resources-config.d.ts +25 -14
  41. package/dist/config/pipeline-config.d.ts +20 -4
  42. package/dist/config/pipeline-tree.resolver.d.ts +2 -2
  43. package/dist/config/pipeline-tree.resolver.js +2 -3
  44. package/dist/contracts/access-route.rules.d.ts +10 -0
  45. package/dist/contracts/access-route.rules.js +45 -0
  46. package/dist/contracts/canonical-json.writer.d.ts +7 -0
  47. package/dist/contracts/canonical-json.writer.js +55 -0
  48. package/dist/contracts/capability.d.ts +26 -1
  49. package/dist/contracts/capability.js +20 -0
  50. package/dist/contracts/client-contract-structure.validator.d.ts +365 -89
  51. package/dist/contracts/client-contract-structure.validator.js +49 -2
  52. package/dist/contracts/contract-access.d.ts +29 -0
  53. package/dist/contracts/contract-access.js +1 -0
  54. package/dist/contracts/contract-canonicalizer.d.ts +9 -1
  55. package/dist/contracts/contract-canonicalizer.js +35 -4
  56. package/dist/contracts/contract-hash.d.ts +0 -1
  57. package/dist/contracts/contract-hash.js +1 -1
  58. package/dist/contracts/contract-limits.d.ts +6 -0
  59. package/dist/contracts/contract-limits.js +2 -0
  60. package/dist/contracts/contract.d.ts +42 -1
  61. package/dist/contracts/field.d.ts +58 -1
  62. package/dist/contracts/json-schema.projector.d.ts +11 -0
  63. package/dist/contracts/json-schema.projector.js +76 -0
  64. package/dist/contracts/scalar-value-type.d.ts +3 -1
  65. package/dist/framework/access-facade.d.ts +116 -0
  66. package/dist/framework/access-facade.js +118 -0
  67. package/dist/framework/contract-view.d.ts +120 -16
  68. package/dist/framework/framework-construction.error.d.ts +14 -4
  69. package/dist/framework/framework-construction.error.js +18 -2
  70. package/dist/framework/framework.d.ts +26 -5
  71. package/dist/framework/framework.factory.d.ts +1 -1
  72. package/dist/framework/framework.factory.js +145 -24
  73. package/dist/framework/operation-facade.d.ts +141 -13
  74. package/dist/framework/operation-facade.js +9 -1
  75. package/dist/framework/operation-set.runner.d.ts +47 -0
  76. package/dist/framework/operation-set.runner.js +168 -0
  77. package/dist/index.d.ts +19 -5
  78. package/dist/index.js +3 -0
  79. package/dist/internal.d.ts +9 -2
  80. package/dist/internal.js +8 -0
  81. package/dist/operations/database-refusal.d.ts +51 -0
  82. package/dist/operations/database-refusal.js +45 -0
  83. package/dist/operations/operation-arguments.d.ts +148 -60
  84. package/dist/operations/operation-call.d.ts +9 -5
  85. package/dist/operations/operation-result.d.ts +6 -4
  86. package/dist/operations/operation-validator-core.js +160 -39
  87. package/dist/operations/operation-validator.d.ts +1 -1
  88. package/dist/operations/structural-limits.walker.d.ts +1 -1
  89. package/dist/operations/structural-limits.walker.js +1 -3
  90. package/dist/operations/validation-code.guidance.d.ts +6 -0
  91. package/dist/operations/validation-code.guidance.js +90 -0
  92. package/dist/operations/write-scope.resolver.d.ts +4 -0
  93. package/dist/operations/write-scope.resolver.js +2 -0
  94. package/dist/policy/access-provider.interface.d.ts +91 -0
  95. package/dist/policy/access-provider.interface.js +1 -0
  96. package/dist/policy/access-provider.registry.d.ts +17 -0
  97. package/dist/policy/access-provider.registry.js +15 -0
  98. package/dist/policy/access-question.d.ts +20 -0
  99. package/dist/policy/access-question.js +1 -0
  100. package/dist/policy/access-question.registry.d.ts +5 -0
  101. package/dist/policy/access-question.registry.js +19 -0
  102. package/dist/policy/access-question.runtime.d.ts +36 -0
  103. package/dist/policy/access-question.runtime.js +295 -0
  104. package/dist/policy/access-verb.table.d.ts +56 -0
  105. package/dist/policy/access-verb.table.js +21 -0
  106. package/dist/policy/access-verbs.d.ts +46 -0
  107. package/dist/policy/access-verbs.js +1 -0
  108. package/dist/policy/policy-admission.d.ts +20 -0
  109. package/dist/policy/policy-admission.js +407 -0
  110. package/dist/policy/policy-after-update.runtime.d.ts +79 -0
  111. package/dist/policy/policy-after-update.runtime.js +206 -0
  112. package/dist/policy/policy-condition.d.ts +15 -0
  113. package/dist/policy/policy-condition.js +36 -0
  114. package/dist/policy/policy-engine.d.ts +205 -0
  115. package/dist/policy/policy-engine.js +1 -0
  116. package/dist/policy/policy-named-rows.d.ts +18 -0
  117. package/dist/policy/policy-named-rows.js +51 -0
  118. package/dist/policy/policy-nested-write.runtime.d.ts +44 -0
  119. package/dist/policy/policy-nested-write.runtime.js +536 -0
  120. package/dist/policy/policy-read.runtime.d.ts +81 -0
  121. package/dist/policy/policy-read.runtime.js +501 -0
  122. package/dist/policy/policy-reference-write.runtime.d.ts +51 -0
  123. package/dist/policy/policy-reference-write.runtime.js +336 -0
  124. package/dist/policy/policy-request.d.ts +72 -0
  125. package/dist/policy/policy-request.js +115 -0
  126. package/dist/policy/policy-session.d.ts +106 -0
  127. package/dist/policy/policy-session.js +293 -0
  128. package/dist/policy/policy-startup.validator.d.ts +10 -0
  129. package/dist/policy/policy-startup.validator.js +112 -0
  130. package/dist/policy/policy-write.runtime.d.ts +39 -0
  131. package/dist/policy/policy-write.runtime.js +530 -0
  132. package/dist/prebuilt/core-version.generated.d.ts +2 -0
  133. package/dist/prebuilt/core-version.generated.js +1 -0
  134. package/dist/prebuilt/prebuilt-changes.d.ts +29 -0
  135. package/dist/prebuilt/prebuilt-changes.js +63 -0
  136. package/dist/prebuilt/prebuilt-contracts.d.ts +40 -0
  137. package/dist/prebuilt/prebuilt-contracts.emitter.d.ts +16 -0
  138. package/dist/prebuilt/prebuilt-contracts.emitter.js +50 -0
  139. package/dist/prebuilt/prebuilt-contracts.js +1 -0
  140. package/dist/prebuilt/prebuilt-contracts.loader.d.ts +19 -0
  141. package/dist/prebuilt/prebuilt-contracts.loader.js +75 -0
  142. package/dist/prebuilt/prebuilt-inputs.fingerprint.d.ts +16 -0
  143. package/dist/prebuilt/prebuilt-inputs.fingerprint.js +227 -0
  144. package/dist/protocol/absent-route.responder.d.ts +49 -14
  145. package/dist/protocol/absent-route.responder.js +92 -15
  146. package/dist/protocol/contract-document.responder.d.ts +9 -1
  147. package/dist/protocol/contract-document.responder.js +3 -2
  148. package/dist/protocol/http-request.decoder.d.ts +52 -3
  149. package/dist/protocol/http-request.decoder.js +45 -6
  150. package/dist/protocol/http-request.reader.d.ts +10 -3
  151. package/dist/protocol/http-request.reader.js +12 -2
  152. package/dist/protocol/http-response.encoder.d.ts +12 -0
  153. package/dist/protocol/http-response.encoder.js +17 -3
  154. package/dist/protocol/operation-response.guard.js +1 -3
  155. package/dist/protocol/operation-set.decoder.d.ts +48 -0
  156. package/dist/protocol/operation-set.decoder.js +185 -0
  157. package/dist/protocol/operation-set.handler.d.ts +27 -0
  158. package/dist/protocol/operation-set.handler.js +179 -0
  159. package/dist/protocol/protocol-headers.d.ts +12 -3
  160. package/dist/protocol/protocol-headers.js +12 -5
  161. package/dist/protocol/protocol-surface.d.ts +16 -3
  162. package/dist/protocol/protocol-surface.js +41 -1
  163. package/dist/protocol/protocol.binder.d.ts +52 -1
  164. package/dist/protocol/protocol.binder.js +6 -1
  165. package/dist/protocol/protocol.handler.d.ts +45 -1
  166. package/dist/protocol/protocol.handler.js +164 -19
  167. package/dist/protocol/read-cache.responder.d.ts +26 -0
  168. package/dist/protocol/read-cache.responder.js +47 -0
  169. package/dist/protocol/read-query.codec.d.ts +34 -0
  170. package/dist/protocol/read-query.codec.js +125 -0
  171. package/dist/runtime/caller-data.copier.d.ts +18 -3
  172. package/dist/runtime/caller-data.copier.js +21 -8
  173. package/dist/runtime/caller-data.door.d.ts +13 -6
  174. package/dist/runtime/computed-read-runtime.d.ts +6 -1
  175. package/dist/runtime/computed-read-runtime.js +229 -48
  176. package/dist/runtime/computed-value.error.d.ts +3 -2
  177. package/dist/runtime/computed-value.error.js +3 -2
  178. package/dist/runtime/context-executor.runtime.d.ts +4 -3
  179. package/dist/runtime/context-executor.runtime.js +4 -2
  180. package/dist/runtime/core-class.brand.d.ts +10 -0
  181. package/dist/runtime/core-class.brand.js +21 -0
  182. package/dist/runtime/create-requirement.d.ts +31 -5
  183. package/dist/runtime/create-requirement.js +130 -24
  184. package/dist/runtime/decimal.d.ts +14 -0
  185. package/dist/runtime/decimal.js +21 -0
  186. package/dist/runtime/diagnostics-reporter.d.ts +49 -9
  187. package/dist/runtime/diagnostics-reporter.js +16 -9
  188. package/dist/runtime/error-boundary.d.ts +9 -2
  189. package/dist/runtime/error-boundary.js +12 -0
  190. package/dist/runtime/error-guidance.d.ts +12 -0
  191. package/dist/runtime/error-guidance.js +1 -0
  192. package/dist/runtime/error.catalog.d.ts +49 -0
  193. package/dist/runtime/error.catalog.js +49 -0
  194. package/dist/runtime/execution-options.d.ts +8 -0
  195. package/dist/runtime/field-check.evaluator.d.ts +0 -2
  196. package/dist/runtime/field-check.evaluator.js +1 -1
  197. package/dist/runtime/field-compute.d.ts +11 -10
  198. package/dist/runtime/field-stage.runtime.d.ts +3 -3
  199. package/dist/runtime/field-stage.runtime.js +9 -11
  200. package/dist/runtime/field-validator.runtime.d.ts +19 -1
  201. package/dist/runtime/field-validator.runtime.js +49 -9
  202. package/dist/runtime/framework-error.js +9 -0
  203. package/dist/runtime/framework-warning.emitter.d.ts +6 -0
  204. package/dist/runtime/framework-warning.emitter.js +8 -0
  205. package/dist/runtime/json-value.d.ts +10 -5
  206. package/dist/runtime/level-lifecycle.runtime.d.ts +4 -3
  207. package/dist/runtime/level-lifecycle.runtime.js +3 -5
  208. package/dist/runtime/mutation-planner.d.ts +1 -6
  209. package/dist/runtime/mutation-planner.js +4 -17
  210. package/dist/runtime/nested-write.walker.js +2 -1
  211. package/dist/runtime/operation-code.guidance.d.ts +6 -0
  212. package/dist/runtime/operation-code.guidance.js +167 -0
  213. package/dist/runtime/operation-request.d.ts +16 -9
  214. package/dist/runtime/operation-runtime.d.ts +35 -17
  215. package/dist/runtime/operation-runtime.js +220 -49
  216. package/dist/runtime/outcome-mapper.d.ts +2 -1
  217. package/dist/runtime/output-validator.d.ts +1 -1
  218. package/dist/runtime/output-validator.js +1 -3
  219. package/dist/runtime/owned-execution.registry.d.ts +34 -4
  220. package/dist/runtime/pipe-output.validator.d.ts +10 -0
  221. package/dist/runtime/pipe-output.validator.js +4 -2
  222. package/dist/runtime/pipeline.d.ts +52 -23
  223. package/dist/runtime/readonly-value.d.ts +20 -5
  224. package/dist/runtime/readonly-value.js +74 -26
  225. package/dist/runtime/record.guard.d.ts +14 -0
  226. package/dist/runtime/record.guard.js +10 -0
  227. package/dist/runtime/referential-action.d.ts +1 -1
  228. package/dist/runtime/request-envelope.validator.js +13 -10
  229. package/dist/runtime/scalar-runtime.d.ts +4 -21
  230. package/dist/runtime/scalar-runtime.js +91 -31
  231. package/dist/runtime/thenable.guard.d.ts +7 -0
  232. package/dist/runtime/thenable.guard.js +5 -0
  233. package/dist/runtime/unsent-value.normalizer.d.ts +15 -0
  234. package/dist/runtime/unsent-value.normalizer.js +129 -0
  235. package/dist/transactions/operation-arguments-encoder.js +9 -10
  236. package/dist/transactions/operation-fingerprint.js +2 -2
  237. package/dist/transactions/sql-statement.d.ts +10 -2
  238. package/dist/transactions/sql-statement.validator.d.ts +2 -2
  239. package/dist/transactions/sql-statement.validator.js +40 -6
  240. package/dist/transactions/transaction-envelope.d.ts +5 -4
  241. package/dist/transactions/transaction-integrity-error.js +2 -0
  242. package/dist/transactions/transaction-plan-assembler.d.ts +12 -5
  243. package/dist/transactions/transaction-plan-assembler.js +49 -17
  244. package/dist/transactions/transaction-plan-validator.d.ts +23 -7
  245. package/dist/transactions/transaction-plan-validator.js +31 -7
  246. package/dist/transactions/transaction-reference-collector.js +8 -10
  247. package/dist/transactions/transaction-reference-resolver.d.ts +3 -2
  248. package/dist/transactions/transaction-reference-resolver.js +1 -3
  249. package/dist/transactions/transaction-reference-validator.d.ts +43 -3
  250. package/dist/transactions/transaction-reference-validator.js +83 -57
  251. package/dist/transactions/transaction-reference.d.ts +1 -1
  252. package/dist/transactions/transaction-reference.js +5 -0
  253. package/dist/transactions/transaction-request.d.ts +8 -8
  254. package/dist/transactions/transaction-runtime.d.ts +5 -2
  255. package/dist/transactions/transaction-runtime.js +108 -27
  256. package/dist/transactions/transaction-settlement.runtime.d.ts +4 -3
  257. package/dist/transactions/transaction-slot-path-error.js +2 -0
  258. package/dist/transactions/transaction-stage.runtime.d.ts +5 -3
  259. package/dist/transactions/transaction-stage.runtime.js +8 -7
  260. package/package.json +6 -5
  261. package/src/runtime/field-check.evaluator.ts +1 -1
@@ -0,0 +1,16 @@
1
+ import type { AvAdapterModel } from "../adapters/adapter-model.js";
2
+ import type { AvContracts } from "../compiler/contract.compiler.js";
3
+ import { type AvPrebuiltContracts } from "./prebuilt-contracts.js";
4
+ /**
5
+ * The prebuilt file's value for Contracts `compileContracts` compiled from
6
+ * `model` and `config` (the configuration as authored; its `adapter` and
7
+ * `prebuilt`, if any, are no inputs): each Contract's canonical text, and the
8
+ * fingerprints of the inputs.
9
+ */
10
+ export declare function prebuiltContractsOf(model: AvAdapterModel, config: object, contracts: AvContracts): Promise<AvPrebuiltContracts>;
11
+ /**
12
+ * The generated module that exports `prebuilt` as `aventaraContracts`. Each
13
+ * Contract stays a string, so loading it is one `JSON.parse`; the type is
14
+ * imported for checking only.
15
+ */
16
+ export declare function emitPrebuiltContracts(prebuilt: AvPrebuiltContracts): string;
@@ -0,0 +1,50 @@
1
+ import { canonicalContractTextOf } from "../contracts/contract-canonicalizer.js";
2
+ import { AVENTARA_PROTOCOL_VERSION } from "../contracts/contract-protocol.js";
3
+ import { CORE_VERSION } from "./core-version.generated.js";
4
+ import { PREBUILT_FORMAT, } from "./prebuilt-contracts.js";
5
+ import { prebuiltInputsFingerprint, prebuiltPartFingerprints, } from "./prebuilt-inputs.fingerprint.js";
6
+ export async function prebuiltContractsOf(model, config, contracts) {
7
+ const [fingerprint, fingerprints] = await Promise.all([
8
+ prebuiltInputsFingerprint(model, config),
9
+ prebuiltPartFingerprints(model, config),
10
+ ]);
11
+ return {
12
+ format: PREBUILT_FORMAT,
13
+ core: CORE_VERSION,
14
+ protocol: AVENTARA_PROTOCOL_VERSION,
15
+ fingerprint,
16
+ fingerprints,
17
+ contracts: {
18
+ core: canonicalContractTextOf(contracts.core),
19
+ application: canonicalContractTextOf(contracts.application),
20
+ client: canonicalContractTextOf(contracts.client),
21
+ agent: canonicalContractTextOf(contracts.agent),
22
+ },
23
+ };
24
+ }
25
+ const literal = (value) => JSON.stringify(value);
26
+ const key = (name) => name === "__proto__" ? `[${literal(name)}]` : literal(name);
27
+ export function emitPrebuiltContracts(prebuilt) {
28
+ const resources = Object.entries(prebuilt.fingerprints.resources).map(([name, fingerprint]) => `\t\t\t${key(name)}: ${literal(fingerprint)},\n`);
29
+ return `// Generated by @aventara/core from the configuration and the adapter's model. Do not edit: regenerate it.
30
+ import type { AvPrebuiltContracts } from "@aventara/core";
31
+
32
+ export const aventaraContracts: AvPrebuiltContracts = {
33
+ \tformat: ${prebuilt.format},
34
+ \tcore: ${literal(prebuilt.core)},
35
+ \tprotocol: ${prebuilt.protocol},
36
+ \tfingerprint: ${literal(prebuilt.fingerprint)},
37
+ \tfingerprints: {
38
+ \t\tshared: ${literal(prebuilt.fingerprints.shared)},
39
+ \t\tresources: {
40
+ ${resources.join("")}\t\t},
41
+ \t},
42
+ \tcontracts: {
43
+ \t\tcore: ${literal(prebuilt.contracts.core)},
44
+ \t\tapplication: ${literal(prebuilt.contracts.application)},
45
+ \t\tclient: ${literal(prebuilt.contracts.client)},
46
+ \t\tagent: ${literal(prebuilt.contracts.agent)},
47
+ \t},
48
+ };
49
+ `;
50
+ }
@@ -0,0 +1 @@
1
+ export const PREBUILT_FORMAT = 1;
@@ -0,0 +1,19 @@
1
+ import type { AvAdapterModel } from "../adapters/adapter-model.js";
2
+ import { type AvContracts } from "../compiler/contract.compiler.js";
3
+ import type { ResolvedFrameworkConfig } from "../config/config.resolver.js";
4
+ /** The loaded Contracts, or why the file cannot be used. */
5
+ export type PrebuiltLoad = {
6
+ readonly ok: true;
7
+ readonly contracts: AvContracts;
8
+ } | {
9
+ readonly ok: false;
10
+ readonly reason: string;
11
+ };
12
+ /**
13
+ * Loads the Contracts of a prebuilt file when it was compiled by this core, for
14
+ * this protocol, from `config` (as authored) and `model`; binds them to the
15
+ * runtime pieces of the live `resolved` configuration.
16
+ */
17
+ export declare function loadPrebuiltContracts<M extends AvAdapterModel>(prebuilt: unknown, model: M, config: object, resolved: ResolvedFrameworkConfig<M>): Promise<PrebuiltLoad>;
18
+ /** Warns, once for the framework being created, that its prebuilt file was not used, and why. */
19
+ export declare function warnStalePrebuilt(reason: string): void;
@@ -0,0 +1,75 @@
1
+ import { bindPrebuiltContracts, } from "../compiler/contract.compiler.js";
2
+ import { recordCanonicalContractText } from "../contracts/contract-canonicalizer.js";
3
+ import { AVENTARA_PROTOCOL_VERSION } from "../contracts/contract-protocol.js";
4
+ import { emitFrameworkWarning } from "../runtime/framework-warning.emitter.js";
5
+ import { isRecord } from "../runtime/record.guard.js";
6
+ import { CORE_VERSION } from "./core-version.generated.js";
7
+ import { listedNames, prebuiltHeaderChanges, prebuiltInputChanges, } from "./prebuilt-changes.js";
8
+ import { PREBUILT_FORMAT } from "./prebuilt-contracts.js";
9
+ import { prebuiltInputsFingerprint, prebuiltPartFingerprints, } from "./prebuilt-inputs.fingerprint.js";
10
+ const PREBUILT_STALE_WARNING = "AVENTARA_PREBUILT_STALE";
11
+ async function changedInputs(stored, model, config) {
12
+ const changes = prebuiltInputChanges(stored, await prebuiltPartFingerprints(model, config));
13
+ return changes.length === 0
14
+ ? "its fingerprint does not match the configuration and model"
15
+ : `${listedNames(changes)} since it was built`;
16
+ }
17
+ function textAt(record, key) {
18
+ const value = Object.hasOwn(record, key) ? record[key] : undefined;
19
+ return typeof value === "string" ? value : undefined;
20
+ }
21
+ function parsedContracts(texts) {
22
+ if (!isRecord(texts)) {
23
+ return undefined;
24
+ }
25
+ const parsed = {};
26
+ for (const origin of ["core", "application", "client", "agent"]) {
27
+ const text = textAt(texts, origin);
28
+ if (text === undefined) {
29
+ return undefined;
30
+ }
31
+ let contract;
32
+ try {
33
+ contract = JSON.parse(text);
34
+ }
35
+ catch {
36
+ return undefined;
37
+ }
38
+ if (!isRecord(contract)) {
39
+ return undefined;
40
+ }
41
+ parsed[origin] = contract;
42
+ }
43
+ const contracts = parsed;
44
+ recordCanonicalContractText(contracts.client, textAt(texts, "client") ?? "");
45
+ recordCanonicalContractText(contracts.agent, textAt(texts, "agent") ?? "");
46
+ return contracts;
47
+ }
48
+ export async function loadPrebuiltContracts(prebuilt, model, config, resolved) {
49
+ if (!isRecord(prebuilt)) {
50
+ return { ok: false, reason: "it is not a prebuilt Contracts file" };
51
+ }
52
+ const [header] = prebuiltHeaderChanges(prebuilt, {
53
+ format: PREBUILT_FORMAT,
54
+ core: CORE_VERSION,
55
+ protocol: AVENTARA_PROTOCOL_VERSION,
56
+ });
57
+ if (header !== undefined) {
58
+ return { ok: false, reason: header };
59
+ }
60
+ if ((await prebuiltInputsFingerprint(model, config)) !== prebuilt.fingerprint) {
61
+ return {
62
+ ok: false,
63
+ reason: await changedInputs(prebuilt.fingerprints, model, config),
64
+ };
65
+ }
66
+ const contracts = parsedContracts(prebuilt.contracts);
67
+ if (contracts === undefined) {
68
+ return { ok: false, reason: "its Contracts are not readable JSON objects" };
69
+ }
70
+ bindPrebuiltContracts(model, resolved, contracts);
71
+ return { ok: true, contracts };
72
+ }
73
+ export function warnStalePrebuilt(reason) {
74
+ emitFrameworkWarning(`prebuilt Contracts are stale and were not used: ${reason}. The Contracts were compiled at startup instead; regenerate the file with aventara-build.`, PREBUILT_STALE_WARNING);
75
+ }
@@ -0,0 +1,16 @@
1
+ import type { AvAdapterModel } from "../adapters/adapter-model.js";
2
+ /**
3
+ * The fingerprint of the inputs Contracts are compiled from: `config` as
4
+ * authored (its `adapter` and `prebuilt` left out), `model`, this core's
5
+ * version, the protocol version and the file format.
6
+ */
7
+ export declare function prebuiltInputsFingerprint(model: AvAdapterModel, config: object): Promise<string>;
8
+ /** The inputs' parts, each fingerprinted on its own: what a file stores to name what changed. */
9
+ export type PrebuiltPartFingerprints = {
10
+ /** The inputs that belong to no single Resource. */
11
+ readonly shared: string;
12
+ /** Each Resource's inputs (its model, and its entries in every layer), by name, sorted. */
13
+ readonly resources: Readonly<Record<string, string>>;
14
+ };
15
+ /** The parts of the same inputs as {@link prebuiltInputsFingerprint}'s, each fingerprinted. */
16
+ export declare function prebuiltPartFingerprints(model: AvAdapterModel, config: object): Promise<PrebuiltPartFingerprints>;
@@ -0,0 +1,227 @@
1
+ import { avzCheckOf } from "../avz/avz-check.registry.js";
2
+ import { jsonShapeOf } from "../avz/json-shape.registry.js";
3
+ import { hashCanonicalContractText } from "../contracts/contract-hash.js";
4
+ import { AVENTARA_PROTOCOL_VERSION } from "../contracts/contract-protocol.js";
5
+ import { isRecord } from "../runtime/record.guard.js";
6
+ import { CORE_VERSION } from "./core-version.generated.js";
7
+ import { PREBUILT_FORMAT } from "./prebuilt-contracts.js";
8
+ const LAYERS = ["root", "application", "client", "agent"];
9
+ const NOT_INPUTS = new Set(["adapter", "prebuilt"]);
10
+ const PER_RESOURCE = "#resources";
11
+ function sortedRecord(record) {
12
+ const keys = Object.keys(record);
13
+ const prototype = Object.getPrototypeOf(record);
14
+ const plain = prototype === Object.prototype || prototype === null;
15
+ let written = plain;
16
+ for (let index = 0; written && index < keys.length; index += 1) {
17
+ const key = keys[index];
18
+ written =
19
+ !key.startsWith("#") &&
20
+ (index === 0 || keys[index - 1] < key);
21
+ }
22
+ if (written) {
23
+ return record;
24
+ }
25
+ const sorted = {};
26
+ if (!plain) {
27
+ const name = record.constructor?.name;
28
+ sorted["#class"] = typeof name === "string" ? name : "";
29
+ }
30
+ for (const key of keys.sort()) {
31
+ sorted[key.startsWith("#") ? `#${key}` : key] = record[key];
32
+ }
33
+ return sorted;
34
+ }
35
+ function inputMember(key, value) {
36
+ const raw = this[key];
37
+ switch (typeof raw) {
38
+ case "string":
39
+ return raw.startsWith("#") ? `#${raw}` : raw;
40
+ case "number":
41
+ return Number.isFinite(raw) ? raw : `#number(${raw})`;
42
+ case "bigint":
43
+ return `#bigint(${raw})`;
44
+ case "function":
45
+ return "#function";
46
+ case "symbol":
47
+ return `#symbol(${String(raw.description)})`;
48
+ case "undefined":
49
+ return "#undefined";
50
+ case "boolean":
51
+ return raw;
52
+ }
53
+ if (raw === null) {
54
+ return value;
55
+ }
56
+ const check = avzCheckOf(raw);
57
+ if (check !== undefined) {
58
+ return `#avz(${inputText(check)})`;
59
+ }
60
+ const shape = jsonShapeOf(raw);
61
+ if (shape !== undefined) {
62
+ return `#shape(${inputText(shape.schema)})`;
63
+ }
64
+ if (raw instanceof Date) {
65
+ return `#date(${Number.isNaN(raw.getTime()) ? "invalid" : raw.toISOString()})`;
66
+ }
67
+ if (raw instanceof RegExp) {
68
+ return `#regexp(${JSON.stringify(raw.source)},${raw.flags})`;
69
+ }
70
+ if (raw instanceof Map || raw instanceof Set) {
71
+ return `#${raw instanceof Map ? "map" : "set"}(${inputText([...raw])})`;
72
+ }
73
+ if (value !== raw) {
74
+ return `#json(${inputText(value)})`;
75
+ }
76
+ return Array.isArray(raw) ? raw : sortedRecord(raw);
77
+ }
78
+ function inputText(value) {
79
+ return JSON.stringify(value, inputMember);
80
+ }
81
+ function modelText(value) {
82
+ try {
83
+ return JSON.stringify(value) ?? "#undefined";
84
+ }
85
+ catch {
86
+ return inputText(value);
87
+ }
88
+ }
89
+ function recordAt(value, key) {
90
+ if (!isRecord(value) || !Object.hasOwn(value, key)) {
91
+ return undefined;
92
+ }
93
+ const member = value[key];
94
+ return isRecord(member) ? member : undefined;
95
+ }
96
+ function layerOf(config, layer) {
97
+ return layer === "root"
98
+ ? config
99
+ : Object.hasOwn(config, layer)
100
+ ? config[layer]
101
+ : undefined;
102
+ }
103
+ function sharedLayer(layer) {
104
+ if (!isRecord(layer)) {
105
+ return layer;
106
+ }
107
+ const shared = { ...layer };
108
+ if (isRecord(layer.resources)) {
109
+ shared.resources = PER_RESOURCE;
110
+ }
111
+ const exemptions = layer.exemptions;
112
+ if (isRecord(exemptions) && isRecord(exemptions.resources)) {
113
+ shared.exemptions = { ...exemptions, resources: PER_RESOURCE };
114
+ }
115
+ return shared;
116
+ }
117
+ function policyInput(policy) {
118
+ if (!isRecord(policy) || !Object.hasOwn(policy, "engine")) {
119
+ return policy;
120
+ }
121
+ const engine = policy.engine;
122
+ const governed = engine !== null && typeof engine === "object"
123
+ ? engine.governed
124
+ : undefined;
125
+ return { ...policy, engine: { governed: governed ?? null } };
126
+ }
127
+ function accessInput(access) {
128
+ if (!isRecord(access)) {
129
+ return access;
130
+ }
131
+ const engine = access.policy;
132
+ const governed = engine !== null && typeof engine === "object"
133
+ ? engine.governed
134
+ : undefined;
135
+ const policy = { policy: { governed: governed ?? null } };
136
+ return access.client === undefined
137
+ ? policy
138
+ : { ...policy, client: accessClientInput(access.client) };
139
+ }
140
+ function accessClientInput(client) {
141
+ if (!isRecord(client)) {
142
+ return client;
143
+ }
144
+ const verbs = isRecord(client.verbs)
145
+ ? Object.fromEntries(Object.entries(client.verbs).map(([name, verb]) => [
146
+ name,
147
+ isRecord(verb)
148
+ ? {
149
+ method: verb.method,
150
+ path: verb.path,
151
+ args: verb.args,
152
+ result: verb.result,
153
+ }
154
+ : verb,
155
+ ]))
156
+ : client.verbs;
157
+ return { url: client.url, verbs };
158
+ }
159
+ function authoredInputs(config) {
160
+ const authored = config;
161
+ const root = {};
162
+ for (const key of Object.keys(authored)) {
163
+ if (!NOT_INPUTS.has(key)) {
164
+ root[key] =
165
+ key === "policy"
166
+ ? policyInput(authored[key])
167
+ : key === "access"
168
+ ? accessInput(authored[key])
169
+ : authored[key];
170
+ }
171
+ }
172
+ return root;
173
+ }
174
+ const HEADER = `aventara-prebuilt format ${PREBUILT_FORMAT} core ${CORE_VERSION} protocol ${AVENTARA_PROTOCOL_VERSION}`;
175
+ export function prebuiltInputsFingerprint(model, config) {
176
+ return hashCanonicalContractText(`${HEADER}\n${inputText(authoredInputs(config))}\n${modelText(model)}`);
177
+ }
178
+ export async function prebuiltPartFingerprints(model, config) {
179
+ const root = authoredInputs(config);
180
+ const names = new Set(Object.keys(model.resources));
181
+ for (const layer of LAYERS) {
182
+ const value = layerOf(root, layer);
183
+ for (const name of Object.keys(recordAt(value, "resources") ?? {})) {
184
+ names.add(name);
185
+ }
186
+ const exemptions = recordAt(value, "exemptions");
187
+ for (const name of Object.keys(recordAt(exemptions, "resources") ?? {})) {
188
+ names.add(name);
189
+ }
190
+ }
191
+ const sharedRoot = sharedLayer(root);
192
+ for (const layer of LAYERS) {
193
+ if (layer !== "root" && Object.hasOwn(root, layer)) {
194
+ sharedRoot[layer] = sharedLayer(root[layer]);
195
+ }
196
+ }
197
+ const { resources: _resources, ...sharedModel } = model;
198
+ const shared = hashCanonicalContractText(`${HEADER}\n${inputText(sharedRoot)}\n${modelText(sharedModel)}`);
199
+ const sorted = [...names].sort();
200
+ const parts = sorted.map((name) => {
201
+ const entries = {};
202
+ for (const layer of LAYERS) {
203
+ const value = layerOf(root, layer);
204
+ const resources = recordAt(value, "resources");
205
+ const exemptions = recordAt(recordAt(value, "exemptions"), "resources");
206
+ const entry = {};
207
+ if (resources !== undefined && Object.hasOwn(resources, name)) {
208
+ entry.resources = resources[name];
209
+ }
210
+ if (exemptions !== undefined && Object.hasOwn(exemptions, name)) {
211
+ entry.exemptions = exemptions[name];
212
+ }
213
+ if (Object.keys(entry).length > 0) {
214
+ entries[layer] = entry;
215
+ }
216
+ }
217
+ const modelPart = Object.hasOwn(model.resources, name)
218
+ ? modelText(model.resources[name])
219
+ : "#absent";
220
+ return hashCanonicalContractText(`${inputText(entries)}\n${modelPart}`);
221
+ });
222
+ const hashes = await Promise.all(parts);
223
+ return {
224
+ shared: await shared,
225
+ resources: Object.fromEntries(sorted.map((name, index) => [name, hashes[index]])),
226
+ };
227
+ }
@@ -1,12 +1,14 @@
1
1
  import type { AvContracts } from "../compiler/contract.compiler.js";
2
2
  import type { RemoteRequestOrigin } from "../config/config-layer.js";
3
+ import type { AvContractClient } from "../contracts/contract.js";
3
4
  import { type AvOperationIdentity } from "../operations/operation-identity.js";
4
5
  import { type AvDiagnosticsSink } from "../runtime/diagnostics-reporter.js";
5
- import type { ClientProtocolIdentity } from "../runtime/operation-request.js";
6
+ import type { AvRequestProtocol } from "../runtime/operation-request.js";
6
7
  import { type AvOperationFailureResponse } from "../runtime/operation-response.js";
7
8
  import type { AvProtocolRequest } from "./http-request.decoder.js";
8
9
  import { type ReadRequest } from "./http-request.reader.js";
9
10
  import { type AvProtocolResponse } from "./http-response.encoder.js";
11
+ import { type ReadQuery } from "./read-query.codec.js";
10
12
  /**
11
13
  * The absence answers: the checks a framework route makes before it reads a body, runs
12
14
  * a pipeline or reaches an Adapter — the protocol version (`A2006`), the
@@ -22,7 +24,7 @@ export type OperationRouteSegments = {
22
24
  readonly variant: string;
23
25
  };
24
26
  /** What a route check resolves to: the operation it names, or the answer that refuses it. */
25
- export type OperationRouteResolution = {
27
+ type OperationRouteResolution = {
26
28
  readonly ok: true;
27
29
  readonly operation: AvOperationIdentity;
28
30
  } | {
@@ -36,7 +38,7 @@ export type OperationRouteResolution = {
36
38
  * is a standard operation the Resource advertises, read through
37
39
  * `isOperationVariantAvailable` alone.
38
40
  */
39
- export declare function resolveOperationRoute(contracts: AvContracts, protocol: ClientProtocolIdentity, route: OperationRouteSegments, origin?: RemoteRequestOrigin): OperationRouteResolution;
41
+ export declare function resolveOperationRoute(contracts: AvContracts, protocol: AvRequestProtocol, route: OperationRouteSegments, origin?: RemoteRequestOrigin): OperationRouteResolution;
40
42
  /**
41
43
  * The `/_transactions` route under one client protocol identity: version → hash → the
42
44
  * ClientContract's transaction capability. The route exists only when that capability
@@ -44,37 +46,70 @@ export declare function resolveOperationRoute(contracts: AvContracts, protocol:
44
46
  * it — and is otherwise absent with core's own refusal of a plan. `undefined` when the
45
47
  * route is there.
46
48
  */
47
- export declare function transactionsRouteFailure(contracts: AvContracts, protocol: ClientProtocolIdentity, origin?: RemoteRequestOrigin): AvOperationFailureResponse | undefined;
49
+ declare function transactionsRouteFailure(contracts: AvContracts, protocol: AvRequestProtocol, origin?: RemoteRequestOrigin): AvOperationFailureResponse | undefined;
50
+ /**
51
+ * The `/_access/can` route under one client protocol identity: version → hash →
52
+ * the Contract's `access` section. The route exists only when the section is
53
+ * there — tested as `protocol.surface()` tests it — and is otherwise absent.
54
+ * `undefined` when the route is there.
55
+ */
56
+ declare function accessCanRouteFailure(contracts: AvContracts, protocol: AvRequestProtocol, origin?: RemoteRequestOrigin): AvOperationFailureResponse | undefined;
57
+ /**
58
+ * The `/_all` route under one client protocol identity: version → hash → whether
59
+ * the Contract advertises any operation, tested as `protocol.surface()` tests it.
60
+ * `undefined` when the route is there.
61
+ */
62
+ declare function allRouteFailure(contracts: AvContracts, protocol: AvRequestProtocol, origin?: RemoteRequestOrigin): AvOperationFailureResponse | undefined;
48
63
  /**
49
64
  * What a route's checks before its body resolve to: the route a request
50
65
  * reaches, or the framework response that answers it instead.
51
66
  */
52
67
  type RouteCheck<Route> = ({
53
68
  readonly ok: true;
54
- readonly protocol: ClientProtocolIdentity;
69
+ readonly protocol: AvRequestProtocol;
55
70
  } & Route) | {
56
71
  readonly ok: false;
57
72
  readonly response: AvProtocolResponse;
58
73
  };
74
+ /** A cached read's mark in the Contract a route reads: its `for` and `maxAge`. */
75
+ type ReadCacheMark = NonNullable<NonNullable<AvContractClient["resources"][string]["cache"]>["first" | "unique" | "many" | "count"]>;
59
76
  /**
60
77
  * An operation route's checks before its body (decoder steps 2–4): the path (`A2000`
61
78
  * unless `/_resources/<r>/<f>/<v>`, each segment decodable and none empty), the
62
- * identity headers' presence (`A2000`), then {@link resolveOperationRoute} — version,
63
- * hash, Resource, operation — and the method (`A2012`, `Allow: POST`). One sequence
64
- * for both route styles: `decodeOperation` reads the body only after it passes,
79
+ * identity — a `GET`'s well-formed `q`/`v` query when it has a query, otherwise
80
+ * the headers' presence (`A2000`) — then {@link resolveOperationRoute} — version, hash, Resource,
81
+ * operation — and the method (`A2012`): `POST`, or `GET` for a `find` operation of
82
+ * read the Contract marks cacheable, whose `Allow` is then `GET, POST`. One sequence for
83
+ * both route styles: `decodeOperation` reads the body only after it passes,
65
84
  * `answerAbsent` never.
66
85
  */
67
- export declare function checkOperationRoute(contracts: AvContracts, read: ReadRequest, origin?: RemoteRequestOrigin): RouteCheck<{
86
+ export declare function checkOperationRoute(contracts: AvContracts, read: ReadRequest, origin?: RemoteRequestOrigin): OperationRouteCheck;
87
+ /** What an operation route's checks resolve to. */
88
+ type OperationRouteCheck = RouteCheck<{
68
89
  readonly resource: string;
69
90
  readonly operation: AvOperationIdentity;
91
+ /** The read's cache mark, for a `find` variant the Contract marks. */
92
+ readonly cache: ReadCacheMark | undefined;
93
+ /** A `GET`'s query, read; `undefined` without one (`A2000` for a cached read). */
94
+ readonly query: ReadQuery | undefined;
70
95
  }>;
96
+ /** Each fixed `POST` route, by path, and its absence under one protocol identity. */
97
+ declare const POST_ROUTE_FAILURES: {
98
+ readonly "/_transactions": typeof transactionsRouteFailure;
99
+ readonly "/_access/can": typeof accessCanRouteFailure;
100
+ readonly "/_all": typeof allRouteFailure;
101
+ };
102
+ /** `/_transactions`, `/_access/can` or `/_all`. */
103
+ type PostRoute = keyof typeof POST_ROUTE_FAILURES;
71
104
  /**
72
- * `/_transactions`' checks before its body: the path (`A2000` unless exactly
73
- * `/_transactions`), the identity headers' presence (`A2000`), then
74
- * {@link transactionsRouteFailure} — version, hash, `"interactive"` — and the
75
- * method (`A2012`, `Allow: POST`).
105
+ * A fixed `POST` route's checks before its body: the path (`A2000` unless
106
+ * exactly `route`), the identity headers' presence (`A2000`), then the route's
107
+ * own absence — version, hash, and {@link transactionsRouteFailure}'s
108
+ * `"interactive"`, {@link accessCanRouteFailure}'s `access` section or
109
+ * {@link allRouteFailure}'s advertised operation — and the method (`A2012`,
110
+ * `Allow: POST`).
76
111
  */
77
- export declare function checkTransactionsRoute(contracts: AvContracts, read: ReadRequest, origin?: RemoteRequestOrigin): RouteCheck<object>;
112
+ export declare function checkPostRoute(route: PostRoute, contracts: AvContracts, read: ReadRequest, origin?: RemoteRequestOrigin): RouteCheck<object>;
78
113
  /**
79
114
  * `protocol.answerAbsent(request)` — the fallback a host that mounts one route per
80
115
  * `protocol.surface()` entry mounts for every path it did not. Never a catch-all into