Skip to content

Commit

Permalink
refactor: add JSDoc [skip deploy]
Browse files Browse the repository at this point in the history
  • Loading branch information
tszhong0411 committed Sep 18, 2023
1 parent 0a7b3c0 commit ecc06cb
Show file tree
Hide file tree
Showing 58 changed files with 659 additions and 115 deletions.
Binary file modified bun.lockb
Binary file not shown.
22 changes: 13 additions & 9 deletions contentlayer.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,13 @@ const Pages = defineDocumentType(() => ({
}
}))

const rehypeAddClassesToCodeBlocks = (option: { className: string }) => {
const { className } = option

/**
* A rehype plugin that adds a class to all code blocks with a specific data attribute.
* @function rehypeAddClassesToCodeBlocks
* @param className The class name to add to the code blocks.
* @returns A rehype transformer function.
*/
const rehypeAddClassesToCodeBlocks = (className: string) => {
return (tree: Root) => {
visit(tree, 'element', (node, index, parent) => {
if (node.properties?.['data-rehype-pretty-code-fragment'] === undefined)
Expand All @@ -141,6 +145,11 @@ const rehypeAddClassesToCodeBlocks = (option: { className: string }) => {
}
}

/**
* Adds a language icon to code blocks.
* @function rehypeAddLanguageIconToCodeBlocks
* @returns A function that adds a language icon to code blocks.
*/
const rehypeAddLanguageIconToCodeBlocks = () => {
return (tree: Root) => {
visit(tree, 'element', (node) => {
Expand Down Expand Up @@ -201,12 +210,7 @@ export default makeSource({
keepBackground: false
}
],
[
rehypeAddClassesToCodeBlocks,
{
className: 'relative'
}
],
[rehypeAddClassesToCodeBlocks, 'relative'],
rehypeAddLanguageIconToCodeBlocks
]
}
Expand Down
44 changes: 41 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"type": "module",
"scripts": {
"build": "next build",
"dev": "concurrently \"contentlayer dev\" \"next dev\"",
"dev": "concurrently \"contentlayer dev\" \"cross-env NODE_OPTIONS='--inspect' next dev\"",
"format": "prettier -w .",
"postinstall": "prisma generate && contentlayer build",
"lint": "eslint .",
Expand Down Expand Up @@ -94,6 +94,7 @@
"@vitest/ui": "^0.34.4",
"autoprefixer": "^10.4.15",
"concurrently": "^8.2.1",
"cross-env": "^7.0.3",
"eslint": "^8.49.0",
"eslint-config-next": "^13.4.19",
"eslint-plugin-jsdoc": "^46.8.1",
Expand All @@ -112,6 +113,18 @@
"unified": "10.1.2",
"vitest": "^0.34.4"
},
"browserslist": {
"production": [
">0.3%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"eslintConfig": {
"extends": [
"next/core-web-vitals",
Expand All @@ -127,8 +140,33 @@
"ecmaVersion": "latest"
},
"rules": {
"jsdoc/require-param-type": "off",
"jsdoc/require-returns-type": "off"
"require-jsdoc": 0,
"valid-jsdoc": 0,
"jsdoc/require-jsdoc": [
"warn",
{
"require": {
"FunctionDeclaration": true,
"MethodDefinition": true,
"ClassDeclaration": true
},
"contexts": [
"TSInterfaceDeclaration",
"TSTypeAliasDeclaration",
"TSEnumDeclaration",
"TSPropertySignature"
]
}
],
"jsdoc/require-param": [
0,
{
"checkRestProperty": false
}
],
"jsdoc/require-returns": 0,
"jsdoc/require-param-type": 0,
"jsdoc/require-returns-type": 0
},
"settings": {
"jsdoc": {
Expand Down
9 changes: 9 additions & 0 deletions src/app/about/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,17 @@ import getPage from '@/utils/get-page'
const title = 'About'
const description = 'A student who loves web development.'

/**
* The props of {@link AboutPage}.
*/
type AboutPageProps = {
/**
* The params of the URL.
*/
params: Record<string, never>
/**
* The search params of the URL.
*/
searchParams: Record<string, never>
}

Expand Down
13 changes: 10 additions & 3 deletions src/app/api/spotify/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,16 @@ export const GET = async () => {
const isPlaying = song.is_playing
const name = song.item.name
const artist = song.item.artists
.map((_artist) => {
return _artist.name
})
.map(
(_artist: {
/**
* The name of the artist.
*/
name: string
}) => {
return _artist.name
}
)
.join(', ')
const album = song.item.album.name
const albumImage = song.item.album.images[0].url
Expand Down
7 changes: 6 additions & 1 deletion src/app/api/views/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ export const GET = async (req: Request) => {
}

export const POST = async (req: Request) => {
const { slug } = (await req.json()) as { slug: string }
const { slug } = (await req.json()) as {
/**
* The slug of the post.
*/
slug: string
}

if (!slug) {
return NextResponse.json(
Expand Down
7 changes: 4 additions & 3 deletions src/app/api/wakatime/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { NextResponse } from 'next/server'

import { env } from '@/env.mjs'
import { WakatimeRes } from '@/types'

export const dynamic = 'force-dynamic'

Expand All @@ -17,9 +16,11 @@ export const GET = async () => {
}
)

const data: WakatimeRes = await res.json()
const {
data: { total_seconds }
} = await res.json()

return NextResponse.json({
seconds: data.data.total_seconds
seconds: total_seconds
})
}
3 changes: 1 addition & 2 deletions src/app/api/youtube/route.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { NextResponse } from 'next/server'

import { env } from '@/env.mjs'
import { YouTubeRes } from '@/types'

export const dynamic = 'force-dynamic'

export const GET = async () => {
const res = await fetch(
`https://www.googleapis.com/youtube/v3/channels?id=UC2hMWOaOlk9vrkvFVaGmn0Q&part=statistics&key=${env.GOOGLE_API_KEY}`
)
const data: YouTubeRes = await res.json()
const data = await res.json()

const channel = data.items[0]
const statistics = channel.statistics
Expand Down
9 changes: 9 additions & 0 deletions src/app/blog/[slug]/content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@ import { getHeadings } from '@/utils/get-headings'
import LikeButton from './like-button'
import TableOfContents from './table-of-contents'

/**
* The props of {@link Content}.
*/
type ContentProps = {
/**
* The post data.
*/
post: BlogPost
/**
* The slug of the post.
*/
slug: string
}

Expand Down
9 changes: 9 additions & 0 deletions src/app/blog/[slug]/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,17 @@ import { Skeleton } from '@/components/ui'
const editURL = (slug: string) =>
`https://github.com/tszhong0411/honghong.me/blob/main/src/content/blog/${slug}.mdx?plain=1`

/**
* The props of {@link Footer}.
*/
type FooterProps = {
/**
* The slug of the blog post.
*/
slug: string
/**
* The last modified time of the blog post.
*/
modifiedTime: string
}

Expand Down
12 changes: 12 additions & 0 deletions src/app/blog/[slug]/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,21 @@ import { Skeleton } from '@/components/ui'
import fetcher from '@/lib/fetcher'
import { Views } from '@/types'

/**
* The props of {@link Header}.
*/
type HeaderProps = {
/**
* The published date of the blog post.
*/
date: string
/**
* The title of the blog post.
*/
title: string
/**
* The slug of the blog post.
*/
slug: string
}

Expand Down
6 changes: 6 additions & 0 deletions src/app/blog/[slug]/like-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ import fetcher from '@/lib/fetcher'
import { Likes } from '@/types'
import cn from '@/utils/cn'

/**
* The props of {@link LikeButton}.
*/
export type LikeButtonProps = {
/**
* The slug of the blog post.
*/
slug: string
}

Expand Down
13 changes: 13 additions & 0 deletions src/app/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,23 @@ import Content from './content'
import Footer from './footer'
import Header from './header'

/**
* The props of {@link BlogPostPage}.
*/
type BlogPostPageProps = {
/**
* The params of the URL.
*/
params: {
/**
* The slug of the URL.
*/
slug: string
}
/**
* The search params of the URL.
*/
searchParams: Record<string, never>
}

export const generateStaticParams = (): Array<BlogPostPageProps['params']> => {
Expand Down
6 changes: 6 additions & 0 deletions src/app/blog/[slug]/table-of-contents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import useScrollspy from '@/hooks/use-scrollspy'
import cn from '@/utils/cn'
import { Heading } from '@/utils/get-headings'

/**
* The props of {@link TableOfContents}.
*/
type TableOfContentsProps = {
/**
* The headings to display in the table of contents.
*/
headings: Heading[]
}

Expand Down
9 changes: 9 additions & 0 deletions src/app/blog/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,17 @@ const title = 'Blog'
const description =
'My personal website and blog where I share my thoughts on various topics including tutorials, notes, and personal experiences. As a full-stack developer from Hong Kong, I started learning web development as a hobby in December 2020. I use Next.js for building websites, GitHub for code hosting, and Vercel for deployment. Explore my site to learn more about my Journey and discover some of the web development resources that have inspired me.'

/**
* The props of {@link BlogPage}.
*/
type BlogPageProps = {
/**
* The params of the URL.
*/
params: Record<string, never>
/**
* The search params of the URL.
*/
searchParams: Record<string, never>
}

Expand Down
23 changes: 19 additions & 4 deletions src/app/dashboard/items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,36 @@ import useSWR from 'swr'

import { Skeleton } from '@/components/ui'
import fetcher from '@/lib/fetcher'
import { GithubData, Likes, Views, WakatimeData, YouTubeData } from '@/types'
import { Github, Likes, Views, Wakatime, YouTube } from '@/types'

/**
* A metric card with an icon, title, link, and value.
*/
type Card = {
/**
* The icon to display on the card.
*/
icon: React.ReactNode
/**
* The title of the card.
*/
title: string
/**
* The link to navigate to when the card is clicked.
*/
link: string
/**
* The value to display on the card.
*/
value: number | string | undefined
}

const Items = () => {
const { data: youtubeData } = useSWR<YouTubeData>('/api/youtube', fetcher)
const { data: githubData } = useSWR<GithubData>('/api/github', fetcher)
const { data: youtubeData } = useSWR<YouTube>('/api/youtube', fetcher)
const { data: githubData } = useSWR<Github>('/api/github', fetcher)
const { data: likesData } = useSWR<Likes>('/api/likes', fetcher)
const { data: viewsData } = useSWR<Views>('/api/views', fetcher)
const { data: wakatimeData } = useSWR<WakatimeData>('/api/wakatime', fetcher)
const { data: wakatimeData } = useSWR<Wakatime>('/api/wakatime', fetcher)

const [age, setAge] = React.useState<string>()

Expand Down
9 changes: 9 additions & 0 deletions src/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,17 @@ const title = 'Dashboard'
const description =
'This is my personal dashboard, built with Next.js API routes deployed as serverless functions. I use this dashboard to track various metrics across platforms like YouTube, GitHub, and more.'

/**
* The props of {@link DashboardPage}.
*/
type DashboardPageProps = {
/**
* The params of the URL.
*/
params: Record<string, never>
/**
* The search params of the URL.
*/
searchParams: Record<string, never>
}

Expand Down
Loading

0 comments on commit ecc06cb

Please sign in to comment.