// @ts-nocheck import { walkDir, removeIndex, isIndexEnd } from "./util" import * as Joi from "joi" const path = require("path") const fs = require("fs") class routePlugin { public name: string = "routePlugin" public version: string = "0.0.1" public register(server: any, opts: any) { const sourceDir = opts.sourceDir const type = opts.type || "jwt" const auth = opts.auth || [] let array = [] for (let i = 0; i < sourceDir.length; i++) { const dir = sourceDir[i] console.log(dir) array.push(dir.dir + "对应路径:") array = array.concat(this.registerRoute(server, dir.dir, dir.prefix || "", auth, type)) } fs.writeFileSync(path.resolve(process.cwd(), "route.txt"), array.join("\n"), { encoding: "utf-8", }) } registerRoute(server, sourceDir, prefix, auth, type) { const files = walkDir(sourceDir) const routes = [] files.forEach(file => { let filename = file.relativeFileNoExt let array = filename.split(path.sep).slice(1) let fileNoExt = removeIndex("/" + array.join("/")) const moduleName = path.resolve(sourceDir, filename) const obj = require(moduleName) if (obj.default) { const func = new (obj.default || obj)() const prototype = Object.getPrototypeOf(func) const keys = Reflect.ownKeys(prototype) for (const key of keys) { if (key !== "constructor") { let ff = func[key] let handler: () => void = undefined // 默认方法 const method = ff.$method || "GET" // 路由收集规则 let route = "" if(ff.$route_path){ route = ff.$route_path route = prefix ? route[0] + prefix + "/" + route.slice(1) : route }else{ if (ff.$route) { if (isIndexEnd(fileNoExt)) { route = ff.$route } else { route = fileNoExt + ff.$route } } else { if (isIndexEnd(fileNoExt)) { route = fileNoExt + key.toString() } else { route = fileNoExt + "/" + key.toString() } } route = removeIndex(route) route = prefix ? route[0] + prefix + "/" + route.slice(1) : route } // 配置规则 const options = ff.$options ? ff.$options : {} if (!options.auth) { if (ff.$auth == undefined) { if (auth && auth.length && auth.filter(v => route.startsWith(v)).length) { options.auth = type } else { options.auth = false } } else if (ff.$auth) { options.auth = typeof ff.$auth === "boolean" ? type : { strategy: type, mode: ff.$auth, } } else { options.auth = false } } if (!options.validate) { let validateObj = ff.$validate || {} if (options.auth && type === "jwt") { if (validateObj.headers) { validateObj.headers = validateObj.headers.keys({ Authorization: Joi.string(), }) } else { validateObj.headers = Joi.object({ headers: Joi.object({ Authorization: Joi.string(), }).unknown(), // 注意加上这个 }) } } if (validateObj && !!Object.keys(validateObj).length) { const failReason = validateObj.failReason delete validateObj.failReason 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)); request.yar.flash("error", failReason || 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", failReason || request.$joi_error) delete request.$joi_error return h.redirect(errto) } return await ff.call(this, ...argus) } } options.validate = validateObj } } // && route.startsWith("/api") if (ff.$swagger) { options.description = ff.$swagger[0] options.notes = ff.$swagger[1] options.tags = ff.$swagger[2] } let str = route if ( (typeof options.auth === "string" && options.auth) || (typeof options.auth === "object" && options.auth.mode === "required") ) { str = " 需要权限 : " + " " + full(method) + " " + str } else if (typeof options.auth === "object" && options.auth.mode === "optional") { str = " 不需权限(提供即需验证): " + " " + full(method) + " " + str } else if (typeof options.auth === "object" && options.auth.mode === "try") { str = " 不需权限(提供无需验证): " + " " + full(method) + " " + str } else { str = " 不需权限 : " + " " + 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: handler, options: options, }) } } } }) return routes } } function full(str: string, length = 10) { let len = str.length let need = length - len if (need <= 0) return str return str + [...Array(need)].map((v, i) => " ").join("") } const plugin = new routePlugin() export { plugin } export * from "./util/decorators"