UNPKG

nxkit

Version:

This is a collection of tools, independent of any other libraries

708 lines (707 loc) 20.4 kB
"use strict"; /* ***** BEGIN LICENSE BLOCK ***** * Distributed under the BSD license: * * Copyright (c) 2015, xuewen.chu * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of xuewen.chu nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL xuewen.chu BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); const buffer_1 = require("buffer"); const Path = require("path"); const fs = require("fs"); __export(require("fs")); function inl_copy_symlink(path, target, options, cb) { if (options.is_cancel) return; fs.lstat(target, function (err, stat) { if (err) return cp(); if (stat.isSymbolicLink() || !stat.isDirectory()) { fs.unlink(target, e => e ? cb(e) : cp()); // rm } else { inl_rm(options, target, (e) => e ? cb(e) : cp()); // rm } }); function cp() { fs.readlink(path, function (err, path) { if (err) { cb(err); } else { fs.symlink(path, target, cb); } }); } } function inl_copy_file(path, target, options, cb) { if (options.is_cancel) return; fs.lstat(target, function (err, stat) { if (err) return cp(); if (stat.isSymbolicLink()) { fs.unlink(target, e => e ? cb(e) : cp()); // rm } else if (!stat.isFile()) { inl_rm(options, target, (e) => e ? cb(e) : cp()); // rm } else { if (!options.replace) { // 不替换 return cb(); // 结束 } else { cp(); } } }); function cp() { var read = fs.createReadStream(path); var write = fs.createWriteStream(target); function error(e) { read.destroy(); write.destroy(); console.error(e); cb(e); } read.on('data', function (buff) { if (options.is_cancel) { read.destroy(); write.destroy(); } else { write.write(buff); } }); read.on('end', function () { if (!options.is_cancel) { write.end(); cb(); } }); read.on('error', error); write.on('error', error); } } function inl_copy_dir(path, target, options, cb) { if (options.is_cancel) return; fs.lstat(target, function (err, stat) { if (err) return cp(); if (stat) { if (stat.isSymbolicLink() || !stat.isDirectory()) { fs.unlink(target, e => e ? cb(e) : fs.mkdir(target, cp)); // rm } } else { fs.mkdir(target, cp); } }); var list = null; function cp(err) { if (err) return cb(err); fs.readdir(path, function (err, ls) { if (err) return cb(err); list = ls; shift(); }); } function shift(err) { if (err) return cb(err); if (!list.length) return cb(); // 完成 var name = list.shift(); if (options.ignore_hide && name[0] == '.') return shift(); // 忽略隐藏 var path1 = path + '/' + name; var target1 = target + '/' + name; fs.lstat(path1, function (err, stat) { if (err) return cb(err); if (stat.isSymbolicLink() && options.symlink) { // copy symlink inl_copy_symlink(path1, target1, options, shift); } else if (stat.isFile()) { inl_copy_file(path1, target1, options, shift); } else if (stat.isDirectory()) { inl_copy_dir(path1, target1, options, shift); } else { console.warn('ignore cp', path1, 'to', target1); shift(); } }); } } function inl_copy_symlink_sync(path, target, options, check) { if (!check(path, target)) return; // 取消 var stat; try { stat = fs.lstatSync(target); } catch (e) { } if (stat) { if (stat.isSymbolicLink() || !stat.isDirectory()) { fs.unlinkSync(target); // rm } else { inl_rm_sync(target); // rm } } fs.symlinkSync(fs.readlinkSync(path), target); } function inl_copy_file_sync(path, target, options, check) { if (!check(path, target)) return; // 取消 var stat; try { stat = fs.lstatSync(target); } catch (e) { } if (stat) { if (stat.isSymbolicLink()) { fs.unlinkSync(target); // rm } else if (!stat.isFile()) { inl_rm_sync(target); // rm } else { if (!options.replace) { // 不替换 return; // 结束 } } } var rfd = fs.openSync(path, 'r'); var wfd = fs.openSync(target, 'w'); var size = 1024 * 100; var buff = buffer_1.Buffer.alloc(size); // 100kb var len = 0; do { if (!check(path, target)) break; // 取消 len = fs.readSync(rfd, buff, 0, size, null); fs.writeSync(wfd, buff, 0, len, null); } while (len == size); fs.closeSync(rfd); fs.closeSync(wfd); } function inl_copy_dir_sync(path, target, options, check) { if (!check(path, target)) return; // 取消 var stat; try { stat = fs.lstatSync(target); } catch (e) { } if (stat) { if (stat.isSymbolicLink() || !stat.isDirectory()) { fs.unlinkSync(target); // rm fs.mkdirSync(target); } } else { fs.mkdirSync(target); } var ls = fs.readdirSync(path); for (var i = 0; i < ls.length; i++) { var name = ls[i]; if (options.ignore_hide && name[0] == '.') continue; // 忽略隐藏 var path1 = path + '/' + name; var target1 = target + '/' + name; let stat = fs.lstatSync(path1); if (stat.isSymbolicLink() && options.symlink) { // copy symlink inl_copy_symlink_sync(path1, target1, options, check); } else if (stat.isFile()) { inl_copy_file_sync(path1, target1, options, check); } else if (stat.isDirectory()) { inl_copy_dir_sync(path1, target1, options, check); } else { console.warn('ignore cp', path1, 'to', target1); } } } function inl_rm_sync(path) { var stat = fs.lstatSync(path); if (stat.isFile() || stat.isSymbolicLink()) { return fs.unlinkSync(path); } else if (!stat.isDirectory()) { return; } var ls = fs.readdirSync(path); for (var i = 0; i < ls.length; i++) { inl_rm_sync(path + '/' + ls[i]); } fs.rmdirSync(path); } function inl_rm(handle, path, cb) { fs.lstat(path, function (err, stat) { if (err) { return cb(err); } if (stat.isFile() || stat.isSymbolicLink()) { if (!handle.is_cancel) { // 没有取消 fs.unlink(path, cb); } return; } else if (!stat.isDirectory()) { return cb(); } var ls = null; function shift(err) { if (err) { return cb(err); } if (!ls.length) { return fs.rmdir(path, cb); } inl_rm(handle, path + '/' + ls.shift(), shift); } //dir fs.readdir(path, function (err, data) { ls = data; shift(err); }); }); } function async_call(func, ...args) { return new Promise(function (resolve, reject) { func(...args, (e, args) => e ? reject(e) : resolve(args)); }); } /** * set dir and file */ function chownr(path, uid, gid, cb) { path = Path.resolve(path); cb = cb || function (err) { if (err) throw Error.new(err); }; function shift(path, _cb) { fs.stat(path, function (err, stat) { if (err) { return cb(err); } if (!stat.isDirectory()) { return _cb(); } var dir = path + '/'; function shift2(ls) { if (!ls.length) { return _cb(); } path = dir + ls.shift(); fs.chown(path, uid, gid, function (err) { if (err) { return cb(err); } shift(path, function () { shift2(ls); }); }); } fs.readdir(dir, function (err, ls) { if (err) { return cb(err); } shift2(ls); }); }); } fs.chown(path, uid, gid, function (err) { if (err) { return cb; } shift(path, cb); }); } exports.chownr = chownr; /** * set user file weight * @param {String} path * @param {String} mode * @param {Function} cb (Optional) */ function chmodr(path, mode, cb) { path = Path.resolve(path); cb = cb || function (err) { if (err) throw Error.new(err); }; function shift(path, _cb) { fs.stat(path, function (err, stat) { if (err) { return cb(err); } if (!stat.isDirectory()) { return _cb(); } var dir = path + '/'; function shift2(ls) { if (!ls.length) { return _cb(); } path = dir + ls.shift(); fs.chmod(path, mode, function (err) { if (err) { return cb(err); } shift(path, function () { shift2(ls); }); }); } fs.readdir(dir, function (err, ls) { if (err) { return cb(err); } shift2(ls); }); }); } fs.chmod(path, mode, function (err) { if (err) { return cb(err); } shift(path, cb); }); } exports.chmodr = chmodr; exports.remove = fs.unlink; exports.removeSync = fs.unlinkSync; /** * remove all file async * @param {String} path * @param {Function} cb (Optional) */ function remover(path, cb) { var handle = { is_cancel: false }; cb = cb || function (err) { if (err) throw Error.new(err); }; fs.lstat(path, function (err, stat) { if (err) { return cb(null); } if (stat.isFile() || stat.isSymbolicLink()) { if (!handle.is_cancel) { // 没有取消 fs.unlink(path, cb); } } else { inl_rm(handle, path, cb); } }); return { cancel: function () { handle.is_cancel = true; cb(null, true); } }; } exports.remover = remover; /** * 删除文件与文件夹 */ function removerSync(path) { try { var stat = fs.lstatSync(path); } catch (err) { return; } if (stat.isFile() || stat.isSymbolicLink()) { fs.unlinkSync(path); } else { inl_rm_sync(path); } } exports.removerSync = removerSync; /** * copy all file * @param {String} path * @param {String} target * @param {Object} options (Optional) * @param {Function} cb (Optional) */ function copy(path, target, options, cb) { path = Path.resolve(path); target = Path.resolve(target); if (typeof options == 'function') { cb = options; options = {}; } var options2 = Object.assign({ ignore_hide: false, replace: true, symlink: true, is_cancel: false, }, options); var cb2 = cb || function (err) { if (err) throw Error.new(err); }; if (options2.ignore_hide && Path.basename(path)[0] == '.') return cb2(null); // 忽略隐藏 fs.lstat(path, function (err, stat) { if (err) { return cb2(err); } mkdirp(Path.dirname(target), function () { if (stat.isSymbolicLink() && options2.symlink) { // copy symlink inl_copy_symlink(path, target, options, cb2); } else if (stat.isFile()) { inl_copy_file(path, target, options2, cb2); } else if (stat.isDirectory()) { inl_copy_dir(path, target, options2, cb2); } else { console.warn('ignore cp', path, 'to', target); cb2(null); } }); }); return { cancel: function () { options2.is_cancel = true; cb2(null, true); } }; } exports.copy = copy; /** * copy all file sync * @param {String} path * @param {String} target * @param {Object} options (Optional) */ function copySync(path, target, options) { path = Path.resolve(path); target = Path.resolve(target); var options2 = Object.assign({ ignore_hide: false, replace: true, symlink: true, isCancel: function () { return false; }, }, options); var check = (source, target) => !options2.isCancel(source, target); if (options2.ignore_hide && Path.basename(path)[0] == '.') return; // 忽略隐藏 var stat = fs.lstatSync(path); mkdirpSync(Path.dirname(target)); if (stat.isSymbolicLink() && options2.symlink) { // copy symlink inl_copy_symlink_sync(path, target, options2, check); } else if (stat.isFile()) { inl_copy_file_sync(path, target, options2, check); } else if (stat.isDirectory()) { inl_copy_dir_sync(path, target, options2, check); } else { console.warn('ignore cp', path, 'to', target); } } exports.copySync = copySync; /** * create all file dir * @param {String} path * @param {String} mode (Optional) * @param {Function} cb (Optional) */ function mkdirp(path, mode, cb) { var mode2 = mode; if (typeof mode == 'function') { cb = mode; mode2 = null; } var cb2 = cb || function (err) { if (err) throw Error.new(err); }; path = Path.resolve(path); fs.exists(path, function (exists) { if (exists) return cb2(null); var mat = path.match(/^(\w+:)?\//); var prefix = mat[0]; var ls = path.substr(prefix.length).split('/'); function shift(err) { if (err) return cb2(err); if (!ls.length) return cb2(null); prefix += ls.shift() + '/'; fs.exists(prefix, function (exists) { if (exists) { return shift(); } fs.mkdir(prefix, mode2, shift); }); } shift(); }); } exports.mkdirp = mkdirp; /** * create all file dir sync * @param {String} path * @param {String} mode (Optional) */ function mkdirpSync(path, mode) { path = Path.resolve(path); if (fs.existsSync(path)) { return; } var mat = path.match(/^(\w+:)?\//); var prefix = mat[0]; var ls = path.substr(prefix.length).split('/'); for (var i = 0; i < ls.length; i++) { prefix += ls[i] + '/'; if (!fs.existsSync(prefix)) { fs.mkdirSync(prefix, mode); } } } exports.mkdirpSync = mkdirpSync; /** * @func inl_ls_sync */ function inl_ls_sync(origin, path, depth, each_cb) { var ls = fs.readdirSync(`${origin}/${path}`); var rev = []; for (var i = 0; i < ls.length; i++) { var name = ls[i]; var pathname = path ? `${path}/${name}` : name; var stat = fs.statSync(`${origin}/${pathname}`); stat.name = name; stat.children = []; if (!each_cb(stat, pathname)) { if (depth && stat.isDirectory()) { stat.children = inl_ls_sync(origin, pathname, depth, each_cb); } } rev.push(stat); } return rev; } async function inl_ls(origin, path, depth, each_cb) { var ls = await async_call(fs.readdir, `${origin}/${path}`); var rev = []; for (var i = 0; i < ls.length; i++) { var name = ls[i]; var pathname = path ? `${path}/${name}` : name; var stat = await async_call(fs.stat, `${origin}/${pathname}`); stat.name = name; stat.children = []; if (!each_cb(stat, pathname)) { if (depth && stat.isDirectory()) { stat.children = await inl_ls(origin, pathname, depth, each_cb); } } rev.push(stat); } return rev; } /** * get all info * @param {String} path * @param {Boolean} depth * @param {Function} cb */ function list(path, depth, each_cb) { path = Path.resolve(path); if (typeof depth == 'function') { each_cb = depth; depth = false; } var depth2 = !!depth; var each_cb2 = each_cb || function () { }; return new Promise(function (reserve, reject) { fs.stat(path, function (err, stat) { if (err) return reject(err); var stat2 = stat; stat2.name = Path.basename(path); stat2.children = []; if (each_cb2(stat2, '')) { return reserve([]); } if (stat.isDirectory()) { inl_ls(path, '', depth2, each_cb2).then(e => reserve(e)).catch(reject); } else { reserve([]); } }); }); } exports.list = list; /** * get dir info */ function listSync(path, depth, each_cb) { path = Path.resolve(path); if (typeof depth == 'function') { each_cb = depth; depth = false; } var depth2 = !!depth; var each_cb2 = each_cb || function () { }; var stat = fs.statSync(path); stat.name = Path.basename(path); stat.children = []; if (each_cb2(stat, '')) { return []; } return stat.isDirectory() ? inl_ls_sync(path, '', depth2, each_cb2) : []; } exports.listSync = listSync; exports.ls = list; exports.ls_sync = listSync; exports.mkdir_p_sync = mkdirpSync; exports.mkdir_p = mkdirp; exports.cp_sync = copySync; exports.cp = copy; exports.rm_r_sync = removerSync; exports.rm_r = remover; exports.chmod_r = chmodr; exports.chown_r = chownr;