diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-01-26 15:57:39 -0500 |
---|---|---|
committer | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-02-02 10:12:01 -0500 |
commit | 52b623b5cdb1963aa1fb65228f9377e147708959 (patch) | |
tree | 217e6e6ebec1fc35b5885207a1d5d90d815936f5 | |
parent | 31dbeab67ce79a9c46053ce124ad3924f71b67cc (diff) |
Improve getPropertySchema's type detection
-rw-r--r-- | ext/bg/js/json-schema.js | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/ext/bg/js/json-schema.js b/ext/bg/js/json-schema.js index 61bd3d43..9b651f46 100644 --- a/ext/bg/js/json-schema.js +++ b/ext/bg/js/json-schema.js @@ -64,7 +64,7 @@ class JsonSchemaProxyHandler { } } - const propertySchema = JsonSchemaProxyHandler.getPropertySchema(this._schema, property); + const propertySchema = JsonSchemaProxyHandler.getPropertySchema(this._schema, property, target); if (propertySchema === null) { 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) { throw new Error(`Property ${property} not supported`); } @@ -122,11 +122,8 @@ class JsonSchemaProxyHandler { throw new Error('construct not supported'); } - static getPropertySchema(schema, property) { - const type = schema.type; - if (Array.isArray(type)) { - throw new Error(`Ambiguous property type for ${property}`); - } + static getPropertySchema(schema, property, value) { + const type = JsonSchemaProxyHandler.getSchemaOrValueType(schema, value); switch (type) { 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) { let result = JsonSchemaProxyHandler.validateSingleSchema(value, schema); if (result !== null) { return result; } @@ -376,7 +396,7 @@ class JsonSchemaProxyHandler { } for (const property of properties) { - const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, property); + const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, property, value); if (propertySchema === null) { return `No schema found for ${property}`; } @@ -492,14 +512,14 @@ class JsonSchemaProxyHandler { for (const property of required) { properties.delete(property); - const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, property); + const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, property, value); if (propertySchema === null) { continue; } value[property] = JsonSchemaProxyHandler.getValidValueOrDefault(propertySchema, value[property]); } } for (const property of properties) { - const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, property); + const propertySchema = JsonSchemaProxyHandler.getPropertySchema(schema, property, value); if (propertySchema === null) { Reflect.deleteProperty(value, property); } else { @@ -512,7 +532,7 @@ class JsonSchemaProxyHandler { static populateArrayDefaults(value, schema) { 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; } value[i] = JsonSchemaProxyHandler.getValidValueOrDefault(propertySchema, value[i]); } |