/** * Prepares an object map of variables of the correct type based on the provided * variable definitions and arbitrary input. If the input cannot be coerced * to match the variable definitions, a Error will be thrown. * * @param Schema $schema * @param VariableDefinitionNode[] $definitionNodes * @param array $inputs * @return array * @throws Error */ public static function getVariableValues(Schema $schema, $definitionNodes, array $inputs) { $coercedValues = []; foreach ($definitionNodes as $definitionNode) { $varName = $definitionNode->variable->name->value; $varType = Utils\TypeInfo::typeFromAST($schema, $definitionNode->type); if (!Type::isInputType($varType)) { throw new Error('Variable "$' . $varName . '" expected value of type ' . '"' . Printer::doPrint($definitionNode->type) . '" which cannot be used as an input type.', [$definitionNode->type]); } if (!array_key_exists($varName, $inputs)) { $defaultValue = $definitionNode->defaultValue; if ($defaultValue) { $coercedValues[$varName] = Utils\AST::valueFromAST($defaultValue, $varType); } if ($varType instanceof NonNull) { throw new Error('Variable "$' . $varName . '" of required type ' . '"' . Utils::printSafe($varType) . '" was not provided.', [$definitionNode]); } } else { $value = $inputs[$varName]; $errors = self::isValidPHPValue($value, $varType); if (!empty($errors)) { $message = "\n" . implode("\n", $errors); throw new Error('Variable "$' . $varName . '" got invalid value ' . json_encode($value) . '.' . $message, [$definitionNode]); } $coercedValue = self::coerceValue($varType, $value); Utils::invariant($coercedValue !== Utils::undefined(), 'Should have reported error.'); $coercedValues[$varName] = $coercedValue; } } return $coercedValues; }
/** * Given a variable definition, and any value of input, return a value which * adheres to the variable definition, or throw an error. */ private static function getVariableValue(Schema $schema, VariableDefinition $definitionAST, $input) { $type = Utils\TypeInfo::typeFromAST($schema, $definitionAST->type); $variable = $definitionAST->variable; if (!$type || !Type::isInputType($type)) { $printed = Printer::doPrint($definitionAST->type); throw new Error("Variable \"\${$variable->name->value}\" expected value of type " . "\"{$printed}\" which cannot be used as an input type.", [$definitionAST]); } $inputType = $type; $errors = self::isValidPHPValue($input, $inputType); if (empty($errors)) { if (null === $input) { $defaultValue = $definitionAST->defaultValue; if ($defaultValue) { return Utils\AST::valueFromAST($defaultValue, $inputType); } } return self::coerceValue($inputType, $input); } if (null === $input) { $printed = Printer::doPrint($definitionAST->type); throw new Error("Variable \"\${$variable->name->value}\" of required type " . "\"{$printed}\" was not provided.", [$definitionAST]); } $message = $errors ? "\n" . implode("\n", $errors) : ''; $val = json_encode($input); throw new Error("Variable \"\${$variable->name->value}\" got invalid value " . "{$val}.{$message}", [$definitionAST]); }
public function __invoke(ValidationContext $context) { return [NodeKind::VARIABLE_DEFINITION => function (VariableDefinitionNode $node) use($context) { $type = Utils\TypeInfo::typeFromAST($context->getSchema(), $node->type); // If the variable type is not an input type, return an error. if ($type && !Type::isInputType($type)) { $variableName = $node->variable->name->value; $context->reportError(new Error(self::nonInputTypeOnVarMessage($variableName, Printer::doPrint($node->type)), [$node->type])); } }]; }
public static function noOutputTypesAsInputArgsRule() { return function ($context) { /** @var Schema $schema */ $schema = $context['schema']; $typeMap = $schema->getTypeMap(); $errors = []; foreach ($typeMap as $typeName => $type) { if ($type instanceof InputObjectType) { $fields = $type->getFields(); foreach ($fields as $fieldName => $field) { if (!Type::isInputType($field->getType())) { $errors[] = new Error("Input field {$type->name}.{$field->name} has type " . "{$field->getType()}, which is not an input type!"); } } } } return !empty($errors) ? $errors : null; }; }
public function testIdentifiesInputTypes() { $expected = [[Type::int(), true], [$this->objectType, false], [$this->interfaceType, false], [$this->unionType, false], [$this->enumType, true], [$this->inputObjectType, true]]; foreach ($expected as $index => $entry) { $this->assertSame($entry[1], Type::isInputType($entry[0]), "Type {$entry[0]} was detected incorrectly"); } }
/** * Given a variable definition, and any value of input, return a value which * adheres to the variable definition, or throw an error. */ private static function getVariableValue(Schema $schema, VariableDefinition $definitionAST, $input) { $type = Utils\TypeInfo::typeFromAST($schema, $definitionAST->type); $variable = $definitionAST->variable; if (!$type || !Type::isInputType($type)) { $printed = Printer::doPrint($definitionAST->type); throw new Error("Variable \"\${$variable->name->value}\" expected value of type " . "\"{$printed}\" which cannot be used as an input type.", [$definitionAST]); } if (self::isValidValue($input, $type)) { if (null === $input) { $defaultValue = $definitionAST->defaultValue; if ($defaultValue) { return self::valueFromAST($defaultValue, $type); } } return self::coerceValue($type, $input); } throw new Error("Variable \${$definitionAST->variable->name->value} expected value of type " . Printer::doPrint($definitionAST->type) . " but got: " . json_encode($input) . '.', [$definitionAST]); }