@oscarpalmer/jhunal 0.23.0 → 0.24.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/dist/constants.d.mts +5 -2
- package/dist/constants.mjs +17 -20
- package/dist/helpers/message.helper.d.mts +11 -5
- package/dist/helpers/message.helper.mjs +31 -9
- package/dist/helpers/misc.helper.d.mts +1 -1
- package/dist/helpers/misc.helper.mjs +1 -1
- package/dist/index.d.mts +5 -17
- package/dist/index.mjs +83 -45
- package/dist/models/schema.plain.model.d.mts +2 -0
- package/dist/models/schema.typed.model.d.mts +3 -17
- package/dist/models/validation.model.d.mts +11 -1
- package/dist/validator/named.handler.d.mts +1 -1
- package/dist/validator/named.handler.mjs +3 -2
- package/dist/validator/named.validator.mjs +2 -3
- package/dist/validator/object.validator.mjs +37 -19
- package/package.json +1 -1
- package/src/constants.ts +21 -25
- package/src/helpers/message.helper.ts +74 -9
- package/src/helpers/misc.helper.ts +6 -7
- package/src/models/schema.plain.model.ts +2 -0
- package/src/models/schema.typed.model.ts +4 -22
- package/src/models/validation.model.ts +12 -0
- package/src/validator/named.handler.ts +16 -1
- package/src/validator/named.validator.ts +3 -4
- package/src/validator/object.validator.ts +78 -52
package/dist/constants.d.mts
CHANGED
|
@@ -12,6 +12,7 @@ declare const NAME_SCHEMATIC = "Schematic";
|
|
|
12
12
|
declare const NAME_SCHEMATIC_PREFIXED = "a Schematic";
|
|
13
13
|
declare const NAME_ERROR_SCHEMATIC = "SchematicError";
|
|
14
14
|
declare const NAME_ERROR_VALIDATION = "ValidationError";
|
|
15
|
+
declare const PROPERTY_DEFAULT = "$default";
|
|
15
16
|
declare const PROPERTY_REQUIRED = "$required";
|
|
16
17
|
declare const PROPERTY_SCHEMATIC = "$schematic";
|
|
17
18
|
declare const PROPERTY_TYPE = "$type";
|
|
@@ -27,8 +28,10 @@ declare const REPORTING_FIRST: ReportingType;
|
|
|
27
28
|
declare const REPORTING_NONE: ReportingType;
|
|
28
29
|
declare const REPORTING_THROW: ReportingType;
|
|
29
30
|
declare const REPORTING_TYPES: Set<ReportingType>;
|
|
31
|
+
declare const SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_REQUIRED = "'<>' has a default value but is not required";
|
|
32
|
+
declare const SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_TYPE = "Expected default value for property '<>' to be <>";
|
|
30
33
|
declare const SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY = "Schema must have at least one property";
|
|
31
|
-
declare const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED = "'<>.<>' property is not allowed for schemas
|
|
34
|
+
declare const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED = "'<>.<>' property is not allowed for plain schemas";
|
|
32
35
|
declare const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE = "'<>' property must not be 'null' or 'undefined'";
|
|
33
36
|
declare const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED = "'<>.$required' property must be a boolean";
|
|
34
37
|
declare const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE = "'<>' property must be of a valid type";
|
|
@@ -47,4 +50,4 @@ declare const VALIDATABLE_TYPES: Set<keyof Values>;
|
|
|
47
50
|
declare const TYPE_ALL: Set<keyof Values>;
|
|
48
51
|
declare const PREFIXED_TYPES: Record<ValueName, string>;
|
|
49
52
|
//#endregion
|
|
50
|
-
export { COMMA, CONJUNCTION_AND, CONJUNCTION_AND_COMMA, CONJUNCTION_OR, CONJUNCTION_OR_COMMA, MESSAGE_CONSTRUCTOR, NAME_ERROR_SCHEMATIC, NAME_ERROR_VALIDATION, NAME_SCHEMATIC, NAME_SCHEMATIC_PREFIXED, PREFIXED_TYPES, PROPERTY_REQUIRED, PROPERTY_SCHEMATIC, PROPERTY_TYPE, PROPERTY_VALIDATORS, REPORTING_ALL, REPORTING_FIRST, REPORTING_NONE, REPORTING_THROW, REPORTING_TYPES, SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE, TEMPLATE_PATTERN, TYPE_ALL, TYPE_ARRAY, TYPE_FUNCTION, TYPE_FUNCTION_RESULT, TYPE_NULL, TYPE_OBJECT, TYPE_UNDEFINED, VALIDATABLE_TYPES, VALIDATION_MESSAGE_INVALID_INPUT, VALIDATION_MESSAGE_INVALID_REQUIRED, VALIDATION_MESSAGE_INVALID_TYPE, VALIDATION_MESSAGE_INVALID_VALUE, VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX, VALIDATION_MESSAGE_UNKNOWN_KEYS };
|
|
53
|
+
export { COMMA, CONJUNCTION_AND, CONJUNCTION_AND_COMMA, CONJUNCTION_OR, CONJUNCTION_OR_COMMA, MESSAGE_CONSTRUCTOR, NAME_ERROR_SCHEMATIC, NAME_ERROR_VALIDATION, NAME_SCHEMATIC, NAME_SCHEMATIC_PREFIXED, PREFIXED_TYPES, PROPERTY_DEFAULT, PROPERTY_REQUIRED, PROPERTY_SCHEMATIC, PROPERTY_TYPE, PROPERTY_VALIDATORS, REPORTING_ALL, REPORTING_FIRST, REPORTING_NONE, REPORTING_THROW, REPORTING_TYPES, SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_REQUIRED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_TYPE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE, TEMPLATE_PATTERN, TYPE_ALL, TYPE_ARRAY, TYPE_FUNCTION, TYPE_FUNCTION_RESULT, TYPE_NULL, TYPE_OBJECT, TYPE_UNDEFINED, VALIDATABLE_TYPES, VALIDATION_MESSAGE_INVALID_INPUT, VALIDATION_MESSAGE_INVALID_REQUIRED, VALIDATION_MESSAGE_INVALID_TYPE, VALIDATION_MESSAGE_INVALID_VALUE, VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX, VALIDATION_MESSAGE_UNKNOWN_KEYS };
|
package/dist/constants.mjs
CHANGED
|
@@ -9,6 +9,7 @@ const NAME_SCHEMATIC = "Schematic";
|
|
|
9
9
|
const NAME_SCHEMATIC_PREFIXED = "a Schematic";
|
|
10
10
|
const NAME_ERROR_SCHEMATIC = "SchematicError";
|
|
11
11
|
const NAME_ERROR_VALIDATION = "ValidationError";
|
|
12
|
+
const PROPERTY_DEFAULT = "$default";
|
|
12
13
|
const PROPERTY_REQUIRED = "$required";
|
|
13
14
|
const PROPERTY_SCHEMATIC = "$schematic";
|
|
14
15
|
const PROPERTY_TYPE = "$type";
|
|
@@ -29,8 +30,10 @@ const REPORTING_TYPES = new Set([
|
|
|
29
30
|
REPORTING_NONE,
|
|
30
31
|
REPORTING_THROW
|
|
31
32
|
]);
|
|
33
|
+
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_REQUIRED = "'<>' has a default value but is not required";
|
|
34
|
+
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_TYPE = "Expected default value for property '<>' to be <>";
|
|
32
35
|
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY = "Schema must have at least one property";
|
|
33
|
-
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED = "'<>.<>' property is not allowed for schemas
|
|
36
|
+
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED = "'<>.<>' property is not allowed for plain schemas";
|
|
34
37
|
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE = "'<>' property must not be 'null' or 'undefined'";
|
|
35
38
|
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED = "'<>.$required' property must be a boolean";
|
|
36
39
|
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE = "'<>' property must be of a valid type";
|
|
@@ -40,27 +43,21 @@ const SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE = "Validators must be an object";
|
|
|
40
43
|
const SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE = "Validator '<>' must be a function or an array of functions";
|
|
41
44
|
const TEMPLATE_PATTERN = "<>";
|
|
42
45
|
const TYPE_ARRAY = "array";
|
|
43
|
-
const TYPE_BIGINT = "bigint";
|
|
44
|
-
const TYPE_BOOLEAN = "boolean";
|
|
45
|
-
const TYPE_DATE = "date";
|
|
46
46
|
const TYPE_FUNCTION = "function";
|
|
47
47
|
const TYPE_FUNCTION_RESULT = "a validated value";
|
|
48
48
|
const TYPE_NULL = "null";
|
|
49
|
-
const TYPE_NUMBER = "number";
|
|
50
49
|
const TYPE_OBJECT = "object";
|
|
51
|
-
const TYPE_STRING = "string";
|
|
52
|
-
const TYPE_SYMBOL = "symbol";
|
|
53
50
|
const TYPE_UNDEFINED = "undefined";
|
|
54
51
|
const VALIDATABLE_TYPES = new Set([
|
|
55
52
|
TYPE_ARRAY,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
"bigint",
|
|
54
|
+
"boolean",
|
|
55
|
+
"date",
|
|
59
56
|
TYPE_FUNCTION,
|
|
60
|
-
|
|
57
|
+
"number",
|
|
61
58
|
TYPE_OBJECT,
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
"string",
|
|
60
|
+
"symbol"
|
|
64
61
|
]);
|
|
65
62
|
const TYPE_ALL = new Set([
|
|
66
63
|
...VALIDATABLE_TYPES,
|
|
@@ -69,16 +66,16 @@ const TYPE_ALL = new Set([
|
|
|
69
66
|
]);
|
|
70
67
|
const PREFIXED_TYPES = {
|
|
71
68
|
[TYPE_ARRAY]: `an ${TYPE_ARRAY}`,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
bigint: `a bigint`,
|
|
70
|
+
boolean: `a boolean`,
|
|
71
|
+
date: `a date`,
|
|
75
72
|
[TYPE_FUNCTION]: `a ${TYPE_FUNCTION}`,
|
|
76
73
|
[TYPE_NULL]: TYPE_NULL,
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
number: `a number`,
|
|
75
|
+
string: `a string`,
|
|
76
|
+
symbol: `a symbol`,
|
|
80
77
|
[TYPE_OBJECT]: `an ${TYPE_OBJECT}`,
|
|
81
78
|
[TYPE_UNDEFINED]: TYPE_UNDEFINED
|
|
82
79
|
};
|
|
83
80
|
//#endregion
|
|
84
|
-
export { COMMA, CONJUNCTION_AND, CONJUNCTION_AND_COMMA, CONJUNCTION_OR, CONJUNCTION_OR_COMMA, MESSAGE_CONSTRUCTOR, NAME_ERROR_SCHEMATIC, NAME_ERROR_VALIDATION, NAME_SCHEMATIC, NAME_SCHEMATIC_PREFIXED, PREFIXED_TYPES, PROPERTY_REQUIRED, PROPERTY_SCHEMATIC, PROPERTY_TYPE, PROPERTY_VALIDATORS, REPORTING_ALL, REPORTING_FIRST, REPORTING_NONE, REPORTING_THROW, REPORTING_TYPES, SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE, TEMPLATE_PATTERN, TYPE_ALL, TYPE_ARRAY, TYPE_FUNCTION, TYPE_FUNCTION_RESULT, TYPE_NULL, TYPE_OBJECT, TYPE_UNDEFINED, VALIDATABLE_TYPES, VALIDATION_MESSAGE_INVALID_INPUT, VALIDATION_MESSAGE_INVALID_REQUIRED, VALIDATION_MESSAGE_INVALID_TYPE, VALIDATION_MESSAGE_INVALID_VALUE, VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX, VALIDATION_MESSAGE_UNKNOWN_KEYS };
|
|
81
|
+
export { COMMA, CONJUNCTION_AND, CONJUNCTION_AND_COMMA, CONJUNCTION_OR, CONJUNCTION_OR_COMMA, MESSAGE_CONSTRUCTOR, NAME_ERROR_SCHEMATIC, NAME_ERROR_VALIDATION, NAME_SCHEMATIC, NAME_SCHEMATIC_PREFIXED, PREFIXED_TYPES, PROPERTY_DEFAULT, PROPERTY_REQUIRED, PROPERTY_SCHEMATIC, PROPERTY_TYPE, PROPERTY_VALIDATORS, REPORTING_ALL, REPORTING_FIRST, REPORTING_NONE, REPORTING_THROW, REPORTING_TYPES, SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_REQUIRED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_TYPE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE, TEMPLATE_PATTERN, TYPE_ALL, TYPE_ARRAY, TYPE_FUNCTION, TYPE_FUNCTION_RESULT, TYPE_NULL, TYPE_OBJECT, TYPE_UNDEFINED, VALIDATABLE_TYPES, VALIDATION_MESSAGE_INVALID_INPUT, VALIDATION_MESSAGE_INVALID_REQUIRED, VALIDATION_MESSAGE_INVALID_TYPE, VALIDATION_MESSAGE_INVALID_VALUE, VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX, VALIDATION_MESSAGE_UNKNOWN_KEYS };
|
|
@@ -2,10 +2,16 @@ import { ValidatorType } from "../models/validation.model.mjs";
|
|
|
2
2
|
import { ValueName } from "../models/misc.model.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/helpers/message.helper.d.ts
|
|
5
|
-
declare function
|
|
6
|
-
declare function
|
|
7
|
-
declare function
|
|
8
|
-
declare function
|
|
5
|
+
declare function getDefaultRequiredMessage(key: string): string;
|
|
6
|
+
declare function getDefaultTypeMessage(key: string, types: ValidatorType[]): string;
|
|
7
|
+
declare function getDisallowedMessage(key: string, property: string): string;
|
|
8
|
+
declare function getInputTypeMessage(actual: unknown): string;
|
|
9
|
+
declare function getInputPropertyMissingMessage(key: string, types: ValidatorType[]): string;
|
|
10
|
+
declare function getInputPropertyTypeMessage(key: string, types: ValidatorType[], actual: unknown): string;
|
|
11
|
+
declare function getInputPropertyValidatorMessage(key: string, type: ValueName, index: number, length: number): string;
|
|
12
|
+
declare function getSchematicPropertyNullableMessage(key: string): string;
|
|
13
|
+
declare function getSchematicPropertyTypeMessage(key: string): string;
|
|
14
|
+
declare function getRequiredMessage(key: string): string;
|
|
9
15
|
declare function getUnknownKeysMessage(keys: string[]): string;
|
|
10
16
|
//#endregion
|
|
11
|
-
export {
|
|
17
|
+
export { getDefaultRequiredMessage, getDefaultTypeMessage, getDisallowedMessage, getInputPropertyMissingMessage, getInputPropertyTypeMessage, getInputPropertyValidatorMessage, getInputTypeMessage, getRequiredMessage, getSchematicPropertyNullableMessage, getSchematicPropertyTypeMessage, getUnknownKeysMessage };
|
|
@@ -1,26 +1,45 @@
|
|
|
1
|
-
import { CONJUNCTION_AND, CONJUNCTION_AND_COMMA, CONJUNCTION_OR, CONJUNCTION_OR_COMMA, PREFIXED_TYPES, TYPE_ALL, TYPE_ARRAY, TYPE_FUNCTION_RESULT, TYPE_NULL, TYPE_OBJECT, VALIDATION_MESSAGE_INVALID_INPUT, VALIDATION_MESSAGE_INVALID_REQUIRED, VALIDATION_MESSAGE_INVALID_TYPE, VALIDATION_MESSAGE_INVALID_VALUE, VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX, VALIDATION_MESSAGE_UNKNOWN_KEYS } from "../constants.mjs";
|
|
1
|
+
import { CONJUNCTION_AND, CONJUNCTION_AND_COMMA, CONJUNCTION_OR, CONJUNCTION_OR_COMMA, PREFIXED_TYPES, SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_REQUIRED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_TYPE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE, TYPE_ALL, TYPE_ARRAY, TYPE_FUNCTION_RESULT, TYPE_NULL, TYPE_OBJECT, VALIDATION_MESSAGE_INVALID_INPUT, VALIDATION_MESSAGE_INVALID_REQUIRED, VALIDATION_MESSAGE_INVALID_TYPE, VALIDATION_MESSAGE_INVALID_VALUE, VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX, VALIDATION_MESSAGE_UNKNOWN_KEYS } from "../constants.mjs";
|
|
2
2
|
import { isConstructor, isPlainObject } from "@oscarpalmer/atoms/is";
|
|
3
3
|
//#region src/helpers/message.helper.ts
|
|
4
|
-
function
|
|
4
|
+
function getDefaultRequiredMessage(key) {
|
|
5
|
+
return SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_REQUIRED.replace("<>", key);
|
|
6
|
+
}
|
|
7
|
+
function getDefaultTypeMessage(key, types) {
|
|
8
|
+
let message = SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_TYPE.replace("<>", key);
|
|
9
|
+
message = message.replace("<>", renderTypes(types));
|
|
10
|
+
return message;
|
|
11
|
+
}
|
|
12
|
+
function getDisallowedMessage(key, property) {
|
|
13
|
+
let message = SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED.replace("<>", key);
|
|
14
|
+
message = message.replace("<>", property);
|
|
15
|
+
return message;
|
|
16
|
+
}
|
|
17
|
+
function getInputTypeMessage(actual) {
|
|
5
18
|
return VALIDATION_MESSAGE_INVALID_INPUT.replace("<>", getValueType(actual));
|
|
6
19
|
}
|
|
7
|
-
function
|
|
20
|
+
function getInputPropertyMissingMessage(key, types) {
|
|
8
21
|
let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace("<>", renderTypes(types));
|
|
9
22
|
message = message.replace("<>", key);
|
|
10
23
|
return message;
|
|
11
24
|
}
|
|
12
|
-
function
|
|
25
|
+
function getInputPropertyTypeMessage(key, types, actual) {
|
|
13
26
|
let message = VALIDATION_MESSAGE_INVALID_TYPE.replace("<>", renderTypes(types));
|
|
14
27
|
message = message.replace("<>", key);
|
|
15
28
|
message = message.replace("<>", getValueType(actual));
|
|
16
29
|
return message;
|
|
17
30
|
}
|
|
18
|
-
function
|
|
31
|
+
function getInputPropertyValidatorMessage(key, type, index, length) {
|
|
19
32
|
let message = VALIDATION_MESSAGE_INVALID_VALUE.replace("<>", key);
|
|
20
33
|
message = message.replace("<>", type);
|
|
21
34
|
if (length > 1) message += VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX.replace("<>", String(index));
|
|
22
35
|
return message;
|
|
23
36
|
}
|
|
37
|
+
function getSchematicPropertyNullableMessage(key) {
|
|
38
|
+
return SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE.replace("<>", key);
|
|
39
|
+
}
|
|
40
|
+
function getSchematicPropertyTypeMessage(key) {
|
|
41
|
+
return SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE.replace("<>", key);
|
|
42
|
+
}
|
|
24
43
|
function getPropertyType(type) {
|
|
25
44
|
switch (true) {
|
|
26
45
|
case typeof type === "function": return isConstructor(type) ? type.name : TYPE_FUNCTION_RESULT;
|
|
@@ -28,9 +47,6 @@ function getPropertyType(type) {
|
|
|
28
47
|
default: return PREFIXED_TYPES[TYPE_OBJECT];
|
|
29
48
|
}
|
|
30
49
|
}
|
|
31
|
-
function getUnknownKeysMessage(keys) {
|
|
32
|
-
return VALIDATION_MESSAGE_UNKNOWN_KEYS.replace("<>", renderKeys(keys));
|
|
33
|
-
}
|
|
34
50
|
function getValueType(value) {
|
|
35
51
|
const valueType = typeof value;
|
|
36
52
|
switch (true) {
|
|
@@ -66,5 +82,11 @@ function renderTypes(types) {
|
|
|
66
82
|
}
|
|
67
83
|
return renderParts(parts, CONJUNCTION_OR, CONJUNCTION_OR_COMMA);
|
|
68
84
|
}
|
|
85
|
+
function getRequiredMessage(key) {
|
|
86
|
+
return SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED.replace("<>", key);
|
|
87
|
+
}
|
|
88
|
+
function getUnknownKeysMessage(keys) {
|
|
89
|
+
return VALIDATION_MESSAGE_UNKNOWN_KEYS.replace("<>", renderKeys(keys));
|
|
90
|
+
}
|
|
69
91
|
//#endregion
|
|
70
|
-
export {
|
|
92
|
+
export { getDefaultRequiredMessage, getDefaultTypeMessage, getDisallowedMessage, getInputPropertyMissingMessage, getInputPropertyTypeMessage, getInputPropertyValidatorMessage, getInputTypeMessage, getRequiredMessage, getSchematicPropertyNullableMessage, getSchematicPropertyTypeMessage, getUnknownKeysMessage };
|
|
@@ -4,7 +4,7 @@ import { Constructor } from "@oscarpalmer/atoms/models";
|
|
|
4
4
|
|
|
5
5
|
//#region src/helpers/misc.helper.d.ts
|
|
6
6
|
declare function getParameters(input?: unknown): ValidatorParameters;
|
|
7
|
-
declare function getReporting(value
|
|
7
|
+
declare function getReporting(value?: unknown): ReportingInformation;
|
|
8
8
|
/**
|
|
9
9
|
* Creates a validator function for a given constructor
|
|
10
10
|
* @param constructor - Constructor to check against
|
package/dist/index.d.mts
CHANGED
|
@@ -8,6 +8,7 @@ import { Result } from "@oscarpalmer/atoms/result/models";
|
|
|
8
8
|
type PlainSchema = {
|
|
9
9
|
[key: string]: PlainSchema | SchemaEntry | SchemaEntry[] | undefined;
|
|
10
10
|
} & {
|
|
11
|
+
$default?: never;
|
|
11
12
|
$required?: never;
|
|
12
13
|
$type?: never;
|
|
13
14
|
$validators?: never;
|
|
@@ -47,6 +48,7 @@ type SchemaEntry = Constructor | PlainSchema | SchemaProperty | Schematic<unknow
|
|
|
47
48
|
* ```
|
|
48
49
|
*/
|
|
49
50
|
type SchemaProperty = {
|
|
51
|
+
$default?: unknown;
|
|
50
52
|
/**
|
|
51
53
|
* Whether the property is required _(defaults to `true`)_
|
|
52
54
|
*/
|
|
@@ -346,6 +348,7 @@ type ToValueType<Value> = Value extends Schematic<any> ? Value : { [Key in keyof
|
|
|
346
348
|
* ```
|
|
347
349
|
*/
|
|
348
350
|
type TypedPropertyOptional<Value> = {
|
|
351
|
+
$default?: never;
|
|
349
352
|
$required: false;
|
|
350
353
|
$type: ToSchemaPropertyType<Exclude<Value, undefined>>;
|
|
351
354
|
$validators?: PropertyValidators<ToSchemaPropertyType<Exclude<Value, undefined>>>;
|
|
@@ -363,6 +366,7 @@ type TypedPropertyOptional<Value> = {
|
|
|
363
366
|
* ```
|
|
364
367
|
*/
|
|
365
368
|
type TypedPropertyRequired<Value> = {
|
|
369
|
+
$default?: unknown;
|
|
366
370
|
$required?: true;
|
|
367
371
|
$type: ToSchemaPropertyType<Value>;
|
|
368
372
|
$validators?: PropertyValidators<ToSchemaPropertyType<Value>>;
|
|
@@ -385,23 +389,7 @@ type TypedPropertyRequired<Value> = {
|
|
|
385
389
|
* };
|
|
386
390
|
* ```
|
|
387
391
|
*/
|
|
388
|
-
type TypedSchema<Model extends PlainObject> = Simplify<{ [Key in RequiredKeys<Model>]: Model[Key] extends PlainObject ?
|
|
389
|
-
/**
|
|
390
|
-
* A {@link TypedSchema} variant for optional nested objects, with `$required` fixed to `false`
|
|
391
|
-
*
|
|
392
|
-
* @template Model Nested object type
|
|
393
|
-
*/
|
|
394
|
-
type TypedSchemaOptional<Model extends PlainObject> = {
|
|
395
|
-
$required: false;
|
|
396
|
-
} & TypedSchema<Model>;
|
|
397
|
-
/**
|
|
398
|
-
* A {@link TypedSchema} variant for required nested objects, with `$required` defaulting to `true`
|
|
399
|
-
*
|
|
400
|
-
* @template Model Nested object type
|
|
401
|
-
*/
|
|
402
|
-
type TypedSchemaRequired<Model extends PlainObject> = {
|
|
403
|
-
$required?: true;
|
|
404
|
-
} & TypedSchema<Model>;
|
|
392
|
+
type TypedSchema<Model extends PlainObject> = Simplify<{ [Key in RequiredKeys<Model>]: Model[Key] extends PlainObject ? Schematic<Model[Key]> : ToSchemaType<Model[Key]> | TypedPropertyRequired<Model[Key]> } & { [Key in OptionalKeys<Model>]: Exclude<Model[Key], undefined> extends PlainObject ? Schematic<Exclude<Model[Key], undefined>> : TypedPropertyOptional<Model[Key]> }>;
|
|
405
393
|
//#endregion
|
|
406
394
|
//#region src/schematic.d.ts
|
|
407
395
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -10,6 +10,7 @@ const CONJUNCTION_AND_COMMA = ", and ";
|
|
|
10
10
|
const MESSAGE_CONSTRUCTOR = "Expected a constructor function";
|
|
11
11
|
const NAME_ERROR_SCHEMATIC = "SchematicError";
|
|
12
12
|
const NAME_ERROR_VALIDATION = "ValidationError";
|
|
13
|
+
const PROPERTY_DEFAULT = "$default";
|
|
13
14
|
const PROPERTY_REQUIRED = "$required";
|
|
14
15
|
const PROPERTY_SCHEMATIC = "$schematic";
|
|
15
16
|
const PROPERTY_TYPE = "$type";
|
|
@@ -29,8 +30,10 @@ const REPORTING_TYPES = new Set([
|
|
|
29
30
|
REPORTING_NONE,
|
|
30
31
|
REPORTING_THROW
|
|
31
32
|
]);
|
|
33
|
+
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_REQUIRED = "'<>' has a default value but is not required";
|
|
34
|
+
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_TYPE = "Expected default value for property '<>' to be <>";
|
|
32
35
|
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY = "Schema must have at least one property";
|
|
33
|
-
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED = "'<>.<>' property is not allowed for schemas
|
|
36
|
+
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED = "'<>.<>' property is not allowed for plain schemas";
|
|
34
37
|
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE = "'<>' property must not be 'null' or 'undefined'";
|
|
35
38
|
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED = "'<>.$required' property must be a boolean";
|
|
36
39
|
const SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE = "'<>' property must be of a valid type";
|
|
@@ -39,42 +42,36 @@ const SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY = "Validator '<>' does not exist";
|
|
|
39
42
|
const SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE = "Validators must be an object";
|
|
40
43
|
const SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE = "Validator '<>' must be a function or an array of functions";
|
|
41
44
|
const TYPE_ARRAY = "array";
|
|
42
|
-
const TYPE_BIGINT = "bigint";
|
|
43
|
-
const TYPE_BOOLEAN = "boolean";
|
|
44
|
-
const TYPE_DATE = "date";
|
|
45
45
|
const TYPE_FUNCTION = "function";
|
|
46
46
|
const TYPE_FUNCTION_RESULT = "a validated value";
|
|
47
47
|
const TYPE_NULL = "null";
|
|
48
|
-
const TYPE_NUMBER = "number";
|
|
49
48
|
const TYPE_OBJECT = "object";
|
|
50
|
-
const TYPE_STRING = "string";
|
|
51
|
-
const TYPE_SYMBOL = "symbol";
|
|
52
49
|
const TYPE_UNDEFINED = "undefined";
|
|
53
50
|
const TYPE_ALL = new Set([
|
|
54
51
|
...new Set([
|
|
55
52
|
TYPE_ARRAY,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
"bigint",
|
|
54
|
+
"boolean",
|
|
55
|
+
"date",
|
|
59
56
|
TYPE_FUNCTION,
|
|
60
|
-
|
|
57
|
+
"number",
|
|
61
58
|
TYPE_OBJECT,
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
"string",
|
|
60
|
+
"symbol"
|
|
64
61
|
]),
|
|
65
62
|
TYPE_NULL,
|
|
66
63
|
TYPE_UNDEFINED
|
|
67
64
|
]);
|
|
68
65
|
const PREFIXED_TYPES = {
|
|
69
66
|
[TYPE_ARRAY]: `an ${TYPE_ARRAY}`,
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
bigint: `a bigint`,
|
|
68
|
+
boolean: `a boolean`,
|
|
69
|
+
date: `a date`,
|
|
73
70
|
[TYPE_FUNCTION]: `a ${TYPE_FUNCTION}`,
|
|
74
71
|
[TYPE_NULL]: TYPE_NULL,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
number: `a number`,
|
|
73
|
+
string: `a string`,
|
|
74
|
+
symbol: `a symbol`,
|
|
78
75
|
[TYPE_OBJECT]: `an ${TYPE_OBJECT}`,
|
|
79
76
|
[TYPE_UNDEFINED]: TYPE_UNDEFINED
|
|
80
77
|
};
|
|
@@ -84,7 +81,7 @@ function getParameters(input) {
|
|
|
84
81
|
if (typeof input === "boolean") return {
|
|
85
82
|
clone: true,
|
|
86
83
|
output: {},
|
|
87
|
-
reporting: getReporting(
|
|
84
|
+
reporting: getReporting(),
|
|
88
85
|
strict: input
|
|
89
86
|
};
|
|
90
87
|
if (REPORTING_TYPES.has(input)) return {
|
|
@@ -154,26 +151,45 @@ var ValidationError = class extends Error {
|
|
|
154
151
|
};
|
|
155
152
|
//#endregion
|
|
156
153
|
//#region src/helpers/message.helper.ts
|
|
157
|
-
function
|
|
154
|
+
function getDefaultRequiredMessage(key) {
|
|
155
|
+
return SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_REQUIRED.replace("<>", key);
|
|
156
|
+
}
|
|
157
|
+
function getDefaultTypeMessage(key, types) {
|
|
158
|
+
let message = SCHEMATIC_MESSAGE_SCHEMA_INVALID_DEFAULT_TYPE.replace("<>", key);
|
|
159
|
+
message = message.replace("<>", renderTypes(types));
|
|
160
|
+
return message;
|
|
161
|
+
}
|
|
162
|
+
function getDisallowedMessage(key, property) {
|
|
163
|
+
let message = SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED.replace("<>", key);
|
|
164
|
+
message = message.replace("<>", property);
|
|
165
|
+
return message;
|
|
166
|
+
}
|
|
167
|
+
function getInputTypeMessage(actual) {
|
|
158
168
|
return VALIDATION_MESSAGE_INVALID_INPUT.replace("<>", getValueType(actual));
|
|
159
169
|
}
|
|
160
|
-
function
|
|
170
|
+
function getInputPropertyMissingMessage(key, types) {
|
|
161
171
|
let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace("<>", renderTypes(types));
|
|
162
172
|
message = message.replace("<>", key);
|
|
163
173
|
return message;
|
|
164
174
|
}
|
|
165
|
-
function
|
|
175
|
+
function getInputPropertyTypeMessage(key, types, actual) {
|
|
166
176
|
let message = VALIDATION_MESSAGE_INVALID_TYPE.replace("<>", renderTypes(types));
|
|
167
177
|
message = message.replace("<>", key);
|
|
168
178
|
message = message.replace("<>", getValueType(actual));
|
|
169
179
|
return message;
|
|
170
180
|
}
|
|
171
|
-
function
|
|
181
|
+
function getInputPropertyValidatorMessage(key, type, index, length) {
|
|
172
182
|
let message = VALIDATION_MESSAGE_INVALID_VALUE.replace("<>", key);
|
|
173
183
|
message = message.replace("<>", type);
|
|
174
184
|
if (length > 1) message += VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX.replace("<>", String(index));
|
|
175
185
|
return message;
|
|
176
186
|
}
|
|
187
|
+
function getSchematicPropertyNullableMessage(key) {
|
|
188
|
+
return SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE.replace("<>", key);
|
|
189
|
+
}
|
|
190
|
+
function getSchematicPropertyTypeMessage(key) {
|
|
191
|
+
return SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE.replace("<>", key);
|
|
192
|
+
}
|
|
177
193
|
function getPropertyType(type) {
|
|
178
194
|
switch (true) {
|
|
179
195
|
case typeof type === "function": return isConstructor(type) ? type.name : TYPE_FUNCTION_RESULT;
|
|
@@ -181,9 +197,6 @@ function getPropertyType(type) {
|
|
|
181
197
|
default: return PREFIXED_TYPES[TYPE_OBJECT];
|
|
182
198
|
}
|
|
183
199
|
}
|
|
184
|
-
function getUnknownKeysMessage(keys) {
|
|
185
|
-
return VALIDATION_MESSAGE_UNKNOWN_KEYS.replace("<>", renderKeys(keys));
|
|
186
|
-
}
|
|
187
200
|
function getValueType(value) {
|
|
188
201
|
const valueType = typeof value;
|
|
189
202
|
switch (true) {
|
|
@@ -219,6 +232,12 @@ function renderTypes(types) {
|
|
|
219
232
|
}
|
|
220
233
|
return renderParts(parts, CONJUNCTION_OR, CONJUNCTION_OR_COMMA);
|
|
221
234
|
}
|
|
235
|
+
function getRequiredMessage(key) {
|
|
236
|
+
return SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED.replace("<>", key);
|
|
237
|
+
}
|
|
238
|
+
function getUnknownKeysMessage(keys) {
|
|
239
|
+
return VALIDATION_MESSAGE_UNKNOWN_KEYS.replace("<>", renderKeys(keys));
|
|
240
|
+
}
|
|
222
241
|
//#endregion
|
|
223
242
|
//#region src/validator/base.validator.ts
|
|
224
243
|
function getBaseValidator(validators) {
|
|
@@ -245,9 +264,10 @@ function getFunctionValidator(fn) {
|
|
|
245
264
|
}
|
|
246
265
|
//#endregion
|
|
247
266
|
//#region src/validator/named.handler.ts
|
|
248
|
-
function getNamedHandlers(original, prefix) {
|
|
267
|
+
function getNamedHandlers(original, prefix, allowed) {
|
|
249
268
|
const handlers = {};
|
|
250
269
|
if (original == null) return handlers;
|
|
270
|
+
if (!allowed) throw new TypeError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED.replace("<>", prefix).replace("<>", PROPERTY_VALIDATORS));
|
|
251
271
|
if (!isPlainObject(original)) throw new TypeError(SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE);
|
|
252
272
|
const keys = Object.keys(original);
|
|
253
273
|
const { length } = keys;
|
|
@@ -276,7 +296,7 @@ function getNamedValidator(key, name, handlers) {
|
|
|
276
296
|
const information = {
|
|
277
297
|
key,
|
|
278
298
|
validator,
|
|
279
|
-
message:
|
|
299
|
+
message: getInputPropertyValidatorMessage(key.full, name, index, length),
|
|
280
300
|
value: input
|
|
281
301
|
};
|
|
282
302
|
parameters.information?.push(information);
|
|
@@ -313,7 +333,13 @@ function getSchematicValidator(schematic) {
|
|
|
313
333
|
}
|
|
314
334
|
//#endregion
|
|
315
335
|
//#region src/validator/object.validator.ts
|
|
336
|
+
function getDefaults(obj, key, allowed) {
|
|
337
|
+
if (!("$default" in obj)) return;
|
|
338
|
+
if (!allowed) throw new SchematicError(getDisallowedMessage(key, PROPERTY_DEFAULT));
|
|
339
|
+
return { value: obj[PROPERTY_DEFAULT] };
|
|
340
|
+
}
|
|
316
341
|
function getDisallowedProperty(obj) {
|
|
342
|
+
if ("$default" in obj) return PROPERTY_DEFAULT;
|
|
317
343
|
if ("$required" in obj) return PROPERTY_REQUIRED;
|
|
318
344
|
if ("$type" in obj) return PROPERTY_TYPE;
|
|
319
345
|
if ("$validators" in obj) return PROPERTY_VALIDATORS;
|
|
@@ -324,14 +350,14 @@ function getObjectValidator(original, origin, fromType) {
|
|
|
324
350
|
if (keysLength === 0) throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY);
|
|
325
351
|
if (fromType ?? false) {
|
|
326
352
|
const property = getDisallowedProperty(original);
|
|
327
|
-
if (property != null) throw new SchematicError(
|
|
353
|
+
if (property != null) throw new SchematicError(getDisallowedMessage(origin.full, property));
|
|
328
354
|
}
|
|
329
355
|
const set = /* @__PURE__ */ new Set();
|
|
330
356
|
const items = [];
|
|
331
357
|
for (let keyIndex = 0; keyIndex < keysLength; keyIndex += 1) {
|
|
332
358
|
const key = keys[keyIndex];
|
|
333
359
|
const value = original[key];
|
|
334
|
-
if (value == null) throw new SchematicError(
|
|
360
|
+
if (value == null) throw new SchematicError(getSchematicPropertyNullableMessage(join([origin?.full, key], ".")));
|
|
335
361
|
const prefixedKey = origin == null ? key : join([origin.full, key], ".");
|
|
336
362
|
const fullKey = {
|
|
337
363
|
full: prefixedKey,
|
|
@@ -340,16 +366,18 @@ function getObjectValidator(original, origin, fromType) {
|
|
|
340
366
|
let handlers = {};
|
|
341
367
|
let required = true;
|
|
342
368
|
let typed = false;
|
|
369
|
+
let defaults;
|
|
343
370
|
let types;
|
|
344
371
|
const validators = [];
|
|
345
372
|
if (isPlainObject(value)) {
|
|
346
373
|
typed = PROPERTY_TYPE in value;
|
|
347
374
|
const type = typed ? value[PROPERTY_TYPE] : value;
|
|
348
|
-
|
|
349
|
-
|
|
375
|
+
defaults = getDefaults(value, prefixedKey, typed);
|
|
376
|
+
handlers = getNamedHandlers(value[PROPERTY_VALIDATORS], prefixedKey, typed);
|
|
377
|
+
required = getRequired(value, prefixedKey, typed) ?? required;
|
|
350
378
|
types = Array.isArray(type) ? type : [type];
|
|
351
379
|
} else types = Array.isArray(value) ? value : [value];
|
|
352
|
-
if (types.length === 0) throw new SchematicError(
|
|
380
|
+
if (types.length === 0) throw new SchematicError(getSchematicPropertyTypeMessage(prefixedKey));
|
|
353
381
|
const typesLength = types.length;
|
|
354
382
|
for (let typeIndex = 0; typeIndex < typesLength; typeIndex += 1) {
|
|
355
383
|
const type = types[typeIndex];
|
|
@@ -367,17 +395,22 @@ function getObjectValidator(original, origin, fromType) {
|
|
|
367
395
|
case TYPE_ALL.has(type):
|
|
368
396
|
validator = getNamedValidator(fullKey, type, handlers);
|
|
369
397
|
break;
|
|
370
|
-
default: throw new SchematicError(
|
|
398
|
+
default: throw new SchematicError(getSchematicPropertyTypeMessage(prefixedKey));
|
|
371
399
|
}
|
|
372
400
|
validators.push(validator);
|
|
373
401
|
}
|
|
374
|
-
|
|
402
|
+
required = required && !types.includes("undefined");
|
|
403
|
+
if (defaults != null && !required) throw new SchematicError(getDefaultRequiredMessage(prefixedKey));
|
|
404
|
+
const validator = getBaseValidator(validators);
|
|
405
|
+
if (defaults != null && Array.isArray(validator(defaults.value, getParameters(), false))) throw new SchematicError(getDefaultTypeMessage(prefixedKey, types));
|
|
375
406
|
items.push({
|
|
407
|
+
defaults,
|
|
408
|
+
required,
|
|
376
409
|
types,
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
validator: getBaseValidator(validators)
|
|
410
|
+
validator,
|
|
411
|
+
key: fullKey
|
|
380
412
|
});
|
|
413
|
+
set.add(key);
|
|
381
414
|
}
|
|
382
415
|
const validatorsLength = items.length;
|
|
383
416
|
return (input, parameters, get) => {
|
|
@@ -389,7 +422,7 @@ function getObjectValidator(original, origin, fromType) {
|
|
|
389
422
|
short: ""
|
|
390
423
|
},
|
|
391
424
|
value: input,
|
|
392
|
-
message:
|
|
425
|
+
message: getInputTypeMessage(input)
|
|
393
426
|
};
|
|
394
427
|
if (parameters.reporting.throw) throw new ValidationError([information]);
|
|
395
428
|
parameters.information?.push(information);
|
|
@@ -414,15 +447,19 @@ function getObjectValidator(original, origin, fromType) {
|
|
|
414
447
|
const allInformation = [];
|
|
415
448
|
const output = {};
|
|
416
449
|
for (let validatorIndex = 0; validatorIndex < validatorsLength; validatorIndex += 1) {
|
|
417
|
-
const { key, required, types, validator } = items[validatorIndex];
|
|
450
|
+
const { defaults, key, required, types, validator } = items[validatorIndex];
|
|
418
451
|
const value = input[key.short];
|
|
419
452
|
if (value === void 0) {
|
|
420
453
|
if (required) {
|
|
454
|
+
if (get && defaults != null) {
|
|
455
|
+
output[key.short] = clone(defaults.value);
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
421
458
|
if (parameters.reporting.none) return [];
|
|
422
459
|
const information = {
|
|
423
460
|
key,
|
|
424
461
|
value,
|
|
425
|
-
message:
|
|
462
|
+
message: getInputPropertyMissingMessage(key.full, types)
|
|
426
463
|
};
|
|
427
464
|
if (parameters.reporting.throw) throw new ValidationError([information]);
|
|
428
465
|
parameters.information?.push(information);
|
|
@@ -446,7 +483,7 @@ function getObjectValidator(original, origin, fromType) {
|
|
|
446
483
|
const information = typeof result !== "boolean" && result.length > 0 ? result : [{
|
|
447
484
|
key,
|
|
448
485
|
value,
|
|
449
|
-
message:
|
|
486
|
+
message: getInputPropertyTypeMessage(key.full, types, value)
|
|
450
487
|
}];
|
|
451
488
|
if (parameters.reporting.throw) throw new ValidationError(information);
|
|
452
489
|
if (parameters.reporting.all) {
|
|
@@ -460,9 +497,10 @@ function getObjectValidator(original, origin, fromType) {
|
|
|
460
497
|
return allInformation.length === 0 ? true : allInformation;
|
|
461
498
|
};
|
|
462
499
|
}
|
|
463
|
-
function getRequired(key,
|
|
500
|
+
function getRequired(obj, key, allowed) {
|
|
464
501
|
if (!("$required" in obj)) return;
|
|
465
|
-
if (
|
|
502
|
+
if (!allowed) throw new SchematicError(getDisallowedMessage(key, PROPERTY_REQUIRED));
|
|
503
|
+
if (typeof obj["$required"] !== "boolean") throw new SchematicError(getRequiredMessage(key));
|
|
466
504
|
return obj[PROPERTY_REQUIRED];
|
|
467
505
|
}
|
|
468
506
|
//#endregion
|
|
@@ -9,6 +9,7 @@ import { Constructor } from "@oscarpalmer/atoms/models";
|
|
|
9
9
|
type PlainSchema = {
|
|
10
10
|
[key: string]: PlainSchema | SchemaEntry | SchemaEntry[] | undefined;
|
|
11
11
|
} & {
|
|
12
|
+
$default?: never;
|
|
12
13
|
$required?: never;
|
|
13
14
|
$type?: never;
|
|
14
15
|
$validators?: never;
|
|
@@ -48,6 +49,7 @@ type SchemaEntry = Constructor | PlainSchema | SchemaProperty | Schematic<unknow
|
|
|
48
49
|
* ```
|
|
49
50
|
*/
|
|
50
51
|
type SchemaProperty = {
|
|
52
|
+
$default?: unknown;
|
|
51
53
|
/**
|
|
52
54
|
* Whether the property is required _(defaults to `true`)_
|
|
53
55
|
*/
|
|
@@ -18,6 +18,7 @@ import { PlainObject, Simplify } from "@oscarpalmer/atoms/models";
|
|
|
18
18
|
* ```
|
|
19
19
|
*/
|
|
20
20
|
type TypedPropertyOptional<Value> = {
|
|
21
|
+
$default?: never;
|
|
21
22
|
$required: false;
|
|
22
23
|
$type: ToSchemaPropertyType<Exclude<Value, undefined>>;
|
|
23
24
|
$validators?: PropertyValidators<ToSchemaPropertyType<Exclude<Value, undefined>>>;
|
|
@@ -35,6 +36,7 @@ type TypedPropertyOptional<Value> = {
|
|
|
35
36
|
* ```
|
|
36
37
|
*/
|
|
37
38
|
type TypedPropertyRequired<Value> = {
|
|
39
|
+
$default?: unknown;
|
|
38
40
|
$required?: true;
|
|
39
41
|
$type: ToSchemaPropertyType<Value>;
|
|
40
42
|
$validators?: PropertyValidators<ToSchemaPropertyType<Value>>;
|
|
@@ -57,22 +59,6 @@ type TypedPropertyRequired<Value> = {
|
|
|
57
59
|
* };
|
|
58
60
|
* ```
|
|
59
61
|
*/
|
|
60
|
-
type TypedSchema<Model extends PlainObject> = Simplify<{ [Key in RequiredKeys<Model>]: Model[Key] extends PlainObject ?
|
|
61
|
-
/**
|
|
62
|
-
* A {@link TypedSchema} variant for optional nested objects, with `$required` fixed to `false`
|
|
63
|
-
*
|
|
64
|
-
* @template Model Nested object type
|
|
65
|
-
*/
|
|
66
|
-
type TypedSchemaOptional<Model extends PlainObject> = {
|
|
67
|
-
$required: false;
|
|
68
|
-
} & TypedSchema<Model>;
|
|
69
|
-
/**
|
|
70
|
-
* A {@link TypedSchema} variant for required nested objects, with `$required` defaulting to `true`
|
|
71
|
-
*
|
|
72
|
-
* @template Model Nested object type
|
|
73
|
-
*/
|
|
74
|
-
type TypedSchemaRequired<Model extends PlainObject> = {
|
|
75
|
-
$required?: true;
|
|
76
|
-
} & TypedSchema<Model>;
|
|
62
|
+
type TypedSchema<Model extends PlainObject> = Simplify<{ [Key in RequiredKeys<Model>]: Model[Key] extends PlainObject ? Schematic<Model[Key]> : ToSchemaType<Model[Key]> | TypedPropertyRequired<Model[Key]> } & { [Key in OptionalKeys<Model>]: Exclude<Model[Key], undefined> extends PlainObject ? Schematic<Exclude<Model[Key], undefined>> : TypedPropertyOptional<Model[Key]> }>;
|
|
77
63
|
//#endregion
|
|
78
64
|
export { TypedPropertyOptional, TypedPropertyRequired, TypedSchema };
|