From 38baa374948013c716cbe4b683969557e713fc94 Mon Sep 17 00:00:00 2001 From: Akos Balasko Date: Sat, 20 Jan 2024 16:45:22 +0100 Subject: [PATCH] fix: Invalid note links breaking other links during replacement (#585) * fix: Invalid note links breaking other links during replacement Story: #487 #584 A more robust check in isEvernoteLink protects against invalid links getting into the link map, causing erronious text replacements in apply-links.ts. Previously, all links starting with "https://www.evernote.com" were incorrectly assumed to be note links, now those links are better identified by an expected note link format, while other evernote.com links will be correctly treated as regular web links. * tests fixed --------- Co-authored-by: bumper314 --- .../turndown-rules/internal-links-rule.ts | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/utils/turndown-rules/internal-links-rule.ts b/src/utils/turndown-rules/internal-links-rule.ts index 309344bb..70b67cd9 100644 --- a/src/utils/turndown-rules/internal-links-rule.ts +++ b/src/utils/turndown-rules/internal-links-rule.ts @@ -20,7 +20,25 @@ export const removeDoubleBackSlashes = (str: string): string => { return str.replace(/\\/g, ''); }; const isEvernoteLink = (value: string): boolean => { - return value.startsWith('evernote:///view') || value.startsWith('https://www.evernote.com') + let url; + try { + url = new URL(value); + } catch(e){ + return false; + } + // NOTE: URL automatically converts to lowercase + if (url.protocol === 'evernote:') { + // Internal link format: evernote:///view/92167309/s714/00ba720b-e3f1-49fd-9b43-5d915a3bca8a/00ba720b-e3f1-49fd-9b43-5d915a3bca8a/ + const pathSpl = url.pathname.split('/').filter(Boolean); // Split and removes empty strings + if (pathSpl[0] !== 'view' || pathSpl.length < 4) return false; + return true; + } else if ((url.protocol === 'http:' || url.protocol === 'https:') && url.host === 'www.evernote.com') { + // External link format: https://www.evernote.com/shard/s714/nl/92167309/00ba720b-e3f1-49fd-9b43-5d915a3bca8a/ + const pathSpl = url.pathname.split('/').filter(Boolean); // Removes empty strings + if (pathSpl[0] !== 'shard' || pathSpl.length < 5) return false; + return true; + } + return false; } const getEvernoteUniqueId = (value: string): string => { const urlSpl = value.split('/').reverse() @@ -61,7 +79,9 @@ export const wikiStyleLinksRule = { ? `![[${realValue}]]` : getShortLinkIfPossible(token, value); } - if (value.match(/^(https?:|tel:|www\.|file:|busycalevent:|ftp:|mailto:)/) && !value.startsWith("https://www.evernote.com")) { + + const isValueEvernoteLink = isEvernoteLink(value); + if (value.match(/^(https?:|tel:|www\.|file:|busycalevent:|ftp:|mailto:)/) && !isValueEvernoteLink) { return getShortLinkIfPossible(token, value); } @@ -74,7 +94,7 @@ export const wikiStyleLinksRule = { && yarleOptions.obsidianSettings?.omitLinkDisplayName; const renderedObsidianDisplayName = omitObsidianLinksDisplayName ? '' : `|${displayName}`; - if (isEvernoteLink(value) ) { + if (isValueEvernoteLink) { const fileName = normalizeTitle(token['text']); const noteIdNameMap = RuntimePropertiesSingleton.getInstance(); const uniqueEnd = getUniqueId();