diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-11-24 20:00:08 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-11-27 14:47:51 +0100 |
| commit | f111685c5886f3e77edfd3621c98d8ac1b9bcce4 (patch) | |
| tree | 62a541fe3afeb64bf745443706fbfb02e96c5230 /src/services/graphql/thematics.ts | |
| parent | bee515641cb144be9a855ff2cac258d2fedab21d (diff) | |
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
Diffstat (limited to 'src/services/graphql/thematics.ts')
| -rw-r--r-- | src/services/graphql/thematics.ts | 157 |
1 files changed, 0 insertions, 157 deletions
diff --git a/src/services/graphql/thematics.ts b/src/services/graphql/thematics.ts deleted file mode 100644 index c02a42c..0000000 --- a/src/services/graphql/thematics.ts +++ /dev/null @@ -1,157 +0,0 @@ -import type { - EdgesResponse, - GraphQLEdgesInput, - PageLink, - RawArticle, - RawThematic, - RawThematicPreview, - Slug, - Thematic, - TotalItems, -} from '../../types'; -import { - getImageFromRawData, - getPageLinkFromRawData, - sortPageLinksByName, -} from '../../utils/helpers'; -import { fetchAPI } from './api'; -import { getArticleFromRawData } from './articles'; -import { - thematicBySlugQuery, - thematicsListQuery, - thematicsSlugQuery, - totalThematicsQuery, -} from './thematics.query'; - -/** - * Retrieve the total number of thematics. - * - * @returns {Promise<number>} - The thematics total number. - */ -export const getTotalThematics = async (): Promise<number> => { - const response = await fetchAPI<TotalItems, typeof totalThematicsQuery>({ - query: totalThematicsQuery, - }); - - return response.thematics.pageInfo.total; -}; - -/** - * Retrieve the given number of thematics from API. - * - * @param {GraphQLEdgesInput} props - An object of GraphQL variables. - * @returns {Promise<EdgesResponse<RawThematicPreview>>} The thematics data. - */ -export const getThematicsPreview = async ( - props: GraphQLEdgesInput -): Promise<EdgesResponse<RawThematicPreview>> => { - const response = await fetchAPI< - RawThematicPreview, - typeof thematicsListQuery - >({ query: thematicsListQuery, variables: props }); - - return response.thematics; -}; - -/** - * Convert raw data to an Thematic object. - * - * @param {RawThematic} data - The page raw data. - * @returns {Thematic} The page data. - */ -export const getThematicFromRawData = async ( - data: RawThematic -): Promise<Thematic> => { - const { - acfThematics, - contentParts, - databaseId, - date, - featuredImage, - info, - modified, - slug, - title, - seo, - } = data; - - /** - * Retrieve an array of related topics. - * - * @param posts - The thematic posts. - * @returns {PageLink[]} An array of topics links. - */ - const getRelatedTopics = (posts: RawArticle[]): PageLink[] => { - const topics: PageLink[] = []; - - posts.forEach((post) => { - if (post.acfPosts.postsInTopic) { - for (const topic of post.acfPosts.postsInTopic) { - topics.push(getPageLinkFromRawData(topic, 'topic')); - } - } - }); - - const topicsIds = topics.map((topic) => topic.id); - const uniqueTopics = topics.filter( - ({ id }, index) => !topicsIds.includes(id, index + 1) - ); - - return uniqueTopics.sort(sortPageLinksByName); - }; - - return { - content: contentParts.afterMore, - id: databaseId, - intro: contentParts.beforeMore, - meta: { - articles: await Promise.all( - acfThematics.postsInThematic.map(async (post) => - getArticleFromRawData(post) - ) - ), - cover: featuredImage?.node - ? getImageFromRawData(featuredImage.node) - : undefined, - dates: { publication: date, update: modified }, - seo: { - description: seo?.metaDesc ?? '', - title: seo?.title ?? '', - }, - topics: getRelatedTopics(acfThematics.postsInThematic), - wordsCount: info.wordsCount, - }, - slug, - title, - }; -}; - -/** - * Retrieve a Thematic object by slug. - * - * @param {string} slug - The thematic slug. - * @returns {Promise<Article>} The requested thematic. - */ -export const getThematicBySlug = async (slug: string): Promise<Thematic> => { - const response = await fetchAPI<RawThematic, typeof thematicBySlugQuery>({ - query: thematicBySlugQuery, - variables: { slug }, - }); - - return getThematicFromRawData(response.thematic); -}; - -/** - * Retrieve all the thematics slugs. - * - * @returns {Promise<string[]>} - An array of thematics slugs. - */ -export const getAllThematicsSlugs = async (): Promise<string[]> => { - const totalThematics = await getTotalThematics(); - const response = await fetchAPI<Slug, typeof thematicsSlugQuery>({ - query: thematicsSlugQuery, - variables: { first: totalThematics }, - }); - - return response.thematics.edges.map((edge) => edge.node.slug); -}; |
