diff --git a/apps/design-system/__registry__/index.tsx b/apps/design-system/__registry__/index.tsx index a9955207f18..e46c387c320 100644 --- a/apps/design-system/__registry__/index.tsx +++ b/apps/design-system/__registry__/index.tsx @@ -2568,6 +2568,116 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, + "mermaid-demo": { + name: "mermaid-demo", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-demo")), + source: "", + files: ["registry/default/example/mermaid-demo.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "mermaid-flowchart": { + name: "mermaid-flowchart", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-flowchart")), + source: "", + files: ["registry/default/example/mermaid-flowchart.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "mermaid-er-diagram": { + name: "mermaid-er-diagram", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-er-diagram")), + source: "", + files: ["registry/default/example/mermaid-er-diagram.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "mermaid-sequence-async": { + name: "mermaid-sequence-async", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-sequence-async")), + source: "", + files: ["registry/default/example/mermaid-sequence-async.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "mermaid-sequence-sync": { + name: "mermaid-sequence-sync", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-sequence-sync")), + source: "", + files: ["registry/default/example/mermaid-sequence-sync.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "mermaid-oauth-flow": { + name: "mermaid-oauth-flow", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-oauth-flow")), + source: "", + files: ["registry/default/example/mermaid-oauth-flow.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "mermaid-flowchart-subgraph": { + name: "mermaid-flowchart-subgraph", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-flowchart-subgraph")), + source: "", + files: ["registry/default/example/mermaid-flowchart-subgraph.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "mermaid-sequence-api": { + name: "mermaid-sequence-api", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-sequence-api")), + source: "", + files: ["registry/default/example/mermaid-sequence-api.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "mermaid-er-simple": { + name: "mermaid-er-simple", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-er-simple")), + source: "", + files: ["registry/default/example/mermaid-er-simple.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "mermaid-basic": { + name: "mermaid-basic", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-basic")), + source: "", + files: ["registry/default/example/mermaid-basic.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, "chart-area-axes": { name: "chart-area-axes", type: "components:block", diff --git a/apps/design-system/config/docs.ts b/apps/design-system/config/docs.ts index 62fb4949d15..4c921fd1170 100644 --- a/apps/design-system/config/docs.ts +++ b/apps/design-system/config/docs.ts @@ -317,6 +317,12 @@ export const docsConfig: DocsConfig = { href: '/docs/components/label', items: [], }, + { + title: 'Mermaid', + href: '/docs/components/mermaid', + items: [], + label: 'New', + }, { title: 'Menubar', href: '/docs/components/menubar', diff --git a/apps/design-system/content/docs/components/mermaid.mdx b/apps/design-system/content/docs/components/mermaid.mdx new file mode 100644 index 00000000000..0d12331145d --- /dev/null +++ b/apps/design-system/content/docs/components/mermaid.mdx @@ -0,0 +1,121 @@ +--- +title: Mermaid +description: Render diagrams from text using Mermaid syntax. +component: true +--- + + + +## Usage + +### In MDX (Blog Posts) + +The simplest way to add diagrams in blog posts is with a fenced code block using the `mermaid` language tag: + +````mdx +```mermaid +flowchart LR + A[User Request] --> B{Authenticated?} + B -->|Yes| C[Process Request] + B -->|No| D[Return 401] +``` +```` + +This is automatically rendered as a diagram. No imports needed. + +### As a Component + +For more control, import and use the component directly: + +```tsx +import { Mermaid } from 'ui' + +export function MyDiagram() { + return ( + B{Authenticated?} + B -->|Yes| C[Process Request] + B -->|No| D[Return 401] +`} + /> + ) +} +``` + +Use the component when you need to pass props like `className`, conditionally render, or integrate with React logic. + +## Flowcharts + +Use `flowchart` or `graph` to create flowcharts with nodes and edges. Supports decision diamonds, different node shapes, and directional layouts (TD, LR, etc). +[View Mermaid flowchart docs](https://mermaid.js.org/syntax/flowchart.html) + +A basic request flow showing conditional branching with a decision node (`{}`), demonstrating how to visualize auth checks and data flow. + + + +### With Subgraphs + +Group related nodes into labeled subgraphs to show system boundaries. Useful for depicting frontend/backend separation or microservice architecture. + + + +### Supabase Architecture + +Shows how client requests flow through the API Gateway to core services (Auth, PostgREST, Realtime) which all connect to PostgreSQL. + + + +### OAuth Authorization Flow + +Illustrates the OAuth 2.0 authorization code flow, showing the handoff between a third-party app, your authorization endpoint, and Supabase Auth for token exchange. + + + +## ER Diagrams + +Use `erDiagram` to create entity-relationship diagrams showing database schemas. Great for documenting table relationships and foreign keys. +[View Mermaid ER diagram docs](https://mermaid.js.org/syntax/entityRelationshipDiagram.html) + +A simple e-commerce schema showing cardinality between customers, orders, products, and line items using crow's foot notation. + + + +### With Attributes + +Include column definitions with types and constraints (PK, FK) to create more detailed schema documentation. + + + +## Sequence Diagrams + +Use `sequenceDiagram` to show interactions between participants over time. Ideal for documenting API flows, authentication handshakes, or any request/response patterns. +[View Mermaid sequence diagram docs](https://mermaid.js.org/syntax/sequenceDiagram.html) + +A typical authenticated API request showing JWT validation, database insert, and response flow between Client, API, Auth, and DB participants. + + + +### Async Streaming (FDW) + +Shows how Foreign Data Wrappers can stream data asynchronously using bounded channels, with parallel execution indicated by the `par` block. + + + +### Sync Blocking (FDW) + +Contrasts with async by showing traditional blocking FDW behavior where all rows are fetched and buffered before processing. + + + +## Props + +| Prop | Type | Description | +| ----------- | -------- | ------------------------------------ | +| `chart` | `string` | The Mermaid diagram definition | +| `className` | `string` | Optional CSS class for the container | + +## Learn More + +See the [Mermaid documentation](https://mermaid.js.org/intro/) for full syntax reference and additional diagram types. diff --git a/apps/design-system/registry/default/example/mermaid-basic.tsx b/apps/design-system/registry/default/example/mermaid-basic.tsx new file mode 100644 index 00000000000..4fb5c6f2d6f --- /dev/null +++ b/apps/design-system/registry/default/example/mermaid-basic.tsx @@ -0,0 +1,16 @@ +import { Mermaid } from 'ui' + +export default function MermaidBasic() { + return ( + B{Is it working?} + B -->|Yes| C[Great!] + B -->|No| D[Debug] + D --> B + C --> E[End] +`} + /> + ) +} diff --git a/apps/design-system/registry/default/example/mermaid-demo.tsx b/apps/design-system/registry/default/example/mermaid-demo.tsx new file mode 100644 index 00000000000..a282b9d2df9 --- /dev/null +++ b/apps/design-system/registry/default/example/mermaid-demo.tsx @@ -0,0 +1,30 @@ +import { Mermaid } from 'ui' + +export default function MermaidDemo() { + return ( + Gateway + Client --> PgBouncer + Client <--> Realtime + Gateway --> Auth + Gateway --> API + Auth --> Postgres + API --> Postgres + Realtime <--> Postgres + PgBouncer --> Postgres +`} + /> + ) +} diff --git a/apps/design-system/registry/default/example/mermaid-er-diagram.tsx b/apps/design-system/registry/default/example/mermaid-er-diagram.tsx new file mode 100644 index 00000000000..aaa7882106f --- /dev/null +++ b/apps/design-system/registry/default/example/mermaid-er-diagram.tsx @@ -0,0 +1,31 @@ +import { Mermaid } from 'ui' + +export default function MermaidERDiagram() { + return ( + + ) +} diff --git a/apps/design-system/registry/default/example/mermaid-er-simple.tsx b/apps/design-system/registry/default/example/mermaid-er-simple.tsx new file mode 100644 index 00000000000..b49f8e366cf --- /dev/null +++ b/apps/design-system/registry/default/example/mermaid-er-simple.tsx @@ -0,0 +1,14 @@ +import { Mermaid } from 'ui' + +export default function MermaidErSimple() { + return ( + + ) +} diff --git a/apps/design-system/registry/default/example/mermaid-flowchart-subgraph.tsx b/apps/design-system/registry/default/example/mermaid-flowchart-subgraph.tsx new file mode 100644 index 00000000000..5ba8f754fec --- /dev/null +++ b/apps/design-system/registry/default/example/mermaid-flowchart-subgraph.tsx @@ -0,0 +1,21 @@ +import { Mermaid } from 'ui' + +export default function MermaidFlowchartSubgraph() { + return ( + B[API Client] + end + + subgraph Backend + C[Edge Functions] --> D[Database] + C --> E[Storage] + end + + B --> C +`} + /> + ) +} diff --git a/apps/design-system/registry/default/example/mermaid-flowchart.tsx b/apps/design-system/registry/default/example/mermaid-flowchart.tsx new file mode 100644 index 00000000000..87bc64e813b --- /dev/null +++ b/apps/design-system/registry/default/example/mermaid-flowchart.tsx @@ -0,0 +1,16 @@ +import { Mermaid } from 'ui' + +export default function MermaidFlowchart() { + return ( + B{Auth Check} + B -->|Valid| C[Query Postgres] + B -->|Invalid| D[Return 401] + C --> E[Apply RLS Policies] + E --> F[Return Data] +`} + /> + ) +} diff --git a/apps/design-system/registry/default/example/mermaid-oauth-flow.tsx b/apps/design-system/registry/default/example/mermaid-oauth-flow.tsx new file mode 100644 index 00000000000..bd76de36874 --- /dev/null +++ b/apps/design-system/registry/default/example/mermaid-oauth-flow.tsx @@ -0,0 +1,23 @@ +import { Mermaid } from 'ui' + +export default function MermaidOAuthFlow() { + return ( + B + B -- "(2) User authenticates & approves" --> C + C -- "(3) Authorization code issued" --> D + D -- "(4) Exchange code for access token" --> E + E -- "(5) Access token + refresh token" --> F +`} + /> + ) +} diff --git a/apps/design-system/registry/default/example/mermaid-sequence-api.tsx b/apps/design-system/registry/default/example/mermaid-sequence-api.tsx new file mode 100644 index 00000000000..69050f824dc --- /dev/null +++ b/apps/design-system/registry/default/example/mermaid-sequence-api.tsx @@ -0,0 +1,22 @@ +import { Mermaid } from 'ui' + +export default function MermaidSequenceApi() { + return ( + >API: POST /api/data + API->>Auth: Validate JWT + Auth-->>API: Token valid + API->>DB: INSERT query + DB-->>API: Success + API-->>Client: 201 Created +`} + /> + ) +} diff --git a/apps/design-system/registry/default/example/mermaid-sequence-async.tsx b/apps/design-system/registry/default/example/mermaid-sequence-async.tsx new file mode 100644 index 00000000000..87769866ff1 --- /dev/null +++ b/apps/design-system/registry/default/example/mermaid-sequence-async.tsx @@ -0,0 +1,22 @@ +import { Mermaid } from 'ui' + +export default function MermaidSequenceAsync() { + return ( + >R: Execute Query + P->>P: Spawn async task (non-blocking) + par Async Task + R->>P: + Note over R,P: Stream rows incrementally
Send via bounded channel + end + P-->P: Read from channel (blocking_recv) + P-->P: Convert & emit row immediately +`} + /> + ) +} diff --git a/apps/design-system/registry/default/example/mermaid-sequence-sync.tsx b/apps/design-system/registry/default/example/mermaid-sequence-sync.tsx new file mode 100644 index 00000000000..e22c4153899 --- /dev/null +++ b/apps/design-system/registry/default/example/mermaid-sequence-sync.tsx @@ -0,0 +1,19 @@ +import { Mermaid } from 'ui' + +export default function MermaidSequenceSync() { + return ( + >R: Execute Query + R->>P: Wait (blocking) + Note over R,P: Fetch all rows (or fixed batch) + P-->P: Buffer all rows in memory + P-->P: Convert & emit rows in the batch +`} + /> + ) +} diff --git a/apps/design-system/registry/examples.ts b/apps/design-system/registry/examples.ts index f98f0564cf7..59495e9004f 100644 --- a/apps/design-system/registry/examples.ts +++ b/apps/design-system/registry/examples.ts @@ -1397,4 +1397,64 @@ export const examples: Registry = [ type: 'components:example', files: ['example/metric-card-with-icon-link-tooltip.tsx'], }, + { + name: 'mermaid-demo', + type: 'components:example', + registryDependencies: ['mermaid'], + files: ['example/mermaid-demo.tsx'], + }, + { + name: 'mermaid-flowchart', + type: 'components:example', + registryDependencies: ['mermaid'], + files: ['example/mermaid-flowchart.tsx'], + }, + { + name: 'mermaid-er-diagram', + type: 'components:example', + registryDependencies: ['mermaid'], + files: ['example/mermaid-er-diagram.tsx'], + }, + { + name: 'mermaid-sequence-async', + type: 'components:example', + registryDependencies: ['mermaid'], + files: ['example/mermaid-sequence-async.tsx'], + }, + { + name: 'mermaid-sequence-sync', + type: 'components:example', + registryDependencies: ['mermaid'], + files: ['example/mermaid-sequence-sync.tsx'], + }, + { + name: 'mermaid-oauth-flow', + type: 'components:example', + registryDependencies: ['mermaid'], + files: ['example/mermaid-oauth-flow.tsx'], + }, + { + name: 'mermaid-flowchart-subgraph', + type: 'components:example', + registryDependencies: ['mermaid'], + files: ['example/mermaid-flowchart-subgraph.tsx'], + }, + { + name: 'mermaid-sequence-api', + type: 'components:example', + registryDependencies: ['mermaid'], + files: ['example/mermaid-sequence-api.tsx'], + }, + { + name: 'mermaid-er-simple', + type: 'components:example', + registryDependencies: ['mermaid'], + files: ['example/mermaid-er-simple.tsx'], + }, + { + name: 'mermaid-basic', + type: 'components:example', + registryDependencies: ['mermaid'], + files: ['example/mermaid-basic.tsx'], + }, ] diff --git a/apps/www/lib/mdx/mdxComponents.tsx b/apps/www/lib/mdx/mdxComponents.tsx index 2e391394b8a..7abff78971b 100644 --- a/apps/www/lib/mdx/mdxComponents.tsx +++ b/apps/www/lib/mdx/mdxComponents.tsx @@ -11,6 +11,7 @@ import { CollapsibleTrigger_Shadcn_, Heading, Image, + Mermaid, } from 'ui' import { Admonition } from 'ui-patterns/admonition' import type { PropsWithChildren } from 'react' @@ -105,7 +106,12 @@ export default function mdxComponents(type?: 'blog' | 'lp' | undefined) { }, pre: (props: any) => { if (props.className !== ignoreClass) { - return + const childProps = props.children?.props + // Detect mermaid code blocks and render with Mermaid component + if (childProps?.className === 'language-mermaid') { + return + } + return } else { return } @@ -146,6 +152,7 @@ export default function mdxComponents(type?: 'blog' | 'lp' | undefined) {

), Admonition, + Mermaid, } return components as any diff --git a/apps/www/lib/mdx/mdxSerialize.ts b/apps/www/lib/mdx/mdxSerialize.ts index 7e4b6d7cd29..61d8949eaf3 100644 --- a/apps/www/lib/mdx/mdxSerialize.ts +++ b/apps/www/lib/mdx/mdxSerialize.ts @@ -81,7 +81,7 @@ export async function mdxSerialize(source: string, options?: { tocDepth?: number theme: codeHikeTheme, lineNumbers: true, showCopyButton: true, - skipLanguages: [], + skipLanguages: ['mermaid'], autoImport: false, } diff --git a/packages/ui/index.tsx b/packages/ui/index.tsx index d98d81ca7c4..6bbb63a5dc0 100644 --- a/packages/ui/index.tsx +++ b/packages/ui/index.tsx @@ -17,6 +17,7 @@ export * from './src/components/Accordion' export * from './src/components/Collapsible' export * from './src/components/CodeBlock' export * from './src/components/SimpleCodeBlock' +export * from './src/components/Mermaid' // NAV diff --git a/packages/ui/package.json b/packages/ui/package.json index 713cceb7b2c..256d53957b3 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -60,6 +60,7 @@ "input-otp": "^1.2.3", "lodash": "^4.17.21", "lucide-react": "^0.436.0", + "mermaid": "^11.12.1", "next-themes": "^0.3.0", "prism-react-renderer": "^2.3.1", "prop-types": "^15.7.2", diff --git a/packages/ui/src/components/Mermaid/Mermaid.tsx b/packages/ui/src/components/Mermaid/Mermaid.tsx new file mode 100644 index 00000000000..1928c6d16d6 --- /dev/null +++ b/packages/ui/src/components/Mermaid/Mermaid.tsx @@ -0,0 +1,193 @@ +'use client' + +import { useEffect, useState } from 'react' +import mermaid from 'mermaid' +import { useTheme } from 'next-themes' +import { cn } from '../../lib/utils/cn' + +// @mildtomato - 28/11/2025 +// Colors are hardcoded because Mermaid's parser doesn't support CSS variables +const darkThemeVariables = { + background: 'transparent', + mainBkg: '#171717', + primaryTextColor: '#ededed', + secondaryTextColor: '#a0a0a0', + tertiaryTextColor: '#ededed', + textColor: '#ededed', + primaryColor: '#3ecf8e', + primaryBorderColor: '#3ecf8e', + secondaryColor: '#9333ea', + secondaryBorderColor: '#a855f7', + tertiaryColor: '#262626', + tertiaryBorderColor: '#404040', + lineColor: '#525252', + border1: '#404040', + border2: '#525252', + noteBkgColor: '#1a3a2a', + noteTextColor: '#ededed', + noteBorderColor: '#3ecf8e', + actorBkg: '#171717', + actorBorder: '#525252', + actorTextColor: '#ededed', + actorLineColor: '#525252', + activationBkgColor: '#9333ea', + activationBorderColor: '#a855f7', + signalColor: '#ededed', + signalTextColor: '#ededed', + sequenceNumberColor: '#171717', + nodeBkg: '#262626', + nodeBorder: '#404040', + clusterBkg: '#1a1a1a', + clusterBorder: '#404040', + defaultLinkColor: '#3ecf8e', + edgeLabelBackground: '#171717', + attributeBackgroundColorOdd: '#262626', + attributeBackgroundColorEven: '#171717', + rowOdd: '#262626', + rowEven: '#171717', + fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace', + fontSize: '14px', +} + +const lightThemeVariables = { + background: 'transparent', + mainBkg: '#ffffff', + primaryTextColor: '#1c1c1c', + secondaryTextColor: '#6b7280', + tertiaryTextColor: '#1c1c1c', + textColor: '#1c1c1c', + primaryColor: '#3ecf8e', + primaryBorderColor: '#3ecf8e', + secondaryColor: '#9333ea', + secondaryBorderColor: '#a855f7', + tertiaryColor: '#f5f5f5', + tertiaryBorderColor: '#e5e5e5', + lineColor: '#d4d4d4', + border1: '#e5e5e5', + border2: '#d4d4d4', + noteBkgColor: '#ecfdf5', + noteTextColor: '#1c1c1c', + noteBorderColor: '#3ecf8e', + actorBkg: '#ffffff', + actorBorder: '#d4d4d4', + actorTextColor: '#1c1c1c', + actorLineColor: '#d4d4d4', + activationBkgColor: '#9333ea', + activationBorderColor: '#a855f7', + signalColor: '#1c1c1c', + signalTextColor: '#1c1c1c', + sequenceNumberColor: '#ffffff', + nodeBkg: '#f5f5f5', + nodeBorder: '#e5e5e5', + clusterBkg: '#fafafa', + clusterBorder: '#e5e5e5', + defaultLinkColor: '#3ecf8e', + edgeLabelBackground: '#ffffff', + attributeBackgroundColorOdd: '#f5f5f5', + attributeBackgroundColorEven: '#ffffff', + rowOdd: '#f5f5f5', + rowEven: '#ffffff', + fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace', + fontSize: '13px', +} + +export interface MermaidProps { + /** Mermaid diagram definition (e.g. flowchart, sequence, erDiagram) */ + chart: string + /** Additional CSS classes for the container */ + className?: string +} + +/** + * Renders a Mermaid diagram from text. + * + * Supports flowcharts, sequence diagrams, ER diagrams, and other Mermaid syntax. + * Automatically adapts to light/dark theme. + * + * @example + * ```tsx + * B[End] + * `} /> + * ``` + * + * @see https://mermaid.js.org/intro/ + */ +export function Mermaid({ chart, className }: MermaidProps) { + const [svg, setSvg] = useState('') + const [error, setError] = useState(null) + const { resolvedTheme } = useTheme() + + const isDark = resolvedTheme === 'dark' + + useEffect(() => { + if (!resolvedTheme) return + + // Re-initialize mermaid with current theme + mermaid.initialize({ + startOnLoad: false, + theme: 'base', + themeVariables: isDark ? darkThemeVariables : lightThemeVariables, + sequence: { + useMaxWidth: false, + actorMargin: 150, + messageMargin: 60, + noteMargin: 20, + }, + flowchart: { + useMaxWidth: false, + }, + er: { + useMaxWidth: false, + }, + }) + + const renderChart = async () => { + try { + // Mermaid requires a unique ID per render to avoid DOM conflicts + const id = `mermaid-${Math.random().toString(36).substring(2, 11)}` + const { svg } = await mermaid.render(id, chart.trim()) + // Mermaid outputs
which isn't valid XML - fix for browser compatibility + setSvg(svg.replace(//gi, '
')) + setError(null) + } catch (err) { + // Invalid chart syntax throws - display error instead of crashing + console.error('Mermaid rendering error:', err) + setError(err instanceof Error ? err.message : 'Failed to render diagram') + } + } + + renderChart() + }, [chart, resolvedTheme]) + + if (!resolvedTheme) { + return

+ } + + if (error) { + return ( +
+

Mermaid Error: {error}

+
{chart}
+
+ ) + } + + return ( +
+ ) +} diff --git a/packages/ui/src/components/Mermaid/index.tsx b/packages/ui/src/components/Mermaid/index.tsx new file mode 100644 index 00000000000..b6f25b21520 --- /dev/null +++ b/packages/ui/src/components/Mermaid/index.tsx @@ -0,0 +1,2 @@ +export { Mermaid, type MermaidProps } from './Mermaid' + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f97cf8ff744..83c51a55cce 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -263,7 +263,7 @@ importers: version: 15.5.2(@babel/core@7.28.4(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) next-contentlayer2: specifier: 0.4.6 - version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@15.5.2(@babel/core@7.28.4(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1) + version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@15.5.2(@babel/core@7.28.4(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1) next-themes: specifier: ^0.3.0 version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -1409,7 +1409,7 @@ importers: version: 15.5.2(@babel/core@7.28.4(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) next-contentlayer2: specifier: 0.4.6 - version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@15.5.2(@babel/core@7.28.4(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1) + version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@15.5.2(@babel/core@7.28.4(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1) next-themes: specifier: ^0.3.0 version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -2313,6 +2313,9 @@ importers: lucide-react: specifier: ^0.436.0 version: 0.436.0(react@18.3.1) + mermaid: + specifier: ^11.12.1 + version: 11.12.1(supports-color@8.1.1) next: specifier: 'catalog:' version: 15.5.2(@babel/core@7.28.4(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) @@ -4591,6 +4594,9 @@ packages: '@mermaid-js/parser@0.6.2': resolution: {integrity: sha512-+PO02uGF6L6Cs0Bw8RpGhikVvMWEysfAyl27qTlroUB8jSWr1lL0Sf6zi78ZxlSnmgSY2AMMKVgghnN9jTtwkQ==} + '@mermaid-js/parser@0.6.3': + resolution: {integrity: sha512-lnjOhe7zyHjc+If7yT4zoedx2vo4sHaTmtkl1+or8BRTnCtDmcTpAjpzDSfCZrshM5bCoz0GyidzadJAH1xobA==} + '@mertasan/tailwindcss-variables@2.7.0': resolution: {integrity: sha512-rKPhxi/0r6XWP0+OjPmsfrloX/TtQmvONj2Pr3Nl8BNBznQVP3M9sphguDBUDC0AiKYx2xgup3XzAhlIDLPLIA==} engines: {node: '>=12.13.0'} @@ -11154,6 +11160,9 @@ packages: dagre-d3-es@7.0.11: resolution: {integrity: sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==} + dagre-d3-es@7.0.13: + resolution: {integrity: sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q==} + damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} @@ -11504,9 +11513,6 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - dompurify@3.2.4: - resolution: {integrity: sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==} - dompurify@3.2.7: resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==} @@ -14469,6 +14475,9 @@ packages: mermaid@11.12.0: resolution: {integrity: sha512-ZudVx73BwrMJfCFmSSJT84y6u5brEoV8DOItdHomNLz32uBjNrelm7mg95X7g+C6UoQH/W6mBLGDEDv73JdxBg==} + mermaid@11.12.1: + resolution: {integrity: sha512-UlIZrRariB11TY1RtTgUWp65tphtBv4CSq7vyS2ZZ2TgoMjs2nloq+wFqxiwcxlhHUvs7DPGgMjs2aeQxz5h9g==} + meros@1.3.0: resolution: {integrity: sha512-2BNGOimxEz5hmjUG2FwoxCt5HN7BXdaWyFqEwxPTrJzVdABtrL4TiHTcsWSFAxPQ/tOnEaQEJh3qWq71QRMY+w==} engines: {node: '>=13'} @@ -22672,6 +22681,10 @@ snapshots: dependencies: langium: 3.3.1 + '@mermaid-js/parser@0.6.3': + dependencies: + langium: 3.3.1 + '@mertasan/tailwindcss-variables@2.7.0(autoprefixer@10.4.21(postcss@8.5.6))(postcss@8.5.6)': dependencies: autoprefixer: 10.4.21(postcss@8.5.6) @@ -30771,6 +30784,11 @@ snapshots: d3: 7.9.0 lodash-es: 4.17.21 + dagre-d3-es@7.0.13: + dependencies: + d3: 7.9.0 + lodash-es: 4.17.21 + damerau-levenshtein@1.0.8: {} dat.gui@0.7.9: {} @@ -31040,10 +31058,6 @@ snapshots: dependencies: domelementtype: 2.3.0 - dompurify@3.2.4: - optionalDependencies: - '@types/trusted-types': 2.0.7 - dompurify@3.2.7: optionalDependencies: '@types/trusted-types': 2.0.7 @@ -34662,6 +34676,31 @@ snapshots: transitivePeerDependencies: - supports-color + mermaid@11.12.1(supports-color@8.1.1): + dependencies: + '@braintree/sanitize-url': 7.1.1 + '@iconify/utils': 3.0.2(supports-color@8.1.1) + '@mermaid-js/parser': 0.6.3 + '@types/d3': 7.4.3 + cytoscape: 3.33.1 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.1) + cytoscape-fcose: 2.2.0(cytoscape@3.33.1) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.13 + dayjs: 1.11.18 + dompurify: 3.2.7 + katex: 0.16.22 + khroma: 2.1.0 + lodash-es: 4.17.21 + marked: 16.3.0 + roughjs: 4.6.6 + stylis: 4.3.6 + ts-dedent: 2.2.0 + uuid: 11.1.0 + transitivePeerDependencies: + - supports-color + meros@1.3.0(@types/node@22.13.14): optionalDependencies: '@types/node': 22.13.14 @@ -35469,7 +35508,7 @@ snapshots: neo-async@2.6.2: {} - next-contentlayer2@0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@15.5.2(@babel/core@7.28.4(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1): + next-contentlayer2@0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@15.5.2(@babel/core@7.28.4(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1): dependencies: '@contentlayer2/core': 0.4.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1) '@contentlayer2/utils': 0.4.3 @@ -37764,7 +37803,7 @@ snapshots: classnames: 2.5.1 core-js: 3.35.0 decko: 1.2.0 - dompurify: 3.2.4 + dompurify: 3.2.7 eventemitter3: 5.0.1 json-pointer: 0.6.2 lunr: 2.3.9