Skip to content
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

Extend directive command to allow choosing interfaces #1251

Merged
merged 16 commits into from Jun 11, 2020
Merged

Extend directive command to allow choosing interfaces #1251

merged 16 commits into from Jun 11, 2020

Conversation

WoutervdBrink
Copy link
Contributor

@WoutervdBrink WoutervdBrink commented Mar 22, 2020

  • Added or updated tests
  • Added Docs for all relevant versions
  • Updated CHANGELOG.md

Continuation of #1240; adds extensive options for implementing methods and interfaces belonging to directive types.

Changes

The lighthouse:directive command now takes the --type, --field and --argument options to implement the respective interfaces when creating a directive. The method stubs and imports are correctly created.

Writing tests for generators has proven to be quite difficult, as you can't really mock the Filesystem API used by the base GeneratorCommand, so you'd be spamming generated directives throughout your code. However, I have ran the command lots of times with varying options and so far it has not yet given invalid PHP code. For reference, an empty directive generated by the command looks like this:

<?php

namespace App\GraphQL\Directives;

use Nuwave\Lighthouse\Schema\Directives\BaseDirective;

class DoesNothingDirective extends BaseDirective 
{
    // TODO implement the directive https://lighthouse-php.com/master/custom-directives/getting-started.html
}

And a directive with all options enabled results in this:

Click to expand
<?php

namespace App\GraphQL\Directives;

use Closure;
use GraphQL\Language\AST\FieldDefinitionNode;
use GraphQL\Language\AST\InputValueDefinitionNode;
use GraphQL\Language\AST\ObjectTypeDefinitionNode;
use GraphQL\Language\AST\TypeDefinitionNode;
use GraphQL\Language\AST\TypeExtensionNode;
use Nuwave\Lighthouse\Execution\Arguments\ArgumentSet;
use Nuwave\Lighthouse\Schema\AST\DocumentAST;
use Nuwave\Lighthouse\Schema\Directives\BaseDirective;
use Nuwave\Lighthouse\Schema\Values\FieldValue;
use Nuwave\Lighthouse\Schema\Values\TypeValue;
use Nuwave\Lighthouse\Support\Contracts\ArgBuilderDirective;
use Nuwave\Lighthouse\Support\Contracts\ArgDirectiveForArray;
use Nuwave\Lighthouse\Support\Contracts\ArgManipulator;
use Nuwave\Lighthouse\Support\Contracts\ArgResolver;
use Nuwave\Lighthouse\Support\Contracts\ArgTransformerDirective;
use Nuwave\Lighthouse\Support\Contracts\FieldManipulator;
use Nuwave\Lighthouse\Support\Contracts\FieldMiddleware;
use Nuwave\Lighthouse\Support\Contracts\FieldResolver;
use Nuwave\Lighthouse\Support\Contracts\TypeExtensionManipulator;
use Nuwave\Lighthouse\Support\Contracts\TypeManipulator;
use Nuwave\Lighthouse\Support\Contracts\TypeMiddleware;
use Nuwave\Lighthouse\Support\Contracts\TypeResolver;

class DoesManyThingsDirective extends BaseDirective implements TypeManipulator, TypeMiddleware, TypeResolver, TypeExtensionManipulator, FieldResolver, FieldMiddleware, FieldManipulator, ArgDirectiveForArray, ArgTransformerDirective, ArgBuilderDirective, ArgResolver, ArgManipulator
{
    // TODO implement the directive https://lighthouse-php.com/master/custom-directives/getting-started.html

    /**
     * Apply manipulations from a type definition node.
     *
     * @param  \Nuwave\Lighthouse\Schema\AST\DocumentAST  $documentAST
     * @param  \GraphQL\Language\AST\TypeDefinitionNode  $typeDefinition
     * @return void
     */
    public function manipulateTypeDefinition(DocumentAST &$documentAST, TypeDefinitionNode &$typeDefinition)
    {
        // TODO implement the type manipulator
    }

    /**
     * Handle a type AST as it is converted to an executable type.
     *
     * @param  \Nuwave\Lighthouse\Schema\Values\TypeValue  $value
     * @param  \Closure  $next
     * @return \GraphQL\Type\Definition\Type
     */
    public function handleNode(TypeValue $value, Closure $next)
    {
        // TODO implement the type middleware
    }

    /**
     * Resolve a type AST to a GraphQL Type.
     *
     * @param  \Nuwave\Lighthouse\Schema\Values\TypeValue  $value
     * @return \GraphQL\Type\Definition\Type
     */
    public function resolveNode(TypeValue $value)
    {
        // TODO implement the type resolver
    }

    /**
     * Apply manipulations from a type extension node.
     *
     * @param  \Nuwave\Lighthouse\Schema\AST\DocumentAST  $documentAST
     * @param  \GraphQL\Language\AST\TypeExtensionNode  $typeExtension
     * @return void
     */
    public function manipulateTypeExtension(DocumentAST &$documentAST, TypeExtensionNode &$typeExtension)
    {
        // TODO implement the type extension manipulator
    }

    /**
     * Set a field resolver on the FieldValue.
     *
     * This must call $fieldValue->setResolver() before returning
     * the FieldValue.
     *
     * @param  \Nuwave\Lighthouse\Schema\Values\FieldValue  $fieldValue
     * @return \Nuwave\Lighthouse\Schema\Values\FieldValue
     */
    public function resolveField(FieldValue $fieldValue)
    {
        // TODO implement the field resolver
    }

    /**
     * Wrap around the final field resolver.
     *
     * @param  \Nuwave\Lighthouse\Schema\Values\FieldValue  $fieldValue
     * @param  \Closure  $next
     * @return \Nuwave\Lighthouse\Schema\Values\FieldValue
     */
    public function handleField(FieldValue $fieldValue, Closure $next)
    {
        // TODO implement the field middleware
    }

    /**
     * Manipulate the AST based on a field definition.
     *
     * @param  \Nuwave\Lighthouse\Schema\AST\DocumentAST  $documentAST
     * @param  \GraphQL\Language\AST\FieldDefinitionNode  $fieldDefinition
     * @param  \GraphQL\Language\AST\ObjectTypeDefinitionNode  $parentType
     * @return void
     */
    public function manipulateFieldDefinition(
        DocumentAST &$documentAST,
        FieldDefinitionNode &$fieldDefinition,
        ObjectTypeDefinitionNode &$parentType
    )
    {
        // TODO implement the field manipulator
    }

    /**
     * Apply transformations on the value of an argument given to a field.
     *
     * @param  mixed  $argumentValue
     * @return mixed
     */
    public function transform($argumentValue)
    {
        // TODO implement the arg transformer
    }

    /**
     * Add additional constraints to the builder based on the given argument value.
     *
     * @param  \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder  $builder
     * @param  mixed  $value
     * @return \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder
     */
    public function handleBuilder($builder, $value)
    {
        // TODO implement the arg builder
    }

    /**
     * @param  mixed  $root  The result of the parent resolver.
     * @param  mixed|ArgumentSet|ArgumentSet[]  $value  The slice of arguments that belongs to this nested resolver.
     * @return mixed
     */
    public function __invoke($root, $value)
    {
        // TODO implement the arg resolver
    }

    /**
     * Manipulate the AST.
     *
     * @param  \Nuwave\Lighthouse\Schema\AST\DocumentAST  $documentAST
     * @param  \GraphQL\Language\AST\InputValueDefinitionNode  $argDefinition
     * @param  \GraphQL\Language\AST\FieldDefinitionNode  $parentField
     * @param  \GraphQL\Language\AST\ObjectTypeDefinitionNode  $parentType
     * @return void
     */
    public function manipulateArgDefinition(
        DocumentAST &$documentAST,
        InputValueDefinitionNode &$argDefinition,
        FieldDefinitionNode &$parentField,
        ObjectTypeDefinitionNode &$parentType
    )
    {
        // TODO implement the arg manipulator
    }
}

Breaking changes

None 😄

src/Console/DirectiveCommand.php Show resolved Hide resolved
src/Console/DirectiveCommand.php Outdated Show resolved Hide resolved
src/Console/DirectiveCommand.php Outdated Show resolved Hide resolved
src/Console/stubs/directives/arg_resolver.stub Outdated Show resolved Hide resolved
@spawnia
Copy link
Collaborator

spawnia commented Mar 29, 2020

Really great effort. I think it needs some polish in terms of formatting, the overall design is sound.

In terms of testing, it might be a good idea to isolate a pure functional core of this command that does not write to the filesystem. There is quite a lot of functionality in there. Even testing some smaller functions might help.

Ping me once you think it is ready for another review. Don't worry about formatting too much, i will make a final pass over the PR anywas.

@spawnia spawnia changed the title Extended directive command Extend directive command to allow choosing interfaces Apr 5, 2020
Copy link
Collaborator

@spawnia spawnia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just tried it out in https://github.com/nuwave/lighthouse-example, works great.

I don't mind the lack of tests that much, developers will notice soon if things do not work out. Thank you and great job 👍

@spawnia spawnia merged commit 9679c32 into nuwave:master Jun 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants