Improve getPropertySchema's type detection

This commit is contained in:
toasted-nutbread 2020-01-26 15:57:39 -05:00
parent 31dbeab67c
commit 52b623b5cd

View File

@ -64,7 +64,7 @@ class JsonSchemaProxyHandler {
} }
} }
const propertySchema = JsonSchemaProxyHandler.getPropertySchema(this._schema, property); const propertySchema = JsonSchemaProxyHandler.getPropertySchema(this._schema, property, target);
if (propertySchema === null) { if (propertySchema === null) {
return; return;
} }
@ -86,7 +86,7 @@ class JsonSchemaProxyHandler {
} }
} }
const propertySchema = JsonSchemaProxyHandler.getPropertySchema(this._schema, property); const propertySchema = JsonSchemaProxyHandler.getPropertySchema(this._schema, property, target);
if (propertySchema === null) { if (propertySchema === null) {
throw new Error(`Property ${property} not supported`); throw new Error(`Property ${property} not supported`);
} }
@ -122,11 +122,8 @@ class JsonSchemaProxyHandler {
throw new Error('construct not supported'); throw new Error('construct not supported');
} }
static getPropertySchema(schema, property) { static getPropertySchema(schema, property, value) {
const type = schema.type; const type = JsonSchemaProxyHandler.getSchemaOrValueType(schema, value);
if (Array.isArray(type)) {
throw new Error(`Ambiguous property type for ${property}`);
}
switch (type) { switch (type) {
case 'object': case 'object':
{ {
@ -172,6 +169,29 @@ class JsonSchemaProxyHandler {
} }
} }
static getSchemaOrValueType(schema, value) {
const type = schema.type;
if (Array.isArray(type)) {
if (typeof value !== 'undefined') {
const valueType = JsonSchemaProxyHandler.getValueType(value);
if (type.indexOf(valueType) >= 0) {
return valueType;
}
}
throw new Error(`Ambiguous property type for ${property}`);
}
if (typeof type === 'undefined') {
if (typeof value !== 'undefined') {
return JsonSchemaProxyHandler.getValueType(value);
}
throw new Error(`No property type for ${property}`);
}
return type;
}
static validate(value, schema) { static validate(value, schema) {
let result = JsonSchemaProxyHandler.validateSingleSchema(value, schema); let result = JsonSchemaProxyHandler.validateSingleSchema(value, schema);
if (result !== null) { return result; } if (result !== null) { return result; }
@ -376,7 +396,7 @@ class JsonSchemaProxyHandler {
} }
for (const property of properties) { for (const property of properties) {
const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, property); const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, property, value);
if (propertySchema === null) { if (propertySchema === null) {
return `No schema found for ${property}`; return `No schema found for ${property}`;
} }
@ -492,14 +512,14 @@ class JsonSchemaProxyHandler {
for (const property of required) { for (const property of required) {
properties.delete(property); properties.delete(property);
const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, property); const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, property, value);
if (propertySchema === null) { continue; } if (propertySchema === null) { continue; }
value[property] = JsonSchemaProxyHandler.getValidValueOrDefault(propertySchema, value[property]); value[property] = JsonSchemaProxyHandler.getValidValueOrDefault(propertySchema, value[property]);
} }
} }
for (const property of properties) { for (const property of properties) {
const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, property); const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, property, value);
if (propertySchema === null) { if (propertySchema === null) {
Reflect.deleteProperty(value, property); Reflect.deleteProperty(value, property);
} else { } else {
@ -512,7 +532,7 @@ class JsonSchemaProxyHandler {
static populateArrayDefaults(value, schema) { static populateArrayDefaults(value, schema) {
for (let i = 0, ii = value.length; i < ii; ++i) { for (let i = 0, ii = value.length; i < ii; ++i) {
const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, i); const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, i, value);
if (propertySchema === null) { continue; } if (propertySchema === null) { continue; }
value[i] = JsonSchemaProxyHandler.getValidValueOrDefault(propertySchema, value[i]); value[i] = JsonSchemaProxyHandler.getValidValueOrDefault(propertySchema, value[i]);
} }