Files
next-ai-draw-io/packages/mcp-server/src/new-diagram.ts
T
dayuan.jiang e49e9f0c47 refactor(web): validate and repair diagram XML with the MCP server's engine
- Delete the web app's own copy of the XML checks and repairs from
  lib/utils.ts (1,074 lines). loadDiagram now uses the MCP server's
  validateAndFixXml without the strict checks, because the XML may hold
  the user's own diagram
- display_diagram and append_diagram prepare the model's XML with the new
  shared prepareNewDiagram, also used by the MCP create_new_diagram: wrap,
  validate strictly and auto-fix while it is still a bare model (where
  duplicate ids are renamed), then turn it into an mxfile
- The streaming preview of display_diagram no longer redraws the model's
  raw cells after the tool handler loaded the checked diagram, and drops
  a queued preview once the input is complete. That redraw lost
  auto-fixes and UserObject/object wrappers, so a linked cell lost its
  label; it also showed a second error toast
- The web repair regression tests now run against the MCP functions
- New e2e test checks the canvas content after display_diagram
- Fix the e2e upload tests, whose file input locator also matched the
  template import input
2026-10-04 12:44:01 +09:00

37 lines
1.3 KiB
TypeScript

/**
* A whole new diagram written by the model, for the create_new_diagram tool
* and the web app's display_diagram tool.
*/
import { normalizeToMxfile, wrapCellsInModel } from "./pages.ts"
import { validateAndFixXml } from "./xml-validation.ts"
export type NewDiagram =
| { ok: true; xml: string; fixes: string[] }
| { ok: false; error: string }
/**
* Bare cells get the wrapper and root cells first, since the strict parser
* rejects several top-level elements. Then the XML is validated and
* auto-fixed while it is still a bare model, where duplicate ids are
* renamed, and finally turned into an <mxfile>.
*/
export function prepareNewDiagram(
input: string,
page: { pageId?: string; pageName?: string } = {},
): NewDiagram {
let xml = wrapCellsInModel(input)
const { valid, error, fixed, fixes } = validateAndFixXml(xml)
if (fixed) xml = fixed
if (!valid) {
return { ok: false, error: `XML validation failed - ${error}` }
}
const normalized = normalizeToMxfile(xml, page)
if (!normalized) {
return {
ok: false,
error: "XML must be the mxCell elements of one page, a <mxGraphModel>, or an <mxfile> with one or more <diagram> children.",
}
}
return { ok: true, xml: normalized, fixes }
}