@oscarpalmer/jhunal 0.21.0 → 0.22.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/helpers.d.mts +4 -4
- package/dist/helpers.mjs +2 -1
- package/dist/index.d.mts +17 -56
- package/dist/index.mjs +211 -215
- package/dist/models/schema.plain.model.d.mts +2 -8
- package/dist/models/validation.model.d.mts +10 -54
- package/dist/schematic.d.mts +4 -4
- package/dist/schematic.mjs +12 -15
- package/dist/validation.d.mts +7 -0
- package/dist/validation.mjs +245 -0
- package/package.json +1 -1
- package/src/helpers.ts +11 -8
- package/src/index.ts +6 -1
- package/src/models/schema.plain.model.ts +1 -8
- package/src/models/validation.model.ts +37 -72
- package/src/schematic.ts +18 -23
- package/src/validation.ts +498 -0
- package/dist/validation/property.validation.d.mts +0 -7
- package/dist/validation/property.validation.mjs +0 -92
- package/dist/validation/value.validation.d.mts +0 -7
- package/dist/validation/value.validation.mjs +0 -162
- package/src/validation/property.validation.ts +0 -217
- package/src/validation/value.validation.ts +0 -293
|
@@ -4,11 +4,18 @@ import {NAME_ERROR_SCHEMATIC, NAME_ERROR_VALIDATION} from '../constants';
|
|
|
4
4
|
import type {Schematic} from '../schematic';
|
|
5
5
|
import type {ValueName} from './misc.model';
|
|
6
6
|
|
|
7
|
+
// #region Named validation
|
|
8
|
+
|
|
9
|
+
export type NamedValidatorHandlers = {
|
|
10
|
+
[Key in ValueName]?: Array<(value: unknown) => boolean>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type NamedValidators = Record<ValueName, (value: unknown) => boolean>;
|
|
14
|
+
|
|
15
|
+
// #endregion
|
|
16
|
+
|
|
7
17
|
// #region Reporting
|
|
8
18
|
|
|
9
|
-
/**
|
|
10
|
-
* Maps each {@link ReportingType} to a boolean flag
|
|
11
|
-
*/
|
|
12
19
|
export type ReportingInformation = Record<ReportingType, boolean> & {
|
|
13
20
|
type: ReportingType;
|
|
14
21
|
};
|
|
@@ -16,16 +23,16 @@ export type ReportingInformation = Record<ReportingType, boolean> & {
|
|
|
16
23
|
/**
|
|
17
24
|
* Controls how validation failures are reported
|
|
18
25
|
*
|
|
19
|
-
* - `'none'
|
|
20
|
-
* - `'first'
|
|
21
|
-
* - `'all'
|
|
22
|
-
* - `'throw'
|
|
26
|
+
* - `'none'`, returns a boolean _(default)_
|
|
27
|
+
* - `'first'`, returns the first failure as a `Result`
|
|
28
|
+
* - `'all'`, returns all failures as a `Result` _(from same level)_
|
|
29
|
+
* - `'throw'`, throws a {@link ValidationError} on failure
|
|
23
30
|
*/
|
|
24
31
|
export type ReportingType = 'all' | 'first' | 'none' | 'throw';
|
|
25
32
|
|
|
26
33
|
// #endregion
|
|
27
34
|
|
|
28
|
-
// #region
|
|
35
|
+
// #region Errors
|
|
29
36
|
|
|
30
37
|
/**
|
|
31
38
|
* Thrown when a schema definition is invalid
|
|
@@ -38,66 +45,6 @@ export class SchematicError extends Error {
|
|
|
38
45
|
}
|
|
39
46
|
}
|
|
40
47
|
|
|
41
|
-
// #endregion
|
|
42
|
-
|
|
43
|
-
// #region Validated property
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* The runtime representation of a parsed schema property, used internally during validation
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```ts
|
|
50
|
-
* const parsed: ValidatedProperty = {
|
|
51
|
-
* key: 'age',
|
|
52
|
-
* required: true,
|
|
53
|
-
* types: ['number'],
|
|
54
|
-
* validators: { number: [(v) => v > 0] },
|
|
55
|
-
* };
|
|
56
|
-
* ```
|
|
57
|
-
*/
|
|
58
|
-
export type ValidatedProperty = {
|
|
59
|
-
/**
|
|
60
|
-
* The property name in the schema
|
|
61
|
-
*/
|
|
62
|
-
key: string;
|
|
63
|
-
/**
|
|
64
|
-
* Whether the property is required
|
|
65
|
-
*/
|
|
66
|
-
required: boolean;
|
|
67
|
-
/**
|
|
68
|
-
* The allowed types for this property
|
|
69
|
-
*/
|
|
70
|
-
types: ValidatedPropertyType[];
|
|
71
|
-
/**
|
|
72
|
-
* Custom validators grouped by {@link ValueName}
|
|
73
|
-
*/
|
|
74
|
-
validators: ValidatedPropertyValidators;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* A union of valid types for a {@link ValidatedProperty}'s `types` array
|
|
79
|
-
*
|
|
80
|
-
* Can be a callback _(custom validator)_, a {@link Schematic}, a nested {@link ValidatedProperty}, or a {@link ValueName} string
|
|
81
|
-
*/
|
|
82
|
-
export type ValidatedPropertyType =
|
|
83
|
-
| GenericCallback
|
|
84
|
-
| ValidatedProperty[]
|
|
85
|
-
| Schematic<unknown>
|
|
86
|
-
| ValueName;
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* A map of validator functions keyed by {@link ValueName}, used at runtime in {@link ValidatedProperty}
|
|
90
|
-
*
|
|
91
|
-
* Each key holds an array of validator functions that receive an `unknown` value and return a `boolean`
|
|
92
|
-
*/
|
|
93
|
-
export type ValidatedPropertyValidators = {
|
|
94
|
-
[Key in ValueName]?: Array<(value: unknown) => boolean>;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
// #endregion
|
|
98
|
-
|
|
99
|
-
// #region Property validation
|
|
100
|
-
|
|
101
48
|
/**
|
|
102
49
|
* Thrown in `'throw'` mode when one or more properties fail validation; `information` holds all failures
|
|
103
50
|
*/
|
|
@@ -114,6 +61,10 @@ export class ValidationError extends Error {
|
|
|
114
61
|
}
|
|
115
62
|
}
|
|
116
63
|
|
|
64
|
+
// #endregion
|
|
65
|
+
|
|
66
|
+
// #region Results
|
|
67
|
+
|
|
117
68
|
/**
|
|
118
69
|
* Describes a single validation failure
|
|
119
70
|
*/
|
|
@@ -129,13 +80,17 @@ export type ValidationInformation = {
|
|
|
129
80
|
};
|
|
130
81
|
|
|
131
82
|
/**
|
|
132
|
-
*
|
|
83
|
+
*
|
|
133
84
|
*/
|
|
134
85
|
export type ValidationInformationKey = {
|
|
135
86
|
full: string;
|
|
136
87
|
short: string;
|
|
137
88
|
};
|
|
138
89
|
|
|
90
|
+
// #endregion
|
|
91
|
+
|
|
92
|
+
// #region Options
|
|
93
|
+
|
|
139
94
|
/**
|
|
140
95
|
* Options for validation
|
|
141
96
|
*/
|
|
@@ -150,13 +105,23 @@ export type ValidationOptions<Errors extends ReportingType> = {
|
|
|
150
105
|
strict?: boolean;
|
|
151
106
|
};
|
|
152
107
|
|
|
153
|
-
|
|
108
|
+
// #endregion
|
|
109
|
+
|
|
110
|
+
// #region Validator
|
|
111
|
+
|
|
112
|
+
export type Validator = (
|
|
113
|
+
input: unknown,
|
|
114
|
+
parameters: ValidatorParameters,
|
|
115
|
+
get: boolean,
|
|
116
|
+
) => boolean | ValidationInformation[];
|
|
117
|
+
|
|
118
|
+
export type ValidatorParameters = {
|
|
154
119
|
information?: ValidationInformation[];
|
|
155
|
-
origin?: ValidatedProperty;
|
|
156
120
|
output: PlainObject;
|
|
157
|
-
prefix?: string;
|
|
158
121
|
reporting: ReportingInformation;
|
|
159
122
|
strict: boolean;
|
|
160
123
|
};
|
|
161
124
|
|
|
125
|
+
export type ValidatorType = Function | PlainObject | Schematic<unknown> | ValueName;
|
|
126
|
+
|
|
162
127
|
// #endregion
|
package/src/schematic.ts
CHANGED
|
@@ -9,12 +9,11 @@ import type {Schema} from './models/schema.plain.model';
|
|
|
9
9
|
import type {TypedSchema} from './models/schema.typed.model';
|
|
10
10
|
import {
|
|
11
11
|
SchematicError,
|
|
12
|
-
type ValidatedProperty,
|
|
13
12
|
type ValidationInformation,
|
|
14
13
|
type ValidationOptions,
|
|
14
|
+
type Validator,
|
|
15
15
|
} from './models/validation.model';
|
|
16
|
-
import {
|
|
17
|
-
import {validateObject} from './validation/value.validation';
|
|
16
|
+
import {getObjectValidator} from './validation';
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
19
|
* A schematic for validating objects
|
|
@@ -22,16 +21,16 @@ import {validateObject} from './validation/value.validation';
|
|
|
22
21
|
export class Schematic<Model> {
|
|
23
22
|
declare private readonly $schematic: true;
|
|
24
23
|
|
|
25
|
-
#
|
|
24
|
+
#validator: Validator;
|
|
26
25
|
|
|
27
|
-
constructor(
|
|
26
|
+
constructor(validator: Validator) {
|
|
28
27
|
Object.defineProperty(this, PROPERTY_SCHEMATIC, {
|
|
29
28
|
value: true,
|
|
30
29
|
});
|
|
31
30
|
|
|
32
|
-
this.#
|
|
31
|
+
this.#validator = validator;
|
|
33
32
|
|
|
34
|
-
|
|
33
|
+
schematicValidator.set(this, validator);
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
/**
|
|
@@ -107,14 +106,14 @@ export class Schematic<Model> {
|
|
|
107
106
|
get(value: unknown, options?: unknown): unknown {
|
|
108
107
|
const parameters = getParameters(options);
|
|
109
108
|
|
|
110
|
-
const result =
|
|
109
|
+
const result = this.#validator(value, parameters, true);
|
|
111
110
|
|
|
112
|
-
if (result
|
|
113
|
-
return
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
if (typeof result === 'boolean') {
|
|
112
|
+
return parameters.reporting.none
|
|
113
|
+
? result
|
|
114
|
+
? parameters.output
|
|
115
|
+
: undefined
|
|
116
|
+
: ok(parameters.output);
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
return error(parameters.reporting.all ? result : result[0]);
|
|
@@ -193,14 +192,10 @@ export class Schematic<Model> {
|
|
|
193
192
|
is(value: unknown, options?: unknown): unknown {
|
|
194
193
|
const parameters = getParameters(options);
|
|
195
194
|
|
|
196
|
-
const result =
|
|
195
|
+
const result = this.#validator(value, parameters, false);
|
|
197
196
|
|
|
198
|
-
if (result
|
|
199
|
-
return
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (!Array.isArray(result)) {
|
|
203
|
-
return parameters.reporting.none ? true : ok(true);
|
|
197
|
+
if (typeof result === 'boolean') {
|
|
198
|
+
return parameters.reporting.none ? result : ok(result);
|
|
204
199
|
}
|
|
205
200
|
|
|
206
201
|
return error(parameters.reporting.all ? result : result[0]);
|
|
@@ -234,7 +229,7 @@ export function schematic<Model extends Schema>(schema: Model): Schematic<Model>
|
|
|
234
229
|
throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE);
|
|
235
230
|
}
|
|
236
231
|
|
|
237
|
-
return new Schematic<Model>(
|
|
232
|
+
return new Schematic<Model>(getObjectValidator(schema));
|
|
238
233
|
}
|
|
239
234
|
|
|
240
|
-
export const
|
|
235
|
+
export const schematicValidator = new WeakMap<Schematic<unknown>, Validator>();
|