@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.
Files changed (43) hide show
  1. package/README.md +2 -0
  2. package/dist/helpers.cjs +24 -3
  3. package/dist/helpers.js +24 -3
  4. package/dist/is.cjs +19 -0
  5. package/dist/is.js +14 -0
  6. package/dist/schematic.cjs +5 -3
  7. package/dist/schematic.js +5 -3
  8. package/dist/validation/schema.validation.cjs +54 -0
  9. package/dist/validation/schema.validation.js +49 -0
  10. package/dist/validation/type.validation.cjs +33 -0
  11. package/dist/validation/type.validation.js +29 -0
  12. package/dist/validation/value.validation.cjs +35 -0
  13. package/dist/validation/value.validation.js +31 -0
  14. package/package.json +1 -1
  15. package/src/helpers.ts +33 -5
  16. package/src/index.ts +1 -1
  17. package/src/is.ts +22 -0
  18. package/src/model.ts +84 -43
  19. package/src/schematic.ts +14 -10
  20. package/src/validation/schema.validation.ts +63 -0
  21. package/src/validation/type.validation.ts +34 -0
  22. package/src/validation/value.validation.ts +46 -0
  23. package/types/helpers.d.cts +26 -1
  24. package/types/helpers.d.ts +2 -2
  25. package/types/index.d.cts +25 -14
  26. package/types/index.d.ts +1 -1
  27. package/types/is.d.cts +15 -0
  28. package/types/is.d.ts +3 -0
  29. package/types/model.d.cts +27 -12
  30. package/types/model.d.ts +27 -11
  31. package/types/schematic.d.cts +25 -14
  32. package/types/schematic.d.ts +4 -4
  33. package/types/validation/schema.validation.d.cts +55 -0
  34. package/types/validation/schema.validation.d.ts +3 -0
  35. package/types/validation/type.validation.d.cts +43 -0
  36. package/types/validation/type.validation.d.ts +2 -0
  37. package/types/validation/value.validation.d.cts +43 -0
  38. package/types/validation/value.validation.d.ts +2 -0
  39. package/dist/validation.cjs +0 -89
  40. package/dist/validation.js +0 -84
  41. package/src/validation.ts +0 -109
  42. package/types/validation.d.cts +0 -28
  43. 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 {getValidatedSchema, validate} from './validation';
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<Inferred<Model>>;
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
- is: (value: unknown) => canValidate && validate(validated, value),
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
+ }
@@ -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): (keyof Values)[];
41
+ export declare function getTypes(value: unknown): ValidatedPropertyType[];
17
42
 
18
43
  export {};
@@ -1,2 +1,2 @@
1
- import type { Values } from './model';
2
- export declare function getTypes(value: unknown): (keyof Values)[];
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 keyof Values]: Value extends Values[Key] ? Key : never;
275
- }[keyof Values];
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 Single
278
- ] ? Single : Value;
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"] extends keyof Values ? Values[Value["type"]] : Value["type"] extends (keyof Values)[] ? Values[Value["type"][number]] : never : never;
281
- export type InferValue<Value> = Value extends keyof Values ? Values[Value] : Value extends (keyof Values)[] ? Values[Value[number]] : never;
282
- export type Inferred<Model extends Schema> = {
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: keyof Values | (keyof Values)[];
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 = Record<string, keyof Values | (keyof Values)[] | Property>;
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
@@ -0,0 +1,3 @@
1
+ import type { Schematic } from './model';
2
+ export declare function isDateLike(value: unknown): value is Date;
3
+ export declare function isSchematic(value: unknown): value is Schematic<never>;
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 keyof Values]: Value extends Values[Key] ? Key : never;
275
- }[keyof Values];
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 Single
278
- ] ? Single : Value;
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"] extends keyof Values ? Values[Value["type"]] : Value["type"] extends (keyof Values)[] ? Values[Value["type"][number]] : never : never;
281
- export type InferValue<Value> = Value extends keyof Values ? Values[Value] : Value extends (keyof Values)[] ? Values[Value[number]] : never;
282
- export type Inferred<Model extends Schema> = {
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: keyof Values | (keyof Values)[];
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 = Record<string, keyof Values | (keyof Values)[] | Property>;
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: (keyof Values)[];
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: Record<string, ValidatedProperty>;
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 keyof Values]: Value extends Values[Key] ? Key : never;
4
- }[keyof Values];
5
- export type GetTypes<Value extends unknown[]> = Value extends [infer Single] ? Single : Value;
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'] extends keyof Values ? Values[Value['type']] : Value['type'] extends (keyof Values)[] ? Values[Value['type'][number]] : never : never;
8
- export type InferValue<Value> = Value extends keyof Values ? Values[Value] : Value extends (keyof Values)[] ? Values[Value[number]] : never;
9
- export type Inferred<Model extends Schema> = {
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: keyof Values | (keyof Values)[];
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 = Record<string, keyof Values | (keyof Values)[] | Property>;
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: (keyof Values)[];
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: Record<string, ValidatedProperty>;
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 {};
@@ -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 keyof Values]: Value extends Values[Key] ? Key : never;
275
- }[keyof Values];
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 Single
278
- ] ? Single : Value;
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"] extends keyof Values ? Values[Value["type"]] : Value["type"] extends (keyof Values)[] ? Values[Value["type"][number]] : never : never;
281
- export type InferValue<Value> = Value extends keyof Values ? Values[Value] : Value extends (keyof Values)[] ? Values[Value[number]] : never;
282
- export type Inferred<Model extends Schema> = {
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: keyof Values | (keyof Values)[];
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 = Record<string, keyof Values | (keyof Values)[] | Property>;
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 {};
@@ -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>;