From f111685c5886f3e77edfd3621c98d8ac1b9bcce4 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Fri, 24 Nov 2023 20:00:08 +0100 Subject: 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 --- src/types/data.ts | 289 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 src/types/data.ts (limited to 'src/types/data.ts') diff --git a/src/types/data.ts b/src/types/data.ts new file mode 100644 index 0000000..9a6d674 --- /dev/null +++ b/src/types/data.ts @@ -0,0 +1,289 @@ +import type { StaticImageData } from 'next/image'; +import type { Nullable } from './generics'; +import type { GraphQLNode } from './gql'; + +export type SlugNode = { + slug: string; +}; + +//=========================================================================== +// Data from WordPress +//=========================================================================== + +type WPSeo = { + metaDesc: string; + title: string; +}; + +type WPCommentAuthorAvatar = { + height: number; + url: string; + width: number; +}; + +type WPCommentAuthor = { + avatar: Nullable; + name: string; + url: Nullable; +}; + +export type WPCommentStatus = 'APPROVE' | 'HOLD' | 'SPAM' | 'TRASH'; + +export type WPComment = { + approved: boolean; + author: GraphQLNode; + content: string; + databaseId: number; + date: string; + parentDatabaseId: number; + status: WPCommentStatus; +}; + +type WPContentParts = { + afterMore: string; + beforeMore: string; +}; + +export type WPImage = { + altText: Nullable; + mediaDetails: { + height: number; + width: number; + }; + sourceUrl: string; + title: Nullable; +}; + +type WPInfo = { wordsCount: number }; + +type WPContent = { + date: string; + featuredImage: Nullable>; + modified: string; + seo: WPSeo; + slug: string; + title: string; +}; + +export type WPPage = WPContent & { + contentParts: WPContentParts; + info: WPInfo; +}; + +type WPPostAuthor = { name: string }; + +type WPAcfPosts = { + postsInThematic: Nullable; + postsInTopic: Nullable; +}; + +export type WPPost = WPContent & { + acfPosts: Nullable>; + author: GraphQLNode; + commentCount: Nullable; + contentParts: WPContentParts; + databaseId: number; + info: WPInfo; +}; + +export type WPPostPreview = Pick< + WPPost, + | 'commentCount' + | 'databaseId' + | 'date' + | 'featuredImage' + | 'info' + | 'modified' + | 'slug' + | 'title' +> & { + acfPosts: + | Nullable> + | Nullable>; + contentParts: Pick; +}; + +export type RecentWPPost = Pick< + WPPost, + 'date' | 'featuredImage' | 'slug' | 'title' +> & { + databaseId: number; +}; + +type WPAcfThematics = { + postsInThematic: Nullable; +}; + +export type WPThematic = WPContent & { + acfThematics: Nullable; +}; + +export type WPThematicPreview = Pick & { + databaseId: number; +}; + +type WPAcfTopics = { + officialWebsite: string; + postsInTopic: Nullable; +}; + +export type WPTopic = WPContent & { + acfTopics: Nullable; +}; + +export type WPTopicPreview = Pick< + WPTopic, + 'featuredImage' | 'slug' | 'title' +> & { + databaseId: number; +}; + +//=========================================================================== +// Data from MDX files +//=========================================================================== + +export type MDXData = { + file: string; + image: MDXImage; +}; + +export type MDXImage = StaticImageData & { + alt: string; + title?: string; +}; + +export type MDXPageMeta = Omit & { + intro: string; + title: string; +}; + +export type MDXProjectMeta = Omit & { + intro: string; + title: string; +}; + +//=========================================================================== +// Data used in this application +//=========================================================================== + +export type Dates = { + publication: string; + update?: string; +}; + +export type SEO = { + description: string; + title: string; +}; + +export type Img = { + alt: string; + height: number; + src: string; + title?: string; + width: number; +}; + +export type CommentAuthor = { + avatar?: Omit; + name: string; + website?: string; +}; + +export type CommentMeta = { + author: CommentAuthor; + date: string; +}; + +export type SingleComment = { + content: string; + id: number; + isApproved: boolean; + meta: CommentMeta; + parentId?: number; + replies: SingleComment[]; +}; + +export type PageMeta = { + cover?: Img; + dates: Dates; + seo: SEO; + wordsCount: number; +}; + +export type Page = { + content: string; + intro: string; + slug: string; + title: string; +}; + +export type PageLink = { + id: number; + logo?: Img; + name: string; + url: string; +}; + +type ArticleMeta = PageMeta & { + author?: string; + commentsCount?: number; + thematics?: PageLink[]; + topics?: PageLink[]; +}; + +export type Article = Page & { + id: number; + meta: ArticleMeta; +}; + +export type ArticlePreview = Pick & { + id: number; + meta: Omit; +}; + +export type RecentArticle = Pick & + Pick & { + id: number; + publicationDate: string; + }; + +export type Repos = { + github?: string; + gitlab?: string; +}; + +export type ProjectMeta = Omit & { + license?: string; + repos?: Repos; + tagline?: string; + technologies?: string[]; +}; + +export type Project = Omit & { + id: string; + meta: ProjectMeta; +}; + +export type ProjectPreview = Omit & { + meta: Omit; +}; + +export type ThematicMeta = PageMeta & { + articles?: ArticlePreview[]; + topics?: PageLink[]; +}; + +export type Thematic = Page & { + meta: ThematicMeta; +}; + +export type TopicMeta = PageMeta & { + articles?: ArticlePreview[]; + thematics?: PageLink[]; + website?: string; +}; + +export type Topic = Page & { + meta: TopicMeta; +}; -- cgit v1.2.3