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

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 (97) hide show
  1. package/CHANGELOG.md +295 -1
  2. package/ERRORS.md +142 -0
  3. package/README.md +24 -1
  4. package/dist/adapters/adapter-discovery-diagnostic.guidance.d.ts +6 -0
  5. package/dist/adapters/adapter-discovery-diagnostic.guidance.js +7 -0
  6. package/dist/adapters/adapter-field.d.ts +14 -0
  7. package/dist/adapters/adapter-model.d.ts +9 -0
  8. package/dist/adapters/adapter.interface.d.ts +10 -0
  9. package/dist/compiler/contract-compiler-diagnostic.guidance.d.ts +6 -0
  10. package/dist/compiler/contract-compiler-diagnostic.guidance.js +97 -0
  11. package/dist/compiler/contract.compiler.js +94 -6
  12. package/dist/config/computed-fields.d.ts +62 -0
  13. package/dist/config/computed-fields.js +80 -0
  14. package/dist/config/config-diagnostic.guidance.d.ts +6 -0
  15. package/dist/config/config-diagnostic.guidance.js +32 -0
  16. package/dist/config/define-resource.d.ts +1 -1
  17. package/dist/config/exact-framework-config.d.ts +48 -20
  18. package/dist/config/field-compute.resolver.d.ts +2 -0
  19. package/dist/config/field-compute.resolver.js +8 -0
  20. package/dist/config/framework-config.d.ts +7 -6
  21. package/dist/config/framework-resources-config.d.ts +18 -12
  22. package/dist/config/pipeline-config.d.ts +4 -4
  23. package/dist/contracts/capability.d.ts +10 -1
  24. package/dist/contracts/capability.js +2 -0
  25. package/dist/contracts/client-contract-structure.validator.d.ts +65 -35
  26. package/dist/contracts/client-contract-structure.validator.js +4 -2
  27. package/dist/contracts/contract-canonicalizer.d.ts +7 -0
  28. package/dist/contracts/contract-canonicalizer.js +18 -4
  29. package/dist/contracts/field.d.ts +30 -1
  30. package/dist/framework/contract-view.d.ts +4 -4
  31. package/dist/framework/framework-construction.error.d.ts +12 -3
  32. package/dist/framework/framework-construction.error.js +5 -1
  33. package/dist/framework/framework.factory.d.ts +1 -1
  34. package/dist/framework/framework.factory.js +9 -2
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.js +1 -0
  37. package/dist/internal.d.ts +2 -0
  38. package/dist/internal.js +1 -0
  39. package/dist/operations/database-refusal.d.ts +51 -0
  40. package/dist/operations/database-refusal.js +45 -0
  41. package/dist/operations/operation-arguments.d.ts +102 -31
  42. package/dist/operations/operation-validator-core.js +86 -4
  43. package/dist/operations/validation-code.guidance.d.ts +6 -0
  44. package/dist/operations/validation-code.guidance.js +90 -0
  45. package/dist/operations/write-scope.resolver.d.ts +4 -0
  46. package/dist/operations/write-scope.resolver.js +2 -0
  47. package/dist/protocol/protocol.handler.js +55 -16
  48. package/dist/runtime/caller-data.copier.d.ts +17 -0
  49. package/dist/runtime/caller-data.copier.js +18 -1
  50. package/dist/runtime/caller-data.door.d.ts +11 -5
  51. package/dist/runtime/computed-read-runtime.js +15 -2
  52. package/dist/runtime/computed-value.error.d.ts +3 -2
  53. package/dist/runtime/computed-value.error.js +3 -2
  54. package/dist/runtime/create-requirement.d.ts +41 -5
  55. package/dist/runtime/create-requirement.js +137 -20
  56. package/dist/runtime/diagnostics-reporter.d.ts +2 -1
  57. package/dist/runtime/error-boundary.js +4 -0
  58. package/dist/runtime/error-guidance.d.ts +12 -0
  59. package/dist/runtime/error-guidance.js +1 -0
  60. package/dist/runtime/error.catalog.d.ts +49 -0
  61. package/dist/runtime/error.catalog.js +49 -0
  62. package/dist/runtime/field-stage.runtime.d.ts +2 -0
  63. package/dist/runtime/field-stage.runtime.js +8 -4
  64. package/dist/runtime/field-validator.runtime.d.ts +9 -1
  65. package/dist/runtime/field-validator.runtime.js +11 -6
  66. package/dist/runtime/json-value.d.ts +10 -5
  67. package/dist/runtime/level-lifecycle.runtime.d.ts +2 -2
  68. package/dist/runtime/level-lifecycle.runtime.js +2 -5
  69. package/dist/runtime/mutation-planner.js +3 -14
  70. package/dist/runtime/operation-code.guidance.d.ts +6 -0
  71. package/dist/runtime/operation-code.guidance.js +167 -0
  72. package/dist/runtime/operation-runtime.d.ts +20 -6
  73. package/dist/runtime/operation-runtime.js +77 -35
  74. package/dist/runtime/owned-execution.registry.d.ts +12 -2
  75. package/dist/runtime/pipe-output.validator.d.ts +10 -0
  76. package/dist/runtime/pipe-output.validator.js +4 -2
  77. package/dist/runtime/pipeline.d.ts +35 -8
  78. package/dist/runtime/readonly-value.d.ts +14 -3
  79. package/dist/runtime/readonly-value.js +10 -1
  80. package/dist/runtime/scalar-runtime.d.ts +5 -1
  81. package/dist/runtime/scalar-runtime.js +86 -16
  82. package/dist/runtime/unsent-value.normalizer.d.ts +15 -0
  83. package/dist/runtime/unsent-value.normalizer.js +128 -0
  84. package/dist/transactions/operation-fingerprint.js +2 -2
  85. package/dist/transactions/sql-statement.d.ts +8 -0
  86. package/dist/transactions/sql-statement.validator.js +36 -3
  87. package/dist/transactions/transaction-plan-assembler.d.ts +1 -1
  88. package/dist/transactions/transaction-plan-assembler.js +33 -10
  89. package/dist/transactions/transaction-plan-validator.d.ts +16 -0
  90. package/dist/transactions/transaction-plan-validator.js +27 -1
  91. package/dist/transactions/transaction-reference-validator.d.ts +42 -0
  92. package/dist/transactions/transaction-reference-validator.js +82 -56
  93. package/dist/transactions/transaction-reference.js +5 -0
  94. package/dist/transactions/transaction-runtime.js +47 -22
  95. package/dist/transactions/transaction-stage.runtime.d.ts +2 -1
  96. package/dist/transactions/transaction-stage.runtime.js +7 -4
  97. package/package.json +4 -3
@@ -5,8 +5,9 @@ import type { AvTransactionCapability } from "../contracts/transaction-capabilit
5
5
  import type { AvDiagnosticsSink } from "../runtime/diagnostics-reporter.js";
6
6
  import type { AvMisuseSink } from "../runtime/misuse-reporter.js";
7
7
  import type { AvConfigAny } from "./any-framework-config.js";
8
+ import type { AvConfigLayerName } from "./config-layer.js";
8
9
  import type { AvConfigExemptions } from "./framework-exemptions-config.js";
9
- import type { AvConfigLayerKind, AvConfigResources } from "./framework-resources-config.js";
10
+ import type { AvConfigLayerKind, AvConfigResources, LayerOfKind } from "./framework-resources-config.js";
10
11
  import type { AvPipeline } from "./pipeline-config.js";
11
12
  /**
12
13
  * Request limits to override; each one left out takes its default from
@@ -29,7 +30,7 @@ type MovedLayerKeys = {
29
30
  * `agent`. Stages are added to the root's; `transactionsStyle` and `limits`
30
31
  * replace it where an overlay states them; exposure only narrows.
31
32
  */
32
- export type AvConfigLayer<M extends AvAdapterModel = AvAdapterModel, Cfg = AvConfigAny, Kind extends AvConfigLayerKind = "root"> = MovedLayerKeys & {
33
+ export type AvConfigLayer<M extends AvAdapterModel = AvAdapterModel, Cfg = AvConfigAny, Kind extends AvConfigLayerKind = "root", Layer extends AvConfigLayerName = LayerOfKind<Kind>> = MovedLayerKeys & {
33
34
  /**
34
35
  * Whether the layer's `exemptions` hide (`true`, the root's default) or are
35
36
  * the only entries exposed (`false`). Each layer narrows its parent: the root
@@ -43,7 +44,7 @@ export type AvConfigLayer<M extends AvAdapterModel = AvAdapterModel, Cfg = AvCon
43
44
  /** Guards, pipes, hooks, interceptors and filters run around every operation of the layer. */
44
45
  readonly pipelines?: AvPipeline<NoInfer<M>>;
45
46
  /** The per-Resource tree: stages, operations, transactions and fields. */
46
- readonly resources?: AvConfigResources<M, Cfg, Kind>;
47
+ readonly resources?: AvConfigResources<M, Cfg, Kind, Layer>;
47
48
  /**
48
49
  * The entries that are the opposite of `exposed`. An overlay that sets them
49
50
  * states its own `exposed`.
@@ -73,8 +74,8 @@ export type AvConfig<M extends AvAdapterModel = AvAdapterModel, Cfg = AvConfigAn
73
74
  readonly diagnostics?: AvDiagnosticsSink;
74
75
  /** Told about every caller value refused as unreadable or not plain data. */
75
76
  readonly misuse?: AvMisuseSink;
76
- readonly application?: AvConfigLayer<M, Cfg, "overlay">;
77
- readonly client?: AvConfigLayer<M, Cfg, "overlay">;
77
+ readonly application?: AvConfigLayer<M, Cfg, "overlay", "application">;
78
+ readonly client?: AvConfigLayer<M, Cfg, "overlay", "client">;
78
79
  /**
79
80
  * The layer an AI agent's calls run under. It narrows the view of the layer it
80
81
  * `extends` (the client's when left out), and its stages run after that
@@ -109,7 +110,7 @@ export type AvConfigMcp = string | {
109
110
  * The `agent` layer: the six layer keys, and `extends`, the layer whose final
110
111
  * view it narrows and whose stages run before its own.
111
112
  */
112
- export type AvConfigAgentLayer<M extends AvAdapterModel = AvAdapterModel, Cfg = AvConfigAny> = AvConfigLayer<M, Cfg, "overlay"> & {
113
+ export type AvConfigAgentLayer<M extends AvAdapterModel = AvAdapterModel, Cfg = AvConfigAny> = AvConfigLayer<M, Cfg, "overlay", "agent"> & {
113
114
  /**
114
115
  * The layer the agent starts from: `"client"` (the default), `"application"`
115
116
  * or `"root"`. The agent never widens it.
@@ -2,8 +2,10 @@ import type { AvAdapterModel } from "../adapters/adapter-model.js";
2
2
  import type { AvAdapterFieldKey } from "../adapters/adapter-resource.js";
3
3
  import type { AvZCheck } from "../avz/avz-check.registry.js";
4
4
  import type { AvOperationFamily } from "../operations/operation-identity.js";
5
- import type { AvStageArguments } from "../runtime/pipeline.js";
5
+ import type { AvPreComputeStageArguments, AvStageArguments } from "../runtime/pipeline.js";
6
6
  import type { AvConfigAny } from "./any-framework-config.js";
7
+ import type { AvPreComputeLift } from "./computed-fields.js";
8
+ import type { AvConfigLayerName } from "./config-layer.js";
7
9
  import type { AvEffectiveFieldKey } from "./effective-fields.js";
8
10
  import type { AvRelationFieldPipeline, AvScalarFieldPipeline } from "./field-pipeline-config.js";
9
11
  import type { AvConfigAddedFieldDefinition, AvConfigFieldDefinition, AvConfigKnownFieldDefinition, AvConfigResourceKey } from "./framework-field-definition.js";
@@ -14,12 +16,14 @@ import type { AvPipeline, AvTransactionPipeline } from "./pipeline-config.js";
14
16
  */
15
17
  export type AvConfigLayerKind = "root" | "overlay";
16
18
  /** One operation variant's level: its stages and `forceTransaction`. */
17
- export type AvConfigVariant<M extends AvAdapterModel = AvAdapterModel, R extends string = AvConfigResourceKey<M>, F extends AvOperationFamily = AvOperationFamily, V extends string = string, A = NoInfer<AvStageArguments<M, R, F, V>>> = {
19
+ export type AvConfigVariant<M extends AvAdapterModel = AvAdapterModel, R extends string = AvConfigResourceKey<M>, F extends AvOperationFamily = AvOperationFamily, V extends string = string, A = NoInfer<AvStageArguments<M, R, F, V>>, PreCompute = NoInfer<AvPreComputeStageArguments<M, R, F, V>>> = {
18
20
  /**
19
21
  * Stages that run for this one operation: at a variant, `ctx.$args` (and a
20
- * pipe's arguments) are typed as the operation's arguments.
22
+ * pipe's arguments) are typed as the operation's arguments; in a guard, a
23
+ * pipe or a filter a create may lack the fields `compute.create` fills
24
+ * (write compute runs after them).
21
25
  */
22
- readonly pipelines?: AvPipeline<NoInfer<M>, R, F, V, A>;
26
+ readonly pipelines?: AvPipeline<NoInfer<M>, R, F, V, A, PreCompute>;
23
27
  /** Runs a plain call of this operation as a one-step transaction. */
24
28
  readonly forceTransaction?: boolean;
25
29
  };
@@ -31,12 +35,12 @@ type FamilyStageVariant<F extends AvOperationFamily, V extends string> = F exten
31
35
  */
32
36
  export type AvConfigFamily<M extends AvAdapterModel = AvAdapterModel, Variants = {
33
37
  readonly [V in "first" | "unique" | "many" | "count" | "one"]?: unknown;
34
- }, R extends string = AvConfigResourceKey<M>, F extends AvOperationFamily = AvOperationFamily> = AvConfigVariant<M, R, F, FamilyStageVariant<F, Extract<keyof NonNullable<Variants>, string>>, unknown> & {
35
- readonly [V in Extract<keyof NonNullable<Variants>, string>]?: AvConfigVariant<M, R, F, V> | undefined;
38
+ }, R extends string = AvConfigResourceKey<M>, F extends AvOperationFamily = AvOperationFamily, Layer extends AvConfigLayerName = "root"> = AvConfigVariant<M, R, F, FamilyStageVariant<F, Extract<keyof NonNullable<Variants>, string>>, unknown, unknown> & {
39
+ readonly [V in Extract<keyof NonNullable<Variants>, string>]?: AvConfigVariant<M, R, F, V, NoInfer<AvStageArguments<M, R, F, V>>, NoInfer<AvPreComputeStageArguments<M, R, F, V, AvPreComputeLift<M, Layer>>>> | undefined;
36
40
  };
37
41
  /** A Resource's families, as the adapter model offers them, each with its level. */
38
- export type AvConfigOperations<M extends AvAdapterModel = AvAdapterModel, R extends AvConfigResourceKey<M> = AvConfigResourceKey<M>> = {
39
- readonly [F in Extract<keyof M["resources"][R]["operations"], AvOperationFamily>]?: AvConfigFamily<M, M["resources"][R]["operations"][F], R, F>;
42
+ export type AvConfigOperations<M extends AvAdapterModel = AvAdapterModel, R extends AvConfigResourceKey<M> = AvConfigResourceKey<M>, Layer extends AvConfigLayerName = "root"> = {
43
+ readonly [F in Extract<keyof M["resources"][R]["operations"], AvOperationFamily>]?: AvConfigFamily<M, M["resources"][R]["operations"][F], R, F, Layer>;
40
44
  };
41
45
  /** A Resource's transaction level. */
42
46
  export type AvConfigResourceTransactions<M extends AvAdapterModel = AvAdapterModel> = {
@@ -99,18 +103,20 @@ export type AvConfigResourceFields<in out M extends AvAdapterModel = AvAdapterMo
99
103
  readonly [F in AvEffectiveFieldKey<M, Cfg, R>]?: Kind extends "root" ? RootFieldConfigFor<M, Cfg, R, F> : OverlayFieldConfigFor<M, Cfg, R, F>;
100
104
  };
101
105
  /** One Resource's tree: its stages, operations, transactions and fields. */
102
- export type AvConfigResource<in out M extends AvAdapterModel = AvAdapterModel, in out Cfg = AvConfigAny, in out R extends AvConfigResourceKey<M> = AvConfigResourceKey<M>, Kind extends AvConfigLayerKind = "root"> = {
106
+ export type AvConfigResource<in out M extends AvAdapterModel = AvAdapterModel, in out Cfg = AvConfigAny, in out R extends AvConfigResourceKey<M> = AvConfigResourceKey<M>, Kind extends AvConfigLayerKind = "root", Layer extends AvConfigLayerName = LayerOfKind<Kind>> = {
103
107
  /** Stages that run for every operation of this Resource. */
104
108
  readonly pipelines?: AvPipeline<NoInfer<M>, R>;
105
109
  /** Per family, and per variant under its family. */
106
- readonly operations?: AvConfigOperations<M, R>;
110
+ readonly operations?: AvConfigOperations<M, R, Layer>;
107
111
  /** Stages that run once per transaction with a top-level step on this Resource. */
108
112
  readonly transactions?: AvConfigResourceTransactions<M>;
109
113
  /** Per field: its definition (root only) and its stages. */
110
114
  readonly fields?: AvConfigResourceFields<M, Cfg, R, Kind>;
111
115
  };
112
116
  /** The `resources` tree of one layer, keyed by the adapter's Resource names. */
113
- export type AvConfigResources<in out M extends AvAdapterModel = AvAdapterModel, in out Cfg = AvConfigAny, in out Kind extends AvConfigLayerKind = "root"> = {
114
- readonly [R in AvConfigResourceKey<M>]?: AvConfigResource<M, Cfg, R, Kind>;
117
+ export type AvConfigResources<in out M extends AvAdapterModel = AvAdapterModel, in out Cfg = AvConfigAny, in out Kind extends AvConfigLayerKind = "root", in out Layer extends AvConfigLayerName = LayerOfKind<Kind>> = {
118
+ readonly [R in AvConfigResourceKey<M>]?: AvConfigResource<M, Cfg, R, Kind, Layer>;
115
119
  };
120
+ /** The layers a tree of kind `Kind` may be written in, when it names none. */
121
+ export type LayerOfKind<Kind extends AvConfigLayerKind> = Kind extends "root" ? "root" : Exclude<AvConfigLayerName, "root">;
116
122
  export {};
@@ -6,11 +6,11 @@ import type { AvConfigResourceKey } from "./framework-field-definition.js";
6
6
  * Pipeline registrations for one level of the configuration: a layer, a
7
7
  * Resource, a family or a variant. See {@link AvContext}.
8
8
  */
9
- export type AvPipeline<M extends AvAdapterModel = AvAdapterModel, R extends string = AvConfigResourceKey<M>, F extends AvOperationFamily = AvOperationFamily, V extends string = string, A = unknown> = {
9
+ export type AvPipeline<M extends AvAdapterModel = AvAdapterModel, R extends string = AvConfigResourceKey<M>, F extends AvOperationFamily = AvOperationFamily, V extends string = string, A = unknown, PreCompute = A> = {
10
10
  /** Run first; a guard returning `false` denies the operation with `A4001`. */
11
- readonly guards?: readonly AvGuard<M, R, F, V, A>[];
11
+ readonly guards?: readonly AvGuard<M, R, F, V, PreCompute>[];
12
12
  /** Run in order on the arguments; a pipe may return replacement arguments. */
13
- readonly pipes?: readonly AvPipe<M, R, F, V, A>[];
13
+ readonly pipes?: readonly AvPipe<M, R, F, V, PreCompute>[];
14
14
  /**
15
15
  * Run around the operation, inside every level's interceptors: `before`
16
16
  * hooks outer to inner, `after` hooks inner to outer.
@@ -22,7 +22,7 @@ export type AvPipeline<M extends AvAdapterModel = AvAdapterModel, R extends stri
22
22
  /** Wrap everything below this level; each calls `next()` to continue. */
23
23
  readonly interceptors?: readonly AvInterceptor<M, R, F, V, A>[];
24
24
  /** Turn a thrown error into a {@link AvError} outcome. */
25
- readonly filters?: readonly AvFilter<M, R, F, V, A>[];
25
+ readonly filters?: readonly AvFilter<M, R, F, V, PreCompute>[];
26
26
  };
27
27
  /**
28
28
  * A Resource's transaction stages: they run once per transaction with a
@@ -1,5 +1,14 @@
1
1
  /** The operators a scalar field can be filtered with. */
2
2
  export type AvScalarFilterOperator = "equals" | "not" | "in" | "notIn" | "lt" | "lte" | "gt" | "gte" | "contains" | "startsWith" | "endsWith" | "mode" | "has" | "hasEvery" | "hasSome" | "isEmpty" | "path" | "stringContains" | "stringStartsWith" | "stringEndsWith" | "arrayContains" | "arrayStartsWith" | "arrayEndsWith";
3
+ /**
4
+ * The case-sensitivity a text filter's `mode` asks for. `"default"` is whatever
5
+ * the database's own comparison does and is always available; `"sensitive"` and
6
+ * `"insensitive"` are an explicit promise, available on a field only where its
7
+ * `filterModes` lists them.
8
+ */
9
+ export declare const FILTER_MODES: readonly ["default", "sensitive", "insensitive"];
10
+ /** @see FILTER_MODES, the axis this union is derived from. */
11
+ export type ScalarFilterMode = (typeof FILTER_MODES)[number];
3
12
  /** What an update can do to a scalar value besides setting it. */
4
13
  export type AvScalarMutationDirective = "$increment" | "$decrement" | "$multiply" | "$divide" | "$push" | "$unset";
5
14
  /** How a relation can be filtered on. */
@@ -24,6 +33,6 @@ export type AvProjectionScope = (typeof PROJECTION_SCOPES)[number];
24
33
  * not the operation that carries it. The write counterpart of
25
34
  * {@link AvProjectionScope}.
26
35
  */
27
- export declare const WRITE_SCOPES: readonly ["nested", "bulkWrite"];
36
+ export declare const WRITE_SCOPES: readonly ["nested", "bulkWrite", "loopback"];
28
37
  /** @see WRITE_SCOPES, the axis this union is derived from. */
29
38
  export type AvWriteScope = (typeof WRITE_SCOPES)[number];
@@ -1,3 +1,4 @@
1
+ export const FILTER_MODES = ["default", "sensitive", "insensitive"];
1
2
  export const PROJECTION_SCOPES = [
2
3
  "record",
3
4
  "bulkWrite",
@@ -5,4 +6,5 @@ export const PROJECTION_SCOPES = [
5
6
  export const WRITE_SCOPES = [
6
7
  "nested",
7
8
  "bulkWrite",
9
+ "loopback",
8
10
  ];
@@ -197,6 +197,24 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
197
197
  readonly minimum: 0;
198
198
  readonly unique: false;
199
199
  };
200
+ readonly filterModes: {
201
+ readonly is: "list";
202
+ readonly item: {
203
+ readonly is: "literal";
204
+ readonly values: readonly ["default", "sensitive", "insensitive"];
205
+ };
206
+ readonly minimum: 0;
207
+ readonly unique: false;
208
+ };
209
+ readonly pathFilterModes: {
210
+ readonly is: "list";
211
+ readonly item: {
212
+ readonly is: "literal";
213
+ readonly values: readonly ["default", "sensitive", "insensitive"];
214
+ };
215
+ readonly minimum: 0;
216
+ readonly unique: false;
217
+ };
200
218
  readonly order: {
201
219
  readonly is: "boolean";
202
220
  };
@@ -613,7 +631,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
613
631
  readonly is: "list";
614
632
  readonly item: {
615
633
  readonly is: "literal";
616
- readonly values: readonly ["nested", "bulkWrite"];
634
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
617
635
  };
618
636
  readonly minimum: 1;
619
637
  readonly unique: false;
@@ -648,7 +666,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
648
666
  readonly is: "list";
649
667
  readonly item: {
650
668
  readonly is: "literal";
651
- readonly values: readonly ["nested", "bulkWrite"];
669
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
652
670
  };
653
671
  readonly minimum: 1;
654
672
  readonly unique: false;
@@ -664,7 +682,19 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
664
682
  };
665
683
  };
666
684
  };
667
- readonly optional: Record<never, never>;
685
+ readonly optional: {
686
+ readonly inverse: {
687
+ readonly is: "string";
688
+ };
689
+ readonly referenceFields: {
690
+ readonly is: "list";
691
+ readonly item: {
692
+ readonly is: "string";
693
+ };
694
+ readonly minimum: 1;
695
+ readonly unique: false;
696
+ };
697
+ };
668
698
  };
669
699
  };
670
700
  };
@@ -706,7 +736,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
706
736
  readonly optional: {
707
737
  readonly write: {
708
738
  readonly is: "literal";
709
- readonly values: readonly ["nested", "bulkWrite"];
739
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
710
740
  };
711
741
  };
712
742
  }, {
@@ -714,7 +744,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
714
744
  readonly required: {
715
745
  readonly write: {
716
746
  readonly is: "literal";
717
- readonly values: readonly ["nested", "bulkWrite"];
747
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
718
748
  };
719
749
  };
720
750
  readonly optional: {
@@ -741,7 +771,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
741
771
  readonly optional: {
742
772
  readonly write: {
743
773
  readonly is: "literal";
744
- readonly values: readonly ["nested", "bulkWrite"];
774
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
745
775
  };
746
776
  };
747
777
  }, {
@@ -749,7 +779,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
749
779
  readonly required: {
750
780
  readonly write: {
751
781
  readonly is: "literal";
752
- readonly values: readonly ["nested", "bulkWrite"];
782
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
753
783
  };
754
784
  };
755
785
  readonly optional: {
@@ -776,7 +806,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
776
806
  readonly optional: {
777
807
  readonly write: {
778
808
  readonly is: "literal";
779
- readonly values: readonly ["nested", "bulkWrite"];
809
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
780
810
  };
781
811
  };
782
812
  }, {
@@ -784,7 +814,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
784
814
  readonly required: {
785
815
  readonly write: {
786
816
  readonly is: "literal";
787
- readonly values: readonly ["nested", "bulkWrite"];
817
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
788
818
  };
789
819
  };
790
820
  readonly optional: {
@@ -811,7 +841,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
811
841
  readonly optional: {
812
842
  readonly write: {
813
843
  readonly is: "literal";
814
- readonly values: readonly ["nested", "bulkWrite"];
844
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
815
845
  };
816
846
  };
817
847
  }, {
@@ -819,7 +849,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
819
849
  readonly required: {
820
850
  readonly write: {
821
851
  readonly is: "literal";
822
- readonly values: readonly ["nested", "bulkWrite"];
852
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
823
853
  };
824
854
  };
825
855
  readonly optional: {
@@ -852,7 +882,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
852
882
  readonly optional: {
853
883
  readonly write: {
854
884
  readonly is: "literal";
855
- readonly values: readonly ["nested", "bulkWrite"];
885
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
856
886
  };
857
887
  };
858
888
  }, {
@@ -860,7 +890,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
860
890
  readonly required: {
861
891
  readonly write: {
862
892
  readonly is: "literal";
863
- readonly values: readonly ["nested", "bulkWrite"];
893
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
864
894
  };
865
895
  };
866
896
  readonly optional: {
@@ -887,7 +917,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
887
917
  readonly optional: {
888
918
  readonly write: {
889
919
  readonly is: "literal";
890
- readonly values: readonly ["nested", "bulkWrite"];
920
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
891
921
  };
892
922
  };
893
923
  }, {
@@ -895,7 +925,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
895
925
  readonly required: {
896
926
  readonly write: {
897
927
  readonly is: "literal";
898
- readonly values: readonly ["nested", "bulkWrite"];
928
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
899
929
  };
900
930
  };
901
931
  readonly optional: {
@@ -922,7 +952,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
922
952
  readonly optional: {
923
953
  readonly write: {
924
954
  readonly is: "literal";
925
- readonly values: readonly ["nested", "bulkWrite"];
955
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
926
956
  };
927
957
  };
928
958
  }, {
@@ -930,7 +960,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
930
960
  readonly required: {
931
961
  readonly write: {
932
962
  readonly is: "literal";
933
- readonly values: readonly ["nested", "bulkWrite"];
963
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
934
964
  };
935
965
  };
936
966
  readonly optional: {
@@ -963,7 +993,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
963
993
  readonly optional: {
964
994
  readonly write: {
965
995
  readonly is: "literal";
966
- readonly values: readonly ["nested", "bulkWrite"];
996
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
967
997
  };
968
998
  };
969
999
  }, {
@@ -971,7 +1001,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
971
1001
  readonly required: {
972
1002
  readonly write: {
973
1003
  readonly is: "literal";
974
- readonly values: readonly ["nested", "bulkWrite"];
1004
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
975
1005
  };
976
1006
  };
977
1007
  readonly optional: {
@@ -998,7 +1028,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
998
1028
  readonly optional: {
999
1029
  readonly write: {
1000
1030
  readonly is: "literal";
1001
- readonly values: readonly ["nested", "bulkWrite"];
1031
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1002
1032
  };
1003
1033
  };
1004
1034
  }, {
@@ -1006,7 +1036,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1006
1036
  readonly required: {
1007
1037
  readonly write: {
1008
1038
  readonly is: "literal";
1009
- readonly values: readonly ["nested", "bulkWrite"];
1039
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1010
1040
  };
1011
1041
  };
1012
1042
  readonly optional: {
@@ -1033,7 +1063,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1033
1063
  readonly optional: {
1034
1064
  readonly write: {
1035
1065
  readonly is: "literal";
1036
- readonly values: readonly ["nested", "bulkWrite"];
1066
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1037
1067
  };
1038
1068
  };
1039
1069
  }, {
@@ -1041,7 +1071,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1041
1071
  readonly required: {
1042
1072
  readonly write: {
1043
1073
  readonly is: "literal";
1044
- readonly values: readonly ["nested", "bulkWrite"];
1074
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1045
1075
  };
1046
1076
  };
1047
1077
  readonly optional: {
@@ -1068,7 +1098,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1068
1098
  readonly optional: {
1069
1099
  readonly write: {
1070
1100
  readonly is: "literal";
1071
- readonly values: readonly ["nested", "bulkWrite"];
1101
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1072
1102
  };
1073
1103
  };
1074
1104
  }, {
@@ -1076,7 +1106,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1076
1106
  readonly required: {
1077
1107
  readonly write: {
1078
1108
  readonly is: "literal";
1079
- readonly values: readonly ["nested", "bulkWrite"];
1109
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1080
1110
  };
1081
1111
  };
1082
1112
  readonly optional: {
@@ -1109,7 +1139,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1109
1139
  readonly optional: {
1110
1140
  readonly write: {
1111
1141
  readonly is: "literal";
1112
- readonly values: readonly ["nested", "bulkWrite"];
1142
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1113
1143
  };
1114
1144
  };
1115
1145
  }, {
@@ -1117,7 +1147,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1117
1147
  readonly required: {
1118
1148
  readonly write: {
1119
1149
  readonly is: "literal";
1120
- readonly values: readonly ["nested", "bulkWrite"];
1150
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1121
1151
  };
1122
1152
  };
1123
1153
  readonly optional: {
@@ -1144,7 +1174,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1144
1174
  readonly optional: {
1145
1175
  readonly write: {
1146
1176
  readonly is: "literal";
1147
- readonly values: readonly ["nested", "bulkWrite"];
1177
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1148
1178
  };
1149
1179
  };
1150
1180
  }, {
@@ -1152,7 +1182,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1152
1182
  readonly required: {
1153
1183
  readonly write: {
1154
1184
  readonly is: "literal";
1155
- readonly values: readonly ["nested", "bulkWrite"];
1185
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1156
1186
  };
1157
1187
  };
1158
1188
  readonly optional: {
@@ -1179,7 +1209,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1179
1209
  readonly optional: {
1180
1210
  readonly write: {
1181
1211
  readonly is: "literal";
1182
- readonly values: readonly ["nested", "bulkWrite"];
1212
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1183
1213
  };
1184
1214
  };
1185
1215
  }, {
@@ -1187,7 +1217,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1187
1217
  readonly required: {
1188
1218
  readonly write: {
1189
1219
  readonly is: "literal";
1190
- readonly values: readonly ["nested", "bulkWrite"];
1220
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1191
1221
  };
1192
1222
  };
1193
1223
  readonly optional: {
@@ -1214,7 +1244,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1214
1244
  readonly optional: {
1215
1245
  readonly write: {
1216
1246
  readonly is: "literal";
1217
- readonly values: readonly ["nested", "bulkWrite"];
1247
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1218
1248
  };
1219
1249
  };
1220
1250
  }, {
@@ -1222,7 +1252,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1222
1252
  readonly required: {
1223
1253
  readonly write: {
1224
1254
  readonly is: "literal";
1225
- readonly values: readonly ["nested", "bulkWrite"];
1255
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1226
1256
  };
1227
1257
  };
1228
1258
  readonly optional: {
@@ -1255,7 +1285,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1255
1285
  readonly optional: {
1256
1286
  readonly write: {
1257
1287
  readonly is: "literal";
1258
- readonly values: readonly ["nested", "bulkWrite"];
1288
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1259
1289
  };
1260
1290
  };
1261
1291
  }, {
@@ -1263,7 +1293,7 @@ export declare const CLIENT_CONTRACT_STRUCTURE: {
1263
1293
  readonly required: {
1264
1294
  readonly write: {
1265
1295
  readonly is: "literal";
1266
- readonly values: readonly ["nested", "bulkWrite"];
1296
+ readonly values: readonly ["nested", "bulkWrite", "loopback"];
1267
1297
  };
1268
1298
  };
1269
1299
  readonly optional: {
@@ -1,4 +1,4 @@
1
- import { PROJECTION_SCOPES, WRITE_SCOPES } from "./capability.js";
1
+ import { FILTER_MODES, PROJECTION_SCOPES, WRITE_SCOPES } from "./capability.js";
2
2
  import { AVENTARA_PROTOCOL_VERSION } from "./contract-protocol.js";
3
3
  import { LIFECYCLE_TRAITS } from "./lifecycle-trait.js";
4
4
  import { REFERENCE_WRITE_LIMITS } from "./reference-write-limit.js";
@@ -226,6 +226,8 @@ const SCALAR_FIELD = object({
226
226
  capabilities: object({}, {
227
227
  select: BOOLEAN,
228
228
  filter: list(literal(SCALAR_FILTER_OPERATORS)),
229
+ filterModes: list(literal(FILTER_MODES)),
230
+ pathFilterModes: list(literal(FILTER_MODES)),
229
231
  order: BOOLEAN,
230
232
  orderNulls: BOOLEAN,
231
233
  create: list(literal(SCALAR_MUTATION_DIRECTIVES)),
@@ -255,7 +257,7 @@ const RELATION_FIELD = object({
255
257
  update: RELATION_MUTATION,
256
258
  nestedWriteFilter: literal(["scalar"]),
257
259
  }),
258
- });
260
+ }, { inverse: STRING, referenceFields: nonEmptyList(STRING) });
259
261
  const OPERATION_AVAILABILITY = union(literal([true]), object({ projection: literal(PROJECTION_SCOPES) }, { write: literal(WRITE_SCOPES) }), object({ write: literal(WRITE_SCOPES) }, { projection: literal(PROJECTION_SCOPES) }));
260
262
  const RESOURCE = object({
261
263
  fields: registry({
@@ -7,6 +7,13 @@ export declare class AvCanonicalJsonError extends TypeError {
7
7
  }
8
8
  /** Canonical JSON (RFC 8785) for a JSON-safe value. */
9
9
  export declare function canonicalizeJson(value: unknown): string;
10
+ /**
11
+ * Canonical JSON (RFC 8785) for a value as JSON carries it: a key holding
12
+ * `undefined` is left out, and an array element holding it (or a hole) is
13
+ * `null`, as `JSON.stringify` writes them. Everything else as
14
+ * {@link canonicalizeJson}.
15
+ */
16
+ export declare function canonicalizeWireJson(value: unknown): string;
10
17
  /** One top-level member of a canonical Contract: its key and its value's canonical text. */
11
18
  export type CanonicalContractMember = {
12
19
  readonly key: string;
@@ -1,4 +1,4 @@
1
- import { PROJECTION_SCOPES, WRITE_SCOPES } from "./capability.js";
1
+ import { FILTER_MODES, PROJECTION_SCOPES, WRITE_SCOPES } from "./capability.js";
2
2
  import { LIFECYCLE_TRAITS } from "./lifecycle-trait.js";
3
3
  import { projectionScopeOf, writeScopeOf } from "./resource-operations.js";
4
4
  const PAGINATION_ORDER = ["limit", "offset", "cursor"];
@@ -61,6 +61,12 @@ function normalizeCapabilities(capabilities) {
61
61
  if (Array.isArray(filter)) {
62
62
  normalized.filter = normalizeStringSet(filter);
63
63
  }
64
+ for (const key of ["filterModes", "pathFilterModes"]) {
65
+ const modes = normalized[key];
66
+ if (Array.isArray(modes)) {
67
+ normalized[key] = normalizeStringSet(modes, FILTER_MODES);
68
+ }
69
+ }
64
70
  for (const key of ["create", "update"]) {
65
71
  const value = normalized[key];
66
72
  if (Array.isArray(value)) {
@@ -286,7 +292,7 @@ function canonicalizePrimitive(value, link) {
286
292
  return undefined;
287
293
  }
288
294
  }
289
- function canonicalizeValue(value, link = undefined) {
295
+ function canonicalizeValue(value, link = undefined, undefinedAsJson = false) {
290
296
  const output = [];
291
297
  const stack = [{ kind: "value", value, link }];
292
298
  while (stack.length > 0) {
@@ -310,7 +316,10 @@ function canonicalizeValue(value, link = undefined) {
310
316
  output.push("[");
311
317
  stack.push({ kind: "text", text: "]" });
312
318
  for (let index = current.length - 1; index >= 0; index -= 1) {
313
- if (index in current) {
319
+ if (undefinedAsJson && current[index] === undefined) {
320
+ stack.push({ kind: "text", text: "null" });
321
+ }
322
+ else if (index in current) {
314
323
  stack.push({
315
324
  kind: "value",
316
325
  value: current[index],
@@ -328,7 +337,9 @@ function canonicalizeValue(value, link = undefined) {
328
337
  throw new AvCanonicalJsonError(`non-plain object at ${pathOf(link)} is not canonical JSON`);
329
338
  }
330
339
  const record = current;
331
- const keys = Object.keys(record).sort(compareCodeUnits);
340
+ const keys = Object.keys(record)
341
+ .filter((key) => !undefinedAsJson || record[key] !== undefined)
342
+ .sort(compareCodeUnits);
332
343
  output.push("{");
333
344
  stack.push({ kind: "text", text: "}" });
334
345
  for (let index = keys.length - 1; index >= 0; index -= 1) {
@@ -349,6 +360,9 @@ function canonicalizeValue(value, link = undefined) {
349
360
  export function canonicalizeJson(value) {
350
361
  return canonicalizeValue(value);
351
362
  }
363
+ export function canonicalizeWireJson(value) {
364
+ return canonicalizeValue(value, undefined, true);
365
+ }
352
366
  export function canonicalizeContractMembers(contract) {
353
367
  const record = normalizeContract(contract);
354
368
  return Object.keys(record)