aboutsummaryrefslogtreecommitdiffstats
path: root/teal-src/util/jsonschema.tl
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2021-12-29 16:57:35 +0100
committerKim Alvefur <zash@zash.se>2021-12-29 16:57:35 +0100
commitcd091bf95ce0e0853edeeb359d3387e06a518427 (patch)
tree8921a697da0c27c51cc1bcccbd3846909d9a5a83 /teal-src/util/jsonschema.tl
parentd8017615c75ec62be48d09fa53bbb58e93656c9c (diff)
downloadprosody-cd091bf95ce0e0853edeeb359d3387e06a518427.tar.gz
prosody-cd091bf95ce0e0853edeeb359d3387e06a518427.zip
util.jsonschema: Add support for $ref pointers
Diffstat (limited to 'teal-src/util/jsonschema.tl')
-rw-r--r--teal-src/util/jsonschema.tl60
1 files changed, 37 insertions, 23 deletions
diff --git a/teal-src/util/jsonschema.tl b/teal-src/util/jsonschema.tl
index 1f731781..5c5fd4ce 100644
--- a/teal-src/util/jsonschema.tl
+++ b/teal-src/util/jsonschema.tl
@@ -11,6 +11,8 @@
local json = require"util.json"
local null = json.null;
+local pointer = require "util.jsonpointer"
+
local type json_type_name = json.json_type_name
-- json_type_name here is non-standard
@@ -33,6 +35,8 @@ local record json_schema_object
["then"] : schema_t
["else"] : schema_t
+ ["$ref"] : string
+
-- numbers
multipleOf : number
maximum : number
@@ -90,12 +94,12 @@ local record json_schema_object
writeOnly : boolean
-- methods
- validate : function ( schema_t, any) : boolean
+ validate : function ( schema_t, any, json_schema_object ) : boolean
end
-- TODO validator function per schema property
-local type_validators : { json_type_name : function (schema_t, any) : boolean } = {}
+local type_validators : { json_type_name : function (schema_t, any, json_schema_object) : boolean } = {}
local function simple_validate(schema : json_type_name, data : any) : boolean
if schema == "object" and data is table then
@@ -152,7 +156,7 @@ end
type_validators.integer = type_validators.number
-local function validate(schema : schema_t, data : any) : boolean
+local function validate(schema : schema_t, data : any, root : json_schema_object) : boolean
if schema is boolean then
return schema
end
@@ -160,9 +164,19 @@ local function validate(schema : schema_t, data : any) : boolean
return simple_validate(schema, data)
end
if schema is json_schema_object then
+ if root == nil then
+ root = schema
+ end
+ if schema["$ref"] and schema["$ref"]:sub(1,1) == "#" then
+ local referenced = pointer.resolve(root as table, schema["$ref"]:sub(2)) as schema_t
+ if referenced ~= nil then
+ return validate(referenced, data, root);
+ end
+ end
+
if schema.allOf then
for _, sub in ipairs(schema.allOf) do
- if not validate(sub, data) then
+ if not validate(sub, data, root) then
return false
end
end
@@ -172,7 +186,7 @@ local function validate(schema : schema_t, data : any) : boolean
if schema.oneOf then
local valid = 0
for _, sub in ipairs(schema.oneOf) do
- if validate(sub, data) then
+ if validate(sub, data, root) then
valid = valid + 1
end
end
@@ -181,7 +195,7 @@ local function validate(schema : schema_t, data : any) : boolean
if schema.anyOf then
for _, sub in ipairs(schema.anyOf) do
- if validate(sub, data) then
+ if validate(sub, data, root) then
return true
end
end
@@ -189,19 +203,19 @@ local function validate(schema : schema_t, data : any) : boolean
end
if schema["not"] then
- if validate(schema["not"], data) then
+ if validate(schema["not"], data, root) then
return false
end
end
if schema["if"] then
- if validate(schema["if"], data) then
+ if validate(schema["if"], data, root) then
if schema["then"] then
- return validate(schema["then"], data)
+ return validate(schema["then"], data, root)
end
else
if schema["else"] then
- return validate(schema["else"], data)
+ return validate(schema["else"], data, root)
end
end
end
@@ -226,14 +240,14 @@ local function validate(schema : schema_t, data : any) : boolean
local validator = type_validators[schema.type]
if validator then
- return validator(schema, data)
+ return validator(schema, data, root)
end
end
return true
end
end
-type_validators.table = function (schema : json_schema_object, data : any) : boolean
+type_validators.table = function (schema : json_schema_object, data : any, root : json_schema_object) : boolean
if data is table then
if schema.maxItems and #data > schema.maxItems then
@@ -255,20 +269,20 @@ type_validators.table = function (schema : json_schema_object, data : any) : boo
if schema.properties then
local additional : schema_t = schema.additionalProperties or true
for k, v in pairs(data) do
- if schema.propertyNames and not validate(schema.propertyNames, k) then
+ if schema.propertyNames and not validate(schema.propertyNames, k, root) then
return false
end
local s = schema.properties[k as string] or additional
- if not validate(s, v) then
+ if not validate(s, v, root) then
return false
end
end
elseif schema.additionalProperties then
for k, v in pairs(data) do
- if schema.propertyNames and not validate(schema.propertyNames, k) then
+ if schema.propertyNames and not validate(schema.propertyNames, k, root) then
return false
end
- if not validate(schema.additionalProperties, v) then
+ if not validate(schema.additionalProperties, v, root) then
return false
end
end
@@ -288,7 +302,7 @@ type_validators.table = function (schema : json_schema_object, data : any) : boo
local p = 0
if schema.prefixItems then
for i, s in ipairs(schema.prefixItems) do
- if validate(s, data[i]) then
+ if validate(s, data[i], root) then
p = i
else
return false
@@ -298,7 +312,7 @@ type_validators.table = function (schema : json_schema_object, data : any) : boo
if schema.items then
for i = p+1, #data do
- if not validate(schema.items, data[i]) then
+ if not validate(schema.items, data[i], root) then
return false
end
end
@@ -307,7 +321,7 @@ type_validators.table = function (schema : json_schema_object, data : any) : boo
if schema.contains then
local found = false
for i = 1, #data do
- if validate(schema.contains, data[i]) then
+ if validate(schema.contains, data[i], root) then
found = true
break
end
@@ -322,7 +336,7 @@ type_validators.table = function (schema : json_schema_object, data : any) : boo
return false
end
-type_validators.object = function (schema : schema_t, data : any) : boolean
+type_validators.object = function (schema : schema_t, data : any, root : json_schema_object) : boolean
if data is table then
for k in pairs(data) do
if not k is string then
@@ -330,12 +344,12 @@ type_validators.object = function (schema : schema_t, data : any) : boolean
end
end
- return type_validators.table(schema, data)
+ return type_validators.table(schema, data, root)
end
return false
end
-type_validators.array = function (schema : schema_t, data : any) : boolean
+type_validators.array = function (schema : schema_t, data : any, root : json_schema_object) : boolean
if data is table then
-- just check that there the keys are all numbers
@@ -345,7 +359,7 @@ type_validators.array = function (schema : schema_t, data : any) : boolean
end
end
- return type_validators.table(schema, data)
+ return type_validators.table(schema, data, root)
end
return false
end