@oscarpalmer/jhunal 0.19.0 → 0.21.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 +7 -1
- package/dist/constants.mjs +7 -1
- package/dist/helpers.d.mts +7 -5
- package/dist/helpers.mjs +47 -18
- package/dist/index.d.mts +190 -109
- package/dist/index.mjs +161 -62
- package/dist/models/infer.model.d.mts +12 -12
- package/dist/models/misc.model.d.mts +20 -29
- package/dist/models/schema.plain.model.d.mts +4 -4
- package/dist/models/schema.typed.model.d.mts +5 -23
- package/dist/models/transform.model.d.mts +9 -13
- package/dist/models/validation.model.d.mts +55 -22
- package/dist/models/validation.model.mjs +4 -1
- package/dist/schematic.d.mts +103 -11
- package/dist/schematic.mjs +18 -8
- package/dist/validation/property.validation.mjs +2 -6
- package/dist/validation/value.validation.d.mts +3 -2
- package/dist/validation/value.validation.mjs +92 -34
- package/package.json +52 -52
- package/src/constants.ts +16 -0
- package/src/helpers.ts +81 -29
- package/src/models/infer.model.ts +12 -12
- package/src/models/misc.model.ts +20 -29
- package/src/models/schema.plain.model.ts +4 -4
- package/src/models/schema.typed.model.ts +5 -23
- package/src/models/transform.model.ts +9 -13
- package/src/models/validation.model.ts +57 -19
- package/src/schematic.ts +143 -17
- package/src/validation/property.validation.ts +8 -11
- package/src/validation/value.validation.ts +148 -44
package/dist/index.d.mts
CHANGED
|
@@ -5,7 +5,7 @@ import { Result } from "@oscarpalmer/atoms/result/models";
|
|
|
5
5
|
/**
|
|
6
6
|
* Infers the TypeScript type from a {@link Schema} definition
|
|
7
7
|
*
|
|
8
|
-
* @template Model
|
|
8
|
+
* @template Model Schema to infer types from
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
11
|
* ```ts
|
|
@@ -27,37 +27,37 @@ type Infer<Model extends Schema> = Simplify<{ [Key in InferRequiredKeys<Model>]:
|
|
|
27
27
|
*/
|
|
28
28
|
type InferOptionalKeys<Model extends Schema> = keyof { [Key in keyof Model as IsOptionalProperty<Model[Key]> extends true ? Key : never]: never };
|
|
29
29
|
/**
|
|
30
|
-
* Infers the TypeScript type
|
|
30
|
+
* Infers the TypeScript type from a {@link SchemaProperty}'s `$type` field
|
|
31
31
|
*
|
|
32
|
-
* @template Value
|
|
32
|
+
* @template Value `$type` value _(single or array)_
|
|
33
33
|
*/
|
|
34
34
|
type InferPropertyType<Value> = Value extends (infer Item)[] ? InferPropertyValue<Item> : InferPropertyValue<Value>;
|
|
35
35
|
/**
|
|
36
|
-
* Maps a single type definition to its TypeScript equivalent
|
|
36
|
+
* Maps a single `$type` definition to its TypeScript equivalent
|
|
37
37
|
*
|
|
38
|
-
* Resolves, in order: {@link Constructor} instances, {@link Schematic} models, {@link ValueName} strings, and nested {@link
|
|
38
|
+
* Resolves, in order: {@link Constructor} instances, {@link Schematic} models, {@link ValueName} strings, and nested {@link PlainSchema} objects
|
|
39
39
|
*
|
|
40
|
-
* @template Value
|
|
40
|
+
* @template Value single type definition
|
|
41
41
|
*/
|
|
42
42
|
type InferPropertyValue<Value> = Value extends Constructor<infer Instance> ? Instance : Value extends Schematic<infer Model> ? Model : Value extends ValueName ? Values[Value & ValueName] : Value extends Schema ? Infer<Value> : never;
|
|
43
43
|
/**
|
|
44
44
|
* Extracts keys from a {@link Schema} whose entries are required _(i.e., `$required` is not `false`)_
|
|
45
45
|
*
|
|
46
|
-
* @template Model
|
|
46
|
+
* @template Model Schema to extract required keys from
|
|
47
47
|
*/
|
|
48
48
|
type InferRequiredKeys<Model extends Schema> = keyof { [Key in keyof Model as IsOptionalProperty<Model[Key]> extends true ? never : Key]: never };
|
|
49
49
|
/**
|
|
50
|
-
* Infers the type
|
|
50
|
+
* Infers the TypeScript type from a top-level {@link Schema} entry
|
|
51
51
|
*
|
|
52
|
-
* @template Value
|
|
52
|
+
* @template Value Schema entry value _(single or array)_
|
|
53
53
|
*/
|
|
54
54
|
type InferSchemaEntry<Value> = Value extends (infer Item)[] ? InferSchemaEntryValue<Item> : InferSchemaEntryValue<Value>;
|
|
55
55
|
/**
|
|
56
|
-
*
|
|
56
|
+
* Maps a single top-level schema entry to its TypeScript type
|
|
57
57
|
*
|
|
58
|
-
*
|
|
58
|
+
* Resolves, in order: {@link Constructor} instances, {@link Schematic} models, {@link SchemaProperty} objects, {@link PlainSchema} objects, and {@link ValueName} strings
|
|
59
59
|
*
|
|
60
|
-
* @template Value
|
|
60
|
+
* @template Value single schema entry
|
|
61
61
|
*/
|
|
62
62
|
type InferSchemaEntryValue<Value> = Value extends Constructor<infer Instance> ? Instance : Value extends Schematic<infer Model> ? Model : Value extends SchemaProperty ? InferPropertyType<Value['$type']> : Value extends PlainSchema ? Infer<Value & Schema> : Value extends ValueName ? Values[Value & ValueName] : Value extends Schema ? Infer<Value> : never;
|
|
63
63
|
//#endregion
|
|
@@ -65,37 +65,33 @@ type InferSchemaEntryValue<Value> = Value extends Constructor<infer Instance> ?
|
|
|
65
65
|
/**
|
|
66
66
|
* Maps each element of a tuple through {@link ToValueType}
|
|
67
67
|
*
|
|
68
|
-
* @template Value
|
|
68
|
+
* @template Value Tuple of types to map
|
|
69
69
|
*/
|
|
70
70
|
type MapToValueTypes<Value extends unknown[]> = Value extends [infer Head, ...infer Tail] ? [ToValueType<Head>, ...MapToValueTypes<Tail>] : [];
|
|
71
71
|
/**
|
|
72
72
|
* Maps each element of a tuple through {@link ToSchemaPropertyTypeEach}
|
|
73
73
|
*
|
|
74
|
-
* @template Value
|
|
74
|
+
* @template Value Tuple of types to map
|
|
75
75
|
*/
|
|
76
76
|
type MapToSchemaPropertyTypes<Value extends unknown[]> = Value extends [infer Head, ...infer Tail] ? [ToSchemaPropertyTypeEach<Head>, ...MapToSchemaPropertyTypes<Tail>] : [];
|
|
77
77
|
/**
|
|
78
|
-
* Converts a type
|
|
78
|
+
* Converts a TypeScript type to its {@link SchemaPropertyType} representation, suitable for use in a typed schema
|
|
79
79
|
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* @template Value - type to convert
|
|
80
|
+
* @template Value Type to convert
|
|
83
81
|
*/
|
|
84
82
|
type ToSchemaPropertyType<Value> = UnwrapSingle<DeduplicateTuple<MapToSchemaPropertyTypes<UnionToTuple<Value>>>>;
|
|
85
83
|
/**
|
|
86
84
|
* Converts a single type to its schema property equivalent
|
|
87
85
|
*
|
|
88
|
-
*
|
|
86
|
+
* Plain objects become {@link TypedSchema}; primitives go through {@link ToValueType}
|
|
89
87
|
*
|
|
90
|
-
* @template Value
|
|
88
|
+
* @template Value Type to convert
|
|
91
89
|
*/
|
|
92
90
|
type ToSchemaPropertyTypeEach<Value> = Value extends PlainObject ? TypedSchema<Value> : ToValueType<Value>;
|
|
93
91
|
/**
|
|
94
|
-
* Converts a type
|
|
95
|
-
*
|
|
96
|
-
* Deduplicates and unwraps single-element tuples via {@link UnwrapSingle}
|
|
92
|
+
* Converts a TypeScript type to its {@link ValueName} representation, suitable for use as a top-level schema entry
|
|
97
93
|
*
|
|
98
|
-
* @template Value
|
|
94
|
+
* @template Value Type to convert
|
|
99
95
|
*/
|
|
100
96
|
type ToSchemaType<Value> = UnwrapSingle<DeduplicateTuple<MapToValueTypes<UnionToTuple<Value>>>>;
|
|
101
97
|
/**
|
|
@@ -103,7 +99,7 @@ type ToSchemaType<Value> = UnwrapSingle<DeduplicateTuple<MapToValueTypes<UnionTo
|
|
|
103
99
|
*
|
|
104
100
|
* Resolves {@link Schematic} 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
|
|
105
101
|
*
|
|
106
|
-
* @template Value
|
|
102
|
+
* @template Value Type to map
|
|
107
103
|
*
|
|
108
104
|
* @example
|
|
109
105
|
* ```ts
|
|
@@ -118,7 +114,7 @@ type ToValueType<Value> = Value extends Schematic<any> ? Value : { [Key in keyof
|
|
|
118
114
|
/**
|
|
119
115
|
* A typed optional property definition generated by {@link TypedSchema} for optional keys, with `$required` set to `false` and excludes `undefined` from the type
|
|
120
116
|
*
|
|
121
|
-
* @template Value
|
|
117
|
+
* @template Value Property's type _(including `undefined`)_
|
|
122
118
|
*
|
|
123
119
|
* @example
|
|
124
120
|
* ```ts
|
|
@@ -128,23 +124,14 @@ type ToValueType<Value> = Value extends Schematic<any> ? Value : { [Key in keyof
|
|
|
128
124
|
* ```
|
|
129
125
|
*/
|
|
130
126
|
type TypedPropertyOptional<Value> = {
|
|
131
|
-
/**
|
|
132
|
-
* The property is not required
|
|
133
|
-
*/
|
|
134
127
|
$required: false;
|
|
135
|
-
/**
|
|
136
|
-
* The type(s) of the property
|
|
137
|
-
*/
|
|
138
128
|
$type: ToSchemaPropertyType<Exclude<Value, undefined>>;
|
|
139
|
-
/**
|
|
140
|
-
* Custom validators for the property and its types
|
|
141
|
-
*/
|
|
142
129
|
$validators?: PropertyValidators<ToSchemaPropertyType<Exclude<Value, undefined>>>;
|
|
143
130
|
};
|
|
144
131
|
/**
|
|
145
132
|
* A typed required property definition generated by {@link TypedSchema} for required keys, with `$required` defaulting to `true`
|
|
146
133
|
*
|
|
147
|
-
* @template Value
|
|
134
|
+
* @template Value Property's type
|
|
148
135
|
*
|
|
149
136
|
* @example
|
|
150
137
|
* ```ts
|
|
@@ -154,17 +141,8 @@ type TypedPropertyOptional<Value> = {
|
|
|
154
141
|
* ```
|
|
155
142
|
*/
|
|
156
143
|
type TypedPropertyRequired<Value> = {
|
|
157
|
-
/**
|
|
158
|
-
* The property is required _(defaults to `true`)_
|
|
159
|
-
*/
|
|
160
144
|
$required?: true;
|
|
161
|
-
/**
|
|
162
|
-
* The type(s) of the property
|
|
163
|
-
*/
|
|
164
145
|
$type: ToSchemaPropertyType<Value>;
|
|
165
|
-
/**
|
|
166
|
-
* Custom validators for the property and its types
|
|
167
|
-
*/
|
|
168
146
|
$validators?: PropertyValidators<ToSchemaPropertyType<Value>>;
|
|
169
147
|
};
|
|
170
148
|
/**
|
|
@@ -172,7 +150,7 @@ type TypedPropertyRequired<Value> = {
|
|
|
172
150
|
*
|
|
173
151
|
* Required keys map to {@link ToSchemaType} or {@link TypedPropertyRequired}; plain object values may also use {@link Schematic}. Optional keys map to {@link TypedPropertyOptional} or, for plain objects, {@link TypedSchemaOptional}
|
|
174
152
|
*
|
|
175
|
-
* @template Model
|
|
153
|
+
* @template Model Object type to generate a schema for
|
|
176
154
|
*
|
|
177
155
|
* @example
|
|
178
156
|
* ```ts
|
|
@@ -189,7 +167,7 @@ type TypedSchema<Model extends PlainObject> = Simplify<{ [Key in RequiredKeys<Mo
|
|
|
189
167
|
/**
|
|
190
168
|
* A {@link TypedSchema} variant for optional nested objects, with `$required` fixed to `false`
|
|
191
169
|
*
|
|
192
|
-
* @template Model
|
|
170
|
+
* @template Model Nested object type
|
|
193
171
|
*/
|
|
194
172
|
type TypedSchemaOptional<Model extends PlainObject> = {
|
|
195
173
|
$required: false;
|
|
@@ -197,7 +175,7 @@ type TypedSchemaOptional<Model extends PlainObject> = {
|
|
|
197
175
|
/**
|
|
198
176
|
* A {@link TypedSchema} variant for required nested objects, with `$required` defaulting to `true`
|
|
199
177
|
*
|
|
200
|
-
* @template Model
|
|
178
|
+
* @template Model Nested object type
|
|
201
179
|
*/
|
|
202
180
|
type TypedSchemaRequired<Model extends PlainObject> = {
|
|
203
181
|
$required?: true;
|
|
@@ -205,7 +183,16 @@ type TypedSchemaRequired<Model extends PlainObject> = {
|
|
|
205
183
|
//#endregion
|
|
206
184
|
//#region src/models/validation.model.d.ts
|
|
207
185
|
/**
|
|
208
|
-
*
|
|
186
|
+
* Controls how validation failures are reported
|
|
187
|
+
*
|
|
188
|
+
* - `'none'` — returns a boolean _(default)_
|
|
189
|
+
* - `'first'` — returns the first failure as a `Result`
|
|
190
|
+
* - `'all'` — returns all failures as a `Result` _(from same level)_
|
|
191
|
+
* - `'throw'` — throws a {@link ValidationError} on failure
|
|
192
|
+
*/
|
|
193
|
+
type ReportingType = 'all' | 'first' | 'none' | 'throw';
|
|
194
|
+
/**
|
|
195
|
+
* Thrown when a schema definition is invalid
|
|
209
196
|
*/
|
|
210
197
|
declare class SchematicError extends Error {
|
|
211
198
|
constructor(message: string);
|
|
@@ -227,7 +214,7 @@ type ValidatedProperty = {
|
|
|
227
214
|
/**
|
|
228
215
|
* The property name in the schema
|
|
229
216
|
*/
|
|
230
|
-
key:
|
|
217
|
+
key: string;
|
|
231
218
|
/**
|
|
232
219
|
* Whether the property is required
|
|
233
220
|
*/
|
|
@@ -241,19 +228,6 @@ type ValidatedProperty = {
|
|
|
241
228
|
*/
|
|
242
229
|
validators: ValidatedPropertyValidators;
|
|
243
230
|
};
|
|
244
|
-
/**
|
|
245
|
-
* Property name in schema
|
|
246
|
-
*/
|
|
247
|
-
type ValidatedPropertyKey = {
|
|
248
|
-
/**
|
|
249
|
-
* Full property key, including parent keys for nested properties _(e.g., `address.street`)_
|
|
250
|
-
*/
|
|
251
|
-
full: string;
|
|
252
|
-
/**
|
|
253
|
-
* The last segment of the property key _(e.g., `street` for `address.street`)_
|
|
254
|
-
*/
|
|
255
|
-
short: string;
|
|
256
|
-
};
|
|
257
231
|
/**
|
|
258
232
|
* A union of valid types for a {@link ValidatedProperty}'s `types` array
|
|
259
233
|
*
|
|
@@ -266,17 +240,42 @@ type ValidatedPropertyType = GenericCallback | ValidatedProperty[] | Schematic<u
|
|
|
266
240
|
* Each key holds an array of validator functions that receive an `unknown` value and return a `boolean`
|
|
267
241
|
*/
|
|
268
242
|
type ValidatedPropertyValidators = { [Key in ValueName]?: Array<(value: unknown) => boolean> };
|
|
243
|
+
/**
|
|
244
|
+
* Thrown in `'throw'` mode when one or more properties fail validation; `information` holds all failures
|
|
245
|
+
*/
|
|
269
246
|
declare class ValidationError extends Error {
|
|
270
247
|
readonly information: ValidationInformation[];
|
|
271
248
|
constructor(information: ValidationInformation[]);
|
|
272
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* Describes a single validation failure
|
|
252
|
+
*/
|
|
273
253
|
type ValidationInformation = {
|
|
274
|
-
key: ValidationInformationKey;
|
|
275
|
-
message: string;
|
|
276
|
-
validator?: GenericCallback;
|
|
254
|
+
/** The key path of the property that failed */key: ValidationInformationKey; /** Human-readable description of the failure */
|
|
255
|
+
message: string; /** The validator function that failed, if the failure was from a `$validators` entry */
|
|
256
|
+
validator?: GenericCallback; /** The value that was provided */
|
|
277
257
|
value: unknown;
|
|
278
258
|
};
|
|
279
|
-
|
|
259
|
+
/**
|
|
260
|
+
*
|
|
261
|
+
*/
|
|
262
|
+
type ValidationInformationKey = {
|
|
263
|
+
full: string;
|
|
264
|
+
short: string;
|
|
265
|
+
};
|
|
266
|
+
/**
|
|
267
|
+
* Options for validation
|
|
268
|
+
*/
|
|
269
|
+
type ValidationOptions<Errors extends ReportingType> = {
|
|
270
|
+
/**
|
|
271
|
+
* How should validation failures be reported; see {@link ReportingType} _(defaults to `'none'`)_
|
|
272
|
+
*/
|
|
273
|
+
errors?: Errors;
|
|
274
|
+
/**
|
|
275
|
+
* Validate if unknown keys are present in the object? _(defaults to `false`)_
|
|
276
|
+
*/
|
|
277
|
+
strict?: boolean;
|
|
278
|
+
};
|
|
280
279
|
//#endregion
|
|
281
280
|
//#region src/schematic.d.ts
|
|
282
281
|
/**
|
|
@@ -286,41 +285,132 @@ declare class Schematic<Model> {
|
|
|
286
285
|
#private;
|
|
287
286
|
private readonly $schematic;
|
|
288
287
|
constructor(properties: ValidatedProperty[]);
|
|
288
|
+
/**
|
|
289
|
+
* Parse a value according to the schema
|
|
290
|
+
*
|
|
291
|
+
* Returns a deeply cloned version of the value or throws an error for the first property that fails validation
|
|
292
|
+
* @param value Value to parse
|
|
293
|
+
* @param options Validation options
|
|
294
|
+
* @returns Deeply cloned version of the value if it matches the schema, otherwise throws an error
|
|
295
|
+
*/
|
|
296
|
+
get(value: unknown, options: ValidationOptions<'throw'>): Model;
|
|
297
|
+
/**
|
|
298
|
+
* Parse a value according to the schema
|
|
299
|
+
*
|
|
300
|
+
* Returns a deeply cloned version of the value or throws an error for the first property that fails validation
|
|
301
|
+
* @param value Value to parse
|
|
302
|
+
* @param errors Reporting type
|
|
303
|
+
* @returns Deeply cloned version of the value if it matches the schema, otherwise throws an error
|
|
304
|
+
*/
|
|
305
|
+
get(value: unknown, errors: 'throw'): Model;
|
|
306
|
+
/**
|
|
307
|
+
* Parse a value according to the schema
|
|
308
|
+
*
|
|
309
|
+
* Returns a result of a deeply cloned version of the value or all validation information for validation failures from the same depth in the value
|
|
310
|
+
* @param value Value to parse
|
|
311
|
+
* @param options Validation options
|
|
312
|
+
* @returns Result holding deeply cloned value or all validation information
|
|
313
|
+
*/
|
|
314
|
+
get(value: unknown, options: ValidationOptions<'all'>): Result<Model, ValidationInformation[]>;
|
|
315
|
+
/**
|
|
316
|
+
* Parse a value according to the schema
|
|
317
|
+
*
|
|
318
|
+
* Returns a result of a deeply cloned version of the value or all validation information for validation failures from the same depth in the value
|
|
319
|
+
* @param value Value to parse
|
|
320
|
+
* @param errors Reporting type
|
|
321
|
+
* @returns Result holding deeply cloned value or all validation information
|
|
322
|
+
*/
|
|
323
|
+
get(value: unknown, errors: 'all'): Result<Model, ValidationInformation[]>;
|
|
324
|
+
/**
|
|
325
|
+
* Parse a value according to the schema
|
|
326
|
+
*
|
|
327
|
+
* Returns a deeply cloned version of the value or all validation information for the first failing property
|
|
328
|
+
* @param value Value to parse
|
|
329
|
+
* @param options Validation options
|
|
330
|
+
* @returns Result holding deeply cloned value or all validation information
|
|
331
|
+
*/
|
|
332
|
+
get(value: unknown, options: ValidationOptions<'first'>): Result<Model, ValidationInformation>;
|
|
333
|
+
/**
|
|
334
|
+
* Parse a value according to the schema
|
|
335
|
+
*
|
|
336
|
+
* Returns a deeply cloned version of the value or all validation information for the first failing property
|
|
337
|
+
* @param value Value to parse
|
|
338
|
+
* @param errors Reporting type
|
|
339
|
+
* @returns Result holding deeply cloned value or all validation information
|
|
340
|
+
*/
|
|
341
|
+
get(value: unknown, errors: 'first'): Result<Model, ValidationInformation>;
|
|
342
|
+
/**
|
|
343
|
+
* Parse a value according to the schema
|
|
344
|
+
*
|
|
345
|
+
* Returns a deeply cloned version of the value or `undefined` if the value does not match the schema
|
|
346
|
+
* @param value Value to parse
|
|
347
|
+
* @param strict Validate if unknown keys are present in the object? _(defaults to `false`)_
|
|
348
|
+
* @returns Deeply cloned value, or `undefined` if it's invalid
|
|
349
|
+
*/
|
|
350
|
+
get(value: unknown, strict?: true): Model | undefined;
|
|
289
351
|
/**
|
|
290
352
|
* Does the value match the schema?
|
|
291
353
|
*
|
|
292
|
-
* Will assert that the values matches the schema and throw an error if it does not. The error will contain all validation information for the first property that fails validation
|
|
354
|
+
* Will assert that the values matches the schema and throw an error if it does not. The error will contain all validation information for the first property that fails validation
|
|
293
355
|
* @param value Value to validate
|
|
294
|
-
* @param
|
|
356
|
+
* @param options Validation options
|
|
357
|
+
* @returns `true` if the value matches the schema, otherwise throws an error
|
|
358
|
+
*/
|
|
359
|
+
is(value: unknown, options: ValidationOptions<'throw'>): asserts value is Model;
|
|
360
|
+
/**
|
|
361
|
+
* Does the value match the schema?
|
|
362
|
+
*
|
|
363
|
+
* Will assert that the values matches the schema and throw an error if it does not. The error will contain all validation information for the first property that fails validation
|
|
364
|
+
* @param value Value to validate
|
|
365
|
+
* @param errors Reporting type
|
|
295
366
|
* @returns `true` if the value matches the schema, otherwise throws an error
|
|
296
367
|
*/
|
|
297
368
|
is(value: unknown, errors: 'throw'): asserts value is Model;
|
|
298
369
|
/**
|
|
299
370
|
* Does the value match the schema?
|
|
300
371
|
*
|
|
301
|
-
* Will validate that the value matches the schema and return a result of `true` or all validation information for validation failures from the same depth in the
|
|
372
|
+
* Will validate that the value matches the schema and return a result of `true` or all validation information for validation failures from the same depth in the value
|
|
302
373
|
* @param value Value to validate
|
|
303
|
-
* @param
|
|
304
|
-
* @returns `true`
|
|
374
|
+
* @param options Validation options
|
|
375
|
+
* @returns Result holding `true` or all validation information
|
|
376
|
+
*/
|
|
377
|
+
is(value: unknown, options: ValidationOptions<'all'>): Result<true, ValidationInformation[]>;
|
|
378
|
+
/**
|
|
379
|
+
* Does the value match the schema?
|
|
380
|
+
*
|
|
381
|
+
* Will validate that the value matches the schema and return a result of `true` or all validation information for validation failures from the same depth in the value
|
|
382
|
+
* @param value Value to validate
|
|
383
|
+
* @param errors Reporting type
|
|
384
|
+
* @returns Result holding `true` or all validation information
|
|
305
385
|
*/
|
|
306
386
|
is(value: unknown, errors: 'all'): Result<true, ValidationInformation[]>;
|
|
307
387
|
/**
|
|
308
388
|
* Does the value match the schema?
|
|
309
389
|
*
|
|
310
|
-
* Will validate that the value matches the schema and return a result of `true` or all validation information for the failing property
|
|
390
|
+
* Will validate that the value matches the schema and return a result of `true` or all validation information for the first failing property
|
|
311
391
|
* @param value Value to validate
|
|
312
|
-
* @param
|
|
392
|
+
* @param options Validation options
|
|
393
|
+
* @returns `true` if the value matches the schema, otherwise `false`
|
|
394
|
+
*/
|
|
395
|
+
is(value: unknown, options: ValidationOptions<'first'>): Result<true, ValidationInformation>;
|
|
396
|
+
/**
|
|
397
|
+
* Does the value match the schema?
|
|
398
|
+
*
|
|
399
|
+
* Will validate that the value matches the schema and return a result of `true` or all validation information for the first failing property
|
|
400
|
+
* @param value Value to validate
|
|
401
|
+
* @param errors Reporting type
|
|
313
402
|
* @returns `true` if the value matches the schema, otherwise `false`
|
|
314
403
|
*/
|
|
315
404
|
is(value: unknown, errors: 'first'): Result<true, ValidationInformation>;
|
|
316
405
|
/**
|
|
317
406
|
* Does the value match the schema?
|
|
318
407
|
*
|
|
319
|
-
* Will validate that the value matches the schema and return `true` or `false`, without any validation information for validation failures
|
|
408
|
+
* Will validate that the value matches the schema and return `true` or `false`, without any validation information for validation failures
|
|
320
409
|
* @param value Value to validate
|
|
410
|
+
* @param strict Validate if unknown keys are present in the object? _(defaults to `false`)_
|
|
321
411
|
* @returns `true` if the value matches the schema, otherwise `false`
|
|
322
412
|
*/
|
|
323
|
-
is(value: unknown): value is Model;
|
|
413
|
+
is(value: unknown, strict?: true): value is Model;
|
|
324
414
|
}
|
|
325
415
|
/**
|
|
326
416
|
* Create a schematic from a schema
|
|
@@ -341,7 +431,7 @@ declare function schematic<Model extends PlainObject>(schema: TypedSchema<Model>
|
|
|
341
431
|
//#endregion
|
|
342
432
|
//#region src/models/schema.plain.model.d.ts
|
|
343
433
|
/**
|
|
344
|
-
* A generic schema allowing
|
|
434
|
+
* A generic schema allowing nested schemas, {@link SchemaEntry} values, or arrays of {@link SchemaEntry} as values
|
|
345
435
|
*/
|
|
346
436
|
type PlainSchema = {
|
|
347
437
|
[key: string]: PlainSchema | SchemaEntry | SchemaEntry[] | undefined;
|
|
@@ -366,11 +456,11 @@ type Schema = SchemaIndex;
|
|
|
366
456
|
/**
|
|
367
457
|
* A union of all valid types for a single schema entry
|
|
368
458
|
*
|
|
369
|
-
* Can be a {@link Constructor},
|
|
459
|
+
* Can be a {@link Constructor}, {@link PlainSchema}, {@link SchemaProperty}, {@link Schematic}, {@link ValueName} string, or a custom validator function
|
|
370
460
|
*/
|
|
371
461
|
type SchemaEntry = Constructor | PlainSchema | SchemaProperty | Schematic<unknown> | ValueName | ((value: unknown) => boolean);
|
|
372
462
|
/**
|
|
373
|
-
* Index signature interface backing {@link Schema}, allowing string-keyed entries of {@link
|
|
463
|
+
* Index signature interface backing {@link Schema}, allowing string-keyed entries of {@link PlainSchema}, {@link SchemaEntry}, or arrays of {@link SchemaEntry}
|
|
374
464
|
*/
|
|
375
465
|
interface SchemaIndex {
|
|
376
466
|
[key: string]: PlainSchema | SchemaEntry | SchemaEntry[];
|
|
@@ -415,7 +505,7 @@ type SchemaPropertyType = Constructor | PlainSchema | Schematic<unknown> | Value
|
|
|
415
505
|
*
|
|
416
506
|
* Each key may hold a single validator or an array of validators that receive the typed value
|
|
417
507
|
*
|
|
418
|
-
* @template Value
|
|
508
|
+
* @template Value `$type` value(s) to derive validator keys from
|
|
419
509
|
*
|
|
420
510
|
* @example
|
|
421
511
|
* ```ts
|
|
@@ -430,8 +520,8 @@ type PropertyValidators<Value> = { [Key in ExtractValueNames<Value>]?: ((value:
|
|
|
430
520
|
/**
|
|
431
521
|
* Removes duplicate types from a tuple, preserving first occurrence order
|
|
432
522
|
*
|
|
433
|
-
* @template Value
|
|
434
|
-
* @template Seen
|
|
523
|
+
* @template Value Tuple to deduplicate
|
|
524
|
+
* @template Seen Accumulator for already-seen types _(internal)_
|
|
435
525
|
*
|
|
436
526
|
* @example
|
|
437
527
|
* ```ts
|
|
@@ -443,7 +533,7 @@ type DeduplicateTuple<Value extends unknown[], Seen extends unknown[] = []> = Va
|
|
|
443
533
|
/**
|
|
444
534
|
* Recursively extracts {@link ValueName} strings from a type, unwrapping arrays and readonly arrays
|
|
445
535
|
*
|
|
446
|
-
* @template Value
|
|
536
|
+
* @template Value Type to extract value names from
|
|
447
537
|
*
|
|
448
538
|
* @example
|
|
449
539
|
* ```ts
|
|
@@ -455,27 +545,27 @@ type ExtractValueNames<Value> = Value extends ValueName ? Value : Value extends
|
|
|
455
545
|
/**
|
|
456
546
|
* Determines whether a schema entry is optional
|
|
457
547
|
*
|
|
458
|
-
* Returns `true` if the entry is a {@link SchemaProperty}
|
|
548
|
+
* Returns `true` if the entry is a {@link SchemaProperty} with `$required` set to `false`; otherwise returns `false`
|
|
459
549
|
*
|
|
460
|
-
* @template Value
|
|
550
|
+
* @template Value Schema entry to check
|
|
461
551
|
*/
|
|
462
552
|
type IsOptionalProperty<Value> = Value extends SchemaProperty ? Value['$required'] extends false ? true : false : false;
|
|
463
553
|
/**
|
|
464
|
-
* Extracts the last member from a union type by leveraging
|
|
554
|
+
* Extracts the last member from a union type by leveraging contravariance of function parameter types
|
|
465
555
|
*
|
|
466
|
-
* @template Value
|
|
556
|
+
* @template Value Union type
|
|
467
557
|
*/
|
|
468
558
|
type LastOfUnion<Value> = UnionToIntersection<Value extends unknown ? () => Value : never> extends (() => infer Item) ? Item : never;
|
|
469
559
|
/**
|
|
470
560
|
* Extracts keys from an object type that are optional
|
|
471
561
|
*
|
|
472
|
-
* @template Value
|
|
562
|
+
* @template Value Object type to inspect
|
|
473
563
|
*/
|
|
474
564
|
type OptionalKeys<Value> = { [Key in keyof Value]-?: {} extends Pick<Value, Key> ? Key : never }[keyof Value];
|
|
475
565
|
/**
|
|
476
566
|
* Extracts keys from an object type that are required _(i.e., not optional)_
|
|
477
567
|
*
|
|
478
|
-
* @template Value
|
|
568
|
+
* @template Value Object type to inspect
|
|
479
569
|
*/
|
|
480
570
|
type RequiredKeys<Value> = Exclude<keyof Value, OptionalKeys<Value>>;
|
|
481
571
|
/**
|
|
@@ -483,8 +573,8 @@ type RequiredKeys<Value> = Exclude<keyof Value, OptionalKeys<Value>>;
|
|
|
483
573
|
*
|
|
484
574
|
* Used by {@link UnwrapSingle} to allow schema types in any order for small tuples _(length ≤ 5)_
|
|
485
575
|
*
|
|
486
|
-
* @template Tuple
|
|
487
|
-
* @template Elput
|
|
576
|
+
* @template Tuple Tuple to permute
|
|
577
|
+
* @template Elput Accumulator for the current permutation _(internal; name is Tuple backwards)_
|
|
488
578
|
*
|
|
489
579
|
* @example
|
|
490
580
|
* ```ts
|
|
@@ -498,9 +588,9 @@ type TuplePermutations<Tuple extends unknown[], Elput extends unknown[] = []> =
|
|
|
498
588
|
*
|
|
499
589
|
* Used internally by {@link TuplePermutations}
|
|
500
590
|
*
|
|
501
|
-
* @template Items
|
|
502
|
-
* @template Item
|
|
503
|
-
* @template Prefix
|
|
591
|
+
* @template Items Tuple to remove from
|
|
592
|
+
* @template Item Index as a string literal
|
|
593
|
+
* @template Prefix Accumulator for elements before the target _(internal)_
|
|
504
594
|
*/
|
|
505
595
|
type TupleRemoveAt<Items extends unknown[], Item extends string, Prefix extends unknown[] = []> = Items extends [infer Head, ...infer Tail] ? `${Prefix['length']}` extends Item ? [...Prefix, ...Tail] : TupleRemoveAt<Tail, Item, [...Prefix, Head]> : Prefix;
|
|
506
596
|
/**
|
|
@@ -508,7 +598,7 @@ type TupleRemoveAt<Items extends unknown[], Item extends string, Prefix extends
|
|
|
508
598
|
*
|
|
509
599
|
* Uses the contravariance of function parameter types to collapse a union into an intersection
|
|
510
600
|
*
|
|
511
|
-
* @template Value
|
|
601
|
+
* @template Value Union type to convert
|
|
512
602
|
*
|
|
513
603
|
* @example
|
|
514
604
|
* ```ts
|
|
@@ -522,8 +612,8 @@ type UnionToIntersection<Value> = (Value extends unknown ? (value: Value) => voi
|
|
|
522
612
|
*
|
|
523
613
|
* Repeatedly extracts the {@link LastOfUnion} member and prepends it to the accumulator
|
|
524
614
|
*
|
|
525
|
-
* @template Value
|
|
526
|
-
* @template Items
|
|
615
|
+
* @template Value Union type to convert
|
|
616
|
+
* @template Items Accumulator for the resulting tuple _(internal)_
|
|
527
617
|
*
|
|
528
618
|
* @example
|
|
529
619
|
* ```ts
|
|
@@ -537,7 +627,7 @@ type UnionToTuple<Value, Items extends unknown[] = []> = [Value] extends [never]
|
|
|
537
627
|
*
|
|
538
628
|
* For tuples of length 2–5, returns all {@link TuplePermutations} to allow types in any order. Longer tuples are returned as-is
|
|
539
629
|
*
|
|
540
|
-
* @template Value
|
|
630
|
+
* @template Value Tuple to potentially unwrap
|
|
541
631
|
*
|
|
542
632
|
* @example
|
|
543
633
|
* ```ts
|
|
@@ -547,20 +637,11 @@ type UnionToTuple<Value, Items extends unknown[] = []> = [Value] extends [never]
|
|
|
547
637
|
*/
|
|
548
638
|
type UnwrapSingle<Value extends unknown[]> = Value extends [infer Only] ? Only : Value['length'] extends 1 | 2 | 3 | 4 | 5 ? TuplePermutations<Value> : Value;
|
|
549
639
|
/**
|
|
550
|
-
*
|
|
640
|
+
* A union of valid type name strings, e.g. `'string'`, `'number'`, `'date'`
|
|
551
641
|
*/
|
|
552
642
|
type ValueName = keyof Values;
|
|
553
643
|
/**
|
|
554
|
-
* Maps
|
|
555
|
-
*
|
|
556
|
-
* Used by the type system to resolve {@link ValueName} strings into actual types
|
|
557
|
-
*
|
|
558
|
-
* @example
|
|
559
|
-
* ```ts
|
|
560
|
-
* // Values['string'] => string
|
|
561
|
-
* // Values['date'] => Date
|
|
562
|
-
* // Values['null'] => null
|
|
563
|
-
* ```
|
|
644
|
+
* Maps {@link ValueName} strings to their TypeScript equivalents
|
|
564
645
|
*/
|
|
565
646
|
type Values = {
|
|
566
647
|
array: unknown[];
|