Ruslan Talpa 9 vuotta sitten
vanhempi
commit
1dda8572b0
3 muutettua tiedostoa jossa 33 lisäystä ja 24 poistoa
  1. 3 0
      graphql/schema.lua
  2. 20 24
      graphql/types.lua
  3. 10 0
      graphql/util.lua

+ 3 - 0
graphql/schema.lua

@@ -24,6 +24,8 @@ function schema.create(config)
   self.directiveMap = {}
 
   local function generateTypeMap(node)
+    if self.typeMap[node.name] and self.typeMap[node.name] == node then return end
+
     if node.__type == 'NonNull' or node.__type == 'List' then
       return generateTypeMap(node.ofType)
     end
@@ -43,6 +45,7 @@ function schema.create(config)
     end
 
     if node.__type == 'Object' or node.__type == 'Interface' or node.__type == 'InputObject' then
+      if type(node.fields) == 'function' then node.fields = node.fields() end
       for fieldName, field in pairs(node.fields) do
         if field.arguments then
           for _, argument in pairs(field.arguments) do

+ 20 - 24
graphql/types.lua

@@ -1,3 +1,6 @@
+local path = (...):gsub('%.[^%.]+$', '')
+local util = require(path .. '.util')
+
 local types = {}
 
 function types.nonNull(kind)
@@ -47,24 +50,12 @@ function types.object(config)
   if config.isTypeOf then
     assert(type(config.isTypeOf) == 'function', 'must provide isTypeOf as a function')
   end
-  assert(type(config.fields) == 'table', 'fields table must be provided')
-
-  local fields = {}
-  for fieldName, field in pairs(config.fields) do
-    field = field.__type and { kind = field } or field
-    fields[fieldName] = {
-      name = fieldName,
-      kind = field.kind,
-      arguments = field.arguments or {},
-      resolve = field.resolve
-    }
-  end
 
   local instance = {
     __type = 'Object',
     name = config.name,
     isTypeOf = config.isTypeOf,
-    fields = fields,
+    fields = type(config.fields) == 'function' and util.compose(util.bind1(initFields, 'Object'), config.fields) or initFields('Object', config.fields),
     interfaces = config.interfaces
   }
 
@@ -80,21 +71,11 @@ function types.interface(config)
     assert(type(config.resolveType) == 'function', 'must provide resolveType as a function')
   end
 
-  local fields = {}
-  for fieldName, field in pairs(config.fields) do
-    field = field.__type and { kind = field } or field
-    fields[fieldName] = {
-      name = fieldName,
-      kind = field.kind,
-      arguments = field.arguments or {}
-    }
-  end
-
   local instance = {
     __type = 'Interface',
     name = config.name,
     description = config.description,
-    fields = fields,
+    fields = type(config.fields) == 'function' and util.compose(util.bind1(initFields, 'Interface'), config.fields) or initFields('Interface', config.fields),
     resolveType = config.resolveType
   }
 
@@ -103,6 +84,21 @@ function types.interface(config)
   return instance
 end
 
+function initFields(kind, flds)
+  assert(type(flds) == 'table', 'fields table must be provided')
+  local fields = {}
+  for fieldName, field in pairs(flds) do
+    field = field.__type and { kind = field } or field
+    fields[fieldName] = {
+      name = fieldName,
+      kind = field.kind,
+      arguments = field.arguments or {},
+      resolve = kind == 'Object' and field.resolve or nil
+    }
+  end
+  return fields
+end
+
 function types.enum(config)
   assert(type(config.name) == 'string', 'type name must be provided as a string')
   assert(type(config.values) == 'table', 'values table must be provided')

+ 10 - 0
graphql/util.lua

@@ -73,4 +73,14 @@ function util.coerceValue(node, schemaType, variables)
   end
 end
 
+function util.compose (f,g)
+    return function(...) return f(g(...)) end
+end
+
+function util.bind1(func, val1)
+  return function (val2)
+    return func(val1, val2)
+  end
+end
+
 return util