diff --git a/.editorconfig b/.editorconfig index f1b5c5b..0ad99e7 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,11 +4,11 @@ root = true # 应在文件顶部指定的特殊属性,true表示停止搜索 [*] charset = utf-8 # 统一字符格式 indent_style = space # 缩进方式为空格 -indent_size = 2 # 缩进为两个空格 +indent_size = 4 # 缩进为两个空格 end_of_line = lf # 换行符统一用lf insert_final_newline = true # 保证文件结尾留一个空行 trim_trailing_whitespace = true # 移除新一行前的空白字符 [*.md] insert_final_newline = false -trim_trailing_whitespace = false \ No newline at end of file +trim_trailing_whitespace = false diff --git a/packages/hapi-router/dist/hapi-router.cjs.js b/packages/hapi-router/dist/hapi-router.cjs.js index 4cbc063..c355ca4 100644 --- a/packages/hapi-router/dist/hapi-router.cjs.js +++ b/packages/hapi-router/dist/hapi-router.cjs.js @@ -42,6 +42,44 @@ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +} + function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); @@ -225,15 +263,16 @@ var routePlugin = (function () { var keys = Reflect.ownKeys(prototype); var _loop_1 = function (key) { if (key !== "constructor") { - var ff = func[key]; - var method = ff.$method || "GET"; + var ff_1 = func[key]; + var handler = undefined; + var method = ff_1.$method || "GET"; var route_1 = ""; - if (ff.$route) { + if (ff_1.$route) { if (isIndexEnd(fileNoExt)) { - route_1 = ff.$route; + route_1 = ff_1.$route; } else { - route_1 = fileNoExt + ff.$route; + route_1 = fileNoExt + ff_1.$route; } } else { @@ -246,9 +285,9 @@ var routePlugin = (function () { } route_1 = removeIndex(route_1); route_1 = prefix ? route_1[0] + prefix + "/" + route_1.slice(1) : route_1; - var options = ff.$options ? ff.$options : {}; + var options = ff_1.$options ? ff_1.$options : {}; if (!options.auth) { - if (ff.$auth == undefined) { + if (ff_1.$auth == undefined) { if (auth && auth.length && auth.filter(function (v) { return route_1.startsWith(v); }).length) { @@ -258,13 +297,13 @@ var routePlugin = (function () { options.auth = false; } } - else if (ff.$auth) { + else if (ff_1.$auth) { options.auth = - typeof ff.$auth === "boolean" + typeof ff_1.$auth === "boolean" ? type : { strategy: type, - mode: ff.$auth, + mode: ff_1.$auth, }; } else { @@ -272,7 +311,7 @@ var routePlugin = (function () { } } if (!options.validate) { - var validateObj = ff.$validate || {}; + var validateObj = ff_1.$validate || {}; if (options.auth && type === "jwt") { if (validateObj.headers) { validateObj.headers = validateObj.headers.keys({ @@ -287,14 +326,79 @@ var routePlugin = (function () { }); } } - if (validateObj) { + if (validateObj && !!Object.keys(validateObj).length) { + if (validateObj.failAction === "log") { + if (!options.log) + options.log = {}; + options.log.collect = true; + var errto_1 = validateObj.$errto; + handler = function () { + var argus = []; + for (var _i = 0; _i < arguments.length; _i++) { + argus[_i] = arguments[_i]; + } + return __awaiter(this, void 0, void 0, function () { + var request, h; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + request = argus[0]; + h = argus[1]; + if (request.logs && !!request.logs.length && errto_1) { + request.yar.flash('error', request.logs.map(function (v) { return v.error.message; })); + return [2, h.redirect(errto_1)]; + } + return [4, ff_1.call.apply(ff_1, __spread([this], argus))]; + case 1: return [2, _a.sent()]; + } + }); + }); + }; + } + if (validateObj.failAction === "function") { + var errto_2 = validateObj.$errto; + validateObj.failAction = function (request, h, err) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + if (err.details) { + request.$joi_error = err.details.map(function (v) { return v.message; }); + } + return [2, h.continue]; + }); + }); + }; + handler = function () { + var argus = []; + for (var _i = 0; _i < arguments.length; _i++) { + argus[_i] = arguments[_i]; + } + return __awaiter(this, void 0, void 0, function () { + var request, h; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + request = argus[0]; + h = argus[1]; + if (request.$joi_error) { + loggerSite.debug('传输参数错误: ', request.$joi_error); + request.yar.flash('error', request.$joi_error); + delete request.$joi_error; + return [2, h.redirect(errto_2)]; + } + return [4, ff_1.call.apply(ff_1, __spread([this], argus))]; + case 1: return [2, _a.sent()]; + } + }); + }); + }; + } options.validate = validateObj; } } - if (ff.$swagger) { - options.description = ff.$swagger[0]; - options.notes = ff.$swagger[1]; - options.tags = ff.$swagger[2]; + if (ff_1.$swagger) { + options.description = ff_1.$swagger[0]; + options.notes = ff_1.$swagger[1]; + options.tags = ff_1.$swagger[2]; } var str = route_1; if ((typeof options.auth === "string" && options.auth) || @@ -318,10 +422,16 @@ var routePlugin = (function () { " 不需权限 : " + " " + full(method) + " " + str; } routes.push(str); + if (options.validate && options.validate.$errto) { + delete options.validate.$errto; + } + if (!handler) { + handler = ff_1; + } server.route({ method: method, path: route_1, - handler: ff, + handler: handler, options: options, }); } diff --git a/packages/hapi-router/dist/hapi-router.cjs.js.map b/packages/hapi-router/dist/hapi-router.cjs.js.map index f695e01..7b44d0b 100644 --- a/packages/hapi-router/dist/hapi-router.cjs.js.map +++ b/packages/hapi-router/dist/hapi-router.cjs.js.map @@ -1 +1 @@ -{"version":3,"file":"hapi-router.cjs.js","sources":["../src/util/index.ts","../src/util/decorators.ts","../src/index.ts"],"sourcesContent":["// @ts-nocheck\r\n\r\nconst path = require(\"path\")\r\nconst fs = require(\"fs\")\r\n\r\nexport function removeIndex(ss:any) {\r\n const remove = (str:any) => {\r\n if (str.endsWith(\"/index\")) {\r\n return str.slice(0, -6);\r\n }\r\n if (str.endsWith(\"index\")) {\r\n return str.slice(0, -5);\r\n }\r\n return str ? str : \"/\";\r\n };\r\n let r = true;\r\n let rr = ss;\r\n while (r) {\r\n if (rr.endsWith(\"/index\")) {\r\n rr = remove(rr);\r\n } else {\r\n r = false;\r\n }\r\n }\r\n return rr ? rr : \"/\";\r\n}\r\n\r\nexport function isIndexEnd(str:any) {\r\n return str.length == 1 && str.endsWith(\"/\");\r\n}\r\n\r\n\r\nexport function walkDir(\r\n filePath:any,\r\n exclude = [\"node_modules\", \"^_\", \".git\", \".idea\", \".gitignore\", \"client\",\"\\.txt$\",\"\\.test\\.js$\",\"\\.test\\.ts$\"]\r\n) {\r\n let files:any[] = [];\r\n function Data(opts:any) {\r\n this.relativeDir = opts.relativeDir;\r\n this.relativeFile = opts.relativeFile;\r\n this.filename = opts.filename;\r\n this.file = opts.file;\r\n this.absoluteFile = opts.absoluteFile;\r\n this.relativeFileNoExt = opts.relativeFileNoExt;\r\n this.absoluteDir = opts.absoluteDir;\r\n }\r\n function readDir(filePath, dirname = \".\") {\r\n let res = fs.readdirSync(filePath);\r\n res.forEach((filename) => {\r\n const filepath = path.resolve(filePath, filename);\r\n const stat = fs.statSync(filepath);\r\n const name = filepath.split(path.sep).slice(-1)[0];\r\n if (typeof exclude === \"string\" && new RegExp(exclude).test(name)) {\r\n return;\r\n }\r\n if (Array.isArray(exclude)) {\r\n for (let i = 0; i < exclude.length; i++) {\r\n const excludeItem = exclude[i];\r\n if (new RegExp(excludeItem).test(name)) {\r\n return;\r\n }\r\n }\r\n }\r\n if (!stat.isFile()) {\r\n readDir(filepath, dirname + path.sep + name);\r\n } else {\r\n const data = new Data({\r\n relativeDir: dirname,\r\n relativeFile: dirname + path.sep + path.parse(filepath).base,\r\n relativeFileNoExt: dirname + path.sep + path.parse(filepath).name,\r\n file: path.parse(filepath).base,\r\n filename: path.parse(filepath).name,\r\n absoluteFile: filepath,\r\n absoluteDir: path.parse(filepath).dir,\r\n });\r\n files.push(data);\r\n }\r\n });\r\n }\r\n readDir(filePath);\r\n return files;\r\n}\r\n","// @ts-nocheck\r\n/**\r\n * 方法\r\n * @param opts 参数\r\n*/\r\nexport function method(opts?:string|Array) {\r\n return function (target, propertyKey: string, descriptor: PropertyDescriptor) {\r\n target[propertyKey].$method = opts\r\n }\r\n}\r\nexport function route(route?:string) {\r\n return function (target, propertyKey: string, descriptor: PropertyDescriptor) {\r\n target[propertyKey].$route = route\r\n }\r\n}\r\n\r\nexport function config(options:Object) {\r\n return function (target, propertyKey: string, descriptor: PropertyDescriptor) {\r\n target[propertyKey].$options = options\r\n }\r\n}\r\n\r\nexport function auth(isAuth:boolean | \"try\" | \"required\" | \"optional\" = true) {\r\n return function (target, propertyKey: string, descriptor: PropertyDescriptor) {\r\n target[propertyKey].$auth = isAuth\r\n }\r\n}\r\n\r\nexport function validate(validate:Object) {\r\n return function (target, propertyKey: string, descriptor: PropertyDescriptor) {\r\n target[propertyKey].$validate = validate\r\n }\r\n}\r\n\r\nexport function swagger(desc,notes,tags) {\r\n return function (target, propertyKey: string, descriptor: PropertyDescriptor) {\r\n target[propertyKey].$swagger = [desc,notes,tags]\r\n }\r\n}\r\n","// @ts-nocheck\r\n\r\nimport { walkDir, removeIndex, isIndexEnd } from \"./util\";\r\nimport * as Joi from \"joi\";\r\nconst path = require(\"path\");\r\nconst fs = require(\"fs\");\r\n\r\nclass routePlugin {\r\n public name: string = \"routePlugin\";\r\n public version: string = \"0.0.1\";\r\n public register(server: any, opts: any) {\r\n const sourceDir = opts.sourceDir;\r\n const type = opts.type || \"jwt\";\r\n const auth = opts.auth || [];\r\n let array = [];\r\n for (let i = 0; i < sourceDir.length; i++) {\r\n const dir = sourceDir[i];\r\n console.log(dir);\r\n array.push(dir.dir + \"对应路径:\");\r\n array = array.concat(\r\n this.registerRoute(server, dir.dir, dir.prefix || \"\", auth, type)\r\n );\r\n }\r\n fs.writeFileSync(\r\n path.resolve(process.cwd(), \"route.txt\"),\r\n array.join(\"\\n\"),\r\n {\r\n encoding: \"utf-8\",\r\n }\r\n );\r\n }\r\n registerRoute(server, sourceDir, prefix, auth, type) {\r\n const files = walkDir(sourceDir);\r\n const routes = [];\r\n files.forEach((file) => {\r\n let filename = file.relativeFileNoExt;\r\n let array = filename.split(path.sep).slice(1);\r\n let fileNoExt = removeIndex(\"/\" + array.join(\"/\"));\r\n const moduleName = path.resolve(sourceDir, filename);\r\n const obj = require(moduleName);\r\n if (obj.default) {\r\n const func = new (obj.default || obj)();\r\n const prototype = Object.getPrototypeOf(func);\r\n const keys = Reflect.ownKeys(prototype);\r\n for (const key of keys) {\r\n if (key !== \"constructor\") {\r\n let ff = func[key];\r\n // 默认方法\r\n const method = ff.$method || \"GET\";\r\n // 路由收集规则\r\n let route = \"\";\r\n if (ff.$route) {\r\n if (isIndexEnd(fileNoExt)) {\r\n route = ff.$route;\r\n } else {\r\n route = fileNoExt + ff.$route;\r\n }\r\n } else {\r\n if (isIndexEnd(fileNoExt)) {\r\n route = fileNoExt + key.toString();\r\n } else {\r\n route = fileNoExt + \"/\" + key.toString();\r\n }\r\n }\r\n route = removeIndex(route);\r\n route = prefix ? route[0] + prefix + \"/\" + route.slice(1) : route;\r\n // 配置规则\r\n const options = ff.$options ? ff.$options : {};\r\n if (!options.auth) {\r\n if (ff.$auth == undefined) {\r\n if (\r\n auth &&\r\n auth.length &&\r\n auth.filter((v) => route.startsWith(v)).length\r\n ) {\r\n options.auth = type;\r\n } else {\r\n options.auth = false;\r\n }\r\n } else if (ff.$auth) {\r\n options.auth =\r\n typeof ff.$auth === \"boolean\"\r\n ? type\r\n : {\r\n strategy: type,\r\n mode: ff.$auth,\r\n };\r\n } else {\r\n options.auth = false;\r\n }\r\n }\r\n if (!options.validate) {\r\n let validateObj = ff.$validate || {};\r\n if (options.auth && type === \"jwt\") {\r\n if (validateObj.headers) {\r\n validateObj.headers = validateObj.headers.keys({\r\n Authorization: Joi.string(),\r\n });\r\n } else {\r\n validateObj.headers = Joi.object({\r\n headers: Joi.object({\r\n Authorization: Joi.string(),\r\n }).unknown(), // 注意加上这个\r\n });\r\n }\r\n }\r\n if (validateObj) {\r\n options.validate = validateObj;\r\n }\r\n }\r\n // && route.startsWith(\"/api\")\r\n if (ff.$swagger) {\r\n options.description = ff.$swagger[0];\r\n options.notes = ff.$swagger[1];\r\n options.tags = ff.$swagger[2];\r\n }\r\n let str = route;\r\n if (\r\n (typeof options.auth === \"string\" && options.auth) ||\r\n (typeof options.auth === \"object\" &&\r\n options.auth.mode === \"required\")\r\n ) {\r\n str =\r\n \" 需要权限 : \" + \" \" + full(method) + \" \" + str;\r\n } else if (\r\n typeof options.auth === \"object\" &&\r\n options.auth.mode === \"optional\"\r\n ) {\r\n str =\r\n \" 不需权限(提供即需验证): \" + \" \" + full(method) + \" \" + str;\r\n } else if (\r\n typeof options.auth === \"object\" &&\r\n options.auth.mode === \"try\"\r\n ) {\r\n str =\r\n \" 不需权限(提供无需验证): \" + \" \" + full(method) + \" \" + str;\r\n } else {\r\n str =\r\n \" 不需权限 : \" + \" \" + full(method) + \" \" + str;\r\n }\r\n routes.push(str);\r\n server.route({\r\n method: method,\r\n path: route,\r\n handler: ff,\r\n options: options,\r\n });\r\n }\r\n }\r\n }\r\n });\r\n return routes;\r\n }\r\n}\r\n\r\nfunction full(str: string, length = 10) {\r\n let len = str.length;\r\n let need = length - len;\r\n if (need <= 0) return str;\r\n return str + [...Array(need)].map((v, i) => \" \").join(\"\");\r\n}\r\n\r\nconst plugin = new routePlugin();\r\n\r\nexport { plugin };\r\nexport * from \"./util/decorators\";\r\n"],"names":["path","fs","Joi"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"hapi-router.cjs.js","sources":["../src/util/index.ts","../src/util/decorators.ts","../src/index.ts"],"sourcesContent":["// @ts-nocheck\r\n\r\nconst path = require(\"path\")\r\nconst fs = require(\"fs\")\r\n\r\nexport function removeIndex(ss:any) {\r\n const remove = (str:any) => {\r\n if (str.endsWith(\"/index\")) {\r\n return str.slice(0, -6);\r\n }\r\n if (str.endsWith(\"index\")) {\r\n return str.slice(0, -5);\r\n }\r\n return str ? str : \"/\";\r\n };\r\n let r = true;\r\n let rr = ss;\r\n while (r) {\r\n if (rr.endsWith(\"/index\")) {\r\n rr = remove(rr);\r\n } else {\r\n r = false;\r\n }\r\n }\r\n return rr ? rr : \"/\";\r\n}\r\n\r\nexport function isIndexEnd(str:any) {\r\n return str.length == 1 && str.endsWith(\"/\");\r\n}\r\n\r\n\r\nexport function walkDir(\r\n filePath:any,\r\n exclude = [\"node_modules\", \"^_\", \".git\", \".idea\", \".gitignore\", \"client\",\"\\.txt$\",\"\\.test\\.js$\",\"\\.test\\.ts$\"]\r\n) {\r\n let files:any[] = [];\r\n function Data(opts:any) {\r\n this.relativeDir = opts.relativeDir;\r\n this.relativeFile = opts.relativeFile;\r\n this.filename = opts.filename;\r\n this.file = opts.file;\r\n this.absoluteFile = opts.absoluteFile;\r\n this.relativeFileNoExt = opts.relativeFileNoExt;\r\n this.absoluteDir = opts.absoluteDir;\r\n }\r\n function readDir(filePath, dirname = \".\") {\r\n let res = fs.readdirSync(filePath);\r\n res.forEach((filename) => {\r\n const filepath = path.resolve(filePath, filename);\r\n const stat = fs.statSync(filepath);\r\n const name = filepath.split(path.sep).slice(-1)[0];\r\n if (typeof exclude === \"string\" && new RegExp(exclude).test(name)) {\r\n return;\r\n }\r\n if (Array.isArray(exclude)) {\r\n for (let i = 0; i < exclude.length; i++) {\r\n const excludeItem = exclude[i];\r\n if (new RegExp(excludeItem).test(name)) {\r\n return;\r\n }\r\n }\r\n }\r\n if (!stat.isFile()) {\r\n readDir(filepath, dirname + path.sep + name);\r\n } else {\r\n const data = new Data({\r\n relativeDir: dirname,\r\n relativeFile: dirname + path.sep + path.parse(filepath).base,\r\n relativeFileNoExt: dirname + path.sep + path.parse(filepath).name,\r\n file: path.parse(filepath).base,\r\n filename: path.parse(filepath).name,\r\n absoluteFile: filepath,\r\n absoluteDir: path.parse(filepath).dir,\r\n });\r\n files.push(data);\r\n }\r\n });\r\n }\r\n readDir(filePath);\r\n return files;\r\n}\r\n","// @ts-nocheck\r\n/**\r\n * 方法\r\n * @param opts 参数\r\n*/\r\nexport function method(opts?:string|Array) {\r\n return function (target, propertyKey: string, descriptor: PropertyDescriptor) {\r\n target[propertyKey].$method = opts\r\n }\r\n}\r\nexport function route(route?:string) {\r\n return function (target, propertyKey: string, descriptor: PropertyDescriptor) {\r\n target[propertyKey].$route = route\r\n }\r\n}\r\n\r\nexport function config(options:Object) {\r\n return function (target, propertyKey: string, descriptor: PropertyDescriptor) {\r\n target[propertyKey].$options = options\r\n }\r\n}\r\n\r\nexport function auth(isAuth:boolean | \"try\" | \"required\" | \"optional\" = true) {\r\n return function (target, propertyKey: string, descriptor: PropertyDescriptor) {\r\n target[propertyKey].$auth = isAuth\r\n }\r\n}\r\n\r\nexport function validate(validate:Object) {\r\n return function (target, propertyKey: string, descriptor: PropertyDescriptor) {\r\n target[propertyKey].$validate = validate\r\n }\r\n}\r\n\r\nexport function swagger(desc,notes,tags) {\r\n return function (target, propertyKey: string, descriptor: PropertyDescriptor) {\r\n target[propertyKey].$swagger = [desc,notes,tags]\r\n }\r\n}\r\n","// @ts-nocheck\n\nimport { walkDir, removeIndex, isIndexEnd } from \"./util\";\nimport * as Joi from \"joi\";\nconst path = require(\"path\");\nconst fs = require(\"fs\");\n\nclass routePlugin {\n public name: string = \"routePlugin\";\n public version: string = \"0.0.1\";\n public register(server: any, opts: any) {\n const sourceDir = opts.sourceDir;\n const type = opts.type || \"jwt\";\n const auth = opts.auth || [];\n let array = [];\n for (let i = 0; i < sourceDir.length; i++) {\n const dir = sourceDir[i];\n console.log(dir);\n array.push(dir.dir + \"对应路径:\");\n array = array.concat(\n this.registerRoute(server, dir.dir, dir.prefix || \"\", auth, type)\n );\n }\n fs.writeFileSync(\n path.resolve(process.cwd(), \"route.txt\"),\n array.join(\"\\n\"),\n {\n encoding: \"utf-8\",\n }\n );\n }\n registerRoute(server, sourceDir, prefix, auth, type) {\n const files = walkDir(sourceDir);\n const routes = [];\n files.forEach((file) => {\n let filename = file.relativeFileNoExt;\n let array = filename.split(path.sep).slice(1);\n let fileNoExt = removeIndex(\"/\" + array.join(\"/\"));\n const moduleName = path.resolve(sourceDir, filename);\n const obj = require(moduleName);\n if (obj.default) {\n const func = new (obj.default || obj)();\n const prototype = Object.getPrototypeOf(func);\n const keys = Reflect.ownKeys(prototype);\n for (const key of keys) {\n if (key !== \"constructor\") {\n let ff = func[key];\n let handler:()=>void = undefined\n // 默认方法\n const method = ff.$method || \"GET\";\n // 路由收集规则\n let route = \"\";\n if (ff.$route) {\n if (isIndexEnd(fileNoExt)) {\n route = ff.$route;\n } else {\n route = fileNoExt + ff.$route;\n }\n } else {\n if (isIndexEnd(fileNoExt)) {\n route = fileNoExt + key.toString();\n } else {\n route = fileNoExt + \"/\" + key.toString();\n }\n }\n route = removeIndex(route);\n route = prefix ? route[0] + prefix + \"/\" + route.slice(1) : route;\n // 配置规则\n const options = ff.$options ? ff.$options : {};\n if (!options.auth) {\n if (ff.$auth == undefined) {\n if (\n auth &&\n auth.length &&\n auth.filter((v) => route.startsWith(v)).length\n ) {\n options.auth = type;\n } else {\n options.auth = false;\n }\n } else if (ff.$auth) {\n options.auth =\n typeof ff.$auth === \"boolean\"\n ? type\n : {\n strategy: type,\n mode: ff.$auth,\n };\n } else {\n options.auth = false;\n }\n }\n if (!options.validate) {\n let validateObj = ff.$validate || {};\n if (options.auth && type === \"jwt\") {\n if (validateObj.headers) {\n validateObj.headers = validateObj.headers.keys({\n Authorization: Joi.string(),\n });\n } else {\n validateObj.headers = Joi.object({\n headers: Joi.object({\n Authorization: Joi.string(),\n }).unknown(), // 注意加上这个\n });\n }\n }\n if (validateObj&&!!Object.keys(validateObj).length) {\n if(validateObj.failAction === \"log\"){\n if(!options.log) options.log = {}\n options.log.collect = true\n let errto = validateObj.$errto\n handler = async function (...argus){\n const request = argus[0]\n const h = argus[1]\n if(request.logs&&!!request.logs.length && errto){\n request.yar.flash('error', request.logs.map((v: any)=>v.error.message));\n return h.redirect(errto);\n }\n return await ff.call(this, ...argus)\n }\n }\n if(validateObj.failAction === \"function\"){\n let errto = validateObj.$errto\n validateObj.failAction = async function(request, h, err){\n if(err.details){\n request.$joi_error = err.details.map(v=>v.message)\n }\n return h.continue;\n }\n handler = async function (...argus){\n const request = argus[0]\n const h = argus[1]\n if(request.$joi_error){\n loggerSite.debug('传输参数错误: ', request.$joi_error)\n request.yar.flash('error', request.$joi_error);\n delete request.$joi_error\n return h.redirect(errto);\n }\n return await ff.call(this, ...argus)\n }\n }\n options.validate = validateObj;\n }\n }\n // && route.startsWith(\"/api\")\n if (ff.$swagger) {\n options.description = ff.$swagger[0];\n options.notes = ff.$swagger[1];\n options.tags = ff.$swagger[2];\n }\n let str = route;\n if (\n (typeof options.auth === \"string\" && options.auth) ||\n (typeof options.auth === \"object\" &&\n options.auth.mode === \"required\")\n ) {\n str =\n \" 需要权限 : \" + \" \" + full(method) + \" \" + str;\n } else if (\n typeof options.auth === \"object\" &&\n options.auth.mode === \"optional\"\n ) {\n str =\n \" 不需权限(提供即需验证): \" + \" \" + full(method) + \" \" + str;\n } else if (\n typeof options.auth === \"object\" &&\n options.auth.mode === \"try\"\n ) {\n str =\n \" 不需权限(提供无需验证): \" + \" \" + full(method) + \" \" + str;\n } else {\n str =\n \" 不需权限 : \" + \" \" + full(method) + \" \" + str;\n }\n routes.push(str);\n\n if(options.validate && options.validate.$errto){\n delete options.validate.$errto\n }\n if(!handler){\n handler = ff\n }\n server.route({\n method: method,\n path: route,\n handler: handler,\n options: options,\n });\n }\n }\n }\n });\n return routes;\n }\n}\n\nfunction full(str: string, length = 10) {\n let len = str.length;\n let need = length - len;\n if (need <= 0) return str;\n return str + [...Array(need)].map((v, i) => \" \").join(\"\");\n}\n\nconst plugin = new routePlugin();\n\nexport { plugin };\nexport * from \"./util/decorators\";\n"],"names":["path","fs","Joi"],"mappings":"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"} \ No newline at end of file diff --git a/packages/hapi-router/pnpm-lock.yaml b/packages/hapi-router/pnpm-lock.yaml index 3dc8cfd..0a47f4b 100644 --- a/packages/hapi-router/pnpm-lock.yaml +++ b/packages/hapi-router/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: 5.3 +lockfileVersion: 5.4 specifiers: '@rollup/plugin-alias': ^3.1.1 @@ -35,8 +35,8 @@ devDependencies: ftp-deploy: 2.4.1 lodash: 4.17.21 rollup: 2.51.2 - rollup-plugin-sourcemaps: 0.6.3_0092beb8efba53e1329cf7064a1da378 - rollup-plugin-typescript2: 0.27.3_rollup@2.51.2+typescript@3.9.9 + rollup-plugin-sourcemaps: 0.6.3_acjl5ohpxjj6cmu464deuhndpa + rollup-plugin-typescript2: 0.27.3_uiok2ebg7dovbc73ivn6j7a2ry tslib: 2.3.0 typescript: 3.9.9 @@ -453,6 +453,7 @@ packages: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + requiresBuild: true dev: true optional: true @@ -922,7 +923,7 @@ packages: engines: {node: '>= 4'} dev: true - /rollup-plugin-sourcemaps/0.6.3_0092beb8efba53e1329cf7064a1da378: + /rollup-plugin-sourcemaps/0.6.3_acjl5ohpxjj6cmu464deuhndpa: resolution: {integrity: sha512-paFu+nT1xvuO1tPFYXGe+XnQvg4Hjqv/eIhG8i5EspfYYPBKL57X7iVbfv55aNVASg3dzWvES9dmWsL2KhfByw==} engines: {node: '>=10.0.0'} peerDependencies: @@ -938,7 +939,7 @@ packages: source-map-resolve: 0.6.0 dev: true - /rollup-plugin-typescript2/0.27.3_rollup@2.51.2+typescript@3.9.9: + /rollup-plugin-typescript2/0.27.3_uiok2ebg7dovbc73ivn6j7a2ry: resolution: {integrity: sha512-gmYPIFmALj9D3Ga1ZbTZAKTXq1JKlTQBtj299DXhqYz9cL3g/AQfUvbb2UhH+Nf++cCq941W2Mv7UcrcgLzJJg==} peerDependencies: rollup: '>=1.26.3' diff --git a/packages/hapi-router/src/index.ts b/packages/hapi-router/src/index.ts index 0044739..43fe50d 100755 --- a/packages/hapi-router/src/index.ts +++ b/packages/hapi-router/src/index.ts @@ -45,6 +45,7 @@ class routePlugin { for (const key of keys) { if (key !== "constructor") { let ff = func[key]; + let handler:()=>void = undefined // 默认方法 const method = ff.$method || "GET"; // 路由收集规则 @@ -104,7 +105,41 @@ class routePlugin { }); } } - if (validateObj) { + if (validateObj&&!!Object.keys(validateObj).length) { + if(validateObj.failAction === "log"){ + if(!options.log) options.log = {} + options.log.collect = true + let errto = validateObj.$errto + handler = async function (...argus){ + const request = argus[0] + const h = argus[1] + if(request.logs&&!!request.logs.length && errto){ + request.yar.flash('error', request.logs.map((v: any)=>v.error.message)); + return h.redirect(errto); + } + return await ff.call(this, ...argus) + } + } + if(validateObj.failAction === "function"){ + let errto = validateObj.$errto + validateObj.failAction = async function(request, h, err){ + if(err.details){ + request.$joi_error = err.details.map(v=>v.message) + } + return h.continue; + } + handler = async function (...argus){ + const request = argus[0] + const h = argus[1] + if(request.$joi_error){ + loggerSite.debug('传输参数错误: ', request.$joi_error) + request.yar.flash('error', request.$joi_error); + delete request.$joi_error + return h.redirect(errto); + } + return await ff.call(this, ...argus) + } + } options.validate = validateObj; } } @@ -139,10 +174,17 @@ class routePlugin { " 不需权限 : " + " " + full(method) + " " + str; } routes.push(str); + + if(options.validate && options.validate.$errto){ + delete options.validate.$errto + } + if(!handler){ + handler = ff + } server.route({ method: method, path: route, - handler: ff, + handler: handler, options: options, }); } diff --git a/readme.md b/readme.md index e7435da..20727cf 100644 --- a/readme.md +++ b/readme.md @@ -10,4 +10,9 @@ 增加测试库 - @hapi/code - @hapi/lab -暂时不太清楚怎么结合使用 \ No newline at end of file +暂时不太清楚怎么结合使用 + + +## 对于验证库的处理方式参考 +https://docs4dev.com/questions/345443 +https://github.com/nelsonic/hapi-validation-question \ No newline at end of file diff --git a/route.txt b/route.txt index 412e74b..48fe151 100644 --- a/route.txt +++ b/route.txt @@ -7,6 +7,8 @@ D:\@code\project\hapi-demo\source\route\api对应路径: 不需权限 : POST /api/v1/user/login 需要权限 : DELETE /api/v1/user/del 需要权限 : GET /api/v1/user/userinfo +D:\@code\project\hapi-demo\source\route\htmx对应路径: + 不需权限 : GET /htmx/clicked D:\@code\project\hapi-demo\source\route\views对应路径: 不需权限(提供无需验证): GET /404 不需权限 : GET /css @@ -19,4 +21,5 @@ D:\@code\project\hapi-demo\source\route\views对应路径: 需要权限 : GET /logout 不需权限(提供无需验证): GET /register 不需权限 : POST /register - 不需权限 : GET /nav \ No newline at end of file + 不需权限 : GET /nav + 需要权限 : GET /user \ No newline at end of file diff --git a/source/db/data.db b/source/db/data.db index 85db86f..fd6ad66 100644 Binary files a/source/db/data.db and b/source/db/data.db differ diff --git a/source/models/User.ts b/source/models/User.ts index 81c8275..6dfa72c 100644 --- a/source/models/User.ts +++ b/source/models/User.ts @@ -8,11 +8,15 @@ module.exports = function (sequelize, DataTypes) { type: DataTypes.STRING, allowNull: false }, + nickname: { + type: DataTypes.STRING, + allowNull: false + }, email: { type: DataTypes.STRING, } }, { - + }); return User -}; \ No newline at end of file +}; diff --git a/source/models/ha/user.ts b/source/models/ha/user.ts new file mode 100644 index 0000000..d2c2375 --- /dev/null +++ b/source/models/ha/user.ts @@ -0,0 +1,26 @@ +module.exports = function (sequelize, DataTypes) { + const User = sequelize.define('ha-user', { + username: { + type: DataTypes.STRING, + allowNull: false + }, + avatar: { + type: DataTypes.STRING, + allowNull: false + }, + password: { + type: DataTypes.STRING, + allowNull: false + }, + nickname: { + type: DataTypes.STRING, + allowNull: false + }, + email: { + type: DataTypes.STRING, + } + }, { + + }); + return User +}; diff --git a/source/plugins/index.ts b/source/plugins/index.ts index 0d68709..c8f0335 100644 --- a/source/plugins/index.ts +++ b/source/plugins/index.ts @@ -21,6 +21,10 @@ export default [ prefix: "api" }, { + dir: path.resolve(sourceDir, "route/htmx"), + prefix: "htmx" + }, + { dir: path.resolve(sourceDir, "route/views"), prefix: "" }, @@ -37,20 +41,21 @@ export default [ server.ext('onPreResponse', async function(request: Request, h) { // @ts-ignore if(request.response.variety === "file") return h.continue; // 返回文件时不处理 + if(request.path.startsWith("/api") || request.path.startsWith("/htmx")) return h.continue; // 需要设置auth是try或者true才行 const isLogin = request.auth.isAuthenticated; console.log("是否登录:",isLogin, request.path); // @ts-ignore // console.log(isLogin, request.path, request.response.variety); - let user; - if(isLogin){ - const { id } = request.auth.credentials; - const User = request.getModel("User") - user = await User.findOne({ where: { id: id } }); - user = user.toJSON(); - delete user.password; - } + // let user; + // if(isLogin){ + // const { id } = request.auth.credentials; + // const User = request.getModel("User") + // user = await User.findOne({ where: { id: id } }); + // user = user.toJSON(); + // delete user.password; + // } // @ts-ignore if (request.yar && request.yar.flash && request.response.variety === 'view') { var flash = request.yar.flash(); @@ -60,7 +65,7 @@ export default [ { flash: !!Object.keys(flash).length?flash:false, isLogin: isLogin, - user: user + user: isLogin?request.auth.credentials:false, }, // @ts-ignore request.response.source.context diff --git a/source/route/htmx/index.ts b/source/route/htmx/index.ts new file mode 100644 index 0000000..7ac90af --- /dev/null +++ b/source/route/htmx/index.ts @@ -0,0 +1,13 @@ +import { Req, Res, ReturnValue } from "#/global" +import { LoginUserSchema, RegisterUserSchema, UserSchema } from "@/schema" +import { gFail, gSuccess } from "@/util" +import { auth, config, method, route, validate } from "@noderun/hapi-router" +import * as bcrypt from "bcrypt" + +export default class { + @route("/clicked") + async clicked(request: Req, h: Res): ReturnValue { + // return 'aaaaaaaaaaaaaabbbbbbbbbbbbbbbb' + return h.view('htmx/a.pug') + } +} diff --git a/source/route/views/index.ts b/source/route/views/index.ts index a9418b4..1e63b8f 100644 --- a/source/route/views/index.ts +++ b/source/route/views/index.ts @@ -1,5 +1,5 @@ import { Req, Res, ReturnValue } from "#/global"; -import { UserSchema } from "@/schema"; +import { LoginUserSchema, RegisterUserSchema, UserSchema } from "@/schema"; import { gFail, gSuccess } from "@/util"; import { auth, config, method, route, validate } from "@noderun/hapi-router"; import * as bcrypt from "bcrypt"; @@ -20,6 +20,12 @@ export default class { return h.view("views/login.pug"); } + @validate({ + payload: LoginUserSchema, + $errto: '/login', + // failAction: 'log' + failAction: 'function' + }) @method("POST") @route("/login") async login_POST(request: Req, h: Res): ReturnValue { @@ -35,7 +41,8 @@ export default class { request.yar.flash('error', 'Invalid username or password'); return h.redirect("/login"); } - request.cookieAuth.set({ id: account.id }); + request.cookieAuth.set({ id: account.id, nickname: account.nickname }); + console.log(account.nickname); request.yar.flash('success', '用户已登录'); return h.redirect(referrer ? referrer : "/"); } @@ -61,10 +68,18 @@ export default class { return h.view("views/login.pug"); } + @validate({ + payload: RegisterUserSchema, + }) @method("POST") async register(request: Req, h: Res): ReturnValue { - let { username, password, email } = request.payload as any; + let { username, password, email, nickname } = request.payload as any; + if(!email){ + request.yar.flash('error', '必须填写邮箱'); + return h.redirect("/login"); + } if (!username) username = email; + if (!nickname) nickname = username; const User = request.getModel("User") logger.trace(username, email); try { @@ -75,7 +90,7 @@ export default class { } let salt = bcrypt.genSaltSync(10); let pwdLock = bcrypt.hashSync(password, salt); - await User.create({ username, password: pwdLock, email }); + await User.create({ username, nickname, password: pwdLock, email }); return h.redirect("/") } catch (e) { request.yar.flash('error', '注册用户失败'); diff --git a/source/route/views/index/index.ts b/source/route/views/index/index.ts index 416b839..fa14b96 100644 --- a/source/route/views/index/index.ts +++ b/source/route/views/index/index.ts @@ -7,9 +7,6 @@ import { validate, } from "@noderun/hapi-router"; import { Req, Res, ReturnValue } from "#/global"; -import Joi from "joi"; -import * as bcrypt from "bcrypt"; -import glob from "fast-glob"; import path from "path"; import fs from "fs-extra"; import { baseDir } from "@/util"; @@ -67,7 +64,9 @@ export default class Index { // console.log(await glob("docs/"+"*.md")); const mdPath = path.resolve(baseDir, "docs/"+req.params.path) if(fs.existsSync(mdPath)){ - const str = fs.readFileSync(mdPath, "utf8") + const str = fs.readFileSync(mdPath, "utf8") + console.log("---->", mdPath); + return h.view("views/css.pug", { content: str.toString() }); @@ -80,8 +79,7 @@ export default class Index { } @route("/{path*}") async any(req: Req, h: Res): ReturnValue { - console.log(req.raw.req.url); - + console.log('404: ',req.raw.req.url); return h.redirect("/404?r="+encodeURIComponent(req.raw.req.url)); } @route("/404") @@ -95,6 +93,8 @@ export default class Index { if(request.query?.r){ // 可重定向返回 } - return h.view("404.pug"); + return h.view("404.pug", { + rollback: request.query?.r + }); } } diff --git a/source/route/views/user.ts b/source/route/views/user.ts new file mode 100644 index 0000000..5d162b7 --- /dev/null +++ b/source/route/views/user.ts @@ -0,0 +1,24 @@ +import { Req, Res, ReturnValue } from "#/global" +import { UserSchema } from "@/schema" +import { gFail, gSuccess } from "@/util" +import { auth, config, method, route, validate } from "@noderun/hapi-router" +import * as bcrypt from "bcrypt" +/** + * 登录界面 + */ +export default class { + @method("GET") + @auth() + async index(request: Req, h: Res): ReturnValue { + const { id } = request.auth.credentials + const User = request.getModel("User") + let result = await User.findOne({ where: { id: id } }) + if (result == null) { + return gFail(null, "不存在该用户") + } + result = result.toJSON() + delete result.password + console.log(result); + return h.view("views/user.pug", { userinfo: result }) + } +} diff --git a/source/schema/index.ts b/source/schema/index.ts index b7ffeff..53c900e 100644 --- a/source/schema/index.ts +++ b/source/schema/index.ts @@ -8,3 +8,23 @@ export const UserSchema = Joi.object({ tlds: { allow: ["com", "net"] }, }) }).or("username", "email"); + +export const RegisterUserSchema = Joi.object({ + username: Joi.string().alphanum().min(6).max(35), + password: Joi.string().pattern(new RegExp("^[a-zA-Z0-9]{3,30}$")).required(), + email: Joi.string().email({ + minDomainSegments: 2, + tlds: { allow: ["com", "net"] }, + }).required(), + nickname: Joi.string().alphanum().min(4).max(35), +}) + +export const LoginUserSchema = Joi.object({ + referrer: Joi.string().allow('').optional(), + username: Joi.string().min(6).max(35), //Joi.string().alphanum().min(6).max(35) + password: Joi.string().pattern(new RegExp("^[a-zA-Z0-9]{3,30}$")).required(), + email: Joi.string().email({ + minDomainSegments: 2, + tlds: { allow: ["com", "net"] }, + }), +}).or("username", "email"); diff --git a/template/404.pug b/template/404.pug index 5b90813..dee416c 100644 --- a/template/404.pug +++ b/template/404.pug @@ -6,3 +6,4 @@ block head block content div(style="text-align: center") span.text404 404 + div 重定向回:#{rollback} diff --git a/template/helper/helper.pug b/template/helper/helper.pug index 09846b6..ee962ba 100644 --- a/template/helper/helper.pug +++ b/template/helper/helper.pug @@ -1,5 +1,5 @@ mixin css(href) - link(rel="stylesheet" href="/public/"+href) + link(rel="stylesheet", href="/public/"+href) mixin script(src) script(src="/public/"+src) diff --git a/template/htmx/a.pug b/template/htmx/a.pug new file mode 100644 index 0000000..cf459d4 --- /dev/null +++ b/template/htmx/a.pug @@ -0,0 +1 @@ +div aaaaaaasdaasdasdada diff --git a/template/layout/layout.pug b/template/layout/layout.pug index ff7c42d..b353996 100644 --- a/template/layout/layout.pug +++ b/template/layout/layout.pug @@ -17,5 +17,6 @@ html(lang="zh-cn" class=hideHeader?"":"has-navbar-fixed-top") if !hideHeader include @/ui/header.pug block content + script(src="https://unpkg.com/htmx.org@1.8.4" integrity="sha384-wg5Y/JwF7VxGk4zLsJEcAojRtlVp1FKKdGy1qN+OMtdq72WRvX/EdRdqg/LOhYeV" crossorigin="anonymous") +script("js/common/main.js") block script diff --git a/template/ui/header.pug b/template/ui/header.pug index acaf162..a739e00 100644 --- a/template/ui/header.pug +++ b/template/ui/header.pug @@ -1,4 +1,5 @@ -nav.is-fixed-top.navbar(role='navigation', aria-label='main navigation') +nav.is-fixed-top.navbar(role='navigation', aria-label='main navigation', style="box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px;") + .container .navbar-brand a.navbar-item(href='/') img(src='https://bulma.io/images/bulma-logo.png', width='112', height='28') @@ -33,6 +34,6 @@ nav.is-fixed-top.navbar(role='navigation', aria-label='main navigation') .navbar-item .buttons button.button.is-white - | #{user.username} + | #{user.nickname} a.button.is-danger.is-light(href="/logout") | 退出 diff --git a/template/views/index.pug b/template/views/index.pug index e6a0b50..c0d033c 100644 --- a/template/views/index.pug +++ b/template/views/index.pug @@ -15,3 +15,5 @@ block content | My first website with strong Bulma | ! + if isLogin + button(hx-get="/htmx/clicked" hx-push-url="/about" hx-trigger="click" hx-target="this" hx-swap="outerHTML") Click Me! diff --git a/template/views/user.pug b/template/views/user.pug new file mode 100644 index 0000000..9a7acf3 --- /dev/null +++ b/template/views/user.pug @@ -0,0 +1,13 @@ +extends @/layout/layout + +block var + -title="用户信息" // 网页标题 +//- -hideHeader=true + +block head + +block content + section.section + .container + div username: #{user.username} + div id: #{user.id}