vona-module-a-web 5.0.31 → 5.0.33

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.
@@ -124,6 +124,23 @@ declare module 'vona-module-a-web' {
124
124
  }
125
125
  }
126
126
  /** filterTransform: end */
127
+ /** hmr: begin */
128
+ export * from '../bean/hmr.controller.ts';
129
+ import 'vona';
130
+ declare module 'vona' {
131
+ interface IHmrRecord {
132
+ 'a-web:controller': never;
133
+ }
134
+ }
135
+ declare module 'vona-module-a-web' {
136
+ interface HmrController {
137
+ }
138
+ interface HmrController {
139
+ get $beanFullName(): 'a-web.hmr.controller';
140
+ get $onionName(): 'a-web:controller';
141
+ }
142
+ }
143
+ /** hmr: end */
127
144
  /** config: begin */
128
145
  export * from '../config/config.ts';
129
146
  import type { config } from '../config/config.ts';
@@ -1,12 +1,11 @@
1
- import type { Constructable, VonaContext } from 'vona';
2
1
  import * as ModuleInfo from '@cabloy/module-info';
3
2
  import Router from 'find-my-way';
4
3
  import { BeanBase } from 'vona';
5
4
  export declare class BeanRouter extends BeanBase {
6
- registerController(moduleName: string, controller: Constructable): void;
5
+ reRegisterController(beanFullName: string): void;
6
+ registerController(beanFullName: string): void;
7
7
  register(method: Router.HTTPMethod, moduleName: ModuleInfo.IModuleInfo | string, path: string | undefined, simplify: boolean, fn: Router.Handler<Router.HTTPVersion.V1>): void;
8
8
  unRegister(method: Router.HTTPMethod, moduleName: ModuleInfo.IModuleInfo | string, path: string | undefined, simplify: boolean): void;
9
9
  findByPath(method: Router.HTTPMethod, moduleName: ModuleInfo.IModuleInfo | string, path: string | undefined, simplify: boolean): any;
10
10
  private _registerControllerAction;
11
- _registerComposeMiddlewares(ctx: VonaContext): (context: any, next?: any) => any;
12
11
  }
@@ -0,0 +1,6 @@
1
+ import type { IDecoratorBeanOptionsBase } from 'vona';
2
+ import type { IHmrReload } from 'vona-module-a-hmr';
3
+ import { BeanBase } from 'vona';
4
+ export declare class HmrController extends BeanBase implements IHmrReload {
5
+ reload(beanOptions: IDecoratorBeanOptionsBase): Promise<void>;
6
+ }
package/dist/index.js CHANGED
@@ -1,8 +1,7 @@
1
1
  import { BeanInfo, BeanBase, cast, beanFullNameFromOnionName, appMetadata, appResource, deepExtend, compose, createBeanDecorator, BeanSimple, BeanScopeBase } from 'vona';
2
2
  import { isNil, isNilOrEmptyString } from '@cabloy/utils';
3
3
  import { ZodMetadata } from '@cabloy/zod-openapi';
4
- import { Pipe, createArgumentPipe, setArgumentPipe } from 'vona-module-a-aspect';
5
- import * as ModuleInfo from '@cabloy/module-info';
4
+ import { Pipe, createArgumentPipe, SymbolCacheComposeGuards, SymbolCacheComposeInterceptors, SymbolCacheComposePipes, SymbolCacheComposeMiddlewares, clearCacheComposesRouter, SymbolCacheComposeMiddlewareSystems, setArgumentPipe } from 'vona-module-a-aspect';
6
5
  import { Bean, Service, Scope } from 'vona-module-a-bean';
7
6
  import { SymbolUseOnionOptions } from 'vona-module-a-onion';
8
7
  import { SymbolRouteHandlersArgumentsValue, SymbolRouteHandlersArgumentsMeta, makeSchemaLikes, $schema, SymbolOpenApiOptions, mergeFieldsOpenapiMetadata } from 'vona-module-a-openapiutils';
@@ -11,21 +10,22 @@ import http from 'node:http';
11
10
  import { Startup } from 'vona-module-a-startup';
12
11
  import { DateTime } from 'luxon';
13
12
  import 'vona-module-a-web';
13
+ import { Hmr } from 'vona-module-a-hmr';
14
14
  import Router from 'find-my-way';
15
15
  import { SymbolRouterMiddleware } from 'vona-module-a-executor';
16
16
  import { z } from 'zod';
17
17
 
18
- var _dec$7, _dec2$7, _class$7;
18
+ var _dec$8, _dec2$8, _class$8;
19
19
  const __FieldsSystem = ['columns', 'where', 'orders', 'pageNo', 'pageSize'];
20
- let PipeFilter = (_dec$7 = Pipe({
20
+ let PipeFilter = (_dec$8 = Pipe({
21
21
  // ValidatorOptions
22
22
  disableErrorMessages: false,
23
23
  errorHttpStatusCode: 400,
24
24
  loose: false,
25
25
  strict: false
26
- }), _dec2$7 = BeanInfo({
26
+ }), _dec2$8 = BeanInfo({
27
27
  module: "a-web"
28
- }), _dec$7(_class$7 = _dec2$7(_class$7 = class PipeFilter extends BeanBase {
28
+ }), _dec$8(_class$8 = _dec2$8(_class$8 = class PipeFilter extends BeanBase {
29
29
  async transform(value, metadata, options) {
30
30
  if (!options.schema) throw new Error(`should specify the schema of pipeFilter: ${metadata.controller.name}.${metadata.method}#${metadata.index}`);
31
31
  // validateSchema
@@ -164,19 +164,19 @@ let PipeFilter = (_dec$7 = Pipe({
164
164
  await this._transformField(key, value[key], params, value, options);
165
165
  }
166
166
  }
167
- }) || _class$7) || _class$7);
167
+ }) || _class$8) || _class$8);
168
168
  const ArgFilterPro = createArgumentPipe('a-web:filter');
169
169
 
170
- var _dec$6, _dec2$6, _class$6;
171
- let PipeValid = (_dec$6 = Pipe({
170
+ var _dec$7, _dec2$7, _class$7;
171
+ let PipeValid = (_dec$7 = Pipe({
172
172
  // ValidatorOptions
173
173
  disableErrorMessages: false,
174
174
  errorHttpStatusCode: 400,
175
175
  loose: false,
176
176
  strict: false
177
- }), _dec2$6 = BeanInfo({
177
+ }), _dec2$7 = BeanInfo({
178
178
  module: "a-web"
179
- }), _dec$6(_class$6 = _dec2$6(_class$6 = class PipeValid extends BeanBase {
179
+ }), _dec$7(_class$7 = _dec2$7(_class$7 = class PipeValid extends BeanBase {
180
180
  async transform(value, metadata, options) {
181
181
  if (options.schema) {
182
182
  // validateSchema
@@ -184,26 +184,56 @@ let PipeValid = (_dec$6 = Pipe({
184
184
  }
185
185
  return value;
186
186
  }
187
- }) || _class$6) || _class$6);
187
+ }) || _class$7) || _class$7);
188
188
  const ArgValid = createArgumentPipe('a-web:valid');
189
189
 
190
+ const SymbolCacheControllerRoutes = Symbol('SymbolCacheControllerRoutes');
191
+ function getCacheControllerRoutes(app) {
192
+ if (!app.meta[SymbolCacheControllerRoutes]) app.meta[SymbolCacheControllerRoutes] = {};
193
+ return app.meta[SymbolCacheControllerRoutes];
194
+ }
195
+
190
196
  async function middlewareGuard(ctx, next) {
191
197
  // check handler
192
198
  const handler = ctx.getHandler();
193
199
  if (!handler) return next();
194
200
  // compose
195
- const result = await ctx.app.bean.onion.guard.compose(ctx)(ctx);
201
+ const result = await _composeGuards(ctx.app, ctx.route)(ctx);
196
202
  if (result === false) ctx.app.throw(403);
197
203
  // next
198
204
  return next();
199
205
  }
206
+ function _composeGuards(app, route) {
207
+ // compose
208
+ if (!app.meta[SymbolCacheComposeGuards]) app.meta[SymbolCacheComposeGuards] = {};
209
+ const cacheComposeGuards = app.meta[SymbolCacheComposeGuards];
210
+ const beanFullName = route.controllerBeanFullName;
211
+ const handlerName = route.action;
212
+ const key = `${beanFullName}:${handlerName}`;
213
+ if (!cacheComposeGuards[key]) {
214
+ cacheComposeGuards[key] = app.bean.onion.guard.compose(route);
215
+ }
216
+ return cacheComposeGuards[key];
217
+ }
200
218
 
201
219
  async function middlewareInterceptor(ctx, next) {
202
220
  // check handler
203
221
  const handler = ctx.getHandler();
204
222
  if (!handler) return next();
205
223
  // compose
206
- return await ctx.app.bean.onion.interceptor.compose(ctx)(ctx, next);
224
+ return await _composeInterceptors(ctx.app, ctx.route)(ctx, next);
225
+ }
226
+ function _composeInterceptors(app, route) {
227
+ // compose
228
+ if (!app.meta[SymbolCacheComposeInterceptors]) app.meta[SymbolCacheComposeInterceptors] = {};
229
+ const cacheComposeInterceptors = app.meta[SymbolCacheComposeInterceptors];
230
+ const beanFullName = route.controllerBeanFullName;
231
+ const handlerName = route.action;
232
+ const key = `${beanFullName}:${handlerName}`;
233
+ if (!cacheComposeInterceptors[key]) {
234
+ cacheComposeInterceptors[key] = app.bean.onion.interceptor.compose(route);
235
+ }
236
+ return cacheComposeInterceptors[key];
207
237
  }
208
238
 
209
239
  function extractValue(ctx, argMeta) {
@@ -256,16 +286,16 @@ async function middlewarePipe(ctx, next) {
256
286
  const handler = ctx.getHandler();
257
287
  if (!handler) return next();
258
288
  // arguments
259
- ctx[SymbolRouteHandlersArgumentsValue] = await _transformArguments(ctx, ctx.getController(), handler);
289
+ ctx[SymbolRouteHandlersArgumentsValue] = await _transformArguments(ctx.app, ctx.route);
260
290
  // next
261
291
  return next();
262
292
  }
263
- async function _transformArguments(ctx, controller, handler) {
264
- const paramtypes = appMetadata.getMetadata('design:paramtypes', controller.prototype, handler.name);
293
+ async function _transformArguments(app, route) {
294
+ const paramtypes = appMetadata.getMetadata('design:paramtypes', route.controller.prototype, route.action);
265
295
  if (!paramtypes) return;
266
296
 
267
297
  // meta
268
- const argsMeta = appMetadata.getMetadata(SymbolRouteHandlersArgumentsMeta, controller.prototype, handler.name);
298
+ const argsMeta = appMetadata.getMetadata(SymbolRouteHandlersArgumentsMeta, route.controller.prototype, route.action);
269
299
  if (!argsMeta) return;
270
300
 
271
301
  // args
@@ -276,24 +306,24 @@ async function _transformArguments(ctx, controller, handler) {
276
306
  const argMeta = argsMeta.find(item => item?.index === index);
277
307
  if (!argMeta) continue;
278
308
  // extractValue
279
- const value = await _extractArgumentValue(ctx, argMeta);
309
+ const value = await _extractArgumentValue(app.ctx, argMeta);
280
310
  // metadata
281
311
  const metadata = {
282
312
  type: argMeta.type,
283
313
  field: argMeta.field,
284
314
  metaType: paramtypes[index],
285
- controller,
286
- method: handler.name,
315
+ controller: route.controller,
316
+ method: route.action,
287
317
  index: argMeta.index
288
318
  };
289
319
  // transform
290
- args[index] = await _transformArgument(ctx, argMeta, metadata, value);
320
+ args[index] = await _transformArgument(app, route, argMeta, metadata, value);
291
321
  }
292
322
  return args;
293
323
  }
294
- async function _transformArgument(ctx, argMeta, metadata, value) {
324
+ async function _transformArgument(app, route, argMeta, metadata, value) {
295
325
  // pipes
296
- const pipes = composePipes(ctx, argMeta, (beanInstance, value, options, _next) => {
326
+ const pipes = composePipes(app, route, argMeta, (beanInstance, value, options, _next) => {
297
327
  if (!isNil(options.argIndex) && argMeta.index !== options.argIndex) return value;
298
328
  return beanInstance.transform(value, metadata, options);
299
329
  });
@@ -313,22 +343,21 @@ async function _extractArgumentValue(ctx, argMeta) {
313
343
  }
314
344
  return extractValue(ctx, argMeta);
315
345
  }
316
- const SymbolCacheMiddlewaresArgument = Symbol('SymbolCacheMiddlewaresArgument');
317
- function composePipes(ctx, argMeta, executeCustom) {
318
- if (!ctx.app.meta[SymbolCacheMiddlewaresArgument]) ctx.app.meta[SymbolCacheMiddlewaresArgument] = {};
319
- const __cacheMiddlewaresArgument = ctx.app.meta[SymbolCacheMiddlewaresArgument];
320
- const onionPipe = ctx.app.bean.onion.pipe;
321
- const beanFullName = ctx.getControllerBeanFullName();
322
- const handlerName = ctx.getHandler().name;
346
+ function composePipes(app, route, argMeta, executeCustom) {
347
+ if (!app.meta[SymbolCacheComposePipes]) app.meta[SymbolCacheComposePipes] = {};
348
+ const cacheComposePipes = app.meta[SymbolCacheComposePipes];
349
+ const onionPipe = app.bean.onion.pipe;
350
+ const beanFullName = route.controllerBeanFullName;
351
+ const handlerName = route.action;
323
352
  const key = `${beanFullName}:${handlerName}:${argMeta.index}`;
324
- if (!__cacheMiddlewaresArgument[key]) {
353
+ if (!cacheComposePipes[key]) {
325
354
  const middlewares = [];
326
355
  // pipes: global
327
356
  for (const item of onionPipe.onionsGlobal) {
328
357
  middlewares.push(onionPipe._wrapOnion(item, executeCustom));
329
358
  }
330
359
  // pipes: route
331
- const middlewaresLocal = onionPipe._collectOnionsHandler(ctx);
360
+ const middlewaresLocal = onionPipe._collectOnionsHandler(route);
332
361
  for (const item of middlewaresLocal) {
333
362
  middlewares.push(onionPipe._wrapOnion(item, executeCustom));
334
363
  }
@@ -339,9 +368,9 @@ function composePipes(ctx, argMeta, executeCustom) {
339
368
  middlewares.push(onionPipe._wrapOnion(item, executeCustom));
340
369
  }
341
370
  }
342
- __cacheMiddlewaresArgument[key] = middlewares;
371
+ cacheComposePipes[key] = middlewares;
343
372
  }
344
- return __cacheMiddlewaresArgument[key];
373
+ return cacheComposePipes[key];
345
374
  }
346
375
  function _collectArgumentMiddlewares(onionPipe, argMeta) {
347
376
  if (!argMeta.pipes) return;
@@ -373,17 +402,28 @@ const SymbolRequestMappingHandler = Symbol('SymbolRequestMappingHandler');
373
402
  // HEAD = 'head',
374
403
  // }
375
404
 
376
- var _dec$5, _dec2$5, _class$5;
377
- const SymbolRouteComposeMiddlewaresCache = Symbol('SymbolRouteComposeMiddlewaresCache');
378
- let BeanRouter = (_dec$5 = Bean(), _dec2$5 = BeanInfo({
405
+ var _dec$6, _dec2$6, _class$6;
406
+ let BeanRouter = (_dec$6 = Bean(), _dec2$6 = BeanInfo({
379
407
  module: "a-web"
380
- }), _dec$5(_class$5 = _dec2$5(_class$5 = class BeanRouter extends BeanBase {
381
- registerController(moduleName, controller) {
382
- // info
383
- const info = ModuleInfo.parseInfo(moduleName);
408
+ }), _dec$6(_class$6 = _dec2$6(_class$6 = class BeanRouter extends BeanBase {
409
+ reRegisterController(beanFullName) {
410
+ const app = this.app;
411
+ // remove
412
+ const cacheControllerRoutes = getCacheControllerRoutes(this.app);
413
+ const routes = cacheControllerRoutes[beanFullName];
414
+ if (!routes) return;
415
+ delete cacheControllerRoutes[beanFullName];
416
+ for (const route of routes) {
417
+ app.router.off(route.routeMethod.toUpperCase(), route.routePath);
418
+ }
419
+ // register
420
+ this.registerController(beanFullName);
421
+ }
422
+ registerController(beanFullName) {
384
423
  // controller options
385
- const beanOptions = appResource.getBean(controller);
424
+ const beanOptions = appResource.getBean(beanFullName);
386
425
  if (!beanOptions) return;
426
+ const controller = beanOptions.beanClass;
387
427
  const controllerBeanFullName = beanOptions.beanFullName;
388
428
  const controllerOptions = beanOptions.options;
389
429
  const controllerPath = controllerOptions.path;
@@ -394,7 +434,7 @@ let BeanRouter = (_dec$5 = Bean(), _dec2$5 = BeanInfo({
394
434
  const desc = descs[actionKey];
395
435
  if (['constructor'].includes(actionKey)) continue;
396
436
  if (!desc.value || typeof desc.value !== 'function') continue;
397
- this._registerControllerAction(info, controller, controllerBeanFullName, controllerPath, controllerMiddlewaresOptions, actionKey, desc);
437
+ this._registerControllerAction(beanOptions.module, controller, controllerBeanFullName, controllerPath, controllerMiddlewaresOptions, actionKey, desc);
398
438
  }
399
439
  }
400
440
  register(method, moduleName, path, simplify, fn) {
@@ -412,7 +452,7 @@ let BeanRouter = (_dec$5 = Bean(), _dec2$5 = BeanInfo({
412
452
  const _path = app.util.combineApiPath(path, moduleName, true, simplify);
413
453
  return app.router.findRoute(method, _path);
414
454
  }
415
- _registerControllerAction(info, controller, controllerBeanFullName, controllerPath, controllerMiddlewaresOptions, actionKey, desc) {
455
+ _registerControllerAction(moduleName, controller, controllerBeanFullName, controllerPath, controllerMiddlewaresOptions, actionKey, desc) {
416
456
  // app
417
457
  const app = this.app;
418
458
 
@@ -422,8 +462,8 @@ let BeanRouter = (_dec$5 = Bean(), _dec2$5 = BeanInfo({
422
462
  const actionPath = handlerMetadata.path || '';
423
463
  const actionMethod = handlerMetadata.method || 'get';
424
464
  // routePath
425
- const routePath = app.util.combineApiPathControllerAndAction(info.relativeName, controllerPath, actionPath, true, true);
426
- const routePathRaw = app.util.combineApiPathControllerAndActionRaw(info.relativeName, controllerPath, actionPath, true);
465
+ const routePath = app.util.combineApiPathControllerAndAction(moduleName, controllerPath, actionPath, true, true);
466
+ const routePathRaw = app.util.combineApiPathControllerAndActionRaw(moduleName, controllerPath, actionPath, true);
427
467
 
428
468
  // middlewares options
429
469
  const actionMiddlewaresOptions = appMetadata.getMetadata(SymbolUseOnionOptions, controller.prototype, actionKey);
@@ -435,8 +475,6 @@ let BeanRouter = (_dec$5 = Bean(), _dec2$5 = BeanInfo({
435
475
 
436
476
  // route
437
477
  const _route = {
438
- pid: info.pid,
439
- module: info.name,
440
478
  controller,
441
479
  actionDescriptor: desc,
442
480
  controllerBeanFullName,
@@ -448,22 +486,33 @@ let BeanRouter = (_dec$5 = Bean(), _dec2$5 = BeanInfo({
448
486
  };
449
487
 
450
488
  // fn
451
- const self = this;
452
489
  const fn = function (_req, _res, params, _store, searchParams) {
453
490
  const ctx = this;
454
491
  ctx.route = _route;
455
492
  ctx.request.params = params;
456
493
  ctx.request.query = searchParams;
457
- if (!_route[SymbolRouteComposeMiddlewaresCache]) {
458
- _route[SymbolRouteComposeMiddlewaresCache] = self._registerComposeMiddlewares(ctx);
459
- }
460
- return _route[SymbolRouteComposeMiddlewaresCache](ctx);
494
+ return _composeMiddlewares(this.app, _route)(ctx);
461
495
  };
462
496
 
497
+ // add
498
+ const cacheControllerRoutes = getCacheControllerRoutes(this.app);
499
+ if (!cacheControllerRoutes[controllerBeanFullName]) {
500
+ cacheControllerRoutes[controllerBeanFullName] = [];
501
+ }
502
+ cacheControllerRoutes[controllerBeanFullName].push(_route);
503
+
463
504
  // register
464
- app.router.on(_route.routeMethod.toUpperCase(), _route.routePath.toString(), fn);
505
+ app.router.on(_route.routeMethod.toUpperCase(), _route.routePath, fn);
465
506
  }
466
- _registerComposeMiddlewares(ctx) {
507
+ }) || _class$6) || _class$6);
508
+ function _composeMiddlewares(app, route) {
509
+ // compose
510
+ if (!app.meta[SymbolCacheComposeMiddlewares]) app.meta[SymbolCacheComposeMiddlewares] = {};
511
+ const cacheComposeMiddlewares = app.meta[SymbolCacheComposeMiddlewares];
512
+ const beanFullName = route.controllerBeanFullName;
513
+ const handlerName = route.action;
514
+ const key = `${beanFullName}:${handlerName}`;
515
+ if (!cacheComposeMiddlewares[key]) {
467
516
  // start
468
517
  const fnStart = routeStartMiddleware;
469
518
  // mid: guard/interceptor/pipes/tail
@@ -474,10 +523,10 @@ let BeanRouter = (_dec$5 = Bean(), _dec2$5 = BeanInfo({
474
523
  fnMid.push(routeTailDoneMiddleware);
475
524
  // end: controller
476
525
  const fnEnd = classControllerMiddleware;
477
- // compose
478
- return this.app.bean.onion.middleware.compose(ctx, fnStart, fnMid, fnEnd);
526
+ cacheComposeMiddlewares[key] = app.bean.onion.middleware.compose(route, fnStart, fnMid, fnEnd);
479
527
  }
480
- }) || _class$5) || _class$5);
528
+ return cacheComposeMiddlewares[key];
529
+ }
481
530
  function classControllerMiddleware(ctx) {
482
531
  const handlerName = ctx.getHandlerName();
483
532
  const controller = ctx.getControllerBean();
@@ -500,61 +549,10 @@ async function routeTailDoneMiddleware(ctx, next) {
500
549
  return res;
501
550
  }
502
551
 
503
- // _registerInner(route, middlewaresLocal) {
504
- // // app
505
- // const app = this.app;
506
- // // args
507
- // let args: any[] = [];
508
- // // middlewares: start
509
- // const fnStart = async (ctx: VonaContext, next: Next) => {
510
- // // route
511
- // ctx.route = route;
512
- // // next
513
- // const res = await next();
514
- // // invoke callbackes: handle secondly
515
- // await ctx.commitsDone();
516
- // // ok
517
- // return res;
518
- // };
519
- // fnStart._name = 'start';
520
- // args.push(fnStart);
521
-
522
- // // middlewares: globals
523
- // args.push(...app.bean.onion.middleware.composedOnionsGlobal);
524
- // // middlewares: guard/interceptor/pipes
525
- // args.push(middlewareGuard);
526
- // args.push(middlewareInterceptor);
527
- // args.push(middlewarePipe);
528
-
529
- // // middlewares: tailDone
530
- // const fnTailDone = async (ctx, next) => {
531
- // // next
532
- // const res = await next();
533
- // // invoke callbackes: handle firstly
534
- // await ctx.commitsDone();
535
- // // ok
536
- // return res;
537
- // };
538
- // fnTailDone._name = 'tailDone';
539
- // args.push(fnTailDone);
540
-
541
- // // middlewares
542
- // if (middlewaresLocal.length > 0) {
543
- // args = args.concat(middlewaresLocal);
544
- // }
545
-
546
- // // load
547
- // if (route.routeName) {
548
- // app.router[route.routeMethod](route.routeName, route.routePath, ...args);
549
- // } else {
550
- // app.router[route.routeMethod](route.routePath, ...args);
551
- // }
552
- // }
553
-
554
- var _dec$4, _dec2$4, _class$4;
555
- let ServiceWeb = (_dec$4 = Service(), _dec2$4 = BeanInfo({
552
+ var _dec$5, _dec2$5, _class$5;
553
+ let ServiceWeb = (_dec$5 = Service(), _dec2$5 = BeanInfo({
556
554
  module: "a-web"
557
- }), _dec$4(_class$4 = _dec2$4(_class$4 = class ServiceWeb extends BeanBase {
555
+ }), _dec$5(_class$5 = _dec2$5(_class$5 = class ServiceWeb extends BeanBase {
558
556
  combineControllerActionApiPath(controller, actionKey, prefix, simplify) {
559
557
  // beanOptions
560
558
  const beanOptions = appResource.getBean(controller);
@@ -568,14 +566,14 @@ let ServiceWeb = (_dec$4 = Service(), _dec2$4 = BeanInfo({
568
566
  // combine
569
567
  return this.app.util.combineApiPathControllerAndAction(beanOptions.module, controllerPath, actionPath, prefix, simplify);
570
568
  }
571
- }) || _class$4) || _class$4);
569
+ }) || _class$5) || _class$5);
572
570
 
573
- var _dec$3, _dec2$3, _class$3;
574
- let StartupListen = (_dec$3 = Startup({
571
+ var _dec$4, _dec2$4, _class$4;
572
+ let StartupListen = (_dec$4 = Startup({
575
573
  after: true
576
- }), _dec2$3 = BeanInfo({
574
+ }), _dec2$4 = BeanInfo({
577
575
  module: "a-web"
578
- }), _dec$3(_class$3 = _dec2$3(_class$3 = class StartupListen extends BeanBase {
576
+ }), _dec$4(_class$4 = _dec2$4(_class$4 = class StartupListen extends BeanBase {
579
577
  async execute() {
580
578
  if (!this.app.config.server.listen.disable) {
581
579
  this.app.server = this._listen(this.app.config.server.listen.port, this.app.config.server.listen.hostname);
@@ -601,16 +599,16 @@ let StartupListen = (_dec$3 = Startup({
601
599
  }); // not set instanceName
602
600
  };
603
601
  }
604
- }) || _class$3) || _class$3);
602
+ }) || _class$4) || _class$4);
605
603
 
606
604
  function FilterTransform(options) {
607
605
  return createBeanDecorator('filterTransform', options);
608
606
  }
609
607
 
610
- var _dec$2, _dec2$2, _class$2;
611
- let FilterTransformBase = (_dec$2 = FilterTransform(), _dec2$2 = BeanInfo({
608
+ var _dec$3, _dec2$3, _class$3;
609
+ let FilterTransformBase = (_dec$3 = FilterTransform(), _dec2$3 = BeanInfo({
612
610
  module: "a-web"
613
- }), _dec$2(_class$2 = _dec2$2(_class$2 = class FilterTransformBase extends BeanBase {
611
+ }), _dec$3(_class$3 = _dec2$3(_class$3 = class FilterTransformBase extends BeanBase {
614
612
  async where(info, _options) {
615
613
  const {
616
614
  value,
@@ -635,14 +633,14 @@ let FilterTransformBase = (_dec$2 = FilterTransform(), _dec2$2 = BeanInfo({
635
633
  }
636
634
  return where;
637
635
  }
638
- }) || _class$2) || _class$2);
636
+ }) || _class$3) || _class$3);
639
637
 
640
- var _dec$1, _dec2$1, _class$1;
641
- let FilterTransformDateRange = (_dec$1 = FilterTransform({
638
+ var _dec$2, _dec2$2, _class$2;
639
+ let FilterTransformDateRange = (_dec$2 = FilterTransform({
642
640
  separator: '~'
643
- }), _dec2$1 = BeanInfo({
641
+ }), _dec2$2 = BeanInfo({
644
642
  module: "a-web"
645
- }), _dec$1(_class$1 = _dec2$1(_class$1 = class FilterTransformDateRange extends BeanBase {
643
+ }), _dec$2(_class$2 = _dec2$2(_class$2 = class FilterTransformDateRange extends BeanBase {
646
644
  async where(info, options) {
647
645
  const {
648
646
  value
@@ -667,6 +665,17 @@ let FilterTransformDateRange = (_dec$1 = FilterTransform({
667
665
  }
668
666
  return where;
669
667
  }
668
+ }) || _class$2) || _class$2);
669
+
670
+ var _dec$1, _dec2$1, _class$1;
671
+ let HmrController = (_dec$1 = Hmr(), _dec2$1 = BeanInfo({
672
+ module: "a-web"
673
+ }), _dec$1(_class$1 = _dec2$1(_class$1 = class HmrController extends BeanBase {
674
+ async reload(beanOptions) {
675
+ clearCacheComposesRouter(this.app);
676
+ this.bean.router.reRegisterController(beanOptions.beanFullName);
677
+ await this.$scope.openapi.service.openapi.clearAllCaches();
678
+ }
670
679
  }) || _class$1) || _class$1);
671
680
 
672
681
  function config(_app) {
@@ -700,36 +709,18 @@ class Main extends BeanSimple {
700
709
  }
701
710
  });
702
711
  // register controllers
703
- for (const controller of this.bean.onion.controller.getOnionsEnabled()) {
704
- this.bean.router.registerController(controller.beanOptions.module, controller.beanOptions.beanClass);
712
+ for (const controller of this.bean.onion.controller.getOnionsEnabledCached()) {
713
+ this.bean.router.registerController(controller.beanOptions.beanFullName);
705
714
  }
706
715
  // middleware: system
707
- const middlewares = this.bean.onion.middlewareSystem.getOnionsEnabledWrapped(item => {
708
- return this._wrapOnion(item);
716
+ this.app.use((ctx, next) => {
717
+ return _composeMiddlewareSystems(this.app)(ctx, next);
709
718
  });
710
- this.app.use(compose(middlewares));
711
719
  // middleware: router
712
720
  this.app[SymbolRouterMiddleware] = routerMiddleware(this[SymbolRouter]);
713
721
  this.app.use(this.app[SymbolRouterMiddleware]);
714
722
  }
715
723
  async configLoaded(_config) {}
716
- _wrapOnion(item) {
717
- const fn = (_ctx, next) => {
718
- const options = item.beanOptions.options;
719
- if (!this.bean.onion.checkOnionOptionsEnabled(options, this.ctx.path)) {
720
- return next();
721
- }
722
- // execute
723
- const beanFullName = item.beanOptions.beanFullName;
724
- const beanInstance = this.app.bean._getBean(beanFullName);
725
- if (!beanInstance) {
726
- throw new Error(`middlewareSystem bean not found: ${beanFullName}`);
727
- }
728
- return beanInstance.execute(options, next);
729
- };
730
- fn._name = item.name;
731
- return fn;
732
- }
733
724
  }
734
725
  function routerMiddleware(router) {
735
726
  return function (ctx) {
@@ -741,6 +732,33 @@ function routerMiddleware(router) {
741
732
  });
742
733
  };
743
734
  }
735
+ function _composeMiddlewareSystems(app) {
736
+ // compose
737
+ if (!app.meta[SymbolCacheComposeMiddlewareSystems]) {
738
+ const middlewares = app.bean.onion.middlewareSystem.getOnionsEnabledWrapped(item => {
739
+ return _wrapOnion(app, item);
740
+ });
741
+ app.meta[SymbolCacheComposeMiddlewareSystems] = compose(middlewares);
742
+ }
743
+ return app.meta[SymbolCacheComposeMiddlewareSystems];
744
+ }
745
+ function _wrapOnion(app, item) {
746
+ const fn = (_ctx, next) => {
747
+ const options = item.beanOptions.options;
748
+ if (!app.bean.onion.checkOnionOptionsEnabled(options, app.ctx.path)) {
749
+ return next();
750
+ }
751
+ // execute
752
+ const beanFullName = item.beanOptions.beanFullName;
753
+ const beanInstance = app.bean._getBean(beanFullName);
754
+ if (!beanInstance) {
755
+ throw new Error(`middlewareSystem bean not found: ${beanFullName}`);
756
+ }
757
+ return beanInstance.execute(options, next);
758
+ };
759
+ fn._name = item.name;
760
+ return fn;
761
+ }
744
762
 
745
763
  var _dec, _dec2, _class;
746
764
  let ScopeModuleAWeb = (_dec = Scope(), _dec2 = BeanInfo({
@@ -918,4 +936,4 @@ const Web = {
918
936
  head: Head
919
937
  };
920
938
 
921
- export { Arg, ArgFilterPro, ArgValid, BeanRouter, Controller, Dto, FilterTransform, FilterTransformBase, FilterTransformDateRange, Main, PipeFilter, PipeValid, RequestMapping, ScopeModuleAWeb, ServiceWeb, StartupListen, SymbolRequestMappingHandler, Web, config, createPipesArgumentDecorator, mergeActionsOpenapiMetadata };
939
+ export { Arg, ArgFilterPro, ArgValid, BeanRouter, Controller, Dto, FilterTransform, FilterTransformBase, FilterTransformDateRange, HmrController, Main, PipeFilter, PipeValid, RequestMapping, ScopeModuleAWeb, ServiceWeb, StartupListen, SymbolCacheControllerRoutes, SymbolRequestMappingHandler, Web, config, createPipesArgumentDecorator, getCacheControllerRoutes, mergeActionsOpenapiMetadata };
@@ -0,0 +1,4 @@
1
+ import type { VonaApplication } from 'vona';
2
+ import type { ContextRoute } from '../types/router.ts';
3
+ export declare const SymbolCacheControllerRoutes: unique symbol;
4
+ export declare function getCacheControllerRoutes(app: VonaApplication): Record<string, ContextRoute[]>;
@@ -1 +1,2 @@
1
+ export * from './const.ts';
1
2
  export * from './decorator/index.ts';
package/dist/main.d.ts CHANGED
@@ -6,6 +6,5 @@ export declare class Main extends BeanSimple implements IModuleMain {
6
6
  moduleLoading(): Promise<void>;
7
7
  moduleLoaded(): Promise<void>;
8
8
  configLoaded(_config: any): Promise<void>;
9
- private _wrapOnion;
10
9
  }
11
10
  export {};
@@ -5,16 +5,14 @@ export interface ContextRouteMetadata {
5
5
  meta: any;
6
6
  }
7
7
  export interface ContextRoute {
8
- pid: string;
9
- module: string;
10
8
  controller: Constructable;
11
9
  actionDescriptor: PropertyDescriptor;
12
10
  controllerBeanFullName: string;
13
11
  action: string;
14
12
  route: ContextRouteMetadata;
15
13
  routeMethod: TypeRequestMethod;
16
- routePath: string | RegExp;
17
- routePathRaw: string | RegExp;
14
+ routePath: string;
15
+ routePathRaw: string;
18
16
  }
19
17
  declare module 'vona' {
20
18
  interface VonaApplication {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vona-module-a-web",
3
3
  "type": "module",
4
- "version": "5.0.31",
4
+ "version": "5.0.33",
5
5
  "title": "a-web",
6
6
  "vonaModule": {
7
7
  "capabilities": {