From 766473c291be78854eeb3646a802df79dc4b8e8b Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 3 Feb 2025 18:59:56 +0200 Subject: [PATCH] fix(search): empty mindmap note breaking search (closes #1107) --- .../expressions/note_content_fulltext.spec.ts | 13 +++ .../expressions/note_content_fulltext.ts | 106 ++++++++++-------- 2 files changed, 73 insertions(+), 46 deletions(-) create mode 100644 src/services/search/expressions/note_content_fulltext.spec.ts diff --git a/src/services/search/expressions/note_content_fulltext.spec.ts b/src/services/search/expressions/note_content_fulltext.spec.ts new file mode 100644 index 000000000..9ef4a7d78 --- /dev/null +++ b/src/services/search/expressions/note_content_fulltext.spec.ts @@ -0,0 +1,13 @@ +import { describe, it, expect } from "vitest"; +import { processMindmapContent } from "./note_content_fulltext.js"; + +describe("processMindmapContent", () => { + it("supports empty JSON", () => { + expect(processMindmapContent("{}")).toEqual(""); + }); + + it("supports blank text / invalid JSON", () => { + expect(processMindmapContent("")).toEqual(""); + expect(processMindmapContent(`{ "node": " }`)).toEqual(""); + }); +}); diff --git a/src/services/search/expressions/note_content_fulltext.ts b/src/services/search/expressions/note_content_fulltext.ts index 083fd3d0e..b0a97da76 100644 --- a/src/services/search/expressions/note_content_fulltext.ts +++ b/src/services/search/expressions/note_content_fulltext.ts @@ -131,52 +131,7 @@ class NoteContentFulltextExp extends Expression { content = content.replace(/ /g, " "); } else if (type === "mindMap" && mime === "application/json") { - let mindMapcontent = JSON.parse(content); - - // Define interfaces for the JSON structure - interface MindmapNode { - id: string; - topic: string; - children: MindmapNode[]; // Recursive structure - direction?: number; - expanded?: boolean; - } - - interface MindmapData { - nodedata: MindmapNode; - arrows: any[]; // If you know the structure, replace `any` with the correct type - summaries: any[]; - direction: number; - theme: { - name: string; - type: string; - palette: string[]; - cssvar: Record; // Object with string keys and string values - }; - } - - // Recursive function to collect all topics - function collectTopics(node: MindmapNode): string[] { - // Collect the current node's topic - let topics = [node.topic]; - - // If the node has children, collect topics recursively - if (node.children && node.children.length > 0) { - for (const child of node.children) { - topics = topics.concat(collectTopics(child)); - } - } - - return topics; - } - - // Start extracting from the root node - const topicsArray = collectTopics(mindMapcontent.nodedata); - - // Combine topics into a single string - const topicsString = topicsArray.join(", "); - - content = normalize(topicsString.toString()); + content = processMindmapContent(content); } else if (type === "canvas" && mime === "application/json") { interface Element { type: string; @@ -215,4 +170,63 @@ class NoteContentFulltextExp extends Expression { } } +export function processMindmapContent(content: string) { + let mindMapcontent; + + try { + mindMapcontent = JSON.parse(content); + } catch (e) { + return ""; + } + + // Define interfaces for the JSON structure + interface MindmapNode { + id: string; + topic: string; + children: MindmapNode[]; // Recursive structure + direction?: number; + expanded?: boolean; + } + + interface MindmapData { + nodedata: MindmapNode; + arrows: any[]; // If you know the structure, replace `any` with the correct type + summaries: any[]; + direction: number; + theme: { + name: string; + type: string; + palette: string[]; + cssvar: Record; // Object with string keys and string values + }; + } + + // Recursive function to collect all topics + function collectTopics(node?: MindmapNode): string[] { + if (!node) { + return []; + } + + // Collect the current node's topic + let topics = [node.topic]; + + // If the node has children, collect topics recursively + if (node.children && node.children.length > 0) { + for (const child of node.children) { + topics = topics.concat(collectTopics(child)); + } + } + + return topics; + } + + // Start extracting from the root node + const topicsArray = collectTopics(mindMapcontent.nodedata); + + // Combine topics into a single string + const topicsString = topicsArray.join(", "); + + return normalize(topicsString.toString()); +} + export default NoteContentFulltextExp;