mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
Local MD: support native JS + MDX
This commit is contained in:
@@ -17,6 +17,9 @@
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./dev": "./dist/dev/index.js",
|
||||
"./js/executor": "./dist/js/executor.js",
|
||||
"./js/executor-native": "./dist/js/executor-native.js",
|
||||
"./js/executor-virtual": "./dist/js/executor-virtual.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"publishConfig": {
|
||||
@@ -30,12 +33,12 @@
|
||||
"types:check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mdx-js/mdx": "^3.1.1",
|
||||
"@standard-schema/spec": "^1.1.0",
|
||||
"chokidar": "^5.0.0",
|
||||
"estree-util-to-js": "^2.0.0",
|
||||
"hast-util-to-jsx-runtime": "^2.3.6",
|
||||
"remark": "^15.0.1",
|
||||
"remark-mdx": "^3.1.1",
|
||||
"remark-rehype": "^11.1.2",
|
||||
"tinyglobby": "^0.2.16",
|
||||
"unified": "^11.0.5",
|
||||
@@ -45,7 +48,6 @@
|
||||
"@types/estree": "^1.0.8",
|
||||
"@types/estree-jsx": "^1.0.5",
|
||||
"@types/hast": "^3.0.4",
|
||||
"@types/mdx": "^2.0.13",
|
||||
"@types/node": "25.6.0",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
@@ -59,28 +61,30 @@
|
||||
"tsdown": "0.21.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/estree": "*",
|
||||
"@types/estree-jsx": "*",
|
||||
"@types/hast": "*",
|
||||
"@types/mdx": "*",
|
||||
"@types/react": "*",
|
||||
"@types/unist": "*",
|
||||
"fumadocs-core": "^16.7.17",
|
||||
"react": "^19.2.0"
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/estree": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/estree-jsx": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/hast": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/unist": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/mdx": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"inlinedDependencies": {
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { StandardSchemaV1 } from '@standard-schema/spec';
|
||||
import { createStorage } from './storage';
|
||||
import type * as defaultSchemas from 'fumadocs-core/source/schema';
|
||||
import { createMarkdownRenderer, MarkdownRendererOptions, PageRenderer } from './md/renderer';
|
||||
import { createMarkdownCompiler, MarkdownCompilerOptions } from './md/compiler-full';
|
||||
import { createMarkdownCompiler, MarkdownCompilerOptions } from './md/compiler';
|
||||
|
||||
export interface LocalMarkdownConfig<
|
||||
FrontmatterSchema extends StandardSchemaV1,
|
||||
|
||||
@@ -11,25 +11,23 @@ import type {
|
||||
JSXSpreadAttribute,
|
||||
JSXSpreadChild,
|
||||
JSXText,
|
||||
Pattern,
|
||||
Program,
|
||||
Statement,
|
||||
} from 'estree-jsx';
|
||||
import type { Handler, Handlers, State } from 'estree-util-to-js';
|
||||
import { toJs } from 'estree-util-to-js';
|
||||
import type * as JsxRuntime from 'react/jsx-runtime';
|
||||
import { JSExecutor } from './executor';
|
||||
import type { JSExecutor, JSExecutorConfig } from './executor';
|
||||
|
||||
const JSX_VAR_NAMES = {
|
||||
const INTERNAL_VAR_NAMES = {
|
||||
jsx: '__fumadocs_jsx',
|
||||
jsxs: '__fumadocs_jsxs',
|
||||
fragment: '__fumadocs_fragment',
|
||||
exports: '__fumadocs_exports',
|
||||
} as const;
|
||||
|
||||
type Generator = ThisParameterType<Handler>;
|
||||
|
||||
interface NativeExecutorOptions {
|
||||
jsx: typeof JsxRuntime;
|
||||
}
|
||||
|
||||
const jsxHandlers: Handlers = {
|
||||
JSXElement(node, state) {
|
||||
return writeJsxElement.call(this as Generator, node, state);
|
||||
@@ -39,52 +37,161 @@ const jsxHandlers: Handlers = {
|
||||
},
|
||||
};
|
||||
|
||||
export function executorNative(options?: NativeExecutorOptions): JSExecutor {
|
||||
const jsxContext = options?.jsx
|
||||
? {
|
||||
[JSX_VAR_NAMES.jsx]: options.jsx.jsx,
|
||||
[JSX_VAR_NAMES.jsxs]: options.jsx.jsxs,
|
||||
[JSX_VAR_NAMES.fragment]: options.jsx.Fragment,
|
||||
/**
|
||||
* Execute JavaScript with `new Function()`, this is unsafe.
|
||||
*/
|
||||
export function executorNative(options: JSExecutorConfig): JSExecutor {
|
||||
const { filePath, jsx } = options;
|
||||
const exports: Record<string, unknown> = {};
|
||||
const globalContext: Record<string, unknown> = {
|
||||
[INTERNAL_VAR_NAMES.exports]: exports,
|
||||
};
|
||||
|
||||
if (jsx) {
|
||||
Object.assign(globalContext, {
|
||||
[INTERNAL_VAR_NAMES.jsx]: jsx.jsx,
|
||||
[INTERNAL_VAR_NAMES.jsxs]: jsx.jsxs,
|
||||
[INTERNAL_VAR_NAMES.fragment]: jsx.Fragment,
|
||||
});
|
||||
}
|
||||
|
||||
function generateExportAssign(name: string, expression: Expression): ExpressionStatement {
|
||||
return {
|
||||
type: 'ExpressionStatement',
|
||||
expression: {
|
||||
type: 'AssignmentExpression',
|
||||
left: {
|
||||
type: 'MemberExpression',
|
||||
object: { type: 'Identifier', name: INTERNAL_VAR_NAMES.exports },
|
||||
property: { type: 'Identifier', name },
|
||||
computed: false,
|
||||
optional: false,
|
||||
},
|
||||
right: expression,
|
||||
operator: '=',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function allNames(pattern: Pattern): string[] {
|
||||
switch (pattern.type) {
|
||||
case 'Identifier':
|
||||
return [pattern.name];
|
||||
case 'ArrayPattern': {
|
||||
const out: string[] = [];
|
||||
for (const element of pattern.elements) {
|
||||
if (element) out.push(...allNames(element));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
: {};
|
||||
case 'AssignmentPattern':
|
||||
return allNames(pattern.left);
|
||||
case 'MemberExpression':
|
||||
return [];
|
||||
case 'ObjectPattern': {
|
||||
const out: string[] = [];
|
||||
for (const prop of pattern.properties) {
|
||||
if (prop.type === 'Property') {
|
||||
if ('value' in prop && typeof prop.value === 'string') out.push(prop.value);
|
||||
else if ('name' in prop && typeof prop.name === 'string') out.push(prop.name);
|
||||
} else {
|
||||
out.push(...allNames(prop.argument));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
case 'RestElement':
|
||||
return allNames(pattern.argument);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
expression(expression, context) {
|
||||
const code = serializeExpression(expression);
|
||||
return executeExpression(code, { ...context, ...jsxContext });
|
||||
const code = toJs(
|
||||
{
|
||||
type: 'Program',
|
||||
sourceType: 'module',
|
||||
body: [
|
||||
{
|
||||
type: 'ReturnStatement',
|
||||
argument: expression,
|
||||
},
|
||||
],
|
||||
},
|
||||
{ filePath, handlers: jsxHandlers },
|
||||
).value;
|
||||
return execute(code, { ...globalContext, ...context });
|
||||
},
|
||||
program(program, context) {
|
||||
const code = serializeProgram(program);
|
||||
return execute(code, { ...context, ...jsxContext });
|
||||
const cloned: Program = { ...program };
|
||||
cloned.body = cloned.body.flatMap((statement) => {
|
||||
if (statement.type === 'ExportAllDeclaration') {
|
||||
throw new Error(`${statement.type} is not supported`);
|
||||
}
|
||||
|
||||
if (statement.type === 'ExportDefaultDeclaration') {
|
||||
if (!statement.declaration) {
|
||||
throw new Error(`${statement.type} is not supported without an initializer`);
|
||||
}
|
||||
|
||||
let right: Expression;
|
||||
switch (statement.declaration.type) {
|
||||
case 'ClassDeclaration':
|
||||
right = {
|
||||
...statement.declaration,
|
||||
type: 'ClassExpression',
|
||||
};
|
||||
break;
|
||||
case 'FunctionDeclaration':
|
||||
right = {
|
||||
...statement.declaration,
|
||||
type: 'FunctionExpression',
|
||||
};
|
||||
break;
|
||||
default:
|
||||
right = statement.declaration;
|
||||
}
|
||||
return generateExportAssign('default', right);
|
||||
}
|
||||
|
||||
if (statement.type === 'ExportNamedDeclaration') {
|
||||
if (!statement.declaration) {
|
||||
throw new Error(`${statement.type} is not supported without an initializer`);
|
||||
}
|
||||
|
||||
switch (statement.declaration.type) {
|
||||
case 'ClassDeclaration':
|
||||
case 'FunctionDeclaration':
|
||||
return [
|
||||
statement.declaration,
|
||||
generateExportAssign(statement.declaration.id.name, statement.declaration.id),
|
||||
];
|
||||
case 'VariableDeclaration': {
|
||||
const out: Statement[] = [statement.declaration];
|
||||
for (const d of statement.declaration.declarations) {
|
||||
for (const name of allNames(d.id)) {
|
||||
out.push(generateExportAssign(name, { type: 'Identifier', name }));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return statement;
|
||||
});
|
||||
|
||||
return execute(toJs(cloned, { filePath, handlers: jsxHandlers }).value, {
|
||||
...globalContext,
|
||||
...context,
|
||||
});
|
||||
},
|
||||
getExports() {
|
||||
return {};
|
||||
return exports;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function serializeExpression(expression: Expression): string {
|
||||
const code = toJs(
|
||||
{
|
||||
type: 'Program',
|
||||
sourceType: 'module',
|
||||
body: [
|
||||
{
|
||||
type: 'ExpressionStatement',
|
||||
expression,
|
||||
} satisfies ExpressionStatement,
|
||||
],
|
||||
},
|
||||
{ handlers: jsxHandlers },
|
||||
).value;
|
||||
|
||||
return code.replace(/;\s*$/, '');
|
||||
}
|
||||
|
||||
function serializeProgram(program: Program): string {
|
||||
return toJs(program, { handlers: jsxHandlers }).value;
|
||||
}
|
||||
|
||||
function execute(code: string, context: Record<string, unknown>) {
|
||||
const argNames = Object.keys(context);
|
||||
const argValues = Object.values(context);
|
||||
@@ -92,15 +199,11 @@ function execute(code: string, context: Record<string, unknown>) {
|
||||
return evaluator(...argValues);
|
||||
}
|
||||
|
||||
function executeExpression(code: string, context: Record<string, unknown>) {
|
||||
return execute(`return (${code});`, context);
|
||||
}
|
||||
|
||||
function writeJsxElement(this: Generator, node: JSXElement, state: State) {
|
||||
const children = normalizeJsxChildren(node.children);
|
||||
const hasArrayChildren =
|
||||
children.length > 1 || children.some((child) => child.type === 'JSXSpreadChild');
|
||||
const runtime = hasArrayChildren ? JSX_VAR_NAMES.jsxs : JSX_VAR_NAMES.jsx;
|
||||
const runtime = hasArrayChildren ? INTERNAL_VAR_NAMES.jsxs : INTERNAL_VAR_NAMES.jsx;
|
||||
|
||||
state.write(`${runtime}(`, node);
|
||||
writeJsxType.call(this, node.openingElement.name, state);
|
||||
@@ -113,9 +216,9 @@ function writeJsxFragment(this: Generator, node: JSXFragment, state: State) {
|
||||
const children = normalizeJsxChildren(node.children);
|
||||
const hasArrayChildren =
|
||||
children.length > 1 || children.some((child) => child.type === 'JSXSpreadChild');
|
||||
const runtime = hasArrayChildren ? JSX_VAR_NAMES.jsxs : JSX_VAR_NAMES.jsx;
|
||||
const runtime = hasArrayChildren ? INTERNAL_VAR_NAMES.jsxs : INTERNAL_VAR_NAMES.jsx;
|
||||
|
||||
state.write(`${runtime}(${JSX_VAR_NAMES.fragment}, `, node);
|
||||
state.write(`${runtime}(${INTERNAL_VAR_NAMES.fragment}, `, node);
|
||||
writeJsxProps.call(this, [], children, state);
|
||||
state.write(')');
|
||||
}
|
||||
@@ -127,12 +230,7 @@ function writeJsxType(
|
||||
) {
|
||||
switch (node.type) {
|
||||
case 'JSXIdentifier':
|
||||
if (/^[a-z]/.test(node.name) || node.name.includes('-')) {
|
||||
state.write(JSON.stringify(node.name), node);
|
||||
return;
|
||||
}
|
||||
|
||||
state.write(node.name, node);
|
||||
state.write(JSON.stringify(node.name), node);
|
||||
return;
|
||||
|
||||
case 'JSXMemberExpression':
|
||||
@@ -210,11 +308,7 @@ function writeJsxProps(
|
||||
|
||||
function writeObjectKey(node: JSXAttribute['name'], state: State) {
|
||||
if (node.type === 'JSXIdentifier') {
|
||||
if (/^[A-Za-z_$][\w$]*$/.test(node.name)) {
|
||||
state.write(node.name, node);
|
||||
} else {
|
||||
state.write(JSON.stringify(node.name), node);
|
||||
}
|
||||
state.write(JSON.stringify(node.name), node);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { EvaluateOptions, ExpressionSync } from '@/eval-estree-expression';
|
||||
import { JSExecutor } from './executor';
|
||||
import { ExpressionSync } from '@/eval-estree-expression';
|
||||
import type { JSExecutor, JSExecutorConfig } from './executor';
|
||||
|
||||
/**
|
||||
* Execute JavaScript with a faked JS engine, limited features but works on workerd.
|
||||
*/
|
||||
export function executorVirtual(options?: EvaluateOptions): JSExecutor {
|
||||
export function executorVirtual(options: JSExecutorConfig): JSExecutor {
|
||||
const sync = new ExpressionSync(options);
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type * as JsxRuntime from 'react/jsx-runtime';
|
||||
import type { Expression, Program } from 'estree-jsx';
|
||||
|
||||
export interface JSExecutor {
|
||||
@@ -8,3 +9,8 @@ export interface JSExecutor {
|
||||
*/
|
||||
getExports: () => Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface JSExecutorConfig {
|
||||
jsx: typeof JsxRuntime;
|
||||
filePath: string;
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
import { remarkGfm } from 'fumadocs-core/mdx-plugins/remark-gfm';
|
||||
import { createBaseCompiler, BaseCompilerOptions, plugin, BaseCompiler, plugins } from './compiler';
|
||||
import { remarkHeading } from 'fumadocs-core/mdx-plugins/remark-heading';
|
||||
import { remarkNpm } from 'fumadocs-core/mdx-plugins/remark-npm';
|
||||
import { remarkCodeTab } from 'fumadocs-core/mdx-plugins/remark-code-tab';
|
||||
import { rehypeCode } from 'fumadocs-core/mdx-plugins/rehype-code';
|
||||
import { rehypeToc } from 'fumadocs-core/mdx-plugins/rehype-toc';
|
||||
import { remarkStructure } from 'fumadocs-core/mdx-plugins/remark-structure';
|
||||
import { VFile } from 'vfile';
|
||||
import remarkMdx from 'remark-mdx';
|
||||
|
||||
export type MarkdownCompilerOptions = BaseCompilerOptions;
|
||||
export type MarkdownCompiler = BaseCompiler;
|
||||
|
||||
export function createMarkdownCompiler(options?: MarkdownCompilerOptions): MarkdownCompiler {
|
||||
const compilers = new Map<'md' | 'mdx', BaseCompiler>();
|
||||
|
||||
function createCompiler(preset: 'md' | 'mdx') {
|
||||
return createBaseCompiler({
|
||||
...options,
|
||||
remarkPlugins: plugins(
|
||||
remarkGfm,
|
||||
preset === 'mdx' && remarkMdx,
|
||||
plugin(remarkHeading, { generateToc: false }),
|
||||
plugin(remarkNpm, { persist: { id: 'package-manager' } }),
|
||||
remarkCodeTab,
|
||||
remarkStructure,
|
||||
...(options?.remarkPlugins ?? []),
|
||||
),
|
||||
remarkRehypeOptions: {
|
||||
passThrough: ['mdxJsxFlowElement', 'mdxJsxTextElement'],
|
||||
...options?.remarkRehypeOptions,
|
||||
},
|
||||
rehypePlugins: [
|
||||
plugin(rehypeCode, { lazy: true, fallbackLanguage: 'text' }),
|
||||
plugin(rehypeToc, { exportToc: { as: 'data' } }),
|
||||
...(options?.rehypePlugins ?? []),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
compile(input) {
|
||||
const file = new VFile(input);
|
||||
const format = file.extname === '.mdx' ? 'mdx' : 'md';
|
||||
let compiler = compilers.get(format);
|
||||
if (!compiler) {
|
||||
compiler = createCompiler(format);
|
||||
compilers.set(format, compiler);
|
||||
}
|
||||
|
||||
return compiler.compile(file);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,55 +1,116 @@
|
||||
import { remark } from 'remark';
|
||||
import remarkRehype, { type Options as RemarkRehypeOptions } from 'remark-rehype';
|
||||
import { type Compatible, VFile } from 'vfile';
|
||||
import { remarkGfm } from 'fumadocs-core/mdx-plugins/remark-gfm';
|
||||
import { plugin, plugins } from './utils';
|
||||
import { remarkHeading } from 'fumadocs-core/mdx-plugins/remark-heading';
|
||||
import { remarkNpm } from 'fumadocs-core/mdx-plugins/remark-npm';
|
||||
import { remarkCodeTab } from 'fumadocs-core/mdx-plugins/remark-code-tab';
|
||||
import { rehypeCode } from 'fumadocs-core/mdx-plugins/rehype-code';
|
||||
import { rehypeToc } from 'fumadocs-core/mdx-plugins/rehype-toc';
|
||||
import { remarkStructure } from 'fumadocs-core/mdx-plugins/remark-structure';
|
||||
import { Compatible, VFile } from 'vfile';
|
||||
import type { Root } from 'hast';
|
||||
import type { Pluggable, PluggableList, Plugin } from 'unified';
|
||||
import * as Mdx from '@mdx-js/mdx';
|
||||
import { remark } from 'remark';
|
||||
import type { PluggableList } from 'unified';
|
||||
import remarkRehype, { type Options as RemarkRehypeOptions } from 'remark-rehype';
|
||||
|
||||
export interface BaseCompilerOptions {
|
||||
export interface MarkdownCompilerOptions {
|
||||
mdOptions?: MarkdownProcessorOptions;
|
||||
mdxOptions?: Mdx.ProcessorOptions;
|
||||
}
|
||||
|
||||
export interface MarkdownProcessorOptions {
|
||||
remarkPlugins?: PluggableList;
|
||||
rehypePlugins?: PluggableList;
|
||||
remarkRehypeOptions?: RemarkRehypeOptions;
|
||||
}
|
||||
|
||||
export interface CompileResult {
|
||||
tree: Root;
|
||||
file: VFile;
|
||||
}
|
||||
|
||||
export interface BaseCompiler {
|
||||
export interface MarkdownCompiler {
|
||||
compile: (input: Compatible) => Promise<CompileResult>;
|
||||
}
|
||||
|
||||
export function createBaseCompiler({
|
||||
rehypePlugins = [],
|
||||
remarkPlugins = [],
|
||||
remarkRehypeOptions,
|
||||
}: BaseCompilerOptions = {}): BaseCompiler {
|
||||
const processor = remark()
|
||||
.use(remarkPlugins)
|
||||
.use(remarkRehype, remarkRehypeOptions)
|
||||
.use(rehypePlugins);
|
||||
export type CompileResult =
|
||||
| {
|
||||
type: 'ast';
|
||||
tree: Root;
|
||||
file: VFile;
|
||||
}
|
||||
| {
|
||||
type: 'js';
|
||||
file: VFile;
|
||||
code: string;
|
||||
};
|
||||
|
||||
export function createMarkdownCompiler(options?: MarkdownCompilerOptions): MarkdownCompiler {
|
||||
let mdx: ReturnType<typeof createMdxCompiler> | undefined;
|
||||
let md: ReturnType<typeof createMdCompiler> | undefined;
|
||||
|
||||
function createMdCompiler() {
|
||||
const mdOptions = options?.mdOptions ?? {};
|
||||
return remark()
|
||||
.use(
|
||||
plugins(
|
||||
remarkGfm,
|
||||
plugin(remarkHeading, { generateToc: false }),
|
||||
plugin(remarkNpm, { persist: { id: 'package-manager' } }),
|
||||
remarkCodeTab,
|
||||
remarkStructure,
|
||||
...(mdOptions.remarkPlugins ?? []),
|
||||
),
|
||||
)
|
||||
.use(remarkRehype, {
|
||||
passThrough: ['mdxJsxFlowElement', 'mdxJsxTextElement'],
|
||||
...mdOptions.remarkRehypeOptions,
|
||||
})
|
||||
.use([
|
||||
plugin(rehypeCode, { lazy: true, fallbackLanguage: 'text' }),
|
||||
plugin(rehypeToc, { exportToc: { as: 'data' } }),
|
||||
...(mdOptions.rehypePlugins ?? []),
|
||||
]);
|
||||
}
|
||||
|
||||
function createMdxCompiler() {
|
||||
const mdxOptions = options?.mdxOptions ?? {};
|
||||
|
||||
return Mdx.createProcessor({
|
||||
...mdxOptions,
|
||||
outputFormat: 'function-body',
|
||||
development: false,
|
||||
remarkPlugins: plugins(
|
||||
remarkGfm,
|
||||
plugin(remarkHeading, { generateToc: false }),
|
||||
plugin(remarkNpm, { persist: { id: 'package-manager' } }),
|
||||
remarkCodeTab,
|
||||
remarkStructure,
|
||||
...(mdxOptions.remarkPlugins ?? []),
|
||||
),
|
||||
rehypePlugins: [
|
||||
plugin(rehypeCode, { lazy: true, fallbackLanguage: 'text' }),
|
||||
plugin(rehypeToc, { exportToc: { as: 'esm', name: 'toc' } }),
|
||||
...(mdxOptions.rehypePlugins ?? []),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
async compile(input) {
|
||||
// inherit vfile
|
||||
const file = input instanceof VFile ? input : new VFile(input);
|
||||
const tree = await processor.run(processor.parse(file), file);
|
||||
const file = new VFile(input);
|
||||
if (file.extname === '.mdx') {
|
||||
mdx ??= createMdxCompiler();
|
||||
const out = await mdx.process(file);
|
||||
return {
|
||||
type: 'js',
|
||||
file,
|
||||
code: String(out.value),
|
||||
};
|
||||
}
|
||||
|
||||
md ??= createMdCompiler();
|
||||
const tree = await md.run(md.parse(file), file);
|
||||
return {
|
||||
type: 'ast',
|
||||
tree,
|
||||
file,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function plugin<
|
||||
PluginParameters extends unknown[],
|
||||
Input extends string | import('unist').Node | undefined,
|
||||
Output,
|
||||
>(plugin: Plugin<PluginParameters, Input, Output>, ...params: NoInfer<PluginParameters>) {
|
||||
return [plugin, ...params] as Pluggable;
|
||||
}
|
||||
|
||||
export function plugins(...plugins: (Pluggable | false | null | undefined)[]): Pluggable[] {
|
||||
return plugins.filter((v) => v !== false && v != null);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
interface Options {
|
||||
scope?: Record<string, unknown>;
|
||||
baseUrl?: string | URL;
|
||||
jsxRuntime: object;
|
||||
}
|
||||
|
||||
const AsyncFunction: new (...args: string[]) => (...args: unknown[]) => Promise<unknown> =
|
||||
Object.getPrototypeOf(executeMdx).constructor;
|
||||
|
||||
/**
|
||||
* Note: unsafe by design
|
||||
*/
|
||||
export async function executeMdx(compiled: string, options: Options) {
|
||||
const { opts: scopeOpts, ...scope } = options.scope ?? {};
|
||||
const fullScope = {
|
||||
opts: {
|
||||
...(scopeOpts as object),
|
||||
...options.jsxRuntime,
|
||||
baseUrl: options.baseUrl,
|
||||
},
|
||||
...scope,
|
||||
};
|
||||
|
||||
const hydrateFn = new AsyncFunction(...Object.keys(fullScope), compiled);
|
||||
return await hydrateFn.apply(hydrateFn, Object.values(fullScope));
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { CompileResult, BaseCompiler } from './compiler';
|
||||
import type { TOCItemType } from 'fumadocs-core/toc';
|
||||
import type { StructuredData } from 'fumadocs-core/mdx-plugins';
|
||||
import type { ReactNode } from 'react';
|
||||
@@ -8,27 +7,39 @@ import * as JsxRuntime from 'react/jsx-runtime';
|
||||
import { type Components, toJsxRuntime } from 'hast-util-to-jsx-runtime';
|
||||
import { Root } from 'hast';
|
||||
import { VFile } from 'vfile';
|
||||
import type { JSExecutor } from '@/js/executor';
|
||||
import { executorVirtual } from '@/js/executor-virtual';
|
||||
import type { JSExecutor, JSExecutorConfig } from '@/js/executor';
|
||||
import type { CompileResult, MarkdownCompiler } from './compiler';
|
||||
import { executeMdx } from './execute-js';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
|
||||
export interface PageRenderer {
|
||||
structuredData: StructuredData;
|
||||
render: (components?: Components) => Promise<{
|
||||
exports: Record<string, unknown>;
|
||||
toc?: TOCItemType[];
|
||||
toc: TOCItemType[];
|
||||
body: ReactNode;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface MarkdownRendererOptions {
|
||||
executor?: (ctx: { jsx: typeof JsxRuntime }) => JSExecutor;
|
||||
/**
|
||||
* the engine to execute JavaScript (given estree with JSX)
|
||||
*
|
||||
* by default, it uses a virtual JS engine with limited
|
||||
*/
|
||||
executor?: (ctx: JSExecutorConfig) => JSExecutor | Promise<JSExecutor>;
|
||||
}
|
||||
|
||||
export function createMarkdownRenderer(
|
||||
compiler: BaseCompiler,
|
||||
compiler: MarkdownCompiler,
|
||||
options: MarkdownRendererOptions = {},
|
||||
) {
|
||||
const { executor: getExecutor = executorVirtual } = options;
|
||||
const {
|
||||
executor: getExecutor = async (config) => {
|
||||
const { executorVirtual } = await import('@/js/executor-virtual');
|
||||
return executorVirtual(config);
|
||||
},
|
||||
} = options;
|
||||
const cache = new Map<string, Promise<CompileResult>>();
|
||||
|
||||
function render(
|
||||
@@ -56,26 +67,16 @@ export function createMarkdownRenderer(
|
||||
});
|
||||
}
|
||||
|
||||
function getExports(
|
||||
tree: Root,
|
||||
sync: JSExecutor,
|
||||
context: Record<string, unknown>,
|
||||
): Record<string, unknown> {
|
||||
for (const node of tree.children) {
|
||||
if (node.type !== 'mdxjsEsm' || !node.data?.estree) continue;
|
||||
|
||||
sync.program(node.data.estree, context);
|
||||
}
|
||||
|
||||
return sync.getExports();
|
||||
}
|
||||
|
||||
return {
|
||||
async compile<V>(page: RawPage<V>): Promise<PageRenderer> {
|
||||
const cacheKey = stableHash({ path: page.absolutePath, value: page.content, compiler });
|
||||
const cacheKey = stableHash([page.absolutePath, page.content, page.frontmatter, compiler]);
|
||||
let promise = cache.get(cacheKey);
|
||||
if (!promise) {
|
||||
promise = compiler.compile({ path: page.absolutePath, value: page.content });
|
||||
promise = compiler.compile({
|
||||
path: page.absolutePath,
|
||||
value: page.content,
|
||||
data: { frontmatter: page.frontmatter },
|
||||
});
|
||||
cache.set(cacheKey, promise);
|
||||
}
|
||||
|
||||
@@ -91,30 +92,50 @@ export function createMarkdownRenderer(
|
||||
);
|
||||
},
|
||||
async render(components?: Components) {
|
||||
const executor = getExecutor({ jsx: JsxRuntime });
|
||||
const context: Record<string, unknown> = { ...components };
|
||||
const exports = getExports(compiled.tree, executor, context);
|
||||
const executor = await getExecutor({
|
||||
jsx: JsxRuntime,
|
||||
filePath: page.absolutePath,
|
||||
});
|
||||
|
||||
const toc = compiled.file.data.rehypeToc?.map(
|
||||
(item): TOCItemType => ({
|
||||
...item,
|
||||
title: render(
|
||||
{
|
||||
type: 'root',
|
||||
children: item.title.children,
|
||||
},
|
||||
compiled.file,
|
||||
executor,
|
||||
components,
|
||||
context,
|
||||
),
|
||||
}),
|
||||
);
|
||||
if (compiled.type === 'ast') {
|
||||
const context: Record<string, unknown> = { ...components };
|
||||
const toc =
|
||||
compiled.file.data.rehypeToc?.map(
|
||||
(item): TOCItemType => ({
|
||||
...item,
|
||||
title: render(
|
||||
{
|
||||
type: 'root',
|
||||
children: item.title.children,
|
||||
},
|
||||
compiled.file,
|
||||
executor,
|
||||
components,
|
||||
context,
|
||||
),
|
||||
}),
|
||||
) ?? [];
|
||||
|
||||
return {
|
||||
toc,
|
||||
body: render(compiled.tree, compiled.file, executor, components, context),
|
||||
exports: executor.getExports(),
|
||||
};
|
||||
}
|
||||
|
||||
const _out = await executeMdx(compiled.code, {
|
||||
baseUrl: pathToFileURL(page.absolutePath),
|
||||
jsxRuntime: JsxRuntime,
|
||||
});
|
||||
const out = _out as {
|
||||
toc: TOCItemType[];
|
||||
default: (props: { components?: Components }) => ReactNode;
|
||||
};
|
||||
|
||||
return {
|
||||
toc,
|
||||
body: render(compiled.tree, compiled.file, executor, components, context),
|
||||
exports,
|
||||
toc: out.toc,
|
||||
body: JsxRuntime.jsx(out.default, { components }),
|
||||
exports: out,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { Pluggable, Plugin } from 'unified';
|
||||
|
||||
export function plugin<
|
||||
PluginParameters extends unknown[],
|
||||
Input extends string | import('unist').Node | undefined,
|
||||
Output,
|
||||
>(plugin: Plugin<PluginParameters, Input, Output>, ...params: NoInfer<PluginParameters>) {
|
||||
return [plugin, ...params] as Pluggable;
|
||||
}
|
||||
|
||||
export function plugins(...plugins: (Pluggable | false | null | undefined)[]): Pluggable[] {
|
||||
return plugins.filter((v) => v !== false && v != null);
|
||||
}
|
||||
+2
-738
@@ -1,704 +1,11 @@
|
||||
{
|
||||
"tree": {
|
||||
"type": "root",
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"tagName": "h1",
|
||||
"properties": {
|
||||
"id": "mdx-expressions"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"value": "MDX expressions",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 3,
|
||||
"offset": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18,
|
||||
"offset": 17
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 1,
|
||||
"offset": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18,
|
||||
"offset": 17
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"value": "\n"
|
||||
},
|
||||
{
|
||||
"type": "mdxJsxFlowElement",
|
||||
"name": "div",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "mdxJsxAttribute",
|
||||
"name": "data-sum",
|
||||
"value": {
|
||||
"type": "mdxJsxAttributeValueExpression",
|
||||
"value": "1 + 2",
|
||||
"data": {
|
||||
"estree": {
|
||||
"type": "Program",
|
||||
"start": 34,
|
||||
"end": 39,
|
||||
"body": [
|
||||
{
|
||||
"type": "ExpressionStatement",
|
||||
"expression": {
|
||||
"type": "BinaryExpression",
|
||||
"start": 34,
|
||||
"end": 39,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 15,
|
||||
"offset": 34
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 20,
|
||||
"offset": 39
|
||||
}
|
||||
},
|
||||
"left": {
|
||||
"type": "Literal",
|
||||
"start": 34,
|
||||
"end": 35,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 15,
|
||||
"offset": 34
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 16,
|
||||
"offset": 35
|
||||
}
|
||||
},
|
||||
"value": 1,
|
||||
"raw": "1",
|
||||
"range": [
|
||||
34,
|
||||
35
|
||||
]
|
||||
},
|
||||
"operator": "+",
|
||||
"right": {
|
||||
"type": "Literal",
|
||||
"start": 38,
|
||||
"end": 39,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 19,
|
||||
"offset": 38
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 20,
|
||||
"offset": 39
|
||||
}
|
||||
},
|
||||
"value": 2,
|
||||
"raw": "2",
|
||||
"range": [
|
||||
38,
|
||||
39
|
||||
]
|
||||
},
|
||||
"range": [
|
||||
34,
|
||||
39
|
||||
]
|
||||
},
|
||||
"start": 34,
|
||||
"end": 39,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 15,
|
||||
"offset": 34
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 20,
|
||||
"offset": 39
|
||||
}
|
||||
},
|
||||
"range": [
|
||||
34,
|
||||
39
|
||||
]
|
||||
}
|
||||
],
|
||||
"sourceType": "module",
|
||||
"comments": [],
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 15,
|
||||
"offset": 34
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 20,
|
||||
"offset": 39
|
||||
}
|
||||
},
|
||||
"range": [
|
||||
34,
|
||||
39
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 6,
|
||||
"offset": 24
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 22,
|
||||
"offset": 40
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "mdxJsxAttribute",
|
||||
"name": "data-product",
|
||||
"value": {
|
||||
"type": "mdxJsxAttributeValueExpression",
|
||||
"value": "2 * 3",
|
||||
"data": {
|
||||
"estree": {
|
||||
"type": "Program",
|
||||
"start": 55,
|
||||
"end": 60,
|
||||
"body": [
|
||||
{
|
||||
"type": "ExpressionStatement",
|
||||
"expression": {
|
||||
"type": "BinaryExpression",
|
||||
"start": 55,
|
||||
"end": 60,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 36,
|
||||
"offset": 55
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 41,
|
||||
"offset": 60
|
||||
}
|
||||
},
|
||||
"left": {
|
||||
"type": "Literal",
|
||||
"start": 55,
|
||||
"end": 56,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 36,
|
||||
"offset": 55
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 37,
|
||||
"offset": 56
|
||||
}
|
||||
},
|
||||
"value": 2,
|
||||
"raw": "2",
|
||||
"range": [
|
||||
55,
|
||||
56
|
||||
]
|
||||
},
|
||||
"operator": "*",
|
||||
"right": {
|
||||
"type": "Literal",
|
||||
"start": 59,
|
||||
"end": 60,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 40,
|
||||
"offset": 59
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 41,
|
||||
"offset": 60
|
||||
}
|
||||
},
|
||||
"value": 3,
|
||||
"raw": "3",
|
||||
"range": [
|
||||
59,
|
||||
60
|
||||
]
|
||||
},
|
||||
"range": [
|
||||
55,
|
||||
60
|
||||
]
|
||||
},
|
||||
"start": 55,
|
||||
"end": 60,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 36,
|
||||
"offset": 55
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 41,
|
||||
"offset": 60
|
||||
}
|
||||
},
|
||||
"range": [
|
||||
55,
|
||||
60
|
||||
]
|
||||
}
|
||||
],
|
||||
"sourceType": "module",
|
||||
"comments": [],
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 36,
|
||||
"offset": 55
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 41,
|
||||
"offset": 60
|
||||
}
|
||||
},
|
||||
"range": [
|
||||
55,
|
||||
60
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 23,
|
||||
"offset": 41
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 43,
|
||||
"offset": 61
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "mdxJsxAttribute",
|
||||
"name": "id",
|
||||
"value": "sum-box",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 44,
|
||||
"offset": 62
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 56,
|
||||
"offset": 74
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 1,
|
||||
"offset": 19
|
||||
},
|
||||
"end": {
|
||||
"line": 5,
|
||||
"column": 7,
|
||||
"offset": 96
|
||||
}
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"tagName": "p",
|
||||
"properties": {},
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"value": "Static body",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 4,
|
||||
"column": 3,
|
||||
"offset": 78
|
||||
},
|
||||
"end": {
|
||||
"line": 4,
|
||||
"column": 14,
|
||||
"offset": 89
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 4,
|
||||
"column": 3,
|
||||
"offset": 78
|
||||
},
|
||||
"end": {
|
||||
"line": 4,
|
||||
"column": 14,
|
||||
"offset": 89
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"value": "\n"
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"tagName": "p",
|
||||
"properties": {},
|
||||
"children": [
|
||||
{
|
||||
"type": "mdxJsxTextElement",
|
||||
"name": "abbr",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "mdxJsxAttribute",
|
||||
"name": "title",
|
||||
"value": {
|
||||
"type": "mdxJsxAttributeValueExpression",
|
||||
"value": "['a', 'b'].join('-')",
|
||||
"data": {
|
||||
"estree": {
|
||||
"type": "Program",
|
||||
"start": 111,
|
||||
"end": 131,
|
||||
"body": [
|
||||
{
|
||||
"type": "ExpressionStatement",
|
||||
"expression": {
|
||||
"type": "CallExpression",
|
||||
"start": 111,
|
||||
"end": 131,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 13,
|
||||
"offset": 111
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 33,
|
||||
"offset": 131
|
||||
}
|
||||
},
|
||||
"callee": {
|
||||
"type": "MemberExpression",
|
||||
"start": 111,
|
||||
"end": 126,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 13,
|
||||
"offset": 111
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 28,
|
||||
"offset": 126
|
||||
}
|
||||
},
|
||||
"object": {
|
||||
"type": "ArrayExpression",
|
||||
"start": 111,
|
||||
"end": 121,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 13,
|
||||
"offset": 111
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 23,
|
||||
"offset": 121
|
||||
}
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"type": "Literal",
|
||||
"start": 112,
|
||||
"end": 115,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 14,
|
||||
"offset": 112
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 17,
|
||||
"offset": 115
|
||||
}
|
||||
},
|
||||
"value": "a",
|
||||
"raw": "'a'",
|
||||
"range": [
|
||||
112,
|
||||
115
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Literal",
|
||||
"start": 117,
|
||||
"end": 120,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 19,
|
||||
"offset": 117
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 22,
|
||||
"offset": 120
|
||||
}
|
||||
},
|
||||
"value": "b",
|
||||
"raw": "'b'",
|
||||
"range": [
|
||||
117,
|
||||
120
|
||||
]
|
||||
}
|
||||
],
|
||||
"range": [
|
||||
111,
|
||||
121
|
||||
]
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"start": 122,
|
||||
"end": 126,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 24,
|
||||
"offset": 122
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 28,
|
||||
"offset": 126
|
||||
}
|
||||
},
|
||||
"name": "join",
|
||||
"range": [
|
||||
122,
|
||||
126
|
||||
]
|
||||
},
|
||||
"computed": false,
|
||||
"optional": false,
|
||||
"range": [
|
||||
111,
|
||||
126
|
||||
]
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Literal",
|
||||
"start": 127,
|
||||
"end": 130,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 29,
|
||||
"offset": 127
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 32,
|
||||
"offset": 130
|
||||
}
|
||||
},
|
||||
"value": "-",
|
||||
"raw": "'-'",
|
||||
"range": [
|
||||
127,
|
||||
130
|
||||
]
|
||||
}
|
||||
],
|
||||
"optional": false,
|
||||
"range": [
|
||||
111,
|
||||
131
|
||||
]
|
||||
},
|
||||
"start": 111,
|
||||
"end": 131,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 13,
|
||||
"offset": 111
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 33,
|
||||
"offset": 131
|
||||
}
|
||||
},
|
||||
"range": [
|
||||
111,
|
||||
131
|
||||
]
|
||||
}
|
||||
],
|
||||
"sourceType": "module",
|
||||
"comments": [],
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 13,
|
||||
"offset": 111
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 33,
|
||||
"offset": 131
|
||||
}
|
||||
},
|
||||
"range": [
|
||||
111,
|
||||
131
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 7,
|
||||
"offset": 104
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 35,
|
||||
"offset": 132
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 1,
|
||||
"offset": 98
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 49,
|
||||
"offset": 146
|
||||
}
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"value": "Joined",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 36,
|
||||
"offset": 133
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 42,
|
||||
"offset": 139
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 1,
|
||||
"offset": 98
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 49,
|
||||
"offset": 146
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 1,
|
||||
"offset": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 8,
|
||||
"column": 1,
|
||||
"offset": 147
|
||||
}
|
||||
}
|
||||
},
|
||||
"code": "\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nlet toc = [{\n depth: 1,\n url: \"#mdx-expressions\",\n title: _jsx(_Fragment, {\n children: \"MDX expressions\"\n })\n}];\nfunction _createMdxContent(props) {\n const _components = {\n h1: \"h1\",\n p: \"p\",\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsx(_components.h1, {\n id: \"mdx-expressions\",\n children: \"MDX expressions\"\n }), \"\\n\", _jsx(\"div\", {\n \"data-sum\": 1 + 2,\n \"data-product\": 2 * 3,\n id: \"sum-box\",\n children: _jsx(_components.p, {\n children: \"Static body\"\n })\n }), \"\\n\", _jsx(\"abbr\", {\n title: ['a', 'b'].join('-'),\n children: \"Joined\"\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = props.components || ({});\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n toc,\n default: MDXContent\n};\n",
|
||||
"data": {
|
||||
"structuredData": {
|
||||
"contents": [
|
||||
{
|
||||
"heading": "mdx-expressions",
|
||||
"content": "Static body"
|
||||
},
|
||||
{
|
||||
"heading": "mdx-expressions",
|
||||
"content": "Joined"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
@@ -707,49 +14,6 @@
|
||||
"content": "MDX expressions"
|
||||
}
|
||||
]
|
||||
},
|
||||
"rehypeToc": [
|
||||
{
|
||||
"title": {
|
||||
"type": "element",
|
||||
"tagName": "h1",
|
||||
"properties": {
|
||||
"id": "mdx-expressions"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"value": "MDX expressions",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 3,
|
||||
"offset": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18,
|
||||
"offset": 17
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 1,
|
||||
"offset": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18,
|
||||
"offset": 17
|
||||
}
|
||||
}
|
||||
},
|
||||
"depth": 1,
|
||||
"url": "#mdx-expressions"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,6 @@
|
||||
{
|
||||
"heading": "mdx-expressions",
|
||||
"content": "Static body"
|
||||
},
|
||||
{
|
||||
"heading": "mdx-expressions",
|
||||
"content": "Joined"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
@@ -17,7 +13,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"bodyHtml": "<h1 id=\"mdx-expressions\">MDX expressions</h1>\n<div data-sum=\"3\" data-product=\"6\" id=\"sum-box\"><p>Static body</p></div>\n<p><abbr title=\"a-b\">Joined</abbr></p>",
|
||||
"bodyHtml": "<h1 id=\"mdx-expressions\">MDX expressions</h1>\n<div data-sum=\"3\" data-product=\"6\" id=\"sum-box\"><p>Static body</p></div>\n<abbr title=\"a-b\">Joined</abbr>",
|
||||
"toc": [
|
||||
{
|
||||
"url": "#mdx-expressions",
|
||||
|
||||
+3
-308
@@ -1,319 +1,14 @@
|
||||
{
|
||||
"tree": {
|
||||
"type": "root",
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"tagName": "h1",
|
||||
"properties": {
|
||||
"id": "jsx-expressions"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"value": "JSX expressions",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 3,
|
||||
"offset": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18,
|
||||
"offset": 17
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 1,
|
||||
"offset": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18,
|
||||
"offset": 17
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"value": "\n"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"value": "export const ignored = <span>Ignored export</span>",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 1,
|
||||
"offset": 19
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 51,
|
||||
"offset": 69
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"value": "\n"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"value": "<div id=\"native-jsx\">Native JSX child</div>",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 5,
|
||||
"column": 1,
|
||||
"offset": 71
|
||||
},
|
||||
"end": {
|
||||
"line": 5,
|
||||
"column": 46,
|
||||
"offset": 116
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"value": "\n"
|
||||
},
|
||||
{
|
||||
"type": "mdxJsxFlowElement",
|
||||
"name": null,
|
||||
"attributes": [],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 1,
|
||||
"offset": 118
|
||||
},
|
||||
"end": {
|
||||
"line": 10,
|
||||
"column": 4,
|
||||
"offset": 194
|
||||
}
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"tagName": "p",
|
||||
"properties": {},
|
||||
"children": [
|
||||
{
|
||||
"type": "mdxJsxTextElement",
|
||||
"name": "span",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "mdxJsxAttribute",
|
||||
"name": "data-inline",
|
||||
"value": "one",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 8,
|
||||
"column": 9,
|
||||
"offset": 129
|
||||
},
|
||||
"end": {
|
||||
"line": 8,
|
||||
"column": 26,
|
||||
"offset": 146
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 8,
|
||||
"column": 3,
|
||||
"offset": 123
|
||||
},
|
||||
"end": {
|
||||
"line": 8,
|
||||
"column": 35,
|
||||
"offset": 155
|
||||
}
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"value": "A",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 8,
|
||||
"column": 27,
|
||||
"offset": 147
|
||||
},
|
||||
"end": {
|
||||
"line": 8,
|
||||
"column": 28,
|
||||
"offset": 148
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"value": "\n",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 8,
|
||||
"column": 35,
|
||||
"offset": 155
|
||||
},
|
||||
"end": {
|
||||
"line": 9,
|
||||
"column": 1,
|
||||
"offset": 156
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "mdxJsxTextElement",
|
||||
"name": "span",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "mdxJsxAttribute",
|
||||
"name": "data-inline",
|
||||
"value": "two",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 9,
|
||||
"column": 9,
|
||||
"offset": 164
|
||||
},
|
||||
"end": {
|
||||
"line": 9,
|
||||
"column": 26,
|
||||
"offset": 181
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 9,
|
||||
"column": 3,
|
||||
"offset": 158
|
||||
},
|
||||
"end": {
|
||||
"line": 9,
|
||||
"column": 35,
|
||||
"offset": 190
|
||||
}
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"value": "B",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 9,
|
||||
"column": 27,
|
||||
"offset": 182
|
||||
},
|
||||
"end": {
|
||||
"line": 9,
|
||||
"column": 28,
|
||||
"offset": 183
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 8,
|
||||
"column": 3,
|
||||
"offset": 123
|
||||
},
|
||||
"end": {
|
||||
"line": 9,
|
||||
"column": 35,
|
||||
"offset": 190
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 1,
|
||||
"offset": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 11,
|
||||
"column": 1,
|
||||
"offset": 195
|
||||
}
|
||||
}
|
||||
},
|
||||
"code": "\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst ignored = _jsx(\"span\", {\n children: \"Ignored export\"\n});\nlet toc = [{\n depth: 1,\n url: \"#jsx-expressions\",\n title: _jsx(_Fragment, {\n children: \"JSX expressions\"\n })\n}];\nfunction _createMdxContent(props) {\n const _components = {\n h1: \"h1\",\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsx(_components.h1, {\n id: \"jsx-expressions\",\n children: \"JSX expressions\"\n }), \"\\n\", \"\\n\", _jsx(\"div\", {\n id: \"native-jsx\",\n children: \"Native JSX child\"\n }), \"\\n\", _jsxs(_Fragment, {\n children: [_jsx(\"span\", {\n \"data-inline\": \"one\",\n children: \"A\"\n }), _jsx(\"span\", {\n \"data-inline\": \"two\",\n children: \"B\"\n })]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = props.components || ({});\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n ignored,\n toc,\n default: MDXContent\n};\n",
|
||||
"data": {
|
||||
"structuredData": {
|
||||
"contents": [
|
||||
{
|
||||
"heading": "jsx-expressions",
|
||||
"content": "A\nB"
|
||||
}
|
||||
],
|
||||
"contents": [],
|
||||
"headings": [
|
||||
{
|
||||
"id": "jsx-expressions",
|
||||
"content": "JSX expressions"
|
||||
}
|
||||
]
|
||||
},
|
||||
"rehypeToc": [
|
||||
{
|
||||
"title": {
|
||||
"type": "element",
|
||||
"tagName": "h1",
|
||||
"properties": {
|
||||
"id": "jsx-expressions"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"value": "JSX expressions",
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 3,
|
||||
"offset": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18,
|
||||
"offset": 17
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"position": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 1,
|
||||
"offset": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18,
|
||||
"offset": 17
|
||||
}
|
||||
}
|
||||
},
|
||||
"depth": 1,
|
||||
"url": "#jsx-expressions"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-7
@@ -1,11 +1,6 @@
|
||||
{
|
||||
"structuredData": {
|
||||
"contents": [
|
||||
{
|
||||
"heading": "jsx-expressions",
|
||||
"content": "A\nB"
|
||||
}
|
||||
],
|
||||
"contents": [],
|
||||
"headings": [
|
||||
{
|
||||
"id": "jsx-expressions",
|
||||
@@ -13,7 +8,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"bodyHtml": "<h1 id=\"jsx-expressions\">JSX expressions</h1>\nexport const ignored = <span>Ignored export</span>\n<div id="native-jsx">Native JSX child</div>\n<p><span data-inline=\"one\">A</span>\n<span data-inline=\"two\">B</span></p>",
|
||||
"bodyHtml": "<h1 id=\"jsx-expressions\">JSX expressions</h1>\n\n<div id=\"native-jsx\">Native JSX child</div>\n<span data-inline=\"one\">A</span><span data-inline=\"two\">B</span>",
|
||||
"toc": [
|
||||
{
|
||||
"url": "#jsx-expressions",
|
||||
|
||||
@@ -3,7 +3,7 @@ import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { renderToStaticMarkup } from 'react-dom/server';
|
||||
import { createMarkdownCompiler, MarkdownCompiler } from '@/md/compiler-full';
|
||||
import { createMarkdownCompiler, MarkdownCompiler } from '@/md/compiler';
|
||||
import { createMarkdownRenderer } from '@/md/renderer';
|
||||
import type { RawPage } from '@/storage';
|
||||
import type { TOCItemType } from 'fumadocs-core/toc';
|
||||
@@ -43,15 +43,18 @@ for (const { name, file } of cases) {
|
||||
test(`compiler: ${name}`, async () => {
|
||||
const { filePath, content } = await readFixture(file);
|
||||
const compiler = createMarkdownCompiler();
|
||||
const { tree, file: vfile } = await compiler.compile({ path: filePath, value: content });
|
||||
const out = await compiler.compile({ path: filePath, value: content });
|
||||
|
||||
const payload = {
|
||||
tree,
|
||||
data: {
|
||||
structuredData: vfile.data.structuredData,
|
||||
rehypeToc: vfile.data.rehypeToc,
|
||||
},
|
||||
};
|
||||
const payload =
|
||||
out.type === 'ast'
|
||||
? {
|
||||
tree: out.tree,
|
||||
data: out.file.data,
|
||||
}
|
||||
: {
|
||||
code: out.code,
|
||||
data: out.file.data,
|
||||
};
|
||||
|
||||
await expect(JSON.stringify(payload, null, 2)).toMatchFileSnapshot(
|
||||
path.join(fixturesDir, `${name}.compiler.json`),
|
||||
|
||||
@@ -4,7 +4,7 @@ export default defineConfig({
|
||||
dts: true,
|
||||
fixedExtension: false,
|
||||
target: 'es2023',
|
||||
entry: ['./src/index.ts', './src/dev/index.ts'],
|
||||
entry: ['./src/index.ts', './src/js/*', './src/dev/index.ts'],
|
||||
format: 'esm',
|
||||
exports: true,
|
||||
deps: {
|
||||
|
||||
Generated
+32
-36
@@ -1798,7 +1798,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
unified:
|
||||
specifier: ^11.0.5
|
||||
version: 11.0.5
|
||||
@@ -1832,7 +1832,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
|
||||
packages/content:
|
||||
dependencies:
|
||||
@@ -1857,7 +1857,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
|
||||
packages/content-collections:
|
||||
dependencies:
|
||||
@@ -1885,7 +1885,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
|
||||
packages/core:
|
||||
dependencies:
|
||||
@@ -2033,7 +2033,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
typescript:
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
@@ -2085,7 +2085,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
typescript:
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
@@ -2176,7 +2176,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
typescript:
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
@@ -2222,7 +2222,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
typescript:
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
@@ -2232,6 +2232,9 @@ importers:
|
||||
|
||||
packages/local-md:
|
||||
dependencies:
|
||||
'@mdx-js/mdx':
|
||||
specifier: ^3.1.1
|
||||
version: 3.1.1
|
||||
'@standard-schema/spec':
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0
|
||||
@@ -2247,9 +2250,6 @@ importers:
|
||||
remark:
|
||||
specifier: ^15.0.1
|
||||
version: 15.0.1
|
||||
remark-mdx:
|
||||
specifier: ^3.1.1
|
||||
version: 3.1.1
|
||||
remark-rehype:
|
||||
specifier: ^11.1.2
|
||||
version: 11.1.2
|
||||
@@ -2272,9 +2272,6 @@ importers:
|
||||
'@types/hast':
|
||||
specifier: ^3.0.4
|
||||
version: 3.0.4
|
||||
'@types/mdx':
|
||||
specifier: ^2.0.13
|
||||
version: 2.0.13
|
||||
'@types/node':
|
||||
specifier: 25.6.0
|
||||
version: 25.6.0
|
||||
@@ -2307,7 +2304,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
|
||||
packages/mdx:
|
||||
dependencies:
|
||||
@@ -2413,7 +2410,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
vite:
|
||||
specifier: ^8.0.8
|
||||
version: 8.0.8(@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])
|
||||
@@ -2462,7 +2459,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
|
||||
packages/obsidian:
|
||||
dependencies:
|
||||
@@ -2538,7 +2535,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
typescript:
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
@@ -2650,7 +2647,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
|
||||
packages/press:
|
||||
dependencies:
|
||||
@@ -2789,7 +2786,7 @@ importers:
|
||||
version: 4.2.2
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
typescript:
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
@@ -2841,7 +2838,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
|
||||
packages/radix-ui:
|
||||
dependencies:
|
||||
@@ -2962,7 +2959,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
unified:
|
||||
specifier: ^11.0.5
|
||||
version: 11.0.5
|
||||
@@ -3006,7 +3003,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
|
||||
packages/story:
|
||||
dependencies:
|
||||
@@ -3064,7 +3061,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
|
||||
packages/tailwind:
|
||||
devDependencies:
|
||||
@@ -3088,7 +3085,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
|
||||
packages/tsconfig: {}
|
||||
|
||||
@@ -3148,7 +3145,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
typescript:
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
@@ -3224,7 +3221,7 @@ importers:
|
||||
version: link:../tsconfig
|
||||
tsdown:
|
||||
specifier: 0.21.8
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
version: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
typescript:
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
@@ -7835,7 +7832,6 @@ packages:
|
||||
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-KLwDUqs5WIny/94F4xZ4QfaAE6YWyjR+s79pt/ItQhk2CG+PJQ5xL6VuOWhiyN2eP3fryZK95vog9CTLCaYV2Q==}
|
||||
cpu: [arm64, x64]
|
||||
os: [darwin, linux, win32]
|
||||
hasBin: true
|
||||
|
||||
@@ -16200,7 +16196,7 @@ snapshots:
|
||||
react: 19.2.5
|
||||
react-dom: 19.2.5([email protected])
|
||||
optionalDependencies:
|
||||
'@vitejs/plugin-rsc': 0.5.24([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
|
||||
'@vitejs/plugin-rsc': 0.5.24([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected])([email protected]([email protected])))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
|
||||
transitivePeerDependencies:
|
||||
- '@rsbuild/core'
|
||||
- crossws
|
||||
@@ -16236,7 +16232,7 @@ snapshots:
|
||||
react-dom: 19.2.5([email protected])
|
||||
vite: 8.0.8(@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])
|
||||
optionalDependencies:
|
||||
'@vitejs/plugin-rsc': 0.5.24([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
|
||||
'@vitejs/plugin-rsc': 0.5.24([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected])([email protected]([email protected])))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
|
||||
transitivePeerDependencies:
|
||||
- '@rsbuild/core'
|
||||
- crossws
|
||||
@@ -16407,7 +16403,7 @@ snapshots:
|
||||
lightningcss: 1.32.0
|
||||
postcss-load-config: 6.0.1([email protected])([email protected])([email protected])([email protected])
|
||||
rolldown: 1.0.0-rc.15
|
||||
tsdown: 0.21.8(@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])
|
||||
tsdown: 0.21.8(@tsdown/[email protected])([email protected])([email protected])
|
||||
optionalDependencies:
|
||||
postcss: 8.5.9
|
||||
transitivePeerDependencies:
|
||||
@@ -18073,7 +18069,7 @@ snapshots:
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
[email protected]([email protected](@emnapi/[email protected])(@emnapi/[email protected])):
|
||||
[email protected]([email protected]):
|
||||
optionalDependencies:
|
||||
oxc-resolver: 11.19.1(@emnapi/[email protected])(@emnapi/[email protected])
|
||||
|
||||
@@ -21451,7 +21447,7 @@ snapshots:
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
[email protected]([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])([email protected]):
|
||||
[email protected]([email protected])([email protected])([email protected]):
|
||||
dependencies:
|
||||
'@babel/generator': 8.0.0-rc.3
|
||||
'@babel/helper-validator-identifier': 8.0.0-rc.3
|
||||
@@ -21459,7 +21455,7 @@ snapshots:
|
||||
'@babel/types': 8.0.0-rc.3
|
||||
ast-kit: 3.0.0-beta.1
|
||||
birpc: 4.0.0
|
||||
dts-resolver: 2.1.3([email protected](@emnapi/[email protected])(@emnapi/[email protected]))
|
||||
dts-resolver: 2.1.3([email protected])
|
||||
get-tsconfig: 4.14.0
|
||||
obug: 2.1.1
|
||||
picomatch: 4.0.4
|
||||
@@ -22098,7 +22094,7 @@ snapshots:
|
||||
minimist: 1.2.8
|
||||
strip-bom: 3.0.0
|
||||
|
||||
[email protected](@tsdown/[email protected])([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected]):
|
||||
[email protected](@tsdown/[email protected])([email protected])([email protected]):
|
||||
dependencies:
|
||||
ansis: 4.2.0
|
||||
cac: 7.0.0
|
||||
@@ -22109,7 +22105,7 @@ snapshots:
|
||||
obug: 2.1.1
|
||||
picomatch: 4.0.4
|
||||
rolldown: 1.0.0-rc.15
|
||||
rolldown-plugin-dts: 0.23.2([email protected](@emnapi/[email protected])(@emnapi/[email protected]))([email protected])([email protected])
|
||||
rolldown-plugin-dts: 0.23.2([email protected])([email protected])([email protected])
|
||||
semver: 7.7.4
|
||||
tinyexec: 1.1.1
|
||||
tinyglobby: 0.2.16
|
||||
|
||||
Reference in New Issue
Block a user