diff --git a/.changeset/late-olives-pull.md b/.changeset/late-olives-pull.md new file mode 100644 index 00000000000..2291238c53b --- /dev/null +++ b/.changeset/late-olives-pull.md @@ -0,0 +1,6 @@ +--- +'@graphql-codegen/visitor-plugin-common': patch +'@graphql-codegen/typescript-resolvers': patch +--- + +Respect avoidOptionals when all arguments are optional diff --git a/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts index 123f9e6b3b6..ac43a2328a7 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts @@ -1401,6 +1401,11 @@ export class BaseResolversVisitor< ) : null; + const avoidInputsOptionals = + typeof this.config.avoidOptionals === 'object' + ? this.config.avoidOptionals?.inputValue + : this.config.avoidOptionals === true; + if (argsType !== null) { const argsToForceRequire = original.arguments.filter( arg => !!arg.defaultValue || arg.type.kind === 'NonNullType' @@ -1408,7 +1413,7 @@ export class BaseResolversVisitor< if (argsToForceRequire.length > 0) { argsType = this.applyRequireFields(argsType, argsToForceRequire); - } else if (original.arguments.length > 0) { + } else if (original.arguments.length > 0 && avoidInputsOptionals !== true) { argsType = this.applyOptionalFields(argsType, original.arguments); } } @@ -1428,7 +1433,7 @@ export class BaseResolversVisitor< const resolverType = isSubscriptionType ? 'SubscriptionResolver' : directiveMappings[0] ?? 'Resolver'; - const avoidOptionals = + const avoidResolverOptionals = typeof this.config.avoidOptionals === 'object' ? this.config.avoidOptionals?.resolvers : this.config.avoidOptionals === true; @@ -1439,7 +1444,7 @@ export class BaseResolversVisitor< genericTypes: string[]; } = { name: node.name as any, - modifier: avoidOptionals ? '' : '?', + modifier: avoidResolverOptionals ? '' : '?', type: resolverType, genericTypes: [mappedTypeKey, parentTypeSignature, contextType, argsType].filter(f => f), }; diff --git a/packages/plugins/typescript/resolvers/tests/ts-resolvers.spec.ts b/packages/plugins/typescript/resolvers/tests/ts-resolvers.spec.ts index ca86237229a..c557bad7b97 100644 --- a/packages/plugins/typescript/resolvers/tests/ts-resolvers.spec.ts +++ b/packages/plugins/typescript/resolvers/tests/ts-resolvers.spec.ts @@ -3002,4 +3002,41 @@ export type ResolverFn = ( }; `); }); + + it('#9438 - avoidOptionals should not wrap arguments with partial', async () => { + const testSchema = buildSchema(/* GraphQL */ ` + type Query { + users(filter: UserFilterInput): [User!]! + } + + input UserFilterInput { + status: String = "ACTIVE" + } + + type User { + id: ID! + } + `); + + const output = (await plugin( + testSchema, + [], + { + avoidOptionals: { + defaultValue: true, + field: true, + inputValue: true, + object: true, + resolvers: false, + }, + } as any, + { outputFile: 'graphql.ts' } + )) as Types.ComplexPluginOutput; + + expect(output.content).toBeSimilarStringTo(` + export type QueryResolvers = { + users?: Resolver, ParentType, ContextType, QueryUsersArgs>; + }; + `); + }); });