Explorar el Código

uniqueInputObjectFields;

bjorn hace 9 años
padre
commit
590fa1817a
Se han modificado 3 ficheros con 44 adiciones y 10 borrados
  1. 1 1
      parse.lua
  2. 26 5
      rules.lua
  3. 17 4
      validate.lua

+ 1 - 1
parse.lua

@@ -69,7 +69,7 @@ end
 
 local function cObject(fields)
   return {
-    kind = 'object',
+    kind = 'inputObject',
     values = fields
   }
 end

+ 26 - 5
rules.lua

@@ -25,7 +25,7 @@ function rules.loneAnonymousOperation(node, context)
 end
 
 function rules.fieldsDefinedOnType(node, context)
-  if context.currentField == false then
+  if context.objects[#context.objects] == false then
     local parent = context.objects[#context.objects - 1]
     error('Field "' .. node.name.value .. '" is not defined on type "' .. parent.name .. '"')
   end
@@ -44,13 +44,13 @@ function rules.argumentsDefinedOnType(node, context)
 end
 
 function rules.scalarFieldsAreLeaves(node, context)
-  if context.currentField.__type == 'Scalar' and node.selectionSet then
+  if context.objects[#context.objects].__type == 'Scalar' and node.selectionSet then
     error('Scalar values cannot have subselections')
   end
 end
 
 function rules.compositeFieldsAreNotLeaves(node, context)
-  local _type = context.currentField.__type
+  local _type = context.objects[#context.objects].__type
   local isCompositeType = _type == 'Object' or _type == 'Interface' or _type == 'Union'
 
   if isCompositeType and not node.selectionSet then
@@ -189,8 +189,8 @@ function rules.argumentsOfCorrectType(node, context)
     end
 
     if argumentType.__type == 'InputObject' then
-      if valueNode.kind ~= 'object' then
-        error('Expected an object')
+      if valueNode.kind ~= 'inputObject' then
+        error('Expected an input object')
       end
 
       for _, field in ipairs(valueNode.values) do
@@ -363,4 +363,25 @@ function rules.fragmentSpreadIsPossible(node, context)
   end
 end
 
+function rules.uniqueInputObjectFields(node, context)
+  local function validateValue(value)
+    if value.kind == 'listType' or value.kind == 'nonNullType' then
+      return validateValue(value.type)
+    elseif value.kind == 'inputObject' then
+      local fieldMap = {}
+      for _, field in ipairs(value.values) do
+        if fieldMap[field.name] then
+          error('Multiple input object fields named "' .. field.name .. '"')
+        end
+
+        fieldMap[field.name] = true
+
+        validateValue(field.value)
+      end
+    end
+  end
+
+  validateValue(node.value)
+end
+
 return rules

+ 17 - 4
validate.lua

@@ -49,20 +49,29 @@ local visitors = {
       local parentField = context.objects[#context.objects].fields[node.name.value]
 
       -- false is a special value indicating that the field was not present in the type definition.
-      context.currentField = parentField and parentField.kind or false
+      local field = parentField and parentField.kind or false
 
-      table.insert(context.objects, context.currentField)
+      table.insert(context.objects, field)
     end,
 
     exit = function(node, context)
       table.remove(context.objects)
-      context.currentField = nil
     end,
 
     children = function(node)
+      local children = {}
+
+      if node.arguments then
+        for i = 1, #node.arguments do
+          table.insert(children, node.arguments[i])
+        end
+      end
+
       if node.selectionSet then
-        return {node.selectionSet}
+        table.insert(children, node.selectionSet)
       end
+
+      return children
     end,
 
     rules = {
@@ -128,6 +137,10 @@ local visitors = {
     end,
 
     rules = { rules.fragmentHasValidType, rules.fragmentDefinitionHasNoCycles }
+  },
+
+  argument = {
+    rules = { rules.uniqueInputObjectFields }
   }
 }