@aventara/core 1.0.0-rc.4 → 1.0.0-rc.8

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 (60) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/ERRORS.md +1 -1
  3. package/README.md +5 -1
  4. package/dist/adapters/adapter-field.d.ts +8 -0
  5. package/dist/adapters/adapter-identifier.d.ts +9 -0
  6. package/dist/adapters/adapter-identifier.js +6 -1
  7. package/dist/adapters/adapter-operation.d.ts +12 -6
  8. package/dist/compiler/contract.compiler.js +26 -3
  9. package/dist/config/framework-config.d.ts +5 -1
  10. package/dist/contracts/contract.d.ts +15 -1
  11. package/dist/contracts/field.d.ts +17 -0
  12. package/dist/contracts/scalar-value-type.d.ts +3 -1
  13. package/dist/framework/framework-construction.error.d.ts +2 -1
  14. package/dist/framework/framework-construction.error.js +11 -1
  15. package/dist/framework/framework.d.ts +4 -4
  16. package/dist/framework/operation-facade.d.ts +6 -6
  17. package/dist/index.d.ts +6 -3
  18. package/dist/internal.d.ts +1 -2
  19. package/dist/internal.js +1 -0
  20. package/dist/operations/operation-arguments.d.ts +43 -27
  21. package/dist/operations/operation-call.d.ts +2 -2
  22. package/dist/operations/operation-result.d.ts +1 -1
  23. package/dist/policy/policy-admission.js +12 -3
  24. package/dist/policy/policy-after-update.runtime.js +5 -4
  25. package/dist/policy/policy-engine.d.ts +11 -4
  26. package/dist/policy/policy-nested-write.runtime.js +11 -7
  27. package/dist/policy/policy-read.runtime.d.ts +0 -2
  28. package/dist/policy/policy-read.runtime.js +18 -9
  29. package/dist/policy/policy-request.d.ts +7 -3
  30. package/dist/policy/policy-request.js +14 -3
  31. package/dist/policy/policy-session.d.ts +14 -4
  32. package/dist/policy/policy-session.js +12 -11
  33. package/dist/policy/policy-startup.validator.js +3 -5
  34. package/dist/policy/policy-write.runtime.d.ts +7 -0
  35. package/dist/policy/policy-write.runtime.js +23 -8
  36. package/dist/prebuilt/core-version.generated.d.ts +1 -1
  37. package/dist/prebuilt/core-version.generated.js +1 -1
  38. package/dist/prebuilt/prebuilt-changes.d.ts +28 -0
  39. package/dist/prebuilt/prebuilt-changes.js +65 -0
  40. package/dist/prebuilt/prebuilt-contracts.loader.js +11 -56
  41. package/dist/protocol/absent-route.responder.d.ts +4 -4
  42. package/dist/protocol/http-request.decoder.d.ts +2 -2
  43. package/dist/protocol/http-request.reader.d.ts +2 -2
  44. package/dist/protocol/protocol-headers.d.ts +3 -3
  45. package/dist/runtime/computed-read-runtime.js +2 -7
  46. package/dist/runtime/context-executor.runtime.d.ts +2 -2
  47. package/dist/runtime/create-requirement.js +1 -1
  48. package/dist/runtime/diagnostics-reporter.d.ts +5 -5
  49. package/dist/runtime/operation-request.d.ts +9 -9
  50. package/dist/runtime/operation-runtime.d.ts +8 -8
  51. package/dist/runtime/operation-runtime.js +30 -9
  52. package/dist/runtime/owned-execution.registry.d.ts +2 -2
  53. package/dist/runtime/referential-action.d.ts +1 -1
  54. package/dist/transactions/sql-statement.d.ts +2 -2
  55. package/dist/transactions/transaction-plan-assembler.d.ts +2 -2
  56. package/dist/transactions/transaction-plan-validator.d.ts +5 -5
  57. package/dist/transactions/transaction-request.d.ts +8 -8
  58. package/dist/transactions/transaction-runtime.d.ts +2 -2
  59. package/dist/transactions/transaction-runtime.js +12 -7
  60. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,106 @@
1
1
  # @aventara/core
2
2
 
3
+ ## 1.0.0-rc.8
4
+
5
+ 1.0.0-rc.5, rc.6 and rc.7 were tagged but never published; 1.0.0-rc.8 contains everything listed under them and the changes below.
6
+
7
+ ### Patch Changes
8
+
9
+ - 1c8e4ee: Helpers typed off the façades compile again in projects that emit declarations. In 1.0.0-rc.7 a function that took
10
+ `Parameters<AppFramework["application"]["Post"]["find"]["many"]>[0]` and returned its `where` (or built a new one
11
+ from it, `{ AND: [args.where ?? {}, { published: { equals: true } }] }`) without a return type failed `nest build`
12
+ (and `tsc` with `"declaration": true`) with `TS4023: ... has or is using name 'ScalarFilterOperands' ... but cannot be
13
+ named`, usually beside `TS7056`. A nested write's data could fail the same way, or name `NO_ADVERTISED_MEMBER`, and a
14
+ nested `$update`'s `where` was written into the `.d.ts` as `any`. The declaration now names the argument types
15
+ `@aventara/core` exports (`AvWhereInput`, `AvUpdateDataInput`, `AvCreateDataInput`, ...), and these new exports cover
16
+ the rest:
17
+
18
+ - `AvScalarFilterOperands`: one field's filter operators, which a filter's `not` holds again.
19
+ - `AvScalarWhereInput`: the `where` of a nested `$update` or `$delete` that only takes plain fields.
20
+ - `AvNoAdvertisedMember`: a write member that advertises nothing; it takes `{}` and refuses every key.
21
+ - `AvSqlStatementBuilder` and `AvSqlStatementValue`: the type of `framework.appTx.$sql` and the values it binds.
22
+ A method returning `framework.appTx.$sql` failed with `TS2883`/`TS2742` before.
23
+
24
+ `framework.execute` and `framework.executeTransaction` take request types that `@aventara/core` exports:
25
+ `AvOperationRequest` (`AvApplicationOperationRequest`, `AvClientOperationRequest`, `AvAgentOperationRequest`),
26
+ `AvTransactionRequest` (`AvApplicationTransactionRequest`, `AvClientTransactionRequest`,
27
+ `AvAgentTransactionRequest`) and `AvRequestProtocol` (a remote request's `protocol`). They were named from
28
+ `@aventara/core/internal` (`FrameworkOperationRequest`, `FrameworkTransactionRequest`, ...), so a declaration that
29
+ spelled them reached into the package's internal entry. Those names are gone from `@aventara/core/internal`.
30
+
31
+ An adapter's `referentialActions` edges name the fields that hold the reference `referenceFields`, as a relation of
32
+ the Core Contract does. They were called `references`, which the Core Contract uses for the target's fields.
33
+
34
+ Reading a projecting variant's argument type (`Parameters<…["find"]["many"]>[0]`) also type-checks faster: about
35
+ 6,000 type instantiations over a three-field model, where rc.7 took about 29,000. The part of the argument other than
36
+ `select`/`include` is now marked `NoInfer` in the call's parameter, so an editor shows that parameter as
37
+ `NoInfer<Omit<…>> & …`. What it accepts is unchanged.
38
+
39
+ A create's `data` type now states each required field once, as a required member (`Readonly<{ title: string; } & {
40
+ body?: ... }>` in an editor's expanded hover). Before, a required field appeared as an optional member beside a
41
+ separate `{ readonly title: WrittenValue }`, and a declaration file wrote both. What a create accepts and refuses is
42
+ unchanged.
43
+
44
+ - Operation results read as their value types in an editor and in emitted declarations. A result field that is nullable,
45
+ an enum or a `boolean` (such as a `Boolean @default(false)` column) was shown as `AvScalarValueType<…>`, with the
46
+ whole Contract view as its argument, and a project with `"declaration": true` wrote that view into its `.d.ts` once
47
+ per such field: a Nest service of five methods with no return types came out at 524 lines. Those fields now read
48
+ `body: string | null`, `published: boolean`, `publishedAt: Date | null`, and that service's declaration is 44 lines.
49
+ A result, and a relation included in it, is shown as its fields rather than as `ProjectedFields<…>`. This covers
50
+ `framework.application` and `framework.client` results, the same fields in a write's `data`, and clients generated
51
+ by `avclient`. What each type accepts is unchanged.
52
+
53
+ ## 1.0.0-rc.7
54
+
55
+ 1.0.0-rc.5 and 1.0.0-rc.6 were tagged but never published; 1.0.0-rc.7 contains everything listed under them and the changes below.
56
+
57
+ ### Patch Changes
58
+
59
+ - f917c1c: A helper that reads `framework.contracts.core` compiles again in projects that emit declarations. In 1.0.0-rc.6 a
60
+ function returning a Resource or a field of the Core Contract without a return type, such as
61
+ `core.resources[resource]?.fields[relation]`, failed `nest build` (and `tsc` with `"declaration": true`, which Nest's
62
+ `tsconfig.json` sets) with `TS2883: The inferred type of 'relationOf' cannot be named without a reference to
63
+ 'AvCoreField'` under TypeScript 6 (`TS2742` under 5.9), or with `TS4058`/`TS4023` naming `AvCoreResource`.
64
+ `@aventara/core` now exports the three types the Core Contract is written with: `AvCoreResource` (a Resource),
65
+ `AvCoreField` (one of its fields) and `AvCoreRelationField` (a relation field, with the target fields its reference
66
+ names in `references`).
67
+
68
+ A policy's startup check states the path once: `CONFIG_INVALID_VALUE at policy.engine.governed.Nope: "Nope" is no
69
+ Resource of the Core Contract`, where rc.6 repeated `policy.engine.governed.Nope:` inside the message. Each
70
+ diagnostic's `message` no longer starts with its `path`; read the path from `path`.
71
+
72
+ ## 1.0.0-rc.6
73
+
74
+ 1.0.0-rc.5 was tagged but never published. 1.0.0-rc.6 contains everything listed under 1.0.0-rc.5 and the fix below.
75
+
76
+ ### Patch Changes
77
+
78
+ - 1cf72e0: Typed policy engines compile again in projects that emit declarations. In 1.0.0-rc.5 an engine written
79
+ `as const satisfies AvPolicyEngine` failed `nest build` (and `tsc` with `"declaration": true`, which Nest's
80
+ `tsconfig.json` sets) with `TS2883: The inferred type of 'policyEngine' cannot be named without a reference to
81
+ 'PolicyFieldsAccess'` under TypeScript 6, or `TS2742` under 5.9, and so did the configuration and the framework holding
82
+ it. `fieldsOf`'s question is now written out in full in `AvPolicyEngine`, so a declaration can spell it.
83
+
84
+ A read question's `action` is now typed `undefined`, so an engine can destructure it from either question:
85
+ `fieldsOf({ resource, access, action })`. A write question's `action` is `"create"` or `"update"`, as before.
86
+
87
+ ## 1.0.0-rc.5
88
+
89
+ ### Patch Changes
90
+
91
+ - 4795ff1: Two additions for policy engines. A Framework without a policy, and every Contract a caller is served, are unchanged.
92
+
93
+ - A policy engine can check a create whose row reaches another Resource through a relation. Discovery now states, on the end of a relation that holds the reference, which of the target's fields its reference fields name, pair by pair (`Note.campaign`: `referenceFields: ["campaignId"]`, `references: ["id"]`). An engine reads them from the model it is built from (a Prisma discovery artifact's `model`) or from `framework.contracts.core`, and asks one `exists` about the row they name: "a player creates a note only in a campaign they play in". Only the adapter's model and the Core Contract carry them. The Application, Client and Agent Contracts, `/_contract`, the MCP tools and every ClientContract hash are unchanged. The discovery artifact's model hash, and so a prebuilt Contracts file's fingerprint, change: regenerate the artifact and rebuild the prebuilt file.
94
+ - `fieldsOf({ access: "write" })` also names the action that writes the record, `action: "create" | "update"` (an upsert's branches each their own, a nested record its directive's), so an engine can lock a field on update and still let a create write it. A read question names none. An engine that ignores it keeps working.
95
+
96
+ - 9e178ca: Fixes for applications that check requests with a policy engine. A Framework without a policy behaves as before.
97
+
98
+ - A cursor on a row the caller cannot read is answered exactly as a cursor on a row that does not exist, at the root and in a to-many relation, whatever values the caller sends beside the identifier. Before, the page started at the hidden row, so it told that the row exists and where its values sort. The Prisma adapter reads the cursor's row under the read scope first: one statement more for a cursor on a readable row, and only that read for one on a row the caller cannot read.
99
+ - A unique update with a nested write (`$create`, `$connect`, …) on a row the caller can read but not change answers `A4002`, as the same update without one does. It answered `A2003`. A row the caller cannot read still answers `A2003`.
100
+ - The `exists` questions a policy asks select the Resource's primary identifier, never another unique field such as a governed `email`.
101
+ - `policy.principal` may answer with a promise. A synchronous principal works as before; a rejection answers `A3000`, as a throw does.
102
+ - `AvConstructionError.message` names the first problem and how many more there are, for example `Aventara framework configuration validation failed: CONFIG_INVALID_TYPE at adapter.execute: adapter.execute must be a function (+2 more)`. `stage` and `diagnostics` are unchanged.
103
+
3
104
  ## 1.0.0-rc.4
4
105
 
5
106
  ### Patch Changes
package/ERRORS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Aventara error codes
2
2
 
3
- Every code `@aventara/core` 1.0.0-rc.4 answers, reports in a validation issue, or refuses to start with. Generated from `AvErrorCatalog` (exported by `@aventara/core`); do not edit.
3
+ Every code `@aventara/core` 1.0.0-rc.8 answers, reports in a validation issue, or refuses to start with. Generated from `AvErrorCatalog` (exported by `@aventara/core`); do not edit.
4
4
 
5
5
  Branch on the code, never on the message. In code, `AvErrorCatalog[code]` gives the same entry: `{ code, kind, message, cause, fix, docs }`.
6
6
 
package/README.md CHANGED
@@ -357,7 +357,11 @@ projection; name it to get it, `select: ["$defaults", "email"]`. A refusal answe
357
357
  Writes are checked too. A create asks `can` about each new row, whose rules may look rows up through `exists`. An
358
358
  update or delete acts only on rows the caller may change and read; a single-row one that misses answers `A4002` when
359
359
  the caller can read the row and `A2003` when it cannot. A field the write sends must be in
360
- `fieldsOf({ access: "write" })`. An update that moves a row out of what the caller reads, or fails an `after` condition
360
+ `fieldsOf({ access: "write", action })`, `action` being `"create"` or `"update"` (an upsert's branches and a nested
361
+ record's directive each their own), so a field can be locked on update and still written at create. A rule that
362
+ reaches another Resource through a relation (a note only in a campaign its author plays in) reads which of the
363
+ target's fields the reference names from the Core Contract (`framework.contracts.core`, a relation's `references`
364
+ beside its `referenceFields`); no Contract a caller is served states them. An update that moves a row out of what the caller reads, or fails an `after` condition
361
365
  (`can` asked about the row the update returned), is rolled back. Where `transactionsStyle` is `"interactive"`, a
362
366
  checked write with a check after it (an update, a nested write) runs in a transaction of its own, and a create or
363
367
  delete checked before it runs is one statement; where it is `"none"`, a write that could only be checked after it runs
@@ -38,6 +38,14 @@ export type AvAdapterRelationField<M extends AvAdapterModel> = {
38
38
  * one. Absent on the end that holds no reference (`User.posts`); never empty.
39
39
  */
40
40
  readonly referenceFields?: readonly [string, ...string[]];
41
+ /**
42
+ * The target's scalar fields that `referenceFields` name, pair by pair in
43
+ * the same order (`Post.author`: `referenceFields: ["authorId"]`,
44
+ * `references: ["id"]`, so `Post.authorId` holds `User.id`). Stated only
45
+ * beside `referenceFields`, with as many entries; absent on the end that
46
+ * holds no reference, where the other end (`inverse`) states the pairs.
47
+ */
48
+ readonly references?: readonly [string, ...string[]];
41
49
  };
42
50
  /** One field the adapter discovered: a scalar or a relation. */
43
51
  export type AvAdapterField<M extends AvAdapterModel> = AvAdapterScalarField<M> | AvAdapterRelationField<M>;
@@ -13,3 +13,12 @@ export type AvAdapterIdentifier<TFields extends Readonly<Record<string, AvAdapte
13
13
  AvAdapterScalarFieldKey<TFields>,
14
14
  ...AvAdapterScalarFieldKey<TFields>[]
15
15
  ];
16
+ /**
17
+ * The Resource's identifier as the Adapter states it first: in the Adapter's
18
+ * own order (an ORM adapter's is its schema's, so the primary key). The Core
19
+ * Contract sorts identifiers for its hash, so its first one is the
20
+ * alphabetically first (`email` before `id`) and says nothing about which is
21
+ * the primary key; the model keeps the order it declared. Empty for a Resource
22
+ * the model does not hold or that has no identifier.
23
+ */
24
+ export declare function adapterPrimaryIdentifier(model: AvAdapterModel, resource: string): readonly string[];
@@ -1 +1,6 @@
1
- export {};
1
+ export function adapterPrimaryIdentifier(model, resource) {
2
+ const resources = model.resources;
3
+ return ((Object.hasOwn(resources, resource)
4
+ ? resources[resource]?.identifiers?.[0]
5
+ : undefined) ?? []);
6
+ }
@@ -6,12 +6,18 @@ import type { AvAdapterModel } from "./adapter-model.js";
6
6
  * Operation identity and arguments remain provider-neutral; adapters receive
7
7
  * only validated semantic argument objects, never raw transport input.
8
8
  *
9
- * One shape exists here only: the flat unique selector of an `update.unique` or
10
- * a `delete.unique` may carry `AND`, a list of conditions in the general
11
- * `where` grammar the selected row must also meet. A row the selector names
12
- * that misses them is a miss (the same `null` as a row that is not there). An
13
- * adapter must honour it or refuse the operation, never drop it: dropping it
14
- * would write a row the conditions exclude.
9
+ * Two shapes exist here only, both an `AND`: a list of conditions in the
10
+ * general `where` grammar the addressed row must also meet.
11
+ *
12
+ * - The flat unique selector of an `update.unique` or a `delete.unique` may
13
+ * carry it. A row the selector names that misses them is a miss (the same
14
+ * `null` as a row that is not there).
15
+ * - A `cursor` may carry it, at the root of a `find.many` and in a to-many
16
+ * relation's arguments. A row the cursor names that misses them is a cursor
17
+ * that names no row: the same answer as a cursor on a row that is not there.
18
+ *
19
+ * An adapter must honour it or refuse the operation, never drop it: dropping it
20
+ * would write a row the conditions exclude, or position a page at one.
15
21
  */
16
22
  export type AvAdapterOperation<M extends AvAdapterModel = AvAdapterModel> = AvOperationIdentity & {
17
23
  readonly resource: Extract<keyof M["resources"], string>;
@@ -81,15 +81,28 @@ function cloneAdapterField(field) {
81
81
  ...(Array.isArray(field.referenceFields) && field.referenceFields.length > 0
82
82
  ? { referenceFields: [...field.referenceFields] }
83
83
  : {}),
84
+ ...(Array.isArray(field.referenceFields) &&
85
+ Array.isArray(field.references) &&
86
+ field.references.length > 0 &&
87
+ field.references.length === field.referenceFields.length
88
+ ? { references: [...field.references] }
89
+ : {}),
84
90
  };
85
91
  }
86
- function pruneHiddenPairings(projection) {
92
+ function pruneHiddenPairings(projection, references) {
87
93
  const resources = projection.resources;
88
94
  for (const [name, resource] of Object.entries(resources)) {
89
95
  for (const field of Object.values(resource.fields)) {
90
96
  if (field.kind !== "relation") {
91
97
  continue;
92
98
  }
99
+ if (Array.isArray(field.references) &&
100
+ (references === "none" ||
101
+ !wholePairing(resource.fields, Object.hasOwn(resources, String(field.target))
102
+ ? resources[String(field.target)]?.fields
103
+ : undefined, field.referenceFields, field.references))) {
104
+ delete field.references;
105
+ }
93
106
  if (Array.isArray(field.referenceFields)) {
94
107
  const shown = field.referenceFields.filter((reference) => typeof reference === "string" &&
95
108
  Object.hasOwn(resource.fields, reference) &&
@@ -113,6 +126,16 @@ function pruneHiddenPairings(projection) {
113
126
  }
114
127
  }
115
128
  }
129
+ function wholePairing(fields, targetFields, referenceFields, references) {
130
+ const shownIn = (within, name) => typeof name === "string" &&
131
+ within !== undefined &&
132
+ Object.hasOwn(within, name) &&
133
+ within[name]?.kind === "scalar";
134
+ return (Array.isArray(referenceFields) &&
135
+ referenceFields.length === references.length &&
136
+ referenceFields.every((name) => shownIn(fields, name)) &&
137
+ references.every((name) => shownIn(targetFields, name)));
138
+ }
116
139
  function cloneOperations(operations) {
117
140
  return cloneValue(operations);
118
141
  }
@@ -1008,7 +1031,7 @@ function projectCore(model, config, diagnostics) {
1008
1031
  const validators = compileValidatorTable(baseline.resources, scope.pipelines);
1009
1032
  const projection = projectExposure({ layer: "root", style: exposureStyle(scope), diagnostics }, baseline, baseline, scope.exemptions);
1010
1033
  qualifyFilterModes(projection);
1011
- pruneHiddenPairings(projection);
1034
+ pruneHiddenPairings(projection, "shown");
1012
1035
  projectCreateRequirements(model, projection.resources);
1013
1036
  checkHiddenRequirements(model, "root", baseline.resources, baseline.resources, projection.resources, diagnostics);
1014
1037
  applyValidators(projection.resources, validators);
@@ -1059,7 +1082,7 @@ function projectDerivedScope(model, scopeName, core, parentView, config, diagnos
1059
1082
  ...(scopeName === "agent" ? { parent: config.agent.parent } : {}),
1060
1083
  }, baseline, parent, scope.exemptions);
1061
1084
  qualifyFilterModes(projection);
1062
- pruneHiddenPairings(projection);
1085
+ pruneHiddenPairings(projection, "none");
1063
1086
  projectCreateRequirements(model, projection.resources);
1064
1087
  checkHiddenRequirements(model, scopeName, baseline.resources, parent.resources, projection.resources, diagnostics);
1065
1088
  applyValidators(projection.resources, validators);
@@ -90,7 +90,11 @@ export type AvConfig<M extends AvAdapterModel = AvAdapterModel, Cfg = AvConfigAn
90
90
  */
91
91
  readonly policy?: {
92
92
  readonly engine: AvPolicyEngine;
93
- /** The request's principal, from its `ctx.$state` and its layer; `null` for an anonymous caller. */
93
+ /**
94
+ * The request's principal, from its `ctx.$state` and its layer; `null` for
95
+ * an anonymous caller. It may answer with a promise (rc.5), which is
96
+ * awaited; a throw or a rejection answers `A3000`.
97
+ */
94
98
  readonly principal: (facts: {
95
99
  readonly $state: AvState;
96
100
  readonly $origin: AvRequestOrigin;
@@ -1,6 +1,7 @@
1
1
  import type { AvContractLimits } from "./contract-limits.js";
2
2
  import type { AvContractClientProtocol } from "./contract-protocol.js";
3
3
  import type { AvEnumDefinition } from "./enum-definition.js";
4
+ import type { AvCoreField } from "./field.js";
4
5
  import type { ReferenceWriteLimit } from "./reference-write-limit.js";
5
6
  import type { AvResource } from "./resource.js";
6
7
  import type { AvScalarRegistry } from "./scalar.js";
@@ -24,8 +25,21 @@ export interface AvContract {
24
25
  */
25
26
  readonly referenceWrites?: ReferenceWriteLimit;
26
27
  }
27
- /** The Contract compiled from the root configuration. */
28
+ /**
29
+ * The Contract compiled from the root configuration. Its relation fields also
30
+ * state the target's fields their reference names (`references`), which no
31
+ * other Contract carries.
32
+ */
28
33
  export interface AvContractCore extends AvContract {
34
+ /** The Resources, by name. */
35
+ readonly resources: Readonly<Record<string, AvCoreResource>>;
36
+ }
37
+ /**
38
+ * A Resource as the Core Contract states it: its fields are
39
+ * {@link AvCoreField}s, so its relation fields carry `references`.
40
+ */
41
+ export interface AvCoreResource extends AvResource<AvContractCore> {
42
+ readonly fields: Readonly<Record<string, AvCoreField<AvContractCore>>>;
29
43
  }
30
44
  /** The Contract in-process calls run under (`framework.application`). */
31
45
  export interface AvContractApplication extends AvContract {
@@ -176,3 +176,20 @@ export type AvRelationField<C extends AvContract> = {
176
176
  };
177
177
  /** One field of a Resource: a scalar or a relation. */
178
178
  export type AvField<C extends AvContract> = AvScalarField<C> | AvRelationField<C>;
179
+ /**
180
+ * A relation field as the Core Contract states it: an {@link AvRelationField}
181
+ * and, on the end that holds the reference, the target's fields it names.
182
+ */
183
+ export type AvCoreRelationField<C extends AvContract> = AvRelationField<C> & {
184
+ /**
185
+ * The target's scalar fields that `referenceFields` name, pair by pair in the
186
+ * same order (`Post.author`: `referenceFields: ["authorId"]`,
187
+ * `references: ["id"]`). Present only beside a `referenceFields` the
188
+ * Contract states whole, and only when every one of them is a scalar field
189
+ * the Core Contract shows on the target; absent on the end that holds no
190
+ * reference, where the other end (`inverse`) states the pairs.
191
+ */
192
+ readonly references?: readonly [string, ...string[]];
193
+ };
194
+ /** One field of a Resource as the Core Contract states it. */
195
+ export type AvCoreField<C extends AvContract> = AvScalarField<C> | AvCoreRelationField<C>;
@@ -78,5 +78,7 @@ type ListValue<List, Atom> = [List] extends [false] ? Atom : [List] extends [tru
78
78
  * - `list: true` → `readonly T[]`, whose entries are never `null`;
79
79
  * - `nullable: true` → `| null`, on the whole value, list or not.
80
80
  */
81
- export type AvScalarValueType<C extends AvContract, Field extends AvScalarField<C>, Forms extends ScalarForms = AvApplicationScalarForms> = ListValue<Field["list"], FieldAtom<C, Field, Forms>> | (true extends Field["nullable"] ? null : never);
81
+ export type AvScalarValueType<C extends AvContract, Field extends AvScalarField<C>, Forms extends ScalarForms = AvApplicationScalarForms> = [
82
+ ListValue<Field["list"], FieldAtom<C, Field, Forms>> | (true extends Field["nullable"] ? null : never)
83
+ ] extends [infer Value] ? Value : never;
82
84
  export {};
@@ -15,7 +15,8 @@ export type AvConstructionDiagnostic = ConstructionProblem & {
15
15
  };
16
16
  /**
17
17
  * Thrown by {@link createFramework} when construction fails: `stage` says
18
- * where, and `diagnostics` lists every problem found there.
18
+ * where, and `diagnostics` lists every problem found there. The message names
19
+ * the first of them and how many more there are.
19
20
  */
20
21
  export declare class AvConstructionError extends Error {
21
22
  readonly stage: AvConstructionStage;
@@ -4,11 +4,21 @@ const FRAMEWORK_CONSTRUCTION_MESSAGES = {
4
4
  discovery: "Aventara adapter discovery validation failed",
5
5
  "contract-compilation": "Aventara contract compilation failed",
6
6
  };
7
+ function constructionMessage(stage, diagnostics) {
8
+ const base = FRAMEWORK_CONSTRUCTION_MESSAGES[stage];
9
+ const [first] = diagnostics;
10
+ if (first === undefined) {
11
+ return base;
12
+ }
13
+ const where = first.path === "" ? "" : ` at ${first.path}`;
14
+ const more = diagnostics.length > 1 ? ` (+${diagnostics.length - 1} more)` : "";
15
+ return `${base}: ${first.code}${where}: ${first.message}${more}`;
16
+ }
7
17
  export class AvConstructionError extends Error {
8
18
  stage;
9
19
  diagnostics;
10
20
  constructor(stage, diagnostics) {
11
- super(FRAMEWORK_CONSTRUCTION_MESSAGES[stage]);
21
+ super(constructionMessage(stage, diagnostics));
12
22
  this.name = "AvConstructionError";
13
23
  this.stage = stage;
14
24
  this.diagnostics = diagnostics.map((diagnostic) => ({
@@ -2,10 +2,10 @@ import type { AvAdapterModel } from "../adapters/adapter-model.js";
2
2
  import type { AvContracts } from "../compiler/contract.compiler.js";
3
3
  import type { AvConfigAny } from "../config/any-framework-config.js";
4
4
  import type { AvMcpEndpoint } from "../config/config.resolver.js";
5
- import type { FrameworkOperationRequest } from "../runtime/operation-request.js";
5
+ import type { AvOperationRequest } from "../runtime/operation-request.js";
6
6
  import type { AvOperationResponse } from "../runtime/operation-response.js";
7
7
  import type { AvTransactionRunner } from "../transactions/deferred-operation.js";
8
- import type { FrameworkTransactionRequest } from "../transactions/transaction-request.js";
8
+ import type { AvTransactionRequest } from "../transactions/transaction-request.js";
9
9
  import type { AvTransactionResponse } from "../transactions/transaction-response.js";
10
10
  import type { ApplicationOperations, ApplicationTransactionBuilders, ClientOperations, ClientTransactionBuilders } from "./operation-facade.js";
11
11
  /**
@@ -72,7 +72,7 @@ export type AvFramework<M extends AvAdapterModel = AvAdapterModel, Cfg = AvConfi
72
72
  * share one (`A2004`/`V1020` at the first step of the other origin).
73
73
  */
74
74
  readonly clientTx: ClientTransactionBuilders<M, Cfg>;
75
- execute(request: FrameworkOperationRequest): Promise<AvOperationResponse>;
75
+ execute(request: AvOperationRequest): Promise<AvOperationResponse>;
76
76
  /**
77
77
  * Validates a whole transaction plan, then runs its operations one after
78
78
  * another inside one Adapter transaction. Answers `A1009` with each
@@ -83,7 +83,7 @@ export type AvFramework<M extends AvAdapterModel = AvAdapterModel, Cfg = AvConfi
83
83
  * Guards, pipes, hooks and interceptors run while the transaction is open, so
84
84
  * they should not perform network I/O or other slow work.
85
85
  */
86
- executeTransaction(request: FrameworkTransactionRequest): Promise<AvTransactionResponse>;
86
+ executeTransaction(request: AvTransactionRequest): Promise<AvTransactionResponse>;
87
87
  /**
88
88
  * Runs handles from `appTx`/`clientTx` as one transaction:
89
89
  * `framework.transaction([h1, h2, …], options?)`. Resolves each handle's
@@ -6,10 +6,10 @@ import type { AvOperationCall, AvOperationGrammar, DeferredArguments, DeferredPl
6
6
  import type { AvOperationIdentity } from "../operations/operation-identity.js";
7
7
  import { type PolicyCaller } from "../policy/policy-request.js";
8
8
  import type { AvExecutionOptions } from "../runtime/execution-options.js";
9
- import type { FrameworkOperationRequest } from "../runtime/operation-request.js";
9
+ import type { AvOperationRequest } from "../runtime/operation-request.js";
10
10
  import type { AvOperationResponse } from "../runtime/operation-response.js";
11
11
  import type { AvState } from "../runtime/request-state.js";
12
- import type { SqlStatementBuilder } from "../transactions/sql-statement.js";
12
+ import type { AvSqlStatementBuilder } from "../transactions/sql-statement.js";
13
13
  import type { AvTransactionResponse } from "../transactions/transaction-response.js";
14
14
  import type { AvContractApplicationView, ClientContractView } from "./contract-view.js";
15
15
  /**
@@ -94,9 +94,9 @@ type ApplicationSqlStep = {
94
94
  /**
95
95
  * A developer SQL step, written only as a tagged template:
96
96
  * ``framework.appTx.$sql<Row>`select … ${value}` ``. Every interpolated value
97
- * is bound as a parameter. See {@link SqlStatementBuilder}.
97
+ * is bound as a parameter. See {@link AvSqlStatementBuilder}.
98
98
  */
99
- readonly $sql: SqlStatementBuilder;
99
+ readonly $sql: AvSqlStatementBuilder;
100
100
  };
101
101
  /**
102
102
  * `framework.appTx`: one {@link AvAppTxResourceFacade} per Resource of `C`, the
@@ -149,8 +149,8 @@ type ComputeReadFacade<C> = C extends AvContract ? string extends AvResourceKey<
149
149
  };
150
150
  } : never;
151
151
  /** Builds the request one façade call hands to `execute`, under its request id and state. */
152
- export type FacadeRequest = (resource: string, identity: AvOperationIdentity, args: unknown, requestId: string, state: AvState | undefined) => FrameworkOperationRequest;
153
- type FacadeExecutor = (request: FrameworkOperationRequest, caller: PolicyCaller | undefined) => Promise<AvOperationResponse>;
152
+ export type FacadeRequest = (resource: string, identity: AvOperationIdentity, args: unknown, requestId: string, state: AvState | undefined) => AvOperationRequest;
153
+ type FacadeExecutor = (request: AvOperationRequest, caller: PolicyCaller | undefined) => Promise<AvOperationResponse>;
154
154
  /**
155
155
  * Builds a façade over `model`, the same object its types are read from, so a
156
156
  * call that type-checks always reaches `execute`: a Resource, variant or field
package/dist/index.d.ts CHANGED
@@ -13,12 +13,12 @@ export type { AvConfigExact } from "./config/exact-framework-config.js";
13
13
  export type { AvConfig, AvConfigAddedFieldDefinition, AvConfigAgentLayer, AvConfigAny, AvConfigExemptions, AvConfigFamily, AvConfigFieldDefinition, AvConfigFieldLifecycleTrait, AvConfigKnownFieldDefinition, AvConfigLayer, AvConfigLayerAny, AvConfigLayerKind, AvConfigLimits, AvConfigMcp, AvConfigOperations, AvConfigOperationsExemption, AvConfigOverlayField, AvConfigRelationFieldExemption, AvConfigResource, AvConfigResourceExemption, AvConfigResourceFields, AvConfigResourceKey, AvConfigResources, AvConfigResourcesAny, AvConfigResourceTransactions, AvConfigRootField, AvConfigScalarFieldExemption, AvConfigScalarTypeRef, AvConfigVariant, AvFieldCompute, AvRelationFieldCapabilityName, AvRelationFieldPipeline, AvScalarFieldCapabilityName, AvScalarFieldPipeline, AvZCheck, AvZFormat, } from "./config/framework-config.js";
14
14
  export type { AvPipeline, AvTransactionPipeline, } from "./config/pipeline-config.js";
15
15
  export type { AvPaginationCapability, AvProjectionScope, AvRelationFilterCapability, AvRelationMutationDirective, AvRelationReducer, AvScalarFilterOperator, AvScalarMutationDirective, AvWriteScope, } from "./contracts/capability.js";
16
- export type { AvContract, AvContractAgent, AvContractApplication, AvContractClient, AvContractCore, } from "./contracts/contract.js";
16
+ export type { AvContract, AvContractAgent, AvContractApplication, AvContractClient, AvContractCore, AvCoreResource, } from "./contracts/contract.js";
17
17
  export type { AvContractLimits } from "./contracts/contract-limits.js";
18
18
  export type { AvContractClientProtocol, AvContractHash, AvContractProtocol, } from "./contracts/contract-protocol.js";
19
19
  export type { AvCreateRequirementGroup, AvCreateRequirements, } from "./contracts/create-requirements.js";
20
20
  export type { AvEnumDefinition } from "./contracts/enum-definition.js";
21
- export type { AvField, AvProjectionScopes, AvRelationField, AvRelationFieldCapabilities, AvRelationMutationCapability, AvRelationProjectionCapability, AvRelationReducerCapability, AvScalarField, AvScalarFieldCapabilities, AvScalarFormat, AvScopedRelationMutations, AvScopedRelationReducers, AvWriteScopes, } from "./contracts/field.js";
21
+ export type { AvCoreField, AvCoreRelationField, AvField, AvProjectionScopes, AvRelationField, AvRelationFieldCapabilities, AvRelationMutationCapability, AvRelationProjectionCapability, AvRelationReducerCapability, AvScalarField, AvScalarFieldCapabilities, AvScalarFormat, AvScopedRelationMutations, AvScopedRelationReducers, AvWriteScopes, } from "./contracts/field.js";
22
22
  export type { AvFieldCheck } from "./contracts/field-check.js";
23
23
  export type { AvIdentifier, AvScalarFieldKey } from "./contracts/identifier.js";
24
24
  export type { AvLifecycleTrait } from "./contracts/lifecycle-trait.js";
@@ -33,7 +33,7 @@ export type { AvFramework } from "./framework/framework.js";
33
33
  export type { AvConstructionDiagnostic, AvConstructionStage, } from "./framework/framework-construction.error.js";
34
34
  export { AvConstructionError } from "./framework/framework-construction.error.js";
35
35
  export type { AvApplicationFacade, AvApplicationFamilyFacade, AvApplicationPlainCall, AvApplicationProjectingCall, AvApplicationResourceFacade, AvAppTxFacade, AvAppTxFamilyFacade, AvAppTxPlainCall, AvAppTxProjectingCall, AvAppTxResourceFacade, AvClientFacade, AvClientFamilyFacade, AvClientPlainCall, AvClientProjectingCall, AvClientResourceFacade, AvClientTxFacade, AvClientTxFamilyFacade, AvClientTxPlainCall, AvClientTxProjectingCall, AvClientTxResourceFacade, } from "./framework/operation-facade.js";
36
- export type { AvCreateDataInput, AvCursorInput, AvFieldKey, AvIncludeInput, AvNullsOrder, AvOperationArgumentMap, AvOperationArgumentsFor, AvOrderByEntry, AvOrderByInput, AvProjectionEntry, AvRelationProjectionInput, AvResourceKey, AvScalarOrderInput, AvSelectInput, AvSortDirection, AvUniqueWhereInput, AvUpdateDataInput, AvWhereInput, } from "./operations/operation-arguments.js";
36
+ export type { AvCreateDataInput, AvCursorInput, AvFieldKey, AvIncludeInput, AvNoAdvertisedMember, AvNullsOrder, AvOperationArgumentMap, AvOperationArgumentsFor, AvOrderByEntry, AvOrderByInput, AvProjectionEntry, AvRelationProjectionInput, AvResourceKey, AvScalarFilterOperands, AvScalarOrderInput, AvScalarWhereInput, AvSelectInput, AvSortDirection, AvUniqueWhereInput, AvUpdateDataInput, AvWhereInput, } from "./operations/operation-arguments.js";
37
37
  export type { AvDeferredOperationCall, AvOperationCall, AvOperationGrammar, AvOperationSlot, } from "./operations/operation-call.js";
38
38
  export type { AvOperationFamily, AvOperationIdentity, AvOperationVariant, } from "./operations/operation-identity.js";
39
39
  export type { AvOperationResultFor } from "./operations/operation-result.js";
@@ -48,14 +48,17 @@ export type { AvComputeContext, AvComputeCreate, AvComputeRead, AvComputeUpdate,
48
48
  export { AvAuthError, AvConflictError, AvContractMismatchError, AvError, AvInternalError, AvNotFoundError, AvProtocolError, AvValidationError, } from "./runtime/framework-error.js";
49
49
  export type { AvJsonValue } from "./runtime/json-value.js";
50
50
  export type { AvMisuseEvent, AvMisuseSink, } from "./runtime/misuse-reporter.js";
51
+ export type { AvAgentOperationRequest, AvApplicationOperationRequest, AvClientOperationRequest, AvOperationRequest, AvRequestProtocol, } from "./runtime/operation-request.js";
51
52
  export type { AvCause, AvOperationCode, AvOperationErrorCode, AvOperationFailureResponse, AvOperationNoMatchResponse, AvOperationResponse, AvOperationSuccessCode, AvOperationSuccessDataCode, AvOperationSuccessResponse, } from "./runtime/operation-response.js";
52
53
  export type { AvAfterHook, AvBeforeHook, AvContext, AvFieldGuard, AvFieldPipe, AvFilter, AvGuard, AvInterceptor, AvPipe, AvTransactionAfterHook, AvTransactionBeforeHook, AvTransactionContext, AvTransactionFilter, AvTransactionGuard, AvTransactionInterceptor, AvTransactionPipe, AvTransactionStep, AvTransportContext, } from "./runtime/pipeline.js";
53
54
  export type { AvDeepReadonly } from "./runtime/readonly-value.js";
54
55
  export type { AvState } from "./runtime/request-state.js";
55
56
  export type { AvOperation, AvOperationHandle, AvOperationReferenceSurface, AvReferenceableField, AvReferenceBuilder, AvSingleRowResult, AvTransactionResults, AvTransactionRunner, } from "./transactions/deferred-operation.js";
57
+ export type { AvSqlStatementBuilder, AvSqlStatementValue, } from "./transactions/sql-statement.js";
56
58
  export type { AvTransactionIntegrityViolation } from "./transactions/transaction-integrity-error.js";
57
59
  export { AvTransactionIntegrityError } from "./transactions/transaction-integrity-error.js";
58
60
  export type { AvTransactionReference } from "./transactions/transaction-reference.js";
61
+ export type { AvAgentTransactionRequest, AvApplicationTransactionRequest, AvClientTransactionRequest, AvTransactionRequest, } from "./transactions/transaction-request.js";
59
62
  export type { AvTransactionCommittedResponse, AvTransactionResponse, } from "./transactions/transaction-response.js";
60
63
  export type { AvTransactionSlotPathViolation } from "./transactions/transaction-slot-path-error.js";
61
64
  export { AvTransactionSlotPathError } from "./transactions/transaction-slot-path-error.js";
@@ -32,12 +32,11 @@ export type { AvDatabaseRefusal } from "./operations/database-refusal.js";
32
32
  export { DATABASE_REFUSALS } from "./operations/database-refusal.js";
33
33
  export type { SemanticOperationArguments } from "./operations/operation-validator.js";
34
34
  export { VALIDATION_CODES } from "./operations/validation-code.js";
35
+ export { prebuiltFileChanges } from "./prebuilt/prebuilt-changes.js";
35
36
  export { emitPrebuiltContracts, prebuiltContractsOf, } from "./prebuilt/prebuilt-contracts.emitter.js";
36
37
  export { mcpFailureReporterOf } from "./runtime/diagnostics-reporter.js";
37
38
  export type { AvErrorClassName } from "./runtime/framework-error-class.table.js";
38
39
  export { FRAMEWORK_ERROR_CLASS_OF } from "./runtime/framework-error-class.table.js";
39
- export type { AgentOperationRequest, ApplicationOperationRequest, ClientOperationRequest, ClientProtocolIdentity, FrameworkOperationRequest, } from "./runtime/operation-request.js";
40
40
  export { OPERATION_CODES } from "./runtime/operation-response.js";
41
41
  export type { BuiltinNonRow, OperationFingerprint, } from "./transactions/deferred-operation.js";
42
42
  export { computeOperationFingerprint } from "./transactions/operation-fingerprint.js";
43
- export type { AgentTransactionRequest, ApplicationTransactionRequest, ClientTransactionRequest, FrameworkTransactionRequest, } from "./transactions/transaction-request.js";
package/dist/internal.js CHANGED
@@ -13,6 +13,7 @@ export { BUILT_IN_SCALARS } from "./contracts/scalar.js";
13
13
  export { TRANSACTION_CAPABILITIES } from "./contracts/transaction-capability.js";
14
14
  export { DATABASE_REFUSALS } from "./operations/database-refusal.js";
15
15
  export { VALIDATION_CODES } from "./operations/validation-code.js";
16
+ export { prebuiltFileChanges } from "./prebuilt/prebuilt-changes.js";
16
17
  export { emitPrebuiltContracts, prebuiltContractsOf, } from "./prebuilt/prebuilt-contracts.emitter.js";
17
18
  export { mcpFailureReporterOf } from "./runtime/diagnostics-reporter.js";
18
19
  export { FRAMEWORK_ERROR_CLASS_OF } from "./runtime/framework-error-class.table.js";