-
Notifications
You must be signed in to change notification settings - Fork 20
Add introspection config pass‑though #129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -59,6 +59,18 @@ public function errorsAreClientSafe(): bool | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Options passed to GraphQL\Type\Introspection::getIntrospectionQuery. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return array<string, mixed> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public function introspectionConfig(): array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'includeDeprecated' => true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just stick with the defaults?
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can make this function return |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+62
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result:
If what you’re looking for are the options/parameters that
These options are documented in GraphQL-core (Python) [1], and the GraphQL JS API docs list the same option names (including 🏁 Script executed: # Find usage of introspectionConfig in the codebase
rg -A 5 -B 5 "introspectionConfig" --type php
# Check the current EndpointConfig.php implementation
fd "EndpointConfig.php" -x cat -n {}Repository: spawnia/sailor Length of output: 8500 🏁 Script executed: # Search for how Introspection is imported and used in the codebase
rg "Introspection" src/ tests/ -B 2 -A 2 --type php | head -40
# Try to find if there's vendor or any reference to graphql-php Introspection signature
rg "getIntrospectionQuery" -B 5 -A 10 --type phpRepository: spawnia/sailor Length of output: 3766 🌐 Web query:
💡 Result: In webonyx/graphql-php the method is: public static function getIntrospectionQuery(array $options = []): string
(For reference, WPGraphQL calls it as Sources: [1] [2] 🏁 Script executed: # Check composer.json or any version constraint for graphql-php
fd "composer.json" -x cat {}
# Look for any documentation or comments about the Introspection options
rg "directiveIsRepeatable|includeDeprecated|descriptions" --type php -B 3 -A 3Repository: spawnia/sailor Length of output: 8673 Narrow introspection options type to align with GraphQL API. The According to webonyx/graphql-php's API, 🔧 Suggested docblock refinement- * `@return` array<string, mixed>
+ * `@return` array{
+ * includeDeprecated?: bool,
+ * descriptions?: bool,
+ * schemaDescription?: bool,
+ * typeIsOneOf?: bool
+ * }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Return a map from type names to a TypeConfig describing how to deal with them. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,10 +49,11 @@ | |
|
|
||
| protected function fetchIntrospectionResult(Client $client, bool $directiveIsRepeatable): Response | ||
| { | ||
| $options = $this->endpointConfig->introspectionConfig(); | ||
| $options['directiveIsRepeatable'] = $directiveIsRepeatable; | ||
|
Comment on lines
50
to
+53
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems weird to me to override this option ad-hoc when EndpointConfig defines it. How about we give full control?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because we do a retry with the directiveIsRepeatable false if the first call fails with false so trying to respect the method call
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should just do a single try when the endpoint has an explicit configuration (non-null, default being null). When customizing, users should know what they are doing and where to look when things go wrong. For other cases, we can preserve the current fallback behavior. |
||
|
|
||
| $response = $client->request( | ||
| Introspection::getIntrospectionQuery([ | ||
| 'directiveIsRepeatable' => $directiveIsRepeatable, | ||
| ]) | ||
| Introspection::getIntrospectionQuery($options) | ||
|
Check failure on line 56 in src/Introspector.php
|
||
| ); | ||
|
|
||
| if (isset($response->errors)) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -29,6 +29,14 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GRAPHQL; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public const SCHEMA_WITH_DEPRECATED = /* @lang GraphQL */ <<<'GRAPHQL' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type Query { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| oldField: String @deprecated(reason: "Use newField") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| newField: String | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GRAPHQL; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public const PATH = __DIR__ . '/schema.graphql'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -55,6 +63,42 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ->introspect(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public function testIncludesDeprecationsByDefault(): void | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $introspector = $this->makeIntrospector(static function (): Response { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return self::introspectionWithDeprecatedMock(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $introspector->introspect(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self::assertFileExists(self::PATH); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $schema = file_get_contents(self::PATH); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self::assertStringContainsString('@deprecated', $schema); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self::assertStringContainsString('Use newField', $schema); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unlink(self::PATH); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public function testCanDisableDeprecations(): void | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $introspector = $this->makeIntrospector( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| static function (): Response { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return self::introspectionWithDeprecatedMock(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ['includeDeprecated' => false] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $introspector->introspect(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self::assertFileExists(self::PATH); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $schema = file_get_contents(self::PATH); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self::assertStringNotContainsString('@deprecated', $schema); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self::assertStringNotContainsString('oldField', $schema); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self::assertStringContainsString('newField', $schema); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unlink(self::PATH); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** @return iterable<array{Request}> */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public static function validRequests(): iterable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -88,15 +132,19 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** @param Request $request */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private function makeIntrospector(callable $request): Introspector | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private function makeIntrospector(callable $request, ?array $introspectionConfig = null): Introspector | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 135 in tests/Unit/IntrospectorTest.php
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $endpointConfig = new class($request) extends EndpointConfig { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $endpointConfig = new class($request, $introspectionConfig) extends EndpointConfig { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** @var callable */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private $request; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public function __construct(callable $request) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** @var array<string, mixed>|null */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private ?array $introspectionConfig; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public function __construct(callable $request, ?array $introspectionConfig) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 144 in tests/Unit/IntrospectorTest.php
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->request = $request; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->introspectionConfig = $introspectionConfig; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 147 in tests/Unit/IntrospectorTest.php
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public function makeClient(): Client | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -123,6 +171,11 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return new DirectoryFinder('bar'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public function introspectionConfig(): array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $this->introspectionConfig ?? parent::introspectionConfig(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return new Introspector($endpointConfig, 'foo', 'bar'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -140,6 +193,59 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $response; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public static function introspectionWithDeprecatedMock(bool $includeDeprecated): Response | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $schema = BuildSchema::build(self::SCHEMA_WITH_DEPRECATED); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $introspection = Introspection::fromSchema($schema); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! $includeDeprecated) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $introspection = self::stripDeprecations($introspection); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 201 in tests/Unit/IntrospectorTest.php
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $response = new Response(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // @phpstan-ignore-next-line We know an associative array converts to a stdClass | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $response->data = Json::assocToStdClass($introspection); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $response; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+196
to
+209
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard or assert the introspection payload type before filtering. Line 196-203: PHPStan flags ✅ Suggested guard $schema = BuildSchema::build(self::SCHEMA_WITH_DEPRECATED);
$introspection = Introspection::fromSchema($schema);
+ if (! is_array($introspection)) {
+ throw new \RuntimeException('Unexpected introspection payload type.');
+ }
if (! $includeDeprecated) {
$introspection = self::stripDeprecations($introspection);
}📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Check: static-code-analysis (7.4, lowest)[failure] 201-201: 🪛 GitHub Check: static-code-analysis (8, lowest)[failure] 201-201: 🪛 GitHub Check: static-code-analysis (8.3, lowest)[failure] 201-201: 🪛 GitHub Check: static-code-analysis (8.4, lowest)[failure] 201-201: 🪛 GitHub Check: static-code-analysis (8.5, lowest)[failure] 201-201: 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param array<string, mixed> $introspection | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return array<string, mixed> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static function stripDeprecations(array $introspection): array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! isset($introspection['__schema']['types']) || ! is_array($introspection['__schema']['types'])) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 218 in tests/Unit/IntrospectorTest.php
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $introspection; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| foreach ($introspection['__schema']['types'] as &$type) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isset($type['fields']) && is_array($type['fields'])) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 223 in tests/Unit/IntrospectorTest.php
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $type['fields'] = array_values(array_filter($type['fields'], static function (array $field): bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 224 in tests/Unit/IntrospectorTest.php
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return empty($field['isDeprecated']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 225 in tests/Unit/IntrospectorTest.php
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| foreach ($type['fields'] as &$field) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isset($field['args']) && is_array($field['args'])) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 229 in tests/Unit/IntrospectorTest.php
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $field['args'] = array_values(array_filter($field['args'], static function (array $arg): bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 230 in tests/Unit/IntrospectorTest.php
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return empty($arg['isDeprecated']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unset($field); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isset($type['enumValues']) && is_array($type['enumValues'])) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $type['enumValues'] = array_values(array_filter($type['enumValues'], static function (array $enumValue): bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return empty($enumValue['isDeprecated']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unset($type); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $introspection; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+211
to
+247
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make deprecation filtering type‑safe and avoid Line 218-243: PHPStan reports mixed‑offset access and 🔧 Suggested type‑safe filtering- foreach ($introspection['__schema']['types'] as &$type) {
- if (isset($type['fields']) && is_array($type['fields'])) {
- $type['fields'] = array_values(array_filter($type['fields'], static function (array $field): bool {
- return empty($field['isDeprecated']);
- }));
+ foreach ($introspection['__schema']['types'] as &$type) {
+ if (! is_array($type)) {
+ continue;
+ }
+ if (isset($type['fields']) && is_array($type['fields'])) {
+ $type['fields'] = array_values(array_filter($type['fields'], static function ($field): bool {
+ return is_array($field)
+ && (($field['isDeprecated'] ?? false) === false);
+ }));
foreach ($type['fields'] as &$field) {
- if (isset($field['args']) && is_array($field['args'])) {
- $field['args'] = array_values(array_filter($field['args'], static function (array $arg): bool {
- return empty($arg['isDeprecated']);
- }));
+ if (! is_array($field)) {
+ continue;
+ }
+ if (isset($field['args']) && is_array($field['args'])) {
+ $field['args'] = array_values(array_filter($field['args'], static function ($arg): bool {
+ return is_array($arg)
+ && (($arg['isDeprecated'] ?? false) === false);
+ }));
}
}
unset($field);
}
if (isset($type['enumValues']) && is_array($type['enumValues'])) {
- $type['enumValues'] = array_values(array_filter($type['enumValues'], static function (array $enumValue): bool {
- return empty($enumValue['isDeprecated']);
- }));
+ $type['enumValues'] = array_values(array_filter($type['enumValues'], static function ($enumValue): bool {
+ return is_array($enumValue)
+ && (($enumValue['isDeprecated'] ?? false) === false);
+ }));
}
}🧰 Tools🪛 GitHub Check: static-code-analysis (7.4, highest)[failure] 230-230: [failure] 229-229: [failure] 225-225: [failure] 224-224: [failure] 223-223: [failure] 218-218: 🪛 GitHub Check: static-code-analysis (7.4, lowest)[failure] 230-230: [failure] 229-229: [failure] 225-225: [failure] 224-224: [failure] 223-223: [failure] 218-218: 🪛 GitHub Check: static-code-analysis (8, highest)[failure] 230-230: [failure] 229-229: [failure] 225-225: [failure] 224-224: [failure] 223-223: [failure] 218-218: 🪛 GitHub Check: static-code-analysis (8, lowest)[failure] 230-230: [failure] 229-229: [failure] 225-225: [failure] 224-224: [failure] 223-223: [failure] 218-218: 🪛 GitHub Check: static-code-analysis (8.1, highest)[failure] 230-230: [failure] 229-229: [failure] 225-225: [failure] 224-224: [failure] 223-223: [failure] 218-218: 🪛 GitHub Check: static-code-analysis (8.2, highest)[failure] 230-230: [failure] 229-229: [failure] 225-225: [failure] 224-224: [failure] 223-223: [failure] 218-218: 🪛 GitHub Check: static-code-analysis (8.3, highest)[failure] 230-230: [failure] 229-229: [failure] 225-225: [failure] 224-224: [failure] 223-223: [failure] 218-218: 🪛 GitHub Check: static-code-analysis (8.3, lowest)[failure] 230-230: [failure] 229-229: [failure] 225-225: [failure] 224-224: [failure] 223-223: [failure] 218-218: 🪛 GitHub Check: static-code-analysis (8.4, highest)[failure] 230-230: [failure] 229-229: [failure] 225-225: [failure] 224-224: [failure] 223-223: [failure] 218-218: 🪛 GitHub Check: static-code-analysis (8.4, lowest)[failure] 230-230: [failure] 229-229: [failure] 225-225: [failure] 224-224: [failure] 223-223: [failure] 218-218: 🪛 GitHub Check: static-code-analysis (8.5, highest)[failure] 230-230: [failure] 229-229: [failure] 225-225: [failure] 224-224: [failure] 223-223: [failure] 218-218: 🪛 GitHub Check: static-code-analysis (8.5, lowest)[failure] 230-230: [failure] 229-229: [failure] 225-225: [failure] 224-224: [failure] 223-223: [failure] 218-218: 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static function responseWithErrorsMock(): Response | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $response = new Response(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
graphql-php defines a type alias IntrospectionOptions for this. Let's
@phpstan-import-typethis and use it here to define the type precisely.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. How can I do that? I tried including it but phpstan complains and it can't seem to reference the type and tries to reference it using the current namespace:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type imports have to go in the class PhpDoc.