mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 23:49:51 +00:00
Press: support Mermaid
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumapress': patch
|
||||
---
|
||||
|
||||
Support Mermaid
|
||||
+15
-14
@@ -33,33 +33,21 @@
|
||||
"types:check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hono/node-server": "^1.19.10",
|
||||
"@hono/node-ws": "^1.3.0",
|
||||
"@takumi-rs/image-response": "^0.69.5",
|
||||
"chokidar": "^5.0.0",
|
||||
"commander": "^14.0.3",
|
||||
"dotenv": "^17.3.1",
|
||||
"fumadocs-core": "workspace:*",
|
||||
"fumadocs-ui": "workspace:*",
|
||||
"gray-matter": "^4.0.3",
|
||||
"hast-util-to-jsx-runtime": "^2.3.6",
|
||||
"hono": "^4.12.4",
|
||||
"lucide-react": "^0.575.0",
|
||||
"picomatch": "^4.0.3",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"react-server-dom-webpack": "^19.2.4",
|
||||
"rehype-katex": "^7.0.1",
|
||||
"remark": "^15.0.1",
|
||||
"remark-math": "^6.0.0",
|
||||
"remark-rehype": "^11.1.2",
|
||||
"tinyglobby": "^0.2.15",
|
||||
"unrun": "^0.2.28",
|
||||
"vfile": "^6.0.3",
|
||||
"waku": "1.0.0-alpha.5",
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@hono/node-server": "^1.19.10",
|
||||
"@hono/node-ws": "^1.3.0",
|
||||
"@tailwindcss/vite": "^4.2.1",
|
||||
"@types/hast": "^3.0.4",
|
||||
"@types/mdast": "^4.0.4",
|
||||
@@ -69,11 +57,24 @@
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/unist": "^3.0.3",
|
||||
"beautiful-mermaid": "^1.1.3",
|
||||
"gray-matter": "^4.0.3",
|
||||
"hast-util-to-jsx-runtime": "^2.3.6",
|
||||
"hono": "^4.12.4",
|
||||
"katex": "^0.16.33",
|
||||
"lucide-react": "^0.575.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"react-server-dom-webpack": "^19.2.4",
|
||||
"rehype-katex": "^7.0.1",
|
||||
"remark": "^15.0.1",
|
||||
"remark-math": "^6.0.0",
|
||||
"remark-rehype": "^11.1.2",
|
||||
"tailwindcss": "^4.2.1",
|
||||
"tsdown": "0.20.3",
|
||||
"typescript": "^5.9.3",
|
||||
"unified": "^11.0.5",
|
||||
"vfile": "^6.0.3",
|
||||
"vite": "^7.3.1",
|
||||
"vite-tsconfig-paths": "^6.1.1"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { program } from 'commander';
|
||||
import { runStart } from './commands.js';
|
||||
import fs from 'node:fs/promises';
|
||||
import { findConfigPath } from '@/config/load-node.js';
|
||||
import { version } from 'package.json';
|
||||
|
||||
program
|
||||
.command('init')
|
||||
@@ -27,4 +28,4 @@ program
|
||||
await runStart(options);
|
||||
});
|
||||
|
||||
void program.parseAsync(process.argv);
|
||||
void program.version(version).parseAsync(process.argv);
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
export async function Mermaid({ chart }: { chart: string }) {
|
||||
const { renderMermaidSVG } = await import('beautiful-mermaid');
|
||||
const svg = renderMermaidSVG(chart, {
|
||||
bg: 'var(--color-fd-background)',
|
||||
fg: 'var(--color-fd-foreground)',
|
||||
interactive: true,
|
||||
transparent: true,
|
||||
});
|
||||
|
||||
return <div dangerouslySetInnerHTML={{ __html: svg }} />;
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { revalidable } from '@/lib/revalidable.js';
|
||||
import { defineConfig, type FumapressConfig } from './global.js';
|
||||
import { checkConfig, findConfigPath } from './load-node.js';
|
||||
import { unrun } from 'unrun';
|
||||
@@ -26,14 +27,9 @@ async function loadConfig(configPath: string | null): Promise<FumapressConfig> {
|
||||
}
|
||||
}
|
||||
|
||||
let cached: Promise<FumapressConfig> | undefined;
|
||||
|
||||
export function getConfigRuntime(): Promise<FumapressConfig> {
|
||||
if (cached) return cached;
|
||||
|
||||
cached = (async () => {
|
||||
export const getConfigRuntime = revalidable({
|
||||
async create() {
|
||||
const configPath = await findConfigPath();
|
||||
return await loadConfig(configPath);
|
||||
})();
|
||||
return cached;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { DocsLayoutProps } from 'fumadocs-ui/layouts/docs';
|
||||
import type { HomeLayoutProps } from 'fumadocs-ui/layouts/home';
|
||||
import { FumadocsLogo } from '@/components/logo';
|
||||
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
|
||||
import { getConfigRuntime } from '@/config/load-runtime';
|
||||
|
||||
export function layoutConfig(config: FumapressConfig) {
|
||||
const { base } = config.layout ?? {};
|
||||
@@ -28,7 +29,8 @@ export function layoutConfig(config: FumapressConfig) {
|
||||
};
|
||||
},
|
||||
async docs(): Promise<DocsLayoutProps> {
|
||||
const source = await getSource();
|
||||
const config = await getConfigRuntime();
|
||||
const source = await getSource(config);
|
||||
return {
|
||||
tree: source.getPageTree(),
|
||||
...(await this.base()),
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
const refMap = new WeakMap<object, string>();
|
||||
let nextRefId = 0;
|
||||
|
||||
export function hash(value: unknown): string {
|
||||
if (typeof value === 'boolean') return value ? '1:' : '0:';
|
||||
if (value === null) return 'n:';
|
||||
if (value === undefined) return 'u:';
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return `a:${value.map(hash).join('\0')}`;
|
||||
}
|
||||
|
||||
if (typeof value === 'object') {
|
||||
const v = refMap.get(value);
|
||||
if (v) return v;
|
||||
|
||||
const result = `o:${nextRefId++}`;
|
||||
refMap.set(value, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (typeof value === 'function' || typeof value === 'symbol') {
|
||||
throw new Error('not supported');
|
||||
}
|
||||
|
||||
return `${typeof value}:${value}`.replaceAll('\0', '');
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
import { cache } from 'react';
|
||||
import { hash } from './hash';
|
||||
|
||||
export interface RevalidableConfig<Args extends unknown[], O> {
|
||||
/**
|
||||
* If specified, revalidate by stale time.
|
||||
*/
|
||||
staleTime?: number;
|
||||
create: (...args: Args) => O;
|
||||
cacheKey?: (...args: Args) => string;
|
||||
}
|
||||
|
||||
export type WithRevalidate<Args extends unknown[], O> = {
|
||||
@@ -16,52 +14,63 @@ export type WithRevalidate<Args extends unknown[], O> = {
|
||||
export function revalidable<Args extends unknown[], O>(
|
||||
config: RevalidableConfig<Args, O>,
|
||||
): WithRevalidate<Args, O> {
|
||||
const { create, staleTime } = config;
|
||||
const { create, staleTime, cacheKey = (...args) => hash(args) } = config;
|
||||
|
||||
if (typeof staleTime === 'number') {
|
||||
let lastValidated: number | null = null;
|
||||
let lastResult: O = undefined as O;
|
||||
let revalidating = false;
|
||||
|
||||
const out: WithRevalidate<Args, O> = function (...args: Args) {
|
||||
if (lastValidated === null) {
|
||||
// init
|
||||
lastResult = create(...args);
|
||||
lastValidated = Date.now();
|
||||
return lastResult;
|
||||
}
|
||||
|
||||
const isStale = Date.now() - lastValidated >= staleTime;
|
||||
if (!isStale || revalidating) return lastResult;
|
||||
|
||||
revalidating = true;
|
||||
const next = create(...args);
|
||||
|
||||
if (next instanceof Promise) {
|
||||
void next
|
||||
.then((res) => {
|
||||
lastResult = res;
|
||||
lastValidated = Date.now();
|
||||
})
|
||||
.finally(() => {
|
||||
revalidating = false;
|
||||
});
|
||||
} else {
|
||||
lastResult = next;
|
||||
lastValidated = Date.now();
|
||||
}
|
||||
const cacheMap = new Map<
|
||||
string,
|
||||
{
|
||||
lastValidated: number;
|
||||
lastResult: O;
|
||||
revalidating: boolean;
|
||||
}
|
||||
>();
|
||||
const out: WithRevalidate<Args, O> = function (...args: Args) {
|
||||
const key = cacheKey(...args);
|
||||
const cache = cacheMap.get(key);
|
||||
|
||||
if (!cache) {
|
||||
const lastResult = create(...args);
|
||||
// init
|
||||
cacheMap.set(key, {
|
||||
lastResult,
|
||||
lastValidated: Date.now(),
|
||||
revalidating: false,
|
||||
});
|
||||
return lastResult;
|
||||
};
|
||||
}
|
||||
|
||||
out.revalidate = (keepStale = true) => {
|
||||
lastValidated = keepStale ? 0 : null;
|
||||
};
|
||||
}
|
||||
const isStale = staleTime !== undefined && Date.now() - cache.lastValidated >= staleTime;
|
||||
if (!isStale || cache.revalidating) return cache.lastResult;
|
||||
|
||||
const out = cache(create) as WithRevalidate<Args, O>;
|
||||
out.revalidate = () => {
|
||||
return;
|
||||
const next = create(...args);
|
||||
|
||||
if (next instanceof Promise) {
|
||||
cache.revalidating = true;
|
||||
void next
|
||||
.then((res) => {
|
||||
cache.lastResult = res;
|
||||
cache.lastValidated = Date.now();
|
||||
})
|
||||
.finally(() => {
|
||||
cache.revalidating = false;
|
||||
});
|
||||
} else {
|
||||
cache.lastResult = next;
|
||||
cache.lastValidated = Date.now();
|
||||
}
|
||||
|
||||
return cache.lastResult;
|
||||
};
|
||||
|
||||
out.revalidate = (keepStale = true) => {
|
||||
if (keepStale) {
|
||||
for (const value of cacheMap.values()) {
|
||||
value.lastValidated = 0;
|
||||
}
|
||||
} else {
|
||||
cacheMap.clear();
|
||||
}
|
||||
};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
import { type InferPageType, loader, source } from 'fumadocs-core/source';
|
||||
import { getConfigRuntime } from '@/config/load-runtime';
|
||||
import { revalidable } from '@/lib/revalidable';
|
||||
import { lucideIconsPlugin } from 'fumadocs-core/source/lucide-icons';
|
||||
import { getPages } from './storage';
|
||||
import { FumapressConfig } from '@/config/global';
|
||||
|
||||
export const getSource = revalidable({
|
||||
async create() {
|
||||
const config = await getConfigRuntime();
|
||||
|
||||
async create(config: FumapressConfig) {
|
||||
return loader({
|
||||
source: source(await getPages(config.content ?? {})),
|
||||
plugins: [lucideIconsPlugin()],
|
||||
baseUrl: '/',
|
||||
});
|
||||
},
|
||||
staleTime: 60 * 1000,
|
||||
});
|
||||
|
||||
export type SourcePage = InferPageType<Awaited<ReturnType<typeof getSource>>>;
|
||||
export type Source = Awaited<ReturnType<typeof getSource>>;
|
||||
export type SourcePage = InferPageType<Source>;
|
||||
|
||||
export function getPageImage(slugs: string[]) {
|
||||
const segments = [...slugs, 'image.webp'];
|
||||
|
||||
@@ -16,11 +16,14 @@ import { Fragment } from 'react/jsx-runtime';
|
||||
import remarkMath from 'remark-math';
|
||||
import rehypeKatex from 'rehype-katex';
|
||||
import { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock';
|
||||
import { remarkMdxMermaid } from 'fumadocs-core/mdx-plugins/remark-mdx-mermaid';
|
||||
import { Mermaid } from '@/components/mermaid';
|
||||
|
||||
const compiler = createMarkdownCompiler({
|
||||
remarkPlugins: [
|
||||
remarkGfm,
|
||||
remarkMath,
|
||||
remarkMdxMermaid,
|
||||
plugin(remarkHeading, { generateToc: false }),
|
||||
plugin(remarkNpm, { persist: { id: 'package-manager' } }),
|
||||
remarkCodeTab,
|
||||
@@ -37,9 +40,10 @@ const compiler = createMarkdownCompiler({
|
||||
|
||||
const mdxComponents = {
|
||||
...defaultMdxComponents,
|
||||
Mermaid,
|
||||
};
|
||||
|
||||
interface MdPresetData {
|
||||
interface MdPresetComponents {
|
||||
layout: typeof import('fumadocs-ui/layouts/docs') | typeof import('fumadocs-ui/layouts/flux');
|
||||
page:
|
||||
| typeof import('fumadocs-ui/layouts/docs/page')
|
||||
@@ -47,29 +51,29 @@ interface MdPresetData {
|
||||
}
|
||||
|
||||
export default async function DocPage({ slugs }: PageProps<'/docs/[...slugs]'>) {
|
||||
const source = await getSource();
|
||||
const config = await getConfigRuntime();
|
||||
const source = await getSource(config);
|
||||
const layout = layoutConfig(config);
|
||||
const page = source.getPage(slugs);
|
||||
const mdPreset = config.layout?.presets?.md ?? 'docs';
|
||||
let mdPresetData: MdPresetData;
|
||||
let mdPresetComponents: MdPresetComponents;
|
||||
|
||||
if (mdPreset === 'docs') {
|
||||
mdPresetData = {
|
||||
mdPresetComponents = {
|
||||
layout: await import('fumadocs-ui/layouts/docs'),
|
||||
page: await import('fumadocs-ui/layouts/docs/page'),
|
||||
};
|
||||
} else {
|
||||
mdPresetData = {
|
||||
mdPresetComponents = {
|
||||
layout: await import('fumadocs-ui/layouts/flux'),
|
||||
page: await import('fumadocs-ui/layouts/flux/page'),
|
||||
};
|
||||
}
|
||||
|
||||
const { DocsLayout } = mdPresetData.layout;
|
||||
const { DocsLayout } = mdPresetComponents.layout;
|
||||
return (
|
||||
<DocsLayout {...await layout.docs()}>
|
||||
<MdContent slugs={slugs} page={page} data={mdPresetData} />
|
||||
<MdContent slugs={slugs} page={page} components={mdPresetComponents} />
|
||||
</DocsLayout>
|
||||
);
|
||||
}
|
||||
@@ -77,14 +81,15 @@ export default async function DocPage({ slugs }: PageProps<'/docs/[...slugs]'>)
|
||||
async function MdContent({
|
||||
slugs,
|
||||
page,
|
||||
data,
|
||||
components,
|
||||
}: {
|
||||
slugs: string[];
|
||||
page?: SourcePage;
|
||||
data: MdPresetData;
|
||||
components: MdPresetComponents;
|
||||
}) {
|
||||
const { DocsBody, DocsTitle, DocsPage, DocsDescription } = data.page;
|
||||
const source = await getSource();
|
||||
const config = await getConfigRuntime();
|
||||
const source = await getSource(config);
|
||||
const { DocsBody, DocsTitle, DocsPage, DocsDescription } = components.page;
|
||||
|
||||
if (!page) {
|
||||
if (slugs.length === 0) {
|
||||
@@ -171,10 +176,12 @@ async function MdContent({
|
||||
}
|
||||
|
||||
export async function getConfig() {
|
||||
const config = await getConfigRuntime();
|
||||
const source = await getSource(config);
|
||||
const staticPaths: string[][] = [];
|
||||
let hasIndex = false;
|
||||
|
||||
for (const item of (await getSource()).generateParams()) {
|
||||
for (const item of source.generateParams()) {
|
||||
const staticPath = item.lang ? [item.lang, ...item.slug] : item.slug;
|
||||
staticPaths.push(staticPath);
|
||||
if (staticPath.length === 0) hasIndex = true;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { createFromSource, type SearchAPI } from 'fumadocs-core/search/server';
|
||||
import { getSource } from '@/lib/source';
|
||||
import { createFromSource } from 'fumadocs-core/search/server';
|
||||
import { getSource, Source } from '@/lib/source';
|
||||
import { revalidable } from '@/lib/revalidable';
|
||||
import { structure } from 'fumadocs-core/mdx-plugins/remark-structure';
|
||||
import { getConfigRuntime } from '@/config/load-runtime';
|
||||
|
||||
const getServer = revalidable({
|
||||
async create(): Promise<SearchAPI> {
|
||||
return createFromSource(await getSource(), {
|
||||
async create(source: Source) {
|
||||
return createFromSource(source, {
|
||||
language: 'english',
|
||||
buildIndex(page) {
|
||||
return {
|
||||
@@ -18,9 +19,11 @@ const getServer = revalidable({
|
||||
},
|
||||
});
|
||||
},
|
||||
staleTime: 10 * 1000,
|
||||
});
|
||||
|
||||
export async function GET(request: Request) {
|
||||
return (await getServer()).GET(request);
|
||||
const config = await getConfigRuntime();
|
||||
const source = await getSource(config);
|
||||
const server = await getServer(source);
|
||||
return server.GET(request);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { getConfigRuntime } from '@/config/load-runtime';
|
||||
import { getSource } from '@/lib/source';
|
||||
import { ImageResponse } from '@takumi-rs/image-response';
|
||||
import { generate as DefaultImage } from 'fumadocs-ui/og/takumi';
|
||||
import { ApiContext } from 'waku/router';
|
||||
|
||||
export async function GET(_: Request, { params }: ApiContext<'/og/[...slugs]/image.webp'>) {
|
||||
const page = (await getSource()).getPage(params.slugs);
|
||||
const config = await getConfigRuntime();
|
||||
const page = (await getSource(config)).getPage(params.slugs);
|
||||
|
||||
if (!page) return new Response(undefined, { status: 404 });
|
||||
|
||||
@@ -19,7 +21,8 @@ export async function GET(_: Request, { params }: ApiContext<'/og/[...slugs]/ima
|
||||
}
|
||||
|
||||
export async function getConfig() {
|
||||
const pages = (await getSource())
|
||||
const config = await getConfigRuntime();
|
||||
const pages = (await getSource(config))
|
||||
.generateParams()
|
||||
.map((item) => (item.lang ? [item.lang, ...item.slug] : item.slug));
|
||||
|
||||
|
||||
Generated
+58
-42
@@ -2453,12 +2453,6 @@ importers:
|
||||
|
||||
packages/press:
|
||||
dependencies:
|
||||
'@hono/node-server':
|
||||
specifier: ^1.19.10
|
||||
version: 1.19.10([email protected])
|
||||
'@hono/node-ws':
|
||||
specifier: ^1.3.0
|
||||
version: 1.3.0(@hono/[email protected]([email protected]))([email protected])
|
||||
'@takumi-rs/image-response':
|
||||
specifier: ^0.69.5
|
||||
version: 0.69.5
|
||||
@@ -2477,51 +2471,15 @@ importers:
|
||||
fumadocs-ui:
|
||||
specifier: workspace:*
|
||||
version: link:../radix-ui
|
||||
gray-matter:
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3
|
||||
hast-util-to-jsx-runtime:
|
||||
specifier: ^2.3.6
|
||||
version: 2.3.6
|
||||
hono:
|
||||
specifier: ^4.12.4
|
||||
version: 4.12.4
|
||||
lucide-react:
|
||||
specifier: ^0.575.0
|
||||
version: 0.575.0([email protected])
|
||||
picomatch:
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3
|
||||
react:
|
||||
specifier: ^19.2.4
|
||||
version: 19.2.4
|
||||
react-dom:
|
||||
specifier: ^19.2.4
|
||||
version: 19.2.4([email protected])
|
||||
react-server-dom-webpack:
|
||||
specifier: ^19.2.4
|
||||
version: 19.2.4([email protected]([email protected]))([email protected])([email protected])
|
||||
rehype-katex:
|
||||
specifier: ^7.0.1
|
||||
version: 7.0.1
|
||||
remark:
|
||||
specifier: ^15.0.1
|
||||
version: 15.0.1
|
||||
remark-math:
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0
|
||||
remark-rehype:
|
||||
specifier: ^11.1.2
|
||||
version: 11.1.2
|
||||
tinyglobby:
|
||||
specifier: ^0.2.15
|
||||
version: 0.2.15
|
||||
unrun:
|
||||
specifier: ^0.2.28
|
||||
version: 0.2.28
|
||||
vfile:
|
||||
specifier: ^6.0.3
|
||||
version: 6.0.3
|
||||
waku:
|
||||
specifier: 1.0.0-alpha.5
|
||||
version: 1.0.0-alpha.5(@types/[email protected])([email protected])([email protected])([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected])([email protected]))([email protected])([email protected])([email protected])([email protected])
|
||||
@@ -2529,6 +2487,12 @@ importers:
|
||||
specifier: ^4.3.6
|
||||
version: 4.3.6
|
||||
devDependencies:
|
||||
'@hono/node-server':
|
||||
specifier: ^1.19.10
|
||||
version: 1.19.10([email protected])
|
||||
'@hono/node-ws':
|
||||
specifier: ^1.3.0
|
||||
version: 1.3.0(@hono/[email protected]([email protected]))([email protected])
|
||||
'@tailwindcss/vite':
|
||||
specifier: ^4.2.1
|
||||
version: 4.2.1([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
|
||||
@@ -2556,9 +2520,45 @@ importers:
|
||||
'@types/unist':
|
||||
specifier: ^3.0.3
|
||||
version: 3.0.3
|
||||
beautiful-mermaid:
|
||||
specifier: ^1.1.3
|
||||
version: 1.1.3
|
||||
gray-matter:
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3
|
||||
hast-util-to-jsx-runtime:
|
||||
specifier: ^2.3.6
|
||||
version: 2.3.6
|
||||
hono:
|
||||
specifier: ^4.12.4
|
||||
version: 4.12.4
|
||||
katex:
|
||||
specifier: ^0.16.33
|
||||
version: 0.16.33
|
||||
lucide-react:
|
||||
specifier: ^0.575.0
|
||||
version: 0.575.0([email protected])
|
||||
react:
|
||||
specifier: ^19.2.4
|
||||
version: 19.2.4
|
||||
react-dom:
|
||||
specifier: ^19.2.4
|
||||
version: 19.2.4([email protected])
|
||||
react-server-dom-webpack:
|
||||
specifier: ^19.2.4
|
||||
version: 19.2.4([email protected]([email protected]))([email protected])([email protected])
|
||||
rehype-katex:
|
||||
specifier: ^7.0.1
|
||||
version: 7.0.1
|
||||
remark:
|
||||
specifier: ^15.0.1
|
||||
version: 15.0.1
|
||||
remark-math:
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0
|
||||
remark-rehype:
|
||||
specifier: ^11.1.2
|
||||
version: 11.1.2
|
||||
tailwindcss:
|
||||
specifier: ^4.2.1
|
||||
version: 4.2.1
|
||||
@@ -2571,6 +2571,9 @@ importers:
|
||||
unified:
|
||||
specifier: ^11.0.5
|
||||
version: 11.0.5
|
||||
vfile:
|
||||
specifier: ^6.0.3
|
||||
version: 6.0.3
|
||||
vite:
|
||||
specifier: ^7.3.1
|
||||
version: 7.3.1(@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])
|
||||
@@ -7579,6 +7582,9 @@ packages:
|
||||
resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-TItrtrAyHp1vwFfFVYauWGrquouk/6SS21Aq3RsxindSYZODcN4xYrPZD6BiZRU+o5mKJzDPz9MUSMvELdylyg==}
|
||||
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==}
|
||||
|
||||
@@ -8404,6 +8410,9 @@ packages:
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==}
|
||||
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-zxxR9k+rx5ktMwT/FwyLdPCrq7xN6e4VGGHH8hA01vVYKjTFik7nHOxBnAYtrgYUB1RpAiLvA1/U2YraWxyKKg==}
|
||||
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==}
|
||||
|
||||
@@ -17377,6 +17386,11 @@ snapshots:
|
||||
dependencies:
|
||||
safe-buffer: 5.1.2
|
||||
|
||||
[email protected]:
|
||||
dependencies:
|
||||
elkjs: 0.11.1
|
||||
entities: 7.0.1
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
[email protected]:
|
||||
@@ -18197,6 +18211,8 @@ snapshots:
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
Reference in New Issue
Block a user