summaryrefslogtreecommitdiffstats
path: root/src/services/graphql/api.ts
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-08-20 21:39:51 +0200
committerArmand Philippot <git@armandphilippot.com>2022-08-20 21:39:51 +0200
commita0d00743cbbdb77b27c1a3d5711407ffed5befac (patch)
treef4caab160daf6b93c74d60ab93edd265c8edb158 /src/services/graphql/api.ts
parent46b158bf9d2f7fa9cc253915151e0b53c052a444 (diff)
refactor(types): move and rename GraphQL types
The api file in services was not really readable. So I move the types and I also rewrite a little the fetch function. I also rename most of the type to avoid conflict with preexisting types (like Node) and to keep consistency.
Diffstat (limited to 'src/services/graphql/api.ts')
-rw-r--r--src/services/graphql/api.ts312
1 files changed, 43 insertions, 269 deletions
diff --git a/src/services/graphql/api.ts b/src/services/graphql/api.ts
index 009aea4..e587ccc 100644
--- a/src/services/graphql/api.ts
+++ b/src/services/graphql/api.ts
@@ -1,271 +1,60 @@
-import { settings } from '@utils/config';
-import {
- articleBySlugQuery,
- articlesCardQuery,
- articlesEndCursor,
- articlesQuery,
- articlesSlugQuery,
- totalArticlesQuery,
-} from './articles.query';
-import { sendCommentMutation } from './comments.mutation';
-import { commentsQuery } from './comments.query';
-import { sendMailMutation } from './contact.mutation';
import {
- thematicBySlugQuery,
- thematicsListQuery,
- thematicsSlugQuery,
- totalThematicsQuery,
-} from './thematics.query';
+ Mutations,
+ MutationsInputMap,
+ MutationsResponseMap,
+} from '@ts/types/graphql/mutations';
import {
- topicBySlugQuery,
- topicsListQuery,
- topicsSlugQuery,
- totalTopicsQuery,
-} from './topics.query';
-
-export type Mutations = typeof sendMailMutation | typeof sendCommentMutation;
-
-export type Queries =
- | typeof articlesQuery
- | typeof articleBySlugQuery
- | typeof articlesCardQuery
- | typeof articlesEndCursor
- | typeof articlesSlugQuery
- | typeof commentsQuery
- | typeof thematicBySlugQuery
- | typeof thematicsListQuery
- | typeof thematicsSlugQuery
- | typeof topicBySlugQuery
- | typeof topicsListQuery
- | typeof topicsSlugQuery
- | typeof totalArticlesQuery
- | typeof totalThematicsQuery
- | typeof totalTopicsQuery;
-
-export type ArticleResponse<T> = {
- post: T;
-};
-
-export type ArticlesResponse<T> = {
- posts: T;
-};
-
-export type CommentsResponse<T> = {
- comments: T;
-};
-
-export type SendCommentResponse<T> = {
- createComment: T;
-};
-
-export type SendMailResponse<T> = {
- sendEmail: T;
-};
-
-export type ThematicResponse<T> = {
- thematic: T;
-};
-
-export type ThematicsResponse<T> = {
- thematics: T;
-};
-
-export type TopicResponse<T> = {
- topic: T;
-};
-
-export type TopicsResponse<T> = {
- topics: T;
-};
-
-export type PageInfo = {
- endCursor: string;
- hasNextPage: boolean;
- total: number;
-};
-
-export type Edges<T> = {
- cursor: string;
- node: T;
-};
-
-export type EdgesResponse<T> = {
- edges: Edges<T>[];
- pageInfo: PageInfo;
-};
-
-export type NodeResponse<T> = {
- node: T;
-};
-
-export type NodesResponse<T> = {
- nodes: T[];
-};
-
-export type EndCursor = Pick<
- EdgesResponse<Pick<PageInfo, 'endCursor'>>,
- 'pageInfo'
->;
-
-export type ResponseMap<T> = {
- [articleBySlugQuery]: ArticleResponse<T>;
- [articlesCardQuery]: ArticlesResponse<NodesResponse<T>>;
- [articlesEndCursor]: ArticlesResponse<EndCursor>;
- [articlesQuery]: ArticlesResponse<EdgesResponse<T>>;
- [articlesSlugQuery]: ArticlesResponse<EdgesResponse<T>>;
- [commentsQuery]: CommentsResponse<NodesResponse<T>>;
- [sendCommentMutation]: SendCommentResponse<T>;
- [sendMailMutation]: SendMailResponse<T>;
- [thematicBySlugQuery]: ThematicResponse<T>;
- [thematicsListQuery]: ThematicsResponse<EdgesResponse<T>>;
- [thematicsSlugQuery]: ThematicsResponse<EdgesResponse<T>>;
- [topicBySlugQuery]: TopicResponse<T>;
- [topicsListQuery]: TopicsResponse<EdgesResponse<T>>;
- [topicsSlugQuery]: TopicsResponse<EdgesResponse<T>>;
- [totalArticlesQuery]: ArticlesResponse<T>;
- [totalThematicsQuery]: ThematicsResponse<T>;
- [totalTopicsQuery]: TopicsResponse<T>;
-};
+ Queries,
+ QueriesInputMap,
+ QueriesResponseMap,
+} from '@ts/types/graphql/queries';
+import { settings } from '@utils/config';
-export type GraphQLResponse<
- T extends keyof ResponseMap<U>,
- U
-> = ResponseMap<U>[T];
+/**
+ * Retrieve the API url from settings.
+ *
+ * @returns {string} The API url.
+ */
+export const getAPIUrl = (): string => {
+ const { url } = settings.api;
-export type BySlugVar = {
- /**
- * A slug.
- */
- slug: string;
-};
+ if (!url) {
+ throw new Error('API url is not defined.');
+ }
-export type EdgesVars = {
- /**
- * A cursor.
- */
- after?: string;
- /**
- * The number of items to return.
- */
- first: number;
- /**
- * A search query.
- */
- search?: string;
+ return url;
};
-export type ByContentIdVar = {
- /**
- * An article id.
- */
- contentId: number;
-};
+export type ResponseMap<T, K extends Mutations | Queries> = K extends Mutations
+ ? MutationsResponseMap<T>
+ : QueriesResponseMap<T>;
-export type SearchVar = {
- /**
- * A search term.
- */
- search?: string;
-};
+export type InputMap<T extends Mutations | Queries> = T extends Mutations
+ ? MutationsInputMap
+ : QueriesInputMap;
-export type SendCommentVars = {
- /**
- * The author name.
- */
- author: string;
- /**
- * The author e-mail address.
- */
- authorEmail: string;
- /**
- * The author website.
- */
- authorUrl: string;
- /**
- * A mutation id.
- */
- clientMutationId: string;
- /**
- * A post or page id.
- */
- commentOn: number;
- /**
- * The comment body.
- */
- content: string;
- /**
- * The comment parent.
- */
- parent?: number;
-};
+type FetchAPIVariables<T> = T extends Queries
+ ? QueriesInputMap[T]
+ : T extends Mutations
+ ? MutationsInputMap[T]
+ : never;
-export type SendMailVars = {
- /**
- * The mail body.
- */
- body: string;
- /**
- * A mutation id.
- */
- clientMutationId: string;
- /**
- * The reply to e-mail address.
- */
- replyTo: string;
- /**
- * The mail subject.
- */
- subject: string;
+type FetchAPIProps<Q extends Queries | Mutations, V = FetchAPIVariables<Q>> = {
+ query: Q;
+ variables?: V;
};
-export type VariablesMap = {
- [articleBySlugQuery]: BySlugVar;
- [articlesCardQuery]: EdgesVars;
- [articlesEndCursor]: EdgesVars;
- [articlesQuery]: EdgesVars;
- [articlesSlugQuery]: EdgesVars;
- [commentsQuery]: ByContentIdVar;
- [sendCommentMutation]: SendCommentVars;
- [sendMailMutation]: SendMailVars;
- [thematicBySlugQuery]: BySlugVar;
- [thematicsListQuery]: EdgesVars;
- [thematicsSlugQuery]: EdgesVars;
- [topicBySlugQuery]: BySlugVar;
- [topicsListQuery]: EdgesVars;
- [topicsSlugQuery]: EdgesVars;
- [totalArticlesQuery]: SearchVar;
- [totalThematicsQuery]: null;
- [totalTopicsQuery]: null;
-};
+type FetchAPIResponse<T, K extends Queries | Mutations> = K extends Queries
+ ? QueriesResponseMap<T>[K]
+ : K extends Mutations
+ ? MutationsResponseMap<T>[K]
+ : never;
-export type FetchAPIProps<T extends Queries | Mutations> = {
- /**
- * 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<T, U extends Queries | Mutations>({
- api,
+export const fetchAPI = async <T, K extends Queries | Mutations>({
query,
variables,
-}: FetchAPIProps<U>): Promise<GraphQLResponse<U, T>> {
- const response = await fetch(api, {
+}: FetchAPIProps<K>): Promise<FetchAPIResponse<T, K>> => {
+ const response = await fetch(getAPIUrl(), {
method: 'POST',
headers: {
'content-type': 'application/json;charset=UTF-8',
@@ -277,7 +66,7 @@ export async function fetchAPI<T, U extends Queries | Mutations>({
});
type JSONResponse = {
- data?: GraphQLResponse<U, T>;
+ data?: FetchAPIResponse<T, K>;
errors?: Array<{ message: string }>;
};
@@ -294,19 +83,4 @@ export async function fetchAPI<T, U extends Queries | Mutations>({
);
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;
};