99 lines
2.7 KiB
TypeScript
99 lines
2.7 KiB
TypeScript
/**
|
|
* Converter registry and shared types for rNotes import/export.
|
|
*
|
|
* All source-specific converters implement NoteConverter.
|
|
* ConvertedNote is the intermediate format between external sources and NoteItem.
|
|
*/
|
|
|
|
import type { NoteItem, SourceRef } from '../schemas';
|
|
|
|
// ── Shared types ──
|
|
|
|
export interface ConvertedNote {
|
|
title: string;
|
|
content: string; // TipTap JSON string
|
|
contentPlain: string; // Plain text for search
|
|
markdown: string; // Original/generated markdown (for canvas shapes)
|
|
tags: string[];
|
|
sourceRef: SourceRef;
|
|
/** Optional note type override */
|
|
type?: NoteItem['type'];
|
|
}
|
|
|
|
export interface ImportResult {
|
|
notes: ConvertedNote[];
|
|
notebookTitle: string;
|
|
warnings: string[];
|
|
}
|
|
|
|
export interface ExportResult {
|
|
data: Uint8Array;
|
|
filename: string;
|
|
mimeType: string;
|
|
}
|
|
|
|
export interface NoteConverter {
|
|
id: string;
|
|
name: string;
|
|
requiresAuth: boolean;
|
|
|
|
/** Import from external source into ConvertedNote[] */
|
|
import(input: ImportInput): Promise<ImportResult>;
|
|
|
|
/** Export NoteItems to external format */
|
|
export(notes: NoteItem[], opts: ExportOptions): Promise<ExportResult>;
|
|
}
|
|
|
|
export interface ImportInput {
|
|
/** ZIP file data for file-based sources (Logseq, Obsidian) */
|
|
fileData?: Uint8Array;
|
|
/** Page/doc IDs for API-based sources (Notion, Google Docs) */
|
|
pageIds?: string[];
|
|
/** Whether to import recursively (sub-pages) */
|
|
recursive?: boolean;
|
|
/** Access token for authenticated sources */
|
|
accessToken?: string;
|
|
}
|
|
|
|
export interface ExportOptions {
|
|
/** Notebook title for the export */
|
|
notebookTitle?: string;
|
|
/** Access token for authenticated sources */
|
|
accessToken?: string;
|
|
/** Target parent page/folder ID for API-based exports */
|
|
parentId?: string;
|
|
}
|
|
|
|
// ── Converter registry ──
|
|
|
|
const converters = new Map<string, NoteConverter>();
|
|
|
|
export function registerConverter(converter: NoteConverter): void {
|
|
converters.set(converter.id, converter);
|
|
}
|
|
|
|
export function getConverter(id: string): NoteConverter | undefined {
|
|
ensureConvertersLoaded();
|
|
return converters.get(id);
|
|
}
|
|
|
|
export function getAllConverters(): NoteConverter[] {
|
|
ensureConvertersLoaded();
|
|
return Array.from(converters.values());
|
|
}
|
|
|
|
// ── Lazy-load converters to avoid circular init ──
|
|
// Each converter imports registerConverter from this file; importing them
|
|
// synchronously at the module level causes a "Cannot access before
|
|
// initialization" error in Bun because the converters Map hasn't been
|
|
// assigned yet when the circular import triggers registerConverter().
|
|
let _loaded = false;
|
|
export function ensureConvertersLoaded(): void {
|
|
if (_loaded) return;
|
|
_loaded = true;
|
|
require('./obsidian');
|
|
require('./logseq');
|
|
require('./notion');
|
|
require('./google-docs');
|
|
}
|