@afora/core 0.0.2 → 0.0.4

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 (82) hide show
  1. package/README.md +220 -733
  2. package/dist/core/application/application.d.ts +9 -1
  3. package/dist/core/application/exceptions.d.ts +28 -0
  4. package/dist/core/application/registry.d.ts +33 -0
  5. package/dist/core/application/start.d.ts +75 -0
  6. package/dist/core/application/types/application.interface.d.ts +229 -7
  7. package/dist/core/blueprint/types/blueprint.interface.d.ts +66 -11
  8. package/dist/core/blueprint/types/slice.interface.d.ts +7 -2
  9. package/dist/core/command/command.d.ts +25 -0
  10. package/dist/core/command/exceptions.d.ts +33 -0
  11. package/dist/core/command/types/command.interface.d.ts +108 -0
  12. package/dist/core/entity/event.d.ts +12 -2
  13. package/dist/core/environment/environment.d.ts +4 -1
  14. package/dist/core/exception/exception.d.ts +4 -0
  15. package/dist/core/exception/exported.d.ts +4 -0
  16. package/dist/core/json.d.ts +10 -0
  17. package/dist/core/logger/exceptions.d.ts +4 -0
  18. package/dist/core/logger/logger.d.ts +106 -0
  19. package/dist/core/output/exceptions.d.ts +8 -0
  20. package/dist/core/output/openapi-sink.d.ts +83 -0
  21. package/dist/core/output/output.d.ts +19 -0
  22. package/dist/core/output/problem.d.ts +15 -0
  23. package/dist/core/output/select.d.ts +14 -0
  24. package/dist/core/output/stage.d.ts +24 -0
  25. package/dist/core/output/status.d.ts +17 -0
  26. package/dist/core/output/types/output.interface.d.ts +171 -0
  27. package/dist/core/property/abstract-property.d.ts +8 -7
  28. package/dist/core/property/define-property.d.ts +8 -7
  29. package/dist/core/property/property.d.ts +26 -15
  30. package/dist/core/property/types/abstract-property-constructor.type.d.ts +8 -7
  31. package/dist/core/property/types/define-property.interface.d.ts +5 -4
  32. package/dist/core/property/types/optional-property.type.d.ts +5 -5
  33. package/dist/core/property/types/property-collection.type.d.ts +2 -2
  34. package/dist/core/property/types/property-constructor.type.d.ts +5 -1
  35. package/dist/core/property/types/property-options.interface.d.ts +17 -8
  36. package/dist/core/property/types/property-type.interface.d.ts +7 -3
  37. package/dist/core/property/types/property.interface.d.ts +5 -4
  38. package/dist/core/record/abstract-record.d.ts +12 -4
  39. package/dist/core/record/types/plugin.interface.d.ts +13 -3
  40. package/dist/core/record/types/record.interface.d.ts +20 -8
  41. package/dist/core/repository/exceptions.d.ts +4 -0
  42. package/dist/core/repository/in-memory.d.ts +3 -0
  43. package/dist/core/repository/provider.d.ts +6 -0
  44. package/dist/core/repository/query.d.ts +9 -0
  45. package/dist/core/repository/references.d.ts +4 -2
  46. package/dist/core/repository/repository.d.ts +4 -2
  47. package/dist/core/repository/state.d.ts +4 -0
  48. package/dist/core/repository/types/query.interface.d.ts +67 -0
  49. package/dist/core/repository/types/repository.interface.d.ts +13 -13
  50. package/dist/core/schema/types/schema.interface.d.ts +11 -4
  51. package/dist/core/symbols/meta.d.ts +2 -0
  52. package/dist/core/use-case/exceptions.d.ts +10 -0
  53. package/dist/core/use-case/scope.d.ts +24 -0
  54. package/dist/core/use-case/steps/describe.d.ts +13 -0
  55. package/dist/core/use-case/steps/references.d.ts +27 -0
  56. package/dist/core/use-case/steps/run.d.ts +20 -0
  57. package/dist/core/use-case/steps/types/steps.interface.d.ts +153 -0
  58. package/dist/core/use-case/steps/validate.d.ts +17 -0
  59. package/dist/core/use-case/use-case.d.ts +79 -13
  60. package/dist/experimental.d.ts +6 -0
  61. package/dist/experimental.js +123 -0
  62. package/dist/index-ewm6r4nw.js +5335 -0
  63. package/dist/index-hn82hm31.js +1651 -0
  64. package/dist/index.d.ts +34 -12
  65. package/dist/index.js +343 -4142
  66. package/dist/std/blueprint-plugin.d.ts +10 -10
  67. package/dist/std/blueprint.d.ts +10 -10
  68. package/dist/std/entity.d.ts +2 -2
  69. package/dist/std/properties/contact.d.ts +4 -4
  70. package/dist/std/properties/enum.d.ts +1 -1
  71. package/dist/std/properties/headless.d.ts +1 -1
  72. package/dist/std/properties/identity.d.ts +2 -2
  73. package/dist/std/properties/password.d.ts +1 -1
  74. package/dist/std/properties/primitives.d.ts +5 -5
  75. package/dist/std/properties/time.d.ts +2 -2
  76. package/dist/std/record-plugins.d.ts +12 -12
  77. package/dist/std/record.d.ts +1 -1
  78. package/dist/std/stages.d.ts +2 -0
  79. package/dist/testing/index.d.ts +2 -0
  80. package/dist/testing/index.js +502 -0
  81. package/dist/testing/provider-contract.d.ts +22 -0
  82. package/package.json +28 -8
@@ -0,0 +1,171 @@
1
+ import type { AnyBlueprint } from "../../blueprint/types/blueprint.interface.js";
2
+ import type { AnyCommand } from "../../command/types/command.interface.js";
3
+ import type { JsonValue } from "../../json.js";
4
+ import type { Kind } from "../../symbols/kind.js";
5
+ import type { AnyExceptionClass } from "../../use-case/use-case.js";
6
+ /** The options of a stage: a JSON object. */
7
+ export type StageOptions = {
8
+ readonly [key: string]: JsonValue;
9
+ };
10
+ /** An HTTP-style status by exception name. */
11
+ export type OutputStatuses = Readonly<Record<string, number>>;
12
+ /** The call of an operation: `context` is what the command (or use case) declares. */
13
+ export interface OperationCallOptions {
14
+ readonly context?: unknown;
15
+ }
16
+ /**
17
+ * One operation of a command, as an output sees it. Frozen; transforms change
18
+ * a copy with `operationOf`.
19
+ */
20
+ export interface OperationDescriptor {
21
+ readonly kind: "operation";
22
+ readonly version: 1;
23
+ /** `"Users.register"`. */
24
+ readonly id: string;
25
+ /** The name of the command. */
26
+ readonly command: string;
27
+ /** The operation name inside the command. */
28
+ readonly name: string;
29
+ /** The `useCaseName`. */
30
+ readonly useCase: string;
31
+ /** The use case description, else the command one. */
32
+ readonly description?: string;
33
+ /** The command tags, then the use case ones, deduplicated. */
34
+ readonly tags: readonly string[];
35
+ readonly deprecated: boolean;
36
+ readonly input: AnyBlueprint;
37
+ readonly response: AnyBlueprint;
38
+ /** The command context, else the use case one. */
39
+ readonly context?: AnyBlueprint;
40
+ /** The `errors` of the use case. */
41
+ readonly errors: readonly AnyExceptionClass[];
42
+ /** Set by transforms; `{}` initially. */
43
+ readonly meta: Readonly<Record<string, unknown>>;
44
+ /** `command.run(name, input, options)`. */
45
+ invoke(input: unknown, options?: OperationCallOptions): Promise<unknown>;
46
+ }
47
+ /** What `operationOf` can change. */
48
+ export interface OperationPatch {
49
+ readonly meta?: Readonly<Record<string, unknown>>;
50
+ readonly tags?: readonly string[];
51
+ readonly description?: string | undefined;
52
+ readonly deprecated?: boolean;
53
+ readonly invoke?: OperationDescriptor["invoke"];
54
+ }
55
+ /** What a stage knows about the output running it. */
56
+ export interface StageContext {
57
+ readonly output: {
58
+ readonly name: string;
59
+ readonly statuses: OutputStatuses;
60
+ };
61
+ }
62
+ /** A stage that changes (or removes, with `null`) each operation. */
63
+ export interface TransformStage<Options extends object = StageOptions> {
64
+ readonly kind: "transform";
65
+ readonly name?: string;
66
+ readonly options?: Options;
67
+ apply(operation: OperationDescriptor, context: StageContext): OperationDescriptor | null;
68
+ }
69
+ /** The last stage: builds something concrete out of the operations. */
70
+ export interface SinkStage<Result = unknown, Options extends object = StageOptions> {
71
+ readonly kind: "sink";
72
+ readonly name?: string;
73
+ readonly options?: Options;
74
+ build(operations: readonly OperationDescriptor[], context: StageContext): Result;
75
+ }
76
+ /** Any stage. */
77
+ export type Stage = TransformStage<any> | SinkStage<any, any>;
78
+ type AnyTransform = TransformStage<any>;
79
+ type AnySink<Result> = SinkStage<Result, any>;
80
+ /** What a stage is, out of band: a name and JSON options, or opaque. */
81
+ export type StageDescription = {
82
+ readonly kind: "transform" | "sink";
83
+ readonly name: string;
84
+ readonly options: StageOptions;
85
+ } | {
86
+ readonly kind: "opaque";
87
+ };
88
+ export interface TransformSettings<Options extends object> {
89
+ readonly name: string;
90
+ /** Returns the operation, a changed copy, or `null` to remove it. */
91
+ readonly apply: (operation: OperationDescriptor, options: Options, context: StageContext) => OperationDescriptor | null;
92
+ /** Why `options` cannot be used, or `undefined`. Checked when the stage is made. */
93
+ readonly validate?: (options: Options) => string | undefined;
94
+ }
95
+ export interface SinkSettings<Result, Options extends object> {
96
+ readonly name: string;
97
+ readonly build: (operations: readonly OperationDescriptor[], options: Options, context: StageContext) => Result;
98
+ /** Why `options` cannot be used, or `undefined`. Checked when the stage is made. */
99
+ readonly validate?: (options: Options) => string | undefined;
100
+ }
101
+ /** Makes a stage from JSON options. */
102
+ export type TransformFactory<Options extends object = StageOptions> = (options?: Options) => TransformStage<Options>;
103
+ export type SinkFactory<Result = unknown, Options extends object = StageOptions> = (options?: Options) => SinkStage<Result, Options>;
104
+ /** Any stage factory. */
105
+ export type StageFactory = TransformFactory<any> | SinkFactory<any, any>;
106
+ /** Stage factories by name. */
107
+ export interface IStageCatalog<Factories extends Readonly<Record<string, StageFactory>> = Readonly<Record<string, StageFactory>>> {
108
+ readonly [Kind]: "stage-catalog";
109
+ readonly stages: Factories;
110
+ readonly list: readonly StageFactory[];
111
+ /** Makes the stage `name` with `options`; throws `InvalidOutputStage` for an unknown name. */
112
+ resolve(name: string, options?: StageOptions): Stage;
113
+ }
114
+ /** The result of the sink at the end of a pipe, or `never` when there is none. */
115
+ export type PipeResult<Pipe extends readonly Stage[]> = Pipe extends readonly [
116
+ ...Stage[],
117
+ SinkStage<infer Result, any>
118
+ ] ? Result : never;
119
+ /** An application, as far as an output is concerned: it gives its commands. */
120
+ export interface OutputApplication {
121
+ readonly [Kind]: "application";
122
+ readonly commands: Readonly<Record<string, AnyCommand>>;
123
+ }
124
+ /** What an output takes its commands from. */
125
+ export type OutputSource = AnyCommand | OutputApplication;
126
+ export interface OutputSettings<Pipe extends readonly Stage[]> {
127
+ readonly name: string;
128
+ /** The commands the output exposes: commands, applications (all their commands) or a mix. */
129
+ readonly commands: OutputApplication | readonly OutputSource[];
130
+ /** HTTP-style status by exception name. */
131
+ readonly statuses?: OutputStatuses;
132
+ readonly pipe?: Pipe;
133
+ }
134
+ /** An output made by `outputOf`. */
135
+ export interface OutputOf<Result = never> {
136
+ readonly [Kind]: "output";
137
+ readonly outputName: string;
138
+ readonly commands: readonly AnyCommand[];
139
+ /** The operations after the transforms, in declaration order. */
140
+ readonly operations: readonly OperationDescriptor[];
141
+ readonly stages: readonly Stage[];
142
+ readonly statuses: OutputStatuses;
143
+ /** The result of the sink (memoized); throws when the pipe has no sink. */
144
+ build(): Result;
145
+ /** The result of the sink when the last stage is one, else a new, unnamed output. */
146
+ pipe<Built>(...stages: [...AnyTransform[], AnySink<Built>]): Built;
147
+ pipe(...stages: Stage[]): OutputOf<never>;
148
+ }
149
+ /** Any output. */
150
+ export type AnyOutput = OutputOf<any>;
151
+ /** An RFC 9457 problem. */
152
+ export interface Problem {
153
+ readonly type: string;
154
+ readonly title: string;
155
+ readonly status: number;
156
+ readonly detail: string;
157
+ readonly layer?: string;
158
+ /** Only for a 400 with validation issues. */
159
+ readonly issues?: readonly {
160
+ readonly path: readonly (string | number)[];
161
+ readonly code: string;
162
+ readonly message: string;
163
+ }[];
164
+ /** Only with `debug`. */
165
+ readonly trace?: string;
166
+ }
167
+ export interface ProblemOptions {
168
+ readonly status: number;
169
+ readonly debug?: boolean;
170
+ }
171
+ export {};
@@ -1,4 +1,4 @@
1
- import type { TSchema } from "typebox";
1
+ import type { Static, TSchema } from "typebox";
2
2
  import type { ParseResult } from "../parse/types/parse.interface.js";
3
3
  import type { StandardSchemaV1 } from "../standard/standard-schema.js";
4
4
  import { State } from "../symbols/state.js";
@@ -9,11 +9,12 @@ import type { AnyPropertyConstructor } from "./types/property-collection.type.js
9
9
  import type { PropertyValue } from "./types/property-constructor.type.js";
10
10
  import type { PropertyOptions } from "./types/property-options.interface.js";
11
11
  import type { IPropertyType } from "./types/property-type.interface.js";
12
- export declare abstract class AbstractProperty<SchemaType extends TSchema> implements IProperty<SchemaType> {
12
+ /** A property instance; `Value` is the value of its schema, as in `ISchema`. */
13
+ export declare abstract class AbstractProperty<SchemaType extends TSchema, Value = Static<SchemaType>> implements IProperty<SchemaType, Value> {
13
14
  get [State](): PropertyStates;
14
- readonly definition: AbstractDefineProperty<SchemaType>;
15
- readonly value: PropertyValue<SchemaType>;
16
- constructor(value: PropertyValue<SchemaType>);
15
+ readonly definition: AbstractDefineProperty<SchemaType, Value>;
16
+ readonly value: PropertyValue<SchemaType, Value>;
17
+ constructor(value: PropertyValue<SchemaType, Value>);
17
18
  /**
18
19
  * Builds an instance from the property's `default` value. Throws if the
19
20
  * property is required and has no `default`.
@@ -32,11 +33,11 @@ export declare abstract class AbstractProperty<SchemaType extends TSchema> imple
32
33
  * `pattern`... are checked along with its own constraints, which they can
33
34
  * only narrow. Its demo value is `default`, or the first of `examples`.
34
35
  */
35
- static with<Self extends AnyPropertyConstructor>(this: Self, options: PropertyOptions<Self["type"] extends IPropertyType<infer SchemaType> ? SchemaType : never>): Self;
36
+ static with<Self extends AnyPropertyConstructor>(this: Self, options: Self["type"] extends IPropertyType<infer SchemaType, infer Value> ? PropertyOptions<SchemaType, Value> : never): Self;
36
37
  /**
37
38
  * The Standard Schema of the class it is read from, a subclass included:
38
39
  * `validate` gives the handled value, or the issues that reject it.
39
40
  */
40
41
  static get "~standard"(): StandardSchemaV1.Props<any, any>;
41
- protected abstract createDefinition(): AbstractDefineProperty<SchemaType>;
42
+ protected abstract createDefinition(): AbstractDefineProperty<SchemaType, Value>;
42
43
  }
@@ -4,15 +4,16 @@ import { State } from "../symbols/state.js";
4
4
  import { PropertyStates } from "./enums/property-states.js";
5
5
  import type { IDefineProperty } from "./types/define-property.interface.js";
6
6
  import type { IPropertyType } from "./types/property-type.interface.js";
7
- export declare abstract class AbstractDefineProperty<SchemaType extends TSchema> implements IDefineProperty<SchemaType> {
7
+ /** How a property handles its value; `Value` is the value of its schema, as in `ISchema`. */
8
+ export declare abstract class AbstractDefineProperty<SchemaType extends TSchema, Value = Static<SchemaType>> implements IDefineProperty<SchemaType, Value> {
8
9
  [State]: PropertyStates;
9
- abstract get type(): IPropertyType<SchemaType>;
10
+ abstract get type(): IPropertyType<SchemaType, Value>;
10
11
  /**
11
12
  * The value handled by the property; throws `PropertyRequired` for
12
13
  * `undefined` on a required property, and `InvalidPropertyValue` (or the
13
14
  * exception of a handler) for a value it rejects.
14
15
  */
15
- make(value: Static<SchemaType>): Static<SchemaType>;
16
+ make(value: Value): Value;
16
17
  /**
17
18
  * Like `make`, but never throws: the handled value, or an issue for each
18
19
  * reason the value is rejected, whose `cause` is the exception `make` would
@@ -21,11 +22,11 @@ export declare abstract class AbstractDefineProperty<SchemaType extends TSchema>
21
22
  * `Exception`, from any step, rejects the value too, as the cause of an
22
23
  * `InvalidPropertyValue`.
23
24
  */
24
- parse(value: unknown): ParseResult<Static<SchemaType>>;
25
- protected preHandle(value: Static<SchemaType>): Static<SchemaType>;
26
- protected afterHandle(value: Static<SchemaType>): Static<SchemaType>;
25
+ parse(value: unknown): ParseResult<Value>;
26
+ protected preHandle(value: Value): Value;
27
+ protected afterHandle(value: Value): Value;
27
28
  /** The value, or `MISMATCH` when the schema rejects it. */
28
- protected handle(value: Static<SchemaType>): Static<SchemaType>;
29
+ protected handle(value: Value): Value;
29
30
  /** `attempt`, with the error of any step as a failure. */
30
31
  private attemptWithoutThrowing;
31
32
  /** Runs the pipeline, updating the state, and tells why it stopped if it did. */
@@ -8,10 +8,15 @@ import type { PropertyValue } from "./types/property-constructor.type.js";
8
8
  import type { PropertyOptions } from "./types/property-options.interface.js";
9
9
  import type { IPropertyType, UniqueMark } from "./types/property-type.interface.js";
10
10
  type SchemaValueType<SchemaType extends TSchema, Optional extends boolean = false> = Optional extends true ? TOptional<SchemaType> : SchemaType;
11
- type PropertyOfArgs<SchemaType extends TSchema, Optional extends boolean = false, Unique extends boolean = false> = {
11
+ /**
12
+ * What `propertyOf` takes. `SchemaType` is inferred from `schema` alone: the
13
+ * value is `NoInfer`, since inferring through `Static` makes TypeScript
14
+ * measure `Static` itself, which costs about a second on every check.
15
+ */
16
+ type PropertyOfArgs<SchemaType extends TSchema, Optional extends boolean = false, Unique extends boolean = false, Value = Static<SchemaType>> = {
12
17
  name: string;
13
18
  schema: SchemaType;
14
- default?: Static<SchemaType>;
19
+ default?: NoInfer<Value>;
15
20
  optional?: Optional;
16
21
  /** A record masks its value in `toJSON`, at any depth, as `Password`. */
17
22
  sensitive?: boolean;
@@ -20,27 +25,33 @@ type PropertyOfArgs<SchemaType extends TSchema, Optional extends boolean = false
20
25
  * do not check it, repositories (or the database) enforce it.
21
26
  */
22
27
  unique?: Unique;
23
- preHandle?: (value: Static<SchemaType>) => Static<SchemaType>;
24
- afterHandle?: (value: Static<SchemaType>) => Static<SchemaType>;
28
+ preHandle?: (value: NoInfer<Value>) => NoInfer<Value>;
29
+ afterHandle?: (value: NoInfer<Value>) => NoInfer<Value>;
25
30
  };
26
- /** The instance type of a class declared with `propertyOf`. */
27
- export declare class DeclaredProperty<SchemaType extends TSchema> extends AbstractProperty<SchemaType> {
28
- protected createDefinition(): AbstractDefineProperty<SchemaType>;
31
+ /**
32
+ * The instance type of a class declared with `propertyOf`; `Value` is the
33
+ * value of its schema, as in `ISchema`.
34
+ */
35
+ export declare class DeclaredProperty<SchemaType extends TSchema, Value = Static<SchemaType>> extends AbstractProperty<SchemaType, Value> {
36
+ protected createDefinition(): AbstractDefineProperty<SchemaType, Value>;
29
37
  }
30
- /** A class declared with `propertyOf`; extend it to add behavior, as `Id` does. */
31
- export interface PropertyClass<SchemaType extends TSchema> {
32
- new (value: PropertyValue<SchemaType>): DeclaredProperty<SchemaType>;
33
- readonly type: IPropertyType<SchemaType>;
38
+ /**
39
+ * A class declared with `propertyOf`; extend it to add behavior, as `Id` does.
40
+ * `Value` is the value of its schema, as in `ISchema`.
41
+ */
42
+ export interface PropertyClass<SchemaType extends TSchema, Value = Static<SchemaType>> {
43
+ new (value: PropertyValue<SchemaType, Value>): DeclaredProperty<SchemaType, Value>;
44
+ readonly type: IPropertyType<SchemaType, Value>;
34
45
  /** The value handled by the property, or every issue that rejects `value`; never throws. */
35
- safeParse(value: unknown): ParseResult<PropertyValue<SchemaType>>;
46
+ safeParse(value: unknown): ParseResult<PropertyValue<SchemaType, Value>>;
36
47
  /** The Standard Schema of the class: `validate` gives the handled value. */
37
- readonly "~standard": StandardSchemaV1.Props<PropertyValue<SchemaType>, PropertyValue<SchemaType>>;
48
+ readonly "~standard": StandardSchemaV1.Props<PropertyValue<SchemaType, Value>, PropertyValue<SchemaType, Value>>;
38
49
  /**
39
50
  * A subclass narrowed and documented by `options`, e.g.
40
51
  * `Integer.with({ min: 1, description: "Age in years" })`.
41
52
  */
42
- with<Self extends AnyPropertyConstructor>(this: Self, options: PropertyOptions<SchemaType>): Self;
53
+ with<Self extends AnyPropertyConstructor>(this: Self, options: PropertyOptions<SchemaType, Value>): Self;
43
54
  demo<Self extends AbstractProperty<any>>(this: new (value: never) => Self): Self;
44
55
  }
45
- export declare function propertyOf<SchemaType extends TSchema, Optional extends boolean = false, const Unique extends boolean = false>({ name, schema, optional, sensitive, unique, default: _default, preHandle: onPreHandle, afterHandle: onAfterHandle, }: PropertyOfArgs<SchemaType, Optional, Unique>): PropertyClass<SchemaValueType<SchemaType, Optional>> & UniqueMark<Unique>;
56
+ export declare function propertyOf<SchemaType extends TSchema, Optional extends boolean = false, const Unique extends boolean = false>({ name, schema, optional, sensitive, unique, default: _default, preHandle: onPreHandle, afterHandle: onAfterHandle, }: PropertyOfArgs<SchemaType, Optional, Unique>): PropertyClass<SchemaValueType<SchemaType, Optional>, Static<SchemaType>> & UniqueMark<Unique>;
46
57
  export {};
@@ -1,13 +1,14 @@
1
- import type { TSchema } from "typebox";
1
+ import type { Static, TSchema } from "typebox";
2
2
  import type { ParseResult } from "../../parse/types/parse.interface.js";
3
3
  import type { StandardSchemaV1 } from "../../standard/standard-schema.js";
4
4
  import type { AbstractProperty } from "../abstract-property.js";
5
5
  import type { PropertyValue } from "./property-constructor.type.js";
6
6
  import type { IPropertyType } from "./property-type.interface.js";
7
- export type AbstractPropertyConstructor<SchemaType extends TSchema> = {
8
- new (value: PropertyValue<SchemaType>): AbstractProperty<SchemaType>;
9
- readonly type: IPropertyType<SchemaType>;
10
- demo(): AbstractProperty<SchemaType>;
11
- safeParse(value: unknown): ParseResult<PropertyValue<SchemaType>>;
12
- readonly "~standard": StandardSchemaV1.Props<PropertyValue<SchemaType>, PropertyValue<SchemaType>>;
7
+ /** A property class; `Value` is the value of its schema, as in `ISchema`. */
8
+ export type AbstractPropertyConstructor<SchemaType extends TSchema, Value = Static<SchemaType>> = {
9
+ new (value: PropertyValue<SchemaType, Value>): AbstractProperty<SchemaType, Value>;
10
+ readonly type: IPropertyType<SchemaType, Value>;
11
+ demo(): AbstractProperty<SchemaType, Value>;
12
+ safeParse(value: unknown): ParseResult<PropertyValue<SchemaType, Value>>;
13
+ readonly "~standard": StandardSchemaV1.Props<PropertyValue<SchemaType, Value>, PropertyValue<SchemaType, Value>>;
13
14
  };
@@ -3,10 +3,11 @@ import type { ParseResult } from "../../parse/types/parse.interface.js";
3
3
  import { State } from "../../symbols/state.js";
4
4
  import type { PropertyStates } from "../enums/property-states.js";
5
5
  import type { IPropertyType } from "./property-type.interface.js";
6
- export interface IDefineProperty<SchemaType extends TSchema> {
6
+ /** How a property handles its value; `Value` is the value of its schema, as in `ISchema`. */
7
+ export interface IDefineProperty<SchemaType extends TSchema, Value = Static<SchemaType>> {
7
8
  [State]: PropertyStates;
8
- get type(): IPropertyType<SchemaType>;
9
- make(value: Static<SchemaType>): Static<SchemaType>;
9
+ get type(): IPropertyType<SchemaType, Value>;
10
+ make(value: Value): Value;
10
11
  /** Like `make`, but returns the issues of a rejected value instead of throwing. */
11
- parse(value: unknown): ParseResult<Static<SchemaType>>;
12
+ parse(value: unknown): ParseResult<Value>;
12
13
  }
@@ -11,10 +11,10 @@ import type { IPropertyType, UniqueTypeOf } from "./property-type.interface.js";
11
11
  * own methods and statics (e.g. `Password#verify`, `Id.generate`) are kept.
12
12
  */
13
13
  export type OptionalProperty<Property extends AnyPropertyConstructor> = Property extends {
14
- readonly type: IPropertyType<infer SchemaType>;
14
+ readonly type: IPropertyType<infer SchemaType, infer Value>;
15
15
  } ? SchemaType extends TOptional<TSchema> ? StoredField<Property> : Omit<Property, "type" | "prototype" | "safeParse" | "~standard" | CallableKey> & {
16
- new (value: PropertyValue<TOptional<SchemaType>>): AbstractProperty<TOptional<SchemaType>> & Omit<InstanceType<Property>, keyof AbstractProperty<TSchema>>;
17
- readonly type: IPropertyType<TOptional<SchemaType>> & UniqueTypeOf<Property>;
18
- safeParse(value: unknown): ParseResult<PropertyValue<TOptional<SchemaType>>>;
19
- readonly "~standard": StandardSchemaV1.Props<PropertyValue<TOptional<SchemaType>>, PropertyValue<TOptional<SchemaType>>>;
16
+ new (value: PropertyValue<TOptional<SchemaType>, Value>): AbstractProperty<TOptional<SchemaType>, Value> & Omit<InstanceType<Property>, keyof AbstractProperty<TSchema>>;
17
+ readonly type: IPropertyType<TOptional<SchemaType>, Value> & UniqueTypeOf<Property>;
18
+ safeParse(value: unknown): ParseResult<PropertyValue<TOptional<SchemaType>, Value>>;
19
+ readonly "~standard": StandardSchemaV1.Props<PropertyValue<TOptional<SchemaType>, Value>, PropertyValue<TOptional<SchemaType>, Value>>;
20
20
  } : never;
@@ -7,8 +7,8 @@ import type { IPropertyType } from "./property-type.interface.js";
7
7
  * to `unknown`, which a constructor taking a narrower value would reject.
8
8
  */
9
9
  export type AnyPropertyConstructor = {
10
- new (value: any): AbstractProperty<any>;
11
- readonly type: IPropertyType<any>;
10
+ new (value: any): AbstractProperty<any, any>;
11
+ readonly type: IPropertyType<any, any>;
12
12
  safeParse(value: unknown): ParseResult<any>;
13
13
  readonly "~standard": StandardSchemaV1.Props<any, any>;
14
14
  };
@@ -1,2 +1,6 @@
1
1
  import type { Static, TOptional, TSchema } from "typebox";
2
- export type PropertyValue<SchemaType extends TSchema> = SchemaType extends TOptional<TSchema> ? Static<SchemaType> | undefined : Static<SchemaType>;
2
+ /**
3
+ * The value a property holds: the value of its schema, or `undefined` too
4
+ * when it is optional. `Value` is the value of the schema, as in `ISchema`.
5
+ */
6
+ export type PropertyValue<SchemaType extends TSchema, Value = Static<SchemaType>> = SchemaType extends TOptional<TSchema> ? Value | undefined : Value;
@@ -46,7 +46,7 @@ export interface StringConstraints {
46
46
  * What `Property.with` and `ctx.<property>(options)` take: the metadata of any
47
47
  * property, plus the constraints of its kind of schema, for strings and numbers.
48
48
  */
49
- export type PropertyOptions<SchemaType extends TSchema> = PropertyMetadata<NonNullable<Static<SchemaType>>> & (SchemaType extends TString ? StringConstraints : SchemaType extends TNumber | TInteger ? NumberConstraints : unknown);
49
+ export type PropertyOptions<SchemaType extends TSchema, Value = Static<SchemaType>> = PropertyMetadata<NonNullable<Value>> & (SchemaType extends TString ? StringConstraints : SchemaType extends TNumber | TInteger ? NumberConstraints : unknown);
50
50
  /**
51
51
  * Brands a `CallableProperty` with the property it stands for.
52
52
  *
@@ -60,18 +60,27 @@ export declare const Callable: unique symbol;
60
60
  export type CallableProperty<Property extends {
61
61
  readonly type: IPropertyType<TSchema>;
62
62
  }> = Property & {
63
- (options?: PropertyOptions<SchemaOfProperty<Property>>): Property;
63
+ (options?: OptionsOfProperty<Property>): Property;
64
64
  readonly [Callable]: Property;
65
65
  };
66
- /** The schema of a property class. */
67
- type SchemaOfProperty<Property> = Property extends {
68
- readonly type: IPropertyType<infer SchemaType>;
69
- } ? SchemaType : TSchema;
70
- /** `Field`, or the property it stands for when it is a `CallableProperty`, as a blueprint stores it. */
66
+ /**
67
+ * The `PropertyOptions` of a property class, from its schema and the value
68
+ * its type carries, so `Static` is not measured again.
69
+ */
70
+ type OptionsOfProperty<Property> = Property extends {
71
+ readonly type: IPropertyType<infer SchemaType, infer Value>;
72
+ } ? PropertyOptions<SchemaType, Value> : PropertyOptions<TSchema>;
73
+ /**
74
+ * `Field`, or the property it stands for when it is a `CallableProperty`, as a blueprint stores it.
75
+ * @internal
76
+ */
71
77
  export type StoredField<Field> = Field extends {
72
78
  readonly [Callable]: infer Property;
73
79
  } ? Property : Field;
74
- /** `StoredField` of every field of a collection. */
80
+ /**
81
+ * `StoredField` of every field of a collection.
82
+ * @internal
83
+ */
75
84
  export type StoredFields<Fields> = {
76
85
  [Key in keyof Fields]: StoredField<Fields[Key]>;
77
86
  };
@@ -1,11 +1,15 @@
1
1
  import type { Static, TSchema } from "typebox";
2
2
  import type { ISchema } from "../../schema/types/schema.interface.js";
3
3
  import { Demo } from "../../symbols/demo.js";
4
- export interface IPropertyType<SchemaType extends TSchema> {
4
+ /**
5
+ * What a property declares about itself. `Value` is the value of its schema,
6
+ * computed where `SchemaType` is known, as in `ISchema`.
7
+ */
8
+ export interface IPropertyType<SchemaType extends TSchema, Value = Static<SchemaType>> {
5
9
  /** Value used by `demo()`; it is the property's `default`, when there is one. */
6
- readonly [Demo]: Static<SchemaType> | undefined;
10
+ readonly [Demo]: Value | undefined;
7
11
  readonly name: string;
8
- readonly schema: ISchema<SchemaType>;
12
+ readonly schema: ISchema<SchemaType, Value>;
9
13
  readonly optional?: boolean;
10
14
  /** Whether a record masks its value in `toJSON`, at any depth. */
11
15
  readonly sensitive?: boolean;
@@ -1,7 +1,8 @@
1
- import type { TSchema } from "typebox";
1
+ import type { Static, TSchema } from "typebox";
2
2
  import type { AbstractDefineProperty } from "../define-property.js";
3
3
  import type { PropertyValue } from "./property-constructor.type.js";
4
- export interface IProperty<SchemaType extends TSchema> {
5
- readonly definition: AbstractDefineProperty<SchemaType>;
6
- readonly value: PropertyValue<SchemaType>;
4
+ /** A property instance; `Value` is the value of its schema, as in `ISchema`. */
5
+ export interface IProperty<SchemaType extends TSchema, Value = Static<SchemaType>> {
6
+ readonly definition: AbstractDefineProperty<SchemaType, Value>;
7
+ readonly value: PropertyValue<SchemaType, Value>;
7
8
  }
@@ -1,7 +1,13 @@
1
1
  import type { BlueprintData, BlueprintField, BlueprintInput, BlueprintValue, IBlueprint, IBlueprintCollection } from "../blueprint/types/blueprint.interface.js";
2
2
  import type { ParseResult } from "../parse/types/parse.interface.js";
3
3
  import type { StandardSchemaV1 } from "../standard/standard-schema.js";
4
+ import { Meta } from "../symbols/meta.js";
4
5
  import type { IRecord, RecordChange, RecordEffects, RecordSettings } from "./types/record.interface.js";
6
+ /** The statics of a class made by `recordOf`, that its records read. */
7
+ interface RecordDeclaration<Properties extends IBlueprintCollection> {
8
+ readonly blueprint: IBlueprint<Properties>;
9
+ readonly options: RecordSettings<Properties>;
10
+ }
5
11
  /**
6
12
  * The names of the record's own members, and of those every object inherits
7
13
  * (`toString`, `valueOf`, `__proto__`...), which no key of a blueprint can take.
@@ -32,8 +38,10 @@ export declare function recordFieldDataOf(field: BlueprintField | undefined, val
32
38
  * and the one it replaced.
33
39
  */
34
40
  export declare function storeRecordValue(record: {
35
- readonly blueprint: {
36
- readonly properties: IBlueprintCollection;
41
+ readonly [Meta]: {
42
+ readonly blueprint: {
43
+ readonly properties: IBlueprintCollection;
44
+ };
37
45
  };
38
46
  }, key: string, value: unknown): {
39
47
  readonly next: unknown;
@@ -47,8 +55,7 @@ export declare const RecordPluginHooks: unique symbol;
47
55
  */
48
56
  export declare function runRecordEffects<Self extends object>(record: Self, key: PropertyKey, next: unknown, previous: unknown): Self;
49
57
  export declare abstract class AbstractRecord<Properties extends IBlueprintCollection> implements IRecord<Properties> {
50
- readonly blueprint: IBlueprint<Properties>;
51
- readonly options: RecordSettings<Properties>;
58
+ get [Meta](): RecordDeclaration<Properties>;
52
59
  constructor(value: BlueprintInput<Properties>);
53
60
  /**
54
61
  * An instance of the class for `value`, each key handled, or every issue
@@ -82,3 +89,4 @@ export declare abstract class AbstractRecord<Properties extends IBlueprintCollec
82
89
  */
83
90
  protected onSet(): RecordEffects<IRecord<Properties>>;
84
91
  }
92
+ export {};
@@ -90,13 +90,17 @@ export interface IRecordPluginCatalog<Plugins extends Readonly<globalThis.Record
90
90
  /** `resolve` for each of `references`, e.g. `JSON.parse(JSON.stringify(Post.plugins))`. */
91
91
  resolveAll(references: readonly RecordPluginReference[]): readonly AnyRecordPlugin[];
92
92
  }
93
- /** The plugins of a catalog made of `Plugins`, by name. */
93
+ /**
94
+ * The plugins of a catalog made of `Plugins`, by name.
95
+ * @internal
96
+ */
94
97
  export type RecordPluginsByName<Plugins extends readonly AnyRecordPlugin[]> = {
95
98
  readonly [Plugin in Plugins[number] as Plugin["name"]]: Plugin;
96
99
  };
97
100
  /**
98
101
  * What `options.plugins` picks from: the plugins of every catalog, by name; a
99
102
  * later catalog replaces a plugin of an earlier one with the same name.
103
+ * @internal
100
104
  */
101
105
  export type RecordPluginContext<Catalogs extends readonly IRecordPluginCatalog[]> = Catalogs extends readonly [
102
106
  infer Head extends IRecordPluginCatalog,
@@ -111,7 +115,10 @@ type PluginProperties<Plugin> = Plugin extends {
111
115
  readonly blueprint: IBlueprint<infer Properties, boolean>;
112
116
  };
113
117
  } ? Properties : never;
114
- /** The fields of a record, and those of each of its plugins. */
118
+ /**
119
+ * The fields of a record, and those of each of its plugins.
120
+ * @internal
121
+ */
115
122
  export type WithPluginProperties<Properties extends IBlueprintCollection, Plugins extends readonly AnyRecordPlugin[]> = [Plugins[number]] extends [never] ? Properties : Properties & UnionToIntersection<PluginProperties<Plugins[number]>> extends infer Merged ? {
116
123
  readonly [Key in keyof Merged]: Merged[Key];
117
124
  } : never;
@@ -119,7 +126,10 @@ export type WithPluginProperties<Properties extends IBlueprintCollection, Plugin
119
126
  type PluginInstance<Plugin> = Plugin extends {
120
127
  readonly record: abstract new (value: never) => infer Instance;
121
128
  } ? Instance : never;
122
- /** What the plugins add to the records they are applied to: their keys and methods. */
129
+ /**
130
+ * What the plugins add to the records they are applied to: their keys and methods.
131
+ * @internal
132
+ */
123
133
  export type PluginMembers<Plugins extends readonly AnyRecordPlugin[]> = [
124
134
  Plugins[number]
125
135
  ] extends [never] ? unknown : UnionToIntersection<PluginInstance<Plugins[number]>>;
@@ -1,14 +1,25 @@
1
- import type { BlueprintData, BlueprintInput, BlueprintValue, IBlueprint, IBlueprintCollection, RecordAccepts } from "../../blueprint/types/blueprint.interface.js";
1
+ import type { AnyBlueprint, BlueprintData, BlueprintInput, BlueprintValue, IBlueprint, IBlueprintCollection, RecordAccepts } from "../../blueprint/types/blueprint.interface.js";
2
2
  import type { ParseResult } from "../../parse/types/parse.interface.js";
3
3
  import type { StandardSchemaV1 } from "../../standard/standard-schema.js";
4
4
  import type { Kind } from "../../symbols/kind.js";
5
+ import type { Meta } from "../../symbols/meta.js";
5
6
  import type { AbstractRecord } from "../abstract-record.js";
6
7
  import type { AnyRecordPlugin, RecordPluginsOption, RecordUniqueKeys } from "./plugin.interface.js";
7
8
  /** The value of a record, read from its blueprint. */
8
- export type RecordValue<Record extends AnyRecordShape> = Record["blueprint"] extends IBlueprint<infer Properties> ? BlueprintValue<Properties> : never;
9
- /** Anything with a blueprint, as records are. */
9
+ export type RecordValue<Record extends AnyRecordShape> = Record extends {
10
+ readonly [Meta]: {
11
+ readonly blueprint: IBlueprint<infer Properties>;
12
+ };
13
+ } ? BlueprintValue<Properties> : Record extends {
14
+ readonly blueprint: IBlueprint<infer Properties>;
15
+ } ? BlueprintValue<Properties> : never;
16
+ /** A record instance's metadata, or a record class's statics. */
10
17
  type AnyRecordShape = {
11
- readonly blueprint: IBlueprint<any>;
18
+ readonly blueprint: AnyBlueprint;
19
+ } | {
20
+ readonly [Meta]: {
21
+ readonly blueprint: AnyBlueprint;
22
+ };
12
23
  };
13
24
  /** A side effect of a change to a key: its new value and the one it replaced. */
14
25
  export type RecordEffect<Value> = (value: Value, previous: Value) => void;
@@ -81,10 +92,11 @@ type RecordChangeMethods<Self, Properties extends IBlueprintCollection, Key exte
81
92
  readonly [K in Key]: (value: K extends keyof BlueprintValue<Properties> ? BlueprintValue<Properties>[K] : never) => Self;
82
93
  };
83
94
  export interface IRecord<Properties extends IBlueprintCollection> {
84
- /** The blueprint whose shape the record implements. */
85
- readonly blueprint: IBlueprint<Properties>;
86
- /** Which keys are sensitive, unique or have a `change.<key>` method. */
87
- readonly options: RecordSettings<Properties>;
95
+ /** Declaration metadata, separate from domain keys. */
96
+ readonly [Meta]: {
97
+ readonly blueprint: IBlueprint<Properties>;
98
+ readonly options: RecordSettings<Properties>;
99
+ };
88
100
  /** The value with the sensitive keys, and every `sensitive` property, masked. */
89
101
  toJSON(): Readonly<Partial<BlueprintData<Properties>>>;
90
102
  }
@@ -1,3 +1,7 @@
1
+ /** A query contains unsupported keys, ordering or pagination. */
2
+ export declare const InvalidRepositoryQuery: import("../../index.js").DeclaredExceptionClass<{
3
+ readonly reason: string;
4
+ }>;
1
5
  /** `repositoryOf` got something other than an entity, actions and a provider. */
2
6
  export declare const InvalidRepositoryDeclaration: import("../../index.js").DeclaredExceptionClass<{
3
7
  readonly reason: string;
@@ -3,5 +3,8 @@ import type { IRepositoryProvider } from "./types/repository.interface.js";
3
3
  * A provider that keeps the values in memory, one table per entity class,
4
4
  * enforcing its unique keys. Each `repositoryOf` without a provider gets its
5
5
  * own; repositories given the same one share the tables of their entities.
6
+ * Its `transaction` works on isolated snapshots: commits on success, discards
7
+ * on rejection, runs one at a time and makes other operations wait; nested
8
+ * transactions are savepoints.
6
9
  */
7
10
  export declare function inMemoryProvider(): IRepositoryProvider;
@@ -0,0 +1,6 @@
1
+ import type { ProviderDescription, ProviderOptions, ProviderSettings } from "./types/query.interface.js";
2
+ import type { IRepositoryProvider } from "./types/repository.interface.js";
3
+ /** Creates a provider once and attaches an immutable, serializable declaration out of band. */
4
+ export declare function providerOf<Options extends ProviderOptions = ProviderOptions, Provider extends IRepositoryProvider = IRepositoryProvider>(settings: ProviderSettings<Options, Provider>): Provider;
5
+ /** Describes a named provider; an anonymous one needs an explicit import on extraction. */
6
+ export declare function providerDescriptionOf(provider: IRepositoryProvider): ProviderDescription;