gcl
Version:
码农村nodejs类库,完成解决回调陷阱,配置框架,IOC框架,统一多DB访问框架,可扩展日志框架和io/db/net/thread/pool 克隆表达式,加解密算法等等一系列基础类库和算法的实现
247 lines (239 loc) • 8.56 kB
JavaScript
import V from '../common/tool';
import F from 'fs';
import P from 'path';
/**
*
*/
export const formatPath = path => P.format(P.parse(P.resolve(P.normalize(path))));
export const execDir = () => P.parse(P.resolve(P.normalize(process.mainModule.filename))).dir;
export const createDir = function(target) {
const tt = P.parse(P.resolve(P.normalize(target)));
let sb = V.sb();
let dirs = (tt.base.indexOf('.') >= 0 ? tt.dir : P.format(tt)).split(V.environment.splitChar);
return V.each(dirs, async v => {
sb.append(v + V.environment.splitChar);
const path = sb.toString();
if (!await V.callback(call => F.exists(path, ist => call(null, ist))))
await V.callback(F.mkdir, F, path);
return false;
}, true);
};
export const copyFile = async function(source, target) {
let istrue = await V.callback(call => F.exists(source, ist => call(null, ist)));
if (istrue) {
await createDir(target);
await V.callback(call => {
let tar = F.createWriteStream(target);
tar.on('error', call);
tar.on('finish', call);
let src = F.createReadStream(source);
src.pipe(tar);
})
return true;
} else throw new Error(`源文件${source}没有找到`);
};
export const moveFile = async(source, target) => {
await copyFile(source, target);
await V.callback(F.unlink, F, source);
return true;
};
export const copyDir = async function(source, target, isMove) {
let tt = P.parse(P.resolve(P.normalize(target)));
target = P.format(tt);
tt = P.parse(P.resolve(P.normalize(source)));
source = P.format(tt);
let istrue = await V.callback((call) => F.exists(source, (istrue) => call(null, istrue)));
if (istrue) {
istrue = await V.callback((call) => F.exists(target, (istrue) => call(null, istrue)));
if (!istrue && !(target.endWith('\\') || target.endWith('/'))) {
await V.callback(F.mkdir, F, target);
}
const st = await V.callback(F.stat, F, source);
if (!st.isDirectory()) throw new Error(`${source}不是文件夹`);
else {
let paths = await V.callback(F.readdir, F, source);
await V.each(paths, async v => {
let _src = `${source}/${v}`,
_dst = `${target}/${v}`;
let st = await V.callback(F.stat, F, _src);
if (st.isFile()) {
if (isMove) await moveFile(_src, _dst);
else await copyFile(_src, _dst);
} else if (st.isDirectory()) {
if (isMove) await moveDir(_src, _dst);
else await copyDir(_src, _dst);
}
return false;
}, true);
return true;
}
} else throw new Error(`源文件夹${source}没有找到`);
}
export const moveDir = async(source, target) => {
await copyDir(source, target, true);
await V.callback(F.rmdir, F, source);
};
/**
*
* @param {string} source 目标文件夹
*/
export const rmDir = async(source) => {
let tt = P.parse(P.resolve(P.normalize(source)));
source = P.format(tt);
let istrue = await V.callback((call) => F.exists(source, (istrue) => call(null, istrue)));
if (istrue) {
const st = await V.callback(F.stat, F, source);
if (!st.isDirectory()) throw new Error(`${source}不是文件夹`);
else {
let paths = await V.callback(F.readdir, F, source);
await V.each(paths, async v => {
let _src = `${source}/${v}`;
let st = await V.callback(F.stat, F, _src);
if (st.isFile()) {
await V.callback(F.unlink, F, _src);
} else if (st.isDirectory()) {
await rmDir(_src);
}
return false;
}, true);
await V.callback(F.rmdir, F, source);
return true;
}
} else throw new Error(`源文件夹${source}没有找到`);
};
export const checker = class {
constructor(call) {
const that = this;
const { _, __ } = pri(that, {
call: call,
list: [],
isEnd: false,
check: () => {
const { _, __ } = pri(that);
if (!__.isEnd) {
let isF = true;
V.each(__.list, v => { isF = isF && v.isEnd; return false; }).then(() => {
if (isF) {
__.isEnd = true;
if (__.call) {
let f = __.call;
delete __.call;
V.each(__.list, v => { v.removeChecker(); return false; }).then(f);
}
}
});
}
}
});
}
push(stream) {
const { _, __ } = pri(this);
const callback = () => {
stream.isEnd = true;
__.check();
};
stream.on('end', callback);
stream.on('finish', callback);
stream.removeChecker = () => {
stream.removeListener('end', callback);
stream.removeListener('finish', callback);
};
__.list.push(stream);
}
};
/**
* 对于流对象转换的简单实现
* @param {*} s
* @param {*} t
*/
export const transform = async function(s, t) {
if (!s.pipe) throw new Error('源对象不是Stream类型!');
if (!t.pipe) throw new Error('目标对象不是Stream类型!');
return await V.callback(call => {
t.on('error', call);
t.on('finish', call);
s.pipe(t);
});
}
export const tranform = transform;
/**
* 实现 JSON向另一个JSON的转换,其中keys由 "a[0][1].count":"aaa[333].abc" 这种赋值方式 键值对定义
* @param {*} ret 此次操作对象 {ope:}
* @param {*} keys 此次赋值用Key 譬如session,temp/share,set
*/
export const convert = function(ret, keys) {
var res = {};
for(var method in keys){
var p = ret,v=res,lp=null,lv=null;
var k = method.replace(/[\[\]\.]+/g,'.').trim('.').split('.');
k.map((_k,_i)=>{
lp=_k;
//处理数组
if (k.length - _i > 1)
p = p!==undefined && p[_k] || undefined;
});
if(p===undefined || p[lp]=== undefined) continue;
//p是最终结果的上一级;
k = (''+keys[method]).split('.');
k.map((_k,_i)=>{
if (_k.indexOf('[') >= 0) {
_k = _k.replace(/[\[\]\.]+/g,'.').trim('.').split('.');
//使用循环比shift更快
_k.forEach((_name2, _i2) => {
lv=_name2;
//长度等于最大值+1
if (_k.length - _i2 > 1) {
if (v[_name2]===undefined) v[_name2] = [];
v = v[_name2];
} else {
if (v[_name2]===undefined) v[_name2] = {};
}
});
} else {
//处理非数组对象 实现 a.count
//长度等于最大值+1
_k = _k.replace(/[\[\]\.]+/g,'.').trim('.').split('.');
_k.forEach((_name2, _i2)=>{
lv=_name2;
//处理数组
if (_k.length - _i2 > 1) {
if (v[_name2]===undefined) v[_name2] = {};
v = v[_name2];
} else {
if (v[_name2]===undefined) v[_name2] = {};
}
})
}
if (k.length - _i > 1) {
v = v[lv];
}
});
v[lv] = p && p[lp];
}
return res;
};
/**
* 负责将JSON展平成为JSON转换用字典
* @param {*} json
*/
export const toConvertIdic = function(json={}) {
var res = {},stack =[{k:'',p:json}];
while(stack.length){
var {k,p} = stack.pop();
for(var key in p)
if(typeof p[key] == 'string')
res[(k?k+'.':'')+key] = p[key];
else stack.push({k:(k?k+'.':'')+key,p:p[key]});
}
return res;
};
/**
* 负责JSON键值互转
*/
export const revert = function(json={}) {
var ret = {};
for(var k in json) ret[json[k]] = k;
return ret;
};
export default { formatPath, execDir, createDir, copyFile, moveFile, copyDir, moveDir, checker, transform, tranform, rmDir,convert,toConvertIdic,revert }
const pri = V.pris();