aboutsummaryrefslogtreecommitdiffstats
path: root/packages/shared/import-export
diff options
context:
space:
mode:
authorMoondragon85 <42060641+Moondragon85@users.noreply.github.com>2025-12-27 12:52:37 +0100
committerGitHub <noreply@github.com>2025-12-27 11:52:37 +0000
commit93630ce88dcb07bcdf7445185fe20612a5c22b7b (patch)
tree888cefced37ae1a136c322daf65e03d55cbc07c5 /packages/shared/import-export
parent267db791290f4f539d7bda113992e3d1690b0e8b (diff)
downloadkarakeep-93630ce88dcb07bcdf7445185fe20612a5c22b7b.tar.zst
feat: add Matter import support (#2245)
* Matter import * use zod * fix date parsing --------- Co-authored-by: Mohamed Bassem <me@mbassem.com>
Diffstat (limited to 'packages/shared/import-export')
-rw-r--r--packages/shared/import-export/parsers.ts50
1 files changed, 50 insertions, 0 deletions
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;