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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +231 -1
  2. package/ERRORS.md +6 -6
  3. package/README.md +76 -12
  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 +13 -0
  8. package/dist/compiler/contract.compiler.d.ts +6 -0
  9. package/dist/compiler/contract.compiler.js +99 -15
  10. package/dist/config/computed-fields.js +2 -9
  11. package/dist/config/config-diagnostic.guidance.js +3 -3
  12. package/dist/config/config.resolver.d.ts +14 -0
  13. package/dist/config/config.resolver.js +31 -0
  14. package/dist/config/config.validator.js +82 -0
  15. package/dist/config/exact-framework-config.d.ts +5 -0
  16. package/dist/config/framework-config.d.ts +30 -1
  17. package/dist/contracts/client-contract-structure.validator.d.ts +8 -0
  18. package/dist/contracts/client-contract-structure.validator.js +6 -1
  19. package/dist/contracts/contract.d.ts +15 -1
  20. package/dist/contracts/field.d.ts +28 -0
  21. package/dist/contracts/scalar-value-type.d.ts +3 -1
  22. package/dist/framework/contract-view.d.ts +41 -10
  23. package/dist/framework/framework-construction.error.d.ts +2 -1
  24. package/dist/framework/framework-construction.error.js +11 -1
  25. package/dist/framework/framework.d.ts +4 -4
  26. package/dist/framework/framework.factory.js +39 -11
  27. package/dist/framework/operation-facade.d.ts +29 -10
  28. package/dist/framework/operation-facade.js +2 -1
  29. package/dist/index.d.ts +10 -4
  30. package/dist/internal.d.ts +2 -2
  31. package/dist/internal.js +2 -0
  32. package/dist/operations/operation-arguments.d.ts +44 -28
  33. package/dist/operations/operation-call.d.ts +9 -5
  34. package/dist/operations/operation-result.d.ts +6 -4
  35. package/dist/operations/operation-validator-core.js +6 -0
  36. package/dist/policy/policy-admission.d.ts +22 -0
  37. package/dist/policy/policy-admission.js +409 -0
  38. package/dist/policy/policy-after-update.runtime.d.ts +29 -0
  39. package/dist/policy/policy-after-update.runtime.js +132 -0
  40. package/dist/policy/policy-condition.d.ts +15 -0
  41. package/dist/policy/policy-condition.js +36 -0
  42. package/dist/policy/policy-engine.d.ts +118 -0
  43. package/dist/policy/policy-engine.js +1 -0
  44. package/dist/policy/policy-nested-write.runtime.d.ts +38 -0
  45. package/dist/policy/policy-nested-write.runtime.js +453 -0
  46. package/dist/policy/policy-read.runtime.d.ts +81 -0
  47. package/dist/policy/policy-read.runtime.js +503 -0
  48. package/dist/policy/policy-request.d.ts +41 -0
  49. package/dist/policy/policy-request.js +63 -0
  50. package/dist/policy/policy-session.d.ts +93 -0
  51. package/dist/policy/policy-session.js +235 -0
  52. package/dist/policy/policy-startup.validator.d.ts +8 -0
  53. package/dist/policy/policy-startup.validator.js +104 -0
  54. package/dist/policy/policy-write.runtime.d.ts +37 -0
  55. package/dist/policy/policy-write.runtime.js +409 -0
  56. package/dist/prebuilt/core-version.generated.d.ts +2 -0
  57. package/dist/prebuilt/core-version.generated.js +1 -0
  58. package/dist/prebuilt/prebuilt-changes.d.ts +28 -0
  59. package/dist/prebuilt/prebuilt-changes.js +65 -0
  60. package/dist/prebuilt/prebuilt-contracts.d.ts +40 -0
  61. package/dist/prebuilt/prebuilt-contracts.emitter.d.ts +16 -0
  62. package/dist/prebuilt/prebuilt-contracts.emitter.js +50 -0
  63. package/dist/prebuilt/prebuilt-contracts.js +1 -0
  64. package/dist/prebuilt/prebuilt-contracts.loader.d.ts +21 -0
  65. package/dist/prebuilt/prebuilt-contracts.loader.js +77 -0
  66. package/dist/prebuilt/prebuilt-inputs.fingerprint.d.ts +16 -0
  67. package/dist/prebuilt/prebuilt-inputs.fingerprint.js +192 -0
  68. package/dist/protocol/absent-route.responder.d.ts +4 -4
  69. package/dist/protocol/http-request.decoder.d.ts +2 -2
  70. package/dist/protocol/http-request.reader.d.ts +2 -2
  71. package/dist/protocol/protocol-headers.d.ts +3 -3
  72. package/dist/runtime/computed-read-runtime.d.ts +6 -1
  73. package/dist/runtime/computed-read-runtime.js +226 -52
  74. package/dist/runtime/context-executor.runtime.d.ts +2 -2
  75. package/dist/runtime/context-executor.runtime.js +4 -2
  76. package/dist/runtime/create-requirement.js +1 -1
  77. package/dist/runtime/diagnostics-reporter.d.ts +5 -5
  78. package/dist/runtime/execution-options.d.ts +8 -0
  79. package/dist/runtime/framework-warning.emitter.d.ts +6 -0
  80. package/dist/runtime/framework-warning.emitter.js +8 -0
  81. package/dist/runtime/level-lifecycle.runtime.js +3 -2
  82. package/dist/runtime/operation-code.guidance.js +3 -3
  83. package/dist/runtime/operation-request.d.ts +16 -9
  84. package/dist/runtime/operation-runtime.d.ts +15 -7
  85. package/dist/runtime/operation-runtime.js +139 -14
  86. package/dist/runtime/owned-execution.registry.d.ts +2 -2
  87. package/dist/runtime/readonly-value.d.ts +5 -1
  88. package/dist/runtime/readonly-value.js +67 -28
  89. package/dist/runtime/referential-action.d.ts +1 -1
  90. package/dist/transactions/sql-statement.d.ts +2 -2
  91. package/dist/transactions/transaction-plan-assembler.d.ts +2 -2
  92. package/dist/transactions/transaction-plan-validator.d.ts +5 -5
  93. package/dist/transactions/transaction-request.d.ts +8 -8
  94. package/dist/transactions/transaction-runtime.d.ts +5 -2
  95. package/dist/transactions/transaction-runtime.js +33 -6
  96. package/package.json +2 -2
@@ -114,7 +114,7 @@ type FieldSlotReferences<C extends AvContract, K extends AvResourceKey<C>, F ext
114
114
  * operand but `mode`, `isEmpty`, `path` and the `json` ones may be a `$ref` of
115
115
  * the shape it holds (`References`).
116
116
  */
117
- type ScalarFilterOperands<Value, Atom, Json, References extends Readonly<Record<TransactionSlotShape, unknown>>, Operator extends AvScalarFilterOperator, Mode extends ScalarFilterMode, PathMode extends ScalarFilterMode, LevelMode extends ScalarFilterMode> = {
117
+ export type AvScalarFilterOperands<Value, Atom, Json, References extends Readonly<Record<TransactionSlotShape, unknown>>, Operator extends AvScalarFilterOperator, Mode extends ScalarFilterMode, PathMode extends ScalarFilterMode, LevelMode extends ScalarFilterMode> = {
118
118
  equals: Value | References["value"];
119
119
  not: NegatedValue<Value, References, Operator> | ScalarFilterOperators<Value, Atom, Json, References, Operator, Mode, PathMode>;
120
120
  in: readonly Atom[] | References["entries"];
@@ -149,8 +149,8 @@ type ScalarFilterOperands<Value, Atom, Json, References extends Readonly<Record<
149
149
  type ScalarFilterOperators<Value, Atom, Json, References extends Readonly<Record<TransactionSlotShape, unknown>>, Operator extends AvScalarFilterOperator, Mode extends ScalarFilterMode, PathMode extends ScalarFilterMode> = ScalarFilterLevel<ReadonlyOperands<Value, Atom, Json, References, Operator, Mode, PathMode, Mode>, Operator, Mode, NegatedValue<Value, References, Operator>, "path" extends Operator ? {
150
150
  readonly path?: never;
151
151
  } : unknown> | ("path" extends Operator ? ScalarFilterOperatorsAtPath<ReadonlyOperands<Value, Atom, Json, References, Operator, Mode, PathMode, PathMode>, Operator, PathMode, NegatedValue<Value, References, Operator>> : never);
152
- /** {@link ScalarFilterOperands}, each operand read-only. */
153
- type ReadonlyOperands<Value, Atom, Json, References extends Readonly<Record<TransactionSlotShape, unknown>>, Operator extends AvScalarFilterOperator, Mode extends ScalarFilterMode, PathMode extends ScalarFilterMode, LevelMode extends ScalarFilterMode> = Readonly<ScalarFilterOperands<Value, Atom, Json, References, Operator, Mode, PathMode, LevelMode>>;
152
+ /** {@link AvScalarFilterOperands}, each operand read-only. */
153
+ type ReadonlyOperands<Value, Atom, Json, References extends Readonly<Record<TransactionSlotShape, unknown>>, Operator extends AvScalarFilterOperator, Mode extends ScalarFilterMode, PathMode extends ScalarFilterMode, LevelMode extends ScalarFilterMode> = Readonly<AvScalarFilterOperands<Value, Atom, Json, References, Operator, Mode, PathMode, LevelMode>>;
154
154
  /** The operators of a level that compare something: all but `mode` and `path`. */
155
155
  type ComparingOperator<Operator extends AvScalarFilterOperator> = Exclude<Operator, "mode" | "path">;
156
156
  /** `not`'s value arm: equality negated, offered only where `equals` is. */
@@ -224,7 +224,7 @@ export type AvWhereInput<C extends AvContract, K extends AvResourceKey<C>, Forms
224
224
  AND?: readonly AvWhereInput<C, K, Forms, ReferenceForms>[];
225
225
  OR?: readonly AvWhereInput<C, K, Forms, ReferenceForms>[];
226
226
  NOT?: AvWhereInput<C, K, Forms, ReferenceForms>;
227
- } & ScalarWhereFields<C, K, Forms, ReferenceForms> & RelationWhereFields<C, K, Forms, ReferenceForms>>;
227
+ }> & ScalarWhereFields<C, K, Forms, ReferenceForms> & RelationWhereFields<C, K, Forms, ReferenceForms>;
228
228
  type ActiveIdentifier<C extends AvContract, K extends AvResourceKey<C>> = C["resources"][K]["identifiers"][number];
229
229
  type IdentifierObject<C extends AvContract, K extends AvResourceKey<C>, I extends readonly string[], Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
230
230
  [F in Extract<I[number], AvFieldKey<C, K>>]: ScalarValueAt<C, K, F, Forms> | SlotReference<C, K, F, ReferenceForms, "nonNullValue">;
@@ -335,7 +335,7 @@ type IncludeRelationProjectionEntry<C extends AvContract, K extends AvResourceKe
335
335
  * One entry of a `select` argument, at one projection position. The default is
336
336
  * the unrestricted position.
337
337
  */
338
- export type AvProjectionEntry<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvProjectionScope = UnrestrictedProjection, AllowCount extends boolean = false, Forms extends ScalarForms = UnstatedForms> = SelectableScalarKey<C, K, Scope> | SelectableRelationKey<C, K, Scope> | SelectRelationProjectionEntry<C, K, Scope, Forms> | (AllowCount extends true ? "$count" : never);
338
+ export type AvProjectionEntry<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvProjectionScope = UnrestrictedProjection, AllowCount extends boolean = false, Forms extends ScalarForms = UnstatedForms> = SelectableScalarKey<C, K, Scope> | SelectableRelationKey<C, K, Scope> | SelectRelationProjectionEntry<C, K, Scope, Forms> | "$defaults" | (AllowCount extends true ? "$count" : never);
339
339
  /** A `select` argument: the fields to return. */
340
340
  export type AvSelectInput<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvProjectionScope = UnrestrictedProjection, AllowCount extends boolean = false, Forms extends ScalarForms = UnstatedForms> = readonly AvProjectionEntry<C, K, Scope, AllowCount, Forms>[];
341
341
  /** An `include` argument: the relations to return with each row. */
@@ -356,18 +356,18 @@ type ManyOrOne<C extends AvContract, K extends AvResourceKey<C>, F extends Relat
356
356
  * A `where` of plain fields: each scalar field's filter, combined with
357
357
  * `AND`/`OR`/`NOT`, and no relation filter at any depth.
358
358
  */
359
- type ScalarOnlyWhereInput<C extends AvContract, K extends AvResourceKey<C>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
360
- AND?: readonly ScalarOnlyWhereInput<C, K, Forms, ReferenceForms>[];
361
- OR?: readonly ScalarOnlyWhereInput<C, K, Forms, ReferenceForms>[];
362
- NOT?: ScalarOnlyWhereInput<C, K, Forms, ReferenceForms>;
363
- } & ScalarWhereFields<C, K, Forms, ReferenceForms>>;
359
+ export type AvScalarWhereInput<C extends AvContract, K extends AvResourceKey<C>, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never> = Readonly<{
360
+ AND?: readonly AvScalarWhereInput<C, K, Forms, ReferenceForms>[];
361
+ OR?: readonly AvScalarWhereInput<C, K, Forms, ReferenceForms>[];
362
+ NOT?: AvScalarWhereInput<C, K, Forms, ReferenceForms>;
363
+ }> & ScalarWhereFields<C, K, Forms, ReferenceForms>;
364
364
  /**
365
365
  * The `where` of a nested `$update` or `$delete` through relation `F`: plain fields
366
366
  * only where the relation states `nestedWriteFilter: "scalar"`, any filter otherwise.
367
367
  */
368
368
  type NestedWriteWhereInput<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = CapabilitiesOf<C, K, F> extends {
369
369
  readonly nestedWriteFilter: "scalar";
370
- } ? ScalarOnlyWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms> : AvWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>;
370
+ } ? AvScalarWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms> : AvWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>;
371
371
  type ConnectOrCreateEntry<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Readonly<{
372
372
  where: AvUniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>;
373
373
  create: AvCreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms, readonly [K, F]>;
@@ -397,15 +397,14 @@ type ToManyUpsertEntry<C extends AvContract, K extends AvResourceKey<C>, F exten
397
397
  update: AvUpdateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms, readonly [K, F]>;
398
398
  }>;
399
399
  type RelationDirectiveValue<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Directive extends AvRelationMutationDirective, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = Directive extends "$create" ? ManyOrOne<C, K, F, AvCreateDataInput<C, RelationTarget<C, K, F>, UnrestrictedWrite, Forms, ReferenceForms, readonly [K, F]>> : Directive extends "$connect" ? ManyOrOne<C, K, F, AvUniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>> : Directive extends "$connectOrCreate" ? ManyOrOne<C, K, F, ConnectOrCreateEntry<C, K, F, Forms, ReferenceForms>> : Directive extends "$disconnect" ? RelationCardinality<C, K, F> extends "one" ? true : AvUniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms> | readonly AvUniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>[] : Directive extends "$set" ? RelationCardinality<C, K, F> extends "one" ? AvUniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms> | null : readonly AvUniqueWhereInput<C, RelationTarget<C, K, F>, Forms, ReferenceForms>[] : Directive extends "$update" ? RelationCardinality<C, K, F> extends "one" ? ToOneUpdateEntry<C, K, F, Forms, ReferenceForms> : ManyOrOne<C, K, F, ToManyUpdateEntry<C, K, F, Forms, ReferenceForms>> : Directive extends "$delete" ? RelationCardinality<C, K, F> extends "one" ? ToOneDeleteEntry<C, K, F, Forms, ReferenceForms> : ManyOrOne<C, K, F, ToManyDeleteEntry<C, K, F, Forms, ReferenceForms>> : Directive extends "$upsert" ? RelationCardinality<C, K, F> extends "one" ? ToOneUpsertEntry<C, K, F, Forms, ReferenceForms> : ManyOrOne<C, K, F, ToManyUpsertEntry<C, K, F, Forms, ReferenceForms>> : never;
400
- declare const NO_ADVERTISED_MEMBER: unique symbol;
401
400
  /**
402
401
  * A write member that advertises nothing: it accepts `{}` and refuses every key.
403
402
  */
404
- type NoAdvertisedMember = {
405
- readonly [NO_ADVERTISED_MEMBER]?: never;
406
- };
407
- /** `Write`, or {@link NoAdvertisedMember} when `Write` has no keys at all. */
408
- type RefuseEveryKeyWhenEmpty<Write> = [keyof Write] extends [never] ? NoAdvertisedMember : Write;
403
+ export interface AvNoAdvertisedMember {
404
+ readonly [Symbol.unscopables]?: never;
405
+ }
406
+ /** `Write`, or {@link AvNoAdvertisedMember} when `Write` has no keys at all. */
407
+ type RefuseEveryKeyWhenEmpty<Write> = [keyof Write] extends [never] ? AvNoAdvertisedMember : Write;
409
408
  type RelationMutationActionFor<C extends AvContract, K extends AvResourceKey<C>, F extends RelationFieldKeyOf<C, K>, Stage extends "create" | "update", Scope extends AvWriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms> = RefuseEveryKeyWhenEmpty<Readonly<Partial<{
410
409
  [Directive in Extract<CapabilityTokens<C, K, F, Stage, Scope>, AvRelationMutationDirective>]: RelationDirectiveValue<C, K, F, Directive, Forms, ReferenceForms>;
411
410
  }>>>;
@@ -432,14 +431,23 @@ type OneDirective<Tokens extends AvScalarMutationDirective, C extends AvContract
432
431
  /**
433
432
  * Each writable scalar takes its value under `Forms`, or a directive object of
434
433
  * the directives it advertises at this stage — or, in a transaction plan's
435
- * top-level data, a `$ref` to a source of the same type.
436
- */
437
- type ScalarMutationFields<C extends AvContract, K extends AvResourceKey<C>, Stage extends "create" | "update", Scope extends AvWriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms, Via extends ParentEdge = never> = Readonly<{
438
- [F in Exclude<WritableScalarKey<C, K, Stage, Scope>, LoopbackRefused<C, K, Stage, Via>>]?: ScalarValueAt<C, K, F, Forms> | ScalarMutationActionFor<C, K, F, Stage, Scope, Forms> | SlotReference<C, K, F, ReferenceForms, "value">;
439
- }>;
440
- type RelationMutationFields<C extends AvContract, K extends AvResourceKey<C>, Stage extends "create" | "update", Scope extends AvWriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms, Via extends ParentEdge = never> = Readonly<{
441
- [F in Exclude<WritableRelationKey<C, K, Stage, Scope>, LoopbackRefused<C, K, Stage, Via>>]?: RelationMutationActionFor<C, K, F & RelationFieldKeyOf<C, K>, Stage, Scope, Forms, ReferenceForms>;
442
- }>;
434
+ * top-level data, a `$ref` to a source of the same type. A field a create must
435
+ * write (`RequiredWriteKey`) is required.
436
+ */
437
+ type ScalarMutationFields<C extends AvContract, K extends AvResourceKey<C>, Stage extends "create" | "update", Scope extends AvWriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms, Via extends ParentEdge = never, Keys extends AvFieldKey<C, K> = Exclude<WritableScalarKey<C, K, Stage, Scope>, LoopbackRefused<C, K, Stage, Via>>, Required extends Keys = Extract<Keys, RequiredWriteKey<C, K, Stage, Scope, Via>>> = Readonly<([Required] extends [never] ? unknown : {
438
+ [F in Required]: ScalarValueAt<C, K, F, Forms> | ScalarMutationActionFor<C, K, F, Stage, Scope, Forms> | SlotReference<C, K, F, ReferenceForms, "value">;
439
+ }) & ([Exclude<Keys, Required>] extends [never] ? unknown : {
440
+ [F in Exclude<Keys, Required>]?: ScalarValueAt<C, K, F, Forms> | ScalarMutationActionFor<C, K, F, Stage, Scope, Forms> | SlotReference<C, K, F, ReferenceForms, "value">;
441
+ })>;
442
+ /**
443
+ * Each writable relation takes the directive object it advertises at this
444
+ * stage. A relation a create must write (`RequiredWriteKey`) is required.
445
+ */
446
+ type RelationMutationFields<C extends AvContract, K extends AvResourceKey<C>, Stage extends "create" | "update", Scope extends AvWriteScope, Forms extends ScalarForms, ReferenceForms extends ScalarForms, Via extends ParentEdge = never, Keys extends AvFieldKey<C, K> = Exclude<WritableRelationKey<C, K, Stage, Scope>, LoopbackRefused<C, K, Stage, Via>>, Required extends Keys = Extract<Keys, RequiredWriteKey<C, K, Stage, Scope, Via>>> = Readonly<([Required] extends [never] ? unknown : {
447
+ [F in Required]: RelationMutationActionFor<C, K, F & RelationFieldKeyOf<C, K>, Stage, Scope, Forms, ReferenceForms>;
448
+ }) & ([Exclude<Keys, Required>] extends [never] ? unknown : {
449
+ [F in Exclude<Keys, Required>]?: RelationMutationActionFor<C, K, F & RelationFieldKeyOf<C, K>, Stage, Scope, Forms, ReferenceForms>;
450
+ })>;
443
451
  /** A relation edge a nested create is reached through: `[parent, relation]`. */
444
452
  type ParentEdge = readonly [string, string];
445
453
  /** The other end of `Via`'s relation, as the Contract pairs it; `never` when it does not. */
@@ -497,13 +505,21 @@ type GroupPresence<Group, Scalars, Relations, Supplied> = Group extends readonly
497
505
  }) : Present<Relation> : Present<References[number]> : unknown : unknown;
498
506
  /** Every group of a `oneOf` tuple, each one's presence intersected. */
499
507
  type GroupsPresence<Groups, Scalars, Relations, Supplied> = Groups extends readonly [infer Group, ...infer Rest] ? GroupPresence<Group, Scalars, Relations, Supplied> & GroupsPresence<Rest, Scalars, Relations, Supplied> : unknown;
508
+ /**
509
+ * The names a create of `K` at `Scope` must write: every `required` name it can
510
+ * write there, less what the parent supplies through `Via`. `never` for an
511
+ * update, and where the Contract states nothing.
512
+ */
513
+ type RequiredWriteKey<C extends AvContract, K extends AvResourceKey<C>, Stage extends "create" | "update", Scope extends AvWriteScope, Via> = Stage extends "create" ? [CreateRequirementsAt<C, K>] extends [never] ? never : CreateRequirementsAt<C, K> extends infer Requirements ? string extends RequirementNames<Requirements, "required"> ? never : Exclude<Extract<RequirementNames<Requirements, "required">, WritableScalarKey<C, K, "create", Scope> | WritableRelationKey<C, K, "create", Scope>>, SuppliedThrough<Requirements, Via>> : never : never;
514
+ /** The members a create's two halves hold at `Scope`, reached through `Via`. */
515
+ type HeldCreateKey<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope, Via> = Exclude<WritableScalarKey<C, K, "create", Scope> | WritableRelationKey<C, K, "create", Scope>, LoopbackRefused<C, K, "create", Via>>;
500
516
  /**
501
517
  * What a create of Resource `K` at write position `Scope` must and must not
502
518
  * write: every `required` name it can write, and one side of every `oneOf`
503
519
  * group — less what the parent supplies when the create is nested through
504
520
  * `Via`. `unknown` (no constraint) when the Contract states nothing.
505
521
  */
506
- type CreateRequirementPresence<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope, Via> = [CreateRequirementsAt<C, K>] extends [never] ? unknown : CreateRequirementsAt<C, K> extends infer Requirements ? string extends RequirementNames<Requirements, "required"> ? unknown : Present<Exclude<Extract<RequirementNames<Requirements, "required">, WritableScalarKey<C, K, "create", Scope> | WritableRelationKey<C, K, "create", Scope>>, SuppliedThrough<Requirements, Via>>> & (Requirements extends {
522
+ type CreateRequirementPresence<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope, Via> = [CreateRequirementsAt<C, K>] extends [never] ? unknown : CreateRequirementsAt<C, K> extends infer Requirements ? string extends RequirementNames<Requirements, "required"> ? unknown : Present<Exclude<RequiredWriteKey<C, K, "create", Scope, Via>, HeldCreateKey<C, K, Scope, Via>>> & (Requirements extends {
507
523
  readonly oneOf?: infer Groups;
508
524
  } ? GroupsPresence<Groups, WritableScalarKey<C, K, "create", Scope>, WritableRelationKey<C, K, "create", Scope>, SuppliedThrough<Requirements, Via>> : unknown) : unknown;
509
525
  /**
@@ -518,12 +534,12 @@ type CreateRequirementPresence<C extends AvContract, K extends AvResourceKey<C>,
518
534
  * reference fields — never both. `Via` is the `[parent, relation]` a nested
519
535
  * create is reached through: what that parent supplies is not required.
520
536
  */
521
- export type AvCreateDataInput<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope = UnrestrictedWrite, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never, Via extends ParentEdge = never> = RefuseEveryKeyWhenEmpty<Readonly<ScalarMutationFields<C, K, "create", Scope, Forms, ReferenceForms, Via> & RelationMutationFields<C, K, "create", Scope, Forms, ReferenceForms, Via>>> & CreateRequirementPresence<C, K, Scope, Via>;
537
+ export type AvCreateDataInput<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope = UnrestrictedWrite, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never, Via extends ParentEdge = never> = RefuseEveryKeyWhenEmpty<ScalarMutationFields<C, K, "create", Scope, Forms, ReferenceForms, Via>> & RefuseEveryKeyWhenEmpty<RelationMutationFields<C, K, "create", Scope, Forms, ReferenceForms, Via>> & CreateRequirementPresence<C, K, Scope, Via>;
522
538
  /**
523
539
  * An `update` data argument, at one write position. See {@link AvCreateDataInput};
524
540
  * `Via` is the `[parent, relation]` a nested update is reached through.
525
541
  */
526
- export type AvUpdateDataInput<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope = UnrestrictedWrite, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never, Via extends ParentEdge = never> = RefuseEveryKeyWhenEmpty<Readonly<ScalarMutationFields<C, K, "update", Scope, Forms, ReferenceForms, Via> & RelationMutationFields<C, K, "update", Scope, Forms, ReferenceForms, Via>>>;
542
+ export type AvUpdateDataInput<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvWriteScope = UnrestrictedWrite, Forms extends ScalarForms = UnstatedForms, ReferenceForms extends ScalarForms = never, Via extends ParentEdge = never> = RefuseEveryKeyWhenEmpty<ScalarMutationFields<C, K, "update", Scope, Forms, ReferenceForms, Via>> & RefuseEveryKeyWhenEmpty<RelationMutationFields<C, K, "update", Scope, Forms, ReferenceForms, Via>>;
527
543
  type QueryProjectionArgs<C extends AvContract, K extends AvResourceKey<C>, Scope extends AvProjectionScope, Forms extends ScalarForms> = ProjectionChoice<C, K, Scope, false, Forms>;
528
544
  /**
529
545
  * Every standard operation's argument object, with each argument at its
@@ -55,8 +55,10 @@ export type AvOperationGrammar<C extends AvContract> = {
55
55
  export type AvOperationSlot<I extends AvOperationIdentity, Result> = I["variant"] extends "first" ? Result | null : Result;
56
56
  /** What a direct call resolves: the slot, every failure thrown. */
57
57
  type Settled<I extends AvOperationIdentity, Result> = AvOperationSlot<I, Result>;
58
- type ProjectingCall<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Args, ResultForms extends ScalarForms, Options> = <const Select extends SelectOf<Args> = never, const Include extends IncludeOf<Args> = never>(...args: CallArgumentList<Omit<Args, ProjectionKey>, Omit<Args, ProjectionKey> & ProjectionArgument<Select, Include>, Options>) => Promise<Settled<I, AdmittedOperationResult<C, R, I, InferredProjection<Select, Include>, ResultForms>>>;
59
- type PlainCall<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Args, ResultForms extends ScalarForms, Options> = (...args: CallArgumentList<Args, Args, Options>) => Promise<Settled<I, AdmittedOperationResult<C, R, I, unknown, ResultForms>>>;
58
+ /** A direct call that projects: generic in its `select`/`include` literal. */
59
+ export type ProjectingCall<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Args, ResultForms extends ScalarForms, Options> = <const Select extends SelectOf<Args> = never, const Include extends IncludeOf<Args> = never>(...args: CallArgumentList<Omit<Args, ProjectionKey>, NoInfer<Omit<Args, ProjectionKey>> & ProjectionArgument<Select, Include>, Options>) => Promise<Settled<I, AdmittedOperationResult<C, R, I, InferredProjection<Select, Include>, ResultForms>>>;
60
+ /** A direct call that does not project. */
61
+ export type PlainCall<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Args, ResultForms extends ScalarForms, Options> = (...args: CallArgumentList<Args, Args, Options>) => Promise<Settled<I, AdmittedOperationResult<C, R, I, unknown, ResultForms>>>;
60
62
  /**
61
63
  * One direct call: its arguments in `Forms`, its result in `ResultForms`,
62
64
  * resolving the slot and throwing every failure, taking `Options` per call. It is generic in its
@@ -68,9 +70,11 @@ export type AvOperationCall<C extends AvContract, R extends AvResourceKey<C>, I
68
70
  * `$ref` typed in `ResultForms` — the forms the source's final data is read in, so a
69
71
  * reference carries what its source resolves.
70
72
  */
71
- type DeferredArguments<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Forms extends ScalarForms, ResultForms extends ScalarForms> = ReferenceableArgumentsFor<C, R, I, Forms, ResultForms>;
72
- type DeferredProjectingCall<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Args, ResultForms extends ScalarForms, Origin extends HandleOrigin> = <const Select extends SelectOf<Args> = never, const Include extends IncludeOf<Args> = never>(...args: ArgumentList<Omit<Args, ProjectionKey>, Omit<Args, ProjectionKey> & ProjectionArgument<Select, Include>>) => AvOperation<AvOperationSlot<I, AdmittedOperationResult<C, R, I, InferredProjection<Select, Include>, ResultForms>>, Origin>;
73
- type DeferredPlainCall<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Args, ResultForms extends ScalarForms, Origin extends HandleOrigin> = (...args: ArgumentList<Args, Args>) => AvOperation<AvOperationSlot<I, AdmittedOperationResult<C, R, I, unknown, ResultForms>>, Origin>;
73
+ export type DeferredArguments<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Forms extends ScalarForms, ResultForms extends ScalarForms> = ReferenceableArgumentsFor<C, R, I, Forms, ResultForms>;
74
+ /** A deferred operation that projects: generic in its `select`/`include` literal. */
75
+ export type DeferredProjectingCall<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Args, ResultForms extends ScalarForms, Origin extends HandleOrigin> = <const Select extends SelectOf<Args> = never, const Include extends IncludeOf<Args> = never>(...args: ArgumentList<Omit<Args, ProjectionKey>, NoInfer<Omit<Args, ProjectionKey>> & ProjectionArgument<Select, Include>>) => AvOperation<AvOperationSlot<I, AdmittedOperationResult<C, R, I, InferredProjection<Select, Include>, ResultForms>>, Origin>;
76
+ /** A deferred operation that does not project. */
77
+ export type DeferredPlainCall<C extends AvContract, R extends AvResourceKey<C>, I extends AvOperationIdentity, Args, ResultForms extends ScalarForms, Origin extends HandleOrigin> = (...args: ArgumentList<Args, Args>) => AvOperation<AvOperationSlot<I, AdmittedOperationResult<C, R, I, unknown, ResultForms>>, Origin>;
74
78
  /**
75
79
  * One deferred operation: a handle typed `AvOperation<AvOperationSlot<…>, Origin>`,
76
80
  * with `$ref` present exactly where the result is one row. A handle is not a
@@ -6,7 +6,8 @@ import type { AvOperationIdentity } from "./operation-identity.js";
6
6
  type FieldOf<C extends AvContract, K extends AvResourceKey<C>, F extends AvFieldKey<C, K>> = C["resources"][K]["fields"][F];
7
7
  /**
8
8
  * The fields returned when no projection is given: the scalars whose `select`
9
- * is exactly `true`. A write-only field never appears.
9
+ * is exactly `true` and that the policy does not govern. A write-only field never
10
+ * appears, and a governed one appears only where a projection names it.
10
11
  */
11
12
  type DefaultKey<C extends AvContract, K extends AvResourceKey<C>> = {
12
13
  [F in AvFieldKey<C, K>]: FieldOf<C, K, F> extends {
@@ -14,6 +15,7 @@ type DefaultKey<C extends AvContract, K extends AvResourceKey<C>> = {
14
15
  readonly capabilities: {
15
16
  readonly select: true;
16
17
  };
18
+ readonly governed?: never;
17
19
  } ? F : never;
18
20
  }[AvFieldKey<C, K>];
19
21
  /** The field one projection entry names: a bare key, or a relation entry's key. */
@@ -33,14 +35,14 @@ type EntryArguments<Entry, F extends string> = Entry extends object ? Entry exte
33
35
  */
34
36
  type ProjectedFields<C extends AvContract, K extends AvResourceKey<C>, Keys extends AvFieldKey<C, K>, Entries, Forms extends ScalarForms> = {
35
37
  readonly [F in Keys]: FieldOf<C, K, F> extends AvScalarField<C> ? AvScalarValueType<C, FieldOf<C, K, F>, Forms> : FieldOf<C, K, F> extends AvRelationField<C> ? RelationResult<C, Extract<FieldOf<C, K, F>["target"], AvResourceKey<C>>, FieldOf<C, K, F>, EntryArguments<Entries, F>, Forms> : never;
36
- };
38
+ } extends infer Fields ? Fields : never;
37
39
  /**
38
40
  * One projection level: `select` returns exactly its entries, `include` the
39
41
  * default fields plus the named relations, and no projection the default fields.
40
42
  */
41
43
  type ProjectedRecord<C extends AvContract, K extends AvResourceKey<C>, Arguments, Forms extends ScalarForms> = [Arguments] extends [never] ? ProjectedFields<C, K, DefaultKey<C, K>, never, Forms> : [Arguments] extends [{
42
44
  readonly select: readonly (infer Entry)[];
43
- }] ? ProjectedFields<C, K, Extract<EntryKey<Entry>, AvFieldKey<C, K>>, Entry, Forms> : [Arguments] extends [{
45
+ }] ? ProjectedFields<C, K, Extract<EntryKey<Entry>, AvFieldKey<C, K>> | (Entry extends "$defaults" ? DefaultKey<C, K> : never), Entry, Forms> : [Arguments] extends [{
44
46
  readonly include: readonly (infer Entry)[];
45
47
  }] ? ProjectedFields<C, K, DefaultKey<C, K> | Extract<EntryKey<Entry>, AvFieldKey<C, K>>, Entry, Forms> : ProjectedFields<C, K, DefaultKey<C, K>, never, Forms>;
46
48
  /**
@@ -50,7 +52,7 @@ type ProjectedRecord<C extends AvContract, K extends AvResourceKey<C>, Arguments
50
52
  type CountEnvelope<C extends AvContract, Target extends AvResourceKey<C>, Entry, Forms extends ScalarForms> = [Exclude<Entry, "$count">] extends [never] ? {
51
53
  readonly count: number;
52
54
  } : {
53
- readonly data: readonly ProjectedFields<C, Target, Extract<EntryKey<Entry>, AvFieldKey<C, Target>>, Exclude<Entry, "$count">, Forms>[];
55
+ readonly data: readonly ProjectedFields<C, Target, Extract<EntryKey<Entry>, AvFieldKey<C, Target>> | (Entry extends "$defaults" ? DefaultKey<C, Target> : never), Exclude<Entry, "$count">, Forms>[];
54
56
  readonly count: number;
55
57
  };
56
58
  /** The entries of an argument's own `select`, or `never` when it has none. */
@@ -524,6 +524,12 @@ function validateProjection(contract, resourceName, mode, value, scope, path, is
524
524
  }
525
525
  value.forEach((entry, index) => {
526
526
  const entryPath = [...path, index];
527
+ if (entry === "$defaults") {
528
+ if (mode !== "select") {
529
+ addIssue(issues, "V1008", entryPath, "$defaults is a select entry: include already returns the default fields.");
530
+ }
531
+ return;
532
+ }
527
533
  if (entry === "$count") {
528
534
  if (mode !== "select" ||
529
535
  reducerOwner?.edge.cardinality !== "many" ||
@@ -0,0 +1,22 @@
1
+ import type { AvContract, AvContractCore } from "../contracts/contract.js";
2
+ import type { AvOperationIdentity } from "../operations/operation-identity.js";
3
+ import type { AvOperationFailureResponse } from "../runtime/operation-response.js";
4
+ import { type PolicyAction, type PolicySession } from "./policy-session.js";
5
+ /** The refusal every policy decision answers: `A4002`. */
6
+ export declare function policyRefusal(message: string): AvOperationFailureResponse;
7
+ /** The actions an operation family asks the engine about. */
8
+ export declare function policyActionsOf(family: AvOperationIdentity["family"]): readonly PolicyAction[];
9
+ /**
10
+ * Policy admission for one request (see the module comment): the refusal, or
11
+ * `undefined` when the request may go on to its guards.
12
+ */
13
+ export declare function admitByPolicy(session: PolicySession, core: AvContractCore, active: AvContract, request: AvOperationIdentity & {
14
+ readonly resource: string;
15
+ }, args: unknown): Promise<AvOperationFailureResponse | undefined>;
16
+ /**
17
+ * The write half of policy admission: every field the write sends against
18
+ * `fieldsOf(write)`, nested records included, the refusal or `undefined`.
19
+ */
20
+ export declare function admitWriteByPolicy(session: PolicySession, core: AvContractCore, request: AvOperationIdentity & {
21
+ readonly resource: string;
22
+ }, args: unknown): Promise<AvOperationFailureResponse | undefined>;