@oscarpalmer/jhunal 0.24.0 → 0.26.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.
- package/dist/constants.d.mts +4 -4
- package/dist/constants.mjs +4 -4
- package/dist/helpers/misc.helper.d.mts +3 -3
- package/dist/helpers/misc.helper.mjs +3 -3
- package/dist/index.d.mts +64 -64
- package/dist/index.mjs +78 -56
- package/dist/models/infer.model.d.mts +21 -21
- package/dist/models/misc.model.d.mts +3 -3
- package/dist/models/{schema.plain.model.d.mts → schematic.plain.model.d.mts} +18 -18
- package/dist/models/{schema.typed.model.d.mts → schematic.typed.model.d.mts} +8 -8
- package/dist/models/transform.model.d.mts +6 -6
- package/dist/models/validation.model.d.mts +2 -2
- package/dist/{schematic.d.mts → schema.d.mts} +20 -20
- package/dist/{schematic.mjs → schema.mjs} +13 -13
- package/dist/validator/object.validator.mjs +63 -41
- package/dist/validator/schema.validator.d.mts +7 -0
- package/dist/validator/{schematic.validator.mjs → schema.validator.mjs} +5 -5
- package/package.json +1 -1
- package/src/constants.ts +3 -3
- package/src/helpers/misc.helper.ts +5 -5
- package/src/index.ts +4 -4
- package/src/models/infer.model.ts +26 -28
- package/src/models/misc.model.ts +3 -3
- package/src/models/{schema.plain.model.ts → schematic.plain.model.ts} +20 -20
- package/src/models/{schema.typed.model.ts → schematic.typed.model.ts} +8 -8
- package/src/models/transform.model.ts +6 -6
- package/src/models/validation.model.ts +2 -2
- package/src/{schematic.ts → schema.ts} +29 -27
- package/src/validator/object.validator.ts +123 -63
- package/src/validator/{schematic.validator.ts → schema.validator.ts} +3 -3
- package/dist/validator/schematic.validator.d.mts +0 -7
- /package/dist/models/{schema.plain.model.mjs → schematic.plain.model.mjs} +0 -0
- /package/dist/models/{schema.typed.model.mjs → schematic.typed.model.mjs} +0 -0
package/src/constants.ts
CHANGED
|
@@ -23,9 +23,9 @@ export const MESSAGE_CONSTRUCTOR = 'Expected a constructor function';
|
|
|
23
23
|
|
|
24
24
|
// #region Names
|
|
25
25
|
|
|
26
|
-
export const
|
|
26
|
+
export const NAME_SCHEMA = 'Schema';
|
|
27
27
|
|
|
28
|
-
export const
|
|
28
|
+
export const NAME_SCHEMA_PREFIXED = 'a Schema';
|
|
29
29
|
|
|
30
30
|
export const NAME_ERROR_SCHEMATIC = 'SchematicError';
|
|
31
31
|
|
|
@@ -39,7 +39,7 @@ export const PROPERTY_DEFAULT = '$default';
|
|
|
39
39
|
|
|
40
40
|
export const PROPERTY_REQUIRED = '$required';
|
|
41
41
|
|
|
42
|
-
export const
|
|
42
|
+
export const PROPERTY_SCHEMA = '$schema';
|
|
43
43
|
|
|
44
44
|
export const PROPERTY_TYPE = '$type';
|
|
45
45
|
|
|
@@ -2,7 +2,7 @@ import {isConstructor, isPlainObject} from '@oscarpalmer/atoms/is';
|
|
|
2
2
|
import type {Constructor} from '@oscarpalmer/atoms/models';
|
|
3
3
|
import {
|
|
4
4
|
MESSAGE_CONSTRUCTOR,
|
|
5
|
-
|
|
5
|
+
PROPERTY_SCHEMA,
|
|
6
6
|
REPORTING_ALL,
|
|
7
7
|
REPORTING_FIRST,
|
|
8
8
|
REPORTING_NONE,
|
|
@@ -14,7 +14,7 @@ import type {
|
|
|
14
14
|
ReportingType,
|
|
15
15
|
ValidatorParameters,
|
|
16
16
|
} from '../models/validation.model';
|
|
17
|
-
import type {
|
|
17
|
+
import type {Schema} from '../schema';
|
|
18
18
|
|
|
19
19
|
export function getParameters(input?: unknown): ValidatorParameters {
|
|
20
20
|
if (typeof input === 'boolean') {
|
|
@@ -82,11 +82,11 @@ export function instanceOf<Instance>(
|
|
|
82
82
|
* @param value Value to check
|
|
83
83
|
* @returns `true` if the value is a schematic, `false` otherwise
|
|
84
84
|
*/
|
|
85
|
-
export function
|
|
85
|
+
export function isSchema(value: unknown): value is Schema<never> {
|
|
86
86
|
return (
|
|
87
87
|
typeof value === 'object' &&
|
|
88
88
|
value !== null &&
|
|
89
|
-
|
|
90
|
-
value[
|
|
89
|
+
PROPERTY_SCHEMA in value &&
|
|
90
|
+
value[PROPERTY_SCHEMA] === true
|
|
91
91
|
);
|
|
92
92
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export {instanceOf,
|
|
2
|
-
export type {
|
|
3
|
-
export type {
|
|
1
|
+
export {instanceOf, isSchema} from './helpers/misc.helper';
|
|
2
|
+
export type {Schematic} from './models/schematic.plain.model';
|
|
3
|
+
export type {TypedSchematic} from './models/schematic.typed.model';
|
|
4
4
|
export {
|
|
5
5
|
SchematicError,
|
|
6
6
|
ValidationError,
|
|
7
7
|
type GetOptions,
|
|
8
8
|
type IsOptions,
|
|
9
9
|
} from './models/validation.model';
|
|
10
|
-
export {
|
|
10
|
+
export {schema, type Schema} from './schema';
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import type {Constructor, Simplify} from '@oscarpalmer/atoms/models';
|
|
2
|
-
import type {
|
|
2
|
+
import type {Schema} from '../schema';
|
|
3
3
|
import type {IsOptionalProperty, ValueName, Values} from './misc.model';
|
|
4
|
-
import type {
|
|
4
|
+
import type {PlainSchematic, Schematic, SchematicProperty} from './schematic.plain.model';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Infers the TypeScript type from a {@link
|
|
7
|
+
* Infers the TypeScript type from a {@link Schematic} definition
|
|
8
8
|
*
|
|
9
|
-
* @template Model
|
|
9
|
+
* @template Model Schematic to infer types from
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
12
12
|
* ```ts
|
|
13
|
-
* const
|
|
13
|
+
* const userSchematic = {
|
|
14
14
|
* name: 'string',
|
|
15
15
|
* age: 'number',
|
|
16
16
|
* address: { $required: false, $type: 'string' },
|
|
17
|
-
* } satisfies
|
|
17
|
+
* } satisfies Schematic;
|
|
18
18
|
*
|
|
19
|
-
* type User = Infer<typeof
|
|
19
|
+
* type User = Infer<typeof userSchematic>;
|
|
20
20
|
* // { name: string; age: number; address?: string }
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
|
-
export type Infer<Model extends
|
|
23
|
+
export type Infer<Model extends Schematic> = Simplify<
|
|
24
24
|
{
|
|
25
25
|
[Key in InferRequiredKeys<Model>]: InferSchemaEntry<Model[Key]>;
|
|
26
26
|
} & {
|
|
@@ -29,16 +29,16 @@ export type Infer<Model extends Schema> = Simplify<
|
|
|
29
29
|
>;
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* Extracts keys from a {@link
|
|
32
|
+
* Extracts keys from a {@link Schematic} whose entries are optional _(i.e., `$required` is `false`)_
|
|
33
33
|
*
|
|
34
|
-
* @template Model - {@link
|
|
34
|
+
* @template Model - {@link Schematic} to extract optional keys from
|
|
35
35
|
*/
|
|
36
|
-
export type InferOptionalKeys<Model extends
|
|
36
|
+
export type InferOptionalKeys<Model extends Schematic> = keyof {
|
|
37
37
|
[Key in keyof Model as IsOptionalProperty<Model[Key]> extends true ? Key : never]: never;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
|
-
* Infers the TypeScript type from a {@link
|
|
41
|
+
* Infers the TypeScript type from a {@link SchematicProperty}'s `$type` field
|
|
42
42
|
*
|
|
43
43
|
* @template Value `$type` value _(single or array)_
|
|
44
44
|
*/
|
|
@@ -49,34 +49,34 @@ export type InferPropertyType<Value> = Value extends (infer Item)[]
|
|
|
49
49
|
/**
|
|
50
50
|
* Maps a single `$type` definition to its TypeScript equivalent
|
|
51
51
|
*
|
|
52
|
-
* Resolves, in order: {@link Constructor}
|
|
52
|
+
* Resolves, in order: {@link Constructor}s, {@link Schema} instances, {@link ValueName} values, and nested {@link PlainSchematic} objects
|
|
53
53
|
*
|
|
54
54
|
* @template Value single type definition
|
|
55
55
|
*/
|
|
56
56
|
export type InferPropertyValue<Value> =
|
|
57
57
|
Value extends Constructor<infer Instance>
|
|
58
58
|
? Instance
|
|
59
|
-
: Value extends
|
|
59
|
+
: Value extends Schema<infer Model>
|
|
60
60
|
? Model
|
|
61
61
|
: Value extends ValueName
|
|
62
62
|
? Values[Value & ValueName]
|
|
63
|
-
: Value extends
|
|
63
|
+
: Value extends PlainSchematic
|
|
64
64
|
? Infer<Value>
|
|
65
65
|
: never;
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
|
-
* Extracts keys from a {@link
|
|
68
|
+
* Extracts keys from a {@link Schematic} whose entries are required _(i.e., `$required` is not `false`)_
|
|
69
69
|
*
|
|
70
|
-
* @template Model
|
|
70
|
+
* @template Model Schematic to extract required keys from
|
|
71
71
|
*/
|
|
72
|
-
export type InferRequiredKeys<Model extends
|
|
72
|
+
export type InferRequiredKeys<Model extends Schematic> = keyof {
|
|
73
73
|
[Key in keyof Model as IsOptionalProperty<Model[Key]> extends true ? never : Key]: never;
|
|
74
74
|
};
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
|
-
* Infers the TypeScript type from a top-level {@link
|
|
77
|
+
* Infers the TypeScript type from a top-level {@link Schematic} entry
|
|
78
78
|
*
|
|
79
|
-
* @template Value
|
|
79
|
+
* @template Value Schematic entry value _(single or array)_
|
|
80
80
|
*/
|
|
81
81
|
export type InferSchemaEntry<Value> = Value extends (infer Item)[]
|
|
82
82
|
? InferSchemaEntryValue<Item>
|
|
@@ -85,21 +85,19 @@ export type InferSchemaEntry<Value> = Value extends (infer Item)[]
|
|
|
85
85
|
/**
|
|
86
86
|
* Maps a single top-level schema entry to its TypeScript type
|
|
87
87
|
*
|
|
88
|
-
* Resolves, in order: {@link Constructor}
|
|
88
|
+
* Resolves, in order: {@link Constructor}s, {@link Schema} instances, {@link SchemaProperty} objects, {@link PlainSchematic} objects, and {@link ValueName} values
|
|
89
89
|
*
|
|
90
90
|
* @template Value single schema entry
|
|
91
91
|
*/
|
|
92
92
|
export type InferSchemaEntryValue<Value> =
|
|
93
93
|
Value extends Constructor<infer Instance>
|
|
94
94
|
? Instance
|
|
95
|
-
: Value extends
|
|
95
|
+
: Value extends Schema<infer Model>
|
|
96
96
|
? Model
|
|
97
|
-
: Value extends
|
|
97
|
+
: Value extends SchematicProperty
|
|
98
98
|
? InferPropertyType<Value['$type']>
|
|
99
|
-
: Value extends
|
|
100
|
-
? Infer<Value &
|
|
99
|
+
: Value extends PlainSchematic
|
|
100
|
+
? Infer<Value & Schematic>
|
|
101
101
|
: Value extends ValueName
|
|
102
102
|
? Values[Value & ValueName]
|
|
103
|
-
:
|
|
104
|
-
? Infer<Value>
|
|
105
|
-
: never;
|
|
103
|
+
: never;
|
package/src/models/misc.model.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {SchematicProperty} from './schematic.plain.model';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Removes duplicate types from a tuple, preserving first occurrence order
|
|
@@ -43,11 +43,11 @@ export type ExtractValueNames<Value> = Value extends ValueName
|
|
|
43
43
|
/**
|
|
44
44
|
* Determines whether a schema entry is optional
|
|
45
45
|
*
|
|
46
|
-
* Returns `true` if the entry is a {@link
|
|
46
|
+
* Returns `true` if the entry is a {@link SchematicProperty} with `$required` set to `false`; otherwise returns `false`
|
|
47
47
|
*
|
|
48
48
|
* @template Value Schema entry to check
|
|
49
49
|
*/
|
|
50
|
-
export type IsOptionalProperty<Value> = Value extends
|
|
50
|
+
export type IsOptionalProperty<Value> = Value extends SchematicProperty
|
|
51
51
|
? Value['$required'] extends false
|
|
52
52
|
? true
|
|
53
53
|
: false
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type {Constructor} from '@oscarpalmer/atoms/models';
|
|
2
|
-
import type {
|
|
2
|
+
import type {Schema} from '../schema';
|
|
3
3
|
import type {ExtractValueNames, ValueName, Values} from './misc.model';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* A generic
|
|
6
|
+
* A generic schematic allowing nested schematics, {@link SchematicEntry} values, or arrays of {@link SchematicEntry} as values
|
|
7
7
|
*/
|
|
8
|
-
export type
|
|
9
|
-
[key: string]:
|
|
8
|
+
export type PlainSchematic = {
|
|
9
|
+
[key: string]: PlainSchematic | SchematicEntry | SchematicEntry[] | undefined;
|
|
10
10
|
} & {
|
|
11
11
|
$default?: never;
|
|
12
12
|
$required?: never;
|
|
@@ -15,29 +15,29 @@ export type PlainSchema = {
|
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* A
|
|
18
|
+
* A schematic for validating objects
|
|
19
19
|
*
|
|
20
20
|
* @example
|
|
21
21
|
* ```ts
|
|
22
|
-
* const
|
|
22
|
+
* const schematic = {
|
|
23
23
|
* name: 'string',
|
|
24
24
|
* age: 'number',
|
|
25
25
|
* tags: ['string', 'number'],
|
|
26
|
-
* };
|
|
26
|
+
* } satisfies Schematic;
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
|
-
export type
|
|
29
|
+
export type Schematic = PlainSchematic;
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* A union of all valid types for a single
|
|
32
|
+
* A union of all valid types for a single schematic entry
|
|
33
33
|
*
|
|
34
|
-
* Can be a {@link Constructor}, {@link
|
|
34
|
+
* Can be a {@link Constructor}, {@link PlainSchematic}, {@link SchematicProperty}, {@link Schema}, {@link ValueName}, or a custom validator function
|
|
35
35
|
*/
|
|
36
|
-
export type
|
|
36
|
+
export type SchematicEntry =
|
|
37
37
|
| Constructor
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
38
|
+
| PlainSchematic
|
|
39
|
+
| Schema<unknown>
|
|
40
|
+
| SchematicProperty
|
|
41
41
|
| ValueName
|
|
42
42
|
| ((value: unknown) => boolean);
|
|
43
43
|
|
|
@@ -46,7 +46,7 @@ export type SchemaEntry =
|
|
|
46
46
|
*
|
|
47
47
|
* @example
|
|
48
48
|
* ```ts
|
|
49
|
-
* const prop:
|
|
49
|
+
* const prop: SchematicProperty = {
|
|
50
50
|
* $required: false,
|
|
51
51
|
* $type: ['string', 'number'],
|
|
52
52
|
* $validators: {
|
|
@@ -56,7 +56,7 @@ export type SchemaEntry =
|
|
|
56
56
|
* };
|
|
57
57
|
* ```
|
|
58
58
|
*/
|
|
59
|
-
export type
|
|
59
|
+
export type SchematicProperty = {
|
|
60
60
|
$default?: unknown;
|
|
61
61
|
/**
|
|
62
62
|
* Whether the property is required _(defaults to `true`)_
|
|
@@ -73,14 +73,14 @@ export type SchemaProperty = {
|
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
/**
|
|
76
|
-
* A union of valid types for a {@link
|
|
76
|
+
* A union of valid types for a {@link SchematicProperty}'s `$type` field
|
|
77
77
|
*
|
|
78
|
-
* Can be a {@link Constructor}, {@link
|
|
78
|
+
* Can be a {@link Constructor}, {@link PlainSchematic}, {@link Schema}, {@link ValueName} string, or a custom validator function
|
|
79
79
|
*/
|
|
80
80
|
export type SchemaPropertyType =
|
|
81
81
|
| Constructor
|
|
82
|
-
|
|
|
83
|
-
|
|
|
82
|
+
| PlainSchematic
|
|
83
|
+
| Schema<unknown>
|
|
84
84
|
| ValueName
|
|
85
85
|
| ((value: unknown) => boolean);
|
|
86
86
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type {PlainObject, Simplify} from '@oscarpalmer/atoms/models';
|
|
2
|
-
import type {
|
|
2
|
+
import type {Schema} from '../schema';
|
|
3
3
|
import type {OptionalKeys, RequiredKeys} from './misc.model';
|
|
4
|
-
import type {PropertyValidators} from './
|
|
4
|
+
import type {PropertyValidators} from './schematic.plain.model';
|
|
5
5
|
import type {ToSchemaPropertyType, ToSchemaType} from './transform.model';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* A typed optional property definition generated by {@link
|
|
8
|
+
* A typed optional property definition generated by {@link TypedSchematic} for optional keys, with `$required` set to `false` and excludes `undefined` from the type
|
|
9
9
|
*
|
|
10
10
|
* @template Value Property's type _(including `undefined`)_
|
|
11
11
|
*
|
|
@@ -24,7 +24,7 @@ export type TypedPropertyOptional<Value> = {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* A typed required property definition generated by {@link
|
|
27
|
+
* A typed required property definition generated by {@link TypedSchematic} for required keys, with `$required` defaulting to `true`
|
|
28
28
|
*
|
|
29
29
|
* @template Value Property's type
|
|
30
30
|
*
|
|
@@ -45,7 +45,7 @@ export type TypedPropertyRequired<Value> = {
|
|
|
45
45
|
/**
|
|
46
46
|
* Creates a schema type constrained to match a TypeScript type
|
|
47
47
|
*
|
|
48
|
-
* Required keys map to {@link ToSchemaType} or {@link TypedPropertyRequired}; plain object values may also use {@link
|
|
48
|
+
* Required keys map to {@link ToSchemaType} or {@link TypedPropertyRequired}; plain object values may also use {@link Schema}
|
|
49
49
|
*
|
|
50
50
|
* @template Model Object type to generate a schema for
|
|
51
51
|
*
|
|
@@ -60,14 +60,14 @@ export type TypedPropertyRequired<Value> = {
|
|
|
60
60
|
* };
|
|
61
61
|
* ```
|
|
62
62
|
*/
|
|
63
|
-
export type
|
|
63
|
+
export type TypedSchematic<Model extends PlainObject> = Simplify<
|
|
64
64
|
{
|
|
65
65
|
[Key in RequiredKeys<Model>]: Model[Key] extends PlainObject
|
|
66
|
-
?
|
|
66
|
+
? Schema<Model[Key]>
|
|
67
67
|
: ToSchemaType<Model[Key]> | TypedPropertyRequired<Model[Key]>;
|
|
68
68
|
} & {
|
|
69
69
|
[Key in OptionalKeys<Model>]: Exclude<Model[Key], undefined> extends PlainObject
|
|
70
|
-
?
|
|
70
|
+
? Schema<Exclude<Model[Key], undefined>>
|
|
71
71
|
: TypedPropertyOptional<Model[Key]>;
|
|
72
72
|
}
|
|
73
73
|
>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
-
import type {
|
|
2
|
+
import type {Schema} from '../schema';
|
|
3
3
|
import type {DeduplicateTuple, UnionToTuple, UnwrapSingle, Values} from './misc.model';
|
|
4
|
-
import type {
|
|
4
|
+
import type {TypedSchematic} from './schematic.typed.model';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Maps each element of a tuple through {@link ToValueType}
|
|
@@ -36,12 +36,12 @@ export type ToSchemaPropertyType<Value> = UnwrapSingle<
|
|
|
36
36
|
/**
|
|
37
37
|
* Converts a single type to its schema property equivalent
|
|
38
38
|
*
|
|
39
|
-
* Plain objects become {@link
|
|
39
|
+
* Plain objects become {@link TypedSchematic}; primitives go through {@link ToValueType}
|
|
40
40
|
*
|
|
41
41
|
* @template Value Type to convert
|
|
42
42
|
*/
|
|
43
43
|
export type ToSchemaPropertyTypeEach<Value> = Value extends PlainObject
|
|
44
|
-
?
|
|
44
|
+
? TypedSchematic<Value>
|
|
45
45
|
: ToValueType<Value>;
|
|
46
46
|
|
|
47
47
|
/**
|
|
@@ -56,7 +56,7 @@ export type ToSchemaType<Value> = UnwrapSingle<
|
|
|
56
56
|
/**
|
|
57
57
|
* Maps a type to its {@link ValueName} string equivalent
|
|
58
58
|
*
|
|
59
|
-
* Resolves {@link
|
|
59
|
+
* Resolves {@link Schema} types as-is, then performs a reverse-lookup against {@link Values} _(excluding `'object'`)_ to find a matching key. If no match is found, `object` types resolve to `'object'` or a type-guard function, and all other unrecognised types resolve to a type-guard function
|
|
60
60
|
*
|
|
61
61
|
* @template Value Type to map
|
|
62
62
|
*
|
|
@@ -68,7 +68,7 @@ export type ToSchemaType<Value> = UnwrapSingle<
|
|
|
68
68
|
* ```
|
|
69
69
|
*/
|
|
70
70
|
export type ToValueType<Value> =
|
|
71
|
-
Value extends
|
|
71
|
+
Value extends Schema<any>
|
|
72
72
|
? Value
|
|
73
73
|
: {
|
|
74
74
|
[Key in keyof Omit<Values, 'object'>]: Value extends Values[Key] ? Key : never;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {GenericCallback, PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
2
|
import {join} from '@oscarpalmer/atoms/string';
|
|
3
3
|
import {NAME_ERROR_SCHEMATIC, NAME_ERROR_VALIDATION} from '../constants';
|
|
4
|
-
import type {
|
|
4
|
+
import type {Schema} from '../schema';
|
|
5
5
|
import type {ValueName} from './misc.model';
|
|
6
6
|
|
|
7
7
|
// #region Named validation
|
|
@@ -147,6 +147,6 @@ export type ValidatorParameters = {
|
|
|
147
147
|
strict: boolean;
|
|
148
148
|
};
|
|
149
149
|
|
|
150
|
-
export type ValidatorType = Function | PlainObject |
|
|
150
|
+
export type ValidatorType = Function | PlainObject | Schema<unknown> | ValueName;
|
|
151
151
|
|
|
152
152
|
// #endregion
|
|
@@ -2,11 +2,11 @@ import {isPlainObject} from '@oscarpalmer/atoms/is';
|
|
|
2
2
|
import type {PlainObject} from '@oscarpalmer/atoms/models';
|
|
3
3
|
import {error, ok} from '@oscarpalmer/atoms/result/misc';
|
|
4
4
|
import type {Result} from '@oscarpalmer/atoms/result/models';
|
|
5
|
-
import {
|
|
6
|
-
import {getParameters,
|
|
5
|
+
import {PROPERTY_SCHEMA, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE} from './constants';
|
|
6
|
+
import {getParameters, isSchema} from './helpers/misc.helper';
|
|
7
7
|
import type {Infer} from './models/infer.model';
|
|
8
|
-
import type {
|
|
9
|
-
import type {
|
|
8
|
+
import type {Schematic} from './models/schematic.plain.model';
|
|
9
|
+
import type {TypedSchematic} from './models/schematic.typed.model';
|
|
10
10
|
import {
|
|
11
11
|
SchematicError,
|
|
12
12
|
type GetOptions,
|
|
@@ -17,21 +17,21 @@ import {
|
|
|
17
17
|
import {getObjectValidator} from './validator/object.validator';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* A
|
|
20
|
+
* A schema for validating objects
|
|
21
21
|
*/
|
|
22
|
-
export class
|
|
23
|
-
declare private readonly $
|
|
22
|
+
export class Schema<Model> {
|
|
23
|
+
declare private readonly $schema: true;
|
|
24
24
|
|
|
25
25
|
#validator: Validator;
|
|
26
26
|
|
|
27
27
|
constructor(validator: Validator) {
|
|
28
|
-
Object.defineProperty(this,
|
|
28
|
+
Object.defineProperty(this, PROPERTY_SCHEMA, {
|
|
29
29
|
value: true,
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
this.#validator = validator;
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
schemaValidators.set(this, validator);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/**
|
|
@@ -102,7 +102,7 @@ export class Schematic<Model> {
|
|
|
102
102
|
* @param options Validation options
|
|
103
103
|
* @returns Deeply cloned value, or `undefined` if it's invalid
|
|
104
104
|
*/
|
|
105
|
-
get(value: unknown, options: GetOptions<'none'
|
|
105
|
+
get(value: unknown, options: Partial<GetOptions<'none'>>): Model | undefined;
|
|
106
106
|
|
|
107
107
|
/**
|
|
108
108
|
* Parse a value according to the schema
|
|
@@ -121,8 +121,10 @@ export class Schematic<Model> {
|
|
|
121
121
|
|
|
122
122
|
if (result === true) {
|
|
123
123
|
return parameters.reporting.none || parameters.reporting.throw
|
|
124
|
-
? parameters.
|
|
125
|
-
|
|
124
|
+
? parameters.clone
|
|
125
|
+
? parameters.output
|
|
126
|
+
: value
|
|
127
|
+
: ok(parameters.clone ? parameters.output : value);
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
if (parameters.reporting.none) {
|
|
@@ -200,7 +202,7 @@ export class Schematic<Model> {
|
|
|
200
202
|
* @param options Validation options
|
|
201
203
|
* @returns `true` if the value matches the schema, otherwise `false`
|
|
202
204
|
*/
|
|
203
|
-
is(value: unknown, options: IsOptions<'none'
|
|
205
|
+
is(value: unknown, options: Partial<IsOptions<'none'>>): value is Model;
|
|
204
206
|
|
|
205
207
|
/**
|
|
206
208
|
* Does the value match the schema?
|
|
@@ -230,25 +232,25 @@ export class Schematic<Model> {
|
|
|
230
232
|
}
|
|
231
233
|
|
|
232
234
|
/**
|
|
233
|
-
* Create a
|
|
235
|
+
* Create a schema from a schematic
|
|
234
236
|
* @template Model Schema type
|
|
235
|
-
* @param schema
|
|
236
|
-
* @throws Throws {@link SchematicError} if the
|
|
237
|
-
* @returns A
|
|
237
|
+
* @param schema Schematic to create the schema from
|
|
238
|
+
* @throws Throws {@link SchematicError} if the schematic can not be converted into a schema
|
|
239
|
+
* @returns A schema for the given schematic
|
|
238
240
|
*/
|
|
239
|
-
export function
|
|
241
|
+
export function schema<Model extends Schematic>(schema: Model): Schema<Infer<Model>>;
|
|
240
242
|
|
|
241
243
|
/**
|
|
242
|
-
* Create a
|
|
244
|
+
* Create a schema from a typed schematic
|
|
243
245
|
* @template Model Existing type
|
|
244
|
-
* @param schema Typed
|
|
245
|
-
* @throws Throws {@link SchematicError} if the
|
|
246
|
-
* @returns A
|
|
246
|
+
* @param schema Typed schematic to create the schema from
|
|
247
|
+
* @throws Throws {@link SchematicError} if the schematic can not be converted into a schema
|
|
248
|
+
* @returns A schema for the given typed schematic
|
|
247
249
|
*/
|
|
248
|
-
export function
|
|
250
|
+
export function schema<Model extends PlainObject>(schema: TypedSchematic<Model>): Schema<Model>;
|
|
249
251
|
|
|
250
|
-
export function
|
|
251
|
-
if (
|
|
252
|
+
export function schema<Model extends Schematic>(schema: Model): Schema<Model> {
|
|
253
|
+
if (isSchema(schema)) {
|
|
252
254
|
return schema;
|
|
253
255
|
}
|
|
254
256
|
|
|
@@ -256,7 +258,7 @@ export function schematic<Model extends Schema>(schema: Model): Schematic<Model>
|
|
|
256
258
|
throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE);
|
|
257
259
|
}
|
|
258
260
|
|
|
259
|
-
return new
|
|
261
|
+
return new Schema<Model>(getObjectValidator(schema));
|
|
260
262
|
}
|
|
261
263
|
|
|
262
|
-
export const
|
|
264
|
+
export const schemaValidators = new WeakMap<Schema<unknown>, Validator>();
|