vona-module-a-web 5.0.30 → 5.0.31
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/cli/filterTransform/boilerplate/{{sceneName}}.{{beanName}}.ts_ +10 -0
- package/dist/.metadata/index.d.ts +37 -8
- package/dist/bean/filterTransform.base.d.ts +8 -0
- package/dist/bean/filterTransform.dateRange.d.ts +8 -0
- package/dist/bean/pipe.filter.d.ts +17 -0
- package/dist/index.js +145 -113
- package/dist/lib/decorator/arguments.d.ts +2 -3
- package/dist/lib/decorator/filterTransform.d.ts +2 -0
- package/dist/lib/decorator/index.d.ts +1 -1
- package/dist/lib/index.d.ts +0 -1
- package/dist/types/filter.d.ts +26 -0
- package/dist/types/filterTransform.d.ts +41 -0
- package/dist/types/index.d.ts +2 -0
- package/package.json +6 -1
- package/dist/bean/pipe.query.d.ts +0 -37
- package/dist/lib/decorator/response.d.ts +0 -1
- package/dist/lib/utils.d.ts +0 -6
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IDecoratorFilterTransformOptions, IFilterTransformWhere, IPipeOptionsFilterTransformInfo } from 'vona-module-a-web';
|
|
2
|
+
import { BeanBase } from 'vona';
|
|
3
|
+
import { FilterTransform } from 'vona-module-a-web';
|
|
4
|
+
|
|
5
|
+
export interface IFilterTransformOptions<%=argv.beanNameCapitalize%> extends IDecoratorFilterTransformOptions {}
|
|
6
|
+
|
|
7
|
+
@FilterTransform<IFilterTransformOptions<%=argv.beanNameCapitalize%>>()
|
|
8
|
+
export class FilterTransform<%=argv.beanNameCapitalize%> extends BeanBase implements IFilterTransformWhere {
|
|
9
|
+
async where(_info: IPipeOptionsFilterTransformInfo, _options: IFilterTransformOptions<%=argv.beanNameCapitalize%>): Promise<any | undefined> {}
|
|
10
|
+
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/** pipe: begin */
|
|
2
|
-
export * from '../bean/pipe.
|
|
2
|
+
export * from '../bean/pipe.filter.ts';
|
|
3
3
|
export * from '../bean/pipe.valid.ts';
|
|
4
|
-
import type {
|
|
4
|
+
import type { IPipeOptionsFilter } from '../bean/pipe.filter.ts';
|
|
5
5
|
import type { IPipeOptionsValid } from '../bean/pipe.valid.ts';
|
|
6
6
|
import 'vona-module-a-aspect';
|
|
7
7
|
declare module 'vona-module-a-aspect' {
|
|
8
8
|
interface IPipeRecordLocal {
|
|
9
|
-
'a-web:
|
|
9
|
+
'a-web:filter': IPipeOptionsFilter;
|
|
10
10
|
'a-web:valid': IPipeOptionsValid;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
declare module 'vona-module-a-web' {
|
|
14
|
-
interface
|
|
14
|
+
interface PipeFilter {
|
|
15
15
|
}
|
|
16
|
-
interface
|
|
17
|
-
get $beanFullName(): 'a-web.pipe.
|
|
18
|
-
get $onionName(): 'a-web:
|
|
19
|
-
get $onionOptions():
|
|
16
|
+
interface PipeFilter {
|
|
17
|
+
get $beanFullName(): 'a-web.pipe.filter';
|
|
18
|
+
get $onionName(): 'a-web:filter';
|
|
19
|
+
get $onionOptions(): IPipeOptionsFilter;
|
|
20
20
|
}
|
|
21
21
|
interface PipeValid {
|
|
22
22
|
}
|
|
@@ -95,6 +95,35 @@ declare module 'vona-module-a-web' {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
/** startup: end */
|
|
98
|
+
/** filterTransform: begin */
|
|
99
|
+
export * from '../bean/filterTransform.base.ts';
|
|
100
|
+
export * from '../bean/filterTransform.dateRange.ts';
|
|
101
|
+
import type { IFilterTransformOptionsBase } from '../bean/filterTransform.base.ts';
|
|
102
|
+
import type { IFilterTransformOptionsDateRange } from '../bean/filterTransform.dateRange.ts';
|
|
103
|
+
import 'vona-module-a-web';
|
|
104
|
+
declare module 'vona-module-a-web' {
|
|
105
|
+
interface IFilterTransformRecord {
|
|
106
|
+
'a-web:base': IFilterTransformOptionsBase;
|
|
107
|
+
'a-web:dateRange': IFilterTransformOptionsDateRange;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
declare module 'vona-module-a-web' {
|
|
111
|
+
interface FilterTransformBase {
|
|
112
|
+
}
|
|
113
|
+
interface FilterTransformBase {
|
|
114
|
+
get $beanFullName(): 'a-web.filterTransform.base';
|
|
115
|
+
get $onionName(): 'a-web:base';
|
|
116
|
+
get $onionOptions(): IFilterTransformOptionsBase;
|
|
117
|
+
}
|
|
118
|
+
interface FilterTransformDateRange {
|
|
119
|
+
}
|
|
120
|
+
interface FilterTransformDateRange {
|
|
121
|
+
get $beanFullName(): 'a-web.filterTransform.dateRange';
|
|
122
|
+
get $onionName(): 'a-web:dateRange';
|
|
123
|
+
get $onionOptions(): IFilterTransformOptionsDateRange;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** filterTransform: end */
|
|
98
127
|
/** config: begin */
|
|
99
128
|
export * from '../config/config.ts';
|
|
100
129
|
import type { config } from '../config/config.ts';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { IDecoratorFilterTransformOptions, IFilterTransformWhere, IPipeOptionsFilterTransformInfo } from '../types/filterTransform.ts';
|
|
2
|
+
import { BeanBase } from 'vona';
|
|
3
|
+
export interface IFilterTransformOptionsBase extends IDecoratorFilterTransformOptions {
|
|
4
|
+
test: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare class FilterTransformBase extends BeanBase implements IFilterTransformWhere {
|
|
7
|
+
where(info: IPipeOptionsFilterTransformInfo, _options: IFilterTransformOptionsBase): Promise<any | undefined>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { IDecoratorFilterTransformOptions, IFilterTransformWhere, IPipeOptionsFilterTransformInfo } from '../types/filterTransform.ts';
|
|
2
|
+
import { BeanBase } from 'vona';
|
|
3
|
+
export interface IFilterTransformOptionsDateRange extends IDecoratorFilterTransformOptions {
|
|
4
|
+
separator: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class FilterTransformDateRange extends BeanBase implements IFilterTransformWhere {
|
|
7
|
+
where(info: IPipeOptionsFilterTransformInfo, options: IFilterTransformOptionsDateRange): Promise<any | undefined>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IDecoratorPipeOptions, IDecoratorPipeOptionsArgument, IPipeTransform } from 'vona-module-a-aspect';
|
|
2
|
+
import type { RouteHandlerArgumentMeta } from 'vona-module-a-openapi';
|
|
3
|
+
import type { ValidatorOptions } from 'vona-module-a-validation';
|
|
4
|
+
import { BeanBase } from 'vona';
|
|
5
|
+
export type TypePipeFilterData = unknown;
|
|
6
|
+
export type TypePipeFilterResult = TypePipeFilterData;
|
|
7
|
+
export interface IPipeOptionsFilter extends IDecoratorPipeOptions, IDecoratorPipeOptionsArgument, ValidatorOptions {
|
|
8
|
+
}
|
|
9
|
+
export declare class PipeFilter extends BeanBase implements IPipeTransform<TypePipeFilterData, TypePipeFilterResult> {
|
|
10
|
+
transform(value: TypePipeFilterData, metadata: RouteHandlerArgumentMeta, options: IPipeOptionsFilter): Promise<TypePipeFilterResult>;
|
|
11
|
+
private _transform;
|
|
12
|
+
private _transformSystem;
|
|
13
|
+
private _transformOrders;
|
|
14
|
+
private _transformField;
|
|
15
|
+
private _transformFields;
|
|
16
|
+
}
|
|
17
|
+
export declare const ArgFilterPro: (options?: Partial<IPipeOptionsFilter> | undefined) => any;
|
package/dist/index.js
CHANGED
|
@@ -1,44 +1,45 @@
|
|
|
1
|
-
import { BeanInfo, BeanBase, cast, appMetadata, appResource, deepExtend, compose, BeanSimple, BeanScopeBase
|
|
2
|
-
import { isNil,
|
|
1
|
+
import { BeanInfo, BeanBase, cast, beanFullNameFromOnionName, appMetadata, appResource, deepExtend, compose, createBeanDecorator, BeanSimple, BeanScopeBase } from 'vona';
|
|
2
|
+
import { isNil, isNilOrEmptyString } from '@cabloy/utils';
|
|
3
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';
|
|
7
7
|
import { SymbolUseOnionOptions } from 'vona-module-a-onion';
|
|
8
|
-
import { SymbolRouteHandlersArgumentsValue, SymbolRouteHandlersArgumentsMeta, makeSchemaLikes, $schema, mergeFieldsOpenapiMetadata } from 'vona-module-a-
|
|
8
|
+
import { SymbolRouteHandlersArgumentsValue, SymbolRouteHandlersArgumentsMeta, makeSchemaLikes, $schema, SymbolOpenApiOptions, mergeFieldsOpenapiMetadata } from 'vona-module-a-openapiutils';
|
|
9
9
|
import { SymbolUploadValue } from 'vona-module-a-upload';
|
|
10
10
|
import http from 'node:http';
|
|
11
11
|
import { Startup } from 'vona-module-a-startup';
|
|
12
|
+
import { DateTime } from 'luxon';
|
|
13
|
+
import 'vona-module-a-web';
|
|
12
14
|
import Router from 'find-my-way';
|
|
13
15
|
import { SymbolRouterMiddleware } from 'vona-module-a-executor';
|
|
14
16
|
import { z } from 'zod';
|
|
15
|
-
import { SymbolOpenApiOptions } from 'vona-module-a-openapiutils';
|
|
16
17
|
|
|
17
|
-
var _dec$
|
|
18
|
+
var _dec$7, _dec2$7, _class$7;
|
|
18
19
|
const __FieldsSystem = ['columns', 'where', 'orders', 'pageNo', 'pageSize'];
|
|
19
|
-
let
|
|
20
|
+
let PipeFilter = (_dec$7 = Pipe({
|
|
20
21
|
// ValidatorOptions
|
|
21
22
|
disableErrorMessages: false,
|
|
22
23
|
errorHttpStatusCode: 400,
|
|
23
24
|
loose: false,
|
|
24
25
|
strict: false
|
|
25
|
-
}), _dec2$
|
|
26
|
+
}), _dec2$7 = BeanInfo({
|
|
26
27
|
module: "a-web"
|
|
27
|
-
}), _dec$
|
|
28
|
+
}), _dec$7(_class$7 = _dec2$7(_class$7 = class PipeFilter extends BeanBase {
|
|
28
29
|
async transform(value, metadata, options) {
|
|
29
|
-
if (!options.schema) throw new Error(`should specify the schema of
|
|
30
|
+
if (!options.schema) throw new Error(`should specify the schema of pipeFilter: ${metadata.controller.name}.${metadata.method}#${metadata.index}`);
|
|
30
31
|
// validateSchema
|
|
31
32
|
value = await this.bean.validator.validateSchema(options.schema, value, options, metadata.field);
|
|
32
33
|
// transform
|
|
33
|
-
value = this._transform(value, options);
|
|
34
|
+
value = await this._transform(value, options);
|
|
34
35
|
// ok
|
|
35
36
|
return value;
|
|
36
37
|
}
|
|
37
|
-
_transform(value, options) {
|
|
38
|
+
async _transform(value, options) {
|
|
38
39
|
// 1. system: columns/where/orders/pageNo/pageSize
|
|
39
40
|
const params = this._transformSystem(value);
|
|
40
41
|
// 2. fields
|
|
41
|
-
this._transformFields(params, value, options);
|
|
42
|
+
await this._transformFields(params, value, options);
|
|
42
43
|
// 3. system: orders
|
|
43
44
|
this._transformOrders(params, options);
|
|
44
45
|
// ok
|
|
@@ -76,41 +77,43 @@ let PipeQuery = (_dec$5 = Pipe({
|
|
|
76
77
|
if (!params.orders) return;
|
|
77
78
|
// openapi
|
|
78
79
|
const openapi = ZodMetadata.getOpenapiMetadata(options.schema);
|
|
79
|
-
const table = openapi?.
|
|
80
|
+
const table = openapi?.filter?.table;
|
|
80
81
|
// loop
|
|
81
82
|
for (const order of params.orders) {
|
|
82
83
|
const field = order[0];
|
|
83
84
|
if (field.includes('.')) continue;
|
|
84
85
|
let tableCurrent = table;
|
|
85
86
|
let fieldCurrent = field;
|
|
86
|
-
const fieldSchema = ZodMetadata.
|
|
87
|
+
const fieldSchema = ZodMetadata.getFieldSchema(options.schema, field);
|
|
87
88
|
if (fieldSchema) {
|
|
88
89
|
const openapi = ZodMetadata.getOpenapiMetadata(fieldSchema);
|
|
89
|
-
if (openapi?.
|
|
90
|
-
tableCurrent = openapi?.
|
|
90
|
+
if (openapi?.filter?.table) {
|
|
91
|
+
tableCurrent = openapi?.filter?.table;
|
|
91
92
|
}
|
|
92
|
-
if (openapi?.
|
|
93
|
-
fieldCurrent = openapi?.
|
|
93
|
+
if (openapi?.filter?.originalName) {
|
|
94
|
+
fieldCurrent = openapi?.filter?.originalName;
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
cast(order)[0] = tableCurrent ? `${tableCurrent}.${fieldCurrent}` : fieldCurrent;
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
|
-
_transformField(key, fieldValue, params, value, options) {
|
|
100
|
+
async _transformField(key, fieldValue, params, value, options) {
|
|
101
|
+
if (isNilOrEmptyString(fieldValue)) return;
|
|
100
102
|
if (__FieldsSystem.includes(key)) return;
|
|
101
|
-
const fieldSchema = ZodMetadata.
|
|
103
|
+
const fieldSchema = ZodMetadata.getFieldSchema(options.schema, key);
|
|
102
104
|
if (!fieldSchema) return;
|
|
105
|
+
const fieldSchemaInner = ZodMetadata.unwrapChained(fieldSchema);
|
|
103
106
|
// openapi
|
|
104
107
|
const openapi = ZodMetadata.getOpenapiMetadata(fieldSchema);
|
|
105
108
|
// name
|
|
106
|
-
const originalName = openapi?.
|
|
109
|
+
const originalName = openapi?.filter?.originalName ?? key;
|
|
107
110
|
let fullName;
|
|
108
111
|
// joins
|
|
109
112
|
let joinInfo;
|
|
110
|
-
if (openapi?.
|
|
111
|
-
const joinType = openapi.
|
|
112
|
-
const joinTable = openapi.
|
|
113
|
-
const joinOn = openapi.
|
|
113
|
+
if (openapi?.filter?.joinOn) {
|
|
114
|
+
const joinType = openapi.filter.joinType ?? 'innerJoin';
|
|
115
|
+
const joinTable = openapi.filter.table;
|
|
116
|
+
const joinOn = openapi.filter.joinOn;
|
|
114
117
|
joinInfo = [joinType, joinTable, joinOn];
|
|
115
118
|
fullName = `${joinTable}.${originalName}`;
|
|
116
119
|
} else {
|
|
@@ -118,8 +121,19 @@ let PipeQuery = (_dec$5 = Pipe({
|
|
|
118
121
|
}
|
|
119
122
|
// check where
|
|
120
123
|
if (Object.prototype.hasOwnProperty.call(params.where, fullName)) return;
|
|
121
|
-
//
|
|
122
|
-
const
|
|
124
|
+
// filter transform
|
|
125
|
+
const [transformName, transformOptions] = openapi?.filter?.transform ?? ['a-web:base', undefined];
|
|
126
|
+
const transformOptions2 = this.bean.onion.filterTransform.getOnionOptionsDynamic(transformName, transformOptions);
|
|
127
|
+
// execute
|
|
128
|
+
const beanFullName = beanFullNameFromOnionName(transformName, 'filterTransform');
|
|
129
|
+
const beanInstance = this.bean._getBean(beanFullName);
|
|
130
|
+
if (!beanInstance) {
|
|
131
|
+
throw new Error(`filterTransform bean not found: ${beanFullName}`);
|
|
132
|
+
}
|
|
133
|
+
if (!beanInstance.where) {
|
|
134
|
+
throw new Error(`filterTransform.where not found: ${beanFullName}`);
|
|
135
|
+
}
|
|
136
|
+
const info = {
|
|
123
137
|
params,
|
|
124
138
|
query: value,
|
|
125
139
|
options,
|
|
@@ -127,82 +141,42 @@ let PipeQuery = (_dec$5 = Pipe({
|
|
|
127
141
|
fullName,
|
|
128
142
|
key,
|
|
129
143
|
value: fieldValue,
|
|
144
|
+
type: fieldSchemaInner.type,
|
|
130
145
|
schema: fieldSchema,
|
|
131
146
|
openapi
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (resTransform
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (
|
|
139
|
-
params.joins.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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_';
|
|
147
|
+
};
|
|
148
|
+
const resTransform = await beanInstance.where(info, transformOptions2);
|
|
149
|
+
if (resTransform !== undefined) {
|
|
150
|
+
// where
|
|
151
|
+
params.where[fullName] = resTransform;
|
|
152
|
+
// join
|
|
153
|
+
if (joinInfo) {
|
|
154
|
+
if (!params.joins) params.joins = [];
|
|
155
|
+
if (params.joins.findIndex(item => item[1] === joinInfo.joinTable) === -1) {
|
|
156
|
+
params.joins.push(joinInfo);
|
|
157
|
+
}
|
|
152
158
|
}
|
|
153
159
|
}
|
|
154
|
-
if (op === '_eq_') {
|
|
155
|
-
params.where[fullName] = fieldValue;
|
|
156
|
-
} else {
|
|
157
|
-
params.where[fullName] = {
|
|
158
|
-
[op]: fieldValue
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
160
|
}
|
|
162
|
-
_transformFields(params, value, options) {
|
|
161
|
+
async _transformFields(params, value, options) {
|
|
163
162
|
// loop
|
|
164
163
|
for (const key in value) {
|
|
165
|
-
this._transformField(key, value[key], params, value, options);
|
|
164
|
+
await this._transformField(key, value[key], params, value, options);
|
|
166
165
|
}
|
|
167
|
-
// custom transform
|
|
168
|
-
this._performTransformFn(options, {
|
|
169
|
-
params,
|
|
170
|
-
query: value,
|
|
171
|
-
options
|
|
172
|
-
});
|
|
173
166
|
}
|
|
174
|
-
|
|
175
|
-
|
|
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);
|
|
182
|
-
} else {
|
|
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);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}) || _class$5) || _class$5);
|
|
194
|
-
const ArgQueryPro$1 = createArgumentPipe('a-web:query');
|
|
167
|
+
}) || _class$7) || _class$7);
|
|
168
|
+
const ArgFilterPro = createArgumentPipe('a-web:filter');
|
|
195
169
|
|
|
196
|
-
var _dec$
|
|
197
|
-
let PipeValid = (_dec$
|
|
170
|
+
var _dec$6, _dec2$6, _class$6;
|
|
171
|
+
let PipeValid = (_dec$6 = Pipe({
|
|
198
172
|
// ValidatorOptions
|
|
199
173
|
disableErrorMessages: false,
|
|
200
174
|
errorHttpStatusCode: 400,
|
|
201
175
|
loose: false,
|
|
202
176
|
strict: false
|
|
203
|
-
}), _dec2$
|
|
177
|
+
}), _dec2$6 = BeanInfo({
|
|
204
178
|
module: "a-web"
|
|
205
|
-
}), _dec$
|
|
179
|
+
}), _dec$6(_class$6 = _dec2$6(_class$6 = class PipeValid extends BeanBase {
|
|
206
180
|
async transform(value, metadata, options) {
|
|
207
181
|
if (options.schema) {
|
|
208
182
|
// validateSchema
|
|
@@ -210,7 +184,7 @@ let PipeValid = (_dec$4 = Pipe({
|
|
|
210
184
|
}
|
|
211
185
|
return value;
|
|
212
186
|
}
|
|
213
|
-
}) || _class$
|
|
187
|
+
}) || _class$6) || _class$6);
|
|
214
188
|
const ArgValid = createArgumentPipe('a-web:valid');
|
|
215
189
|
|
|
216
190
|
async function middlewareGuard(ctx, next) {
|
|
@@ -399,11 +373,11 @@ const SymbolRequestMappingHandler = Symbol('SymbolRequestMappingHandler');
|
|
|
399
373
|
// HEAD = 'head',
|
|
400
374
|
// }
|
|
401
375
|
|
|
402
|
-
var _dec$
|
|
376
|
+
var _dec$5, _dec2$5, _class$5;
|
|
403
377
|
const SymbolRouteComposeMiddlewaresCache = Symbol('SymbolRouteComposeMiddlewaresCache');
|
|
404
|
-
let BeanRouter = (_dec$
|
|
378
|
+
let BeanRouter = (_dec$5 = Bean(), _dec2$5 = BeanInfo({
|
|
405
379
|
module: "a-web"
|
|
406
|
-
}), _dec$
|
|
380
|
+
}), _dec$5(_class$5 = _dec2$5(_class$5 = class BeanRouter extends BeanBase {
|
|
407
381
|
registerController(moduleName, controller) {
|
|
408
382
|
// info
|
|
409
383
|
const info = ModuleInfo.parseInfo(moduleName);
|
|
@@ -503,7 +477,7 @@ let BeanRouter = (_dec$3 = Bean(), _dec2$3 = BeanInfo({
|
|
|
503
477
|
// compose
|
|
504
478
|
return this.app.bean.onion.middleware.compose(ctx, fnStart, fnMid, fnEnd);
|
|
505
479
|
}
|
|
506
|
-
}) || _class$
|
|
480
|
+
}) || _class$5) || _class$5);
|
|
507
481
|
function classControllerMiddleware(ctx) {
|
|
508
482
|
const handlerName = ctx.getHandlerName();
|
|
509
483
|
const controller = ctx.getControllerBean();
|
|
@@ -577,10 +551,10 @@ async function routeTailDoneMiddleware(ctx, next) {
|
|
|
577
551
|
// }
|
|
578
552
|
// }
|
|
579
553
|
|
|
580
|
-
var _dec$
|
|
581
|
-
let ServiceWeb = (_dec$
|
|
554
|
+
var _dec$4, _dec2$4, _class$4;
|
|
555
|
+
let ServiceWeb = (_dec$4 = Service(), _dec2$4 = BeanInfo({
|
|
582
556
|
module: "a-web"
|
|
583
|
-
}), _dec$
|
|
557
|
+
}), _dec$4(_class$4 = _dec2$4(_class$4 = class ServiceWeb extends BeanBase {
|
|
584
558
|
combineControllerActionApiPath(controller, actionKey, prefix, simplify) {
|
|
585
559
|
// beanOptions
|
|
586
560
|
const beanOptions = appResource.getBean(controller);
|
|
@@ -594,14 +568,14 @@ let ServiceWeb = (_dec$2 = Service(), _dec2$2 = BeanInfo({
|
|
|
594
568
|
// combine
|
|
595
569
|
return this.app.util.combineApiPathControllerAndAction(beanOptions.module, controllerPath, actionPath, prefix, simplify);
|
|
596
570
|
}
|
|
597
|
-
}) || _class$
|
|
571
|
+
}) || _class$4) || _class$4);
|
|
598
572
|
|
|
599
|
-
var _dec$
|
|
600
|
-
let StartupListen = (_dec$
|
|
573
|
+
var _dec$3, _dec2$3, _class$3;
|
|
574
|
+
let StartupListen = (_dec$3 = Startup({
|
|
601
575
|
after: true
|
|
602
|
-
}), _dec2$
|
|
576
|
+
}), _dec2$3 = BeanInfo({
|
|
603
577
|
module: "a-web"
|
|
604
|
-
}), _dec$
|
|
578
|
+
}), _dec$3(_class$3 = _dec2$3(_class$3 = class StartupListen extends BeanBase {
|
|
605
579
|
async execute() {
|
|
606
580
|
if (!this.app.config.server.listen.disable) {
|
|
607
581
|
this.app.server = this._listen(this.app.config.server.listen.port, this.app.config.server.listen.hostname);
|
|
@@ -627,6 +601,72 @@ let StartupListen = (_dec$1 = Startup({
|
|
|
627
601
|
}); // not set instanceName
|
|
628
602
|
};
|
|
629
603
|
}
|
|
604
|
+
}) || _class$3) || _class$3);
|
|
605
|
+
|
|
606
|
+
function FilterTransform(options) {
|
|
607
|
+
return createBeanDecorator('filterTransform', options);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
var _dec$2, _dec2$2, _class$2;
|
|
611
|
+
let FilterTransformBase = (_dec$2 = FilterTransform(), _dec2$2 = BeanInfo({
|
|
612
|
+
module: "a-web"
|
|
613
|
+
}), _dec$2(_class$2 = _dec2$2(_class$2 = class FilterTransformBase extends BeanBase {
|
|
614
|
+
async where(info, _options) {
|
|
615
|
+
const {
|
|
616
|
+
value,
|
|
617
|
+
type,
|
|
618
|
+
openapi
|
|
619
|
+
} = info;
|
|
620
|
+
let op = openapi?.filter?.op;
|
|
621
|
+
if (!op) {
|
|
622
|
+
if (type === 'string') {
|
|
623
|
+
op = '_includesI_';
|
|
624
|
+
} else {
|
|
625
|
+
op = '_eq_';
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
let where;
|
|
629
|
+
if (op === '_eq_') {
|
|
630
|
+
where = value;
|
|
631
|
+
} else {
|
|
632
|
+
where = {
|
|
633
|
+
[op]: value
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
return where;
|
|
637
|
+
}
|
|
638
|
+
}) || _class$2) || _class$2);
|
|
639
|
+
|
|
640
|
+
var _dec$1, _dec2$1, _class$1;
|
|
641
|
+
let FilterTransformDateRange = (_dec$1 = FilterTransform({
|
|
642
|
+
separator: '~'
|
|
643
|
+
}), _dec2$1 = BeanInfo({
|
|
644
|
+
module: "a-web"
|
|
645
|
+
}), _dec$1(_class$1 = _dec2$1(_class$1 = class FilterTransformDateRange extends BeanBase {
|
|
646
|
+
async where(info, options) {
|
|
647
|
+
const {
|
|
648
|
+
value
|
|
649
|
+
} = info;
|
|
650
|
+
const [dateStartStr, dateEndStr] = value.split(options.separator);
|
|
651
|
+
if (!dateStartStr && !dateEndStr) return;
|
|
652
|
+
//
|
|
653
|
+
const where = {};
|
|
654
|
+
if (dateStartStr) {
|
|
655
|
+
const dateStart = DateTime.fromISO(dateStartStr, {
|
|
656
|
+
zone: this.ctx.tz
|
|
657
|
+
});
|
|
658
|
+
where._gte_ = dateStart.toJSDate();
|
|
659
|
+
}
|
|
660
|
+
if (dateEndStr) {
|
|
661
|
+
const dateEnd = DateTime.fromISO(dateEndStr, {
|
|
662
|
+
zone: this.ctx.tz
|
|
663
|
+
}).plus({
|
|
664
|
+
day: 1
|
|
665
|
+
});
|
|
666
|
+
where._lt_ = dateEnd.toJSDate();
|
|
667
|
+
}
|
|
668
|
+
return where;
|
|
669
|
+
}
|
|
630
670
|
}) || _class$1) || _class$1);
|
|
631
671
|
|
|
632
672
|
function config(_app) {
|
|
@@ -766,13 +806,12 @@ function File(property, ...schemaLikes) {
|
|
|
766
806
|
function User(...schemaLikes) {
|
|
767
807
|
return createPipesArgumentDecorator('user')(undefined, ...schemaLikes);
|
|
768
808
|
}
|
|
769
|
-
function
|
|
809
|
+
function ArgFilter(schemaLike) {
|
|
770
810
|
return function (target, prop, index) {
|
|
771
811
|
const schema = $schema(schemaLike);
|
|
772
|
-
setArgumentPipe('a-web:
|
|
812
|
+
setArgumentPipe('a-web:filter', {
|
|
773
813
|
type: 'query',
|
|
774
|
-
schema
|
|
775
|
-
transformFn
|
|
814
|
+
schema
|
|
776
815
|
}, target, prop, index);
|
|
777
816
|
};
|
|
778
817
|
}
|
|
@@ -786,7 +825,7 @@ const Arg = {
|
|
|
786
825
|
files: Files,
|
|
787
826
|
file: File,
|
|
788
827
|
user: User,
|
|
789
|
-
|
|
828
|
+
filter: ArgFilter
|
|
790
829
|
};
|
|
791
830
|
|
|
792
831
|
function Controller(path, options) {
|
|
@@ -879,11 +918,4 @@ const Web = {
|
|
|
879
918
|
head: Head
|
|
880
919
|
};
|
|
881
920
|
|
|
882
|
-
|
|
883
|
-
return path;
|
|
884
|
-
}
|
|
885
|
-
function $apiPathAndCombineParamsAndQuery(path, options) {
|
|
886
|
-
return combineParamsAndQuery(path, options);
|
|
887
|
-
}
|
|
888
|
-
|
|
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 };
|
|
921
|
+
export { Arg, ArgFilterPro, ArgValid, BeanRouter, Controller, Dto, FilterTransform, FilterTransformBase, FilterTransformDateRange, Main, PipeFilter, PipeValid, RequestMapping, ScopeModuleAWeb, ServiceWeb, StartupListen, SymbolRequestMappingHandler, Web, config, createPipesArgumentDecorator, mergeActionsOpenapiMetadata };
|
|
@@ -1,7 +1,6 @@
|
|
|
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';
|
|
5
4
|
declare function Param(): ParameterDecorator;
|
|
6
5
|
declare function Param(...schemaLikes: SchemaLike[]): ParameterDecorator;
|
|
7
6
|
declare function Param(property: string, ...schemaLikes: SchemaLike[]): ParameterDecorator;
|
|
@@ -27,7 +26,7 @@ declare function File(): ParameterDecorator;
|
|
|
27
26
|
declare function File(...schemaLikes: SchemaLike[]): ParameterDecorator;
|
|
28
27
|
declare function File(property: string, ...schemaLikes: SchemaLike[]): ParameterDecorator;
|
|
29
28
|
declare function User(...schemaLikes: SchemaLike[]): ParameterDecorator;
|
|
30
|
-
declare function
|
|
29
|
+
declare function ArgFilter(schemaLike: z.ZodType | Constructable): any;
|
|
31
30
|
export declare const Arg: {
|
|
32
31
|
param: typeof Param;
|
|
33
32
|
query: typeof Query;
|
|
@@ -38,6 +37,6 @@ export declare const Arg: {
|
|
|
38
37
|
files: typeof Files;
|
|
39
38
|
file: typeof File;
|
|
40
39
|
user: typeof User;
|
|
41
|
-
|
|
40
|
+
filter: typeof ArgFilter;
|
|
42
41
|
};
|
|
43
42
|
export {};
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { IModelSelectParamsJoinType, ITableRecord, TypeOpsNormal } from 'vona-module-a-orm';
|
|
2
|
+
import type { IDecoratorFilterTransformOptions, IFilterTransformRecord } from './filterTransform.ts';
|
|
3
|
+
export interface ISchemaObjectExtensionFieldFilterJoin {
|
|
4
|
+
type?: IModelSelectParamsJoinType;
|
|
5
|
+
table: keyof ITableRecord;
|
|
6
|
+
on: [string, string];
|
|
7
|
+
}
|
|
8
|
+
export interface ISchemaObjectExtensionFieldFilterCapabilities {
|
|
9
|
+
where?: boolean;
|
|
10
|
+
order?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export type TypeSchemaObjectExtensionFieldFilterTransform = [keyof IFilterTransformRecord, IDecoratorFilterTransformOptions | undefined];
|
|
13
|
+
export interface ISchemaObjectExtensionFieldFilter {
|
|
14
|
+
capabilities?: ISchemaObjectExtensionFieldFilterCapabilities;
|
|
15
|
+
table?: keyof ITableRecord;
|
|
16
|
+
joinType?: IModelSelectParamsJoinType;
|
|
17
|
+
joinOn?: [string, string];
|
|
18
|
+
originalName?: string;
|
|
19
|
+
op?: TypeOpsNormal;
|
|
20
|
+
transform?: TypeSchemaObjectExtensionFieldFilterTransform;
|
|
21
|
+
}
|
|
22
|
+
declare module 'vona-module-a-openapi' {
|
|
23
|
+
interface ISchemaObjectExtensionField {
|
|
24
|
+
filter?: ISchemaObjectExtensionFieldFilter;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { OmitNever } from 'vona';
|
|
2
|
+
import type { ServiceOnion } from 'vona-module-a-onion';
|
|
3
|
+
import type { ISchemaObjectExtensionField } from 'vona-module-a-openapi';
|
|
4
|
+
import type { IQueryParams } from 'vona-module-a-orm';
|
|
5
|
+
import type z from 'zod';
|
|
6
|
+
import type { IPipeOptionsFilter } from '../bean/pipe.filter.ts';
|
|
7
|
+
export type TypeQueryParamsPatch = IQueryParams & {
|
|
8
|
+
where: {};
|
|
9
|
+
};
|
|
10
|
+
export interface IPipeOptionsFilterTransformInfo {
|
|
11
|
+
params: TypeQueryParamsPatch;
|
|
12
|
+
query: any;
|
|
13
|
+
options: IPipeOptionsFilter;
|
|
14
|
+
originalName: string;
|
|
15
|
+
fullName: string;
|
|
16
|
+
key?: string;
|
|
17
|
+
value?: any;
|
|
18
|
+
type?: string;
|
|
19
|
+
schema?: z.ZodType;
|
|
20
|
+
openapi?: ISchemaObjectExtensionField;
|
|
21
|
+
}
|
|
22
|
+
export interface IFilterTransformRecord {
|
|
23
|
+
}
|
|
24
|
+
export interface IFilterTransformWhere {
|
|
25
|
+
where(info: IPipeOptionsFilterTransformInfo, options: IDecoratorFilterTransformOptions): Promise<boolean>;
|
|
26
|
+
}
|
|
27
|
+
export interface IDecoratorFilterTransformOptions {
|
|
28
|
+
}
|
|
29
|
+
declare module 'vona-module-a-onion' {
|
|
30
|
+
interface BeanOnion {
|
|
31
|
+
filterTransform: ServiceOnion<IFilterTransformRecord>;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
declare module 'vona' {
|
|
35
|
+
interface ConfigOnions {
|
|
36
|
+
filterTransform: OmitNever<IFilterTransformRecord>;
|
|
37
|
+
}
|
|
38
|
+
interface IBeanSceneRecord {
|
|
39
|
+
filterTransform: never;
|
|
40
|
+
}
|
|
41
|
+
}
|
package/dist/types/index.d.ts
CHANGED
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.31",
|
|
5
5
|
"title": "a-web",
|
|
6
6
|
"vonaModule": {
|
|
7
7
|
"capabilities": {
|
|
@@ -22,6 +22,11 @@
|
|
|
22
22
|
"optionsGlobalInterfaceFrom": "vona-module-a-web",
|
|
23
23
|
"boilerplate": "cli/controller/boilerplate",
|
|
24
24
|
"metadataCustom": "cli/controller/metadata/generate.ts"
|
|
25
|
+
},
|
|
26
|
+
"filterTransform": {
|
|
27
|
+
"optionsGlobalInterfaceName": "IDecoratorFilterTransformOptions",
|
|
28
|
+
"optionsGlobalInterfaceFrom": "vona-module-a-web",
|
|
29
|
+
"boilerplate": "cli/filterTransform/boilerplate"
|
|
25
30
|
}
|
|
26
31
|
}
|
|
27
32
|
},
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { VonaContext } from 'vona';
|
|
2
|
-
import type { IDecoratorPipeOptions, IDecoratorPipeOptionsArgument, IPipeTransform } from 'vona-module-a-aspect';
|
|
3
|
-
import type { ISchemaObjectExtensionField, RouteHandlerArgumentMeta } from 'vona-module-a-openapi';
|
|
4
|
-
import type { IQueryParams } from 'vona-module-a-orm';
|
|
5
|
-
import type { ValidatorOptions } from 'vona-module-a-validation';
|
|
6
|
-
import type z from 'zod';
|
|
7
|
-
import { BeanBase } from 'vona';
|
|
8
|
-
export type TypePipeQueryData = unknown;
|
|
9
|
-
export type TypePipeQueryResult = TypePipeQueryData;
|
|
10
|
-
export interface IPipeOptionsQuery extends IDecoratorPipeOptions, IDecoratorPipeOptionsArgument, ValidatorOptions {
|
|
11
|
-
transformFn?: TypePipeOptionsQueryTransform | string;
|
|
12
|
-
}
|
|
13
|
-
export type TypeQueryParamsPatch = IQueryParams & {
|
|
14
|
-
where: {};
|
|
15
|
-
};
|
|
16
|
-
export interface IPipeOptionsQueryTransformInfo {
|
|
17
|
-
params: TypeQueryParamsPatch;
|
|
18
|
-
query: any;
|
|
19
|
-
options: IPipeOptionsQuery;
|
|
20
|
-
originalName: string;
|
|
21
|
-
fullName: string;
|
|
22
|
-
key?: string;
|
|
23
|
-
value?: any;
|
|
24
|
-
schema?: z.ZodType;
|
|
25
|
-
openapi?: ISchemaObjectExtensionField;
|
|
26
|
-
}
|
|
27
|
-
export type TypePipeOptionsQueryTransform = (ctx: VonaContext, info: IPipeOptionsQueryTransformInfo) => boolean | undefined;
|
|
28
|
-
export declare class PipeQuery extends BeanBase implements IPipeTransform<TypePipeQueryData, TypePipeQueryResult> {
|
|
29
|
-
transform(value: TypePipeQueryData, metadata: RouteHandlerArgumentMeta, options: IPipeOptionsQuery): Promise<TypePipeQueryResult>;
|
|
30
|
-
private _transform;
|
|
31
|
-
private _transformSystem;
|
|
32
|
-
private _transformOrders;
|
|
33
|
-
private _transformField;
|
|
34
|
-
private _transformFields;
|
|
35
|
-
private _performTransformFn;
|
|
36
|
-
}
|
|
37
|
-
export declare const ArgQueryPro: (options?: Partial<IPipeOptionsQuery> | undefined) => any;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/lib/utils.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
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;
|