@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.
@@ -1,17 +1,14 @@
1
- import { ReportingInformation, ValidatedProperty } from "./models/validation.model.mjs";
1
+ import { ReportingInformation, ValidatorParameters, ValidatorType } 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: ValidatorType[]): string;
9
+ declare function getInvalidTypeMessage(key: string, types: ValidatorType[], actual: unknown): string;
10
+ declare function getInvalidValidatorMessage(key: string, type: ValueName, index: number, length: number): string;
11
+ declare function getParameters(input?: unknown): ValidatorParameters;
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,41 +4,45 @@ 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
  };
38
41
  }
39
42
  function getPropertyType(original) {
40
43
  if (typeof original === "function") return "a validated value";
41
- if (Array.isArray(original)) return `'${TYPE_OBJECT}'`;
44
+ if (Array.isArray(original)) return `'array'`;
45
+ if (isPlainObject(original)) return `'${TYPE_OBJECT}'`;
42
46
  if (isSchematic(original)) return `a ${NAME_SCHEMATIC}`;
43
47
  return `'${String(original)}'`;
44
48
  }
@@ -113,4 +117,4 @@ function renderTypes(types) {
113
117
  return renderParts(parts, CONJUNCTION_OR, CONJUNCTION_OR_COMMA);
114
118
  }
115
119
  //#endregion
116
- export { getInvalidInputMessage, getInvalidMissingMessage, getInvalidTypeMessage, getInvalidValidatorMessage, getOptions, getReporting, getUnknownKeysMessage, instanceOf, isSchematic };
120
+ export { getInvalidInputMessage, getInvalidMissingMessage, getInvalidTypeMessage, getInvalidValidatorMessage, getParameters, getReporting, getUnknownKeysMessage, instanceOf, isSchematic };
package/dist/index.d.mts CHANGED
@@ -182,13 +182,16 @@ type TypedSchemaRequired<Model extends PlainObject> = {
182
182
  } & TypedSchema<Model>;
183
183
  //#endregion
184
184
  //#region src/models/validation.model.d.ts
185
+ type ReportingInformation = Record<ReportingType, boolean> & {
186
+ type: ReportingType;
187
+ };
185
188
  /**
186
189
  * Controls how validation failures are reported
187
190
  *
188
- * - `'none'` returns a boolean _(default)_
189
- * - `'first'` returns the first failure as a `Result`
190
- * - `'all'` returns all failures as a `Result` _(from same level)_
191
- * - `'throw'` throws a {@link ValidationError} on failure
191
+ * - `'none'`, returns a boolean _(default)_
192
+ * - `'first'`, returns the first failure as a `Result`
193
+ * - `'all'`, returns all failures as a `Result` _(from same level)_
194
+ * - `'throw'`, throws a {@link ValidationError} on failure
192
195
  */
193
196
  type ReportingType = 'all' | 'first' | 'none' | 'throw';
194
197
  /**
@@ -197,58 +200,6 @@ type ReportingType = 'all' | 'first' | 'none' | 'throw';
197
200
  declare class SchematicError extends Error {
198
201
  constructor(message: string);
199
202
  }
200
- /**
201
- * The runtime representation of a parsed schema property, used internally during validation
202
- *
203
- * @example
204
- * ```ts
205
- * const parsed: ValidatedProperty = {
206
- * key: 'age',
207
- * required: true,
208
- * types: ['number'],
209
- * validators: { number: [(v) => v > 0] },
210
- * };
211
- * ```
212
- */
213
- type ValidatedProperty = {
214
- /**
215
- * The property name in the schema
216
- */
217
- key: ValidatedPropertyKey;
218
- /**
219
- * Whether the property is required
220
- */
221
- required: boolean;
222
- /**
223
- * The allowed types for this property
224
- */
225
- types: ValidatedPropertyType[];
226
- /**
227
- * Custom validators grouped by {@link ValueName}
228
- */
229
- validators: ValidatedPropertyValidators;
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
- /**
241
- * A union of valid types for a {@link ValidatedProperty}'s `types` array
242
- *
243
- * Can be a callback _(custom validator)_, a {@link Schematic}, a nested {@link ValidatedProperty}, or a {@link ValueName} string
244
- */
245
- type ValidatedPropertyType = GenericCallback | ValidatedProperty[] | Schematic<unknown> | ValueName;
246
- /**
247
- * A map of validator functions keyed by {@link ValueName}, used at runtime in {@link ValidatedProperty}
248
- *
249
- * Each key holds an array of validator functions that receive an `unknown` value and return a `boolean`
250
- */
251
- type ValidatedPropertyValidators = { [Key in ValueName]?: Array<(value: unknown) => boolean> };
252
203
  /**
253
204
  * Thrown in `'throw'` mode when one or more properties fail validation; `information` holds all failures
254
205
  */
@@ -266,9 +217,12 @@ type ValidationInformation = {
266
217
  value: unknown;
267
218
  };
268
219
  /**
269
- * Same shape as {@link ValidatedPropertyKey}; the key path of a failed property
220
+ *
270
221
  */
271
- type ValidationInformationKey = ValidatedPropertyKey;
222
+ type ValidationInformationKey = {
223
+ full: string;
224
+ short: string;
225
+ };
272
226
  /**
273
227
  * Options for validation
274
228
  */
@@ -282,6 +236,13 @@ type ValidationOptions<Errors extends ReportingType> = {
282
236
  */
283
237
  strict?: boolean;
284
238
  };
239
+ type Validator = (input: unknown, parameters: ValidatorParameters, get: boolean) => boolean | ValidationInformation[];
240
+ type ValidatorParameters = {
241
+ information?: ValidationInformation[];
242
+ output: PlainObject;
243
+ reporting: ReportingInformation;
244
+ strict: boolean;
245
+ };
285
246
  //#endregion
286
247
  //#region src/schematic.d.ts
287
248
  /**
@@ -290,11 +251,74 @@ type ValidationOptions<Errors extends ReportingType> = {
290
251
  declare class Schematic<Model> {
291
252
  #private;
292
253
  private readonly $schematic;
293
- constructor(properties: ValidatedProperty[]);
254
+ constructor(validator: Validator);
255
+ /**
256
+ * Parse a value according to the schema
257
+ *
258
+ * Returns a deeply cloned version of the value or throws an error for the first property that fails validation
259
+ * @param value Value to parse
260
+ * @param options Validation options
261
+ * @returns Deeply cloned version of the value if it matches the schema, otherwise throws an error
262
+ */
263
+ get(value: unknown, options: ValidationOptions<'throw'>): Model;
264
+ /**
265
+ * Parse a value according to the schema
266
+ *
267
+ * Returns a deeply cloned version of the value or throws an error for the first property that fails validation
268
+ * @param value Value to parse
269
+ * @param errors Reporting type
270
+ * @returns Deeply cloned version of the value if it matches the schema, otherwise throws an error
271
+ */
272
+ get(value: unknown, errors: 'throw'): Model;
273
+ /**
274
+ * Parse a value according to the schema
275
+ *
276
+ * 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
277
+ * @param value Value to parse
278
+ * @param options Validation options
279
+ * @returns Result holding deeply cloned value or all validation information
280
+ */
281
+ get(value: unknown, options: ValidationOptions<'all'>): Result<Model, ValidationInformation[]>;
282
+ /**
283
+ * Parse a value according to the schema
284
+ *
285
+ * 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
286
+ * @param value Value to parse
287
+ * @param errors Reporting type
288
+ * @returns Result holding deeply cloned value or all validation information
289
+ */
290
+ get(value: unknown, errors: 'all'): Result<Model, ValidationInformation[]>;
291
+ /**
292
+ * Parse a value according to the schema
293
+ *
294
+ * Returns a deeply cloned version of the value or all validation information for the first failing property
295
+ * @param value Value to parse
296
+ * @param options Validation options
297
+ * @returns Result holding deeply cloned value or all validation information
298
+ */
299
+ get(value: unknown, options: ValidationOptions<'first'>): Result<Model, ValidationInformation>;
300
+ /**
301
+ * Parse a value according to the schema
302
+ *
303
+ * Returns a deeply cloned version of the value or all validation information for the first failing property
304
+ * @param value Value to parse
305
+ * @param errors Reporting type
306
+ * @returns Result holding deeply cloned value or all validation information
307
+ */
308
+ get(value: unknown, errors: 'first'): Result<Model, ValidationInformation>;
309
+ /**
310
+ * Parse a value according to the schema
311
+ *
312
+ * Returns a deeply cloned version of the value or `undefined` if the value does not match the schema
313
+ * @param value Value to parse
314
+ * @param strict Validate if unknown keys are present in the object? _(defaults to `false`)_
315
+ * @returns Deeply cloned value, or `undefined` if it's invalid
316
+ */
317
+ get(value: unknown, strict?: true): Model | undefined;
294
318
  /**
295
319
  * Does the value match the schema?
296
320
  *
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.
321
+ * 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
322
  * @param value Value to validate
299
323
  * @param options Validation options
300
324
  * @returns `true` if the value matches the schema, otherwise throws an error
@@ -303,7 +327,7 @@ declare class Schematic<Model> {
303
327
  /**
304
328
  * Does the value match the schema?
305
329
  *
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.
330
+ * 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
331
  * @param value Value to validate
308
332
  * @param errors Reporting type
309
333
  * @returns `true` if the value matches the schema, otherwise throws an error
@@ -312,25 +336,25 @@ declare class Schematic<Model> {
312
336
  /**
313
337
  * Does the value match the schema?
314
338
  *
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.
339
+ * 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
340
  * @param value Value to validate
317
341
  * @param options Validation options
318
- * @returns `true` if the value matches the schema, otherwise `false`
342
+ * @returns Result holding `true` or all validation information
319
343
  */
320
344
  is(value: unknown, options: ValidationOptions<'all'>): Result<true, ValidationInformation[]>;
321
345
  /**
322
346
  * Does the value match the schema?
323
347
  *
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.
348
+ * 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
349
  * @param value Value to validate
326
350
  * @param errors Reporting type
327
- * @returns `true` if the value matches the schema, otherwise `false`
351
+ * @returns Result holding `true` or all validation information
328
352
  */
329
353
  is(value: unknown, errors: 'all'): Result<true, ValidationInformation[]>;
330
354
  /**
331
355
  * Does the value match the schema?
332
356
  *
333
- * Will validate that the value matches the schema and return a result of `true` or all validation information for the failing property.
357
+ * Will validate that the value matches the schema and return a result of `true` or all validation information for the first failing property
334
358
  * @param value Value to validate
335
359
  * @param options Validation options
336
360
  * @returns `true` if the value matches the schema, otherwise `false`
@@ -339,7 +363,7 @@ declare class Schematic<Model> {
339
363
  /**
340
364
  * Does the value match the schema?
341
365
  *
342
- * Will validate that the value matches the schema and return a result of `true` or all validation information for the failing property.
366
+ * Will validate that the value matches the schema and return a result of `true` or all validation information for the first failing property
343
367
  * @param value Value to validate
344
368
  * @param errors Reporting type
345
369
  * @returns `true` if the value matches the schema, otherwise `false`
@@ -348,7 +372,7 @@ declare class Schematic<Model> {
348
372
  /**
349
373
  * Does the value match the schema?
350
374
  *
351
- * Will validate that the value matches the schema and return `true` or `false`, without any validation information for validation failures.
375
+ * Will validate that the value matches the schema and return `true` or `false`, without any validation information for validation failures
352
376
  * @param value Value to validate
353
377
  * @param strict Validate if unknown keys are present in the object? _(defaults to `false`)_
354
378
  * @returns `true` if the value matches the schema, otherwise `false`
@@ -395,19 +419,13 @@ type PlainSchema = {
395
419
  * };
396
420
  * ```
397
421
  */
398
- type Schema = SchemaIndex;
422
+ type Schema = PlainSchema;
399
423
  /**
400
424
  * A union of all valid types for a single schema entry
401
425
  *
402
426
  * Can be a {@link Constructor}, {@link PlainSchema}, {@link SchemaProperty}, {@link Schematic}, {@link ValueName} string, or a custom validator function
403
427
  */
404
428
  type SchemaEntry = Constructor | PlainSchema | SchemaProperty | Schematic<unknown> | ValueName | ((value: unknown) => boolean);
405
- /**
406
- * Index signature interface backing {@link Schema}, allowing string-keyed entries of {@link PlainSchema}, {@link SchemaEntry}, or arrays of {@link SchemaEntry}
407
- */
408
- interface SchemaIndex {
409
- [key: string]: PlainSchema | SchemaEntry | SchemaEntry[];
410
- }
411
429
  /**
412
430
  * A property definition with explicit type(s), an optional requirement flag, and optional validators
413
431
  *
@@ -615,4 +633,4 @@ declare function instanceOf<Instance>(constructor: Constructor<Instance>): (valu
615
633
  */
616
634
  declare function isSchematic(value: unknown): value is Schematic<never>;
617
635
  //#endregion
618
- export { type Schema, type Schematic, SchematicError, type TypedSchema, ValidationError, instanceOf, isSchematic, schematic };
636
+ export { type Schema, type Schematic, SchematicError, type TypedSchema, ValidationError, type ValidationInformation, type ValidationOptions, instanceOf, isSchematic, schematic };