@oscarpalmer/jhunal 0.3.0 → 0.4.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/README.md +2 -0
- package/dist/helpers.cjs +24 -3
- package/dist/helpers.js +24 -3
- package/dist/is.cjs +19 -0
- package/dist/is.js +14 -0
- package/dist/schematic.cjs +5 -3
- package/dist/schematic.js +5 -3
- package/dist/validation/schema.validation.cjs +54 -0
- package/dist/validation/schema.validation.js +49 -0
- package/dist/validation/type.validation.cjs +33 -0
- package/dist/validation/type.validation.js +29 -0
- package/dist/validation/value.validation.cjs +35 -0
- package/dist/validation/value.validation.js +31 -0
- package/package.json +1 -1
- package/src/helpers.ts +33 -5
- package/src/index.ts +1 -1
- package/src/is.ts +22 -0
- package/src/model.ts +84 -43
- package/src/schematic.ts +14 -10
- package/src/validation/schema.validation.ts +63 -0
- package/src/validation/type.validation.ts +34 -0
- package/src/validation/value.validation.ts +46 -0
- package/types/helpers.d.cts +26 -1
- package/types/helpers.d.ts +2 -2
- package/types/index.d.cts +25 -14
- package/types/index.d.ts +1 -1
- package/types/is.d.cts +15 -0
- package/types/is.d.ts +3 -0
- package/types/model.d.cts +27 -12
- package/types/model.d.ts +27 -11
- package/types/schematic.d.cts +25 -14
- package/types/schematic.d.ts +4 -4
- package/types/validation/schema.validation.d.cts +55 -0
- package/types/validation/schema.validation.d.ts +3 -0
- package/types/validation/type.validation.d.cts +43 -0
- package/types/validation/type.validation.d.ts +2 -0
- package/types/validation/value.validation.d.cts +43 -0
- package/types/validation/value.validation.d.ts +2 -0
- package/dist/validation.cjs +0 -89
- package/dist/validation.js +0 -84
- package/src/validation.ts +0 -109
- package/types/validation.d.cts +0 -28
- package/types/validation.d.ts +0 -3
package/src/schematic.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type {Inferred, Schema, Schematic, Typed, TypedSchema} from './model';
|
|
2
|
-
import {
|
|
2
|
+
import {validateSchema} from './validation/schema.validation';
|
|
3
|
+
import {validateValue} from './validation/value.validation';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Create a schematic from a schema
|
|
7
|
+
*/
|
|
8
|
+
export function schematic<Model extends Schema>(
|
|
9
|
+
schema: Model,
|
|
10
|
+
): Schematic<Inferred<Model>>;
|
|
3
11
|
|
|
4
12
|
/**
|
|
5
13
|
* Create a schematic from a typed schema
|
|
@@ -8,19 +16,15 @@ export function schematic<Model extends Typed>(
|
|
|
8
16
|
schema: TypedSchema<Model>,
|
|
9
17
|
): Schematic<Model>;
|
|
10
18
|
|
|
11
|
-
/**
|
|
12
|
-
* Create a schematic from a schema
|
|
13
|
-
*/
|
|
14
19
|
export function schematic<Model extends Schema>(
|
|
15
20
|
schema: Model,
|
|
16
|
-
): Schematic<
|
|
17
|
-
|
|
18
|
-
export function schematic<Model extends Schema>(schema: Model) {
|
|
19
|
-
const validated = getValidatedSchema(schema);
|
|
21
|
+
): Schematic<Model> {
|
|
22
|
+
const validated = validateSchema(schema);
|
|
20
23
|
|
|
21
24
|
const canValidate = validated.length > 0;
|
|
22
25
|
|
|
23
26
|
return Object.freeze({
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
$schematic: true,
|
|
28
|
+
is: (value: unknown) => canValidate && validateValue(validated, value),
|
|
29
|
+
}) as never;
|
|
26
30
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type {PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
+
import {getTypes} from '../helpers';
|
|
3
|
+
import type {Schema, ValidatedPropertyType, ValidatedSchema} from '../model';
|
|
4
|
+
|
|
5
|
+
export function validateSchema(schema: unknown): ValidatedSchema {
|
|
6
|
+
if (validatedSchemas.has(schema as never)) {
|
|
7
|
+
return validatedSchemas.get(schema as never) as ValidatedSchema;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const validated: ValidatedSchema = {
|
|
11
|
+
keys: [],
|
|
12
|
+
length: 0,
|
|
13
|
+
properties: {},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
if (typeof schema !== 'object' || schema === null) {
|
|
17
|
+
return validated;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const keys = Object.keys(schema);
|
|
21
|
+
const {length} = keys;
|
|
22
|
+
|
|
23
|
+
for (let index = 0; index < length; index += 1) {
|
|
24
|
+
const key = keys[index];
|
|
25
|
+
const value = (schema as Schema)[key];
|
|
26
|
+
|
|
27
|
+
let required = true;
|
|
28
|
+
let types: ValidatedPropertyType[];
|
|
29
|
+
|
|
30
|
+
if (Array.isArray(value)) {
|
|
31
|
+
types = getTypes(value);
|
|
32
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
33
|
+
if (typeof (value as PlainObject).required === 'boolean') {
|
|
34
|
+
required = (value as PlainObject).required as boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
types = getTypes((value as PlainObject).type);
|
|
38
|
+
} else {
|
|
39
|
+
types = getTypes(value);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (types.length > 0) {
|
|
43
|
+
if (!required && !types.includes('undefined')) {
|
|
44
|
+
types.push('undefined');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
validated.keys.push(key);
|
|
48
|
+
|
|
49
|
+
validated.properties[key] = {
|
|
50
|
+
required,
|
|
51
|
+
types,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
validated.length += 1;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
validatedSchemas.set(schema as never, validated);
|
|
59
|
+
|
|
60
|
+
return validated;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const validatedSchemas = new WeakMap<Schema, ValidatedSchema>();
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {isDateLike, isSchematic} from '../is';
|
|
2
|
+
import type {ValidatedPropertyType, ValidatedSchema, Values} from '../model';
|
|
3
|
+
import {validateValue} from './value.validation';
|
|
4
|
+
|
|
5
|
+
export function validateType(
|
|
6
|
+
type: ValidatedPropertyType,
|
|
7
|
+
value: unknown,
|
|
8
|
+
): boolean {
|
|
9
|
+
if (typeof type === 'string') {
|
|
10
|
+
return validators[type](value);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (isSchematic(type)) {
|
|
14
|
+
return type.is(value);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return validateValue(type as ValidatedSchema, value);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const validators: Record<keyof Values, (value: unknown) => boolean> = {
|
|
21
|
+
array: Array.isArray,
|
|
22
|
+
bigint: value => typeof value === 'bigint',
|
|
23
|
+
boolean: value => typeof value === 'boolean',
|
|
24
|
+
date: value => value instanceof Date,
|
|
25
|
+
'date-like': isDateLike,
|
|
26
|
+
function: value => typeof value === 'function',
|
|
27
|
+
null: value => value === null,
|
|
28
|
+
number: value => typeof value === 'number',
|
|
29
|
+
numerical: value => validators.bigint(value) || validators.number(value),
|
|
30
|
+
object: value => typeof value === 'object' && value !== null,
|
|
31
|
+
string: value => typeof value === 'string',
|
|
32
|
+
symbol: value => typeof value === 'symbol',
|
|
33
|
+
undefined: value => value === undefined,
|
|
34
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type {PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
+
import type {ValidatedSchema} from '../model';
|
|
3
|
+
import {validateType} from './type.validation';
|
|
4
|
+
|
|
5
|
+
export function validateValue(
|
|
6
|
+
validated: ValidatedSchema,
|
|
7
|
+
obj: unknown,
|
|
8
|
+
): boolean {
|
|
9
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
outer: for (let keyIndex = 0; keyIndex < validated.length; keyIndex += 1) {
|
|
14
|
+
const key = validated.keys[keyIndex];
|
|
15
|
+
const property = validated.properties[key];
|
|
16
|
+
const value = (obj as PlainObject)[key];
|
|
17
|
+
|
|
18
|
+
if (
|
|
19
|
+
value === undefined &&
|
|
20
|
+
property.required &&
|
|
21
|
+
!property.types.includes('undefined')
|
|
22
|
+
) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const typesLength = property.types.length;
|
|
27
|
+
|
|
28
|
+
if (typesLength === 1) {
|
|
29
|
+
if (!validateType(property.types[0], value)) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
for (let typeIndex = 0; typeIndex < typesLength; typeIndex += 1) {
|
|
37
|
+
if (validateType(property.types[typeIndex], value)) {
|
|
38
|
+
continue outer;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return true;
|
|
46
|
+
}
|
package/types/helpers.d.cts
CHANGED
|
@@ -1,18 +1,43 @@
|
|
|
1
1
|
// Generated by dts-bundle-generator v9.5.1
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* A schematic for validating objects
|
|
5
|
+
*/
|
|
6
|
+
export type Schematic<Model> = {
|
|
7
|
+
/**
|
|
8
|
+
* Does the value match the schema?
|
|
9
|
+
*/
|
|
10
|
+
is(value: unknown): value is Model;
|
|
11
|
+
};
|
|
12
|
+
export type ValidatedProperty = {
|
|
13
|
+
required: boolean;
|
|
14
|
+
types: ValidatedPropertyType[];
|
|
15
|
+
};
|
|
16
|
+
export type ValidatedPropertyType = Schematic<unknown> | ValidatedSchema | ValueKey;
|
|
17
|
+
export type ValidatedSchema = {
|
|
18
|
+
keys: string[];
|
|
19
|
+
length: number;
|
|
20
|
+
properties: ValidatedSchemaProperties;
|
|
21
|
+
};
|
|
22
|
+
export type ValidatedSchemaProperties = {
|
|
23
|
+
[key: string]: ValidatedProperty;
|
|
24
|
+
};
|
|
25
|
+
export type ValueKey = keyof Values;
|
|
3
26
|
export type Values = {
|
|
4
27
|
array: unknown[];
|
|
5
28
|
bigint: bigint;
|
|
6
29
|
boolean: boolean;
|
|
7
30
|
date: Date;
|
|
31
|
+
"date-like": number | string | Date;
|
|
8
32
|
function: Function;
|
|
9
33
|
null: null;
|
|
10
34
|
number: number;
|
|
35
|
+
numerical: bigint | number;
|
|
11
36
|
object: object;
|
|
12
37
|
string: string;
|
|
13
38
|
symbol: symbol;
|
|
14
39
|
undefined: undefined;
|
|
15
40
|
};
|
|
16
|
-
export declare function getTypes(value: unknown):
|
|
41
|
+
export declare function getTypes(value: unknown): ValidatedPropertyType[];
|
|
17
42
|
|
|
18
43
|
export {};
|
package/types/helpers.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function getTypes(value: unknown):
|
|
1
|
+
import type { ValidatedPropertyType } from './model';
|
|
2
|
+
export declare function getTypes(value: unknown): ValidatedPropertyType[];
|
package/types/index.d.cts
CHANGED
|
@@ -270,20 +270,25 @@ export type UnionToTuple<T, L = LastOfUnion<T>> = IsNever<T> extends false ? [
|
|
|
270
270
|
L
|
|
271
271
|
] : [
|
|
272
272
|
];
|
|
273
|
+
export type AutoInferExclude = "date-like" | "numerical";
|
|
273
274
|
export type GetKey<Value> = {
|
|
274
|
-
[Key in
|
|
275
|
-
}[
|
|
275
|
+
[Key in Exclude<ValueKey, AutoInferExclude>]: Value extends Values[Key] ? Key : never;
|
|
276
|
+
}[Exclude<ValueKey, AutoInferExclude>] extends infer SpecificKey ? SpecificKey extends never ? {
|
|
277
|
+
[Key in AutoInferExclude]: Value extends Values[Key] ? Key : never;
|
|
278
|
+
}[AutoInferExclude] : SpecificKey : never;
|
|
276
279
|
export type GetTypes<Value extends unknown[]> = Value extends [
|
|
277
|
-
infer
|
|
278
|
-
] ?
|
|
280
|
+
infer Type
|
|
281
|
+
] ? Type : Value;
|
|
279
282
|
export type GetType<Value> = GetTypes<UnionToTuple<GetKey<Value>>>;
|
|
280
|
-
export type InferProperty<Value> = Value extends Property ? Value["type"]
|
|
281
|
-
export type
|
|
282
|
-
export type Inferred<Model extends
|
|
283
|
+
export type InferProperty<Value> = Value extends Property ? InferPropertyType<Value["type"]> : never;
|
|
284
|
+
export type InferPropertyType<Value> = Value extends (infer Type)[] ? InferPropertyTypeValue<Type>[] : InferPropertyTypeValue<Value>;
|
|
285
|
+
export type InferPropertyTypeValue<Value> = Value extends PropertyType ? Value extends Schema ? Inferred<Value> : Value extends Schematic<infer Model> ? Model : Value extends ValueKey ? Values[Value] : Value extends (infer NestedElementType)[] ? InferPropertyTypeValue<NestedElementType>[] : Value : never;
|
|
286
|
+
export type InferValue<Value> = Value extends ValueKey ? Values[Value] : Value extends ValueKey[] ? Values[Value[number]] : never;
|
|
287
|
+
export type Inferred<Model extends Schema> = Simplify<{
|
|
283
288
|
[Key in InferredRequiredProperties<Model>]: Model[Key] extends Property ? InferProperty<Model[Key]> : InferValue<Model[Key]>;
|
|
284
289
|
} & {
|
|
285
290
|
[Key in InferredOptionalProperties<Model>]?: Model[Key] extends Property ? InferProperty<Model[Key]> : never;
|
|
286
|
-
}
|
|
291
|
+
}>;
|
|
287
292
|
export type InferredOptionalProperties<Model extends Schema> = {
|
|
288
293
|
[Key in keyof Model]: Model[Key] extends Property ? Model[Key]["required"] extends false ? Key : never : never;
|
|
289
294
|
}[keyof Model];
|
|
@@ -296,8 +301,9 @@ export type OptionalProperty<Type> = {
|
|
|
296
301
|
};
|
|
297
302
|
export type Property = {
|
|
298
303
|
required?: boolean;
|
|
299
|
-
type:
|
|
304
|
+
type: PropertyType | PropertyType[];
|
|
300
305
|
};
|
|
306
|
+
export type PropertyType = Schema | Schematic<unknown> | ValueKey;
|
|
301
307
|
export type RequiredProperty<Type> = {
|
|
302
308
|
required: true;
|
|
303
309
|
type: GetType<Type>;
|
|
@@ -305,7 +311,9 @@ export type RequiredProperty<Type> = {
|
|
|
305
311
|
/**
|
|
306
312
|
* A schema for validating objects
|
|
307
313
|
*/
|
|
308
|
-
export type Schema =
|
|
314
|
+
export type Schema = {
|
|
315
|
+
[key: string]: Property | ValueKey | ValueKey[];
|
|
316
|
+
};
|
|
309
317
|
/**
|
|
310
318
|
* A schematic for validating objects
|
|
311
319
|
*/
|
|
@@ -324,26 +332,29 @@ export type TypedSchema<Model extends Typed> = Simplify<{
|
|
|
324
332
|
} & {
|
|
325
333
|
[Key in OptionalKeysOf<Model>]: OptionalProperty<Model[Key]>;
|
|
326
334
|
}>;
|
|
335
|
+
export type ValueKey = keyof Values;
|
|
327
336
|
export type Values = {
|
|
328
337
|
array: unknown[];
|
|
329
338
|
bigint: bigint;
|
|
330
339
|
boolean: boolean;
|
|
331
340
|
date: Date;
|
|
341
|
+
"date-like": number | string | Date;
|
|
332
342
|
function: Function;
|
|
333
343
|
null: null;
|
|
334
344
|
number: number;
|
|
345
|
+
numerical: bigint | number;
|
|
335
346
|
object: object;
|
|
336
347
|
string: string;
|
|
337
348
|
symbol: symbol;
|
|
338
349
|
undefined: undefined;
|
|
339
350
|
};
|
|
340
|
-
/**
|
|
341
|
-
* Create a schematic from a typed schema
|
|
342
|
-
*/
|
|
343
|
-
export declare function schematic<Model extends Typed>(schema: TypedSchema<Model>): Schematic<Model>;
|
|
344
351
|
/**
|
|
345
352
|
* Create a schematic from a schema
|
|
346
353
|
*/
|
|
347
354
|
export declare function schematic<Model extends Schema>(schema: Model): Schematic<Inferred<Model>>;
|
|
355
|
+
/**
|
|
356
|
+
* Create a schematic from a typed schema
|
|
357
|
+
*/
|
|
358
|
+
export declare function schematic<Model extends Typed>(schema: TypedSchema<Model>): Schematic<Model>;
|
|
348
359
|
|
|
349
360
|
export {};
|
package/types/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { Schema, Schematic } from './model';
|
|
1
|
+
export type { Schema, Schematic, TypedSchema } from './model';
|
|
2
2
|
export * from './schematic';
|
package/types/is.d.cts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Generated by dts-bundle-generator v9.5.1
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A schematic for validating objects
|
|
5
|
+
*/
|
|
6
|
+
export type Schematic<Model> = {
|
|
7
|
+
/**
|
|
8
|
+
* Does the value match the schema?
|
|
9
|
+
*/
|
|
10
|
+
is(value: unknown): value is Model;
|
|
11
|
+
};
|
|
12
|
+
export declare function isDateLike(value: unknown): value is Date;
|
|
13
|
+
export declare function isSchematic(value: unknown): value is Schematic<never>;
|
|
14
|
+
|
|
15
|
+
export {};
|
package/types/is.d.ts
ADDED
package/types/model.d.cts
CHANGED
|
@@ -270,20 +270,25 @@ export type UnionToTuple<T, L = LastOfUnion<T>> = IsNever<T> extends false ? [
|
|
|
270
270
|
L
|
|
271
271
|
] : [
|
|
272
272
|
];
|
|
273
|
+
export type AutoInferExclude = "date-like" | "numerical";
|
|
273
274
|
export type GetKey<Value> = {
|
|
274
|
-
[Key in
|
|
275
|
-
}[
|
|
275
|
+
[Key in Exclude<ValueKey, AutoInferExclude>]: Value extends Values[Key] ? Key : never;
|
|
276
|
+
}[Exclude<ValueKey, AutoInferExclude>] extends infer SpecificKey ? SpecificKey extends never ? {
|
|
277
|
+
[Key in AutoInferExclude]: Value extends Values[Key] ? Key : never;
|
|
278
|
+
}[AutoInferExclude] : SpecificKey : never;
|
|
276
279
|
export type GetTypes<Value extends unknown[]> = Value extends [
|
|
277
|
-
infer
|
|
278
|
-
] ?
|
|
280
|
+
infer Type
|
|
281
|
+
] ? Type : Value;
|
|
279
282
|
export type GetType<Value> = GetTypes<UnionToTuple<GetKey<Value>>>;
|
|
280
|
-
export type InferProperty<Value> = Value extends Property ? Value["type"]
|
|
281
|
-
export type
|
|
282
|
-
export type Inferred<Model extends
|
|
283
|
+
export type InferProperty<Value> = Value extends Property ? InferPropertyType<Value["type"]> : never;
|
|
284
|
+
export type InferPropertyType<Value> = Value extends (infer Type)[] ? InferPropertyTypeValue<Type>[] : InferPropertyTypeValue<Value>;
|
|
285
|
+
export type InferPropertyTypeValue<Value> = Value extends PropertyType ? Value extends Schema ? Inferred<Value> : Value extends Schematic<infer Model> ? Model : Value extends ValueKey ? Values[Value] : Value extends (infer NestedElementType)[] ? InferPropertyTypeValue<NestedElementType>[] : Value : never;
|
|
286
|
+
export type InferValue<Value> = Value extends ValueKey ? Values[Value] : Value extends ValueKey[] ? Values[Value[number]] : never;
|
|
287
|
+
export type Inferred<Model extends Schema> = Simplify<{
|
|
283
288
|
[Key in InferredRequiredProperties<Model>]: Model[Key] extends Property ? InferProperty<Model[Key]> : InferValue<Model[Key]>;
|
|
284
289
|
} & {
|
|
285
290
|
[Key in InferredOptionalProperties<Model>]?: Model[Key] extends Property ? InferProperty<Model[Key]> : never;
|
|
286
|
-
}
|
|
291
|
+
}>;
|
|
287
292
|
export type InferredOptionalProperties<Model extends Schema> = {
|
|
288
293
|
[Key in keyof Model]: Model[Key] extends Property ? Model[Key]["required"] extends false ? Key : never : never;
|
|
289
294
|
}[keyof Model];
|
|
@@ -296,8 +301,9 @@ export type OptionalProperty<Type> = {
|
|
|
296
301
|
};
|
|
297
302
|
export type Property = {
|
|
298
303
|
required?: boolean;
|
|
299
|
-
type:
|
|
304
|
+
type: PropertyType | PropertyType[];
|
|
300
305
|
};
|
|
306
|
+
export type PropertyType = Schema | Schematic<unknown> | ValueKey;
|
|
301
307
|
export type RequiredProperty<Type> = {
|
|
302
308
|
required: true;
|
|
303
309
|
type: GetType<Type>;
|
|
@@ -305,7 +311,9 @@ export type RequiredProperty<Type> = {
|
|
|
305
311
|
/**
|
|
306
312
|
* A schema for validating objects
|
|
307
313
|
*/
|
|
308
|
-
export type Schema =
|
|
314
|
+
export type Schema = {
|
|
315
|
+
[key: string]: Property | ValueKey | ValueKey[];
|
|
316
|
+
};
|
|
309
317
|
/**
|
|
310
318
|
* A schematic for validating objects
|
|
311
319
|
*/
|
|
@@ -326,21 +334,28 @@ export type TypedSchema<Model extends Typed> = Simplify<{
|
|
|
326
334
|
}>;
|
|
327
335
|
export type ValidatedProperty = {
|
|
328
336
|
required: boolean;
|
|
329
|
-
types:
|
|
337
|
+
types: ValidatedPropertyType[];
|
|
330
338
|
};
|
|
339
|
+
export type ValidatedPropertyType = Schematic<unknown> | ValidatedSchema | ValueKey;
|
|
331
340
|
export type ValidatedSchema = {
|
|
332
341
|
keys: string[];
|
|
333
342
|
length: number;
|
|
334
|
-
properties:
|
|
343
|
+
properties: ValidatedSchemaProperties;
|
|
344
|
+
};
|
|
345
|
+
export type ValidatedSchemaProperties = {
|
|
346
|
+
[key: string]: ValidatedProperty;
|
|
335
347
|
};
|
|
348
|
+
export type ValueKey = keyof Values;
|
|
336
349
|
export type Values = {
|
|
337
350
|
array: unknown[];
|
|
338
351
|
bigint: bigint;
|
|
339
352
|
boolean: boolean;
|
|
340
353
|
date: Date;
|
|
354
|
+
"date-like": number | string | Date;
|
|
341
355
|
function: Function;
|
|
342
356
|
null: null;
|
|
343
357
|
number: number;
|
|
358
|
+
numerical: bigint | number;
|
|
344
359
|
object: object;
|
|
345
360
|
string: string;
|
|
346
361
|
symbol: symbol;
|
package/types/model.d.ts
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import type { OptionalKeysOf, RequiredKeysOf, Simplify, UnionToTuple } from 'type-fest';
|
|
2
|
+
export type AutoInferExclude = 'date-like' | 'numerical';
|
|
2
3
|
export type GetKey<Value> = {
|
|
3
|
-
[Key in
|
|
4
|
-
}[
|
|
5
|
-
|
|
4
|
+
[Key in Exclude<ValueKey, AutoInferExclude>]: Value extends Values[Key] ? Key : never;
|
|
5
|
+
}[Exclude<ValueKey, AutoInferExclude>] extends infer SpecificKey ? SpecificKey extends never ? {
|
|
6
|
+
[Key in AutoInferExclude]: Value extends Values[Key] ? Key : never;
|
|
7
|
+
}[AutoInferExclude] : SpecificKey : never;
|
|
8
|
+
export type GetTypes<Value extends unknown[]> = Value extends [infer Type] ? Type : Value;
|
|
6
9
|
export type GetType<Value> = GetTypes<UnionToTuple<GetKey<Value>>>;
|
|
7
|
-
export type InferProperty<Value> = Value extends Property ? Value['type']
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
export type InferProperty<Value> = Value extends Property ? InferPropertyType<Value['type']> : never;
|
|
11
|
+
type InferPropertyType<Value> = Value extends (infer Type)[] ? InferPropertyTypeValue<Type>[] : InferPropertyTypeValue<Value>;
|
|
12
|
+
type InferPropertyTypeValue<Value> = Value extends PropertyType ? Value extends Schema ? Inferred<Value> : Value extends Schematic<infer Model> ? Model : Value extends ValueKey ? Values[Value] : Value extends (infer NestedElementType)[] ? InferPropertyTypeValue<NestedElementType>[] : Value : never;
|
|
13
|
+
export type InferValue<Value> = Value extends ValueKey ? Values[Value] : Value extends ValueKey[] ? Values[Value[number]] : never;
|
|
14
|
+
export type Inferred<Model extends Schema> = Simplify<{
|
|
10
15
|
[Key in InferredRequiredProperties<Model>]: Model[Key] extends Property ? InferProperty<Model[Key]> : InferValue<Model[Key]>;
|
|
11
16
|
} & {
|
|
12
17
|
[Key in InferredOptionalProperties<Model>]?: Model[Key] extends Property ? InferProperty<Model[Key]> : never;
|
|
13
|
-
}
|
|
18
|
+
}>;
|
|
14
19
|
export type InferredOptionalProperties<Model extends Schema> = {
|
|
15
20
|
[Key in keyof Model]: Model[Key] extends Property ? Model[Key]['required'] extends false ? Key : never : never;
|
|
16
21
|
}[keyof Model];
|
|
@@ -23,8 +28,9 @@ export type OptionalProperty<Type> = {
|
|
|
23
28
|
};
|
|
24
29
|
export type Property = {
|
|
25
30
|
required?: boolean;
|
|
26
|
-
type:
|
|
31
|
+
type: PropertyType | PropertyType[];
|
|
27
32
|
};
|
|
33
|
+
type PropertyType = Schema | Schematic<unknown> | ValueKey;
|
|
28
34
|
export type RequiredProperty<Type> = {
|
|
29
35
|
required: true;
|
|
30
36
|
type: GetType<Type>;
|
|
@@ -32,7 +38,9 @@ export type RequiredProperty<Type> = {
|
|
|
32
38
|
/**
|
|
33
39
|
* A schema for validating objects
|
|
34
40
|
*/
|
|
35
|
-
export type Schema =
|
|
41
|
+
export type Schema = {
|
|
42
|
+
[key: string]: Property | ValueKey | ValueKey[];
|
|
43
|
+
};
|
|
36
44
|
/**
|
|
37
45
|
* A schematic for validating objects
|
|
38
46
|
*/
|
|
@@ -53,23 +61,31 @@ export type TypedSchema<Model extends Typed> = Simplify<{
|
|
|
53
61
|
}>;
|
|
54
62
|
export type ValidatedProperty = {
|
|
55
63
|
required: boolean;
|
|
56
|
-
types:
|
|
64
|
+
types: ValidatedPropertyType[];
|
|
57
65
|
};
|
|
66
|
+
export type ValidatedPropertyType = Schematic<unknown> | ValidatedSchema | ValueKey;
|
|
58
67
|
export type ValidatedSchema = {
|
|
59
68
|
keys: string[];
|
|
60
69
|
length: number;
|
|
61
|
-
properties:
|
|
70
|
+
properties: ValidatedSchemaProperties;
|
|
71
|
+
};
|
|
72
|
+
type ValidatedSchemaProperties = {
|
|
73
|
+
[key: string]: ValidatedProperty;
|
|
62
74
|
};
|
|
75
|
+
export type ValueKey = keyof Values;
|
|
63
76
|
export type Values = {
|
|
64
77
|
array: unknown[];
|
|
65
78
|
bigint: bigint;
|
|
66
79
|
boolean: boolean;
|
|
67
80
|
date: Date;
|
|
81
|
+
'date-like': number | string | Date;
|
|
68
82
|
function: Function;
|
|
69
83
|
null: null;
|
|
70
84
|
number: number;
|
|
85
|
+
numerical: bigint | number;
|
|
71
86
|
object: object;
|
|
72
87
|
string: string;
|
|
73
88
|
symbol: symbol;
|
|
74
89
|
undefined: undefined;
|
|
75
90
|
};
|
|
91
|
+
export {};
|
package/types/schematic.d.cts
CHANGED
|
@@ -270,20 +270,25 @@ export type UnionToTuple<T, L = LastOfUnion<T>> = IsNever<T> extends false ? [
|
|
|
270
270
|
L
|
|
271
271
|
] : [
|
|
272
272
|
];
|
|
273
|
+
export type AutoInferExclude = "date-like" | "numerical";
|
|
273
274
|
export type GetKey<Value> = {
|
|
274
|
-
[Key in
|
|
275
|
-
}[
|
|
275
|
+
[Key in Exclude<ValueKey, AutoInferExclude>]: Value extends Values[Key] ? Key : never;
|
|
276
|
+
}[Exclude<ValueKey, AutoInferExclude>] extends infer SpecificKey ? SpecificKey extends never ? {
|
|
277
|
+
[Key in AutoInferExclude]: Value extends Values[Key] ? Key : never;
|
|
278
|
+
}[AutoInferExclude] : SpecificKey : never;
|
|
276
279
|
export type GetTypes<Value extends unknown[]> = Value extends [
|
|
277
|
-
infer
|
|
278
|
-
] ?
|
|
280
|
+
infer Type
|
|
281
|
+
] ? Type : Value;
|
|
279
282
|
export type GetType<Value> = GetTypes<UnionToTuple<GetKey<Value>>>;
|
|
280
|
-
export type InferProperty<Value> = Value extends Property ? Value["type"]
|
|
281
|
-
export type
|
|
282
|
-
export type Inferred<Model extends
|
|
283
|
+
export type InferProperty<Value> = Value extends Property ? InferPropertyType<Value["type"]> : never;
|
|
284
|
+
export type InferPropertyType<Value> = Value extends (infer Type)[] ? InferPropertyTypeValue<Type>[] : InferPropertyTypeValue<Value>;
|
|
285
|
+
export type InferPropertyTypeValue<Value> = Value extends PropertyType ? Value extends Schema ? Inferred<Value> : Value extends Schematic<infer Model> ? Model : Value extends ValueKey ? Values[Value] : Value extends (infer NestedElementType)[] ? InferPropertyTypeValue<NestedElementType>[] : Value : never;
|
|
286
|
+
export type InferValue<Value> = Value extends ValueKey ? Values[Value] : Value extends ValueKey[] ? Values[Value[number]] : never;
|
|
287
|
+
export type Inferred<Model extends Schema> = Simplify<{
|
|
283
288
|
[Key in InferredRequiredProperties<Model>]: Model[Key] extends Property ? InferProperty<Model[Key]> : InferValue<Model[Key]>;
|
|
284
289
|
} & {
|
|
285
290
|
[Key in InferredOptionalProperties<Model>]?: Model[Key] extends Property ? InferProperty<Model[Key]> : never;
|
|
286
|
-
}
|
|
291
|
+
}>;
|
|
287
292
|
export type InferredOptionalProperties<Model extends Schema> = {
|
|
288
293
|
[Key in keyof Model]: Model[Key] extends Property ? Model[Key]["required"] extends false ? Key : never : never;
|
|
289
294
|
}[keyof Model];
|
|
@@ -296,8 +301,9 @@ export type OptionalProperty<Type> = {
|
|
|
296
301
|
};
|
|
297
302
|
export type Property = {
|
|
298
303
|
required?: boolean;
|
|
299
|
-
type:
|
|
304
|
+
type: PropertyType | PropertyType[];
|
|
300
305
|
};
|
|
306
|
+
export type PropertyType = Schema | Schematic<unknown> | ValueKey;
|
|
301
307
|
export type RequiredProperty<Type> = {
|
|
302
308
|
required: true;
|
|
303
309
|
type: GetType<Type>;
|
|
@@ -305,7 +311,9 @@ export type RequiredProperty<Type> = {
|
|
|
305
311
|
/**
|
|
306
312
|
* A schema for validating objects
|
|
307
313
|
*/
|
|
308
|
-
export type Schema =
|
|
314
|
+
export type Schema = {
|
|
315
|
+
[key: string]: Property | ValueKey | ValueKey[];
|
|
316
|
+
};
|
|
309
317
|
/**
|
|
310
318
|
* A schematic for validating objects
|
|
311
319
|
*/
|
|
@@ -324,26 +332,29 @@ export type TypedSchema<Model extends Typed> = Simplify<{
|
|
|
324
332
|
} & {
|
|
325
333
|
[Key in OptionalKeysOf<Model>]: OptionalProperty<Model[Key]>;
|
|
326
334
|
}>;
|
|
335
|
+
export type ValueKey = keyof Values;
|
|
327
336
|
export type Values = {
|
|
328
337
|
array: unknown[];
|
|
329
338
|
bigint: bigint;
|
|
330
339
|
boolean: boolean;
|
|
331
340
|
date: Date;
|
|
341
|
+
"date-like": number | string | Date;
|
|
332
342
|
function: Function;
|
|
333
343
|
null: null;
|
|
334
344
|
number: number;
|
|
345
|
+
numerical: bigint | number;
|
|
335
346
|
object: object;
|
|
336
347
|
string: string;
|
|
337
348
|
symbol: symbol;
|
|
338
349
|
undefined: undefined;
|
|
339
350
|
};
|
|
340
|
-
/**
|
|
341
|
-
* Create a schematic from a typed schema
|
|
342
|
-
*/
|
|
343
|
-
export declare function schematic<Model extends Typed>(schema: TypedSchema<Model>): Schematic<Model>;
|
|
344
351
|
/**
|
|
345
352
|
* Create a schematic from a schema
|
|
346
353
|
*/
|
|
347
354
|
export declare function schematic<Model extends Schema>(schema: Model): Schematic<Inferred<Model>>;
|
|
355
|
+
/**
|
|
356
|
+
* Create a schematic from a typed schema
|
|
357
|
+
*/
|
|
358
|
+
export declare function schematic<Model extends Typed>(schema: TypedSchema<Model>): Schematic<Model>;
|
|
348
359
|
|
|
349
360
|
export {};
|
package/types/schematic.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Inferred, Schema, Schematic, Typed, TypedSchema } from './model';
|
|
2
|
-
/**
|
|
3
|
-
* Create a schematic from a typed schema
|
|
4
|
-
*/
|
|
5
|
-
export declare function schematic<Model extends Typed>(schema: TypedSchema<Model>): Schematic<Model>;
|
|
6
2
|
/**
|
|
7
3
|
* Create a schematic from a schema
|
|
8
4
|
*/
|
|
9
5
|
export declare function schematic<Model extends Schema>(schema: Model): Schematic<Inferred<Model>>;
|
|
6
|
+
/**
|
|
7
|
+
* Create a schematic from a typed schema
|
|
8
|
+
*/
|
|
9
|
+
export declare function schematic<Model extends Typed>(schema: TypedSchema<Model>): Schematic<Model>;
|