-
-
Save akozhemiakin/731b0c1e99eb89b01f80f08f9146b6b6 to your computer and use it in GitHub Desktop.
import { ApolloClient, QueryOptions, MutationOptions } from 'apollo-client'; | |
import { DocumentNode } from 'graphql'; | |
import { getSdk, Requester } from '.generated/schema-typedefs'; | |
import { ApolloRequestError } from './ApolloRequestError'; | |
export type ApolloRequesterOptions<V, R> = | |
| Omit<QueryOptions<V>, 'variables' | 'query'> | |
| Omit<MutationOptions<R, V>, 'variables' | 'mutation'>; | |
const validDocDefOps = ['mutation', 'query', 'subscription']; | |
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type | |
export function getSdkApollo<C>(client: ApolloClient<C>) { | |
const requester: Requester = async <R, V>( | |
doc: DocumentNode, | |
variables: V, | |
options?: ApolloRequesterOptions<V, R>, | |
): Promise<R> => { | |
// Valid document should contain *single* query or mutation unless it's has a fragment | |
if ( | |
doc.definitions.filter( | |
d => | |
d.kind === 'OperationDefinition' && | |
validDocDefOps.includes(d.operation), | |
).length !== 1 | |
) { | |
throw new Error( | |
'DocumentNode passed to Apollo Client must contain single query or mutation', | |
); | |
} | |
const definition = doc.definitions[0]; | |
// Valid document should contain *OperationDefinition* | |
if (definition.kind !== 'OperationDefinition') { | |
throw new Error( | |
'DocumentNode passed to Apollo Client must contain single query or mutation', | |
); | |
} | |
switch (definition.operation) { | |
case 'mutation': { | |
const response = await client.mutate<R, V>({ | |
mutation: doc, | |
variables, | |
...options, | |
}); | |
if (response.errors) { | |
throw new ApolloRequestError(response.errors); | |
} | |
if (response.data === undefined || response.data === null) { | |
throw new Error('No data presented in the GraphQL response'); | |
} | |
return response.data; | |
} | |
case 'query': { | |
const response = await client.query<R, V>({ | |
query: doc, | |
variables, | |
...options, | |
}); | |
if (response.errors) { | |
throw new ApolloRequestError(response.errors); | |
} | |
if (response.data === undefined || response.data === null) { | |
throw new Error('No data presented in the GraphQL response'); | |
} | |
return response.data; | |
} | |
case 'subscription': { | |
throw new Error( | |
'Subscription requests through SDK interface are not supported', | |
); | |
} | |
} | |
}; | |
return getSdk(requester); | |
} | |
export type Sdk = ReturnType<typeof getSdkApollo>; |
fetchPolicy
of QueryOptions
does not compatible with fetchPolicy of MutationOptions
. I fixed it by omitting the fetchPolicy
of QueryOptions
. Are there alternative ways to fix it?
@bakamitai456 I worked around it by doing this:
... (line 42)
case "mutation": {
const fetchPolicy = options?.fetchPolicy as MutationFetchPolicy;
const response = await client.mutate<R, V>({
mutation: doc,
variables,
...options,
fetchPolicy,
});
...
Not sure if that's more "elegant", but I prefer it to omitting QueryOptions
's fetchPolicy
. 😅
i dont think this is working with later versions of typescript. V does not satisfy OperationVariables
@beefancohen Did you find a workaround? I am having the same issue.
Any updates?
Line 15 should be changed to:
const requester = async <R, V extends OperationVariables>(
Line 85 should be changed to
return getSdk(requester as Requester<C>);
This should make it compatible. Since OperationVariables
is just an alias for Record<string, any>
and a necessary constraint this should not introduce any problems.
But feel free to correct me ;-)
I agree with @snejdlawso. It's been a while but if I remember correctly we did something like this:
Here's what we did:
Line 15:
const requester: Requester = async <R, V extends OperationVariables>
Line 46:
const fetchPolicy = options?.fetchPolicy as MutationFetchPolicy;
[Extra]
Might also add this after line 81:
default: {
throw new Error("Invalid Operation type received!");
}
Thanks for this! What does
ApolloRequestError
look like?