MCPcopy Create free account
hub / github.com/ZenNotes/zennotes / renameNote

Function renameNote

apps/desktop/src/main/vault.ts:3107–3154  ·  view source on GitHub ↗
(
  root: string,
  rel: string,
  nextTitle: string
)

Source from the content-addressed store, hash-verified

3105}
3106
3107export async function renameNote(
3108 root: string,
3109 rel: string,
3110 nextTitle: string
3111): Promise<NoteMeta> {
3112 const abs = resolveSafe(root, rel)
3113 const folder = folderOf(root, abs)
3114 if (!folder) throw new Error(`Note not in a known folder: ${rel}`)
3115 const dir = path.dirname(abs)
3116 const trimmed = sanitizeNoteTitle(nextTitle)
3117 // Preserve the file's type on rename — a `.excalidraw` drawing must stay a
3118 // drawing, not get turned into a `.md` note (which would render its JSON).
3119 const ext = isExcalidrawPath(abs) ? '.excalidraw' : '.md'
3120 const target = path.join(dir, `${trimmed}${ext}`)
3121 const willRename = target !== abs
3122 // Snapshot the vault before the rename so inbound [[wikilinks]] still
3123 // resolve to this note under its current name; we rewrite them afterwards.
3124 const notesBefore = willRename ? await listNotes(root) : []
3125 if (willRename) {
3126 // Check for conflicts, but allow case-only renames on case-insensitive FS
3127 try {
3128 await fs.access(target)
3129 const [srcStat, dstStat] = await Promise.all([fs.stat(abs), fs.stat(target)])
3130 if (srcStat.ino !== dstStat.ino) {
3131 throw new Error(`A note named "${trimmed}" already exists in ${folder}`)
3132 }
3133 } catch (e) {
3134 if ((e as NodeJS.ErrnoException).code !== 'ENOENT') throw e
3135 }
3136 // Two-step rename for case-only changes on case-insensitive filesystems
3137 if (abs.toLowerCase() === target.toLowerCase() && abs !== target) {
3138 const tmp = abs + '_rename_tmp_' + Date.now()
3139 await fs.rename(abs, tmp)
3140 await fs.rename(tmp, target)
3141 } else {
3142 await fs.rename(abs, target)
3143 }
3144 }
3145 const meta = await readMeta(root, target, folder)
3146 await moveNoteComments(root, rel, meta.path)
3147 invalidateNoteMetaCache(root, rel)
3148 invalidateNoteMetaCache(root, meta.path)
3149 invalidateVaultTextSearchCache(root)
3150 if (willRename) {
3151 await updateInboundWikilinks(root, notesBefore, rel, meta.title)
3152 }
3153 return meta
3154}
3155
3156/**
3157 * Rewrite every `[[wikilink]]` across the vault that pointed to a note's old

Callers 5

registerIpcFunction · 0.90
NoteListFunction · 0.50
ArchiveViewFunction · 0.50
SidebarFunction · 0.50
cmdRenameFunction · 0.50

Calls 10

isExcalidrawPathFunction · 0.90
sanitizeNoteTitleFunction · 0.85
moveNoteCommentsFunction · 0.85
invalidateNoteMetaCacheFunction · 0.85
updateInboundWikilinksFunction · 0.85
resolveSafeFunction · 0.70
folderOfFunction · 0.70
listNotesFunction · 0.70
readMetaFunction · 0.70

Tested by

no test coverage detected