shell bypass 403
UnknownSec Shell
:
/
home
/
forge
/
lolasweb.brannanatkinson.com
/
vendor
/
webonyx
/
graphql-php
/
src
/
Type
/ [
drwxrwxr-x
]
upload
mass deface
mass delete
console
info server
name :
Schema.php
<?php declare(strict_types=1); namespace GraphQL\Type; use GraphQL\Error\Error; use GraphQL\Error\InvariantViolation; use GraphQL\GraphQL; use GraphQL\Language\AST\OperationDefinitionNode; use GraphQL\Language\AST\SchemaDefinitionNode; use GraphQL\Language\AST\SchemaExtensionNode; use GraphQL\Type\Definition\AbstractType; use GraphQL\Type\Definition\Directive; use GraphQL\Type\Definition\ImplementingType; use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\NamedType; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\UnionType; use GraphQL\Utils\InterfaceImplementations; use GraphQL\Utils\TypeInfo; use GraphQL\Utils\Utils; /** * Schema Definition (see [schema definition docs](schema-definition.md)). * * A Schema is created by supplying the root types of each type of operation: * query, mutation (optional) and subscription (optional). A schema definition is * then supplied to the validator and executor. Usage Example: * * $schema = new GraphQL\Type\Schema([ * 'query' => $MyAppQueryRootType, * 'mutation' => $MyAppMutationRootType, * ]); * * Or using Schema Config instance: * * $config = GraphQL\Type\SchemaConfig::create() * ->setQuery($MyAppQueryRootType) * ->setMutation($MyAppMutationRootType); * * $schema = new GraphQL\Type\Schema($config); * * @phpstan-import-type SchemaConfigOptions from SchemaConfig * @phpstan-import-type OperationType from OperationDefinitionNode * * @see \GraphQL\Tests\Type\SchemaTest */ class Schema { private SchemaConfig $config; /** * Contains currently resolved schema types. * * @var array<string, Type&NamedType> */ private array $resolvedTypes = []; /** * Lazily initialised. * * @var array<string, InterfaceImplementations> */ private array $implementationsMap; /** True when $resolvedTypes contains all possible schema types. */ private bool $fullyLoaded = false; /** @var array<int, Error> */ private array $validationErrors; public ?SchemaDefinitionNode $astNode; /** @var array<SchemaExtensionNode> */ public array $extensionASTNodes = []; /** * @param SchemaConfig|array<string, mixed> $config * * @phpstan-param SchemaConfig|SchemaConfigOptions $config * * @throws InvariantViolation * * @api */ public function __construct($config) { if (\is_array($config)) { $config = SchemaConfig::create($config); } // If this schema was built from a source known to be valid, then it may be // marked with assumeValid to avoid an additional type system validation. if ($config->getAssumeValid()) { $this->validationErrors = []; } $this->astNode = $config->astNode; $this->extensionASTNodes = $config->extensionASTNodes; $this->config = $config; } /** * Returns all types in this schema. * * This operation requires a full schema scan. Do not use in production environment. * * @throws InvariantViolation * * @return array<string, Type&NamedType> Keys represent type names, values are instances of corresponding type definitions * * @api */ public function getTypeMap(): array { if (! $this->fullyLoaded) { $types = $this->config->types; if (\is_callable($types)) { $types = $types(); } // Reset order of user provided types, since calls to getType() may have loaded them $this->resolvedTypes = []; foreach ($types as $typeOrLazyType) { /** @var Type|callable(): Type $typeOrLazyType */ $type = self::resolveType($typeOrLazyType); assert($type instanceof NamedType); /** @var string $typeName Necessary assertion for PHPStan + PHP 8.2 */ $typeName = $type->name; assert( ! isset($this->resolvedTypes[$typeName]) || $type === $this->resolvedTypes[$typeName], "Schema must contain unique named types but contains multiple types named \"{$type}\" (see https://webonyx.github.io/graphql-php/type-definitions/#type-registry).", ); $this->resolvedTypes[$typeName] = $type; } // To preserve order of user-provided types, we add first to add them to // the set of "collected" types, so `collectReferencedTypes` ignore them. /** @var array<string, Type&NamedType> $allReferencedTypes */ $allReferencedTypes = []; foreach ($this->resolvedTypes as $type) { // When we ready to process this type, we remove it from "collected" types // and then add it together with all dependent types in the correct position. unset($allReferencedTypes[$type->name]); TypeInfo::extractTypes($type, $allReferencedTypes); } foreach ([$this->getQueryType(), $this->getMutationType(), $this->getSubscriptionType()] as $rootType) { if ($rootType instanceof ObjectType) { TypeInfo::extractTypes($rootType, $allReferencedTypes); } } foreach ($this->getDirectives() as $directive) { // @phpstan-ignore-next-line generics are not strictly enforceable, error will be caught during schema validation if ($directive instanceof Directive) { TypeInfo::extractTypesFromDirectives($directive, $allReferencedTypes); } } TypeInfo::extractTypes(Introspection::_schema(), $allReferencedTypes); $this->resolvedTypes = $allReferencedTypes; $this->fullyLoaded = true; } return $this->resolvedTypes; } /** * Returns a list of directives supported by this schema. * * @throws InvariantViolation * * @return array<Directive> * * @api */ public function getDirectives(): array { return $this->config->directives ?? GraphQL::getStandardDirectives(); } /** @param mixed $typeLoaderReturn could be anything */ public static function typeLoaderNotType($typeLoaderReturn): string { $typeClass = Type::class; $notType = Utils::printSafe($typeLoaderReturn); return "Type loader is expected to return an instanceof {$typeClass}, but it returned {$notType}"; } public static function typeLoaderWrongTypeName(string $expectedTypeName, string $actualTypeName): string { return "Type loader is expected to return type {$expectedTypeName}, but it returned type {$actualTypeName}."; } /** Returns root type by operation name. */ public function getOperationType(string $operation): ?ObjectType { switch ($operation) { case 'query': return $this->getQueryType(); case 'mutation': return $this->getMutationType(); case 'subscription': return $this->getSubscriptionType(); default: return null; } } /** * Returns root query type. * * @api */ public function getQueryType(): ?ObjectType { $query = $this->config->query; if ($query === null) { return null; } if (is_callable($query)) { return $this->config->query = $query(); } return $query; } /** * Returns root mutation type. * * @api */ public function getMutationType(): ?ObjectType { $mutation = $this->config->mutation; if ($mutation === null) { return null; } if (is_callable($mutation)) { return $this->config->mutation = $mutation(); } return $mutation; } /** * Returns schema subscription. * * @api */ public function getSubscriptionType(): ?ObjectType { $subscription = $this->config->subscription; if ($subscription === null) { return null; } if (is_callable($subscription)) { return $this->config->subscription = $subscription(); } return $subscription; } /** @api */ public function getConfig(): SchemaConfig { return $this->config; } /** * Returns a type by name. * * @throws InvariantViolation * * @return (Type&NamedType)|null * * @api */ public function getType(string $name): ?Type { if (isset($this->resolvedTypes[$name])) { return $this->resolvedTypes[$name]; } $introspectionTypes = Introspection::getTypes(); if (isset($introspectionTypes[$name])) { return $introspectionTypes[$name]; } $standardTypes = Type::getStandardTypes(); if (isset($standardTypes[$name])) { return $standardTypes[$name]; } $type = $this->loadType($name); if ($type === null) { return null; } return $this->resolvedTypes[$name] = self::resolveType($type); } /** @throws InvariantViolation */ public function hasType(string $name): bool { return $this->getType($name) !== null; } /** * @throws InvariantViolation * * @return (Type&NamedType)|null */ private function loadType(string $typeName): ?Type { if (! isset($this->config->typeLoader)) { return $this->getTypeMap()[$typeName] ?? null; } $type = ($this->config->typeLoader)($typeName); if ($type === null) { return null; } // @phpstan-ignore-next-line not strictly enforceable unless PHP gets function types if (! $type instanceof Type) { throw new InvariantViolation(self::typeLoaderNotType($type)); } if ($typeName !== $type->name) { throw new InvariantViolation(self::typeLoaderWrongTypeName($typeName, $type->name)); } return $type; } /** * @template T of Type * * @param Type|callable $type * * @phpstan-param T|callable():T $type * * @phpstan-return T */ public static function resolveType($type): Type { if ($type instanceof Type) { return $type; } return $type(); } /** * Returns all possible concrete types for given abstract type * (implementations for interfaces and members of union type for unions). * * This operation requires full schema scan. Do not use in production environment. * * @param AbstractType&Type $abstractType * * @throws InvariantViolation * * @return array<ObjectType> * * @api */ public function getPossibleTypes(AbstractType $abstractType): array { if ($abstractType instanceof UnionType) { return $abstractType->getTypes(); } assert($abstractType instanceof InterfaceType, 'only other option'); return $this->getImplementations($abstractType)->objects(); } /** * Returns all types that implement a given interface type. * * This operation requires full schema scan. Do not use in production environment. * * @api * * @throws InvariantViolation */ public function getImplementations(InterfaceType $abstractType): InterfaceImplementations { return $this->collectImplementations()[$abstractType->name]; } /** * @throws InvariantViolation * * @return array<string, InterfaceImplementations> */ private function collectImplementations(): array { if (! isset($this->implementationsMap)) { $this->implementationsMap = []; /** * @var array< * string, * array{ * objects: array<int, ObjectType>, * interfaces: array<int, InterfaceType>, * } * > $foundImplementations */ $foundImplementations = []; foreach ($this->getTypeMap() as $type) { if ($type instanceof InterfaceType) { if (! isset($foundImplementations[$type->name])) { $foundImplementations[$type->name] = ['objects' => [], 'interfaces' => []]; } foreach ($type->getInterfaces() as $iface) { if (! isset($foundImplementations[$iface->name])) { $foundImplementations[$iface->name] = ['objects' => [], 'interfaces' => []]; } $foundImplementations[$iface->name]['interfaces'][] = $type; } } elseif ($type instanceof ObjectType) { foreach ($type->getInterfaces() as $iface) { if (! isset($foundImplementations[$iface->name])) { $foundImplementations[$iface->name] = ['objects' => [], 'interfaces' => []]; } $foundImplementations[$iface->name]['objects'][] = $type; } } } foreach ($foundImplementations as $name => $implementations) { $this->implementationsMap[$name] = new InterfaceImplementations($implementations['objects'], $implementations['interfaces']); } } return $this->implementationsMap; } /** * Returns true if the given type is a sub type of the given abstract type. * * @param AbstractType&Type $abstractType * @param ImplementingType&Type $maybeSubType * * @api * * @throws InvariantViolation */ public function isSubType(AbstractType $abstractType, ImplementingType $maybeSubType): bool { if ($abstractType instanceof InterfaceType) { return $maybeSubType->implementsInterface($abstractType); } assert($abstractType instanceof UnionType, 'only other option'); return $abstractType->isPossibleType($maybeSubType); } /** * Returns instance of directive by name. * * @api * * @throws InvariantViolation */ public function getDirective(string $name): ?Directive { foreach ($this->getDirectives() as $directive) { if ($directive->name === $name) { return $directive; } } return null; } /** * Throws if the schema is not valid. * * This operation requires a full schema scan. Do not use in production environment. * * @throws Error * @throws InvariantViolation * * @api */ public function assertValid(): void { $errors = $this->validate(); if ($errors !== []) { throw new InvariantViolation(\implode("\n\n", $this->validationErrors)); } $internalTypes = Type::getStandardTypes() + Introspection::getTypes(); foreach ($this->getTypeMap() as $name => $type) { if (isset($internalTypes[$name])) { continue; } $type->assertValid(); // Make sure type loader returns the same instance as registered in other places of schema if (isset($this->config->typeLoader) && $this->loadType($name) !== $type) { throw new InvariantViolation("Type loader returns different instance for {$name} than field/argument definitions. Make sure you always return the same instance for the same type name."); } } } /** * Validate the schema and return any errors. * * This operation requires a full schema scan. Do not use in production environment. * * @throws InvariantViolation * * @return array<int, Error> * * @api */ public function validate(): array { // If this Schema has already been validated, return the previous results. if (isset($this->validationErrors)) { return $this->validationErrors; } // Validate the schema, producing a list of errors. $context = new SchemaValidationContext($this); $context->validateRootTypes(); $context->validateDirectives(); $context->validateTypes(); // Persist the results of validation before returning to ensure validation // does not run multiple times for this schema. $this->validationErrors = $context->getErrors(); return $this->validationErrors; } }
© 2026 UnknownSec