import { settings } from '@utils/config'; import { articleBySlugQuery, articlesCardQuery, articlesQuery, articlesSlugQuery, totalArticlesQuery, } from './articles.query'; import { commentsQuery } from './comments.query'; import { sendMailMutation } from './contact.mutation'; import { thematicBySlugQuery, thematicsListQuery, thematicsSlugQuery, } from './thematics.query'; import { topicBySlugQuery, topicsListQuery, topicsSlugQuery, } from './topics.query'; export type Mutations = typeof sendMailMutation; export type Queries = | typeof articlesQuery | typeof articleBySlugQuery | typeof articlesCardQuery | typeof articlesSlugQuery | typeof commentsQuery | typeof thematicBySlugQuery | typeof thematicsListQuery | typeof thematicsSlugQuery | typeof topicBySlugQuery | typeof topicsListQuery | typeof topicsSlugQuery | typeof totalArticlesQuery; export type ArticleResponse = { post: T; }; export type ArticlesResponse = { posts: T; }; export type CommentsResponse = { comments: T[]; }; export type SendMailResponse = { sendEmail: T; }; export type ThematicResponse = { thematic: T; }; export type ThematicsResponse = { thematics: T; }; export type TopicResponse = { topic: T; }; export type TopicsResponse = { topics: T; }; export type PageInfo = { endCursor: string; hasNextPage: boolean; total: number; }; export type Edges = { cursor: string; node: T; }; export type EdgesResponse = { edges: Edges[]; pageInfo: PageInfo; }; export type NodeResponse = { node: T; }; export type NodesResponse = { nodes: T[]; }; export type ResponseMap = { [articleBySlugQuery]: ArticleResponse; [articlesCardQuery]: ArticlesResponse>; [articlesQuery]: ArticlesResponse>; [articlesSlugQuery]: ArticlesResponse>; [commentsQuery]: CommentsResponse>; [sendMailMutation]: SendMailResponse; [thematicBySlugQuery]: ThematicResponse; [thematicsListQuery]: ThematicsResponse>; [thematicsSlugQuery]: ThematicsResponse>; [topicBySlugQuery]: TopicResponse; [topicsListQuery]: TopicsResponse>; [topicsSlugQuery]: TopicsResponse>; [totalArticlesQuery]: ArticlesResponse; }; export type GraphQLResponse< T extends keyof ResponseMap, U > = ResponseMap[T]; export type BySlugVar = { /** * A slug. */ slug: string; }; export type EdgesVars = { /** * A cursor. */ after?: string; /** * The number of items to return. */ first: number; /** * A search query. */ search?: string; }; export type ByContentIdVar = { /** * An article id. */ contentId: number; }; export type sendMailVars = { body: string; clientMutationId: string; replyTo: string; subject: string; }; export type VariablesMap = { [articleBySlugQuery]: BySlugVar; [articlesCardQuery]: EdgesVars; [articlesQuery]: EdgesVars; [articlesSlugQuery]: EdgesVars; [commentsQuery]: ByContentIdVar; [sendMailMutation]: sendMailVars; [thematicBySlugQuery]: BySlugVar; [thematicsListQuery]: EdgesVars; [thematicsSlugQuery]: EdgesVars; [topicBySlugQuery]: BySlugVar; [topicsListQuery]: EdgesVars; [topicsSlugQuery]: EdgesVars; [totalArticlesQuery]: null; }; export type FetchAPIProps = { /** * A GraphQL API URL. */ api: string; /** * A GraphQL query. */ query: T; /** * (Optional) The query variables. */ variables?: VariablesMap[T]; }; /** * Fetch a GraphQL API. * @param {object} obj - An object. * @param {string} obj.api - A GraphQL API URL. * @param {Queries} obj.query - A GraphQL query. * @param {object} [obj.variables] - The query variables. */ export async function fetchAPI({ api, query, variables, }: FetchAPIProps): Promise> { const response = await fetch(api, { method: 'POST', headers: { 'content-type': 'application/json;charset=UTF-8', }, body: JSON.stringify({ query, variables, }), }); type JSONResponse = { data?: GraphQLResponse; 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); } } /** * 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; };