aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2020-01-26 15:57:39 -0500
committertoasted-nutbread <toasted-nutbread@users.noreply.github.com>2020-02-02 10:12:01 -0500
commit52b623b5cdb1963aa1fb65228f9377e147708959 (patch)
tree217e6e6ebec1fc35b5885207a1d5d90d815936f5
parent31dbeab67ce79a9c46053ce124ad3924f71b67cc (diff)
Improve getPropertySchema's type detection
-rw-r--r--ext/bg/js/json-schema.js42
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]);
}