schema.lua 2.0 KB

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