[IMP] runtime: allow validating object values using a type description

In JS, objects are often used as a mapping that gives fast lookup on the
keys, in those cases, the keys themselves are not known in advance, but
the values may have a shape that they're expected to follow. This commit
adds support for a `values` key in schema for objects, which will be
checked against all values in the object during validation.
This commit is contained in:
Samuel Degueldre
2023-04-05 08:18:11 +02:00
committed by Géry Debongnie
parent fea8fcaf61
commit 47009912df
5 changed files with 67 additions and 16 deletions
+1 -1
View File
@@ -54,7 +54,7 @@ export {
onWillDestroy,
onError,
} from "./lifecycle_hooks";
export { validate } from "./validation";
export { validate, validateType } from "./validation";
export { OwlError } from "./error_handling";
export const __info__ = {
+15 -3
View File
@@ -17,6 +17,7 @@ interface TypeInfo {
validate?: Function;
shape?: Schema;
element?: TypeDescription;
values?: TypeDescription;
}
type ValueType = { value: any };
@@ -137,7 +138,7 @@ function validateArrayType(key: string, value: any, descr: TypeDescription): str
return null;
}
function validateType(key: string, value: any, descr: TypeDescription): string | null {
export function validateType(key: string, value: any, descr: TypeDescription): string | null {
if (value === undefined) {
return isOptional(descr) ? null : `'${key}' is undefined (should be a ${describe(descr)})`;
} else if (isBaseType(descr)) {
@@ -151,13 +152,24 @@ function validateType(key: string, value: any, descr: TypeDescription): string |
let result: string | null = null;
if ("element" in descr) {
result = validateArrayType(key, value, descr.element!);
} else if ("shape" in descr && !result) {
} else if ("shape" in descr) {
if (typeof value !== "object" || Array.isArray(value)) {
result = `'${key}' is not an object`;
} else {
const errors = validateSchema(value, descr.shape!);
if (errors.length) {
result = `'${key}' has not the correct shape (${errors.join(", ")})`;
result = `'${key}' doesn't have the correct shape (${errors.join(", ")})`;
}
}
} else if ("values" in descr) {
if (typeof value !== "object" || Array.isArray(value)) {
result = `'${key}' is not an object`;
} else {
const errors = Object.entries(value)
.map(([key, value]) => validateType(key, value, descr.values!))
.filter(Boolean);
if (errors.length) {
result = `some of the values in '${key}' are invalid (${errors.join(", ")})`;
}
}
}