diff --git a/src/Type/Definition/Config.php b/src/Type/Definition/Config.php index d5bd057..a561549 100644 --- a/src/Type/Definition/Config.php +++ b/src/Type/Definition/Config.php @@ -65,11 +65,30 @@ class Config public static function validate(array $config, array $definition) { if (self::$enableValidation) { - $name = isset($config['name']) ? $config['name'] : 'UnnamedType'; + $name = isset($config['name']) ? $config['name'] : '(Unnamed Type)'; self::validateMap($name, $config, $definition); } } + /** + * @param $typeName + * @param array $config + * @param array $definition + */ + public static function validateField($typeName, array $config, array $definition) + { + if (self::$enableValidation) { + if (!isset($config['name'])) { + $pathStr = isset($config['type']) + ? '(Unknown Field of type: ' . Utils::printSafe($config['type']) . ')' + : '(Unknown Field)'; + } else { + $pathStr = ''; + } + self::validateMap($typeName ?: '(Unnamed Type)', $config, $definition, $pathStr); + } + } + /** * @param $definition * @param int $flags @@ -121,7 +140,10 @@ class Config // Make sure that all required keys are present in map $requiredKeys = array_filter($definitions, function($def) {return (self::getFlags($def) & self::REQUIRED) > 0;}); $missingKeys = array_keys(array_diff_key($requiredKeys, $map)); - Utils::invariant(empty($missingKeys), 'Error in "'.$typeName.'" type definition: Required keys missing: "%s"' . $suffix, implode(', ', $missingKeys)); + Utils::invariant( + empty($missingKeys), + "Error in '$typeName' type definition: Required keys missing: '%s' $suffix", implode(', ', $missingKeys) + ); // Make sure that every map value is valid given the definition foreach ($map as $key => $value) { @@ -226,28 +248,28 @@ class Config Utils::invariant( is_callable($value) || $value instanceof InputType, $err, - 'callable or instance of GraphQL\Type\Definition\InputType' + 'callable or InputType definition' ); break; case $def & self::OUTPUT_TYPE: Utils::invariant( is_callable($value) || $value instanceof OutputType, $err, - 'callable or instance of GraphQL\Type\Definition\OutputType' + 'callable or OutputType definition' ); break; case $def & self::INTERFACE_TYPE: Utils::invariant( is_callable($value) || $value instanceof InterfaceType, $err, - 'callable or instance of GraphQL\Type\Definition\InterfaceType' + 'callable or InterfaceType definition' ); break; case $def & self::OBJECT_TYPE: Utils::invariant( is_callable($value) || $value instanceof ObjectType, $err, - 'callable or instance of GraphQL\Type\Definition\ObjectType' + 'callable or ObjectType definition' ); break; default: diff --git a/src/Type/Definition/FieldDefinition.php b/src/Type/Definition/FieldDefinition.php index 81d1c53..4d13e21 100644 --- a/src/Type/Definition/FieldDefinition.php +++ b/src/Type/Definition/FieldDefinition.php @@ -1,5 +1,7 @@ $field) { if (!is_array($field)) { - $field = ['type' => $field]; - } - if (!isset($field['name'])) { + if (is_string($name)) { + $field = ['name' => $name, 'type' => $field]; + } else { + throw new InvariantViolation( + "Unexpected field definition for type $typeName at key $name: " . Utils::printSafe($field) + ); + } + } elseif (!isset($field['name']) && is_string($name)) { $field['name'] = $name; } - $map[$name] = self::create($field); + $map[$name] = self::create($field, $typeName); } return $map; } /** * @param array|Config $field + * @param string $typeName * @return FieldDefinition */ - public static function create($field) + public static function create($field, $typeName = null) { - Config::validate($field, self::getDefinition()); + if ($typeName) { + Config::validateField($typeName, $field, self::getDefinition()); + } return new self($field); } diff --git a/src/Type/Definition/InterfaceType.php b/src/Type/Definition/InterfaceType.php index 2d077bd..a34da04 100644 --- a/src/Type/Definition/InterfaceType.php +++ b/src/Type/Definition/InterfaceType.php @@ -60,7 +60,7 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT $this->fields = []; $fields = isset($this->config['fields']) ? $this->config['fields'] : []; $fields = is_callable($fields) ? call_user_func($fields) : $fields; - $this->fields = FieldDefinition::createMap($fields); + $this->fields = FieldDefinition::createMap($fields, $this->name); } return $this->fields; } diff --git a/src/Type/Definition/ObjectType.php b/src/Type/Definition/ObjectType.php index 6836e89..e094a38 100644 --- a/src/Type/Definition/ObjectType.php +++ b/src/Type/Definition/ObjectType.php @@ -112,7 +112,7 @@ class ObjectType extends Type implements OutputType, CompositeType if (null === $this->fields) { $fields = isset($this->config['fields']) ? $this->config['fields'] : []; $fields = is_callable($fields) ? call_user_func($fields) : $fields; - $this->fields = FieldDefinition::createMap($fields); + $this->fields = FieldDefinition::createMap($fields, $this->name); } return $this->fields; }