2
0

validate.lua 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. return function(schema, tree)
  2. local context = {
  3. operationNames = {},
  4. hasAnonymousOperation = false,
  5. typeStack = {}
  6. }
  7. local visitors = {
  8. document = function(node)
  9. return node.definitions
  10. end,
  11. operation = function(node)
  12. local name = node.name and node.name.value
  13. if name then
  14. if context.operationNames[name] then
  15. error('Multiple operations exist named "' .. name .. '"')
  16. else
  17. context.operationNames[name] = true
  18. end
  19. else
  20. if context.hasAnonymousOperation or next(context.operationNames) then
  21. error('Cannot have more than one operation when using anonymous operations')
  22. end
  23. context.hasAnonymousOperation = true
  24. end
  25. return {node.selectionSet}
  26. end,
  27. selectionSet = function(node)
  28. return node.selections
  29. end,
  30. field = function(node)
  31. if context.typeStack[#context.typeStack].__type == 'Scalar' and node.selectionSet then
  32. error('Scalar values cannot have selections')
  33. end
  34. if node.selectionSet then
  35. return {node.selectionSet}
  36. end
  37. end
  38. }
  39. local root = schema.query
  40. local function visit(node)
  41. if node.kind and visitors[node.kind] then
  42. if node.kind == 'operation' then
  43. table.insert(context.typeStack, schema.query)
  44. elseif node.kind == 'field' then
  45. local parent = context.typeStack[#context.typeStack]
  46. table.insert(context.typeStack, parent.fields[node.name.value].kind)
  47. end
  48. local targets = visitors[node.kind](node)
  49. if targets then
  50. for _, target in ipairs(targets) do
  51. visit(target)
  52. end
  53. end
  54. end
  55. end
  56. visit(tree)
  57. end