( root: string, folder: NoteFolder, subpath = '', title?: string )
| 3018 | // createNote (unique title, same folder/subpath resolution) but writes the |
| 3019 | // Excalidraw JSON instead of a Markdown stub. |
| 3020 | export async function createExcalidraw( |
| 3021 | root: string, |
| 3022 | folder: NoteFolder, |
| 3023 | subpath = '', |
| 3024 | title?: string |
| 3025 | ): Promise<NoteMeta> { |
| 3026 | const base = sanitizeNoteTitle(title) || 'Untitled drawing' |
| 3027 | const clean = subpath.replace(/^\/+|\/+$/g, '') |
| 3028 | const topRoot = await folderRoot(root, folder) |
| 3029 | const dir = clean ? resolveSafe(topRoot, clean) : topRoot |
| 3030 | await fs.mkdir(dir, { recursive: true }) |
| 3031 | let finalTitle = base |
| 3032 | for (let n = 2; ; n++) { |
| 3033 | try { |
| 3034 | await fs.access(path.join(dir, `${finalTitle}.excalidraw`)) |
| 3035 | finalTitle = `${base} ${n}` |
| 3036 | } catch { |
| 3037 | break |
| 3038 | } |
| 3039 | } |
| 3040 | const abs = path.join(dir, `${finalTitle}.excalidraw`) |
| 3041 | await fs.writeFile(abs, JSON.stringify(emptyExcalidrawDocument(), null, 2), 'utf8') |
| 3042 | invalidateNoteMetaCache(root, toPosix(path.relative(root, abs))) |
| 3043 | return await readMeta(root, abs, folder) |
| 3044 | } |
| 3045 | |
| 3046 | /** |
| 3047 | * Convert an Obsidian Excalidraw markdown drawing (`*.excalidraw.md`, or a `.md` |
no test coverage detected