diff options
| author | Armand Philippot <git@armandphilippot.com> | 2021-12-20 00:15:20 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2021-12-20 00:15:20 +0100 |
| commit | fa6adedc42e9c6ec39cc30df16b54900c220b094 (patch) | |
| tree | 6bb498beadaa382245cecb86ce56931580313c6f /src/services | |
| parent | 2ff898626c5c0abc6b8195224067b992403e313b (diff) | |
refactor: rewrite types and services
I was repeating myself a lot in services. So I rewrited the different
functions to improve readability and I extracted some formatting
functions to put them in utils. I also rewrited/reorganized some types
to keep consistent names.
Diffstat (limited to 'src/services')
| -rw-r--r-- | src/services/graphql/api.ts | 27 | ||||
| -rw-r--r-- | src/services/graphql/blog.ts | 158 | ||||
| -rw-r--r-- | src/services/graphql/client.ts | 11 | ||||
| -rw-r--r-- | src/services/graphql/comments.ts | 68 | ||||
| -rw-r--r-- | src/services/graphql/contact.ts | 49 | ||||
| -rw-r--r-- | src/services/graphql/homepage.ts | 36 | ||||
| -rw-r--r-- | src/services/graphql/mutations.ts | 82 | ||||
| -rw-r--r-- | src/services/graphql/pages.ts | 60 | ||||
| -rw-r--r-- | src/services/graphql/post.ts | 150 | ||||
| -rw-r--r-- | src/services/graphql/queries.ts | 496 | ||||
| -rw-r--r-- | src/services/graphql/taxonomies.ts | 348 |
11 files changed, 605 insertions, 880 deletions
diff --git a/src/services/graphql/api.ts b/src/services/graphql/api.ts new file mode 100644 index 0000000..de8024f --- /dev/null +++ b/src/services/graphql/api.ts @@ -0,0 +1,27 @@ +import { RequestType, VariablesType } from '@ts/types/app'; +import { GraphQLClient } from 'graphql-request'; + +export const getGraphQLClient = (): GraphQLClient => { + const apiUrl: string = process.env.NEXT_PUBLIC_GRAPHQL_API || ''; + + if (!apiUrl) throw new Error('API URL not defined.'); + + const graphQLClient = new GraphQLClient(apiUrl); + + return graphQLClient; +}; + +export const fetchApi = async <T extends RequestType>( + query: string, + variables: VariablesType<T> +): Promise<T> => { + const client = getGraphQLClient(); + + try { + const response = await client.request(query, variables); + return response; + } catch (error) { + console.error(error, undefined, 2); + process.exit(1); + } +}; diff --git a/src/services/graphql/blog.ts b/src/services/graphql/blog.ts deleted file mode 100644 index 27b972b..0000000 --- a/src/services/graphql/blog.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { ArticlePreview } from '@ts/types/articles'; -import { - AllPostsSlugResponse, - FetchAllPostsSlugReturn, - FetchPostsListReturn, - GetPostsListReturn, - PostsListResponse, -} from '@ts/types/blog'; -import { gql } from 'graphql-request'; -import { getGraphQLClient } from './client'; - -export const fetchPublishedPosts: FetchPostsListReturn = async ( - first = 10, - after = '' -) => { - const client = getGraphQLClient(); - const query = gql` - query AllPublishedPosts($first: Int, $after: String) { - posts( - after: $after - first: $first - where: { status: PUBLISH, orderby: { field: DATE, order: DESC } } - ) { - edges { - cursor - node { - acfPosts { - postsInSubject { - ... on Subject { - databaseId - featuredImage { - node { - altText - sourceUrl - title - } - } - id - slug - title - } - } - postsInThematic { - ... on Thematic { - databaseId - id - slug - title - } - } - } - commentCount - contentParts { - beforeMore - } - date - featuredImage { - node { - altText - sourceUrl - title - } - } - id - databaseId - modified - slug - title - } - } - pageInfo { - endCursor - hasNextPage - } - } - } - `; - - const variables = { first, after }; - - try { - const response: PostsListResponse = await client.request(query, variables); - return response; - } catch (error) { - console.error(JSON.stringify(error, undefined, 2)); - process.exit(1); - } -}; - -export const getPublishedPosts: GetPostsListReturn = async ({ - first = 10, - after = '', -}) => { - const rawPostsList = await fetchPublishedPosts(first, after); - const postsList: ArticlePreview[] = rawPostsList.posts.edges.map((post) => { - const { - acfPosts, - commentCount, - contentParts, - databaseId, - date, - featuredImage, - id, - modified, - slug, - title, - } = post.node; - const content = contentParts.beforeMore; - const cover = featuredImage ? featuredImage.node : null; - const dates = { publication: date, update: modified }; - const subjects = - acfPosts.postsInSubject && acfPosts.postsInSubject?.length > 0 - ? acfPosts.postsInSubject - : []; - const thematics = - acfPosts.postsInThematic && acfPosts.postsInThematic?.length > 0 - ? acfPosts.postsInThematic - : []; - - return { - commentCount, - content, - databaseId, - date: dates, - featuredImage: cover, - id, - slug, - subjects, - thematics, - title, - }; - }); - - return { posts: postsList, pageInfo: rawPostsList.posts.pageInfo }; -}; - -export const fetchAllPostsSlug: FetchAllPostsSlugReturn = async () => { - const client = getGraphQLClient(); - - // 10 000 is an arbitrary number for small websites. - const query = gql` - query AllPostsSlug { - posts(first: 10000) { - nodes { - slug - } - } - } - `; - - try { - const response: AllPostsSlugResponse = await client.request(query); - return response.posts.nodes; - } catch (error) { - console.error(JSON.stringify(error, undefined, 2)); - process.exit(1); - } -}; diff --git a/src/services/graphql/client.ts b/src/services/graphql/client.ts deleted file mode 100644 index a58441f..0000000 --- a/src/services/graphql/client.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { GraphQLClient } from 'graphql-request'; - -export const getGraphQLClient = () => { - const apiUrl: string = process.env.NEXT_PUBLIC_GRAPHQL_API || ''; - - if (!apiUrl) throw new Error('API URL not defined.'); - - const graphQLClient = new GraphQLClient(apiUrl); - - return graphQLClient; -}; diff --git a/src/services/graphql/comments.ts b/src/services/graphql/comments.ts deleted file mode 100644 index b7a9ed2..0000000 --- a/src/services/graphql/comments.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { - CreatedCommentResponse, - CreatedCommentReturn, -} from '@ts/types/comments'; -import { gql } from 'graphql-request'; -import { getGraphQLClient } from './client'; - -export const createComment: CreatedCommentReturn = async ( - author: string, - authorEmail: string, - authorUrl: string, - content: string, - parent: number, - commentOn: number, - mutationId: string -) => { - const client = getGraphQLClient(); - const mutation = gql` - mutation CreateComment( - $author: String! - $authorEmail: String! - $authorUrl: String! - $content: String! - $parent: ID! - $commentOn: Int! - $mutationId: String! - ) { - createComment( - input: { - author: $author - authorEmail: $authorEmail - authorUrl: $authorUrl - content: $content - parent: $parent - commentOn: $commentOn - clientMutationId: $mutationId - } - ) { - clientMutationId - success - comment { - approved - } - } - } - `; - - const variables = { - author, - authorEmail, - authorUrl, - content, - parent, - commentOn, - mutationId, - }; - - try { - const response: CreatedCommentResponse = await client.request( - mutation, - variables - ); - return response.createComment; - } catch (error) { - console.error(error, undefined, 2); - throw new Error(`An uncaught exception has occurred: ${error}`); - } -}; diff --git a/src/services/graphql/contact.ts b/src/services/graphql/contact.ts deleted file mode 100644 index 4699688..0000000 --- a/src/services/graphql/contact.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { SendMailReturn, SentEmailResponse } from '@ts/types/contact'; -import { gql } from 'graphql-request'; -import { getGraphQLClient } from './client'; - -export const sendMail: SendMailReturn = async ( - subject: string, - body: string, - replyTo: string, - mutationId: string -) => { - const client = getGraphQLClient(); - const mutation = gql` - mutation SendEmail( - $subject: String! - $body: String! - $replyTo: String! - $mutationId: String! - ) { - sendEmail( - input: { - clientMutationId: $mutationId - body: $body - replyTo: $replyTo - subject: $subject - } - ) { - clientMutationId - message - sent - origin - replyTo - to - } - } - `; - - const variables = { subject, body, replyTo, mutationId }; - - try { - const response: SentEmailResponse = await client.request( - mutation, - variables - ); - return response.sendEmail; - } catch (error) { - console.error(error, undefined, 2); - process.exit(1); - } -}; diff --git a/src/services/graphql/homepage.ts b/src/services/graphql/homepage.ts deleted file mode 100644 index 6ea71ac..0000000 --- a/src/services/graphql/homepage.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { gql } from 'graphql-request'; -import { - fetchHomePageReturn, - getHomePageReturn, - HomePage, - HomePageResponse, -} from '@ts/types/homepage'; -import { getGraphQLClient } from './client'; - -export const fetchHomepage: fetchHomePageReturn = async () => { - const client = getGraphQLClient(); - const query = gql` - query HomePage { - nodeByUri(uri: "/") { - ... on Page { - id - content - } - } - } - `; - - try { - const response: HomePageResponse = await client.request(query); - return response; - } catch (error) { - console.error(JSON.stringify(error, undefined, 2)); - process.exit(1); - } -}; - -export const getHomePage: getHomePageReturn = async () => { - const rawHomePage = await fetchHomepage(); - const homePage: HomePage = rawHomePage.nodeByUri; - return homePage; -}; diff --git a/src/services/graphql/mutations.ts b/src/services/graphql/mutations.ts new file mode 100644 index 0000000..c697835 --- /dev/null +++ b/src/services/graphql/mutations.ts @@ -0,0 +1,82 @@ +import { CommentData, CreateComment, CreatedComment } from '@ts/types/comments'; +import { ContactData, SendEmail } from '@ts/types/contact'; +import { gql } from 'graphql-request'; +import { fetchApi } from './api'; + +//============================================================================== +// Comment mutation +//============================================================================== + +export const createComment = async ( + data: CommentData +): Promise<CreatedComment> => { + const mutation = gql` + mutation CreateComment( + $author: String! + $authorEmail: String! + $authorUrl: String! + $content: String! + $parent: ID! + $commentOn: Int! + $mutationId: String! + ) { + createComment( + input: { + author: $author + authorEmail: $authorEmail + authorUrl: $authorUrl + content: $content + parent: $parent + commentOn: $commentOn + clientMutationId: $mutationId + } + ) { + clientMutationId + success + comment { + approved + } + } + } + `; + + const variables = { ...data }; + const response = await fetchApi<CreateComment>(mutation, variables); + + return response.createComment; +}; + +//============================================================================== +// Contact mutation +//============================================================================== + +export const sendMail = async (data: ContactData) => { + const mutation = gql` + mutation SendEmail( + $subject: String! + $body: String! + $replyTo: String! + $mutationId: String! + ) { + sendEmail( + input: { + clientMutationId: $mutationId + body: $body + replyTo: $replyTo + subject: $subject + } + ) { + clientMutationId + message + sent + origin + replyTo + to + } + } + `; + + const variables = { ...data }; + const response = await fetchApi<SendEmail>(mutation, variables); + return response.sendEmail; +}; diff --git a/src/services/graphql/pages.ts b/src/services/graphql/pages.ts deleted file mode 100644 index 0781d44..0000000 --- a/src/services/graphql/pages.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { - FetchPageByUriReturn, - GetPageReturn, - Page, - PageResponse, - RawPage, -} from '@ts/types/pages'; -import { gql } from 'graphql-request'; -import { getGraphQLClient } from './client'; - -const fetchPageByUri: FetchPageByUriReturn = async (uri: string) => { - const client = getGraphQLClient(); - const query = gql` - query PageByUri($uri: String!) { - pageBy(uri: $uri) { - contentParts { - afterMore - beforeMore - } - date - modified - title - } - } - `; - - const variables = { uri }; - - try { - const response: PageResponse = await client.request(query, variables); - return response.pageBy; - } catch (error) { - console.error(JSON.stringify(error, undefined, 2)); - process.exit(1); - } -}; - -const getFormattedPage = (page: RawPage) => { - const formattedPage: Page = { - ...page, - content: page.contentParts.afterMore, - intro: page.contentParts.beforeMore, - }; - - return formattedPage; -}; - -export const getCVPage: GetPageReturn = async () => { - const rawCV = await fetchPageByUri('/cv/'); - const formattedCV = getFormattedPage(rawCV); - - return formattedCV; -}; - -export const getLegalNoticePage: GetPageReturn = async () => { - const rawLegalNotice = await fetchPageByUri('/mentions-legales'); - const formattedLegalNotice = getFormattedPage(rawLegalNotice); - - return formattedLegalNotice; -}; diff --git a/src/services/graphql/post.ts b/src/services/graphql/post.ts deleted file mode 100644 index 08411bf..0000000 --- a/src/services/graphql/post.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { - Article, - FetchPostByReturn, - GetPostByReturn, - PostByResponse, -} from '@ts/types/articles'; -import { gql } from 'graphql-request'; -import { getGraphQLClient } from './client'; - -const fetchPostBySlug: FetchPostByReturn = async (slug: string) => { - const client = getGraphQLClient(); - const query = gql` - query PostBySlug($slug: String!) { - postBy(slug: $slug) { - acfPosts { - postsInSubject { - ... on Subject { - id - featuredImage { - node { - altText - sourceUrl - title - } - } - slug - title - } - } - postsInThematic { - ... on Thematic { - id - slug - title - } - } - } - author { - node { - firstName - lastName - name - } - } - commentCount - comments { - nodes { - approved - author { - node { - gravatarUrl - name - url - } - } - commentId - content - date - id - parentDatabaseId - parentId - } - } - contentParts { - afterMore - beforeMore - } - databaseId - date - featuredImage { - node { - altText - sourceUrl - title - } - } - modified - seo { - title - metaDesc - opengraphAuthor - opengraphDescription - opengraphImage { - altText - sourceUrl - srcSet - } - opengraphModifiedTime - opengraphPublishedTime - opengraphPublisher - opengraphSiteName - opengraphTitle - opengraphType - opengraphUrl - readingTime - } - title - } - } - `; - - const variables = { slug }; - - try { - const response: PostByResponse = await client.request(query, variables); - return response; - } catch (error) { - console.error(JSON.stringify(error, undefined, 2)); - process.exit(1); - } -}; - -export const getPostBySlug: GetPostByReturn = async (slug: string) => { - const rawPost = await fetchPostBySlug(slug); - - const author = rawPost.postBy.author.node; - const comments = rawPost.postBy.comments.nodes.reverse().map((comment) => { - const author = comment.author.node; - return { ...comment, author: author, replies: [] }; - }); - const content = rawPost.postBy.contentParts.afterMore; - const featuredImage = rawPost.postBy.featuredImage - ? rawPost.postBy.featuredImage.node - : null; - const date = { - publication: rawPost.postBy.date, - update: rawPost.postBy.modified, - }; - const intro = rawPost.postBy.contentParts.beforeMore; - const subjects = rawPost.postBy.acfPosts.postsInSubject - ? rawPost.postBy.acfPosts.postsInSubject - : []; - const thematics = rawPost.postBy.acfPosts.postsInThematic - ? rawPost.postBy.acfPosts.postsInThematic - : []; - - const formattedPost: Article = { - ...rawPost.postBy, - author, - comments, - content, - featuredImage, - date, - intro, - subjects, - thematics, - }; - - return formattedPost; -}; diff --git a/src/services/graphql/queries.ts b/src/services/graphql/queries.ts new file mode 100644 index 0000000..b449612 --- /dev/null +++ b/src/services/graphql/queries.ts @@ -0,0 +1,496 @@ +import { Slug } from '@ts/types/app'; +import { Article, PostBy } from '@ts/types/articles'; +import { AllPostsSlug, PostsList, RawPostsList } from '@ts/types/blog'; +import { HomePage, HomePageBy } from '@ts/types/homepage'; +import { Page, PageBy } from '@ts/types/pages'; +import { + AllSubjectsSlug, + AllThematicsSlug, + Subject, + SubjectBy, + Thematic, + ThematicBy, +} from '@ts/types/taxonomies'; +import { + getFormattedPage, + getFormattedPost, + getFormattedPostPreview, + getFormattedSubject, + getFormattedThematic, +} from '@utils/helpers/format'; +import { gql } from 'graphql-request'; +import { fetchApi } from './api'; + +//============================================================================== +// Posts list queries +//============================================================================== + +export const getPublishedPosts = async ({ + first = 10, + after = '', +}): Promise<PostsList> => { + const query = gql` + query AllPublishedPosts($first: Int, $after: String) { + posts( + after: $after + first: $first + where: { status: PUBLISH, orderby: { field: DATE, order: DESC } } + ) { + edges { + cursor + node { + acfPosts { + postsInSubject { + ... on Subject { + databaseId + featuredImage { + node { + altText + sourceUrl + title + } + } + id + slug + title + } + } + postsInThematic { + ... on Thematic { + databaseId + id + slug + title + } + } + } + commentCount + contentParts { + beforeMore + } + date + featuredImage { + node { + altText + sourceUrl + title + } + } + id + databaseId + modified + slug + title + } + } + pageInfo { + endCursor + hasNextPage + } + } + } + `; + + const variables = { first, after }; + const response = await fetchApi<RawPostsList>(query, variables); + const formattedPosts = response.posts.edges.map((post) => { + const formattedPost = getFormattedPostPreview(post.node); + + return formattedPost; + }); + + const postsList = { + posts: formattedPosts, + pageInfo: response.posts.pageInfo, + }; + + return postsList; +}; + +export const getAllPostsSlug = async (): Promise<Slug[]> => { + // 10 000 is an arbitrary number that I use for small websites. + const query = gql` + query AllPostsSlug { + posts(first: 10000) { + nodes { + slug + } + } + } + `; + + const response = await fetchApi<AllPostsSlug>(query, null); + return response.posts.nodes; +}; + +//============================================================================== +// Single Post query +//============================================================================== + +export const getPostBySlug = async (slug: string): Promise<Article> => { + const query = gql` + query PostBySlug($slug: String!) { + postBy(slug: $slug) { + acfPosts { + postsInSubject { + ... on Subject { + id + featuredImage { + node { + altText + sourceUrl + title + } + } + slug + title + } + } + postsInThematic { + ... on Thematic { + id + slug + title + } + } + } + author { + node { + firstName + lastName + name + } + } + commentCount + comments { + nodes { + approved + author { + node { + gravatarUrl + name + url + } + } + commentId + content + date + id + parentDatabaseId + parentId + } + } + contentParts { + afterMore + beforeMore + } + databaseId + date + featuredImage { + node { + altText + sourceUrl + title + } + } + id + modified + seo { + title + metaDesc + opengraphAuthor + opengraphDescription + opengraphImage { + altText + sourceUrl + srcSet + } + opengraphModifiedTime + opengraphPublishedTime + opengraphPublisher + opengraphSiteName + opengraphTitle + opengraphType + opengraphUrl + readingTime + } + title + } + } + `; + const variables = { slug }; + const response = await fetchApi<PostBy>(query, variables); + const post = getFormattedPost(response.postBy); + + return post; +}; + +//============================================================================== +// Pages query +//============================================================================== + +export const getHomePage = async (): Promise<HomePage> => { + const query = gql` + query HomePage { + nodeByUri(uri: "/") { + ... on Page { + id + content + } + } + } + `; + + const response = await fetchApi<HomePageBy>(query, null); + const homepage = response.nodeByUri; + + return homepage; +}; + +export const getPageByUri = async (slug: string): Promise<Page> => { + const query = gql` + query PageByUri($slug: String!) { + pageBy(uri: $slug) { + contentParts { + afterMore + beforeMore + } + date + modified + title + } + } + `; + + const variables = { slug }; + const response = await fetchApi<PageBy>(query, variables); + const page = getFormattedPage(response.pageBy); + + return page; +}; + +//============================================================================== +// Subject query +//============================================================================== + +export const getSubjectBySlug = async (slug: string): Promise<Subject> => { + const query = gql` + query SubjectBySlug($slug: String!) { + subjectBy(slug: $slug) { + acfSubjects { + officialWebsite + postsInSubject { + ... on Post { + acfPosts { + postsInSubject { + ... on Subject { + databaseId + featuredImage { + node { + altText + sourceUrl + title + } + } + id + slug + title + } + } + postsInThematic { + ... on Thematic { + databaseId + id + slug + title + } + } + } + id + commentCount + contentParts { + beforeMore + } + databaseId + date + featuredImage { + node { + altText + sourceUrl + title + } + } + modified + slug + title + } + } + } + contentParts { + afterMore + beforeMore + } + databaseId + date + featuredImage { + node { + altText + sourceUrl + title + } + } + id + modified + seo { + metaDesc + opengraphAuthor + opengraphDescription + opengraphImage { + altText + sourceUrl + srcSet + } + opengraphModifiedTime + opengraphPublishedTime + opengraphPublisher + opengraphSiteName + opengraphTitle + opengraphType + opengraphUrl + readingTime + title + } + title + } + } + `; + const variables = { slug }; + const response = await fetchApi<SubjectBy>(query, variables); + const subject = getFormattedSubject(response.subjectBy); + + return subject; +}; + +export const getAllSubjectsSlug = async (): Promise<Slug[]> => { + // 10 000 is an arbitrary number that I use for small websites. + const query = gql` + query AllSubjectsSlug { + subjects(first: 10000) { + nodes { + slug + } + } + } + `; + const response = await fetchApi<AllSubjectsSlug>(query, null); + return response.subjects.nodes; +}; + +//============================================================================== +// Thematic query +//============================================================================== + +export const getThematicBySlug = async (slug: string): Promise<Thematic> => { + const query = gql` + query ThematicBySlug($slug: String!) { + thematicBy(slug: $slug) { + acfThematics { + postsInThematic { + ... on Post { + acfPosts { + postsInSubject { + ... on Subject { + databaseId + featuredImage { + node { + altText + sourceUrl + title + } + } + id + slug + title + } + } + postsInThematic { + ... on Thematic { + databaseId + id + slug + title + } + } + } + id + commentCount + contentParts { + beforeMore + } + databaseId + date + featuredImage { + node { + altText + sourceUrl + title + } + } + modified + slug + title + } + } + } + contentParts { + afterMore + beforeMore + } + databaseId + date + id + modified + seo { + metaDesc + opengraphAuthor + opengraphDescription + opengraphImage { + altText + sourceUrl + srcSet + } + opengraphModifiedTime + opengraphPublishedTime + opengraphPublisher + opengraphSiteName + opengraphTitle + opengraphType + opengraphUrl + readingTime + title + } + title + } + } + `; + const variables = { slug }; + const response = await fetchApi<ThematicBy>(query, variables); + const thematic = getFormattedThematic(response.thematicBy); + + return thematic; +}; + +export const getAllThematicsSlug = async (): Promise<Slug[]> => { + // 10 000 is an arbitrary number that I use for small websites. + const query = gql` + query AllThematicsSlug { + thematics(first: 10000) { + nodes { + slug + } + } + } + `; + const response = await fetchApi<AllThematicsSlug>(query, null); + return response.thematics.nodes; +}; diff --git a/src/services/graphql/taxonomies.ts b/src/services/graphql/taxonomies.ts deleted file mode 100644 index ee73dc8..0000000 --- a/src/services/graphql/taxonomies.ts +++ /dev/null @@ -1,348 +0,0 @@ -import { ArticlePreview } from '@ts/types/articles'; -import { - AllSubjectsSlugResponse, - AllThematicsSlugResponse, - FetchAllTaxonomiesSlugReturn, - FetchSubjectByReturn, - FetchThematicByReturn, - GetTaxonomyByReturn, - Subject, - Taxonomy, -} from '@ts/types/taxonomies'; -import { gql } from 'graphql-request'; -import { getGraphQLClient } from './client'; - -export const fetchThematicBySlug: FetchThematicByReturn = async ( - slug: string -) => { - const client = getGraphQLClient(); - const query = gql` - query ThematicBySlug($slug: String!) { - thematicBy(slug: $slug) { - acfThematics { - postsInThematic { - ... on Post { - acfPosts { - postsInSubject { - ... on Subject { - databaseId - featuredImage { - node { - altText - sourceUrl - title - } - } - id - slug - title - } - } - postsInThematic { - ... on Thematic { - databaseId - id - slug - title - } - } - } - id - commentCount - contentParts { - beforeMore - } - databaseId - date - featuredImage { - node { - altText - sourceUrl - title - } - } - modified - slug - title - } - } - } - contentParts { - afterMore - beforeMore - } - date - modified - seo { - metaDesc - opengraphAuthor - opengraphDescription - opengraphImage { - altText - sourceUrl - srcSet - } - opengraphModifiedTime - opengraphPublishedTime - opengraphPublisher - opengraphSiteName - opengraphTitle - opengraphType - opengraphUrl - readingTime - title - } - title - } - } - `; - - const variables = { slug }; - - try { - const response = client.request(query, variables); - return response; - } catch (error) { - console.error(error, undefined, 2); - process.exit(1); - } -}; - -export const getThematicBySlug: GetTaxonomyByReturn = async (slug: string) => { - const rawThematic = await fetchThematicBySlug(slug); - - const content = rawThematic.thematicBy.contentParts.afterMore; - const intro = rawThematic.thematicBy.contentParts.beforeMore; - const rawPosts = rawThematic.thematicBy.acfThematics.postsInThematic; - const formattedPosts: ArticlePreview[] = rawPosts.map((post) => { - const content = post.contentParts.beforeMore; - const cover = post.featuredImage ? post.featuredImage.node : null; - const dates = { publication: post.date, update: post.modified }; - const subjects = - post.acfPosts.postsInSubject && post.acfPosts.postsInSubject?.length > 0 - ? post.acfPosts.postsInSubject - : []; - const thematics = - post.acfPosts.postsInThematic && post.acfPosts.postsInThematic?.length > 0 - ? post.acfPosts.postsInThematic - : []; - - return { - ...post, - content, - featuredImage: cover, - date: dates, - subjects, - thematics, - }; - }); - - const formattedThematic: Taxonomy = { - ...rawThematic.thematicBy, - content, - intro, - posts: formattedPosts, - }; - - return formattedThematic; -}; - -export const fetchAllThematicsSlug: FetchAllTaxonomiesSlugReturn = async () => { - const client = getGraphQLClient(); - const query = gql` - query AllThematicsSlug { - thematics { - nodes { - slug - } - } - } - `; - - try { - const response: AllThematicsSlugResponse = await client.request(query); - return response.thematics.nodes; - } catch (error) { - console.error(error, undefined, 2); - process.exit(1); - } -}; - -export const fetchSubjectBySlug: FetchSubjectByReturn = async ( - slug: string -) => { - const client = getGraphQLClient(); - const query = gql` - query SubjectBySlug($slug: String!) { - subjectBy(slug: $slug) { - acfSubjects { - officialWebsite - postsInSubject { - ... on Post { - acfPosts { - postsInSubject { - ... on Subject { - databaseId - featuredImage { - node { - altText - sourceUrl - title - } - } - id - slug - title - } - } - postsInThematic { - ... on Thematic { - databaseId - id - slug - title - } - } - } - id - commentCount - contentParts { - beforeMore - } - databaseId - date - featuredImage { - node { - altText - sourceUrl - title - } - } - modified - slug - title - } - } - } - contentParts { - afterMore - beforeMore - } - date - featuredImage { - node { - altText - sourceUrl - title - } - } - modified - seo { - metaDesc - opengraphAuthor - opengraphDescription - opengraphImage { - altText - sourceUrl - srcSet - } - opengraphModifiedTime - opengraphPublishedTime - opengraphPublisher - opengraphSiteName - opengraphTitle - opengraphType - opengraphUrl - readingTime - title - } - title - } - } - `; - - const variables = { slug }; - - try { - const response = client.request(query, variables); - return response; - } catch (error) { - console.error(error, undefined, 2); - process.exit(1); - } -}; - -export const getSubjectBySlug: GetTaxonomyByReturn = async (slug: string) => { - const rawSubject = await fetchSubjectBySlug(slug); - - const content = rawSubject.subjectBy.contentParts.afterMore; - const cover = rawSubject.subjectBy.featuredImage - ? rawSubject.subjectBy.featuredImage.node - : null; - const intro = rawSubject.subjectBy.contentParts.beforeMore; - const rawPosts = rawSubject.subjectBy.acfSubjects.postsInSubject; - console.log(rawPosts); - - // WP GraphQL return empty objects instead of filtering posts that do not - // belong to the queried post type so I need to filter them. - const formattedPosts: ArticlePreview[] = rawPosts - .filter((post) => Object.getOwnPropertyNames(post).length > 0) - .map((post) => { - const content = post.contentParts.beforeMore; - const cover = post.featuredImage ? post.featuredImage.node : null; - const dates = { publication: post.date, update: post.modified }; - const subjects = - post.acfPosts.postsInSubject && post.acfPosts.postsInSubject?.length > 0 - ? post.acfPosts.postsInSubject - : []; - const thematics = - post.acfPosts.postsInThematic && - post.acfPosts.postsInThematic?.length > 0 - ? post.acfPosts.postsInThematic - : []; - - return { - ...post, - content, - featuredImage: cover, - date: dates, - subjects, - thematics, - }; - }); - - const formattedSubject: Subject = { - ...rawSubject.subjectBy, - content, - featuredImage: cover, - intro, - posts: formattedPosts, - }; - - console.log(formattedSubject); - - return formattedSubject; -}; - -export const fetchAllSubjectsSlug: FetchAllTaxonomiesSlugReturn = async () => { - const client = getGraphQLClient(); - - // 10 000 is an arbitrary number for small websites. - const query = gql` - query AllSubjectsSlug { - subjects(first: 10000) { - nodes { - slug - } - } - } - `; - - try { - const response: AllSubjectsSlugResponse = await client.request(query); - return response.subjects.nodes; - } catch (error) { - console.error(error, undefined, 2); - process.exit(1); - } -}; |
