in packages/web-ide-fs/src/browserfs/OverlayFSImpl.ts [191:257]
async rename(oldPath: string, newPath: string): Promise<void> {
// Original impl https://github.com/jvilk/BrowserFS/blob/v1.4.3/src/backend/OverlayFS.ts#L178
// See "Write Strategy" and "Delete Strategy" in class description
this.#throwIfProtectedPath(oldPath);
this.#throwIfProtectedPath(newPath);
const oldExistsInWritable = await this.#existsInWritable(oldPath);
const oldExistsInReadable = await this.#existsInReadable(oldPath);
const oldExists = oldExistsInReadable || oldExistsInWritable;
if (!oldExists) {
throw ApiError.ENOENT(oldPath);
}
if (oldPath === newPath) {
return;
}
if (await this.exists(newPath)) {
throw ApiError.EEXIST(newPath);
}
// what: Optimistically prep newPath directory in writable FS
// why: Without this we could run into errors renaming oldPath to newPath
await mkdirp(this.#writable, dirname(newPath));
const stat = await this.stat(oldPath, false);
if (stat.isFile()) {
// condition: isFile and already exist in writable
// then: we can simply rename
if (oldExistsInWritable) {
await this.#writable.rename(oldPath, newPath);
}
// condition: isFile and exist **only** in readable
// then: we have to write the readable content into writable
else {
const content = await this.#readable.readFile(oldPath, null, FileFlag.getFileFlag('r'));
await this.#writable.writeFile(
newPath,
content,
null,
FileFlag.getFileFlag('w'),
makeModeWritable(stat.mode),
);
}
// what: Add deleted record if oldPath exists in readable
if (oldExistsInReadable) {
await this.#deletedFiles.append('file', oldPath);
}
return;
}
// condition: oldPath isDirectory and exists in readable
// then: we need to move any missing children over to writable
if (oldExistsInReadable) {
await this.#copyFromReadableToWritable(oldPath, { includeChildren: true });
}
await this.#writable.rename(oldPath, newPath);
// what: Add deleted record if oldPath exists in readable
if (oldExistsInReadable) {
await this.#deletedFiles.append('dir', oldPath);
}
}