mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-03 20:06:08 +01:00 
			
		
		
		
	feat(import/zip): support root-relative paths
This commit is contained in:
		@@ -283,7 +283,7 @@ $$`;
 | 
			
		||||
 | 
			
		||||
    it("supports wikilink with root-relative path", () => {
 | 
			
		||||
        const input = `oh no my banana I bought on [[journal/monday]] has gone off! I’m taking it back to the [[other/shop]] for a refund`;
 | 
			
		||||
        const expected = `<p>oh no my banana I bought on <a class="reference-link" href="journal/monday">journal/monday</a> has gone off! I’m taking it back to the <a class="reference-link" href="other/shop">other/shop</a> for a refund</p>`;
 | 
			
		||||
        const expected = `<p>oh no my banana I bought on <a class="reference-link" href="/journal/monday">journal/monday</a> has gone off! I’m taking it back to the <a class="reference-link" href="/other/shop">other/shop</a> for a refund</p>`;
 | 
			
		||||
        expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -215,7 +215,7 @@ function restoreFromMap(text: string, map: Map<string, string>): string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function processWikiLinks(paragraph: string) {
 | 
			
		||||
    paragraph = paragraph.replaceAll(/\[\[([^\[\]]+)\]\]/g, `<a class="reference-link" href="$1">$1</a>`);
 | 
			
		||||
    paragraph = paragraph.replaceAll(/\[\[([^\[\]]+)\]\]/g, `<a class="reference-link" href="/$1">$1</a>`);
 | 
			
		||||
    return paragraph;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,7 @@ async function importZip(taskContext: TaskContext, fileBuffer: Buffer, importRoo
 | 
			
		||||
    const createdPaths: Record<string, string> = { "/": importRootNote.noteId, "\\": importRootNote.noteId };
 | 
			
		||||
    let metaFile: MetaFile | null = null;
 | 
			
		||||
    let firstNote: BNote | null = null;
 | 
			
		||||
    let topLevelPath = "";
 | 
			
		||||
    const createdNoteIds = new Set<string>();
 | 
			
		||||
 | 
			
		||||
    function getNewNoteId(origNoteId: string) {
 | 
			
		||||
@@ -257,29 +258,33 @@ async function importZip(taskContext: TaskContext, fileBuffer: Buffer, importRoo
 | 
			
		||||
        saveAttributes(note, noteMeta);
 | 
			
		||||
 | 
			
		||||
        firstNote = firstNote || note;
 | 
			
		||||
 | 
			
		||||
        return noteId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getEntityIdFromRelativeUrl(url: string, filePath: string) {
 | 
			
		||||
        while (url.startsWith("./")) {
 | 
			
		||||
            url = url.substr(2);
 | 
			
		||||
        let absUrl;
 | 
			
		||||
        if (!url.startsWith("/")) {
 | 
			
		||||
            while (url.startsWith("./")) {
 | 
			
		||||
                url = url.substr(2);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let absUrl = path.dirname(filePath);
 | 
			
		||||
 | 
			
		||||
            while (url.startsWith("../")) {
 | 
			
		||||
                absUrl = path.dirname(absUrl);
 | 
			
		||||
 | 
			
		||||
                url = url.substr(3);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (absUrl === ".") {
 | 
			
		||||
                absUrl = "";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            absUrl += `${absUrl.length > 0 ? "/" : ""}${url}`;
 | 
			
		||||
        } else {
 | 
			
		||||
            absUrl = topLevelPath + url;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let absUrl = path.dirname(filePath);
 | 
			
		||||
 | 
			
		||||
        while (url.startsWith("../")) {
 | 
			
		||||
            absUrl = path.dirname(absUrl);
 | 
			
		||||
 | 
			
		||||
            url = url.substr(3);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (absUrl === ".") {
 | 
			
		||||
            absUrl = "";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        absUrl += `${absUrl.length > 0 ? "/" : ""}${url}`;
 | 
			
		||||
 | 
			
		||||
        const { noteMeta, attachmentMeta } = getMeta(absUrl);
 | 
			
		||||
 | 
			
		||||
        if (attachmentMeta && attachmentMeta.attachmentId && noteMeta.noteId) {
 | 
			
		||||
@@ -527,20 +532,28 @@ async function importZip(taskContext: TaskContext, fileBuffer: Buffer, importRoo
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // we're running two passes to make sure that the meta file is loaded before the rest of the files is processed.
 | 
			
		||||
 | 
			
		||||
    // we're running two passes in order to obtain critical information first (meta file and root)
 | 
			
		||||
    const topLevelItems = new Set<string>();
 | 
			
		||||
    await readZipFile(fileBuffer, async (zipfile: yauzl.ZipFile, entry: yauzl.Entry) => {
 | 
			
		||||
        const filePath = normalizeFilePath(entry.fileName);
 | 
			
		||||
 | 
			
		||||
        // make sure that the meta file is loaded before the rest of the files is processed.
 | 
			
		||||
        if (filePath === "!!!meta.json") {
 | 
			
		||||
            const content = await readContent(zipfile, entry);
 | 
			
		||||
 | 
			
		||||
            metaFile = JSON.parse(content.toString("utf-8"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // determine the root of the .zip (i.e. if it has only one top-level folder then the root is that folder, or the root of the archive if there are multiple top-level folders).
 | 
			
		||||
        const firstSlash = filePath.indexOf("/");
 | 
			
		||||
        const topLevelPath = (firstSlash !== -1 ? filePath.substring(0, firstSlash) : filePath);
 | 
			
		||||
        topLevelItems.add(topLevelPath);
 | 
			
		||||
 | 
			
		||||
        zipfile.readEntry();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    topLevelPath = (topLevelItems.size > 1 ? "" : topLevelItems.values().next().value ?? "");
 | 
			
		||||
 | 
			
		||||
    await readZipFile(fileBuffer, async (zipfile: yauzl.ZipFile, entry: yauzl.Entry) => {
 | 
			
		||||
        const filePath = normalizeFilePath(entry.fileName);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user