mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 23:49:51 +00:00
MDX: Automatic fallback to Zod v3 when app has explicit v3 dependency
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-mdx': patch
|
||||
---
|
||||
|
||||
Automatic fallback to Zod v3 when app has explicit v3 dependency
|
||||
@@ -18,6 +18,11 @@
|
||||
"types": "./dist/config/index.d.ts",
|
||||
"require": "./dist/config/index.cjs"
|
||||
},
|
||||
"./config/zod-3": {
|
||||
"import": "./dist/config/zod-3.js",
|
||||
"types": "./dist/config/zod-3.d.ts",
|
||||
"require": "./dist/config/zod-3.cjs"
|
||||
},
|
||||
"./next": {
|
||||
"import": "./dist/next/index.js",
|
||||
"types": "./dist/next/index.d.ts",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { frontmatterSchema, metaSchema } from '@/utils/schema';
|
||||
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
||||
import type { DefaultMDXOptions } from '@/utils/mdx-options';
|
||||
import type { ProcessorOptions } from '@mdx-js/mdx';
|
||||
import { frontmatterSchema, metaSchema } from '@/config/zod-4';
|
||||
|
||||
export type CollectionSchema<Schema extends StandardSchemaV1, Context> =
|
||||
| Schema
|
||||
|
||||
@@ -3,5 +3,5 @@ export {
|
||||
getDefaultMDXOptions,
|
||||
type DefaultMDXOptions,
|
||||
} from '../utils/mdx-options';
|
||||
export { frontmatterSchema, metaSchema } from '../utils/schema';
|
||||
export * from './zod-4';
|
||||
export * from '../mdx-plugins/remark-include';
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// for backward compatibility
|
||||
// while Fumadocs expose Zod v4 schemas, some Zod v3 users use `.extend()` on schemas
|
||||
// we can expose v3 schema instead
|
||||
import { z } from 'zod/v3';
|
||||
|
||||
export const metaSchema = z.object({
|
||||
title: z.string().optional(),
|
||||
pages: z.array(z.string()).optional(),
|
||||
description: z.string().optional(),
|
||||
root: z.boolean().optional(),
|
||||
defaultOpen: z.boolean().optional(),
|
||||
icon: z.string().optional(),
|
||||
});
|
||||
|
||||
export const frontmatterSchema = z.object({
|
||||
title: z.string(),
|
||||
description: z.string().optional(),
|
||||
icon: z.string().optional(),
|
||||
full: z.boolean().optional(),
|
||||
|
||||
// Fumadocs OpenAPI generated
|
||||
_openapi: z.object({}).passthrough().optional(),
|
||||
});
|
||||
|
||||
export * from './define';
|
||||
export {
|
||||
getDefaultMDXOptions,
|
||||
type DefaultMDXOptions,
|
||||
} from '../utils/mdx-options';
|
||||
export * from '../mdx-plugins/remark-include';
|
||||
@@ -0,0 +1,20 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const metaSchema = z.object({
|
||||
title: z.string().optional(),
|
||||
pages: z.array(z.string()).optional(),
|
||||
description: z.string().optional(),
|
||||
root: z.boolean().optional(),
|
||||
defaultOpen: z.boolean().optional(),
|
||||
icon: z.string().optional(),
|
||||
});
|
||||
|
||||
export const frontmatterSchema = z.object({
|
||||
title: z.string(),
|
||||
description: z.string().optional(),
|
||||
icon: z.string().optional(),
|
||||
full: z.boolean().optional(),
|
||||
|
||||
// Fumadocs OpenAPI generated
|
||||
_openapi: z.looseObject({}).optional(),
|
||||
});
|
||||
@@ -4,7 +4,7 @@ import { type LoaderContext } from 'webpack';
|
||||
import { getConfigHash, loadConfig } from '@/utils/config';
|
||||
import { buildMDX } from '@/utils/build-mdx';
|
||||
import { getGitTimestamp } from './utils/git-timestamp';
|
||||
import { validate, ValidationError } from '@/utils/schema';
|
||||
import { validate, ValidationError } from '@/utils/validation';
|
||||
import { fumaMatter } from '@/utils/fuma-matter';
|
||||
import { countLines } from '@/utils/count-lines';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as fs from 'node:fs/promises';
|
||||
import { glob } from 'tinyglobby';
|
||||
import type { LoadedConfig } from '@/utils/config';
|
||||
import type { DocCollection, MetaCollection } from '@/config';
|
||||
import { validate } from '@/utils/schema';
|
||||
import { validate } from '@/utils/validation';
|
||||
import { fileCache } from '@/map/file-cache';
|
||||
import type { AsyncRuntimeFile, FileInfo } from '@/runtime/types';
|
||||
import { load } from 'js-yaml';
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as fs from 'node:fs/promises';
|
||||
import { getConfigHash, loadConfig } from '@/utils/config';
|
||||
import { generateJS } from '@/map/generate';
|
||||
import { fileCache } from '@/map/file-cache';
|
||||
import { ValidationError } from '@/utils/schema';
|
||||
import { ValidationError } from '@/utils/validation';
|
||||
|
||||
/**
|
||||
* Start a MDX server that builds index and manifest files.
|
||||
|
||||
@@ -9,6 +9,7 @@ import type {
|
||||
import type { ProcessorOptions } from '@mdx-js/mdx';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import { buildConfig } from '@/config/build';
|
||||
import type { Plugin } from 'esbuild';
|
||||
|
||||
export function findConfigFile(): string {
|
||||
return path.resolve('source.config.ts');
|
||||
@@ -27,6 +28,39 @@ let cache: {
|
||||
config: Promise<LoadedConfig>;
|
||||
} | null = null;
|
||||
|
||||
async function isZod3() {
|
||||
try {
|
||||
const content = JSON.parse(
|
||||
(await fs.readFile('node_modules/zod/package.json')).toString(),
|
||||
);
|
||||
const version = content.version;
|
||||
|
||||
return typeof version === 'string' && version.startsWith('3.');
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function createCompatZodPlugin(): Plugin {
|
||||
return {
|
||||
name: 'replace-zod-import',
|
||||
async setup(build) {
|
||||
const usingZod3 = await isZod3();
|
||||
if (!usingZod3) return;
|
||||
|
||||
console.warn(
|
||||
'[Fumadocs MDX] Noticed Zod v3 in your node_modules, we recommend upgrading to Zod v4 for better compatibility.',
|
||||
);
|
||||
build.onResolve({ filter: /^fumadocs-mdx\/config$/ }, () => {
|
||||
return {
|
||||
path: 'fumadocs-mdx/config/zod-3',
|
||||
external: true,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function compileConfig(configPath: string, outDir: string) {
|
||||
const { build } = await import('esbuild');
|
||||
|
||||
@@ -34,11 +68,12 @@ async function compileConfig(configPath: string, outDir: string) {
|
||||
entryPoints: [{ in: configPath, out: 'source.config' }],
|
||||
bundle: true,
|
||||
outdir: outDir,
|
||||
target: 'node18',
|
||||
target: 'node20',
|
||||
write: true,
|
||||
platform: 'node',
|
||||
format: 'esm',
|
||||
packages: 'external',
|
||||
plugins: [createCompatZodPlugin()],
|
||||
outExtension: {
|
||||
'.js': '.mjs',
|
||||
},
|
||||
|
||||
@@ -1,27 +1,7 @@
|
||||
import { z } from 'zod';
|
||||
import type { CollectionSchema } from '@/config';
|
||||
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
||||
import picocolors from 'picocolors';
|
||||
|
||||
export const metaSchema = z.object({
|
||||
title: z.string().optional(),
|
||||
pages: z.array(z.string()).optional(),
|
||||
description: z.string().optional(),
|
||||
root: z.boolean().optional(),
|
||||
defaultOpen: z.boolean().optional(),
|
||||
icon: z.string().optional(),
|
||||
});
|
||||
|
||||
export const frontmatterSchema = z.object({
|
||||
title: z.string(),
|
||||
description: z.string().optional(),
|
||||
icon: z.string().optional(),
|
||||
full: z.boolean().optional(),
|
||||
|
||||
// Fumadocs OpenAPI generated
|
||||
_openapi: z.looseObject({}).optional(),
|
||||
});
|
||||
|
||||
export class ValidationError extends Error {
|
||||
title: string;
|
||||
issues: readonly StandardSchemaV1.Issue[];
|
||||
@@ -4,7 +4,7 @@ import { buildMDX } from '@/utils/build-mdx';
|
||||
import { parse } from 'node:querystring';
|
||||
import { countLines } from '@/utils/count-lines';
|
||||
import { fumaMatter } from '@/utils/fuma-matter';
|
||||
import { validate, ValidationError } from '@/utils/schema';
|
||||
import { validate, ValidationError } from '@/utils/validation';
|
||||
import { z } from 'zod';
|
||||
import { ident, toImportPath } from '@/utils/import-formatter';
|
||||
import type { DocCollection, DocsCollection, MetaCollection } from '@/config';
|
||||
|
||||
@@ -4,6 +4,7 @@ export default defineConfig({
|
||||
entry: [
|
||||
'./src/{index,loader-mdx}.ts',
|
||||
'./src/{config,next,vite}/index.ts',
|
||||
'./src/config/zod-3.ts',
|
||||
'./src/runtime/{async,vite}.ts',
|
||||
],
|
||||
format: ['esm', 'cjs'],
|
||||
|
||||
Reference in New Issue
Block a user