UNPKG

qqjs

Version:

useful functions for writing node scripts

214 lines (213 loc) 6.06 kB
"use strict"; 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;