@fougere/core 0.17.3-alpha.0 → 0.18.0-alpha.0

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 (181) hide show
  1. package/dist/Declared.d.ts +2 -5
  2. package/dist/Declared.d.ts.map +1 -1
  3. package/dist/DeclaredHandler.d.ts +3 -8
  4. package/dist/DeclaredHandler.d.ts.map +1 -1
  5. package/dist/DeclaredSubject.d.ts +2 -5
  6. package/dist/DeclaredSubject.d.ts.map +1 -1
  7. package/dist/EffectiveOperation.d.ts +7 -6
  8. package/dist/EffectiveOperation.d.ts.map +1 -1
  9. package/dist/EffectiveOperationModel.d.ts.map +1 -1
  10. package/dist/EffectiveOperationModel.js +9 -6
  11. package/dist/EffectiveOperationModel.js.map +1 -1
  12. package/dist/FrondConfig.d.ts +0 -2
  13. package/dist/FrondConfig.d.ts.map +1 -1
  14. package/dist/FrondConfig.js.map +1 -1
  15. package/dist/FrondDeclaration.d.ts +3 -8
  16. package/dist/FrondDeclaration.d.ts.map +1 -1
  17. package/dist/FrondDeclaration.js +2 -1
  18. package/dist/FrondDeclaration.js.map +1 -1
  19. package/dist/OperationOverride.d.ts +5 -3
  20. package/dist/OperationOverride.d.ts.map +1 -1
  21. package/dist/SourceView.d.ts +10 -8
  22. package/dist/SourceView.d.ts.map +1 -1
  23. package/dist/SourceView.js +10 -1
  24. package/dist/SourceView.js.map +1 -1
  25. package/dist/boot/bootstrap.d.ts.map +1 -1
  26. package/dist/boot/bootstrap.js +6 -5
  27. package/dist/boot/bootstrap.js.map +1 -1
  28. package/dist/boot/install.d.ts.map +1 -1
  29. package/dist/boot/install.js +8 -4
  30. package/dist/boot/install.js.map +1 -1
  31. package/dist/boot/unregistered.d.ts +11 -0
  32. package/dist/boot/unregistered.d.ts.map +1 -0
  33. package/dist/boot/unregistered.js +35 -0
  34. package/dist/boot/unregistered.js.map +1 -0
  35. package/dist/contract.d.ts +3 -0
  36. package/dist/contract.d.ts.map +1 -1
  37. package/dist/contract.js +3 -0
  38. package/dist/contract.js.map +1 -1
  39. package/dist/descriptor/CollectorEntry.d.ts +2 -7
  40. package/dist/descriptor/CollectorEntry.d.ts.map +1 -1
  41. package/dist/descriptor/FrondDescriptor.d.ts +5 -23
  42. package/dist/descriptor/FrondDescriptor.d.ts.map +1 -1
  43. package/dist/descriptor/FrondDescriptor.js.map +1 -1
  44. package/dist/descriptor/HandlerEntry.d.ts +2 -7
  45. package/dist/descriptor/HandlerEntry.d.ts.map +1 -1
  46. package/dist/descriptor/MiddlewareEntry.d.ts +2 -7
  47. package/dist/descriptor/MiddlewareEntry.d.ts.map +1 -1
  48. package/dist/descriptor/PresenterEntry.d.ts +2 -7
  49. package/dist/descriptor/PresenterEntry.d.ts.map +1 -1
  50. package/dist/descriptor/ProviderEntry.d.ts +2 -7
  51. package/dist/descriptor/ProviderEntry.d.ts.map +1 -1
  52. package/dist/descriptor/Subject.d.ts +10 -0
  53. package/dist/descriptor/Subject.d.ts.map +1 -0
  54. package/dist/descriptor/Subject.js +2 -0
  55. package/dist/descriptor/Subject.js.map +1 -0
  56. package/dist/descriptor/index.d.ts +1 -0
  57. package/dist/descriptor/index.d.ts.map +1 -1
  58. package/dist/descriptor/index.js +1 -0
  59. package/dist/descriptor/index.js.map +1 -1
  60. package/dist/index.d.ts +3 -1
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +2 -0
  63. package/dist/index.js.map +1 -1
  64. package/dist/prefab/AggregateConstructor.d.ts +2 -2
  65. package/dist/prefab/AggregateConstructor.d.ts.map +1 -1
  66. package/dist/prefab/AggregateOf.d.ts +2 -2
  67. package/dist/prefab/AggregateOf.d.ts.map +1 -1
  68. package/dist/prefab/AggregateShape.d.ts +2 -2
  69. package/dist/prefab/AggregateShape.d.ts.map +1 -1
  70. package/dist/prefab/CrudConstructor.d.ts +2 -2
  71. package/dist/prefab/CrudConstructor.d.ts.map +1 -1
  72. package/dist/prefab/CrudConstructor.js +12 -10
  73. package/dist/prefab/CrudConstructor.js.map +1 -1
  74. package/dist/prefab/CrudOps.d.ts +2 -2
  75. package/dist/prefab/CrudOps.d.ts.map +1 -1
  76. package/dist/prefab/CrudViews.d.ts +2 -2
  77. package/dist/prefab/CrudViews.d.ts.map +1 -1
  78. package/dist/prefab/MirrorConstructor.d.ts +2 -2
  79. package/dist/prefab/MirrorConstructor.d.ts.map +1 -1
  80. package/dist/prefab/MirrorConstructor.js.map +1 -1
  81. package/dist/prefab/RepositoryConstructor.d.ts +4 -4
  82. package/dist/prefab/RepositoryConstructor.d.ts.map +1 -1
  83. package/dist/prefab/RepositoryConstructor.js.map +1 -1
  84. package/dist/prefab/collector.d.ts +2 -1
  85. package/dist/prefab/collector.d.ts.map +1 -1
  86. package/dist/prefab/collector.js.map +1 -1
  87. package/dist/prefab/opsOf.d.ts +4 -0
  88. package/dist/prefab/opsOf.d.ts.map +1 -0
  89. package/dist/prefab/opsOf.js +5 -0
  90. package/dist/prefab/opsOf.js.map +1 -0
  91. package/dist/prefab/prefab.d.ts +3 -3
  92. package/dist/prefab/prefab.d.ts.map +1 -1
  93. package/dist/prefab/presenter.d.ts +3 -3
  94. package/dist/prefab/presenter.d.ts.map +1 -1
  95. package/dist/prefab/presenter.js.map +1 -1
  96. package/dist/wire/Addresses.d.ts +4 -4
  97. package/dist/wire/Addresses.d.ts.map +1 -1
  98. package/dist/wire/Cardinality.d.ts +4 -0
  99. package/dist/wire/Cardinality.d.ts.map +1 -0
  100. package/dist/wire/Cardinality.js +3 -0
  101. package/dist/wire/Cardinality.js.map +1 -0
  102. package/dist/wire/OperationContract.d.ts +2 -1
  103. package/dist/wire/OperationContract.d.ts.map +1 -1
  104. package/dist/wire/OperationContract.js.map +1 -1
  105. package/dist/wire/OperationKind.d.ts +3 -1
  106. package/dist/wire/OperationKind.d.ts.map +1 -1
  107. package/dist/wire/OperationKind.js +2 -1
  108. package/dist/wire/OperationKind.js.map +1 -1
  109. package/dist/wire/Placement.d.ts +4 -0
  110. package/dist/wire/Placement.d.ts.map +1 -0
  111. package/dist/wire/Placement.js +3 -0
  112. package/dist/wire/Placement.js.map +1 -0
  113. package/dist/wire/RouteKind.d.ts +2 -1
  114. package/dist/wire/RouteKind.d.ts.map +1 -1
  115. package/dist/wire/StateShape.d.ts +1 -2
  116. package/dist/wire/StateShape.d.ts.map +1 -1
  117. package/dist/wire/StateShape.js +11 -11
  118. package/dist/wire/StateShape.js.map +1 -1
  119. package/dist/wire/TypeRef.d.ts +5 -0
  120. package/dist/wire/TypeRef.d.ts.map +1 -1
  121. package/dist/wire/binding.d.ts +4 -1
  122. package/dist/wire/binding.d.ts.map +1 -1
  123. package/dist/wire/binding.js +4 -2
  124. package/dist/wire/binding.js.map +1 -1
  125. package/dist/wire/card/CardOp.d.ts +4 -10
  126. package/dist/wire/card/CardOp.d.ts.map +1 -1
  127. package/dist/wire/refusals.d.ts +2 -1
  128. package/dist/wire/refusals.d.ts.map +1 -1
  129. package/dist/wire/refusals.js.map +1 -1
  130. package/dist/wire/topology/DeclaredFrond.d.ts +2 -1
  131. package/dist/wire/topology/DeclaredFrond.d.ts.map +1 -1
  132. package/dist/wire/topology/FrondPlacement.d.ts +2 -1
  133. package/dist/wire/topology/FrondPlacement.d.ts.map +1 -1
  134. package/package.json +3 -3
  135. package/src/Declared.ts +3 -7
  136. package/src/DeclaredHandler.ts +3 -8
  137. package/src/DeclaredSubject.ts +3 -5
  138. package/src/EffectiveOperation.ts +7 -6
  139. package/src/EffectiveOperationModel.ts +11 -7
  140. package/src/FrondConfig.ts +0 -2
  141. package/src/FrondDeclaration.ts +5 -8
  142. package/src/OperationOverride.ts +5 -3
  143. package/src/SourceView.ts +21 -3
  144. package/src/boot/bootstrap.ts +8 -5
  145. package/src/boot/install.ts +7 -4
  146. package/src/boot/unregistered.ts +40 -0
  147. package/src/contract.ts +3 -0
  148. package/src/descriptor/CollectorEntry.ts +2 -7
  149. package/src/descriptor/FrondDescriptor.ts +5 -19
  150. package/src/descriptor/HandlerEntry.ts +2 -7
  151. package/src/descriptor/MiddlewareEntry.ts +2 -7
  152. package/src/descriptor/PresenterEntry.ts +2 -7
  153. package/src/descriptor/ProviderEntry.ts +2 -7
  154. package/src/descriptor/Subject.ts +10 -0
  155. package/src/descriptor/index.ts +1 -0
  156. package/src/index.ts +3 -1
  157. package/src/prefab/AggregateConstructor.ts +2 -2
  158. package/src/prefab/AggregateOf.ts +2 -2
  159. package/src/prefab/AggregateShape.ts +2 -2
  160. package/src/prefab/CrudConstructor.ts +17 -13
  161. package/src/prefab/CrudOps.ts +3 -3
  162. package/src/prefab/CrudViews.ts +2 -2
  163. package/src/prefab/MirrorConstructor.ts +2 -2
  164. package/src/prefab/RepositoryConstructor.ts +9 -9
  165. package/src/prefab/collector.ts +4 -3
  166. package/src/prefab/opsOf.ts +6 -0
  167. package/src/prefab/prefab.ts +5 -5
  168. package/src/prefab/presenter.ts +3 -3
  169. package/src/wire/Addresses.ts +4 -4
  170. package/src/wire/Cardinality.ts +4 -0
  171. package/src/wire/OperationContract.ts +2 -1
  172. package/src/wire/OperationKind.ts +4 -1
  173. package/src/wire/Placement.ts +4 -0
  174. package/src/wire/RouteKind.ts +3 -1
  175. package/src/wire/StateShape.ts +9 -11
  176. package/src/wire/TypeRef.ts +2 -0
  177. package/src/wire/binding.ts +7 -2
  178. package/src/wire/card/CardOp.ts +4 -10
  179. package/src/wire/refusals.ts +2 -1
  180. package/src/wire/topology/DeclaredFrond.ts +3 -1
  181. package/src/wire/topology/FrondPlacement.ts +3 -1
@@ -1,17 +1,17 @@
1
1
  import type { FougereOperations } from './FougereOperations.js';
2
2
 
3
- type Served = keyof FougereOperations & string;
3
+ type Generated = keyof FougereOperations & string;
4
4
 
5
5
  /**
6
6
  * Both halves below take the union through a type PARAMETER, which is what makes the
7
- * conditional distribute: `Served` is an alias, and an alias is matched whole — `'a.x' | 'b.y'`
7
+ * conditional distribute: `Generated` is an alias, and an alias is matched whole — `'a.x' | 'b.y'`
8
8
  * does not extend `` `${string}.${string}` `` as one thing, so the naive form answers `never`.
9
9
  */
10
10
  type AddressIn<Key> = Key extends `${infer Address}.${string}` ? Address : never;
11
11
 
12
12
  /**
13
13
  * The addresses this app answers at — or any string, until a scan has said otherwise. The
14
- * `[Served] extends [never]` form is what keeps an ungenerated project compiling: a bare `never`
14
+ * `[Generated] extends [never]` form is what keeps an ungenerated project compiling: a bare `never`
15
15
  * in a parameter position refuses every call, the correct ones included.
16
16
  */
17
- export type Addresses = [Served] extends [never] ? string : AddressIn<Served>;
17
+ export type Addresses = [Generated] extends [never] ? string : AddressIn<Generated>;
@@ -0,0 +1,4 @@
1
+ /** How MUCH an operation answers — the half of a return type that a view cannot say. */
2
+ export const CARDINALITIES = ['one', 'maybe', 'many', 'page', 'none'] as const;
3
+
4
+ export type Cardinality = (typeof CARDINALITIES)[number];
@@ -5,6 +5,7 @@ import type { TypeRef } from './TypeRef.js';
5
5
  import type { ErrorCode } from './ErrorCode.js';
6
6
  import type { OperationKind } from './OperationKind.js';
7
7
  import type { OperationKindInference } from './OperationKindInference.js';
8
+ import type { Cardinality } from './Cardinality.js';
8
9
 
9
10
  /** The contract of one operation — everything the façade needs to serve a call. */
10
11
  export interface OperationContract {
@@ -17,7 +18,7 @@ export interface OperationContract {
17
18
  /** The operation in words, for a caller that meets it over the wire and has to choose. */
18
19
  description?: string;
19
20
  /** How MUCH comes back — the half of the return type that `output` cannot say. */
20
- cardinality?: 'one' | 'maybe' | 'many' | 'page' | 'none';
21
+ cardinality?: Cardinality;
21
22
  /** The argument names and TYPES — the one thing `binding` cannot say. */
22
23
  signature?: Signature;
23
24
  /**
@@ -1 +1,4 @@
1
- export type OperationKind = 'query' | 'command';
1
+ /** `query` reads, `command` writes — the same call REST turns into GET vs POST. */
2
+ export const OPERATION_KINDS = ['query', 'command'] as const;
3
+
4
+ export type OperationKind = (typeof OPERATION_KINDS)[number];
@@ -0,0 +1,4 @@
1
+ /** Where something answers — in this process, or a process away. */
2
+ export const PLACEMENTS = ['local', 'remote'] as const;
3
+
4
+ export type Placement = (typeof PLACEMENTS)[number];
@@ -1,2 +1,4 @@
1
+ import type { Placement } from './Placement.js';
2
+
1
3
  /** Which kind of destination served a call — it travels in a `CallRecord`. */
2
- export type RouteKind = 'local' | 'remote' | 'system';
4
+ export type RouteKind = Placement | 'system';
@@ -1,4 +1,4 @@
1
- import { InputValidator, dotted, optional, type Field, type Fields } from '@fougere/schema';
1
+ import { Schema, dotted, optional, type Field, type Fields, type SchemaConstructor, type SchemaView } from '@fougere/schema';
2
2
  import { ErrorCode } from './ErrorCode.js';
3
3
  import { FougereError } from './FougereError.js';
4
4
 
@@ -16,19 +16,16 @@ export interface StateDeclaration {
16
16
  * Documented: [collectors](https://fougere.dev/docs/business/collectors).
17
17
  */
18
18
  export class StateShape {
19
- static readonly empty = new StateShape({});
19
+ static readonly empty = new StateShape(Schema.of({ fields: {} }));
20
20
 
21
- private readonly validator: InputValidator;
22
-
23
- private constructor(private readonly fields: Fields) {
24
- this.validator = InputValidator.of(fields);
25
- }
21
+ private constructor(private readonly schema: SchemaView) {}
26
22
 
27
23
  /** Two extensions declaring one member refuse: the field that judges it would depend on wiring order. */
28
24
  static of(declarations: readonly StateDeclaration[]): StateShape {
29
- const fields: Fields = {};
30
25
  const owners = new Map<string, string>();
26
+ let schema: SchemaConstructor<Fields> = Schema.of({ fields: {} as Fields });
31
27
  for (const { name, state } of declarations) {
28
+ const fields: Fields = {};
32
29
  for (const [member, field] of Object.entries(state ?? {})) {
33
30
  const owner = owners.get(member);
34
31
  if (owner) {
@@ -40,9 +37,10 @@ export class StateShape {
40
37
  owners.set(member, name);
41
38
  fields[member] = optional(field);
42
39
  }
40
+ schema = schema.extend(fields);
43
41
  }
44
42
 
45
- return new StateShape(fields);
43
+ return new StateShape(schema);
46
44
  }
47
45
 
48
46
  /**
@@ -58,10 +56,10 @@ export class StateShape {
58
56
  const written = Object.fromEntries(Object.entries(state).filter(([member, value]) => entered[member] !== value));
59
57
  if (Object.keys(written).length === 0) return state;
60
58
 
61
- const result = this.validator.validate(written);
59
+ const result = this.schema.validate(written);
62
60
  if (result.success) return { ...state, ...result.data };
63
61
 
64
- const declared = Object.keys(this.fields);
62
+ const declared = Object.keys(this.schema.getFields());
65
63
  const errors = result.errors.map((error) => ({ ...error, path: ['state', ...error.path] }));
66
64
 
67
65
  throw new FougereError({
@@ -16,4 +16,6 @@ export interface TypeRef {
16
16
  undefined?: boolean;
17
17
  /** Whether this is a Promise wrapper (unwrapped in output). */
18
18
  promise?: boolean;
19
+ /** `Post['id']` — the entity whose primary key this value is, and the field holding it. */
20
+ identifies?: { entity: string; field: string };
19
21
  }
@@ -17,7 +17,8 @@ type ParamSource =
17
17
  * (`Emissions.stamped`, which realizes `created()`); this is the declared form of it.
18
18
  */
19
19
  | { kind: 'pipe'; factName: string }
20
- | { kind: 'param'; name: string; coerce?: 'number' | 'boolean' }
20
+ /** `identifies` names the entity whose row the value designates — `id: Post['id']`. */
21
+ | { kind: 'param'; name: string; coerce?: 'number' | 'boolean'; identifies?: string }
21
22
  | { kind: 'input' }
22
23
  | { kind: 'context' }
23
24
  /** The whole query bag, for an op whose argument IS the options (list). */
@@ -76,7 +77,11 @@ function sourceOf(param: Param, collectorTypeNames: Set<string>): ParamSource {
76
77
 
77
78
  if (collectorTypeNames.has(typeKey)) return { kind: 'collector', typeName: typeKey };
78
79
  if (typeName === 'InvocationContext') return { kind: 'context' };
79
- if (PRIMITIVES.has(typeName)) return { kind: 'param', name: param.name, coerce: coercionFor(typeName) };
80
+ if (PRIMITIVES.has(typeName)) {
81
+ const identifies = param.type.identifies?.entity;
82
+
83
+ return { kind: 'param', name: param.name, coerce: coercionFor(typeName), ...(identifies && { identifies }) };
84
+ }
80
85
 
81
86
  return { kind: 'input' };
82
87
  }
@@ -1,24 +1,18 @@
1
1
  import type { SchemaDescriptor } from '@fougere/schema';
2
- import type { ErrorCode } from '../ErrorCode.js';
2
+ import type { OperationContract } from '../OperationContract.js';
3
+ import type { OperationKind } from '../OperationKind.js';
3
4
 
4
5
  /**
5
6
  * One operation, as a stranger meets it — its name, what it is for, what it takes and whether it
6
7
  * reads or writes.
7
8
  */
8
- export interface CardOp {
9
+ export interface CardOp extends Pick<OperationContract, 'description' | 'cardinality' | 'errors'> {
9
10
  name: string;
10
- /** The author's own doc sentence, when the method carries one. */
11
- description?: string;
12
11
  /** JSON Schema of what it accepts, when the contract names a view. */
13
12
  input?: SchemaDescriptor;
14
13
  /** JSON Schema of what it emits, when the contract names one. */
15
14
  output?: SchemaDescriptor;
16
- /** `query` reads, `command` writes — the same call REST turns into GET vs POST. */
17
- kind: 'query' | 'command';
18
- /** How much `output` describes. */
19
- cardinality?: 'one' | 'maybe' | 'many' | 'page' | 'none';
20
- /** What this op can REFUSE, beyond what `kind` and `input` already imply. */
21
- errors?: ErrorCode[];
15
+ kind: OperationKind;
22
16
  /** The fact this op is handed when it is announced — its `Fact<T>`, which IS the subscription. */
23
17
  listens?: string;
24
18
  }
@@ -14,10 +14,11 @@
14
14
  * Documented: [observability](https://fougere.dev/docs/infra/observability).
15
15
  */
16
16
  import { ErrorCode } from './ErrorCode.js';
17
+ import type { OperationKind } from './OperationKind.js';
17
18
 
18
19
  /** The little of an operation this reads — so a card op and an effective one both fit. */
19
20
  export interface Refusable {
20
- kind?: 'query' | 'command';
21
+ kind?: OperationKind;
21
22
  input?: unknown;
22
23
  errors?: readonly string[];
23
24
  /** Absent on a card op read from a frond that answers in this process. */
@@ -1,7 +1,9 @@
1
+ import type { Placement } from '../Placement.js';
2
+
1
3
  /** A frond the config knows of, and where it says to reach it. */
2
4
  export interface DeclaredFrond {
3
5
  frond: string;
4
- placement: 'local' | 'remote';
6
+ placement: Placement;
5
7
  /**
6
8
  * Host and port of the address `remotes:` names, absent when the frond runs here. Never the
7
9
  * whole address: a declared one may carry credentials, and this answer leaves the process.
@@ -1,7 +1,9 @@
1
+ import type { Placement } from '../Placement.js';
2
+
1
3
  /** A frond this process knows about, and whether it runs here. */
2
4
  export interface FrondPlacement {
3
5
  frond: string;
4
- placement: 'local' | 'remote';
6
+ placement: Placement;
5
7
  entities: number;
6
8
  facades: number;
7
9
  }