schema.lua 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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. self.directives = self.directives or {
  48. types.include,
  49. types.skip
  50. }
  51. if self.directives then
  52. for _, directive in ipairs(self.directives) do
  53. self.directiveMap[directive.name] = directive
  54. end
  55. end
  56. return setmetatable(self, schema)
  57. end
  58. function schema:getType(name)
  59. if not name then return end
  60. return self.typeMap[name]
  61. end
  62. function schema:getImplementors(interface)
  63. local kind = self:getType(interface)
  64. local isInterface = kind and kind.__type == 'Interface'
  65. return self.interfaceMap[interface] or (isInterface and {} or nil)
  66. end
  67. function schema:getDirective(name)
  68. if not name then return false end
  69. return self.directiveMap[name]
  70. end
  71. return schema