You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

190 lines
9.3 KiB

// @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) {
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"