diff options
Diffstat (limited to 'src/services/graphql/fetchers/topics')
5 files changed, 262 insertions, 0 deletions
| diff --git a/src/services/graphql/fetchers/topics/fetch-all-topics-slugs.ts b/src/services/graphql/fetchers/topics/fetch-all-topics-slugs.ts new file mode 100644 index 0000000..eab4a7c --- /dev/null +++ b/src/services/graphql/fetchers/topics/fetch-all-topics-slugs.ts @@ -0,0 +1,34 @@ +import type { GraphQLNodes, Nullable, SlugNode } from '../../../../types'; +import { fetchGraphQL, getGraphQLUrl } from '../../../../utils/helpers'; +import { fetchTopicsCount } from './fetch-topics-count'; + +type TopicsSlugsResponse = { +  topics: Nullable<GraphQLNodes<SlugNode>>; +}; + +const topicsSlugsQuery = `query TopicsSlugs($first: Int) { +  topics(first: $first) { +    nodes { +      slug +    } +  } +}`; + +/** + * Retrieve the WordPress topics slugs. + * + * @returns {Promise<string[]>} The topics slugs. + */ +export const fetchAllTopicsSlugs = async (): Promise<string[]> => { +  const topicsCount = await fetchTopicsCount(); +  const response = await fetchGraphQL<TopicsSlugsResponse>({ +    query: topicsSlugsQuery, +    url: getGraphQLUrl(), +    variables: { first: topicsCount }, +  }); + +  if (!response.topics) +    return Promise.reject(new Error('Unable to find the topics slugs.')); + +  return response.topics.nodes.map((node) => node.slug); +}; diff --git a/src/services/graphql/fetchers/topics/fetch-topic.ts b/src/services/graphql/fetchers/topics/fetch-topic.ts new file mode 100644 index 0000000..efc1d9e --- /dev/null +++ b/src/services/graphql/fetchers/topics/fetch-topic.ts @@ -0,0 +1,97 @@ +import type { Nullable, WPTopic } from '../../../../types'; +import { fetchGraphQL, getGraphQLUrl } from '../../../../utils/helpers'; + +type TopicResponse = { +  topic: Nullable<WPTopic>; +}; + +const topicQuery = `query Topic($slug: ID!) { +  topic(id: $slug, idType: SLUG) { +    acfTopics { +      officialWebsite +      postsInTopic { +        ... on Post { +          acfPosts { +            postsInThematic { +              ... on Thematic { +                databaseId +                slug +                title +              } +            } +          } +          author { +            node { +              name +            } +          } +          commentCount +          contentParts { +            beforeMore +          } +          databaseId +          date +          featuredImage { +            node { +              altText +              mediaDetails { +                height +                width +              } +              sourceUrl +              title +            } +          } +          info { +            wordsCount +          } +          modified +          slug +          title +        } +      } +    } +    contentParts { +      afterMore +      beforeMore +    } +    featuredImage { +      node { +        altText +        mediaDetails { +          height +          width +        } +        sourceUrl +        title +      } +    } +    seo { +      metaDesc +      title +    } +    slug +    title +  } +}`; + +/** + * Retrieve a WordPress topic by slug. + * + * @param {string} slug - The topic slug. + * @returns {Promise<WPTopic>} The requested topic. + */ +export const fetchTopic = async (slug: string): Promise<WPTopic> => { +  const response = await fetchGraphQL<TopicResponse>({ +    query: topicQuery, +    url: getGraphQLUrl(), +    variables: { slug }, +  }); + +  if (!response.topic) +    return Promise.reject( +      new Error(`No topic found for the following slug ${slug}.`) +    ); + +  return response.topic; +}; diff --git a/src/services/graphql/fetchers/topics/fetch-topics-count.ts b/src/services/graphql/fetchers/topics/fetch-topics-count.ts new file mode 100644 index 0000000..868b01e --- /dev/null +++ b/src/services/graphql/fetchers/topics/fetch-topics-count.ts @@ -0,0 +1,43 @@ +import type { +  GraphQLPageInfo, +  GraphQLTaxonomyWhere, +  Nullable, +} from '../../../../types'; +import { fetchGraphQL, getGraphQLUrl } from '../../../../utils/helpers'; + +type TopicsCountResponse = { +  topics: Nullable<{ +    pageInfo: Pick<GraphQLPageInfo, 'total'>; +  }>; +}; + +const topicsCountQuery = `query TopicsCount($search: String, $title: String) { +  topics(where: {search: $search, title: $title}) { +    pageInfo { +      total +    } +  } +}`; + +/** + * Retrieve the total of WordPress topics. + * + * @param {GraphQLTaxonomyWhere} [input] - The input to filter the topics. + * @returns {Promise<number>} The total number of topics. + */ +export const fetchTopicsCount = async ( +  input?: GraphQLTaxonomyWhere +): Promise<number> => { +  const response = await fetchGraphQL<TopicsCountResponse>({ +    query: topicsCountQuery, +    url: getGraphQLUrl(), +    variables: { ...input }, +  }); + +  if (!response.topics) +    return Promise.reject( +      new Error('Unable to find the total number of topics.') +    ); + +  return response.topics.pageInfo.total; +}; diff --git a/src/services/graphql/fetchers/topics/fetch-topics-list.ts b/src/services/graphql/fetchers/topics/fetch-topics-list.ts new file mode 100644 index 0000000..1bc2e38 --- /dev/null +++ b/src/services/graphql/fetchers/topics/fetch-topics-list.ts @@ -0,0 +1,84 @@ +import type { +  GraphQLConnection, +  GraphQLEdgesInput, +  GraphQLTaxonomyOrderBy, +  GraphQLTaxonomyWhere, +  Nullable, +  WPTopicPreview, +} from '../../../../types'; +import { fetchGraphQL, getGraphQLUrl } from '../../../../utils/helpers'; + +type TopicsListResponse = { +  topics: Nullable<GraphQLConnection<WPTopicPreview>>; +}; + +const topicsListQuery = `query TopicsList($after: String, $before: String, $first: Int, $last: Int, $orderby: [PostObjectsConnectionOrderbyInput], $search: String, $title: String) { +  topics( +    after: $after +    before: $before +    first: $first +    last: $last +    where: {orderby: $orderby, search: $search, title: $title} +  ) { +    edges { +      cursor +      node { +        contentParts { +          beforeMore +        } +        databaseId +        featuredImage { +          node { +            altText +            mediaDetails { +              height +              width +            } +            slug +            title +          } +        } +        slug +        title +      } +    } +    pageInfo { +      endCursor +      hasNextPage +      hasPreviousPage +      startCursor +      total +    } +  } +}`; + +export type FetchTopicsListInput = GraphQLEdgesInput & { +  orderBy?: GraphQLTaxonomyOrderBy; +  where?: GraphQLTaxonomyWhere; +}; + +/** + * Retrieve a paginated list of WordPress topics. + * + * @param {FetchTopicsListInput} input - The input to retrieve topics. + * @returns {Promise<GraphQLConnection<WPTopicPreview>>} The paginated topics. + */ +export const fetchTopicsList = async ({ +  orderBy, +  where, +  ...vars +}: FetchTopicsListInput): Promise<GraphQLConnection<WPTopicPreview>> => { +  const response = await fetchGraphQL<TopicsListResponse>({ +    query: topicsListQuery, +    url: getGraphQLUrl(), +    variables: { +      ...vars, +      ...where, +      orderBy: orderBy ? [orderBy] : undefined, +    }, +  }); + +  if (!response.topics) return Promise.reject(new Error('No topics found.')); + +  return response.topics; +}; diff --git a/src/services/graphql/fetchers/topics/index.ts b/src/services/graphql/fetchers/topics/index.ts new file mode 100644 index 0000000..e381883 --- /dev/null +++ b/src/services/graphql/fetchers/topics/index.ts @@ -0,0 +1,4 @@ +export * from './fetch-all-topics-slugs'; +export * from './fetch-topic'; +export * from './fetch-topics-count'; +export * from './fetch-topics-list'; | 
