vona-module-a-web 5.0.22 → 5.0.24
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.
|
@@ -5,25 +5,33 @@ import type { IQueryParams } from 'vona-module-a-orm';
|
|
|
5
5
|
import type { ValidatorOptions } from 'vona-module-a-validation';
|
|
6
6
|
import type z from 'zod';
|
|
7
7
|
import { BeanBase } from 'vona';
|
|
8
|
+
export type TypePipeQueryData = unknown;
|
|
9
|
+
export type TypePipeQueryResult = TypePipeQueryData;
|
|
8
10
|
export interface IPipeOptionsQuery extends IDecoratorPipeOptions, IDecoratorPipeOptionsArgument, ValidatorOptions {
|
|
9
|
-
|
|
11
|
+
transformFn?: TypePipeOptionsQueryTransform | string;
|
|
10
12
|
}
|
|
13
|
+
export type TypeQueryParamsPatch = IQueryParams & {
|
|
14
|
+
where: {};
|
|
15
|
+
};
|
|
11
16
|
export interface IPipeOptionsQueryTransformInfo {
|
|
12
|
-
params:
|
|
17
|
+
params: TypeQueryParamsPatch;
|
|
13
18
|
query: any;
|
|
14
19
|
options: IPipeOptionsQuery;
|
|
15
20
|
originalName: string;
|
|
16
21
|
fullName: string;
|
|
17
|
-
key
|
|
18
|
-
value
|
|
19
|
-
schema
|
|
22
|
+
key?: string;
|
|
23
|
+
value?: any;
|
|
24
|
+
schema?: z.ZodType;
|
|
20
25
|
openapi?: ISchemaObjectExtensionField;
|
|
21
26
|
}
|
|
22
27
|
export type TypePipeOptionsQueryTransform = (ctx: VonaContext, info: IPipeOptionsQueryTransformInfo) => boolean | undefined;
|
|
23
|
-
export declare class PipeQuery extends BeanBase implements IPipeTransform<
|
|
24
|
-
transform(value:
|
|
28
|
+
export declare class PipeQuery extends BeanBase implements IPipeTransform<TypePipeQueryData, TypePipeQueryResult> {
|
|
29
|
+
transform(value: TypePipeQueryData, metadata: RouteHandlerArgumentMeta, options: IPipeOptionsQuery): Promise<TypePipeQueryResult>;
|
|
25
30
|
private _transform;
|
|
26
31
|
private _transformSystem;
|
|
32
|
+
private _transformOrders;
|
|
33
|
+
private _transformField;
|
|
27
34
|
private _transformFields;
|
|
35
|
+
private _performTransformFn;
|
|
28
36
|
}
|
|
29
|
-
export declare const
|
|
37
|
+
export declare const ArgQueryPro: (options?: Partial<IPipeOptionsQuery> | undefined) => any;
|
|
@@ -2,9 +2,11 @@ import type { IDecoratorPipeOptions, IDecoratorPipeOptionsArgument, IPipeTransfo
|
|
|
2
2
|
import type { RouteHandlerArgumentMeta } from 'vona-module-a-openapi';
|
|
3
3
|
import type { ValidatorOptions } from 'vona-module-a-validation';
|
|
4
4
|
import { BeanBase } from 'vona';
|
|
5
|
+
export type TypePipeValidData = unknown;
|
|
6
|
+
export type TypePipeValidResult = TypePipeValidData;
|
|
5
7
|
export interface IPipeOptionsValid extends IDecoratorPipeOptions, IDecoratorPipeOptionsArgument, ValidatorOptions {
|
|
6
8
|
}
|
|
7
|
-
export declare class PipeValid extends BeanBase implements IPipeTransform<
|
|
8
|
-
transform(value:
|
|
9
|
+
export declare class PipeValid extends BeanBase implements IPipeTransform<TypePipeValidData, TypePipeValidResult> {
|
|
10
|
+
transform(value: TypePipeValidData, metadata: RouteHandlerArgumentMeta, options: IPipeOptionsValid): Promise<TypePipeValidResult>;
|
|
9
11
|
}
|
|
10
12
|
export declare const ArgValid: (options?: Partial<IPipeOptionsValid> | undefined) => any;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BeanInfo, BeanBase, cast, appMetadata, appResource, deepExtend, compose, BeanSimple, BeanScopeBase, createBeanDecorator } from 'vona';
|
|
2
2
|
import { isNil, combineParamsAndQuery } from '@cabloy/utils';
|
|
3
|
-
import { ZodMetadata } from '@cabloy/zod-
|
|
3
|
+
import { ZodMetadata } from '@cabloy/zod-openapi';
|
|
4
4
|
import { Pipe, createArgumentPipe, setArgumentPipe } from 'vona-module-a-aspect';
|
|
5
5
|
import * as ModuleInfo from '@cabloy/module-info';
|
|
6
6
|
import { Bean, Service, Scope } from 'vona-module-a-bean';
|
|
@@ -19,8 +19,8 @@ const __FieldsSystem = ['columns', 'where', 'orders', 'pageNo', 'pageSize'];
|
|
|
19
19
|
let PipeQuery = (_dec$5 = Pipe({
|
|
20
20
|
// ValidatorOptions
|
|
21
21
|
disableErrorMessages: false,
|
|
22
|
-
errorHttpStatusCode:
|
|
23
|
-
|
|
22
|
+
errorHttpStatusCode: 400,
|
|
23
|
+
loose: false,
|
|
24
24
|
strict: false
|
|
25
25
|
}), _dec2$5 = BeanInfo({
|
|
26
26
|
module: "a-web"
|
|
@@ -38,7 +38,11 @@ let PipeQuery = (_dec$5 = Pipe({
|
|
|
38
38
|
// 1. system: columns/where/orders/pageNo/pageSize
|
|
39
39
|
const params = this._transformSystem(value);
|
|
40
40
|
// 2. fields
|
|
41
|
-
|
|
41
|
+
this._transformFields(params, value, options);
|
|
42
|
+
// 3. system: orders
|
|
43
|
+
this._transformOrders(params, options);
|
|
44
|
+
// ok
|
|
45
|
+
return params;
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
// system: columns/where/orders/pageNo/pageSize
|
|
@@ -68,75 +72,133 @@ let PipeQuery = (_dec$5 = Pipe({
|
|
|
68
72
|
// ok
|
|
69
73
|
return params;
|
|
70
74
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
let
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
75
|
+
_transformOrders(params, options) {
|
|
76
|
+
if (!params.orders) return;
|
|
77
|
+
// openapi
|
|
78
|
+
const openapi = ZodMetadata.getOpenapiMetadata(options.schema);
|
|
79
|
+
const table = openapi?.query?.table;
|
|
80
|
+
// loop
|
|
81
|
+
for (const order of params.orders) {
|
|
82
|
+
const field = order[0];
|
|
83
|
+
if (field.includes('.')) continue;
|
|
84
|
+
let tableCurrent = table;
|
|
85
|
+
let fieldCurrent = field;
|
|
86
|
+
const fieldSchema = ZodMetadata.unwrapChained(ZodMetadata.getFieldSchema(options.schema, field));
|
|
87
|
+
if (fieldSchema) {
|
|
88
|
+
const openapi = ZodMetadata.getOpenapiMetadata(fieldSchema);
|
|
89
|
+
if (openapi?.query?.table) {
|
|
90
|
+
tableCurrent = openapi?.query?.table;
|
|
91
|
+
}
|
|
92
|
+
if (openapi?.query?.originalName) {
|
|
93
|
+
fieldCurrent = openapi?.query?.originalName;
|
|
89
94
|
}
|
|
90
|
-
fullName = `${joinTable}.${originalName}`;
|
|
91
|
-
} else {
|
|
92
|
-
fullName = originalName;
|
|
93
95
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
96
|
+
cast(order)[0] = tableCurrent ? `${tableCurrent}.${fieldCurrent}` : fieldCurrent;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
_transformField(key, fieldValue, params, value, options) {
|
|
100
|
+
if (__FieldsSystem.includes(key)) return;
|
|
101
|
+
const fieldSchema = ZodMetadata.unwrapChained(ZodMetadata.getFieldSchema(options.schema, key));
|
|
102
|
+
if (!fieldSchema) return;
|
|
103
|
+
// openapi
|
|
104
|
+
const openapi = ZodMetadata.getOpenapiMetadata(fieldSchema);
|
|
105
|
+
// name
|
|
106
|
+
const originalName = openapi?.query?.originalName ?? key;
|
|
107
|
+
let fullName;
|
|
108
|
+
// joins
|
|
109
|
+
let joinInfo;
|
|
110
|
+
if (openapi?.query?.joinOn) {
|
|
111
|
+
const joinType = openapi.query.joinType ?? 'innerJoin';
|
|
112
|
+
const joinTable = openapi.query.table;
|
|
113
|
+
const joinOn = openapi.query.joinOn;
|
|
114
|
+
joinInfo = [joinType, joinTable, joinOn];
|
|
115
|
+
fullName = `${joinTable}.${originalName}`;
|
|
116
|
+
} else {
|
|
117
|
+
fullName = originalName;
|
|
118
|
+
}
|
|
119
|
+
// check where
|
|
120
|
+
if (Object.prototype.hasOwnProperty.call(params.where, fullName)) return;
|
|
121
|
+
// custom transform
|
|
122
|
+
const resTransform = this._performTransformFn(options, {
|
|
123
|
+
params,
|
|
124
|
+
query: value,
|
|
125
|
+
options,
|
|
126
|
+
originalName,
|
|
127
|
+
fullName,
|
|
128
|
+
key,
|
|
129
|
+
value: fieldValue,
|
|
130
|
+
schema: fieldSchema,
|
|
131
|
+
openapi
|
|
132
|
+
});
|
|
133
|
+
// res: ignore
|
|
134
|
+
if (resTransform === false) return;
|
|
135
|
+
// join
|
|
136
|
+
if (joinInfo) {
|
|
137
|
+
if (!params.joins) params.joins = [];
|
|
138
|
+
if (params.joins.findIndex(item => item[1] === joinInfo.joinTable) === -1) {
|
|
139
|
+
params.joins.push(joinInfo);
|
|
110
140
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
141
|
+
}
|
|
142
|
+
// res: done
|
|
143
|
+
if (resTransform === true) return;
|
|
144
|
+
// default transform
|
|
145
|
+
let op = openapi?.query?.op;
|
|
146
|
+
if (!op) {
|
|
147
|
+
const typeName = fieldSchema.type;
|
|
148
|
+
if (typeName === 'string') {
|
|
149
|
+
op = '_includesI_';
|
|
150
|
+
} else {
|
|
151
|
+
op = '_eq_';
|
|
120
152
|
}
|
|
121
|
-
|
|
122
|
-
|
|
153
|
+
}
|
|
154
|
+
if (op === '_eq_') {
|
|
155
|
+
params.where[fullName] = fieldValue;
|
|
156
|
+
} else {
|
|
157
|
+
params.where[fullName] = {
|
|
158
|
+
[op]: fieldValue
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
_transformFields(params, value, options) {
|
|
163
|
+
// loop
|
|
164
|
+
for (const key in value) {
|
|
165
|
+
this._transformField(key, value[key], params, value, options);
|
|
166
|
+
}
|
|
167
|
+
// custom transform
|
|
168
|
+
this._performTransformFn(options, {
|
|
169
|
+
params,
|
|
170
|
+
query: value,
|
|
171
|
+
options
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
_performTransformFn(options, info) {
|
|
175
|
+
if (options.transformFn) {
|
|
176
|
+
if (typeof options.transformFn === 'string') {
|
|
177
|
+
const controller = this.ctx.getControllerBean();
|
|
178
|
+
if (!controller[options.transformFn]) {
|
|
179
|
+
throw new Error(`transformFn not found: ${this.ctx.getControllerBeanFullName()}`);
|
|
180
|
+
}
|
|
181
|
+
return controller[options.transformFn](info);
|
|
123
182
|
} else {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
183
|
+
return options.transformFn(this.ctx, info);
|
|
184
|
+
}
|
|
185
|
+
} else {
|
|
186
|
+
const controller = this.ctx.getControllerBean();
|
|
187
|
+
const transformFn = `${String(this.ctx.getHandlerName())}QueryTransform`;
|
|
188
|
+
if (controller[transformFn]) {
|
|
189
|
+
return controller[transformFn](info);
|
|
127
190
|
}
|
|
128
191
|
}
|
|
129
|
-
return params;
|
|
130
192
|
}
|
|
131
193
|
}) || _class$5) || _class$5);
|
|
132
|
-
const
|
|
194
|
+
const ArgQueryPro$1 = createArgumentPipe('a-web:query');
|
|
133
195
|
|
|
134
196
|
var _dec$4, _dec2$4, _class$4;
|
|
135
197
|
let PipeValid = (_dec$4 = Pipe({
|
|
136
198
|
// ValidatorOptions
|
|
137
199
|
disableErrorMessages: false,
|
|
138
|
-
errorHttpStatusCode:
|
|
139
|
-
|
|
200
|
+
errorHttpStatusCode: 400,
|
|
201
|
+
loose: false,
|
|
140
202
|
strict: false
|
|
141
203
|
}), _dec2$4 = BeanInfo({
|
|
142
204
|
module: "a-web"
|
|
@@ -219,8 +281,6 @@ async function middlewarePipe(ctx, next) {
|
|
|
219
281
|
// check handler
|
|
220
282
|
const handler = ctx.getHandler();
|
|
221
283
|
if (!handler) return next();
|
|
222
|
-
// body parser
|
|
223
|
-
await ctx.app.bean._getBean('a-body.service.body').parse(true);
|
|
224
284
|
// arguments
|
|
225
285
|
ctx[SymbolRouteHandlersArgumentsValue] = await _transformArguments(ctx, ctx.getController(), handler);
|
|
226
286
|
// next
|
|
@@ -260,6 +320,7 @@ async function _transformArguments(ctx, controller, handler) {
|
|
|
260
320
|
async function _transformArgument(ctx, argMeta, metadata, value) {
|
|
261
321
|
// pipes
|
|
262
322
|
const pipes = composePipes(ctx, argMeta, (beanInstance, value, options, _next) => {
|
|
323
|
+
if (!isNil(options.argIndex) && argMeta.index !== options.argIndex) return value;
|
|
263
324
|
return beanInstance.transform(value, metadata, options);
|
|
264
325
|
});
|
|
265
326
|
if (pipes.length === 0) return value;
|
|
@@ -444,24 +505,23 @@ let BeanRouter = (_dec$3 = Bean(), _dec2$3 = BeanInfo({
|
|
|
444
505
|
}
|
|
445
506
|
}) || _class$3) || _class$3);
|
|
446
507
|
function classControllerMiddleware(ctx) {
|
|
447
|
-
const
|
|
448
|
-
const
|
|
449
|
-
const controller = ctx.app.bean._getBean(beanFullName);
|
|
508
|
+
const handlerName = ctx.getHandlerName();
|
|
509
|
+
const controller = ctx.getControllerBean();
|
|
450
510
|
return controller[handlerName](...(ctx[SymbolRouteHandlersArgumentsValue] || []));
|
|
451
511
|
}
|
|
452
512
|
async function routeStartMiddleware(ctx, next) {
|
|
453
513
|
// next
|
|
454
514
|
const res = await next();
|
|
455
|
-
// invoke
|
|
456
|
-
await ctx.
|
|
515
|
+
// invoke callbacks: handle secondly
|
|
516
|
+
await ctx.commitsDone();
|
|
457
517
|
// ok
|
|
458
518
|
return res;
|
|
459
519
|
}
|
|
460
520
|
async function routeTailDoneMiddleware(ctx, next) {
|
|
461
521
|
// next
|
|
462
522
|
const res = await next();
|
|
463
|
-
// invoke
|
|
464
|
-
await ctx.
|
|
523
|
+
// invoke callbacks: handle firstly
|
|
524
|
+
await ctx.commitsDone();
|
|
465
525
|
// ok
|
|
466
526
|
return res;
|
|
467
527
|
}
|
|
@@ -478,7 +538,7 @@ async function routeTailDoneMiddleware(ctx, next) {
|
|
|
478
538
|
// // next
|
|
479
539
|
// const res = await next();
|
|
480
540
|
// // invoke callbackes: handle secondly
|
|
481
|
-
// await ctx.
|
|
541
|
+
// await ctx.commitsDone();
|
|
482
542
|
// // ok
|
|
483
543
|
// return res;
|
|
484
544
|
// };
|
|
@@ -497,7 +557,7 @@ async function routeTailDoneMiddleware(ctx, next) {
|
|
|
497
557
|
// // next
|
|
498
558
|
// const res = await next();
|
|
499
559
|
// // invoke callbackes: handle firstly
|
|
500
|
-
// await ctx.
|
|
560
|
+
// await ctx.commitsDone();
|
|
501
561
|
// // ok
|
|
502
562
|
// return res;
|
|
503
563
|
// };
|
|
@@ -706,12 +766,13 @@ function File(property, ...schemaLikes) {
|
|
|
706
766
|
function User(...schemaLikes) {
|
|
707
767
|
return createPipesArgumentDecorator('user')(undefined, ...schemaLikes);
|
|
708
768
|
}
|
|
709
|
-
function ArgQueryPro(schemaLike) {
|
|
769
|
+
function ArgQueryPro(schemaLike, transformFn) {
|
|
710
770
|
return function (target, prop, index) {
|
|
711
771
|
const schema = $schema(schemaLike);
|
|
712
772
|
setArgumentPipe('a-web:query', {
|
|
713
773
|
type: 'query',
|
|
714
|
-
schema
|
|
774
|
+
schema,
|
|
775
|
+
transformFn
|
|
715
776
|
}, target, prop, index);
|
|
716
777
|
};
|
|
717
778
|
}
|
|
@@ -825,4 +886,4 @@ function $apiPathAndCombineParamsAndQuery(path, options) {
|
|
|
825
886
|
return combineParamsAndQuery(path, options);
|
|
826
887
|
}
|
|
827
888
|
|
|
828
|
-
export { $apiPath, $apiPathAndCombineParamsAndQuery, Arg,
|
|
889
|
+
export { $apiPath, $apiPathAndCombineParamsAndQuery, Arg, ArgQueryPro$1 as ArgQueryPro, ArgValid, BeanRouter, Controller, Dto, Main, PipeQuery, PipeValid, RequestMapping, ScopeModuleAWeb, ServiceWeb, StartupListen, SymbolRequestMappingHandler, Web, config, createPipesArgumentDecorator, mergeActionsOpenapiMetadata };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Constructable } from 'vona';
|
|
2
2
|
import type { SchemaLike } from 'vona-module-a-openapiutils';
|
|
3
3
|
import type z from 'zod';
|
|
4
|
+
import type { TypePipeOptionsQueryTransform } from '../../bean/pipe.query.ts';
|
|
4
5
|
declare function Param(): ParameterDecorator;
|
|
5
6
|
declare function Param(...schemaLikes: SchemaLike[]): ParameterDecorator;
|
|
6
7
|
declare function Param(property: string, ...schemaLikes: SchemaLike[]): ParameterDecorator;
|
|
@@ -26,7 +27,7 @@ declare function File(): ParameterDecorator;
|
|
|
26
27
|
declare function File(...schemaLikes: SchemaLike[]): ParameterDecorator;
|
|
27
28
|
declare function File(property: string, ...schemaLikes: SchemaLike[]): ParameterDecorator;
|
|
28
29
|
declare function User(...schemaLikes: SchemaLike[]): ParameterDecorator;
|
|
29
|
-
declare function ArgQueryPro(schemaLike: z.
|
|
30
|
+
declare function ArgQueryPro(schemaLike: z.ZodType | Constructable, transformFn?: TypePipeOptionsQueryTransform | string): any;
|
|
30
31
|
export declare const Arg: {
|
|
31
32
|
param: typeof Param;
|
|
32
33
|
query: typeof Query;
|
|
@@ -28,7 +28,7 @@ export interface IDecoratorControllerOptions extends TypeOnionOptionsEnableSimpl
|
|
|
28
28
|
}
|
|
29
29
|
declare module 'vona-module-a-onion' {
|
|
30
30
|
interface BeanOnion {
|
|
31
|
-
controller: ServiceOnion<
|
|
31
|
+
controller: ServiceOnion<IControllerRecord>;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
declare module 'vona' {
|
package/dist/types/dto.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { OmitNever } from 'vona';
|
|
2
2
|
import type { ServiceOnion } from 'vona-module-a-onion';
|
|
3
3
|
import type { TypeOpenapiMetadata } from 'vona-module-a-openapi';
|
|
4
|
+
import type { SchemaLike } from 'vona-module-a-openapiutils';
|
|
4
5
|
import type { SymbolKeyFieldsMore } from 'vona-module-a-orm';
|
|
5
6
|
export interface IDtoRecord {
|
|
6
7
|
}
|
|
@@ -8,10 +9,11 @@ export interface IDecoratorDtoOptions<FieldsMore = never> {
|
|
|
8
9
|
[SymbolKeyFieldsMore]?: FieldsMore;
|
|
9
10
|
independent?: boolean;
|
|
10
11
|
openapi?: TypeOpenapiMetadata;
|
|
12
|
+
pipes?: SchemaLike | SchemaLike[];
|
|
11
13
|
}
|
|
12
14
|
declare module 'vona-module-a-onion' {
|
|
13
15
|
interface BeanOnion {
|
|
14
|
-
dto: ServiceOnion<
|
|
16
|
+
dto: ServiceOnion<IDtoRecord>;
|
|
15
17
|
}
|
|
16
18
|
}
|
|
17
19
|
declare module 'vona' {
|