@oscarpalmer/jhunal 0.21.0 → 0.22.0

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