mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-12 20:49:53 +08:00
refactor(mcp-server): make the diagram modules usable from the web app
The web app will reuse the MCP server's XML engine instead of its own
copy in lib/utils.ts, so these modules now run in the browser too.
- Relative imports end in .ts, rewritten to .js by tsc
(rewriteRelativeImportExtensions); Next.js resolves them directly
- Every module uses the global DOMParser/XMLSerializer: native in the
browser, linkedom in Node via installDomPolyfill. pages.ts parsed with
linkedom but serialized with the global serializer, which throws in
the browser
- The saxes syntax check moves to xml-syntax.ts, so the browser does not
pull in linkedom; it now also rejects undeclared prefixes such as
xlink:, as the browser does
- Page decompression uses pako and atob instead of node:zlib and Buffer
- hasCells moves to pages.ts, away from the file system code
- The duplicate cell id check counts UserObject/object ids
- wrapCellsInModel drops comments and text before the first cell, which
the web app accepts today
- validateAndFixXml takes { strict: false } for diagrams with user content
- Web tests run these modules with a browser DOM (jsdom)
- saxes becomes a direct dependency of the web app
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { beforeAll, describe, expect, it } from "vitest"
|
||||
import { installDomPolyfill } from "../src/dom.js"
|
||||
import { installDomPolyfill } from "../src/dom.ts"
|
||||
|
||||
// Install the DOM polyfill exactly as index.ts does at runtime — the
|
||||
// helpers under test rely on it.
|
||||
@@ -24,7 +24,7 @@ beforeAll(() => {
|
||||
installDomPolyfill()
|
||||
})
|
||||
|
||||
import { applyDiagramOperations } from "../src/diagram-operations.js"
|
||||
import { applyDiagramOperations } from "../src/diagram-operations.ts"
|
||||
import {
|
||||
addPageToDoc,
|
||||
deletePageFromDoc,
|
||||
@@ -39,8 +39,8 @@ import {
|
||||
projectPage,
|
||||
renamePageInDoc,
|
||||
serializeMxfile,
|
||||
} from "../src/pages.js"
|
||||
import { validateAndFixXml } from "../src/xml-validation.js"
|
||||
} from "../src/pages.ts"
|
||||
import { validateAndFixXml } from "../src/xml-validation.ts"
|
||||
|
||||
const BARE_MODEL_ONE_CELL = `<mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/><mxCell id="2" vertex="1" parent="1" value="Hello"><mxGeometry x="40" y="40" width="100" height="40" as="geometry"/></mxCell></root></mxGraphModel>`
|
||||
|
||||
@@ -296,6 +296,26 @@ describe("xml-validation.ts — multi-page support", () => {
|
||||
expect(result.error).toMatch(/duplicate cell ID/i)
|
||||
})
|
||||
|
||||
it("counts the id of a UserObject/object, not of the mxCell it wraps", () => {
|
||||
const page = (cells: string) =>
|
||||
`<mxfile><diagram id="p1" name="P1"><mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/>${cells}</root></mxGraphModel></diagram></mxfile>`
|
||||
const wrapped = (id: string) =>
|
||||
`<UserObject id="${id}" link="x"><mxCell id="${id}" vertex="1" parent="1"/></UserObject>`
|
||||
expect(validateAndFixXml(page(wrapped("u"))).valid).toBe(true)
|
||||
const clash = validateAndFixXml(
|
||||
page(`${wrapped("2")}<mxCell id="2" vertex="1" parent="1"/>`),
|
||||
)
|
||||
expect(clash.valid).toBe(false)
|
||||
expect(clash.error).toMatch(/duplicate cell ID/i)
|
||||
})
|
||||
|
||||
it("can skip the strict checks for diagrams with user content", () => {
|
||||
const custom = `<mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/><MyObj id="5" label="x"><mxCell vertex="1" parent="1"/></MyObj></root></mxGraphModel>`
|
||||
expect(validateAndFixXml(custom).valid).toBe(true) // fixed by removal
|
||||
const lenient = validateAndFixXml(custom, { strict: false })
|
||||
expect(lenient).toMatchObject({ valid: true, fixed: null })
|
||||
})
|
||||
|
||||
it("rejects duplicate <diagram> ids across the file", () => {
|
||||
const bad = `<mxfile host="app.diagrams.net"><diagram id="p1" name="A"><mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/></root></mxGraphModel></diagram><diagram id="p1" name="B"><mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/></root></mxGraphModel></diagram></mxfile>`
|
||||
const result = validateAndFixXml(bad)
|
||||
|
||||
Reference in New Issue
Block a user