diff --git a/lib/createSchemaMapperForVisitor.ts b/lib/createSchemaMapperForVisitor.ts index 690c983..43228ce 100644 --- a/lib/createSchemaMapperForVisitor.ts +++ b/lib/createSchemaMapperForVisitor.ts @@ -2,6 +2,7 @@ import type { SchemaMapper } from '@graphql-tools/utils'; import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils'; import type { DirectiveLocation, + GraphQLArgument, GraphQLFieldConfig, GraphQLObjectType, GraphQLSchema, @@ -26,6 +27,17 @@ export const createMapper = ( return mutation; }, [MapperKind.OBJECT_TYPE](type, schema): GraphQLObjectType { + Object.values(type.getFields()).forEach(field => { + field.args.forEach(arg => { + const [directive] = getDirective(schema, arg, directiveName) ?? []; + if (!directive) return; + // eslint-disable-next-line no-param-reassign + visitor.args = directive; + visitor.visitArgumentDefinition(arg as GraphQLArgument, { + field, + }); + }); + }); const [directive] = getDirective(schema, type, directiveName) ?? []; if (!directive) return type; // eslint-disable-next-line no-param-reassign diff --git a/lib/foreignNodeId.test.ts b/lib/foreignNodeId.test.ts index dd79861..7888853 100644 --- a/lib/foreignNodeId.test.ts +++ b/lib/foreignNodeId.test.ts @@ -256,6 +256,71 @@ ${validationDirectionEnumTypeDefs(capitalizedName)} expect(result).toEqual({ data: rootValue }); }); + it('should decode arguments in type field argument', async (): Promise => { + const schema = new ForeignNodeId().applyToSchema( + makeExecutableSchema({ + resolvers: { + Query: {}, + TestType: { + typeIds: (_, { ids }) => { + return ids; + }, + }, + }, + typeDefs: [ + ...directiveTypeDefs, + gql` + type TestType { + typeIds( + ids: [ID!]! @foreignNodeId(typename: "TypeID") + otherArgs: String + ): [String!]! + } + type Query { + testType: TestType! + unusedQuery: TestType! + } + `, + ], + }), + ); + const source = print(gql` + query MyQuery($typeIds: [ID!]!) { + testType { + typeIds(ids: $typeIds) + } + } + `); + const decodedIds = ['123', '345', '678', '910']; + const encodedIds = decodedIds.map(id => toNodeId('TypeID', id)); + const variableValues = { + typeIds: encodedIds, + }; + const rootValue = { + testType: {}, + }; + + const contextValue = ForeignNodeId.createDirectiveContext({ + fromNodeId, + }); + const spy = jest.spyOn(contextValue, 'fromNodeId'); + const result = await graphql({ + contextValue, + rootValue, + schema, + source, + variableValues, + }); + expect(spy).toHaveBeenCalledTimes(encodedIds.length); + expect(result).toEqual({ + data: { + testType: { + typeIds: decodedIds, + }, + }, + }); + }); + it('should work when used on mutation inputs', async (): Promise => { const mockResolver = jest.fn().mockReturnValue('return value'); const typeName = 'MyType'; diff --git a/package.json b/package.json index 0c82fcb..120bd4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@profusion/apollo-validation-directives", - "version": "4.1.1", + "version": "4.1.2", "description": "GraphQL directives to implement field validations in Apollo Server", "author": "Gustavo Sverzut Barbieri ", "license": "MIT",