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:
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -732,7 +732,9 @@ export class DocmostClient {
|
||||
// Always fetch subpages to provide context to the agent
|
||||
let subpages: any[] = [];
|
||||
try {
|
||||
subpages = await this.listSidebarPages(resultData.spaceId, pageId);
|
||||
// `pageId` may be a slugId, but the sidebar-pages endpoint requires the
|
||||
// UUID; `resultData.id` holds the resolved UUID returned by getPageRaw.
|
||||
subpages = await this.listSidebarPages(resultData.spaceId, resultData.id);
|
||||
} catch (e: any) {
|
||||
console.warn("Failed to fetch subpages:", e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user