30 changed files with 167 additions and 4342 deletions
@ -1 +0,0 @@ |
|||||
node_modules |
|
@ -1,4 +0,0 @@ |
|||||
# @noderun/hapi-router |
|
||||
|
|
||||
> 发布:npm publish --access public |
|
||||
> 删除:npm unpublish --force |
|
@ -1,477 +0,0 @@ |
|||||
#!/usr/bin/env node
|
|
||||
'use strict'; |
|
||||
|
|
||||
Object.defineProperty(exports, '__esModule', { value: true }); |
|
||||
|
|
||||
var Joi = require('joi'); |
|
||||
|
|
||||
function _interopNamespace(e) { |
|
||||
if (e && e.__esModule) return e; |
|
||||
var n = Object.create(null); |
|
||||
if (e) { |
|
||||
Object.keys(e).forEach(function (k) { |
|
||||
if (k !== 'default') { |
|
||||
var d = Object.getOwnPropertyDescriptor(e, k); |
|
||||
Object.defineProperty(n, k, d.get ? d : { |
|
||||
enumerable: true, |
|
||||
get: function () { |
|
||||
return e[k]; |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
n['default'] = e; |
|
||||
return Object.freeze(n); |
|
||||
} |
|
||||
|
|
||||
var Joi__namespace = /*#__PURE__*/_interopNamespace(Joi); |
|
||||
|
|
||||
/*! ***************************************************************************** |
|
||||
Copyright (c) Microsoft Corporation. |
|
||||
|
|
||||
Permission to use, copy, modify, and/or distribute this software for any |
|
||||
purpose with or without fee is hereby granted. |
|
||||
|
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH |
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR |
|
||||
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); |
|
||||
if (o && typeof o.length === "number") return { |
|
||||
next: function () { |
|
||||
if (o && i >= o.length) o = void 0; |
|
||||
return { value: o && o[i++], done: !o }; |
|
||||
} |
|
||||
}; |
|
||||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); |
|
||||
} |
|
||||
|
|
||||
function __read(o, n) { |
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator]; |
|
||||
if (!m) return o; |
|
||||
var i = m.call(o), r, ar = [], e; |
|
||||
try { |
|
||||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); |
|
||||
} |
|
||||
catch (error) { e = { error: error }; } |
|
||||
finally { |
|
||||
try { |
|
||||
if (r && !r.done && (m = i["return"])) m.call(i); |
|
||||
} |
|
||||
finally { if (e) throw e.error; } |
|
||||
} |
|
||||
return ar; |
|
||||
} |
|
||||
|
|
||||
function __spread() { |
|
||||
for (var ar = [], i = 0; i < arguments.length; i++) |
|
||||
ar = ar.concat(__read(arguments[i])); |
|
||||
return ar; |
|
||||
} |
|
||||
|
|
||||
var path$1 = require("path"); |
|
||||
var fs$1 = require("fs"); |
|
||||
function removeIndex(ss) { |
|
||||
var remove = function (str) { |
|
||||
if (str.endsWith("/index")) { |
|
||||
return str.slice(0, -6); |
|
||||
} |
|
||||
if (str.endsWith("index")) { |
|
||||
return str.slice(0, -5); |
|
||||
} |
|
||||
return str ? str : "/"; |
|
||||
}; |
|
||||
var r = true; |
|
||||
var rr = ss; |
|
||||
while (r) { |
|
||||
if (rr.endsWith("/index")) { |
|
||||
rr = remove(rr); |
|
||||
} |
|
||||
else { |
|
||||
r = false; |
|
||||
} |
|
||||
} |
|
||||
return rr ? rr : "/"; |
|
||||
} |
|
||||
function isIndexEnd(str) { |
|
||||
return str.length == 1 && str.endsWith("/"); |
|
||||
} |
|
||||
function walkDir(filePath, exclude) { |
|
||||
if (exclude === void 0) { exclude = ["node_modules", "^_", ".git", ".idea", ".gitignore", "client", "\.txt$", "\.test\.js$", "\.test\.ts$"]; } |
|
||||
var files = []; |
|
||||
function Data(opts) { |
|
||||
this.relativeDir = opts.relativeDir; |
|
||||
this.relativeFile = opts.relativeFile; |
|
||||
this.filename = opts.filename; |
|
||||
this.file = opts.file; |
|
||||
this.absoluteFile = opts.absoluteFile; |
|
||||
this.relativeFileNoExt = opts.relativeFileNoExt; |
|
||||
this.absoluteDir = opts.absoluteDir; |
|
||||
} |
|
||||
function readDir(filePath, dirname) { |
|
||||
if (dirname === void 0) { dirname = "."; } |
|
||||
var res = fs$1.readdirSync(filePath); |
|
||||
res.forEach(function (filename) { |
|
||||
var filepath = path$1.resolve(filePath, filename); |
|
||||
var stat = fs$1.statSync(filepath); |
|
||||
var name = filepath.split(path$1.sep).slice(-1)[0]; |
|
||||
if (typeof exclude === "string" && new RegExp(exclude).test(name)) { |
|
||||
return; |
|
||||
} |
|
||||
if (Array.isArray(exclude)) { |
|
||||
for (var i = 0; i < exclude.length; i++) { |
|
||||
var excludeItem = exclude[i]; |
|
||||
if (new RegExp(excludeItem).test(name)) { |
|
||||
return; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
if (!stat.isFile()) { |
|
||||
readDir(filepath, dirname + path$1.sep + name); |
|
||||
} |
|
||||
else { |
|
||||
var data = new Data({ |
|
||||
relativeDir: dirname, |
|
||||
relativeFile: dirname + path$1.sep + path$1.parse(filepath).base, |
|
||||
relativeFileNoExt: dirname + path$1.sep + path$1.parse(filepath).name, |
|
||||
file: path$1.parse(filepath).base, |
|
||||
filename: path$1.parse(filepath).name, |
|
||||
absoluteFile: filepath, |
|
||||
absoluteDir: path$1.parse(filepath).dir, |
|
||||
}); |
|
||||
files.push(data); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
readDir(filePath); |
|
||||
return files; |
|
||||
} |
|
||||
|
|
||||
function method(opts) { |
|
||||
return function (target, propertyKey, descriptor) { |
|
||||
target[propertyKey].$method = opts; |
|
||||
}; |
|
||||
} |
|
||||
function route(route) { |
|
||||
return function (target, propertyKey, descriptor) { |
|
||||
target[propertyKey].$route = route; |
|
||||
}; |
|
||||
} |
|
||||
function config(options) { |
|
||||
return function (target, propertyKey, descriptor) { |
|
||||
target[propertyKey].$options = options; |
|
||||
}; |
|
||||
} |
|
||||
function auth(isAuth) { |
|
||||
if (isAuth === void 0) { isAuth = true; } |
|
||||
return function (target, propertyKey, descriptor) { |
|
||||
target[propertyKey].$auth = isAuth; |
|
||||
}; |
|
||||
} |
|
||||
function validate(validate) { |
|
||||
return function (target, propertyKey, descriptor) { |
|
||||
target[propertyKey].$validate = validate; |
|
||||
}; |
|
||||
} |
|
||||
function swagger(desc, notes, tags) { |
|
||||
return function (target, propertyKey, descriptor) { |
|
||||
target[propertyKey].$swagger = [desc, notes, tags]; |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
var path = require("path"); |
|
||||
var fs = require("fs"); |
|
||||
var routePlugin = (function () { |
|
||||
function routePlugin() { |
|
||||
this.name = "routePlugin"; |
|
||||
this.version = "0.0.1"; |
|
||||
} |
|
||||
routePlugin.prototype.register = function (server, opts) { |
|
||||
var sourceDir = opts.sourceDir; |
|
||||
var type = opts.type || "jwt"; |
|
||||
var auth = opts.auth || []; |
|
||||
var array = []; |
|
||||
for (var i = 0; i < sourceDir.length; i++) { |
|
||||
var 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", |
|
||||
}); |
|
||||
}; |
|
||||
routePlugin.prototype.registerRoute = function (server, sourceDir, prefix, auth, type) { |
|
||||
var files = walkDir(sourceDir); |
|
||||
var routes = []; |
|
||||
files.forEach(function (file) { |
|
||||
var e_1, _a; |
|
||||
var filename = file.relativeFileNoExt; |
|
||||
var array = filename.split(path.sep).slice(1); |
|
||||
var fileNoExt = removeIndex("/" + array.join("/")); |
|
||||
var moduleName = path.resolve(sourceDir, filename); |
|
||||
var obj = require(moduleName); |
|
||||
if (obj.default) { |
|
||||
var func = new (obj.default || obj)(); |
|
||||
var prototype = Object.getPrototypeOf(func); |
|
||||
var keys = Reflect.ownKeys(prototype); |
|
||||
var _loop_1 = function (key) { |
|
||||
if (key !== "constructor") { |
|
||||
var ff_1 = func[key]; |
|
||||
var handler = undefined; |
|
||||
var method = ff_1.$method || "GET"; |
|
||||
var route_1 = ""; |
|
||||
if (ff_1.$route) { |
|
||||
if (isIndexEnd(fileNoExt)) { |
|
||||
route_1 = ff_1.$route; |
|
||||
} |
|
||||
else { |
|
||||
route_1 = fileNoExt + ff_1.$route; |
|
||||
} |
|
||||
} |
|
||||
else { |
|
||||
if (isIndexEnd(fileNoExt)) { |
|
||||
route_1 = fileNoExt + key.toString(); |
|
||||
} |
|
||||
else { |
|
||||
route_1 = fileNoExt + "/" + key.toString(); |
|
||||
} |
|
||||
} |
|
||||
route_1 = removeIndex(route_1); |
|
||||
route_1 = prefix ? route_1[0] + prefix + "/" + route_1.slice(1) : route_1; |
|
||||
var options = ff_1.$options ? ff_1.$options : {}; |
|
||||
if (!options.auth) { |
|
||||
if (ff_1.$auth == undefined) { |
|
||||
if (auth && |
|
||||
auth.length && |
|
||||
auth.filter(function (v) { return route_1.startsWith(v); }).length) { |
|
||||
options.auth = type; |
|
||||
} |
|
||||
else { |
|
||||
options.auth = false; |
|
||||
} |
|
||||
} |
|
||||
else if (ff_1.$auth) { |
|
||||
options.auth = |
|
||||
typeof ff_1.$auth === "boolean" |
|
||||
? type |
|
||||
: { |
|
||||
strategy: type, |
|
||||
mode: ff_1.$auth, |
|
||||
}; |
|
||||
} |
|
||||
else { |
|
||||
options.auth = false; |
|
||||
} |
|
||||
} |
|
||||
if (!options.validate) { |
|
||||
var validateObj = ff_1.$validate || {}; |
|
||||
if (options.auth && type === "jwt") { |
|
||||
if (validateObj.headers) { |
|
||||
validateObj.headers = validateObj.headers.keys({ |
|
||||
Authorization: Joi__namespace.string(), |
|
||||
}); |
|
||||
} |
|
||||
else { |
|
||||
validateObj.headers = Joi__namespace.object({ |
|
||||
headers: Joi__namespace.object({ |
|
||||
Authorization: Joi__namespace.string(), |
|
||||
}).unknown(), |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
if (validateObj && !!Object.keys(validateObj).length) { |
|
||||
var failReason_1 = validateObj.failReason; |
|
||||
delete validateObj.failReason; |
|
||||
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', failReason_1); |
|
||||
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', failReason_1); |
|
||||
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_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) || |
|
||||
(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_1; |
|
||||
} |
|
||||
server.route({ |
|
||||
method: method, |
|
||||
path: route_1, |
|
||||
handler: handler, |
|
||||
options: options, |
|
||||
}); |
|
||||
} |
|
||||
}; |
|
||||
try { |
|
||||
for (var keys_1 = __values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) { |
|
||||
var key = keys_1_1.value; |
|
||||
_loop_1(key); |
|
||||
} |
|
||||
} |
|
||||
catch (e_1_1) { e_1 = { error: e_1_1 }; } |
|
||||
finally { |
|
||||
try { |
|
||||
if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1); |
|
||||
} |
|
||||
finally { if (e_1) throw e_1.error; } |
|
||||
} |
|
||||
} |
|
||||
}); |
|
||||
return routes; |
|
||||
}; |
|
||||
return routePlugin; |
|
||||
}()); |
|
||||
function full(str, length) { |
|
||||
if (length === void 0) { length = 10; } |
|
||||
var len = str.length; |
|
||||
var need = length - len; |
|
||||
if (need <= 0) |
|
||||
return str; |
|
||||
return str + __spread(Array(need)).map(function (v, i) { return " "; }).join(""); |
|
||||
} |
|
||||
var plugin = new routePlugin(); |
|
||||
|
|
||||
exports.auth = auth; |
|
||||
exports.config = config; |
|
||||
exports.method = method; |
|
||||
exports.plugin = plugin; |
|
||||
exports.route = route; |
|
||||
exports.swagger = swagger; |
|
||||
exports.validate = validate; |
|
||||
//# sourceMappingURL=hapi-router.cjs.js.map
|
|
File diff suppressed because one or more lines are too long
@ -1,25 +0,0 @@ |
|||||
// Generated by dts-bundle v0.7.3
|
|
||||
|
|
||||
declare module '@noderun/hapi-router' { |
|
||||
class routePlugin { |
|
||||
name: string; |
|
||||
version: string; |
|
||||
register(server: any, opts: any): void; |
|
||||
registerRoute(server: any, sourceDir: any, prefix: any, auth: any, type: any): any[]; |
|
||||
} |
|
||||
const plugin: routePlugin; |
|
||||
export { plugin }; |
|
||||
export * from "@noderun/hapi-router/util/decorators"; |
|
||||
} |
|
||||
|
|
||||
declare module '@noderun/hapi-router/util/decorators' { |
|
||||
type TMethod = "GET" | "POST" | "PUT" | "DELETE"; |
|
||||
export function method(opts?: TMethod | Array<TMethod>): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void; |
|
||||
export function route(route?: string): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void; |
|
||||
export function config(options: Object): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void; |
|
||||
export function auth(isAuth?: boolean | "try" | "required" | "optional"): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void; |
|
||||
export function validate(validate: Object): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void; |
|
||||
export function swagger(desc: any, notes: any, tags: any): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void; |
|
||||
export {}; |
|
||||
} |
|
||||
|
|
@ -1,4 +0,0 @@ |
|||||
|
|
||||
|
|
||||
// 全局替换
|
|
||||
declare var __DEV__: boolean; |
|
File diff suppressed because it is too large
@ -1,42 +0,0 @@ |
|||||
{ |
|
||||
"name": "@noderun/hapi-router", |
|
||||
"version": "0.0.1", |
|
||||
"description": "", |
|
||||
"main": "dist/hapi-router.cjs.js", |
|
||||
"typings": "dist/index.d.ts", |
|
||||
"buildOptions": { |
|
||||
"filename": "hapi-router", |
|
||||
"var": "hapiRouter", |
|
||||
"formats": [ |
|
||||
"cjs" |
|
||||
] |
|
||||
}, |
|
||||
"scripts": { |
|
||||
"build": "node scripts/build.js", |
|
||||
"dev": "node scripts/dev.js" |
|
||||
}, |
|
||||
"keywords": [], |
|
||||
"author": "", |
|
||||
"license": "ISC", |
|
||||
"devDependencies": { |
|
||||
"@rollup/plugin-alias": "^3.1.1", |
|
||||
"@rollup/plugin-commonjs": "^15.0.0", |
|
||||
"@rollup/plugin-replace": "^2.3.3", |
|
||||
"@types/node": "^15.12.2", |
|
||||
"chalk": "^4.1.0", |
|
||||
"dts-bundle": "^0.7.3", |
|
||||
"execa": "^4.0.3", |
|
||||
"fs-extra": "^9.0.1", |
|
||||
"ftp-deploy": "^2.3.6", |
|
||||
"lodash": "^4.17.20", |
|
||||
"rollup": "^2.26.3", |
|
||||
"rollup-plugin-sourcemaps": "^0.6.2", |
|
||||
"rollup-plugin-typescript2": "^0.27.2", |
|
||||
"tslib": "^2.0.1", |
|
||||
"typescript": "^3.9.7" |
|
||||
}, |
|
||||
"dependencies": { |
|
||||
"joi": "^17.4.0", |
|
||||
"json-merge-patch": "^1.0.1" |
|
||||
} |
|
||||
} |
|
File diff suppressed because it is too large
@ -1,113 +0,0 @@ |
|||||
import commonjs from "@rollup/plugin-commonjs"; |
|
||||
import typescript from "rollup-plugin-typescript2"; |
|
||||
import alias from "@rollup/plugin-alias"; |
|
||||
import replace from "@rollup/plugin-replace"; |
|
||||
import sourcemaps from "rollup-plugin-sourcemaps"; |
|
||||
const pkg = require("./package.json"); |
|
||||
const path = require("path"); |
|
||||
|
|
||||
let isProd = process.env.NODE_ENV === "production"; |
|
||||
|
|
||||
const input = "src/index.ts"; |
|
||||
const openSourceMap = true; |
|
||||
const buildOptions = pkg.buildOptions; |
|
||||
buildOptions.formats = process.env.TARGET |
|
||||
? [process.env.TARGET] |
|
||||
: buildOptions.formats; |
|
||||
|
|
||||
export default createConfig(); |
|
||||
|
|
||||
function createConfig() { |
|
||||
return { |
|
||||
input, |
|
||||
external: ['joi'], |
|
||||
output: createOutput(buildOptions), |
|
||||
plugins: createPlugin(), |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
function createPlugin() { |
|
||||
let plugin = []; |
|
||||
const aliasPlugin = alias({ |
|
||||
resolve: [".ts"], |
|
||||
"@": path.resolve(__dirname, "src"), |
|
||||
}); |
|
||||
const tsPlugin = typescript({ |
|
||||
check: isProd, |
|
||||
tsconfig: path.resolve(__dirname, "tsconfig.json"), |
|
||||
cacheRoot: path.resolve(__dirname, "node_modules/.rts2_cache"), |
|
||||
tsconfigOverride: { |
|
||||
compilerOptions: { |
|
||||
declaration: isProd, |
|
||||
}, |
|
||||
}, |
|
||||
}); |
|
||||
const replacePlugin = replace({ |
|
||||
__DEV__: isProd, |
|
||||
preventAssignment: true |
|
||||
}); |
|
||||
plugin = [sourcemaps(), commonjs(), tsPlugin, aliasPlugin, replacePlugin]; |
|
||||
return plugin; |
|
||||
} |
|
||||
|
|
||||
function createOutput(options) { |
|
||||
const output = []; |
|
||||
const filterType = { |
|
||||
//可用script标签导入,会输出一个全局变量
|
|
||||
iife: { |
|
||||
sourcemap: openSourceMap, |
|
||||
file: `dist/${options.filename}.iife.js`, |
|
||||
format: "iife", |
|
||||
name: options.var, |
|
||||
}, |
|
||||
// amd规范,可用require.js加载
|
|
||||
amd: { |
|
||||
sourcemap: openSourceMap, |
|
||||
file: `dist/${options.filename}.amd.js`, |
|
||||
format: "amd", |
|
||||
}, |
|
||||
// 兼容 IIFE, AMD, CJS 三种模块规范
|
|
||||
umd: { |
|
||||
sourcemap: openSourceMap, |
|
||||
file: `dist/${options.filename}.umd.js`, |
|
||||
format: "umd", |
|
||||
name: options.var, |
|
||||
}, |
|
||||
// CommonJS规范
|
|
||||
cjs: { |
|
||||
sourcemap: openSourceMap, |
|
||||
file: `dist/${options.filename}.cjs.js`, |
|
||||
format: "cjs", |
|
||||
exports: "auto", |
|
||||
banner: "#!/usr/bin/env node", // 提供命令行的可执行权限
|
|
||||
}, |
|
||||
// ES2015 Module 规范, 可用 `Webpack`, `Rollup` 加载
|
|
||||
esm: { |
|
||||
sourcemap: openSourceMap, |
|
||||
file: `dist/${options.filename}.esm.js`, |
|
||||
format: "es", |
|
||||
}, |
|
||||
"esm-browser": { |
|
||||
sourcemap: openSourceMap, |
|
||||
file: `dist/${options.filename}.esm-browser.js`, |
|
||||
format: "es", |
|
||||
}, |
|
||||
}; |
|
||||
if (options.formats) { |
|
||||
options.formats.forEach((format) => { |
|
||||
if (filterType[format]) { |
|
||||
output.push(filterType[format]); |
|
||||
} else { |
|
||||
console.error("无效类型:" + format); |
|
||||
} |
|
||||
}); |
|
||||
} else { |
|
||||
for (const key in filterType) { |
|
||||
if (filterType.hasOwnProperty(key)) { |
|
||||
const element = filterType[key]; |
|
||||
output.push(element); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return output; |
|
||||
} |
|
@ -1,24 +0,0 @@ |
|||||
const execa = require("execa"); |
|
||||
const fs = require("fs-extra"); |
|
||||
const chalk = require('chalk'); |
|
||||
const dts = require("dts-bundle"); |
|
||||
const pkg = require("../package.json"); |
|
||||
|
|
||||
(async function () { |
|
||||
console.log(chalk.red("正在清理dist文件夹")); |
|
||||
await fs.remove(`dist`); |
|
||||
console.log(chalk.red("清理完成,开始构建")); |
|
||||
await execa("rollup", ["-c", "--environment", `NODE_ENV:production`], { |
|
||||
stdio: "inherit", |
|
||||
}); |
|
||||
console.log(chalk.red("构建完成,开始生成d.ts")); |
|
||||
const dtsOptions = { |
|
||||
name: pkg.name, |
|
||||
main: `dist/src/index.d.ts`, |
|
||||
out: `../index.d.ts`, |
|
||||
}; |
|
||||
dts.bundle(dtsOptions); |
|
||||
console.log(chalk.red("生成完毕,开始清理残余")); |
|
||||
await fs.remove(`dist/src`); |
|
||||
console.log('所有文件清理完成'); |
|
||||
})(); |
|
@ -1,7 +0,0 @@ |
|||||
const execa = require("execa"); |
|
||||
const chalk = require('chalk'); |
|
||||
|
|
||||
console.log(chalk.red("开始监听,格式:umd")); |
|
||||
execa("rollup", ["-wc", "--environment", `NODE_ENV:development,TARGET:cjs`], { |
|
||||
stdio: "inherit", |
|
||||
}); |
|
@ -1,190 +0,0 @@ |
|||||
// @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" |
|
@ -1,40 +0,0 @@ |
|||||
// @ts-nocheck
|
|
||||
/** |
|
||||
* 方法 |
|
||||
* @param opts 参数 |
|
||||
*/ |
|
||||
type TMethod = "GET" | "POST" | "PUT" | "DELETE" |
|
||||
export function method(opts?: TMethod | Array<TMethod>) { |
|
||||
return function (target, propertyKey: string, descriptor: PropertyDescriptor) { |
|
||||
target[propertyKey].$method = opts |
|
||||
} |
|
||||
} |
|
||||
export function route(route?: string) { |
|
||||
return function (target, propertyKey: string, descriptor: PropertyDescriptor) { |
|
||||
target[propertyKey].$route = route |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export function config(options: Object) { |
|
||||
return function (target, propertyKey: string, descriptor: PropertyDescriptor) { |
|
||||
target[propertyKey].$options = options |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export function auth(isAuth: boolean | "try" | "required" | "optional" = true) { |
|
||||
return function (target, propertyKey: string, descriptor: PropertyDescriptor) { |
|
||||
target[propertyKey].$auth = isAuth |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export function validate(validate: Object) { |
|
||||
return function (target, propertyKey: string, descriptor: PropertyDescriptor) { |
|
||||
target[propertyKey].$validate = validate |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export function swagger(desc, notes, tags) { |
|
||||
return function (target, propertyKey: string, descriptor: PropertyDescriptor) { |
|
||||
target[propertyKey].$swagger = [desc, notes, tags] |
|
||||
} |
|
||||
} |
|
@ -1,81 +0,0 @@ |
|||||
// @ts-nocheck
|
|
||||
|
|
||||
const path = require("path") |
|
||||
const fs = require("fs") |
|
||||
|
|
||||
export function removeIndex(ss: any) { |
|
||||
const remove = (str: any) => { |
|
||||
if (str.endsWith("/index")) { |
|
||||
return str.slice(0, -6) |
|
||||
} |
|
||||
if (str.endsWith("index")) { |
|
||||
return str.slice(0, -5) |
|
||||
} |
|
||||
return str ? str : "/" |
|
||||
} |
|
||||
let r = true |
|
||||
let rr = ss |
|
||||
while (r) { |
|
||||
if (rr.endsWith("/index")) { |
|
||||
rr = remove(rr) |
|
||||
} else { |
|
||||
r = false |
|
||||
} |
|
||||
} |
|
||||
return rr ? rr : "/" |
|
||||
} |
|
||||
|
|
||||
export function isIndexEnd(str: any) { |
|
||||
return str.length == 1 && str.endsWith("/") |
|
||||
} |
|
||||
|
|
||||
export function walkDir( |
|
||||
filePath: any, |
|
||||
exclude = ["node_modules", "^_", ".git", ".idea", ".gitignore", "client", ".txt$", ".test.js$", ".test.ts$"], |
|
||||
) { |
|
||||
let files: any[] = [] |
|
||||
function Data(opts: any) { |
|
||||
this.relativeDir = opts.relativeDir |
|
||||
this.relativeFile = opts.relativeFile |
|
||||
this.filename = opts.filename |
|
||||
this.file = opts.file |
|
||||
this.absoluteFile = opts.absoluteFile |
|
||||
this.relativeFileNoExt = opts.relativeFileNoExt |
|
||||
this.absoluteDir = opts.absoluteDir |
|
||||
} |
|
||||
function readDir(filePath, dirname = ".") { |
|
||||
let res = fs.readdirSync(filePath) |
|
||||
res.forEach(filename => { |
|
||||
const filepath = path.resolve(filePath, filename) |
|
||||
const stat = fs.statSync(filepath) |
|
||||
const name = filepath.split(path.sep).slice(-1)[0] |
|
||||
if (typeof exclude === "string" && new RegExp(exclude).test(name)) { |
|
||||
return |
|
||||
} |
|
||||
if (Array.isArray(exclude)) { |
|
||||
for (let i = 0; i < exclude.length; i++) { |
|
||||
const excludeItem = exclude[i] |
|
||||
if (new RegExp(excludeItem).test(name)) { |
|
||||
return |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
if (!stat.isFile()) { |
|
||||
readDir(filepath, dirname + path.sep + name) |
|
||||
} else { |
|
||||
const data = new Data({ |
|
||||
relativeDir: dirname, |
|
||||
relativeFile: dirname + path.sep + path.parse(filepath).base, |
|
||||
relativeFileNoExt: dirname + path.sep + path.parse(filepath).name, |
|
||||
file: path.parse(filepath).base, |
|
||||
filename: path.parse(filepath).name, |
|
||||
absoluteFile: filepath, |
|
||||
absoluteDir: path.parse(filepath).dir, |
|
||||
}) |
|
||||
files.push(data) |
|
||||
} |
|
||||
}) |
|
||||
} |
|
||||
readDir(filePath) |
|
||||
return files |
|
||||
} |
|
@ -1,37 +0,0 @@ |
|||||
{ |
|
||||
"compilerOptions": { |
|
||||
"allowUnreachableCode": true, |
|
||||
"strictNullChecks": true, |
|
||||
// 严格模式, 强烈建议开启 |
|
||||
"strict": true, |
|
||||
"allowJs": true, |
|
||||
// 目标js的版本 |
|
||||
"target": "ES5", |
|
||||
// 目标代码的模块结构版本 |
|
||||
"module": "ES2015", |
|
||||
// 在表达式和声明上有隐含的 any类型时报错。 |
|
||||
"noImplicitAny": true, |
|
||||
// "__extends"等函数 |
|
||||
// 将以"import {__extends} from 'tslib'的形式导入 |
|
||||
"importHelpers": true, |
|
||||
// 删除注释 |
|
||||
"removeComments": true, |
|
||||
// 保留 const和 enum声明 |
|
||||
"preserveConstEnums": false, |
|
||||
// 编译过程中需要引入的库文件的列表 |
|
||||
"lib": ["dom", "esnext"], |
|
||||
"sourceMap": true, |
|
||||
// 额外支持解构/forof等功能 |
|
||||
"downlevelIteration": true, |
|
||||
// 此处设置为node,才能解析import xx from 'xx' |
|
||||
"moduleResolution": "node", |
|
||||
"esModuleInterop": true, // esModuleInterop选项的作用是支持使用import d from 'cjs'的方式引入commonjs包。 |
|
||||
"baseUrl": ".", |
|
||||
"rootDir": ".", // 这个项目这个里的root必须要加上 |
|
||||
"paths": { |
|
||||
"@/*": ["./src/*"] |
|
||||
} |
|
||||
}, |
|
||||
"include": ["./src/**/*", "./global.d.ts"], |
|
||||
"exclude": ["node_modules"] |
|
||||
} |
|
@ -1,2 +0,0 @@ |
|||||
packages: |
|
||||
- 'packages/*' |
|
@ -1,17 +1,16 @@ |
|||||
/home/topuser/Code/@project/hapi-demo/dist/route/htmx对应路径: |
D:\1XYX\pro\hapi-demo\source\route\htmx对应路径: |
||||
不需权限 : GET /htmx/path/{path*} |
不需权限 : GET /htmx/path/{path*} |
||||
/home/topuser/Code/@project/hapi-demo/dist/route/views对应路径: |
D:\1XYX\pro\hapi-demo\source\route\views对应路径: |
||||
不需权限(提供无需验证): GET /404 |
不需权限(提供无需验证): GET /404 |
||||
不需权限 : GET /css |
|
||||
不需权限(提供无需验证): GET / |
不需权限(提供无需验证): GET / |
||||
不需权限(提供无需验证): GET /about |
不需权限(提供无需验证): GET /about |
||||
需要权限 : GET /docs/{path*} |
需要权限 : GET /docs/{path*} |
||||
不需权限 : GET /{path*} |
不需权限 : GET /{path*} |
||||
不需权限(提供无需验证): GET /login |
不需权限(提供无需验证): GET /login |
||||
不需权限 : POST /login |
不需权限 : POST /login |
||||
需要权限 : GET /logout |
不需权限 : GET /nav |
||||
需要权限 : POST /del |
|
||||
不需权限(提供无需验证): GET /register |
不需权限(提供无需验证): GET /register |
||||
不需权限 : POST /register |
不需权限 : POST /register |
||||
不需权限 : GET /nav |
需要权限 : GET /user |
||||
需要权限 : GET /user |
需要权限 : GET /user/logout |
||||
|
需要权限 : POST /user/del |
Binary file not shown.
@ -1,113 +0,0 @@ |
|||||
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("/login") |
|
||||
@auth("try") |
|
||||
@method("GET") |
|
||||
async login_GET(request: Req, h: Res): ReturnValue { |
|
||||
if (request.auth.isAuthenticated) { |
|
||||
request.yar.flash("warning", "您已经登陆") |
|
||||
return h.redirect("/") |
|
||||
} else { |
|
||||
logger.debug("未登录") |
|
||||
} |
|
||||
return h.view("views/login.pug") |
|
||||
} |
|
||||
|
|
||||
@validate({ |
|
||||
payload: LoginUserSchema, |
|
||||
$errto: "/login", |
|
||||
// failAction: 'log'
|
|
||||
failAction: "function", |
|
||||
// failReason: "用户名或密码错误,请重试",
|
|
||||
}) |
|
||||
@method("POST") |
|
||||
@route("/login") |
|
||||
async login_POST(request: Req, h: Res): ReturnValue { |
|
||||
const { username, password, referrer } = request.payload as any |
|
||||
|
|
||||
const User = request.getModel("User") |
|
||||
const account = <any>await User.findOne({ where: { username: username } }) |
|
||||
|
|
||||
if (!account || !(await bcrypt.compare(password, account.password))) { |
|
||||
request.yar.flash("error", "Invalid username or password") |
|
||||
return h.redirect("/login") |
|
||||
} |
|
||||
request.cookieAuth.set({ id: account.id, nickname: account.nickname }) |
|
||||
request.yar.flash("success", "用户已登录") |
|
||||
return h.redirect(referrer ? referrer : "/") |
|
||||
} |
|
||||
|
|
||||
@method("GET") |
|
||||
@auth() |
|
||||
async logout(request: Req, h: Res): ReturnValue { |
|
||||
request.yar.flash("success", "用户已退出") |
|
||||
request.cookieAuth.clear() |
|
||||
return h.redirect("/") |
|
||||
} |
|
||||
|
|
||||
@method("POST") |
|
||||
@auth() |
|
||||
async del(request: Req, h: Res): ReturnValue { |
|
||||
const { id } = request.auth.credentials |
|
||||
try { |
|
||||
const User = request.getModel("User") |
|
||||
await User.destroy({ where: { id: id }}) |
|
||||
request.yar.flash("success", "用户已删除") |
|
||||
request.cookieAuth.clear() |
|
||||
} catch (error) { |
|
||||
loggerSite.error(`用户删除错误`, error.message) |
|
||||
request.yar.flash("error", "用户删除错误") |
|
||||
} |
|
||||
return h.redirect("/") |
|
||||
} |
|
||||
|
|
||||
@route("/register") |
|
||||
@auth("try") |
|
||||
@method("GET") |
|
||||
async registerView(request: Req, h: Res): ReturnValue { |
|
||||
if (request.auth.isAuthenticated) { |
|
||||
request.yar.flash("warning", "您已经登陆") |
|
||||
return h.redirect("/") |
|
||||
} else { |
|
||||
logger.debug("未登录") |
|
||||
} |
|
||||
return h.view("views/register.pug") |
|
||||
} |
|
||||
|
|
||||
@validate({ |
|
||||
payload: RegisterUserSchema, |
|
||||
$errto: "/register", |
|
||||
failAction: "function", |
|
||||
failReason: "注册账户不符合规范", |
|
||||
}) |
|
||||
@method("POST") |
|
||||
async register(request: Req, h: Res): ReturnValue { |
|
||||
console.log(request); |
|
||||
let { username, password } = request.payload as any |
|
||||
const User = request.getModel("User") |
|
||||
logger.trace("当前注册用户:" + username) |
|
||||
try { |
|
||||
const result = await User.findOne({ where: { username: username } }) |
|
||||
if (result != null) { |
|
||||
request.yar.flash("error", "已存在该用户") |
|
||||
return h.redirect("/register") |
|
||||
} |
|
||||
let salt = bcrypt.genSaltSync(10) |
|
||||
let pwdLock = bcrypt.hashSync(password, salt) |
|
||||
await User.create({ username, password: pwdLock, nickname: username }) |
|
||||
request.yar.flash("success", "用户注册成功") |
|
||||
return h.redirect("/login") |
|
||||
} catch (e) { |
|
||||
loggerSite.error(`注册用户失败`, e.message) |
|
||||
request.yar.flash("error", "注册用户失败") |
|
||||
return h.redirect("/register") |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -0,0 +1,46 @@ |
|||||
|
import { Req, Res, ReturnValue } from "#/global" |
||||
|
import { LoginUserSchema, RegisterUserSchema, UserSchema } from "@/schema" |
||||
|
import { gFail, gSuccess } from "@/util" |
||||
|
import { auth, config, method, route, route_path, validate } from "@noderun/hapi-router" |
||||
|
import * as bcrypt from "bcrypt" |
||||
|
/** |
||||
|
* 登录界面 |
||||
|
*/ |
||||
|
export default class { |
||||
|
@route_path("/login") |
||||
|
@auth("try") |
||||
|
@method("GET") |
||||
|
async login_GET(request: Req, h: Res): ReturnValue { |
||||
|
if (request.auth.isAuthenticated) { |
||||
|
request.yar.flash("warning", "您已经登陆") |
||||
|
return h.redirect("/") |
||||
|
} else { |
||||
|
logger.debug("未登录") |
||||
|
} |
||||
|
return h.view("views/login.pug") |
||||
|
} |
||||
|
|
||||
|
@validate({ |
||||
|
payload: LoginUserSchema, |
||||
|
$errto: "/login", |
||||
|
// failAction: 'log'
|
||||
|
failAction: "function", |
||||
|
// failReason: "用户名或密码错误,请重试",
|
||||
|
}) |
||||
|
@method("POST") |
||||
|
@route_path("/login") |
||||
|
async login_POST(request: Req, h: Res): ReturnValue { |
||||
|
const { username, password, referrer } = request.payload as any |
||||
|
|
||||
|
const User = request.getModel("User") |
||||
|
const account = <any>await User.findOne({ where: { username: username } }) |
||||
|
|
||||
|
if (!account || !(await bcrypt.compare(password, account.password))) { |
||||
|
request.yar.flash("error", "Invalid username or password") |
||||
|
return h.redirect("/login") |
||||
|
} |
||||
|
request.cookieAuth.set({ id: account.id, nickname: account.nickname }) |
||||
|
request.yar.flash("success", "用户已登录") |
||||
|
return h.redirect(referrer ? referrer : "/") |
||||
|
} |
||||
|
} |
@ -0,0 +1,53 @@ |
|||||
|
import { Req, Res, ReturnValue } from "#/global" |
||||
|
import { LoginUserSchema, RegisterUserSchema, UserSchema } from "@/schema" |
||||
|
import { gFail, gSuccess } from "@/util" |
||||
|
import { auth, config, method, route, route_path, validate } from "@noderun/hapi-router" |
||||
|
import * as bcrypt from "bcrypt" |
||||
|
/** |
||||
|
* 登录界面 |
||||
|
*/ |
||||
|
export default class { |
||||
|
@route_path("/register") |
||||
|
@auth("try") |
||||
|
@method("GET") |
||||
|
async register_GET(request: Req, h: Res): ReturnValue { |
||||
|
if (request.auth.isAuthenticated) { |
||||
|
request.yar.flash("warning", "您已经登陆") |
||||
|
return h.redirect("/") |
||||
|
} else { |
||||
|
logger.debug("未登录") |
||||
|
} |
||||
|
return h.view("views/register.pug") |
||||
|
} |
||||
|
|
||||
|
@validate({ |
||||
|
payload: RegisterUserSchema, |
||||
|
$errto: "/register", |
||||
|
failAction: "function", |
||||
|
failReason: "注册账户不符合规范", |
||||
|
}) |
||||
|
@method("POST") |
||||
|
@route_path("/register") |
||||
|
async register_POST(request: Req, h: Res): ReturnValue { |
||||
|
console.log(request) |
||||
|
let { username, password } = request.payload as any |
||||
|
const User = request.getModel("User") |
||||
|
logger.trace("当前注册用户:" + username) |
||||
|
try { |
||||
|
const result = await User.findOne({ where: { username: username } }) |
||||
|
if (result != null) { |
||||
|
request.yar.flash("error", "已存在该用户") |
||||
|
return h.redirect("/register") |
||||
|
} |
||||
|
let salt = bcrypt.genSaltSync(10) |
||||
|
let pwdLock = bcrypt.hashSync(password, salt) |
||||
|
await User.create({ username, password: pwdLock, nickname: username }) |
||||
|
request.yar.flash("success", "用户注册成功") |
||||
|
return h.redirect("/login") |
||||
|
} catch (e) { |
||||
|
loggerSite.error(`注册用户失败`, e.message) |
||||
|
request.yar.flash("error", "注册用户失败") |
||||
|
return h.redirect("/register") |
||||
|
} |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue