@afora/core 0.0.2 → 0.0.3
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.
- package/README.md +220 -733
- package/dist/core/application/application.d.ts +9 -1
- package/dist/core/application/exceptions.d.ts +28 -0
- package/dist/core/application/registry.d.ts +33 -0
- package/dist/core/application/start.d.ts +51 -0
- package/dist/core/application/types/application.interface.d.ts +186 -7
- package/dist/core/blueprint/types/blueprint.interface.d.ts +66 -11
- package/dist/core/blueprint/types/slice.interface.d.ts +7 -2
- package/dist/core/command/command.d.ts +25 -0
- package/dist/core/command/exceptions.d.ts +33 -0
- package/dist/core/command/types/command.interface.d.ts +102 -0
- package/dist/core/environment/environment.d.ts +4 -1
- package/dist/core/exception/exception.d.ts +4 -0
- package/dist/core/exception/exported.d.ts +4 -0
- package/dist/core/json.d.ts +10 -0
- package/dist/core/output/exceptions.d.ts +8 -0
- package/dist/core/output/openapi-sink.d.ts +83 -0
- package/dist/core/output/output.d.ts +19 -0
- package/dist/core/output/problem.d.ts +15 -0
- package/dist/core/output/select.d.ts +14 -0
- package/dist/core/output/stage.d.ts +24 -0
- package/dist/core/output/status.d.ts +17 -0
- package/dist/core/output/types/output.interface.d.ts +171 -0
- package/dist/core/property/abstract-property.d.ts +8 -7
- package/dist/core/property/define-property.d.ts +8 -7
- package/dist/core/property/property.d.ts +26 -15
- package/dist/core/property/types/abstract-property-constructor.type.d.ts +8 -7
- package/dist/core/property/types/define-property.interface.d.ts +5 -4
- package/dist/core/property/types/optional-property.type.d.ts +5 -5
- package/dist/core/property/types/property-collection.type.d.ts +2 -2
- package/dist/core/property/types/property-constructor.type.d.ts +5 -1
- package/dist/core/property/types/property-options.interface.d.ts +17 -8
- package/dist/core/property/types/property-type.interface.d.ts +7 -3
- package/dist/core/property/types/property.interface.d.ts +5 -4
- package/dist/core/record/abstract-record.d.ts +12 -4
- package/dist/core/record/types/plugin.interface.d.ts +13 -3
- package/dist/core/record/types/record.interface.d.ts +20 -8
- package/dist/core/repository/exceptions.d.ts +4 -0
- package/dist/core/repository/in-memory.d.ts +3 -0
- package/dist/core/repository/provider.d.ts +6 -0
- package/dist/core/repository/query.d.ts +9 -0
- package/dist/core/repository/references.d.ts +4 -2
- package/dist/core/repository/repository.d.ts +4 -2
- package/dist/core/repository/state.d.ts +4 -0
- package/dist/core/repository/types/query.interface.d.ts +67 -0
- package/dist/core/repository/types/repository.interface.d.ts +13 -13
- package/dist/core/schema/types/schema.interface.d.ts +11 -4
- package/dist/core/symbols/meta.d.ts +2 -0
- package/dist/core/use-case/exceptions.d.ts +10 -0
- package/dist/core/use-case/scope.d.ts +21 -0
- package/dist/core/use-case/steps/describe.d.ts +13 -0
- package/dist/core/use-case/steps/references.d.ts +27 -0
- package/dist/core/use-case/steps/run.d.ts +20 -0
- package/dist/core/use-case/steps/types/steps.interface.d.ts +153 -0
- package/dist/core/use-case/steps/validate.d.ts +17 -0
- package/dist/core/use-case/use-case.d.ts +74 -9
- package/dist/experimental.d.ts +6 -0
- package/dist/experimental.js +123 -0
- package/dist/index-hn82hm31.js +1651 -0
- package/dist/index-sw2b9ehx.js +5019 -0
- package/dist/index.d.ts +30 -11
- package/dist/index.js +325 -4142
- package/dist/std/blueprint-plugin.d.ts +10 -10
- package/dist/std/blueprint.d.ts +10 -10
- package/dist/std/entity.d.ts +2 -2
- package/dist/std/properties/contact.d.ts +4 -4
- package/dist/std/properties/enum.d.ts +1 -1
- package/dist/std/properties/headless.d.ts +1 -1
- package/dist/std/properties/identity.d.ts +2 -2
- package/dist/std/properties/password.d.ts +1 -1
- package/dist/std/properties/primitives.d.ts +5 -5
- package/dist/std/properties/time.d.ts +2 -2
- package/dist/std/record-plugins.d.ts +12 -12
- package/dist/std/record.d.ts +1 -1
- package/dist/std/stages.d.ts +2 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +502 -0
- package/dist/testing/provider-contract.d.ts +22 -0
- package/package.json +28 -8
|
@@ -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
|
-
|
|
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?:
|
|
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:
|
|
24
|
-
afterHandle?: (value:
|
|
28
|
+
preHandle?: (value: NoInfer<Value>) => NoInfer<Value>;
|
|
29
|
+
afterHandle?: (value: NoInfer<Value>) => NoInfer<Value>;
|
|
25
30
|
};
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
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:
|
|
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<
|
|
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
|
|
17
|
-
readonly type: IPropertyType<TOptional<SchemaType
|
|
18
|
-
safeParse(value: unknown): ParseResult<PropertyValue<TOptional<SchemaType
|
|
19
|
-
readonly "~standard": StandardSchemaV1.Props<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
|
-
|
|
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
|
|
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?:
|
|
63
|
+
(options?: OptionsOfProperty<Property>): Property;
|
|
64
64
|
readonly [Callable]: Property;
|
|
65
65
|
};
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
/**
|
|
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
|
-
|
|
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]:
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
readonly
|
|
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
|
|
36
|
-
readonly
|
|
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
|
-
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
|
9
|
-
|
|
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:
|
|
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
|
-
/**
|
|
85
|
-
readonly
|
|
86
|
-
|
|
87
|
-
|
|
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;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RepositoryQuery } from "./types/query.interface.js";
|
|
2
|
+
import type { RepositoryContext, RepositoryData } from "./types/repository.interface.js";
|
|
3
|
+
/** Validates query structure and optionally normalizes domain values for storage. */
|
|
4
|
+
export declare function prepareQuery(context: RepositoryContext, input?: unknown, map?: (key: string, value: unknown) => unknown): RepositoryQuery;
|
|
5
|
+
/** Structural JSON/data equality without depending on object key insertion order. */
|
|
6
|
+
export declare function sameValue(a: unknown, b: unknown): boolean;
|
|
7
|
+
export declare function matchesQuery(data: RepositoryData, query: RepositoryQuery): boolean;
|
|
8
|
+
/** The rows of `query` after ordering, offset and limit. */
|
|
9
|
+
export declare function selectRows(rows: Iterable<RepositoryData>, query: RepositoryQuery): RepositoryData[];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ExecutionScope } from "../use-case/scope.js";
|
|
1
2
|
import { type RepositoryState } from "./state.js";
|
|
2
3
|
import type { AnyRepositoryEntity, RepositoryData } from "./types/repository.interface.js";
|
|
3
4
|
/** The relations of a repository of `entity` named `name`, one for each entity class it holds. */
|
|
@@ -11,6 +12,7 @@ export type ReferenceSession = Map<RepositoryState, Map<string, object>>;
|
|
|
11
12
|
* entity they hold replaced by the entity, loaded in one batch for each
|
|
12
13
|
* relation. An entity loaded twice in `session` is the same instance. Throws
|
|
13
14
|
* `InvalidRepositoryData`, caused by `RepositoryEntityNotFound`, for an id
|
|
14
|
-
* with no entity.
|
|
15
|
+
* with no entity. The providers of the `scope` of the call, if any, replace
|
|
16
|
+
* those of the relations.
|
|
15
17
|
*/
|
|
16
|
-
export declare function resolveReferences(state: RepositoryState, datas: readonly RepositoryData[], session: ReferenceSession): Promise<readonly RepositoryData[]>;
|
|
18
|
+
export declare function resolveReferences(state: RepositoryState, datas: readonly RepositoryData[], session: ReferenceSession, scope?: ExecutionScope): Promise<readonly RepositoryData[]>;
|
|
@@ -7,6 +7,8 @@ export interface RepositorySettings<Entity extends AnyRepositoryEntity, Actions
|
|
|
7
7
|
readonly entity: Entity;
|
|
8
8
|
/** Its methods, e.g. `["findById", "findByEmail", "findManyByName", "create"]`. */
|
|
9
9
|
readonly actions: Actions;
|
|
10
|
+
/** Physically remove rows (default), or retain them with `deletedAt`. */
|
|
11
|
+
readonly deletion?: "hard" | "soft";
|
|
10
12
|
/** How it reads and writes; a new `inMemoryProvider()` by default. */
|
|
11
13
|
readonly provider?: IRepositoryProvider<MergedEnvironment<Environment>>;
|
|
12
14
|
/** The environments the provider gets, merged, as `context.env`. */
|
|
@@ -49,8 +51,8 @@ export declare abstract class AbstractRepository<Entity extends AnyRepositoryEnt
|
|
|
49
51
|
* A repository of `entity` with the methods of `actions`: `findBy<Key>` for a
|
|
50
52
|
* unique key (`id`, `options.unique`, a `unique` property), giving the entity
|
|
51
53
|
* or `undefined`; `findManyBy<Key>` for any other key, giving a list;
|
|
52
|
-
* `create`, `update`, `delete`
|
|
53
|
-
* and `
|
|
54
|
+
* `create`, `update`, `delete`, `count`, and the queries `findMany`,
|
|
55
|
+
* `exists` and `findPage`. Every method is async and reads and writes through `provider`
|
|
54
56
|
* (a new `inMemoryProvider()` by default), which gets the variables of
|
|
55
57
|
* `environmentDependencies` as `context.env`. The repository can be a
|
|
56
58
|
* dependency of a use case, and `RepositoryOf` extends it with a class.
|
|
@@ -5,6 +5,7 @@ export interface RepositoryState {
|
|
|
5
5
|
readonly name: string;
|
|
6
6
|
readonly entity: AnyRepositoryEntity;
|
|
7
7
|
readonly actions: readonly string[];
|
|
8
|
+
readonly deletion: "hard" | "soft";
|
|
8
9
|
readonly provider: IRepositoryProvider;
|
|
9
10
|
/** Whether `settings.provider` was given, and not the default one. */
|
|
10
11
|
readonly explicitProvider: boolean;
|
|
@@ -24,7 +25,10 @@ export declare function contextOf(state: RepositoryState): RepositoryContext;
|
|
|
24
25
|
export interface RepositoryInspection {
|
|
25
26
|
readonly entity: AnyRepositoryEntity;
|
|
26
27
|
readonly actions: readonly string[];
|
|
28
|
+
readonly deletion: "hard" | "soft";
|
|
27
29
|
readonly explicitProvider: boolean;
|
|
30
|
+
/** The provider, only when the repository declared it. */
|
|
31
|
+
readonly provider: IRepositoryProvider | undefined;
|
|
28
32
|
readonly environments: readonly object[];
|
|
29
33
|
/** The repository state of each related entity class; compare with `inspect(...).state`. */
|
|
30
34
|
readonly relations: readonly object[];
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { EntityInstanceOf, EntityKeyOf, EntityValueOf, IRepositoryProvider, QueryValueOf } from "./repository.interface.js";
|
|
2
|
+
type QueryKey<Entity> = unknown extends Entity ? string : EntityKeyOf<Entity>;
|
|
3
|
+
type QueryValue<Entity, Key extends string> = unknown extends Entity ? unknown : Key extends keyof EntityValueOf<Entity> ? QueryValueOf<EntityValueOf<Entity>[Key]> : unknown;
|
|
4
|
+
/** Equality, or membership in a list. Conditions on different keys are ANDed. */
|
|
5
|
+
export type RepositoryWhere<Entity = unknown> = {
|
|
6
|
+
readonly [Key in QueryKey<Entity>]?: QueryValue<Entity, Key> | {
|
|
7
|
+
readonly in: readonly QueryValue<Entity, Key>[];
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
/** Ordered lexicographically; ties retain provider order. Missing values sort first. */
|
|
11
|
+
export interface RepositoryOrder<Key extends string = string> {
|
|
12
|
+
readonly key: Key;
|
|
13
|
+
readonly direction?: "asc" | "desc";
|
|
14
|
+
}
|
|
15
|
+
/** The v2 query shared by providers and typed repository reads. */
|
|
16
|
+
export interface RepositoryQuery<Entity = unknown> {
|
|
17
|
+
readonly where?: RepositoryWhere<Entity>;
|
|
18
|
+
readonly orderBy?: readonly RepositoryOrder<QueryKey<Entity>>[];
|
|
19
|
+
/** Nonnegative integer; zero returns an empty result. */
|
|
20
|
+
readonly limit?: number;
|
|
21
|
+
/** Nonnegative integer, applied before limit. */
|
|
22
|
+
readonly offset?: number;
|
|
23
|
+
/** Include destroyed rows; repository defaults depend on its deletion policy. */
|
|
24
|
+
readonly withDeleted?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** A page and the unpaginated number of matching live (or explicitly included) rows. */
|
|
27
|
+
export interface RepositoryPage<Entity> {
|
|
28
|
+
readonly items: readonly EntityInstanceOf<Entity>[];
|
|
29
|
+
readonly total: number;
|
|
30
|
+
readonly limit: number;
|
|
31
|
+
readonly offset: number;
|
|
32
|
+
}
|
|
33
|
+
export interface RepositoryFindMany<Entity> {
|
|
34
|
+
findMany(query?: RepositoryQuery<Entity>): Promise<EntityInstanceOf<Entity>[]>;
|
|
35
|
+
}
|
|
36
|
+
export interface RepositoryExists<Entity> {
|
|
37
|
+
exists(query?: RepositoryQuery<Entity>): Promise<boolean>;
|
|
38
|
+
}
|
|
39
|
+
export interface RepositoryFindPage<Entity> {
|
|
40
|
+
/** Defaults to limit 20 and offset 0. */
|
|
41
|
+
findPage(query?: RepositoryQuery<Entity>): Promise<RepositoryPage<Entity>>;
|
|
42
|
+
}
|
|
43
|
+
/** JSON values retained in provider descriptors, including explicit import references. */
|
|
44
|
+
export type ProviderOption = null | boolean | number | string | readonly ProviderOption[] | {
|
|
45
|
+
readonly [key: string]: ProviderOption;
|
|
46
|
+
};
|
|
47
|
+
export type ProviderOptions = Readonly<Record<string, ProviderOption>>;
|
|
48
|
+
/** A named provider can be reconstructed; opaque providers require an import mapping. */
|
|
49
|
+
export type ProviderDescription = {
|
|
50
|
+
readonly kind: "provider";
|
|
51
|
+
readonly name: string;
|
|
52
|
+
readonly options: ProviderOptions;
|
|
53
|
+
} | {
|
|
54
|
+
readonly kind: "opaque";
|
|
55
|
+
};
|
|
56
|
+
/** Equality and `in` are mandatory; additional operators are advertised here. */
|
|
57
|
+
export interface ProviderCapabilities {
|
|
58
|
+
readonly operators?: readonly string[];
|
|
59
|
+
readonly transactions?: boolean;
|
|
60
|
+
}
|
|
61
|
+
/** Declaration input for a named provider, implemented by providerOf in T10. */
|
|
62
|
+
export interface ProviderSettings<Options extends ProviderOptions = ProviderOptions, Provider extends IRepositoryProvider = IRepositoryProvider> {
|
|
63
|
+
readonly name: string;
|
|
64
|
+
readonly options?: Options;
|
|
65
|
+
readonly create: (options: Options) => Provider;
|
|
66
|
+
}
|
|
67
|
+
export {};
|
|
@@ -3,6 +3,7 @@ import type { AbstractEntity, EntityUniqueKeys } from "../../entity/abstract-ent
|
|
|
3
3
|
import type { AnyEntityClass } from "../../entity/event.js";
|
|
4
4
|
import type { RecordSettings } from "../../record/types/record.interface.js";
|
|
5
5
|
import type { AbstractRepository } from "../repository.js";
|
|
6
|
+
import type { ProviderCapabilities, RepositoryExists, RepositoryFindMany, RepositoryFindPage, RepositoryQuery } from "./query.interface.js";
|
|
6
7
|
/** Any class made by `entityOf`, or extending one, that a repository holds. */
|
|
7
8
|
export type AnyRepositoryEntity = AnyRecordClass & AnyEntityClass & {
|
|
8
9
|
readonly [EntityUniqueKeys]: readonly string[];
|
|
@@ -42,8 +43,8 @@ export interface RepositoryDelete<Entity> {
|
|
|
42
43
|
delete(entity: EntityInstanceOf<Entity> | string): Promise<EntityInstanceOf<Entity>>;
|
|
43
44
|
}
|
|
44
45
|
/** `count`: how many entities it holds. */
|
|
45
|
-
export interface RepositoryCount {
|
|
46
|
-
count(): Promise<number>;
|
|
46
|
+
export interface RepositoryCount<Entity = unknown> {
|
|
47
|
+
count(query?: RepositoryQuery<Entity>): Promise<number>;
|
|
47
48
|
}
|
|
48
49
|
/** The `findBy<Key>` of `Actions`, one for each unique key: the entity, or `undefined`. */
|
|
49
50
|
export type RepositoryFindBy<Entity, Actions extends string = string> = {
|
|
@@ -64,10 +65,11 @@ export type RepositoryFindManyBy<Entity, Actions extends string = string> = {
|
|
|
64
65
|
/**
|
|
65
66
|
* The methods of `Actions` for `Entity`. Declared as methods, not properties,
|
|
66
67
|
* so that a class extending a repository can override them.
|
|
68
|
+
* @internal
|
|
67
69
|
*/
|
|
68
|
-
export type RepositoryMethods<Entity, Actions extends string = string> = RepositoryFindBy<Entity, Actions> & RepositoryFindManyBy<Entity, Actions> & ("create" extends Actions ? RepositoryCreate<Entity> : unknown) & ("update" extends Actions ? RepositoryUpdate<Entity> : unknown) & ("delete" extends Actions ? RepositoryDelete<Entity> : unknown) & ("count" extends Actions ? RepositoryCount : unknown);
|
|
70
|
+
export type RepositoryMethods<Entity, Actions extends string = string> = RepositoryFindBy<Entity, Actions> & RepositoryFindManyBy<Entity, Actions> & ("create" extends Actions ? RepositoryCreate<Entity> : unknown) & ("update" extends Actions ? RepositoryUpdate<Entity> : unknown) & ("delete" extends Actions ? RepositoryDelete<Entity> : unknown) & ("count" extends Actions ? RepositoryCount<Entity> : unknown) & ("findMany" extends Actions ? RepositoryFindMany<Entity> : unknown) & ("exists" extends Actions ? RepositoryExists<Entity> : unknown) & ("findPage" extends Actions ? RepositoryFindPage<Entity> : unknown);
|
|
69
71
|
/** A method a repository of `Entity` can have, e.g. `"findByEmail"`. */
|
|
70
|
-
export type RepositoryAction<Entity> = keyof RepositoryFindBy<Entity> | keyof RepositoryFindManyBy<Entity> | "create" | "update" | "delete" | "count";
|
|
72
|
+
export type RepositoryAction<Entity> = keyof RepositoryFindBy<Entity> | keyof RepositoryFindManyBy<Entity> | "create" | "update" | "delete" | "count" | "findMany" | "exists" | "findPage";
|
|
71
73
|
/**
|
|
72
74
|
* A repository of `Entity` with the methods of `Actions`, whose provider gets
|
|
73
75
|
* `Environment` as `context.env`, e.g.
|
|
@@ -96,17 +98,15 @@ export interface RepositoryContext<Environment = unknown> {
|
|
|
96
98
|
* `RepositoryEntityNotFound` for an unknown id.
|
|
97
99
|
*/
|
|
98
100
|
export interface IRepositoryProvider<Environment = unknown> {
|
|
99
|
-
findOne(context: RepositoryContext<Environment>,
|
|
100
|
-
findMany(context: RepositoryContext<Environment>,
|
|
101
|
+
findOne(context: RepositoryContext<Environment>, query?: RepositoryQuery): Promise<RepositoryData | undefined>;
|
|
102
|
+
findMany(context: RepositoryContext<Environment>, query?: RepositoryQuery): Promise<readonly RepositoryData[]>;
|
|
101
103
|
insert(context: RepositoryContext<Environment>, data: RepositoryData): Promise<void>;
|
|
102
104
|
update(context: RepositoryContext<Environment>, data: RepositoryData): Promise<void>;
|
|
103
105
|
remove(context: RepositoryContext<Environment>, id: string): Promise<void>;
|
|
104
|
-
count(context: RepositoryContext<Environment
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
*/
|
|
110
|
-
findIn?(context: RepositoryContext<Environment>, key: string, values: readonly unknown[]): Promise<readonly RepositoryData[]>;
|
|
106
|
+
count(context: RepositoryContext<Environment>, query?: RepositoryQuery): Promise<number>;
|
|
107
|
+
readonly capabilities?: ProviderCapabilities;
|
|
108
|
+
transaction?<Result>(run: (provider: IRepositoryProvider<Environment>) => Promise<Result>): Promise<Result>;
|
|
109
|
+
/** Releases what the provider holds (connections, files); `app.stop()` calls it. */
|
|
110
|
+
close?(): void | Promise<void>;
|
|
111
111
|
}
|
|
112
112
|
export {};
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import type { Static, TSchema } from "typebox";
|
|
2
2
|
import type { Validator } from "typebox/compile";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The compiled validator of a schema. `Value` is the schema's value, computed
|
|
5
|
+
* once where `SchemaType` is known: TypeScript then relates two of them by
|
|
6
|
+
* their values, without measuring `Static` itself, which costs about a second
|
|
7
|
+
* on every check.
|
|
8
|
+
*/
|
|
9
|
+
export type ISchemaType<SchemaType extends TSchema, Value = Static<SchemaType>> = Validator<Record<string, TSchema>, SchemaType, Value, Value>;
|
|
10
|
+
/** A schema; `Value` is its value, as in `ISchemaType`. */
|
|
11
|
+
export interface ISchema<SchemaType extends TSchema, Value = Static<SchemaType>> {
|
|
12
|
+
match(value: unknown): value is Value;
|
|
6
13
|
/**
|
|
7
14
|
* Whether `value` has the structure of the schema (its types), ignoring
|
|
8
15
|
* constraints such as `minLength`, `format`, `pattern` or `const`.
|
|
@@ -10,5 +17,5 @@ export interface ISchema<SchemaType extends TSchema> {
|
|
|
10
17
|
matchShape(value: unknown): boolean;
|
|
11
18
|
errors(value: unknown): string[];
|
|
12
19
|
toString(): string;
|
|
13
|
-
get type(): ISchemaType<SchemaType>;
|
|
20
|
+
get type(): ISchemaType<SchemaType, Value>;
|
|
14
21
|
}
|