diff --git a/.biomeignore b/.biomeignore new file mode 100644 index 0000000..d95d1a6 --- /dev/null +++ b/.biomeignore @@ -0,0 +1,4 @@ +dist/ +dist/** +scripts/ +public/** \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b174514..4ba0051 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,35 +27,18 @@ jobs: - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} - cache: "pnpm" + node-version: "24" + - name: Install dependencies - run: pnpm install - - - name: Compile TypeScript - run: pnpm tsc --project tsconfig.scripts.json - - - name: Rename .js files to .mjs - run: | - for file in dist/scripts/**/*.js; do - mv "$file" "${file%.js}.mjs" - done - - - name: Post-process scripts - run: | - for file in dist/scripts/scripts/content.mjs dist/scripts/lib/pageroutes.mjs; do - if [ -f "$file" ]; then - echo "Processing $file..." - sed -i 's|import { Documents } from "@/settings/documents"|import { Documents } from "../settings/documents.mjs"|g' "$file" - if [ $? -ne 0 ]; then - echo "Error: Failed to update $file" - exit 1 - fi - echo "$file updated successfully." - else - echo "$file not found!" - fi - done - - - name: Run content script - run: node dist/scripts/scripts/content.mjs + run: pnpm install --frozen-lockfile + + - name: Generate content + run: sh .husky/post-process.sh + + - name: Upload search data artifact + uses: actions/upload-artifact@v4 + if: success() + with: + name: search-data + path: public/search-data/ + retention-days: 30 diff --git a/.husky/post-process.sh b/.husky/post-process.sh index 172b1eb..302b2d1 100644 --- a/.husky/post-process.sh +++ b/.husky/post-process.sh @@ -1,26 +1,24 @@ #!/bin/sh -npx tsc --project tsconfig.scripts.json +npx tsc --project tsconfig.scripts.json || exit 1 -for file in dist/scripts/**/*.js; do +find dist/scripts -name "*.js" -type f | while read file; do mv "$file" "${file%.js}.mjs" done -for file in dist/scripts/scripts/content.mjs dist/scripts/lib/pageroutes.mjs; do - if [ -f "$file" ]; then - echo "Processing $file..." +if [ -f "dist/scripts/scripts/content.mjs" ]; then + sed -i.bak 's|from '"'"'@/lib/pageroutes'"'"'|from '"'"'../../lib/pageroutes.mjs'"'"'|g' dist/scripts/scripts/content.mjs + sed -i.bak 's|from '"'"'@/settings/documents'"'"'|from '"'"'../settings/documents.mjs'"'"'|g' dist/scripts/scripts/content.mjs + sed -i.bak 's|from '"'"'@/\([^'"'"']*\)'"'"'|from '"'"'../../\1.mjs'"'"'|g' dist/scripts/scripts/content.mjs + rm -f dist/scripts/scripts/content.mjs.bak +fi - sed -i 's|import { Documents } from "@/settings/documents"|import { Documents } from "../settings/documents.mjs"|g' "$file" +if [ -f "dist/scripts/lib/pageroutes.mjs" ]; then + echo "Processing pageroutes.mjs..." + sed -i.bak 's|from '"'"'@/settings'"'"'|from '"'"'../settings/index.mjs'"'"'|g' dist/scripts/lib/pageroutes.mjs + sed -i.bak 's|from '"'"'@/settings/documents'"'"'|from '"'"'../settings/documents.mjs'"'"'|g' dist/scripts/lib/pageroutes.mjs + sed -i.bak 's|from '"'"'@/\([^'"'"']*\)'"'"'|from '"'"'../\1.mjs'"'"'|g' dist/scripts/lib/pageroutes.mjs + rm -f dist/scripts/lib/pageroutes.mjs.bak +fi - if [ $? -ne 0 ]; then - echo "Error: Failed to update $file" - exit 1 - fi - - echo "$file updated successfully." - else - echo "$file not found!" - fi -done - -node dist/scripts/scripts/content.mjs || exit 1 +node dist/scripts/scripts/content.mjs || exit 1 \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit index 02e6988..6fe0ed0 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,3 +1,3 @@ #!/bin/sh -./.husky/post-process.sh || exit 1 \ No newline at end of file +sh ./.husky/post-process.sh || exit 1 \ No newline at end of file diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index a827113..0000000 --- a/.prettierignore +++ /dev/null @@ -1,28 +0,0 @@ -# dependencies -/node_modules -/.pnp -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/versions -.pnpm-debug.log -pnpm-lock.yaml - -# next.js -/.next/ -/out/ - -# production -/build -/dist - -# misc -.DS_Store -*.pem -.env - -dist -public/search-data -contents/docs \ No newline at end of file diff --git a/app/docs/[[...slug]]/page.tsx b/app/docs/[[...slug]]/page.tsx index 8161b79..687219a 100644 --- a/app/docs/[[...slug]]/page.tsx +++ b/app/docs/[[...slug]]/page.tsx @@ -1,13 +1,12 @@ -import { notFound } from "next/navigation" - -import { Settings } from "@/types/settings" -import { getDocument } from "@/lib/markdown" -import { PageRoutes } from "@/lib/pageroutes" -import { Separator } from "@/components/ui/separator" -import { Typography } from "@/components/ui/typography" -import { ArticleBreadcrumb } from "@/components/article/breadcrumb" -import { Pagination } from "@/components/article/pagination" -import { TableOfContents } from "@/components/toc" +import { notFound } from 'next/navigation' +import { ArticleBreadcrumb } from '@/components/article/breadcrumb' +import { Pagination } from '@/components/article/pagination' +import { TableOfContents } from '@/components/toc' +import { Separator } from '@/components/ui/separator' +import { Typography } from '@/components/ui/typography' +import { getDocument } from '@/lib/markdown' +import { PageRoutes } from '@/lib/pageroutes' +import { Settings } from '@/types/settings' interface PageProps { params: Promise<{ slug: string[] }> @@ -15,7 +14,7 @@ interface PageProps { export default async function Pages({ params }: PageProps) { const { slug = [] } = await params - const pathName = slug.join("/") + const pathName = slug.join('/') const res = await getDocument(pathName) if (!res) notFound() @@ -36,18 +35,14 @@ export default async function Pages({ params }: PageProps) { - + ) } export async function generateMetadata({ params }: PageProps) { const { slug = [] } = await params - const pathName = slug.join("/") + const pathName = slug.join('/') const res = await getDocument(pathName) if (!res) return null @@ -66,7 +61,7 @@ export async function generateMetadata({ params }: PageProps) { description: frontmatter.description || Settings.openGraph.description, url: `${Settings.metadataBase}/docs/${pathName}`, siteName: Settings.openGraph.siteName, - type: "article", + type: 'article', images: Settings.openGraph.images.map((image) => ({ ...image, url: `${Settings.metadataBase}${image.url}`, @@ -90,6 +85,6 @@ export async function generateMetadata({ params }: PageProps) { export function generateStaticParams() { return PageRoutes.filter((item) => item.href).map((item) => ({ - slug: item.href.split("/").slice(1), + slug: item.href.split('/').slice(1), })) } diff --git a/app/docs/layout.tsx b/app/docs/layout.tsx index 5661a64..a8e1239 100644 --- a/app/docs/layout.tsx +++ b/app/docs/layout.tsx @@ -1,4 +1,4 @@ -import { Sidebar } from "@/components/sidebar" +import { Sidebar } from '@/components/sidebar' export default function Documents({ children, diff --git a/app/error.tsx b/app/error.tsx index d16023e..15e2bd6 100644 --- a/app/error.tsx +++ b/app/error.tsx @@ -1,10 +1,9 @@ -"use client" +'use client' -import { useEffect } from "react" +import { useEffect } from 'react' +import { Button } from '@/components/ui/button' -import { Button } from "@/components/ui/button" - -export default function Error({ +export default function ErrorBoundary({ error, reset, }: { diff --git a/app/layout.tsx b/app/layout.tsx index a3f693c..97fddd2 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,17 +1,16 @@ -import type { Metadata } from "next" -import { Inter } from "next/font/google" -import { Providers } from "@/providers" -import { GoogleTagManager } from "@next/third-parties/google" +import { GoogleTagManager } from '@next/third-parties/google' +import type { Metadata } from 'next' +import { Inter } from 'next/font/google' +import { Footer } from '@/components/navigation/footer' +import { Navbar } from '@/components/navigation/navbar' +import { Providers } from '@/providers' +import { Settings } from '@/types/settings' -import { Settings } from "@/types/settings" -import { Footer } from "@/components/navigation/footer" -import { Navbar } from "@/components/navigation/navbar" - -import "@/styles/globals.css" +import '@/styles/globals.css' const inter = Inter({ - variable: "--font-inter", - subsets: ["latin"], + variable: '--font-inter', + subsets: ['latin'], }) const baseUrl = Settings.metadataBase diff --git a/app/not-found.tsx b/app/not-found.tsx index cfb52f7..811272d 100644 --- a/app/not-found.tsx +++ b/app/not-found.tsx @@ -1,14 +1,12 @@ -import { Link } from "lib/transition" +import { Link } from 'lib/transition' -import { Button } from "@/components/ui/button" +import { Button } from '@/components/ui/button' export default function NotFound() { return (

404

-

- Page not found -

+

Page not found

diff --git a/components/markdown/filetree/component.tsx b/components/markdown/filetree/component.tsx index 16f86d9..052ec1a 100644 --- a/components/markdown/filetree/component.tsx +++ b/components/markdown/filetree/component.tsx @@ -1,5 +1,6 @@ -"use client" +'use client' +import cn from 'clsx' import { createContext, memo, @@ -8,10 +9,9 @@ import { useCallback, useContext, useState, -} from "react" -import cn from "clsx" -import { FiFileText } from "react-icons/fi" -import { LuFolder, LuFolderClosed } from "react-icons/lu" +} from 'react' +import { FiFileText } from 'react-icons/fi' +import { LuFolder, LuFolderClosed } from 'react-icons/lu' const ctx = createContext(0) @@ -35,21 +35,12 @@ function useIndent() { function Tree({ children }: { children: ReactNode }): ReactElement { return ( -
    - {children} -
+
    {children}
) } export const Folder = memo( - ({ - label, - name, - open, - defaultOpen = false, - onToggle, - children, - }: FolderProps) => { + ({ label, name, open, defaultOpen = false, onToggle, children }: FolderProps) => { const indent = useIndent() const [isOpen, setIsOpen] = useState(defaultOpen) @@ -66,22 +57,18 @@ export const Folder = memo( onClick={toggle} title={name} className={cn( - "inline-flex cursor-pointer items-center py-1 text-xs transition-all hover:text-muted-foreground" + 'inline-flex cursor-pointer items-center py-1 text-xs transition-all hover:text-muted-foreground' )} > - {isFolderOpen ? ( - - ) : ( - - )} + {isFolderOpen ? : } {label ?? name}
@@ -95,7 +82,7 @@ export const Folder = memo( } ) -Folder.displayName = "Folder" +Folder.displayName = 'Folder' export const File = memo(({ label, name }: FileProps) => (
  • @@ -108,6 +95,6 @@ export const File = memo(({ label, name }: FileProps) => (
  • )) -File.displayName = "File" +File.displayName = 'File' export default Tree diff --git a/components/markdown/filetree/index.tsx b/components/markdown/filetree/index.tsx index adad925..57a81b1 100644 --- a/components/markdown/filetree/index.tsx +++ b/components/markdown/filetree/index.tsx @@ -1,10 +1,7 @@ -"use client" +'use client' -import dynamic from "next/dynamic" +import dynamic from 'next/dynamic' -export const FileTree = dynamic( - () => import("@/components/markdown/filetree/component"), - { - ssr: false, - } -) +export const FileTree = dynamic(() => import('@/components/markdown/filetree/component'), { + ssr: false, +}) diff --git a/components/markdown/link.tsx b/components/markdown/link.tsx index 50860dc..ab69886 100644 --- a/components/markdown/link.tsx +++ b/components/markdown/link.tsx @@ -1,12 +1,12 @@ -import { Link } from "lib/transition" +import { Link } from 'lib/transition' interface Routed { href?: string children: React.ReactNode } -const RoutedLink: React.FC = ({ href = "#", children }) => { - const isInternal = href.startsWith("/") || href.startsWith("#") +const RoutedLink: React.FC = ({ href = '#', children }) => { + const isInternal = href.startsWith('/') || href.startsWith('#') if (isInternal) { return {children} diff --git a/components/markdown/mermaid.tsx b/components/markdown/mermaid.tsx index d91098c..2def3aa 100644 --- a/components/markdown/mermaid.tsx +++ b/components/markdown/mermaid.tsx @@ -1,8 +1,8 @@ -"use client" +'use client' -import React, { useCallback, useEffect, useMemo, useRef } from "react" -import clsx from "clsx" -import mermaid from "mermaid" +import clsx from 'clsx' +import mermaid from 'mermaid' +import React, { useCallback, useEffect, useMemo, useRef } from 'react' interface MermaidProps { chart: string @@ -10,7 +10,7 @@ interface MermaidProps { } mermaid.initialize({ - theme: "neutral", + theme: 'neutral', }) const Mermaid = ({ chart, className }: MermaidProps) => { @@ -24,14 +24,11 @@ const Mermaid = ({ chart, className }: MermaidProps) => { try { mermaid.contentLoaded() } catch (error) { - console.error("Mermaid diagram render error:", error) + console.error('Mermaid diagram render error:', error) } }, [chart]) - const memoizedClassName = useMemo( - () => clsx("mermaid", className), - [className] - ) + const memoizedClassName = useMemo(() => clsx('mermaid', className), [className]) useEffect(() => { renderMermaid() diff --git a/components/markdown/note.tsx b/components/markdown/note.tsx index 0ac93c7..cd9552a 100644 --- a/components/markdown/note.tsx +++ b/components/markdown/note.tsx @@ -1,35 +1,23 @@ -import { PropsWithChildren } from "react" -import clsx from "clsx" +import clsx from 'clsx' +import { PropsWithChildren } from 'react' -import { cn } from "@/lib/utils" +import { cn } from '@/lib/utils' type NoteProps = PropsWithChildren & { title?: string - type?: "note" | "success" | "warning" | "danger" + type?: 'note' | 'success' | 'warning' | 'danger' } -export default function Note({ - children, - title = "Note", - type = "note", -}: NoteProps) { +export default function Note({ children, title = 'Note', type = 'note' }: NoteProps) { const noteClassNames = clsx({ - "dark:bg-neutral-900 bg-neutral-50": type == "note", - "dark:bg-green-950 bg-green-100 border-green-300 dark:border-green-900": - type === "success", - "dark:bg-orange-950 bg-orange-100 border-orange-300 dark:border-orange-900": - type === "warning", - "dark:bg-red-950 bg-red-100 border-red-300 dark:border-red-900": - type === "danger", + 'dark:bg-neutral-900 bg-neutral-50': type == 'note', + 'dark:bg-green-950 bg-green-100 border-green-300 dark:border-green-900': type === 'success', + 'dark:bg-orange-950 bg-orange-100 border-orange-300 dark:border-orange-900': type === 'warning', + 'dark:bg-red-950 bg-red-100 border-red-300 dark:border-red-900': type === 'danger', }) return ( -
    +

    {title}:

    {children}
    diff --git a/components/markdown/step.tsx b/components/markdown/step.tsx index f84bc6b..28cffae 100644 --- a/components/markdown/step.tsx +++ b/components/markdown/step.tsx @@ -1,7 +1,7 @@ -import { Children, PropsWithChildren, ReactNode } from "react" -import clsx from "clsx" +import clsx from 'clsx' +import { Children, PropsWithChildren, ReactNode } from 'react' -import { cn } from "@/lib/utils" +import { cn } from '@/lib/utils' interface StepProps { children: ReactNode @@ -13,12 +13,7 @@ export function Step({ children }: PropsWithChildren) { return (
    {Children.map(children, (child, index) => ( -
    +
    {index + 1}
    diff --git a/components/navigation/footer.tsx b/components/navigation/footer.tsx index 22d4388..0baec16 100644 --- a/components/navigation/footer.tsx +++ b/components/navigation/footer.tsx @@ -1,13 +1,13 @@ -import Image from "next/image" -import Link from "next/link" +import Image from 'next/image' +import Link from 'next/link' -import { Settings } from "@/types/settings" +import { Settings } from '@/types/settings' export function Footer() { return (