als-path-tree
Version:
A Node.js library for managing a virtual file system structure, offering functionalities for file and directory operations with a shared storage system.
104 lines (95 loc) • 3.23 kB
JavaScript
const File = require('./file');
const Item = require('./item');
class Directory extends Item {
static File = File
constructor(name, parent = null) {
super(name, parent, false);
this.files = {};
this.subdirectories = {};
if (parent) parent.subdirectories[name] = this;
}
get isEmpty() { return (Object.keys(this.files).length + Object.keys(this.subdirectories).length) === 0 }
get dirs() {
const dirs = new Set()
function getDirs(obj) {
for (const dir in obj.subdirectories) {
dirs.add(obj.subdirectories[dir])
getDirs(obj.subdirectories[dir])
}
}
getDirs(this)
return Array.from(dirs)
}
get list() {
const dirs = this.dirs, files = [];
for (const filename in this.files) {
files.push(this.files[filename])
}
dirs.forEach(dir => {
for (const filename in dir.files) {
files.push(dir.files[filename])
}
})
return { dirs, files }
}
getItem(path) {
const root = this.root
let item = path.startsWith('.') ? this : root
for (let part of this.getParts(path)) {
if (item === root && part === item.name) continue
if (part === '.') continue
if (part === '..') item = item.parent
else item = item.subdirectories[part] || item.files[part] || null
if (!item) break
}
return item
}
addDir(path) {
let dir = this, root = this.root;
if ((Array.isArray(path) && path[0] === '.') || (typeof path === 'string' && path.startsWith('.'))) dir = root
this.getParts(path).forEach(part => {
if (dir === root && part === dir.name) return
if (part === '.') return
if (part === '..') dir = dir.parent
else {
if (!dir.subdirectories[part]) new this.constructor(part, dir)
dir = dir.subdirectories[part]
}
});
return dir
}
addFile(path, meta, content) {
const { parts, filename } = this.splitPath(path)
const dir = this.addDir(parts)
return new this.constructor.File(filename, meta, dir, content)
}
removeIfEmpty() {
if (!this.isEmpty || !this.parent) return
delete this.parent.subdirectories[this.name]
this.parent.removeIfEmpty()
}
delete() {
if (this.parent) delete this.parent.subdirectories[this.name]
this.main.memMonitor.remove(...this.list.files)
this.files = {}; this.subdirectories = {}
this.removeIfEmpty()
}
copyTo(destPath) {
const path = this.path
const root = this.root
const { dirs, files } = this.list
files.forEach(file => {
file.copyTo(file.path.replace(path, destPath))
})
dirs.forEach(dir => { if(dir.isEmpty) {
root.addDir(dir.path.replace(path, destPath))
}})
}
moveTo(destPath) {
if (this.parent) delete this.parent.subdirectories[this.name]
const dir = this.addDir(destPath)
dir.subdirectories[this.name] = this
this.parent = dir
}
}
module.exports = Directory