Skip to content

Commit

Permalink
fix(typescript-resolvers): Fix optional resolver types (#7004)
Browse files Browse the repository at this point in the history
* Failing test

* Organize better

* Fix it

* Revert mistaken test

* Failing test

* Organize better

* Revert mistaken test

* Revert Maybe change

* Add new resolvers AvoidOptionasConfig key

* Create fluffy-pumpkins-build.md

Co-authored-by: Noah Seger <noah.seger@youearnedit.com>
Co-authored-by: Charly POLY <1252066+charlypoly@users.noreply.github.com>
  • Loading branch information
3 people committed Feb 1, 2022
1 parent ca1a643 commit c8ef37a
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .changeset/fluffy-pumpkins-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@graphql-codegen/typescript-resolvers": patch
"@graphql-codegen/visitor-plugin-common": patch
---

fix(typescript-resolvers): Fix optional field types
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const DEFAULT_AVOID_OPTIONALS: AvoidOptionalsConfig = {
inputValue: false,
field: false,
defaultValue: false,
resolvers: false,
};

export function normalizeAvoidOptionals(avoidOptionals?: boolean | AvoidOptionalsConfig): AvoidOptionalsConfig {
Expand All @@ -14,6 +15,7 @@ export function normalizeAvoidOptionals(avoidOptionals?: boolean | AvoidOptional
inputValue: avoidOptionals,
field: avoidOptionals,
defaultValue: avoidOptionals,
resolvers: avoidOptionals,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -987,14 +987,15 @@ export class BaseResolversVisitor<

const resolverType = isSubscriptionType ? 'SubscriptionResolver' : directiveMappings[0] ?? 'Resolver';

const avoidOptionals = this.config.avoidOptionals?.resolvers ?? this.config.avoidOptionals === true;
const signature: {
name: string;
modifier: string;
type: string;
genericTypes: string[];
} = {
name: node.name as any,
modifier: this.config.avoidOptionals ? '' : '?',
modifier: avoidOptionals ? '' : '?',
type: resolverType,
genericTypes: [
mappedTypeKey,
Expand Down
1 change: 1 addition & 0 deletions packages/plugins/other/visitor-plugin-common/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export interface AvoidOptionalsConfig {
object?: boolean;
inputValue?: boolean;
defaultValue?: boolean;
resolvers?: boolean;
}

export interface ParsedImport {
Expand Down
5 changes: 2 additions & 3 deletions packages/plugins/typescript/resolvers/src/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,8 @@ export class TypeScriptResolversVisitor extends BaseResolversVisitor<
}

protected formatRootResolver(schemaTypeName: string, resolverType: string, declarationKind: DeclarationKind): string {
return `${schemaTypeName}${this.config.avoidOptionals ? '' : '?'}: ${resolverType}${this.getPunctuation(
declarationKind
)}`;
const avoidOptionals = this.config.avoidOptionals?.resolvers ?? this.config.avoidOptionals === true;
return `${schemaTypeName}${avoidOptionals ? '' : '?'}: ${resolverType}${this.getPunctuation(declarationKind)}`;
}

private clearOptional(str: string): string {
Expand Down
39 changes: 39 additions & 0 deletions packages/plugins/typescript/resolvers/tests/ts-resolvers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2290,4 +2290,43 @@ export type ResolverFn<TResult, TParent, TContext, TArgs> = (

await validate(result);
});

it('#7005 - avoidOptionals should preserve optional resolvers', async () => {
const testSchema = buildSchema(/* GraphQL */ `
type Query {
users(filter: UserFilterInput = {}): [User!]!
ping: String!
}
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<ContextType = any, ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query']> = {
users?: Resolver<Array<ResolversTypes['User']>, ParentType, ContextType, RequireFields<QueryUsersArgs, 'filter'>>;
ping?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
};
`);
});
});

1 comment on commit c8ef37a

@vercel
Copy link

@vercel vercel bot commented on c8ef37a Feb 1, 2022

Choose a reason for hiding this comment

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

Please sign in to comment.