magic-oopjs
Version:
新增了 多线程的异常日志输出
1,238 lines (1,066 loc) • 74.9 kB
JavaScript
const { getDataType, objectDeepCompare } = require("./utils/function");
const { isFunction, validate, isAsyncFunction, isArray, isObject } = getDataType();
const Joi = require('@hapi/joi');
const colors = require("colors");
const {
Worker, MessageChannel, MessagePort, isMainThread, parentPort
} = require('worker_threads');
var errorMsg = "";
//判断两个对象是否相等
function _deepCompare(x, y) {
var i, l, leftChain, rightChain;
function compare2Objects(x, y) {
var p;
// remember that NaN === NaN returns false
// and isNaN(undefined) returns true
if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
return true;
}
// Compare primitives and functions.
// Check if both arguments link to the same object.
// Especially useful on the step where we compare prototypes
if (x === y) {
return true;
}
// Works in case when functions are created in constructor.
// Comparing dates is a common scenario. Another built-ins?
// We can even handle functions passed across iframes
if ((typeof x === 'function' && typeof y === 'function') ||
(x instanceof Date && y instanceof Date) ||
(x instanceof RegExp && y instanceof RegExp) ||
(x instanceof String && y instanceof String) ||
(x instanceof Number && y instanceof Number)) {
return x.toString() === y.toString();
}
// At last checking prototypes as good as we can
if (!(x instanceof Object && y instanceof Object)) {
return false;
}
if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
return false;
}
if (x.constructor !== y.constructor) {
return false;
}
if (x.prototype !== y.prototype) {
return false;
}
// Check for infinitive linking loops
if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
return false;
}
// Quick checking of one object being a subset of another.
// todo: cache the structure of arguments[0] for performance
for (p in y) {
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
return false;
} else if (typeof y[p] !== typeof x[p]) {
return false;
}
}
for (p in x) {
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
return false;
} else if (typeof y[p] !== typeof x[p]) {
return false;
}
switch (typeof (x[p])) {
case 'object':
case 'function':
leftChain.push(x);
rightChain.push(y);
if (!compare2Objects(x[p], y[p])) {
return false;
}
leftChain.pop();
rightChain.pop();
break;
default:
if (x[p] !== y[p]) {
return false;
}
break;
}
}
return true;
}
if (arguments.length < 1) {
return true; //Die silently? Don't know how to handle such case, please help...
// throw "Need two or more arguments to compare";
}
for (i = 1, l = arguments.length; i < l; i++) {
leftChain = []; //Todo: this can be cached
rightChain = [];
if (!compare2Objects(arguments[0], arguments[i])) {
return false;
}
}
return true;
}
// 检测对象内的$inner 属性, 该属性为保留属性
function _inner_checkinner(target) {
if (target && !target.$inner) {
target.$inner = {
//$limit:new Map(),// 属性的限制数据格式
$methodsValidate: {
$returns: new Map(),
$params: new Map(),
$desc: new Map(),
},
$className: null,// 类名
$constructor: null,// 构造方法,
$isHandleConstructor: false,// 标致是否执行了构造方法 ,如果未定义构造方法,则这里将不会为true
$parentObj: null,// 父类对象
}
}
if (target && !target.super) {
target.super = {}
}
if (target && !target.$parentInner) {
target.$parentInner = {}
}
// 提供对外访问内部属性的方法
target.$getInner = () => {
return target.$inner;
}
// 提供对外访问内部属性的方法
target.$getParentInner = () => {
return target.$parentInner;
}
// 提供对外访问内部属性的方法
target.$setHandleConstructor = () => {
target.$inner.$isHandleConstructor = true;
}
// 设置父类的对外构造方法
target.$setParentsConstuctor = (fun) => {
target.super['constructor'] = fun;
}
// 读取父类对象
target.$getParentObj = () => {
return target.$inner.$parentObj;
}
}
// 检测类内的$inner 属性, 该属性为保留属性
function _inner_checkClssinner(target) {
if (target && target.prototype && !target.prototype.$inner) {
target.prototype.$inner = {}
}
if (target && target.prototype && !target.prototype.super) {
target.prototype.super = {}
}
if (target && target.prototype && !target.prototype.$parentInner) {
target.prototype.$parentInner = {}
}
}
// 检测对象内的保留属性或方法 返回false 说明 不是内部保留属性,可用业务
/**
* $inner 存放内部装饰修饰的一系列数据
* $parentInner 针对继承, 存放上一级父类的的保留数据
* super 针对继承, 存放上一级父类的在子类中也定义的属性或者方法
*/
function _inner_checkinner_keywords(attr) {
if (!attr) {
return false;
}
let inner_attr = new Set(["$inner", "$parentInner", "super", 'constructor', "getter", "setter"]);
return inner_attr.has(attr);
}
// 兼容读取schame
function _inner_get_schame(paramsSchema) {
if (!paramsSchema) {
return null;
}
let schema = null;
if (paramsSchema.validate && isFunction(paramsSchema.validate)) {
schema = paramsSchema;
}
else {
schema = Joi.object(paramsSchema);
}
if (schema == null) {
throw new Error(`schame 校验对象构建失败`);
}
return schema
}
// schame 异常信息读取
function _inner_joi_error(error) {
if (!error) {
return;
}
let err = "";
if (error.details && error.details.length >= 0) {
for (let e of error.details) {
if (!e) {
continue;
}
err += e.message + "、"
}
}
return err;
}
// 检测传入的params的合法性 callType 为Params 或者 Returns 表示数据检测的类型时 调用检测还是 返回结果检测
function _inner_check_params(paramsSchema, params, className, key, callType = "Params") {
var errorMsg = "";
if (paramsSchema) {
if (callType == 'Params') {
//console.log(paramsSchema,params)
// if (!isArray(paramsSchema) || (!isArray(params))) {
// errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:校验规则或者待校验参数必须是arguments 数组`
// throw new Error(errorMsg);
// }
if (paramsSchema.length != params.length) {
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:校验规则规定的参数个数为${paramsSchema.length},但是实际传入的参数个数为${params.length}`
throw new Error(errorMsg);
}
// 遍历校验参数
let i = 0;
for (; i < paramsSchema.length; i++) {
if (paramsSchema[i].toString() == Any.toString()) {
continue;
}
// 这里处理params 不是对象情况
if (!isObject(params[i])) {
if (paramsSchema[i] && paramsSchema[i].validate && isFunction(paramsSchema[i].validate)) {
// console.log(paramsSchema[i].validate, params[i], '4444');
let { error } = paramsSchema[i].validate(params[i]);
if (error) {
let err = _inner_joi_error(error);
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数数组第${i}参数,校验异常,异常信息:${err}`
throw new Error(errorMsg);
}
continue;
}
else {
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数数组第${i}参数,校验异常,异常信息:需要传入一个对象,因为在${callType}参数校验时,第${i}参数要求传入一个对象`
throw new Error(errorMsg);
}
}
let schema = _inner_get_schame(paramsSchema[i]);
if (schema == null) {
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:schame 校验对象构建失败`
throw new Error(errorMsg);
}
let { error } = schema.validate(params[i]);
if (error) {
let err = _inner_joi_error(error);
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数数组第${i}参数,校验异常,异常信息:${err}`
throw new Error(errorMsg);
}
}
}
else if (callType == 'Returns') {
// 这里处理params 不是对象情况
if (!isObject(params) && !isArray(params)) {
if (paramsSchema && paramsSchema.validate) {
let { error } = paramsSchema.validate(params);
if (error) {
let err = _inner_joi_error(error);
//let err = validateResult && validateResult.error && validateResult.error.ValidationError?validateResult.error.ValidationError:""
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${err}`
throw new Error(errorMsg);
}
return;
}
}
// 这种情况说明是返回的数据是数组, 规则是不是数组,是使用Joi.array() 的规则
if (isArray(params) && !isArray(paramsSchema)) {
// 这里直接校验
let schema = _inner_get_schame(paramsSchema);
if (schema == null) {
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:schame 校验对象构建失败`
throw new Error(errorMsg);
}
let { error } = schema.validate(params);
if (error) {
let err = _inner_joi_error(error);
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${err}`
throw new Error(errorMsg);
}
return;
}
if (isArray(paramsSchema) && !isArray(params)) {
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${callType}参数要求是数组,但实际调用时传入的参数不是数组`
throw new Error(errorMsg);
}
if (isArray(params)) {
if (params.length != paramsSchema.length) {
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${callType}参数要求是数组,但实际调用时传入的数据长度不一致`
throw new Error(errorMsg);
}
for (let i = 0; i < params.length; i++) {
if (!params[i] || !paramsSchema[i]) {
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${callType}参数数组的第${i}个参数和传进来的参数有一个为null或者undefined`
throw new Error(errorMsg);
}
if (paramsSchema[i].toString() == Any.toString()) {
continue;
}
// 这里处理params 不是对象情况
if (!isObject(params[i])) {
if (paramsSchema[i] && paramsSchema[i].validate && isFunction(paramsSchema[i].validate)) {
// console.log(paramsSchema[i].validate, params[i], '4444');
let { error } = paramsSchema[i].validate(params[i]);
if (error) {
let err = _inner_joi_error(error);
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数数组第${i}参数,校验异常,异常信息:${err}`
throw new Error(errorMsg);
}
continue;
}
else {
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数数组第${i}参数,校验异常,异常信息:需要返回一个对象,因为在${callType}参数校验时,第${i}参数要求返回一个对象`
throw new Error(errorMsg);
}
}
if (!isObject(paramsSchema[i]) && paramsSchema[i] != null) {
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${callType}参数数组的第${i}个参数必须要求为一个合法对象,但实际的值为${paramsSchema[i]}`
throw new Error(errorMsg);
}
if (!isObject(params[i])) {
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:传入参数数组的第${i}个元素必须要求为一个合法对象,但实际的值为${params[i]}`
throw new Error(errorMsg);
}
let schema = _inner_get_schame(paramsSchema[i]);
if (schema == null) {
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:schame 校验对象构建失败`
throw new Error(errorMsg);
}
let { error } = schema.validate(params[i]);
if (error) {
let err = _inner_joi_error(error);
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数数组第${i}参数,校验异常,异常信息:${err}`
throw new Error(errorMsg);
}
}
}
else {
if (paramsSchema.toString() == Any.toString()) {
return;
}
let schema = _inner_get_schame(paramsSchema);
if (schema == null) {
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:schame 校验对象构建失败`
throw new Error(errorMsg);
}
//console.log("pramas 检测 ", isArray(params), params);
let { error } = schema.validate(params);
if (error) {
//console.log(error.details)
let err = _inner_joi_error(error);
//let err = validateResult && validateResult.error && validateResult.error.ValidationError?validateResult.error.ValidationError:""
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${err}`
throw new Error(errorMsg);
}
}
}
else {
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,调用类型检测失败,${callType} 为未支持调用类型`
throw new Error(errorMsg);
}
}
// else {
// errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:paramsSchema `
// throw new Error(errorMsg);
// }
}
// 通用getter 控制代理
function _getter(o, className, target, key, receiver, callPosition = "outer") {
_inner_checkinner(target);
if (callPosition == 'outer') {
if (_inner_checkinner_keywords(key)) {
errorMsg = `Factory getter 异常:类${className}的${key}属性或者方法 为内部保留方法/属性,不可直接访问`
throw new Error(errorMsg);
}
}
//console.log(o[key],key)
if ((o[key] === undefined) || (o[key] === "undefined")) {
errorMsg = `Factory getter 异常:类${className}的${key}属性或者方法 可能不存在`
throw new Error(errorMsg);
}
// 访问权限控制
if (isFunction(o[key])) {
if (callPosition == 'outer') {
if (target.$inner.PrivateMethods) {
if (target.$inner.PrivateMethods.has(key)) {
errorMsg = `Factory getter 异常:类${className}的${key}为私有方法,不可外部访问`
throw new Error(errorMsg);
}
}
if (target.$inner.ProtectedMethods) {
if (target.$inner.ProtectedMethods.has(key)) {
errorMsg = `Factory getter 异常:类${className}的${key}为保护方法,不可外部访问`
throw new Error(errorMsg);
}
}
}
//判断是异步函数还是同步
return function () {
var _this = this;
let params = arguments;
//检测传入的parmas是否是正确的
if (target.$inner.$methodsValidate.$params.has(key)) {
let paramsSchema = target.$inner.$methodsValidate.$params.get(key);
//console.log(paramsSchema, arguments);
_inner_check_params(paramsSchema, params, className, key);
}
// 检测方法返回的结果
function checkReturns(key, value) {
let paramsSchema = target.$inner.$methodsValidate.$returns.get(key);
_inner_check_params(paramsSchema, value, className, key, "Returns")
}
// 检测是是否是多线程运行
if (target.$inner.ThreadMethods && target.$inner.ThreadMethods.get(key)) {
//console.log(`方法${key}是多线程方法。。。`);
// 读取方法代码
let funcstr = o[key].toString()
//console.log(funcstr);
let threadConfig = target.$inner.ThreadMethods.get(key);
if (threadConfig && threadConfig.logging) {
console.log(`方法${key}在线程中执行`.cyan)
}
// 异步方法
if (funcstr.indexOf("_regenerator[\"default\"].async") != -1) {
return new Promise((resolve, reject) => {
try {
const subChannel = new MessageChannel();
subChannel.port2.on('message', (value) => {
//console.log('主线程的port2 接收到:', value);
checkReturns(key, value)
resolve(value)
});
const worker = new Worker(`(()=>{
const { parentPort } = require('worker_threads');
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
// 先接收到管道
parentPort.once('message', (value) => {
// 执行子线程的方法
let res = (${funcstr}).apply(this,value.params);
res.then((result)=>{
value.threadPort.postMessage(result);
value.threadPort.close();
}).catch(err=>{
throw err
})
});
console.log('子线程运行成功....')
})()`, { eval: true });
let arr = [];
for (let i in arguments) {
arr[i] = arguments[i]
}
worker.postMessage({ threadPort: subChannel.port1, params: arr }, [subChannel.port1]);
worker.on("exit", () => {
//console.log('子线程退出')
if (threadConfig && threadConfig.logging) {
console.log(`方法${key}在的子线程退出`.cyan)
}
})
worker.on('error', (err) => {
console.log("线程运行报错...", err);
reject(err);
})
}
catch (err) {
reject(err)
}
})
}
else {
if (isMainThread) {
return new Promise((resolve, reject) => {
try {
const subChannel = new MessageChannel();
const logChannel = new MessageChannel(); // 日志管道
subChannel.port2.on('message', (value) => {
//console.log('主线程的port2 接收到:', value);
checkReturns(key, value)
resolve(value,)
});
logChannel.port2.on('message', (value) => {
if (threadConfig && threadConfig.logger && _this[threadConfig.logger] ) {
if(_this[threadConfig.logger].beforelog)
{
value = _this[threadConfig.logger].beforelog(value);
}
_this[threadConfig.logger].apply(_this,value)
}
});
const worker = new Worker(`(()=>{
let logPort = null; // 通信端口
//向主线程发送日志的方法
function logger()
{
//console.log("logger ");
if(logPort)
{
logPort.postMessage(Object.assign([],arguments))
}
else
{
console.log("无法传输日志");
}
}
const { parentPort } = require('worker_threads');
// 先接收到管道
parentPort.once('message', (value) => {
try
{
logPort = value.logPort
// 执行子线程的方法
let res = (${funcstr}).apply(this,value.params);
if(res instanceof Promise)
{
res.then((re)=>{
value.threadPort.postMessage(re);
value.threadPort.close();
value.logPort.close();
}).catch(err=>{
logger({
message:err.message,
stack:err.stack
})
})
}
else
{
value.threadPort.postMessage(res);
value.threadPort.close();
value.logPort.close();
}
}
catch(err)
{
logger({
message:err.message,
stack:err.stack
})
}
});
console.log('子线程运行成功aaa....')
})()`, { eval: true });
let arr = [];
for (let i in arguments) {
arr[i] = arguments[i]
}
worker.postMessage({ threadPort: subChannel.port1,logPort:logChannel.port1, params: arr }, [subChannel.port1,logChannel.port1]);
worker.on("exit", () => {
if (threadConfig && threadConfig.logging) {
console.log(`方法${key}在的子线程退出`.cyan)
}
})
}
catch (err) {
reject(err)
}
})
}
}
}
else {
// 检测是否是异步方法
if (o[key].toString().indexOf("_regenerator[\"default\"].async") != -1) {
return o[key].apply(o, arguments).then((result) => {
// return o[key].call(o, params).then((result) => {
//console.log("异步函数调用结果 是 ", result);
// 检测调用的结果
if (result === null || result === false) {
return result
}
checkReturns(key, result)
return result;
})
}
else {
//console.log("同步函数调用");
let result = o[key].apply(o, arguments)
//let result = o[key].call(o, params)
if (result === null || result === false) {
return result
}
if (result instanceof Promise) // 说明返回的结果是一个Promise 对象
{
return result.then(res => {
if (res === null || res === false) {
return res
}
checkReturns(key, res)
return res;
})
}
else {
checkReturns(key, result)
return result;
}
}
}
};
}
else {
if (target.$inner.PrivateAttr) {
if (target.$inner.PrivateAttr.has(key)) {
errorMsg = `Factory getter 异常:类${className}的${key}为私有属性,不可外部访问`
throw new Error(errorMsg);
}
}
if (target.$inner.ProtectedAttr) {
if (target.$inner.ProtectedAttr.has(key)) {
errorMsg = `Factory getter 异常:类${className}的${key}为保护属性,不可外部访问`
throw new Error(errorMsg);
}
}
return o[key]
}
}
// 内部控制代理
function _inner_proxy(o, className) {
var errorMsg = "";
return new Proxy(o, {
get: function (target, key, receiver) {
return _getter(o, className, target, key, receiver)
},
set(target, key, value) {
//console.log("哈哈哈",key)
_inner_checkinner(target);
if (_inner_checkinner_keywords(key)) {
errorMsg = `Factory setter 异常:类${className}的${key}属性或者方法 为内部保留方法/属性,不可直接访问`
throw new Error(errorMsg);
}
if (isFunction(value)) {
errorMsg = `Factory setter 异常:无法在外部为类${className}的对象新增${key}方法,方法只能类中定义`
throw new Error(errorMsg);
}
if (!isFunction(value) && isFunction(o[key])) {
errorMsg = `Factory setter 异常:类${className}的 ${key} 为方法,无法赋值为一个非函数/方法的值`
throw new Error(errorMsg);
}
if (isFunction(o[key])) {
// 检测是否是readonly
errorMsg = `Factory setter 异常:类${className}的${key}方法保护,不可随意改动对象的方法`
throw new Error(errorMsg);
// o[key] = value;
// return true;
}
else //如何是数值的情况
{
if ((target.$inner.PrivateAttr && target.$inner.PrivateAttr.has(key)) || (target.$inner.ReadonlyAttr && target.$inner.ReadonlyAttr.has(key)) || (target.$parentInner && target.$parentInner && target.$parentInner.$inner && target.$parentInner.$inner.ReadonlyAttr && target.$parentInner.$inner.ReadonlyAttr.has(key))) {
errorMsg = `Factory setter 异常:类${className}的${key}属性为只读或者私有属性,无法赋值`
throw new Error(errorMsg);
}
//console.log("检测schama",target.$parentInner.$inner,key);
//检测数据类型是和定义的数据类型一致
//let schame = target.$inner.AttrLimit.get(key);
if ((target.$inner.AttrLimit && target.$inner.AttrLimit.get(key)) || (target.$parentInner && target.$parentInner.$inner && target.$parentInner.$inner.AttrLimit && target.$parentInner.$inner.AttrLimit.get(key))) {
let schemaRule = null;
if (target.$inner.AttrLimit.get(key)) {
schemaRule = target.$inner.AttrLimit.get(key);
// console.log("@@@",schemaRule);
}
else if (target.$parentInner.$inner.AttrLimit.get(key)) {
schemaRule = target.$parentInner.$inner.AttrLimit.get(key);
}
else {
return;
}
let schema = _inner_get_schame(schemaRule);
if (!schema) {
//console.log(key,target.$parentInner.$inner.AttrLimit.get(key),"rule");
errorMsg = `Factory setter 异常:类${className}的 ${key} 属性赋值时,schame校验对象读取失败`
throw new Error(errorMsg);
}
let { error } = schema.validate(value);
if (error) {
let err = "";
if (error.details && error.details.length >= 0) {
for (let e of error.details) {
if (!e) {
continue;
}
err += e.message + "、"
}
}
//let err = validateResult && validateResult.error && validateResult.error.ValidationError?validateResult.error.ValidationError:""
errorMsg = `Factory setter 异常:类${className}的 ${key} 属性无法赋值,因为数据类型不匹配,异常信息:${err}`
throw new Error(errorMsg);
}
}
o[key] = value;
return true;
}
}
});
}
// 内部设置属性控制代理
function _setter(target, key, value, className, o) {
_inner_checkinner(target);
if (_inner_checkinner_keywords(key)) {
errorMsg = `Factory setter 异常:类${className}的${key}属性或者方法 为内部保留方法/属性,不可直接访问`
throw new Error(errorMsg);
}
// if (isFunction(value) && !isFunction(o[key])) {
// errorMsg = `Factory setter 异常:类${className}的 ${key} 为属性,无法赋值为一个函数/方法`
// throw new Error(errorMsg);
// }
if (isFunction(value)) {
errorMsg = `Factory setter 异常:无法在外部为类${className}的对象新增${key}方法,方法只能类中定义`
throw new Error(errorMsg);
}
if (!isFunction(value) && isFunction(o[key])) {
errorMsg = `Factory setter 异常:类${className}的 ${key} 为方法,无法赋值为一个非函数/方法的值`
throw new Error(errorMsg);
}
if (isFunction(o[key])) {
// 检测是否是readonly
// if (target.$inner.ReadonlyMethods && target.$inner.ReadonlyMethods.has(key)) {
// errorMsg = `Factory setter 异常:类${className}的${key}方法为只读方法,无法赋值`
// throw new Error(errorMsg);
// }
errorMsg = `Factory setter 异常:类${className}的${key}方法保护,不可随意改动对象的方法`
throw new Error(errorMsg);
// o[key] = value;
// return true;
}
else //改属性值
{
//console.log(target.$parentInner)
if ((target.$inner.ReadonlyAttr && target.$inner.ReadonlyAttr.has(key)) || (target.$parentInner && target.$parentInner && target.$parentInner.$inner && target.$parentInner.$inner.ReadonlyAttr && target.$parentInner.$inner.ReadonlyAttr.has(key))) {
errorMsg = `Factory setter 异常:类${className}的${key}属性为只读属性,无法赋值`
throw new Error(errorMsg);
}
//console.log("检测schama",target.$parentInner.$inner,key);
//检测数据类型是和定义的数据类型一致
//let schame = target.$inner.AttrLimit.get(key);
if ((target.$inner.AttrLimit && target.$inner.AttrLimit.get(key)) || (target.$parentInner && target.$parentInner.$inner && target.$parentInner.$inner.AttrLimit && target.$parentInner.$inner.AttrLimit.get(key))) {
let schemaRule = null;
if (target.$inner.AttrLimit.get(key)) {
schemaRule = target.$inner.AttrLimit.get(key);
}
else if (target.$parentInner.$inner.AttrLimit.get(key)) {
schemaRule = target.$parentInner.$inner.AttrLimit.get(key);
}
else {
return;
}
let schema = _inner_get_schame(schemaRule);
if (!schema) {
errorMsg = `Factory setter 异常:类${className}的 ${key} 属性赋值时,构造校验schame失败`
throw new Error(errorMsg);
}
let { error } = schema.validate(value);
if (error) {
let err = "";
if (error.details && error.details.length >= 0) {
for (let e of error.details) {
if (!e) {
continue;
}
err += e.message + "、"
}
}
//let err = validateResult && validateResult.error && validateResult.error.ValidationError?validateResult.error.ValidationError:""
errorMsg = `Factory setter 异常:类${className}的 ${key} 属性无法赋值,因为数据类型不匹配,异常信息:${err}`
throw new Error(errorMsg);
}
}
o[key] = value;
return true;
}
}
function _outer_proxy(o, className) {
var errorMsg = "";
return new Proxy(o, {
get(target, key, receiver) {
_inner_checkinner(target);
if (_inner_checkinner_keywords(key)) {
errorMsg = `Factory getter 异常:类${className}的${key}属性或者方法 为内部保留方法/属性,不可直接访问`
throw new Error(errorMsg);
}
if ((o[key] === undefined) || (o[key] === "undefined")) {
console.log(o[key])
errorMsg = `Factory getter 异常:类${className}的${key}属性或者方法 可能不存在`
throw new Error(errorMsg);
}
// 访问权限控制
if (isFunction(o[key])) {
if (target.$inner.PrivateMethods) {
if (target.$inner.PrivateMethods.has(key)) {
errorMsg = `Factory getter 异常:类${className}的${key}为私有方法,不可外部访问`
throw new Error(errorMsg);
}
}
if (target.$inner.ProtectedMethods) {
if (target.$inner.ProtectedMethods.has(key)) {
errorMsg = `Factory getter 异常:类${className}的${key}为保护方法,不可外部访问`
throw new Error(errorMsg);
}
}
//判断是异步函数还是同步
// let isAsync = isAsyncFunction(async ()=>{})
// console.log("检测",isAsync);
return (params) => {
if (o['__call_before']) {
if (!o['__call_before'](key, params)) {
if (o["__call_stop"]) {
o["__call_stop"](key, params)
}
return;
}
}
//检测传入的parmas是否是正确的
if (target.$inner.$methodsValidate.$params.has(key)) {
let schema = Joi.object(target.$inner.$methodsValidate.$params.get(key));
let { error } = schema.validate(params);
if (error) {
//console.log(error.details)
let err = "";
if (error.details && error.details.length >= 0) {
for (let e of error.details) {
if (!e) {
continue;
}
err += e.message + "、"
}
}
//let err = validateResult && validateResult.error && validateResult.error.ValidationError?validateResult.error.ValidationError:""
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,Params 参数校验异常,异常信息:${err}`
throw new Error(errorMsg);
}
}
// 检测方法返回的结果
function checkReturns(key, value) {
if (target.$inner.$methodsValidate.$returns.has(key)) {
let schema = Joi.object(target.$inner.$methodsValidate.$returns.get(key));
let { error } = schema.validate(value);
if (error) {
let err = "";
if (error.details && error.details.length >= 0) {
for (let e of error.details) {
if (!e) {
continue;
}
err += e.message + "、"
}
}
//let err = validateResult && validateResult.error && validateResult.error.ValidationError?validateResult.error.ValidationError:""
errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,Returns 参数校验异常,异常信息:${err}`
throw new Error(errorMsg);
}
}
}
if (o[key].toString().indexOf("_regenerator[\"default\"].async") != -1) {
return o[key].call(o, params).then((result) => {
//console.log("异步函数调用结果 是 ", result);
// 检测调用的结果
if (result === null || result === false) {
return result
}
checkReturns(key, result)
return result;
})
}
else {
//console.log("同步函数调用");
let result = o[key].call(o, params)
if (result === null || result === false) {
return result
}
checkReturns(key, result)
return result;
}
};
}
else {
if (target.$inner.PrivateAttr) {
if (target.$inner.PrivateAttr.has(key)) {
errorMsg = `Factory getter 异常:类${className}的${key}为私有属性,不可外部访问`
throw new Error(errorMsg);
}
}
if (target.$inner.ProtectedAttr) {
if (target.$inner.ProtectedAttr.has(key)) {
errorMsg = `Factory getter 异常:类${className}的${key}为保护属性,不可外部访问`
throw new Error(errorMsg);
}
}
return o[key]
}
},
set(target, key, value) {
return _setter(target, key, value, className, o)
}
});
}
// 主工厂方法,用于创建对象
function Factory(clas, constructorParams) {
//console.log(clas.prototype.geto,"hahah111");
let className = "";
var errorMsg = "";
if (!clas || !clas.prototype || !clas.prototype.constructor || !clas.prototype.constructor.name) {
errorMsg = `Factory异常:构造对象失败,因为传入了一个不合法的类`
throw new Error(errorMsg);
}
className = clas.prototype.constructor.name;
let o = new clas();
let innerAttr = {};
for (let i in o) {
if (!i) {
continue
}
innerAttr[i] = o[i];
}
o.setter = new Proxy(o, {
set(target, key, value) {
//console.log("内部setter", target.$inner);
return _setter(target, key, value, className, o);
}
});
o.getter = new Proxy(o, {
get: function (target, key, receiver) {
return _getter(o, className, target, key, receiver, 'inner')
}
});
// o.getter = new Proxy(o, {
// set(target, key, value) {
// //console.log("内部setter", target.$inner);
// return _setter(target, key, value, className, o);
// }
// });
// 这里用于控制类的外部调用
let descObj = _inner_proxy(o, className)
let $inner = descObj.$getInner();
if ($inner.$constructor) {
//console.log("实例化对象", o[$inner.$className]);
// 构造方法不能是异步方法
if (o[$inner.$className].toString().indexOf("_regenerator[\"default\"].async") != -1) {
errorMsg = `Factory异常:构造对象失败,构造方法不能是异步方法`
throw new Error(errorMsg);
}
let $parentInner = descObj.$getParentInner();
// 设置父类的构造方法到super对象
if ($parentInner && $parentInner.$inner.$constructor) {
let paramsSchema = $parentInner.$inner.$methodsValidate.$params.get($parentInner.$inner.$className);
descObj.$setParentsConstuctor((parentsConstuctorParams) => {
_inner_check_params(paramsSchema, parentsConstuctorParams, $parentInner.$inner.$className, "构造方法");
$parentInner.$inner.$constructor(parentsConstuctorParams);
let parentsobj = descObj.$getParentObj();
parentsobj.$setHandleConstructor();
})
}
// 执行构造方法
let paramsSchema = $inner.$methodsValidate.$params.get($inner.$className);
_inner_check_params(paramsSchema, constructorParams, $inner.$className, "构造方法");
$inner.$constructor.call(o, constructorParams);
descObj.$setHandleConstructor();// 表示实例化成功
// 检测父类的构造方法
if ($parentInner && $parentInner.$inner.$constructor && !$parentInner.$inner.$isHandleConstructor) {
errorMsg = `Factory异常:构造对象失败,父类${$parentInner.$inner.$className}中自定义了构造方法,必须在子类的构造方法中执行`
throw new Error(errorMsg);
}
//console.log("父类的", $parentInner);
}
return descObj;
}
//访问控制符
function Private(target, name) {
_inner_checkinner(target);
var errorMsg = "";
if (isFunction(target[name])) {
// 检测是否已经被其他的访问修饰符修饰了
if (target.$inner.PublicMethods && target.$inner.PublicMethods.has(name)) {
errorMsg = `@Private修饰报错:${name}方法已经被@Public 修饰过,无法重复修饰`
throw new Error(errorMsg);
}
if (target.$inner.ProtectedMethods && target.$inner.ProtectedMethods.has(name)) {
errorMsg = `@Private修饰报错:${name}方法已经被@Protected 修饰过,无法重复修饰`
throw new Error(errorMsg);
}
if (!target.$inner.PrivateMethods || target.$inner.PrivateMethods.size == 0) {
target.$inner.PrivateMethods = new Set();
}
target.$inner.PrivateMethods.add(name, target.$inner.PublicMethods);
//console.log("设置方法的私有访问权限", name,target.$inner.PublicMethods)
}
else {
if (target.$inner.PublicAttr && target.$inner.PublicAttr.has(name)) {
errorMsg = `@Private修饰报错:${name}属性已经被@Public 修饰过,无法重复修饰`
throw new Error(errorMsg);
}
if (target.$inner.ProtectedAttr && target.$inner.ProtectedAttr.has(name)) {
errorMsg = `@Private修饰报错:${name}属性已经被@Protected 修饰过,无法重复修饰`
throw new Error(errorMsg);
}
if (!target.$inner.PrivateAttr || target.$inner.PrivateAttr.size == 0) {
target.$inner.PrivateAttr = new Set();
}
target.$inner.PrivateAttr.add(name);
//console.log("设置属性的私有访问权限", name)
}
}
// //访问控制符
function Public(target, name, descriptor) {
_inner_checkinner(target);
if (_inner_checkinner_keywords(name)) {
errorMsg = `定义方法或者属性异常:${name}属性或者方法 为内部保留方法/属性,不可重新定义`
throw new Error(errorMsg);
}
if (isFunction(target[name])) {
// 检测是否已经被其他的访问修饰符修饰了
if (target.$inner.PrivateMethods && target.$inner.PrivateMethods.has(name)) {
errorMsg = `@Public修饰报错:${name}方法已经被@Private 修饰过,无法重复修饰`
throw new Error(errorMsg);
}
if (target.$inner.ProtectedMethods && target.$inner.ProtectedMethods.has(name)) {
errorMsg = `@Public修饰报错:${name}方法已经被@Protected 修饰过,无法重复修饰`
throw new Error(errorMsg);
}
if (!target.$inner.PublicMethods || target.$inner.PublicMethods.size == 0) {
target.$inner.PublicMethods = new Set();
}
target.$inner.PublicMethods.add(name);
//console.log("设置方法的公有访问权限", name,target.$inner.PublicMethods)
}
else {
if (target.$inner.PrivateAttr && target.$inner.PrivateAttr.has(name)) {
errorMsg = `@Public修饰报错:${name}属性已经被@Private 修饰过,无法重复修饰`
throw new Error(errorMsg);
}
if (target.$inner.ProtectedAttr && target.$inner.ProtectedAttr.has(name)) {
errorMsg = `@Public修饰报错:${name}属性已经被@Protected 修饰过,无法重复修饰`
throw new Error(errorMsg);
}
if (!target.$inner.PublicAttr || target.$inner.PublicAttr.size == 0) {
target.$inner.PublicAttr = new Set();
}
target.$inner.PublicAttr.add(name);
}
}
// //访问控制符
function Protected(target, name, descriptor) {
_inner_checkinner(target);
if (isFunction(target[name])) {
if (target.$inner.PrivateMethods && target.$inner.PrivateMethods.has(name)) {
errorMsg = `@Protected修饰报错:${name}方法已经被@Private 修饰过,无法重复修饰`
throw new Error(errorMsg);
}
if (target.$inner.PublicMethods && target.$inner.PublicMethods.has(name)) {
errorMsg = `@Protected修饰报错:${name}方法已经被@Public 修饰过,无法重复修饰`
throw new Error(errorMsg);
}
if (!target.$inner.ProtectedMethods || target.$inner.ProtectedMethods.size == 0) {
target.$inner.ProtectedMethods = new Set();
}
target.$inner.ProtectedMethods.add(name);
}
else {
if (target.$inner.PrivateAttr && target.$inner.PrivateAttr.has(name)) {
errorMsg = `@Protected修饰报错:${name}属性已经被@Private 修饰过,无法重复修饰`
throw new Error(errorMsg);
}
if (target.$inner.PublicAttr && target.$inner.PublicAttr.has(name)) {
errorMsg = `@Protected修饰报错:${name}属性已经被@Public 修饰过,无法重复修饰`
throw new Error(errorMsg);
}
if (!target.$inner.ProtectedAttr || target.$inner.ProtectedAttr.size == 0) {
target.$inner.ProtectedAttr = new Set();
}
target.$inner.ProtectedAttr.add(name);