diff --git a/.gitignore b/.gitignore index 9a814d0f..357cb254 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ !.*.example !.vscode/ !.github/ +!.vitepress/ # Common generated folders logs/ diff --git a/apps/content/.gitignore b/apps/content/.gitignore index 55a12ae7..5ba0550f 100644 --- a/apps/content/.gitignore +++ b/apps/content/.gitignore @@ -1,28 +1,24 @@ -# deps -/node_modules - -# generated content -.contentlayer -.content-collections -.source - -# test & build -/coverage -/.next/ -/out/ -/build -*.tsbuildinfo - -# misc -.DS_Store -*.pem -/.pnp -.pnp.js -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# others -.env*.local -.vercel -next-env.d.ts \ No newline at end of file +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? \ No newline at end of file diff --git a/apps/content/.vitepress/.gitignore b/apps/content/.vitepress/.gitignore new file mode 100644 index 00000000..3adbdfad --- /dev/null +++ b/apps/content/.vitepress/.gitignore @@ -0,0 +1,2 @@ +dist +cache diff --git a/apps/content/.vitepress/config.ts b/apps/content/.vitepress/config.ts new file mode 100644 index 00000000..4a7193e5 --- /dev/null +++ b/apps/content/.vitepress/config.ts @@ -0,0 +1,190 @@ +import { transformerTwoslash } from '@shikijs/vitepress-twoslash' +import { defineConfig } from 'vitepress' +import { groupIconMdPlugin, groupIconVitePlugin } from 'vitepress-plugin-group-icons' + +export default defineConfig({ + lang: 'en-US', + title: 'oRPC', + description: + 'oRPC makes it easy to build APIs that are end-to-end type-safe and adhere to OpenAPI standards, ensuring a smooth and enjoyable developer experience.', + lastUpdated: true, + ignoreDeadLinks: true, + cleanUrls: true, + markdown: { + theme: { + light: 'github-light', + dark: 'github-dark', + }, + config(md) { + md.use(groupIconMdPlugin) + }, + codeTransformers: [ + transformerTwoslash(), + ], + }, + themeConfig: { + logo: '/logo.webp', + siteTitle: '', + socialLinks: [ + { icon: 'github', link: 'https://github.com/unnoq/orpc' }, + { icon: 'discord', link: 'https://discord.gg/TXEbwRBvQn' }, + { icon: 'x', link: 'https://x.com/unnoqcom' }, + { icon: 'bluesky', link: 'https://bsky.app/profile/unnoq.com' }, + ], + editLink: { + pattern: 'https://github.com/unnoq/orpc/blob/main/apps/content/:path', + text: 'Edit on GitHub', + }, + footer: { + message: 'Released under the MIT License.', + copyright: 'Copyright © 2024-present Unnoq & oRPC contributors.', + }, + nav: [ + { text: 'Docs', link: '/docs/getting-started', activeMatch: '/docs/(?!openapi/)' }, + { text: 'OpenAPI', link: '/docs/openapi/getting-started', activeMatch: '/docs/openapi/' }, + { text: 'Examples', link: '/examples/', activeMatch: '/examples/' }, + { text: 'Sponsor', link: '/sponsor' }, + { + text: 'About', + items: [ + { text: 'Motivation', link: '/motivation' }, + { text: 'Releases', link: 'https://github.com/unnoq/orpc/releases' }, + ], + }, + { text: 'Discussions', link: 'https://github.com/unnoq/orpc/discussions' }, + ], + sidebar: { + '/docs/': [ + { text: 'Getting Started', link: '/docs/getting-started' }, + { text: 'Procedure', link: '/docs/procedure' }, + { text: 'Router', link: '/docs/router' }, + { text: 'Middleware', link: '/docs/middleware' }, + { text: 'Context', link: '/docs/context' }, + { text: 'Error Handling', link: '/docs/error-handling' }, + { text: 'File Upload/Download', link: '/docs/file-upload-download' }, + { text: 'Event Iterator (SSE)', link: '/docs/event-iterator' }, + { text: 'Server Action', link: '/docs/server-action' }, + { text: 'RPC Handler', link: '/docs/rpc-handler' }, + { text: 'Lifecycle', link: '/docs/lifecycle' }, + { + text: 'Contract First', + collapsed: true, + items: [ + { text: 'Define Contract', link: '/docs/contract-first/define-contract' }, + { text: 'Implement Contract', link: '/docs/contract-first/implement-contract' }, + ], + }, + { + text: 'Integrations', + collapsed: true, + items: [ + { text: 'Fetch server', link: '/docs/integrations/fetch-server' }, + { text: 'Node', link: '/docs/integrations/node' }, + { text: 'Bun', link: '/docs/integrations/bun' }, + { text: 'Cloudflare Workers', link: '/docs/integrations/cloudflare-workers' }, + { text: 'Deno', link: '/docs/integrations/deno' }, + { text: 'Express', link: '/docs/integrations/express' }, + { text: 'Next.js', link: '/docs/integrations/nextjs' }, + { text: 'Nuxt', link: '/docs/integrations/nuxt' }, + { text: 'Hono', link: '/docs/integrations/hono' }, + { text: 'Tanstack Start', link: '/docs/integrations/tanstack-start' }, + { text: 'Elysia', link: '/docs/integrations/elysia' }, + { text: 'SvelteKit', link: '/docs/integrations/svelte-kit' }, + { text: 'Remix', link: '/docs/integrations/remix' }, + { text: 'SolidStart', link: '/docs/integrations/solid-start' }, + ], + }, + { + text: 'Plugins', + collapsed: true, + items: [ + { text: 'CORS', link: '/docs/plugins/cors' }, + { text: 'Response Headers', link: '/docs/plugins/response-headers' }, + ], + }, + { + text: 'Client', + collapsed: true, + items: [ + { text: 'Server-Side', link: '/docs/client/server-side' }, + { text: 'Client-Side', link: '/docs/client/client-side' }, + { text: 'Error Handling', link: '/docs/client/error-handling' }, + { text: 'Event Iterator', link: '/docs/client/event-iterator' }, + { text: 'RPC Link', link: '/docs/client/rpc-link' }, + { text: 'Dynamic Link', link: '/docs/client/dynamic-link' }, + ], + }, + { + text: 'Tanstack Query', + collapsed: true, + items: [ + { text: 'Basic', link: '/docs/tanstack-query/basic' }, + { text: 'React', link: '/docs/tanstack-query/react' }, + { text: 'Vue', link: '/docs/tanstack-query/vue' }, + ], + }, + { + text: 'Advanced', + collapsed: true, + items: [ + { text: 'Validation Errors', link: '/docs/advanced/validation-errors' }, + { text: 'RPC Protocol', link: '/docs/advanced/rpc-protocol' }, + ], + }, + { + text: 'Others', + collapsed: true, + items: [ + { text: 'Pinia Colada', link: '/docs/pinia-colada' }, + { text: 'Playgrounds', link: '/docs/playgrounds' }, + { text: 'Comparison', link: '/docs/comparison' }, + ], + }, + ], + '/docs/openapi/': [ + { text: 'Getting Started', link: '/docs/openapi/getting-started' }, + { text: 'Routing', link: '/docs/openapi/routing' }, + { text: 'Input/Output Structure', link: '/docs/openapi/input-output-structure' }, + { text: 'Error Handling', link: '/docs/openapi/error-handling' }, + { text: 'Bracket Notation', link: '/docs/openapi/bracket-notation' }, + { text: 'OpenAPI Handler', link: '/docs/openapi/openapi-handler' }, + { text: 'OpenAPI Specification', link: '/docs/openapi/openapi-specification' }, + { + text: 'Plugins', + collapsed: true, + items: [ + { text: 'Zod Smart Coercion', link: '/docs/openapi/plugins/zod-smart-coercion' }, + ], + }, + { + text: 'Client', + collapsed: true, + items: [ + { text: 'OpenAPI Link', link: '/docs/openapi/client/openapi-link' }, + ], + }, + ], + '/examples/': [ + + ], + }, + }, + head: [ + ['meta', { property: 'og:image', content: 'https://orpc.unnoq.com/og.jpg' }], + ['meta', { property: 'og:type', content: 'website' }], + ['meta', { property: 'twitter:domain', content: 'orpc.unnoq.com' }], + ['meta', { property: 'twitter:image', content: 'https://orpc.unnoq.com/og.jpg' }], + ['meta', { property: 'twitter:card', content: 'summary_large_image' }], + ['link', { rel: 'shortcut icon', href: '/icon.svg', type: 'image/svg+xml' }], + ], + titleTemplate: ':title - oRPC', + vite: { + plugins: [ + groupIconVitePlugin({ + customIcon: { + cloudflare: 'logos:cloudflare-workers-icon', + }, + }), + ], + }, +}) diff --git a/apps/content/.vitepress/theme/custom.css b/apps/content/.vitepress/theme/custom.css new file mode 100644 index 00000000..7f943c35 --- /dev/null +++ b/apps/content/.vitepress/theme/custom.css @@ -0,0 +1,38 @@ +:root { + --vp-font-family-base: -apple-system, BlinkMacSystemFont, segoe ui, Helvetica, Arial, sans-serif, apple color emoji, + segoe ui emoji; + --vp-font-family-mono: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; +} + +.vp-doc h1, +.vp-doc h2, +.vp-doc h3, +.vp-doc h4, +.vp-doc h5, +.vp-doc h6 { + font-weight: 700; +} + +.title { + font-weight: 700 !important; +} + +.tagline { + max-width: 500px !important; +} + +body { + -webkit-font-smoothing: subpixel-antialiased; +} + +.VPImage.image-src { + padding-top: 12%; + max-width: 512px; + max-height: 512px; +} + +@media screen and (max-width: 960px) { + .VPHero.has-image .image { + display: none; + } +} diff --git a/apps/content/.vitepress/theme/index.ts b/apps/content/.vitepress/theme/index.ts new file mode 100644 index 00000000..aaf2fbce --- /dev/null +++ b/apps/content/.vitepress/theme/index.ts @@ -0,0 +1,14 @@ +import type { EnhanceAppContext } from 'vitepress' +import TwoslashFloatingVue from '@shikijs/vitepress-twoslash/client' +import Theme from 'vitepress/theme' + +import 'virtual:group-icons.css' +import '@shikijs/vitepress-twoslash/style.css' +import './custom.css' + +export default { + extends: Theme, + enhanceApp({ app }: EnhanceAppContext) { + app.use(TwoslashFloatingVue) + }, +} diff --git a/apps/content/README.md b/apps/content/README.md deleted file mode 100644 index 92851e07..00000000 --- a/apps/content/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# content - -This is a Next.js application generated with -[Create Fumadocs](https://github.com/fuma-nama/fumadocs). - -Run development server: - -```bash -npm run dev -# or -pnpm dev -# or -yarn dev -``` - -Open http://localhost:3000 with your browser to see the result. - -## Learn More - -To learn more about Next.js and Fumadocs, take a look at the following -resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js - features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. -- [Fumadocs](https://fumadocs.vercel.app) - learn about Fumadocs diff --git a/apps/content/app/(home)/layout.tsx b/apps/content/app/(home)/layout.tsx deleted file mode 100644 index 9f4331ad..00000000 --- a/apps/content/app/(home)/layout.tsx +++ /dev/null @@ -1,185 +0,0 @@ -import type { ReactNode } from 'react' -import { baseOptions } from '@/app/layout.config' -import { HomeLayout } from 'fumadocs-ui/layouts/home' - -export default function Layout({ - children, -}: { - children: ReactNode -}): React.ReactElement { - return ( - - - - background - - - - - - - - - - - - - - - - - - - - - - - - - {children} -