@oscarpalmer/jhunal 0.20.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.
package/package.json CHANGED
@@ -1,54 +1,54 @@
1
1
  {
2
- "name": "@oscarpalmer/jhunal",
3
- "version": "0.20.0",
4
- "description": "Flies free beneath the glistening moons…",
5
- "keywords": [
6
- "schema",
7
- "validation"
8
- ],
9
- "license": "MIT",
10
- "author": {
11
- "name": "Oscar Palmér",
12
- "url": "https://oscarpalmer.se"
13
- },
14
- "repository": {
15
- "type": "git",
16
- "url": "git+https://github.com/oscarpalmer/jhunal.git"
17
- },
18
- "files": [
19
- "dist",
20
- "src"
21
- ],
22
- "type": "module",
23
- "module": "./dist/index.mjs",
24
- "types": "./dist/index.d.mts",
25
- "exports": {
26
- "./package.json": "./package.json",
27
- ".": {
28
- "types": "./dist/index.d.mts",
29
- "default": "./dist/index.mjs"
30
- }
31
- },
32
- "scripts": {
33
- "build": "npx vp pack && npm run tsdown:build",
34
- "tsdown:build": "npx tsdown -c ./tsdown.config.ts",
35
- "tsdown:watch": "npx tsdown -c ./tsdown.config.ts --watch",
36
- "test": "npx vp test run --coverage",
37
- "test:leak": "npx vp test run --detect-async-leaks --coverage",
38
- "watch": "npx vite build --watch"
39
- },
40
- "dependencies": {
41
- "@oscarpalmer/atoms": "^0.169"
42
- },
43
- "devDependencies": {
44
- "@types/node": "^25.5",
45
- "@vitest/coverage-istanbul": "^4.1",
46
- "jsdom": "^29.0",
47
- "tsdown": "^0.21",
48
- "typescript": "^5.9",
49
- "vite": "npm:@voidzero-dev/vite-plus-core@latest",
50
- "vite-plus": "latest",
51
- "vitest": "npm:@voidzero-dev/vite-plus-test@latest"
52
- },
53
- "packageManager": "npm@11.11.1"
2
+ "name": "@oscarpalmer/jhunal",
3
+ "version": "0.22.0",
4
+ "description": "Flies free beneath the glistening moons…",
5
+ "keywords": [
6
+ "schema",
7
+ "validation"
8
+ ],
9
+ "license": "MIT",
10
+ "author": {
11
+ "name": "Oscar Palmér",
12
+ "url": "https://oscarpalmer.se"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/oscarpalmer/jhunal.git"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "src"
21
+ ],
22
+ "type": "module",
23
+ "module": "./dist/index.mjs",
24
+ "types": "./dist/index.d.mts",
25
+ "exports": {
26
+ "./package.json": "./package.json",
27
+ ".": {
28
+ "types": "./dist/index.d.mts",
29
+ "default": "./dist/index.mjs"
30
+ }
31
+ },
32
+ "scripts": {
33
+ "build": "npx vp pack && npm run tsdown:build",
34
+ "tsdown:build": "npx tsdown -c ./tsdown.config.ts",
35
+ "tsdown:watch": "npx tsdown -c ./tsdown.config.ts --watch",
36
+ "test": "npx vp test run --coverage",
37
+ "test:leak": "npx vp test run --detect-async-leaks --coverage",
38
+ "watch": "npx vite build --watch"
39
+ },
40
+ "dependencies": {
41
+ "@oscarpalmer/atoms": "^0.170"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^25.5",
45
+ "@vitest/coverage-istanbul": "^4.1",
46
+ "jsdom": "^29.0",
47
+ "tsdown": "^0.21",
48
+ "typescript": "^5.9",
49
+ "vite": "npm:@voidzero-dev/vite-plus-core@latest",
50
+ "vite-plus": "latest",
51
+ "vitest": "npm:@voidzero-dev/vite-plus-test@latest"
52
+ },
53
+ "packageManager": "npm@11.11.1"
54
54
  }
package/src/helpers.ts CHANGED
@@ -30,8 +30,8 @@ import type {ValueName} from './models/misc.model';
30
30
  import type {
31
31
  ReportingInformation,
32
32
  ReportingType,
33
- ValidatedProperty,
34
- ValidatedPropertyType,
33
+ ValidatorParameters,
34
+ ValidatorType,
35
35
  } from './models/validation.model';
36
36
  import type {Schematic} from './schematic';
37
37
 
@@ -39,36 +39,34 @@ export function getInvalidInputMessage(actual: unknown): string {
39
39
  return VALIDATION_MESSAGE_INVALID_INPUT.replace(TEMPLATE_PATTERN, getValueType(actual));
40
40
  }
41
41
 
42
- export function getInvalidMissingMessage(property: ValidatedProperty): string {
43
- let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace(
44
- TEMPLATE_PATTERN,
45
- renderTypes(property.types),
46
- );
42
+ export function getInvalidMissingMessage(key: string, types: ValidatorType[]): string {
43
+ let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace(TEMPLATE_PATTERN, renderTypes(types));
47
44
 
48
- message = message.replace(TEMPLATE_PATTERN, property.key.full);
45
+ message = message.replace(TEMPLATE_PATTERN, key);
49
46
 
50
47
  return message;
51
48
  }
52
49
 
53
- export function getInvalidTypeMessage(property: ValidatedProperty, actual: unknown): string {
54
- let message = VALIDATION_MESSAGE_INVALID_TYPE.replace(
55
- TEMPLATE_PATTERN,
56
- renderTypes(property.types),
57
- );
50
+ export function getInvalidTypeMessage(
51
+ key: string,
52
+ types: ValidatorType[],
53
+ actual: unknown,
54
+ ): string {
55
+ let message = VALIDATION_MESSAGE_INVALID_TYPE.replace(TEMPLATE_PATTERN, renderTypes(types));
58
56
 
59
- message = message.replace(TEMPLATE_PATTERN, property.key.full);
57
+ message = message.replace(TEMPLATE_PATTERN, key);
60
58
  message = message.replace(TEMPLATE_PATTERN, getValueType(actual));
61
59
 
62
60
  return message;
63
61
  }
64
62
 
65
63
  export function getInvalidValidatorMessage(
66
- property: ValidatedProperty,
64
+ key: string,
67
65
  type: ValueName,
68
66
  index: number,
69
67
  length: number,
70
68
  ): string {
71
- let message = VALIDATION_MESSAGE_INVALID_VALUE.replace(TEMPLATE_PATTERN, property.key.full);
69
+ let message = VALIDATION_MESSAGE_INVALID_VALUE.replace(TEMPLATE_PATTERN, key);
72
70
 
73
71
  message = message.replace(TEMPLATE_PATTERN, type);
74
72
 
@@ -79,9 +77,10 @@ export function getInvalidValidatorMessage(
79
77
  return message;
80
78
  }
81
79
 
82
- export function getOptions(input: unknown) {
80
+ export function getParameters(input?: unknown): ValidatorParameters {
83
81
  if (typeof input === 'boolean') {
84
82
  return {
83
+ output: {},
85
84
  reporting: getReporting(REPORTING_NONE),
86
85
  strict: input,
87
86
  };
@@ -89,6 +88,7 @@ export function getOptions(input: unknown) {
89
88
 
90
89
  if (REPORTING_TYPES.has(input as ReportingType)) {
91
90
  return {
91
+ output: {},
92
92
  reporting: getReporting(input as ReportingType),
93
93
  strict: false,
94
94
  };
@@ -97,17 +97,22 @@ export function getOptions(input: unknown) {
97
97
  const options = isPlainObject(input) ? input : {};
98
98
 
99
99
  return {
100
+ output: {},
100
101
  reporting: getReporting(options.errors),
101
102
  strict: typeof options.strict === 'boolean' ? options.strict : false,
102
103
  };
103
104
  }
104
105
 
105
- function getPropertyType(original: ValidatedPropertyType): string {
106
+ function getPropertyType(original: ValidatorType): string {
106
107
  if (typeof original === 'function') {
107
108
  return 'a validated value';
108
109
  }
109
110
 
110
111
  if (Array.isArray(original)) {
112
+ return `'array'`;
113
+ }
114
+
115
+ if (isPlainObject(original)) {
111
116
  return `'${TYPE_OBJECT}'`;
112
117
  }
113
118
 
@@ -196,7 +201,11 @@ export function isSchematic(value: unknown): value is Schematic<never> {
196
201
  }
197
202
 
198
203
  function renderKeys(keys: string[]): string {
199
- return renderParts(keys.map(key => `'${key}'`), CONJUNCTION_AND, CONJUNCTION_AND_COMMA);
204
+ return renderParts(
205
+ keys.map(key => `'${key}'`),
206
+ CONJUNCTION_AND,
207
+ CONJUNCTION_AND_COMMA,
208
+ );
200
209
  }
201
210
 
202
211
  function renderParts(parts: string[], delimiterShort: string, delimiterLong: string): string {
@@ -221,7 +230,7 @@ function renderParts(parts: string[], delimiterShort: string, delimiterLong: str
221
230
  return rendered;
222
231
  }
223
232
 
224
- function renderTypes(types: ValidatedPropertyType[]): string {
233
+ function renderTypes(types: ValidatorType[]): string {
225
234
  const unique = new Set<string>();
226
235
  const parts: string[] = [];
227
236
 
package/src/index.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  export {instanceOf, isSchematic} from './helpers';
2
2
  export type {Schema} from './models/schema.plain.model';
3
3
  export type {TypedSchema} from './models/schema.typed.model';
4
- export {SchematicError, ValidationError} from './models/validation.model';
4
+ export {
5
+ SchematicError,
6
+ ValidationError,
7
+ type ValidationInformation,
8
+ type ValidationOptions,
9
+ } from './models/validation.model';
5
10
  export {schematic, type Schematic} from './schematic';
@@ -25,7 +25,7 @@ export type PlainSchema = {
25
25
  * };
26
26
  * ```
27
27
  */
28
- export type Schema = SchemaIndex;
28
+ export type Schema = PlainSchema;
29
29
 
30
30
  /**
31
31
  * A union of all valid types for a single schema entry
@@ -40,13 +40,6 @@ export type SchemaEntry =
40
40
  | ValueName
41
41
  | ((value: unknown) => boolean);
42
42
 
43
- /**
44
- * Index signature interface backing {@link Schema}, allowing string-keyed entries of {@link PlainSchema}, {@link SchemaEntry}, or arrays of {@link SchemaEntry}
45
- */
46
- export interface SchemaIndex {
47
- [key: string]: PlainSchema | SchemaEntry | SchemaEntry[];
48
- }
49
-
50
43
  /**
51
44
  * A property definition with explicit type(s), an optional requirement flag, and optional validators
52
45
  *
@@ -1,14 +1,21 @@
1
- import type {GenericCallback} from '@oscarpalmer/atoms/models';
1
+ import type {GenericCallback, PlainObject} from '@oscarpalmer/atoms/models';
2
2
  import {join} from '@oscarpalmer/atoms/string';
3
3
  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,76 +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: ValidatedPropertyKey;
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
- * The full and short forms of a property's key path
79
- *
80
- * For a nested property `address.street`: `full` is `'address.street'`, `short` is `'street'`
81
- */
82
- export type ValidatedPropertyKey = {
83
- full: string;
84
- short: string;
85
- };
86
-
87
- /**
88
- * A union of valid types for a {@link ValidatedProperty}'s `types` array
89
- *
90
- * Can be a callback _(custom validator)_, a {@link Schematic}, a nested {@link ValidatedProperty}, or a {@link ValueName} string
91
- */
92
- export type ValidatedPropertyType =
93
- | GenericCallback
94
- | ValidatedProperty[]
95
- | Schematic<unknown>
96
- | ValueName;
97
-
98
- /**
99
- * A map of validator functions keyed by {@link ValueName}, used at runtime in {@link ValidatedProperty}
100
- *
101
- * Each key holds an array of validator functions that receive an `unknown` value and return a `boolean`
102
- */
103
- export type ValidatedPropertyValidators = {
104
- [Key in ValueName]?: Array<(value: unknown) => boolean>;
105
- };
106
-
107
- // #endregion
108
-
109
- // #region Property validation
110
-
111
48
  /**
112
49
  * Thrown in `'throw'` mode when one or more properties fail validation; `information` holds all failures
113
50
  */
@@ -124,6 +61,10 @@ export class ValidationError extends Error {
124
61
  }
125
62
  }
126
63
 
64
+ // #endregion
65
+
66
+ // #region Results
67
+
127
68
  /**
128
69
  * Describes a single validation failure
129
70
  */
@@ -139,9 +80,16 @@ export type ValidationInformation = {
139
80
  };
140
81
 
141
82
  /**
142
- * Same shape as {@link ValidatedPropertyKey}; the key path of a failed property
83
+ *
143
84
  */
144
- export type ValidationInformationKey = ValidatedPropertyKey;
85
+ export type ValidationInformationKey = {
86
+ full: string;
87
+ short: string;
88
+ };
89
+
90
+ // #endregion
91
+
92
+ // #region Options
145
93
 
146
94
  /**
147
95
  * Options for validation
@@ -157,9 +105,23 @@ export type ValidationOptions<Errors extends ReportingType> = {
157
105
  strict?: boolean;
158
106
  };
159
107
 
160
- export type ValidationOptionsExtended = {
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 = {
119
+ information?: ValidationInformation[];
120
+ output: PlainObject;
161
121
  reporting: ReportingInformation;
162
122
  strict: boolean;
163
123
  };
164
124
 
125
+ export type ValidatorType = Function | PlainObject | Schematic<unknown> | ValueName;
126
+
165
127
  // #endregion
package/src/schematic.ts CHANGED
@@ -1,20 +1,19 @@
1
1
  import {isPlainObject} from '@oscarpalmer/atoms/is';
2
2
  import type {PlainObject} from '@oscarpalmer/atoms/models';
3
- import {error} from '@oscarpalmer/atoms/result/misc';
3
+ import {error, ok} from '@oscarpalmer/atoms/result/misc';
4
4
  import type {Result} from '@oscarpalmer/atoms/result/models';
5
5
  import {PROPERTY_SCHEMATIC, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE} from './constants';
6
- import {getOptions, isSchematic} from './helpers';
6
+ import {getParameters, isSchematic} from './helpers';
7
7
  import type {Infer} from './models/infer.model';
8
8
  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,22 +21,108 @@ 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);
34
+ }
35
+
36
+ /**
37
+ * Parse a value according to the schema
38
+ *
39
+ * Returns a deeply cloned version of the value or throws an error for the first property that fails validation
40
+ * @param value Value to parse
41
+ * @param options Validation options
42
+ * @returns Deeply cloned version of the value if it matches the schema, otherwise throws an error
43
+ */
44
+ get(value: unknown, options: ValidationOptions<'throw'>): Model;
45
+
46
+ /**
47
+ * Parse a value according to the schema
48
+ *
49
+ * Returns a deeply cloned version of the value or throws an error for the first property that fails validation
50
+ * @param value Value to parse
51
+ * @param errors Reporting type
52
+ * @returns Deeply cloned version of the value if it matches the schema, otherwise throws an error
53
+ */
54
+ get(value: unknown, errors: 'throw'): Model;
55
+
56
+ /**
57
+ * Parse a value according to the schema
58
+ *
59
+ * Returns a result of a deeply cloned version of the value or all validation information for validation failures from the same depth in the value
60
+ * @param value Value to parse
61
+ * @param options Validation options
62
+ * @returns Result holding deeply cloned value or all validation information
63
+ */
64
+ get(value: unknown, options: ValidationOptions<'all'>): Result<Model, ValidationInformation[]>;
65
+
66
+ /**
67
+ * Parse a value according to the schema
68
+ *
69
+ * Returns a result of a deeply cloned version of the value or all validation information for validation failures from the same depth in the value
70
+ * @param value Value to parse
71
+ * @param errors Reporting type
72
+ * @returns Result holding deeply cloned value or all validation information
73
+ */
74
+ get(value: unknown, errors: 'all'): Result<Model, ValidationInformation[]>;
75
+
76
+ /**
77
+ * Parse a value according to the schema
78
+ *
79
+ * Returns a deeply cloned version of the value or all validation information for the first failing property
80
+ * @param value Value to parse
81
+ * @param options Validation options
82
+ * @returns Result holding deeply cloned value or all validation information
83
+ */
84
+ get(value: unknown, options: ValidationOptions<'first'>): Result<Model, ValidationInformation>;
85
+
86
+ /**
87
+ * Parse a value according to the schema
88
+ *
89
+ * Returns a deeply cloned version of the value or all validation information for the first failing property
90
+ * @param value Value to parse
91
+ * @param errors Reporting type
92
+ * @returns Result holding deeply cloned value or all validation information
93
+ */
94
+ get(value: unknown, errors: 'first'): Result<Model, ValidationInformation>;
95
+
96
+ /**
97
+ * Parse a value according to the schema
98
+ *
99
+ * Returns a deeply cloned version of the value or `undefined` if the value does not match the schema
100
+ * @param value Value to parse
101
+ * @param strict Validate if unknown keys are present in the object? _(defaults to `false`)_
102
+ * @returns Deeply cloned value, or `undefined` if it's invalid
103
+ */
104
+ get(value: unknown, strict?: true): Model | undefined;
105
+
106
+ get(value: unknown, options?: unknown): unknown {
107
+ const parameters = getParameters(options);
108
+
109
+ const result = this.#validator(value, parameters, true);
110
+
111
+ if (typeof result === 'boolean') {
112
+ return parameters.reporting.none
113
+ ? result
114
+ ? parameters.output
115
+ : undefined
116
+ : ok(parameters.output);
117
+ }
118
+
119
+ return error(parameters.reporting.all ? result : result[0]);
35
120
  }
36
121
 
37
122
  /**
38
123
  * Does the value match the schema?
39
124
  *
40
- * Will assert that the values matches the schema and throw an error if it does not. The error will contain all validation information for the first property that fails validation.
125
+ * Will assert that the values matches the schema and throw an error if it does not. The error will contain all validation information for the first property that fails validation
41
126
  * @param value Value to validate
42
127
  * @param options Validation options
43
128
  * @returns `true` if the value matches the schema, otherwise throws an error
@@ -47,7 +132,7 @@ export class Schematic<Model> {
47
132
  /**
48
133
  * Does the value match the schema?
49
134
  *
50
- * Will assert that the values matches the schema and throw an error if it does not. The error will contain all validation information for the first property that fails validation.
135
+ * Will assert that the values matches the schema and throw an error if it does not. The error will contain all validation information for the first property that fails validation
51
136
  * @param value Value to validate
52
137
  * @param errors Reporting type
53
138
  * @returns `true` if the value matches the schema, otherwise throws an error
@@ -57,27 +142,27 @@ export class Schematic<Model> {
57
142
  /**
58
143
  * Does the value match the schema?
59
144
  *
60
- * Will validate that the value matches the schema and return a result of `true` or all validation information for validation failures from the same depth in the object.
145
+ * Will validate that the value matches the schema and return a result of `true` or all validation information for validation failures from the same depth in the value
61
146
  * @param value Value to validate
62
147
  * @param options Validation options
63
- * @returns `true` if the value matches the schema, otherwise `false`
148
+ * @returns Result holding `true` or all validation information
64
149
  */
65
150
  is(value: unknown, options: ValidationOptions<'all'>): Result<true, ValidationInformation[]>;
66
151
 
67
152
  /**
68
153
  * Does the value match the schema?
69
154
  *
70
- * Will validate that the value matches the schema and return a result of `true` or all validation information for validation failures from the same depth in the object.
155
+ * Will validate that the value matches the schema and return a result of `true` or all validation information for validation failures from the same depth in the value
71
156
  * @param value Value to validate
72
157
  * @param errors Reporting type
73
- * @returns `true` if the value matches the schema, otherwise `false`
158
+ * @returns Result holding `true` or all validation information
74
159
  */
75
160
  is(value: unknown, errors: 'all'): Result<true, ValidationInformation[]>;
76
161
 
77
162
  /**
78
163
  * Does the value match the schema?
79
164
  *
80
- * Will validate that the value matches the schema and return a result of `true` or all validation information for the failing property.
165
+ * Will validate that the value matches the schema and return a result of `true` or all validation information for the first failing property
81
166
  * @param value Value to validate
82
167
  * @param options Validation options
83
168
  * @returns `true` if the value matches the schema, otherwise `false`
@@ -87,7 +172,7 @@ export class Schematic<Model> {
87
172
  /**
88
173
  * Does the value match the schema?
89
174
  *
90
- * Will validate that the value matches the schema and return a result of `true` or all validation information for the failing property.
175
+ * Will validate that the value matches the schema and return a result of `true` or all validation information for the first failing property
91
176
  * @param value Value to validate
92
177
  * @param errors Reporting type
93
178
  * @returns `true` if the value matches the schema, otherwise `false`
@@ -97,7 +182,7 @@ export class Schematic<Model> {
97
182
  /**
98
183
  * Does the value match the schema?
99
184
  *
100
- * Will validate that the value matches the schema and return `true` or `false`, without any validation information for validation failures.
185
+ * Will validate that the value matches the schema and return `true` or `false`, without any validation information for validation failures
101
186
  * @param value Value to validate
102
187
  * @param strict Validate if unknown keys are present in the object? _(defaults to `false`)_
103
188
  * @returns `true` if the value matches the schema, otherwise `false`
@@ -105,15 +190,15 @@ export class Schematic<Model> {
105
190
  is(value: unknown, strict?: true): value is Model;
106
191
 
107
192
  is(value: unknown, options?: unknown): unknown {
108
- const {reporting, strict} = getOptions(options);
193
+ const parameters = getParameters(options);
109
194
 
110
- const result = validateObject(value, this.#properties, {reporting, strict});
195
+ const result = this.#validator(value, parameters, false);
111
196
 
112
197
  if (typeof result === 'boolean') {
113
- return result;
198
+ return parameters.reporting.none ? result : ok(result);
114
199
  }
115
200
 
116
- return error(reporting.all ? result : result[0]);
201
+ return error(parameters.reporting.all ? result : result[0]);
117
202
  }
118
203
  }
119
204
 
@@ -144,7 +229,7 @@ export function schematic<Model extends Schema>(schema: Model): Schematic<Model>
144
229
  throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE);
145
230
  }
146
231
 
147
- return new Schematic<Model>(getProperties(schema));
232
+ return new Schematic<Model>(getObjectValidator(schema));
148
233
  }
149
234
 
150
- export const schematicProperties = new WeakMap<Schematic<unknown>, ValidatedProperty[]>();
235
+ export const schematicValidator = new WeakMap<Schematic<unknown>, Validator>();