From 343f14848f2d75c2e18efdc8503b3e38e9dc438a Mon Sep 17 00:00:00 2001 From: tianma-if Date: Tue, 20 Oct 2026 22:47:28 +0800 Subject: [PATCH] fix(desktop): parse Markdown when creating imported notes --- apps/web/src/lib/desktop-repository.test.mjs | 23 ++++++++++++++++++++ apps/web/src/lib/desktop-repository.ts | 8 +++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/apps/web/src/lib/desktop-repository.test.mjs b/apps/web/src/lib/desktop-repository.test.mjs index 64e3a17d..d180a522 100644 --- a/apps/web/src/lib/desktop-repository.test.mjs +++ b/apps/web/src/lib/desktop-repository.test.mjs @@ -294,3 +294,26 @@ describe("desktop note duplication", () => { }); }); }); + + +describe("desktop Markdown note creation", () => { + test("parses imported Markdown before sending it to the sidecar", async () => { + const markdown = "### 项目经历\n\n**项目亮点:**\n\n* 使用 `Next.js`\n* [文档](https://example.com)"; + await createDesktopRepository().createMemo({ notebookId: "nb", title: "简历", contentMarkdown: markdown, tags: [] }); + expect(lastRequest.method).toBe("memo.create"); + expect(lastRequest.params.contentMarkdown).toBe(markdown); + const nodes = lastRequest.params.contentJson.content; + expect(nodes[0]).toMatchObject({ type: "heading", attrs: { level: 3 } }); + expect(nodes[1].content[0].marks).toContainEqual({ type: "bold" }); + expect(nodes[2].type).toBe("bulletList"); + expect(lastRequest.params.contentText).not.toContain("###"); + expect(lastRequest.params.contentText).not.toContain("**"); + }); + + test("preserves an explicitly supplied rich document", async () => { + const contentJson = { type: "doc", content: [{ type: "paragraph", content: [{ type: "text", text: "**literal**" }] }] }; + await createDesktopRepository().createMemo({ notebookId: "nb", title: "Rich", contentJson, contentMarkdown: "different", tags: [] }); + expect(lastRequest.params.contentJson).toEqual(contentJson); + expect(lastRequest.params.contentText).toBe("**literal**"); + }); +}); diff --git a/apps/web/src/lib/desktop-repository.ts b/apps/web/src/lib/desktop-repository.ts index e03d5de4..e08b2a24 100644 --- a/apps/web/src/lib/desktop-repository.ts +++ b/apps/web/src/lib/desktop-repository.ts @@ -7,7 +7,7 @@ import type { DesktopRpcParams, DesktopRpcResponses, } from "@edgeever/shared"; -import { docToMarkdown, docToText, type MemoDetail } from "@edgeever/shared"; +import { docToMarkdown, docToText, markdownToDoc, type MemoDetail } from "@edgeever/shared"; import { localizeDefaultMemoTemplate } from "@edgeever/shared/memo-template-seeds"; import type { EdgeEverRepository } from "@/lib/repository"; import { api, getConfiguredDesktopApiBaseUrl } from "@/lib/api"; @@ -312,10 +312,14 @@ export const createDesktopRepository = (): EdgeEverRepository => ({ }, createMemo: (input) => { + // The sidecar fallback wraps raw lines as paragraphs; parse Markdown here + // with the same schema used by the editor before persisting a new note. + const contentJson = input.contentJson ?? markdownToDoc(input.contentMarkdown ?? ""); const rpcParams: DesktopMemoCreateParams = { ...input, + contentJson, contentMarkdown: mapMarkdownResourceUrls(input.contentMarkdown, toApiResourceUrl), - contentText: input.contentJson ? docToText(input.contentJson) : undefined, + contentText: docToText(contentJson), }; return request("memo.create", rpcParams).then((result) => { window.dispatchEvent(new CustomEvent("edgeever:sync-queue-changed"));