summaryrefslogtreecommitdiffstats
path: root/src/services
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2021-12-20 00:15:20 +0100
committerArmand Philippot <git@armandphilippot.com>2021-12-20 00:15:20 +0100
commitfa6adedc42e9c6ec39cc30df16b54900c220b094 (patch)
tree6bb498beadaa382245cecb86ce56931580313c6f /src/services
parent2ff898626c5c0abc6b8195224067b992403e313b (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.ts27
-rw-r--r--src/services/graphql/blog.ts158
-rw-r--r--src/services/graphql/client.ts11
-rw-r--r--src/services/graphql/comments.ts68
-rw-r--r--src/services/graphql/contact.ts49
-rw-r--r--src/services/graphql/homepage.ts36
-rw-r--r--src/services/graphql/mutations.ts82
-rw-r--r--src/services/graphql/pages.ts60
-rw-r--r--src/services/graphql/post.ts150
-rw-r--r--src/services/graphql/queries.ts496
-rw-r--r--src/services/graphql/taxonomies.ts348
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);
- }
-};