graphql-editor / graphql-zeus

GraphQL client and GraphQL code generator with GraphQL autocomplete library generation ⚡⚡⚡ for browser,nodejs and react native ( apollo compatible )
https://graphqleditor.com/docs/tools/zeus/index/
MIT License
1.94k stars 105 forks source link

[FEAT] global scalars setup #358

Closed Hulkmaster closed 6 months ago

Hulkmaster commented 1 year ago

Problem: i have to add scalars to every single request

Solution: create global config with scalars, which will apply them automatically to each request

chain('/graphql', {
  scalars: {...}
});
aexol commented 1 year ago

We've done it internally with Thunder function

import { apiFetch as zeusFetch, Currency, FromSelector, LoginType, ModelTypes, Thunder, ZeusScalars } from '@/zeus';

const gqlRequest = useCallback(
    (props?: Config) => {
        const { config, noLoading = false } = props || {};
        const apiFetch = (query: string, variables: Record<string, unknown> = {}) => {
            const load = !noLoading && startLoading(config?.loadingMsg || 'Loading...');
            const fail = (message: string = config?.errorMsg || 'An error has occured') => {
                createToast({ content: message, type: 'error' });
                load && load.end();
            };
            return zeusFetch([
                process.env['NEXT_PUBLIC_BILLABEE'] || '',
                {
                    headers: {
                        ...(token && { Authorization: token }),
                        'Content-type': 'application/json',
                    },
                },
            ])(query, variables)
                .then(response => {
                    load && load.end();
                    config?.successMsg && createToast({ content: config.successMsg, type: 'success' });
                    return response;
                })
                .catch(err => {
                    const error = getErrorMessage(err);
                    fail(config?.errorMsg || error);
                    return {};
                });
        };
        return Thunder(apiFetch);
    },
    [token],
);
aexol commented 1 year ago

So in our case we display toast on error

aexol commented 1 year ago

and then we have the main functions

const scalars = ZeusScalars({
    Headers: {
        decode: (e: unknown) => e as Record<string, string>,
        encode: (e: unknown) => JSON.stringify(e as Record<string, string>),
    },
});
    const query = useCallback(
        (props?: Config) => {
            return gqlRequest(props)('query', { scalars: scalars });
        },
        [gqlRequest],
    );
    const mutation = useCallback(
        (props?: Config) => {
            return gqlRequest(props)('mutation', { scalars: scalars });
        },
        [gqlRequest],
    );
Hulkmaster commented 1 year ago

yeah we also created a wrapper for that, but having it in kinda "globalconfig" would be nice

rjmackay commented 1 year ago

Just hit this too. It's quite hard to wrap the client and maintain types so it'd be useful to have this as a first-class option.

aexol commented 6 months ago

Added those to thunder, so you won't hit type instatiation too deep on package export of generated SDK that consumes scalars.

export const YourSDK = (...options: chainOptions) =>
  Thunder(apiFetch(options),{ scalars })

//then somewhere else

YourSDK(HOST)("query")({
  collections:[{},{items:{id:true}}]
})