diff --git a/src/__mocks__/obsidian.ts b/src/__mocks__/obsidian.ts index 4d0a41b..25354f5 100644 --- a/src/__mocks__/obsidian.ts +++ b/src/__mocks__/obsidian.ts @@ -1,4 +1,4 @@ -export const request = async () => ({}); +export const request = async () => ({}) export class Notice { constructor() {} hide() {} diff --git a/src/replace-links/__tests__/ai-disambiguation.test.ts b/src/replace-links/__tests__/ai-disambiguation.test.ts index ba3be89..464f609 100644 --- a/src/replace-links/__tests__/ai-disambiguation.test.ts +++ b/src/replace-links/__tests__/ai-disambiguation.test.ts @@ -17,26 +17,26 @@ describe("replaceLinks with AI disambiguation", () => { it("should use the AI-resolved path for unlinked words", () => { const body = "I have a meeting." const resolvedAmbiguities = new Map([["meeting", "work/meeting"]]) - + const result = replaceLinks({ body, linkResolverContext: context, resolvedAmbiguities, }) - + expect(result).toBe("I have a [[work/meeting|meeting]].") }) it("should correct existing links if resolvedAmbiguities contains them", () => { const body = "Check [[private/meeting|meeting]] notes." const resolvedAmbiguities = new Map([["[[private/meeting|meeting]]", "work/meeting"]]) - + const result = replaceLinks({ body, linkResolverContext: context, resolvedAmbiguities, }) - + expect(result).toBe("Check [[work/meeting|meeting]] notes.") }) @@ -44,13 +44,13 @@ describe("replaceLinks with AI disambiguation", () => { const body = "Check [[private/meeting]] notes." // The resolveAmbiguities scanner uses the full link as key const resolvedAmbiguities = new Map([["[[private/meeting]]", "work/meeting"]]) - + const result = replaceLinks({ body, linkResolverContext: context, resolvedAmbiguities, }) - + expect(result).toBe("Check [[work/meeting|private/meeting]] notes.") }) }) diff --git a/src/replace-links/replace-links.ts b/src/replace-links/replace-links.ts index 3576609..84bb935 100644 --- a/src/replace-links/replace-links.ts +++ b/src/replace-links/replace-links.ts @@ -734,9 +734,6 @@ const processStandardText = ( // Case comparison happened during trie traversal if ignoreCase is true. const candidateData = candidateMap.get(trieCandidateKey) - // Store the original text matched for potential use as display text - const originalMatchedText = text.substring(i, i + lastCandidate.length) - if (candidateData) { // Check if this is a self-link and should be prevented if (isSelfLink(candidateData, filePath, settings)) { @@ -968,23 +965,23 @@ export const replaceLinks = ({ const mIndex = match.index const segment = bodyWithPlaceholders.slice(lastIndex, mIndex) resultBody += processTextSegment(segment) - + const fullMatch = match[0] if (resolvedAmbiguities?.has(fullMatch)) { // Existing link replacement const resolvedPath = resolvedAmbiguities.get(fullMatch)! const { linkPath, alias: resolvedAlias } = extractLinkParts(resolvedPath) - + // Try to extract existing alias from the matched link const existingLinkRegex = /\[\[([^|\]]+)(?:\|([^\]]+))?\]\]/ const linkMatch = fullMatch.match(existingLinkRegex) const existingPath = linkMatch ? linkMatch[1] : "" const existingAlias = linkMatch ? linkMatch[2] : undefined - - // Use resolved alias if present, otherwise use existing alias, + + // Use resolved alias if present, otherwise use existing alias, // otherwise use existing path (as alias if it was a simple link) const finalAlias = resolvedAlias || existingAlias || (fullMatch.includes("|") ? undefined : existingPath) - + const isInTable = isIndexInsideMarkdownTable(bodyWithPlaceholders, mIndex) resultBody += linkGenerator({ linkPath, diff --git a/src/utils/__tests__/resolve-ambiguities.test.ts b/src/utils/__tests__/resolve-ambiguities.test.ts index 9214da4..36e7196 100644 --- a/src/utils/__tests__/resolve-ambiguities.test.ts +++ b/src/utils/__tests__/resolve-ambiguities.test.ts @@ -37,7 +37,7 @@ describe("resolveAmbiguities", () => { it("should identify ambiguous unlinked words", async () => { const text = "I have a meeting tomorrow." vi.mocked(aiClient.resolveAmbiguitiesBatch).mockResolvedValue( - new Map([["meeting", "work/meeting"]]) + new Map([["meeting", "work/meeting"]]), ) const result = await resolveAmbiguities(text, candidateMap, trie, mockSettings) @@ -48,8 +48,8 @@ describe("resolveAmbiguities", () => { expect.objectContaining({ word: "meeting", candidates: ["work/meeting", "private/meeting"], - }) - ]) + }), + ]), ) expect(result.get("meeting")).toBe("work/meeting") }) @@ -57,7 +57,7 @@ describe("resolveAmbiguities", () => { it("should identify ambiguous existing links for verification", async () => { const text = "Check the [[private/meeting|meeting]] notes." vi.mocked(aiClient.resolveAmbiguitiesBatch).mockResolvedValue( - new Map([["[[private/meeting|meeting]]", "work/meeting"]]) + new Map([["[[private/meeting|meeting]]", "work/meeting"]]), ) const result = await resolveAmbiguities(text, candidateMap, trie, mockSettings) @@ -68,8 +68,8 @@ describe("resolveAmbiguities", () => { expect.objectContaining({ word: "[[private/meeting|meeting]]", candidates: ["work/meeting", "private/meeting"], - }) - ]) + }), + ]), ) expect(result.get("[[private/meeting|meeting]]")).toBe("work/meeting") }) diff --git a/src/utils/ai-client.ts b/src/utils/ai-client.ts index 0eacf9f..58bc0d6 100644 --- a/src/utils/ai-client.ts +++ b/src/utils/ai-client.ts @@ -53,7 +53,8 @@ export const callAI = async ( const data = JSON.parse(response) return data.choices[0].message.content - } catch (error) { + } + catch (error) { console.error("AI Link Enhancer API Error:", error) throw error } @@ -83,10 +84,10 @@ ${JSON.stringify(requests, null, 2)} ` const resultRaw = await callAI(settings, prompt) - + // Clean up potential markdown code blocks if the AI included them const cleanJson = resultRaw.replace(/```json\n?/, "").replace(/\n?```/, "").trim() - + const result = JSON.parse(cleanJson) const resultMap = new Map() diff --git a/src/utils/resolve-ambiguities.ts b/src/utils/resolve-ambiguities.ts index e7ddcae..831a947 100644 --- a/src/utils/resolve-ambiguities.ts +++ b/src/utils/resolve-ambiguities.ts @@ -10,7 +10,7 @@ export const resolveAmbiguities = async ( settings: AutomaticLinkerSettings, ): Promise> => { const requests: AIResolveRequest[] = [] - + // 1. Scan for existing links [[Path|Alias]] or [[Path]] const existingLinkRegex = /\[\[([^|\]]+)(?:\|([^\]]+))?\]\]/g let match: RegExpExecArray | null @@ -18,12 +18,12 @@ export const resolveAmbiguities = async ( const fullMatch = match[0] const path = match[1] const alias = match[2] || path - + const candidateData = candidateMap.get(alias) if (candidateData && candidateData.candidates.length > 1) { const start = Math.max(0, match.index - settings.aiMaxContext) const end = Math.min(text.length, match.index + fullMatch.length + settings.aiMaxContext) - + requests.push({ word: fullMatch, // Using the full link as the "word" key for replacement text: text.slice(start, end), @@ -38,7 +38,7 @@ export const resolveAmbiguities = async ( while (i < text.length) { let node = trie let j = i - let lastMatch: { word: string; data: CandidateData; index: number } | null = null + let lastMatch: { word: string, data: CandidateData, index: number } | null = null while (j < text.length && node.children.has(text[j].toLowerCase())) { node = node.children.get(text[j].toLowerCase())! @@ -53,13 +53,13 @@ export const resolveAmbiguities = async ( if (lastMatch && lastMatch.data.candidates.length > 1) { // Check if it's already inside a link (simple check) - const isInsideLink = text.slice(Math.max(0, i - 2), i) === "[[" || - text.slice(i + lastMatch.word.length, i + lastMatch.word.length + 2) === "]]" - + const isInsideLink = text.slice(Math.max(0, i - 2), i) === "[[" + || text.slice(i + lastMatch.word.length, i + lastMatch.word.length + 2) === "]]" + if (!isInsideLink) { const start = Math.max(0, i - settings.aiMaxContext) const end = Math.min(text.length, i + lastMatch.word.length + settings.aiMaxContext) - + requests.push({ word: lastMatch.word, text: text.slice(start, end), @@ -67,7 +67,8 @@ export const resolveAmbiguities = async ( }) } i += lastMatch.word.length - } else { + } + else { i++ } } diff --git a/vitest.config.ts b/vitest.config.ts index 77eb926..b57a61c 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -5,7 +5,7 @@ export default defineConfig({ test: { includeSource: ["src/**/*.{js,ts}"], alias: { - "obsidian": path.resolve(__dirname, "./src/__mocks__/obsidian.ts"), + obsidian: path.resolve(__dirname, "./src/__mocks__/obsidian.ts"), }, }, })