schema.lua 2.1 KB

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