Path.js
'use strict';
const path = {
resolve: require('path').resolve,
},
fs = {
readdirSync: require('fs').readdirSync,
rmdirSync: require('fs').rmdirSync,
statSync: require('fs').statSync,
unlinkSync: require('fs').unlinkSync,
};
class Path {
constructor(pathRoot) {
if (!pathRoot || typeof pathRoot !== 'string') throw new Error('Param must be "string"');
this.pathRoot = path.resolve(pathRoot);
}
_get(dir) {
if (!dir || typeof dir !== 'string') throw new Error('Param must be "string"');
if (dir.charAt(0) !== '/') throw new Error(`Invalid path "${dir}"`);
if (!dir.startsWith(this.pathRoot)) return `${this.pathRoot}${dir}`;
return dir;
}
_isDirectory(dir) {
try {
return fs.statSync(dir).isDirectory();
} catch (e) {
throw new Error(`No such file or directory "${dir}"`);
}
}
_getFiles(dir) {
try {
return fs.readdirSync(dir);
} catch (e) {
throw new Error(`Not a directory "${dir}"`);
}
}
get(dir) {
dir = this._get(dir);
if (this._isDirectory(dir) && dir.charAt(dir.length - 1) !== '/')
return `${dir}/`;
return dir;
}
require(path) {
return require(this.get(path));
}
get recursive() {
const self = this;
return {
files: function recursiveFiles(dir, opts, filelist, currentDepth = 0) {
const {match, exclude, maxDepth = -1} = opts || {};
if (maxDepth !== -1 && currentDepth === maxDepth)
return filelist;
dir = self.get(dir);
filelist = filelist || [];
const files = self._getFiles(dir);
for (let i = files.length - 1; i >= 0; i--) {
let file = files[i];
if (self._isDirectory(`${dir}${file}`))
recursiveFiles(`${dir}${file}`, opts, filelist, currentDepth + 1);
else {
let flag = true;
flag &= (match) ? match.test(`${dir}${file}`) : flag;
flag &= (exclude) ? !exclude.test(`${dir}${file}`) : flag;
if (flag)
filelist.push(`${dir}${file}`);
}
}
return filelist;
},
folders: function recursiveFolders(dir, opts, folderlist, currentDepth = 0) {
const {match, exclude, maxDepth = 0} = opts || {};
if (maxDepth > 0 && currentDepth === maxDepth)
return folderlist;
dir = self.get(dir);
folderlist = folderlist || [];
const files = self._getFiles(dir);
for (let i = files.length - 1; i >= 0; i--) {
const file = files[i];
if (self._isDirectory(`${dir}${file}`)) {
let flag = true;
flag &= (match) ? match.test(`${dir}${file}`) : flag;
flag &= (exclude) ? !exclude.test(`${dir}${file}`) : flag;
if (flag)
folderlist.push(`${dir}${file}`);
return recursiveFolders(`${dir}${file}`, opts, folderlist, currentDepth + 1);
}
}
return folderlist;
},
};
}
get remove() {
const self = this,
file = (dir) => fs.unlinkSync(self.get(dir)),
files = (dir, opts) => self.recursive.files(dir, opts).forEach(file),
folder = (dir) => {
try {
fs.rmdirSync(self.get(dir));
} catch (e) {
/* istanbul ignore else */
if (/ENOTEMPTY/g.test(e)) {
const files = self.recursive.files(dir);
for (let i = files.length - 1; i >= 0; i--) {
const file = files[i];
fs.unlinkSync(self.get(file));
}
const folders = self.recursive.folders(dir);
for (let i = folders.length - 1; i >= 0; i--) {
const folder = folders[i];
fs.rmdirSync(self.get(folder));
}
fs.rmdirSync(self.get(dir));
} else throw e;
}
},
folders = (dir, opts) => self.recursive.folders(dir, opts).forEach(folder);
return {file, files, folder, folders};
}
}
module.exports = Path;