mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 23:49:51 +00:00
[Experimental] Docs: Migrate to next-docs-mdx
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'next-docs-zeta': minor
|
||||
'next-docs-ui': minor
|
||||
---
|
||||
|
||||
Improve CommonJS/ESM compatibility
|
||||
@@ -1,26 +0,0 @@
|
||||
# docs
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [67cd8ab]
|
||||
- next-docs-zeta@0.2.1
|
||||
- next-docs-ui@0.1.2
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [5ff94af]
|
||||
- Updated dependencies [5ff94af]
|
||||
- next-docs-zeta@0.2.0
|
||||
- next-docs-ui@0.1.1
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d909192]
|
||||
- Updated dependencies [e88eec8]
|
||||
- next-docs-zeta@0.0.2
|
||||
@@ -1,38 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { Wrapper } from '@/components/preview/wrapper'
|
||||
import { ThemeSwitch } from '@/components/ThemeSwitch'
|
||||
import { useMDXComponent } from 'next-contentlayer/hooks'
|
||||
import { Accordion, Accordions } from 'next-docs-ui/components/accordion'
|
||||
import { Callout } from 'next-docs-ui/components/callout'
|
||||
import { ImageZoom } from 'next-docs-ui/components/image-zoom'
|
||||
import { Tab, Tabs } from 'next-docs-ui/components/tabs'
|
||||
import { TypeTable } from 'next-docs-ui/components/type-table'
|
||||
import defaultComponents from 'next-docs-ui/mdx'
|
||||
import { type HTMLAttributes } from 'react'
|
||||
|
||||
const components = {
|
||||
...defaultComponents,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
img: (props: any) => <ImageZoom {...props} />,
|
||||
pre: (props: HTMLAttributes<HTMLPreElement>) => (
|
||||
<defaultComponents.pre {...props} className="max-h-[400px]" />
|
||||
),
|
||||
ThemeSwitch,
|
||||
Callout,
|
||||
TypeTable,
|
||||
Accordion,
|
||||
Accordions,
|
||||
Tab,
|
||||
Tabs,
|
||||
Wrapper,
|
||||
blockquote: (props: React.QuoteHTMLAttributes<HTMLQuoteElement>) => (
|
||||
<Callout className="my-4">{props.children}</Callout>
|
||||
)
|
||||
}
|
||||
|
||||
export function Content({ code }: { code: string }) {
|
||||
const MDX = useMDXComponent(code)
|
||||
|
||||
return <MDX components={components} />
|
||||
}
|
||||
@@ -1,18 +1,14 @@
|
||||
import { resolve } from 'url'
|
||||
import Preview from '@/components/preview'
|
||||
import { createMetadata } from '@/utils/metadata'
|
||||
import { getPage, getPageUrl, getTree } from '@/utils/source'
|
||||
import { allDocs, type Docs } from 'contentlayer/generated'
|
||||
import { getPage, getPageUrl, getTree, pages } from '@/utils/source'
|
||||
import { ExternalLinkIcon } from 'lucide-react'
|
||||
import type { Metadata } from 'next'
|
||||
import type { Page } from 'next-docs-mdx/types'
|
||||
import { Card, Cards, MDXContent } from 'next-docs-ui/mdx'
|
||||
import { DocsPage } from 'next-docs-ui/page'
|
||||
import {
|
||||
findNeighbour,
|
||||
getGitLastEditTime,
|
||||
getTableOfContents
|
||||
} from 'next-docs-zeta/server'
|
||||
import { findNeighbour, getGitLastEditTime } from 'next-docs-zeta/server'
|
||||
import { notFound } from 'next/navigation'
|
||||
import { Content } from './content'
|
||||
|
||||
type Param = {
|
||||
mode: string
|
||||
@@ -21,14 +17,13 @@ type Param = {
|
||||
|
||||
export default async function Page({ params }: { params: Param }) {
|
||||
const tree = getTree(params.mode)
|
||||
const page = getPage([params.mode, ...(params.slug ?? [])])
|
||||
const page = getPage([params.mode, ...(params.slug ?? [])]) as Page
|
||||
|
||||
if (page == null) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
const toc = await getTableOfContents(page.body.raw)
|
||||
const url = getPageUrl(page.slug)
|
||||
const url = getPageUrl(page.slugs)
|
||||
const neighbours = findNeighbour(tree, url)
|
||||
|
||||
const headers = new Headers()
|
||||
@@ -37,24 +32,28 @@ export default async function Page({ params }: { params: Param }) {
|
||||
|
||||
const time = await getGitLastEditTime(
|
||||
'SonMooSans/next-docs',
|
||||
'apps/docs/content/' + page._raw.sourceFilePath,
|
||||
resolve('apps/docs/', page.file.path),
|
||||
undefined,
|
||||
{
|
||||
headers
|
||||
}
|
||||
)
|
||||
|
||||
const preview = page.preview?.trim()
|
||||
const preview = page.matter.preview?.trim()
|
||||
const MDX = page.data.default
|
||||
|
||||
return (
|
||||
<DocsPage
|
||||
toc={toc}
|
||||
toc={page.data.toc}
|
||||
footer={neighbours}
|
||||
lastUpdate={time}
|
||||
tableOfContent={{
|
||||
footer: (
|
||||
<a
|
||||
href={`https://github.com/fuma-nama/next-docs/blob/main/apps/docs/content/${page._raw.sourceFilePath}`}
|
||||
href={resolve(
|
||||
`https://github.com/fuma-nama/next-docs/blob/main/apps/docs/content`,
|
||||
page.file.path
|
||||
)}
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
className="text-xs inline-flex text-muted-foreground items-center hover:text-foreground"
|
||||
@@ -67,34 +66,33 @@ export default async function Page({ params }: { params: Param }) {
|
||||
<MDXContent>
|
||||
<div className="nd-not-prose mb-12">
|
||||
<h1 className="text-foreground mb-4 text-3xl font-semibold sm:text-4xl">
|
||||
{page.title}
|
||||
{page.matter.title}
|
||||
</h1>
|
||||
<p className="text-muted-foreground sm:text-lg">{page.description}</p>
|
||||
<p className="text-muted-foreground sm:text-lg">
|
||||
{page.matter.description}
|
||||
</p>
|
||||
</div>
|
||||
{preview != null && preview in Preview && Preview[preview]}
|
||||
{page.index ? (
|
||||
<Category page={page} />
|
||||
) : (
|
||||
<Content code={page.body.code} />
|
||||
)}
|
||||
{page.matter.index ? <Category page={page} /> : <MDX />}
|
||||
</MDXContent>
|
||||
</DocsPage>
|
||||
)
|
||||
}
|
||||
|
||||
function Category({ page }: { page: Docs }) {
|
||||
const pages = allDocs.filter(docs =>
|
||||
docs._raw.flattenedPath.startsWith(page._raw.flattenedPath + '/')
|
||||
function Category({ page }: { page: Page }) {
|
||||
const filtered = pages.filter(
|
||||
docs =>
|
||||
docs.file.dirname === page.file.dirname && docs.file.name !== 'index'
|
||||
)
|
||||
|
||||
return (
|
||||
<Cards>
|
||||
{pages.map(page => (
|
||||
{filtered.map(page => (
|
||||
<Card
|
||||
key={page._id}
|
||||
title={page.title}
|
||||
description={page.description ?? 'No Description'}
|
||||
href={getPageUrl(page.slug)}
|
||||
key={page.file.id}
|
||||
title={page.matter.title}
|
||||
description={page.matter.description ?? 'No Description'}
|
||||
href={getPageUrl(page.slugs)}
|
||||
/>
|
||||
))}
|
||||
</Cards>
|
||||
@@ -108,12 +106,11 @@ export function generateMetadata({ params }: { params: Param }): Metadata {
|
||||
if (page == null) return {}
|
||||
|
||||
const description =
|
||||
page.description ??
|
||||
'The headless ui library for building documentation websites'
|
||||
page.matter.description ?? 'The library for building documentation sites'
|
||||
|
||||
const imageParams = new URLSearchParams()
|
||||
imageParams.set('title', page.title)
|
||||
if (page.description) imageParams.set('description', page.description)
|
||||
imageParams.set('title', page.matter.title)
|
||||
imageParams.set('description', description)
|
||||
|
||||
const image = {
|
||||
alt: 'Banner',
|
||||
@@ -123,7 +120,7 @@ export function generateMetadata({ params }: { params: Param }): Metadata {
|
||||
}
|
||||
|
||||
return createMetadata({
|
||||
title: page.title,
|
||||
title: page.matter.title,
|
||||
description,
|
||||
openGraph: {
|
||||
url: `https://next-docs-zeta.vercel.app/docs/${slugs.join('/')}`,
|
||||
@@ -136,8 +133,8 @@ export function generateMetadata({ params }: { params: Param }): Metadata {
|
||||
}
|
||||
|
||||
export function generateStaticParams() {
|
||||
return allDocs.map(docs => {
|
||||
const [mode, ...slugs] = docs.slug.split('/')
|
||||
return pages.map(docs => {
|
||||
const [mode, ...slugs] = docs.slugs
|
||||
|
||||
return {
|
||||
slug: slugs,
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "default",
|
||||
"rsc": true,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.js",
|
||||
"css": "app/style.css",
|
||||
"baseColor": "slate",
|
||||
"cssVariables": true
|
||||
},
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/utils/cn"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { ThemeSwitch as Original } from './ThemeSwitch'
|
||||
|
||||
export const ThemeSwitch = (p => <Original {...p} />) as typeof Original
|
||||
+6
-3
@@ -3,8 +3,11 @@ title: Image Optimization
|
||||
description: Use Next.js image optimization in your MDX documents
|
||||
---
|
||||
|
||||
Next Docs UI uses the built-in `next/image` component. You can enjoy the
|
||||
benefits of Next.js Image Optimization without extra configurations.
|
||||
import Banner from '@/public/banner.png'
|
||||
|
||||
Next Docs Zeta supports the built-in `next/image` component by passing `width`
|
||||
and `height` property automatically. You can enjoy the benefits of Next.js Image
|
||||
Optimization without extra configurations.
|
||||
|
||||
Under the hood, It gets the image size using `rehype-img-size`, then display it
|
||||
via `next/image`.
|
||||
@@ -32,4 +35,4 @@ Assume the image is under the `/public` folder.
|
||||

|
||||
```
|
||||
|
||||

|
||||
<Image alt="Banner" src={Banner} />
|
||||
@@ -3,10 +3,10 @@ title: Quick Start
|
||||
description: Getting Started with Next Docs UI
|
||||
---
|
||||
|
||||
<Wrapper className="p-0 nd-not-prose">
|
||||
|
||||

|
||||
import Features from '@/public/features.png'
|
||||
|
||||
<Wrapper className="nd-not-prose p-0">
|
||||
<Image alt="Features" src={Features} />
|
||||
</Wrapper>
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -4,6 +4,7 @@ description: Add Theme to Next Docs UI
|
||||
---
|
||||
|
||||
import { blue_theme, full_layout } from '@/components/themes.js'
|
||||
import { ThemeSwitch } from '@/components/ThemeSwitch_server'
|
||||
|
||||
The design system is based on [Shadcn UI](https://ui.shadcn.com), allowing you
|
||||
to overwrite css variables.
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import { makeSource } from 'contentlayer/source-files'
|
||||
import { createConfig } from 'next-docs-zeta/contentlayer/configuration'
|
||||
import { remarkDynamicContent, structure } from 'next-docs-zeta/mdx-plugins'
|
||||
import rehypeKatex from 'rehype-katex'
|
||||
import remarkMath from 'remark-math'
|
||||
|
||||
const config = createConfig({
|
||||
docFields: {
|
||||
index: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
required: false
|
||||
},
|
||||
preview: {
|
||||
type: 'string',
|
||||
required: false
|
||||
}
|
||||
},
|
||||
docsComputedFields: {
|
||||
structuredData: {
|
||||
type: 'json',
|
||||
resolve: page => {
|
||||
return structure(page.body.raw, [remarkMath])
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
config.mdx!.remarkPlugins!.push(remarkMath)
|
||||
|
||||
config.mdx!.remarkPlugins!.push(remarkDynamicContent)
|
||||
config.mdx!.rehypePlugins!.push(rehypeKatex)
|
||||
export default makeSource(config)
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Wrapper } from '@/components/preview/wrapper'
|
||||
import type { MDXComponents } from 'mdx/types'
|
||||
import { Accordion, Accordions } from 'next-docs-ui/components/accordion'
|
||||
import { Callout } from 'next-docs-ui/components/callout'
|
||||
import { Tab, Tabs } from 'next-docs-ui/components/tabs'
|
||||
import { TypeTable } from 'next-docs-ui/components/type-table'
|
||||
import defaultComponents from 'next-docs-ui/mdx-server'
|
||||
|
||||
export function useMDXComponents(components: MDXComponents): MDXComponents {
|
||||
return {
|
||||
...defaultComponents,
|
||||
pre: props => (
|
||||
<defaultComponents.pre {...props} className="max-h-[400px]" />
|
||||
),
|
||||
Image: defaultComponents.img,
|
||||
Tabs: (p => <Tabs {...p} />) as typeof Tabs,
|
||||
Tab: (p => <Tab {...p} />) as typeof Tab,
|
||||
Callout: (p => <Callout {...p} />) as typeof Callout,
|
||||
TypeTable: (p => <TypeTable {...p} />) as typeof TypeTable,
|
||||
Accordion: (p => <Accordion {...p} />) as typeof Accordion,
|
||||
Accordions: (p => <Accordions {...p} />) as typeof Accordions,
|
||||
Wrapper,
|
||||
blockquote: props => <Callout className="my-4">{props.children}</Callout>,
|
||||
...components
|
||||
}
|
||||
}
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
import type * as Original from 'next-docs-mdx/types'
|
||||
|
||||
declare module 'next-docs-mdx/types' {
|
||||
interface Frontmatter extends Original.Frontmatter {
|
||||
preview?: string
|
||||
index?: boolean
|
||||
}
|
||||
|
||||
interface MDXExport extends Original.MDXExport {
|
||||
frontmatter: Frontmatter
|
||||
}
|
||||
|
||||
interface Page extends Original.Page {
|
||||
data: MDXExport
|
||||
matter: Frontmatter
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
const withAnalyzer = require('@next/bundle-analyzer')({
|
||||
enabled: process.env.ANALYZE === 'true'
|
||||
})
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const config = {
|
||||
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
|
||||
reactStrictMode: true,
|
||||
eslint: {
|
||||
// Replaced by root workspace command
|
||||
ignoreDuringBuilds: true
|
||||
}
|
||||
}
|
||||
|
||||
const { withContentlayer } = require('next-contentlayer')
|
||||
|
||||
module.exports = withAnalyzer(withContentlayer(config))
|
||||
@@ -0,0 +1,28 @@
|
||||
import createBundleAnalyzer from '@next/bundle-analyzer'
|
||||
import createNextDocs from 'next-docs-mdx/config'
|
||||
import { remarkDynamicContent } from 'next-docs-zeta/mdx-plugins'
|
||||
import rehypeKatex from 'rehype-katex'
|
||||
import remarkMath from 'remark-math'
|
||||
|
||||
const withAnalyzer = createBundleAnalyzer({
|
||||
enabled: process.env.ANALYZE === 'true'
|
||||
})
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const config = {
|
||||
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
|
||||
reactStrictMode: true,
|
||||
eslint: {
|
||||
// Replaced by root workspace command
|
||||
ignoreDuringBuilds: true
|
||||
}
|
||||
}
|
||||
|
||||
const withNextDocs = createNextDocs({
|
||||
options: {
|
||||
remarkPlugins: [remarkMath, remarkDynamicContent],
|
||||
rehypePlugins: [rehypeKatex]
|
||||
}
|
||||
})
|
||||
|
||||
export default withAnalyzer(withNextDocs(config))
|
||||
+10
-7
@@ -9,20 +9,20 @@
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-dialog": "^1.0.4",
|
||||
"@mdx-js/loader": "^2.3.0",
|
||||
"@mdx-js/react": "^2.3.0",
|
||||
"@next/mdx": "^13.5.6",
|
||||
"@next/env": "^13.5.6",
|
||||
"algoliasearch": "^4.20.0",
|
||||
"autoprefixer": "10.4.16",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"contentlayer": "^0.3.4",
|
||||
"katex": "^0.16.8",
|
||||
"lucide-react": "^0.288.0",
|
||||
"next": "13.5.6",
|
||||
"next-contentlayer": "^0.3.4",
|
||||
"next-docs-mdx": "workspace:*",
|
||||
"next-docs-ui": "workspace:*",
|
||||
"next-docs-zeta": "workspace:*",
|
||||
"next-sitemap": "^4.2.3",
|
||||
"postcss": "8.4.31",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"rehype-katex": "^6.0.3",
|
||||
@@ -31,11 +31,14 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/bundle-analyzer": "^13.4.19",
|
||||
"@types/mdx": "^2.0.8",
|
||||
"@types/node": "18.17.5",
|
||||
"@types/react": "18.2.0",
|
||||
"@types/react-dom": "18.2.1",
|
||||
"dotenv": "^16.3.1",
|
||||
"autoprefixer": "10.4.16",
|
||||
"postcss": "8.4.31",
|
||||
"tailwindcss": "3.3.3",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"webpack": "^5.89.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@ module.exports = {
|
||||
content: [
|
||||
'./components/**/*.{ts,tsx}',
|
||||
'./app/**/*.{ts,tsx}',
|
||||
'./content/**/*.mdx'
|
||||
'./content/**/*.mdx',
|
||||
'./mdx-components.tsx'
|
||||
],
|
||||
theme: {
|
||||
container: {
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"paths": {
|
||||
"@/*": ["./*"],
|
||||
"contentlayer/generated": ["./.contentlayer/generated"]
|
||||
"@/*": ["./*"]
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
@@ -27,10 +26,10 @@
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"mdx.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts",
|
||||
".contentlayer/generated"
|
||||
".next/types/**/*.ts"
|
||||
],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
+13
-24
@@ -1,10 +1,14 @@
|
||||
import path from 'path'
|
||||
import { readFileSync } from 'fs'
|
||||
import { resolve } from 'path'
|
||||
import env from '@next/env'
|
||||
import algosearch from 'algoliasearch'
|
||||
import { config } from 'dotenv'
|
||||
import { sync } from 'next-docs-zeta/search-algolia/server'
|
||||
import { allDocs } from './.contentlayer/generated/index.mjs'
|
||||
|
||||
config({ path: path.resolve(process.cwd(), '.env.local') })
|
||||
env.loadEnvConfig(process.cwd())
|
||||
|
||||
const indexes = JSON.parse(
|
||||
readFileSync(resolve('./.next/_map_indexes.json')).toString()
|
||||
)
|
||||
|
||||
const client = algosearch(
|
||||
process.env.ALGOLIA_APP_ID,
|
||||
@@ -12,30 +16,15 @@ const client = algosearch(
|
||||
)
|
||||
|
||||
sync(client, {
|
||||
documents: allDocs.map(docs => ({
|
||||
...docs,
|
||||
url: getPageUrl(['/docs', ...docs.slug.split('/')]),
|
||||
documents: indexes.map(docs => ({
|
||||
_id: docs.id,
|
||||
title: docs.title,
|
||||
url: docs.url,
|
||||
structured: docs.structuredData,
|
||||
extra_data: {
|
||||
tag: docs._raw.flattenedPath.startsWith('docs/ui') ? 'ui' : 'headless'
|
||||
tag: docs.url.startsWith('/docs/ui') ? 'ui' : 'headless'
|
||||
}
|
||||
}))
|
||||
}).then(() => {
|
||||
console.log('search updated')
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {Array<string>} slug
|
||||
* @returns {string}
|
||||
*/
|
||||
function getPageUrl(slug) {
|
||||
const url = slug
|
||||
.filter(segment => segment != null && segment.length > 0)
|
||||
.join('/')
|
||||
|
||||
if (url.startsWith('//')) {
|
||||
return url.slice(1)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
import { allDocs, allMeta } from 'contentlayer/generated'
|
||||
import { createUtils, loadContext } from 'next-docs-zeta/contentlayer'
|
||||
import { writeFileSync } from 'fs'
|
||||
import path from 'path'
|
||||
import { map } from '@/_map'
|
||||
import {
|
||||
createPageUtils,
|
||||
getPageTreeBuilder,
|
||||
resolveFiles
|
||||
} from 'next-docs-mdx/map'
|
||||
import type { PageTree } from 'next-docs-zeta/server'
|
||||
import { PHASE_PRODUCTION_BUILD } from 'next/constants'
|
||||
|
||||
const ctx = loadContext(allMeta, allDocs)
|
||||
const resolved = resolveFiles({ map, root: 'docs' })
|
||||
|
||||
const uiTree = ctx.builder.build({ root: 'docs/ui' })
|
||||
export const { getPage, getPageUrl } = createPageUtils(resolved, '/docs', [])
|
||||
|
||||
const headlessTree = ctx.builder.build({
|
||||
const builder = getPageTreeBuilder(resolved, { getUrl: getPageUrl })
|
||||
|
||||
const uiTree = builder.build({ root: 'docs/ui' })
|
||||
|
||||
const headlessTree = builder.build({
|
||||
root: 'docs/headless'
|
||||
})
|
||||
|
||||
@@ -18,4 +29,31 @@ export function getTree(mode: 'ui' | 'headless' | string): PageTree {
|
||||
return headlessTree
|
||||
}
|
||||
|
||||
export const { getPage, getPageUrl } = createUtils(ctx)
|
||||
export const { pages, metas } = resolved
|
||||
|
||||
// Access and export MDX pages data to json file
|
||||
// So that we can update search indexes after the build
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var __NEXT_DOCS_INDEX_UPDATED: boolean
|
||||
}
|
||||
|
||||
global.__NEXT_DOCS_INDEX_UPDATED = false
|
||||
|
||||
if (
|
||||
process.env.NEXT_PHASE === PHASE_PRODUCTION_BUILD &&
|
||||
!global.__NEXT_DOCS_INDEX_UPDATED
|
||||
) {
|
||||
const mapPath = path.resolve('./.next/_map_indexes.json')
|
||||
const indexes = pages.map(page => ({
|
||||
id: page.file.id,
|
||||
title: page.matter.title,
|
||||
description: page.matter.description,
|
||||
url: getPageUrl(page.slugs, page.file.locale),
|
||||
structuredData: page.data.structuredData
|
||||
}))
|
||||
|
||||
writeFileSync(mapPath, JSON.stringify(indexes))
|
||||
|
||||
global.__NEXT_DOCS_INDEX_UPDATED = true
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { allPages, getPageUrl } from '@/app/source'
|
||||
import { createSearchAPI, setResponse } from 'next-docs-zeta/search/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
setResponse(NextResponse)
|
||||
import { createSearchAPI } from 'next-docs-zeta/search/server'
|
||||
|
||||
export const { GET } = createSearchAPI('advanced', {
|
||||
indexes: allPages.map(page => ({
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import type { MDXComponents } from 'mdx/types'
|
||||
import defaultComponents, { default_image_sizes } from 'next-docs-ui/mdx-server'
|
||||
import NextImage from 'next/image'
|
||||
import defaultComponents from 'next-docs-ui/mdx-server'
|
||||
|
||||
export function useMDXComponents(components: MDXComponents): MDXComponents {
|
||||
return {
|
||||
...defaultComponents,
|
||||
Image: p => <NextImage sizes={default_image_sizes} {...p} />,
|
||||
Image: p => <defaultComponents.img {...p} />,
|
||||
...components
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,21 +42,23 @@
|
||||
"yaml": "^2.3.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@next/mdx": "13.x",
|
||||
"@mdx-js/loader": "2.x",
|
||||
"@mdx-js/react": "2.x",
|
||||
"@next/mdx": "13.x",
|
||||
"next-docs-zeta": "3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mdx-js/loader": "^2.3.0",
|
||||
"@mdx-js/react": "^2.3.0",
|
||||
"@mdx-js/mdx": "^2.3.0",
|
||||
"@next/mdx": "13.5.6",
|
||||
"@types/mdast": "^3.0.12",
|
||||
"@types/mdx": "^2.0.8",
|
||||
"@types/react": "18.2.0",
|
||||
"next": "13.5.6",
|
||||
"next-docs-zeta": "workspace:*",
|
||||
"unified": "^10.1.2",
|
||||
"@types/mdast": "^3.0.12",
|
||||
"@next/mdx": "13.5.6",
|
||||
"next-docs-zeta": "workspace:*"
|
||||
"webpack": "^5.89.0"
|
||||
},
|
||||
"keywords": [
|
||||
"NextJs",
|
||||
|
||||
@@ -3,9 +3,9 @@ import {
|
||||
type PageTreeBuilder
|
||||
} from 'next-docs-zeta/build-page-tree'
|
||||
import type { ReactElement } from 'react'
|
||||
import type { Meta, Page } from './types'
|
||||
import type { ResolvedFiles } from './resolve-files'
|
||||
|
||||
export type ContextOptions = {
|
||||
export type BuilderOptions = {
|
||||
/**
|
||||
* Get url from slugs and locale, override the default getUrl function
|
||||
*/
|
||||
@@ -15,9 +15,8 @@ export type ContextOptions = {
|
||||
}
|
||||
|
||||
export function getPageTreeBuilder(
|
||||
metas: Meta[],
|
||||
pages: Page[],
|
||||
{ getUrl, resolveIcon = () => undefined }: ContextOptions
|
||||
{ metas, pages }: ResolvedFiles,
|
||||
{ getUrl, resolveIcon = () => undefined }: BuilderOptions
|
||||
): PageTreeBuilder {
|
||||
return createPageTreeBuilder({
|
||||
metas: metas.map(meta => ({
|
||||
|
||||
@@ -14,6 +14,7 @@ import remarkFrontmatter, {
|
||||
type Options as RemarkFrontmatterOptions
|
||||
} from 'remark-frontmatter'
|
||||
import type { PluggableList } from 'unified'
|
||||
import type { Compiler } from 'webpack'
|
||||
import remarkMdxExport from './mdx-plugins/remark-exports'
|
||||
import remarkMdxFrontmatter from './mdx-plugins/remark-frontmatter'
|
||||
|
||||
@@ -35,6 +36,18 @@ type NextDocsMDXOptions = NextMDXOptions & {
|
||||
dataExports?: string[]
|
||||
}
|
||||
|
||||
function Plugin(compiler: Compiler) {
|
||||
compiler.hooks.beforeCompile.tap(PLUGIN_NAME, () => {
|
||||
if (firstLoad) {
|
||||
chokidar.watch('./content').on('all', () => {
|
||||
buildMap()
|
||||
})
|
||||
|
||||
firstLoad = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const createNextDocs =
|
||||
({
|
||||
loader = options => createNextMDX(options),
|
||||
@@ -73,18 +86,7 @@ const createNextDocs =
|
||||
|
||||
return Object.assign({}, nextConfig, {
|
||||
webpack: (config, options) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
config.plugins.push((compiler: any) => {
|
||||
compiler.hooks.initialize.tap(PLUGIN_NAME, () => {
|
||||
if (firstLoad) {
|
||||
chokidar.watch('./content').on('all', () => {
|
||||
buildMap()
|
||||
})
|
||||
|
||||
firstLoad = false
|
||||
}
|
||||
})
|
||||
})
|
||||
config.plugins.push(Plugin)
|
||||
|
||||
if (typeof nextConfig.webpack === 'function') {
|
||||
return nextConfig.webpack(config, options)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { PageTree } from 'next-docs-zeta/server'
|
||||
import { getPageTreeBuilder, type ContextOptions } from './build-tree'
|
||||
import { getPageTreeBuilder, type BuilderOptions } from './build-tree'
|
||||
import { createPageUtils, type PageUtils } from './page-utils'
|
||||
import { resolveFiles } from './resolve-files'
|
||||
import type { Meta, Page } from './types'
|
||||
@@ -17,7 +17,7 @@ type UtilsOptions<Langs extends string[] | undefined> = {
|
||||
* @default 'docs'
|
||||
*/
|
||||
root: string
|
||||
} & ContextOptions
|
||||
} & BuilderOptions
|
||||
|
||||
type Utils = PageUtils & {
|
||||
tree: PageTree
|
||||
@@ -39,21 +39,21 @@ function fromMap<Langs extends string[] | undefined = undefined>(
|
||||
languages
|
||||
}: Partial<UtilsOptions<Langs>> = {}
|
||||
): Langs extends string[] ? I18nUtils : Utils {
|
||||
const context = resolveFiles({
|
||||
const resolved = resolveFiles({
|
||||
map,
|
||||
root
|
||||
})
|
||||
|
||||
const pageUtils = createPageUtils(context, baseUrl, languages ?? [])
|
||||
const pageUtils = createPageUtils(resolved, baseUrl, languages ?? [])
|
||||
if (getUrl) pageUtils.getPageUrl = getUrl
|
||||
|
||||
const builder = getPageTreeBuilder(context.metas, context.pages, {
|
||||
const builder = getPageTreeBuilder(resolved, {
|
||||
getUrl: pageUtils.getPageUrl,
|
||||
resolveIcon
|
||||
})
|
||||
|
||||
return {
|
||||
...context,
|
||||
...resolved,
|
||||
...pageUtils,
|
||||
tree: (languages == null
|
||||
? builder.build({ root })
|
||||
@@ -62,4 +62,4 @@ function fromMap<Langs extends string[] | undefined = undefined>(
|
||||
}
|
||||
}
|
||||
|
||||
export { fromMap }
|
||||
export { fromMap, resolveFiles, createPageUtils, getPageTreeBuilder }
|
||||
|
||||
@@ -12,7 +12,8 @@ export type ResolvedFiles = {
|
||||
function parsePath(p: string, prefix = './content'): FileInfo {
|
||||
const subPath = path.relative(prefix, p)
|
||||
const parsed = path.parse(subPath)
|
||||
let flattenedPath = parsed.dir + '/' + parsed.name
|
||||
const normalizedDirname = parsed.dir.replaceAll('\\', '/')
|
||||
let flattenedPath = normalizedDirname + '/' + parsed.name
|
||||
|
||||
while (flattenedPath.startsWith('/')) {
|
||||
flattenedPath = flattenedPath.slice(1)
|
||||
@@ -22,7 +23,7 @@ function parsePath(p: string, prefix = './content'): FileInfo {
|
||||
|
||||
return {
|
||||
id: subPath,
|
||||
dirname: parsed.dir,
|
||||
dirname: normalizedDirname,
|
||||
base: parsed.base,
|
||||
name: parsed.name,
|
||||
flattenedPath,
|
||||
|
||||
@@ -64,12 +64,12 @@ export interface JsonExport {
|
||||
icon?: string
|
||||
}
|
||||
|
||||
export type Meta = {
|
||||
export interface Meta {
|
||||
file: FileInfo
|
||||
data: JsonExport
|
||||
}
|
||||
|
||||
export type Page = {
|
||||
export interface Page {
|
||||
file: FileInfo
|
||||
slugs: string[]
|
||||
data: MDXExport
|
||||
|
||||
@@ -7,16 +7,21 @@
|
||||
"repository": "github:fuma-nama/next-docs",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"dist/*"
|
||||
"dist/*",
|
||||
"server/*"
|
||||
],
|
||||
"exports": {
|
||||
"./style.css": "./dist/style.css",
|
||||
"./components/*": {
|
||||
"import": "./dist/components/*.mjs",
|
||||
"import": "./dist/components/*.js",
|
||||
"types": "./dist/components/*.d.ts"
|
||||
},
|
||||
"./mdx-server": {
|
||||
"import": "./server/mdx-server.js",
|
||||
"types": "./server/mdx-server/d.ts"
|
||||
},
|
||||
"./*": {
|
||||
"import": "./dist/*.mjs",
|
||||
"import": "./dist/*.js",
|
||||
"types": "./dist/*.d.ts"
|
||||
}
|
||||
},
|
||||
@@ -25,6 +30,9 @@
|
||||
"components/*": [
|
||||
"./dist/components/*.d.ts"
|
||||
],
|
||||
"mdx-server": [
|
||||
"./server/mdx-server.d.ts"
|
||||
],
|
||||
"*": [
|
||||
"./dist/*.d.ts"
|
||||
]
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import type { SafeLink } from 'next-docs-zeta/link'
|
||||
import type { HTMLAttributes } from 'react'
|
||||
import type { Card, Cards, Image, Pre, Table } from '../dist/mdx'
|
||||
|
||||
declare const default_image_sizes: string
|
||||
|
||||
declare const defaultMdxComponents: {
|
||||
Card: Card
|
||||
Cards: Cards
|
||||
h1: (p: HTMLAttributes<HTMLHeadingElement>) => JSX.Element
|
||||
h2: (p: HTMLAttributes<HTMLHeadingElement>) => JSX.Element
|
||||
h3: (p: HTMLAttributes<HTMLHeadingElement>) => JSX.Element
|
||||
h4: (p: HTMLAttributes<HTMLHeadingElement>) => JSX.Element
|
||||
h5: (p: HTMLAttributes<HTMLHeadingElement>) => JSX.Element
|
||||
h6: (p: HTMLAttributes<HTMLHeadingElement>) => JSX.Element
|
||||
img: Image
|
||||
a: SafeLink
|
||||
pre: Pre
|
||||
table: Table
|
||||
}
|
||||
|
||||
export { defaultMdxComponents as default, default_image_sizes }
|
||||
@@ -0,0 +1,28 @@
|
||||
import { jsx } from 'react/jsx-runtime'
|
||||
import {
|
||||
Card,
|
||||
Cards,
|
||||
default_image_sizes,
|
||||
Heading,
|
||||
Image,
|
||||
Link,
|
||||
Pre,
|
||||
Table
|
||||
} from '../dist/mdx'
|
||||
|
||||
const defaultMdxComponents = {
|
||||
Card: p => /* @__PURE__ */ jsx(Card, p),
|
||||
Cards: p => /* @__PURE__ */ jsx(Cards, p),
|
||||
h1: p => /* @__PURE__ */ jsx(Heading, { as: 'h1', ...p }),
|
||||
h2: p => /* @__PURE__ */ jsx(Heading, { as: 'h2', ...p }),
|
||||
h3: p => /* @__PURE__ */ jsx(Heading, { as: 'h3', ...p }),
|
||||
h4: p => /* @__PURE__ */ jsx(Heading, { as: 'h4', ...p }),
|
||||
h5: p => /* @__PURE__ */ jsx(Heading, { as: 'h5', ...p }),
|
||||
h6: p => /* @__PURE__ */ jsx(Heading, { as: 'h6', ...p }),
|
||||
img: p => /* @__PURE__ */ jsx(Image, p),
|
||||
a: p => /* @__PURE__ */ jsx(Link, p),
|
||||
pre: p => /* @__PURE__ */ jsx(Pre, p),
|
||||
table: p => /* @__PURE__ */ jsx(Table, p)
|
||||
}
|
||||
|
||||
export { defaultMdxComponents as default, default_image_sizes }
|
||||
@@ -12,18 +12,26 @@ export type ImageZoomProps = ImageProps & {
|
||||
zoomInProps?: ImgHTMLAttributes<HTMLImageElement>
|
||||
}
|
||||
|
||||
export function ImageZoom({ zoomInProps, ...props }: ImageZoomProps) {
|
||||
function getImageSrc(src: ImageProps['src']): string {
|
||||
return typeof src === 'string'
|
||||
? src
|
||||
: 'default' in src
|
||||
? src.default.src
|
||||
: src.src
|
||||
}
|
||||
|
||||
export function ImageZoom({ zoomInProps, children, ...props }: ImageZoomProps) {
|
||||
return (
|
||||
<Zoom
|
||||
zoomMargin={20}
|
||||
wrapElement="span"
|
||||
zoomImg={{
|
||||
src: props.src as string,
|
||||
src: getImageSrc(props.src),
|
||||
sizes: undefined,
|
||||
...zoomInProps
|
||||
}}
|
||||
>
|
||||
<Image sizes={default_image_sizes} {...props} />
|
||||
{children ?? <Image sizes={default_image_sizes} {...props} />}
|
||||
</Zoom>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ function SidebarToggle() {
|
||||
return (
|
||||
<SidebarTrigger
|
||||
aria-label="Toggle Sidebar"
|
||||
className={cn(itemVariants({ className: 'lg:nd-hidden' }))}
|
||||
className={cn(itemVariants({ className: 'md:nd-hidden' }))}
|
||||
>
|
||||
<MenuIcon />
|
||||
</SidebarTrigger>
|
||||
@@ -140,7 +140,7 @@ function DesktopSidebarToggle() {
|
||||
<button
|
||||
aria-label="Toggle Sidebar"
|
||||
onClick={() => setOpen(!open)}
|
||||
className={cn(itemVariants({ className: 'max-lg:nd-hidden' }))}
|
||||
className={cn(itemVariants({ className: 'max-md:nd-hidden' }))}
|
||||
>
|
||||
{open ? <SidebarCloseIcon /> : <SidebarOpenIcon />}
|
||||
</button>
|
||||
|
||||
@@ -40,18 +40,17 @@ export function Sidebar({ banner, footer }: SidebarProps) {
|
||||
|
||||
return (
|
||||
<Base.SidebarList
|
||||
minWidth={1024} // lg
|
||||
minWidth={768} // md
|
||||
className={cn(
|
||||
'nd-flex nd-flex-col nd-w-full',
|
||||
'nd-flex nd-flex-col nd-w-full nd-text-medium md:nd-text-sm md:nd-sticky md:nd-top-16 md:nd-h-body md:nd-transition-all',
|
||||
open
|
||||
? 'md:nd-w-[260px]'
|
||||
: 'md:nd-w-0 md:nd-overflow-hidden md:nd-opacity-0',
|
||||
'md:nd-sticky md:nd-top-16 md:nd-h-body md:nd-transition-[width,opacity]',
|
||||
'max-md:nd-fixed max-md:nd-inset-y-0 max-md:nd-right-0 max-md:nd-bg-background max-md:nd-z-40 max-md:nd-pt-16 max-md:data-[open=false]:nd-hidden sm:max-md:nd-max-w-sm sm:max-md:nd-border-l'
|
||||
)}
|
||||
>
|
||||
<ScrollArea className="nd-flex-1 md:nd-w-[260px]">
|
||||
<div className="nd-flex nd-flex-col nd-pb-10 nd-pt-4 nd-text-medium max-md:nd-px-6 md:nd-pr-4 md:nd-pt-12 md:nd-text-sm">
|
||||
<div className="nd-flex nd-flex-col nd-pb-10 nd-pt-4 md:nd-pr-4 md:nd-pt-12 max-md:nd-px-body">
|
||||
{banner}
|
||||
{tree.children.map((item, i) => (
|
||||
<Node key={i} item={item} level={1} />
|
||||
@@ -60,7 +59,7 @@ export function Sidebar({ banner, footer }: SidebarProps) {
|
||||
</ScrollArea>
|
||||
<div
|
||||
className={cn(
|
||||
'nd-flex nd-flex-row nd-items-center nd-gap-2 nd-border-t nd-py-2 max-md:nd-px-8',
|
||||
'nd-flex nd-flex-row nd-items-center nd-gap-2 nd-border-t nd-py-2 max-md:nd-px-body',
|
||||
!footer && 'md:nd-hidden'
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { type HTMLAttributes } from 'react'
|
||||
import {
|
||||
Card,
|
||||
Cards,
|
||||
default_image_sizes,
|
||||
Heading,
|
||||
Link,
|
||||
Pre,
|
||||
Table
|
||||
} from './mdx'
|
||||
|
||||
const defaultMdxComponents = {
|
||||
Card: (p => <Card {...p} />) as typeof Card,
|
||||
Cards: (p => <Cards {...p} />) as typeof Cards,
|
||||
h1: (p: HTMLAttributes<HTMLHeadingElement>) => <Heading as="h1" {...p} />,
|
||||
h2: (p: HTMLAttributes<HTMLHeadingElement>) => <Heading as="h2" {...p} />,
|
||||
h3: (p: HTMLAttributes<HTMLHeadingElement>) => <Heading as="h3" {...p} />,
|
||||
h4: (p: HTMLAttributes<HTMLHeadingElement>) => <Heading as="h4" {...p} />,
|
||||
h5: (p: HTMLAttributes<HTMLHeadingElement>) => <Heading as="h5" {...p} />,
|
||||
h6: (p: HTMLAttributes<HTMLHeadingElement>) => <Heading as="h6" {...p} />,
|
||||
a: (p => <Link {...p} />) as typeof Link,
|
||||
pre: (p => <Pre {...p} />) as typeof Pre,
|
||||
table: (p => <Table {...p} />) as typeof Table
|
||||
}
|
||||
|
||||
export { defaultMdxComponents as default, default_image_sizes }
|
||||
@@ -37,12 +37,15 @@ module.exports = {
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
padding: '1.5rem',
|
||||
padding: '1rem',
|
||||
screens: {
|
||||
'2xl': '1400px'
|
||||
}
|
||||
},
|
||||
extend: {
|
||||
padding: {
|
||||
body: '1rem'
|
||||
},
|
||||
fontSize: {
|
||||
medium: '15px'
|
||||
},
|
||||
|
||||
@@ -1,24 +1,15 @@
|
||||
import { defineConfig } from 'tsup'
|
||||
import tsconfig from './tsconfig.json'
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
entry: [
|
||||
'./src/components/{type-table,roll-button,image-zoom,files,tabs,accordion,steps,search,inline-toc,callout}.{ts,tsx}',
|
||||
'./src/components/dialog/{search,search-default,search-algolia}.tsx',
|
||||
'./src/{i18n,layout,mdx,nav,not-found,page,provider}.{ts,tsx}'
|
||||
],
|
||||
external: ['next-docs-zeta'],
|
||||
format: 'esm',
|
||||
dts: true,
|
||||
target: tsconfig.compilerOptions.target as 'es2016'
|
||||
},
|
||||
{
|
||||
entry: ['./src/mdx-server.tsx'],
|
||||
external: ['next-docs-zeta'],
|
||||
format: 'esm',
|
||||
bundle: false,
|
||||
dts: true,
|
||||
target: tsconfig.compilerOptions.target as 'es2016'
|
||||
}
|
||||
])
|
||||
export default defineConfig({
|
||||
entry: [
|
||||
'./src/components/{type-table,roll-button,image-zoom,files,tabs,accordion,steps,search,inline-toc,callout}.{ts,tsx}',
|
||||
'./src/components/dialog/{search,search-default,search-algolia}.tsx',
|
||||
'./src/{i18n,layout,mdx,nav,not-found,page,provider}.{ts,tsx}'
|
||||
],
|
||||
outExtension: () => ({ js: '.js' }),
|
||||
external: ['next-docs-zeta'],
|
||||
format: 'esm',
|
||||
dts: true,
|
||||
target: tsconfig.compilerOptions.target as 'es2016'
|
||||
})
|
||||
|
||||
@@ -26,9 +26,13 @@
|
||||
"import": "./dist/toc.mjs",
|
||||
"types": "./dist/toc.d.ts"
|
||||
},
|
||||
"./search/*": {
|
||||
"import": "./dist/search/*.mjs",
|
||||
"types": "./dist/search/*.d.ts"
|
||||
"./search/client": {
|
||||
"import": "./dist/search/client.mjs",
|
||||
"types": "./dist/search/client.d.ts"
|
||||
},
|
||||
"./search/server": {
|
||||
"import": "./dist/search/server.js",
|
||||
"types": "./dist/search/server.d.ts"
|
||||
},
|
||||
"./server": {
|
||||
"import": "./dist/server.mjs",
|
||||
@@ -47,16 +51,20 @@
|
||||
"types": "./dist/contentlayer/configuration.d.ts"
|
||||
},
|
||||
"./middleware": {
|
||||
"import": "./dist/middleware.mjs",
|
||||
"import": "./dist/middleware.js",
|
||||
"types": "./dist/middleware.d.ts"
|
||||
},
|
||||
"./mdx-plugins": {
|
||||
"import": "./dist/mdx-plugins.mjs",
|
||||
"types": "./dist/mdx-plugins.d.ts"
|
||||
},
|
||||
"./search-algolia/*": {
|
||||
"import": "./dist/search-algolia/*.mjs",
|
||||
"types": "./dist/search-algolia/*.d.ts"
|
||||
"./search-algolia/client": {
|
||||
"import": "./dist/search-algolia/client.mjs",
|
||||
"types": "./dist/search-algolia/client.d.ts"
|
||||
},
|
||||
"./search-algolia/server": {
|
||||
"import": "./dist/search-algolia/server.js",
|
||||
"types": "./dist/search-algolia/server.d.ts"
|
||||
}
|
||||
},
|
||||
"typesVersions": {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { randomUUID } from 'crypto'
|
||||
import { randomUUID } from 'node:crypto'
|
||||
import type { StructuredData } from '@/mdx-plugins/remark-structure'
|
||||
import type { SearchClient, SearchIndex } from 'algoliasearch'
|
||||
import type { BaseIndex } from './shared'
|
||||
|
||||
@@ -3,17 +3,6 @@ import FlexSearch from 'flexsearch'
|
||||
import { NextResponse, type NextRequest } from 'next/server'
|
||||
import type { SortedResult } from './shared'
|
||||
|
||||
let Response: typeof NextResponse = NextResponse
|
||||
|
||||
/**
|
||||
* In some circumstances, importing `NextResponse` in external packages can cause problems
|
||||
*
|
||||
* You can call `setResponse` to replace the one bundled by Next.js
|
||||
*/
|
||||
export function setResponse(_new: typeof NextResponse) {
|
||||
Response = _new
|
||||
}
|
||||
|
||||
type SearchAPI = {
|
||||
GET: (
|
||||
request: NextRequest
|
||||
@@ -78,7 +67,7 @@ export function createI18nSearchAPI<T extends 'simple' | 'advanced'>(
|
||||
return map.get(locale)!.GET(request)
|
||||
}
|
||||
|
||||
return Response.json([])
|
||||
return NextResponse.json([])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,7 +125,7 @@ export function initSearchAPI({ indexes, language }: SimpleOptions): SearchAPI {
|
||||
const { searchParams } = request.nextUrl
|
||||
const query = searchParams.get('query')
|
||||
|
||||
if (query == null) return Response.json([])
|
||||
if (query == null) return NextResponse.json([])
|
||||
|
||||
const results = index.search(query, 5, {
|
||||
enrich: true,
|
||||
@@ -150,7 +139,7 @@ export function initSearchAPI({ indexes, language }: SimpleOptions): SearchAPI {
|
||||
url: page.doc.url
|
||||
}))
|
||||
|
||||
return Response.json(pages ?? [])
|
||||
return NextResponse.json(pages ?? [])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,7 +232,7 @@ export function initSearchAPIAdvanced({
|
||||
const query = request.nextUrl.searchParams.get('query')
|
||||
const tag = request.nextUrl.searchParams.get('tag')
|
||||
|
||||
if (query == null) return Response.json([])
|
||||
if (query == null) return NextResponse.json([])
|
||||
|
||||
const results = index.search(query, 5, {
|
||||
enrich: true,
|
||||
@@ -251,7 +240,7 @@ export function initSearchAPIAdvanced({
|
||||
limit: 6
|
||||
})[0]
|
||||
|
||||
if (results == null) return Response.json([])
|
||||
if (results == null) return NextResponse.json([])
|
||||
|
||||
const map = new Map<string, SortedResult[]>()
|
||||
const sortedResult: SortedResult[] = []
|
||||
@@ -294,7 +283,7 @@ export function initSearchAPIAdvanced({
|
||||
sortedResult.push(...items)
|
||||
}
|
||||
|
||||
return Response.json(sortedResult)
|
||||
return NextResponse.json(sortedResult)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,31 @@
|
||||
import { defineConfig } from 'tsup'
|
||||
import tsconfig from './tsconfig.json'
|
||||
|
||||
export default defineConfig({
|
||||
entry: [
|
||||
'src/{toc,link,breadcrumb,sidebar}.tsx',
|
||||
'src/{middleware,server,mdx-plugins,build-page-tree}.ts',
|
||||
'src/{search,search-algolia}/{client,server,shared}.ts',
|
||||
'src/contentlayer/{index,configuration}.ts'
|
||||
],
|
||||
const shared = {
|
||||
external: [
|
||||
'@algolia/client-search',
|
||||
'algoliasearch',
|
||||
'contentlayer',
|
||||
'next',
|
||||
'unified'
|
||||
],
|
||||
format: 'esm',
|
||||
dts: true,
|
||||
target: tsconfig.compilerOptions.target as 'es2016'
|
||||
})
|
||||
}
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
...shared,
|
||||
entry: [
|
||||
'src/{toc,link,breadcrumb,sidebar}.tsx',
|
||||
'src/{server,mdx-plugins,build-page-tree}.ts',
|
||||
'src/{search,search-algolia}/{client,shared}.ts',
|
||||
'src/contentlayer/{index,configuration}.ts'
|
||||
]
|
||||
},
|
||||
{
|
||||
...shared,
|
||||
entry: ['src/{search,search-algolia}/server.ts', 'src/middleware.ts'],
|
||||
format: 'cjs'
|
||||
}
|
||||
])
|
||||
|
||||
Generated
+38
-28
@@ -56,24 +56,27 @@ importers:
|
||||
|
||||
apps/docs:
|
||||
dependencies:
|
||||
'@radix-ui/react-dialog':
|
||||
specifier: ^1.0.4
|
||||
version: 1.0.4(@types/[email protected])(@types/[email protected])([email protected])([email protected].0)
|
||||
'@mdx-js/loader':
|
||||
specifier: ^2.3.0
|
||||
version: 2.3.0([email protected].0)
|
||||
'@mdx-js/react':
|
||||
specifier: ^2.3.0
|
||||
version: 2.3.0([email protected])
|
||||
'@next/env':
|
||||
specifier: ^13.5.6
|
||||
version: 13.5.6
|
||||
'@next/mdx':
|
||||
specifier: ^13.5.6
|
||||
version: 13.5.6(@mdx-js/[email protected])(@mdx-js/[email protected])
|
||||
algoliasearch:
|
||||
specifier: ^4.20.0
|
||||
version: 4.20.0
|
||||
autoprefixer:
|
||||
specifier: 10.4.16
|
||||
version: 10.4.16([email protected])
|
||||
class-variance-authority:
|
||||
specifier: ^0.7.0
|
||||
version: 0.7.0
|
||||
clsx:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
contentlayer:
|
||||
specifier: ^0.3.4
|
||||
version: 0.3.4
|
||||
katex:
|
||||
specifier: ^0.16.8
|
||||
version: 0.16.8
|
||||
@@ -83,9 +86,9 @@ importers:
|
||||
next:
|
||||
specifier: 13.5.6
|
||||
version: 13.5.6(@babel/[email protected])([email protected])([email protected])
|
||||
next-contentlayer:
|
||||
specifier: ^0.3.4
|
||||
version: 0.3.4([email protected])([email protected])([email protected])([email protected])
|
||||
next-docs-mdx:
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/next-docs-mdx
|
||||
next-docs-ui:
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/next-docs-ui
|
||||
@@ -95,9 +98,6 @@ importers:
|
||||
next-sitemap:
|
||||
specifier: ^4.2.3
|
||||
version: 4.2.3([email protected])
|
||||
postcss:
|
||||
specifier: 8.4.31
|
||||
version: 8.4.31
|
||||
react:
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0
|
||||
@@ -117,6 +117,9 @@ importers:
|
||||
'@next/bundle-analyzer':
|
||||
specifier: ^13.4.19
|
||||
version: 13.4.19
|
||||
'@types/mdx':
|
||||
specifier: ^2.0.8
|
||||
version: 2.0.8
|
||||
'@types/node':
|
||||
specifier: 18.17.5
|
||||
version: 18.17.5
|
||||
@@ -126,15 +129,21 @@ importers:
|
||||
'@types/react-dom':
|
||||
specifier: 18.2.1
|
||||
version: 18.2.1
|
||||
dotenv:
|
||||
specifier: ^16.3.1
|
||||
version: 16.3.1
|
||||
autoprefixer:
|
||||
specifier: 10.4.16
|
||||
version: 10.4.16([email protected])
|
||||
postcss:
|
||||
specifier: 8.4.31
|
||||
version: 8.4.31
|
||||
tailwindcss:
|
||||
specifier: 3.3.3
|
||||
version: 3.3.3
|
||||
tailwindcss-animate:
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7([email protected])
|
||||
webpack:
|
||||
specifier: ^5.89.0
|
||||
version: 5.89.0
|
||||
|
||||
examples/advanced:
|
||||
dependencies:
|
||||
@@ -381,6 +390,9 @@ importers:
|
||||
'@mdx-js/loader':
|
||||
specifier: ^2.3.0
|
||||
version: 2.3.0([email protected])
|
||||
'@mdx-js/mdx':
|
||||
specifier: ^2.3.0
|
||||
version: 2.3.0
|
||||
'@mdx-js/react':
|
||||
specifier: ^2.3.0
|
||||
version: 2.3.0([email protected])
|
||||
@@ -405,6 +417,9 @@ importers:
|
||||
unified:
|
||||
specifier: ^10.1.2
|
||||
version: 10.1.2
|
||||
webpack:
|
||||
specifier: ^5.89.0
|
||||
version: 5.89.0
|
||||
|
||||
packages/next-docs-ui:
|
||||
dependencies:
|
||||
@@ -1626,10 +1641,6 @@ packages:
|
||||
- utf-8-validate
|
||||
dev: true
|
||||
|
||||
/@next/[email protected]:
|
||||
resolution: {integrity: sha512-FsAT5x0jF2kkhNkKkukhsyYOrRqtSxrEhfliniIq0bwWbuXLgyt3Gv0Ml+b91XwjwArmuP7NxCiGd++GGKdNMQ==}
|
||||
dev: false
|
||||
|
||||
/@next/[email protected]:
|
||||
resolution: {integrity: sha512-Yac/bV5sBGkkEXmAX5FWPS9Mmo2rthrOPRQQNfycJPkjUAUclomCPH7QFVCDQ4Mp2k2K1SSM6m0zrxYrOwtFQw==}
|
||||
|
||||
@@ -3607,6 +3618,7 @@ packages:
|
||||
picocolors: 1.0.0
|
||||
postcss: 8.4.31
|
||||
postcss-value-parser: 4.2.0
|
||||
dev: true
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
|
||||
@@ -4114,11 +4126,6 @@ packages:
|
||||
esutils: 2.0.3
|
||||
dev: true
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==}
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
|
||||
dev: true
|
||||
@@ -4643,6 +4650,7 @@ packages:
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-n2aZ9tNfYDwaHhvFTkhFErqOMIb8uyzSQ+vGJBjZyanAKZVbGUQ1sngfk9FdkBw7G26O7AgNjLcecLffD1c7eg==}
|
||||
dev: true
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==}
|
||||
@@ -6434,7 +6442,7 @@ packages:
|
||||
next: '*'
|
||||
dependencies:
|
||||
'@corex/deepmerge': 4.0.43
|
||||
'@next/env': 13.4.19
|
||||
'@next/env': 13.5.6
|
||||
fast-glob: 3.3.1
|
||||
minimist: 1.2.8
|
||||
next: 13.5.6(@babel/[email protected])([email protected])([email protected])
|
||||
@@ -6527,6 +6535,7 @@ packages:
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
|
||||
@@ -6922,6 +6931,7 @@ packages:
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
|
||||
dev: true
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"$schema": "https://turbo.build/schema.json",
|
||||
"pipeline": {
|
||||
"build": {
|
||||
"cache": false,
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": [
|
||||
".contentlayer/**",
|
||||
|
||||
Reference in New Issue
Block a user