@aeriajs/validation 0.0.123 → 0.0.125
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/validate.d.ts +1 -0
- package/dist/validate.js +59 -52
- package/dist/validate.mjs +56 -49
- package/package.json +2 -2
package/dist/validate.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { JsonSchema, Property, InferSchema, Description, PropertyValidation
|
|
|
2
2
|
import { Result } from '@aeriajs/types';
|
|
3
3
|
import { ValidationErrorCode } from '@aeriajs/types';
|
|
4
4
|
export type ValidateOptions = {
|
|
5
|
+
tolerateExtraneous?: boolean;
|
|
5
6
|
filterOutExtraneous?: boolean;
|
|
6
7
|
throwOnError?: boolean;
|
|
7
8
|
coerce?: boolean;
|
package/dist/validate.js
CHANGED
|
@@ -12,11 +12,10 @@ const getValueType = (value) => {
|
|
|
12
12
|
const getPropertyType = (property) => {
|
|
13
13
|
if ('type' in property) {
|
|
14
14
|
if ('format' in property && property.format) {
|
|
15
|
-
|
|
16
|
-
'date'
|
|
17
|
-
'date-time'
|
|
18
|
-
|
|
19
|
-
return 'datetime';
|
|
15
|
+
switch (property.format) {
|
|
16
|
+
case 'date':
|
|
17
|
+
case 'date-time':
|
|
18
|
+
return 'datetime';
|
|
20
19
|
}
|
|
21
20
|
}
|
|
22
21
|
return property.type;
|
|
@@ -24,6 +23,9 @@ const getPropertyType = (property) => {
|
|
|
24
23
|
if ('enum' in property) {
|
|
25
24
|
return typeof property.enum[0];
|
|
26
25
|
}
|
|
26
|
+
if ('const' in property) {
|
|
27
|
+
return typeof property.const;
|
|
28
|
+
}
|
|
27
29
|
if ('$ref' in property
|
|
28
30
|
|| 'properties' in property
|
|
29
31
|
|| 'additionalProperties' in property) {
|
|
@@ -41,54 +43,38 @@ const makeValidationError = (error) => {
|
|
|
41
43
|
};
|
|
42
44
|
exports.makeValidationError = makeValidationError;
|
|
43
45
|
const validateProperty = (propName, what, property, options = {}) => {
|
|
44
|
-
const { filterOutExtraneous, coerce } = options;
|
|
45
46
|
if (!property) {
|
|
46
47
|
if (options.parentProperty && 'additionalProperties' in options.parentProperty && options.parentProperty.additionalProperties) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (filterOutExtraneous) {
|
|
50
|
-
return types_1.Result.result(undefined);
|
|
51
|
-
}
|
|
48
|
+
if (options.filterOutExtraneous) {
|
|
49
|
+
return types_1.Result.result(undefined);
|
|
52
50
|
}
|
|
53
51
|
return types_1.Result.result(what);
|
|
54
52
|
}
|
|
53
|
+
if (options.tolerateExtraneous) {
|
|
54
|
+
return types_1.Result.result(undefined);
|
|
55
|
+
}
|
|
55
56
|
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.Extraneous));
|
|
56
57
|
}
|
|
57
58
|
if (what === null || what === undefined) {
|
|
58
59
|
return types_1.Result.result(what);
|
|
59
60
|
}
|
|
60
|
-
if ('properties' in property) {
|
|
61
|
-
return (0, exports.validate)(what, property, options);
|
|
62
|
-
}
|
|
63
|
-
if ('const' in property) {
|
|
64
|
-
if (what !== property.const) {
|
|
65
|
-
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.Unmatching, {
|
|
66
|
-
expected: property.const,
|
|
67
|
-
got: what,
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
|
-
return types_1.Result.result(what);
|
|
71
|
-
}
|
|
72
|
-
if ('enum' in property && property.enum.length === 0) {
|
|
73
|
-
return types_1.Result.result(what);
|
|
74
|
-
}
|
|
75
61
|
if ('getter' in property) {
|
|
76
62
|
return types_1.Result.result(undefined);
|
|
77
63
|
}
|
|
78
64
|
const expectedType = getPropertyType(property);
|
|
79
65
|
const actualType = getValueType(what);
|
|
80
66
|
if (actualType !== expectedType
|
|
81
|
-
&& !('items' in property && actualType === 'array')
|
|
67
|
+
&& !(('items' in property || 'enum' in property) && actualType === 'array')
|
|
82
68
|
&& !(actualType === 'number' && expectedType === 'integer')) {
|
|
83
69
|
if (expectedType === 'datetime' && what instanceof Date) {
|
|
84
70
|
return types_1.Result.result(what);
|
|
85
71
|
}
|
|
86
72
|
if ('$ref' in property && typeof what === 'string') {
|
|
87
|
-
if (/^[0-9a-
|
|
73
|
+
if (/^[0-9a-f]{24}$/.test(what)) {
|
|
88
74
|
return types_1.Result.result(what);
|
|
89
75
|
}
|
|
90
76
|
}
|
|
91
|
-
if (coerce) {
|
|
77
|
+
if (options.coerce) {
|
|
92
78
|
if (expectedType === 'number' && typeof what === 'string') {
|
|
93
79
|
const coerced = parseFloat(what);
|
|
94
80
|
if (!isNaN(coerced)) {
|
|
@@ -110,6 +96,21 @@ const validateProperty = (propName, what, property, options = {}) => {
|
|
|
110
96
|
got: actualType,
|
|
111
97
|
}));
|
|
112
98
|
}
|
|
99
|
+
if ('properties' in property) {
|
|
100
|
+
return (0, exports.validate)(what, property, options);
|
|
101
|
+
}
|
|
102
|
+
if ('enum' in property && property.enum.length === 0) {
|
|
103
|
+
return types_1.Result.result(what);
|
|
104
|
+
}
|
|
105
|
+
if ('const' in property) {
|
|
106
|
+
if (what !== property.const) {
|
|
107
|
+
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.Unmatching, {
|
|
108
|
+
expected: property.const,
|
|
109
|
+
got: what,
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
return types_1.Result.result(what);
|
|
113
|
+
}
|
|
113
114
|
if ('items' in property) {
|
|
114
115
|
if (!Array.isArray(what)) {
|
|
115
116
|
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.Unmatching, {
|
|
@@ -141,29 +142,32 @@ const validateProperty = (propName, what, property, options = {}) => {
|
|
|
141
142
|
}
|
|
142
143
|
}
|
|
143
144
|
else if ('type' in property) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
145
|
+
switch (property.type) {
|
|
146
|
+
case 'number':
|
|
147
|
+
case 'integer': {
|
|
148
|
+
if (typeof what !== 'number') {
|
|
149
|
+
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.Unmatching, {
|
|
150
|
+
expected: expectedType,
|
|
151
|
+
got: actualType,
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
if (property.type === 'integer') {
|
|
155
|
+
if (!Number.isInteger(what)) {
|
|
156
|
+
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.NumericConstraint, {
|
|
157
|
+
expected: 'integer',
|
|
158
|
+
got: 'invalid_number',
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if ((property.maximum && property.maximum < what)
|
|
163
|
+
|| (property.minimum && property.minimum > what)
|
|
164
|
+
|| (property.exclusiveMaximum && property.exclusiveMaximum <= what)
|
|
165
|
+
|| (property.exclusiveMinimum && property.exclusiveMinimum >= what)) {
|
|
166
|
+
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.NumericConstraint, {
|
|
167
|
+
expected: 'number',
|
|
168
|
+
got: 'invalid_number',
|
|
169
|
+
}));
|
|
170
|
+
}
|
|
167
171
|
}
|
|
168
172
|
}
|
|
169
173
|
}
|
|
@@ -212,6 +216,9 @@ const validate = (what, schema, options = {}) => {
|
|
|
212
216
|
}
|
|
213
217
|
const wholenessError = (0, exports.validateWholeness)(what, schema);
|
|
214
218
|
if (wholenessError) {
|
|
219
|
+
if (options.throwOnError) {
|
|
220
|
+
throw new Error(types_2.ValidationErrorCode.MissingProperties);
|
|
221
|
+
}
|
|
215
222
|
return types_1.Result.error(wholenessError);
|
|
216
223
|
}
|
|
217
224
|
const errors = {};
|
package/dist/validate.mjs
CHANGED
|
@@ -8,11 +8,10 @@ const getValueType = (value) => {
|
|
|
8
8
|
const getPropertyType = (property) => {
|
|
9
9
|
if ("type" in property) {
|
|
10
10
|
if ("format" in property && property.format) {
|
|
11
|
-
|
|
12
|
-
"date"
|
|
13
|
-
"date-time"
|
|
14
|
-
|
|
15
|
-
return "datetime";
|
|
11
|
+
switch (property.format) {
|
|
12
|
+
case "date":
|
|
13
|
+
case "date-time":
|
|
14
|
+
return "datetime";
|
|
16
15
|
}
|
|
17
16
|
}
|
|
18
17
|
return property.type;
|
|
@@ -20,6 +19,9 @@ const getPropertyType = (property) => {
|
|
|
20
19
|
if ("enum" in property) {
|
|
21
20
|
return typeof property.enum[0];
|
|
22
21
|
}
|
|
22
|
+
if ("const" in property) {
|
|
23
|
+
return typeof property.const;
|
|
24
|
+
}
|
|
23
25
|
if ("$ref" in property || "properties" in property || "additionalProperties" in property) {
|
|
24
26
|
return "object";
|
|
25
27
|
}
|
|
@@ -34,52 +36,36 @@ export const makeValidationError = (error) => {
|
|
|
34
36
|
return error;
|
|
35
37
|
};
|
|
36
38
|
export const validateProperty = (propName, what, property, options = {}) => {
|
|
37
|
-
const { filterOutExtraneous, coerce } = options;
|
|
38
39
|
if (!property) {
|
|
39
40
|
if (options.parentProperty && "additionalProperties" in options.parentProperty && options.parentProperty.additionalProperties) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (filterOutExtraneous) {
|
|
43
|
-
return Result.result(void 0);
|
|
44
|
-
}
|
|
41
|
+
if (options.filterOutExtraneous) {
|
|
42
|
+
return Result.result(void 0);
|
|
45
43
|
}
|
|
46
44
|
return Result.result(what);
|
|
47
45
|
}
|
|
46
|
+
if (options.tolerateExtraneous) {
|
|
47
|
+
return Result.result(void 0);
|
|
48
|
+
}
|
|
48
49
|
return Result.error(makePropertyError(PropertyValidationErrorCode.Extraneous));
|
|
49
50
|
}
|
|
50
51
|
if (what === null || what === void 0) {
|
|
51
52
|
return Result.result(what);
|
|
52
53
|
}
|
|
53
|
-
if ("properties" in property) {
|
|
54
|
-
return validate(what, property, options);
|
|
55
|
-
}
|
|
56
|
-
if ("const" in property) {
|
|
57
|
-
if (what !== property.const) {
|
|
58
|
-
return Result.error(makePropertyError(PropertyValidationErrorCode.Unmatching, {
|
|
59
|
-
expected: property.const,
|
|
60
|
-
got: what
|
|
61
|
-
}));
|
|
62
|
-
}
|
|
63
|
-
return Result.result(what);
|
|
64
|
-
}
|
|
65
|
-
if ("enum" in property && property.enum.length === 0) {
|
|
66
|
-
return Result.result(what);
|
|
67
|
-
}
|
|
68
54
|
if ("getter" in property) {
|
|
69
55
|
return Result.result(void 0);
|
|
70
56
|
}
|
|
71
57
|
const expectedType = getPropertyType(property);
|
|
72
58
|
const actualType = getValueType(what);
|
|
73
|
-
if (actualType !== expectedType && !("items" in property && actualType === "array") && !(actualType === "number" && expectedType === "integer")) {
|
|
59
|
+
if (actualType !== expectedType && !(("items" in property || "enum" in property) && actualType === "array") && !(actualType === "number" && expectedType === "integer")) {
|
|
74
60
|
if (expectedType === "datetime" && what instanceof Date) {
|
|
75
61
|
return Result.result(what);
|
|
76
62
|
}
|
|
77
63
|
if ("$ref" in property && typeof what === "string") {
|
|
78
|
-
if (/^[0-9a-
|
|
64
|
+
if (/^[0-9a-f]{24}$/.test(what)) {
|
|
79
65
|
return Result.result(what);
|
|
80
66
|
}
|
|
81
67
|
}
|
|
82
|
-
if (coerce) {
|
|
68
|
+
if (options.coerce) {
|
|
83
69
|
if (expectedType === "number" && typeof what === "string") {
|
|
84
70
|
const coerced = parseFloat(what);
|
|
85
71
|
if (!isNaN(coerced)) {
|
|
@@ -101,6 +87,21 @@ export const validateProperty = (propName, what, property, options = {}) => {
|
|
|
101
87
|
got: actualType
|
|
102
88
|
}));
|
|
103
89
|
}
|
|
90
|
+
if ("properties" in property) {
|
|
91
|
+
return validate(what, property, options);
|
|
92
|
+
}
|
|
93
|
+
if ("enum" in property && property.enum.length === 0) {
|
|
94
|
+
return Result.result(what);
|
|
95
|
+
}
|
|
96
|
+
if ("const" in property) {
|
|
97
|
+
if (what !== property.const) {
|
|
98
|
+
return Result.error(makePropertyError(PropertyValidationErrorCode.Unmatching, {
|
|
99
|
+
expected: property.const,
|
|
100
|
+
got: what
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
return Result.result(what);
|
|
104
|
+
}
|
|
104
105
|
if ("items" in property) {
|
|
105
106
|
if (!Array.isArray(what)) {
|
|
106
107
|
return Result.error(makePropertyError(PropertyValidationErrorCode.Unmatching, {
|
|
@@ -131,26 +132,29 @@ export const validateProperty = (propName, what, property, options = {}) => {
|
|
|
131
132
|
i++;
|
|
132
133
|
}
|
|
133
134
|
} else if ("type" in property) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
135
|
+
switch (property.type) {
|
|
136
|
+
case "number":
|
|
137
|
+
case "integer": {
|
|
138
|
+
if (typeof what !== "number") {
|
|
139
|
+
return Result.error(makePropertyError(PropertyValidationErrorCode.Unmatching, {
|
|
140
|
+
expected: expectedType,
|
|
141
|
+
got: actualType
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
144
|
+
if (property.type === "integer") {
|
|
145
|
+
if (!Number.isInteger(what)) {
|
|
146
|
+
return Result.error(makePropertyError(PropertyValidationErrorCode.NumericConstraint, {
|
|
147
|
+
expected: "integer",
|
|
148
|
+
got: "invalid_number"
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (property.maximum && property.maximum < what || property.minimum && property.minimum > what || property.exclusiveMaximum && property.exclusiveMaximum <= what || property.exclusiveMinimum && property.exclusiveMinimum >= what) {
|
|
153
|
+
return Result.error(makePropertyError(PropertyValidationErrorCode.NumericConstraint, {
|
|
154
|
+
expected: "number",
|
|
155
|
+
got: "invalid_number"
|
|
156
|
+
}));
|
|
157
|
+
}
|
|
154
158
|
}
|
|
155
159
|
}
|
|
156
160
|
} else if ("enum" in property) {
|
|
@@ -191,6 +195,9 @@ export const validate = (what, schema, options = {}) => {
|
|
|
191
195
|
}
|
|
192
196
|
const wholenessError = validateWholeness(what, schema);
|
|
193
197
|
if (wholenessError) {
|
|
198
|
+
if (options.throwOnError) {
|
|
199
|
+
throw new Error(ValidationErrorCode.MissingProperties);
|
|
200
|
+
}
|
|
194
201
|
return Result.error(wholenessError);
|
|
195
202
|
}
|
|
196
203
|
const errors = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aeriajs/validation",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.125",
|
|
4
4
|
"description": "## Installation",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@aeriajs/types": "link:../types"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
|
-
"@aeriajs/common": "^0.0.
|
|
29
|
+
"@aeriajs/common": "^0.0.120",
|
|
30
30
|
"@aeriajs/types": "^0.0.102",
|
|
31
31
|
"mongodb": "^6.5.0"
|
|
32
32
|
},
|