Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/spicy-paths-lose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-codegen/typescript-urql-graphcache': patch
---

Resolve a duplicate import, improve typing for "empty object" and respect `defaultScalarType`
21 changes: 8 additions & 13 deletions packages/plugins/typescript/urql-graphcache/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,14 +276,9 @@ function getOptimisticUpdatersConfig(
}

function getImports(config: UrqlGraphCacheConfig): string {
return [
`import { ${
config.offlineExchange ? 'offlineExchange' : 'cacheExchange'
} } from '@urql/exchange-graphcache';`,
`${
config.useTypeImports ? 'import type' : 'import'
} { Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';\n`,
].join('\n');
return `${config.useTypeImports ? 'import type' : 'import'} { ${
config.offlineExchange ? 'offlineExchange' : 'cacheExchange'
}, Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';\n`;
}

export const plugin: PluginFunction<UrqlGraphCacheConfig, Types.ComplexPluginOutput> = (
Expand All @@ -305,24 +300,24 @@ export const plugin: PluginFunction<UrqlGraphCacheConfig, Types.ComplexPluginOut
return {
prepend: [imports],
content: [
`export type WithTypename<T extends { __typename?: any }> = Partial<T> & { __typename: NonNullable<T['__typename']> };`,
`export type WithTypename<T extends { __typename?: ${config.defaultScalarType || 'any'} }> = Partial<T> & { __typename: NonNullable<T['__typename']> };`,

keys,

'export type GraphCacheResolvers = {\n' + resolvers.join(',\n') + '\n};',

'export type GraphCacheOptimisticUpdaters = ' +
(optimisticUpdaters ? '{\n ' + optimisticUpdaters.join(',\n ') + '\n};' : '{};'),
(optimisticUpdaters ? '{\n ' + optimisticUpdaters.join(',\n ') + '\n};' : 'object;'),

'export type GraphCacheUpdaters = {\n' +
` ${(queryType && queryType.name) || 'Mutation'}?: ` +
(queryUpdaters ? `{\n ${queryUpdaters.join(',\n ')}\n }` : '{}') +
(queryUpdaters ? `{\n ${queryUpdaters.join(',\n ')}\n }` : 'object') +
',\n' +
` ${(mutationType && mutationType.name) || 'Mutation'}?: ` +
(mutationUpdaters ? `{\n ${mutationUpdaters.join(',\n ')}\n }` : '{}') +
(mutationUpdaters ? `{\n ${mutationUpdaters.join(',\n ')}\n }` : 'object') +
',\n' +
` ${(subscriptionType && subscriptionType.name) || 'Subscription'}?: ` +
(subscriptionUpdaters ? `{\n ${subscriptionUpdaters.join(',\n ')}\n }` : '{}') +
(subscriptionUpdaters ? `{\n ${subscriptionUpdaters.join(',\n ')}\n }` : 'object') +
',\n' +
`${typeUpdateResolvers.join(',\n')}` +
',\n};',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`urql graphcache Should correctly name GraphCacheResolvers & GraphCacheOptimisticUpdaters with nonstandard mutationType names 1`] = `
"import { cacheExchange } from '@urql/exchange-graphcache';
import { Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';
"import { cacheExchange, Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';

export type WithTypename<T extends { __typename?: any }> = Partial<T> & { __typename: NonNullable<T['__typename']> };

Expand Down Expand Up @@ -32,7 +31,7 @@ export type GraphCacheUpdaters = {
Mutation_Root?: {
toggleTodo?: GraphCacheUpdateResolver<{ toggleTodo: WithTypename<Todo> }, Mutation_RootToggleTodoArgs>
},
Subscription?: {},
Subscription?: object,
Todo?: {
id?: GraphCacheUpdateResolver<Maybe<WithTypename<Todo>>, Record<string, never>>,
text?: GraphCacheUpdateResolver<Maybe<WithTypename<Todo>>, Record<string, never>>,
Expand All @@ -49,8 +48,7 @@ export type GraphCacheConfig = Parameters<typeof cacheExchange>[0] & {
`;

exports[`urql graphcache Should correctly output GraphCacheOptimisticUpdaters when there are no mutations 1`] = `
"import { cacheExchange } from '@urql/exchange-graphcache';
import { Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';
"import { cacheExchange, Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';

export type WithTypename<T extends { __typename?: any }> = Partial<T> & { __typename: NonNullable<T['__typename']> };

Expand All @@ -69,14 +67,14 @@ export type GraphCacheResolvers = {
}
};

export type GraphCacheOptimisticUpdaters = {};
export type GraphCacheOptimisticUpdaters = object;

export type GraphCacheUpdaters = {
Query_Root?: {
todos?: GraphCacheUpdateResolver<{ todos: Maybe<Array<WithTypename<Todo>>> }, Record<string, never>>
},
Mutation?: {},
Subscription?: {},
Mutation?: object,
Subscription?: object,
Todo?: {
id?: GraphCacheUpdateResolver<Maybe<WithTypename<Todo>>, Record<string, never>>,
text?: GraphCacheUpdateResolver<Maybe<WithTypename<Todo>>, Record<string, never>>,
Expand All @@ -93,8 +91,7 @@ export type GraphCacheConfig = Parameters<typeof cacheExchange>[0] & {
`;

exports[`urql graphcache Should output the cache-generic correctly (with interfaces) 1`] = `
"import { cacheExchange } from '@urql/exchange-graphcache';
import { Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';
"import { cacheExchange, Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';

export type WithTypename<T extends { __typename?: any }> = Partial<T> & { __typename: NonNullable<T['__typename']> };

Expand Down Expand Up @@ -128,14 +125,14 @@ export type GraphCacheResolvers = {
}
};

export type GraphCacheOptimisticUpdaters = {};
export type GraphCacheOptimisticUpdaters = object;

export type GraphCacheUpdaters = {
Query?: {
schoolBooks?: GraphCacheUpdateResolver<{ schoolBooks: Maybe<Array<WithTypename<Textbook>>> }, Record<string, never>>
},
Mutation?: {},
Subscription?: {},
Mutation?: object,
Subscription?: object,
Author?: {
id?: GraphCacheUpdateResolver<Maybe<WithTypename<Author>>, Record<string, never>>,
name?: GraphCacheUpdateResolver<Maybe<WithTypename<Author>>, Record<string, never>>,
Expand Down Expand Up @@ -165,8 +162,7 @@ export type GraphCacheConfig = Parameters<typeof cacheExchange>[0] & {
`;

exports[`urql graphcache Should output the cache-generic correctly (with typesPrefix and typesSuffix) 1`] = `
"import { cacheExchange } from '@urql/exchange-graphcache';
import { Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';
"import { cacheExchange, Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';

export type WithTypename<T extends { __typename?: any }> = Partial<T> & { __typename: NonNullable<T['__typename']> };

Expand Down Expand Up @@ -212,7 +208,7 @@ export type GraphCacheUpdaters = {
toggleTodosOptionalEntity?: GraphCacheUpdateResolver<{ toggleTodosOptionalEntity: Array<WithTypename<PrefixTodoSuffix>> }, PrefixMutationToggleTodosOptionalEntityArgsSuffix>,
toggleTodosOptional?: GraphCacheUpdateResolver<{ toggleTodosOptional: Maybe<Array<WithTypename<PrefixTodoSuffix>>> }, PrefixMutationToggleTodosOptionalArgsSuffix>
},
Subscription?: {},
Subscription?: object,
Author?: {
id?: GraphCacheUpdateResolver<Maybe<WithTypename<PrefixAuthorSuffix>>, Record<string, never>>,
name?: GraphCacheUpdateResolver<Maybe<WithTypename<PrefixAuthorSuffix>>, Record<string, never>>,
Expand All @@ -236,8 +232,7 @@ export type GraphCacheConfig = Parameters<typeof cacheExchange>[0] & {
`;

exports[`urql graphcache Should output the cache-generic correctly (with unions) 1`] = `
"import { cacheExchange } from '@urql/exchange-graphcache';
import { Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';
"import { cacheExchange, Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';

export type WithTypename<T extends { __typename?: any }> = Partial<T> & { __typename: NonNullable<T['__typename']> };

Expand Down Expand Up @@ -273,7 +268,7 @@ export type GraphCacheUpdaters = {
Mutation?: {
updateMedia?: GraphCacheUpdateResolver<{ updateMedia: Maybe<WithTypename<Media>> }, MutationUpdateMediaArgs>
},
Subscription?: {},
Subscription?: object,
Book?: {
id?: GraphCacheUpdateResolver<Maybe<WithTypename<Book>>, Record<string, never>>,
title?: GraphCacheUpdateResolver<Maybe<WithTypename<Book>>, Record<string, never>>,
Expand All @@ -295,8 +290,7 @@ export type GraphCacheConfig = Parameters<typeof cacheExchange>[0] & {
`;

exports[`urql graphcache Should output the cache-generic correctly 1`] = `
"import { cacheExchange } from '@urql/exchange-graphcache';
import { Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';
"import { cacheExchange, Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';

export type WithTypename<T extends { __typename?: any }> = Partial<T> & { __typename: NonNullable<T['__typename']> };

Expand Down Expand Up @@ -342,7 +336,7 @@ export type GraphCacheUpdaters = {
toggleTodosOptionalEntity?: GraphCacheUpdateResolver<{ toggleTodosOptionalEntity: Array<WithTypename<Todo>> }, MutationToggleTodosOptionalEntityArgs>,
toggleTodosOptional?: GraphCacheUpdateResolver<{ toggleTodosOptional: Maybe<Array<WithTypename<Todo>>> }, MutationToggleTodosOptionalArgs>
},
Subscription?: {},
Subscription?: object,
Author?: {
id?: GraphCacheUpdateResolver<Maybe<WithTypename<Author>>, Record<string, never>>,
name?: GraphCacheUpdateResolver<Maybe<WithTypename<Author>>, Record<string, never>>,
Expand Down
38 changes: 36 additions & 2 deletions packages/plugins/typescript/urql-graphcache/tests/urql.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,45 @@ describe('urql graphcache', () => {
const result = mergeOutputs([await plugin(schema, [], { useTypeImports: true })]);

expect(result).toBeSimilarStringTo(`\
import { cacheExchange } from '@urql/exchange-graphcache';
import type { Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';
import type { cacheExchange, Resolver as GraphCacheResolver, UpdateResolver as GraphCacheUpdateResolver, OptimisticMutationResolver as GraphCacheOptimisticMutationResolver } from '@urql/exchange-graphcache';
`);
});

it('should emit default scalar type if defaultScalarType config value is used', async () => {
const schema = buildSchema(/* GraphQL */ `
type Query {
todos: [Todo]
}

type Mutation {
toggleTodo(id: ID!): Todo!
toggleTodos(id: [ID!]!): [Todo!]!
toggleTodosOptionalArray(id: [ID!]!): [Todo!]
toggleTodosOptionalEntity(id: [ID!]!): [Todo]!
toggleTodosOptional(id: [ID!]!): [Todo]
}

type Author {
id: ID
name: String
friends: [Author]
friendsPaginated(from: Int!, limit: Int!): [Author]
}

type Todo {
id: ID
text: String
complete: Boolean
author: Author
}
`);
const result = mergeOutputs([await plugin(schema, [], { defaultScalarType: 'unknown' })]);

expect(result).toMatch(
`export type WithTypename<T extends { __typename?: unknown }> = Partial<T> & { __typename: NonNullable<T['__typename']> };`,
);
});

it('Should correctly name GraphCacheResolvers & GraphCacheOptimisticUpdaters with nonstandard mutationType names', async () => {
const schema = buildSchema(/* GraphQL */ `
schema {
Expand Down