|
@@ -36,10 +36,22 @@ return function(schema, tree)
|
|
|
end,
|
|
|
|
|
|
field = function(node)
|
|
|
- if context.typeStack[#context.typeStack].__type == 'Scalar' and node.selectionSet then
|
|
|
- error('Scalar values cannot have selections')
|
|
|
+ local currentType = context.typeStack[#context.typeStack].__type
|
|
|
+ if currentType == 'Scalar' and node.selectionSet then
|
|
|
+ error('Scalar values cannot have subselections')
|
|
|
end
|
|
|
|
|
|
+ local isCompositeType = currentType == 'Object' or currentType == 'Interface' or currentType == 'Union'
|
|
|
+ if isCompositeType and not node.selectionSet then
|
|
|
+ error('Composite types must have subselections')
|
|
|
+ end
|
|
|
+
|
|
|
+ if node.selectionSet then
|
|
|
+ return {node.selectionSet}
|
|
|
+ end
|
|
|
+ end,
|
|
|
+
|
|
|
+ inlineFragment = function(node)
|
|
|
if node.selectionSet then
|
|
|
return {node.selectionSet}
|
|
|
end
|
|
@@ -53,7 +65,25 @@ return function(schema, tree)
|
|
|
table.insert(context.typeStack, schema.query)
|
|
|
elseif node.kind == 'field' then
|
|
|
local parent = context.typeStack[#context.typeStack]
|
|
|
- table.insert(context.typeStack, parent.fields[node.name.value].kind)
|
|
|
+ if parent.fields[node.name.value] then
|
|
|
+ table.insert(context.typeStack, parent.fields[node.name.value].kind)
|
|
|
+ else
|
|
|
+ error('Field "' .. node.name.value .. '" is not defined on type "' .. parent.name .. '"')
|
|
|
+ end
|
|
|
+ elseif node.kind == 'inlineFragment' then
|
|
|
+ if node.typeCondition then
|
|
|
+ local kind = schema:getType(node.typeCondition.name.value)
|
|
|
+
|
|
|
+ if not kind then
|
|
|
+ error('Inline fragment type condition refers to non-existent type')
|
|
|
+ end
|
|
|
+
|
|
|
+ if kind and kind.__type ~= 'Object' and kind.__type ~= 'Interface' and kind.__type ~= 'Union' then
|
|
|
+ error('Inline fragment type condition was not an Object, Interface, or Union')
|
|
|
+ end
|
|
|
+
|
|
|
+ table.insert(context.typeStack, kind)
|
|
|
+ end
|
|
|
end
|
|
|
|
|
|
local targets = visitors[node.kind](node)
|