mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 23:49:51 +00:00
Zeta: Export remark-toc and remark-structure MDX plugins
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'next-docs-zeta': minor
|
||||
---
|
||||
|
||||
Export remark-toc and remark-structure MDX plugins
|
||||
@@ -7,7 +7,7 @@ import type { NextConfig } from 'next'
|
||||
import {
|
||||
rehypeNextDocs,
|
||||
remarkGfm,
|
||||
remarkStructurize,
|
||||
remarkStructure,
|
||||
remarkToc
|
||||
} from 'next-docs-zeta/mdx-plugins'
|
||||
import remarkFrontmatter, {
|
||||
@@ -43,7 +43,7 @@ const createNextDocs =
|
||||
remarkGfm,
|
||||
[remarkFrontmatter, 'yaml' satisfies RemarkFrontmatterOptions],
|
||||
remarkMdxFrontmatter,
|
||||
remarkStructurize,
|
||||
remarkStructure,
|
||||
remarkToc,
|
||||
[remarkMdxExport, { values: dataExports }],
|
||||
...(pluginOptions.options?.remarkPlugins ?? [])
|
||||
|
||||
@@ -11,28 +11,28 @@
|
||||
],
|
||||
"exports": {
|
||||
"./sidebar": {
|
||||
"import": "./dist/sidebar/index.mjs",
|
||||
"types": "./dist/sidebar/index.d.ts"
|
||||
"import": "./dist/sidebar.mjs",
|
||||
"types": "./dist/sidebar.d.ts"
|
||||
},
|
||||
"./breadcrumb": {
|
||||
"import": "./dist/breadcrumb/index.mjs",
|
||||
"types": "./dist/breadcrumb/index.d.ts"
|
||||
"import": "./dist/breadcrumb.mjs",
|
||||
"types": "./dist/breadcrumb.d.ts"
|
||||
},
|
||||
"./toc": {
|
||||
"import": "./dist/toc/index.mjs",
|
||||
"types": "./dist/toc/index.d.ts"
|
||||
"import": "./dist/toc.mjs",
|
||||
"types": "./dist/toc.d.ts"
|
||||
},
|
||||
"./search/*": {
|
||||
"import": "./dist/search/*.mjs",
|
||||
"types": "./dist/search/*.d.ts"
|
||||
},
|
||||
"./server": {
|
||||
"import": "./dist/server/index.mjs",
|
||||
"types": "./dist/server/index.d.ts"
|
||||
"import": "./dist/server.mjs",
|
||||
"types": "./dist/server.d.ts"
|
||||
},
|
||||
"./link": {
|
||||
"import": "./dist/link/index.mjs",
|
||||
"types": "./dist/link/index.d.ts"
|
||||
"import": "./dist/link.mjs",
|
||||
"types": "./dist/link.d.ts"
|
||||
},
|
||||
"./contentlayer": {
|
||||
"import": "./dist/contentlayer/index.mjs",
|
||||
@@ -43,12 +43,12 @@
|
||||
"types": "./dist/contentlayer/configuration.d.ts"
|
||||
},
|
||||
"./middleware": {
|
||||
"import": "./dist/middleware/index.mjs",
|
||||
"types": "./dist/middleware/index.d.ts"
|
||||
"import": "./dist/middleware.mjs",
|
||||
"types": "./dist/middleware.d.ts"
|
||||
},
|
||||
"./mdx-plugins": {
|
||||
"import": "./dist/mdx-plugins/index.mjs",
|
||||
"types": "./dist/mdx-plugins/index.d.ts"
|
||||
"import": "./dist/mdx-plugins.mjs",
|
||||
"types": "./dist/mdx-plugins.d.ts"
|
||||
},
|
||||
"./search-algolia/*": {
|
||||
"import": "./dist/search-algolia/*.mjs",
|
||||
@@ -57,23 +57,8 @@
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"sidebar": [
|
||||
"./dist/sidebar/index.d.ts"
|
||||
],
|
||||
"breadcrumb": [
|
||||
"./dist/breadcrumb/index.d.ts"
|
||||
],
|
||||
"toc": [
|
||||
"./dist/toc/index.d.ts"
|
||||
],
|
||||
"search/*": [
|
||||
"./dist/search/*.d.ts"
|
||||
],
|
||||
"server": [
|
||||
"./dist/server/index.d.ts"
|
||||
],
|
||||
"link": [
|
||||
"./dist/link/index.d.ts"
|
||||
"*": [
|
||||
"./dist/*.d.ts"
|
||||
],
|
||||
"contentlayer": [
|
||||
"./dist/contentlayer/index.d.ts"
|
||||
@@ -81,11 +66,8 @@
|
||||
"contentlayer/configuration": [
|
||||
"./dist/contentlayer/configuration.d.ts"
|
||||
],
|
||||
"mdx-plugins": [
|
||||
"./dist/mdx-plugins/index.d.ts"
|
||||
],
|
||||
"middleware": [
|
||||
"./dist/middleware/index.d.ts"
|
||||
"search/*": [
|
||||
"./dist/search/*.d.ts"
|
||||
],
|
||||
"search-algolia/*": [
|
||||
"./dist/search-algolia/*.d.ts"
|
||||
|
||||
@@ -6,7 +6,7 @@ type Context = PagesContext & {
|
||||
lang?: string
|
||||
}
|
||||
|
||||
type Options = {
|
||||
export type Options = {
|
||||
/**
|
||||
* The root folder to scan files
|
||||
* @default 'docs'
|
||||
|
||||
@@ -11,7 +11,7 @@ import type { Args, ComputedFields, FieldDef } from 'contentlayer/source-files'
|
||||
import { defineDocumentType } from 'contentlayer/source-files'
|
||||
import type { Options as ImgSizeOptions } from 'rehype-img-size'
|
||||
|
||||
function removeSlash(path: string) {
|
||||
function removeSlash(path: string): string {
|
||||
let start = 0,
|
||||
end = path.length
|
||||
while (path.charAt(start) == '/') start++
|
||||
@@ -20,7 +20,7 @@ function removeSlash(path: string) {
|
||||
return path.slice(start, end)
|
||||
}
|
||||
|
||||
function removePattern(path: string, pattern: string) {
|
||||
function removePattern(path: string, pattern: string): string {
|
||||
if (path.endsWith('/index') || path === 'index') {
|
||||
path = path.slice(0, path.length - 'index'.length)
|
||||
}
|
||||
@@ -148,8 +148,8 @@ export function createConfig(options: Partial<Options> = {}): Args {
|
||||
rehypePlugins: [
|
||||
rehypeNextDocs,
|
||||
[
|
||||
/* eslint-disable */
|
||||
rehypeImgSize as any,
|
||||
// @ts-ignore
|
||||
rehypeImgSize,
|
||||
{
|
||||
dir: imgDirPath
|
||||
} as ImgSizeOptions
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import type { PageTree } from '@/server/types'
|
||||
import { buildI18nPageTree, buildPageTree } from './build-tree'
|
||||
import { loadContext, type ContextOptions } from './load-context'
|
||||
import type { DocsPageBase, MetaPageBase, PagesContext } from './types'
|
||||
import { createUtils } from './utils'
|
||||
import { createUtils, type ContentlayerUtils } from './utils'
|
||||
|
||||
type Options<L extends string[] | undefined> = Omit<
|
||||
Partial<ContextOptions>,
|
||||
@@ -20,10 +21,8 @@ type CreateContentlayer = <
|
||||
options?: Options<Langs>
|
||||
) => {
|
||||
__pageContext: PagesContext
|
||||
tree: Langs extends string[]
|
||||
? ReturnType<typeof buildI18nPageTree>
|
||||
: ReturnType<typeof buildPageTree>
|
||||
} & ReturnType<typeof createUtils<Docs>>
|
||||
tree: Langs extends string[] ? Record<Langs[number], PageTree> : PageTree
|
||||
} & ContentlayerUtils<Docs>
|
||||
|
||||
/**
|
||||
* Create page tree and utilities for Contentlayer
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export * from './load-context'
|
||||
export * from './build-tree'
|
||||
export { createUtils } from './utils'
|
||||
export { createUtils, ContentlayerUtils } from './utils'
|
||||
export { createContentlayer } from './create-contentlayer'
|
||||
|
||||
export type * from './types'
|
||||
|
||||
@@ -54,7 +54,7 @@ export function loadContext<
|
||||
function getI18nPages<Docs extends DocsPageBase>(
|
||||
docsMap: Map<string, Docs>,
|
||||
languages: string[]
|
||||
) {
|
||||
): Map<string, Docs[]> {
|
||||
const pages = new Map<string, Docs[]>()
|
||||
|
||||
pages.set('', [])
|
||||
|
||||
@@ -23,9 +23,7 @@ export function getPageUrl(slug: string[], baseUrl: string, locale?: string) {
|
||||
return url
|
||||
}
|
||||
|
||||
export function createUtils<Docs extends DocsPageBase>(
|
||||
context: PagesContext<MetaPageBase, Docs>
|
||||
): {
|
||||
export type ContentlayerUtils<Docs extends DocsPageBase> = {
|
||||
/**
|
||||
* Get list of pages from language
|
||||
*
|
||||
@@ -36,22 +34,28 @@ export function createUtils<Docs extends DocsPageBase>(
|
||||
/**
|
||||
* @param language If empty, the default language will be used
|
||||
*/
|
||||
getPage: (slugs?: string[], language?: string) => Docs | undefined
|
||||
getPage: (slugs: string[] | undefined, language?: string) => Docs | undefined
|
||||
|
||||
getPageUrl: (
|
||||
slugs: string | string[] | undefined,
|
||||
language?: string
|
||||
) => string
|
||||
} {
|
||||
}
|
||||
|
||||
export function createUtils<Docs extends DocsPageBase>(
|
||||
context: PagesContext<MetaPageBase, Docs>
|
||||
): ContentlayerUtils<Docs> {
|
||||
return {
|
||||
getPages: (language = '') => context.pages.get(language),
|
||||
getPage(slugs, language = '') {
|
||||
const path = (slugs ?? []).join('/')
|
||||
getPages(language = '') {
|
||||
return context.pages.get(language)
|
||||
},
|
||||
getPage(slugs = [], language = '') {
|
||||
const path = slugs.join('/')
|
||||
|
||||
return context.pages.get(language)?.find(page => page.slug === path)
|
||||
},
|
||||
getPageUrl(slug, language) {
|
||||
const slugs = typeof slug === 'string' ? slug.split('/') : slug ?? []
|
||||
getPageUrl(slug = [], language) {
|
||||
const slugs = typeof slug === 'string' ? slug.split('/') : slug
|
||||
|
||||
return context.getUrl(slugs, language)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
export {
|
||||
default as rehypeImgSize,
|
||||
Options as RehypeImgSizeOptions
|
||||
} from 'rehype-img-size'
|
||||
export { default as remarkGfm, Options as RemarkGfmOptions } from 'remark-gfm'
|
||||
export { rehypeNextDocs } from './mdx-plugins/rehype-next-docs'
|
||||
export {
|
||||
remarkDynamicContent,
|
||||
Options as RemarkDynamicContentOptions
|
||||
} from './mdx-plugins/remark-dynamic-content'
|
||||
export * from './mdx-plugins/remark-structure'
|
||||
export { remarkToc } from './mdx-plugins/remark-toc'
|
||||
@@ -1,6 +0,0 @@
|
||||
export { default as rehypeImgSize } from 'rehype-img-size'
|
||||
export { default as remarkGfm } from 'remark-gfm'
|
||||
export { rehypeNextDocs } from './rehype-next-docs'
|
||||
export { remarkDynamicContent } from './remark-dynamic-content'
|
||||
export * from './remark-structure'
|
||||
export * from './remark-toc'
|
||||
@@ -7,7 +7,7 @@ import { visit } from 'unist-util-visit'
|
||||
|
||||
const regex = /^\|reference:(.+)\|/
|
||||
|
||||
type Options = {
|
||||
export type Options = {
|
||||
/** @default process.cwd() */
|
||||
cwd?: string
|
||||
/** @default true */
|
||||
|
||||
@@ -41,7 +41,7 @@ const textTypes = ['text', 'inlineCode']
|
||||
/**
|
||||
* Attach structured data to VFile, you can access via `vfile.data.structuredData`.
|
||||
*/
|
||||
export function remarkStructurize({
|
||||
export function remarkStructure({
|
||||
types = ['paragraph', 'blockquote', 'heading']
|
||||
}: Options = {}): Transformer<Root, Root> {
|
||||
return (node, file) => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { SortedResult } from '@/search/shared'
|
||||
import type { Hit, SearchOptions } from '@algolia/client-search'
|
||||
import type { SearchIndex } from 'algoliasearch/lite'
|
||||
import { useState } from 'react'
|
||||
import useSWR from 'swr'
|
||||
import useSWR, { type SWRResponse } from 'swr'
|
||||
import type { BaseIndex } from './shared'
|
||||
|
||||
export function groupResults(hits: Hit<BaseIndex>[]): SortedResult[] {
|
||||
@@ -46,7 +46,20 @@ export async function searchDocs(
|
||||
return groupResults(result.hits)
|
||||
}
|
||||
|
||||
export function useAlgoliaSearch(index: SearchIndex, options?: SearchOptions) {
|
||||
type UseAlgoliaSearch = {
|
||||
search: string
|
||||
setSearch: (v: string) => void
|
||||
query: SWRResponse<
|
||||
SortedResult[] | 'empty',
|
||||
Error,
|
||||
{ keepPreviousData: true }
|
||||
>
|
||||
}
|
||||
|
||||
export function useAlgoliaSearch(
|
||||
index: SearchIndex,
|
||||
options?: SearchOptions
|
||||
): UseAlgoliaSearch {
|
||||
const [search, setSearch] = useState('')
|
||||
|
||||
const query = useSWR(
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
import { randomUUID } from 'crypto'
|
||||
import type { DocsPageBase } from '@/contentlayer/types'
|
||||
import type { StructuredData } from '@/mdx-plugins/remark-structure'
|
||||
import type { SearchClient, SearchIndex } from 'algoliasearch'
|
||||
import type { BaseIndex } from './shared'
|
||||
|
||||
type DocumentRecord = DocsPageBase & {
|
||||
type DocumentRecord = {
|
||||
/**
|
||||
* The ID of document, must be unique
|
||||
*/
|
||||
_id: string
|
||||
|
||||
title: string
|
||||
/**
|
||||
* URL to the page
|
||||
*/
|
||||
@@ -17,12 +22,11 @@ type DocumentRecord = DocsPageBase & {
|
||||
extra_data?: object
|
||||
}
|
||||
|
||||
type SyncOptions = { document?: string; documents: DocumentRecord[] }
|
||||
|
||||
export async function sync(
|
||||
client: SearchClient,
|
||||
{
|
||||
document = 'document',
|
||||
documents
|
||||
}: { document?: string; documents: DocumentRecord[] }
|
||||
{ document = 'document', documents }: SyncOptions
|
||||
) {
|
||||
const index = client.initIndex(document)
|
||||
await setIndexSettings(index)
|
||||
|
||||
@@ -1,11 +1,23 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import useSWR from 'swr'
|
||||
import useSWR, { type SWRResponse } from 'swr'
|
||||
import type { SortedResult } from './shared'
|
||||
|
||||
type UseDocsSearch<Result> = {
|
||||
search: string
|
||||
setSearch: (v: string) => void
|
||||
query: SWRResponse<
|
||||
Result,
|
||||
Error,
|
||||
{
|
||||
keepPreviousData: true
|
||||
}
|
||||
>
|
||||
}
|
||||
|
||||
export function useDocsSearch<Result = SortedResult[]>(
|
||||
locale?: string,
|
||||
tag?: string
|
||||
) {
|
||||
): UseDocsSearch<Result | 'empty'> {
|
||||
const [search, setSearch] = useState('')
|
||||
const debouncedValue = useDebounce(search, 100)
|
||||
|
||||
@@ -32,7 +44,7 @@ export function useDocsSearch<Result = SortedResult[]>(
|
||||
return { search, setSearch, query: searchQuery }
|
||||
}
|
||||
|
||||
function useDebounce<T>(value: T, delayMs: number = 1000) {
|
||||
function useDebounce<T>(value: T, delayMs: number = 1000): T {
|
||||
const [debouncedValue, setDebouncedValue] = useState(value)
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -43,13 +43,13 @@ type ToI18n<T extends { indexes: unknown }> = Omit<
|
||||
|
||||
export function createSearchAPI<T extends 'simple' | 'advanced'>(
|
||||
type: T,
|
||||
_options: T extends 'simple' ? SimpleOptions : AdvancedOptions
|
||||
options: T extends 'simple' ? SimpleOptions : AdvancedOptions
|
||||
): SearchAPI {
|
||||
if (type === 'simple') {
|
||||
return initSearchAPI(_options as SimpleOptions)
|
||||
return initSearchAPI(options as SimpleOptions)
|
||||
}
|
||||
|
||||
return initSearchAPIAdvanced(_options as AdvancedOptions)
|
||||
return initSearchAPIAdvanced(options as AdvancedOptions)
|
||||
}
|
||||
|
||||
export function createI18nSearchAPI<T extends 'simple' | 'advanced'>(
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export * from './server/get-toc'
|
||||
export * from './server/types'
|
||||
export { getTableOfContentsFromPortableText } from './server/get-toc-sanity'
|
||||
export * from './server/tree-utils'
|
||||
export * from './server/git-api'
|
||||
@@ -1,4 +1,4 @@
|
||||
import { remarkToc } from '@/mdx-plugins'
|
||||
import { remarkToc } from '@/mdx-plugins/remark-toc'
|
||||
import { remark } from 'remark'
|
||||
import type { TableOfContents } from './types'
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
export * from './get-toc'
|
||||
export * from './types'
|
||||
export * from './get-toc-sanity'
|
||||
export * from './tree-utils'
|
||||
export * from './git-api'
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
useRef
|
||||
} from 'react'
|
||||
import scrollIntoView from 'scroll-into-view-if-needed'
|
||||
import { useAnchorObserver } from './use-anchor-observer'
|
||||
import { useAnchorObserver } from './utils/use-anchor-observer'
|
||||
|
||||
const ActiveAnchorContext = createContext<{
|
||||
activeAnchor: string | undefined
|
||||
@@ -1,14 +1,15 @@
|
||||
import { defineConfig } from 'tsup'
|
||||
import packageJson from './package.json'
|
||||
import tsconfig from './tsconfig.json'
|
||||
|
||||
export default defineConfig({
|
||||
entry: [
|
||||
'src/{server,breadcrumb,sidebar,toc,link,contentlayer,middleware,mdx-plugins}/index.{ts,tsx}',
|
||||
'src/search/{client,server,shared}.ts',
|
||||
'src/search-algolia/{client,server,shared}.ts',
|
||||
'src/contentlayer/configuration.ts'
|
||||
'src/{toc,link,breadcrumb,sidebar}.tsx',
|
||||
'src/{middleware,server,mdx-plugins}.ts',
|
||||
'src/{search,search-algolia}/{client,server,shared}.ts',
|
||||
'src/contentlayer/{index,configuration}.ts'
|
||||
],
|
||||
external: ['@algolia/client-search', 'algoliasearch', 'contentlayer', 'next'],
|
||||
external: [...Object.keys(packageJson.devDependencies)],
|
||||
format: 'esm',
|
||||
dts: true,
|
||||
target: tsconfig.compilerOptions.target as 'es2016'
|
||||
|
||||
Reference in New Issue
Block a user