import { Mutations, MutationsInputMap, MutationsResponseMap, } from '@ts/types/graphql/mutations'; import { Queries, QueriesInputMap, QueriesResponseMap, } from '@ts/types/graphql/queries'; import { settings } from '@utils/config'; /** * Retrieve the API url from settings. * * @returns {string} The API url. */ export const getAPIUrl = (): string => { const { url } = settings.api; if (!url) { throw new Error('API url is not defined.'); } return url; }; export type ResponseMap = K extends Mutations ? MutationsResponseMap : QueriesResponseMap; export type InputMap = T extends Mutations ? MutationsInputMap : QueriesInputMap; type FetchAPIVariables = T extends Queries ? QueriesInputMap[T] : T extends Mutations ? MutationsInputMap[T] : never; type FetchAPIProps> = { query: Q; variables?: V; }; type FetchAPIResponse = K extends Queries ? QueriesResponseMap[K] : K extends Mutations ? MutationsResponseMap[K] : never; export const fetchAPI = async ({ query, variables, }: FetchAPIProps): Promise> => { const response = await fetch(getAPIUrl(), { method: 'POST', headers: { 'content-type': 'application/json;charset=UTF-8', }, body: JSON.stringify({ query, variables, }), }); type JSONResponse = { data?: FetchAPIResponse; errors?: Array<{ message: string }>; }; const { data, errors }: JSONResponse = await response.json(); if (response.ok) { if (!data) return Promise.reject(new Error(`No data found"`)); return data; } else { console.error('Failed to fetch API'); const error = new Error( errors?.map((e) => e.message).join('\n') ?? 'unknown' ); return Promise.reject(error); } };