diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-08-20 21:39:51 +0200 | 
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-08-20 21:39:51 +0200 | 
| commit | a0d00743cbbdb77b27c1a3d5711407ffed5befac (patch) | |
| tree | f4caab160daf6b93c74d60ab93edd265c8edb158 /src/services/graphql | |
| parent | 46b158bf9d2f7fa9cc253915151e0b53c052a444 (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')
| -rw-r--r-- | src/services/graphql/api.ts | 312 | ||||
| -rw-r--r-- | src/services/graphql/articles.query.ts | 2 | ||||
| -rw-r--r-- | src/services/graphql/articles.ts | 42 | ||||
| -rw-r--r-- | src/services/graphql/comments.ts | 47 | ||||
| -rw-r--r-- | src/services/graphql/contact.ts | 8 | ||||
| -rw-r--r-- | src/services/graphql/thematics.ts | 33 | ||||
| -rw-r--r-- | src/services/graphql/topics.ts | 32 | 
7 files changed, 113 insertions, 363 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;  }; diff --git a/src/services/graphql/articles.query.ts b/src/services/graphql/articles.query.ts index 3e1f575..46e3df6 100644 --- a/src/services/graphql/articles.query.ts +++ b/src/services/graphql/articles.query.ts @@ -181,7 +181,7 @@ export const totalArticlesQuery = `query PostsTotal($search: String = "") {  /**   * Query the end cursor based on the queried posts number.   */ -export const articlesEndCursor = `query EndCursorAfter($first: Int) { +export const articlesEndCursorQuery = `query EndCursorAfter($first: Int) {    posts(first: $first) {      pageInfo {        hasNextPage diff --git a/src/services/graphql/articles.ts b/src/services/graphql/articles.ts index 27406ac..1a7b2e0 100644 --- a/src/services/graphql/articles.ts +++ b/src/services/graphql/articles.ts @@ -1,4 +1,6 @@ -import { Slug, type Article, type ArticleCard } from '@ts/types/app'; +import { type Article, type ArticleCard, type Slug } from '@ts/types/app'; +import { GraphQLEdgesInput, GraphQLPageInfo } from '@ts/types/graphql/generics'; +import { EdgesResponse, EndCursorResponse } from '@ts/types/graphql/queries';  import {    type RawArticle,    type RawArticlePreview, @@ -7,18 +9,11 @@ import {  import { getAuthorFromRawData } from '@utils/helpers/author';  import { getImageFromRawData } from '@utils/helpers/images';  import { getPageLinkFromRawData } from '@utils/helpers/pages'; -import { -  EdgesResponse, -  EdgesVars, -  EndCursor, -  fetchAPI, -  getAPIUrl, -  PageInfo, -} from './api'; +import { fetchAPI } from './api';  import {    articleBySlugQuery,    articlesCardQuery, -  articlesEndCursor, +  articlesEndCursorQuery,    articlesQuery,    articlesSlugQuery,    totalArticlesQuery, @@ -31,7 +26,6 @@ import {   */  export const getTotalArticles = async (search?: string): Promise<number> => {    const response = await fetchAPI<TotalItems, typeof totalArticlesQuery>({ -    api: getAPIUrl(),      query: totalArticlesQuery,      variables: { search },    }); @@ -41,7 +35,7 @@ export const getTotalArticles = async (search?: string): Promise<number> => {  export type GetArticlesReturn = {    articles: Article[]; -  pageInfo: PageInfo; +  pageInfo: GraphQLPageInfo;  };  /** @@ -97,14 +91,13 @@ export const getArticleFromRawData = (data: RawArticle): Article => {  /**   * Retrieve the given number of articles from API.   * - * @param {EdgesVars} props - An object of GraphQL variables. + * @param {GraphQLEdgesInput} props - An object of GraphQL variables.   * @returns {Promise<EdgesResponse<RawArticle>>} The articles data.   */  export const getArticles = async ( -  props: EdgesVars +  props: GraphQLEdgesInput  ): Promise<EdgesResponse<RawArticle>> => {    const response = await fetchAPI<RawArticle, typeof articlesQuery>({ -    api: getAPIUrl(),      query: articlesQuery,      variables: { ...props },    }); @@ -133,15 +126,14 @@ const getArticleCardFromRawData = (data: RawArticlePreview): ArticleCard => {  /**   * Retrieve the given number of article cards from API.   * - * @param {EdgesVars} obj - An object. + * @param {GraphQLEdgesInput} obj - An object.   * @param {number} obj.first - The number of articles.   * @returns {Promise<ArticleCard[]>} - The article cards data.   */  export const getArticlesCard = async ({    first, -}: EdgesVars): Promise<ArticleCard[]> => { +}: GraphQLEdgesInput): Promise<ArticleCard[]> => {    const response = await fetchAPI<RawArticlePreview, typeof articlesCardQuery>({ -    api: getAPIUrl(),      query: articlesCardQuery,      variables: { first },    }); @@ -157,7 +149,6 @@ export const getArticlesCard = async ({   */  export const getArticleBySlug = async (slug: string): Promise<Article> => {    const response = await fetchAPI<RawArticle, typeof articleBySlugQuery>({ -    api: getAPIUrl(),      query: articleBySlugQuery,      variables: { slug },    }); @@ -173,7 +164,6 @@ export const getArticleBySlug = async (slug: string): Promise<Article> => {  export const getAllArticlesSlugs = async (): Promise<string[]> => {    const totalArticles = await getTotalArticles();    const response = await fetchAPI<Slug, typeof articlesSlugQuery>({ -    api: getAPIUrl(),      query: articlesSlugQuery,      variables: { first: totalArticles },    }); @@ -184,15 +174,17 @@ export const getAllArticlesSlugs = async (): Promise<string[]> => {  /**   * Retrieve the last cursor.   * - * @param {EdgesVars} props - An object of GraphQL variables. + * @param {GraphQLEdgesInput} props - An object of GraphQL variables.   * @returns {Promise<string>} - The end cursor.   */  export const getArticlesEndCursor = async ( -  props: EdgesVars +  props: GraphQLEdgesInput  ): Promise<string> => { -  const response = await fetchAPI<EndCursor, typeof articlesEndCursor>({ -    api: getAPIUrl(), -    query: articlesEndCursor, +  const response = await fetchAPI< +    EndCursorResponse, +    typeof articlesEndCursorQuery +  >({ +    query: articlesEndCursorQuery,      variables: { ...props },    }); diff --git a/src/services/graphql/comments.ts b/src/services/graphql/comments.ts index 28ddfd0..86b6a35 100644 --- a/src/services/graphql/comments.ts +++ b/src/services/graphql/comments.ts @@ -1,10 +1,33 @@  import { Comment } from '@ts/types/app'; +import { GraphQLEdgesInput } from '@ts/types/graphql/generics'; +import { SendCommentInput, SentComment } from '@ts/types/graphql/mutations'; +import { ContentId } from '@ts/types/graphql/queries';  import { RawComment } from '@ts/types/raw-data';  import { getAuthorFromRawData } from '@utils/helpers/author'; -import { fetchAPI, getAPIUrl, SendCommentVars } from './api'; +import { fetchAPI } from './api';  import { sendCommentMutation } from './comments.mutation';  import { commentsQuery } from './comments.query'; +type FetchCommentsInput = ContentId & +  Pick<GraphQLEdgesInput, 'after' | 'first'>; + +/** + * Retrieve the comments list from GraphQL. + * + * @param {FetchCommentsInput} variables - An object of variables. + * @returns {Promise<RawComment[]>} The raw comments. + */ +export const fetchComments = async ( +  variables: FetchCommentsInput +): Promise<RawComment[]> => { +  const response = await fetchAPI<RawComment, typeof commentsQuery>({ +    query: commentsQuery, +    variables, +  }); + +  return response.comments.nodes; +}; +  /**   * Create a comments tree with replies.   * @@ -62,27 +85,12 @@ export const getCommentFromRawData = (comment: RawComment): Comment => {   * @returns {Promise<Comment[]>} The comments list.   */  export const getPostComments = async (id: number): Promise<Comment[]> => { -  const response = await fetchAPI<RawComment, typeof commentsQuery>({ -    api: getAPIUrl(), -    query: commentsQuery, -    variables: { contentId: id }, -  }); - -  const comments = response.comments.nodes.map((comment) => -    getCommentFromRawData(comment) -  ); +  const rawComments = await fetchComments({ contentId: id }); +  const comments = rawComments.map((comment) => getCommentFromRawData(comment));    return buildCommentsTree(comments);  }; -export type SentComment = { -  clientMutationId: string; -  success: boolean; -  comment: { -    approved: boolean; -  } | null; -}; -  /**   * Send a comment using GraphQL API.   * @@ -90,10 +98,9 @@ export type SentComment = {   * @returns {Promise<SentEmail>} The mutation response.   */  export const sendComment = async ( -  data: SendCommentVars +  data: SendCommentInput  ): Promise<SentComment> => {    const response = await fetchAPI<SentComment, typeof sendCommentMutation>({ -    api: getAPIUrl(),      query: sendCommentMutation,      variables: { ...data },    }); diff --git a/src/services/graphql/contact.ts b/src/services/graphql/contact.ts index 00c6ca2..de078b9 100644 --- a/src/services/graphql/contact.ts +++ b/src/services/graphql/contact.ts @@ -1,4 +1,5 @@ -import { fetchAPI, getAPIUrl, SendMailVars } from './api'; +import { SendMailInput } from '@ts/types/graphql/mutations'; +import { fetchAPI } from './api';  import { sendMailMutation } from './contact.mutation';  export type SentEmail = { @@ -12,12 +13,11 @@ export type SentEmail = {  /**   * Send an email using GraphQL API.   * - * @param {sendMailVars} data - The mail data. + * @param {SendMailInput} data - The mail data.   * @returns {Promise<SentEmail>} The mutation response.   */ -export const sendMail = async (data: SendMailVars): Promise<SentEmail> => { +export const sendMail = async (data: SendMailInput): Promise<SentEmail> => {    const response = await fetchAPI<SentEmail, typeof sendMailMutation>({ -    api: getAPIUrl(),      query: sendMailMutation,      variables: { ...data },    }); diff --git a/src/services/graphql/thematics.ts b/src/services/graphql/thematics.ts index 4dc69e7..508fc2f 100644 --- a/src/services/graphql/thematics.ts +++ b/src/services/graphql/thematics.ts @@ -1,4 +1,6 @@  import { PageLink, Slug, Thematic } from '@ts/types/app'; +import { GraphQLEdgesInput } from '@ts/types/graphql/generics'; +import { EdgesResponse } from '@ts/types/graphql/queries';  import {    RawArticle,    RawThematic, @@ -6,8 +8,11 @@ import {    TotalItems,  } from '@ts/types/raw-data';  import { getImageFromRawData } from '@utils/helpers/images'; -import { getPageLinkFromRawData } from '@utils/helpers/pages'; -import { EdgesResponse, EdgesVars, fetchAPI, getAPIUrl } from './api'; +import { +  getPageLinkFromRawData, +  sortPageLinksByName, +} from '@utils/helpers/pages'; +import { fetchAPI } from './api';  import { getArticleFromRawData } from './articles';  import {    thematicBySlugQuery, @@ -23,7 +28,6 @@ import {   */  export const getTotalThematics = async (): Promise<number> => {    const response = await fetchAPI<TotalItems, typeof totalThematicsQuery>({ -    api: getAPIUrl(),      query: totalThematicsQuery,    }); @@ -33,16 +37,16 @@ export const getTotalThematics = async (): Promise<number> => {  /**   * Retrieve the given number of thematics from API.   * - * @param {EdgesVars} props - An object of GraphQL variables. + * @param {GraphQLEdgesInput} props - An object of GraphQL variables.   * @returns {Promise<EdgesResponse<RawThematicPreview>>} The thematics data.   */  export const getThematicsPreview = async ( -  props: EdgesVars +  props: GraphQLEdgesInput  ): Promise<EdgesResponse<RawThematicPreview>> => {    const response = await fetchAPI<      RawThematicPreview,      typeof thematicsListQuery -  >({ api: getAPIUrl(), query: thematicsListQuery, variables: props }); +  >({ query: thematicsListQuery, variables: props });    return response.thematics;  }; @@ -88,21 +92,8 @@ export const getThematicFromRawData = (data: RawThematic): Thematic => {      const uniqueTopics = topics.filter(        ({ id }, index) => !topicsIds.includes(id, index + 1)      ); -    const sortTopicByName = (a: PageLink, b: PageLink) => { -      var nameA = a.name.toUpperCase(); // ignore upper and lowercase -      var nameB = b.name.toUpperCase(); // ignore upper and lowercase -      if (nameA < nameB) { -        return -1; -      } -      if (nameA > nameB) { -        return 1; -      } - -      // names must be equal -      return 0; -    }; -    return uniqueTopics.sort(sortTopicByName); +    return uniqueTopics.sort(sortPageLinksByName);    };    return { @@ -137,7 +128,6 @@ export const getThematicFromRawData = (data: RawThematic): Thematic => {   */  export const getThematicBySlug = async (slug: string): Promise<Thematic> => {    const response = await fetchAPI<RawThematic, typeof thematicBySlugQuery>({ -    api: getAPIUrl(),      query: thematicBySlugQuery,      variables: { slug },    }); @@ -153,7 +143,6 @@ export const getThematicBySlug = async (slug: string): Promise<Thematic> => {  export const getAllThematicsSlugs = async (): Promise<string[]> => {    const totalThematics = await getTotalThematics();    const response = await fetchAPI<Slug, typeof thematicsSlugQuery>({ -    api: getAPIUrl(),      query: thematicsSlugQuery,      variables: { first: totalThematics },    }); diff --git a/src/services/graphql/topics.ts b/src/services/graphql/topics.ts index 0b1971b..5448d89 100644 --- a/src/services/graphql/topics.ts +++ b/src/services/graphql/topics.ts @@ -1,4 +1,6 @@  import { PageLink, Slug, Topic } from '@ts/types/app'; +import { GraphQLEdgesInput } from '@ts/types/graphql/generics'; +import { EdgesResponse } from '@ts/types/graphql/queries';  import {    RawArticle,    RawTopic, @@ -6,8 +8,11 @@ import {    TotalItems,  } from '@ts/types/raw-data';  import { getImageFromRawData } from '@utils/helpers/images'; -import { getPageLinkFromRawData } from '@utils/helpers/pages'; -import { EdgesResponse, EdgesVars, fetchAPI, getAPIUrl } from './api'; +import { +  getPageLinkFromRawData, +  sortPageLinksByName, +} from '@utils/helpers/pages'; +import { fetchAPI } from './api';  import { getArticleFromRawData } from './articles';  import {    topicBySlugQuery, @@ -23,7 +28,6 @@ import {   */  export const getTotalTopics = async (): Promise<number> => {    const response = await fetchAPI<TotalItems, typeof totalTopicsQuery>({ -    api: getAPIUrl(),      query: totalTopicsQuery,    }); @@ -33,14 +37,13 @@ export const getTotalTopics = async (): Promise<number> => {  /**   * Retrieve the given number of topics from API.   * - * @param {EdgesVars} props - An object of GraphQL variables. + * @param {GraphQLEdgesInput} props - An object of GraphQL variables.   * @returns {Promise<EdgesResponse<RawTopicPreview>>} The topics data.   */  export const getTopicsPreview = async ( -  props: EdgesVars +  props: GraphQLEdgesInput  ): Promise<EdgesResponse<RawTopicPreview>> => {    const response = await fetchAPI<RawTopicPreview, typeof topicsListQuery>({ -    api: getAPIUrl(),      query: topicsListQuery,      variables: props,    }); @@ -89,21 +92,8 @@ export const getTopicFromRawData = (data: RawTopic): Topic => {      const uniqueThematics = thematics.filter(        ({ id }, index) => !thematicsIds.includes(id, index + 1)      ); -    const sortThematicByName = (a: PageLink, b: PageLink) => { -      var nameA = a.name.toUpperCase(); // ignore upper and lowercase -      var nameB = b.name.toUpperCase(); // ignore upper and lowercase -      if (nameA < nameB) { -        return -1; -      } -      if (nameA > nameB) { -        return 1; -      } - -      // names must be equal -      return 0; -    }; -    return uniqueThematics.sort(sortThematicByName); +    return uniqueThematics.sort(sortPageLinksByName);    };    return { @@ -139,7 +129,6 @@ export const getTopicFromRawData = (data: RawTopic): Topic => {   */  export const getTopicBySlug = async (slug: string): Promise<Topic> => {    const response = await fetchAPI<RawTopic, typeof topicBySlugQuery>({ -    api: getAPIUrl(),      query: topicBySlugQuery,      variables: { slug },    }); @@ -155,7 +144,6 @@ export const getTopicBySlug = async (slug: string): Promise<Topic> => {  export const getAllTopicsSlugs = async (): Promise<string[]> => {    const totalTopics = await getTotalTopics();    const response = await fetchAPI<Slug, typeof topicsSlugQuery>({ -    api: getAPIUrl(),      query: topicsSlugQuery,      variables: { first: totalTopics },    }); | 
