vesh
Version:
码农nodejs版本VESH框架,使用函数责任链模式 实现了 默认文件跳转,自定义错误页,空文件处理,URL解析,Querystring与Form参数解析,PostFiles解析,MVC自动映射,SQL自动服务化,可继承页面,静态文件,json,tjson,jsonp,tjsonp,string,void,xjson,xjosnp等等6种JSON格式,http与https等等操作
1,059 lines (1,002 loc) • 27.3 kB
JavaScript
import V, { finalC } from "gcl/com/coooders/common/tool";
import N from "gcl/com/coooders/db/ni";
import I from "gcl/com/coooders/io/tool";
import { parse, resolve, normalize } from "path";
import { exists } from "fs";
import { AModuler } from "./app";
/**
* AAction基类 用于完成Controler操作
*/
export const AAction = class {
constructor() {
const { _, __ } = pri(this);
_.isStatic = true;
}
preload(req, rep, session) {
return false;
}
unload(req, rep, session) {
return false;
}
};
export const LoadModuler = class extends AModuler {
constructor(base, src, debug = false, isRestful = false) {
super("LoadModuler");
const { _, __ } = pri(this, {
base: base
? base
.trim("/")
.trim("\\")
.replace(/[\\\/]/g, ".")
: "",
src: src ? "/" + src.replace(/^[\\\/]/g, "") : "",
actions: {},
debug,
isRestful,
pathregex: /([/\\][^/\\]+)+[/\\]/g,
});
}
async onrequest(req, rep, session, call) {
const { _, __ } = pri(this);
//todo src=>dist的 es7编译
let query = (session.url.pathname.match(__.pathregex) || "/")[0];
session.classtype = `${__.src}${query}action`.toLowerCase();
session.methodname = `${__.base}${query}${session.status}`
.replace(/[\\\/]/g, ".")
.toLowerCase();
let action = __.actions[session.classtype];
if (typeof action == "undefined") {
let base = parse(resolve(normalize(process.mainModule.filename))).dir;
if ("windows".eq(V.environment.os || "")) {
//windows
base = base.replace(/\//g, "\\");
} else {
//linux
base = base.replace(/\\\\/g, "/");
}
let ist = await V.callback((call) =>
exists(base + session.classtype + ".njs", (ist) => call(null, ist)),
);
// console.log(35, base + session.classtype + ".njs", ist);
action = !ist
? false
: (function () {
try {
const classname = require(base + session.classtype + ".njs");
//console.log(56, base + session.classtype + '.njs', classname);
let action =
classname && classname.Action
? V.create2(classname.Action, [])
: false;
if (action) {
let proto = action.__proto__;
//遍历所有父类方法
while (proto) {
const names = Reflect.ownKeys(proto);
names.forEach((k) => {
if (
k != k.toLowerCase() &&
k != "constructor" &&
k.indexOf("__") < 0 &&
typeof action[k] == "function"
)
action[k.toLowerCase()] = action[k];
});
proto = proto.__proto__;
}
}
return action;
} catch (e) {
session.Log.error("VESH:" + e.stack);
//__.debug &&
console.log(e.stack);
}
})();
if (__.isRestful && !ist) {
let split = "windows".eq(V.environment.os || "") ? "\\" : "/";
let bases = query.toLowerCase().split(split);
let params = [];
bases.pop();
while (bases.length && !ist) {
ist = await V.callback((call) =>
exists(
`${base}${__.src}${bases.join(split)}${split}action.njs`,
(ist) => call(null, ist),
),
);
// console.log(
// 103,
// `${base}${__.src}${bases.join(split)}${split}action.njs`,
// ist,
// );
if (!ist) params.unshift(bases.pop());
else {
action =
__.actions[`${__.src}${bases.join(split)}${split}action.njs`];
if (!action)
try {
// console.log(
// 117,
// `${base}${__.src}${bases.join(split)}${split}action.njs`,
// );
const classname = require(
`${base}${__.src}${bases.join(split)}${split}action.njs`,
);
//console.log(56, base + session.classtype + '.njs', classname);
// 保证是唯一的一个对象
action =
classname && classname.Action
? V.create2(classname.Action, [])
: false;
if (action) {
let proto = action.__proto__;
//遍历所有父类方法
while (proto) {
const names = Reflect.ownKeys(proto);
names.forEach((k) => {
if (
k != k.toLowerCase() &&
k != "constructor" &&
k.indexOf("__") < 0 &&
typeof action[k] == "function"
)
action[k.toLowerCase()] = action[k];
});
proto = proto.__proto__;
}
//`${base}${__.src}${bases.join(split)}${split}action.njs`,
//`${__.src}${query}action`.toLowerCase();
if (action.isStatic)
__.actions[
`${__.src}${bases.join(split)}${split}action.njs`
] = action;
}
session.querystring.params = params;
} catch (e) {
session.Log.error("VESH:" + e.stack);
//__.debug &&
console.log(e.stack);
}
}
}
}
}
if (action) {
if (action.isStatic) __.actions[session.classtype] = action;
session.action = action;
//先调用preload方法
return (
(await V.callback2(action.preload, action, req, rep, session)) || false
);
} else {
__.actions[session.classtype] = false;
return false;
}
}
async onresponse(req, rep, session, call) {
if (session.action && session.action.unload) {
//先调用preload方法
return (
(await V.callback2(
session.action.unload,
session.action,
req,
rep,
session,
)) || false
);
}
return false;
}
};
/**
* 用于自动填充ni对象的方法
*/
export const AFilter = class {
constructor() {}
fill(req, rep, session, form) {
return false;
}
};
/**
* 用户Form参数填充
*/
export const FormFilter = class extends AFilter {
constructor() {
super();
}
fill(req, rep, session, form = {}) {
V.merge(form, session.querystring, true);
if (session.form) V.merge(form, session.form, true);
return false;
}
};
/**
* ;号分割的sessionNames):AFilter子类,使用Session数据填充form的值
*/
export const SessionFilter = class extends AFilter {
constructor(sessionNames) {
super();
const { _, __ } = pri(this, {
sessionNames: (sessionNames + "").split(";").filter((v) => V.isValid(v)),
});
}
async fill(req, rep, session, form) {
const { _, __ } = pri(this);
await V.each(__.sessionNames, async (v) => {
const data = await session.data(v);
if (data) {
const strf = data.Name.replace(/\./g, "_") + "_";
await V.forC(data.serialize(), (key, value) => {
form[strf + key.replace(/\./g, "_")] = value;
return false;
});
}
return false;
});
return false;
}
};
/**
* 设定可以参数化的AppSetting
* @param {string} sessionNames
*/
export const AppSettingFilter = class extends AFilter {
constructor(sessionNames) {
super();
const { _, __ } = pri(this, {
sessionNames: (sessionNames + "").split(";").filter((v) => V.isValid(v)),
});
}
async fill(req, rep, session, form) {
const { _, __ } = pri(this);
await V.each(__.sessionNames, (v) => {
const data = session.AppSettings(v);
data && (form[v.replace(/\./g, "_")] = data);
return false;
});
return false;
}
};
/**
* NiModuler(filters,middler[,appname:"Ni"]):Ni处理器Moduler,主要识别query中的_n参数,并对数据集进行填充和请求
*/
export const NiModuler = class extends AModuler {
constructor(filter = [], middler, appname = "Ni", strict = false) {
super("NiModuler");
const { _, __ } = pri(this, {
filter:
filter.length > 0
? filter
: (function () {
throw new Error("必须定义数据填充逻辑数组filter");
})(),
middler: middler,
ni: middler
? new N.NiTemplateManager(middler, appname)
: (function () {
throw new Error("必须定义中介者middler对象");
})(),
strict: !!strict,
});
}
async onrequest(req, rep, session) {
const { _, __ } = pri(this);
session.dbresult = session.dbresult || [];
const templatename = session.param("_n");
if (templatename) {
await V.next(
(data) => {
data.params = {};
return V.each(__.filter, (v, call) =>
v.fill(req, rep, session, data.params, call),
);
},
async (data) => {
const cmd = await __.ni.getCommand(templatename, session.methodname);
if (cmd && cmd.params) {
if (cmd.params["_TestPermission"]) {
let pers = (cmd.params["_TestPermission"].value || "")
.split(",")
.filter((v) => v.length > 0);
let hasRight = false;
await V.each(
pers,
async (v, call) => {
if (await session.hasRight(v)) hasRight = true;
return false;
},
true,
);
if (pers.length > 0 && !hasRight)
throw new Error(
`${session.methodname}执行需要${cmd.params["_TestPermission"].value}权限!`,
);
}
if (
(cmd.params["_TestLogin"] || cmd.params["_User_UID"]) &&
!session.User.Login
) {
throw new Error(`${session.methodname}执行需要登录执行!`);
}
} else if (__.strict)
throw new Error(`没有找到对应的模板命令:${session.methodname}。`);
return false;
},
async (data) => {
try {
session.dbparams = data.params;
const result = await __.ni.excute(
templatename,
session.methodname,
data.params,
);
if (result.hasData && result.hasData()) {
session.dbresult.push(result.last());
}
return false;
} catch (e) {
console.log(e.stack);
throw e;
}
},
);
return false;
} else return false;
}
onresponse1(req, rep, session) {
delete session.dbparams;
delete session.dbresult;
return false;
}
};
/**
* ActionModuler:Action处理器Moduler并根据返回值决定是否请求页面
*/
export const ActionModuler = class extends AModuler {
constructor() {
super("ActionModuler");
pri(this);
}
async onrequest(req, rep, session) {
const status = (session.status || "").toLowerCase();
if (session.action && session.action[status]) {
const _ac = session.action[status];
let ret = false;
if (_ac["needs"]) {
_ac["needs"].forEach((n) => {
const need = n(req, rep, session);
if (need) {
session.end(401, need);
ret = true;
return true;
}
});
}
if (!ret)
return (
(await V.callback2(
session.action[status],
session.action,
req,
rep,
session,
)) || false
);
}
return false;
}
};
/**
*
* @param {*} 分号隔开的命令类型
*/
export const NeedMethod = (methods = "GET") => {
const method = {};
methods = methods.toUpperCase();
methods.split(";").forEach((v) => (method[v.toLowerCase()] = true));
return (target) =>
V.prop(target, "needs", function (req, rep, session) {
return method[req.method] ? false : "限制的Method为" + methods;
});
};
/**
*
* @param {*} 分号隔开的命令类型
*/
export const TestMethod = (paras, methods = "GET") => {
const session = paras[2];
return session.testMethod(methods);
};
/**
* 限制方法为Get访问
*/
export const NeedGet = () => NeedMethod("get");
/**
* 限制方法为Get访问
*/
export const TestGet = (paras) => {
const session = paras[2];
return session.testGet();
};
/**
* 限制方法为Post访问
*/
export const NeedPost = () => NeedMethod("post");
/**
* 限制方法为POST访问
*/
export const TestPost = (paras) => {
const session = paras[2];
return session.testPost();
};
/**
* 限制方法为Restful访问
*/
export const NeedRestful = () => NeedMethod("get;post;put;patch;delete");
/**
* 限制方法为Get访问
*/
export const TestRestful = (paras) => {
const session = paras[2];
return session.testRestful();
};
/**
* 限制参数满足条件
* @param {要判断的参数} key
* @param {正则} regex
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedRegex = (key, regex, error, isRequire = false) => {
regex = regex.test ? regex : new RegExp(regex, "i");
return (target) =>
V.prop(target, "needs", function (req, rep, session) {
const value = session.param(key);
return typeof value != "undefined" && value != null && ("" + value).length
? regex.test(value)
? false
: error ||
`
限制$ { key }
参数需满足正则表达式要求: $ { regex }
`
: isRequire
? `
限制$ { key }
参数为必填 `
: false;
});
};
/**
* 限制参数满足条件
* @param {要判断的参数} key
* @param {正则} regex
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestRegex = (paras, key, regex, error, isRequire = false) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
return session.testRegex(key, regex, error, isRequire);
};
/**
* 限制参数满足是数字
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedNumber = (key, error, isRequire) =>
NeedRegex(
key,
/^([0-9]+\.{0,1}[0-9]{0,2})$/g,
error ||
`
限制$ { key }
要求是数字 `,
isRequire,
);
/**
* 限制参数满足是数字
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestNumber = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
return session.testNumber(key, error, isRequire);
};
/**
* 限制参数满足是整数
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedInt = (key, error, isRequire) =>
NeedRegex(
key,
/^([0-9]+)$/g,
error ||
`
限制$ { key }
要求是正整数 `,
isRequire,
);
/**
* 限制参数满足是数字
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestInt = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
return session.testInt(key, error, isRequire);
};
/**
* 限制参数满足是连续字母
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedLetter = (key, error, isRequire) =>
NeedRegex(
key,
/^([A-Za-z]+)$/g,
error ||
`
限制$ { key }
要求是连续字母 `,
isRequire,
);
/**
* 限制参数满足是数字
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestLetter = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
return session.testLetter(key, error, isRequire);
};
/**
* 限制参数满足是密码规范
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedPassword = (key, error, isRequire) =>
NeedRegex(
key,
/^(([a-zA-Z]|\w){5,17})$/g,
error ||
`
限制$ { key }
要求满足密码要求 `,
isRequire,
);
/**
* 限制参数满足是数字
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestPassword = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
return session.testPassword(key, error, isRequire);
};
/**
* 限制参数满足是非空必填
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedRequired = (key, error) => {
const regex = /^(\s*\S\s*)+$/g;
return (target) =>
V.prop(target, "needs", function (req, rep, session) {
const value = session.param(key);
return V.isValid(value)
? regex.test(value)
? false
: error ||
`
限制$ { key }
要求满足非空要求 `
: error;
});
};
/**
* 限制参数满足是非空必填
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestRequired = (paras, key, error) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
return session.testRequired(key, error);
};
/**
* 限制参数满足是身份证
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedCard = (key, error, isRequire) =>
NeedRegex(
key,
/^((\d{14}|\d{17})(\d|[a-zA-Z]))$/g,
error ||
`
限制$ { key }
要求身份证 `,
isRequire,
);
/**
* 限制参数满足是身份证
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestCard = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
session.testCard(key, error, isRequire);
};
/**
* 限制参数满足是手机号
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedMobile = (key, error, isRequire) =>
NeedRegex(
key,
/^(1[3|4|5|6|7|8][0-9]\d{8})$/g,
error ||
`
限制$ { key }
要求是手机号 `,
isRequire,
);
/**
* 限制参数满足是手机号
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestMobile = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
session.testMobile(key, error, isRequire);
};
/**
* 限制参数满足是座机
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedPhone = (key, error, isRequire) =>
NeedRegex(
key,
/^(\d{3}-\d{8}|\d{4}-\d{7})$/g,
error ||
`
限制$ { key }
要求是座机号 `,
isRequire,
);
/**
* 限制参数满足是座机
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestPhone = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
session.testPhone(key, error, isRequire);
};
/**
* 限制参数满足是网络地址
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedUrl = (key, error, isRequire) =>
NeedRegex(
key,
/^((http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?)$/g,
error ||
`
限制$ { key }
要求是URL `,
isRequire,
);
/**
* 限制参数满足是网络地址
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestUrl = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
session.testUrl(key, error, isRequire);
};
/**
* 限制参数满足是电子邮箱
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedEmail = (key, error, isRequire) =>
NeedRegex(
key,
/^(\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)$/g,
error ||
`
限制$ { key }
要求是邮箱 `,
isRequire,
);
/**
* 限制参数满足是电子邮箱
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestEmail = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
session.testEmail(key, error, isRequire);
};
/**
* 限制参数满足是中文
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedChinese = (key, error, isRequire) =>
NeedRegex(
key,
/^([\u4e00-\u9fa5]{0,})$/g,
error ||
`
限制$ { key }
要求是中文 `,
isRequire,
);
/**
* 限制参数满足是中文
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestChinese = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
session.testChinese(key, error, isRequire);
};
/**
* 限制参数满足是QQ
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedQQ = (key, error, isRequire) =>
NeedRegex(
key,
/^([1-9]\d{4,12})$/g,
error ||
`
限制$ { key }
要求是QQ号 `,
isRequire,
);
/**
* 限制参数满足是QQ
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestQQ = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
session.testQQ(key, error, isRequire);
};
/**
* 限制参数满足是邮政编码
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedZipCode = (key, error, isRequire) =>
NeedRegex(
key,
/^([1-9]\d{5}(?!\d))$/g,
error ||
`
限制$ { key }
要求是邮编 `,
isRequire,
);
/**
* 限制参数满足是邮政编码
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestZipCode = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
session.testZipCode(key, error, isRequire);
};
/**
* 限制参数满足是IP
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedIP = (key, error, isRequire) =>
NeedRegex(
key,
/^(([\d+\.]{3}|[\d+\.]{5})\d+)$/g,
error ||
`
限制$ { key }
要求是IP `,
isRequire,
);
/**
* 限制参数满足是IP
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestIP = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
session.testIP(key, error, isRequire);
};
/**
* 限制参数满足是金额(2位小数)
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedCurreny = (key, error, isRequire) =>
NeedRegex(
key,
/^(\d+\.\d{2})$/g,
error ||
`
限制$ { key }
要求是金额 `,
isRequire,
);
/**
* 限制参数满足是金额(2位小数)
* @param {要判断的参数} key
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestCurreny = (paras, key, error, isRequire) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
session.testCurreny(key, error, isRequire);
};
/**
* 限制操作所需权限
* @param {要判断的参数} key
* @param {正则} regex
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const NeedPermission = (key, error) => {
return (target) =>
V.prop(target, "needs", async function (req, rep, session) {
let val = false;
await V.each(
key.split(","),
async (v) => {
val =
val || (await session.hasRight(v))
? false
: error || `该操作需要${v}权限 `;
},
true,
);
if (!!val) {
const e = new Error(val);
e.status = 401;
throw e;
}
return false;
});
};
/**
* 限制操作所需权限
* @param {要判断的参数} key
* @param {正则} regex
* @param {错误说明} error
* @param {是否必填} isRequire
*/
export const TestPermission = async (paras, key, error) => {
const req = paras[0],
rep = paras[1],
session = paras[2];
return await session.testPermission(key, error);
};
export default {
AAction,
LoadModuler,
AFilter,
SessionFilter,
FormFilter,
AppSettingFilter,
NiModuler,
NeedCard,
NeedChinese,
NeedCurreny,
NeedEmail,
NeedGet,
NeedIP,
NeedInt,
NeedLetter,
NeedMethod,
NeedMobile,
NeedNumber,
NeedPassword,
NeedPhone,
NeedPost,
NeedQQ,
NeedRegex,
NeedRequired,
NeedRestful,
NeedUrl,
NeedZipCode,
TestCard,
TestChinese,
TestCurreny,
TestEmail,
TestGet,
TestIP,
TestInt,
TestLetter,
TestMethod,
TestMobile,
TestNumber,
TestPassword,
TestPhone,
TestPost,
TestQQ,
TestRegex,
TestRequired,
TestRestful,
TestUrl,
TestZipCode,
NeedPermission,
TestPermission,
};
const pri = V.pris();