feat: expose renderMarkdownToHtml on ExtensionManager (#10700)

## Summary

Expose `renderMarkdownToHtml()` on the `ExtensionManager` interface so
custom node extensions can render markdown to sanitized HTML without
bundling their own copies of `marked`/`DOMPurify`.

## Motivation

Multiple custom node packs (KJNodes, comfy_mtb, rgthree-comfy) bundle
their own markdown rendering libraries to implement help popups on
nodes. This causes:

- **Cloud breakage**: KJNodes uses a `kjweb_async` pattern (custom
aiohttp static route) to lazily load `marked.min.js` and
`purify.min.js`. This 404s on Cloud because the custom route is not
registered.
- **Redundant bundling**: Both `marked` (^15.0.11) and `dompurify`
(^3.2.5) are already direct dependencies of the frontend, used
internally by `markdownRendererUtil.ts`, `NodePreview.vue`,
`WhatsNewPopup.vue`, etc.
- **XSS risk**: Custom nodes using raw `marked` without `DOMPurify`
could introduce XSS vulnerabilities.

By exposing the existing `renderMarkdownToHtml()` through the official
`ExtensionManager` API, custom nodes can:
```js
const html = app.extensionManager.renderMarkdownToHtml(nodeData.description)
```
...instead of bundling and loading their own copies.

## Changes

- **`src/types/extensionTypes.ts`**: Add `renderMarkdownToHtml(markdown:
string, baseUrl?: string): string` to the `ExtensionManager` interface
with JSDoc.
- **`src/stores/workspaceStore.ts`**: Import and re-export
`renderMarkdownToHtml` from `@/utils/markdownRendererUtil`.

## Impact

- **Zero bundle size increase** — the function and its dependencies are
already bundled in the `vendor-markdown` chunk.
- **No breaking changes** — purely additive to the `ExtensionManager`
interface.
- **Follows existing pattern** — same approach as `toast`, `dialog`,
`command`, `setting` on `ExtensionManager`.

Related: #TBD (long-term plan for custom node extension library
dependencies)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10700-feat-expose-renderMarkdownToHtml-on-ExtensionManager-3326d73d36508149bc1dc6bb45e7c077)
by [Unito](https://www.unito.io)
This commit is contained in:
Christian Byrne
2026-03-29 14:51:45 -07:00
committed by GitHub
parent 798f6de4a9
commit 367f810702
2 changed files with 11 additions and 1 deletions

View File

@@ -9,6 +9,7 @@ import type { Settings } from '@/schemas/apiSchema'
import { useColorPaletteService } from '@/services/colorPaletteService'
import { useDialogService } from '@/services/dialogService'
import type { SidebarTabExtension, ToastManager } from '@/types/extensionTypes'
import { renderMarkdownToHtml } from '@/utils/markdownRendererUtil'
import { useApiKeyAuthStore } from './apiKeyAuthStore'
import { useCommandStore } from './commandStore'
@@ -113,7 +114,8 @@ function workspaceStoreSetup() {
registerSidebarTab,
unregisterSidebarTab,
getSidebarTabs
getSidebarTabs,
renderMarkdownToHtml
}
}

View File

@@ -117,6 +117,14 @@ export interface ExtensionManager {
// Execution error state (read-only)
lastNodeErrors: Record<NodeId, NodeError> | null
lastExecutionError: ExecutionErrorWsMessage | null
/**
* Renders a markdown string to sanitized HTML.
* Uses marked (GFM) + DOMPurify. Safe for direct use with innerHTML.
* @param markdown - The markdown string to render.
* @param baseUrl - Optional base URL for resolving relative image/media paths.
*/
renderMarkdownToHtml(markdown: string, baseUrl?: string): string
}
export interface CommandManager {