fix(server,mcp): repair createPage import and sidebar subpages lookup

createPage always failed with "generateJSON can only be used in a Node
environment". Root cause: the MCP module (packages/mcp/.../collaboration.ts)
sets `global.window = dom.window` (jsdom) at load time and is imported
in-process by the server's AI-chat tools, leaking a global `window` into the
Node process. The server's self-contained ProseMirror helpers guarded with
`if (typeof window !== 'undefined') throw`, which then became a false positive
and broke POST /pages/import (the endpoint createPage calls).

- server: drop the vestigial `typeof window` guard in generateJSON.ts and
  generateHTML.ts; both helpers create their own happy-dom Window and never
  read the global one. Replace it with an explanatory comment.
- mcp: in DocmostClient.getPage, pass the resolved UUID (resultData.id) to
  listSidebarPages instead of the original pageId, which may be a slugId and
  triggered a Postgres "invalid input syntax for type uuid" (and a silent
  empty subpages list).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
claude_code
2026-06-22 18:06:15 +03:00
parent 373c56c0d3
commit 44fa11e6eb
3 changed files with 14 additions and 11 deletions

View File

@@ -16,11 +16,12 @@ import { getHTMLFromFragment } from './getHTMLFromFragment';
* ```
*/
export function generateHTML(doc: JSONContent, extensions: Extensions): string {
if (typeof window !== 'undefined') {
throw new Error(
'generateHTML can only be used in a Node environment\nIf you want to use this in a browser environment, use the `@tiptap/html` import instead.',
);
}
// No global-`window` guard here: this helper is server-only and self-contained
// (it serializes via `getHTMLFromFragment`, which creates its own happy-dom
// `Window` and never reads the global `window`). A guard on `typeof window`
// would be a false positive whenever a global `window` is injected into the
// Node process (e.g. by the in-process MCP module, which sets `global.window`
// via jsdom).
const schema = getSchema(extensions);
const contentNode = Node.fromJSON(schema, doc);

View File

@@ -21,11 +21,11 @@ export function generateJSON(
extensions: Extensions,
options?: ParseOptions,
): Record<string, any> {
if (typeof window !== 'undefined') {
throw new Error(
'generateJSON can only be used in a Node environment\nIf you want to use this in a browser environment, use the `@tiptap/html` import instead.',
);
}
// No global-`window` guard here: this helper is server-only and self-contained
// (it creates its own happy-dom `Window` below and never reads the global
// `window`). A guard on `typeof window` would be a false positive whenever a
// global `window` is injected into the Node process (e.g. by the in-process
// MCP module, which sets `global.window` via jsdom).
const localWindow = new Window();
const localDOMParser = new localWindow.DOMParser();