@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.
- package/dist/helpers.d.mts +6 -9
- package/dist/helpers.mjs +13 -10
- package/dist/index.d.mts +78 -21
- package/dist/index.mjs +103 -77
- package/dist/models/validation.model.d.mts +13 -15
- package/dist/schematic.d.mts +72 -9
- package/dist/schematic.mjs +14 -9
- package/dist/validation/property.validation.mjs +2 -6
- package/dist/validation/value.validation.d.mts +3 -2
- package/dist/validation/value.validation.mjs +76 -54
- package/package.json +52 -52
- package/src/helpers.ts +22 -16
- package/src/models/validation.model.ts +12 -15
- package/src/schematic.ts +106 -16
- package/src/validation/property.validation.ts +5 -7
- package/src/validation/value.validation.ts +113 -73
package/dist/schematic.d.mts
CHANGED
|
@@ -13,10 +13,73 @@ declare class Schematic<Model> {
|
|
|
13
13
|
#private;
|
|
14
14
|
private readonly $schematic;
|
|
15
15
|
constructor(properties: ValidatedProperty[]);
|
|
16
|
+
/**
|
|
17
|
+
* Parse a value according to the schema
|
|
18
|
+
*
|
|
19
|
+
* Returns a deeply cloned version of the value or throws an error for the first property that fails validation
|
|
20
|
+
* @param value Value to parse
|
|
21
|
+
* @param options Validation options
|
|
22
|
+
* @returns Deeply cloned version of the value if it matches the schema, otherwise throws an error
|
|
23
|
+
*/
|
|
24
|
+
get(value: unknown, options: ValidationOptions<'throw'>): Model;
|
|
25
|
+
/**
|
|
26
|
+
* Parse a value according to the schema
|
|
27
|
+
*
|
|
28
|
+
* Returns a deeply cloned version of the value or throws an error for the first property that fails validation
|
|
29
|
+
* @param value Value to parse
|
|
30
|
+
* @param errors Reporting type
|
|
31
|
+
* @returns Deeply cloned version of the value if it matches the schema, otherwise throws an error
|
|
32
|
+
*/
|
|
33
|
+
get(value: unknown, errors: 'throw'): Model;
|
|
34
|
+
/**
|
|
35
|
+
* Parse a value according to the schema
|
|
36
|
+
*
|
|
37
|
+
* 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
|
|
38
|
+
* @param value Value to parse
|
|
39
|
+
* @param options Validation options
|
|
40
|
+
* @returns Result holding deeply cloned value or all validation information
|
|
41
|
+
*/
|
|
42
|
+
get(value: unknown, options: ValidationOptions<'all'>): Result<Model, ValidationInformation[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Parse a value according to the schema
|
|
45
|
+
*
|
|
46
|
+
* 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
|
|
47
|
+
* @param value Value to parse
|
|
48
|
+
* @param errors Reporting type
|
|
49
|
+
* @returns Result holding deeply cloned value or all validation information
|
|
50
|
+
*/
|
|
51
|
+
get(value: unknown, errors: 'all'): Result<Model, ValidationInformation[]>;
|
|
52
|
+
/**
|
|
53
|
+
* Parse a value according to the schema
|
|
54
|
+
*
|
|
55
|
+
* Returns a deeply cloned version of the value or all validation information for the first failing property
|
|
56
|
+
* @param value Value to parse
|
|
57
|
+
* @param options Validation options
|
|
58
|
+
* @returns Result holding deeply cloned value or all validation information
|
|
59
|
+
*/
|
|
60
|
+
get(value: unknown, options: ValidationOptions<'first'>): Result<Model, ValidationInformation>;
|
|
61
|
+
/**
|
|
62
|
+
* Parse a value according to the schema
|
|
63
|
+
*
|
|
64
|
+
* Returns a deeply cloned version of the value or all validation information for the first failing property
|
|
65
|
+
* @param value Value to parse
|
|
66
|
+
* @param errors Reporting type
|
|
67
|
+
* @returns Result holding deeply cloned value or all validation information
|
|
68
|
+
*/
|
|
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 strict Validate if unknown keys are present in the object? _(defaults to `false`)_
|
|
76
|
+
* @returns Deeply cloned value, or `undefined` if it's invalid
|
|
77
|
+
*/
|
|
78
|
+
get(value: unknown, strict?: true): Model | undefined;
|
|
16
79
|
/**
|
|
17
80
|
* Does the value match the schema?
|
|
18
81
|
*
|
|
19
|
-
* 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
|
|
82
|
+
* 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
|
|
20
83
|
* @param value Value to validate
|
|
21
84
|
* @param options Validation options
|
|
22
85
|
* @returns `true` if the value matches the schema, otherwise throws an error
|
|
@@ -25,7 +88,7 @@ declare class Schematic<Model> {
|
|
|
25
88
|
/**
|
|
26
89
|
* Does the value match the schema?
|
|
27
90
|
*
|
|
28
|
-
* 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
|
|
91
|
+
* 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
|
|
29
92
|
* @param value Value to validate
|
|
30
93
|
* @param errors Reporting type
|
|
31
94
|
* @returns `true` if the value matches the schema, otherwise throws an error
|
|
@@ -34,25 +97,25 @@ declare class Schematic<Model> {
|
|
|
34
97
|
/**
|
|
35
98
|
* Does the value match the schema?
|
|
36
99
|
*
|
|
37
|
-
* 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
|
|
100
|
+
* 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
|
|
38
101
|
* @param value Value to validate
|
|
39
102
|
* @param options Validation options
|
|
40
|
-
* @returns `true`
|
|
103
|
+
* @returns Result holding `true` or all validation information
|
|
41
104
|
*/
|
|
42
105
|
is(value: unknown, options: ValidationOptions<'all'>): Result<true, ValidationInformation[]>;
|
|
43
106
|
/**
|
|
44
107
|
* Does the value match the schema?
|
|
45
108
|
*
|
|
46
|
-
* 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
|
|
109
|
+
* 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
|
|
47
110
|
* @param value Value to validate
|
|
48
111
|
* @param errors Reporting type
|
|
49
|
-
* @returns `true`
|
|
112
|
+
* @returns Result holding `true` or all validation information
|
|
50
113
|
*/
|
|
51
114
|
is(value: unknown, errors: 'all'): Result<true, ValidationInformation[]>;
|
|
52
115
|
/**
|
|
53
116
|
* Does the value match the schema?
|
|
54
117
|
*
|
|
55
|
-
* Will validate that the value matches the schema and return a result of `true` or all validation information for the failing property
|
|
118
|
+
* Will validate that the value matches the schema and return a result of `true` or all validation information for the first failing property
|
|
56
119
|
* @param value Value to validate
|
|
57
120
|
* @param options Validation options
|
|
58
121
|
* @returns `true` if the value matches the schema, otherwise `false`
|
|
@@ -61,7 +124,7 @@ declare class Schematic<Model> {
|
|
|
61
124
|
/**
|
|
62
125
|
* Does the value match the schema?
|
|
63
126
|
*
|
|
64
|
-
* Will validate that the value matches the schema and return a result of `true` or all validation information for the failing property
|
|
127
|
+
* Will validate that the value matches the schema and return a result of `true` or all validation information for the first failing property
|
|
65
128
|
* @param value Value to validate
|
|
66
129
|
* @param errors Reporting type
|
|
67
130
|
* @returns `true` if the value matches the schema, otherwise `false`
|
|
@@ -70,7 +133,7 @@ declare class Schematic<Model> {
|
|
|
70
133
|
/**
|
|
71
134
|
* Does the value match the schema?
|
|
72
135
|
*
|
|
73
|
-
* Will validate that the value matches the schema and return `true` or `false`, without any validation information for validation failures
|
|
136
|
+
* Will validate that the value matches the schema and return `true` or `false`, without any validation information for validation failures
|
|
74
137
|
* @param value Value to validate
|
|
75
138
|
* @param strict Validate if unknown keys are present in the object? _(defaults to `false`)_
|
|
76
139
|
* @returns `true` if the value matches the schema, otherwise `false`
|
package/dist/schematic.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { PROPERTY_SCHEMATIC, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE } from "./constants.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { getParameters, isSchematic } from "./helpers.mjs";
|
|
3
3
|
import { SchematicError } from "./models/validation.model.mjs";
|
|
4
4
|
import { getProperties } from "./validation/property.validation.mjs";
|
|
5
5
|
import { validateObject } from "./validation/value.validation.mjs";
|
|
6
6
|
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
7
|
-
import { error } from "@oscarpalmer/atoms/result/misc";
|
|
7
|
+
import { error, ok } from "@oscarpalmer/atoms/result/misc";
|
|
8
8
|
//#region src/schematic.ts
|
|
9
9
|
/**
|
|
10
10
|
* A schematic for validating objects
|
|
@@ -16,14 +16,19 @@ var Schematic = class {
|
|
|
16
16
|
this.#properties = properties;
|
|
17
17
|
schematicProperties.set(this, properties);
|
|
18
18
|
}
|
|
19
|
+
get(value, options) {
|
|
20
|
+
const parameters = getParameters(options);
|
|
21
|
+
const result = validateObject(value, this.#properties, parameters, true);
|
|
22
|
+
if (result == null) return;
|
|
23
|
+
if (!Array.isArray(result)) return parameters.reporting.none ? result : ok(result);
|
|
24
|
+
return error(parameters.reporting.all ? result : result[0]);
|
|
25
|
+
}
|
|
19
26
|
is(value, options) {
|
|
20
|
-
const
|
|
21
|
-
const result = validateObject(value, this.#properties,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (typeof result === "boolean") return result;
|
|
26
|
-
return error(reporting.all ? result : result[0]);
|
|
27
|
+
const parameters = getParameters(options);
|
|
28
|
+
const result = validateObject(value, this.#properties, parameters, false);
|
|
29
|
+
if (result == null) return false;
|
|
30
|
+
if (!Array.isArray(result)) return parameters.reporting.none ? true : ok(true);
|
|
31
|
+
return error(parameters.reporting.all ? result : result[0]);
|
|
27
32
|
}
|
|
28
33
|
};
|
|
29
34
|
function schematic(schema) {
|
|
@@ -20,9 +20,8 @@ function getProperties(original, prefix, fromType) {
|
|
|
20
20
|
const properties = [];
|
|
21
21
|
for (let keyIndex = 0; keyIndex < keysLength; keyIndex += 1) {
|
|
22
22
|
const key = keys[keyIndex];
|
|
23
|
-
const prefixed = join([prefix, key], ".");
|
|
24
23
|
const value = original[key];
|
|
25
|
-
if (value == null) throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE.replace("<>",
|
|
24
|
+
if (value == null) throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE.replace("<>", join([prefix, key], ".")));
|
|
26
25
|
const types = [];
|
|
27
26
|
let required = true;
|
|
28
27
|
let validators = {};
|
|
@@ -34,12 +33,9 @@ function getProperties(original, prefix, fromType) {
|
|
|
34
33
|
} else types.push(...getTypes(key, value, prefix));
|
|
35
34
|
if (!required && !types.includes("undefined")) types.push(TYPE_UNDEFINED);
|
|
36
35
|
properties.push({
|
|
36
|
+
key,
|
|
37
37
|
types,
|
|
38
38
|
validators,
|
|
39
|
-
key: {
|
|
40
|
-
full: prefixed,
|
|
41
|
-
short: key
|
|
42
|
-
},
|
|
43
39
|
required: required && !types.includes("undefined")
|
|
44
40
|
});
|
|
45
41
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ValidatedProperty, ValidationInformation,
|
|
1
|
+
import { ValidatedProperty, ValidationInformation, ValidationParameters } from "../models/validation.model.mjs";
|
|
2
|
+
import { PlainObject } from "@oscarpalmer/atoms/models";
|
|
2
3
|
|
|
3
4
|
//#region src/validation/value.validation.d.ts
|
|
4
|
-
declare function validateObject(obj: unknown, properties: ValidatedProperty[],
|
|
5
|
+
declare function validateObject(obj: unknown, properties: ValidatedProperty[], parameters: ValidationParameters, get: boolean): PlainObject | ValidationInformation[] | undefined;
|
|
5
6
|
//#endregion
|
|
6
7
|
export { validateObject };
|
|
@@ -4,19 +4,23 @@ import { ValidationError } from "../models/validation.model.mjs";
|
|
|
4
4
|
import { schematicProperties } from "../schematic.mjs";
|
|
5
5
|
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
6
6
|
import { join } from "@oscarpalmer/atoms/string";
|
|
7
|
+
import { clone } from "@oscarpalmer/atoms/value/clone";
|
|
7
8
|
//#region src/validation/value.validation.ts
|
|
8
|
-
function validateNamed(
|
|
9
|
+
function validateNamed(name, value, parameters) {
|
|
9
10
|
if (!validators[name](value)) return false;
|
|
10
|
-
const propertyValidators =
|
|
11
|
+
const propertyValidators = parameters.origin.validators[name];
|
|
11
12
|
if (propertyValidators == null || propertyValidators.length === 0) return true;
|
|
12
13
|
const { length } = propertyValidators;
|
|
13
14
|
for (let index = 0; index < length; index += 1) {
|
|
14
15
|
const validator = propertyValidators[index];
|
|
15
16
|
if (!validator(value)) {
|
|
16
|
-
|
|
17
|
+
parameters.information.push({
|
|
17
18
|
value,
|
|
18
|
-
key: {
|
|
19
|
-
|
|
19
|
+
key: {
|
|
20
|
+
full: parameters.prefix,
|
|
21
|
+
short: parameters.origin.key
|
|
22
|
+
},
|
|
23
|
+
message: getInvalidValidatorMessage(parameters.prefix, name, index, length),
|
|
20
24
|
validator
|
|
21
25
|
});
|
|
22
26
|
return false;
|
|
@@ -24,103 +28,121 @@ function validateNamed(property, name, value, validation) {
|
|
|
24
28
|
}
|
|
25
29
|
return true;
|
|
26
30
|
}
|
|
27
|
-
function validateObject(obj, properties,
|
|
31
|
+
function validateObject(obj, properties, parameters, get) {
|
|
28
32
|
if (!isPlainObject(obj)) {
|
|
29
|
-
const key = origin == null ? {
|
|
33
|
+
const key = parameters?.origin == null ? {
|
|
30
34
|
full: "",
|
|
31
35
|
short: ""
|
|
32
|
-
} : {
|
|
36
|
+
} : {
|
|
37
|
+
full: parameters.prefix,
|
|
38
|
+
short: parameters.origin.key
|
|
39
|
+
};
|
|
33
40
|
const information = {
|
|
34
41
|
key,
|
|
35
|
-
message: origin == null ? getInvalidInputMessage(obj) : getInvalidTypeMessage(
|
|
36
|
-
...origin,
|
|
37
|
-
key
|
|
38
|
-
}, obj),
|
|
42
|
+
message: parameters?.origin == null ? getInvalidInputMessage(obj) : getInvalidTypeMessage(key.full, parameters.origin.types, obj),
|
|
39
43
|
value: obj
|
|
40
44
|
};
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
return
|
|
45
|
+
if (parameters.reporting.throw) throw new ValidationError([information]);
|
|
46
|
+
parameters?.information?.push(information);
|
|
47
|
+
return parameters.reporting.none ? void 0 : [information];
|
|
44
48
|
}
|
|
45
|
-
if (
|
|
49
|
+
if (parameters.strict) {
|
|
46
50
|
const objKeys = Object.keys(obj);
|
|
47
|
-
const propertiesKeys = new Set(properties.map((property) => property.key
|
|
51
|
+
const propertiesKeys = new Set(properties.map((property) => property.key));
|
|
48
52
|
const unknownKeys = objKeys.filter((key) => !propertiesKeys.has(key));
|
|
49
53
|
if (unknownKeys.length > 0) {
|
|
50
54
|
const information = {
|
|
51
|
-
key: origin == null ? {
|
|
55
|
+
key: parameters?.origin == null ? {
|
|
52
56
|
full: "",
|
|
53
57
|
short: ""
|
|
54
|
-
} : {
|
|
55
|
-
|
|
58
|
+
} : {
|
|
59
|
+
full: join([parameters.prefix, parameters.origin?.key], "."),
|
|
60
|
+
short: parameters.origin.key
|
|
61
|
+
},
|
|
62
|
+
message: getUnknownKeysMessage(unknownKeys.map((key) => join([parameters?.prefix, key], "."))),
|
|
56
63
|
value: obj
|
|
57
64
|
};
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
return
|
|
65
|
+
if (parameters.reporting.throw) throw new ValidationError([information]);
|
|
66
|
+
parameters?.information?.push(information);
|
|
67
|
+
return parameters.reporting.none ? void 0 : [information];
|
|
61
68
|
}
|
|
62
69
|
}
|
|
63
70
|
const allInformation = [];
|
|
71
|
+
const output = {};
|
|
64
72
|
const propertiesLength = properties.length;
|
|
65
73
|
outer: for (let propertyIndex = 0; propertyIndex < propertiesLength; propertyIndex += 1) {
|
|
66
|
-
|
|
67
|
-
property = {
|
|
68
|
-
...property,
|
|
69
|
-
key: {
|
|
70
|
-
full: join([origin?.key.full, property.key.short], "."),
|
|
71
|
-
short: property.key.short
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
+
const property = properties[propertyIndex];
|
|
74
75
|
const { key, required, types } = property;
|
|
75
|
-
const value = obj[key
|
|
76
|
+
const value = obj[key];
|
|
77
|
+
if (get && value === void 0 && !required) continue;
|
|
76
78
|
if (value === void 0 && required) {
|
|
79
|
+
const prefixedKey = join([parameters.prefix, key], ".");
|
|
77
80
|
const information = {
|
|
78
81
|
value,
|
|
79
|
-
key: {
|
|
80
|
-
|
|
82
|
+
key: {
|
|
83
|
+
full: prefixedKey,
|
|
84
|
+
short: key
|
|
85
|
+
},
|
|
86
|
+
message: getInvalidMissingMessage(prefixedKey, property.types)
|
|
81
87
|
};
|
|
82
|
-
if (
|
|
83
|
-
|
|
84
|
-
if (
|
|
88
|
+
if (parameters.reporting.throw) throw new ValidationError([information]);
|
|
89
|
+
parameters?.information?.push(information);
|
|
90
|
+
if (parameters.reporting.all) {
|
|
85
91
|
allInformation.push(information);
|
|
86
92
|
continue;
|
|
87
93
|
}
|
|
88
|
-
return
|
|
94
|
+
return parameters.reporting.none ? void 0 : [information];
|
|
89
95
|
}
|
|
96
|
+
const prefixedKey = join([parameters.prefix, key], ".");
|
|
90
97
|
const typesLength = types.length;
|
|
91
98
|
const information = [];
|
|
92
99
|
for (let typeIndex = 0; typeIndex < typesLength; typeIndex += 1) {
|
|
93
100
|
const type = types[typeIndex];
|
|
94
|
-
if (validateValue(type,
|
|
101
|
+
if (validateValue(type, value, {
|
|
102
|
+
information,
|
|
103
|
+
output,
|
|
104
|
+
origin: property,
|
|
105
|
+
prefix: prefixedKey,
|
|
106
|
+
reporting: parameters.reporting,
|
|
107
|
+
strict: parameters.strict
|
|
108
|
+
}, get)) {
|
|
109
|
+
if (get) output[key] = clone(value);
|
|
110
|
+
continue outer;
|
|
111
|
+
}
|
|
95
112
|
}
|
|
96
113
|
if (information.length === 0) information.push({
|
|
97
114
|
value,
|
|
98
|
-
key: {
|
|
99
|
-
|
|
115
|
+
key: {
|
|
116
|
+
full: prefixedKey,
|
|
117
|
+
short: key
|
|
118
|
+
},
|
|
119
|
+
message: getInvalidTypeMessage(prefixedKey, property.types, value)
|
|
100
120
|
});
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
if (
|
|
121
|
+
if (parameters.reporting.throw) throw new ValidationError(information);
|
|
122
|
+
parameters?.information?.push(...information);
|
|
123
|
+
if (parameters.reporting.all) {
|
|
104
124
|
allInformation.push(...information);
|
|
105
125
|
continue;
|
|
106
126
|
}
|
|
107
|
-
return
|
|
127
|
+
return parameters.reporting.none ? void 0 : information;
|
|
108
128
|
}
|
|
109
|
-
|
|
129
|
+
if (get) if (parameters.origin == null) parameters.output = output;
|
|
130
|
+
else parameters.output[parameters.origin.key] = output;
|
|
131
|
+
return parameters.reporting.none || allInformation.length === 0 ? parameters.output : allInformation;
|
|
110
132
|
}
|
|
111
|
-
function validateSchematic(
|
|
112
|
-
const result = validateObject(value, schematicProperties.get(schematic),
|
|
113
|
-
return
|
|
133
|
+
function validateSchematic(schematic, value, parameters, get) {
|
|
134
|
+
const result = validateObject(value, schematicProperties.get(schematic), parameters, get);
|
|
135
|
+
return result == null || Array.isArray(result) ? false : true;
|
|
114
136
|
}
|
|
115
|
-
function validateValue(type,
|
|
137
|
+
function validateValue(type, value, parameters, get) {
|
|
116
138
|
switch (true) {
|
|
117
139
|
case typeof type === "function": return type(value);
|
|
118
140
|
case Array.isArray(type): {
|
|
119
|
-
const
|
|
120
|
-
return
|
|
141
|
+
const result = validateObject(value, type, parameters, get);
|
|
142
|
+
return result == null || Array.isArray(result) ? false : true;
|
|
121
143
|
}
|
|
122
|
-
case isSchematic(type): return validateSchematic(
|
|
123
|
-
default: return validateNamed(
|
|
144
|
+
case isSchematic(type): return validateSchematic(type, value, parameters, get);
|
|
145
|
+
default: return validateNamed(type, value, parameters);
|
|
124
146
|
}
|
|
125
147
|
}
|
|
126
148
|
const validators = {
|
package/package.json
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
2
|
+
"name": "@oscarpalmer/jhunal",
|
|
3
|
+
"version": "0.21.0",
|
|
4
|
+
"description": "Flies free beneath the glistening moons…",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"schema",
|
|
7
|
+
"validation"
|
|
8
|
+
],
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"author": {
|
|
11
|
+
"name": "Oscar Palmér",
|
|
12
|
+
"url": "https://oscarpalmer.se"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/oscarpalmer/jhunal.git"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"src"
|
|
21
|
+
],
|
|
22
|
+
"type": "module",
|
|
23
|
+
"module": "./dist/index.mjs",
|
|
24
|
+
"types": "./dist/index.d.mts",
|
|
25
|
+
"exports": {
|
|
26
|
+
"./package.json": "./package.json",
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.mts",
|
|
29
|
+
"default": "./dist/index.mjs"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "npx vp pack && npm run tsdown:build",
|
|
34
|
+
"tsdown:build": "npx tsdown -c ./tsdown.config.ts",
|
|
35
|
+
"tsdown:watch": "npx tsdown -c ./tsdown.config.ts --watch",
|
|
36
|
+
"test": "npx vp test run --coverage",
|
|
37
|
+
"test:leak": "npx vp test run --detect-async-leaks --coverage",
|
|
38
|
+
"watch": "npx vite build --watch"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@oscarpalmer/atoms": "^0.170"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^25.5",
|
|
45
|
+
"@vitest/coverage-istanbul": "^4.1",
|
|
46
|
+
"jsdom": "^29.0",
|
|
47
|
+
"tsdown": "^0.21",
|
|
48
|
+
"typescript": "^5.9",
|
|
49
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
|
|
50
|
+
"vite-plus": "latest",
|
|
51
|
+
"vitest": "npm:@voidzero-dev/vite-plus-test@latest"
|
|
52
|
+
},
|
|
53
|
+
"packageManager": "npm@11.11.1"
|
|
54
54
|
}
|
package/src/helpers.ts
CHANGED
|
@@ -32,6 +32,7 @@ import type {
|
|
|
32
32
|
ReportingType,
|
|
33
33
|
ValidatedProperty,
|
|
34
34
|
ValidatedPropertyType,
|
|
35
|
+
ValidationParameters,
|
|
35
36
|
} from './models/validation.model';
|
|
36
37
|
import type {Schematic} from './schematic';
|
|
37
38
|
|
|
@@ -39,36 +40,34 @@ export function getInvalidInputMessage(actual: unknown): string {
|
|
|
39
40
|
return VALIDATION_MESSAGE_INVALID_INPUT.replace(TEMPLATE_PATTERN, getValueType(actual));
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
export function getInvalidMissingMessage(
|
|
43
|
-
let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace(
|
|
44
|
-
TEMPLATE_PATTERN,
|
|
45
|
-
renderTypes(property.types),
|
|
46
|
-
);
|
|
43
|
+
export function getInvalidMissingMessage(key: string, types: ValidatedPropertyType[]): string {
|
|
44
|
+
let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace(TEMPLATE_PATTERN, renderTypes(types));
|
|
47
45
|
|
|
48
|
-
message = message.replace(TEMPLATE_PATTERN,
|
|
46
|
+
message = message.replace(TEMPLATE_PATTERN, key);
|
|
49
47
|
|
|
50
48
|
return message;
|
|
51
49
|
}
|
|
52
50
|
|
|
53
|
-
export function getInvalidTypeMessage(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
export function getInvalidTypeMessage(
|
|
52
|
+
key: string,
|
|
53
|
+
types: ValidatedPropertyType[],
|
|
54
|
+
actual: unknown,
|
|
55
|
+
): string {
|
|
56
|
+
let message = VALIDATION_MESSAGE_INVALID_TYPE.replace(TEMPLATE_PATTERN, renderTypes(types));
|
|
58
57
|
|
|
59
|
-
message = message.replace(TEMPLATE_PATTERN,
|
|
58
|
+
message = message.replace(TEMPLATE_PATTERN, key);
|
|
60
59
|
message = message.replace(TEMPLATE_PATTERN, getValueType(actual));
|
|
61
60
|
|
|
62
61
|
return message;
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
export function getInvalidValidatorMessage(
|
|
66
|
-
|
|
65
|
+
key: string,
|
|
67
66
|
type: ValueName,
|
|
68
67
|
index: number,
|
|
69
68
|
length: number,
|
|
70
69
|
): string {
|
|
71
|
-
let message = VALIDATION_MESSAGE_INVALID_VALUE.replace(TEMPLATE_PATTERN,
|
|
70
|
+
let message = VALIDATION_MESSAGE_INVALID_VALUE.replace(TEMPLATE_PATTERN, key);
|
|
72
71
|
|
|
73
72
|
message = message.replace(TEMPLATE_PATTERN, type);
|
|
74
73
|
|
|
@@ -79,9 +78,10 @@ export function getInvalidValidatorMessage(
|
|
|
79
78
|
return message;
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
export function
|
|
81
|
+
export function getParameters(input?: unknown): ValidationParameters {
|
|
83
82
|
if (typeof input === 'boolean') {
|
|
84
83
|
return {
|
|
84
|
+
output: {},
|
|
85
85
|
reporting: getReporting(REPORTING_NONE),
|
|
86
86
|
strict: input,
|
|
87
87
|
};
|
|
@@ -89,6 +89,7 @@ export function getOptions(input: unknown) {
|
|
|
89
89
|
|
|
90
90
|
if (REPORTING_TYPES.has(input as ReportingType)) {
|
|
91
91
|
return {
|
|
92
|
+
output: {},
|
|
92
93
|
reporting: getReporting(input as ReportingType),
|
|
93
94
|
strict: false,
|
|
94
95
|
};
|
|
@@ -97,6 +98,7 @@ export function getOptions(input: unknown) {
|
|
|
97
98
|
const options = isPlainObject(input) ? input : {};
|
|
98
99
|
|
|
99
100
|
return {
|
|
101
|
+
output: {},
|
|
100
102
|
reporting: getReporting(options.errors),
|
|
101
103
|
strict: typeof options.strict === 'boolean' ? options.strict : false,
|
|
102
104
|
};
|
|
@@ -196,7 +198,11 @@ export function isSchematic(value: unknown): value is Schematic<never> {
|
|
|
196
198
|
}
|
|
197
199
|
|
|
198
200
|
function renderKeys(keys: string[]): string {
|
|
199
|
-
return renderParts(
|
|
201
|
+
return renderParts(
|
|
202
|
+
keys.map(key => `'${key}'`),
|
|
203
|
+
CONJUNCTION_AND,
|
|
204
|
+
CONJUNCTION_AND_COMMA,
|
|
205
|
+
);
|
|
200
206
|
}
|
|
201
207
|
|
|
202
208
|
function renderParts(parts: string[], delimiterShort: string, delimiterLong: string): string {
|