@kevisual/router 0.0.58 → 0.0.59

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.
@@ -1,3 +1,7 @@
1
+ import { EventEmitter } from 'eventemitter3';
2
+ import * as http from 'node:http';
3
+ import { IncomingMessage, ServerResponse } from 'node:http';
4
+ import { IncomingMessage as IncomingMessage$1, ServerResponse as ServerResponse$1 } from 'http';
1
5
  import { Plugin } from '@opencode-ai/plugin';
2
6
 
3
7
  type RouterContextT = {
@@ -336,7 +340,6 @@ declare class QueryRouterServer extends QueryRouter {
336
340
  handle: any;
337
341
  constructor(opts?: QueryRouterServerOpts);
338
342
  setHandle(wrapperFn?: HandleFn, ctx?: RouteContext): void;
339
- use(path: string, fn: (ctx: any) => any, opts?: RouteOpts): void;
340
343
  addRoute(route: Route): void;
341
344
  Route: typeof Route;
342
345
  route(opts: RouteOpts): Route<Required<RouteContext>>;
@@ -360,9 +363,314 @@ declare class QueryRouterServer extends QueryRouter {
360
363
  }): Promise<any>;
361
364
  }
362
365
 
363
- declare const addCallFn: (app: QueryRouterServer) => void;
364
- declare const createRouterAgentPluginFn: (opts?: {
366
+ type Cors = {
367
+ /**
368
+ * @default '*''
369
+ */
370
+ origin?: string | undefined;
371
+ };
372
+ type ServerOpts<T = {}> = {
373
+ /**path default `/api/router` */
374
+ path?: string;
375
+ /**handle Fn */
376
+ handle?: (msg?: {
377
+ path: string;
378
+ key?: string;
379
+ [key: string]: any;
380
+ }, ctx?: {
381
+ req: http.IncomingMessage;
382
+ res: http.ServerResponse;
383
+ }) => any;
384
+ cors?: Cors;
385
+ io?: boolean;
386
+ showConnected?: boolean;
387
+ } & T;
388
+ interface ServerType {
389
+ path?: string;
390
+ server?: any;
391
+ handle: ServerOpts['handle'];
392
+ setHandle(handle?: any): void;
393
+ listeners: Listener[];
394
+ listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
395
+ listen(port: number, hostname?: string, listeningListener?: () => void): void;
396
+ listen(port: number, backlog?: number, listeningListener?: () => void): void;
397
+ listen(port: number, listeningListener?: () => void): void;
398
+ listen(path: string, backlog?: number, listeningListener?: () => void): void;
399
+ listen(path: string, listeningListener?: () => void): void;
400
+ listen(handle: any, backlog?: number, listeningListener?: () => void): void;
401
+ listen(handle: any, listeningListener?: () => void): void;
402
+ /**
403
+ * 兜底监听,当除开 `/api/router` 之外的请求,框架只监听一个api,所以有其他的请求都执行其他的监听
404
+ * @description 主要是为了兼容其他的监听
405
+ * @param listener
406
+ */
407
+ on(listener: OnListener): void;
408
+ onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions): void;
409
+ onWsClose<T = {}>(ws: WS<T>): void;
410
+ sendConnected<T = {}>(ws: WS<T>): void;
411
+ }
412
+ type OnWebSocketOptions<T = {}> = {
413
+ ws: WS<T>;
414
+ message: string | Buffer;
415
+ pathname: string;
416
+ token?: string;
417
+ id?: string;
418
+ };
419
+ type WS<T = {}> = {
420
+ send: (data: any) => void;
421
+ close: (code?: number, reason?: string) => void;
422
+ data?: {
423
+ url: URL;
424
+ pathname: string;
425
+ token?: string;
426
+ id?: string;
427
+ /**
428
+ * 鉴权后的获取的信息
429
+ */
430
+ userApp?: string;
431
+ } & T;
432
+ };
433
+ type Listener = {
434
+ id?: string;
435
+ io?: boolean;
436
+ path?: string;
437
+ func: WebSocketListenerFun | HttpListenerFun;
438
+ /**
439
+ * @description 是否默认解析为 JSON,如果为 true,则 message 会被 JSON.parse 处理,默认是 true
440
+ */
441
+ json?: boolean;
442
+ };
443
+ type WebSocketListenerFun = (req: WebSocketReq, res: WebSocketRes) => Promise<void> | void;
444
+ type HttpListenerFun = (req: RouterReq, res: RouterRes) => Promise<void> | void;
445
+ type WebSocketReq<T = {}, U = Record<string, any>> = {
446
+ emitter?: EventEmitter;
447
+ ws: WS<T>;
448
+ data?: U;
449
+ message?: string | Buffer;
450
+ pathname?: string;
451
+ token?: string;
452
+ id?: string;
453
+ };
454
+ type WebSocketRes = {
455
+ end: (data: any) => void;
456
+ };
457
+ type ListenerFun = WebSocketListenerFun | HttpListenerFun;
458
+ type OnListener = Listener | ListenerFun | (Listener | ListenerFun)[];
459
+ type RouterReq<T = {}> = {
460
+ url: string;
461
+ method: string;
462
+ headers: Record<string, string>;
463
+ socket?: {
464
+ remoteAddress?: string;
465
+ remotePort?: number;
466
+ };
467
+ body?: string;
468
+ cookies?: Record<string, string>;
469
+ } & T;
470
+ type RouterRes<T = {}> = {
471
+ statusCode: number;
472
+ headersSent: boolean;
473
+ _headers: Record<string, string | string[]>;
474
+ _bodyChunks: any[];
475
+ writableEnded: boolean;
476
+ writeHead: (statusCode: number, headers?: Record<string, string>) => void;
477
+ setHeader: (name: string, value: string | string[]) => void;
478
+ cookie: (name: string, value: string, options?: any) => void;
479
+ write: (chunk: any) => void;
480
+ pipe: (stream: any) => void;
481
+ end: (data?: any) => void;
482
+ } & T;
483
+
484
+ interface StringifyOptions {
485
+ /**
486
+ * Specifies a function that will be used to encode a [cookie-value](https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.1).
487
+ * Since value of a cookie has a limited character set (and must be a simple string), this function can be used to encode
488
+ * a value into a string suited for a cookie's value, and should mirror `decode` when parsing.
489
+ *
490
+ * @default encodeURIComponent
491
+ */
492
+ encode?: (str: string) => string;
493
+ }
494
+ /**
495
+ * Set-Cookie object.
496
+ */
497
+ interface SetCookie {
498
+ /**
499
+ * Specifies the name of the cookie.
500
+ */
501
+ name: string;
502
+ /**
503
+ * Specifies the string to be the value for the cookie.
504
+ */
505
+ value: string | undefined;
506
+ /**
507
+ * Specifies the `number` (in seconds) to be the value for the [`Max-Age` `Set-Cookie` attribute](https://tools.ietf.org/html/rfc6265#section-5.2.2).
508
+ *
509
+ * The [cookie storage model specification](https://tools.ietf.org/html/rfc6265#section-5.3) states that if both `expires` and
510
+ * `maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this,
511
+ * so if both are set, they should point to the same date and time.
512
+ */
513
+ maxAge?: number;
514
+ /**
515
+ * Specifies the `Date` object to be the value for the [`Expires` `Set-Cookie` attribute](https://tools.ietf.org/html/rfc6265#section-5.2.1).
516
+ * When no expiration is set, clients consider this a "non-persistent cookie" and delete it when the current session is over.
517
+ *
518
+ * The [cookie storage model specification](https://tools.ietf.org/html/rfc6265#section-5.3) states that if both `expires` and
519
+ * `maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this,
520
+ * so if both are set, they should point to the same date and time.
521
+ */
522
+ expires?: Date;
523
+ /**
524
+ * Specifies the value for the [`Domain` `Set-Cookie` attribute](https://tools.ietf.org/html/rfc6265#section-5.2.3).
525
+ * When no domain is set, clients consider the cookie to apply to the current domain only.
526
+ */
527
+ domain?: string;
528
+ /**
529
+ * Specifies the value for the [`Path` `Set-Cookie` attribute](https://tools.ietf.org/html/rfc6265#section-5.2.4).
530
+ * When no path is set, the path is considered the ["default path"](https://tools.ietf.org/html/rfc6265#section-5.1.4).
531
+ */
532
+ path?: string;
533
+ /**
534
+ * Enables the [`HttpOnly` `Set-Cookie` attribute](https://tools.ietf.org/html/rfc6265#section-5.2.6).
535
+ * When enabled, clients will not allow client-side JavaScript to see the cookie in `document.cookie`.
536
+ */
537
+ httpOnly?: boolean;
538
+ /**
539
+ * Enables the [`Secure` `Set-Cookie` attribute](https://tools.ietf.org/html/rfc6265#section-5.2.5).
540
+ * When enabled, clients will only send the cookie back if the browser has an HTTPS connection.
541
+ */
542
+ secure?: boolean;
543
+ /**
544
+ * Enables the [`Partitioned` `Set-Cookie` attribute](https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/).
545
+ * When enabled, clients will only send the cookie back when the current domain _and_ top-level domain matches.
546
+ *
547
+ * This is an attribute that has not yet been fully standardized, and may change in the future.
548
+ * This also means clients may ignore this attribute until they understand it. More information
549
+ * about can be found in [the proposal](https://github.com/privacycg/CHIPS).
550
+ */
551
+ partitioned?: boolean;
552
+ /**
553
+ * Specifies the value for the [`Priority` `Set-Cookie` attribute](https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1).
554
+ *
555
+ * - `'low'` will set the `Priority` attribute to `Low`.
556
+ * - `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
557
+ * - `'high'` will set the `Priority` attribute to `High`.
558
+ *
559
+ * More information about priority levels can be found in [the specification](https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1).
560
+ */
561
+ priority?: "low" | "medium" | "high";
562
+ /**
563
+ * Specifies the value for the [`SameSite` `Set-Cookie` attribute](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-09#section-5.4.7).
564
+ *
565
+ * - `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
566
+ * - `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
567
+ * - `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
568
+ * - `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
569
+ *
570
+ * More information about enforcement levels can be found in [the specification](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-09#section-5.4.7).
571
+ */
572
+ sameSite?: boolean | "lax" | "strict" | "none";
573
+ }
574
+ /**
575
+ * Backward compatibility serialize options.
576
+ */
577
+ type SerializeOptions = StringifyOptions & Omit<SetCookie, "name" | "value">;
578
+
579
+ type CookieFn = (name: string, value: string, options?: SerializeOptions, end?: boolean) => void;
580
+ type HandleCtx = {
581
+ req: IncomingMessage & {
582
+ cookies: Record<string, string>;
583
+ };
584
+ res: ServerResponse & {
585
+ /**
586
+ * cookie 函数, end 参数用于设置是否立即设置到响应头,设置了后面的cookie再设置会覆盖前面的
587
+ */
588
+ cookie: CookieFn;
589
+ };
590
+ };
591
+
592
+ type ServerNodeOpts = ServerOpts<{
593
+ httpType?: 'http' | 'https' | 'http2';
594
+ httpsKey?: string;
595
+ httpsCert?: string;
596
+ }>;
597
+
598
+ type RouterHandle = (msg: {
599
+ path: string;
600
+ [key: string]: any;
601
+ }) => {
602
+ code: string;
603
+ data?: any;
604
+ message?: string;
605
+ [key: string]: any;
606
+ };
607
+ type AppOptions<T = {}> = {
365
608
  router?: QueryRouter;
609
+ server?: ServerType;
610
+ /** handle msg 关联 */
611
+ routerHandle?: RouterHandle;
612
+ routerContext?: RouteContext<T>;
613
+ serverOptions?: ServerNodeOpts;
614
+ appId?: string;
615
+ };
616
+ type AppRouteContext<T = {}> = HandleCtx & RouteContext<T> & {
617
+ app: App<T>;
618
+ };
619
+ /**
620
+ * 封装了 Router 和 Server 的 App 模块,处理http的请求和响应,内置了 Cookie 和 Token 和 res 的处理
621
+ * U - Route Context的扩展类型
622
+ */
623
+ declare class App<U = {}> extends QueryRouter {
624
+ appId: string;
625
+ router: QueryRouter;
626
+ server: ServerType;
627
+ constructor(opts?: AppOptions<U>);
628
+ listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
629
+ listen(port: number, hostname?: string, listeningListener?: () => void): void;
630
+ listen(port: number, backlog?: number, listeningListener?: () => void): void;
631
+ listen(port: number, listeningListener?: () => void): void;
632
+ listen(path: string, backlog?: number, listeningListener?: () => void): void;
633
+ listen(path: string, listeningListener?: () => void): void;
634
+ listen(handle: any, backlog?: number, listeningListener?: () => void): void;
635
+ listen(handle: any, listeningListener?: () => void): void;
636
+ addRoute(route: Route): void;
637
+ Route: typeof Route;
638
+ route(opts: RouteOpts<AppRouteContext<U>>): Route<AppRouteContext<U>>;
639
+ route(path: string, key?: string): Route<AppRouteContext<U>>;
640
+ route(path: string, opts?: RouteOpts<AppRouteContext<U>>): Route<AppRouteContext<U>>;
641
+ route(path: string, key?: string, opts?: RouteOpts<AppRouteContext<U>>): Route<AppRouteContext<U>>;
642
+ prompt(description: string): Route<AppRouteContext<U>>;
643
+ prompt(description: Function): Route<AppRouteContext<U>>;
644
+ call(message: {
645
+ id?: string;
646
+ path?: string;
647
+ key?: string;
648
+ payload?: any;
649
+ }, ctx?: AppRouteContext<U> & {
650
+ [key: string]: any;
651
+ }): Promise<any>;
652
+ run(msg: {
653
+ id?: string;
654
+ path?: string;
655
+ key?: string;
656
+ payload?: any;
657
+ }, ctx?: Partial<AppRouteContext<U>> & {
658
+ [key: string]: any;
659
+ }): Promise<{
660
+ code: any;
661
+ data: any;
662
+ message: any;
663
+ }>;
664
+ static handleRequest(req: IncomingMessage$1, res: ServerResponse$1): Promise<{
665
+ cookies: Record<string, string>;
666
+ token: string;
667
+ }>;
668
+ onServerRequest(fn: (req: IncomingMessage$1, res: ServerResponse$1) => void): void;
669
+ }
670
+
671
+ declare const addCallFn: (app: App) => void;
672
+ declare const createRouterAgentPluginFn: (opts?: {
673
+ router?: App | QueryRouterServer;
366
674
  query?: string;
367
675
  }) => Plugin;
368
676
 
package/dist/opencode.js CHANGED
@@ -15315,7 +15315,7 @@ const createRouterAgentPluginFn = (opts) => {
15315
15315
  let router = opts?.router;
15316
15316
  if (!router) {
15317
15317
  const app = useContextKey('app');
15318
- router = app.router;
15318
+ router = app;
15319
15319
  }
15320
15320
  if (!router) {
15321
15321
  throw new Error('Router 参数缺失');
@@ -351,7 +351,6 @@ declare class QueryRouterServer extends QueryRouter {
351
351
  handle: any;
352
352
  constructor(opts?: QueryRouterServerOpts);
353
353
  setHandle(wrapperFn?: HandleFn, ctx?: RouteContext): void;
354
- use(path: string, fn: (ctx: any) => any, opts?: RouteOpts): void;
355
354
  addRoute(route: Route): void;
356
355
  Route: typeof Route;
357
356
  route(opts: RouteOpts): Route<Required<RouteContext>>;
@@ -15058,11 +15058,6 @@ class QueryRouterServer extends QueryRouter {
15058
15058
  setHandle(wrapperFn, ctx) {
15059
15059
  this.handle = this.getHandle(this, wrapperFn, ctx);
15060
15060
  }
15061
- use(path, fn, opts) {
15062
- const route = new Route(path, '', opts);
15063
- route.run = fn;
15064
- this.add(route);
15065
- }
15066
15061
  addRoute(route) {
15067
15062
  this.add(route);
15068
15063
  }
package/dist/router.d.ts CHANGED
@@ -358,7 +358,6 @@ declare class QueryRouterServer extends QueryRouter {
358
358
  handle: any;
359
359
  constructor(opts?: QueryRouterServerOpts);
360
360
  setHandle(wrapperFn?: HandleFn, ctx?: RouteContext): void;
361
- use(path: string, fn: (ctx: any) => any, opts?: RouteOpts): void;
362
361
  addRoute(route: Route): void;
363
362
  Route: typeof Route;
364
363
  route(opts: RouteOpts): Route<Required<RouteContext>>;
@@ -873,7 +872,7 @@ type AppRouteContext<T = {}> = HandleCtx & RouteContext<T> & {
873
872
  * 封装了 Router 和 Server 的 App 模块,处理http的请求和响应,内置了 Cookie 和 Token 和 res 的处理
874
873
  * U - Route Context的扩展类型
875
874
  */
876
- declare class App<U = {}> {
875
+ declare class App<U = {}> extends QueryRouter {
877
876
  appId: string;
878
877
  router: QueryRouter;
879
878
  server: ServerType;
@@ -886,9 +885,7 @@ declare class App<U = {}> {
886
885
  listen(path: string, listeningListener?: () => void): void;
887
886
  listen(handle: any, backlog?: number, listeningListener?: () => void): void;
888
887
  listen(handle: any, listeningListener?: () => void): void;
889
- use(path: string, fn: (ctx: any) => any, opts?: RouteOpts): void;
890
888
  addRoute(route: Route): void;
891
- add: (route: Route) => void;
892
889
  Route: typeof Route;
893
890
  route(opts: RouteOpts<AppRouteContext<U>>): Route<AppRouteContext<U>>;
894
891
  route(path: string, key?: string): Route<AppRouteContext<U>>;
@@ -904,34 +901,18 @@ declare class App<U = {}> {
904
901
  }, ctx?: AppRouteContext<U> & {
905
902
  [key: string]: any;
906
903
  }): Promise<any>;
907
- /**
908
- * @deprecated
909
- */
910
- queryRoute(path: string, key?: string, payload?: any, ctx?: AppRouteContext<U> & {
911
- [key: string]: any;
912
- }): Promise<{
913
- code: any;
914
- data: any;
915
- message: any;
916
- }>;
917
904
  run(msg: {
918
905
  id?: string;
919
906
  path?: string;
920
907
  key?: string;
921
908
  payload?: any;
922
- }, ctx?: AppRouteContext<U> & {
909
+ }, ctx?: Partial<AppRouteContext<U>> & {
923
910
  [key: string]: any;
924
911
  }): Promise<{
925
912
  code: any;
926
913
  data: any;
927
914
  message: any;
928
915
  }>;
929
- exportRoutes(): Route<{
930
- [key: string]: any;
931
- }, SimpleObject$1>[];
932
- importRoutes(routes: any[]): void;
933
- importApp(app: App): void;
934
- throw(code?: number | string, message?: string, tips?: string): void;
935
916
  static handleRequest(req: IncomingMessage$1, res: ServerResponse$1): Promise<{
936
917
  cookies: Record<string, string>;
937
918
  token: string;
package/dist/router.js CHANGED
@@ -15082,11 +15082,6 @@ class QueryRouterServer extends QueryRouter {
15082
15082
  setHandle(wrapperFn, ctx) {
15083
15083
  this.handle = this.getHandle(this, wrapperFn, ctx);
15084
15084
  }
15085
- use(path, fn, opts) {
15086
- const route = new Route(path, '', opts);
15087
- route.run = fn;
15088
- this.add(route);
15089
- }
15090
15085
  addRoute(route) {
15091
15086
  this.add(route);
15092
15087
  }
@@ -21616,12 +21611,12 @@ class BunServer extends ServerBase {
21616
21611
  * 封装了 Router 和 Server 的 App 模块,处理http的请求和响应,内置了 Cookie 和 Token 和 res 的处理
21617
21612
  * U - Route Context的扩展类型
21618
21613
  */
21619
- class App {
21620
- appId;
21614
+ class App extends QueryRouter {
21621
21615
  router;
21622
21616
  server;
21623
21617
  constructor(opts) {
21624
- const router = opts?.router || new QueryRouter();
21618
+ super();
21619
+ const router = this;
21625
21620
  let server = opts?.server;
21626
21621
  if (!server) {
21627
21622
  const serverOptions = opts?.serverOptions || {};
@@ -21648,15 +21643,9 @@ class App {
21648
21643
  // @ts-ignore
21649
21644
  this.server.listen(...args);
21650
21645
  }
21651
- use(path, fn, opts) {
21652
- const route = new Route(path, '', opts);
21653
- route.run = fn;
21654
- this.router.add(route);
21655
- }
21656
21646
  addRoute(route) {
21657
- this.router.add(route);
21647
+ super.add(route);
21658
21648
  }
21659
- add = this.addRoute;
21660
21649
  Route = Route;
21661
21650
  route(...args) {
21662
21651
  const [path, key, opts] = args;
@@ -21686,29 +21675,10 @@ class App {
21686
21675
  return new Route('', '', { description });
21687
21676
  }
21688
21677
  async call(message, ctx) {
21689
- const router = this.router;
21690
- return await router.call(message, ctx);
21691
- }
21692
- /**
21693
- * @deprecated
21694
- */
21695
- async queryRoute(path, key, payload, ctx) {
21696
- return await this.router.queryRoute({ path, key, payload }, ctx);
21678
+ return await super.call(message, ctx);
21697
21679
  }
21698
21680
  async run(msg, ctx) {
21699
- return await this.router.run(msg, ctx);
21700
- }
21701
- exportRoutes() {
21702
- return this.router.exportRoutes();
21703
- }
21704
- importRoutes(routes) {
21705
- this.router.importRoutes(routes);
21706
- }
21707
- importApp(app) {
21708
- this.importRoutes(app.exportRoutes());
21709
- }
21710
- throw(...args) {
21711
- throw new CustomError(...args);
21681
+ return await super.run(msg, ctx);
21712
21682
  }
21713
21683
  static handleRequest(req, res) {
21714
21684
  return handleServer(req, res);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@kevisual/router",
4
- "version": "0.0.58",
4
+ "version": "0.0.59",
5
5
  "description": "",
6
6
  "type": "module",
7
7
  "main": "./dist/router.js",
@@ -28,7 +28,7 @@
28
28
  "@kevisual/local-proxy": "^0.0.8",
29
29
  "@kevisual/query": "^0.0.35",
30
30
  "@kevisual/use-config": "^1.0.28",
31
- "@opencode-ai/plugin": "^1.1.26",
31
+ "@opencode-ai/plugin": "^1.1.27",
32
32
  "@rollup/plugin-alias": "^6.0.0",
33
33
  "@rollup/plugin-commonjs": "29.0.0",
34
34
  "@rollup/plugin-node-resolve": "^16.0.3",
package/src/app.ts CHANGED
@@ -26,12 +26,13 @@ export type AppRouteContext<T = {}> = HandleCtx & RouteContext<T> & { app: App<T
26
26
  * 封装了 Router 和 Server 的 App 模块,处理http的请求和响应,内置了 Cookie 和 Token 和 res 的处理
27
27
  * U - Route Context的扩展类型
28
28
  */
29
- export class App<U = {}> {
30
- appId: string;
29
+ export class App<U = {}> extends QueryRouter {
30
+ declare appId: string;
31
31
  router: QueryRouter;
32
32
  server: ServerType;
33
33
  constructor(opts?: AppOptions<U>) {
34
- const router = opts?.router || new QueryRouter();
34
+ super();
35
+ const router = this;
35
36
  let server = opts?.server;
36
37
  if (!server) {
37
38
  const serverOptions = opts?.serverOptions || {};
@@ -64,15 +65,9 @@ export class App<U = {}> {
64
65
  // @ts-ignore
65
66
  this.server.listen(...args);
66
67
  }
67
- use(path: string, fn: (ctx: any) => any, opts?: RouteOpts) {
68
- const route = new Route(path, '', opts);
69
- route.run = fn;
70
- this.router.add(route);
71
- }
72
68
  addRoute(route: Route) {
73
- this.router.add(route);
69
+ super.add(route);
74
70
  }
75
- add = this.addRoute;
76
71
 
77
72
  Route = Route;
78
73
  route(opts: RouteOpts<AppRouteContext<U>>): Route<AppRouteContext<U>>;
@@ -109,30 +104,10 @@ export class App<U = {}> {
109
104
  }
110
105
 
111
106
  async call(message: { id?: string, path?: string; key?: string; payload?: any }, ctx?: AppRouteContext<U> & { [key: string]: any }) {
112
- const router = this.router;
113
- return await router.call(message, ctx);
114
- }
115
- /**
116
- * @deprecated
117
- */
118
- async queryRoute(path: string, key?: string, payload?: any, ctx?: AppRouteContext<U> & { [key: string]: any }) {
119
- return await this.router.queryRoute({ path, key, payload }, ctx);
120
- }
121
- async run(msg: { id?: string, path?: string; key?: string; payload?: any }, ctx?: AppRouteContext<U> & { [key: string]: any }) {
122
- return await this.router.run(msg, ctx);
123
- }
124
- exportRoutes() {
125
- return this.router.exportRoutes();
126
- }
127
- importRoutes(routes: any[]) {
128
- this.router.importRoutes(routes);
129
- }
130
- importApp(app: App) {
131
- this.importRoutes(app.exportRoutes());
107
+ return await super.call(message, ctx);
132
108
  }
133
- throw(code?: number | string, message?: string, tips?: string): void;
134
- throw(...args: any[]) {
135
- throw new CustomError(...args);
109
+ async run(msg: { id?: string, path?: string; key?: string; payload?: any }, ctx?: Partial<AppRouteContext<U>> & { [key: string]: any }) {
110
+ return await super.run(msg, ctx);
136
111
  }
137
112
  static handleRequest(req: IncomingMessage, res: ServerResponse) {
138
113
  return handleServer(req, res);
package/src/opencode.ts CHANGED
@@ -4,7 +4,7 @@ import { type App } from './app.ts'
4
4
  import { type Plugin } from "@opencode-ai/plugin"
5
5
 
6
6
  import { filter } from '@kevisual/js-filter';
7
- export const addCallFn = (app: QueryRouterServer) => {
7
+ export const addCallFn = (app: App) => {
8
8
  app.route({
9
9
  path: 'call',
10
10
  key: '',
@@ -35,20 +35,20 @@ export const addCallFn = (app: QueryRouterServer) => {
35
35
  }).addTo(app)
36
36
  }
37
37
  export const createRouterAgentPluginFn = (opts?: {
38
- router?: QueryRouter,
38
+ router?: App | QueryRouterServer,
39
39
  //** 过滤比如,WHERE metadata.tags includes 'opencode' */
40
40
  query?: string
41
41
  }) => {
42
42
  let router = opts?.router
43
43
  if (!router) {
44
44
  const app = useContextKey<App>('app')
45
- router = app.router
45
+ router = app
46
46
  }
47
47
  if (!router) {
48
48
  throw new Error('Router 参数缺失')
49
49
  }
50
50
  if (!router.hasRoute('call', '')) {
51
- addCallFn(router as QueryRouterServer)
51
+ addCallFn(router as App)
52
52
  }
53
53
  const _routes = filter(router.routes, opts?.query || '')
54
54
  const routes = _routes.filter(r => {
package/src/route.ts CHANGED
@@ -664,15 +664,9 @@ export class QueryRouterServer extends QueryRouter {
664
664
  setHandle(wrapperFn?: HandleFn, ctx?: RouteContext) {
665
665
  this.handle = this.getHandle(this, wrapperFn, ctx);
666
666
  }
667
- use(path: string, fn: (ctx: any) => any, opts?: RouteOpts) {
668
- const route = new Route(path, '', opts);
669
- route.run = fn;
670
- this.add(route);
671
- }
672
667
  addRoute(route: Route) {
673
668
  this.add(route);
674
669
  }
675
-
676
670
  Route = Route;
677
671
  route(opts: RouteOpts): Route<Required<RouteContext>>;
678
672
  route(path: string, key?: string): Route<Required<RouteContext>>;