Skip to content

Instantly share code, notes, and snippets.

@akozhemiakin
Last active February 12, 2025 17:38
Show Gist options
  • Save akozhemiakin/731b0c1e99eb89b01f80f08f9146b6b6 to your computer and use it in GitHub Desktop.
Save akozhemiakin/731b0c1e99eb89b01f80f08f9146b6b6 to your computer and use it in GitHub Desktop.

Revisions

  1. akozhemiakin revised this gist Feb 26, 2021. 1 changed file with 41 additions and 24 deletions.
    65 changes: 41 additions & 24 deletions apollo-requester.ts
    Original file line number Diff line number Diff line change
    @@ -1,44 +1,57 @@
    export class ApolloRequestError extends Error {
    readonly errors: ReadonlyArray<GraphQLError>;
    import { ApolloClient, QueryOptions, MutationOptions } from 'apollo-client';
    import { DocumentNode } from 'graphql';

    constructor(errors: ReadonlyArray<GraphQLError>) {
    super(`One or more errors while performing GraphQL request:\n${errors.map(v => `- ${v.message}`).join('\n')}`);
    import { getSdk, Requester } from '.generated/schema-typedefs';
    import { ApolloRequestError } from './ApolloRequestError';

    this.errors = errors;
    }
    }

    export type Sdk = ReturnType<typeof getSdk>;
    export type ApolloRequesterOptions<V, R> =
    | Omit<QueryOptions<V>, 'variables' | 'query'>
    | Omit<MutationOptions<R, V>, 'variables' | 'mutation'>;

    type ApolloRequesterOptions<V, R> = Omit<QueryOptions<V>, 'variables' | 'query'> | Omit<MutationOptions<R, V>, 'variables' | 'mutation'>;
    const validDocDefOps = ['mutation', 'query', 'subscription'];

    export function getSdkApollo<C>(client: ApolloClient<C>): Sdk {
    const requester: Requester = async <R, V>(doc: DocumentNode, variables: V, options?: ApolloRequesterOptions<V, R>): Promise<R> => {
    // Valid document should contain *single* query or mutation
    if (doc.definitions.length !== 1) {
    throw new Error('DocumentNode passed to Apollo Client must contain single query or mutation')
    // 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')
    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
    ...options,
    });

    if (response.errors) {
    throw new ApolloRequestError(response.errors)
    throw new ApolloRequestError(response.errors);
    }

    if(response.data === undefined || response.data === null) {
    if (response.data === undefined || response.data === null) {
    throw new Error('No data presented in the GraphQL response');
    }

    @@ -48,24 +61,28 @@ export function getSdkApollo<C>(client: ApolloClient<C>): Sdk {
    const response = await client.query<R, V>({
    query: doc,
    variables,
    ...options
    ...options,
    });

    if (response.errors) {
    throw new ApolloRequestError(response.errors)
    throw new ApolloRequestError(response.errors);
    }

    if(response.data === undefined || response.data === null) {
    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');
    throw new Error(
    'Subscription requests through SDK interface are not supported',
    );
    }
    }
    };

    return getSdk(requester);
    }
    }

    export type Sdk = ReturnType<typeof getSdkApollo>;
  2. akozhemiakin revised this gist Nov 24, 2019. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion apollo-requester.ts
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,6 @@ export type Sdk = ReturnType<typeof getSdk>;

    type ApolloRequesterOptions<V, R> = Omit<QueryOptions<V>, 'variables' | 'query'> | Omit<MutationOptions<R, V>, 'variables' | 'mutation'>;

    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
    export function getSdkApollo<C>(client: ApolloClient<C>): Sdk {
    const requester: Requester = async <R, V>(doc: DocumentNode, variables: V, options?: ApolloRequesterOptions<V, R>): Promise<R> => {
    // Valid document should contain *single* query or mutation
  3. akozhemiakin created this gist Nov 24, 2019.
    72 changes: 72 additions & 0 deletions apollo-requester.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,72 @@
    export class ApolloRequestError extends Error {
    readonly errors: ReadonlyArray<GraphQLError>;

    constructor(errors: ReadonlyArray<GraphQLError>) {
    super(`One or more errors while performing GraphQL request:\n${errors.map(v => `- ${v.message}`).join('\n')}`);

    this.errors = errors;
    }
    }

    export type Sdk = ReturnType<typeof getSdk>;

    type ApolloRequesterOptions<V, R> = Omit<QueryOptions<V>, 'variables' | 'query'> | Omit<MutationOptions<R, V>, 'variables' | 'mutation'>;

    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
    export function getSdkApollo<C>(client: ApolloClient<C>): Sdk {
    const requester: Requester = async <R, V>(doc: DocumentNode, variables: V, options?: ApolloRequesterOptions<V, R>): Promise<R> => {
    // Valid document should contain *single* query or mutation
    if (doc.definitions.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);
    }