@aeriajs/validation 0.0.125 → 0.0.126
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 -2
- package/dist/validate.js +65 -70
- package/dist/validate.mjs +66 -72
- package/package.json +1 -1
package/dist/validate.d.ts
CHANGED
|
@@ -3,13 +3,12 @@ import { Result } from '@aeriajs/types';
|
|
|
3
3
|
import { ValidationErrorCode } from '@aeriajs/types';
|
|
4
4
|
export type ValidateOptions = {
|
|
5
5
|
tolerateExtraneous?: boolean;
|
|
6
|
-
filterOutExtraneous?: boolean;
|
|
7
6
|
throwOnError?: boolean;
|
|
8
7
|
coerce?: boolean;
|
|
9
8
|
parentProperty?: Omit<Description, '$id'> | Property;
|
|
10
9
|
};
|
|
11
10
|
export declare const makeValidationError: <TValidationError extends ValidationError>(error: TValidationError) => TValidationError;
|
|
12
|
-
export declare const validateProperty: <TWhat>(
|
|
11
|
+
export declare const validateProperty: <TWhat>(what: TWhat, property: Property | undefined, options?: ValidateOptions) => Result.Either<PropertyValidationError | ValidationError, unknown>;
|
|
13
12
|
export declare const validateWholeness: (what: Record<string, unknown>, schema: Omit<JsonSchema, "$id">) => {
|
|
14
13
|
code: ValidationErrorCode.MissingProperties;
|
|
15
14
|
errors: {
|
package/dist/validate.js
CHANGED
|
@@ -26,9 +26,9 @@ const getPropertyType = (property) => {
|
|
|
26
26
|
if ('const' in property) {
|
|
27
27
|
return typeof property.const;
|
|
28
28
|
}
|
|
29
|
-
if ('
|
|
30
|
-
|| '
|
|
31
|
-
|| '
|
|
29
|
+
if ('properties' in property
|
|
30
|
+
|| 'additionalProperties' in property
|
|
31
|
+
|| '$ref' in property) {
|
|
32
32
|
return 'object';
|
|
33
33
|
}
|
|
34
34
|
};
|
|
@@ -42,13 +42,13 @@ const makeValidationError = (error) => {
|
|
|
42
42
|
return error;
|
|
43
43
|
};
|
|
44
44
|
exports.makeValidationError = makeValidationError;
|
|
45
|
-
const validateProperty = (
|
|
45
|
+
const validateProperty = (what, property, options = {}) => {
|
|
46
46
|
if (!property) {
|
|
47
47
|
if (options.parentProperty && 'additionalProperties' in options.parentProperty && options.parentProperty.additionalProperties) {
|
|
48
|
-
if (options.
|
|
49
|
-
return types_1.Result.result(
|
|
48
|
+
if (typeof options.parentProperty.additionalProperties === 'boolean') {
|
|
49
|
+
return types_1.Result.result(what);
|
|
50
50
|
}
|
|
51
|
-
return
|
|
51
|
+
return (0, exports.validateProperty)(what, options.parentProperty.additionalProperties);
|
|
52
52
|
}
|
|
53
53
|
if (options.tolerateExtraneous) {
|
|
54
54
|
return types_1.Result.result(undefined);
|
|
@@ -64,7 +64,6 @@ const validateProperty = (propName, what, property, options = {}) => {
|
|
|
64
64
|
const expectedType = getPropertyType(property);
|
|
65
65
|
const actualType = getValueType(what);
|
|
66
66
|
if (actualType !== expectedType
|
|
67
|
-
&& !(('items' in property || 'enum' in property) && actualType === 'array')
|
|
68
67
|
&& !(actualType === 'number' && expectedType === 'integer')) {
|
|
69
68
|
if (expectedType === 'datetime' && what instanceof Date) {
|
|
70
69
|
return types_1.Result.result(what);
|
|
@@ -96,89 +95,85 @@ const validateProperty = (propName, what, property, options = {}) => {
|
|
|
96
95
|
got: actualType,
|
|
97
96
|
}));
|
|
98
97
|
}
|
|
99
|
-
if ('
|
|
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
|
-
}
|
|
114
|
-
if ('items' in property) {
|
|
115
|
-
if (!Array.isArray(what)) {
|
|
116
|
-
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.Unmatching, {
|
|
117
|
-
expected: expectedType,
|
|
118
|
-
got: actualType,
|
|
119
|
-
}));
|
|
120
|
-
}
|
|
121
|
-
if (property.minItems) {
|
|
122
|
-
if (what.length < property.minItems) {
|
|
123
|
-
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.MoreItemsExpected));
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if (property.maxItems) {
|
|
127
|
-
if (what.length > property.maxItems) {
|
|
128
|
-
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.LessItemsExpected));
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
let i = 0;
|
|
132
|
-
for (const elem of what) {
|
|
133
|
-
const { error } = (0, exports.validateProperty)(propName, elem, property.items, options);
|
|
134
|
-
if (error) {
|
|
135
|
-
if ('errors' in error) {
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
138
|
-
error.index = i;
|
|
139
|
-
return types_1.Result.error(error);
|
|
140
|
-
}
|
|
141
|
-
i++;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
else if ('type' in property) {
|
|
98
|
+
if ('type' in property) {
|
|
145
99
|
switch (property.type) {
|
|
146
|
-
case 'number':
|
|
147
100
|
case 'integer': {
|
|
101
|
+
if (!Number.isInteger(what)) {
|
|
102
|
+
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.NumericConstraint, {
|
|
103
|
+
expected: 'integer',
|
|
104
|
+
got: 'invalid_number',
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
case 'number': {
|
|
148
109
|
if (typeof what !== 'number') {
|
|
149
110
|
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.Unmatching, {
|
|
150
111
|
expected: expectedType,
|
|
151
112
|
got: actualType,
|
|
152
113
|
}));
|
|
153
114
|
}
|
|
154
|
-
if (property.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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)) {
|
|
115
|
+
if ((typeof property.maximum === 'number' && property.maximum < what)
|
|
116
|
+
|| (typeof property.minimum === 'number' && property.minimum > what)
|
|
117
|
+
|| (typeof property.exclusiveMaximum === 'number' && property.exclusiveMaximum <= what)
|
|
118
|
+
|| (typeof property.exclusiveMinimum === 'number' && property.exclusiveMinimum >= what)) {
|
|
166
119
|
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.NumericConstraint, {
|
|
167
120
|
expected: 'number',
|
|
168
121
|
got: 'invalid_number',
|
|
169
122
|
}));
|
|
170
123
|
}
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
case 'object': {
|
|
127
|
+
return (0, exports.validate)(what, property, options);
|
|
128
|
+
}
|
|
129
|
+
case 'array': {
|
|
130
|
+
if (!Array.isArray(what)) {
|
|
131
|
+
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.Unmatching, {
|
|
132
|
+
expected: expectedType,
|
|
133
|
+
got: actualType,
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
if (property.minItems) {
|
|
137
|
+
if (what.length < property.minItems) {
|
|
138
|
+
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.MoreItemsExpected));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (property.maxItems) {
|
|
142
|
+
if (what.length > property.maxItems) {
|
|
143
|
+
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.LessItemsExpected));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
let i = 0;
|
|
147
|
+
for (const elem of what) {
|
|
148
|
+
const { error } = (0, exports.validateProperty)(elem, property.items, options);
|
|
149
|
+
if (error) {
|
|
150
|
+
if ('errors' in error) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
error.index = i;
|
|
154
|
+
return types_1.Result.error(error);
|
|
155
|
+
}
|
|
156
|
+
i++;
|
|
157
|
+
}
|
|
171
158
|
}
|
|
172
159
|
}
|
|
173
160
|
}
|
|
174
161
|
else if ('enum' in property) {
|
|
175
|
-
if (!property.enum.includes(what)) {
|
|
162
|
+
if (!property.enum.includes(what) && property.enum.length === 0) {
|
|
176
163
|
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.ExtraneousElement, {
|
|
177
164
|
expected: property.enum,
|
|
178
165
|
got: what,
|
|
179
166
|
}));
|
|
180
167
|
}
|
|
181
168
|
}
|
|
169
|
+
else if ('const' in property) {
|
|
170
|
+
if (what !== property.const) {
|
|
171
|
+
return types_1.Result.error(makePropertyError(types_2.PropertyValidationErrorCode.Unmatching, {
|
|
172
|
+
expected: property.const,
|
|
173
|
+
got: what,
|
|
174
|
+
}));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
182
177
|
return types_1.Result.result(what);
|
|
183
178
|
};
|
|
184
179
|
exports.validateProperty = validateProperty;
|
|
@@ -209,7 +204,7 @@ const validate = (what, schema, options = {}) => {
|
|
|
209
204
|
}));
|
|
210
205
|
}
|
|
211
206
|
if (!('properties' in schema)) {
|
|
212
|
-
const { error } = (0, exports.validateProperty)(
|
|
207
|
+
const { error } = (0, exports.validateProperty)(what, schema);
|
|
213
208
|
return error
|
|
214
209
|
? types_1.Result.error(error)
|
|
215
210
|
: types_1.Result.result(what);
|
|
@@ -224,7 +219,7 @@ const validate = (what, schema, options = {}) => {
|
|
|
224
219
|
const errors = {};
|
|
225
220
|
const resultCopy = {};
|
|
226
221
|
for (const propName in what) {
|
|
227
|
-
const { error, result: parsed } = (0, exports.validateProperty)(
|
|
222
|
+
const { error, result: parsed } = (0, exports.validateProperty)(what[propName], schema.properties[propName], {
|
|
228
223
|
...options,
|
|
229
224
|
parentProperty: schema,
|
|
230
225
|
});
|
package/dist/validate.mjs
CHANGED
|
@@ -22,7 +22,7 @@ const getPropertyType = (property) => {
|
|
|
22
22
|
if ("const" in property) {
|
|
23
23
|
return typeof property.const;
|
|
24
24
|
}
|
|
25
|
-
if ("
|
|
25
|
+
if ("properties" in property || "additionalProperties" in property || "$ref" in property) {
|
|
26
26
|
return "object";
|
|
27
27
|
}
|
|
28
28
|
};
|
|
@@ -35,13 +35,16 @@ const makePropertyError = (type, details) => {
|
|
|
35
35
|
export const makeValidationError = (error) => {
|
|
36
36
|
return error;
|
|
37
37
|
};
|
|
38
|
-
export const validateProperty = (
|
|
38
|
+
export const validateProperty = (what, property, options = {}) => {
|
|
39
39
|
if (!property) {
|
|
40
40
|
if (options.parentProperty && "additionalProperties" in options.parentProperty && options.parentProperty.additionalProperties) {
|
|
41
|
-
if (options.
|
|
42
|
-
return Result.result(
|
|
41
|
+
if (typeof options.parentProperty.additionalProperties === "boolean") {
|
|
42
|
+
return Result.result(what);
|
|
43
43
|
}
|
|
44
|
-
return
|
|
44
|
+
return validateProperty(
|
|
45
|
+
what,
|
|
46
|
+
options.parentProperty.additionalProperties
|
|
47
|
+
);
|
|
45
48
|
}
|
|
46
49
|
if (options.tolerateExtraneous) {
|
|
47
50
|
return Result.result(void 0);
|
|
@@ -56,7 +59,7 @@ export const validateProperty = (propName, what, property, options = {}) => {
|
|
|
56
59
|
}
|
|
57
60
|
const expectedType = getPropertyType(property);
|
|
58
61
|
const actualType = getValueType(what);
|
|
59
|
-
if (actualType !== expectedType && !(
|
|
62
|
+
if (actualType !== expectedType && !(actualType === "number" && expectedType === "integer")) {
|
|
60
63
|
if (expectedType === "datetime" && what instanceof Date) {
|
|
61
64
|
return Result.result(what);
|
|
62
65
|
}
|
|
@@ -87,83 +90,79 @@ export const validateProperty = (propName, what, property, options = {}) => {
|
|
|
87
90
|
got: actualType
|
|
88
91
|
}));
|
|
89
92
|
}
|
|
90
|
-
if ("
|
|
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
|
-
}
|
|
105
|
-
if ("items" in property) {
|
|
106
|
-
if (!Array.isArray(what)) {
|
|
107
|
-
return Result.error(makePropertyError(PropertyValidationErrorCode.Unmatching, {
|
|
108
|
-
expected: expectedType,
|
|
109
|
-
got: actualType
|
|
110
|
-
}));
|
|
111
|
-
}
|
|
112
|
-
if (property.minItems) {
|
|
113
|
-
if (what.length < property.minItems) {
|
|
114
|
-
return Result.error(makePropertyError(PropertyValidationErrorCode.MoreItemsExpected));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
if (property.maxItems) {
|
|
118
|
-
if (what.length > property.maxItems) {
|
|
119
|
-
return Result.error(makePropertyError(PropertyValidationErrorCode.LessItemsExpected));
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
let i = 0;
|
|
123
|
-
for (const elem of what) {
|
|
124
|
-
const { error } = validateProperty(propName, elem, property.items, options);
|
|
125
|
-
if (error) {
|
|
126
|
-
if ("errors" in error) {
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
error.index = i;
|
|
130
|
-
return Result.error(error);
|
|
131
|
-
}
|
|
132
|
-
i++;
|
|
133
|
-
}
|
|
134
|
-
} else if ("type" in property) {
|
|
93
|
+
if ("type" in property) {
|
|
135
94
|
switch (property.type) {
|
|
136
|
-
case "number":
|
|
137
95
|
case "integer": {
|
|
96
|
+
if (!Number.isInteger(what)) {
|
|
97
|
+
return Result.error(makePropertyError(PropertyValidationErrorCode.NumericConstraint, {
|
|
98
|
+
expected: "integer",
|
|
99
|
+
got: "invalid_number"
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
case "number": {
|
|
138
104
|
if (typeof what !== "number") {
|
|
139
105
|
return Result.error(makePropertyError(PropertyValidationErrorCode.Unmatching, {
|
|
140
106
|
expected: expectedType,
|
|
141
107
|
got: actualType
|
|
142
108
|
}));
|
|
143
109
|
}
|
|
144
|
-
if (property.
|
|
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) {
|
|
110
|
+
if (typeof property.maximum === "number" && property.maximum < what || typeof property.minimum === "number" && property.minimum > what || typeof property.exclusiveMaximum === "number" && property.exclusiveMaximum <= what || typeof property.exclusiveMinimum === "number" && property.exclusiveMinimum >= what) {
|
|
153
111
|
return Result.error(makePropertyError(PropertyValidationErrorCode.NumericConstraint, {
|
|
154
112
|
expected: "number",
|
|
155
113
|
got: "invalid_number"
|
|
156
114
|
}));
|
|
157
115
|
}
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
case "object": {
|
|
119
|
+
return validate(what, property, options);
|
|
120
|
+
}
|
|
121
|
+
case "array": {
|
|
122
|
+
if (!Array.isArray(what)) {
|
|
123
|
+
return Result.error(makePropertyError(PropertyValidationErrorCode.Unmatching, {
|
|
124
|
+
expected: expectedType,
|
|
125
|
+
got: actualType
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
if (property.minItems) {
|
|
129
|
+
if (what.length < property.minItems) {
|
|
130
|
+
return Result.error(makePropertyError(PropertyValidationErrorCode.MoreItemsExpected));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (property.maxItems) {
|
|
134
|
+
if (what.length > property.maxItems) {
|
|
135
|
+
return Result.error(makePropertyError(PropertyValidationErrorCode.LessItemsExpected));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
let i = 0;
|
|
139
|
+
for (const elem of what) {
|
|
140
|
+
const { error } = validateProperty(elem, property.items, options);
|
|
141
|
+
if (error) {
|
|
142
|
+
if ("errors" in error) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
error.index = i;
|
|
146
|
+
return Result.error(error);
|
|
147
|
+
}
|
|
148
|
+
i++;
|
|
149
|
+
}
|
|
158
150
|
}
|
|
159
151
|
}
|
|
160
152
|
} else if ("enum" in property) {
|
|
161
|
-
if (!property.enum.includes(what)) {
|
|
153
|
+
if (!property.enum.includes(what) && property.enum.length === 0) {
|
|
162
154
|
return Result.error(makePropertyError(PropertyValidationErrorCode.ExtraneousElement, {
|
|
163
155
|
expected: property.enum,
|
|
164
156
|
got: what
|
|
165
157
|
}));
|
|
166
158
|
}
|
|
159
|
+
} else if ("const" in property) {
|
|
160
|
+
if (what !== property.const) {
|
|
161
|
+
return Result.error(makePropertyError(PropertyValidationErrorCode.Unmatching, {
|
|
162
|
+
expected: property.const,
|
|
163
|
+
got: what
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
167
166
|
}
|
|
168
167
|
return Result.result(what);
|
|
169
168
|
};
|
|
@@ -190,7 +189,7 @@ export const validate = (what, schema, options = {}) => {
|
|
|
190
189
|
}));
|
|
191
190
|
}
|
|
192
191
|
if (!("properties" in schema)) {
|
|
193
|
-
const { error } = validateProperty(
|
|
192
|
+
const { error } = validateProperty(what, schema);
|
|
194
193
|
return error ? Result.error(error) : Result.result(what);
|
|
195
194
|
}
|
|
196
195
|
const wholenessError = validateWholeness(what, schema);
|
|
@@ -203,15 +202,10 @@ export const validate = (what, schema, options = {}) => {
|
|
|
203
202
|
const errors = {};
|
|
204
203
|
const resultCopy = {};
|
|
205
204
|
for (const propName in what) {
|
|
206
|
-
const { error, result: parsed } = validateProperty(
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
{
|
|
211
|
-
...options,
|
|
212
|
-
parentProperty: schema
|
|
213
|
-
}
|
|
214
|
-
);
|
|
205
|
+
const { error, result: parsed } = validateProperty(what[propName], schema.properties[propName], {
|
|
206
|
+
...options,
|
|
207
|
+
parentProperty: schema
|
|
208
|
+
});
|
|
215
209
|
if (error) {
|
|
216
210
|
errors[propName] = error;
|
|
217
211
|
}
|