From f111685c5886f3e77edfd3621c98d8ac1b9bcce4 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Fri, 24 Nov 2023 20:00:08 +0100 Subject: refactor(services, types): reorganize GraphQL fetchers and data types The Typescript mapped types was useful for autocompletion in fetchers but their are harder to maintain. I think it's better to keep each query close to its fetcher to have a better understanding of the fetched data. So I: * colocate queries with their own fetcher * colocate mutations with their own mutator * remove Typescript mapped types for queries and mutations * move data convertors inside graphql services * rename most of data types and fetchers --- src/utils/helpers/graphql.ts | 64 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/utils/helpers/graphql.ts (limited to 'src/utils/helpers/graphql.ts') diff --git a/src/utils/helpers/graphql.ts b/src/utils/helpers/graphql.ts new file mode 100644 index 0000000..e07b151 --- /dev/null +++ b/src/utils/helpers/graphql.ts @@ -0,0 +1,64 @@ +import type { Nullable } from '../../types'; +import { CONFIG } from '../config'; + +/** + * Retrieve the API url from settings. + * + * @returns {string} The API url. + */ +export const getGraphQLUrl = (): string => { + if (!CONFIG.api.url) throw new Error('You forgot to define the API url.'); + + return CONFIG.api.url; +}; + +export type GraphQLData = Record>; + +type GraphQLResponse> = { + data: T; + errors?: { message: string }[]; +}; + +export type FetchGraphQLConfig = { + query: string; + url: string; + variables?: Record; +}; + +/** + * Retrieve GraphQL data using fetch. + * + * @template T - The expected data type. + * @param {FetchGraphQLConfig} config - A configuration object. + * @returns {Promise} The data. + */ +export const fetchGraphQL = async < + T extends GraphQLData = GraphQLData, +>({ + query, + url, + variables, +}: FetchGraphQLConfig): Promise => { + const response = await fetch(url, { + method: 'POST', + headers: { + 'content-type': 'application/json;charset=UTF-8', + }, + body: JSON.stringify({ + query, + variables, + }), + }); + + const { data, errors }: GraphQLResponse = await response.json(); + + if (!response.ok) { + const error = new Error( + errors?.map((e) => e.message).join('\n') ?? 'Network response was not OK' + ); + + return Promise.reject(error); + } + + return data; +}; -- cgit v1.2.3