@aventara/core 0.1.0-pilot.1 → 0.1.0-pilot.3

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 (139) hide show
  1. package/dist/adapters/adapter-field.d.ts +4 -4
  2. package/dist/adapters/adapter-resource.d.ts +10 -12
  3. package/dist/adapters/adapter.interface.d.ts +20 -10
  4. package/dist/compiler/contract-compiler-diagnostic.d.ts +3 -4
  5. package/dist/compiler/contract.compiler.d.ts +5 -4
  6. package/dist/compiler/contract.compiler.js +0 -132
  7. package/dist/config/config.resolver.d.ts +2 -2
  8. package/dist/config/config.resolver.js +0 -5
  9. package/dist/config/config.validator.d.ts +3 -3
  10. package/dist/config/config.validator.js +0 -8
  11. package/dist/config/define-fields.d.ts +2 -7
  12. package/dist/config/define-fields.js +0 -15
  13. package/dist/config/effective-fields.d.ts +4 -8
  14. package/dist/config/entrypoint.normalizer.d.ts +7 -7
  15. package/dist/config/entrypoint.normalizer.js +0 -22
  16. package/dist/config/framework-behaviors-config.d.ts +6 -6
  17. package/dist/config/framework-config.d.ts +3 -5
  18. package/dist/config/framework-restrictions-config.d.ts +19 -29
  19. package/dist/config/pipeline-config.d.ts +8 -18
  20. package/dist/contracts/capability.d.ts +18 -21
  21. package/dist/contracts/capability.js +0 -75
  22. package/dist/contracts/client-contract-structure.validator.d.ts +15 -22
  23. package/dist/contracts/client-contract-structure.validator.js +0 -27
  24. package/dist/contracts/contract-canonicalizer.js +0 -96
  25. package/dist/contracts/contract-hash.js +0 -2
  26. package/dist/contracts/contract-limits.js +0 -1
  27. package/dist/contracts/contract-lookup.js +0 -10
  28. package/dist/contracts/contract-protocol.js +0 -10
  29. package/dist/contracts/field.d.ts +23 -26
  30. package/dist/contracts/field.js +0 -107
  31. package/dist/contracts/lifecycle-trait.js +0 -5
  32. package/dist/contracts/resource-operations.d.ts +17 -18
  33. package/dist/contracts/resource-operations.js +0 -63
  34. package/dist/contracts/scalar-value-type.d.ts +12 -22
  35. package/dist/contracts/scalar.js +0 -1
  36. package/dist/contracts/wire-scalar-format.d.ts +20 -20
  37. package/dist/contracts/wire-scalar-format.js +0 -26
  38. package/dist/framework/contract-view.d.ts +7 -8
  39. package/dist/framework/framework-construction.error.js +0 -1
  40. package/dist/framework/framework.d.ts +26 -27
  41. package/dist/framework/framework.factory.js +0 -49
  42. package/dist/framework/operation-facade.js +0 -17
  43. package/dist/operations/operation-arguments.d.ts +36 -46
  44. package/dist/operations/operation-boolean-nodes.js +0 -16
  45. package/dist/operations/operation-call.d.ts +4 -9
  46. package/dist/operations/operation-identity.js +0 -1
  47. package/dist/operations/operation-nesting.js +0 -5
  48. package/dist/operations/operation-result.d.ts +4 -4
  49. package/dist/operations/operation-validator-core.d.ts +2 -2
  50. package/dist/operations/operation-validator-core.js +6 -71
  51. package/dist/operations/operation-validator.d.ts +4 -4
  52. package/dist/operations/operation-validator.js +0 -12
  53. package/dist/operations/projection-scope.resolver.d.ts +8 -10
  54. package/dist/operations/projection-scope.resolver.js +0 -35
  55. package/dist/operations/validation-code.d.ts +11 -18
  56. package/dist/operations/validation-code.js +0 -24
  57. package/dist/operations/write-scope.resolver.d.ts +4 -7
  58. package/dist/operations/write-scope.resolver.js +0 -37
  59. package/dist/protocol/absent-route.responder.d.ts +33 -48
  60. package/dist/protocol/absent-route.responder.js +0 -55
  61. package/dist/protocol/av-protocol.d.ts +6 -6
  62. package/dist/protocol/av-protocol.js +0 -10
  63. package/dist/protocol/contract-document.responder.d.ts +15 -18
  64. package/dist/protocol/contract-document.responder.js +0 -33
  65. package/dist/protocol/http-request.decoder.d.ts +55 -61
  66. package/dist/protocol/http-request.decoder.js +0 -62
  67. package/dist/protocol/http-request.reader.d.ts +12 -13
  68. package/dist/protocol/http-request.reader.js +0 -45
  69. package/dist/protocol/http-response.encoder.d.ts +17 -18
  70. package/dist/protocol/http-response.encoder.js +0 -59
  71. package/dist/protocol/http-status.table.d.ts +7 -11
  72. package/dist/protocol/http-status.table.js +1 -15
  73. package/dist/protocol/index.d.ts +5 -5
  74. package/dist/protocol/index.js +0 -9
  75. package/dist/protocol/operation-response.guard.d.ts +12 -19
  76. package/dist/protocol/operation-response.guard.js +0 -29
  77. package/dist/protocol/protocol-failure.d.ts +21 -26
  78. package/dist/protocol/protocol-failure.js +0 -12
  79. package/dist/protocol/protocol-headers.d.ts +25 -30
  80. package/dist/protocol/protocol-headers.js +0 -66
  81. package/dist/protocol/protocol-surface.d.ts +25 -29
  82. package/dist/protocol/protocol-surface.js +0 -19
  83. package/dist/protocol/protocol.binder.d.ts +58 -71
  84. package/dist/protocol/protocol.binder.js +0 -8
  85. package/dist/protocol/protocol.handler.d.ts +28 -32
  86. package/dist/protocol/protocol.handler.js +0 -43
  87. package/dist/runtime/computed-read-runtime.js +0 -29
  88. package/dist/runtime/create-requirement.d.ts +65 -0
  89. package/dist/runtime/create-requirement.js +141 -0
  90. package/dist/runtime/decimal.d.ts +2 -2
  91. package/dist/runtime/decimal.js +0 -8
  92. package/dist/runtime/diagnostics-reporter.d.ts +6 -6
  93. package/dist/runtime/diagnostics-reporter.js +0 -35
  94. package/dist/runtime/error-boundary.d.ts +3 -3
  95. package/dist/runtime/error-boundary.js +2 -167
  96. package/dist/runtime/execution-options.d.ts +4 -4
  97. package/dist/runtime/field-behavior.d.ts +6 -9
  98. package/dist/runtime/framework-error.js +0 -4
  99. package/dist/runtime/mutation-planner.d.ts +5 -6
  100. package/dist/runtime/mutation-planner.js +0 -23
  101. package/dist/runtime/operation-response.d.ts +1 -1
  102. package/dist/runtime/operation-response.js +1 -17
  103. package/dist/runtime/operation-runtime.d.ts +24 -22
  104. package/dist/runtime/operation-runtime.js +18 -52
  105. package/dist/runtime/outcome-mapper.js +0 -22
  106. package/dist/runtime/output-validator.js +0 -1
  107. package/dist/runtime/pipe-output.validator.d.ts +48 -0
  108. package/dist/runtime/pipe-output.validator.js +79 -0
  109. package/dist/runtime/pipeline.d.ts +20 -26
  110. package/dist/runtime/referential-action.d.ts +14 -19
  111. package/dist/runtime/referential-action.js +0 -23
  112. package/dist/runtime/request-id.js +0 -21
  113. package/dist/runtime/scalar-runtime.d.ts +14 -16
  114. package/dist/runtime/scalar-runtime.js +12 -57
  115. package/dist/transactions/deferred-operation.d.ts +9 -14
  116. package/dist/transactions/operation-arguments-encoder.d.ts +0 -1
  117. package/dist/transactions/operation-arguments-encoder.js +0 -14
  118. package/dist/transactions/operation-fingerprint.js +0 -1
  119. package/dist/transactions/transaction-envelope.js +0 -14
  120. package/dist/transactions/transaction-integrity-error.d.ts +10 -11
  121. package/dist/transactions/transaction-integrity-error.js +0 -5
  122. package/dist/transactions/transaction-plan-assembler.d.ts +0 -1
  123. package/dist/transactions/transaction-plan-assembler.js +0 -35
  124. package/dist/transactions/transaction-plan-validator.d.ts +5 -5
  125. package/dist/transactions/transaction-plan-validator.js +0 -63
  126. package/dist/transactions/transaction-reference-resolver.d.ts +12 -13
  127. package/dist/transactions/transaction-reference-resolver.js +0 -16
  128. package/dist/transactions/transaction-reference-validator.js +0 -8
  129. package/dist/transactions/transaction-reference.d.ts +19 -43
  130. package/dist/transactions/transaction-reference.js +0 -11
  131. package/dist/transactions/transaction-request.d.ts +4 -5
  132. package/dist/transactions/transaction-response.d.ts +1 -1
  133. package/dist/transactions/transaction-runtime.d.ts +2 -3
  134. package/dist/transactions/transaction-runtime.js +5 -44
  135. package/dist/transactions/transaction-slot-path-error.d.ts +10 -11
  136. package/dist/transactions/transaction-slot-path-error.js +0 -7
  137. package/dist/transactions/transaction-slot-writer.d.ts +12 -12
  138. package/dist/transactions/transaction-slot-writer.js +0 -34
  139. package/package.json +2 -2
@@ -11,19 +11,19 @@ export type Framework<M extends AdapterModel = AdapterModel, Cfg = AnyFrameworkC
11
11
  readonly entrypoint: string;
12
12
  readonly contracts: FrameworkContracts;
13
13
  /**
14
- * The typed in-process façade: `framework.application.<resource>.<family>.<variant>(args)`.
14
+ * The typed in-process façade:
15
+ * `framework.application.<resource>.<family>.<variant>(args)`.
15
16
  *
16
- * Arguments and results are derived from the Application Contract's view of
17
- * `M` and `Cfg` (`ApplicationContractView`), so this is the member that reads
18
- * the pair: two configurations that differ in one `fields` entry give two
19
- * different `Framework` types. Each call is an application-scope request to
20
- * {@link execute} — the same totality guard and validation layer — which still
21
- * refuses what a restriction removed, since restrictions stay invisible to the
22
- * types (ADR 0009).
17
+ * Arguments and results are derived from the Application Contract's view of `M`
18
+ * and `Cfg` (`ApplicationContractView`), so this is the member that reads the
19
+ * pair: two configurations that differ in one `fields` entry give two different
20
+ * `Framework` types. Each call is an application-scope request to {@link execute}
21
+ * — the same totality guard and validation layer — which still refuses what a
22
+ * restriction removed, since restrictions stay invisible to the types.
23
23
  *
24
24
  * A call's optional second argument is its `ExecutionOptions`: a supplied
25
- * `requestId` is the request's, in every pipeline context and diagnostic;
26
- * omitted or empty, a fresh id is minted per call (F-833).
25
+ * `requestId` is the request's, in every pipeline context and diagnostic; omitted
26
+ * or empty, a fresh id is minted per call.
27
27
  */
28
28
  readonly application: ApplicationOperations<M, Cfg>;
29
29
  /**
@@ -58,33 +58,32 @@ export type Framework<M extends AdapterModel = AdapterModel, Cfg = AnyFrameworkC
58
58
  /**
59
59
  * Validates a whole transaction plan, then runs its operations strictly
60
60
  * sequentially inside one Adapter transaction. Answers `A1009` with each
61
- * operation's final data in plan order, the failing operation's own code
62
- * with `cause.operation` after rollback, or `A3002` when the transaction
63
- * infrastructure fails. Total: it resolves for every input.
61
+ * operation's final data in plan order, the failing operation's own code with
62
+ * `cause.operation` after rollback, or `A3002` when the transaction infrastructure
63
+ * fails. Total: it resolves for every input.
64
64
  *
65
- * Every operation's guards, pipes, hooks and interceptors run while the
66
- * provider transaction is open and must not perform network I/O or
67
- * unrelated slow work (spec §14.5). The Adapter must reject with the exact
68
- * value its transaction callback threw, by identity.
65
+ * Every operation's guards, pipes, hooks and interceptors run while the provider
66
+ * transaction is open and must not perform network I/O or unrelated slow work. The
67
+ * Adapter must reject with the exact value its transaction callback threw, by
68
+ * identity.
69
69
  */
70
70
  executeTransaction(request: FrameworkTransactionRequest): Promise<TransactionResponse>;
71
71
  /**
72
72
  * The one typed transaction runner: `framework.transaction([h1, h2, …])`.
73
73
  *
74
74
  * Binds each `$ref` to its source's position in this list, fingerprints every
75
- * step, and runs the resulting passive plan through the same validation layer
76
- * and transaction runtime as {@link executeTransaction} — each step under its
77
- * own handle's origin, its own layer's Contract and pipelines, inside one
78
- * Adapter transaction. The committed response is typed per position.
75
+ * step, and runs the resulting passive plan through the same validation layer and
76
+ * transaction runtime as {@link executeTransaction} — each step under its own
77
+ * handle's origin, its own layer's Contract and pipelines, inside one Adapter
78
+ * transaction. The committed response is typed per position.
79
79
  *
80
80
  * Refused before anything runs: an entry that is not one of this Framework's
81
- * handles, or the same handle twice (`A2004`/`V1001`); a `$ref` to a handle not
82
- * in the list (`A2007`/`V1010`). Total: it resolves for every input.
81
+ * handles, or the same handle twice (`A2004`/`V1001`); a `$ref` to a handle not in
82
+ * the list (`A2007`/`V1010`). Total: it resolves for every input.
83
83
  *
84
- * The optional second argument is the run's `ExecutionOptions`: its
85
- * `requestId` is every step's, under either origin; omitted or empty, one id
86
- * is minted for the run. Handles take no options — a handle is not a request
87
- * (Q14).
84
+ * The optional second argument is the run's `ExecutionOptions`: its `requestId` is
85
+ * every step's, under either origin; omitted or empty, one id is minted for the
86
+ * run. Handles take no options — a handle is not a request.
88
87
  */
89
88
  readonly transaction: TransactionRunner;
90
89
  };
@@ -10,26 +10,6 @@ import { createTransactionPlanAssembler } from "../transactions/transaction-plan
10
10
  import { createTransactionRuntime } from "../transactions/transaction-runtime.js";
11
11
  import { FrameworkConstructionError } from "./framework-construction.error.js";
12
12
  import { createOperationFacade, createOperationTree, } from "./operation-facade.js";
13
- /**
14
- * Validate, read the model, resolve, compile, and bind one Aventara Framework
15
- * instance.
16
- *
17
- * The parameter is deliberately `Cfg & FrameworkConfig<M, Cfg>` rather than
18
- * the obvious `FrameworkConfig<M, Cfg>`. `Cfg` has to appear somewhere the
19
- * compiler actually infers from; inside `FrameworkConfig`'s body it only ever
20
- * reaches non-inference positions, so it would fall back to its
21
- * `AnyFrameworkConfig` default with no error reported anywhere, and every
22
- * narrowing keyed on the authored configuration would quietly widen. The
23
- * intersection puts `Cfg` directly against the argument type.
24
- *
25
- * `Cfg` is a `const` type parameter for the same reason: it stands for the
26
- * configuration *as authored*. Without `const`, inferring `Cfg` from an
27
- * inline configuration literal widens its scalar references away from their
28
- * literal types, and the widened `Cfg` then loses to the intersection's own
29
- * `FrameworkConfig` half — a call site that compiles today stops compiling.
30
- * A configuration passed as an already-annotated variable is unaffected
31
- * either way.
32
- */
33
13
  export async function createFramework(config) {
34
14
  const configDiagnostics = validateFrameworkConfig(config);
35
15
  if (configDiagnostics.length > 0) {
@@ -62,8 +42,6 @@ export async function createFramework(config) {
62
42
  config: resolvedConfig,
63
43
  });
64
44
  const executeOperation = (request) => executeTotally(execute, request, resolvedConfig.diagnostics);
65
- // A client-origin call in process carries the server's own protocol
66
- // identity: there is no remote generated client whose hash could be stale.
67
45
  const protocol = {
68
46
  version: AVENTARA_PROTOCOL_VERSION,
69
47
  hash: compilation.contracts.client.protocol.hash,
@@ -91,23 +69,11 @@ export async function createFramework(config) {
91
69
  clientTx: createOperationTree(model, (resource, identity) => (args) => assembler.defer("client", resource, identity, args === undefined ? {} : args)),
92
70
  execute: executeOperation,
93
71
  executeTransaction: (request) => executeTransactionTotally(executeTransaction, request, resolvedConfig.diagnostics),
94
- // The result type is the handles' derivation, an authoring affordance
95
- // (ADR 0009): every slot was held to its own Contract by output validation.
96
72
  transaction: ((operations, options) => runTransactionTotally(executeTransaction, assembler, operations, requestIdOf(options), resolvedConfig.diagnostics)),
97
73
  };
98
74
  recordDiagnosticsSink(framework, resolvedConfig.diagnostics);
99
75
  return framework;
100
76
  }
101
- /**
102
- * Outermost totality guard on the public execution seam. The validation
103
- * boundary and the pipeline boundary do the real work; this covers only what
104
- * they cannot — a failure inside those boundaries themselves. It reads
105
- * nothing off the caught value and calls no sanitizer: the envelope is a
106
- * constant, so this guard is incapable of failing. Reporting the raw error
107
- * to the diagnostics channel preserves that property, because the reporter
108
- * is total by construction. `Framework.execute()` therefore resolves to a
109
- * valid OperationResponse for every input.
110
- */
111
77
  async function executeTotally(execute, request, diagnostics) {
112
78
  const report = createDiagnosticsReporter(diagnostics, request);
113
79
  try {
@@ -118,12 +84,6 @@ async function executeTotally(execute, request, diagnostics) {
118
84
  return internalFailure();
119
85
  }
120
86
  }
121
- /**
122
- * Outermost totality guard for the transport-independent transaction seam.
123
- * The channel it binds is the only diagnostics route of the plan: the guard
124
- * reports through its plan-level reporter, and the executor receives the
125
- * same channel.
126
- */
127
87
  async function executeTransactionTotally(execute, request, diagnostics, origins) {
128
88
  const channel = createTransactionDiagnosticsChannel(diagnostics, request);
129
89
  const report = channel.transaction();
@@ -135,15 +95,6 @@ async function executeTransactionTotally(execute, request, diagnostics, origins)
135
95
  return internalFailure();
136
96
  }
137
97
  }
138
- /**
139
- * The typed runner's seam: assemble the handles into the passive plan, then run
140
- * it through the same guard as `executeTransaction`, each step under its own
141
- * origin. The plan is server code's, so its request is application-origin — no
142
- * remote client identity to check — and every origin a step carries is gated by
143
- * the validation layer. Assembly sits inside the same totality boundary: it
144
- * resolves for every input. `requestId` is the run's — the caller's, or minted
145
- * once for the whole run — so every step and every diagnostic carries one id.
146
- */
147
98
  async function runTransactionTotally(execute, assembler, operations, requestId, diagnostics) {
148
99
  let assembled;
149
100
  try {
@@ -1,25 +1,9 @@
1
1
  import { isOperationVariantAvailable } from "../contracts/resource-operations.js";
2
2
  import { parseOperationIdentity } from "../operations/operation-identity.js";
3
3
  import { requestIdOf } from "../runtime/request-id.js";
4
- /**
5
- * Builds a façade over `model`, the same object its types are read from, so a
6
- * call that type-checks always reaches `execute`: a Resource, variant or field
7
- * the active Contract does not carry is still a function here, and the
8
- * validation layer answers it.
9
- *
10
- * Each call's request is `request`'s — its origin — under the caller's
11
- * `ExecutionOptions.requestId`, or a freshly minted id when there is none; an
12
- * omitted argument is the empty argument object, which the type admits only
13
- * when every member is optional.
14
- */
15
4
  export function createOperationFacade(model, request, execute) {
16
5
  return createOperationTree(model, (resource, identity) => (args, options) => execute(request(resource, identity, args === undefined ? {} : args, requestIdOf(options))));
17
6
  }
18
- /**
19
- * The runtime shape every façade and builder shares: one frozen property per
20
- * Resource of `model`, one per family under it, one leaf per variant the model
21
- * advertises in the standard grammar.
22
- */
23
7
  export function createOperationTree(model, leaf) {
24
8
  const resources = Object.entries(model.resources).map(([resource, { operations }]) => {
25
9
  const families = Object.entries(operations).map(([family, variants]) => [family, variantLeaves(leaf, resource, family, variants)]);
@@ -27,7 +11,6 @@ export function createOperationTree(model, leaf) {
27
11
  });
28
12
  return Object.freeze(Object.fromEntries(resources));
29
13
  }
30
- /** One family's leaves: each advertised variant of the standard grammar. */
31
14
  function variantLeaves(leaf, resource, family, variants) {
32
15
  const leaves = Object.entries(variants ?? {}).flatMap(([variant, availability]) => {
33
16
  const identity = parseOperationIdentity(family, variant);
@@ -59,11 +59,11 @@ type HoldsAtScope<Value, Scope extends ProjectionScope | WriteScope> = Value ext
59
59
  readonly scopes: readonly (infer Stated)[];
60
60
  } ? Scope extends Stated ? true : false : Value extends ProjectionScopes ? Scope extends Value[number] ? true : false : true;
61
61
  /**
62
- * The tokens a capability member advertises, whichever arm it is written in —
63
- * the type-level mirror of `advertisedDirectives` and `advertisedReducers`, and
62
+ * The tokens a capability member advertises, whichever arm it is written in — the
63
+ * type-level mirror of `advertisedDirectives` and `advertisedReducers`, and
64
64
  * scope-blind for the same reason they are: reading the tokens and deciding where
65
65
  * they hold are two questions, and a reader handed both in one answer answers the
66
- * second by forgetting it (C-855). {@link CapabilityTokens} asks both.
66
+ * second by forgetting it. {@link CapabilityTokens} asks both.
67
67
  */
68
68
  type AdvertisedTokens<Value> = Value extends {
69
69
  readonly scopes: readonly WriteScope[];
@@ -135,13 +135,12 @@ export type ScalarFilterInput = unknown | Readonly<Partial<Record<ScalarFilterOp
135
135
  * A scalar filter's shorthand equality value: the field's value, minus a JSON
136
136
  * object.
137
137
  *
138
- * Every reader of a filter position — the validation layer, the scalar runtime
139
- * and the adapter — reads it through one discriminant
140
- * (`runtime/scalar-runtime.ts` `isPlainRecord`): a plain record is an operator
141
- * object, anything else is a value. So a `Date`, a `Decimal` and a `Uint8Array`
142
- * are shorthand for their field (spec §9.1), and a JSON object is an operator
143
- * object by construction — `{ equals: document }` carries it. The same
144
- * exclusion as `not`'s value arm below.
138
+ * Every reader of a filter position — the validation layer, the scalar runtime and
139
+ * the adapter — reads it through one discriminant (`runtime/scalar-runtime.ts`
140
+ * `isPlainRecord`): a plain record is an operator object, anything else is a
141
+ * value. So a `Date`, a `Decimal` and a `Uint8Array` are shorthand for their
142
+ * field, and a JSON object is an operator object by construction — `{ equals:
143
+ * document }` carries it. The same exclusion as `not`'s value arm below.
145
144
  */
146
145
  type ScalarFilterShorthand<Value> = Exclude<Value, JsonObject>;
147
146
  /**
@@ -241,25 +240,22 @@ type OrderValue<C extends Contract, K extends ResourceKey<C>, F extends Orderabl
241
240
  /**
242
241
  * One `orderBy` precedence entry: exactly one orderable field and its value.
243
242
  *
244
- * **The value is read inside the entry's own mapped property, never handed in
245
- * as a type argument** — the shape {@link RelationProjectionEntry} shares, and
246
- * the whole of F-823. A to-one relation's value
247
- * is the target's entry, so a self-relation (`Author.mentor → Author`) or a
248
- * one-to-one pair makes this type recursive. A type argument is instantiated
249
- * eagerly, so resolving `OrderByEntry<C, "Author">` needed
250
- * `OrderValue<…, "mentor">`, which IS `OrderByEntry<C, "Author">`: TS2615, after
251
- * which the entry degraded to `any` and refused nothing. A mapped property is
252
- * resolved only when read, by which time the entry it recurses into exists. The
243
+ * A to-one relation's value is the target's entry, so a self-relation
244
+ * (`Author.mentor → Author`) or a one-to-one pair makes this type recursive. A
245
+ * type argument is instantiated eagerly, so resolving `OrderByEntry<C, "Author">`
246
+ * needed `OrderValue<…, "mentor">`, which IS `OrderByEntry<C, "Author">`: TS2615,
247
+ * after which the entry degraded to `any` and refused nothing. A mapped property
248
+ * is resolved only when read, by which time the entry it recurses into exists. The
253
249
  * projection walk never hit this because its recursion already sits behind an
254
250
  * object property (`{ select?: … }`).
255
251
  *
256
252
  * **No type-level depth cap, deliberately.** The runtime bound is the Contract's
257
- * `limits.maxNestingDepth` — each to-one hop counts one level, and one past it
258
- * is V1013 (`operation-nesting.ts` `walkOrderBy`). That limit is a `number` in
259
- * the Contract, resolved per scope at construction, so no literal exists for a
260
- * type to count against; a fixed cap would refuse what a Contract with a larger
261
- * limit accepts. `where` and `select` recurse uncapped for the same reason, and
262
- * the validation layer refuses past the limit for all three.
253
+ * `limits.maxNestingDepth` — each to-one hop counts one level, and one past it is
254
+ * V1013 (`operation-nesting.ts` `walkOrderBy`). That limit is a `number` in the
255
+ * Contract, resolved per scope at construction, so no literal exists for a type to
256
+ * count against; a fixed cap would refuse what a Contract with a larger limit
257
+ * accepts. `where` and `select` recurse uncapped for the same reason, and the
258
+ * validation layer refuses past the limit for all three.
263
259
  */
264
260
  export type OrderByEntry<C extends Contract, K extends ResourceKey<C>> = {
265
261
  [F in OrderableFieldKey<C, K>]: {
@@ -325,16 +321,14 @@ export type RelationProjectionInput<C extends Contract, K extends ResourceKey<C>
325
321
  * One relation entry of a projection: exactly relation `F` of `Keys`, with its
326
322
  * argument object, and every other key of `Keys` absent.
327
323
  *
328
- * **The argument object is read inside the entry's own mapped property, never
329
- * handed in as a type argument** — the shape {@link OrderByEntry} has for
330
- * F-823's reason, kept here for cost. A projection's entry union is formed
331
- * whenever its `select`/`include` constraint is — at every call, including one
332
- * that passes no projection — and a type argument is instantiated when the union
333
- * is: every relation's {@link RelationProjectionInput} (its nested `where`,
334
- * `orderBy`, pagination and projection choice) for every relation the Resource
335
- * has. A mapped property is resolved only when an entry names it, so a call pays
336
- * for the relations it projects. Measured on the six-resource artifact shape:
337
- * ≈4,500–6,700 instantiations per call whose projection names no relation.
324
+ * A projection's entry union is formed whenever its `select`/`include` constraint
325
+ * is — at every call, including one that passes no projection — and a type
326
+ * argument is instantiated when the union is: every relation's {@link
327
+ * RelationProjectionInput} (its nested `where`, `orderBy`, pagination and
328
+ * projection choice) for every relation the Resource has. A mapped property is
329
+ * resolved only when an entry names it, so a call pays for the relations it
330
+ * projects. Measured on the six-resource artifact shape: ≈4,500–6,700
331
+ * instantiations per call whose projection names no relation.
338
332
  */
339
333
  type RelationProjectionEntry<C extends Contract, K extends ResourceKey<C>, Keys extends RelationFieldKeyOf<C, K>, F extends Keys, Scope extends ProjectionScope, Forms extends ScalarForms> = {
340
334
  readonly [Only in F]: RelationProjectionInput<C, K, Only & RelationFieldKeyOf<C, K>, Scope, Forms>;
@@ -408,13 +402,13 @@ declare const NO_ADVERTISED_MEMBER: unique symbol;
408
402
  *
409
403
  * TypeScript runs no excess-property check against an object type with no known
410
404
  * properties, so an empty mapped member would type as `{}` and accept any key
411
- * silently, leaving it to `V1006` at runtime (F-810). One optional member on a
405
+ * silently, leaving it to `V1006` at runtime. One optional member on a
412
406
  * module-private symbol keeps the type weak — `{}` still assigns — while giving
413
- * the excess-property check something to measure against, so the diagnostic
414
- * names the offending key.
407
+ * the excess-property check something to measure against, so the diagnostic names
408
+ * the offending key.
415
409
  *
416
- * The empty case is reachable by design: `directives: []` means "writable, with
417
- * no directive", distinct from an absent member (see `contracts/field.ts`).
410
+ * The empty case is reachable by design: `directives: []` means "writable, with no
411
+ * directive", distinct from an absent member (see `contracts/field.ts`).
418
412
  */
419
413
  type NoAdvertisedMember = {
420
414
  readonly [NO_ADVERTISED_MEMBER]?: never;
@@ -489,11 +483,7 @@ type QueryProjectionArgs<C extends Contract, K extends ResourceKey<C>, Scope ext
489
483
  * **This binding is core's grammar, not the adapter's routing.** A variant's real
490
484
  * scope is an adapter fact and the adapter states it on the advertised variant
491
485
  * (`OperationVariantScopes`); a host that routed, say, `update.first` through a
492
- * bulk-returning call would make this map's `"record"` too generous. The
493
- * consequence is that the type can over-advertise where an adapter is narrower,
494
- * never the reverse, and the runtime guard refuses what it advertised — which is
495
- * why this surface is not a substitute for the validation layer (ADR 0009: the
496
- * compiled Contract is untyped, so no type here is load-bearing at runtime).
486
+ * bulk-returning call would make this map's `"record"` too generous.
497
487
  *
498
488
  * An unqualified capability holds in every scope, so a Contract whose adapter has
499
489
  * not measured the axis is bound to the same surface it had before the axis
@@ -580,7 +570,7 @@ export type OperationArgumentMap<C extends Contract, K extends ResourceKey<C>, F
580
570
  * value is `unknown` ({@link UnstatedForms}); the application façade passes
581
571
  * `ApplicationScalarForms`, so a `Date` handed to a `json` field or a number to a
582
572
  * `string` one is refused where it is written rather than by `V1001` at runtime.
583
- * The validation layer stays the guard either way (ADR 0009).
573
+ * The validation layer stays the guard either way.
584
574
  */
585
575
  export type OperationArgumentsFor<C extends Contract, K extends ResourceKey<C>, I extends OperationIdentity, Forms extends ScalarForms = UnstatedForms> = I extends {
586
576
  family: infer F;
@@ -95,10 +95,6 @@ function projectionRelation(contract, resourceName, entry, mode, scope) {
95
95
  if (field?.kind !== "relation") {
96
96
  return undefined;
97
97
  }
98
- // The SAME scope-aware read the grammar walk uses. This walk skips a relation it
99
- // cannot descend, so reading the member scope-blind would stop counting beneath
100
- // every measured relation — `maxBooleanNodes` silently unenforced inside a
101
- // projection the grammar walk then admits.
102
98
  if (mode === "select" && !holdsAt(field.capabilities.select, scope)) {
103
99
  return undefined;
104
100
  }
@@ -132,7 +128,6 @@ function walkProjection(state, resourceName, value, mode, scope, path) {
132
128
  if (!(nestedMode in relation.value)) {
133
129
  continue;
134
130
  }
135
- // Nested is unrestricted at every depth — {@link NESTED_PROJECTION_SCOPE}.
136
131
  const issue = walkProjection(state, relation.edge.target, relation.value[nestedMode], nestedMode, NESTED_PROJECTION_SCOPE, [...relationPath, nestedMode]);
137
132
  if (issue !== undefined) {
138
133
  return issue;
@@ -157,12 +152,6 @@ function walkMutationData(state, resourceName, value, stage, path) {
157
152
  if (edge?.kind !== "relation" || !isRecord(fieldValue)) {
158
153
  continue;
159
154
  }
160
- // Scope-blind, unlike the projection read above, and deliberately: this walk
161
- // may only ever be a SUPERSET of what the grammar walk admits. The write scope
162
- // narrows the top level of a write, so a scope-aware read here could only
163
- // descend less — and a walk that stops counting inside a write the grammar walk
164
- // admits is `maxBooleanNodes` silently unenforced. Counting inside one it is
165
- // about to refuse costs a node tally nobody reads.
166
155
  const supported = advertisedDirectives(edge.capabilities[stage]);
167
156
  for (const [directive, directiveValue] of Object.entries(fieldValue)) {
168
157
  if (supported?.includes(directive) !== true) {
@@ -241,11 +230,6 @@ function isUniqueOperation(request) {
241
230
  request.family === "delete" ||
242
231
  request.family === "upsert"));
243
232
  }
244
- /**
245
- * Enforces maxBooleanNodes across every general where tree in one semantic
246
- * operation, including root filters, returned-relation filters, and nested
247
- * relation mutation filters. Unique selectors are intentionally excluded.
248
- */
249
233
  export function findOperationBooleanNodeIssue(contract, request, args) {
250
234
  const state = { contract, count: 0 };
251
235
  const projectionScope = resolveProjectionScope(lookupResource(contract, request.resource), request);
@@ -54,8 +54,8 @@ export type OperationGrammar<C extends Contract> = {
54
54
  };
55
55
  /**
56
56
  * An operation's slot: its result, except that a first-style miss contributes
57
- * `null` (DA-1) — where the miss is not the `A1001` arm of a response of its own:
58
- * a committed plan's slot, and a remote call that resolves to the data.
57
+ * `null` — where the miss is not the `A1001` arm of a response of its own: a
58
+ * committed plan's slot, and a remote call that resolves to the data.
59
59
  */
60
60
  export type OperationSlot<I extends OperationIdentity, Result> = I["variant"] extends "first" ? Result | null : Result;
61
61
  /**
@@ -72,18 +72,13 @@ type PlainCall<C extends Contract, R extends ResourceKey<C>, I extends Operation
72
72
  * projection when it carries one.
73
73
  */
74
74
  export type OperationCall<C extends Contract, R extends ResourceKey<C>, I extends OperationIdentity, Forms extends ScalarForms, ResultForms extends ScalarForms, Settlement extends "response" | "data", Options> = "select" extends keyof OperationArgumentsFor<C, R, I, Forms> ? ProjectingCall<C, R, I, OperationArgumentsFor<C, R, I, Forms>, ResultForms, Settlement, Options> : PlainCall<C, R, I, OperationArgumentsFor<C, R, I, Forms>, ResultForms, Settlement, Options>;
75
- /**
76
- * A deferred operation's arguments: `Forms`, with DA-3 reference positions opened
77
- * to a `$ref` typed in `ResultForms` — the forms the source's final data is read
78
- * in, so a reference carries what its source resolves.
79
- */
80
75
  type DeferredArguments<C extends Contract, R extends ResourceKey<C>, I extends OperationIdentity, Forms extends ScalarForms, ResultForms extends ScalarForms> = ReferenceableArgumentsFor<C, R, I, Forms, ResultForms>;
81
76
  type DeferredProjectingCall<C extends Contract, R extends ResourceKey<C>, I extends OperationIdentity, Args, ResultForms extends ScalarForms> = <const Select extends SelectOf<Args> = never, const Include extends IncludeOf<Args> = never>(...args: ArgumentList<Omit<Args, ProjectionKey>, Omit<Args, ProjectionKey> & ProjectionArgument<Select, Include>>) => Operation<OperationSlot<I, AdmittedOperationResult<C, R, I, InferredProjection<Select, Include>, ResultForms>>>;
82
77
  type DeferredPlainCall<C extends Contract, R extends ResourceKey<C>, I extends OperationIdentity, Args, ResultForms extends ScalarForms> = (...args: ArgumentList<Args, Args>) => Operation<OperationSlot<I, AdmittedOperationResult<C, R, I, unknown, ResultForms>>>;
83
78
  /**
84
79
  * One deferred operation: a handle typed `Operation<OperationSlot<…>>` — `$ref`
85
- * present exactly where the result is one row. A handle is not a request and
86
- * takes no options (Q14).
80
+ * present exactly where the result is one row. A handle is not a request and takes
81
+ * no options.
87
82
  */
88
83
  export type DeferredOperationCall<C extends Contract, R extends ResourceKey<C>, I extends OperationIdentity, Forms extends ScalarForms, ResultForms extends ScalarForms> = "select" extends keyof DeferredArguments<C, R, I, Forms, ResultForms> ? DeferredProjectingCall<C, R, I, DeferredArguments<C, R, I, Forms, ResultForms>, ResultForms> : DeferredPlainCall<C, R, I, DeferredArguments<C, R, I, Forms, ResultForms>, ResultForms>;
89
84
  export {};
@@ -16,7 +16,6 @@ const STANDARD_OPERATIONS = {
16
16
  "delete.count": true,
17
17
  "upsert.unique": true,
18
18
  };
19
- /** Parses one exact standard operation family/variant pair. */
20
19
  export function parseOperationIdentity(family, variant) {
21
20
  const key = `${family}.${variant}`;
22
21
  if (!Object.hasOwn(STANDARD_OPERATIONS, key)) {
@@ -257,11 +257,6 @@ function walkMutationData(context, resourceName, value, depth, path) {
257
257
  }
258
258
  return undefined;
259
259
  }
260
- /**
261
- * Enforces the Contract's semantic nesting limit across where, projection,
262
- * orderBy, mutation data, and relation traversal before deeper argument
263
- * validation.
264
- */
265
260
  export function findOperationNestingIssue(contract, resourceName, args) {
266
261
  if ("where" in args) {
267
262
  const rootPath = ["arguments", "where"];
@@ -90,7 +90,7 @@ type RelationResult<C extends Contract, Target extends ResourceKey<C>, Relation
90
90
  /**
91
91
  * The value a standard operation returns in `OperationResponse.data` on success,
92
92
  * derived from the Contract, the Resource, the operation identity and the
93
- * projection argument (F-701).
93
+ * projection argument.
94
94
  *
95
95
  * - `count` → `number`;
96
96
  * - `many` → `readonly Record[]`;
@@ -104,9 +104,9 @@ type RelationResult<C extends Contract, Target extends ResourceKey<C>, Relation
104
104
  * unadvertised `$count`, a relation outside a bulk write's ceiling — is refused
105
105
  * here instead of typed as present.
106
106
  *
107
- * `Forms` (Q3 = 3a) is the scalar-form map. It defaults to the application forms,
108
- * which are what a framework-produced value is in either scope; a transport or a
109
- * generated client passes the wire forms and gets the same derivation.
107
+ * `Forms` is the scalar-form map. It defaults to the application forms, which are
108
+ * what a framework-produced value is in either scope; a transport or a generated
109
+ * client passes the wire forms and gets the same derivation.
110
110
  */
111
111
  export type OperationResultFor<C extends Contract, K extends ResourceKey<C>, I extends OperationIdentity, Args extends OperationArgumentsFor<C, K, I>, Forms extends ScalarForms = ApplicationScalarForms> = AdmittedOperationResult<C, K, I, Args, Forms>;
112
112
  /**
@@ -17,8 +17,8 @@ export type OperationValidationOptions = {
17
17
  /**
18
18
  * The Framework Validation Layer's issue for a request naming a Resource the
19
19
  * active Contract does not have (`V1005` at `["resource"]`, rolling up to
20
- * `A2001`). The one spelling — the protocol's absence answers
21
- * (`@aventara/core/protocol`, Q2's O3) build theirs with it.
20
+ * `A2001`). The one spelling — the protocol's absence answers build theirs with
21
+ * it.
22
22
  */
23
23
  export declare function resourceUnavailableIssue(resource: string): ValidationIssue;
24
24
  export declare function validateOperationArguments(contract: Contract, request: OperationIdentity & {
@@ -168,11 +168,6 @@ function validateScalarFilter(fieldName, field, value, path, state) {
168
168
  }
169
169
  return;
170
170
  }
171
- // Equality shorthand: anything that is not a plain record is a value — a
172
- // `Date`, a `Decimal` and a `Uint8Array` included — read through the scalar
173
- // runtime's own discriminant, which holds it to the field's scalar after
174
- // this layer (`normalizeScalarFilter`). Reading every object as operators
175
- // refused the shorthand the ORM accepts (C-855, sign flipped).
176
171
  if (!isPlainRecord(value)) {
177
172
  if (!includes(supported, "equals")) {
178
173
  addIssue(state.issues, "V1006", path, `Equality filtering is not available on field "${fieldName}".`);
@@ -409,14 +404,7 @@ function validateCursor(contract, resourceName, cursor, orderBy, path, issues) {
409
404
  addIssue(issues, "V1009", path, "orderBy must include a complete Resource identifier as an explicit tie-breaker.");
410
405
  }
411
406
  }
412
- function validateProjection(contract, resourceName, mode, value,
413
- /**
414
- * The projection position THIS projection's own field and relation entries sit
415
- * in. The caller resolves it once from the advertised variant; a nested call
416
- * passes {@link NESTED_PROJECTION_SCOPE}, because a scope qualifies the top level
417
- * only. A `$count` entry is the exception and reads {@link ReducerOwner.scope}.
418
- */
419
- scope, path, issues, reducerOwner) {
407
+ function validateProjection(contract, resourceName, mode, value, scope, path, issues, reducerOwner) {
420
408
  if (!Array.isArray(value)) {
421
409
  addIssue(issues, "V1008", path, `${mode} must be an array.`);
422
410
  return;
@@ -431,10 +419,7 @@ scope, path, issues, reducerOwner) {
431
419
  if (entry === "$count") {
432
420
  if (mode !== "select" ||
433
421
  reducerOwner?.edge.cardinality !== "many" ||
434
- !includes(advertisedReducersAt(reducerOwner.edge.capabilities.reducers,
435
- // The OWNER's position, not this projection's: see
436
- // {@link ReducerOwner}.
437
- reducerOwner.scope), "$count")) {
422
+ !includes(advertisedReducersAt(reducerOwner.edge.capabilities.reducers, reducerOwner.scope), "$count")) {
438
423
  addIssue(issues, "V1008", entryPath, "$count is available only as an advertised to-many relation reducer.");
439
424
  }
440
425
  return;
@@ -477,16 +462,10 @@ scope, path, issues, reducerOwner) {
477
462
  addIssue(issues, "V1008", relationPath, `Relation "${relationName}" is not available for ${mode}.`);
478
463
  return;
479
464
  }
480
- validateRelationProjection(contract, field,
481
- // The position the edge itself was admitted in. The edge's nested
482
- // projection is unrestricted, but a `$count` of this edge is carried at
483
- // THIS level, so the scope has to travel with the edge.
484
- scope, entry[relationName], relationPath, issues);
465
+ validateRelationProjection(contract, field, scope, entry[relationName], relationPath, issues);
485
466
  });
486
467
  }
487
- function validateRelationProjection(contract, edge,
488
- /** The projection position `edge` itself was admitted in — see {@link ReducerOwner}. */
489
- scope, value, path, issues) {
468
+ function validateRelationProjection(contract, edge, scope, value, path, issues) {
490
469
  if (!isRecord(value)) {
491
470
  addIssue(issues, "V1008", path, "Customized relation projection must be an object.");
492
471
  return;
@@ -551,10 +530,6 @@ scope, value, path, issues) {
551
530
  validateCursor(contract, edge.target, value.cursor, value.orderBy, [...path, "cursor"], issues);
552
531
  }
553
532
  }
554
- // Past an admitted relation the unrestricted surface returns, measured on both
555
- // pilot engines — see {@link NESTED_PROJECTION_SCOPE}. The edge's own scope is
556
- // deliberately NOT passed down: a recursive narrowing would refuse what the ORM
557
- // accepts.
558
533
  if ("select" in value) {
559
534
  validateProjection(contract, edge.target, "select", value.select, NESTED_PROJECTION_SCOPE, [...path, "select"], issues, { edge, scope });
560
535
  }
@@ -595,16 +570,6 @@ function validateScalarMutation(fieldName, field, value, stage, path, issues, tr
595
570
  }
596
571
  }
597
572
  }
598
- /**
599
- * One relation mutation directive's operand, past the point where the directive
600
- * itself was admitted.
601
- *
602
- * It takes **no write scope**, and that is the rule rather than an omission: every
603
- * data object it reaches is nested, and {@link NESTED_WRITE_SCOPE} is the answer at
604
- * every depth. A parameter here would be a parameter this function could only
605
- * ignore, and the next reader would thread the caller's scope through it and refuse
606
- * what the ORM accepts.
607
- */
608
573
  function validateRelationMutationEntry(contract, edge, directive, value, path, issues) {
609
574
  const target = edge.target;
610
575
  if (edge.cardinality === "one" && Array.isArray(value)) {
@@ -747,13 +712,7 @@ function validateRelationMutationEntry(contract, edge, directive, value, path, i
747
712
  }
748
713
  }
749
714
  }
750
- function validateRelationMutation(contract, fieldName, field, value, stage,
751
- /** The write position this relation member itself sits in; see {@link WriteScope}. */
752
- scope, path, issues) {
753
- // Scope-aware, through the shape owner's one reader. A stage that does not hold
754
- // at this write position is not writable at this write position, and says so with
755
- // the message an absent member already has — which is why the two answers
756
- // `advertisedDirectivesAt` can give are the two this branch already handled.
715
+ function validateRelationMutation(contract, fieldName, field, value, stage, scope, path, issues) {
757
716
  const directives = advertisedDirectivesAt(field.capabilities[stage], scope);
758
717
  if (directives === undefined) {
759
718
  addIssue(issues, "V1006", path, `Relation "${fieldName}" is not writable during ${stage}.`);
@@ -772,15 +731,7 @@ scope, path, issues) {
772
731
  validateRelationMutationEntry(contract, field, directive, directiveValue, directivePath, issues);
773
732
  }
774
733
  }
775
- function validateMutationData(contract, resourceName, data, stage,
776
- /**
777
- * The write position THIS data object's own relation members sit in. The caller
778
- * resolves it once from the advertised variant; a nested call passes
779
- * {@link NESTED_WRITE_SCOPE}, because a scope qualifies the top level only.
780
- * Scalar members never read it — all six scalar capability members were measured
781
- * uniform across every variant on the axis.
782
- */
783
- scope, path, issues, transactionReferences = false) {
734
+ function validateMutationData(contract, resourceName, data, stage, scope, path, issues, transactionReferences = false) {
784
735
  if (!isRecord(data)) {
785
736
  addIssue(issues, "V1001", path, `${stage} data must be an object.`);
786
737
  return;
@@ -806,14 +757,6 @@ scope, path, issues, transactionReferences = false) {
806
757
  }
807
758
  }
808
759
  function validateMutationArguments(contract, resourceName, request, args, issues, options) {
809
- // The one resolution, from the variant the Resource advertises, and the write
810
- // mirror of the projection scope resolved at the top level. It qualifies the top
811
- // level of the write argument only; everything beneath an admitted relation
812
- // directive is nested and asks about the unrestricted position instead.
813
- //
814
- // Resolved here rather than passed in because `request` is what carries the
815
- // variant, and an argument walk handed a scope could be handed one resolved for a
816
- // different request.
817
760
  const scope = resolveWriteScope(getResource(contract, resourceName), request);
818
761
  if (request.family === "create") {
819
762
  if (!("data" in args)) {
@@ -853,12 +796,6 @@ function isUniqueOperation(request) {
853
796
  request.family === "delete" ||
854
797
  request.family === "upsert"));
855
798
  }
856
- /**
857
- * The Framework Validation Layer's issue for a request naming a Resource the
858
- * active Contract does not have (`V1005` at `["resource"]`, rolling up to
859
- * `A2001`). The one spelling — the protocol's absence answers
860
- * (`@aventara/core/protocol`, Q2's O3) build theirs with it.
861
- */
862
799
  export function resourceUnavailableIssue(resource) {
863
800
  return {
864
801
  code: "V1005",
@@ -911,8 +848,6 @@ export function validateOperationArguments(contract, request, options) {
911
848
  if ("cursor" in request.arguments) {
912
849
  validateCursor(contract, request.resource, request.arguments.cursor, request.arguments.orderBy, ["arguments", "cursor"], issues);
913
850
  }
914
- // The one resolution, from the variant the Resource advertises. Everything below
915
- // the top level is nested and asks about the unrestricted position instead.
916
851
  const projectionScope = resolveProjectionScope(resource, request);
917
852
  if ("select" in request.arguments) {
918
853
  validateProjection(contract, request.resource, "select", request.arguments.select, projectionScope, ["arguments", "select"], issues);