qqjs
Version:
useful functions for writing node scripts
214 lines (213 loc) • 6.06 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const crypto = require("crypto");
const fs = require("fs-extra");
const path = require("path");
const util_1 = require("util");
const log_1 = require("./log");
const path_1 = require("./path");
const deps = {
m: {},
get tmp() { return this.m.tmp = this.m.globby || require('tmp'); },
get globby() { return this.m.globby = this.m.globby || require('globby'); },
};
/**
* creates a directory if it does not exist
* this will automatically join the paths if you pass multiple strings with path.join()
*/
async function mkdirp(...filepaths) {
for (let f of filepaths.map(path_1.join)) {
log_1.log('mkdirp', f);
await fs.mkdirp(f);
}
}
exports.mkdirp = mkdirp;
(function (mkdirp) {
function sync(...filepaths) {
for (let f of filepaths.map(path_1.join)) {
log_1.log('mkdirpSync', f);
fs.mkdirpSync(f);
}
}
mkdirp.sync = sync;
})(mkdirp = exports.mkdirp || (exports.mkdirp = {}));
/**
* glob matcher (find files)
*/
function globby(patterns, options = {}) {
log_1.log('globby', ...patterns);
return deps.globby(patterns, options);
}
exports.globby = globby;
/**
* output string to file
* creates directory if not exists
*/
function write(filepaths, data, options = {}) {
const filepath = path_1.join(filepaths);
log_1.log('write', filepath);
return fs.outputFile(filepath, data, options);
}
exports.write = write;
/**
* read file into string
*/
function read(filepaths, options = {}) {
const filepath = path_1.join(filepaths);
log_1.log('read', filepath);
return fs.readFile(filepath, Object.assign({ encoding: 'utf8' }, options));
}
exports.read = read;
/**
* list files in directory
*/
async function ls(filepaths, options = {}) {
const filepath = path_1.join(filepaths);
// log('ls', filepath)
const files = await fs.readdir(filepath);
if (options.fullpath)
return files.map(f => path_1.join([filepath, f]));
else
return files;
}
exports.ls = ls;
async function fileType(fp) {
try {
const stats = await fs.stat(path_1.join(fp));
if (stats.isSymbolicLink())
return 'symlink';
if (stats.isDirectory())
return 'directory';
if (stats.isFile())
return 'file';
}
catch (err) {
if (err.code === 'ENOENT')
return;
throw err;
}
}
exports.fileType = fileType;
/**
* copy files with fs.copy
* can copy directories
*/
async function cp(source, destinationpaths, options = {}) {
source = path_1.join(source);
let dest = path_1.join(destinationpaths);
switch (await fileType(dest)) {
case 'directory':
dest = path.join(dest, path.basename(source));
break;
case 'file':
await rm(dest);
}
log_1.log('cp', source, dest);
return fs.copy(source, dest, options);
}
exports.cp = cp;
/**
* rm -rf
*/
async function rm(...filesArray) {
for (let f of filesArray.map(path_1.join)) {
log_1.log('rm', f);
await fs.remove(f);
}
}
exports.rm = rm;
async function rmIfEmpty(...filesArray) {
const rmdir = async (f) => {
let removedSomething = false;
const getFiles = async () => (await ls(f)).map(s => path_1.join([f, s]));
let files = await getFiles();
for (let subdir of files) {
if ((await fileType(subdir)) === 'directory') {
await rmdir(subdir);
removedSomething = true;
}
}
// check files again if we removed any
if (removedSomething)
files = await getFiles();
if (files.length === 0)
await rm(f);
};
for (let f of filesArray.map(path_1.join)) {
log_1.log('rmIfEmpty', f);
await rmdir(f);
}
}
exports.rmIfEmpty = rmIfEmpty;
async function mv(source, dest) {
source = path_1.join(source);
dest = path_1.join(dest);
switch (await fileType(dest)) {
case 'directory':
dest = path.join(dest, path.basename(source));
break;
case 'file':
await rm(dest);
}
log_1.log('mv', source, dest);
return fs.move(source, dest);
}
exports.mv = mv;
async function exists(filepath) {
filepath = path_1.join(filepath);
const exists = await fs.pathExists(filepath);
log_1.log('exists', filepath, exists);
return exists;
}
exports.exists = exists;
(function (exists_1) {
function sync(filepath) {
filepath = path_1.join(filepath);
const exists = fs.pathExistsSync(filepath);
log_1.log('exists.sync', filepath, exists);
return exists;
}
exists_1.sync = sync;
})(exists = exports.exists || (exports.exists = {}));
function chmod(filepath, mode) {
filepath = path_1.join(filepath);
log_1.log('chmod', filepath, mode.toString(8));
return fs.chmod(filepath, mode);
}
exports.chmod = chmod;
function ln(from, to) {
from = path_1.join(from);
to = path_1.join(to);
log_1.log('ln', from, to);
return fs.link(from, to);
}
exports.ln = ln;
/**
* create a new temporary directory
* uses tmp
*/
async function tmpDir() {
const output = await util_1.promisify(deps.tmp.dir)();
log_1.log('tmpDir', output.name);
return output.name;
}
exports.tmpDir = tmpDir;
async function emptyDir(filepath) {
filepath = path_1.join(filepath);
log_1.log('emptyDir', filepath);
await fs.mkdirp(path.dirname(filepath));
return fs.emptyDir(filepath);
}
exports.emptyDir = emptyDir;
async function hash(algo, fp) {
const f = path_1.join(fp);
log_1.log('hash', algo, f);
return new Promise((resolve, reject) => {
const hash = crypto.createHash(algo);
const stream = fs.createReadStream(f);
stream.on('error', err => reject(err));
stream.on('data', chunk => hash.update(chunk));
stream.on('end', () => resolve(hash.digest('hex')));
});
}
exports.hash = hash;
;