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*} |
|||
/home/topuser/Code/@project/hapi-demo/dist/route/views对应路径: |
|||
D:\1XYX\pro\hapi-demo\source\route\views对应路径: |
|||
不需权限(提供无需验证): GET /404 |
|||
不需权限 : GET /css |
|||
不需权限(提供无需验证): GET / |
|||
不需权限(提供无需验证): GET /about |
|||
需要权限 : GET /docs/{path*} |
|||
不需权限 : GET /{path*} |
|||
不需权限(提供无需验证): GET /login |
|||
不需权限 : POST /login |
|||
需要权限 : GET /logout |
|||
需要权限 : POST /del |
|||
不需权限 : GET /nav |
|||
不需权限(提供无需验证): GET /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