@oscarpalmer/jhunal 0.22.0 → 0.23.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 (40) hide show
  1. package/dist/constants.d.mts +7 -3
  2. package/dist/constants.mjs +34 -12
  3. package/dist/helpers/message.helper.d.mts +11 -0
  4. package/dist/helpers/message.helper.mjs +70 -0
  5. package/dist/helpers/misc.helper.d.mts +22 -0
  6. package/dist/helpers/misc.helper.mjs +56 -0
  7. package/dist/index.d.mts +304 -275
  8. package/dist/index.mjs +187 -154
  9. package/dist/models/validation.model.d.mts +18 -7
  10. package/dist/schematic.d.mts +25 -7
  11. package/dist/schematic.mjs +6 -4
  12. package/dist/validator/base.validator.d.mts +6 -0
  13. package/dist/validator/base.validator.mjs +19 -0
  14. package/dist/validator/function.validator.d.mts +6 -0
  15. package/dist/validator/function.validator.mjs +9 -0
  16. package/dist/validator/named.handler.d.mts +6 -0
  17. package/dist/validator/named.handler.mjs +22 -0
  18. package/dist/validator/named.validator.d.mts +7 -0
  19. package/dist/validator/named.validator.mjs +39 -0
  20. package/dist/validator/object.validator.d.mts +7 -0
  21. package/dist/{validation.mjs → validator/object.validator.mjs} +20 -98
  22. package/dist/validator/schematic.validator.d.mts +7 -0
  23. package/dist/validator/schematic.validator.mjs +16 -0
  24. package/package.json +1 -1
  25. package/src/constants.ts +42 -10
  26. package/src/helpers/message.helper.ts +152 -0
  27. package/src/helpers/misc.helper.ts +93 -0
  28. package/src/index.ts +3 -3
  29. package/src/models/validation.model.ts +19 -6
  30. package/src/schematic.ts +43 -16
  31. package/src/validator/base.validator.ts +31 -0
  32. package/src/validator/function.validator.ts +9 -0
  33. package/src/validator/named.handler.ts +50 -0
  34. package/src/validator/named.validator.ts +62 -0
  35. package/src/{validation.ts → validator/object.validator.ts} +23 -181
  36. package/src/validator/schematic.validator.ts +25 -0
  37. package/dist/helpers.d.mts +0 -28
  38. package/dist/helpers.mjs +0 -120
  39. package/dist/validation.d.mts +0 -7
  40. package/src/helpers.ts +0 -249
package/dist/index.mjs CHANGED
@@ -1,7 +1,6 @@
1
1
  import { isConstructor, isPlainObject } from "@oscarpalmer/atoms/is";
2
2
  import { join } from "@oscarpalmer/atoms/string";
3
3
  import { error, ok } from "@oscarpalmer/atoms/result/misc";
4
- import { join as join$1 } from "@oscarpalmer/atoms";
5
4
  import { clone } from "@oscarpalmer/atoms/value/clone";
6
5
  //#region src/constants.ts
7
6
  const CONJUNCTION_OR = " or ";
@@ -9,14 +8,13 @@ const CONJUNCTION_OR_COMMA = ", or ";
9
8
  const CONJUNCTION_AND = " and ";
10
9
  const CONJUNCTION_AND_COMMA = ", and ";
11
10
  const MESSAGE_CONSTRUCTOR = "Expected a constructor function";
12
- const NAME_SCHEMATIC = "Schematic";
13
11
  const NAME_ERROR_SCHEMATIC = "SchematicError";
14
12
  const NAME_ERROR_VALIDATION = "ValidationError";
15
13
  const PROPERTY_REQUIRED = "$required";
16
14
  const PROPERTY_SCHEMATIC = "$schematic";
17
15
  const PROPERTY_TYPE = "$type";
18
16
  const PROPERTY_VALIDATORS = "$validators";
19
- const VALIDATION_MESSAGE_INVALID_INPUT = "Expected 'object' as input but received <>";
17
+ const VALIDATION_MESSAGE_INVALID_INPUT = "Expected an object as input but received <>";
20
18
  const VALIDATION_MESSAGE_INVALID_REQUIRED = "Expected <> for required property '<>'";
21
19
  const VALIDATION_MESSAGE_INVALID_TYPE = "Expected <> for '<>' but received <>";
22
20
  const VALIDATION_MESSAGE_INVALID_VALUE = "Value does not satisfy validator for '<>' and type '<>'";
@@ -41,71 +39,68 @@ const SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY = "Validator '<>' does not exist";
41
39
  const SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE = "Validators must be an object";
42
40
  const SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE = "Validator '<>' must be a function or an array of functions";
43
41
  const TYPE_ARRAY = "array";
42
+ const TYPE_BIGINT = "bigint";
43
+ const TYPE_BOOLEAN = "boolean";
44
+ const TYPE_DATE = "date";
45
+ const TYPE_FUNCTION = "function";
46
+ const TYPE_FUNCTION_RESULT = "a validated value";
44
47
  const TYPE_NULL = "null";
48
+ const TYPE_NUMBER = "number";
45
49
  const TYPE_OBJECT = "object";
50
+ const TYPE_STRING = "string";
51
+ const TYPE_SYMBOL = "symbol";
46
52
  const TYPE_UNDEFINED = "undefined";
47
53
  const TYPE_ALL = new Set([
48
54
  ...new Set([
49
- "array",
50
- "bigint",
51
- "boolean",
52
- "date",
53
- "function",
54
- "number",
55
- "string",
56
- "symbol",
57
- TYPE_OBJECT
55
+ TYPE_ARRAY,
56
+ TYPE_BIGINT,
57
+ TYPE_BOOLEAN,
58
+ TYPE_DATE,
59
+ TYPE_FUNCTION,
60
+ TYPE_NUMBER,
61
+ TYPE_OBJECT,
62
+ TYPE_STRING,
63
+ TYPE_SYMBOL
58
64
  ]),
59
- "null",
65
+ TYPE_NULL,
60
66
  TYPE_UNDEFINED
61
67
  ]);
68
+ const PREFIXED_TYPES = {
69
+ [TYPE_ARRAY]: `an ${TYPE_ARRAY}`,
70
+ [TYPE_BIGINT]: `a ${TYPE_BIGINT}`,
71
+ [TYPE_BOOLEAN]: `a ${TYPE_BOOLEAN}`,
72
+ [TYPE_DATE]: `a ${TYPE_DATE}`,
73
+ [TYPE_FUNCTION]: `a ${TYPE_FUNCTION}`,
74
+ [TYPE_NULL]: TYPE_NULL,
75
+ [TYPE_NUMBER]: `a ${TYPE_NUMBER}`,
76
+ [TYPE_STRING]: `a ${TYPE_STRING}`,
77
+ [TYPE_SYMBOL]: `a ${TYPE_SYMBOL}`,
78
+ [TYPE_OBJECT]: `an ${TYPE_OBJECT}`,
79
+ [TYPE_UNDEFINED]: TYPE_UNDEFINED
80
+ };
62
81
  //#endregion
63
- //#region src/helpers.ts
64
- function getInvalidInputMessage(actual) {
65
- return VALIDATION_MESSAGE_INVALID_INPUT.replace("<>", getValueType(actual));
66
- }
67
- function getInvalidMissingMessage(key, types) {
68
- let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace("<>", renderTypes(types));
69
- message = message.replace("<>", key);
70
- return message;
71
- }
72
- function getInvalidTypeMessage(key, types, actual) {
73
- let message = VALIDATION_MESSAGE_INVALID_TYPE.replace("<>", renderTypes(types));
74
- message = message.replace("<>", key);
75
- message = message.replace("<>", getValueType(actual));
76
- return message;
77
- }
78
- function getInvalidValidatorMessage(key, type, index, length) {
79
- let message = VALIDATION_MESSAGE_INVALID_VALUE.replace("<>", key);
80
- message = message.replace("<>", type);
81
- if (length > 1) message += VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX.replace("<>", String(index));
82
- return message;
83
- }
82
+ //#region src/helpers/misc.helper.ts
84
83
  function getParameters(input) {
85
84
  if (typeof input === "boolean") return {
85
+ clone: true,
86
86
  output: {},
87
87
  reporting: getReporting(REPORTING_NONE),
88
88
  strict: input
89
89
  };
90
90
  if (REPORTING_TYPES.has(input)) return {
91
+ clone: true,
91
92
  output: {},
92
93
  reporting: getReporting(input),
93
94
  strict: false
94
95
  };
95
96
  const options = isPlainObject(input) ? input : {};
96
97
  return {
98
+ clone: typeof options.clone === "boolean" ? options.clone : true,
97
99
  output: {},
98
100
  reporting: getReporting(options.errors),
99
101
  strict: typeof options.strict === "boolean" ? options.strict : false
100
102
  };
101
103
  }
102
- function getPropertyType(original) {
103
- if (typeof original === "function") return "a validated value";
104
- if (Array.isArray(original)) return `'array'`;
105
- if (isPlainObject(original)) return `'${TYPE_OBJECT}'`;
106
- if (isSchematic(original)) return `a ${NAME_SCHEMATIC}`;
107
- return `'${String(original)}'`;
108
- }
109
104
  function getReporting(value) {
110
105
  const type = REPORTING_TYPES.has(value) ? value : REPORTING_NONE;
111
106
  return {
@@ -116,21 +111,6 @@ function getReporting(value) {
116
111
  [REPORTING_THROW]: type === REPORTING_THROW
117
112
  };
118
113
  }
119
- function getUnknownKeysMessage(keys) {
120
- return VALIDATION_MESSAGE_UNKNOWN_KEYS.replace("<>", renderKeys(keys));
121
- }
122
- function getValueType(value) {
123
- const valueType = typeof value;
124
- switch (true) {
125
- case value === null: return `'${TYPE_NULL}'`;
126
- case value === void 0: return `'${TYPE_UNDEFINED}'`;
127
- case valueType !== TYPE_OBJECT: return `'${valueType}'`;
128
- case Array.isArray(value): return `'${TYPE_ARRAY}'`;
129
- case isPlainObject(value): return `'${TYPE_OBJECT}'`;
130
- case isSchematic(value): return `a ${NAME_SCHEMATIC}`;
131
- default: return value.constructor.name;
132
- }
133
- }
134
114
  /**
135
115
  * Creates a validator function for a given constructor
136
116
  * @param constructor - Constructor to check against
@@ -151,6 +131,69 @@ function instanceOf(constructor) {
151
131
  function isSchematic(value) {
152
132
  return typeof value === "object" && value !== null && "$schematic" in value && value["$schematic"] === true;
153
133
  }
134
+ //#endregion
135
+ //#region src/models/validation.model.ts
136
+ /**
137
+ * Thrown when a schema definition is invalid
138
+ */
139
+ var SchematicError = class extends Error {
140
+ constructor(message) {
141
+ super(message);
142
+ this.name = NAME_ERROR_SCHEMATIC;
143
+ }
144
+ };
145
+ /**
146
+ * Thrown in `'throw'` mode when one or more properties fail validation; `information` holds all failures
147
+ */
148
+ var ValidationError = class extends Error {
149
+ constructor(information) {
150
+ super(join(information.map((item) => item.message), "; "));
151
+ this.information = information;
152
+ this.name = NAME_ERROR_VALIDATION;
153
+ }
154
+ };
155
+ //#endregion
156
+ //#region src/helpers/message.helper.ts
157
+ function getInvalidInputMessage(actual) {
158
+ return VALIDATION_MESSAGE_INVALID_INPUT.replace("<>", getValueType(actual));
159
+ }
160
+ function getInvalidMissingMessage(key, types) {
161
+ let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace("<>", renderTypes(types));
162
+ message = message.replace("<>", key);
163
+ return message;
164
+ }
165
+ function getInvalidTypeMessage(key, types, actual) {
166
+ let message = VALIDATION_MESSAGE_INVALID_TYPE.replace("<>", renderTypes(types));
167
+ message = message.replace("<>", key);
168
+ message = message.replace("<>", getValueType(actual));
169
+ return message;
170
+ }
171
+ function getInvalidValidatorMessage(key, type, index, length) {
172
+ let message = VALIDATION_MESSAGE_INVALID_VALUE.replace("<>", key);
173
+ message = message.replace("<>", type);
174
+ if (length > 1) message += VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX.replace("<>", String(index));
175
+ return message;
176
+ }
177
+ function getPropertyType(type) {
178
+ switch (true) {
179
+ case typeof type === "function": return isConstructor(type) ? type.name : TYPE_FUNCTION_RESULT;
180
+ case TYPE_ALL.has(type): return PREFIXED_TYPES[type];
181
+ default: return PREFIXED_TYPES[TYPE_OBJECT];
182
+ }
183
+ }
184
+ function getUnknownKeysMessage(keys) {
185
+ return VALIDATION_MESSAGE_UNKNOWN_KEYS.replace("<>", renderKeys(keys));
186
+ }
187
+ function getValueType(value) {
188
+ const valueType = typeof value;
189
+ switch (true) {
190
+ case value === null: return TYPE_NULL;
191
+ case Array.isArray(value): return PREFIXED_TYPES[TYPE_ARRAY];
192
+ case isPlainObject(value): return PREFIXED_TYPES[TYPE_OBJECT];
193
+ case valueType !== TYPE_OBJECT: return PREFIXED_TYPES[valueType];
194
+ default: return value.constructor.name;
195
+ }
196
+ }
154
197
  function renderKeys(keys) {
155
198
  return renderParts(keys.map((key) => `'${key}'`), CONJUNCTION_AND, CONJUNCTION_AND_COMMA);
156
199
  }
@@ -177,43 +220,56 @@ function renderTypes(types) {
177
220
  return renderParts(parts, CONJUNCTION_OR, CONJUNCTION_OR_COMMA);
178
221
  }
179
222
  //#endregion
180
- //#region src/models/validation.model.ts
181
- /**
182
- * Thrown when a schema definition is invalid
183
- */
184
- var SchematicError = class extends Error {
185
- constructor(message) {
186
- super(message);
187
- this.name = NAME_ERROR_SCHEMATIC;
188
- }
189
- };
190
- /**
191
- * Thrown in `'throw'` mode when one or more properties fail validation; `information` holds all failures
192
- */
193
- var ValidationError = class extends Error {
194
- constructor(information) {
195
- super(join(information.map((item) => item.message), "; "));
196
- this.information = information;
197
- this.name = NAME_ERROR_VALIDATION;
198
- }
199
- };
200
- //#endregion
201
- //#region src/validation.ts
202
- function getDisallowedProperty(obj) {
203
- if ("$required" in obj) return PROPERTY_REQUIRED;
204
- if ("$type" in obj) return PROPERTY_TYPE;
205
- if ("$validators" in obj) return PROPERTY_VALIDATORS;
223
+ //#region src/validator/base.validator.ts
224
+ function getBaseValidator(validators) {
225
+ const { length } = validators;
226
+ return (input, parameters, get) => {
227
+ const allInformation = [];
228
+ for (let index = 0; index < length; index += 1) {
229
+ const previousInformation = parameters.information;
230
+ parameters.information = [];
231
+ const result = validators[index](input, parameters, get);
232
+ parameters.information = previousInformation;
233
+ if (result === true) return true;
234
+ parameters.information?.push(...result);
235
+ allInformation.push(...result);
236
+ }
237
+ return allInformation;
238
+ };
206
239
  }
240
+ //#endregion
241
+ //#region src/validator/function.validator.ts
207
242
  function getFunctionValidator(fn) {
208
243
  const validator = isConstructor(fn) ? instanceOf(fn) : fn;
209
- return (input) => validator(input) === true;
244
+ return (input) => validator(input) ? true : [];
210
245
  }
246
+ //#endregion
247
+ //#region src/validator/named.handler.ts
248
+ function getNamedHandlers(original, prefix) {
249
+ const handlers = {};
250
+ if (original == null) return handlers;
251
+ if (!isPlainObject(original)) throw new TypeError(SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE);
252
+ const keys = Object.keys(original);
253
+ const { length } = keys;
254
+ for (let index = 0; index < length; index += 1) {
255
+ const key = keys[index];
256
+ if (!TYPE_ALL.has(key)) throw new TypeError(SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY.replace("<>", key));
257
+ const value = original[key];
258
+ handlers[key] = (Array.isArray(value) ? value : [value]).map((item) => {
259
+ if (typeof item !== "function") throw new TypeError(SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE.replace("<>", key).replace("<>", prefix));
260
+ return item;
261
+ });
262
+ }
263
+ return handlers;
264
+ }
265
+ //#endregion
266
+ //#region src/validator/named.validator.ts
211
267
  function getNamedValidator(key, name, handlers) {
212
268
  const validator = namedValidators[name];
213
269
  const named = handlers[name] ?? [];
214
270
  const { length } = named;
215
271
  return (input, parameters) => {
216
- if (!validator(input)) return false;
272
+ if (!validator(input)) return [];
217
273
  for (let index = 0; index < length; index += 1) {
218
274
  const handler = named[index];
219
275
  if (handler(input) === true) continue;
@@ -224,27 +280,43 @@ function getNamedValidator(key, name, handlers) {
224
280
  value: input
225
281
  };
226
282
  parameters.information?.push(information);
227
- return parameters.reporting.none ? false : [information];
283
+ return parameters.reporting.none ? [] : [information];
228
284
  }
229
285
  return true;
230
286
  };
231
287
  }
232
- function getNamedHandlers(original, prefix) {
233
- const handlers = {};
234
- if (original == null) return handlers;
235
- if (!isPlainObject(original)) throw new TypeError(SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE);
236
- const keys = Object.keys(original);
237
- const { length } = keys;
238
- for (let index = 0; index < length; index += 1) {
239
- const key = keys[index];
240
- if (!TYPE_ALL.has(key)) throw new TypeError(SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY.replace("<>", key));
241
- const value = original[key];
242
- handlers[key] = (Array.isArray(value) ? value : [value]).map((item) => {
243
- if (typeof item !== "function") throw new TypeError(SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE.replace("<>", key).replace("<>", prefix));
244
- return item;
245
- });
246
- }
247
- return handlers;
288
+ const namedValidators = {
289
+ array: Array.isArray,
290
+ bigint: (value) => typeof value === "bigint",
291
+ boolean: (value) => typeof value === "boolean",
292
+ date: (value) => value instanceof Date,
293
+ function: (value) => typeof value === "function",
294
+ null: (value) => value === null,
295
+ number: (value) => typeof value === "number",
296
+ object: (value) => typeof value === "object" && value !== null,
297
+ string: (value) => typeof value === "string",
298
+ symbol: (value) => typeof value === "symbol",
299
+ undefined: (value) => value === void 0
300
+ };
301
+ //#endregion
302
+ //#region src/validator/schematic.validator.ts
303
+ function getSchematicValidator(schematic) {
304
+ const validator = schematicValidator.get(schematic);
305
+ return (input, parameters, get) => {
306
+ let result;
307
+ if (isPlainObject(input)) result = validator(input, parameters, get);
308
+ else result = [];
309
+ if (result === true) return result;
310
+ parameters.information?.push(...result);
311
+ return result;
312
+ };
313
+ }
314
+ //#endregion
315
+ //#region src/validator/object.validator.ts
316
+ function getDisallowedProperty(obj) {
317
+ if ("$required" in obj) return PROPERTY_REQUIRED;
318
+ if ("$type" in obj) return PROPERTY_TYPE;
319
+ if ("$validators" in obj) return PROPERTY_VALIDATORS;
248
320
  }
249
321
  function getObjectValidator(original, origin, fromType) {
250
322
  const keys = Object.keys(original);
@@ -259,8 +331,8 @@ function getObjectValidator(original, origin, fromType) {
259
331
  for (let keyIndex = 0; keyIndex < keysLength; keyIndex += 1) {
260
332
  const key = keys[keyIndex];
261
333
  const value = original[key];
262
- if (value == null) throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE.replace("<>", join$1([origin?.full, key], ".")));
263
- const prefixedKey = origin == null ? key : join$1([origin.full, key], ".");
334
+ if (value == null) throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE.replace("<>", join([origin?.full, key], ".")));
335
+ const prefixedKey = origin == null ? key : join([origin.full, key], ".");
264
336
  const fullKey = {
265
337
  full: prefixedKey,
266
338
  short: key
@@ -304,13 +376,13 @@ function getObjectValidator(original, origin, fromType) {
304
376
  types,
305
377
  key: fullKey,
306
378
  required: required && !types.includes("undefined"),
307
- validator: getValidator(validators)
379
+ validator: getBaseValidator(validators)
308
380
  });
309
381
  }
310
382
  const validatorsLength = items.length;
311
383
  return (input, parameters, get) => {
312
384
  if (!isPlainObject(input)) {
313
- if (origin != null) return false;
385
+ if (origin != null) return [];
314
386
  const information = {
315
387
  key: {
316
388
  full: "",
@@ -321,7 +393,7 @@ function getObjectValidator(original, origin, fromType) {
321
393
  };
322
394
  if (parameters.reporting.throw) throw new ValidationError([information]);
323
395
  parameters.information?.push(information);
324
- return parameters.reporting.none ? false : [information];
396
+ return [information];
325
397
  }
326
398
  if (parameters.strict) {
327
399
  const unknownKeys = Object.keys(input).filter((key) => !set.has(key));
@@ -336,7 +408,7 @@ function getObjectValidator(original, origin, fromType) {
336
408
  };
337
409
  if (parameters.reporting.throw) throw new ValidationError([information]);
338
410
  parameters.information?.push(information);
339
- return parameters.reporting.none ? false : [information];
411
+ return [information];
340
412
  }
341
413
  }
342
414
  const allInformation = [];
@@ -346,7 +418,7 @@ function getObjectValidator(original, origin, fromType) {
346
418
  const value = input[key.short];
347
419
  if (value === void 0) {
348
420
  if (required) {
349
- if (parameters.reporting.none) return false;
421
+ if (parameters.reporting.none) return [];
350
422
  const information = {
351
423
  key,
352
424
  value,
@@ -366,12 +438,11 @@ function getObjectValidator(original, origin, fromType) {
366
438
  parameters.output = output;
367
439
  const result = validator(value, parameters, get);
368
440
  parameters.output = previousOutput;
369
- if (result === false) continue;
370
441
  if (result === true) {
371
- if (get) output[key.short] = clone(value);
442
+ if (get && !isPlainObject(value)) output[key.short] = parameters.clone ? clone(value) : value;
372
443
  continue;
373
444
  }
374
- if (parameters.reporting.none) return false;
445
+ if (parameters.reporting.none) return [];
375
446
  const information = typeof result !== "boolean" && result.length > 0 ? result : [{
376
447
  key,
377
448
  value,
@@ -386,7 +457,7 @@ function getObjectValidator(original, origin, fromType) {
386
457
  }
387
458
  if (get) if (origin == null) parameters.output = output;
388
459
  else parameters.output[origin.short] = output;
389
- return parameters.reporting.none || allInformation.length === 0 ? true : allInformation;
460
+ return allInformation.length === 0 ? true : allInformation;
390
461
  };
391
462
  }
392
463
  function getRequired(key, obj) {
@@ -394,46 +465,6 @@ function getRequired(key, obj) {
394
465
  if (typeof obj["$required"] !== "boolean") throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED.replace("<>", key));
395
466
  return obj[PROPERTY_REQUIRED];
396
467
  }
397
- function getSchematicValidator(schematic) {
398
- const validator = schematicValidator.get(schematic);
399
- return (input, parameters, get) => {
400
- let result = false;
401
- if (isPlainObject(input)) result = validator(input, parameters, get);
402
- if (typeof result === "boolean") return result;
403
- parameters.information?.push(...result);
404
- return result.length === 0 ? true : result;
405
- };
406
- }
407
- function getValidator(validators) {
408
- const { length } = validators;
409
- return (input, parameters, get) => {
410
- const allInformation = [];
411
- for (let index = 0; index < length; index += 1) {
412
- const previousInformation = parameters.information;
413
- parameters.information = [];
414
- const result = validators[index](input, parameters, get);
415
- parameters.information = previousInformation;
416
- if (result === false) continue;
417
- if (result === true) return true;
418
- parameters.information?.push(...result);
419
- allInformation.push(...result);
420
- }
421
- return allInformation;
422
- };
423
- }
424
- const namedValidators = {
425
- array: Array.isArray,
426
- bigint: (value) => typeof value === "bigint",
427
- boolean: (value) => typeof value === "boolean",
428
- date: (value) => value instanceof Date,
429
- function: (value) => typeof value === "function",
430
- null: (value) => value === null,
431
- number: (value) => typeof value === "number",
432
- object: (value) => typeof value === "object" && value !== null,
433
- string: (value) => typeof value === "string",
434
- symbol: (value) => typeof value === "symbol",
435
- undefined: (value) => value === void 0
436
- };
437
468
  //#endregion
438
469
  //#region src/schematic.ts
439
470
  /**
@@ -449,13 +480,15 @@ var Schematic = class {
449
480
  get(value, options) {
450
481
  const parameters = getParameters(options);
451
482
  const result = this.#validator(value, parameters, true);
452
- if (typeof result === "boolean") return parameters.reporting.none ? result ? parameters.output : void 0 : ok(parameters.output);
483
+ if (result === true) return parameters.reporting.none || parameters.reporting.throw ? parameters.output : ok(parameters.output);
484
+ if (parameters.reporting.none) return;
453
485
  return error(parameters.reporting.all ? result : result[0]);
454
486
  }
455
487
  is(value, options) {
456
488
  const parameters = getParameters(options);
457
489
  const result = this.#validator(value, parameters, false);
458
- if (typeof result === "boolean") return parameters.reporting.none ? result : ok(result);
490
+ if (result === true) return parameters.reporting.none || parameters.reporting.throw ? result : ok(result);
491
+ if (parameters.reporting.none) return false;
459
492
  return error(parameters.reporting.all ? result : result[0]);
460
493
  }
461
494
  };
@@ -46,21 +46,32 @@ type ValidationInformationKey = {
46
46
  full: string;
47
47
  short: string;
48
48
  };
49
- /**
50
- * Options for validation
51
- */
52
- type ValidationOptions<Errors extends ReportingType> = {
49
+ type BaseOptions<Errors extends ReportingType> = {
53
50
  /**
54
51
  * How should validation failures be reported; see {@link ReportingType} _(defaults to `'none'`)_
55
52
  */
56
- errors?: Errors;
53
+ errors: Errors;
57
54
  /**
58
55
  * Validate if unknown keys are present in the object? _(defaults to `false`)_
59
56
  */
60
57
  strict?: boolean;
61
58
  };
62
- type Validator = (input: unknown, parameters: ValidatorParameters, get: boolean) => boolean | ValidationInformation[];
59
+ /**
60
+ * Options for validating and getting a value from an input
61
+ */
62
+ type GetOptions<Errors extends ReportingType> = BaseOptions<Errors> & {
63
+ /**
64
+ * Get a deeply cloned version of the input? _(defaults to `true`)_
65
+ */
66
+ clone?: boolean;
67
+ };
68
+ /**
69
+ * Options for validation an input value
70
+ */
71
+ type IsOptions<Errors extends ReportingType> = BaseOptions<Errors>;
72
+ type Validator = (input: unknown, parameters: ValidatorParameters, get: boolean) => true | ValidationInformation[];
63
73
  type ValidatorParameters = {
74
+ clone: boolean;
64
75
  information?: ValidationInformation[];
65
76
  output: PlainObject;
66
77
  reporting: ReportingInformation;
@@ -68,4 +79,4 @@ type ValidatorParameters = {
68
79
  };
69
80
  type ValidatorType = Function | PlainObject | Schematic<unknown> | ValueName;
70
81
  //#endregion
71
- export { NamedValidatorHandlers, NamedValidators, ReportingInformation, ReportingType, SchematicError, ValidationError, ValidationInformation, ValidationInformationKey, ValidationOptions, Validator, ValidatorParameters, ValidatorType };
82
+ export { GetOptions, IsOptions, NamedValidatorHandlers, NamedValidators, ReportingInformation, ReportingType, SchematicError, ValidationError, ValidationInformation, ValidationInformationKey, Validator, ValidatorParameters, ValidatorType };
@@ -1,6 +1,6 @@
1
1
  import { Infer } from "./models/infer.model.mjs";
2
2
  import { TypedSchema } from "./models/schema.typed.model.mjs";
3
- import { ValidationInformation, ValidationOptions, Validator } from "./models/validation.model.mjs";
3
+ import { GetOptions, IsOptions, ValidationInformation, Validator } from "./models/validation.model.mjs";
4
4
  import { Schema } from "./models/schema.plain.model.mjs";
5
5
  import { PlainObject } from "@oscarpalmer/atoms/models";
6
6
  import { Result } from "@oscarpalmer/atoms/result/models";
@@ -21,7 +21,7 @@ declare class Schematic<Model> {
21
21
  * @param options Validation options
22
22
  * @returns Deeply cloned version of the value if it matches the schema, otherwise throws an error
23
23
  */
24
- get(value: unknown, options: ValidationOptions<'throw'>): Model;
24
+ get(value: unknown, options: GetOptions<'throw'>): Model;
25
25
  /**
26
26
  * Parse a value according to the schema
27
27
  *
@@ -39,7 +39,7 @@ declare class Schematic<Model> {
39
39
  * @param options Validation options
40
40
  * @returns Result holding deeply cloned value or all validation information
41
41
  */
42
- get(value: unknown, options: ValidationOptions<'all'>): Result<Model, ValidationInformation[]>;
42
+ get(value: unknown, options: GetOptions<'all'>): Result<Model, ValidationInformation[]>;
43
43
  /**
44
44
  * Parse a value according to the schema
45
45
  *
@@ -57,7 +57,7 @@ declare class Schematic<Model> {
57
57
  * @param options Validation options
58
58
  * @returns Result holding deeply cloned value or all validation information
59
59
  */
60
- get(value: unknown, options: ValidationOptions<'first'>): Result<Model, ValidationInformation>;
60
+ get(value: unknown, options: GetOptions<'first'>): Result<Model, ValidationInformation>;
61
61
  /**
62
62
  * Parse a value according to the schema
63
63
  *
@@ -67,6 +67,15 @@ declare class Schematic<Model> {
67
67
  * @returns Result holding deeply cloned value or all validation information
68
68
  */
69
69
  get(value: unknown, errors: 'first'): Result<Model, ValidationInformation>;
70
+ /**
71
+ * Parse a value according to the schema
72
+ *
73
+ * Returns a deeply cloned version of the value or `undefined` if the value does not match the schema
74
+ * @param value Value to parse
75
+ * @param options Validation options
76
+ * @returns Deeply cloned value, or `undefined` if it's invalid
77
+ */
78
+ get(value: unknown, options: GetOptions<'none'>): Model | undefined;
70
79
  /**
71
80
  * Parse a value according to the schema
72
81
  *
@@ -84,7 +93,7 @@ declare class Schematic<Model> {
84
93
  * @param options Validation options
85
94
  * @returns `true` if the value matches the schema, otherwise throws an error
86
95
  */
87
- is(value: unknown, options: ValidationOptions<'throw'>): asserts value is Model;
96
+ is(value: unknown, options: IsOptions<'throw'>): asserts value is Model;
88
97
  /**
89
98
  * Does the value match the schema?
90
99
  *
@@ -102,7 +111,7 @@ declare class Schematic<Model> {
102
111
  * @param options Validation options
103
112
  * @returns Result holding `true` or all validation information
104
113
  */
105
- is(value: unknown, options: ValidationOptions<'all'>): Result<true, ValidationInformation[]>;
114
+ is(value: unknown, options: IsOptions<'all'>): Result<true, ValidationInformation[]>;
106
115
  /**
107
116
  * Does the value match the schema?
108
117
  *
@@ -120,7 +129,7 @@ declare class Schematic<Model> {
120
129
  * @param options Validation options
121
130
  * @returns `true` if the value matches the schema, otherwise `false`
122
131
  */
123
- is(value: unknown, options: ValidationOptions<'first'>): Result<true, ValidationInformation>;
132
+ is(value: unknown, options: IsOptions<'first'>): Result<true, ValidationInformation>;
124
133
  /**
125
134
  * Does the value match the schema?
126
135
  *
@@ -130,6 +139,15 @@ declare class Schematic<Model> {
130
139
  * @returns `true` if the value matches the schema, otherwise `false`
131
140
  */
132
141
  is(value: unknown, errors: 'first'): Result<true, ValidationInformation>;
142
+ /**
143
+ * Does the value match the schema?
144
+ *
145
+ * Will validate that the value matches the schema and return `true` or `false`, without any validation information for validation failures
146
+ * @param value Value to validate
147
+ * @param options Validation options
148
+ * @returns `true` if the value matches the schema, otherwise `false`
149
+ */
150
+ is(value: unknown, options: IsOptions<'none'>): value is Model;
133
151
  /**
134
152
  * Does the value match the schema?
135
153
  *
@@ -1,7 +1,7 @@
1
1
  import { PROPERTY_SCHEMATIC, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE } from "./constants.mjs";
2
- import { getParameters, isSchematic } from "./helpers.mjs";
2
+ import { getParameters, isSchematic } from "./helpers/misc.helper.mjs";
3
3
  import { SchematicError } from "./models/validation.model.mjs";
4
- import { getObjectValidator } from "./validation.mjs";
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
7
  //#region src/schematic.ts
@@ -18,13 +18,15 @@ var Schematic = class {
18
18
  get(value, options) {
19
19
  const parameters = getParameters(options);
20
20
  const result = this.#validator(value, parameters, true);
21
- if (typeof result === "boolean") return parameters.reporting.none ? result ? parameters.output : void 0 : ok(parameters.output);
21
+ if (result === true) return parameters.reporting.none || parameters.reporting.throw ? parameters.output : ok(parameters.output);
22
+ if (parameters.reporting.none) return;
22
23
  return error(parameters.reporting.all ? result : result[0]);
23
24
  }
24
25
  is(value, options) {
25
26
  const parameters = getParameters(options);
26
27
  const result = this.#validator(value, parameters, false);
27
- if (typeof result === "boolean") return parameters.reporting.none ? result : ok(result);
28
+ if (result === true) return parameters.reporting.none || parameters.reporting.throw ? result : ok(result);
29
+ if (parameters.reporting.none) return false;
28
30
  return error(parameters.reporting.all ? result : result[0]);
29
31
  }
30
32
  };