1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
import { Article } from '@ts/types/app';
import { RawArticle, TotalItems } from '@ts/types/raw-data';
import { getAuthorFromRawData } from '@utils/helpers/author';
import { getImageFromRawData } from '@utils/helpers/images';
import { getPageLinkFromRawData } from '@utils/helpers/pages';
import { EdgesVars, fetchAPI, getAPIUrl, PageInfo } from './api';
import { articlesQuery, totalArticlesQuery } from './articles.query';
/**
* Retrieve the total number of articles.
*
* @returns {Promise<number>} - The articles total number.
*/
export const getTotalArticles = async (): Promise<number> => {
const response = await fetchAPI<TotalItems, typeof totalArticlesQuery>({
api: getAPIUrl(),
query: totalArticlesQuery,
});
return response.posts.pageInfo.total;
};
export type GetArticlesReturn = {
articles: Article[];
pageInfo: PageInfo;
};
/**
* Convert raw data to an Article object.
*
* @param {RawArticle} data - The page raw data.
* @returns {Article} The page data.
*/
export const getArticleFromRawData = (data: RawArticle): Article => {
const {
acfPosts,
author,
commentCount,
contentParts,
databaseId,
date,
featuredImage,
info,
modified,
slug,
title,
seo,
} = data;
return {
content: contentParts.afterMore,
id: databaseId,
intro: contentParts.beforeMore,
meta: {
author: getAuthorFromRawData(author.node, 'page'),
commentsCount: commentCount || 0,
cover: featuredImage?.node
? getImageFromRawData(featuredImage.node)
: undefined,
dates: {
publication: date,
update: modified,
},
readingTime: info.readingTime,
seo: {
description: seo?.metaDesc || '',
title: seo?.title || '',
},
thematics: acfPosts.postsInThematic?.map((thematic) =>
getPageLinkFromRawData(thematic)
),
topics: acfPosts.postsInTopic?.map((topic) =>
getPageLinkFromRawData(topic)
),
wordsCount: info.wordsCount,
},
slug,
title,
};
};
/**
* Retrieve the given number of articles from API.
*
* @param {EdgesVars} obj - An object.
* @param {number} obj.first - The number of articles.
* @returns {Promise<GetArticlesReturn>} - The articles data.
*/
export const getArticles = async ({
first,
}: EdgesVars): Promise<GetArticlesReturn> => {
const response = await fetchAPI<RawArticle, typeof articlesQuery>({
api: getAPIUrl(),
query: articlesQuery,
variables: { first },
});
return {
articles: response.posts.edges.map((edge) =>
getArticleFromRawData(edge.node)
),
pageInfo: response.posts.pageInfo,
};
};
|