mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 23:49:51 +00:00
MDX: Make file paths relative to rootDir when resolving files
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
---
|
||||
'next-docs-mdx': major
|
||||
---
|
||||
|
||||
**Make file paths relative to `rootDir` when resolving files**
|
||||
|
||||
For a more simplified usage, the resolved file paths will be relative to `rootDir`.
|
||||
|
||||
You can now generate slugs automatically depending on the root directory you have configured.
|
||||
|
||||
```ts
|
||||
const utils = fromMap(map, {
|
||||
rootDir: 'ui',
|
||||
validate: {
|
||||
frontmatter: frontmatterSchema
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The configuration above will generate `/hello` slugs for a file named `/content/ui/hello.mdx`, while the previous one generates `/ui/hello`.
|
||||
@@ -2,7 +2,6 @@ import { writeFileSync } from 'fs'
|
||||
import path from 'path'
|
||||
import { map } from '@/_map'
|
||||
import { defaultValidators, fromMap, type Utils } from 'next-docs-mdx/map'
|
||||
import type { FileInfo } from 'next-docs-mdx/types'
|
||||
import type { StructuredData } from 'next-docs-zeta/mdx-plugins'
|
||||
import { PHASE_PRODUCTION_BUILD } from 'next/constants'
|
||||
import { z } from 'zod'
|
||||
@@ -12,17 +11,10 @@ const frontmatterSchema = defaultValidators.frontmatter.extend({
|
||||
index: z.boolean().default(false)
|
||||
})
|
||||
|
||||
const getSlugs = (file: FileInfo) =>
|
||||
file.flattenedPath
|
||||
.split('/')
|
||||
.filter(p => !['index', ''].includes(p))
|
||||
.slice(1)
|
||||
|
||||
export const tabs: Record<string, Utils> = {
|
||||
ui: fromMap(map, {
|
||||
rootDir: 'ui',
|
||||
baseUrl: '/docs/ui',
|
||||
getSlugs,
|
||||
validate: {
|
||||
frontmatter: frontmatterSchema
|
||||
}
|
||||
@@ -30,7 +22,6 @@ export const tabs: Record<string, Utils> = {
|
||||
headless: fromMap(map, {
|
||||
rootDir: 'headless',
|
||||
baseUrl: '/docs/headless',
|
||||
getSlugs,
|
||||
validate: {
|
||||
frontmatter: frontmatterSchema
|
||||
}
|
||||
@@ -38,7 +29,6 @@ export const tabs: Record<string, Utils> = {
|
||||
mdx: fromMap(map, {
|
||||
rootDir: 'mdx',
|
||||
baseUrl: '/docs/mdx',
|
||||
getSlugs,
|
||||
validate: {
|
||||
frontmatter: frontmatterSchema
|
||||
}
|
||||
|
||||
@@ -20,19 +20,9 @@ type UtilsOptions<Langs extends string[] | undefined> = {
|
||||
*/
|
||||
baseUrl: string
|
||||
|
||||
/**
|
||||
* Root directory, files outside of the root directory will be ignored
|
||||
*
|
||||
* @default ''
|
||||
*/
|
||||
rootDir: string
|
||||
|
||||
pageTreeOptions: BuildPageTreeOptions
|
||||
|
||||
getSlugs: ResolveOptions['getSlugs']
|
||||
getUrl?: ResolveOptions['getUrl']
|
||||
validate: ResolveOptions['validate']
|
||||
} & BuilderOptions
|
||||
} & BuilderOptions &
|
||||
Pick<ResolveOptions, 'getSlugs' | 'getUrl' | 'validate' | 'rootDir'>
|
||||
|
||||
export type Utils = PageUtils & {
|
||||
tree: PageTree
|
||||
@@ -52,7 +42,7 @@ function fromMap<Langs extends string[] | undefined = undefined>(
|
||||
getSlugs,
|
||||
getUrl = createGetUrl(baseUrl),
|
||||
resolveIcon,
|
||||
pageTreeOptions = { root: rootDir },
|
||||
pageTreeOptions = { root: '' },
|
||||
languages,
|
||||
validate
|
||||
}: Partial<UtilsOptions<Langs>> = {}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import path from 'path'
|
||||
import type { AnyZodObject } from 'zod'
|
||||
import type { FileInfo, MDXExport, Meta, Page } from './types'
|
||||
import {
|
||||
frontmatterSchema,
|
||||
metaSchema,
|
||||
type Frontmatter,
|
||||
type MetaExport
|
||||
} from './validate/schema'
|
||||
import path from 'path';
|
||||
import { joinPaths, splitPath } from 'next-docs-zeta/server';
|
||||
import type { AnyZodObject } from 'zod';
|
||||
import type { FileInfo, MDXExport, Meta, Page } from './types';
|
||||
import { frontmatterSchema, metaSchema, type Frontmatter, type MetaExport } from './validate/schema';
|
||||
|
||||
|
||||
const pageTypes = ['.md', '.mdx']
|
||||
const metaTypes = ['.json']
|
||||
@@ -20,7 +17,7 @@ export type ResolveOptions = {
|
||||
map: Record<string, unknown>
|
||||
|
||||
/**
|
||||
* root directory to resolve files
|
||||
* root directory to resolve files, all slugs will be relative to the root directory
|
||||
*
|
||||
* @default ''
|
||||
*/
|
||||
@@ -52,15 +49,13 @@ export const defaultValidators = {
|
||||
meta: metaSchema
|
||||
}
|
||||
|
||||
function parsePath(p: string): FileInfo {
|
||||
const parsed = path.parse(p)
|
||||
function parsePath(p: string, root: string = ''): FileInfo | false {
|
||||
if (!p.startsWith(root)) return false;
|
||||
const relativePath = splitPath(p.substring(root.length)).join('/')
|
||||
|
||||
const parsed = path.parse(relativePath)
|
||||
const normalizedDirname = parsed.dir.replaceAll('\\', '/')
|
||||
let flattenedPath = normalizedDirname + '/' + parsed.name
|
||||
|
||||
while (flattenedPath.startsWith('/')) {
|
||||
flattenedPath = flattenedPath.slice(1)
|
||||
}
|
||||
|
||||
const flattenedPath = joinPaths([normalizedDirname, parsed.name])
|
||||
const [, locale] = parsed.name.split('.')
|
||||
|
||||
return {
|
||||
@@ -71,7 +66,7 @@ function parsePath(p: string): FileInfo {
|
||||
flattenedPath,
|
||||
locale,
|
||||
type: parsed.ext,
|
||||
path: p
|
||||
path: relativePath
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,13 +95,8 @@ export function resolveFiles({
|
||||
const pages: Page[] = []
|
||||
|
||||
for (const [path, v] of Object.entries(map)) {
|
||||
const file = parsePath(path)
|
||||
if (
|
||||
rootDir.length > 0 &&
|
||||
file.dirname != rootDir &&
|
||||
!file.dirname.startsWith(rootDir + '/')
|
||||
)
|
||||
continue
|
||||
const file = parsePath(path, rootDir)
|
||||
if (file === false) continue
|
||||
|
||||
if (metaTypes.includes(file.type)) {
|
||||
const meta: Meta = {
|
||||
@@ -151,4 +141,4 @@ export function resolveFiles({
|
||||
pages,
|
||||
metas
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,6 @@ import type { StructuredData } from 'next-docs-zeta/mdx-plugins'
|
||||
import type { TableOfContents } from 'next-docs-zeta/server'
|
||||
import type * as Default from './validate/schema'
|
||||
|
||||
/**
|
||||
* The file info, relative to root content directory
|
||||
*/
|
||||
export type FileInfo = {
|
||||
locale?: string
|
||||
|
||||
@@ -30,17 +27,19 @@ export type FileInfo = {
|
||||
name: string
|
||||
|
||||
/**
|
||||
* Original path
|
||||
* Path relative to `rootDir`
|
||||
*/
|
||||
path: string
|
||||
|
||||
/**
|
||||
* A flatten path without extensions and prefixes, like `dir/file`
|
||||
*
|
||||
* relative to `rootDir`
|
||||
*/
|
||||
flattenedPath: string
|
||||
|
||||
/**
|
||||
* Unique ID for each file, based on `path`
|
||||
* Unique ID for each file, based on original path which is not relative to `rootDir`
|
||||
*/
|
||||
id: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user