Skip to content

Commit

Permalink
Merge branch 'refs/heads/master' into with-directive-multiple-nested-…
Browse files Browse the repository at this point in the history
…relations
  • Loading branch information
spawnia committed Jun 5, 2024
2 parents f7a6f18 + 6f2ee68 commit 7c560e2
Show file tree
Hide file tree
Showing 23 changed files with 359 additions and 66 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
composer-normalize:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}

Expand All @@ -29,7 +29,7 @@ jobs:
prettier:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}

Expand All @@ -45,7 +45,7 @@ jobs:
php-cs-fixer:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}

Expand Down
21 changes: 16 additions & 5 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
laravel-version:
- "^9"
- "^10"
- "^11"
composer:
- name: lowest
arg: "--prefer-lowest --prefer-stable"
Expand All @@ -38,9 +39,13 @@ jobs:
exclude:
- php-version: "8.0"
laravel-version: "^10"
- php-version: "8.0"
laravel-version: "^11"
- php-version: "8.1"
laravel-version: "^11"

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: shivammathur/setup-php@v2
with:
Expand Down Expand Up @@ -86,6 +91,7 @@ jobs:
laravel-version:
- "^9"
- "^10"
- "^11"
os:
- ubuntu-latest
composer:
Expand All @@ -96,6 +102,10 @@ jobs:
exclude:
- php-version: "8.0"
laravel-version: "^10"
- php-version: "8.0"
laravel-version: "^11"
- php-version: "8.1"
laravel-version: "^11"

services:
mysql:
Expand All @@ -113,10 +123,11 @@ jobs:
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: shivammathur/setup-php@v2
with:
coverage: none
extensions: ${{ env.REQUIRED_PHP_EXTENSIONS }}
php-version: ${{ matrix.php-version }}

Expand All @@ -129,7 +140,7 @@ jobs:
- name: "Remove conflicting dependencies that are not needed here"
run: composer remove --dev --no-update larastan/larastan phpstan/phpstan-mockery phpbench/phpbench rector/rector

- if: matrix.laravel-version != '^10'
- if: matrix.laravel-version != '^10' && matrix.laravel-version != '^11'
run: composer remove --dev --no-update laravel/pennant

- run: >
Expand Down Expand Up @@ -169,7 +180,7 @@ jobs:
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: shivammathur/setup-php@v2
with:
Expand Down Expand Up @@ -203,7 +214,7 @@ jobs:
- "^10"

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: shivammathur/setup-php@v2
with:
Expand Down
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,30 @@ You can find and compare releases at the [GitHub release page](https://github.co

## Unreleased

## v6.36.3

### Fixed

- Actually use raw attributes in comparison of paginated related models https://github.com/nuwave/lighthouse/pull/2550

## v6.36.2

### Changed

- Compare raw attributes only when ensuring uniqueness of paginated related models https://github.com/nuwave/lighthouse/pull/2540

## v6.36.1

### Fixed

- Native PHP Enums registered through the `TypeRegistry` may be used as morph type in nested `MorphTo` relations https://github.com/nuwave/lighthouse/pull/2544

## v6.36.0

### Added

- Support Laravel 11 https://github.com/nuwave/lighthouse/pull/2508

## v6.35.0

### Added
Expand Down
28 changes: 13 additions & 15 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@
"php": "^8",
"ext-json": "*",
"haydenpierce/class-finder": "^0.4 || ^0.5",
"illuminate/auth": "^9 || ^10",
"illuminate/bus": "^9 || ^10",
"illuminate/contracts": "^9 || ^10",
"illuminate/http": "^9 || ^10",
"illuminate/pagination": "^9 || ^10",
"illuminate/queue": "^9 || ^10",
"illuminate/routing": "^9 || ^10",
"illuminate/support": "^9 || ^10",
"illuminate/validation": "^9 || ^10",
"illuminate/auth": "^9 || ^10 || ^11",
"illuminate/bus": "^9 || ^10 || ^11",
"illuminate/contracts": "^9 || ^10 || ^11",
"illuminate/http": "^9 || ^10 || ^11",
"illuminate/pagination": "^9 || ^10 || ^11",
"illuminate/queue": "^9 || ^10 || ^11",
"illuminate/routing": "^9 || ^10 || ^11",
"illuminate/support": "^9 || ^10 || ^11",
"illuminate/validation": "^9 || ^10 || ^11",
"laragraph/utils": "^1.5 || ^2",
"thecodingmachine/safe": "^1 || ^2",
"webonyx/graphql-php": "^15"
Expand All @@ -50,31 +50,29 @@
"fakerphp/faker": "^1.21",
"google/protobuf": "^3.21",
"larastan/larastan": "^2.6.1",
"laravel/framework": "^9 || ^10",
"laravel/framework": "^9 || ^10 || ^11",
"laravel/legacy-factories": "^1.1.1",
"laravel/lumen-framework": "^9 || ^10 || dev-master",
"laravel/pennant": "^1",
"laravel/scout": "^8 || ^9 || ^10",
"laravel/scout": "^8 || ^9 || ^10 || ^11",
"mattiasgeniar/phpunit-query-count-assertions": "^1.1",
"mll-lab/graphql-php-scalars": "^6",
"mll-lab/php-cs-fixer-config": "^5",
"mockery/mockery": "^1.5",
"nesbot/carbon": "^2.62.1",
"orchestra/testbench": "^7.7 || ^8.8",
"orchestra/testbench": "^7.7 || ^8.8 || ^9",
"phpbench/phpbench": "^1.2.6",
"phpstan/extension-installer": "^1",
"phpstan/phpstan": "^1.10.3",
"phpstan/phpstan-mockery": "^1.1",
"phpstan/phpstan-phpunit": "^1.1.1",
"phpunit/phpunit": "^9.6.4 || ^10",
"phpunit/phpunit": "^9.6.4 || ^10 || ^11",
"predis/predis": "^1.1 || ^2.1",
"pusher/pusher-php-server": "^5 || ^6 || ^7.0.2",
"rector/rector": "^1",
"thecodingmachine/phpstan-safe-rule": "^1.2"
},
"suggest": {
"ext-protobuf": "Improve protobuf serialization performance (used for tracing)",
"bensampo/laravel-enum": "Convenient enum definitions that can easily be registered in your Schema",
"google/protobuf": "Required when using the tracing driver federated-tracing",
"laravel/pennant": "Required for the @feature directive",
"laravel/scout": "Required for the @search directive",
Expand Down
7 changes: 4 additions & 3 deletions docs/6/the-basics/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,18 +316,19 @@ Read more about them in the [GraphQL Reference](https://graphql.org/learn/schema
## Union

A Union is an abstract type that simply enumerates other Object Types.
They are similar to interfaces in that they can return different types, but they can not
have fields defined.
They are similar to interfaces in that they can return different types, but do not prescribe any common fields.

```graphql
union Person = User | Employee

type User {
id: ID!
email: String!
}

type Employee {
employeeId: ID!
id: ID!
department: Department!
}
```

Expand Down
2 changes: 1 addition & 1 deletion docs/master/custom-directives/field-directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ directive can be used to manipulate the schema AST.
This directive type is implemented as an abstract class rather than a pure interface and allows
you to define complex validation rules for a field with ease.

[Read more about it in the Validation section](../security/validation.md#validate-fields).
[Read more about it in the Validation section](../security/validation.md#validator-for-fields).

## ComplexityResolverDirective

Expand Down
18 changes: 10 additions & 8 deletions docs/master/custom-directives/getting-started.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Implementing Your Own Directives

As you grow your GraphQL schema, you may find the need for more specialized functionality.
Learn how you can abstract logic in a composable and reusable manner by using custom directives.

Directives are implemented as PHP classes, each directive available
in the schema corresponds to a single class.
You can abstract logic in a composable and reusable manner by using custom directives.

## Naming Convention

Directives are implemented as PHP classes.
Each directive available in the schema corresponds to a single class.

Directive names themselves are typically defined in **camelCase**.
The class name of a directive must follow the following pattern:

Expand Down Expand Up @@ -51,12 +51,11 @@ GRAPHQL;
## Directive Interfaces

At this point, the directive does not do anything.
Depending on what your directive should do, you can pick one or more of the provided
directive interfaces to add functionality. They serve as the point of contact to Lighthouse.
Depending on what your directive should do, you can pick one or more of the provided directive interfaces to add functionality.
They serve as the point of contact to Lighthouse.

In this case, our directive needs to run after the actual resolver.
Just like [Laravel Middleware](https://laravel.com/docs/middleware),
we can wrap around it by using the `FieldMiddleware` directive.
Just like [Laravel Middleware](https://laravel.com/docs/middleware), we can wrap around it by using the `FieldMiddleware` directive.

```php
namespace App\GraphQL\Directives;
Expand Down Expand Up @@ -87,6 +86,9 @@ final class UpperCaseDirective extends BaseDirective implements FieldMiddleware
}
```

Given there are a lot of use cases for custom directives, the documentation does not provide examples for most interfaces.
It is advised to look at the Lighthouse source code to find directives that implement certain interfaces to learn more.

## Register Directives

Now that we defined and implemented the directive, how can Lighthouse find it?
Expand Down
7 changes: 4 additions & 3 deletions docs/master/the-basics/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,18 +316,19 @@ Read more about them in the [GraphQL Reference](https://graphql.org/learn/schema
## Union

A Union is an abstract type that simply enumerates other Object Types.
They are similar to interfaces in that they can return different types, but they can not
have fields defined.
They are similar to interfaces in that they can return different types, but do not prescribe any common fields.

```graphql
union Person = User | Employee

type User {
id: ID!
email: String!
}

type Employee {
employeeId: ID!
id: ID!
department: Department!
}
```

Expand Down
34 changes: 34 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ parameters:
- src/Pennant
- tests/Integration/Pennant
- 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
# Native enums
- tests/Utils/Enums/ImageableType.php
- tests/Utils/Enums/ImageableType.php
ignoreErrors:
# PHPStan does not get it
- '#Parameter \#1 \$callback of static method Closure::fromCallable\(\) expects callable\(\): mixed, array{object, .*} given\.#'
Expand Down Expand Up @@ -64,3 +69,32 @@ parameters:

# Older versions of bensampo/laravel-enum are not generic yet
- '#contains generic type BenSampo\\Enum\\Enum<.+> but class BenSampo\\Enum\\Enum is not generic\.#'

# Ignore errors caused by the absence of Lumen in the dev dependencies
- path: src/Support/AppVersion.php
message: '#PHPDoc tag @var for variable \$container contains unknown class Laravel\\Lumen\\Application.#'
- path: src/Support/AppVersion.php
message: '#Call to method version\(\) on an unknown class Laravel\\Lumen\\Application.#'
- path: src/Subscriptions/SubscriptionRouter.php
messages:
- '#Parameter \$router of method Nuwave\\Lighthouse\\Subscriptions\\SubscriptionRouter::pusher\(\) has invalid type Laravel\\Lumen\\Routing\\Router\.#'
- '#Call to method post\(\) on an unknown class Laravel\\Lumen\\Routing\\Router\.#'
- '#Parameter \$router of method Nuwave\\Lighthouse\\Subscriptions\\SubscriptionRouter::echoRoutes\(\) has invalid type Laravel\\Lumen\\Routing\\Router\.#'
- path: src/Http/routes.php
messages:
- '#PHPDoc tag @var for variable \$router contains unknown class Laravel\\Lumen\\Routing\\Router\.#'
- '#Call to method addRoute\(\) on an unknown class Laravel\\Lumen\\Routing\\Router\.#'

# Recent Mockery versions do not account for the last arg possibly being a closure
- path: tests/Unit/Subscriptions/Iterators/AuthenticatingSyncIteratorTest.php
message: '#Parameter \#2 \.\.\.\$args of static method Mockery::mock\(\) expects array\|class-string<Nuwave\\Lighthouse\\Subscriptions\\SubscriptionGuard>\|Nuwave\\Lighthouse\\Subscriptions\\SubscriptionGuard, Closure given\.#'

- path: tests/Integration/Schema/Directives/BuilderDirectiveTest.php
message: '#Return type of call to static method Mockery::mock\(\) contains unresolvable type\.#'

# Laravel added generics to Arr::first in 11.x, not sure how to handle them for now.
- path: src/OrderBy/OrderByDirective.php
message: '#Unable to resolve the template type TValue in call to method static method Illuminate\\Support\\Arr::first\(\)#'
- path: src/Testing/TestResponseMixin.php
message: '#Unable to resolve the template type TValue in call to method static method Illuminate\\Support\\Arr::first\(\)#'

27 changes: 25 additions & 2 deletions src/Execution/Arguments/NestedMorphTo.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Nuwave\Lighthouse\Execution\Arguments;

use Illuminate\Database\Eloquent\Relations\MorphTo;
use Nuwave\Lighthouse\Exceptions\DefinitionException;
use Nuwave\Lighthouse\Support\Contracts\ArgResolver;

class NestedMorphTo implements ArgResolver
Expand All @@ -24,18 +25,40 @@ public function __invoke($parent, $args): void

if ($args->has('connect')) {
$connectArgs = $args->arguments['connect']->value;
$connectArgsArguments = $connectArgs->arguments;

$morphToModel = $this->relation->createModelByType(
(string) $connectArgs->arguments['type']->value,
$this->morphTypeValue($connectArgsArguments['type']->value),
);
$morphToModel->setAttribute(
$morphToModel->getKeyName(),
$connectArgs->arguments['id']->value,
$connectArgsArguments['id']->value,
);

$this->relation->associate($morphToModel);
}

NestedBelongsTo::disconnectOrDelete($this->relation, $args);
}

protected function morphTypeValue(mixed $morphType): string
{
if (PHP_VERSION_ID >= 80100) {
if ($morphType instanceof \BackedEnum) {
$value = $morphType->value;
if (! is_string($value)) {
$enumClass = $morphType::class;
throw new DefinitionException("Enum {$enumClass} must be string backed.");
}

return $value;
}

if ($morphType instanceof \UnitEnum) {
return $morphType->name;
}
}

return (string) $morphType;
}
}
Loading

0 comments on commit 7c560e2

Please sign in to comment.