/** * @return Schema */ public static function getDefaultSchema() { $FurColor = null; $Being = new InterfaceType(['name' => 'Being', 'fields' => ['name' => ['type' => Type::string(), 'args' => ['surname' => ['type' => Type::boolean()]]]]]); $Pet = new InterfaceType(['name' => 'Pet', 'fields' => ['name' => ['type' => Type::string(), 'args' => ['surname' => ['type' => Type::boolean()]]]]]); $Canine = new InterfaceType(['name' => 'Canine', 'fields' => function () { return ['name' => ['type' => Type::string(), 'args' => ['surname' => ['type' => Type::boolean()]]]]; }]); $DogCommand = new EnumType(['name' => 'DogCommand', 'values' => ['SIT' => ['value' => 0], 'HEEL' => ['value' => 1], 'DOWN' => ['value' => 2]]]); $Dog = new ObjectType(['name' => 'Dog', 'isTypeOf' => function () { return true; }, 'fields' => ['name' => ['type' => Type::string(), 'args' => ['surname' => ['type' => Type::boolean()]]], 'nickname' => ['type' => Type::string()], 'barkVolume' => ['type' => Type::int()], 'barks' => ['type' => Type::boolean()], 'doesKnowCommand' => ['type' => Type::boolean(), 'args' => ['dogCommand' => ['type' => $DogCommand]]], 'isHousetrained' => ['type' => Type::boolean(), 'args' => ['atOtherHomes' => ['type' => Type::boolean(), 'defaultValue' => true]]], 'isAtLocation' => ['type' => Type::boolean(), 'args' => ['x' => ['type' => Type::int()], 'y' => ['type' => Type::int()]]]], 'interfaces' => [$Being, $Pet, $Canine]]); $Cat = new ObjectType(['name' => 'Cat', 'isTypeOf' => function () { return true; }, 'fields' => function () use(&$FurColor) { return ['name' => ['type' => Type::string(), 'args' => ['surname' => ['type' => Type::boolean()]]], 'nickname' => ['type' => Type::string()], 'meows' => ['type' => Type::boolean()], 'meowVolume' => ['type' => Type::int()], 'furColor' => $FurColor]; }, 'interfaces' => [$Being, $Pet]]); $CatOrDog = new UnionType(['name' => 'CatOrDog', 'types' => [$Dog, $Cat], 'resolveType' => function ($value) { // not used for validation return null; }]); $Intelligent = new InterfaceType(['name' => 'Intelligent', 'fields' => ['iq' => ['type' => Type::int()]]]); $Human = null; $Human = new ObjectType(['name' => 'Human', 'isTypeOf' => function () { return true; }, 'interfaces' => [$Being, $Intelligent], 'fields' => function () use(&$Human, $Pet) { return ['name' => ['type' => Type::string(), 'args' => ['surname' => ['type' => Type::boolean()]]], 'pets' => ['type' => Type::listOf($Pet)], 'relatives' => ['type' => Type::listOf($Human)], 'iq' => ['type' => Type::int()]]; }]); $Alien = new ObjectType(['name' => 'Alien', 'isTypeOf' => function () { return true; }, 'interfaces' => [$Being, $Intelligent], 'fields' => ['iq' => ['type' => Type::int()], 'name' => ['type' => Type::string(), 'args' => ['surname' => ['type' => Type::boolean()]]], 'numEyes' => ['type' => Type::int()]]]); $DogOrHuman = new UnionType(['name' => 'DogOrHuman', 'types' => [$Dog, $Human], 'resolveType' => function () { // not used for validation return null; }]); $HumanOrAlien = new UnionType(['name' => 'HumanOrAlien', 'types' => [$Human, $Alien], 'resolveType' => function () { // not used for validation return null; }]); $FurColor = new EnumType(['name' => 'FurColor', 'values' => ['BROWN' => ['value' => 0], 'BLACK' => ['value' => 1], 'TAN' => ['value' => 2], 'SPOTTED' => ['value' => 3]]]); $ComplexInput = new InputObjectType(['name' => 'ComplexInput', 'fields' => ['requiredField' => ['type' => Type::nonNull(Type::boolean())], 'intField' => ['type' => Type::int()], 'stringField' => ['type' => Type::string()], 'booleanField' => ['type' => Type::boolean()], 'stringListField' => ['type' => Type::listOf(Type::string())]]]); $ComplicatedArgs = new ObjectType(['name' => 'ComplicatedArgs', 'fields' => ['intArgField' => ['type' => Type::string(), 'args' => ['intArg' => ['type' => Type::int()]]], 'nonNullIntArgField' => ['type' => Type::string(), 'args' => ['nonNullIntArg' => ['type' => Type::nonNull(Type::int())]]], 'stringArgField' => ['type' => Type::string(), 'args' => ['stringArg' => ['type' => Type::string()]]], 'booleanArgField' => ['type' => Type::string(), 'args' => ['booleanArg' => ['type' => Type::boolean()]]], 'enumArgField' => ['type' => Type::string(), 'args' => ['enumArg' => ['type' => $FurColor]]], 'floatArgField' => ['type' => Type::string(), 'args' => ['floatArg' => ['type' => Type::float()]]], 'idArgField' => ['type' => Type::string(), 'args' => ['idArg' => ['type' => Type::id()]]], 'stringListArgField' => ['type' => Type::string(), 'args' => ['stringListArg' => ['type' => Type::listOf(Type::string())]]], 'complexArgField' => ['type' => Type::string(), 'args' => ['complexArg' => ['type' => $ComplexInput]]], 'multipleReqs' => ['type' => Type::string(), 'args' => ['req1' => ['type' => Type::nonNull(Type::int())], 'req2' => ['type' => Type::nonNull(Type::int())]]], 'multipleOpts' => ['type' => Type::string(), 'args' => ['opt1' => ['type' => Type::int(), 'defaultValue' => 0], 'opt2' => ['type' => Type::int(), 'defaultValue' => 0]]], 'multipleOptAndReq' => ['type' => Type::string(), 'args' => ['req1' => ['type' => Type::nonNull(Type::int())], 'req2' => ['type' => Type::nonNull(Type::int())], 'opt1' => ['type' => Type::int(), 'defaultValue' => 0], 'opt2' => ['type' => Type::int(), 'defaultValue' => 0]]]]]); $queryRoot = new ObjectType(['name' => 'QueryRoot', 'fields' => ['human' => ['args' => ['id' => ['type' => Type::id()]], 'type' => $Human], 'alien' => ['type' => $Alien], 'dog' => ['type' => $Dog], 'cat' => ['type' => $Cat], 'pet' => ['type' => $Pet], 'catOrDog' => ['type' => $CatOrDog], 'dogOrHuman' => ['type' => $DogOrHuman], 'humanOrAlien' => ['type' => $HumanOrAlien], 'complicatedArgs' => ['type' => $ComplicatedArgs]]]); $defaultSchema = new Schema(['query' => $queryRoot, 'directives' => array_merge(GraphQL::getInternalDirectives(), [new Directive(['name' => 'operationOnly', 'locations' => ['QUERY']])])]); return $defaultSchema; }
/** * @param array $config */ protected function init(array $config) { $config += ['query' => null, 'mutation' => null, 'subscription' => null, 'types' => [], 'directives' => [], 'validate' => true]; if ($config['query'] instanceof DefinitionContainer) { $config['query'] = $config['query']->getDefinition(); } if ($config['mutation'] instanceof DefinitionContainer) { $config['mutation'] = $config['mutation']->getDefinition(); } if ($config['subscription'] instanceof DefinitionContainer) { $config['subscription'] = $config['subscription']->getDefinition(); } Utils::invariant($config['query'] instanceof ObjectType, "Schema query must be Object Type but got: " . Utils::getVariableType($config['query'])); $this->queryType = $config['query']; Utils::invariant(!$config['mutation'] || $config['mutation'] instanceof ObjectType, "Schema mutation must be Object Type if provided but got: " . Utils::getVariableType($config['mutation'])); $this->mutationType = $config['mutation']; Utils::invariant(!$config['subscription'] || $config['subscription'] instanceof ObjectType, "Schema subscription must be Object Type if provided but got: " . Utils::getVariableType($config['subscription'])); $this->subscriptionType = $config['subscription']; Utils::invariant(!$config['types'] || is_array($config['types']), "Schema types must be Array if provided but got: " . Utils::getVariableType($config['types'])); Utils::invariant(!$config['directives'] || is_array($config['directives']) && Utils::every($config['directives'], function ($d) { return $d instanceof Directive; }), "Schema directives must be Directive[] if provided but got " . Utils::getVariableType($config['directives'])); $this->directives = $config['directives'] ?: GraphQL::getInternalDirectives(); // Build type map now to detect any errors within this schema. $initialTypes = [$config['query'], $config['mutation'], $config['subscription'], Introspection::_schema()]; if (!empty($config['types'])) { $initialTypes = array_merge($initialTypes, $config['types']); } foreach ($initialTypes as $type) { $this->extractTypes($type); } $this->typeMap += Type::getInternalTypes(); // Keep track of all implementations by interface name. $this->implementations = []; foreach ($this->typeMap as $typeName => $type) { if ($type instanceof ObjectType) { foreach ($type->getInterfaces() as $iface) { $this->implementations[$iface->name][] = $type; } } } }