From 93630ce88dcb07bcdf7445185fe20612a5c22b7b Mon Sep 17 00:00:00 2001 From: Moondragon85 <42060641+Moondragon85@users.noreply.github.com> Date: Sat, 27 Dec 2025 12:52:37 +0100 Subject: feat: add Matter import support (#2245) * Matter import * use zod * fix date parsing --------- Co-authored-by: Mohamed Bassem --- packages/shared/import-export/parsers.ts | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'packages') diff --git a/packages/shared/import-export/parsers.ts b/packages/shared/import-export/parsers.ts index 5b8b01e8..a56cbb98 100644 --- a/packages/shared/import-export/parsers.ts +++ b/packages/shared/import-export/parsers.ts @@ -10,6 +10,7 @@ import { zExportSchema } from "./exporters"; export type ImportSource = | "html" | "pocket" + | "matter" | "omnivore" | "karakeep" | "linkwarden" @@ -97,6 +98,52 @@ function parsePocketBookmarkFile(textContent: string): ParsedBookmark[] { }); } +function parseMatterBookmarkFile(textContent: string): ParsedBookmark[] { + const zMatterRecordSchema = z.object({ + Title: z.string(), + Author: z.string(), + Publisher: z.string(), + URL: z.string(), + Tags: z + .string() + .transform((tags) => (tags.length > 0 ? tags.split(";") : [])), + "Word Count": z.string(), + "In Queue": z.string().transform((inQueue) => inQueue === "False"), + Favorited: z.string(), + Read: z.string(), + Highlight_Count: z.string(), + "Last Interaction Date": z + .string() + .transform((date) => Date.parse(date) / 1000), + "File Id": z.string(), + }); + + const zMatterExportSchema = z.array(zMatterRecordSchema); + + const records = parse(textContent, { + columns: true, + skip_empty_lines: true, + }); + + const parsed = zMatterExportSchema.safeParse(records); + if (!parsed.success) { + throw new Error( + `The uploaded CSV file contains an invalid Matter bookmark file: ${parsed.error.toString()}`, + ); + } + + return parsed.data.map((record) => { + return { + title: record.Title, + content: { type: BookmarkTypes.LINK as const, url: record.URL }, + tags: record.Tags, + addDate: record["Last Interaction Date"], + archived: record["In Queue"], + paths: [], // TODO + }; + }); +} + function parseKarakeepBookmarkFile(textContent: string): ParsedBookmark[] { const parsed = zExportSchema.safeParse(JSON.parse(textContent)); if (!parsed.success) { @@ -347,6 +394,9 @@ export function parseImportFile( case "pocket": result = parsePocketBookmarkFile(textContent); break; + case "matter": + result = parseMatterBookmarkFile(textContent); + break; case "karakeep": result = parseKarakeepBookmarkFile(textContent); break; -- cgit v1.2.3-70-g09d2