schema.lua 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. local types = require 'types'
  2. local schema = {}
  3. schema.__index = schema
  4. function schema.create(config)
  5. assert(type(config.query) == 'table', 'must provide query object')
  6. local self = {}
  7. for k, v in pairs(config) do
  8. self[k] = v
  9. end
  10. self.typeMap = {
  11. Int = types.int,
  12. Float = types.float,
  13. String = types.string,
  14. Boolean = types.boolean,
  15. ID = types.id
  16. }
  17. self.interfaceMap = {}
  18. self.directiveMap = {}
  19. local function generateTypeMap(node)
  20. if node.__type == 'NonNull' or node.__type == 'List' then
  21. return generateTypeMap(node.ofType)
  22. end
  23. if self.typeMap[node.name] and self.typeMap[node.name] ~= node then
  24. error('Encountered multiple types named "' .. node.name .. '"')
  25. end
  26. self.typeMap[node.name] = node
  27. if node.__type == 'Object' and node.interfaces then
  28. for _, interface in ipairs(node.interfaces) do
  29. generateTypeMap(interface)
  30. self.interfaceMap[interface.name] = self.interfaceMap[interface.name] or {}
  31. self.interfaceMap[interface.name][node] = node
  32. end
  33. end
  34. if node.__type == 'Object' or node.__type == 'Interface' or node.__type == 'InputObject' then
  35. for fieldName, field in pairs(node.fields) do
  36. if field.arguments then
  37. for _, argument in pairs(field.arguments) do
  38. generateTypeMap(argument)
  39. end
  40. end
  41. generateTypeMap(field.kind)
  42. end
  43. end
  44. end
  45. generateTypeMap(self.query)
  46. for _, directive in ipairs(self.directives) do
  47. self.directiveMap[directive.name] = directive
  48. end
  49. return setmetatable(self, schema)
  50. end
  51. function schema:getType(name)
  52. if not name then return end
  53. return self.typeMap[name]
  54. end
  55. function schema:getImplementors(interface)
  56. local kind = self:getType(interface)
  57. local isInterface = kind and kind.__type == 'Interface'
  58. return self.interfaceMap[interface] or (isInterface and {} or nil)
  59. end
  60. function schema:getDirective(name)
  61. if not name then return false end
  62. return self.directiveMap[name]
  63. end
  64. return schema