aboutsummaryrefslogtreecommitdiffstats
path: root/src/types/data.ts
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-11-24 20:00:08 +0100
committerArmand Philippot <git@armandphilippot.com>2023-11-27 14:47:51 +0100
commitf111685c5886f3e77edfd3621c98d8ac1b9bcce4 (patch)
tree62a541fe3afeb64bf745443706fbfb02e96c5230 /src/types/data.ts
parentbee515641cb144be9a855ff2cac258d2fedab21d (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/types/data.ts')
-rw-r--r--src/types/data.ts289
1 files changed, 289 insertions, 0 deletions
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<WPCommentAuthorAvatar>;
+ name: string;
+ url: Nullable<string>;
+};
+
+export type WPCommentStatus = 'APPROVE' | 'HOLD' | 'SPAM' | 'TRASH';
+
+export type WPComment = {
+ approved: boolean;
+ author: GraphQLNode<WPCommentAuthor>;
+ content: string;
+ databaseId: number;
+ date: string;
+ parentDatabaseId: number;
+ status: WPCommentStatus;
+};
+
+type WPContentParts = {
+ afterMore: string;
+ beforeMore: string;
+};
+
+export type WPImage = {
+ altText: Nullable<string>;
+ mediaDetails: {
+ height: number;
+ width: number;
+ };
+ sourceUrl: string;
+ title: Nullable<string>;
+};
+
+type WPInfo = { wordsCount: number };
+
+type WPContent = {
+ date: string;
+ featuredImage: Nullable<GraphQLNode<WPImage>>;
+ modified: string;
+ seo: WPSeo;
+ slug: string;
+ title: string;
+};
+
+export type WPPage = WPContent & {
+ contentParts: WPContentParts;
+ info: WPInfo;
+};
+
+type WPPostAuthor = { name: string };
+
+type WPAcfPosts = {
+ postsInThematic: Nullable<WPThematicPreview[]>;
+ postsInTopic: Nullable<WPTopicPreview[]>;
+};
+
+export type WPPost = WPContent & {
+ acfPosts: Nullable<Partial<WPAcfPosts>>;
+ author: GraphQLNode<WPPostAuthor>;
+ commentCount: Nullable<number>;
+ contentParts: WPContentParts;
+ databaseId: number;
+ info: WPInfo;
+};
+
+export type WPPostPreview = Pick<
+ WPPost,
+ | 'commentCount'
+ | 'databaseId'
+ | 'date'
+ | 'featuredImage'
+ | 'info'
+ | 'modified'
+ | 'slug'
+ | 'title'
+> & {
+ acfPosts:
+ | Nullable<Pick<WPAcfPosts, 'postsInThematic'>>
+ | Nullable<Pick<WPAcfPosts, 'postsInTopic'>>;
+ contentParts: Pick<WPContentParts, 'beforeMore'>;
+};
+
+export type RecentWPPost = Pick<
+ WPPost,
+ 'date' | 'featuredImage' | 'slug' | 'title'
+> & {
+ databaseId: number;
+};
+
+type WPAcfThematics = {
+ postsInThematic: Nullable<WPPostPreview[]>;
+};
+
+export type WPThematic = WPContent & {
+ acfThematics: Nullable<WPAcfThematics>;
+};
+
+export type WPThematicPreview = Pick<WPThematic, 'slug' | 'title'> & {
+ databaseId: number;
+};
+
+type WPAcfTopics = {
+ officialWebsite: string;
+ postsInTopic: Nullable<WPPostPreview[]>;
+};
+
+export type WPTopic = WPContent & {
+ acfTopics: Nullable<WPAcfTopics>;
+};
+
+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<PageMeta, 'wordsCount'> & {
+ intro: string;
+ title: string;
+};
+
+export type MDXProjectMeta = Omit<ProjectMeta, 'wordsCount'> & {
+ 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<Img, 'title'>;
+ 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<Article, 'intro' | 'slug' | 'title'> & {
+ id: number;
+ meta: Omit<ArticleMeta, 'author' | 'seo' | 'topics'>;
+};
+
+export type RecentArticle = Pick<Article, 'slug' | 'title'> &
+ Pick<ArticleMeta, 'cover'> & {
+ id: number;
+ publicationDate: string;
+ };
+
+export type Repos = {
+ github?: string;
+ gitlab?: string;
+};
+
+export type ProjectMeta = Omit<PageMeta, 'wordsCount'> & {
+ license?: string;
+ repos?: Repos;
+ tagline?: string;
+ technologies?: string[];
+};
+
+export type Project = Omit<Page, 'content'> & {
+ id: string;
+ meta: ProjectMeta;
+};
+
+export type ProjectPreview = Omit<Project, 'meta'> & {
+ meta: Omit<ProjectMeta, 'license' | 'repos'>;
+};
+
+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;
+};