vona-module-a-web 5.0.9 → 5.0.10
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/.metadata/index.d.ts +89 -0
- package/dist/.metadata/index.js +38 -0
- package/dist/.metadata/this.d.ts +2 -0
- package/dist/.metadata/this.js +2 -0
- package/dist/bean/bean.router.d.ts +12 -0
- package/dist/bean/bean.router.js +188 -0
- package/dist/bean/startup.listen.d.ts +7 -0
- package/dist/bean/startup.listen.js +34 -0
- package/dist/config/config.d.ts +6 -0
- package/dist/config/config.js +8 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/lib/decorator/bean.d.ts +8 -0
- package/dist/lib/decorator/bean.js +42 -0
- package/dist/lib/decorator/index.d.ts +3 -0
- package/dist/lib/decorator/index.js +3 -0
- package/dist/lib/decorator/request.d.ts +17 -0
- package/dist/lib/decorator/request.js +46 -0
- package/dist/lib/decorator/response.d.ts +1 -0
- package/dist/lib/decorator/response.js +12 -0
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.js +2 -0
- package/dist/lib/middleware/extractValue.d.ts +4 -0
- package/dist/lib/middleware/extractValue.js +48 -0
- package/dist/lib/middleware/middlewareGuard.d.ts +2 -0
- package/dist/lib/middleware/middlewareGuard.js +12 -0
- package/dist/lib/middleware/middlewareInterceptor.d.ts +2 -0
- package/dist/lib/middleware/middlewareInterceptor.js +8 -0
- package/dist/lib/middleware/middlewarePipe.d.ts +2 -0
- package/dist/lib/middleware/middlewarePipe.js +118 -0
- package/dist/lib/utils.d.ts +6 -0
- package/dist/lib/utils.js +7 -0
- package/dist/main.d.ts +11 -0
- package/dist/main.js +63 -0
- package/dist/service/web.d.ts +5 -0
- package/dist/service/web.js +28 -0
- package/dist/types/controller.d.ts +42 -0
- package/dist/types/controller.js +1 -0
- package/dist/types/dto.d.ts +23 -0
- package/dist/types/dto.js +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.js +6 -0
- package/dist/types/request.d.ts +11 -0
- package/dist/types/request.js +11 -0
- package/dist/types/response.d.ts +1 -0
- package/dist/types/response.js +4 -0
- package/dist/types/router.d.ts +36 -0
- package/dist/types/router.js +1 -0
- package/dist/types/service.d.ts +13 -0
- package/dist/types/service.js +1 -0
- package/package.json +7 -3
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { BeanScopeUtil, TypeModuleConfig } from 'vona';
|
|
2
|
+
import type { IDecoratorStartupOptions } from 'vona-module-a-startup';
|
|
3
|
+
/** bean: end */
|
|
4
|
+
/** bean: begin */
|
|
5
|
+
import type { BeanRouter } from '../bean/bean.router.ts';
|
|
6
|
+
import type { config } from '../config/config.ts';
|
|
7
|
+
/** service: end */
|
|
8
|
+
/** service: begin */
|
|
9
|
+
import type { ServiceWeb } from '../service/web.ts';
|
|
10
|
+
/** main: end */
|
|
11
|
+
/** scope: begin */
|
|
12
|
+
import { BeanScopeBase } from 'vona';
|
|
13
|
+
/** service: end */
|
|
14
|
+
/** service: begin */
|
|
15
|
+
/** bean: begin */
|
|
16
|
+
import 'vona';
|
|
17
|
+
import 'vona';
|
|
18
|
+
import 'vona';
|
|
19
|
+
import 'vona';
|
|
20
|
+
import 'vona';
|
|
21
|
+
export * from '../bean/bean.router.ts';
|
|
22
|
+
declare module 'vona' {
|
|
23
|
+
}
|
|
24
|
+
declare module 'vona-module-a-web' {
|
|
25
|
+
interface BeanRouter {
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
declare module 'vona' {
|
|
29
|
+
interface IBeanRecordGlobal {
|
|
30
|
+
router: BeanRouter;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** bean: end */
|
|
34
|
+
/** startup: begin */
|
|
35
|
+
export * from '../bean/startup.listen.ts';
|
|
36
|
+
declare module 'vona-module-a-startup' {
|
|
37
|
+
interface IStartupRecord {
|
|
38
|
+
'a-web:listen': IDecoratorStartupOptions;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
declare module 'vona-module-a-web' {
|
|
42
|
+
interface StartupListen {
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** service: end */
|
|
46
|
+
/** config: begin */
|
|
47
|
+
export * from '../config/config.ts';
|
|
48
|
+
declare module 'vona-module-a-web' {
|
|
49
|
+
interface IServiceRecord {
|
|
50
|
+
'a-web:web': never;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
declare module 'vona-module-a-web' {
|
|
54
|
+
interface ServiceWeb {
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export interface IModuleService {
|
|
58
|
+
web: ServiceWeb;
|
|
59
|
+
}
|
|
60
|
+
declare module 'vona' {
|
|
61
|
+
interface IBeanRecordGeneral {
|
|
62
|
+
'a-web.service.web': ServiceWeb;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** config: end */
|
|
66
|
+
/** main: begin */
|
|
67
|
+
export * from '../main.ts';
|
|
68
|
+
/** startup: end */
|
|
69
|
+
/** service: begin */
|
|
70
|
+
export * from '../service/web.ts';
|
|
71
|
+
export declare class ScopeModuleAWeb extends BeanScopeBase {
|
|
72
|
+
}
|
|
73
|
+
export interface ScopeModuleAWeb {
|
|
74
|
+
util: BeanScopeUtil;
|
|
75
|
+
config: TypeModuleConfig<typeof config>;
|
|
76
|
+
service: IModuleService;
|
|
77
|
+
}
|
|
78
|
+
declare module 'vona' {
|
|
79
|
+
interface IBeanScopeRecord {
|
|
80
|
+
'a-web': ScopeModuleAWeb;
|
|
81
|
+
}
|
|
82
|
+
interface IBeanScopeContainer {
|
|
83
|
+
web: ScopeModuleAWeb;
|
|
84
|
+
}
|
|
85
|
+
interface IBeanScopeConfig {
|
|
86
|
+
'a-web': ReturnType<typeof config>;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** scope: end */
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
/** main: end */
|
|
8
|
+
/** scope: begin */
|
|
9
|
+
import { BeanScopeBase } from 'vona';
|
|
10
|
+
import { Scope } from 'vona-module-a-bean';
|
|
11
|
+
/** service: end */
|
|
12
|
+
/** service: begin */
|
|
13
|
+
/** bean: begin */
|
|
14
|
+
import 'vona';
|
|
15
|
+
import 'vona';
|
|
16
|
+
import 'vona';
|
|
17
|
+
import 'vona';
|
|
18
|
+
import 'vona';
|
|
19
|
+
export * from "../bean/bean.router.js";
|
|
20
|
+
/** bean: end */
|
|
21
|
+
/** startup: begin */
|
|
22
|
+
export * from "../bean/startup.listen.js";
|
|
23
|
+
/** service: end */
|
|
24
|
+
/** config: begin */
|
|
25
|
+
export * from "../config/config.js";
|
|
26
|
+
/** config: end */
|
|
27
|
+
/** main: begin */
|
|
28
|
+
export * from "../main.js";
|
|
29
|
+
/** startup: end */
|
|
30
|
+
/** service: begin */
|
|
31
|
+
export * from "../service/web.js";
|
|
32
|
+
let ScopeModuleAWeb = class ScopeModuleAWeb extends BeanScopeBase {
|
|
33
|
+
};
|
|
34
|
+
ScopeModuleAWeb = __decorate([
|
|
35
|
+
Scope()
|
|
36
|
+
], ScopeModuleAWeb);
|
|
37
|
+
export { ScopeModuleAWeb };
|
|
38
|
+
/** scope: end */
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Constructable, VonaContext } from 'vona';
|
|
2
|
+
import * as ModuleInfo from '@cabloy/module-info';
|
|
3
|
+
import Router from 'find-my-way';
|
|
4
|
+
import { BeanBase } from 'vona';
|
|
5
|
+
export declare class BeanRouter extends BeanBase {
|
|
6
|
+
registerController(moduleName: string, controller: Constructable): void;
|
|
7
|
+
register(method: Router.HTTPMethod, moduleName: ModuleInfo.IModuleInfo | string, path: string | undefined, simplify: boolean, fn: Router.Handler<Router.HTTPVersion.V1>): void;
|
|
8
|
+
unRegister(method: Router.HTTPMethod, moduleName: ModuleInfo.IModuleInfo | string, path: string | undefined, simplify: boolean): void;
|
|
9
|
+
findByPath(method: Router.HTTPMethod, moduleName: ModuleInfo.IModuleInfo | string, path: string | undefined, simplify: boolean): any;
|
|
10
|
+
private _registerControllerAction;
|
|
11
|
+
_registerComposeMiddlewares(ctx: VonaContext): (context: any, next?: any) => any;
|
|
12
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import * as ModuleInfo from '@cabloy/module-info';
|
|
8
|
+
import Router from 'find-my-way';
|
|
9
|
+
import { appMetadata, appResource, BeanBase, deepExtend } from 'vona';
|
|
10
|
+
import { Bean } from 'vona-module-a-bean';
|
|
11
|
+
import { SymbolUseOnionOptions } from 'vona-module-a-onion';
|
|
12
|
+
import { SymbolRouteHandlersArgumentsValue } from 'vona-module-a-openapi';
|
|
13
|
+
import { middlewareGuard } from "../lib/middleware/middlewareGuard.js";
|
|
14
|
+
import { middlewareInterceptor } from "../lib/middleware/middlewareInterceptor.js";
|
|
15
|
+
import { middlewarePipe } from "../lib/middleware/middlewarePipe.js";
|
|
16
|
+
import { RequestMethod, SymbolRequestMappingHandler } from "../types/request.js";
|
|
17
|
+
const SymbolRouteComposeMiddlewaresCache = Symbol('SymbolRouteComposeMiddlewaresCache');
|
|
18
|
+
let BeanRouter = class BeanRouter extends BeanBase {
|
|
19
|
+
registerController(moduleName, controller) {
|
|
20
|
+
// info
|
|
21
|
+
const info = ModuleInfo.parseInfo(moduleName);
|
|
22
|
+
// controller options
|
|
23
|
+
const beanOptions = appResource.getBean(controller);
|
|
24
|
+
if (!beanOptions)
|
|
25
|
+
return;
|
|
26
|
+
const controllerBeanFullName = beanOptions.beanFullName;
|
|
27
|
+
const controllerOptions = beanOptions.options;
|
|
28
|
+
const controllerPath = controllerOptions.path;
|
|
29
|
+
const controllerMiddlewaresOptions = appMetadata.getMetadata(SymbolUseOnionOptions, controller);
|
|
30
|
+
// descs
|
|
31
|
+
const descs = Object.getOwnPropertyDescriptors(controller.prototype);
|
|
32
|
+
for (const actionKey in descs) {
|
|
33
|
+
const desc = descs[actionKey];
|
|
34
|
+
if (['constructor'].includes(actionKey))
|
|
35
|
+
continue;
|
|
36
|
+
if (!desc.value || typeof desc.value !== 'function')
|
|
37
|
+
continue;
|
|
38
|
+
this._registerControllerAction(info, controller, controllerBeanFullName, controllerPath, controllerMiddlewaresOptions, actionKey, desc);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
register(method, moduleName, path, simplify, fn) {
|
|
42
|
+
const app = this.app;
|
|
43
|
+
const _path = app.util.combineApiPath(path, moduleName, true, simplify);
|
|
44
|
+
app.router.on(method, _path, fn);
|
|
45
|
+
}
|
|
46
|
+
unRegister(method, moduleName, path, simplify) {
|
|
47
|
+
const app = this.app;
|
|
48
|
+
const _path = app.util.combineApiPath(path, moduleName, true, simplify);
|
|
49
|
+
app.router.off(method, _path);
|
|
50
|
+
}
|
|
51
|
+
findByPath(method, moduleName, path, simplify) {
|
|
52
|
+
const app = this.app;
|
|
53
|
+
const _path = app.util.combineApiPath(path, moduleName, true, simplify);
|
|
54
|
+
return app.router.findRoute(method, _path);
|
|
55
|
+
}
|
|
56
|
+
_registerControllerAction(info, controller, controllerBeanFullName, controllerPath, controllerMiddlewaresOptions, actionKey, desc) {
|
|
57
|
+
// app
|
|
58
|
+
const app = this.app;
|
|
59
|
+
// actionPath/actionMethod
|
|
60
|
+
if (!appMetadata.hasMetadata(SymbolRequestMappingHandler, controller.prototype, actionKey))
|
|
61
|
+
return;
|
|
62
|
+
const handlerMetadata = appMetadata.getMetadata(SymbolRequestMappingHandler, controller.prototype, actionKey);
|
|
63
|
+
const actionPath = handlerMetadata.path || '';
|
|
64
|
+
const actionMethod = handlerMetadata.method || RequestMethod.GET;
|
|
65
|
+
// routePath
|
|
66
|
+
const routePath = app.util.combineApiPathControllerAndAction(info.relativeName, controllerPath, actionPath, true, true);
|
|
67
|
+
const routePathRaw = app.util.combineApiPathControllerAndActionRaw(info.relativeName, controllerPath, actionPath, true);
|
|
68
|
+
// middlewares options
|
|
69
|
+
const actionMiddlewaresOptions = appMetadata.getMetadata(SymbolUseOnionOptions, controller.prototype, actionKey);
|
|
70
|
+
// route
|
|
71
|
+
const route = {
|
|
72
|
+
meta: deepExtend({}, controllerMiddlewaresOptions, actionMiddlewaresOptions),
|
|
73
|
+
};
|
|
74
|
+
// route
|
|
75
|
+
const _route = {
|
|
76
|
+
pid: info.pid,
|
|
77
|
+
module: info.name,
|
|
78
|
+
controller,
|
|
79
|
+
actionDescriptor: desc,
|
|
80
|
+
controllerBeanFullName,
|
|
81
|
+
action: actionKey,
|
|
82
|
+
route,
|
|
83
|
+
routeMethod: actionMethod,
|
|
84
|
+
routePath,
|
|
85
|
+
routePathRaw,
|
|
86
|
+
};
|
|
87
|
+
// fn
|
|
88
|
+
const self = this;
|
|
89
|
+
const fn = function (_req, _res, params, _store, searchParams) {
|
|
90
|
+
const ctx = this;
|
|
91
|
+
ctx.route = _route;
|
|
92
|
+
ctx.request.params = params;
|
|
93
|
+
ctx.request.query = searchParams;
|
|
94
|
+
if (!_route[SymbolRouteComposeMiddlewaresCache]) {
|
|
95
|
+
_route[SymbolRouteComposeMiddlewaresCache] = self._registerComposeMiddlewares(ctx);
|
|
96
|
+
}
|
|
97
|
+
return _route[SymbolRouteComposeMiddlewaresCache](ctx);
|
|
98
|
+
};
|
|
99
|
+
// register
|
|
100
|
+
app.router.on(_route.routeMethod.toUpperCase(), _route.routePath.toString(), fn);
|
|
101
|
+
}
|
|
102
|
+
_registerComposeMiddlewares(ctx) {
|
|
103
|
+
// start
|
|
104
|
+
const fnStart = routeStartMiddleware;
|
|
105
|
+
// mid: guard/interceptor/pipes/tail
|
|
106
|
+
const fnMid = [];
|
|
107
|
+
fnMid.push(middlewareGuard);
|
|
108
|
+
fnMid.push(middlewareInterceptor);
|
|
109
|
+
fnMid.push(middlewarePipe);
|
|
110
|
+
fnMid.push(routeTailDoneMiddleware);
|
|
111
|
+
// end: controller
|
|
112
|
+
const fnEnd = classControllerMiddleware;
|
|
113
|
+
// compose
|
|
114
|
+
return this.app.bean.onion.middleware.compose(ctx, fnStart, fnMid, fnEnd);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
BeanRouter = __decorate([
|
|
118
|
+
Bean()
|
|
119
|
+
], BeanRouter);
|
|
120
|
+
export { BeanRouter };
|
|
121
|
+
function classControllerMiddleware(ctx) {
|
|
122
|
+
const beanFullName = ctx.getControllerBeanFullName();
|
|
123
|
+
const handlerName = ctx.getHandler().name;
|
|
124
|
+
const controller = ctx.app.bean._getBean(beanFullName);
|
|
125
|
+
return controller[handlerName](...(ctx[SymbolRouteHandlersArgumentsValue] || []));
|
|
126
|
+
}
|
|
127
|
+
async function routeStartMiddleware(ctx, next) {
|
|
128
|
+
// next
|
|
129
|
+
const res = await next();
|
|
130
|
+
// invoke callbackes: handle secondly
|
|
131
|
+
await ctx.commitDone();
|
|
132
|
+
// ok
|
|
133
|
+
return res;
|
|
134
|
+
}
|
|
135
|
+
async function routeTailDoneMiddleware(ctx, next) {
|
|
136
|
+
// next
|
|
137
|
+
const res = await next();
|
|
138
|
+
// invoke callbackes: handle firstly
|
|
139
|
+
await ctx.commitDone();
|
|
140
|
+
// ok
|
|
141
|
+
return res;
|
|
142
|
+
}
|
|
143
|
+
// _registerInner(route, middlewaresLocal) {
|
|
144
|
+
// // app
|
|
145
|
+
// const app = this.app;
|
|
146
|
+
// // args
|
|
147
|
+
// let args: any[] = [];
|
|
148
|
+
// // middlewares: start
|
|
149
|
+
// const fnStart = async (ctx: VonaContext, next: Next) => {
|
|
150
|
+
// // route
|
|
151
|
+
// ctx.route = route;
|
|
152
|
+
// // next
|
|
153
|
+
// const res = await next();
|
|
154
|
+
// // invoke callbackes: handle secondly
|
|
155
|
+
// await ctx.commitDone();
|
|
156
|
+
// // ok
|
|
157
|
+
// return res;
|
|
158
|
+
// };
|
|
159
|
+
// fnStart._name = 'start';
|
|
160
|
+
// args.push(fnStart);
|
|
161
|
+
// // middlewares: globals
|
|
162
|
+
// args.push(...app.bean.onion.middleware.composedOnionsGlobal);
|
|
163
|
+
// // middlewares: guard/interceptor/pipes
|
|
164
|
+
// args.push(middlewareGuard);
|
|
165
|
+
// args.push(middlewareInterceptor);
|
|
166
|
+
// args.push(middlewarePipe);
|
|
167
|
+
// // middlewares: tailDone
|
|
168
|
+
// const fnTailDone = async (ctx, next) => {
|
|
169
|
+
// // next
|
|
170
|
+
// const res = await next();
|
|
171
|
+
// // invoke callbackes: handle firstly
|
|
172
|
+
// await ctx.commitDone();
|
|
173
|
+
// // ok
|
|
174
|
+
// return res;
|
|
175
|
+
// };
|
|
176
|
+
// fnTailDone._name = 'tailDone';
|
|
177
|
+
// args.push(fnTailDone);
|
|
178
|
+
// // middlewares
|
|
179
|
+
// if (middlewaresLocal.length > 0) {
|
|
180
|
+
// args = args.concat(middlewaresLocal);
|
|
181
|
+
// }
|
|
182
|
+
// // load
|
|
183
|
+
// if (route.routeName) {
|
|
184
|
+
// app.router[route.routeMethod](route.routeName, route.routePath, ...args);
|
|
185
|
+
// } else {
|
|
186
|
+
// app.router[route.routeMethod](route.routePath, ...args);
|
|
187
|
+
// }
|
|
188
|
+
// }
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import http from 'node:http';
|
|
8
|
+
import { BeanBase, cast, compose } from 'vona';
|
|
9
|
+
import { Startup } from 'vona-module-a-startup';
|
|
10
|
+
let StartupListen = class StartupListen extends BeanBase {
|
|
11
|
+
async execute() {
|
|
12
|
+
if (!this.app.config.server.listen.disable) {
|
|
13
|
+
this.app.server = this._listen(this.app.config.server.listen.port, this.app.config.server.listen.hostname);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
_listen(port, hostname) {
|
|
17
|
+
const server = http.createServer(this._callback());
|
|
18
|
+
return server.listen(port, hostname);
|
|
19
|
+
}
|
|
20
|
+
_callback() {
|
|
21
|
+
const fn = compose(this.app.middleware);
|
|
22
|
+
if (!this.app.listenerCount('error'))
|
|
23
|
+
this.app.on('error', this.app.onerror);
|
|
24
|
+
return (req, res) => {
|
|
25
|
+
return this.app.bean.executor.newCtx(() => {
|
|
26
|
+
return cast(this.app).handleRequest(this.app.ctx, fn);
|
|
27
|
+
}, { dbInfo: { level: 0 }, innerAccess: false, req, res }); // not set instanceName
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
StartupListen = __decorate([
|
|
32
|
+
Startup({ after: true })
|
|
33
|
+
], StartupListen);
|
|
34
|
+
export { StartupListen };
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Constructable } from 'vona';
|
|
2
|
+
import type { IDecoratorControllerOptions } from '../../types/controller.ts';
|
|
3
|
+
import type { IDecoratorDtoOptions } from '../../types/dto.ts';
|
|
4
|
+
export declare function Controller<T extends IDecoratorControllerOptions>(options?: T): ClassDecorator;
|
|
5
|
+
export declare function Controller<T extends IDecoratorControllerOptions>(path?: string, options?: Omit<T, 'path'>): ClassDecorator;
|
|
6
|
+
export declare function Service(): ClassDecorator;
|
|
7
|
+
export declare function Dto<T extends IDecoratorDtoOptions<any>>(options?: T): ClassDecorator;
|
|
8
|
+
export declare function mergeActionsOpenAPIMetadata(target: Constructable): void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { appMetadata, appResource, cast, createBeanDecorator, deepExtend } from 'vona';
|
|
2
|
+
import { mergeFieldsOpenAPIMetadata, SymbolOpenApiOptions } from 'vona-module-a-openapi';
|
|
3
|
+
export function Controller(path, options) {
|
|
4
|
+
if (typeof path === 'string') {
|
|
5
|
+
options = Object.assign({}, options, { path });
|
|
6
|
+
}
|
|
7
|
+
else {
|
|
8
|
+
options = path || {};
|
|
9
|
+
}
|
|
10
|
+
return createBeanDecorator('controller', options, false, false, target => {
|
|
11
|
+
// IOpenApiOptions
|
|
12
|
+
const optionsMeta = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target);
|
|
13
|
+
for (const key of ['exclude', 'tags']) {
|
|
14
|
+
if (options[key] !== undefined)
|
|
15
|
+
optionsMeta[key] = options[key];
|
|
16
|
+
}
|
|
17
|
+
// IOpenApiOptions
|
|
18
|
+
mergeActionsOpenAPIMetadata(target);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export function Service() {
|
|
22
|
+
return createBeanDecorator('service');
|
|
23
|
+
}
|
|
24
|
+
export function Dto(options) {
|
|
25
|
+
return createBeanDecorator('dto', options, false, false, target => {
|
|
26
|
+
mergeFieldsOpenAPIMetadata(target);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export function mergeActionsOpenAPIMetadata(target) {
|
|
30
|
+
// beanOptions
|
|
31
|
+
const beanOptions = appResource.getBean(target);
|
|
32
|
+
const actions = cast(beanOptions?.options)?.actions;
|
|
33
|
+
if (!actions)
|
|
34
|
+
return;
|
|
35
|
+
for (const key in actions) {
|
|
36
|
+
const action = actions[key];
|
|
37
|
+
if (!action)
|
|
38
|
+
continue;
|
|
39
|
+
const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target.prototype, key);
|
|
40
|
+
deepExtend(options, action);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IOpenApiOptions } from 'vona-module-a-openapi';
|
|
2
|
+
import { RequestMethod } from '../../types/request.ts';
|
|
3
|
+
export interface RequestMappingMetadata {
|
|
4
|
+
path?: string;
|
|
5
|
+
method?: RequestMethod;
|
|
6
|
+
options?: IOpenApiOptions;
|
|
7
|
+
}
|
|
8
|
+
export declare function RequestMapping(metadata?: RequestMappingMetadata): MethodDecorator;
|
|
9
|
+
export declare const Web: {
|
|
10
|
+
post: (path?: IOpenApiOptions | string, options?: IOpenApiOptions) => MethodDecorator;
|
|
11
|
+
get: (path?: IOpenApiOptions | string, options?: IOpenApiOptions) => MethodDecorator;
|
|
12
|
+
delete: (path?: IOpenApiOptions | string, options?: IOpenApiOptions) => MethodDecorator;
|
|
13
|
+
put: (path?: IOpenApiOptions | string, options?: IOpenApiOptions) => MethodDecorator;
|
|
14
|
+
patch: (path?: IOpenApiOptions | string, options?: IOpenApiOptions) => MethodDecorator;
|
|
15
|
+
options: (path?: IOpenApiOptions | string, options?: IOpenApiOptions) => MethodDecorator;
|
|
16
|
+
head: (path?: IOpenApiOptions | string, options?: IOpenApiOptions) => MethodDecorator;
|
|
17
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { appMetadata } from 'vona';
|
|
2
|
+
import { SymbolOpenApiOptions } from 'vona-module-a-openapi';
|
|
3
|
+
import { RequestMethod, SymbolRequestMappingHandler } from "../../types/request.js";
|
|
4
|
+
const defaultMetadata = {
|
|
5
|
+
method: RequestMethod.GET,
|
|
6
|
+
path: '',
|
|
7
|
+
options: undefined,
|
|
8
|
+
};
|
|
9
|
+
export function RequestMapping(metadata = defaultMetadata) {
|
|
10
|
+
const path = metadata.path || '';
|
|
11
|
+
const method = metadata.method || RequestMethod.GET;
|
|
12
|
+
const options = metadata.options;
|
|
13
|
+
return (target, prop, descriptor) => {
|
|
14
|
+
appMetadata.defineMetadata(SymbolRequestMappingHandler, { path, method }, target, prop);
|
|
15
|
+
if (options) {
|
|
16
|
+
const optionsMeta = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
|
|
17
|
+
Object.assign(optionsMeta, options);
|
|
18
|
+
}
|
|
19
|
+
return descriptor;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function createMappingDecorator(method) {
|
|
23
|
+
return (path, options) => {
|
|
24
|
+
if (path && typeof path === 'object') {
|
|
25
|
+
options = path;
|
|
26
|
+
path = undefined;
|
|
27
|
+
}
|
|
28
|
+
return RequestMapping({ method, path, options });
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const Post = createMappingDecorator(RequestMethod.POST);
|
|
32
|
+
const Get = createMappingDecorator(RequestMethod.GET);
|
|
33
|
+
const Delete = createMappingDecorator(RequestMethod.DELETE);
|
|
34
|
+
const Put = createMappingDecorator(RequestMethod.PUT);
|
|
35
|
+
const Patch = createMappingDecorator(RequestMethod.PATCH);
|
|
36
|
+
const Options = createMappingDecorator(RequestMethod.OPTIONS);
|
|
37
|
+
const Head = createMappingDecorator(RequestMethod.HEAD);
|
|
38
|
+
export const Web = {
|
|
39
|
+
post: Post,
|
|
40
|
+
get: Get,
|
|
41
|
+
delete: Delete,
|
|
42
|
+
put: Put,
|
|
43
|
+
patch: Patch,
|
|
44
|
+
options: Options,
|
|
45
|
+
head: Head,
|
|
46
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// todo: 如果没有必要,就删除这里的代码
|
|
2
|
+
// import { appMetadata, MetadataKey } from 'vona';
|
|
3
|
+
// import { SymbolResponseMetadata, TypeResponseContentType } from '../../types/response.ts';
|
|
4
|
+
export {};
|
|
5
|
+
// function contentType(contentType: TypeResponseContentType): MethodDecorator {
|
|
6
|
+
// return function (target: object, prop?: MetadataKey, descriptor?: PropertyDescriptor) {
|
|
7
|
+
// const map = appMetadata.getOwnMetadataMap(false, SymbolResponseMetadata, target, prop);
|
|
8
|
+
// map.contentType = contentType;
|
|
9
|
+
// return descriptor;
|
|
10
|
+
// } as any;
|
|
11
|
+
// }
|
|
12
|
+
// export const Res = { contentType };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { VonaContext } from 'vona';
|
|
2
|
+
import type { RouteHandlerArgumentMetaDecorator, RouteHandlerArgumentType } from 'vona-module-a-openapi';
|
|
3
|
+
export declare function extractValue(ctx: VonaContext, argMeta: RouteHandlerArgumentMetaDecorator): any;
|
|
4
|
+
export declare function exchangeKeyForValue(ctx: VonaContext, type: RouteHandlerArgumentType, field: string | undefined): any;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { SymbolUploadValue } from 'vona-module-a-upload';
|
|
2
|
+
export function extractValue(ctx, argMeta) {
|
|
3
|
+
return exchangeKeyForValue(ctx, argMeta.type, argMeta.field);
|
|
4
|
+
}
|
|
5
|
+
export function exchangeKeyForValue(ctx, type, field) {
|
|
6
|
+
const req = ctx.request;
|
|
7
|
+
const res = ctx.response;
|
|
8
|
+
const modes = {
|
|
9
|
+
request: () => req,
|
|
10
|
+
response: () => res,
|
|
11
|
+
body: () => (field && req.body ? req.body[field] : req.body),
|
|
12
|
+
query: () => (field ? req.query[field] : req.query),
|
|
13
|
+
param: () => (field ? req.params[field] : req.params),
|
|
14
|
+
headers: () => (field ? req.headers[field.toLowerCase()] : req.headers),
|
|
15
|
+
host: () => {
|
|
16
|
+
const hosts = req.hosts || {};
|
|
17
|
+
return field ? hosts[field] : hosts;
|
|
18
|
+
},
|
|
19
|
+
ip: () => req.ip,
|
|
20
|
+
rawBody: () => req.rawBody,
|
|
21
|
+
user: () => ctx.app.bean.passport.getCurrentUser(),
|
|
22
|
+
fields: () => {
|
|
23
|
+
const uploadValue = ctx[SymbolUploadValue];
|
|
24
|
+
if (!uploadValue)
|
|
25
|
+
throw new Error('should use interceptor: a-upload:upload');
|
|
26
|
+
return field ? uploadValue.fields.filter(item => item.name === field).map(item => item.value) : uploadValue.fields;
|
|
27
|
+
},
|
|
28
|
+
field: () => {
|
|
29
|
+
const uploadValue = ctx[SymbolUploadValue];
|
|
30
|
+
if (!uploadValue)
|
|
31
|
+
throw new Error('should use interceptor: a-upload:upload');
|
|
32
|
+
return field ? uploadValue.fields.find(item => item.name === field)?.value : uploadValue.fields[0]?.value;
|
|
33
|
+
},
|
|
34
|
+
files: () => {
|
|
35
|
+
const uploadValue = ctx[SymbolUploadValue];
|
|
36
|
+
if (!uploadValue)
|
|
37
|
+
throw new Error('should use interceptor: a-upload:upload');
|
|
38
|
+
return field ? uploadValue.files.filter(item => item.name === field) : uploadValue.files;
|
|
39
|
+
},
|
|
40
|
+
file: () => {
|
|
41
|
+
const uploadValue = ctx[SymbolUploadValue];
|
|
42
|
+
if (!uploadValue)
|
|
43
|
+
throw new Error('should use interceptor: a-upload:upload');
|
|
44
|
+
return field ? uploadValue.files.find(item => item.name === field) : uploadValue.files[0];
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
return modes[type]?.();
|
|
48
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export async function middlewareGuard(ctx, next) {
|
|
2
|
+
// check handler
|
|
3
|
+
const handler = ctx.getHandler();
|
|
4
|
+
if (!handler)
|
|
5
|
+
return next();
|
|
6
|
+
// compose
|
|
7
|
+
const result = await ctx.app.bean.onion.guard.compose(ctx)(ctx);
|
|
8
|
+
if (result === false)
|
|
9
|
+
ctx.app.throw(403);
|
|
10
|
+
// next
|
|
11
|
+
return next();
|
|
12
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { appMetadata } from 'vona';
|
|
2
|
+
import { SymbolRouteHandlersArgumentsMeta, SymbolRouteHandlersArgumentsValue, } from 'vona-module-a-openapi';
|
|
3
|
+
import { valid } from 'vona-module-a-validation';
|
|
4
|
+
import { extractValue } from "./extractValue.js";
|
|
5
|
+
export async function middlewarePipe(ctx, next) {
|
|
6
|
+
// check handler
|
|
7
|
+
const handler = ctx.getHandler();
|
|
8
|
+
if (!handler)
|
|
9
|
+
return next();
|
|
10
|
+
// body parser
|
|
11
|
+
await ctx.app.bean._getBean('a-body.service.body').parse(true);
|
|
12
|
+
// arguments
|
|
13
|
+
ctx[SymbolRouteHandlersArgumentsValue] = await _transformArguments(ctx, ctx.getController(), handler);
|
|
14
|
+
// next
|
|
15
|
+
return next();
|
|
16
|
+
}
|
|
17
|
+
async function _transformArguments(ctx, controller, handler) {
|
|
18
|
+
const paramtypes = appMetadata.getMetadata('design:paramtypes', controller.prototype, handler.name);
|
|
19
|
+
if (!paramtypes)
|
|
20
|
+
return;
|
|
21
|
+
// meta
|
|
22
|
+
const argsMeta = appMetadata.getMetadata(SymbolRouteHandlersArgumentsMeta, controller.prototype, handler.name);
|
|
23
|
+
if (!argsMeta)
|
|
24
|
+
return;
|
|
25
|
+
// args
|
|
26
|
+
const args = Array.from({ length: paramtypes.length });
|
|
27
|
+
for (let index = args.length - 1; index >= 0; index--) {
|
|
28
|
+
const argMeta = argsMeta.find(item => item.index === index);
|
|
29
|
+
if (!argMeta)
|
|
30
|
+
continue;
|
|
31
|
+
// extractValue
|
|
32
|
+
const value = await _extractArgumentValue(ctx, argMeta);
|
|
33
|
+
// metadata
|
|
34
|
+
const metadata = {
|
|
35
|
+
type: argMeta.type,
|
|
36
|
+
field: argMeta.field,
|
|
37
|
+
metaType: paramtypes[index],
|
|
38
|
+
controller,
|
|
39
|
+
method: handler.name,
|
|
40
|
+
index: argMeta.index,
|
|
41
|
+
};
|
|
42
|
+
// transform
|
|
43
|
+
args[index] = await _transformArgument(ctx, argMeta, metadata, value);
|
|
44
|
+
}
|
|
45
|
+
return args;
|
|
46
|
+
}
|
|
47
|
+
async function _transformArgument(ctx, argMeta, metadata, value) {
|
|
48
|
+
// pipes
|
|
49
|
+
const pipes = composePipes(ctx, argMeta, (beanInstance, value, options, _next) => {
|
|
50
|
+
return beanInstance.transform(value, metadata, options);
|
|
51
|
+
});
|
|
52
|
+
if (pipes.length === 0)
|
|
53
|
+
return value;
|
|
54
|
+
// apply
|
|
55
|
+
for (const pipe of pipes) {
|
|
56
|
+
value = await pipe(value, _pipeNextDefault);
|
|
57
|
+
}
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
function _pipeNextDefault(value) {
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
async function _extractArgumentValue(ctx, argMeta) {
|
|
64
|
+
if (argMeta.extractValue) {
|
|
65
|
+
return await argMeta.extractValue(ctx, argMeta);
|
|
66
|
+
}
|
|
67
|
+
return extractValue(ctx, argMeta);
|
|
68
|
+
}
|
|
69
|
+
const SymbolCacheMiddlewaresArgument = Symbol('SymbolCacheMiddlewaresArgument');
|
|
70
|
+
function composePipes(ctx, argMeta, executeCustom) {
|
|
71
|
+
if (!ctx.app.meta[SymbolCacheMiddlewaresArgument])
|
|
72
|
+
ctx.app.meta[SymbolCacheMiddlewaresArgument] = {};
|
|
73
|
+
const __cacheMiddlewaresArgument = ctx.app.meta[SymbolCacheMiddlewaresArgument];
|
|
74
|
+
const onionPipe = ctx.app.bean.onion.pipe;
|
|
75
|
+
const beanFullName = ctx.getControllerBeanFullName();
|
|
76
|
+
const handlerName = ctx.getHandler().name;
|
|
77
|
+
const key = `${beanFullName}:${handlerName}:${argMeta.index}`;
|
|
78
|
+
if (!__cacheMiddlewaresArgument[key]) {
|
|
79
|
+
const middlewares = [];
|
|
80
|
+
// pipes: global
|
|
81
|
+
for (const item of onionPipe.onionsGlobal) {
|
|
82
|
+
middlewares.push(onionPipe._wrapOnion(item, executeCustom));
|
|
83
|
+
}
|
|
84
|
+
// pipes: route
|
|
85
|
+
const middlewaresLocal = onionPipe._collectOnionsHandler(ctx);
|
|
86
|
+
for (const item of middlewaresLocal) {
|
|
87
|
+
middlewares.push(onionPipe._wrapOnion(item, executeCustom));
|
|
88
|
+
}
|
|
89
|
+
// pipes: arguments
|
|
90
|
+
const middlewaresArgument = _collectArgumentMiddlewares(onionPipe, argMeta);
|
|
91
|
+
if (middlewaresArgument) {
|
|
92
|
+
for (const item of middlewaresArgument) {
|
|
93
|
+
middlewares.push(onionPipe._wrapOnion(item, executeCustom));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
__cacheMiddlewaresArgument[key] = middlewares;
|
|
97
|
+
}
|
|
98
|
+
return __cacheMiddlewaresArgument[key];
|
|
99
|
+
}
|
|
100
|
+
function _collectArgumentMiddlewares(onionPipe, argMeta) {
|
|
101
|
+
if (!argMeta.pipes)
|
|
102
|
+
return;
|
|
103
|
+
return argMeta.pipes.map(pipe => {
|
|
104
|
+
if (typeof pipe !== 'function') {
|
|
105
|
+
pipe = valid({ schema: pipe });
|
|
106
|
+
}
|
|
107
|
+
const { pipeName, options } = pipe();
|
|
108
|
+
const item = onionPipe.onionsNormal[pipeName];
|
|
109
|
+
if (!item)
|
|
110
|
+
throw new Error(`${onionPipe.sceneName} not found: ${pipeName}`);
|
|
111
|
+
return {
|
|
112
|
+
...item,
|
|
113
|
+
argumentPipe: {
|
|
114
|
+
options,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
});
|
|
118
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { IApiPathRecord } from '../types/controller.ts';
|
|
2
|
+
export declare function $apiPath<K extends keyof IApiPathRecord>(path: K): K;
|
|
3
|
+
export declare function $apiPathAndCombineParamsAndQuery<K extends keyof IApiPathRecord>(path: K, options?: {
|
|
4
|
+
params?: object;
|
|
5
|
+
query?: object;
|
|
6
|
+
}): string;
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IModuleMain } from 'vona';
|
|
2
|
+
import { BeanSimple } from 'vona';
|
|
3
|
+
declare const SymbolRouter: unique symbol;
|
|
4
|
+
export declare class Main extends BeanSimple implements IModuleMain {
|
|
5
|
+
private [SymbolRouter];
|
|
6
|
+
moduleLoading(): Promise<void>;
|
|
7
|
+
moduleLoaded(): Promise<void>;
|
|
8
|
+
configLoaded(_config: any): Promise<void>;
|
|
9
|
+
private _wrapOnion;
|
|
10
|
+
}
|
|
11
|
+
export {};
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import Router from 'find-my-way';
|
|
2
|
+
import { BeanSimple, compose } from 'vona';
|
|
3
|
+
import { SymbolRouterMiddleware } from 'vona-module-a-executor';
|
|
4
|
+
import { __ThisModule__ } from "./.metadata/this.js";
|
|
5
|
+
const SymbolRouter = Symbol('SymbolRouter');
|
|
6
|
+
export class Main extends BeanSimple {
|
|
7
|
+
[SymbolRouter];
|
|
8
|
+
async moduleLoading() { }
|
|
9
|
+
async moduleLoaded() {
|
|
10
|
+
const config = this.bean.scope(__ThisModule__).config;
|
|
11
|
+
const self = this;
|
|
12
|
+
// router
|
|
13
|
+
Object.defineProperty(this.app, 'router', {
|
|
14
|
+
get() {
|
|
15
|
+
if (!self[SymbolRouter]) {
|
|
16
|
+
self[SymbolRouter] = Router(config.router);
|
|
17
|
+
}
|
|
18
|
+
return self[SymbolRouter];
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
// register controllers
|
|
22
|
+
for (const controller of this.bean.onion.controller.getOnionsEnabled()) {
|
|
23
|
+
this.bean.router.registerController(controller.beanOptions.module, controller.beanOptions.beanClass);
|
|
24
|
+
}
|
|
25
|
+
// middleware: system
|
|
26
|
+
const middlewares = this.bean.onion.middlewareSystem.getOnionsEnabledWrapped(item => {
|
|
27
|
+
return this._wrapOnion(item);
|
|
28
|
+
});
|
|
29
|
+
this.app.use(compose(middlewares));
|
|
30
|
+
// middleware: router
|
|
31
|
+
this.app[SymbolRouterMiddleware] = routerMiddleware(this[SymbolRouter]);
|
|
32
|
+
this.app.use(this.app[SymbolRouterMiddleware]);
|
|
33
|
+
}
|
|
34
|
+
async configLoaded(_config) { }
|
|
35
|
+
_wrapOnion(item) {
|
|
36
|
+
const fn = (_ctx, next) => {
|
|
37
|
+
const options = item.beanOptions.options;
|
|
38
|
+
if (!this.bean.onion.checkOnionOptionsEnabled(options, this.ctx.path)) {
|
|
39
|
+
return next();
|
|
40
|
+
}
|
|
41
|
+
// execute
|
|
42
|
+
const beanFullName = item.beanOptions.beanFullName;
|
|
43
|
+
const beanInstance = this.app.bean._getBean(beanFullName);
|
|
44
|
+
if (!beanInstance) {
|
|
45
|
+
throw new Error(`middlewareSystem bean not found: ${beanFullName}`);
|
|
46
|
+
}
|
|
47
|
+
return beanInstance.execute(options, next);
|
|
48
|
+
};
|
|
49
|
+
fn._name = item.name;
|
|
50
|
+
return fn;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function routerMiddleware(router) {
|
|
54
|
+
return function (ctx) {
|
|
55
|
+
return new Promise((resolve, reject) => {
|
|
56
|
+
router.lookup(ctx.req, ctx.res, ctx, (err, result) => {
|
|
57
|
+
if (err)
|
|
58
|
+
reject(err);
|
|
59
|
+
resolve(result);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Constructable, MetadataKey } from 'vona';
|
|
2
|
+
import { BeanBase } from 'vona';
|
|
3
|
+
export declare class ServiceWeb extends BeanBase {
|
|
4
|
+
combineControllerActionApiPath(controller: Constructable, actionKey: MetadataKey, prefix?: string | boolean, simplify?: boolean): string | undefined;
|
|
5
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { appMetadata, appResource, BeanBase } from 'vona';
|
|
8
|
+
import { Service, SymbolRequestMappingHandler } from 'vona-module-a-web';
|
|
9
|
+
let ServiceWeb = class ServiceWeb extends BeanBase {
|
|
10
|
+
combineControllerActionApiPath(controller, actionKey, prefix, simplify) {
|
|
11
|
+
// beanOptions
|
|
12
|
+
const beanOptions = appResource.getBean(controller);
|
|
13
|
+
if (!beanOptions)
|
|
14
|
+
return undefined;
|
|
15
|
+
// controllerPath
|
|
16
|
+
const controllerOptions = beanOptions.options;
|
|
17
|
+
const controllerPath = controllerOptions.path;
|
|
18
|
+
// actionPath
|
|
19
|
+
const handlerMetadata = appMetadata.getMetadata(SymbolRequestMappingHandler, controller.prototype, actionKey);
|
|
20
|
+
const actionPath = handlerMetadata.path || '';
|
|
21
|
+
// combine
|
|
22
|
+
return this.app.util.combineApiPathControllerAndAction(beanOptions.module, controllerPath, actionPath, prefix, simplify);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
ServiceWeb = __decorate([
|
|
26
|
+
Service()
|
|
27
|
+
], ServiceWeb);
|
|
28
|
+
export { ServiceWeb };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { OmitNever } from 'vona';
|
|
2
|
+
import type { ServiceOnion } from 'vona-module-a-onion';
|
|
3
|
+
import type { IOnionOptionsEnable } from 'vona-module-a-onion';
|
|
4
|
+
export interface IApiPathRecordMethodMap {
|
|
5
|
+
get: IApiPathGetRecord;
|
|
6
|
+
post: IApiPathPostRecord;
|
|
7
|
+
delete: IApiPathDeleteRecord;
|
|
8
|
+
put: IApiPathPutRecord;
|
|
9
|
+
patch: IApiPathPatchRecord;
|
|
10
|
+
}
|
|
11
|
+
export interface IApiPathRecord extends IApiPathGetRecord, IApiPathPostRecord, IApiPathDeleteRecord, IApiPathPutRecord, IApiPathPatchRecord {
|
|
12
|
+
}
|
|
13
|
+
export interface IApiPathGetRecord {
|
|
14
|
+
}
|
|
15
|
+
export interface IApiPathPostRecord {
|
|
16
|
+
}
|
|
17
|
+
export interface IApiPathDeleteRecord {
|
|
18
|
+
}
|
|
19
|
+
export interface IApiPathPutRecord {
|
|
20
|
+
}
|
|
21
|
+
export interface IApiPathPatchRecord {
|
|
22
|
+
}
|
|
23
|
+
export interface IControllerRecord {
|
|
24
|
+
}
|
|
25
|
+
export interface IDecoratorControllerOptions extends IOnionOptionsEnable {
|
|
26
|
+
path?: string;
|
|
27
|
+
exclude?: boolean;
|
|
28
|
+
tags?: string[];
|
|
29
|
+
}
|
|
30
|
+
declare module 'vona-module-a-onion' {
|
|
31
|
+
interface BeanOnion {
|
|
32
|
+
controller: ServiceOnion<IDecoratorControllerOptions, keyof IControllerRecord>;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
declare module 'vona' {
|
|
36
|
+
interface ConfigOnions {
|
|
37
|
+
controller: OmitNever<IControllerRecord>;
|
|
38
|
+
}
|
|
39
|
+
interface IBeanSceneRecord {
|
|
40
|
+
controller: never;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { OmitNever } from 'vona';
|
|
2
|
+
import type { ServiceOnion } from 'vona-module-a-onion';
|
|
3
|
+
import type { TypeOpenAPIMetadata } from 'vona-module-a-openapi';
|
|
4
|
+
export interface IDtoRecord {
|
|
5
|
+
}
|
|
6
|
+
export interface IDecoratorDtoOptions<FieldsMore = never> {
|
|
7
|
+
independent?: boolean;
|
|
8
|
+
openapi?: TypeOpenAPIMetadata;
|
|
9
|
+
fieldsMore?: FieldsMore;
|
|
10
|
+
}
|
|
11
|
+
declare module 'vona-module-a-onion' {
|
|
12
|
+
interface BeanOnion {
|
|
13
|
+
dto: ServiceOnion<IDecoratorDtoOptions, keyof IDtoRecord>;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
declare module 'vona' {
|
|
17
|
+
interface ConfigOnions {
|
|
18
|
+
dto: OmitNever<IDtoRecord>;
|
|
19
|
+
}
|
|
20
|
+
interface IBeanSceneRecord {
|
|
21
|
+
dto: never;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const SymbolRequestMappingHandler: unique symbol;
|
|
2
|
+
export type TypeRequestMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'options' | 'head';
|
|
3
|
+
export declare enum RequestMethod {
|
|
4
|
+
GET = "get",
|
|
5
|
+
POST = "post",
|
|
6
|
+
PUT = "put",
|
|
7
|
+
DELETE = "delete",
|
|
8
|
+
PATCH = "patch",
|
|
9
|
+
OPTIONS = "options",
|
|
10
|
+
HEAD = "head"
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const SymbolRequestMappingHandler = Symbol('SymbolRequestMappingHandler');
|
|
2
|
+
export var RequestMethod;
|
|
3
|
+
(function (RequestMethod) {
|
|
4
|
+
RequestMethod["GET"] = "get";
|
|
5
|
+
RequestMethod["POST"] = "post";
|
|
6
|
+
RequestMethod["PUT"] = "put";
|
|
7
|
+
RequestMethod["DELETE"] = "delete";
|
|
8
|
+
RequestMethod["PATCH"] = "patch";
|
|
9
|
+
RequestMethod["OPTIONS"] = "options";
|
|
10
|
+
RequestMethod["HEAD"] = "head";
|
|
11
|
+
})(RequestMethod || (RequestMethod = {}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type Router from 'find-my-way';
|
|
2
|
+
import type { Constructable } from 'vona';
|
|
3
|
+
import type { RequestMethod } from './request.ts';
|
|
4
|
+
export interface ContextRouteMetadata {
|
|
5
|
+
meta: any;
|
|
6
|
+
}
|
|
7
|
+
export interface ContextRoute {
|
|
8
|
+
pid: string;
|
|
9
|
+
module: string;
|
|
10
|
+
controller: Constructable;
|
|
11
|
+
actionDescriptor: PropertyDescriptor;
|
|
12
|
+
controllerBeanFullName: string;
|
|
13
|
+
action: string;
|
|
14
|
+
route: ContextRouteMetadata;
|
|
15
|
+
routeMethod: RequestMethod;
|
|
16
|
+
routePath: string | RegExp;
|
|
17
|
+
routePathRaw: string | RegExp;
|
|
18
|
+
}
|
|
19
|
+
declare module 'vona' {
|
|
20
|
+
interface VonaApplication {
|
|
21
|
+
router: Router.Instance<Router.HTTPVersion.V1>;
|
|
22
|
+
}
|
|
23
|
+
interface VonaContext {
|
|
24
|
+
route: ContextRoute;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
declare module 'koa' {
|
|
28
|
+
interface Request {
|
|
29
|
+
params: {
|
|
30
|
+
[key: string]: string;
|
|
31
|
+
};
|
|
32
|
+
query: {
|
|
33
|
+
[key: string]: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ServiceOnion } from 'vona-module-a-onion';
|
|
2
|
+
export interface IServiceRecord {
|
|
3
|
+
}
|
|
4
|
+
declare module 'vona-module-a-onion' {
|
|
5
|
+
interface BeanOnion {
|
|
6
|
+
service: ServiceOnion<never, keyof IServiceRecord>;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
declare module 'vona' {
|
|
10
|
+
interface IBeanSceneRecord {
|
|
11
|
+
service: never;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
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.
|
|
4
|
+
"version": "5.0.10",
|
|
5
5
|
"title": "a-web",
|
|
6
6
|
"vonaModule": {
|
|
7
7
|
"capabilities": {
|
|
@@ -55,8 +55,12 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"find-my-way": "^9.2.0"
|
|
57
57
|
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"clean-package": "^2.2.0",
|
|
60
|
+
"rimraf": "^6.0.1"
|
|
61
|
+
},
|
|
58
62
|
"scripts": {
|
|
59
|
-
"clean": "rimraf dist tsconfig.tsbuildinfo",
|
|
60
|
-
"tsc:publish": "npm run clean && tsc"
|
|
63
|
+
"clean": "rimraf dist tsconfig.build.tsbuildinfo",
|
|
64
|
+
"tsc:publish": "npm run clean && tsc -p tsconfig.build.json"
|
|
61
65
|
}
|
|
62
66
|
}
|