vona-module-a-web 5.0.29 → 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.
@@ -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.query.ts';
2
+ export * from '../bean/pipe.filter.ts';
3
3
  export * from '../bean/pipe.valid.ts';
4
- import type { IPipeOptionsQuery } from '../bean/pipe.query.ts';
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:query': IPipeOptionsQuery;
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 PipeQuery {
14
+ interface PipeFilter {
15
15
  }
16
- interface PipeQuery {
17
- get $beanFullName(): 'a-web.pipe.query';
18
- get $onionName(): 'a-web:query';
19
- get $onionOptions(): IPipeOptionsQuery;
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, createBeanDecorator } from 'vona';
2
- import { isNil, combineParamsAndQuery } from '@cabloy/utils';
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-openapi';
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$5, _dec2$5, _class$5;
18
+ var _dec$7, _dec2$7, _class$7;
18
19
  const __FieldsSystem = ['columns', 'where', 'orders', 'pageNo', 'pageSize'];
19
- let PipeQuery = (_dec$5 = Pipe({
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$5 = BeanInfo({
26
+ }), _dec2$7 = BeanInfo({
26
27
  module: "a-web"
27
- }), _dec$5(_class$5 = _dec2$5(_class$5 = class PipeQuery extends BeanBase {
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 pipeQuery: ${metadata.controller.name}.${metadata.method}#${metadata.index}`);
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?.query?.table;
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.unwrapChained(ZodMetadata.getFieldSchema(options.schema, field));
87
+ const fieldSchema = ZodMetadata.getFieldSchema(options.schema, field);
87
88
  if (fieldSchema) {
88
89
  const openapi = ZodMetadata.getOpenapiMetadata(fieldSchema);
89
- if (openapi?.query?.table) {
90
- tableCurrent = openapi?.query?.table;
90
+ if (openapi?.filter?.table) {
91
+ tableCurrent = openapi?.filter?.table;
91
92
  }
92
- if (openapi?.query?.originalName) {
93
- fieldCurrent = openapi?.query?.originalName;
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.unwrapChained(ZodMetadata.getFieldSchema(options.schema, key));
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?.query?.originalName ?? key;
109
+ const originalName = openapi?.filter?.originalName ?? key;
107
110
  let fullName;
108
111
  // joins
109
112
  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;
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
- // custom transform
122
- const resTransform = this._performTransformFn(options, {
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
- // 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);
140
- }
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_';
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
- _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);
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$4, _dec2$4, _class$4;
197
- let PipeValid = (_dec$4 = Pipe({
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$4 = BeanInfo({
177
+ }), _dec2$6 = BeanInfo({
204
178
  module: "a-web"
205
- }), _dec$4(_class$4 = _dec2$4(_class$4 = class PipeValid extends BeanBase {
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$4) || _class$4);
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$3, _dec2$3, _class$3;
376
+ var _dec$5, _dec2$5, _class$5;
403
377
  const SymbolRouteComposeMiddlewaresCache = Symbol('SymbolRouteComposeMiddlewaresCache');
404
- let BeanRouter = (_dec$3 = Bean(), _dec2$3 = BeanInfo({
378
+ let BeanRouter = (_dec$5 = Bean(), _dec2$5 = BeanInfo({
405
379
  module: "a-web"
406
- }), _dec$3(_class$3 = _dec2$3(_class$3 = class BeanRouter extends BeanBase {
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$3) || _class$3);
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$2, _dec2$2, _class$2;
581
- let ServiceWeb = (_dec$2 = Service(), _dec2$2 = BeanInfo({
554
+ var _dec$4, _dec2$4, _class$4;
555
+ let ServiceWeb = (_dec$4 = Service(), _dec2$4 = BeanInfo({
582
556
  module: "a-web"
583
- }), _dec$2(_class$2 = _dec2$2(_class$2 = class ServiceWeb extends BeanBase {
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$2) || _class$2);
571
+ }) || _class$4) || _class$4);
598
572
 
599
- var _dec$1, _dec2$1, _class$1;
600
- let StartupListen = (_dec$1 = Startup({
573
+ var _dec$3, _dec2$3, _class$3;
574
+ let StartupListen = (_dec$3 = Startup({
601
575
  after: true
602
- }), _dec2$1 = BeanInfo({
576
+ }), _dec2$3 = BeanInfo({
603
577
  module: "a-web"
604
- }), _dec$1(_class$1 = _dec2$1(_class$1 = class StartupListen extends BeanBase {
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 ArgQueryPro(schemaLike, transformFn) {
809
+ function ArgFilter(schemaLike) {
770
810
  return function (target, prop, index) {
771
811
  const schema = $schema(schemaLike);
772
- setArgumentPipe('a-web:query', {
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
- queryPro: ArgQueryPro
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
- function $apiPath(path) {
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 ArgQueryPro(schemaLike: z.ZodType | Constructable, transformFn?: TypePipeOptionsQueryTransform | string): any;
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
- queryPro: typeof ArgQueryPro;
40
+ filter: typeof ArgFilter;
42
41
  };
43
42
  export {};
@@ -0,0 +1,2 @@
1
+ import type { IDecoratorFilterTransformOptions } from '../../types/filterTransform.ts';
2
+ export declare function FilterTransform<T extends IDecoratorFilterTransformOptions>(options?: T): ClassDecorator;
@@ -1,5 +1,5 @@
1
1
  export * from './arguments.ts';
2
2
  export * from './bean.ts';
3
+ export * from './filterTransform.ts';
3
4
  export * from './pipesArgument.ts';
4
5
  export * from './request.ts';
5
- export * from './response.ts';
@@ -1,2 +1 @@
1
1
  export * from './decorator/index.ts';
2
- export * from './utils.ts';
@@ -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
+ }
@@ -1,5 +1,7 @@
1
1
  export * from './controller.ts';
2
2
  export * from './dto.ts';
3
+ export * from './filter.ts';
4
+ export * from './filterTransform.ts';
3
5
  export * from './request.ts';
4
6
  export * from './response.ts';
5
7
  export * from './router.ts';
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.29",
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
  },
@@ -41,9 +46,9 @@
41
46
  "./package.json": "./package.json"
42
47
  },
43
48
  "files": [
49
+ "assets",
44
50
  "cli",
45
- "dist",
46
- "static"
51
+ "dist"
47
52
  ],
48
53
  "dependencies": {
49
54
  "find-my-way": "^9.2.0"
@@ -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 {};
@@ -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;