feat: add metadata and middleware add preivew middleware
This commit is contained in:
parent
986b5687c4
commit
1c3e65df8a
@ -3,7 +3,7 @@ import { readFileSync } from 'fs';
|
|||||||
const app = new App({
|
const app = new App({
|
||||||
serverOptions: {
|
serverOptions: {
|
||||||
cors: {},
|
cors: {},
|
||||||
isHTTPS: true,
|
httpType: 'https',
|
||||||
httpsKey: readFileSync('https-key.pem', 'utf8'),
|
httpsKey: readFileSync('https-key.pem', 'utf8'),
|
||||||
httpsCert: readFileSync('https-cert.pem', 'utf-8'),
|
httpsCert: readFileSync('https-cert.pem', 'utf-8'),
|
||||||
},
|
},
|
||||||
|
52
demo/simple/src/three-link/three.ts
Normal file
52
demo/simple/src/three-link/three.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import { Route, App } from '@kevisual/router';
|
||||||
|
import { readFileSync } from 'fs';
|
||||||
|
const app = new App({
|
||||||
|
serverOptions: {
|
||||||
|
cors: {},
|
||||||
|
httpType: 'https',
|
||||||
|
httpsKey: readFileSync('https-key.pem', 'utf8'),
|
||||||
|
httpsCert: readFileSync('https-cert.pem', 'utf-8'),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
app
|
||||||
|
.route({
|
||||||
|
path: 'demo',
|
||||||
|
key: '01',
|
||||||
|
})
|
||||||
|
.define(async (ctx) => {
|
||||||
|
ctx.token = '01';
|
||||||
|
ctx.body = '01';
|
||||||
|
ctx.state.t01 = '01';
|
||||||
|
console.log('state01', ctx.state);
|
||||||
|
})
|
||||||
|
.addTo(app);
|
||||||
|
|
||||||
|
app
|
||||||
|
.route({
|
||||||
|
path: 'demo',
|
||||||
|
key: '02',
|
||||||
|
middleware: [{ path: 'demo', key: '01' } as Route],
|
||||||
|
})
|
||||||
|
.define(async (ctx) => {
|
||||||
|
ctx.body = '02';
|
||||||
|
ctx.state.t02 = '02';
|
||||||
|
console.log('state02', ctx.state, 't', ctx.token);
|
||||||
|
})
|
||||||
|
.addTo(app);
|
||||||
|
|
||||||
|
app
|
||||||
|
.route({
|
||||||
|
path: 'demo',
|
||||||
|
key: '03',
|
||||||
|
middleware: [{ path: 'demo', key: '02' } as Route],
|
||||||
|
})
|
||||||
|
.define(async (ctx) => {
|
||||||
|
ctx.body = '03';
|
||||||
|
console.log('state03', ctx.state);
|
||||||
|
})
|
||||||
|
.addTo(app);
|
||||||
|
|
||||||
|
app.call({ path: 'demo', key: '03' }).then((ctx) => {
|
||||||
|
console.log('result', ctx.body);
|
||||||
|
});
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package",
|
"$schema": "https://json.schemastore.org/package",
|
||||||
"name": "@kevisual/router",
|
"name": "@kevisual/router",
|
||||||
"version": "0.0.6",
|
"version": "0.0.7",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"module": "dist/index.js",
|
"module": "dist/index.js",
|
||||||
|
45
src/route.ts
45
src/route.ts
@ -48,6 +48,7 @@ export type RouteOpts = {
|
|||||||
run?: Run;
|
run?: Run;
|
||||||
nextRoute?: NextRoute; // route to run after this route
|
nextRoute?: NextRoute; // route to run after this route
|
||||||
description?: string;
|
description?: string;
|
||||||
|
metadata?: { [key: string]: any };
|
||||||
middleware?: Route[] | string[]; // middleware
|
middleware?: Route[] | string[]; // middleware
|
||||||
type?: 'route' | 'middleware';
|
type?: 'route' | 'middleware';
|
||||||
/**
|
/**
|
||||||
@ -73,19 +74,32 @@ export type DefineRouteOpts = Omit<RouteOpts, 'idUsePath' | 'verify' | 'verifyKe
|
|||||||
const pickValue = ['path', 'key', 'id', 'description', 'type', 'validator', 'middleware'] as const;
|
const pickValue = ['path', 'key', 'id', 'description', 'type', 'validator', 'middleware'] as const;
|
||||||
export type RouteInfo = Pick<Route, (typeof pickValue)[number]>;
|
export type RouteInfo = Pick<Route, (typeof pickValue)[number]>;
|
||||||
export class Route<U = { [key: string]: any }> {
|
export class Route<U = { [key: string]: any }> {
|
||||||
|
/**
|
||||||
|
* 一级路径
|
||||||
|
*/
|
||||||
path?: string;
|
path?: string;
|
||||||
|
/**
|
||||||
|
* 二级路径
|
||||||
|
*/
|
||||||
key?: string;
|
key?: string;
|
||||||
id?: string;
|
id?: string;
|
||||||
share? = false;
|
share? = false;
|
||||||
run?: Run;
|
run?: Run;
|
||||||
nextRoute?: NextRoute; // route to run after this route
|
nextRoute?: NextRoute; // route to run after this route
|
||||||
description?: string;
|
description?: string;
|
||||||
|
metadata?: { [key: string]: any };
|
||||||
middleware?: (Route | string)[]; // middleware
|
middleware?: (Route | string)[]; // middleware
|
||||||
type? = 'route';
|
type? = 'route';
|
||||||
private _validator?: { [key: string]: Rule };
|
private _validator?: { [key: string]: Rule };
|
||||||
schema?: { [key: string]: Schema<any> };
|
schema?: { [key: string]: Schema<any> };
|
||||||
data?: any;
|
data?: any;
|
||||||
|
/**
|
||||||
|
* 是否需要验证
|
||||||
|
*/
|
||||||
isVerify?: boolean;
|
isVerify?: boolean;
|
||||||
|
/**
|
||||||
|
* 是否开启debug,开启后会打印错误信息
|
||||||
|
*/
|
||||||
isDebug?: boolean;
|
isDebug?: boolean;
|
||||||
constructor(path: string, key: string = '', opts?: RouteOpts) {
|
constructor(path: string, key: string = '', opts?: RouteOpts) {
|
||||||
path = path.trim();
|
path = path.trim();
|
||||||
@ -100,6 +114,7 @@ export class Route<U = { [key: string]: any }> {
|
|||||||
this.run = opts.run;
|
this.run = opts.run;
|
||||||
this.nextRoute = opts.nextRoute;
|
this.nextRoute = opts.nextRoute;
|
||||||
this.description = opts.description;
|
this.description = opts.description;
|
||||||
|
this.metadata = opts.metadata;
|
||||||
this.type = opts.type || 'route';
|
this.type = opts.type || 'route';
|
||||||
this.validator = opts.validator;
|
this.validator = opts.validator;
|
||||||
this.middleware = opts.middleware || [];
|
this.middleware = opts.middleware || [];
|
||||||
@ -218,7 +233,7 @@ export class Route<U = { [key: string]: any }> {
|
|||||||
// 全覆盖,所以opts需要准确,不能由idUsePath 需要check的变量
|
// 全覆盖,所以opts需要准确,不能由idUsePath 需要check的变量
|
||||||
const setOpts = (opts: DefineRouteOpts) => {
|
const setOpts = (opts: DefineRouteOpts) => {
|
||||||
const keys = Object.keys(opts);
|
const keys = Object.keys(opts);
|
||||||
const checkList = ['path', 'key', 'run', 'nextRoute', 'description', 'middleware', 'type', 'validator', 'isVerify', 'isDebug'];
|
const checkList = ['path', 'key', 'run', 'nextRoute', 'description', 'metadata', 'middleware', 'type', 'validator', 'isVerify', 'isDebug'];
|
||||||
for (let item of keys) {
|
for (let item of keys) {
|
||||||
if (!checkList.includes(item)) {
|
if (!checkList.includes(item)) {
|
||||||
continue;
|
continue;
|
||||||
@ -319,19 +334,22 @@ export class QueryRouter {
|
|||||||
// run middleware
|
// run middleware
|
||||||
if (route && route.middleware && route.middleware.length > 0) {
|
if (route && route.middleware && route.middleware.length > 0) {
|
||||||
const errorMiddleware: { path?: string; key?: string; id?: string }[] = [];
|
const errorMiddleware: { path?: string; key?: string; id?: string }[] = [];
|
||||||
// TODO: 向上递归执行动作, 暂时不考虑
|
const getMiddleware = (m: Route) => {
|
||||||
const routeMiddleware = route.middleware.map((m) => {
|
if (!m.middleware || m.middleware.length === 0) return [];
|
||||||
|
const routeMiddleware: Route[] = [];
|
||||||
|
for (let i = 0; i < m.middleware.length; i++) {
|
||||||
|
const item = m.middleware[i];
|
||||||
let route: Route | undefined;
|
let route: Route | undefined;
|
||||||
const isString = typeof m === 'string';
|
const isString = typeof item === 'string';
|
||||||
if (typeof m === 'string') {
|
if (isString) {
|
||||||
route = this.routes.find((r) => r.id === m);
|
route = this.routes.find((r) => r.id === item);
|
||||||
} else {
|
} else {
|
||||||
route = this.routes.find((r) => r.path === m.path && r.key === m.key);
|
route = this.routes.find((r) => r.path === item.path && r.key === item.key);
|
||||||
}
|
}
|
||||||
if (!route) {
|
if (!route) {
|
||||||
if (isString) {
|
if (isString) {
|
||||||
errorMiddleware.push({
|
errorMiddleware.push({
|
||||||
id: m as string,
|
id: item as string,
|
||||||
});
|
});
|
||||||
} else
|
} else
|
||||||
errorMiddleware.push({
|
errorMiddleware.push({
|
||||||
@ -339,8 +357,15 @@ export class QueryRouter {
|
|||||||
key: m?.key,
|
key: m?.key,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return route;
|
const routeMiddlewarePrevious = getMiddleware(route);
|
||||||
});
|
if (routeMiddlewarePrevious.length > 0) {
|
||||||
|
routeMiddleware.push(...routeMiddlewarePrevious);
|
||||||
|
}
|
||||||
|
routeMiddleware.push(route);
|
||||||
|
}
|
||||||
|
return routeMiddleware;
|
||||||
|
};
|
||||||
|
const routeMiddleware = getMiddleware(route);
|
||||||
if (errorMiddleware.length > 0) {
|
if (errorMiddleware.length > 0) {
|
||||||
console.error('middleware not found');
|
console.error('middleware not found');
|
||||||
ctx.body = errorMiddleware;
|
ctx.body = errorMiddleware;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user