mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-22 12:56:05 +03:00
Updated config validation rules
This commit is contained in:
parent
6d7a4a4f34
commit
2b305ad6e2
@ -27,12 +27,18 @@ class Config
|
|||||||
const KEY_AS_NAME = 131072;
|
const KEY_AS_NAME = 131072;
|
||||||
const MAYBE_THUNK = 262144;
|
const MAYBE_THUNK = 262144;
|
||||||
const MAYBE_TYPE = 524288;
|
const MAYBE_TYPE = 524288;
|
||||||
|
const MAYBE_NAME = 1048576;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private static $enableValidation = false;
|
private static $enableValidation = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private static $allowCustomOptions = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables config validation
|
* Disables config validation
|
||||||
*/
|
*/
|
||||||
@ -45,9 +51,10 @@ class Config
|
|||||||
* Enable deep config validation (disabled by default because it creates significant performance overhead).
|
* Enable deep config validation (disabled by default because it creates significant performance overhead).
|
||||||
* Useful only at development to catch type definition errors quickly.
|
* Useful only at development to catch type definition errors quickly.
|
||||||
*/
|
*/
|
||||||
public static function enableValidation()
|
public static function enableValidation($allowCustomOptions = true)
|
||||||
{
|
{
|
||||||
self::$enableValidation = true;
|
self::$enableValidation = true;
|
||||||
|
self::$allowCustomOptions = $allowCustomOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,8 +109,11 @@ class Config
|
|||||||
|
|
||||||
// Make sure there are no unexpected keys in map
|
// Make sure there are no unexpected keys in map
|
||||||
$unexpectedKeys = array_keys(array_diff_key($map, $definitions));
|
$unexpectedKeys = array_keys(array_diff_key($map, $definitions));
|
||||||
|
|
||||||
if (!empty($unexpectedKeys)) {
|
if (!empty($unexpectedKeys)) {
|
||||||
trigger_error(sprintf('"%s" type definition: Unexpected keys "%s" ' . $suffix, $typeName, implode(', ', $unexpectedKeys)));
|
if (!self::$allowCustomOptions) {
|
||||||
|
trigger_error(sprintf('"%s" type definition: Non-standard keys "%s" ' . $suffix, $typeName, implode(', ', $unexpectedKeys)));
|
||||||
|
}
|
||||||
$map = array_intersect_key($map, $definitions);
|
$map = array_intersect_key($map, $definitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,29 +162,32 @@ class Config
|
|||||||
Utils::invariant(!empty($value), 'Error in "'.$typeName.'" type definition: ' . "Value at '$pathStr' cannot be empty array");
|
Utils::invariant(!empty($value), 'Error in "'.$typeName.'" type definition: ' . "Value at '$pathStr' cannot be empty array");
|
||||||
}
|
}
|
||||||
|
|
||||||
$err = 'Error in "'.$typeName.'" type definition:' . "Each entry at '$pathStr' must be an array, but '%s' is '%s'";
|
$err = 'Error in "'.$typeName.'" type definition: ' . "Each entry at '$pathStr' must be an array, but '%s' is '%s'";
|
||||||
|
|
||||||
foreach ($value as $arrKey => $arrValue) {
|
foreach ($value as $arrKey => $arrValue) {
|
||||||
if (is_array($def->definition)) {
|
if (is_array($def->definition)) {
|
||||||
if ($def->flags & self::MAYBE_TYPE) {
|
if ($def->flags & self::MAYBE_TYPE && $arrValue instanceof Type) {
|
||||||
Utils::invariant(is_array($arrValue) || $arrValue instanceof Type, $err, $arrKey, Utils::getVariableType($arrValue));
|
$arrValue = ['type' => $arrValue];
|
||||||
} else {
|
|
||||||
Utils::invariant(is_array($arrValue), $err, $arrKey, Utils::getVariableType($arrValue));
|
|
||||||
}
|
}
|
||||||
|
if ($def->flags & self::MAYBE_NAME && is_string($arrValue)) {
|
||||||
|
$arrValue = ['name' => $arrValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::invariant(is_array($arrValue), $err, $arrKey, Utils::getVariableType($arrValue));
|
||||||
|
|
||||||
if ($def->flags & self::KEY_AS_NAME) {
|
if ($def->flags & self::KEY_AS_NAME) {
|
||||||
$arrValue += ['name' => $arrKey];
|
$arrValue += ['name' => $arrKey];
|
||||||
}
|
}
|
||||||
self::validateMap($typeName, $arrValue, $def->definition, "$pathStr:$arrKey");
|
self::validateMap($typeName, $arrValue, $def->definition, "$pathStr: $arrKey");
|
||||||
} else {
|
} else {
|
||||||
self::validateEntry($typeName, $arrKey, $arrValue, $def->definition, "$pathStr:$arrKey");
|
self::validateEntry($typeName, $arrKey, $arrValue, $def->definition, "$pathStr: $arrKey");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new \Exception('Error in "'.$typeName.'" type definition:' . "unexpected definition: " . print_r($def, true));
|
throw new \Exception('Error in "'.$typeName.'" type definition: ' . "unexpected definition: " . print_r($def, true));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Utils::invariant(is_int($def), 'Error in "'.$typeName.'" type definition:' . "Definition for '$pathStr' is expected to be single integer value");
|
Utils::invariant(is_int($def), 'Error in "'.$typeName.'" type definition: ' . "Definition for '$pathStr' is expected to be single integer value");
|
||||||
|
|
||||||
if ($def & self::REQUIRED) {
|
if ($def & self::REQUIRED) {
|
||||||
Utils::invariant($value !== null, 'Value at "%s" can not be null', $pathStr);
|
Utils::invariant($value !== null, 'Value at "%s" can not be null', $pathStr);
|
||||||
|
@ -34,7 +34,7 @@ class EnumType extends Type implements InputType, OutputType, LeafType
|
|||||||
'value' => Config::ANY,
|
'value' => Config::ANY,
|
||||||
'deprecationReason' => Config::STRING,
|
'deprecationReason' => Config::STRING,
|
||||||
'description' => Config::STRING
|
'description' => Config::STRING
|
||||||
], Config::KEY_AS_NAME),
|
], Config::KEY_AS_NAME | Config::MAYBE_NAME),
|
||||||
'description' => Config::STRING
|
'description' => Config::STRING
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class FieldDefinition
|
|||||||
'type' => Config::INPUT_TYPE | Config::REQUIRED,
|
'type' => Config::INPUT_TYPE | Config::REQUIRED,
|
||||||
'description' => Config::STRING,
|
'description' => Config::STRING,
|
||||||
'defaultValue' => Config::ANY
|
'defaultValue' => Config::ANY
|
||||||
], Config::KEY_AS_NAME),
|
], Config::KEY_AS_NAME | Config::MAYBE_TYPE),
|
||||||
'resolve' => Config::CALLBACK,
|
'resolve' => Config::CALLBACK,
|
||||||
'map' => Config::CALLBACK,
|
'map' => Config::CALLBACK,
|
||||||
'description' => Config::STRING,
|
'description' => Config::STRING,
|
||||||
|
@ -39,7 +39,7 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT
|
|||||||
'name' => Config::STRING,
|
'name' => Config::STRING,
|
||||||
'fields' => Config::arrayOf(
|
'fields' => Config::arrayOf(
|
||||||
FieldDefinition::getDefinition(),
|
FieldDefinition::getDefinition(),
|
||||||
Config::KEY_AS_NAME | Config::MAYBE_THUNK
|
Config::KEY_AS_NAME | Config::MAYBE_THUNK | Config::MAYBE_TYPE
|
||||||
),
|
),
|
||||||
'resolveType' => Config::CALLBACK, // function($value, $context, ResolveInfo $info) => ObjectType
|
'resolveType' => Config::CALLBACK, // function($value, $context, ResolveInfo $info) => ObjectType
|
||||||
'description' => Config::STRING
|
'description' => Config::STRING
|
||||||
|
Loading…
Reference in New Issue
Block a user