Software / code / prosody
Comparison
util/jsonschema.lua @ 12581:6ee9071c0a1f
Merge 0.12->trunk
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Fri, 08 Jul 2022 19:36:07 +0200 |
| parent | 12579:ca6a43fe0231 |
| child | 12759:ec54fe0003d5 |
comparison
equal
deleted
inserted
replaced
| 12578:10bb58ad5583 | 12581:6ee9071c0a1f |
|---|---|
| 1 -- This file is generated from teal-src/util/jsonschema.lua | |
| 2 | |
| 1 local m_type = math.type or function (n) | 3 local m_type = math.type or function (n) |
| 2 return n % 1 == 0 and n <= 9007199254740992 and n >= -9007199254740992 and "integer" or "float"; | 4 return n % 1 == 0 and n <= 9007199254740992 and n >= -9007199254740992 and "integer" or "float"; |
| 3 end; | 5 end; |
| 4 local json = require("util.json") | 6 local json = require("util.json") |
| 5 local null = json.null; | 7 local null = json.null; |
| 8 | 10 |
| 9 local json_type_name = json.json_type_name | 11 local json_type_name = json.json_type_name |
| 10 | 12 |
| 11 local schema_t = {} | 13 local schema_t = {} |
| 12 | 14 |
| 13 local json_schema_object = {xml_t = {}} | 15 local json_schema_object = { xml_t = {} } |
| 14 | |
| 15 local type_validators = {} | |
| 16 | 16 |
| 17 local function simple_validate(schema, data) | 17 local function simple_validate(schema, data) |
| 18 if schema == "object" and type(data) == "table" then | 18 if schema == nil then |
| 19 return true | |
| 20 elseif schema == "object" and type(data) == "table" then | |
| 19 return type(data) == "table" and (next(data) == nil or type((next(data, nil))) == "string") | 21 return type(data) == "table" and (next(data) == nil or type((next(data, nil))) == "string") |
| 20 elseif schema == "array" and type(data) == "table" then | 22 elseif schema == "array" and type(data) == "table" then |
| 21 return type(data) == "table" and (next(data) == nil or type((next(data, nil))) == "number") | 23 return type(data) == "table" and (next(data) == nil or type((next(data, nil))) == "number") |
| 22 elseif schema == "integer" then | 24 elseif schema == "integer" then |
| 23 return m_type(data) == schema | 25 return m_type(data) == schema |
| 24 elseif schema == "null" then | 26 elseif schema == "null" then |
| 25 return data == null | 27 return data == null |
| 28 elseif type(schema) == "table" then | |
| 29 for _, one in ipairs(schema) do | |
| 30 if simple_validate(one, data) then | |
| 31 return true | |
| 32 end | |
| 33 end | |
| 34 return false | |
| 26 else | 35 else |
| 27 return type(data) == schema | 36 return type(data) == schema |
| 28 end | 37 end |
| 29 end | 38 end |
| 30 | 39 |
| 31 type_validators.string = function(schema, data) | 40 local complex_validate |
| 32 | |
| 33 if type(data) == "string" then | |
| 34 if schema.maxLength and #data > schema.maxLength then | |
| 35 return false | |
| 36 end | |
| 37 if schema.minLength and #data < schema.minLength then | |
| 38 return false | |
| 39 end | |
| 40 return true | |
| 41 end | |
| 42 return false | |
| 43 end | |
| 44 | |
| 45 type_validators.number = function(schema, data) | |
| 46 if schema.multipleOf and data % schema.multipleOf ~= 0 then | |
| 47 return false | |
| 48 end | |
| 49 | |
| 50 if schema.maximum and not (data <= schema.maximum) then | |
| 51 return false | |
| 52 end | |
| 53 | |
| 54 if schema.exclusiveMaximum and not (data < schema.exclusiveMaximum) then | |
| 55 return false | |
| 56 end | |
| 57 | |
| 58 if schema.minimum and not (data >= schema.minimum) then | |
| 59 return false | |
| 60 end | |
| 61 | |
| 62 if schema.exclusiveMinimum and not (data > schema.exclusiveMinimum) then | |
| 63 return false | |
| 64 end | |
| 65 | |
| 66 return true | |
| 67 end | |
| 68 | |
| 69 type_validators.integer = type_validators.number | |
| 70 | 41 |
| 71 local function validate(schema, data, root) | 42 local function validate(schema, data, root) |
| 72 if type(schema) == "boolean" then | 43 if type(schema) == "boolean" then |
| 73 return schema | 44 return schema |
| 74 end | 45 else |
| 75 if type(schema) == "string" then | 46 return complex_validate(schema, data, root) |
| 76 return simple_validate(schema, data) | 47 end |
| 77 end | 48 end |
| 78 if type(schema) == "table" then | 49 |
| 79 if root == nil then | 50 function complex_validate(schema, data, root) |
| 80 root = schema | 51 |
| 81 end | 52 if root == nil then |
| 82 if schema["$ref"] and schema["$ref"]:sub(1, 1) == "#" then | 53 root = schema |
| 83 local referenced = pointer.resolve(root, schema["$ref"]:sub(2)) | 54 end |
| 84 if referenced ~= nil then | 55 |
| 85 return validate(referenced, data, root) | 56 if schema["$ref"] and schema["$ref"]:sub(1, 1) == "#" then |
| 86 end | 57 local referenced = pointer.resolve(root, schema["$ref"]:sub(2)) |
| 87 end | 58 if referenced ~= nil and referenced ~= root and referenced ~= schema then |
| 88 | 59 if not validate(referenced, data, root) then |
| 89 if schema.allOf then | |
| 90 for _, sub in ipairs(schema.allOf) do | |
| 91 if not validate(sub, data, root) then | |
| 92 return false | |
| 93 end | |
| 94 end | |
| 95 return true | |
| 96 end | |
| 97 | |
| 98 if schema.oneOf then | |
| 99 local valid = 0 | |
| 100 for _, sub in ipairs(schema.oneOf) do | |
| 101 if validate(sub, data, root) then | |
| 102 valid = valid + 1 | |
| 103 end | |
| 104 end | |
| 105 return valid == 1 | |
| 106 end | |
| 107 | |
| 108 if schema.anyOf then | |
| 109 for _, sub in ipairs(schema.anyOf) do | |
| 110 if validate(sub, data, root) then | |
| 111 return true | |
| 112 end | |
| 113 end | |
| 114 return false | |
| 115 end | |
| 116 | |
| 117 if schema["not"] then | |
| 118 if validate(schema["not"], data, root) then | |
| 119 return false | 60 return false |
| 120 end | 61 end |
| 121 end | 62 end |
| 122 | 63 end |
| 123 if schema["if"] then | 64 |
| 124 if validate(schema["if"], data, root) then | 65 if not simple_validate(schema.type, data) then |
| 125 if schema["then"] then | 66 return false |
| 126 return validate(schema["then"], data, root) | 67 end |
| 127 end | 68 |
| 128 else | 69 if schema.type == "object" then |
| 129 if schema["else"] then | 70 if type(data) == "table" then |
| 130 return validate(schema["else"], data, root) | 71 |
| 131 end | 72 for k in pairs(data) do |
| 132 end | 73 if not (type(k) == "string") then |
| 133 end | 74 return false |
| 134 | 75 end |
| 135 if schema.const ~= nil and schema.const ~= data then | 76 end |
| 136 return false | 77 end |
| 137 end | 78 end |
| 138 | 79 |
| 139 if schema["enum"] ~= nil then | 80 if schema.type == "array" then |
| 140 for _, v in ipairs(schema["enum"]) do | 81 if type(data) == "table" then |
| 141 if v == data then | 82 |
| 142 return true | 83 for i in pairs(data) do |
| 143 end | 84 if not (math.type(i) == "integer") then |
| 144 end | 85 return false |
| 145 return false | 86 end |
| 146 end | 87 end |
| 147 | 88 end |
| 148 if schema.type then | 89 end |
| 149 if not simple_validate(schema.type, data) then | 90 |
| 91 if schema["enum"] ~= nil then | |
| 92 local match = false | |
| 93 for _, v in ipairs(schema["enum"]) do | |
| 94 if v == data then | |
| 95 | |
| 96 match = true | |
| 97 break | |
| 98 end | |
| 99 end | |
| 100 if not match then | |
| 101 return false | |
| 102 end | |
| 103 end | |
| 104 | |
| 105 if type(data) == "string" then | |
| 106 if schema.maxLength and #data > schema.maxLength then | |
| 107 return false | |
| 108 end | |
| 109 if schema.minLength and #data < schema.minLength then | |
| 110 return false | |
| 111 end | |
| 112 end | |
| 113 | |
| 114 if type(data) == "number" then | |
| 115 if schema.multipleOf and (data == 0 or data % schema.multipleOf ~= 0) then | |
| 116 return false | |
| 117 end | |
| 118 | |
| 119 if schema.maximum and not (data <= schema.maximum) then | |
| 120 return false | |
| 121 end | |
| 122 | |
| 123 if schema.exclusiveMaximum and not (data < schema.exclusiveMaximum) then | |
| 124 return false | |
| 125 end | |
| 126 | |
| 127 if schema.minimum and not (data >= schema.minimum) then | |
| 128 return false | |
| 129 end | |
| 130 | |
| 131 if schema.exclusiveMinimum and not (data > schema.exclusiveMinimum) then | |
| 132 return false | |
| 133 end | |
| 134 end | |
| 135 | |
| 136 if schema.allOf then | |
| 137 for _, sub in ipairs(schema.allOf) do | |
| 138 if not validate(sub, data, root) then | |
| 150 return false | 139 return false |
| 151 end | 140 end |
| 152 | 141 end |
| 153 local validator = type_validators[schema.type] | 142 end |
| 154 if validator then | 143 |
| 155 return validator(schema, data, root) | 144 if schema.oneOf then |
| 156 end | 145 local valid = 0 |
| 157 end | 146 for _, sub in ipairs(schema.oneOf) do |
| 158 return true | 147 if validate(sub, data, root) then |
| 159 end | 148 valid = valid + 1 |
| 160 end | 149 end |
| 161 | 150 end |
| 162 type_validators.table = function(schema, data, root) | 151 if valid ~= 1 then |
| 152 return false | |
| 153 end | |
| 154 end | |
| 155 | |
| 156 if schema.anyOf then | |
| 157 local match = false | |
| 158 for _, sub in ipairs(schema.anyOf) do | |
| 159 if validate(sub, data, root) then | |
| 160 match = true | |
| 161 break | |
| 162 end | |
| 163 end | |
| 164 if not match then | |
| 165 return false | |
| 166 end | |
| 167 end | |
| 168 | |
| 169 if schema["not"] then | |
| 170 if validate(schema["not"], data, root) then | |
| 171 return false | |
| 172 end | |
| 173 end | |
| 174 | |
| 175 if schema["if"] ~= nil then | |
| 176 if validate(schema["if"], data, root) then | |
| 177 if schema["then"] then | |
| 178 return validate(schema["then"], data, root) | |
| 179 end | |
| 180 else | |
| 181 if schema["else"] then | |
| 182 return validate(schema["else"], data, root) | |
| 183 end | |
| 184 end | |
| 185 end | |
| 186 | |
| 187 if schema.const ~= nil and schema.const ~= data then | |
| 188 return false | |
| 189 end | |
| 190 | |
| 163 if type(data) == "table" then | 191 if type(data) == "table" then |
| 164 | 192 |
| 165 if schema.maxItems and #data > schema.maxItems then | 193 if schema.maxItems and #data > schema.maxItems then |
| 166 return false | 194 return false |
| 167 end | 195 end |
| 176 return false | 204 return false |
| 177 end | 205 end |
| 178 end | 206 end |
| 179 end | 207 end |
| 180 | 208 |
| 209 if schema.propertyNames ~= nil then | |
| 210 for k in pairs(data) do | |
| 211 if not validate(schema.propertyNames, k, root) then | |
| 212 return false | |
| 213 end | |
| 214 end | |
| 215 end | |
| 216 | |
| 181 if schema.properties then | 217 if schema.properties then |
| 182 local additional = schema.additionalProperties or true | 218 for k, sub in pairs(schema.properties) do |
| 219 if data[k] ~= nil and not validate(sub, data[k], root) then | |
| 220 return false | |
| 221 end | |
| 222 end | |
| 223 end | |
| 224 | |
| 225 if schema.additionalProperties ~= nil then | |
| 183 for k, v in pairs(data) do | 226 for k, v in pairs(data) do |
| 184 if schema.propertyNames and not validate(schema.propertyNames, k, root) then | 227 if schema.properties == nil or schema.properties[k] == nil then |
| 185 return false | 228 if not validate(schema.additionalProperties, v, root) then |
| 186 end | 229 return false |
| 187 local s = schema.properties[k] or additional | 230 end |
| 188 if not validate(s, v, root) then | |
| 189 return false | |
| 190 end | |
| 191 end | |
| 192 elseif schema.additionalProperties then | |
| 193 for k, v in pairs(data) do | |
| 194 if schema.propertyNames and not validate(schema.propertyNames, k, root) then | |
| 195 return false | |
| 196 end | |
| 197 if not validate(schema.additionalProperties, v, root) then | |
| 198 return false | |
| 199 end | 231 end |
| 200 end | 232 end |
| 201 end | 233 end |
| 202 | 234 |
| 203 if schema.uniqueItems then | 235 if schema.uniqueItems then |
| 210 values[v] = true | 242 values[v] = true |
| 211 end | 243 end |
| 212 end | 244 end |
| 213 | 245 |
| 214 local p = 0 | 246 local p = 0 |
| 215 if schema.prefixItems then | 247 if schema.prefixItems ~= nil then |
| 216 for i, s in ipairs(schema.prefixItems) do | 248 for i, s in ipairs(schema.prefixItems) do |
| 217 if validate(s, data[i], root) then | 249 if data[i] == nil then |
| 250 break | |
| 251 elseif validate(s, data[i], root) then | |
| 218 p = i | 252 p = i |
| 219 else | 253 else |
| 220 return false | 254 return false |
| 221 end | 255 end |
| 222 end | 256 end |
| 223 end | 257 end |
| 224 | 258 |
| 225 if schema.items then | 259 if schema.items ~= nil then |
| 226 for i = p + 1, #data do | 260 for i = p + 1, #data do |
| 227 if not validate(schema.items, data[i], root) then | 261 if not validate(schema.items, data[i], root) then |
| 228 return false | 262 return false |
| 229 end | 263 end |
| 230 end | 264 end |
| 231 end | 265 end |
| 232 | 266 |
| 233 if schema.contains then | 267 if schema.contains ~= nil then |
| 234 local found = false | 268 local found = false |
| 235 for i = 1, #data do | 269 for i = 1, #data do |
| 236 if validate(schema.contains, data[i], root) then | 270 if validate(schema.contains, data[i], root) then |
| 237 found = true | 271 found = true |
| 238 break | 272 break |
| 240 end | 274 end |
| 241 if not found then | 275 if not found then |
| 242 return false | 276 return false |
| 243 end | 277 end |
| 244 end | 278 end |
| 245 | 279 end |
| 246 return true | 280 |
| 247 end | 281 return true |
| 248 return false | |
| 249 end | 282 end |
| 250 | 283 |
| 251 type_validators.object = function(schema, data, root) | |
| 252 if type(data) == "table" then | |
| 253 for k in pairs(data) do | |
| 254 if not (type(k) == "string") then | |
| 255 return false | |
| 256 end | |
| 257 end | |
| 258 | |
| 259 return type_validators.table(schema, data, root) | |
| 260 end | |
| 261 return false | |
| 262 end | |
| 263 | |
| 264 type_validators.array = function(schema, data, root) | |
| 265 if type(data) == "table" then | |
| 266 | |
| 267 for i in pairs(data) do | |
| 268 if not (type(i) == "number") then | |
| 269 return false | |
| 270 end | |
| 271 end | |
| 272 | |
| 273 return type_validators.table(schema, data, root) | |
| 274 end | |
| 275 return false | |
| 276 end | |
| 277 | |
| 278 json_schema_object.validate = validate; | 284 json_schema_object.validate = validate; |
| 279 | 285 |
| 280 return json_schema_object | 286 return json_schema_object |