UNPKG

gcl

Version:

码农村nodejs类库,完成解决回调陷阱,配置框架,IOC框架,统一多DB访问框架,可扩展日志框架和io/db/net/thread/pool 克隆表达式,加解密算法等等一系列基础类库和算法的实现

422 lines (414 loc) 16 kB
import V from '../common/tool'; import F from 'fs'; import I from './tool'; import P from 'path'; /** * todo * Config基础存储类 拥有getValue(k),setValue(k,v),merge(config)等方法 * @param */ export const Config = class { constructor() { let _ = this; _.data = {}; } getValue(key) { return this.data[key]; } setValue(key, value) { this.data[key] = value; } merge(config) { this.data = V.merge(this.data, config.data); } }; /** * ConfigConvert的基础类模型说明 基本上只有接口定义 未实现任何功能 * */ export const ConfigConvert = class { constructor() { this.needConfig = false; } toConfig() { return null } toStrings(config) { return ""; } }; /** * ConfigConvert的基本定义负责将一个KeyValueMap转换成真实的config */ export const AppSettingsConfigConvert = class extends ConfigConvert { constructor() { super(); } toConfig(val) { let config = new Config(); val = V.getValue(val, {}); for (let k in val) { let v = val[k]; config.data[k] = v; } return config; } }; export const AppSettings = (cm, key) => cm.getConfigValue('AppSettings', key); /** * Config的代理,用于调用configmanger完成config的获取与赋值操作,保护ConfigManager的调用完整逻辑 */ export const ProxyConfig = class extends Config { constructor(config, confkey) { super(); const { _, __ } = pri(this, { config: config, confkey: confkey }); } getValue(key) { const { _, __ } = pri(this); return __.config.getConfigValue(__.confkey, key); } setValue(key, value) { const { _, __ } = pri(this); return __.config.setConfigValue(__.confkey, key, value); } merge(config) { V.shoeException("不支持的功能merge") } }; /** * ConfigManager Config类库的核心类,负责完成链式连接,提供统一的接口供ConfigManager 获取值,并监控配置的变更 */ export const ConfigManager = class extends Config { constructor(parent, resource) { super(); const { _, __ } = pri(this, { dic: {}, data: {}, hasUpdate: false, parent, resource }); if (!parent) { __.dic['ConfigConverts'] = new ___.ConfigConvert(); } _.adapter = ___.getConfigAdapter(); _.adapter.fill(_, __.dic, __.resource); } getConfig(key) { const { _, __ } = pri(this); __.data[key] = __.data[key] || new ProxyConfig(_, key); return __.data[key]; } getConfigValue(config, key) { const { _, __ } = pri(this); if (!__.dic[config]) return ___.getValue(__.parent, config, key); else { return __.dic[config].getValue(key); } } setConfigValue(config, key, value) { const { _, __ } = pri(this); __.hasUpdate = true; if (!__.dic[config]) ___.setValue(__.parent, config, key, value); else __.dic[config].setValue(key, value); } update() { const { _, __ } = pri(this); if (__.hasUpdate) _.adapter.update(_, __.dic, __.resource); } refill() { const { _, __ } = pri(this); __.dic = {}; _.adapter.fill(_, __.dic, __.resource); } }; export const ConfigAdapter = class { constructor() {} fill(cm, dic, resource) { resource = resource.load(); if (typeof(resource) == 'string') { //拿到配置的JSON数据 比JSON不要求严格格式 resource = eval('(' + resource + ')'); } for (var i in resource) { if (i == 'base') continue; //放置base属性被误读 var convert = cm.getConfigValue('ConfigConverts', i); if (!convert) { V.showException('ConfigConverts 没有找到对应的解析器' + i); } else { var val = convert.toConfig(resource[i], convert.needConfig ? cm : null); if (!val) { console.log('ConfigConverts 解析失败' + i + ':'); console.log(resource[i]); } else { if (dic[i]) { dic[i].merge(val); } else { dic[i] = val; } } } } } update(cm, dic, resource) { var data = {}; for (var i in dic) { var convert = cm.getConfigValue('ConfigConverts', i); if (!convert) { V.showException('ConfigConverts 没有找到对应的解析器' + i); } else { var val = convert.toString(dic[i]); if (!val) { console.log('ConfigConverts 解析失败' + i + ':'); console.log(dic[i]); } else { data[i] = val; } } } resource.save(V.toJsonString(data)); } }; export const getConfigManagerFromObj = function(cm, obj) { if (!obj) return cm; return new ConfigManager(cm, (function() { return new class { constructor() { const { __ } = pri(this); if (typeof(obj) === 'string') { obj = eval('(' + obj + ')'); } } load() { return obj; } save() { V.showException('getConfigManagerFromObj不支持此方式'); } }; })()); }; export const getConfigManagerFromJS = function(cm, path) { if (!path) return cm; return new ConfigManager(cm, (function() { return new class { constructor() { if (typeof(path) === 'string') { path = V.include(path); } } load() { return path; } save() { V.showException('getConfigManagerFromJS不支持此方式'); } }; })()); }; /** * 异步获取配置文件 * @param {*} cm * @param {*} path */ export const getConfigManagerFromFile = async function(cm, path) { if (!path) return cm; let config = {}; let cm2 = null; let fill = async() => { var paths = V.isArray(path) ? path : path.split(';'); await V.each(paths, async v => { try { const _v = v; if (!(v.startWith('/') || v.startWith('\\'))) v = (I.execDir() + V.environment.splitChar + v.trim('/').trim('\\')); else v = I.formatPath(v); let cont = (await V.callback(F.readFile, F, v) || '{}'); cont = eval('(' + cont.toString('utf-8').replace(/(\s+\/\/[^\r\n]*[\r\n]*)+|[\r\n\s]+/g, ' ') + ')'); V.merge(config, cont, true); F.watchFile(_v, fill); return false; } catch (e) { console.log(`读取文件${v}错误:` + e.message); throw new Error(`读取文件${path + '\\' + v}错误:` + e.message); } }, true).then(() => { if (cm2) cm2.refill(); else cm2 = new ConfigManager(cm, new class { load() { return config; }; save() { V.showException('getConfigManagerFromFile不支持此方式'); } }); }); return cm2; }; await fill(); return cm2; }; /** * 同步获取配置文件 * @param {*} cm * @param {*} path */ export const getConfigManagerFromFileSync = function(cm, path) { if (!path) return cm; let config = {}; let cm2 = null; let fill = () => { let paths = V.isArray(path) ? path : path.split(';'); paths.forEach(v => { try { const _v = v; if (!(v.startWith('/') || v.startWith('\\'))) v = (I.execDir() + V.environment.splitChar + v.trim('/').trim('\\')); else v = I.formatPath(v); let cont = F.readFileSync(v) || '{}'; cont = eval('(' + cont.toString('utf-8').replace(/(\s+\/\/[^\r\n]*[\r\n]*)+|[\r\n\s]+/g, ' ') + ')'); V.merge(config, cont, true); F.watchFile(_v, fill); return; } catch (e) { console.log(`读取文件${v}错误:` + e.message); throw new Error(`读取文件${path + '\\' + v}错误:` + e.message); } }); if (cm2) cm2.refill(); else cm2 = new ConfigManager(cm, new class { load() { return config; }; save() { V.showException('getConfigManagerFromFileSync不支持此方式'); } }); return cm2; }; fill(); return cm2; }; export const getConfigManagerFromDir = async function(cm, path, regex = '^\\S+\\.npcf$') { if (!path) return cm; if (path.startWith('/') || path.startWith('\\')) path = (P.parse(P.resolve(P.normalize(process.mainModule.filename))).dir + V.environment.splitChar + path.trim('/').trim('\\')); else path = I.formatPath(path); let config = {}; let cm2 = null; let fill = async() => { var data = await V.callback(F.readdir, F, path) || []; const reg = new RegExp(regex); await V.each(data, async v => { try { if (!reg.test(v)) return false; let cont = (await V.callback(F.readFile, F, path + V.environment.splitChar + v) || '{}'); cont = eval('(' + cont.toString('utf-8').replace(/(\s+\/\/[^\r\n]*[\r\n]*)+|[\r\n\s]+/g, ' ') + ')'); V.merge(config, cont, true); return false; } catch (e) { console.log(`读取文件${path + V.environment.splitChar + v}错误:` + e.message); throw new Error(`读取文件${path + V.environment.splitChar + v}错误:` + e.message); } }, true).then(() => { if (cm2) cm2.refill(); else cm2 = new ConfigManager(cm, new class { load() { return config; }; save() { V.showException('getConfigManagerFromFileSync不支持此方式'); } }); }); return cm2; }; F.watchFile(path, fill); await fill(); return cm2; }; export const getConfigManagerFromDirSync = function(cm, path, regex = '^\\S+\\.npcf$') { if (!path) return cm; if (path.startWith('/') || path.startWith('\\')) path = (P.parse(P.resolve(P.normalize(process.mainModule.filename))).dir + V.environment.splitChar + path.trim('/').trim('\\')); else path = I.formatPath(path); let config = {}; let cm2 = null; let fill = () => { let data = F.readdirSync(path) || []; const reg = new RegExp(regex); data.forEach(v => { try { if (!reg.test(v)) return; let cont = F.readFileSync(path + V.environment.splitChar + v) || '{}'; cont = eval('(' + cont.toString('utf-8').replace(/(\s+\/\/[^\r\n]*[\r\n]*)+|[\r\n\s]+/g, ' ') + ')'); V.merge(config, cont, true); return; } catch (e) { console.log(`读取文件${path + V.environment.splitChar + v}错误:` + e.message); throw new Error(`读取文件${path + '\\' + v}错误:` + e.message); } }); if (cm2) cm2.refill(); else cm2 = new ConfigManager(cm, new class { load() { return config; }; save() { V.showException('getConfigManagerFromFileSync不支持此方式'); } }); return cm2; }; F.watchFile(path, fill); fill(); return cm2; }; export const getBaseConfigManager = async() => { if (___.baseConfig) {} else ___.baseConfig = await getConfigManagerFromFile(null, 'base.npcf'); return ___.baseConfig; }; export const getApplicationConfigManager = async() => { if (___.appConfig) {} else ___.appConfig = await getApplicationConfigManagerFromFile(P.parse(process.mainModule.filename).name + '.npcf'); return ___.appConfig; }; export const getApplicationConfigManagerFromJS = async path => getConfigManagerFromJS(await getBaseConfigManager(), path); export const getApplicationConfigManagerFromObj = async obj => getConfigManagerFromObj(await getBaseConfigManager(), obj); export const getApplicationConfigManagerFromFile = async path => getConfigManagerFromFile(await getBaseConfigManager(), path); export const getApplicationConfigManagerFromDir = async path => getConfigManagerFromDir(await getBaseConfigManager(), path); export const getBaseConfigManagerSync = () => { if (___.baseConfig) {} else ___.baseConfig = getConfigManagerFromFileSync(null, 'base.npcf'); return ___.baseConfig; }; export const getApplicationConfigManagerSync = () => { if (___.appConfig) {} else ___.appConfig = getApplicationConfigManagerFromFileSync(P.parse(process.mainModule.filename).name + '.npcf'); return ___.appConfig; }; export const getApplicationConfigManagerFromFileSync = path => getConfigManagerFromFileSync(getBaseConfigManagerSync(), path); export const getApplicationConfigManagerFromDirSync = path => getConfigManagerFromDirSync(getBaseConfigManagerSync(), path); const ___ = { Configs: { ConfigConverts: { AppSettings: { type: 'AppSettingsConfigConvert', path: '/com/coooders/io/config' } } }, getValue: (parent, config, key) => parent ? parent.getConfigValue(config, key) : null, setValue: (parent, config, key, value) => parent ? parent.setConfigValue(config, key, value) : null, ConfigConvert: class extends Config { constructor() { super(); this.data['ConfigConverts'] = this; } toConfig(val) { return new class extends Config { constructor() { super(); let _ = this; for (var i in val) { if (i == 'base') { _.basepath = val.base ? val.base : null; ___.Configs.base = _.basepath; continue; } _.data[i] = (function() { const conf = val[i]; //create要求是类定义 不能是 类名!! //require 如何获取全局的参数或者npm后的参数 全文件地址可以不带盘符 或者相对路径查找文件 //注意使用了地址的类方法 const cls = V.include(conf.path, _.basepath); if (conf.type && cls[conf.type]) return V.create2(cls[conf.type], []); else return V.create2(cls, []); })(); } } }; } toStrings(config) { V.showException('基础解析器不支持此功能'); } }, getConfigAdapter: function() { if (!ConfigAdapter.instance) { ConfigAdapter.instance = new ConfigAdapter(); } return ConfigAdapter.instance; } }; export const Configs = ___.Configs; export default { Configs, Config, ConfigConvert, AppSettingsConfigConvert, ProxyConfig, AppSettings, ConfigManager, ConfigAdapter, getConfigManagerFromJS, getConfigManagerFromObj, getConfigManagerFromFile, getConfigManagerFromDir, getBaseConfigManager, getApplicationConfigManager, getApplicationConfigManagerFromDir, getApplicationConfigManagerFromFile, getApplicationConfigManagerFromJS, getApplicationConfigManagerFromObj, getBaseConfigManagerSync, getApplicationConfigManagerSync, getConfigManagerFromFileSync, getConfigManagerFromDirSync }; const pri = V.pris();