@travetto/schema 4.0.0-rc.5 → 4.0.0-rc.7
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/README.md +26 -22
- package/package.json +3 -3
- package/src/validate/validator.ts +39 -28
package/README.md
CHANGED
|
@@ -220,20 +220,22 @@ Validation Failed {
|
|
|
220
220
|
"category": "data",
|
|
221
221
|
"type": "ValidationResultError",
|
|
222
222
|
"at": "2029-03-14T04:00:00.618Z",
|
|
223
|
-
"
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
223
|
+
"details": {
|
|
224
|
+
"errors": [
|
|
225
|
+
{
|
|
226
|
+
"kind": "type",
|
|
227
|
+
"type": "number",
|
|
228
|
+
"message": "age is not a valid number",
|
|
229
|
+
"path": "age"
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"kind": "required",
|
|
233
|
+
"active": true,
|
|
234
|
+
"message": "address.street2 is required",
|
|
235
|
+
"path": "address.street2"
|
|
236
|
+
}
|
|
237
|
+
]
|
|
238
|
+
}
|
|
237
239
|
}
|
|
238
240
|
```
|
|
239
241
|
|
|
@@ -363,14 +365,16 @@ Validation Failed {
|
|
|
363
365
|
"category": "data",
|
|
364
366
|
"type": "ValidationResultError",
|
|
365
367
|
"at": "2029-03-14T04:00:00.837Z",
|
|
366
|
-
"
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
368
|
+
"details": {
|
|
369
|
+
"errors": [
|
|
370
|
+
{
|
|
371
|
+
"kind": "type",
|
|
372
|
+
"type": "PointImpl",
|
|
373
|
+
"message": "point is not a valid PointImpl",
|
|
374
|
+
"path": "point"
|
|
375
|
+
}
|
|
376
|
+
]
|
|
377
|
+
}
|
|
374
378
|
}
|
|
375
379
|
```
|
|
376
380
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/schema",
|
|
3
|
-
"version": "4.0.0-rc.
|
|
3
|
+
"version": "4.0.0-rc.7",
|
|
4
4
|
"description": "Data type registry for runtime validation, reflection and binding.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"schema",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"directory": "module/schema"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@travetto/registry": "^4.0.0-rc.
|
|
30
|
+
"@travetto/registry": "^4.0.0-rc.7"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@travetto/transformer": "^4.0.0-rc.
|
|
33
|
+
"@travetto/transformer": "^4.0.0-rc.6"
|
|
34
34
|
},
|
|
35
35
|
"peerDependenciesMeta": {
|
|
36
36
|
"@travetto/transformer": {
|
|
@@ -56,16 +56,7 @@ export class SchemaValidator {
|
|
|
56
56
|
* @param relative The relative path of object traversal
|
|
57
57
|
*/
|
|
58
58
|
static #validateFieldSchema(fieldSchema: FieldConfig, val: unknown, relative: string = ''): ValidationError[] {
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Validate a single field config against a passed in value
|
|
64
|
-
* @param fieldSchema The field schema configuration
|
|
65
|
-
* @param val The raw value, could be an array or not
|
|
66
|
-
* @param path The current path of validation traversal
|
|
67
|
-
*/
|
|
68
|
-
static #validateFieldSchemaRaw(fieldSchema: FieldConfig, val: unknown, path: string = ''): ValidationError[] {
|
|
59
|
+
const path = `${relative}${relative ? '.' : ''}${fieldSchema.name}`;
|
|
69
60
|
const hasValue = !(val === undefined || val === null || (typeof val === 'string' && val === '') || (Array.isArray(val) && val.length === 0));
|
|
70
61
|
|
|
71
62
|
if (!hasValue) {
|
|
@@ -242,27 +233,17 @@ export class SchemaValidator {
|
|
|
242
233
|
}
|
|
243
234
|
|
|
244
235
|
/**
|
|
245
|
-
* Validate
|
|
246
|
-
* @param cls The class to validate the objects against
|
|
247
|
-
* @param o The object to validate
|
|
248
|
-
* @param view The optional view to limit the scope to
|
|
236
|
+
* Validate the class level validations
|
|
249
237
|
*/
|
|
250
|
-
static async
|
|
251
|
-
|
|
252
|
-
if (!
|
|
253
|
-
|
|
254
|
-
throw new TypeMismatchError(cls.name, (o as ClassInstance).constructor.name);
|
|
238
|
+
static async #validateClassLevel<T>(cls: Class<T>, o: T, view?: string): Promise<ValidationError[]> {
|
|
239
|
+
const schema = SchemaRegistry.get(cls);
|
|
240
|
+
if (!schema) {
|
|
241
|
+
return [];
|
|
255
242
|
}
|
|
256
|
-
cls = SchemaRegistry.resolveSubTypeForInstance(cls, o);
|
|
257
|
-
|
|
258
|
-
const config = SchemaRegistry.getViewSchema(cls, view);
|
|
259
|
-
const validators = SchemaRegistry.get(cls).validators;
|
|
260
|
-
|
|
261
|
-
// Validate using standard behaviors
|
|
262
|
-
const errors = this.#validateSchema(config.schema, o, '');
|
|
263
243
|
|
|
244
|
+
const errors: ValidationError[] = [];
|
|
264
245
|
// Handle class level validators
|
|
265
|
-
for (const fn of validators) {
|
|
246
|
+
for (const fn of schema.validators) {
|
|
266
247
|
try {
|
|
267
248
|
const res = await fn(o, view);
|
|
268
249
|
if (res) {
|
|
@@ -276,7 +257,30 @@ export class SchemaValidator {
|
|
|
276
257
|
}
|
|
277
258
|
}
|
|
278
259
|
}
|
|
260
|
+
return errors;
|
|
261
|
+
}
|
|
279
262
|
|
|
263
|
+
/**
|
|
264
|
+
* Validate an object against it's constructor's schema
|
|
265
|
+
* @param cls The class to validate the objects against
|
|
266
|
+
* @param o The object to validate
|
|
267
|
+
* @param view The optional view to limit the scope to
|
|
268
|
+
*/
|
|
269
|
+
static async validate<T>(cls: Class<T>, o: T, view?: string): Promise<T> {
|
|
270
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
271
|
+
if (!ObjectUtil.isPlainObject(o) && !(o instanceof cls || cls.Ⲑid === (o as ClassInstance<T>).constructor.Ⲑid)) {
|
|
272
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
273
|
+
throw new TypeMismatchError(cls.name, (o as ClassInstance).constructor.name);
|
|
274
|
+
}
|
|
275
|
+
cls = SchemaRegistry.resolveSubTypeForInstance(cls, o);
|
|
276
|
+
|
|
277
|
+
const config = SchemaRegistry.getViewSchema(cls, view);
|
|
278
|
+
|
|
279
|
+
// Validate using standard behaviors
|
|
280
|
+
const errors = [
|
|
281
|
+
...this.#validateSchema(config.schema, o, ''),
|
|
282
|
+
... await this.#validateClassLevel(cls, o, view)
|
|
283
|
+
];
|
|
280
284
|
if (errors.length) {
|
|
281
285
|
throw new ValidationResultError(errors);
|
|
282
286
|
}
|
|
@@ -327,7 +331,14 @@ export class SchemaValidator {
|
|
|
327
331
|
static async validateMethod<T>(cls: Class<T>, method: string, params: unknown[], prefixes: (string | undefined)[] = []): Promise<void> {
|
|
328
332
|
const errors: ValidationError[] = [];
|
|
329
333
|
for (const field of SchemaRegistry.getMethodSchema(cls, method)) {
|
|
330
|
-
|
|
334
|
+
const i = field.index!;
|
|
335
|
+
errors.push(...[
|
|
336
|
+
... this.#validateFieldSchema(field, params[i]),
|
|
337
|
+
... await this.#validateClassLevel(field.type, params[i])
|
|
338
|
+
].map(x => {
|
|
339
|
+
x.path = !prefixes[i] ? x.path.replace(`${field.name}.`, '') : x.path.replace(field.name, prefixes[i]!);
|
|
340
|
+
return x;
|
|
341
|
+
}));
|
|
331
342
|
}
|
|
332
343
|
if (errors.length) {
|
|
333
344
|
throw new ValidationResultError(errors);
|