@oscarpalmer/jhunal 0.20.0 → 0.21.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.
@@ -1,17 +1,14 @@
1
- import { ReportingInformation, ValidatedProperty } from "./models/validation.model.mjs";
1
+ import { ReportingInformation, ValidatedPropertyType, ValidationParameters } from "./models/validation.model.mjs";
2
2
  import { Schematic } from "./schematic.mjs";
3
3
  import { ValueName } from "./models/misc.model.mjs";
4
4
  import { Constructor } from "@oscarpalmer/atoms/models";
5
5
 
6
6
  //#region src/helpers.d.ts
7
7
  declare function getInvalidInputMessage(actual: unknown): string;
8
- declare function getInvalidMissingMessage(property: ValidatedProperty): string;
9
- declare function getInvalidTypeMessage(property: ValidatedProperty, actual: unknown): string;
10
- declare function getInvalidValidatorMessage(property: ValidatedProperty, type: ValueName, index: number, length: number): string;
11
- declare function getOptions(input: unknown): {
12
- reporting: ReportingInformation;
13
- strict: boolean;
14
- };
8
+ declare function getInvalidMissingMessage(key: string, types: ValidatedPropertyType[]): string;
9
+ declare function getInvalidTypeMessage(key: string, types: ValidatedPropertyType[], actual: unknown): string;
10
+ declare function getInvalidValidatorMessage(key: string, type: ValueName, index: number, length: number): string;
11
+ declare function getParameters(input?: unknown): ValidationParameters;
15
12
  declare function getReporting(value: unknown): ReportingInformation;
16
13
  declare function getUnknownKeysMessage(keys: string[]): string;
17
14
  /**
@@ -28,4 +25,4 @@ declare function instanceOf<Instance>(constructor: Constructor<Instance>): (valu
28
25
  */
29
26
  declare function isSchematic(value: unknown): value is Schematic<never>;
30
27
  //#endregion
31
- export { getInvalidInputMessage, getInvalidMissingMessage, getInvalidTypeMessage, getInvalidValidatorMessage, getOptions, getReporting, getUnknownKeysMessage, instanceOf, isSchematic };
28
+ export { getInvalidInputMessage, getInvalidMissingMessage, getInvalidTypeMessage, getInvalidValidatorMessage, getParameters, getReporting, getUnknownKeysMessage, instanceOf, isSchematic };
package/dist/helpers.mjs CHANGED
@@ -4,34 +4,37 @@ import { isConstructor, isPlainObject } from "@oscarpalmer/atoms/is";
4
4
  function getInvalidInputMessage(actual) {
5
5
  return VALIDATION_MESSAGE_INVALID_INPUT.replace("<>", getValueType(actual));
6
6
  }
7
- function getInvalidMissingMessage(property) {
8
- let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace("<>", renderTypes(property.types));
9
- message = message.replace("<>", property.key.full);
7
+ function getInvalidMissingMessage(key, types) {
8
+ let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace("<>", renderTypes(types));
9
+ message = message.replace("<>", key);
10
10
  return message;
11
11
  }
12
- function getInvalidTypeMessage(property, actual) {
13
- let message = VALIDATION_MESSAGE_INVALID_TYPE.replace("<>", renderTypes(property.types));
14
- message = message.replace("<>", property.key.full);
12
+ function getInvalidTypeMessage(key, types, actual) {
13
+ let message = VALIDATION_MESSAGE_INVALID_TYPE.replace("<>", renderTypes(types));
14
+ message = message.replace("<>", key);
15
15
  message = message.replace("<>", getValueType(actual));
16
16
  return message;
17
17
  }
18
- function getInvalidValidatorMessage(property, type, index, length) {
19
- let message = VALIDATION_MESSAGE_INVALID_VALUE.replace("<>", property.key.full);
18
+ function getInvalidValidatorMessage(key, type, index, length) {
19
+ let message = VALIDATION_MESSAGE_INVALID_VALUE.replace("<>", key);
20
20
  message = message.replace("<>", type);
21
21
  if (length > 1) message += VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX.replace("<>", String(index));
22
22
  return message;
23
23
  }
24
- function getOptions(input) {
24
+ function getParameters(input) {
25
25
  if (typeof input === "boolean") return {
26
+ output: {},
26
27
  reporting: getReporting(REPORTING_NONE),
27
28
  strict: input
28
29
  };
29
30
  if (REPORTING_TYPES.has(input)) return {
31
+ output: {},
30
32
  reporting: getReporting(input),
31
33
  strict: false
32
34
  };
33
35
  const options = isPlainObject(input) ? input : {};
34
36
  return {
37
+ output: {},
35
38
  reporting: getReporting(options.errors),
36
39
  strict: typeof options.strict === "boolean" ? options.strict : false
37
40
  };
@@ -113,4 +116,4 @@ function renderTypes(types) {
113
116
  return renderParts(parts, CONJUNCTION_OR, CONJUNCTION_OR_COMMA);
114
117
  }
115
118
  //#endregion
116
- export { getInvalidInputMessage, getInvalidMissingMessage, getInvalidTypeMessage, getInvalidValidatorMessage, getOptions, getReporting, getUnknownKeysMessage, instanceOf, isSchematic };
119
+ export { getInvalidInputMessage, getInvalidMissingMessage, getInvalidTypeMessage, getInvalidValidatorMessage, getParameters, getReporting, getUnknownKeysMessage, instanceOf, isSchematic };
package/dist/index.d.mts CHANGED
@@ -214,7 +214,7 @@ type ValidatedProperty = {
214
214
  /**
215
215
  * The property name in the schema
216
216
  */
217
- key: ValidatedPropertyKey;
217
+ key: string;
218
218
  /**
219
219
  * Whether the property is required
220
220
  */
@@ -228,15 +228,6 @@ type ValidatedProperty = {
228
228
  */
229
229
  validators: ValidatedPropertyValidators;
230
230
  };
231
- /**
232
- * The full and short forms of a property's key path
233
- *
234
- * For a nested property `address.street`: `full` is `'address.street'`, `short` is `'street'`
235
- */
236
- type ValidatedPropertyKey = {
237
- full: string;
238
- short: string;
239
- };
240
231
  /**
241
232
  * A union of valid types for a {@link ValidatedProperty}'s `types` array
242
233
  *
@@ -266,9 +257,12 @@ type ValidationInformation = {
266
257
  value: unknown;
267
258
  };
268
259
  /**
269
- * Same shape as {@link ValidatedPropertyKey}; the key path of a failed property
260
+ *
270
261
  */
271
- type ValidationInformationKey = ValidatedPropertyKey;
262
+ type ValidationInformationKey = {
263
+ full: string;
264
+ short: string;
265
+ };
272
266
  /**
273
267
  * Options for validation
274
268
  */
@@ -291,10 +285,73 @@ declare class Schematic<Model> {
291
285
  #private;
292
286
  private readonly $schematic;
293
287
  constructor(properties: ValidatedProperty[]);
288
+ /**
289
+ * Parse a value according to the schema
290
+ *
291
+ * Returns a deeply cloned version of the value or throws an error for the first property that fails validation
292
+ * @param value Value to parse
293
+ * @param options Validation options
294
+ * @returns Deeply cloned version of the value if it matches the schema, otherwise throws an error
295
+ */
296
+ get(value: unknown, options: ValidationOptions<'throw'>): Model;
297
+ /**
298
+ * Parse a value according to the schema
299
+ *
300
+ * Returns a deeply cloned version of the value or throws an error for the first property that fails validation
301
+ * @param value Value to parse
302
+ * @param errors Reporting type
303
+ * @returns Deeply cloned version of the value if it matches the schema, otherwise throws an error
304
+ */
305
+ get(value: unknown, errors: 'throw'): Model;
306
+ /**
307
+ * Parse a value according to the schema
308
+ *
309
+ * 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
310
+ * @param value Value to parse
311
+ * @param options Validation options
312
+ * @returns Result holding deeply cloned value or all validation information
313
+ */
314
+ get(value: unknown, options: ValidationOptions<'all'>): Result<Model, ValidationInformation[]>;
315
+ /**
316
+ * Parse a value according to the schema
317
+ *
318
+ * 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
319
+ * @param value Value to parse
320
+ * @param errors Reporting type
321
+ * @returns Result holding deeply cloned value or all validation information
322
+ */
323
+ get(value: unknown, errors: 'all'): Result<Model, ValidationInformation[]>;
324
+ /**
325
+ * Parse a value according to the schema
326
+ *
327
+ * Returns a deeply cloned version of the value or all validation information for the first failing property
328
+ * @param value Value to parse
329
+ * @param options Validation options
330
+ * @returns Result holding deeply cloned value or all validation information
331
+ */
332
+ get(value: unknown, options: ValidationOptions<'first'>): Result<Model, ValidationInformation>;
333
+ /**
334
+ * Parse a value according to the schema
335
+ *
336
+ * Returns a deeply cloned version of the value or all validation information for the first failing property
337
+ * @param value Value to parse
338
+ * @param errors Reporting type
339
+ * @returns Result holding deeply cloned value or all validation information
340
+ */
341
+ get(value: unknown, errors: 'first'): Result<Model, ValidationInformation>;
342
+ /**
343
+ * Parse a value according to the schema
344
+ *
345
+ * Returns a deeply cloned version of the value or `undefined` if the value does not match the schema
346
+ * @param value Value to parse
347
+ * @param strict Validate if unknown keys are present in the object? _(defaults to `false`)_
348
+ * @returns Deeply cloned value, or `undefined` if it's invalid
349
+ */
350
+ get(value: unknown, strict?: true): Model | undefined;
294
351
  /**
295
352
  * Does the value match the schema?
296
353
  *
297
- * 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.
354
+ * 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
298
355
  * @param value Value to validate
299
356
  * @param options Validation options
300
357
  * @returns `true` if the value matches the schema, otherwise throws an error
@@ -303,7 +360,7 @@ declare class Schematic<Model> {
303
360
  /**
304
361
  * Does the value match the schema?
305
362
  *
306
- * 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.
363
+ * 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
307
364
  * @param value Value to validate
308
365
  * @param errors Reporting type
309
366
  * @returns `true` if the value matches the schema, otherwise throws an error
@@ -312,25 +369,25 @@ declare class Schematic<Model> {
312
369
  /**
313
370
  * Does the value match the schema?
314
371
  *
315
- * 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.
372
+ * 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
316
373
  * @param value Value to validate
317
374
  * @param options Validation options
318
- * @returns `true` if the value matches the schema, otherwise `false`
375
+ * @returns Result holding `true` or all validation information
319
376
  */
320
377
  is(value: unknown, options: ValidationOptions<'all'>): Result<true, ValidationInformation[]>;
321
378
  /**
322
379
  * Does the value match the schema?
323
380
  *
324
- * 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.
381
+ * 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
325
382
  * @param value Value to validate
326
383
  * @param errors Reporting type
327
- * @returns `true` if the value matches the schema, otherwise `false`
384
+ * @returns Result holding `true` or all validation information
328
385
  */
329
386
  is(value: unknown, errors: 'all'): Result<true, ValidationInformation[]>;
330
387
  /**
331
388
  * Does the value match the schema?
332
389
  *
333
- * Will validate that the value matches the schema and return a result of `true` or all validation information for the failing property.
390
+ * Will validate that the value matches the schema and return a result of `true` or all validation information for the first failing property
334
391
  * @param value Value to validate
335
392
  * @param options Validation options
336
393
  * @returns `true` if the value matches the schema, otherwise `false`
@@ -339,7 +396,7 @@ declare class Schematic<Model> {
339
396
  /**
340
397
  * Does the value match the schema?
341
398
  *
342
- * Will validate that the value matches the schema and return a result of `true` or all validation information for the failing property.
399
+ * Will validate that the value matches the schema and return a result of `true` or all validation information for the first failing property
343
400
  * @param value Value to validate
344
401
  * @param errors Reporting type
345
402
  * @returns `true` if the value matches the schema, otherwise `false`
@@ -348,7 +405,7 @@ declare class Schematic<Model> {
348
405
  /**
349
406
  * Does the value match the schema?
350
407
  *
351
- * Will validate that the value matches the schema and return `true` or `false`, without any validation information for validation failures.
408
+ * Will validate that the value matches the schema and return `true` or `false`, without any validation information for validation failures
352
409
  * @param value Value to validate
353
410
  * @param strict Validate if unknown keys are present in the object? _(defaults to `false`)_
354
411
  * @returns `true` if the value matches the schema, otherwise `false`
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import { isConstructor, isPlainObject } from "@oscarpalmer/atoms/is";
2
2
  import { join } from "@oscarpalmer/atoms/string";
3
- import { error } from "@oscarpalmer/atoms/result/misc";
3
+ import { error, ok } from "@oscarpalmer/atoms/result/misc";
4
+ import { clone } from "@oscarpalmer/atoms/value/clone";
4
5
  //#region src/constants.ts
5
6
  const CONJUNCTION_OR = " or ";
6
7
  const CONJUNCTION_OR_COMMA = ", or ";
@@ -63,34 +64,37 @@ const TYPE_ALL = new Set([
63
64
  function getInvalidInputMessage(actual) {
64
65
  return VALIDATION_MESSAGE_INVALID_INPUT.replace("<>", getValueType(actual));
65
66
  }
66
- function getInvalidMissingMessage(property) {
67
- let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace("<>", renderTypes(property.types));
68
- message = message.replace("<>", property.key.full);
67
+ function getInvalidMissingMessage(key, types) {
68
+ let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace("<>", renderTypes(types));
69
+ message = message.replace("<>", key);
69
70
  return message;
70
71
  }
71
- function getInvalidTypeMessage(property, actual) {
72
- let message = VALIDATION_MESSAGE_INVALID_TYPE.replace("<>", renderTypes(property.types));
73
- message = message.replace("<>", property.key.full);
72
+ function getInvalidTypeMessage(key, types, actual) {
73
+ let message = VALIDATION_MESSAGE_INVALID_TYPE.replace("<>", renderTypes(types));
74
+ message = message.replace("<>", key);
74
75
  message = message.replace("<>", getValueType(actual));
75
76
  return message;
76
77
  }
77
- function getInvalidValidatorMessage(property, type, index, length) {
78
- let message = VALIDATION_MESSAGE_INVALID_VALUE.replace("<>", property.key.full);
78
+ function getInvalidValidatorMessage(key, type, index, length) {
79
+ let message = VALIDATION_MESSAGE_INVALID_VALUE.replace("<>", key);
79
80
  message = message.replace("<>", type);
80
81
  if (length > 1) message += VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX.replace("<>", String(index));
81
82
  return message;
82
83
  }
83
- function getOptions(input) {
84
+ function getParameters(input) {
84
85
  if (typeof input === "boolean") return {
86
+ output: {},
85
87
  reporting: getReporting(REPORTING_NONE),
86
88
  strict: input
87
89
  };
88
90
  if (REPORTING_TYPES.has(input)) return {
91
+ output: {},
89
92
  reporting: getReporting(input),
90
93
  strict: false
91
94
  };
92
95
  const options = isPlainObject(input) ? input : {};
93
96
  return {
97
+ output: {},
94
98
  reporting: getReporting(options.errors),
95
99
  strict: typeof options.strict === "boolean" ? options.strict : false
96
100
  };
@@ -210,9 +214,8 @@ function getProperties(original, prefix, fromType) {
210
214
  const properties = [];
211
215
  for (let keyIndex = 0; keyIndex < keysLength; keyIndex += 1) {
212
216
  const key = keys[keyIndex];
213
- const prefixed = join([prefix, key], ".");
214
217
  const value = original[key];
215
- if (value == null) throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE.replace("<>", prefixed));
218
+ if (value == null) throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE.replace("<>", join([prefix, key], ".")));
216
219
  const types = [];
217
220
  let required = true;
218
221
  let validators = {};
@@ -224,12 +227,9 @@ function getProperties(original, prefix, fromType) {
224
227
  } else types.push(...getTypes(key, value, prefix));
225
228
  if (!required && !types.includes("undefined")) types.push(TYPE_UNDEFINED);
226
229
  properties.push({
230
+ key,
227
231
  types,
228
232
  validators,
229
- key: {
230
- full: prefixed,
231
- short: key
232
- },
233
233
  required: required && !types.includes("undefined")
234
234
  });
235
235
  }
@@ -284,18 +284,21 @@ function getValidators(original) {
284
284
  }
285
285
  //#endregion
286
286
  //#region src/validation/value.validation.ts
287
- function validateNamed(property, name, value, validation) {
287
+ function validateNamed(name, value, parameters) {
288
288
  if (!validators[name](value)) return false;
289
- const propertyValidators = property.validators[name];
289
+ const propertyValidators = parameters.origin.validators[name];
290
290
  if (propertyValidators == null || propertyValidators.length === 0) return true;
291
291
  const { length } = propertyValidators;
292
292
  for (let index = 0; index < length; index += 1) {
293
293
  const validator = propertyValidators[index];
294
294
  if (!validator(value)) {
295
- validation.push({
295
+ parameters.information.push({
296
296
  value,
297
- key: { ...property.key },
298
- message: getInvalidValidatorMessage(property, name, index, length),
297
+ key: {
298
+ full: parameters.prefix,
299
+ short: parameters.origin.key
300
+ },
301
+ message: getInvalidValidatorMessage(parameters.prefix, name, index, length),
299
302
  validator
300
303
  });
301
304
  return false;
@@ -303,103 +306,121 @@ function validateNamed(property, name, value, validation) {
303
306
  }
304
307
  return true;
305
308
  }
306
- function validateObject(obj, properties, options, origin, validation) {
309
+ function validateObject(obj, properties, parameters, get) {
307
310
  if (!isPlainObject(obj)) {
308
- const key = origin == null ? {
311
+ const key = parameters?.origin == null ? {
309
312
  full: "",
310
313
  short: ""
311
- } : { ...origin.key };
314
+ } : {
315
+ full: parameters.prefix,
316
+ short: parameters.origin.key
317
+ };
312
318
  const information = {
313
319
  key,
314
- message: origin == null ? getInvalidInputMessage(obj) : getInvalidTypeMessage({
315
- ...origin,
316
- key
317
- }, obj),
320
+ message: parameters?.origin == null ? getInvalidInputMessage(obj) : getInvalidTypeMessage(key.full, parameters.origin.types, obj),
318
321
  value: obj
319
322
  };
320
- if (options.reporting.throw) throw new ValidationError([information]);
321
- validation?.push(information);
322
- return options.reporting.none ? false : [information];
323
+ if (parameters.reporting.throw) throw new ValidationError([information]);
324
+ parameters?.information?.push(information);
325
+ return parameters.reporting.none ? void 0 : [information];
323
326
  }
324
- if (options.strict) {
327
+ if (parameters.strict) {
325
328
  const objKeys = Object.keys(obj);
326
- const propertiesKeys = new Set(properties.map((property) => property.key.short));
329
+ const propertiesKeys = new Set(properties.map((property) => property.key));
327
330
  const unknownKeys = objKeys.filter((key) => !propertiesKeys.has(key));
328
331
  if (unknownKeys.length > 0) {
329
332
  const information = {
330
- key: origin == null ? {
333
+ key: parameters?.origin == null ? {
331
334
  full: "",
332
335
  short: ""
333
- } : { ...origin.key },
334
- message: getUnknownKeysMessage(unknownKeys.map((key) => join([origin?.key.full, key], "."))),
336
+ } : {
337
+ full: join([parameters.prefix, parameters.origin?.key], "."),
338
+ short: parameters.origin.key
339
+ },
340
+ message: getUnknownKeysMessage(unknownKeys.map((key) => join([parameters?.prefix, key], "."))),
335
341
  value: obj
336
342
  };
337
- if (options.reporting.throw) throw new ValidationError([information]);
338
- validation?.push(information);
339
- return options.reporting.none ? false : [information];
343
+ if (parameters.reporting.throw) throw new ValidationError([information]);
344
+ parameters?.information?.push(information);
345
+ return parameters.reporting.none ? void 0 : [information];
340
346
  }
341
347
  }
342
348
  const allInformation = [];
349
+ const output = {};
343
350
  const propertiesLength = properties.length;
344
351
  outer: for (let propertyIndex = 0; propertyIndex < propertiesLength; propertyIndex += 1) {
345
- let property = properties[propertyIndex];
346
- property = {
347
- ...property,
348
- key: {
349
- full: join([origin?.key.full, property.key.short], "."),
350
- short: property.key.short
351
- }
352
- };
352
+ const property = properties[propertyIndex];
353
353
  const { key, required, types } = property;
354
- const value = obj[key.short];
354
+ const value = obj[key];
355
+ if (get && value === void 0 && !required) continue;
355
356
  if (value === void 0 && required) {
357
+ const prefixedKey = join([parameters.prefix, key], ".");
356
358
  const information = {
357
359
  value,
358
- key: { ...key },
359
- message: getInvalidMissingMessage(property)
360
+ key: {
361
+ full: prefixedKey,
362
+ short: key
363
+ },
364
+ message: getInvalidMissingMessage(prefixedKey, property.types)
360
365
  };
361
- if (options.reporting.throw && validation == null) throw new ValidationError([information]);
362
- if (validation != null) validation.push(information);
363
- if (options.reporting.all) {
366
+ if (parameters.reporting.throw) throw new ValidationError([information]);
367
+ parameters?.information?.push(information);
368
+ if (parameters.reporting.all) {
364
369
  allInformation.push(information);
365
370
  continue;
366
371
  }
367
- return options.reporting.none ? false : [information];
372
+ return parameters.reporting.none ? void 0 : [information];
368
373
  }
374
+ const prefixedKey = join([parameters.prefix, key], ".");
369
375
  const typesLength = types.length;
370
376
  const information = [];
371
377
  for (let typeIndex = 0; typeIndex < typesLength; typeIndex += 1) {
372
378
  const type = types[typeIndex];
373
- if (validateValue(type, property, value, options, information)) continue outer;
379
+ if (validateValue(type, value, {
380
+ information,
381
+ output,
382
+ origin: property,
383
+ prefix: prefixedKey,
384
+ reporting: parameters.reporting,
385
+ strict: parameters.strict
386
+ }, get)) {
387
+ if (get) output[key] = clone(value);
388
+ continue outer;
389
+ }
374
390
  }
375
391
  if (information.length === 0) information.push({
376
392
  value,
377
- key: { ...key },
378
- message: getInvalidTypeMessage(property, value)
393
+ key: {
394
+ full: prefixedKey,
395
+ short: key
396
+ },
397
+ message: getInvalidTypeMessage(prefixedKey, property.types, value)
379
398
  });
380
- if (options.reporting.throw && validation == null) throw new ValidationError(information);
381
- validation?.push(...information);
382
- if (options.reporting.all) {
399
+ if (parameters.reporting.throw) throw new ValidationError(information);
400
+ parameters?.information?.push(...information);
401
+ if (parameters.reporting.all) {
383
402
  allInformation.push(...information);
384
403
  continue;
385
404
  }
386
- return options.reporting.none ? false : information;
405
+ return parameters.reporting.none ? void 0 : information;
387
406
  }
388
- return options.reporting.none || allInformation.length === 0 ? true : allInformation;
407
+ if (get) if (parameters.origin == null) parameters.output = output;
408
+ else parameters.output[parameters.origin.key] = output;
409
+ return parameters.reporting.none || allInformation.length === 0 ? parameters.output : allInformation;
389
410
  }
390
- function validateSchematic(property, schematic, value, options, validation) {
391
- const result = validateObject(value, schematicProperties.get(schematic), options, property, validation);
392
- return typeof result === "boolean" ? result : result.length === 0;
411
+ function validateSchematic(schematic, value, parameters, get) {
412
+ const result = validateObject(value, schematicProperties.get(schematic), parameters, get);
413
+ return result == null || Array.isArray(result) ? false : true;
393
414
  }
394
- function validateValue(type, property, value, options, validation) {
415
+ function validateValue(type, value, parameters, get) {
395
416
  switch (true) {
396
417
  case typeof type === "function": return type(value);
397
418
  case Array.isArray(type): {
398
- const validated = validateObject(value, type, options, property, validation);
399
- return typeof validated === "boolean" ? validated : false;
419
+ const result = validateObject(value, type, parameters, get);
420
+ return result == null || Array.isArray(result) ? false : true;
400
421
  }
401
- case isSchematic(type): return validateSchematic(property, type, value, options, validation);
402
- default: return validateNamed(property, type, value, validation);
422
+ case isSchematic(type): return validateSchematic(type, value, parameters, get);
423
+ default: return validateNamed(type, value, parameters);
403
424
  }
404
425
  }
405
426
  const validators = {
@@ -427,14 +448,19 @@ var Schematic = class {
427
448
  this.#properties = properties;
428
449
  schematicProperties.set(this, properties);
429
450
  }
451
+ get(value, options) {
452
+ const parameters = getParameters(options);
453
+ const result = validateObject(value, this.#properties, parameters, true);
454
+ if (result == null) return;
455
+ if (!Array.isArray(result)) return parameters.reporting.none ? result : ok(result);
456
+ return error(parameters.reporting.all ? result : result[0]);
457
+ }
430
458
  is(value, options) {
431
- const { reporting, strict } = getOptions(options);
432
- const result = validateObject(value, this.#properties, {
433
- reporting,
434
- strict
435
- });
436
- if (typeof result === "boolean") return result;
437
- return error(reporting.all ? result : result[0]);
459
+ const parameters = getParameters(options);
460
+ const result = validateObject(value, this.#properties, parameters, false);
461
+ if (result == null) return false;
462
+ if (!Array.isArray(result)) return parameters.reporting.none ? true : ok(true);
463
+ return error(parameters.reporting.all ? result : result[0]);
438
464
  }
439
465
  };
440
466
  function schematic(schema) {
@@ -1,6 +1,6 @@
1
1
  import { Schematic } from "../schematic.mjs";
2
2
  import { ValueName } from "./misc.model.mjs";
3
- import { GenericCallback } from "@oscarpalmer/atoms/models";
3
+ import { GenericCallback, PlainObject } from "@oscarpalmer/atoms/models";
4
4
 
5
5
  //#region src/models/validation.model.d.ts
6
6
  /**
@@ -41,7 +41,7 @@ type ValidatedProperty = {
41
41
  /**
42
42
  * The property name in the schema
43
43
  */
44
- key: ValidatedPropertyKey;
44
+ key: string;
45
45
  /**
46
46
  * Whether the property is required
47
47
  */
@@ -55,15 +55,6 @@ type ValidatedProperty = {
55
55
  */
56
56
  validators: ValidatedPropertyValidators;
57
57
  };
58
- /**
59
- * The full and short forms of a property's key path
60
- *
61
- * For a nested property `address.street`: `full` is `'address.street'`, `short` is `'street'`
62
- */
63
- type ValidatedPropertyKey = {
64
- full: string;
65
- short: string;
66
- };
67
58
  /**
68
59
  * A union of valid types for a {@link ValidatedProperty}'s `types` array
69
60
  *
@@ -93,9 +84,12 @@ type ValidationInformation = {
93
84
  value: unknown;
94
85
  };
95
86
  /**
96
- * Same shape as {@link ValidatedPropertyKey}; the key path of a failed property
87
+ *
97
88
  */
98
- type ValidationInformationKey = ValidatedPropertyKey;
89
+ type ValidationInformationKey = {
90
+ full: string;
91
+ short: string;
92
+ };
99
93
  /**
100
94
  * Options for validation
101
95
  */
@@ -109,9 +103,13 @@ type ValidationOptions<Errors extends ReportingType> = {
109
103
  */
110
104
  strict?: boolean;
111
105
  };
112
- type ValidationOptionsExtended = {
106
+ type ValidationParameters = {
107
+ information?: ValidationInformation[];
108
+ origin?: ValidatedProperty;
109
+ output: PlainObject;
110
+ prefix?: string;
113
111
  reporting: ReportingInformation;
114
112
  strict: boolean;
115
113
  };
116
114
  //#endregion
117
- export { ReportingInformation, ReportingType, SchematicError, ValidatedProperty, ValidatedPropertyKey, ValidatedPropertyType, ValidatedPropertyValidators, ValidationError, ValidationInformation, ValidationInformationKey, ValidationOptions, ValidationOptionsExtended };
115
+ export { ReportingInformation, ReportingType, SchematicError, ValidatedProperty, ValidatedPropertyType, ValidatedPropertyValidators, ValidationError, ValidationInformation, ValidationInformationKey, ValidationOptions, ValidationParameters };