From 376c94ddb4973d43a1f35f86d57600ef19421817 Mon Sep 17 00:00:00 2001 From: Arno DUBOIS Date: Tue, 15 Aug 2023 22:44:11 +0000 Subject: [PATCH] fix(graphql): fix directives on arguments There has been a lot of issues with directives not being applied and registered. Most of those cases have been fixed by simply forcing the IDL (like explained here https://github.com/graphql/graphql-js/issues/1343). Unfortunately, arguments have been forgotten, meaning that no directive applied on arguments were actually run or even detected. This PR stands to correct that and properly add directive to needed fields. --- .../schema-builder/factories/args.factory.ts | 26 ++++++++++++++----- .../factories/ast-definition-node.factory.ts | 26 +++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/packages/graphql/lib/schema-builder/factories/args.factory.ts b/packages/graphql/lib/schema-builder/factories/args.factory.ts index 62a6753ba..735ffd2d6 100644 --- a/packages/graphql/lib/schema-builder/factories/args.factory.ts +++ b/packages/graphql/lib/schema-builder/factories/args.factory.ts @@ -7,10 +7,14 @@ import { getDefaultValue } from '../helpers/get-default-value.helper'; import { ClassMetadata, MethodArgsMetadata } from '../metadata'; import { TypeMetadataStorage } from '../storages/type-metadata.storage'; import { InputTypeFactory } from './input-type.factory'; +import { AstDefinitionNodeFactory } from './ast-definition-node.factory'; @Injectable() export class ArgsFactory { - constructor(private readonly inputTypeFactory: InputTypeFactory) {} + constructor( + private readonly inputTypeFactory: InputTypeFactory, + private readonly astDefinitionNodeFactory: AstDefinitionNodeFactory, + ) {} public create( args: MethodArgsMetadata[], @@ -73,15 +77,25 @@ export class ArgsFactory { ); const { schemaName } = field; + const type = this.inputTypeFactory.create( + field.name, + field.typeFn(), + options, + field.options, + ); fieldConfigMap[schemaName] = { description: field.description, - type: this.inputTypeFactory.create( + type, + defaultValue: field.options.defaultValue, + /** + * AST node has to be manually created in order to define directives + * (more on this topic here: https://github.com/graphql/graphql-js/issues/1343) + */ + astNode: this.astDefinitionNodeFactory.createArgNode( field.name, - field.typeFn(), - options, - field.options, + type, + field.directives, ), - defaultValue: field.options.defaultValue, }; }); } diff --git a/packages/graphql/lib/schema-builder/factories/ast-definition-node.factory.ts b/packages/graphql/lib/schema-builder/factories/ast-definition-node.factory.ts index 653590648..190dc002b 100644 --- a/packages/graphql/lib/schema-builder/factories/ast-definition-node.factory.ts +++ b/packages/graphql/lib/schema-builder/factories/ast-definition-node.factory.ts @@ -130,6 +130,32 @@ export class AstDefinitionNodeFactory { }; } + createArgNode( + name: string, + type: GraphQLInputType, + directiveMetadata?: DirectiveMetadata[], + ): InputValueDefinitionNode | undefined { + if (isEmpty(directiveMetadata)) { + return; + } + + return { + kind: Kind.INPUT_VALUE_DEFINITION, + type: { + kind: Kind.NAMED_TYPE, + name: { + kind: Kind.NAME, + value: type.toString(), + }, + }, + name: { + kind: Kind.NAME, + value: name, + }, + directives: directiveMetadata.map(this.createDirectiveNode), + }; + } + private createDirectiveNode( directive: DirectiveMetadata, ): ConstDirectiveNode {