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

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 (89) hide show
  1. package/CHANGELOG.md +157 -0
  2. package/ERRORS.md +2 -2
  3. package/README.md +80 -7
  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-diagnostic.guidance.js +2 -2
  9. package/dist/compiler/contract.compiler.js +26 -3
  10. package/dist/config/config.resolver.d.ts +2 -0
  11. package/dist/config/config.resolver.js +7 -2
  12. package/dist/config/config.validator.js +36 -12
  13. package/dist/config/exact-framework-config.d.ts +11 -1
  14. package/dist/config/framework-config.d.ts +14 -1
  15. package/dist/contracts/contract-canonicalizer.js +2 -0
  16. package/dist/contracts/contract.d.ts +15 -1
  17. package/dist/contracts/field.d.ts +17 -0
  18. package/dist/contracts/scalar-value-type.d.ts +3 -1
  19. package/dist/framework/contract-view.d.ts +9 -1
  20. package/dist/framework/framework-construction.error.d.ts +2 -1
  21. package/dist/framework/framework-construction.error.js +13 -1
  22. package/dist/framework/framework.d.ts +26 -5
  23. package/dist/framework/framework.factory.js +29 -10
  24. package/dist/framework/operation-facade.d.ts +59 -12
  25. package/dist/index.d.ts +8 -4
  26. package/dist/internal.d.ts +2 -2
  27. package/dist/internal.js +2 -0
  28. package/dist/operations/operation-arguments.d.ts +43 -27
  29. package/dist/operations/operation-call.d.ts +2 -2
  30. package/dist/operations/operation-result.d.ts +1 -1
  31. package/dist/policy/access-provider.interface.d.ts +36 -0
  32. package/dist/policy/access-provider.interface.js +1 -0
  33. package/dist/policy/access-provider.registry.d.ts +9 -0
  34. package/dist/policy/access-provider.registry.js +10 -0
  35. package/dist/policy/policy-admission.js +12 -3
  36. package/dist/policy/policy-after-update.runtime.js +5 -4
  37. package/dist/policy/policy-engine.d.ts +11 -4
  38. package/dist/policy/policy-nested-write.runtime.js +11 -7
  39. package/dist/policy/policy-read.runtime.d.ts +0 -2
  40. package/dist/policy/policy-read.runtime.js +18 -9
  41. package/dist/policy/policy-request.d.ts +7 -3
  42. package/dist/policy/policy-request.js +14 -3
  43. package/dist/policy/policy-session.d.ts +14 -4
  44. package/dist/policy/policy-session.js +12 -11
  45. package/dist/policy/policy-startup.validator.js +13 -15
  46. package/dist/policy/policy-write.runtime.d.ts +7 -0
  47. package/dist/policy/policy-write.runtime.js +23 -8
  48. package/dist/prebuilt/core-version.generated.d.ts +1 -1
  49. package/dist/prebuilt/core-version.generated.js +1 -1
  50. package/dist/prebuilt/prebuilt-changes.d.ts +28 -0
  51. package/dist/prebuilt/prebuilt-changes.js +65 -0
  52. package/dist/prebuilt/prebuilt-contracts.loader.js +11 -56
  53. package/dist/prebuilt/prebuilt-inputs.fingerprint.js +16 -1
  54. package/dist/protocol/absent-route.responder.d.ts +4 -4
  55. package/dist/protocol/http-request.decoder.d.ts +2 -2
  56. package/dist/protocol/http-request.reader.d.ts +2 -2
  57. package/dist/protocol/http-response.encoder.js +2 -2
  58. package/dist/protocol/protocol-headers.d.ts +3 -3
  59. package/dist/runtime/caller-data.copier.js +3 -4
  60. package/dist/runtime/computed-read-runtime.js +2 -7
  61. package/dist/runtime/context-executor.runtime.d.ts +2 -2
  62. package/dist/runtime/core-class.brand.d.ts +10 -0
  63. package/dist/runtime/core-class.brand.js +21 -0
  64. package/dist/runtime/create-requirement.js +1 -1
  65. package/dist/runtime/decimal.d.ts +14 -0
  66. package/dist/runtime/decimal.js +21 -0
  67. package/dist/runtime/diagnostics-reporter.d.ts +5 -5
  68. package/dist/runtime/diagnostics-reporter.js +13 -1
  69. package/dist/runtime/framework-error.js +9 -0
  70. package/dist/runtime/operation-request.d.ts +9 -9
  71. package/dist/runtime/operation-runtime.d.ts +8 -8
  72. package/dist/runtime/operation-runtime.js +30 -9
  73. package/dist/runtime/owned-execution.registry.d.ts +2 -2
  74. package/dist/runtime/readonly-value.d.ts +1 -1
  75. package/dist/runtime/readonly-value.js +2 -2
  76. package/dist/runtime/referential-action.d.ts +1 -1
  77. package/dist/runtime/scalar-runtime.js +4 -5
  78. package/dist/transactions/operation-arguments-encoder.js +8 -3
  79. package/dist/transactions/sql-statement.d.ts +2 -2
  80. package/dist/transactions/sql-statement.validator.js +2 -2
  81. package/dist/transactions/transaction-integrity-error.js +2 -0
  82. package/dist/transactions/transaction-plan-assembler.d.ts +11 -4
  83. package/dist/transactions/transaction-plan-assembler.js +17 -2
  84. package/dist/transactions/transaction-plan-validator.d.ts +5 -5
  85. package/dist/transactions/transaction-request.d.ts +8 -8
  86. package/dist/transactions/transaction-runtime.d.ts +2 -2
  87. package/dist/transactions/transaction-runtime.js +12 -7
  88. package/dist/transactions/transaction-slot-path-error.js +2 -0
  89. package/package.json +1 -1
@@ -0,0 +1,10 @@
1
+ /** The registered symbol every copy of this major brands class `name` with. */
2
+ export declare function coreBrandOf(name: string): symbol;
3
+ /** Whether `value` carries `brand`, wherever it was made: one `in`. */
4
+ export declare function hasCoreBrand(value: unknown, brand: symbol): boolean;
5
+ /**
6
+ * Brands `type`'s prototype as `name` and makes `instanceof type` read the brand.
7
+ * A developer's own subclass of `type` inherits the static `Symbol.hasInstance`, so
8
+ * on any constructor but `type` itself it answers as `instanceof` always does.
9
+ */
10
+ export declare function brandCoreClass(type: abstract new (...args: never[]) => object, name: string): symbol;
@@ -0,0 +1,21 @@
1
+ import { CORE_VERSION } from "../prebuilt/core-version.generated.js";
2
+ const CORE_MAJOR = CORE_VERSION.slice(0, CORE_VERSION.indexOf("."));
3
+ export function coreBrandOf(name) {
4
+ return Symbol.for(`aventara.core.${name}@${CORE_MAJOR}`);
5
+ }
6
+ export function hasCoreBrand(value, brand) {
7
+ return typeof value === "object" && value !== null && brand in value;
8
+ }
9
+ const ordinaryHasInstance = Function.prototype[Symbol.hasInstance];
10
+ export function brandCoreClass(type, name) {
11
+ const brand = coreBrandOf(name);
12
+ Object.defineProperty(type.prototype, brand, { value: true });
13
+ Object.defineProperty(type, Symbol.hasInstance, {
14
+ value: function hasInstance(value) {
15
+ return this === type
16
+ ? hasCoreBrand(value, brand)
17
+ : ordinaryHasInstance.call(this, value);
18
+ },
19
+ });
20
+ return brand;
21
+ }
@@ -13,7 +13,7 @@ function edgesOf(table, resource) {
13
13
  return Array.isArray(listed) ? listed : [];
14
14
  }
15
15
  function referencesOf(edge) {
16
- return Array.isArray(edge.references) ? edge.references : [];
16
+ return Array.isArray(edge.referenceFields) ? edge.referenceFields : [];
17
17
  }
18
18
  function creatableScalar(contract, resource, field) {
19
19
  const found = lookupField(lookupResource(contract, resource), field);
@@ -12,3 +12,17 @@ export declare class AvDecimal {
12
12
  */
13
13
  toJSON(): string;
14
14
  }
15
+ /**
16
+ * Whether `value` is an `AvDecimal`, made by this copy of core or by another of
17
+ * its major: one `in`, for the hot paths that ask about every value.
18
+ */
19
+ export declare function isAvDecimal(value: unknown): value is AvDecimal;
20
+ /**
21
+ * The digits of `value`, read without running anything the caller could have put
22
+ * on it when this copy made it. Another copy's decimal is read through its own
23
+ * `toString`, which only that copy can answer; what it returns is checked as a
24
+ * decimal string, so the caller's copy keeps the grammar.
25
+ *
26
+ * @throws TypeError when another copy's decimal does not answer a decimal string.
27
+ */
28
+ export declare function decimalDigitsOf(value: AvDecimal): string;
@@ -1,6 +1,11 @@
1
1
  import { WIRE_SCALAR_PATTERNS } from "../contracts/wire-scalar-format.js";
2
+ import { brandCoreClass, hasCoreBrand } from "./core-class.brand.js";
3
+ let ownDigitsOf;
2
4
  export class AvDecimal {
3
5
  #value;
6
+ static {
7
+ ownDigitsOf = (value) => (#value in value ? value.#value : undefined);
8
+ }
4
9
  constructor(value) {
5
10
  if (typeof value !== "string") {
6
11
  throw new TypeError("Decimal value must be a string.");
@@ -17,3 +22,19 @@ export class AvDecimal {
17
22
  return this.#value;
18
23
  }
19
24
  }
25
+ const DECIMAL_BRAND = brandCoreClass(AvDecimal, "AvDecimal");
26
+ export function isAvDecimal(value) {
27
+ return hasCoreBrand(value, DECIMAL_BRAND);
28
+ }
29
+ export function decimalDigitsOf(value) {
30
+ const own = ownDigitsOf(value);
31
+ if (own !== undefined) {
32
+ return own;
33
+ }
34
+ const digits = value.toString();
35
+ if (typeof digits !== "string" ||
36
+ !WIRE_SCALAR_PATTERNS.decimal.test(digits)) {
37
+ throw new TypeError("Decimal value must be a valid decimal string.");
38
+ }
39
+ return digits;
40
+ }
@@ -1,7 +1,7 @@
1
1
  import type { AvRequestOrigin } from "../config/config-layer.js";
2
2
  import type { AvOperationFamily } from "../operations/operation-identity.js";
3
- import type { FrameworkTransactionRequest } from "../transactions/transaction-request.js";
4
- import type { FrameworkOperationRequest } from "./operation-request.js";
3
+ import type { AvTransactionRequest } from "../transactions/transaction-request.js";
4
+ import type { AvOperationRequest } from "./operation-request.js";
5
5
  import { type AvOperationErrorCode, type AvOperationFailureResponse } from "./operation-response.js";
6
6
  /**
7
7
  * One unplanned failure of an operation: the raw error, the code the caller
@@ -100,14 +100,14 @@ export declare function diagnosticsSinkOf(framework: object): AvDiagnosticsSink
100
100
  * Binds the configured sink to one operation request. The sink is not awaited,
101
101
  * and nothing it throws or rejects with reaches the response.
102
102
  */
103
- export declare function createDiagnosticsReporter(sink: AvDiagnosticsSink | undefined, request: FrameworkOperationRequest, operation?: number): DiagnosticsReporter;
103
+ export declare function createDiagnosticsReporter(sink: AvDiagnosticsSink | undefined, request: AvOperationRequest, operation?: number): DiagnosticsReporter;
104
104
  /** The diagnostics channel of one transaction request. */
105
105
  export type TransactionDiagnosticsChannel = {
106
106
  /** A plan-level report; `operation` attributes it to a recorded failing index. */
107
107
  readonly transaction: (operation?: number) => DiagnosticsReporter;
108
108
  /** A report carrying one plan operation's own identity and index. */
109
- readonly operation: (request: FrameworkOperationRequest, operation: number) => DiagnosticsReporter;
109
+ readonly operation: (request: AvOperationRequest, operation: number) => DiagnosticsReporter;
110
110
  };
111
111
  /** Binds the configured sink to one transaction request and its plan operations. */
112
- export declare function createTransactionDiagnosticsChannel(sink: AvDiagnosticsSink | undefined, request: FrameworkTransactionRequest): TransactionDiagnosticsChannel;
112
+ export declare function createTransactionDiagnosticsChannel(sink: AvDiagnosticsSink | undefined, request: AvTransactionRequest): TransactionDiagnosticsChannel;
113
113
  export {};
@@ -1,3 +1,4 @@
1
+ import { coreBrandOf } from "./core-class.brand.js";
1
2
  import { internalFailure, } from "./operation-response.js";
2
3
  import { requestIdOf } from "./request-id.js";
3
4
  const IGNORE_DIAGNOSTIC = () => undefined;
@@ -31,7 +32,18 @@ export function createReporter(sink, identity) {
31
32
  }
32
33
  };
33
34
  }
34
- const CONFIGURED_SINKS = new WeakMap();
35
+ const CONFIGURED_SINKS = sharedSinkRegistry();
36
+ function sharedSinkRegistry() {
37
+ const key = coreBrandOf("diagnostics");
38
+ const holder = globalThis;
39
+ const existing = holder[key];
40
+ if (existing instanceof WeakMap) {
41
+ return existing;
42
+ }
43
+ const registry = new WeakMap();
44
+ Object.defineProperty(holder, key, { value: registry });
45
+ return registry;
46
+ }
35
47
  export function mcpFailureReporterOf(framework) {
36
48
  const sink = CONFIGURED_SINKS.get(framework);
37
49
  return (error) => {
@@ -1,3 +1,4 @@
1
+ import { brandCoreClass } from "./core-class.brand.js";
1
2
  export class AvError extends Error {
2
3
  name = "AvError";
3
4
  code;
@@ -30,3 +31,11 @@ export class AvProtocolError extends AvError {
30
31
  export class AvContractMismatchError extends AvError {
31
32
  name = "AvContractMismatchError";
32
33
  }
34
+ brandCoreClass(AvError, "AvError");
35
+ brandCoreClass(AvValidationError, "AvValidationError");
36
+ brandCoreClass(AvNotFoundError, "AvNotFoundError");
37
+ brandCoreClass(AvConflictError, "AvConflictError");
38
+ brandCoreClass(AvAuthError, "AvAuthError");
39
+ brandCoreClass(AvInternalError, "AvInternalError");
40
+ brandCoreClass(AvProtocolError, "AvProtocolError");
41
+ brandCoreClass(AvContractMismatchError, "AvContractMismatchError");
@@ -6,7 +6,7 @@ import type { AvState } from "./request-state.js";
6
6
  * The protocol version and Contract hash a remote caller says it was built for:
7
7
  * the Client Contract's for a client, the Agent Contract's for an agent.
8
8
  */
9
- export type ClientProtocolIdentity = {
9
+ export type AvRequestProtocol = {
10
10
  readonly version: number;
11
11
  readonly hash: string;
12
12
  };
@@ -21,7 +21,7 @@ type RuntimeOperationBase = AvOperationIdentity & {
21
21
  readonly state?: AvState;
22
22
  };
23
23
  /** An in-process request, run under the Application Contract. */
24
- export type ApplicationOperationRequest = RuntimeOperationBase & {
24
+ export type AvApplicationOperationRequest = RuntimeOperationBase & {
25
25
  readonly origin: "application";
26
26
  readonly protocol?: never;
27
27
  readonly transport?: never;
@@ -30,24 +30,24 @@ export type ApplicationOperationRequest = RuntimeOperationBase & {
30
30
  * A remote request, run under the Client Contract; `protocol` is the identity
31
31
  * the client sent.
32
32
  */
33
- export type ClientOperationRequest = RuntimeOperationBase & {
33
+ export type AvClientOperationRequest = RuntimeOperationBase & {
34
34
  readonly origin: "client";
35
- readonly protocol: ClientProtocolIdentity;
35
+ readonly protocol: AvRequestProtocol;
36
36
  readonly transport?: AvTransportContext;
37
37
  };
38
38
  /**
39
39
  * An AI agent's request, run under the Agent Contract; `protocol` is the
40
40
  * identity of the Agent Contract the caller (an MCP server) was built from.
41
41
  */
42
- export type AgentOperationRequest = RuntimeOperationBase & {
42
+ export type AvAgentOperationRequest = RuntimeOperationBase & {
43
43
  readonly origin: "agent";
44
- readonly protocol: ClientProtocolIdentity;
44
+ readonly protocol: AvRequestProtocol;
45
45
  readonly transport?: AvTransportContext;
46
46
  };
47
47
  /** A request from outside the server: a client's or an agent's. */
48
- export type RemoteOperationRequest = ClientOperationRequest | AgentOperationRequest;
48
+ export type RemoteOperationRequest = AvClientOperationRequest | AvAgentOperationRequest;
49
49
  /** One operation request, as `framework.execute` takes it. */
50
- export type FrameworkOperationRequest = ApplicationOperationRequest | ClientOperationRequest | AgentOperationRequest;
50
+ export type AvOperationRequest = AvApplicationOperationRequest | AvClientOperationRequest | AvAgentOperationRequest;
51
51
  type WithoutArguments<Request> = Request extends unknown ? Omit<Request, "arguments"> : never;
52
52
  /**
53
53
  * A request as every stage after the Framework Validation Layer sees it:
@@ -57,7 +57,7 @@ type WithoutArguments<Request> = Request extends unknown ? Omit<Request, "argume
57
57
  * unreachable by type. Distributive, so the origin and family/variant
58
58
  * correlations survive the omission.
59
59
  */
60
- export type OperationExecutionRequest = WithoutArguments<FrameworkOperationRequest>;
60
+ export type OperationExecutionRequest = WithoutArguments<AvOperationRequest>;
61
61
  /**
62
62
  * A request whose stages run: its `state` settled once, the seed or the `{}`
63
63
  * the runtime made for it, so every stage is told the same object.
@@ -8,14 +8,14 @@ import type { AvRequestOrigin, RemoteRequestOrigin } from "../config/config-laye
8
8
  import type { AvContract } from "../contracts/contract.js";
9
9
  import type { OperationValidationOptions, SemanticOperationArguments } from "../operations/operation-validator.js";
10
10
  import { type PolicyCaller } from "../policy/policy-request.js";
11
- import type { FrameworkTransactionRequest } from "../transactions/transaction-request.js";
11
+ import type { AvTransactionRequest } from "../transactions/transaction-request.js";
12
12
  import { type ArgumentsSource } from "./caller-data.door.js";
13
13
  import { type ContextExecutor, type ExecutorScope } from "./context-executor.runtime.js";
14
14
  import { type RecordWriteFacts } from "./create-requirement.js";
15
15
  import { type DiagnosticsReporter } from "./diagnostics-reporter.js";
16
16
  import { type OuterFailureLayer } from "./error-boundary.js";
17
17
  import { type FieldStagePlan } from "./field-stage.plan.js";
18
- import type { ClientProtocolIdentity, FrameworkOperationRequest, StatefulOperationRequest } from "./operation-request.js";
18
+ import type { AvOperationRequest, AvRequestProtocol, StatefulOperationRequest } from "./operation-request.js";
19
19
  import type { AvOperationFailureResponse, AvOperationResponse } from "./operation-response.js";
20
20
  import type { AvState } from "./request-state.js";
21
21
  import { type NormalizationWrite } from "./scalar-runtime.js";
@@ -70,7 +70,7 @@ export declare function withRequestState<Request extends {
70
70
  * `request` with its policy session when the policy checks it, or the failure
71
71
  * deriving its principal answered.
72
72
  */
73
- export declare function withRequestPolicy<M extends AvAdapterModel>(dependencies: Pick<OperationRuntimeDependencies<M>, "adapter" | "config" | "contracts">, request: StatefulOperationRequest, caller: PolicyCaller | undefined, report: DiagnosticsReporter): StatefulOperationRequest | AvOperationFailureResponse;
73
+ export declare function withRequestPolicy<M extends AvAdapterModel>(dependencies: Pick<OperationRuntimeDependencies<M>, "adapter" | "config" | "contracts">, request: StatefulOperationRequest, caller: PolicyCaller | undefined, report: DiagnosticsReporter): StatefulOperationRequest | AvOperationFailureResponse | Promise<StatefulOperationRequest | AvOperationFailureResponse>;
74
74
  /**
75
75
  * Builds what every operation's pipeline shares, the ctx executor included: its
76
76
  * raw calls run the application's operation path with every developer stage
@@ -85,15 +85,15 @@ export declare function createPipelineDependencies<M extends AvAdapterModel>(dep
85
85
  * request's arguments are the caller's own objects, copied at the door, or data
86
86
  * no caller holds (see {@link ArgumentsSource}).
87
87
  */
88
- export type FrameworkOperationExecutor = (request: FrameworkOperationRequest, report: DiagnosticsReporter, source: ArgumentsSource,
88
+ export type FrameworkOperationExecutor = (request: AvOperationRequest, report: DiagnosticsReporter, source: ArgumentsSource,
89
89
  /** The principal an application call runs as (`{ as }`), when it names one. */
90
90
  caller?: PolicyCaller) => Promise<AvOperationResponse>;
91
91
  /** Selects the Contract of the request's origin. */
92
- export declare function activeContract(contracts: AvContracts, request: FrameworkOperationRequest | FrameworkTransactionRequest): AvContract;
92
+ export declare function activeContract(contracts: AvContracts, request: AvOperationRequest | AvTransactionRequest): AvContract;
93
93
  /** Creates the transport-independent operation executor owned by core. */
94
94
  export declare function createOperationRuntime<M extends AvAdapterModel>(dependencies: OperationRuntimeDependencies<M>, pipelineDependencies: OperationPipelineDependencies<M>): FrameworkOperationExecutor;
95
95
  /** Validates the request-level protocol identity. */
96
- export declare function validateProtocolIdentity(contracts: AvContracts, request: FrameworkOperationRequest | FrameworkTransactionRequest): AvOperationFailureResponse | undefined;
96
+ export declare function validateProtocolIdentity(contracts: AvContracts, request: AvOperationRequest | AvTransactionRequest): AvOperationFailureResponse | undefined;
97
97
  /**
98
98
  * The stale-client check on one remote protocol identity: the protocol version first
99
99
  * (`A2006`), then the hash of the origin's Contract (`A2005`): the ClientContract's
@@ -102,7 +102,7 @@ export declare function validateProtocolIdentity(contracts: AvContracts, request
102
102
  * (`@aventara/core/protocol`) call it too, so a stale client hears the same envelope
103
103
  * whichever layer answers.
104
104
  */
105
- export declare function protocolIdentityFailure(contracts: AvContracts, protocol: ClientProtocolIdentity, origin: RemoteRequestOrigin): AvOperationFailureResponse | undefined;
105
+ export declare function protocolIdentityFailure(contracts: AvContracts, protocol: AvRequestProtocol, origin: RemoteRequestOrigin): AvOperationFailureResponse | undefined;
106
106
  export type ValidatedOperationArguments = {
107
107
  readonly ok: true;
108
108
  readonly arguments: SemanticOperationArguments;
@@ -111,7 +111,7 @@ export type ValidatedOperationArguments = {
111
111
  readonly response: AvOperationFailureResponse;
112
112
  };
113
113
  /** Validates one operation's arguments through the Framework Validation Layer. */
114
- export declare function validateOperationRequest(contract: AvContract, request: FrameworkOperationRequest, options?: OperationValidationOptions, write?: NormalizationWrite): ValidatedOperationArguments;
114
+ export declare function validateOperationRequest(contract: AvContract, request: AvOperationRequest, options?: OperationValidationOptions, write?: NormalizationWrite): ValidatedOperationArguments;
115
115
  /** The subject a refused output of an operation's pipes is reported under at a plan step. */
116
116
  export declare const STEP_PIPES = "Pipes";
117
117
  /**
@@ -44,13 +44,19 @@ export function withRequestState(request) {
44
44
  return { ...request, state: requestStateOf(request.state) };
45
45
  }
46
46
  export function withRequestPolicy(dependencies, request, caller, report) {
47
+ const failed = (error) => {
48
+ report(error, "A3000");
49
+ return internalFailure();
50
+ };
51
+ const withPolicy = (policy) => policy === undefined ? request : { ...request, policy };
47
52
  try {
48
53
  const policy = openRequestPolicy(dependencies.config.policy, dependencies.contracts.core, request, caller, dependencies.adapter);
49
- return policy === undefined ? request : { ...request, policy };
54
+ return policy instanceof Promise
55
+ ? policy.then(withPolicy, failed)
56
+ : withPolicy(policy);
50
57
  }
51
58
  catch (error) {
52
- report(error, "A3000");
53
- return internalFailure();
59
+ return failed(error);
54
60
  }
55
61
  }
56
62
  export function createPipelineDependencies(dependencies, model) {
@@ -197,7 +203,8 @@ export function createOperationRuntime(dependencies, pipelineDependencies) {
197
203
  if (!validated.ok) {
198
204
  return validated.response;
199
205
  }
200
- const stateful = withRequestPolicy(dependencies, withRequestState(request), caller, report);
206
+ const opened = withRequestPolicy(dependencies, withRequestState(request), caller, report);
207
+ const stateful = opened instanceof Promise ? await opened : opened;
201
208
  if (!("state" in stateful)) {
202
209
  return stateful;
203
210
  }
@@ -612,8 +619,10 @@ export async function executeAdmittedOperation(dependencies, request, contract,
612
619
  let operation = request;
613
620
  let settle;
614
621
  let writeMiss;
622
+ let failedWriteMiss;
615
623
  if (policyWrite !== undefined && policyWrite.kind !== "refused") {
616
624
  writeMiss = policyWrite.miss;
625
+ failedWriteMiss = policyWrite.failedMiss;
617
626
  if (policyWrite.kind === "empty") {
618
627
  if (writeMiss !== undefined && policyWrite.data === null) {
619
628
  refuseWrite(await writeMiss());
@@ -643,11 +652,23 @@ export async function executeAdmittedOperation(dependencies, request, contract,
643
652
  settle = read.settle;
644
653
  }
645
654
  const { policy: _session, ...identity } = operation;
646
- let adapterData = await adapterBoundary.execute(() => executor.execute({
647
- ...identity,
648
- resource: request.resource,
649
- arguments: adapterArguments,
650
- }));
655
+ let adapterData;
656
+ try {
657
+ adapterData = await adapterBoundary.execute(() => executor.execute({
658
+ ...identity,
659
+ resource: request.resource,
660
+ arguments: adapterArguments,
661
+ }));
662
+ }
663
+ catch (error) {
664
+ const missed = failedWriteMiss === undefined
665
+ ? undefined
666
+ : await failedWriteMiss().catch(() => undefined);
667
+ if (missed !== undefined) {
668
+ refuseWrite(missed);
669
+ }
670
+ throw error;
671
+ }
651
672
  if (writeMiss !== undefined && adapterData === null) {
652
673
  refuseWrite(await writeMiss());
653
674
  }
@@ -1,4 +1,4 @@
1
- import type { AgentTransactionRequest, ClientTransactionRequest } from "../transactions/transaction-request.js";
1
+ import type { AvAgentTransactionRequest, AvClientTransactionRequest } from "../transactions/transaction-request.js";
2
2
  import type { AvTransactionResponse } from "../transactions/transaction-response.js";
3
3
  import type { AvCallerDataError } from "./caller-data.copier.js";
4
4
  import type { RemoteOperationRequest } from "./operation-request.js";
@@ -15,7 +15,7 @@ export type OwnedExecution = {
15
15
  * at the call, and these steps' arguments could not be copied there: each is
16
16
  * answered at its turn as the door answers that failure.
17
17
  */
18
- readonly executeTransaction: (request: ClientTransactionRequest | AgentTransactionRequest, refused?: ReadonlyMap<number, AvCallerDataError>) => Promise<AvTransactionResponse>;
18
+ readonly executeTransaction: (request: AvClientTransactionRequest | AvAgentTransactionRequest, refused?: ReadonlyMap<number, AvCallerDataError>) => Promise<AvTransactionResponse>;
19
19
  };
20
20
  /** Records `framework`'s owned entries; called once, at construction. */
21
21
  export declare function recordOwnedExecution(framework: object, execution: OwnedExecution): void;
@@ -1,4 +1,4 @@
1
- import { AvDecimal } from "./decimal.js";
1
+ import { type AvDecimal } from "./decimal.js";
2
2
  /** A value `AvDeepReadonly` leaves as it is: a primitive, a function, or a scalar instance. */
3
3
  export type AvDeepReadonlyLeaf = string | number | boolean | bigint | symbol | null | undefined | Date | Uint8Array | AvDecimal | ((...args: never[]) => unknown);
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { AvDecimal } from "./decimal.js";
1
+ import { isAvDecimal } from "./decimal.js";
2
2
  function isContainer(value) {
3
3
  if (value === null || typeof value !== "object") {
4
4
  return false;
@@ -6,7 +6,7 @@ function isContainer(value) {
6
6
  if (Array.isArray(value)) {
7
7
  return true;
8
8
  }
9
- if (value instanceof AvDecimal) {
9
+ if (isAvDecimal(value)) {
10
10
  return false;
11
11
  }
12
12
  const prototype = Object.getPrototypeOf(value);
@@ -29,7 +29,7 @@ export type ReferentialEdge = {
29
29
  * relation `field` and any of these names the reference twice and is refused;
30
30
  * a required relation may be written through all of them instead.
31
31
  */
32
- readonly references: readonly string[];
32
+ readonly referenceFields: readonly string[];
33
33
  /** What deleting a `target` row does to rows of the ENCLOSING Resource. */
34
34
  readonly onDelete: ReferentialDeleteEffect;
35
35
  };
@@ -4,7 +4,7 @@ import { FILTER_MODES, } from "../contracts/capability.js";
4
4
  import { lookupField, lookupOwn, lookupResource, } from "../contracts/contract-lookup.js";
5
5
  import { decodeBase64, WIRE_SCALAR_PATTERNS, } from "../contracts/wire-scalar-format.js";
6
6
  import { routeTransactionReferenceCandidate, } from "../transactions/transaction-reference.js";
7
- import { AvDecimal } from "./decimal.js";
7
+ import { AvDecimal, isAvDecimal } from "./decimal.js";
8
8
  import { fieldCheckIssues } from "./field-check.evaluator.js";
9
9
  const INT_MIN = -(2 ** 31);
10
10
  const INT_MAX = 2 ** 31 - 1;
@@ -238,10 +238,9 @@ function normalizeScalarAtom(contract, field, value, origin, path, allowNull) {
238
238
  break;
239
239
  case "decimal":
240
240
  if (origin === "application") {
241
- normalized =
242
- value instanceof AvDecimal
243
- ? { ok: true, value }
244
- : { ok: false, issues: [typeIssue(path, "an Aventara Decimal")] };
241
+ normalized = isAvDecimal(value)
242
+ ? { ok: true, value }
243
+ : { ok: false, issues: [typeIssue(path, "an Aventara Decimal")] };
245
244
  }
246
245
  else if (typeof value !== "string") {
247
246
  normalized = {
@@ -1,6 +1,6 @@
1
1
  import { lookupField, lookupResource } from "../contracts/contract-lookup.js";
2
2
  import { encodeBase64 } from "../contracts/wire-scalar-format.js";
3
- import { AvDecimal } from "../runtime/decimal.js";
3
+ import { isAvDecimal } from "../runtime/decimal.js";
4
4
  import { isRelationMutationDirective, RELATION_MUTATION_RECORD_SITES, } from "../runtime/mutation-planner.js";
5
5
  import { isTransactionReferenceCandidate } from "./transaction-reference.js";
6
6
  function isPlainRecord(value) {
@@ -27,9 +27,11 @@ function encodeScalarAtom(field, value) {
27
27
  case "bigint":
28
28
  return typeof value === "bigint" ? value.toString(10) : value;
29
29
  case "decimal":
30
- return value instanceof AvDecimal ? value.toString() : value;
30
+ return isAvDecimal(value) ? value.toString() : value;
31
31
  case "datetime":
32
- return value instanceof Date ? value.toISOString() : value;
32
+ return value instanceof Date && !Number.isNaN(value.getTime())
33
+ ? value.toISOString()
34
+ : value;
33
35
  case "bytes":
34
36
  return value instanceof Uint8Array ? encodeBase64(value) : value;
35
37
  default:
@@ -282,6 +284,9 @@ function isUniqueOperation(operation) {
282
284
  operation.family === "upsert"));
283
285
  }
284
286
  export function encodeOperationArgumentsForWire(contract, operation, args) {
287
+ if (!isPlainRecord(args)) {
288
+ return args;
289
+ }
285
290
  const encoded = cloneRecord(args);
286
291
  if (hasOwnWireProperty(args, "where")) {
287
292
  encoded.where = isUniqueOperation(operation)
@@ -10,7 +10,7 @@ import type { AvTransactionReference } from "./transaction-reference.js";
10
10
  * `${value}::jsonb`), or a `$ref` to an earlier step's field, resolved when the
11
11
  * earlier steps have run and then bound like any other value.
12
12
  */
13
- export type SqlStatementValue = AvAdapterSqlValue | AvTransactionReference;
13
+ export type AvSqlStatementValue = AvAdapterSqlValue | AvTransactionReference;
14
14
  /**
15
15
  * `framework.appTx.$sql`: a developer SQL step, written only as a tagged template —
16
16
  * ``framework.appTx.$sql`select pgmq.send('jobs', jsonb_build_object('id', ${ref}))` ``.
@@ -23,7 +23,7 @@ export type SqlStatementValue = AvAdapterSqlValue | AvTransactionReference;
23
23
  * SQL step's rows. No guard, pipe, hook, interceptor or filter runs around it: it
24
24
  * has no Resource or operation for one to wrap.
25
25
  */
26
- export type SqlStatementBuilder = <Row = unknown>(strings: TemplateStringsArray, ...values: readonly SqlStatementValue[]) => AvOperation<Row[], "application">;
26
+ export type AvSqlStatementBuilder = <Row = unknown>(strings: TemplateStringsArray, ...values: readonly AvSqlStatementValue[]) => AvOperation<Row[], "application">;
27
27
  /** One value of a planned SQL step, as the typed runner bound it. */
28
28
  export type PlannedSqlValue = {
29
29
  readonly kind: "value";
@@ -1,7 +1,7 @@
1
1
  import { validationIssue } from "../operations/validation-code.js";
2
2
  import { AvCallerDataError, locateCallerDataError, } from "../runtime/caller-data.copier.js";
3
3
  import { refuseCallerData } from "../runtime/caller-data.door.js";
4
- import { AvDecimal } from "../runtime/decimal.js";
4
+ import { isAvDecimal } from "../runtime/decimal.js";
5
5
  import { planStepPath } from "../runtime/error-boundary.js";
6
6
  import { operationFailure } from "../runtime/operation-response.js";
7
7
  import { mapValidationOutcome } from "../runtime/outcome-mapper.js";
@@ -19,7 +19,7 @@ export function normalizeSqlValue(value, path) {
19
19
  typeof value === "string" ||
20
20
  typeof value === "boolean" ||
21
21
  typeof value === "bigint" ||
22
- value instanceof AvDecimal ||
22
+ isAvDecimal(value) ||
23
23
  value instanceof Uint8Array) {
24
24
  return { ok: true, value };
25
25
  }
@@ -1,3 +1,4 @@
1
+ import { brandCoreClass } from "../runtime/core-class.brand.js";
1
2
  const TRANSACTION_INTEGRITY_MESSAGES = {
2
3
  "transaction-unavailable": "Adapter transaction function is unavailable.",
3
4
  "resolved-after-abort": "Adapter transaction resolved after the framework requested rollback.",
@@ -15,3 +16,4 @@ export class AvTransactionIntegrityError extends Error {
15
16
  this.violation = violation;
16
17
  }
17
18
  }
19
+ brandCoreClass(AvTransactionIntegrityError, "AvTransactionIntegrityError");
@@ -2,13 +2,15 @@ import type { AvContracts } from "../compiler/contract.compiler.js";
2
2
  import type { AvOperationIdentity } from "../operations/operation-identity.js";
3
3
  import { AvCallerDataError } from "../runtime/caller-data.copier.js";
4
4
  import type { MisuseReporter } from "../runtime/misuse-reporter.js";
5
- import type { ClientProtocolIdentity } from "../runtime/operation-request.js";
5
+ import type { AvRequestProtocol } from "../runtime/operation-request.js";
6
6
  import type { AvOperationFailureResponse } from "../runtime/operation-response.js";
7
7
  import type { AvOperation, OperationFingerprint } from "./deferred-operation.js";
8
8
  import type { PlannedSqlStatement } from "./sql-statement.js";
9
9
  import type { TransactionOperationOrigin } from "./transaction-request.js";
10
10
  /** The origin a handle's builder gives it. */
11
11
  type HandleOrigin = "application" | "client";
12
+ /** The scalar forms a builder takes its arguments in. */
13
+ type ArgumentForms = "wire" | "application";
12
14
  /** One wire node, exactly as the transaction runtime receives it. */
13
15
  type WireOperationNode = {
14
16
  readonly resource: string;
@@ -37,8 +39,13 @@ export type AssembledTransactionPlan = {
37
39
  readonly response: AvOperationFailureResponse;
38
40
  };
39
41
  export type TransactionPlanAssembler = {
40
- /** Defers one operation into a handle; nothing runs. */
41
- defer(origin: HandleOrigin, resource: string, identity: AvOperationIdentity, args: unknown): AvOperation<unknown>;
42
+ /**
43
+ * Defers one operation into a handle; nothing runs. `forms` says which scalar
44
+ * forms a client-origin handle's arguments are in: `"wire"` (`clientTx`, the
45
+ * default) or `"application"` (`serverClientTx`), encoded into the wire forms
46
+ * from the builder's copy.
47
+ */
48
+ defer(origin: HandleOrigin, resource: string, identity: AvOperationIdentity, args: unknown, forms?: ArgumentForms): AvOperation<unknown>;
42
49
  /** Defers one `appTx.$sql` statement into a handle; nothing runs. */
43
50
  deferSql(strings: unknown, values: readonly unknown[]): AvOperation<unknown>;
44
51
  /** Binds a list of handles into the passive plan, or refuses it. */
@@ -49,5 +56,5 @@ export type TransactionPlanAssembler = {
49
56
  * handle, so a handle another instance built — typed against another model,
50
57
  * bound to other Contracts — is refused rather than run.
51
58
  */
52
- export declare function createTransactionPlanAssembler(contracts: AvContracts, protocol: ClientProtocolIdentity, misuse: MisuseReporter): TransactionPlanAssembler;
59
+ export declare function createTransactionPlanAssembler(contracts: AvContracts, protocol: AvRequestProtocol, misuse: MisuseReporter): TransactionPlanAssembler;
53
60
  export {};
@@ -139,8 +139,23 @@ export function createTransactionPlanAssembler(contracts, protocol, misuse) {
139
139
  handles.set(handle, record);
140
140
  return handle;
141
141
  };
142
- const defer = (origin, resource, identity, args) => {
143
- const copy = snapshot(args, STEP_REFERENCE_MIRROR);
142
+ const defer = (origin, resource, identity, args, forms = "wire") => {
143
+ const snapped = snapshot(args, STEP_REFERENCE_MIRROR);
144
+ let copy = snapped;
145
+ if (origin === "client" &&
146
+ forms === "application" &&
147
+ snapped.refused === undefined) {
148
+ try {
149
+ copy = {
150
+ args: encodeOperationArgumentsForWire(contracts.client, { resource, ...identity }, snapped.args),
151
+ };
152
+ }
153
+ catch (error) {
154
+ if (!(error instanceof AvCallerDataError)) {
155
+ throw error;
156
+ }
157
+ }
158
+ }
144
159
  let sent = copy.args;
145
160
  try {
146
161
  sent = withoutUnsentWriteValues(origin === "application" ? contracts.application : contracts.client, { resource, family: identity.family }, copy.args);
@@ -4,7 +4,7 @@ import type { AvScalarField } from "../contracts/field.js";
4
4
  import type { SemanticOperationArguments } from "../operations/operation-validator.js";
5
5
  import { AvCallerDataError } from "../runtime/caller-data.copier.js";
6
6
  import { type ReadProjectionPlan } from "../runtime/computed-read-runtime.js";
7
- import type { FrameworkOperationRequest } from "../runtime/operation-request.js";
7
+ import type { AvOperationRequest } from "../runtime/operation-request.js";
8
8
  import type { AvOperationFailureResponse } from "../runtime/operation-response.js";
9
9
  import type { OperationPipelineDependencies } from "../runtime/operation-runtime.js";
10
10
  import type { CascadeClosure } from "../runtime/referential-action.js";
@@ -13,7 +13,7 @@ import type { PlannedSqlStatement, ValidatedSqlStatement } from "./sql-statement
13
13
  import type { AvTransactionReference } from "./transaction-reference.js";
14
14
  import { type TransactionSlotShape } from "./transaction-reference.js";
15
15
  import { type TransactionReferenceCandidateSlot } from "./transaction-reference-collector.js";
16
- import type { FrameworkTransactionRequest, TransactionOperationOrigin } from "./transaction-request.js";
16
+ import type { AvTransactionRequest, TransactionOperationOrigin } from "./transaction-request.js";
17
17
  /**
18
18
  * Where a plan's step arguments came from, so the validator knows whether to copy
19
19
  * them at the door (see `ArgumentsSource`):
@@ -65,7 +65,7 @@ export type TransactionReferenceSlot = {
65
65
  };
66
66
  export type CandidateTransactionOperation = {
67
67
  readonly index: number;
68
- readonly request: FrameworkOperationRequest;
68
+ readonly request: AvOperationRequest;
69
69
  readonly arguments: SemanticOperationArguments;
70
70
  readonly projection: ReadProjectionPlan | undefined;
71
71
  readonly declaredFingerprint: unknown;
@@ -74,7 +74,7 @@ export type CandidateTransactionOperation = {
74
74
  export type ValidatedTransactionOperation = {
75
75
  readonly kind: "operation";
76
76
  readonly index: number;
77
- readonly request: FrameworkOperationRequest;
77
+ readonly request: AvOperationRequest;
78
78
  /**
79
79
  * The Contract of this operation's origin, which is the plan's: the one it was
80
80
  * validated against, the one it runs under, and the one a later `$ref` reads its
@@ -118,4 +118,4 @@ export declare function transactionsUnavailableFailure(): AvOperationFailureResp
118
118
  /**
119
119
  * Whole-plan Framework Validation Layer for transaction structure and identity.
120
120
  */
121
- export declare function validateTransactionPlan<M extends AvAdapterModel>(dependencies: TransactionPlanDependencies<M>, request: FrameworkTransactionRequest, origins?: readonly TransactionOperationOrigin[], planArguments?: PlanArguments): Promise<TransactionPlanValidationResult>;
121
+ export declare function validateTransactionPlan<M extends AvAdapterModel>(dependencies: TransactionPlanDependencies<M>, request: AvTransactionRequest, origins?: readonly TransactionOperationOrigin[], planArguments?: PlanArguments): Promise<TransactionPlanValidationResult>;