Skip to content
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
01508dd
Extract RootType::namespaces() and refactor FieldValue::parentNamespa…
spawnia Jul 10, 2026
3683814
Add RootResolverSignatureRector with type-fixing behavior
spawnia Jul 10, 2026
be9a69c
Add name normalization tests for RootResolverSignatureRector
spawnia Jul 10, 2026
e6f85c1
Document root resolvers and the RootResolverSignatureRector rule
spawnia Jul 10, 2026
89bcd0b
Require Larastan bootstrap for RootResolverSignatureRector
spawnia Jul 10, 2026
1110380
Use protected visibility in RootResolverSignatureRector
spawnia Jul 10, 2026
96d6bfb
Ignore docs/superpowers in .gitignore
spawnia Jul 10, 2026
9d88837
Fix isMissingRootParam producing duplicate param names
spawnia Jul 10, 2026
13435be
Validate paramNames element types in configure()
spawnia Jul 10, 2026
6d7dacd
Throw when resolver namespaces are empty (misconfigured bootstrap)
spawnia Jul 10, 2026
2ac1ac8
Refactor RootResolverSignatureRector for clarity
spawnia Jul 10, 2026
7acf822
Fix docs: sentence line break and missing $args insertion bullet
spawnia Jul 10, 2026
1840f90
Add missing test fixtures for fixObjectParam paths
spawnia Jul 10, 2026
03a4ef9
Add CHANGELOG entry for RootResolverSignatureRector
spawnia Jul 10, 2026
ebab0a4
Apply fixes from tooling (rector, php-cs-fixer, phpstan)
spawnia Jul 10, 2026
d9f02dd
Fix normalizeNames to rename variable usages in method body
spawnia Jul 10, 2026
4db7570
Use mixed $root in docs example for PHP 8.0/8.1 compat
spawnia Jul 10, 2026
5c95630
Replace assert with InvalidConfigurationException for paramNames
spawnia Jul 10, 2026
046cee7
Replace TODO placeholder with actual PR number in CHANGELOG
spawnia Jul 10, 2026
332fee5
Keep rector/rector installed in CI to validate Rector code
spawnia Jul 10, 2026
585638b
Keep larastan installed in PHPUnit CI job
spawnia Jul 10, 2026
be1c194
Add @dataProvider annotations for PHPUnit 9.x compatibility
spawnia Jul 14, 2026
837450d
Merge branch 'master' into root-resolver-signature-rector-rule
spawnia Jul 15, 2026
a657821
fix risky test
spawnia Jul 15, 2026
20d9943
bump phpstan and rector minimum versions
spawnia Jul 15, 2026
ed8b242
fix risky test by avoiding AbstractRectorTestCase
spawnia Jul 15, 2026
c21ea81
Fix CI dependency conflicts between rector and phpstan
spawnia Jul 15, 2026
ced5f40
Exclude Rector files from PHPStan analysis
spawnia Jul 15, 2026
5b695b5
Validate RootType::namespaces() returns non-empty strings
spawnia Jul 15, 2026
6c85faf
Address code style review comments
spawnia Jul 15, 2026
db79118
Pin PHP 8.2 target in Rector test configs
spawnia Jul 15, 2026
4934a86
Use imports instead of FQCNs for GraphQLContext and ResolveInfo
spawnia Jul 15, 2026
c633c64
Use array-key in RootType::namespaces() return type annotation
spawnia Jul 15, 2026
3d1eaa5
Apply php-cs-fixer changes
spawnia Jul 15, 2026
f14e4ba
Don't add args param when root was already present without args
spawnia Jul 16, 2026
b6d2dec
Strip useless single root params instead of adding args
spawnia Jul 16, 2026
60a42e1
Update docs to match single-param stripping behavior
spawnia Jul 16, 2026
3597bd9
Reindex namespaces array to guarantee list return type
spawnia Jul 16, 2026
9cfe2e1
Document that the rule assumes all __invoke classes in resolver paths…
spawnia Jul 16, 2026
d368c88
Add docs for RootResolverSignatureRector including known limitation
spawnia Jul 16, 2026
82e6e14
Move Rector docs to testing/rector.md as canonical source, add short …
spawnia Jul 16, 2026
3ab761e
Sync docs/6 from docs/master
spawnia Jul 16, 2026
9bba73b
Handle ?array $args as a valid args parameter type
spawnia Jul 17, 2026
dacceb4
Remove unreachable ensureArgsParam block and method
spawnia Jul 17, 2026
37fe9e8
Reindex paramNames to guarantee positional access
spawnia Jul 17, 2026
5d21444
Annotate null $root examples as PHP 8.2+
spawnia Jul 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ jobs:
key: php-${{ matrix.php-version }}-composer-${{ matrix.laravel-version }}-os-${{ matrix.os }}-composer-${{ matrix.composer.name }}

- name: "Remove conflicting dependencies that are not needed here"
run: composer remove --dev --no-update larastan/larastan phpstan/phpstan-mockery phpbench/phpbench rector/rector
run: composer remove --dev --no-update phpstan/phpstan-mockery phpbench/phpbench

- name: "Remove Pennant for Laravel 9 because it is not compatible"
if: matrix.laravel-version == '^9'
Expand Down Expand Up @@ -224,7 +224,7 @@ jobs:
path: ~/.composer/cache
key: php-${{ matrix.php-version }}-composer-${{ matrix.laravel-version }}

- run: composer remove --dev phpbench/phpbench rector/rector --no-update
- run: composer remove --dev phpbench/phpbench --no-update

- run: composer require laravel/framework:${{ matrix.laravel-version }} --no-interaction --prefer-dist --no-progress

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
.vscode
phpunit.xml
.gitpod.yml
docs/superpowers

# Generated files
.phpunit.result.cache
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ You can find and compare releases at the [GitHub release page](https://github.co

## Unreleased

### Added

- Add `RootResolverSignatureRector` rule to auto-fix root resolver `__invoke` signatures https://github.com/nuwave/lighthouse/pull/2779

## v6.68.0

### Added
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"ergebnis/composer-normalize": "^2.2.2",
"fakerphp/faker": "^1.21",
"google/protobuf": "^3.21 || ^4.33.6",
"larastan/larastan": "^2.9.14 || ^3.0.4",
"larastan/larastan": "^2.9.14 || ^3.10",
"laravel/framework": "^9 || ^10 || ^11 || ^12 || ^13",
"laravel/legacy-factories": "^1.1.1",
"laravel/pennant": "^1",
Expand All @@ -68,7 +68,7 @@
"phpunit/phpunit": "^9.6.4 || ^10 || ^11 || ^12",
"predis/predis": "^1.1 || ^2.1",
"pusher/pusher-php-server": "^5 || ^6 || ^7.0.2",
"rector/rector": "^1 || ^2",
"rector/rector": "^1.2.10 || ^2.5.7",
"thecodingmachine/phpstan-safe-rule": "^1.2"
},
"suggest": {
Expand Down
71 changes: 71 additions & 0 deletions docs/master/api-reference/resolvers.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,77 @@ function (mixed $root, array $args, GraphQLContext $context, ResolveInfo $resolv

The return value of this must fit the return type defined for the corresponding field from the schema.

## Root resolvers

Root resolvers are classes with an `__invoke` method that sit directly in the configured
`lighthouse.namespaces.queries` or `lighthouse.namespaces.mutations` namespaces.
Lighthouse calls them with positional arguments `($root, $args, $context, $resolveInfo)` where `$root` is always `null` for root types.
Comment thread
spawnia marked this conversation as resolved.

Omitting `$root` causes Lighthouse's positional `null` to bind to `$args`, producing TypeErrors at runtime.
The canonical signature for a root resolver is:

```php
use Nuwave\Lighthouse\Execution\ResolveInfo;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;

class MyQuery
{
public function __invoke(mixed $root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo)
{
// ...
}
}
```

On PHP 8.2+, you can use the more precise `null` type instead of `mixed`.
The Rector rule below automatically picks the correct type for your PHP version.

### Rector rule

Lighthouse ships a Rector rule that enforces correct `__invoke` signatures on root resolvers.
Enable it in your `rector.php`:

```php
use Nuwave\Lighthouse\Rector\RootResolverSignatureRector;
use Rector\Config\RectorConfig;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(RootResolverSignatureRector::class);

// Required: Larastan bootstrap makes config() available
$rectorConfig->bootstrapFiles([
__DIR__ . '/vendor/larastan/larastan/bootstrap.php',
]);
};
```

The rule fixes:

- Missing `$root` parameter (detected when there is a single param typed `array` or untyped)
- Missing `$args` parameter when only `$root` is present
- Wrong type on the `$root` parameter (must be `null` on PHP 8.2+, `mixed` on earlier versions)
Comment thread
spawnia marked this conversation as resolved.
Outdated
- Wrong type on `$args` (must be `array`)
- Wrong type on `$context` if present (must implement `GraphQLContext`)
- Wrong type on `$resolveInfo` if present (must be or extend `ResolveInfo`)

#### Name normalization

Optionally configure preferred parameter names:

```php
$rectorConfig->ruleWithConfiguration(RootResolverSignatureRector::class, [
'paramNames' => ['_', 'args', 'context', 'resolveInfo'],
]);
```

Use `null` at any position to skip renaming that parameter:

```php
$rectorConfig->ruleWithConfiguration(RootResolverSignatureRector::class, [
'paramNames' => [null, null, 'context', 'resolveInfo'],
]);
```

## Complexity function signature

The complexity function is used to calculate a query complexity score for a field.
Expand Down
3 changes: 3 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ parameters:
# laravel/pennant requires Laravel 10
- src/Pennant
- tests/Integration/Pennant
# rector/rector is removed for PHPStan CI to avoid dependency conflicts
- src/Rector
- tests/Unit/Rector
- src/Tracing/FederatedTracing/Proto # Generated classes from protobuf
# Ignore errors caused by the absence of Lumen in the dev dependencies
- tests/Unit/Testing/TestingTraitDummyLumen.php
Expand Down
Loading
Loading