@kevisual/router 0.0.35 → 0.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/router-browser.d.ts +51 -113
- package/dist/router-browser.js +3454 -4665
- package/dist/router-define.d.ts +1 -1
- package/dist/router.d.ts +77 -126
- package/dist/router.js +4511 -5704
- package/package.json +1 -1
- package/src/app.ts +20 -12
- package/src/route.ts +28 -178
- package/src/router-define.ts +3 -3
- package/src/server/server.ts +12 -2
- package/src/test/app-type.ts +13 -0
package/package.json
CHANGED
package/src/app.ts
CHANGED
|
@@ -16,16 +16,18 @@ type AppOptions<T = {}> = {
|
|
|
16
16
|
io?: boolean;
|
|
17
17
|
ioOpts?: { routerHandle?: RouterHandle; routerContext?: RouteContext<T>; path?: string };
|
|
18
18
|
};
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
export type AppRouteContext<T = {}> = HandleCtx & RouteContext<T> & { app: App<T> };
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* 封装了 Router 和 Server 的 App 模块,处理http的请求和响应,内置了 Cookie 和 Token 和 res 的处理
|
|
24
|
+
* U - Route Context的扩展类型
|
|
23
25
|
*/
|
|
24
|
-
export class App<
|
|
26
|
+
export class App<U = {}> {
|
|
25
27
|
router: QueryRouter;
|
|
26
28
|
server: Server;
|
|
27
29
|
io: WsServer;
|
|
28
|
-
constructor(opts?: AppOptions<
|
|
30
|
+
constructor(opts?: AppOptions<U>) {
|
|
29
31
|
const router = opts?.router || new QueryRouter();
|
|
30
32
|
const server = opts?.server || new Server(opts?.serverOptions || {});
|
|
31
33
|
server.setHandle(router.getHandle(router, opts?.routerHandle, opts?.routerContext));
|
|
@@ -62,10 +64,10 @@ export class App<T = {}, U = AppReqRes> {
|
|
|
62
64
|
add = this.addRoute;
|
|
63
65
|
|
|
64
66
|
Route = Route;
|
|
65
|
-
route(opts: RouteOpts): Route<U
|
|
66
|
-
route(path: string, key?: string): Route<U
|
|
67
|
-
route(path: string, opts?: RouteOpts): Route<U
|
|
68
|
-
route(path: string, key?: string, opts?: RouteOpts): Route<U
|
|
67
|
+
route(opts: RouteOpts<AppRouteContext<U>>): Route<AppRouteContext<U>>;
|
|
68
|
+
route(path: string, key?: string): Route<AppRouteContext<U>>;
|
|
69
|
+
route(path: string, opts?: RouteOpts<AppRouteContext<U>>): Route<AppRouteContext<U>>;
|
|
70
|
+
route(path: string, key?: string, opts?: RouteOpts<AppRouteContext<U>>): Route<AppRouteContext<U>>;
|
|
69
71
|
route(...args: any[]) {
|
|
70
72
|
const [path, key, opts] = args;
|
|
71
73
|
if (typeof path === 'object') {
|
|
@@ -82,8 +84,8 @@ export class App<T = {}, U = AppReqRes> {
|
|
|
82
84
|
}
|
|
83
85
|
return new Route(path, key, opts);
|
|
84
86
|
}
|
|
85
|
-
prompt(description: string): Route<
|
|
86
|
-
prompt(description: Function): Route<
|
|
87
|
+
prompt(description: string): Route<AppRouteContext<U>>
|
|
88
|
+
prompt(description: Function): Route<AppRouteContext<U>>
|
|
87
89
|
prompt(...args: any[]) {
|
|
88
90
|
const [desc] = args;
|
|
89
91
|
let description = ''
|
|
@@ -94,14 +96,20 @@ export class App<T = {}, U = AppReqRes> {
|
|
|
94
96
|
}
|
|
95
97
|
return new Route('', '', { description });
|
|
96
98
|
}
|
|
97
|
-
|
|
98
|
-
async call(message: { id?: string, path?: string; key?: string; payload?: any }, ctx?:
|
|
99
|
+
|
|
100
|
+
async call(message: { id?: string, path?: string; key?: string; payload?: any }, ctx?: AppRouteContext<U> & { [key: string]: any }) {
|
|
99
101
|
const router = this.router;
|
|
100
102
|
return await router.call(message, ctx);
|
|
101
103
|
}
|
|
102
|
-
|
|
104
|
+
/**
|
|
105
|
+
* @deprecated
|
|
106
|
+
*/
|
|
107
|
+
async queryRoute(path: string, key?: string, payload?: any, ctx?: AppRouteContext<U> & { [key: string]: any }) {
|
|
103
108
|
return await this.router.queryRoute({ path, key, payload }, ctx);
|
|
104
109
|
}
|
|
110
|
+
async run(path: string, key?: string, payload?: any, ctx?: AppRouteContext<U> & { [key: string]: any }) {
|
|
111
|
+
return await this.router.run({ path, key, payload }, ctx);
|
|
112
|
+
}
|
|
105
113
|
exportRoutes() {
|
|
106
114
|
return this.router.exportRoutes();
|
|
107
115
|
}
|
package/src/route.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { nanoid
|
|
1
|
+
import { nanoid } from 'nanoid';
|
|
2
2
|
import { CustomError } from './result/error.ts';
|
|
3
|
-
import { Schema, Rule, createSchema } from './validator/index.ts';
|
|
4
3
|
import { pick } from './utils/pick.ts';
|
|
5
|
-
import { get } from 'lodash-es';
|
|
6
4
|
import { listenProcess } from './utils/listen-process.ts';
|
|
7
5
|
|
|
8
6
|
export type RouterContextT = { code?: number;[key: string]: any };
|
|
@@ -12,6 +10,7 @@ export type RouteContext<T = { code?: number }, S = any> = {
|
|
|
12
10
|
// response body
|
|
13
11
|
/** return body */
|
|
14
12
|
body?: number | string | Object;
|
|
13
|
+
forward?: (response: { code: number, data?: any, message?: any }) => void;
|
|
15
14
|
/** return code */
|
|
16
15
|
code?: number;
|
|
17
16
|
/** return msg */
|
|
@@ -39,20 +38,15 @@ export type RouteContext<T = { code?: number }, S = any> = {
|
|
|
39
38
|
nextQuery?: { [key: string]: any };
|
|
40
39
|
// end
|
|
41
40
|
end?: boolean;
|
|
42
|
-
|
|
43
|
-
// TODO:
|
|
44
|
-
/**
|
|
45
|
-
* 请求 route的返回结果,包函ctx
|
|
46
|
-
*/
|
|
47
|
-
queryRouter?: QueryRouter;
|
|
41
|
+
app?: QueryRouter;
|
|
48
42
|
error?: any;
|
|
49
|
-
/** 请求 route
|
|
43
|
+
/** 请求 route的返回结果,不解析body为data */
|
|
50
44
|
call?: (
|
|
51
45
|
message: { path: string; key?: string; payload?: any;[key: string]: any } | { id: string; apyload?: any;[key: string]: any },
|
|
52
46
|
ctx?: RouteContext & { [key: string]: any },
|
|
53
47
|
) => Promise<any>;
|
|
54
|
-
/** 请求 route
|
|
55
|
-
|
|
48
|
+
/** 请求 route的返回结果,解析了body为data,就类同于 query.post获取的数据*/
|
|
49
|
+
run?: (message: { path: string; key?: string; payload?: any }, ctx?: RouteContext & { [key: string]: any }) => Promise<any>;
|
|
56
50
|
index?: number;
|
|
57
51
|
throw?: (code?: number | string, message?: string, tips?: string) => void;
|
|
58
52
|
/** 是否需要序列化, 使用JSON.stringify和JSON.parse */
|
|
@@ -69,29 +63,16 @@ export type RouteMiddleware =
|
|
|
69
63
|
id?: string;
|
|
70
64
|
}
|
|
71
65
|
| string;
|
|
72
|
-
export type RouteOpts = {
|
|
66
|
+
export type RouteOpts<T = {}> = {
|
|
73
67
|
path?: string;
|
|
74
68
|
key?: string;
|
|
75
69
|
id?: string;
|
|
76
|
-
run?: Run
|
|
70
|
+
run?: Run<T>;
|
|
77
71
|
nextRoute?: NextRoute; // route to run after this route
|
|
78
72
|
description?: string;
|
|
79
73
|
metadata?: { [key: string]: any };
|
|
80
74
|
middleware?: RouteMiddleware[]; // middleware
|
|
81
75
|
type?: 'route' | 'middleware';
|
|
82
|
-
/**
|
|
83
|
-
* validator: {
|
|
84
|
-
* packageName: {
|
|
85
|
-
* type: 'string',
|
|
86
|
-
* required: true,
|
|
87
|
-
* },
|
|
88
|
-
* }
|
|
89
|
-
*/
|
|
90
|
-
validator?: { [key: string]: Rule };
|
|
91
|
-
schema?: { [key: string]: any };
|
|
92
|
-
isVerify?: boolean;
|
|
93
|
-
verify?: (ctx?: RouteContext, dev?: boolean) => boolean;
|
|
94
|
-
verifyKey?: (key: string, ctx?: RouteContext, dev?: boolean) => boolean;
|
|
95
76
|
/**
|
|
96
77
|
* $#$ will be used to split path and key
|
|
97
78
|
*/
|
|
@@ -102,8 +83,8 @@ export type RouteOpts = {
|
|
|
102
83
|
delimiter?: string;
|
|
103
84
|
isDebug?: boolean;
|
|
104
85
|
};
|
|
105
|
-
export type DefineRouteOpts = Omit<RouteOpts, 'idUsePath' | '
|
|
106
|
-
const pickValue = ['path', 'key', 'id', 'description', 'type', '
|
|
86
|
+
export type DefineRouteOpts = Omit<RouteOpts, 'idUsePath' | 'nextRoute'>;
|
|
87
|
+
const pickValue = ['path', 'key', 'id', 'description', 'type', 'middleware', 'metadata'] as const;
|
|
107
88
|
export type RouteInfo = Pick<Route, (typeof pickValue)[number]>;
|
|
108
89
|
export class Route<U = { [key: string]: any }> {
|
|
109
90
|
/**
|
|
@@ -121,13 +102,7 @@ export class Route<U = { [key: string]: any }> {
|
|
|
121
102
|
metadata?: { [key: string]: any };
|
|
122
103
|
middleware?: RouteMiddleware[]; // middleware
|
|
123
104
|
type? = 'route';
|
|
124
|
-
private _validator?: { [key: string]: Rule };
|
|
125
|
-
schema?: { [key: string]: any };
|
|
126
105
|
data?: any;
|
|
127
|
-
/**
|
|
128
|
-
* 是否需要验证
|
|
129
|
-
*/
|
|
130
|
-
isVerify?: boolean;
|
|
131
106
|
/**
|
|
132
107
|
* 是否开启debug,开启后会打印错误信息
|
|
133
108
|
*/
|
|
@@ -151,118 +126,16 @@ export class Route<U = { [key: string]: any }> {
|
|
|
151
126
|
this.description = opts.description;
|
|
152
127
|
this.metadata = opts.metadata;
|
|
153
128
|
this.type = opts.type || 'route';
|
|
154
|
-
this.validator = opts.validator;
|
|
155
129
|
this.middleware = opts.middleware || [];
|
|
156
130
|
this.key = opts.key || key;
|
|
157
131
|
this.path = opts.path || path;
|
|
158
|
-
this.isVerify = opts.isVerify ?? true;
|
|
159
|
-
this.createSchema();
|
|
160
132
|
} else {
|
|
161
|
-
this.isVerify = true;
|
|
162
133
|
this.middleware = [];
|
|
163
134
|
this.id = nanoid();
|
|
164
135
|
}
|
|
165
136
|
this.isDebug = opts?.isDebug ?? false;
|
|
166
137
|
}
|
|
167
|
-
private createSchema() {
|
|
168
|
-
try {
|
|
169
|
-
const validator = this.validator;
|
|
170
|
-
const keys = Object.keys(validator || {});
|
|
171
|
-
const schemaList = keys.map((key) => {
|
|
172
|
-
return { [key]: createSchema(validator[key]) };
|
|
173
|
-
});
|
|
174
|
-
const schema = schemaList.reduce((prev, current) => {
|
|
175
|
-
return { ...prev, ...current };
|
|
176
|
-
}, {});
|
|
177
|
-
this.schema = schema;
|
|
178
|
-
} catch (e) {
|
|
179
|
-
console.error('createSchema error:', e);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* set validator and create schema
|
|
185
|
-
* @param validator
|
|
186
|
-
*/
|
|
187
|
-
set validator(validator: { [key: string]: Rule }) {
|
|
188
|
-
this._validator = validator;
|
|
189
|
-
this.createSchema();
|
|
190
|
-
}
|
|
191
|
-
get validator() {
|
|
192
|
-
return this._validator || {};
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* has code, body, message in ctx, return ctx if has error
|
|
196
|
-
* @param ctx
|
|
197
|
-
* @param dev
|
|
198
|
-
* @returns
|
|
199
|
-
*/
|
|
200
|
-
verify(ctx: RouteContext, dev = false) {
|
|
201
|
-
const query = ctx.query || {};
|
|
202
|
-
const schema = this.schema || {};
|
|
203
|
-
const validator = this.validator;
|
|
204
|
-
const check = () => {
|
|
205
|
-
const queryKeys = Object.keys(validator);
|
|
206
|
-
for (let i = 0; i < queryKeys.length; i++) {
|
|
207
|
-
const key = queryKeys[i];
|
|
208
|
-
const value = query[key];
|
|
209
|
-
if (schema[key]) {
|
|
210
|
-
const result = schema[key].safeParse(value);
|
|
211
|
-
if (!result.success) {
|
|
212
|
-
const path = result.error.errors[0]?.path?.join?.('.properties.');
|
|
213
|
-
let message = 'Invalid params';
|
|
214
|
-
if (path) {
|
|
215
|
-
const keyS = `${key}.properties.${path}.message`;
|
|
216
|
-
message = get(validator, keyS, 'Invalid params') as any;
|
|
217
|
-
}
|
|
218
|
-
throw new CustomError(500, message);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
};
|
|
223
|
-
check();
|
|
224
|
-
}
|
|
225
138
|
|
|
226
|
-
/**
|
|
227
|
-
* Need to manully call return ctx fn and configure body, code, message
|
|
228
|
-
* @param key
|
|
229
|
-
* @param ctx
|
|
230
|
-
* @param dev
|
|
231
|
-
* @returns
|
|
232
|
-
*/
|
|
233
|
-
verifyKey(key: string, ctx: RouteContext, dev = false) {
|
|
234
|
-
const query = ctx.query || {};
|
|
235
|
-
const schema = this.schema || {};
|
|
236
|
-
const validator = this.validator;
|
|
237
|
-
const check = () => {
|
|
238
|
-
const value = query[key];
|
|
239
|
-
if (schema[key]) {
|
|
240
|
-
try {
|
|
241
|
-
schema[key].parse(value);
|
|
242
|
-
} catch (e) {
|
|
243
|
-
if (dev) {
|
|
244
|
-
return {
|
|
245
|
-
message: validator[key].message || 'Invalid params',
|
|
246
|
-
path: this.path,
|
|
247
|
-
key: this.key,
|
|
248
|
-
error: e.message.toString(),
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
return {
|
|
252
|
-
message: validator[key].message || 'Invalid params',
|
|
253
|
-
path: this.path,
|
|
254
|
-
key: this.key,
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
const checkRes = check();
|
|
260
|
-
return checkRes;
|
|
261
|
-
}
|
|
262
|
-
setValidator(validator: { [key: string]: Rule }) {
|
|
263
|
-
this.validator = validator;
|
|
264
|
-
return this;
|
|
265
|
-
}
|
|
266
139
|
prompt(description: string): this;
|
|
267
140
|
prompt(description: Function): this;
|
|
268
141
|
prompt(...args: any[]) {
|
|
@@ -283,15 +156,11 @@ export class Route<U = { [key: string]: any }> {
|
|
|
283
156
|
// 全覆盖,所以opts需要准确,不能由idUsePath 需要check的变量
|
|
284
157
|
const setOpts = (opts: DefineRouteOpts) => {
|
|
285
158
|
const keys = Object.keys(opts);
|
|
286
|
-
const checkList = ['path', 'key', 'run', 'nextRoute', 'description', 'metadata', 'middleware', 'type', '
|
|
159
|
+
const checkList = ['path', 'key', 'run', 'nextRoute', 'description', 'metadata', 'middleware', 'type', 'isDebug'];
|
|
287
160
|
for (let item of keys) {
|
|
288
161
|
if (!checkList.includes(item)) {
|
|
289
162
|
continue;
|
|
290
163
|
}
|
|
291
|
-
if (item === 'validator') {
|
|
292
|
-
this.validator = opts[item];
|
|
293
|
-
continue;
|
|
294
|
-
}
|
|
295
164
|
if (item === 'middleware') {
|
|
296
165
|
this.middleware = this.middleware.concat(opts[item]);
|
|
297
166
|
continue;
|
|
@@ -320,16 +189,12 @@ export class Route<U = { [key: string]: any }> {
|
|
|
320
189
|
|
|
321
190
|
update(opts: DefineRouteOpts, checkList?: string[]): this {
|
|
322
191
|
const keys = Object.keys(opts);
|
|
323
|
-
const defaultCheckList = ['path', 'key', 'run', 'nextRoute', 'description', 'metadata', 'middleware', 'type', '
|
|
192
|
+
const defaultCheckList = ['path', 'key', 'run', 'nextRoute', 'description', 'metadata', 'middleware', 'type', 'isDebug'];
|
|
324
193
|
checkList = checkList || defaultCheckList;
|
|
325
194
|
for (let item of keys) {
|
|
326
195
|
if (!checkList.includes(item)) {
|
|
327
196
|
continue;
|
|
328
197
|
}
|
|
329
|
-
if (item === 'validator') {
|
|
330
|
-
this.validator = opts[item];
|
|
331
|
-
continue;
|
|
332
|
-
}
|
|
333
198
|
if (item === 'middleware') {
|
|
334
199
|
this.middleware = this.middleware.concat(opts[item]);
|
|
335
200
|
continue;
|
|
@@ -360,10 +225,10 @@ export class QueryRouter {
|
|
|
360
225
|
}
|
|
361
226
|
|
|
362
227
|
add(route: Route) {
|
|
363
|
-
const has = this.routes.
|
|
364
|
-
if (has) {
|
|
228
|
+
const has = this.routes.findIndex((r) => r.path === route.path && r.key === route.key);
|
|
229
|
+
if (has !== -1) {
|
|
365
230
|
// remove the old route
|
|
366
|
-
this.routes
|
|
231
|
+
this.routes.splice(has, 1);
|
|
367
232
|
}
|
|
368
233
|
this.routes.push(route);
|
|
369
234
|
}
|
|
@@ -460,19 +325,6 @@ export class QueryRouter {
|
|
|
460
325
|
for (let i = 0; i < routeMiddleware.length; i++) {
|
|
461
326
|
const middleware = routeMiddleware[i];
|
|
462
327
|
if (middleware) {
|
|
463
|
-
if (middleware?.isVerify) {
|
|
464
|
-
try {
|
|
465
|
-
middleware.verify(ctx);
|
|
466
|
-
} catch (e) {
|
|
467
|
-
if (middleware?.isDebug) {
|
|
468
|
-
console.error('=====debug====:', 'middleware verify error:', e.message);
|
|
469
|
-
}
|
|
470
|
-
ctx.message = e.message;
|
|
471
|
-
ctx.code = 500;
|
|
472
|
-
ctx.body = null;
|
|
473
|
-
return ctx;
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
328
|
try {
|
|
477
329
|
await middleware.run(ctx);
|
|
478
330
|
} catch (e) {
|
|
@@ -503,19 +355,6 @@ export class QueryRouter {
|
|
|
503
355
|
// run route
|
|
504
356
|
if (route) {
|
|
505
357
|
if (route.run) {
|
|
506
|
-
if (route?.isVerify) {
|
|
507
|
-
try {
|
|
508
|
-
route.verify(ctx);
|
|
509
|
-
} catch (e) {
|
|
510
|
-
if (route?.isDebug) {
|
|
511
|
-
console.error('=====debug====:', 'verify error:', e.message);
|
|
512
|
-
}
|
|
513
|
-
ctx.message = e.message;
|
|
514
|
-
ctx.code = 500;
|
|
515
|
-
ctx.body = null;
|
|
516
|
-
return ctx;
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
358
|
try {
|
|
520
359
|
await route.run(ctx);
|
|
521
360
|
} catch (e) {
|
|
@@ -588,9 +427,20 @@ export class QueryRouter {
|
|
|
588
427
|
ctx.throw = this.throw;
|
|
589
428
|
ctx.app = this;
|
|
590
429
|
ctx.call = this.call.bind(this);
|
|
591
|
-
ctx.
|
|
430
|
+
ctx.run = this.run.bind(this);
|
|
592
431
|
ctx.index = 0;
|
|
593
432
|
ctx.progress = ctx.progress || [];
|
|
433
|
+
ctx.forward = (response: { code: number; data?: any; message?: any }) => {
|
|
434
|
+
if (response.code) {
|
|
435
|
+
ctx.code = response.code;
|
|
436
|
+
}
|
|
437
|
+
if (response.data !== undefined) {
|
|
438
|
+
ctx.body = response.data;
|
|
439
|
+
}
|
|
440
|
+
if (response.message !== undefined) {
|
|
441
|
+
ctx.message = response.message;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
594
444
|
const res = await this.runRoute(path, key, ctx);
|
|
595
445
|
const serialize = ctx.needSerialize ?? true; // 是否需要序列化
|
|
596
446
|
if (serialize) {
|
|
@@ -816,4 +666,4 @@ export class QueryRouterServer extends QueryRouter {
|
|
|
816
666
|
}
|
|
817
667
|
|
|
818
668
|
|
|
819
|
-
export class Mini extends QueryRouterServer {}
|
|
669
|
+
export class Mini extends QueryRouterServer { }
|
package/src/router-define.ts
CHANGED
|
@@ -11,8 +11,8 @@ type SimpleObject = Record<string, any>;
|
|
|
11
11
|
export function define<T extends Record<string, RouteOpts>>(
|
|
12
12
|
value: T,
|
|
13
13
|
): {
|
|
14
|
-
|
|
15
|
-
} {
|
|
14
|
+
[K in keyof T]: T[K] & RouteOpts;
|
|
15
|
+
} {
|
|
16
16
|
return value as { [K in keyof T]: T[K] & RouteOpts };
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -95,7 +95,7 @@ class QueryChain {
|
|
|
95
95
|
* @param queryData
|
|
96
96
|
* @returns
|
|
97
97
|
*/
|
|
98
|
-
getKey(queryData?: SimpleObject): Pick<RouteOpts, 'path' | 'key' | 'metadata' | 'description'
|
|
98
|
+
getKey(queryData?: SimpleObject): Pick<RouteOpts, 'path' | 'key' | 'metadata' | 'description'> {
|
|
99
99
|
const obj = this.omit(this.obj, this.omitKeys);
|
|
100
100
|
return {
|
|
101
101
|
...obj,
|
package/src/server/server.ts
CHANGED
|
@@ -53,7 +53,7 @@ export type ServerOpts = {
|
|
|
53
53
|
/**path default `/api/router` */
|
|
54
54
|
path?: string;
|
|
55
55
|
/**handle Fn */
|
|
56
|
-
handle?: (msg?: { path: string; key?: string;
|
|
56
|
+
handle?: (msg?: { path: string; key?: string;[key: string]: any }, ctx?: { req: http.IncomingMessage; res: http.ServerResponse }) => any;
|
|
57
57
|
cors?: Cors;
|
|
58
58
|
httpType?: 'http' | 'https' | 'http2';
|
|
59
59
|
httpsKey?: string;
|
|
@@ -222,7 +222,17 @@ export class Server {
|
|
|
222
222
|
} else {
|
|
223
223
|
this._server.on('request', listener);
|
|
224
224
|
}
|
|
225
|
-
|
|
225
|
+
const callbackListener = this._callback || this.createCallback();
|
|
226
|
+
this._server.on('request', callbackListener);
|
|
227
|
+
return () => {
|
|
228
|
+
if (Array.isArray(listener)) {
|
|
229
|
+
listener.forEach((l) => this._server.removeListener('request', l as Listener));
|
|
230
|
+
} else {
|
|
231
|
+
this._server.removeListener('request', listener as Listener);
|
|
232
|
+
}
|
|
233
|
+
this.hasOn = false;
|
|
234
|
+
this._server.removeListener('request', callbackListener);
|
|
235
|
+
}
|
|
226
236
|
}
|
|
227
237
|
get callback() {
|
|
228
238
|
return this._callback || this.createCallback();
|