@oscarpalmer/jhunal 0.24.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/constants.d.mts +4 -4
  2. package/dist/constants.mjs +4 -4
  3. package/dist/helpers/misc.helper.d.mts +3 -3
  4. package/dist/helpers/misc.helper.mjs +3 -3
  5. package/dist/index.d.mts +64 -64
  6. package/dist/index.mjs +78 -56
  7. package/dist/models/infer.model.d.mts +21 -21
  8. package/dist/models/misc.model.d.mts +3 -3
  9. package/dist/models/{schema.plain.model.d.mts → schematic.plain.model.d.mts} +18 -18
  10. package/dist/models/{schema.typed.model.d.mts → schematic.typed.model.d.mts} +8 -8
  11. package/dist/models/transform.model.d.mts +6 -6
  12. package/dist/models/validation.model.d.mts +2 -2
  13. package/dist/{schematic.d.mts → schema.d.mts} +20 -20
  14. package/dist/{schematic.mjs → schema.mjs} +13 -13
  15. package/dist/validator/object.validator.mjs +63 -41
  16. package/dist/validator/schema.validator.d.mts +7 -0
  17. package/dist/validator/{schematic.validator.mjs → schema.validator.mjs} +5 -5
  18. package/package.json +1 -1
  19. package/src/constants.ts +3 -3
  20. package/src/helpers/misc.helper.ts +5 -5
  21. package/src/index.ts +4 -4
  22. package/src/models/infer.model.ts +26 -28
  23. package/src/models/misc.model.ts +3 -3
  24. package/src/models/{schema.plain.model.ts → schematic.plain.model.ts} +20 -20
  25. package/src/models/{schema.typed.model.ts → schematic.typed.model.ts} +8 -8
  26. package/src/models/transform.model.ts +6 -6
  27. package/src/models/validation.model.ts +2 -2
  28. package/src/{schematic.ts → schema.ts} +29 -27
  29. package/src/validator/object.validator.ts +123 -63
  30. package/src/validator/{schematic.validator.ts → schema.validator.ts} +3 -3
  31. package/dist/validator/schematic.validator.d.mts +0 -7
  32. /package/dist/models/{schema.plain.model.mjs → schematic.plain.model.mjs} +0 -0
  33. /package/dist/models/{schema.typed.model.mjs → schematic.typed.model.mjs} +0 -0
@@ -1,35 +1,35 @@
1
- import { Schematic } from "../schematic.mjs";
2
- import { PlainSchema, Schema, SchemaProperty } from "./schema.plain.model.mjs";
1
+ import { Schema } from "../schema.mjs";
2
+ import { PlainSchematic, Schematic, SchematicProperty } from "./schematic.plain.model.mjs";
3
3
  import { IsOptionalProperty, ValueName, Values } from "./misc.model.mjs";
4
4
  import { Constructor, Simplify } from "@oscarpalmer/atoms/models";
5
5
 
6
6
  //#region src/models/infer.model.d.ts
7
7
  /**
8
- * Infers the TypeScript type from a {@link Schema} definition
8
+ * Infers the TypeScript type from a {@link Schematic} definition
9
9
  *
10
- * @template Model Schema to infer types from
10
+ * @template Model Schematic to infer types from
11
11
  *
12
12
  * @example
13
13
  * ```ts
14
- * const userSchema = {
14
+ * const userSchematic = {
15
15
  * name: 'string',
16
16
  * age: 'number',
17
17
  * address: { $required: false, $type: 'string' },
18
- * } satisfies Schema;
18
+ * } satisfies Schematic;
19
19
  *
20
- * type User = Infer<typeof userSchema>;
20
+ * type User = Infer<typeof userSchematic>;
21
21
  * // { name: string; age: number; address?: string }
22
22
  * ```
23
23
  */
24
- type Infer<Model extends Schema> = Simplify<{ [Key in InferRequiredKeys<Model>]: InferSchemaEntry<Model[Key]> } & { [Key in InferOptionalKeys<Model>]?: InferSchemaEntry<Model[Key]> }>;
24
+ type Infer<Model extends Schematic> = Simplify<{ [Key in InferRequiredKeys<Model>]: InferSchemaEntry<Model[Key]> } & { [Key in InferOptionalKeys<Model>]?: InferSchemaEntry<Model[Key]> }>;
25
25
  /**
26
- * Extracts keys from a {@link Schema} whose entries are optional _(i.e., `$required` is `false`)_
26
+ * Extracts keys from a {@link Schematic} whose entries are optional _(i.e., `$required` is `false`)_
27
27
  *
28
- * @template Model - {@link Schema} to extract optional keys from
28
+ * @template Model - {@link Schematic} to extract optional keys from
29
29
  */
30
- type InferOptionalKeys<Model extends Schema> = keyof { [Key in keyof Model as IsOptionalProperty<Model[Key]> extends true ? Key : never]: never };
30
+ type InferOptionalKeys<Model extends Schematic> = keyof { [Key in keyof Model as IsOptionalProperty<Model[Key]> extends true ? Key : never]: never };
31
31
  /**
32
- * Infers the TypeScript type from a {@link SchemaProperty}'s `$type` field
32
+ * Infers the TypeScript type from a {@link SchematicProperty}'s `$type` field
33
33
  *
34
34
  * @template Value `$type` value _(single or array)_
35
35
  */
@@ -37,30 +37,30 @@ type InferPropertyType<Value> = Value extends (infer Item)[] ? InferPropertyValu
37
37
  /**
38
38
  * Maps a single `$type` definition to its TypeScript equivalent
39
39
  *
40
- * Resolves, in order: {@link Constructor} instances, {@link Schematic} models, {@link ValueName} strings, and nested {@link PlainSchema} objects
40
+ * Resolves, in order: {@link Constructor}s, {@link Schema} instances, {@link ValueName} values, and nested {@link PlainSchematic} objects
41
41
  *
42
42
  * @template Value single type definition
43
43
  */
44
- 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;
44
+ type InferPropertyValue<Value> = Value extends Constructor<infer Instance> ? Instance : Value extends Schema<infer Model> ? Model : Value extends ValueName ? Values[Value & ValueName] : Value extends PlainSchematic ? Infer<Value> : never;
45
45
  /**
46
- * Extracts keys from a {@link Schema} whose entries are required _(i.e., `$required` is not `false`)_
46
+ * Extracts keys from a {@link Schematic} whose entries are required _(i.e., `$required` is not `false`)_
47
47
  *
48
- * @template Model Schema to extract required keys from
48
+ * @template Model Schematic to extract required keys from
49
49
  */
50
- type InferRequiredKeys<Model extends Schema> = keyof { [Key in keyof Model as IsOptionalProperty<Model[Key]> extends true ? never : Key]: never };
50
+ type InferRequiredKeys<Model extends Schematic> = keyof { [Key in keyof Model as IsOptionalProperty<Model[Key]> extends true ? never : Key]: never };
51
51
  /**
52
- * Infers the TypeScript type from a top-level {@link Schema} entry
52
+ * Infers the TypeScript type from a top-level {@link Schematic} entry
53
53
  *
54
- * @template Value Schema entry value _(single or array)_
54
+ * @template Value Schematic entry value _(single or array)_
55
55
  */
56
56
  type InferSchemaEntry<Value> = Value extends (infer Item)[] ? InferSchemaEntryValue<Item> : InferSchemaEntryValue<Value>;
57
57
  /**
58
58
  * Maps a single top-level schema entry to its TypeScript type
59
59
  *
60
- * Resolves, in order: {@link Constructor} instances, {@link Schematic} models, {@link SchemaProperty} objects, {@link PlainSchema} objects, and {@link ValueName} strings
60
+ * Resolves, in order: {@link Constructor}s, {@link Schema} instances, {@link SchemaProperty} objects, {@link PlainSchematic} objects, and {@link ValueName} values
61
61
  *
62
62
  * @template Value single schema entry
63
63
  */
64
- 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;
64
+ type InferSchemaEntryValue<Value> = Value extends Constructor<infer Instance> ? Instance : Value extends Schema<infer Model> ? Model : Value extends SchematicProperty ? InferPropertyType<Value['$type']> : Value extends PlainSchematic ? Infer<Value & Schematic> : Value extends ValueName ? Values[Value & ValueName] : never;
65
65
  //#endregion
66
66
  export { Infer, InferOptionalKeys, InferPropertyType, InferPropertyValue, InferRequiredKeys, InferSchemaEntry, InferSchemaEntryValue };
@@ -1,4 +1,4 @@
1
- import { SchemaProperty } from "./schema.plain.model.mjs";
1
+ import { SchematicProperty } from "./schematic.plain.model.mjs";
2
2
 
3
3
  //#region src/models/misc.model.d.ts
4
4
  /**
@@ -29,11 +29,11 @@ type ExtractValueNames<Value> = Value extends ValueName ? Value : Value extends
29
29
  /**
30
30
  * Determines whether a schema entry is optional
31
31
  *
32
- * Returns `true` if the entry is a {@link SchemaProperty} with `$required` set to `false`; otherwise returns `false`
32
+ * Returns `true` if the entry is a {@link SchematicProperty} with `$required` set to `false`; otherwise returns `false`
33
33
  *
34
34
  * @template Value Schema entry to check
35
35
  */
36
- type IsOptionalProperty<Value> = Value extends SchemaProperty ? Value['$required'] extends false ? true : false : false;
36
+ type IsOptionalProperty<Value> = Value extends SchematicProperty ? Value['$required'] extends false ? true : false : false;
37
37
  /**
38
38
  * Extracts the last member from a union type by leveraging contravariance of function parameter types
39
39
  *
@@ -1,13 +1,13 @@
1
- import { Schematic } from "../schematic.mjs";
1
+ import { Schema } from "../schema.mjs";
2
2
  import { ExtractValueNames, ValueName, Values } from "./misc.model.mjs";
3
3
  import { Constructor } from "@oscarpalmer/atoms/models";
4
4
 
5
- //#region src/models/schema.plain.model.d.ts
5
+ //#region src/models/schematic.plain.model.d.ts
6
6
  /**
7
- * A generic schema allowing nested schemas, {@link SchemaEntry} values, or arrays of {@link SchemaEntry} as values
7
+ * A generic schematic allowing nested schematics, {@link SchematicEntry} values, or arrays of {@link SchematicEntry} as values
8
8
  */
9
- type PlainSchema = {
10
- [key: string]: PlainSchema | SchemaEntry | SchemaEntry[] | undefined;
9
+ type PlainSchematic = {
10
+ [key: string]: PlainSchematic | SchematicEntry | SchematicEntry[] | undefined;
11
11
  } & {
12
12
  $default?: never;
13
13
  $required?: never;
@@ -15,30 +15,30 @@ type PlainSchema = {
15
15
  $validators?: never;
16
16
  };
17
17
  /**
18
- * A schema for validating objects
18
+ * A schematic for validating objects
19
19
  *
20
20
  * @example
21
21
  * ```ts
22
- * const schema: Schema = {
22
+ * const schematic = {
23
23
  * name: 'string',
24
24
  * age: 'number',
25
25
  * tags: ['string', 'number'],
26
- * };
26
+ * } satisfies Schematic;
27
27
  * ```
28
28
  */
29
- type Schema = PlainSchema;
29
+ type Schematic = PlainSchematic;
30
30
  /**
31
- * A union of all valid types for a single schema entry
31
+ * A union of all valid types for a single schematic entry
32
32
  *
33
- * Can be a {@link Constructor}, {@link PlainSchema}, {@link SchemaProperty}, {@link Schematic}, {@link ValueName} string, or a custom validator function
33
+ * Can be a {@link Constructor}, {@link PlainSchematic}, {@link SchematicProperty}, {@link Schema}, {@link ValueName}, or a custom validator function
34
34
  */
35
- type SchemaEntry = Constructor | PlainSchema | SchemaProperty | Schematic<unknown> | ValueName | ((value: unknown) => boolean);
35
+ type SchematicEntry = Constructor | PlainSchematic | Schema<unknown> | SchematicProperty | ValueName | ((value: unknown) => boolean);
36
36
  /**
37
37
  * A property definition with explicit type(s), an optional requirement flag, and optional validators
38
38
  *
39
39
  * @example
40
40
  * ```ts
41
- * const prop: SchemaProperty = {
41
+ * const prop: SchematicProperty = {
42
42
  * $required: false,
43
43
  * $type: ['string', 'number'],
44
44
  * $validators: {
@@ -48,7 +48,7 @@ type SchemaEntry = Constructor | PlainSchema | SchemaProperty | Schematic<unknow
48
48
  * };
49
49
  * ```
50
50
  */
51
- type SchemaProperty = {
51
+ type SchematicProperty = {
52
52
  $default?: unknown;
53
53
  /**
54
54
  * Whether the property is required _(defaults to `true`)_
@@ -64,11 +64,11 @@ type SchemaProperty = {
64
64
  $validators?: PropertyValidators<SchemaPropertyType | SchemaPropertyType[]>;
65
65
  };
66
66
  /**
67
- * A union of valid types for a {@link SchemaProperty}'s `$type` field
67
+ * A union of valid types for a {@link SchematicProperty}'s `$type` field
68
68
  *
69
- * Can be a {@link Constructor}, {@link PlainSchema}, {@link Schematic}, {@link ValueName} string, or a custom validator function
69
+ * Can be a {@link Constructor}, {@link PlainSchematic}, {@link Schema}, {@link ValueName} string, or a custom validator function
70
70
  */
71
- type SchemaPropertyType = Constructor | PlainSchema | Schematic<unknown> | ValueName | ((value: unknown) => boolean);
71
+ type SchemaPropertyType = Constructor | PlainSchematic | Schema<unknown> | ValueName | ((value: unknown) => boolean);
72
72
  /**
73
73
  * A map of optional validator functions keyed by {@link ValueName}, used to add custom validation to {@link SchemaProperty} definitions
74
74
  *
@@ -85,4 +85,4 @@ type SchemaPropertyType = Constructor | PlainSchema | Schematic<unknown> | Value
85
85
  */
86
86
  type PropertyValidators<Value> = { [Key in ExtractValueNames<Value>]?: ((value: Values[Key]) => boolean) | Array<(value: Values[Key]) => boolean> };
87
87
  //#endregion
88
- export { PlainSchema, PropertyValidators, Schema, SchemaEntry, SchemaProperty, SchemaPropertyType };
88
+ export { PlainSchematic, PropertyValidators, SchemaPropertyType, Schematic, SchematicEntry, SchematicProperty };
@@ -1,12 +1,12 @@
1
1
  import { ToSchemaPropertyType, ToSchemaType } from "./transform.model.mjs";
2
- import { Schematic } from "../schematic.mjs";
3
- import { PropertyValidators } from "./schema.plain.model.mjs";
2
+ import { Schema } from "../schema.mjs";
3
+ import { PropertyValidators } from "./schematic.plain.model.mjs";
4
4
  import { OptionalKeys, RequiredKeys } from "./misc.model.mjs";
5
5
  import { PlainObject, Simplify } from "@oscarpalmer/atoms/models";
6
6
 
7
- //#region src/models/schema.typed.model.d.ts
7
+ //#region src/models/schematic.typed.model.d.ts
8
8
  /**
9
- * A typed optional property definition generated by {@link TypedSchema} for optional keys, with `$required` set to `false` and excludes `undefined` from the type
9
+ * A typed optional property definition generated by {@link TypedSchematic} for optional keys, with `$required` set to `false` and excludes `undefined` from the type
10
10
  *
11
11
  * @template Value Property's type _(including `undefined`)_
12
12
  *
@@ -24,7 +24,7 @@ type TypedPropertyOptional<Value> = {
24
24
  $validators?: PropertyValidators<ToSchemaPropertyType<Exclude<Value, undefined>>>;
25
25
  };
26
26
  /**
27
- * A typed required property definition generated by {@link TypedSchema} for required keys, with `$required` defaulting to `true`
27
+ * A typed required property definition generated by {@link TypedSchematic} for required keys, with `$required` defaulting to `true`
28
28
  *
29
29
  * @template Value Property's type
30
30
  *
@@ -44,7 +44,7 @@ type TypedPropertyRequired<Value> = {
44
44
  /**
45
45
  * Creates a schema type constrained to match a TypeScript type
46
46
  *
47
- * 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}
47
+ * Required keys map to {@link ToSchemaType} or {@link TypedPropertyRequired}; plain object values may also use {@link Schema}
48
48
  *
49
49
  * @template Model Object type to generate a schema for
50
50
  *
@@ -59,6 +59,6 @@ type TypedPropertyRequired<Value> = {
59
59
  * };
60
60
  * ```
61
61
  */
62
- type TypedSchema<Model extends PlainObject> = Simplify<{ [Key in RequiredKeys<Model>]: Model[Key] extends PlainObject ? Schematic<Model[Key]> : ToSchemaType<Model[Key]> | TypedPropertyRequired<Model[Key]> } & { [Key in OptionalKeys<Model>]: Exclude<Model[Key], undefined> extends PlainObject ? Schematic<Exclude<Model[Key], undefined>> : TypedPropertyOptional<Model[Key]> }>;
62
+ type TypedSchematic<Model extends PlainObject> = Simplify<{ [Key in RequiredKeys<Model>]: Model[Key] extends PlainObject ? Schema<Model[Key]> : ToSchemaType<Model[Key]> | TypedPropertyRequired<Model[Key]> } & { [Key in OptionalKeys<Model>]: Exclude<Model[Key], undefined> extends PlainObject ? Schema<Exclude<Model[Key], undefined>> : TypedPropertyOptional<Model[Key]> }>;
63
63
  //#endregion
64
- export { TypedPropertyOptional, TypedPropertyRequired, TypedSchema };
64
+ export { TypedPropertyOptional, TypedPropertyRequired, TypedSchematic };
@@ -1,5 +1,5 @@
1
- import { TypedSchema } from "./schema.typed.model.mjs";
2
- import { Schematic } from "../schematic.mjs";
1
+ import { TypedSchematic } from "./schematic.typed.model.mjs";
2
+ import { Schema } from "../schema.mjs";
3
3
  import { DeduplicateTuple, UnionToTuple, UnwrapSingle, Values } from "./misc.model.mjs";
4
4
  import { PlainObject } from "@oscarpalmer/atoms/models";
5
5
 
@@ -25,11 +25,11 @@ type ToSchemaPropertyType<Value> = UnwrapSingle<DeduplicateTuple<MapToSchemaProp
25
25
  /**
26
26
  * Converts a single type to its schema property equivalent
27
27
  *
28
- * Plain objects become {@link TypedSchema}; primitives go through {@link ToValueType}
28
+ * Plain objects become {@link TypedSchematic}; primitives go through {@link ToValueType}
29
29
  *
30
30
  * @template Value Type to convert
31
31
  */
32
- type ToSchemaPropertyTypeEach<Value> = Value extends PlainObject ? TypedSchema<Value> : ToValueType<Value>;
32
+ type ToSchemaPropertyTypeEach<Value> = Value extends PlainObject ? TypedSchematic<Value> : ToValueType<Value>;
33
33
  /**
34
34
  * Converts a TypeScript type to its {@link ValueName} representation, suitable for use as a top-level schema entry
35
35
  *
@@ -39,7 +39,7 @@ type ToSchemaType<Value> = UnwrapSingle<DeduplicateTuple<MapToValueTypes<UnionTo
39
39
  /**
40
40
  * Maps a type to its {@link ValueName} string equivalent
41
41
  *
42
- * 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
42
+ * Resolves {@link Schema} types as-is, then performs a reverse-lookup against {@link Values} _(excluding `'object'`)_ to find a matching key. If no match is found, `object` types resolve to `'object'` or a type-guard function, and all other unrecognised types resolve to a type-guard function
43
43
  *
44
44
  * @template Value Type to map
45
45
  *
@@ -50,6 +50,6 @@ type ToSchemaType<Value> = UnwrapSingle<DeduplicateTuple<MapToValueTypes<UnionTo
50
50
  * // ToValueType<Date> => 'date'
51
51
  * ```
52
52
  */
53
- type ToValueType<Value> = Value extends Schematic<any> ? Value : { [Key in keyof Omit<Values, 'object'>]: Value extends Values[Key] ? Key : never }[keyof Omit<Values, 'object'>] extends infer Match ? [Match] extends [never] ? Value extends object ? 'object' | ((value: unknown) => value is Value) : (value: unknown) => value is Value : Match : never;
53
+ type ToValueType<Value> = Value extends Schema<any> ? Value : { [Key in keyof Omit<Values, 'object'>]: Value extends Values[Key] ? Key : never }[keyof Omit<Values, 'object'>] extends infer Match ? [Match] extends [never] ? Value extends object ? 'object' | ((value: unknown) => value is Value) : (value: unknown) => value is Value : Match : never;
54
54
  //#endregion
55
55
  export { MapToSchemaPropertyTypes, MapToValueTypes, ToSchemaPropertyType, ToSchemaPropertyTypeEach, ToSchemaType, ToValueType };
@@ -1,4 +1,4 @@
1
- import { Schematic } from "../schematic.mjs";
1
+ import { Schema } from "../schema.mjs";
2
2
  import { ValueName } from "./misc.model.mjs";
3
3
  import { GenericCallback, PlainObject } from "@oscarpalmer/atoms/models";
4
4
 
@@ -87,6 +87,6 @@ type ValidatorParameters = {
87
87
  reporting: ReportingInformation;
88
88
  strict: boolean;
89
89
  };
90
- type ValidatorType = Function | PlainObject | Schematic<unknown> | ValueName;
90
+ type ValidatorType = Function | PlainObject | Schema<unknown> | ValueName;
91
91
  //#endregion
92
92
  export { GetOptions, IsOptions, NamedValidatorHandlers, NamedValidators, ReportingInformation, ReportingType, SchematicError, ValidationError, ValidationInformation, ValidationInformationKey, Validator, ValidatorDefaults, ValidatorItem, ValidatorParameters, ValidatorType };
@@ -1,17 +1,17 @@
1
1
  import { Infer } from "./models/infer.model.mjs";
2
- import { TypedSchema } from "./models/schema.typed.model.mjs";
2
+ import { TypedSchematic } from "./models/schematic.typed.model.mjs";
3
3
  import { GetOptions, IsOptions, ValidationInformation, Validator } from "./models/validation.model.mjs";
4
- import { Schema } from "./models/schema.plain.model.mjs";
4
+ import { Schematic } from "./models/schematic.plain.model.mjs";
5
5
  import { PlainObject } from "@oscarpalmer/atoms/models";
6
6
  import { Result } from "@oscarpalmer/atoms/result/models";
7
7
 
8
- //#region src/schematic.d.ts
8
+ //#region src/schema.d.ts
9
9
  /**
10
- * A schematic for validating objects
10
+ * A schema for validating objects
11
11
  */
12
- declare class Schematic<Model> {
12
+ declare class Schema<Model> {
13
13
  #private;
14
- private readonly $schematic;
14
+ private readonly $schema;
15
15
  constructor(validator: Validator);
16
16
  /**
17
17
  * Parse a value according to the schema
@@ -75,7 +75,7 @@ declare class Schematic<Model> {
75
75
  * @param options Validation options
76
76
  * @returns Deeply cloned value, or `undefined` if it's invalid
77
77
  */
78
- get(value: unknown, options: GetOptions<'none'>): Model | undefined;
78
+ get(value: unknown, options: Partial<GetOptions<'none'>>): Model | undefined;
79
79
  /**
80
80
  * Parse a value according to the schema
81
81
  *
@@ -147,7 +147,7 @@ declare class Schematic<Model> {
147
147
  * @param options Validation options
148
148
  * @returns `true` if the value matches the schema, otherwise `false`
149
149
  */
150
- is(value: unknown, options: IsOptions<'none'>): value is Model;
150
+ is(value: unknown, options: Partial<IsOptions<'none'>>): value is Model;
151
151
  /**
152
152
  * Does the value match the schema?
153
153
  *
@@ -159,21 +159,21 @@ declare class Schematic<Model> {
159
159
  is(value: unknown, strict?: true): value is Model;
160
160
  }
161
161
  /**
162
- * Create a schematic from a schema
162
+ * Create a schema from a schematic
163
163
  * @template Model Schema type
164
- * @param schema Schema to create the schematic from
165
- * @throws Throws {@link SchematicError} if the schema can not be converted into a schematic
166
- * @returns A schematic for the given schema
164
+ * @param schema Schematic to create the schema from
165
+ * @throws Throws {@link SchematicError} if the schematic can not be converted into a schema
166
+ * @returns A schema for the given schematic
167
167
  */
168
- declare function schematic<Model extends Schema>(schema: Model): Schematic<Infer<Model>>;
168
+ declare function schema<Model extends Schematic>(schema: Model): Schema<Infer<Model>>;
169
169
  /**
170
- * Create a schematic from a typed schema
170
+ * Create a schema from a typed schematic
171
171
  * @template Model Existing type
172
- * @param schema Typed schema to create the schematic from
173
- * @throws Throws {@link SchematicError} if the schema can not be converted into a schematic
174
- * @returns A schematic for the given typed schema
172
+ * @param schema Typed schematic to create the schema from
173
+ * @throws Throws {@link SchematicError} if the schematic can not be converted into a schema
174
+ * @returns A schema for the given typed schematic
175
175
  */
176
- declare function schematic<Model extends PlainObject>(schema: TypedSchema<Model>): Schematic<Model>;
177
- declare const schematicValidator: WeakMap<Schematic<unknown>, Validator>;
176
+ declare function schema<Model extends PlainObject>(schema: TypedSchematic<Model>): Schema<Model>;
177
+ declare const schemaValidators: WeakMap<Schema<unknown>, Validator>;
178
178
  //#endregion
179
- export { Schematic, schematic, schematicValidator };
179
+ export { Schema, schema, schemaValidators };
@@ -1,24 +1,24 @@
1
- import { PROPERTY_SCHEMATIC, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE } from "./constants.mjs";
2
- import { getParameters, isSchematic } from "./helpers/misc.helper.mjs";
1
+ import { PROPERTY_SCHEMA, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE } from "./constants.mjs";
2
+ import { getParameters, isSchema } from "./helpers/misc.helper.mjs";
3
3
  import { SchematicError } from "./models/validation.model.mjs";
4
4
  import { getObjectValidator } from "./validator/object.validator.mjs";
5
5
  import { isPlainObject } from "@oscarpalmer/atoms/is";
6
6
  import { error, ok } from "@oscarpalmer/atoms/result/misc";
7
- //#region src/schematic.ts
7
+ //#region src/schema.ts
8
8
  /**
9
- * A schematic for validating objects
9
+ * A schema for validating objects
10
10
  */
11
- var Schematic = class {
11
+ var Schema = class {
12
12
  #validator;
13
13
  constructor(validator) {
14
- Object.defineProperty(this, PROPERTY_SCHEMATIC, { value: true });
14
+ Object.defineProperty(this, PROPERTY_SCHEMA, { value: true });
15
15
  this.#validator = validator;
16
- schematicValidator.set(this, validator);
16
+ schemaValidators.set(this, validator);
17
17
  }
18
18
  get(value, options) {
19
19
  const parameters = getParameters(options);
20
20
  const result = this.#validator(value, parameters, true);
21
- if (result === true) return parameters.reporting.none || parameters.reporting.throw ? parameters.output : ok(parameters.output);
21
+ if (result === true) return parameters.reporting.none || parameters.reporting.throw ? parameters.clone ? parameters.output : value : ok(parameters.clone ? parameters.output : value);
22
22
  if (parameters.reporting.none) return;
23
23
  return error(parameters.reporting.all ? result : result[0]);
24
24
  }
@@ -30,11 +30,11 @@ var Schematic = class {
30
30
  return error(parameters.reporting.all ? result : result[0]);
31
31
  }
32
32
  };
33
- function schematic(schema) {
34
- if (isSchematic(schema)) return schema;
33
+ function schema(schema) {
34
+ if (isSchema(schema)) return schema;
35
35
  if (!isPlainObject(schema)) throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE);
36
- return new Schematic(getObjectValidator(schema));
36
+ return new Schema(getObjectValidator(schema));
37
37
  }
38
- const schematicValidator = /* @__PURE__ */ new WeakMap();
38
+ const schemaValidators = /* @__PURE__ */ new WeakMap();
39
39
  //#endregion
40
- export { Schematic, schematic, schematicValidator };
40
+ export { Schema, schema, schemaValidators };
@@ -1,12 +1,12 @@
1
1
  import { PROPERTY_DEFAULT, PROPERTY_REQUIRED, PROPERTY_TYPE, PROPERTY_VALIDATORS, SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY, TYPE_ALL } from "../constants.mjs";
2
- import { getParameters, isSchematic } from "../helpers/misc.helper.mjs";
2
+ import { getParameters, isSchema } from "../helpers/misc.helper.mjs";
3
3
  import { SchematicError, ValidationError } from "../models/validation.model.mjs";
4
4
  import { getDefaultRequiredMessage, getDefaultTypeMessage, getDisallowedMessage, getInputPropertyMissingMessage, getInputPropertyTypeMessage, getInputTypeMessage, getRequiredMessage, getSchematicPropertyNullableMessage, getSchematicPropertyTypeMessage, getUnknownKeysMessage } from "../helpers/message.helper.mjs";
5
5
  import { getBaseValidator } from "./base.validator.mjs";
6
6
  import { getFunctionValidator } from "./function.validator.mjs";
7
7
  import { getNamedHandlers } from "./named.handler.mjs";
8
8
  import { getNamedValidator } from "./named.validator.mjs";
9
- import { getSchematicValidator } from "./schematic.validator.mjs";
9
+ import { getSchemaValidator } from "./schema.validator.mjs";
10
10
  import { isPlainObject } from "@oscarpalmer/atoms/is";
11
11
  import { join } from "@oscarpalmer/atoms/string";
12
12
  import { clone } from "@oscarpalmer/atoms/value/clone";
@@ -35,8 +35,8 @@ function getObjectValidator(original, origin, fromType) {
35
35
  for (let keyIndex = 0; keyIndex < keysLength; keyIndex += 1) {
36
36
  const key = keys[keyIndex];
37
37
  const value = original[key];
38
- if (value == null) throw new SchematicError(getSchematicPropertyNullableMessage(join([origin?.full, key], ".")));
39
38
  const prefixedKey = origin == null ? key : join([origin.full, key], ".");
39
+ if (value == null) throw new SchematicError(getSchematicPropertyNullableMessage(prefixedKey));
40
40
  const fullKey = {
41
41
  full: prefixedKey,
42
42
  short: key
@@ -67,8 +67,8 @@ function getObjectValidator(original, origin, fromType) {
67
67
  case isPlainObject(type):
68
68
  validator = getObjectValidator(type, fullKey, typed);
69
69
  break;
70
- case isSchematic(type):
71
- validator = getSchematicValidator(type);
70
+ case isSchema(type):
71
+ validator = getSchemaValidator(type);
72
72
  break;
73
73
  case TYPE_ALL.has(type):
74
74
  validator = getNamedValidator(fullKey, type, handlers);
@@ -92,20 +92,18 @@ function getObjectValidator(original, origin, fromType) {
92
92
  }
93
93
  const validatorsLength = items.length;
94
94
  return (input, parameters, get) => {
95
- if (!isPlainObject(input)) {
96
- if (origin != null) return [];
97
- const information = {
98
- key: {
99
- full: "",
100
- short: ""
101
- },
102
- value: input,
103
- message: getInputTypeMessage(input)
104
- };
105
- if (parameters.reporting.throw) throw new ValidationError([information]);
106
- parameters.information?.push(information);
107
- return [information];
108
- }
95
+ if (!isPlainObject(input)) return origin == null ? report({
96
+ key: {
97
+ full: "",
98
+ short: ""
99
+ },
100
+ message: {
101
+ arguments: [input],
102
+ callback: getInputTypeMessage
103
+ },
104
+ original: parameters,
105
+ value: input
106
+ }, true) : [];
109
107
  if (parameters.strict) {
110
108
  const unknownKeys = Object.keys(input).filter((key) => !set.has(key));
111
109
  if (unknownKeys.length > 0) {
@@ -122,6 +120,7 @@ function getObjectValidator(original, origin, fromType) {
122
120
  return [information];
123
121
  }
124
122
  }
123
+ const getAndClone = get && parameters.clone;
125
124
  const allInformation = [];
126
125
  const output = {};
127
126
  for (let validatorIndex = 0; validatorIndex < validatorsLength; validatorIndex += 1) {
@@ -130,22 +129,24 @@ function getObjectValidator(original, origin, fromType) {
130
129
  if (value === void 0) {
131
130
  if (required) {
132
131
  if (get && defaults != null) {
133
- output[key.short] = clone(defaults.value);
132
+ const defaultValue = clone(defaults.value);
133
+ if (parameters.clone) output[key.short] = defaultValue;
134
+ else input[key.short] = defaultValue;
134
135
  continue;
135
136
  }
136
137
  if (parameters.reporting.none) return [];
137
- const information = {
138
+ const reported = report({
138
139
  key,
139
140
  value,
140
- message: getInputPropertyMissingMessage(key.full, types)
141
- };
142
- if (parameters.reporting.throw) throw new ValidationError([information]);
143
- parameters.information?.push(information);
144
- if (parameters.reporting.all) {
145
- allInformation.push(information);
146
- continue;
147
- }
148
- return [information];
141
+ information: { all: allInformation },
142
+ message: {
143
+ arguments: [key.full, types],
144
+ callback: getInputPropertyMissingMessage
145
+ },
146
+ original: parameters
147
+ });
148
+ if (reported == null) continue;
149
+ return reported;
149
150
  }
150
151
  continue;
151
152
  }
@@ -154,23 +155,32 @@ function getObjectValidator(original, origin, fromType) {
154
155
  const result = validator(value, parameters, get);
155
156
  parameters.output = previousOutput;
156
157
  if (result === true) {
157
- if (get && !isPlainObject(value)) output[key.short] = parameters.clone ? clone(value) : value;
158
+ if (getAndClone && !isPlainObject(value)) output[key.short] = clone(value);
158
159
  continue;
159
160
  }
160
161
  if (parameters.reporting.none) return [];
161
- const information = typeof result !== "boolean" && result.length > 0 ? result : [{
162
+ const reported = report({
162
163
  key,
163
164
  value,
164
- message: getInputPropertyTypeMessage(key.full, types, value)
165
- }];
166
- if (parameters.reporting.throw) throw new ValidationError(information);
167
- if (parameters.reporting.all) {
168
- allInformation.push(...information);
169
- continue;
170
- }
171
- return information;
165
+ extract: false,
166
+ information: {
167
+ all: allInformation,
168
+ existing: typeof result !== "boolean" && result.length > 0 ? result : void 0
169
+ },
170
+ message: {
171
+ arguments: [
172
+ key.full,
173
+ types,
174
+ value
175
+ ],
176
+ callback: getInputPropertyTypeMessage
177
+ },
178
+ original: parameters
179
+ });
180
+ if (reported == null) continue;
181
+ return reported;
172
182
  }
173
- if (get) if (origin == null) parameters.output = output;
183
+ if (getAndClone) if (origin == null) parameters.output = output;
174
184
  else parameters.output[origin.short] = output;
175
185
  return allInformation.length === 0 ? true : allInformation;
176
186
  };
@@ -181,5 +191,17 @@ function getRequired(obj, key, allowed) {
181
191
  if (typeof obj["$required"] !== "boolean") throw new SchematicError(getRequiredMessage(key));
182
192
  return obj[PROPERTY_REQUIRED];
183
193
  }
194
+ function report(parameters, getReports) {
195
+ const { information, message, original } = parameters;
196
+ const reported = information?.existing ?? [{
197
+ key: parameters.key,
198
+ value: parameters.value,
199
+ message: message.callback(...message.arguments)
200
+ }];
201
+ if (original.reporting.throw) throw new ValidationError(reported);
202
+ information?.all.push(...reported);
203
+ if (parameters.extract ?? true) original.information?.push(...reported);
204
+ if ((getReports ?? false) || !original.reporting.all) return reported;
205
+ }
184
206
  //#endregion
185
207
  export { getObjectValidator };
@@ -0,0 +1,7 @@
1
+ import { Validator } from "../models/validation.model.mjs";
2
+ import { Schema } from "../schema.mjs";
3
+
4
+ //#region src/validator/schema.validator.d.ts
5
+ declare function getSchemaValidator(schematic: Schema<unknown>): Validator;
6
+ //#endregion
7
+ export { getSchemaValidator };
@@ -1,8 +1,8 @@
1
- import { schematicValidator } from "../schematic.mjs";
1
+ import { schemaValidators } from "../schema.mjs";
2
2
  import { isPlainObject } from "@oscarpalmer/atoms/is";
3
- //#region src/validator/schematic.validator.ts
4
- function getSchematicValidator(schematic) {
5
- const validator = schematicValidator.get(schematic);
3
+ //#region src/validator/schema.validator.ts
4
+ function getSchemaValidator(schematic) {
5
+ const validator = schemaValidators.get(schematic);
6
6
  return (input, parameters, get) => {
7
7
  let result;
8
8
  if (isPlainObject(input)) result = validator(input, parameters, get);
@@ -13,4 +13,4 @@ function getSchematicValidator(schematic) {
13
13
  };
14
14
  }
15
15
  //#endregion
16
- export { getSchematicValidator };
16
+ export { getSchemaValidator };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/jhunal",
3
- "version": "0.24.0",
3
+ "version": "0.26.0",
4
4
  "description": "Flies free beneath the glistening moons…",
5
5
  "keywords": [
6
6
  "schema",