Skip to content

Commit 09dc6ed

Browse files
authored
feat: support $ref without full URI (#31)
1 parent 08cb122 commit 09dc6ed

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

lib/jsonschema/store.lua

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ local function urlunescape(fragment)
3636
return fragment:gsub('%%(%x%x)', percent_unescape):gsub('~[01]', tilde_unescape)
3737
end
3838

39-
-- attempt to translate a URI fragemnt part to a valid table index:
39+
-- attempt to translate a URI fragment part to a valid table index:
4040
-- * if the part can be converted to number, that number+1 is returned to
4141
-- compensate with Lua 1-based indices
4242
-- * otherwise, the part is returned URL-escaped
@@ -192,6 +192,16 @@ function store_mt:insert(schema)
192192
local map = {}
193193

194194
local function walk(s, p)
195+
-- handle '$id' keyword
196+
if s['$id'] then
197+
local u = url.parse(s['$id'])
198+
if u.schema ~= nil or u.fragment == nil then
199+
error("Only location independent id is supported. Unsupported $id: " .. s['$id'])
200+
end
201+
202+
map[u.fragment] = self:ref(s).schema
203+
end
204+
195205
local id = s.id
196206
if id and s ~= schema and is_schema(p) then
197207
-- there is an id, but it is not over: we have 2 different cases (!)

t/draft7.lua

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ local blacklist = {
3535
['contains keyword validation'] = {
3636
['not array is valid'] = true
3737
},
38+
-- not support: an external resolver is required
39+
['remote ref, containing refs itself'] = true,
40+
['Recursive references between schemas'] = true,
41+
['Location-independent identifier with absolute URI'] = true,
42+
['Location-independent identifier with base URI change in subschema'] = true,
3843
}
3944

4045
local supported = {
@@ -88,9 +93,10 @@ local supported = {
8893
'spec/JSON-Schema-Test-Suite/tests/draft7/const.json',
8994
'spec/JSON-Schema-Test-Suite/tests/draft7/contains.json',
9095

96+
-- ref
97+
'spec/JSON-Schema-Test-Suite/tests/draft7/ref.json',
9198
-- not support: an external resolver is required
9299
-- 'spec/JSON-Schema-Test-Suite/tests/draft7/refRemote.json',
93-
-- 'spec/JSON-Schema-Test-Suite/tests/draft7/ref.json',
94100
-- 'spec/JSON-Schema-Test-Suite/tests/draft7/definitions.json',
95101

96102
-- not support: todo
@@ -114,9 +120,12 @@ for _, descriptor in ipairs(supported) do
114120
for _, suite in decode_descriptor(descriptor) do
115121
local skipped = blacklist[suite.description] or {}
116122
if skipped ~= true then
117-
local validator = jsonschema.generate_validator(suite.schema, {
123+
local ok, validator = pcall(jsonschema.generate_validator, suite.schema, {
118124
name = suite.description,
119125
})
126+
if not ok then
127+
error("failed to generate validator for case " .. suite.description .. ", err: " .. validator)
128+
end
120129
for _, case in ipairs(suite.tests) do
121130
if skipped[case.description] then
122131
print("skip suite case: [" .. suite.description .. "] -> [" .. case.description .. "]")

0 commit comments

Comments
 (0)