feat: add metadata and middleware add preivew middleware

This commit is contained in:
熊潇 2025-02-26 11:26:52 +08:00
parent 986b5687c4
commit 1c3e65df8a
4 changed files with 100 additions and 23 deletions

View File

@ -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'),
}, },

View 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);
});

View File

@ -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",

View File

@ -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,28 +334,38 @@ 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 [];
let route: Route | undefined; const routeMiddleware: Route[] = [];
const isString = typeof m === 'string'; for (let i = 0; i < m.middleware.length; i++) {
if (typeof m === 'string') { const item = m.middleware[i];
route = this.routes.find((r) => r.id === m); let route: Route | undefined;
} else { const isString = typeof item === 'string';
route = this.routes.find((r) => r.path === m.path && r.key === m.key);
}
if (!route) {
if (isString) { if (isString) {
errorMiddleware.push({ route = this.routes.find((r) => r.id === item);
id: m as string, } else {
}); route = this.routes.find((r) => r.path === item.path && r.key === item.key);
} else }
errorMiddleware.push({ if (!route) {
path: m?.path, if (isString) {
key: m?.key, errorMiddleware.push({
}); id: item as string,
});
} else
errorMiddleware.push({
path: m?.path,
key: m?.key,
});
}
const routeMiddlewarePrevious = getMiddleware(route);
if (routeMiddlewarePrevious.length > 0) {
routeMiddleware.push(...routeMiddlewarePrevious);
}
routeMiddleware.push(route);
} }
return 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;