vona-module-test-vona 5.0.49 → 5.0.51

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.
@@ -9,15 +9,16 @@ export declare class ServicePost extends BeanBase {
9
9
  };
10
10
  with?: Record<string, unknown>;
11
11
  distinct?: boolean | keyof import("vona-module-test-vona").EntityPost | (keyof import("vona-module-test-vona").EntityPost)[] | undefined;
12
- columns?: "iid" | "id" | "createdAt" | "updatedAt" | "deleted" | "*" | "title" | "userId" | "stars" | ("iid" | "id" | "createdAt" | "updatedAt" | "deleted" | "*" | "title" | "userId" | "stars")[] | undefined;
12
+ columns?: "title" | "id" | "iid" | "createdAt" | "updatedAt" | "deleted" | "*" | "userId" | "stars" | ("title" | "id" | "iid" | "createdAt" | "updatedAt" | "deleted" | "*" | "userId" | "stars")[] | undefined;
13
13
  where?: import("vona-module-a-orm").TypeModelWhereInner<{
14
- "testVonaPostContent.content": string;
15
- "testVonaPostContent.postId": TableIdentity;
16
- "testVonaPostContent.id": TableIdentity;
17
- "testVonaPostContent.createdAt": Date;
18
- "testVonaPostContent.updatedAt": Date;
19
- "testVonaPostContent.deleted": boolean;
20
- "testVonaPostContent.iid": number;
14
+ "testVonaUser.name": string;
15
+ "testVonaUser.age"?: number | undefined;
16
+ "testVonaUser.scores"?: number | undefined;
17
+ "testVonaUser.id": TableIdentity;
18
+ "testVonaUser.createdAt": Date;
19
+ "testVonaUser.updatedAt": Date;
20
+ "testVonaUser.deleted": boolean;
21
+ "testVonaUser.iid": number;
21
22
  } & {
22
23
  "testVonaPost.title": string;
23
24
  "testVonaPost.userId": TableIdentity;
@@ -28,14 +29,13 @@ export declare class ServicePost extends BeanBase {
28
29
  "testVonaPost.deleted": boolean;
29
30
  "testVonaPost.iid": number;
30
31
  } & import("vona-module-test-vona").EntityPost> | import("vona-module-a-orm").TypeModelWhereInner<{
31
- "testVonaUser.name": string;
32
- "testVonaUser.age"?: number | undefined;
33
- "testVonaUser.scores"?: number | undefined;
34
- "testVonaUser.id": TableIdentity;
35
- "testVonaUser.createdAt": Date;
36
- "testVonaUser.updatedAt": Date;
37
- "testVonaUser.deleted": boolean;
38
- "testVonaUser.iid": number;
32
+ "testVonaPostContent.content": string;
33
+ "testVonaPostContent.postId": TableIdentity;
34
+ "testVonaPostContent.id": TableIdentity;
35
+ "testVonaPostContent.createdAt": Date;
36
+ "testVonaPostContent.updatedAt": Date;
37
+ "testVonaPostContent.deleted": boolean;
38
+ "testVonaPostContent.iid": number;
39
39
  } & {
40
40
  "testVonaPost.title": string;
41
41
  "testVonaPost.userId": TableIdentity;
@@ -50,12 +50,12 @@ export declare class ServicePost extends BeanBase {
50
50
  postContent: "testVonaPostContent";
51
51
  user: "testVonaUser";
52
52
  }>, import("vona-module-a-orm").TypeEntityTableColumnNamesOfModelSelf<ModelPost> | import("vona").TypeRecordValues<{
53
- postContent: "testVonaPostContent.content" | "testVonaPostContent.postId" | "testVonaPostContent.id" | "testVonaPostContent.createdAt" | "testVonaPostContent.updatedAt" | "testVonaPostContent.deleted" | "testVonaPostContent.iid";
54
- user: "testVonaUser.name" | "testVonaUser.age" | "testVonaUser.scores" | "testVonaUser.id" | "testVonaUser.createdAt" | "testVonaUser.updatedAt" | "testVonaUser.deleted" | "testVonaUser.iid";
53
+ postContent: "testVonaPostContent.id" | "testVonaPostContent.content" | "testVonaPostContent.iid" | "testVonaPostContent.createdAt" | "testVonaPostContent.updatedAt" | "testVonaPostContent.deleted" | "testVonaPostContent.postId";
54
+ user: "testVonaUser.name" | "testVonaUser.id" | "testVonaUser.iid" | "testVonaUser.createdAt" | "testVonaUser.updatedAt" | "testVonaUser.deleted" | "testVonaUser.age" | "testVonaUser.scores";
55
55
  }>>[] | undefined;
56
56
  orders?: import("vona-module-a-orm").IModelSelectParamsOrder<import("vona-module-a-orm").TypeEntityTableColumnNamesOfModelSelf<ModelPost> | import("vona").TypeRecordValues<{
57
- postContent: "testVonaPostContent.content" | "testVonaPostContent.postId" | "testVonaPostContent.id" | "testVonaPostContent.createdAt" | "testVonaPostContent.updatedAt" | "testVonaPostContent.deleted" | "testVonaPostContent.iid";
58
- user: "testVonaUser.name" | "testVonaUser.age" | "testVonaUser.scores" | "testVonaUser.id" | "testVonaUser.createdAt" | "testVonaUser.updatedAt" | "testVonaUser.deleted" | "testVonaUser.iid";
57
+ postContent: "testVonaPostContent.id" | "testVonaPostContent.content" | "testVonaPostContent.iid" | "testVonaPostContent.createdAt" | "testVonaPostContent.updatedAt" | "testVonaPostContent.deleted" | "testVonaPostContent.postId";
58
+ user: "testVonaUser.name" | "testVonaUser.id" | "testVonaUser.iid" | "testVonaUser.createdAt" | "testVonaUser.updatedAt" | "testVonaUser.deleted" | "testVonaUser.age" | "testVonaUser.scores";
59
59
  }>>[] | undefined;
60
60
  limit?: number;
61
61
  offset?: number;
@@ -100,7 +100,7 @@ export declare class ServicePost extends BeanBase {
100
100
  };
101
101
  }, undefined, 50>[]>;
102
102
  select2(): Promise<import("vona-module-a-orm").TypeModelRelationResult_Normal<import("vona-module-test-vona").EntityPost, ModelPost, {
103
- columns: ("id" | "title" | "userId")[];
103
+ columns: ("title" | "id" | "userId")[];
104
104
  where: {
105
105
  id: {
106
106
  _gt_: number;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vona-module-test-vona",
3
3
  "type": "module",
4
- "version": "5.0.49",
4
+ "version": "5.0.51",
5
5
  "title": "test-vona",
6
6
  "vonaModule": {
7
7
  "fileVersion": 1,
@@ -1330,6 +1330,7 @@ export interface IModuleSummerCache {
1330
1330
  /** dto: begin */
1331
1331
  export * from '../dto/categoryTree.ts';
1332
1332
  export * from '../dto/orderCreate.ts';
1333
+ export * from '../dto/orderQuery.ts';
1333
1334
  export * from '../dto/orderResult.ts';
1334
1335
  export * from '../dto/orderUpdate.ts';
1335
1336
  export * from '../dto/postCreate.ts';
@@ -1344,6 +1345,7 @@ export * from '../dto/userLazy.ts';
1344
1345
  export * from '../dto/userUpdate.ts';
1345
1346
  import type { IDtoOptionsCategoryTree } from '../dto/categoryTree.ts';
1346
1347
  import type { IDtoOptionsOrderCreate } from '../dto/orderCreate.ts';
1348
+ import type { IDtoOptionsOrderQuery } from '../dto/orderQuery.ts';
1347
1349
  import type { IDtoOptionsOrderResult } from '../dto/orderResult.ts';
1348
1350
  import type { IDtoOptionsOrderUpdate } from '../dto/orderUpdate.ts';
1349
1351
  import type { IDtoOptionsPostCreate } from '../dto/postCreate.ts';
@@ -1362,6 +1364,7 @@ declare module 'vona-module-a-web' {
1362
1364
  export interface IDtoRecord {
1363
1365
  'test-vona:categoryTree': IDtoOptionsCategoryTree;
1364
1366
  'test-vona:orderCreate': IDtoOptionsOrderCreate;
1367
+ 'test-vona:orderQuery': IDtoOptionsOrderQuery;
1365
1368
  'test-vona:orderResult': IDtoOptionsOrderResult;
1366
1369
  'test-vona:orderUpdate': IDtoOptionsOrderUpdate;
1367
1370
  'test-vona:postCreate': IDtoOptionsPostCreate;
@@ -1385,6 +1388,7 @@ declare module 'vona-module-test-vona' {
1385
1388
  /** dto: begin */
1386
1389
  import type { DtoCategoryTree } from '../dto/categoryTree.ts';
1387
1390
  import type { DtoOrderCreate } from '../dto/orderCreate.ts';
1391
+ import type { DtoOrderQuery } from '../dto/orderQuery.ts';
1388
1392
  import type { DtoOrderResult } from '../dto/orderResult.ts';
1389
1393
  import type { DtoOrderUpdate } from '../dto/orderUpdate.ts';
1390
1394
  import type { DtoPostCreate } from '../dto/postCreate.ts';
@@ -1407,6 +1411,10 @@ declare module 'vona-module-test-vona' {
1407
1411
  fields?: TypeEntityOptionsFields<DtoOrderCreate, IDtoOptionsOrderCreate[TypeSymbolKeyFieldsMore]>;
1408
1412
  }
1409
1413
 
1414
+ export interface IDtoOptionsOrderQuery {
1415
+ fields?: TypeEntityOptionsFields<DtoOrderQuery, IDtoOptionsOrderQuery[TypeSymbolKeyFieldsMore]>;
1416
+ }
1417
+
1410
1418
  export interface IDtoOptionsOrderResult {
1411
1419
  fields?: TypeEntityOptionsFields<DtoOrderResult, IDtoOptionsOrderResult[TypeSymbolKeyFieldsMore]>;
1412
1420
  }
@@ -1807,6 +1815,7 @@ export interface IApiPathPostRecord{
1807
1815
  '//echo': undefined;
1808
1816
  '/test/vona/onion/echo2/:userId/:userName': undefined;
1809
1817
  '/test/vona/onion/echo4': undefined;
1818
+ '/test/vona/order/create': undefined;
1810
1819
  '/test/vona/passport/login': undefined;
1811
1820
  '/test/vona/passport/refresh': undefined;
1812
1821
  '/test/vona/passport/logout': undefined;
@@ -1,7 +1,7 @@
1
1
  export default {
2
2
  Name: 'Name',
3
3
  User: 'User',
4
- UserId: 'User Id',
4
+ UserId: 'User ID',
5
5
  Test: 'Test',
6
6
  TestHelloWorld: 'Hello World',
7
7
  TestApples: '%d apples',
@@ -1,7 +1,7 @@
1
1
  export default {
2
2
  Name: '名称',
3
3
  User: '用户',
4
- UserId: '用户Id',
4
+ UserId: '用户ID',
5
5
  Test: '测试',
6
6
  TestHelloWorld: '您好,世界',
7
7
  TestApples: '%d个苹果',
@@ -1,6 +1,6 @@
1
1
  import type { IDecoratorControllerOptions } from 'vona-module-a-web';
2
2
  import { BeanBase } from 'vona';
3
- import { Aspect } from 'vona-module-a-aspect';
3
+ import { Captcha } from 'vona-module-a-captcha';
4
4
  import { Passport } from 'vona-module-a-user';
5
5
  import { Arg, Controller, Web } from 'vona-module-a-web';
6
6
  import { DtoSignin } from '../dto/signin.ts';
@@ -11,7 +11,7 @@ export interface IControllerOptionsCaptcha extends IDecoratorControllerOptions {
11
11
  export class ControllerCaptcha extends BeanBase {
12
12
  @Web.post('signin')
13
13
  @Passport.public()
14
- @Aspect.middleware('a-captcha:captcha', { scene: 'a-captchasimple:simple' })
14
+ @Captcha.verify({ scene: 'a-captchasimple:simple' })
15
15
  async signin(@Arg.body() _user: DtoSignin) {
16
16
  }
17
17
  }
@@ -42,7 +42,7 @@ export class ControllerOnion extends BeanBase {
42
42
  @Web.post('echo2/:userId/:userName')
43
43
  // @Aspect.middlewareGlobal('a-core:gate', { gate: { mode: 'dev' } })
44
44
  @Aspect.guardGlobal('a-user:passport', { public: true })
45
- // echo2(@Arg.query(v.object(DtoUser, { passthrough: false, strict: false })) book: Partial<DtoUser>) {
45
+ // echo2(@Arg.query(v.object(DtoUser, { loose: false, strict: false })) book: Partial<DtoUser>) {
46
46
  echo2(
47
47
  @Arg.param('userId', v.title($locale('UserId')), v.example('example:1')) _userId: number,
48
48
  @Arg.param('userName', v.title($locale('UserId')), v.example('example:1')) _userName: string,
@@ -1,17 +1,39 @@
1
- import type { IDecoratorControllerOptions } from 'vona-module-a-web';
1
+ import type { VonaContext } from 'vona';
2
+ import type { IQueryParams } from 'vona-module-a-orm';
3
+ import type { IDecoratorControllerOptions, IPipeOptionsQueryTransformInfo } from 'vona-module-a-web';
4
+ import type { ModelOrder } from '../model/order.ts';
2
5
  import { BeanBase } from 'vona';
3
6
  import { Api, v } from 'vona-module-a-openapi';
4
- import { Controller, Web } from 'vona-module-a-web';
7
+ import { Arg, Controller, Web } from 'vona-module-a-web';
8
+ import { DtoOrderCreate } from '../dto/orderCreate.ts';
9
+ import { DtoOrderQuery } from '../dto/orderQuery.ts';
5
10
  import { DtoOrderResult } from '../dto/orderResult.ts';
6
11
 
7
12
  export interface IControllerOptionsOrder extends IDecoratorControllerOptions {}
8
13
 
14
+ function myCustomQueryTransform(_ctx: VonaContext, info: IPipeOptionsQueryTransformInfo): boolean | undefined {
15
+ if (info.key === 'userName') {
16
+ info.params.where[info.fullName] = info.value;
17
+ return true;
18
+ }
19
+ return undefined;
20
+ }
21
+
9
22
  @Controller<IControllerOptionsOrder>('order')
10
23
  export class ControllerOrder extends BeanBase {
24
+ @Web.post('create')
25
+ @Api.body(DtoOrderResult)
26
+ async create(@Arg.body(DtoOrderCreate) data: DtoOrderCreate) {
27
+ return await this.scope.model.order.insert(data);
28
+ }
29
+
11
30
  @Web.get('findAll')
12
31
  @Api.body(v.array(DtoOrderResult))
13
- async findAll(): Promise<DtoOrderResult[]> {
32
+ async findAll(
33
+ @Arg.queryPro(DtoOrderQuery, myCustomQueryTransform) params: IQueryParams<ModelOrder>,
34
+ ): Promise<DtoOrderResult[]> {
14
35
  return this.scope.model.order.select({
36
+ ...params,
15
37
  include: {
16
38
  products: true,
17
39
  },
@@ -5,7 +5,7 @@ import assert from 'node:assert';
5
5
  import { BeanBase } from 'vona';
6
6
  import { DtoJwtToken } from 'vona-module-a-jwt';
7
7
  import { Api, v } from 'vona-module-a-openapi';
8
- import { $getUserName, Passport } from 'vona-module-a-user';
8
+ import { Passport } from 'vona-module-a-user';
9
9
  import { Arg, Controller, Web } from 'vona-module-a-web';
10
10
 
11
11
  export interface IControllerOptionsPassport extends IDecoratorControllerOptions {}
@@ -17,7 +17,7 @@ export class ControllerPassport extends BeanBase {
17
17
  @Passport.public()
18
18
  echo(@Arg.param('name') name: string, @Arg.user() user: IUserBase) {
19
19
  assert.equal(name, 'admin');
20
- assert.equal($getUserName(user), 'admin');
20
+ assert.equal(user.name, 'admin');
21
21
  return { name, user };
22
22
  }
23
23
 
@@ -1,5 +1,5 @@
1
1
  import type { IQueryParams } from 'vona-module-a-orm';
2
- import type { IDecoratorControllerOptions } from 'vona-module-a-web';
2
+ import type { IDecoratorControllerOptions, IPipeOptionsQueryTransformInfo } from 'vona-module-a-web';
3
3
  import type { ModelPost } from '../model/post.ts';
4
4
  import { BeanBase } from 'vona';
5
5
  import { Api } from 'vona-module-a-openapi';
@@ -19,13 +19,14 @@ export class ControllerPost extends BeanBase {
19
19
  return params;
20
20
  }
21
21
 
22
+ findManyQueryTransform(_info: IPipeOptionsQueryTransformInfo): boolean | undefined {
23
+ return undefined;
24
+ }
25
+
22
26
  @Web.get('findMany')
23
27
  @Api.body(DtoPostQueryRes)
24
28
  @Passport.public()
25
29
  async findMany(@Arg.queryPro(DtoPostQuery) params: IQueryParams<ModelPost>) {
26
- if (!params.orders) {
27
- params.orders = [['testVonaPost.createdAt', 'desc']];
28
- }
29
30
  return await this.scope.service.post.findMany(params);
30
31
  }
31
32
  }
@@ -17,10 +17,10 @@ export class ControllerTail extends BeanBase {
17
17
  cast(this.ctx)._tail_test = 1;
18
18
 
19
19
  // tail
20
- this.ctx.db.commit(() => {
20
+ this.ctx.commit(() => {
21
21
  assert.equal(cast(this.ctx)._tail_test_als_caller, undefined);
22
22
  assert.equal(cast(this.ctx)._tail_test, 2);
23
- this.ctx.db.commit(() => {
23
+ this.ctx.commit(() => {
24
24
  assert.equal(cast(this.ctx)._tail_test, 3);
25
25
  });
26
26
  cast(this.ctx)._tail_test = 3;
@@ -2,9 +2,8 @@ import type { IUploadField, IUploadFile } from 'vona-module-a-upload';
2
2
  import type { IDecoratorControllerOptions } from 'vona-module-a-web';
3
3
  import assert from 'node:assert';
4
4
  import { BeanBase } from 'vona';
5
- import { Aspect } from 'vona-module-a-aspect';
6
5
  import { Api, v } from 'vona-module-a-openapi';
7
- import { SymbolUploadValue } from 'vona-module-a-upload';
6
+ import { File, SymbolUploadValue } from 'vona-module-a-upload';
8
7
  import { Passport } from 'vona-module-a-user';
9
8
  import { Arg, Controller, Web } from 'vona-module-a-web';
10
9
  import { z } from 'zod';
@@ -15,7 +14,7 @@ export interface IControllerOptionsUpload extends IDecoratorControllerOptions {}
15
14
  export class ControllerUpload extends BeanBase {
16
15
  @Web.post('fields')
17
16
  @Passport.public()
18
- @Aspect.interceptor('a-upload:upload')
17
+ @File.upload()
19
18
  @Api.contentType('application/json')
20
19
  fields(
21
20
  @Arg.fields() fields: IUploadField[],
@@ -30,7 +29,7 @@ export class ControllerUpload extends BeanBase {
30
29
 
31
30
  @Web.post('file')
32
31
  @Passport.public()
33
- @Aspect.interceptor('a-upload:upload')
32
+ @File.upload()
34
33
  @Api.contentType('application/json')
35
34
  file(@Arg.field('name', v.default('zhennann')) name: string, @Arg.file('welcome') file: IUploadFile) {
36
35
  assert.equal(name, 'zhennann');
@@ -40,7 +39,7 @@ export class ControllerUpload extends BeanBase {
40
39
 
41
40
  @Web.post('files')
42
41
  @Passport.public()
43
- @Aspect.interceptor('a-upload:upload')
42
+ @File.upload()
44
43
  @Api.contentType('application/json')
45
44
  files(
46
45
  @Arg.files(v.title('more files')) files: IUploadFile[],
@@ -0,0 +1,28 @@
1
+ import type { IDecoratorDtoOptions } from 'vona-module-a-web';
2
+ import { Api, v } from 'vona-module-a-openapi';
3
+ import { $Dto, $tableName } from 'vona-module-a-orm';
4
+ import { Dto } from 'vona-module-a-web';
5
+ import { EntityOrder } from '../entity/order.ts';
6
+ import { EntityUser } from '../entity/user.ts';
7
+
8
+ export interface IDtoOptionsOrderQuery extends IDecoratorDtoOptions {}
9
+
10
+ @Dto<IDtoOptionsOrderQuery>({
11
+ openapi: {
12
+ query: {
13
+ table: $tableName(EntityOrder),
14
+ },
15
+ },
16
+ })
17
+ export class DtoOrderQuery
18
+ extends $Dto.query(EntityOrder, ['orderNo', 'remark']) {
19
+ @Api.field(v.optional(), v.openapi({
20
+ query: {
21
+ table: $tableName(EntityUser),
22
+ joinType: 'innerJoin',
23
+ joinOn: ['userId', 'testVonaUser.id'],
24
+ originalName: 'name',
25
+ },
26
+ }))
27
+ userName?: string;
28
+ }
@@ -1,22 +1,21 @@
1
1
  import type { IDecoratorDtoOptions } from 'vona-module-a-web';
2
2
  import { Api, v } from 'vona-module-a-openapi';
3
- import { $Dto } from 'vona-module-a-orm';
3
+ import { $Dto, $tableName } from 'vona-module-a-orm';
4
4
  import { Dto } from 'vona-module-a-web';
5
5
  import { EntityPost } from '../entity/post.ts';
6
6
 
7
7
  export interface IDtoOptionsPostQuery extends IDecoratorDtoOptions {}
8
8
 
9
- @Dto<IDtoOptionsPostQuery>()
9
+ @Dto<IDtoOptionsPostQuery>({
10
+ openapi: { query: { table: $tableName(EntityPost) } },
11
+ })
10
12
  export class DtoPostQuery extends $Dto.queryPage(EntityPost, ['title']) {
11
13
  @Api.field(v.optional(), v.openapi({
12
14
  query: {
13
- join: {
14
- type: 'innerJoin',
15
- table: 'testVonaUser',
16
- on: ['userId', 'testVonaUser.id'],
17
- },
15
+ table: 'testVonaUser',
16
+ joinOn: ['userId', 'testVonaUser.id'],
18
17
  originalName: 'name',
19
- op: '_eq_',
18
+ op: '_eqI_',
20
19
  },
21
20
  }))
22
21
  userName?: string;
package/src/dto/signin.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { DtoCaptchaVerify } from 'vona-module-a-captcha';
1
2
  import type { IDecoratorDtoOptions } from 'vona-module-a-web';
2
3
  import { Api, v } from 'vona-module-a-openapi';
3
4
  import { Dto } from 'vona-module-a-web';
@@ -11,4 +12,7 @@ export class DtoSignin {
11
12
 
12
13
  @Api.field(v.min(3))
13
14
  password: string;
15
+
16
+ @Api.field(v.captcha({ scene: 'a-captchasimple:simple' }))
17
+ captcha: DtoCaptchaVerify;
14
18
  }
@@ -37,6 +37,7 @@ describe('authSimple.test.ts', () => {
37
37
  // login again
38
38
  const jwt2 = await app.bean.authSimple.authenticate(
39
39
  { username: 'admin', password: '123456' },
40
+ 'login',
40
41
  'default',
41
42
  );
42
43
  assert.equal(!!jwt2?.accessToken, true);
@@ -8,7 +8,7 @@ describe('captcha.test.ts', () => {
8
8
  // scene/provider
9
9
  const sceneName = 'a-captchasimple:simple';
10
10
  const providerName = 'a-captchasimple:imageText';
11
- it('action:captcha', async () => {
11
+ it('action:captcha:error', async () => {
12
12
  await app.bean.executor.mockCtx(async () => {
13
13
  // create
14
14
  const captcha = await app.bean.captcha.create(sceneName);
@@ -21,12 +21,27 @@ describe('captcha.test.ts', () => {
21
21
  // verify: false
22
22
  const verifiedFalse = await app.bean.captcha.verify(captcha.id, `${token}!`, sceneName);
23
23
  assert.equal(verifiedFalse, false);
24
+ // verify: false
25
+ const verifiedFalse2 = await app.bean.captcha.verify(captcha.id, token, sceneName);
26
+ assert.equal(verifiedFalse2, false);
27
+ });
28
+ });
29
+ it('action:captcha:ok', async () => {
30
+ await app.bean.executor.mockCtx(async () => {
31
+ // create
32
+ const captcha = await app.bean.captcha.create(sceneName);
33
+ assert.equal(captcha.provider, providerName);
34
+ // get
35
+ const captchaData = await app.bean.captcha.getCaptchaData(captcha.id);
36
+ assert.equal(captchaData?.provider, providerName);
37
+ // token
38
+ const token = captchaData?.token;
24
39
  // verify: true
25
40
  const verifiedTrue = await app.bean.captcha.verify(captcha.id, token, sceneName);
26
41
  assert.equal(verifiedTrue, true);
27
42
  });
28
43
  });
29
- it('action:captcha api', async () => {
44
+ it('action:captcha api:error', async () => {
30
45
  await app.bean.executor.mockCtx(async () => {
31
46
  // create
32
47
  const captcha: ICaptchaData = await app.bean.executor.performAction('post', '/captcha/create', {
@@ -56,6 +71,38 @@ describe('captcha.test.ts', () => {
56
71
  });
57
72
  });
58
73
  assert.equal(error?.code, 403);
74
+ // verifyImmediate: error again
75
+ const [_2, error2] = await catchError(() => {
76
+ return app.bean.executor.performAction('post', '/captcha/verifyImmediate', {
77
+ body: {
78
+ id: captcha2.id,
79
+ token: captchaData?.token,
80
+ },
81
+ });
82
+ });
83
+ assert.equal(error2?.code, 403);
84
+ });
85
+ });
86
+ it('action:captcha api:ok', async () => {
87
+ await app.bean.executor.mockCtx(async () => {
88
+ // create
89
+ const captcha: ICaptchaData = await app.bean.executor.performAction('post', '/captcha/create', {
90
+ body: {
91
+ scene: sceneName,
92
+ },
93
+ });
94
+ assert.equal(captcha.provider, providerName);
95
+ // refresh
96
+ const captcha2: ICaptchaData = await app.bean.executor.performAction('post', '/captcha/refresh', {
97
+ body: {
98
+ id: captcha.id,
99
+ scene: sceneName,
100
+ },
101
+ });
102
+ assert.equal(captcha2.provider, providerName);
103
+ assert.equal(captcha2.id, captcha.id);
104
+ // get token
105
+ const captchaData = await app.bean.captcha.getCaptchaData(captcha2.id);
59
106
  // verifyImmediate: ok
60
107
  const tokenSecondary = await app.bean.executor.performAction('post', '/captcha/verifyImmediate', {
61
108
  body: {
@@ -1,3 +1,5 @@
1
+ import type { TypeDecoratorRules } from 'vona-module-a-openapiutils';
2
+ import type z from 'zod';
1
3
  import assert from 'node:assert';
2
4
  import { describe, it } from 'node:test';
3
5
  import { app } from 'vona-mock';
@@ -16,15 +18,16 @@ describe('dtoAggregate.test.ts', () => {
16
18
  // max: 'age',
17
19
  // min: 'age',
18
20
  });
19
- let rules: any;
21
+ let rules: TypeDecoratorRules;
20
22
  rules = getTargetDecoratorRules(DtoUserAggr.prototype);
21
- assert.equal(rules.count_all._def.typeName, 'ZodOptional');
22
- assert.equal(rules.count_all._def.innerType._def.typeName, 'ZodUnion');
23
- assert.equal(rules.count_all._def.innerType._def.options[0]._def.typeName, 'ZodString');
24
- assert.equal(rules.count_all._def.innerType._def.options[1]._def.typeName, 'ZodNumber');
25
- assert.equal(rules.count_age._def.typeName, 'ZodOptional');
26
- assert.equal(rules.sum_age._def.typeName, 'ZodOptional');
27
- assert.equal(rules.avg_age._def.typeName, 'ZodOptional');
23
+ assert.equal(rules.count_all?.type === 'optional', true);
24
+ const rule_count_all = (rules.count_all as z.ZodOptional)?.def.innerType as z.ZodUnion;
25
+ assert.equal(rule_count_all.type === 'union', true);
26
+ assert.equal((rule_count_all.def.options[0] as z.ZodType).type === 'string', true);
27
+ assert.equal((rule_count_all.def.options[1] as z.ZodType).type === 'number', true);
28
+ assert.equal(rules.count_age?.type === 'optional', true);
29
+ assert.equal(rules.sum_age?.type === 'optional', true);
30
+ assert.equal(rules.avg_age?.type === 'optional', true);
28
31
  assert.equal(rules.max_age, undefined);
29
32
  assert.equal(rules.min_age, undefined);
30
33
  // aggr: usersStats: posts: autoload
@@ -33,10 +36,10 @@ describe('dtoAggregate.test.ts', () => {
33
36
  include: { roles: true },
34
37
  });
35
38
  rules = getTargetDecoratorRules(DtoUserStats.prototype);
36
- assert.equal(rules.name._def.typeName, 'ZodString');
39
+ assert.equal(rules.name?.type === 'string', true);
37
40
  assert.equal(rules.iid, undefined);
38
- assert.equal(rules.posts._def.typeName, 'ZodOptional');
39
- assert.equal(rules.roles._def.typeName, 'ZodOptional');
41
+ assert.equal(rules.posts?.type === 'optional', true);
42
+ assert.equal(rules.roles?.type === 'optional', true);
40
43
  });
41
44
  });
42
45
  });
@@ -1,3 +1,4 @@
1
+ import type { TypeDecoratorRules } from 'vona-module-a-openapiutils';
1
2
  import assert from 'node:assert';
2
3
  import { describe, it } from 'node:test';
3
4
  import { app } from 'vona-mock';
@@ -33,21 +34,21 @@ describe('dtoGet.test.ts', () => {
33
34
  }),
34
35
  },
35
36
  });
36
- const rules: any = getTargetDecoratorRules(DtoPostNew.prototype);
37
- assert.equal(['ZodString', 'ZodNumber'].includes(rules.id._def.typeName), true);
38
- assert.equal(rules.title._def.typeName, 'ZodString');
39
- assert.equal(['ZodString', 'ZodNumber'].includes(rules.userId._def.typeName), true);
37
+ const rules: TypeDecoratorRules = getTargetDecoratorRules(DtoPostNew.prototype);
38
+ assert.equal(['string', 'number'].includes(rules.id?.type as string), true);
39
+ assert.equal(rules.title?.type === 'string', true);
40
+ assert.equal(['string', 'number'].includes(rules.userId?.type as string), true);
40
41
  assert.equal(rules.iid, undefined);
41
- assert.equal(rules.postContent._def.typeName, 'ZodOptional');
42
- assert.equal(rules.user._def.typeName, 'ZodOptional');
43
- assert.equal(rules.user3._def.typeName, 'ZodOptional');
42
+ assert.equal(rules.postContent?.type === 'optional', true);
43
+ assert.equal(rules.user?.type === 'optional', true);
44
+ assert.equal(rules.user3?.type === 'optional', true);
44
45
  });
45
46
  });
46
47
  it('action:dtoGet:categoryTree', async () => {
47
48
  await app.bean.executor.mockCtx(async () => {
48
49
  const DtoCategoryTree = $Dto.get('test-vona:category', { columns: ['id', 'name'], include: { children: { columns: ['id'] } } });
49
- const rules: any = getTargetDecoratorRules(DtoCategoryTree.prototype);
50
- assert.equal(rules.children._def.typeName, 'ZodEffects');
50
+ const rules: TypeDecoratorRules = getTargetDecoratorRules(DtoCategoryTree.prototype);
51
+ assert.equal(rules.children?.type === 'pipe', true);
51
52
  assert.equal(rules.iid, undefined);
52
53
  const DtoCategoryChain = $Dto.get('test-vona:categoryChain', { columns: ['id', 'name', 'categoryIdParent'] });
53
54
  const _apiJson = await app.bean.scope('a-openapi').service.openapi.generateJsonOfClass(DtoCategoryChain);
@@ -1,3 +1,5 @@
1
+ import type { TypeDecoratorRules } from 'vona-module-a-openapiutils';
2
+ import type z from 'zod';
1
3
  import assert from 'node:assert';
2
4
  import { describe, it } from 'node:test';
3
5
  import { app } from 'vona-mock';
@@ -15,16 +17,17 @@ describe('dtoGroup.test.ts', () => {
15
17
  // max: 'age',
16
18
  // min: 'age',
17
19
  });
18
- let rules: any;
20
+ let rules: TypeDecoratorRules;
19
21
  rules = getTargetDecoratorRules(DtoUserAggr.prototype);
20
- assert.equal(rules.name._def.typeName, 'ZodString');
21
- assert.equal(rules.count_all._def.typeName, 'ZodOptional');
22
- assert.equal(rules.count_all._def.innerType._def.typeName, 'ZodUnion');
23
- assert.equal(rules.count_all._def.innerType._def.options[0]._def.typeName, 'ZodString');
24
- assert.equal(rules.count_all._def.innerType._def.options[1]._def.typeName, 'ZodNumber');
25
- assert.equal(rules.count_age._def.typeName, 'ZodOptional');
26
- assert.equal(rules.sum_age._def.typeName, 'ZodOptional');
27
- assert.equal(rules.avg_age._def.typeName, 'ZodOptional');
22
+ assert.equal(rules.name?.type === 'string', true);
23
+ assert.equal(rules.count_all?.type === 'optional', true);
24
+ const rule_count_all = (rules.count_all as z.ZodOptional)?.def.innerType as z.ZodUnion;
25
+ assert.equal(rule_count_all.type === 'union', true);
26
+ assert.equal((rule_count_all.def.options[0] as z.ZodType).type === 'string', true);
27
+ assert.equal((rule_count_all.def.options[1] as z.ZodType).type === 'number', true);
28
+ assert.equal(rules.count_age?.type === 'optional', true);
29
+ assert.equal(rules.sum_age?.type === 'optional', true);
30
+ assert.equal(rules.avg_age?.type === 'optional', true);
28
31
  assert.equal(rules.max_age, undefined);
29
32
  assert.equal(rules.min_age, undefined);
30
33
  // group: userStats: posts: autoload
@@ -33,10 +36,10 @@ describe('dtoGroup.test.ts', () => {
33
36
  include: { roles: true },
34
37
  });
35
38
  rules = getTargetDecoratorRules(DtoUserStats.prototype);
36
- assert.equal(rules.name._def.typeName, 'ZodString');
39
+ assert.equal(rules.name?.type === 'string', true);
37
40
  assert.equal(rules.iid, undefined);
38
- assert.equal(rules.posts._def.typeName, 'ZodEffects');
39
- assert.equal(rules.roles._def.typeName, 'ZodEffects');
41
+ assert.equal(rules.posts?.type === 'pipe', true);
42
+ assert.equal(rules.roles?.type === 'pipe', true);
40
43
  });
41
44
  });
42
45
  });
@@ -1,6 +1,6 @@
1
1
  import assert from 'node:assert';
2
2
  import { describe, it } from 'node:test';
3
- import { OpenApiGeneratorV31, OpenAPIRegistry } from '@asteasolutions/zod-to-openapi';
3
+ import { OpenApiGeneratorV31, OpenAPIRegistry } from '@cabloy/zod-to-openapi';
4
4
  import { appResource, cast } from 'vona';
5
5
  import { app } from 'vona-mock';
6
6
  import { $schema } from 'vona-module-a-openapi';