cabloy 5.1.106 → 5.1.107

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.
Files changed (51) hide show
  1. package/.cabloy-version +1 -1
  2. package/CHANGELOG.md +12 -0
  3. package/cabloy-docs/backend/backend-resource-module-contract-chain.md +1 -0
  4. package/cabloy-docs/backend/controller-aop-guide.md +12 -0
  5. package/cabloy-docs/backend/controller-guide.md +45 -3
  6. package/cabloy-docs/backend/crud-workflow.md +14 -0
  7. package/cabloy-docs/backend/unit-testing.md +8 -2
  8. package/cabloy-docs/fullstack/openapi-to-sdk.md +1 -0
  9. package/cabloy-docs/fullstack/tutorial-2-first-crud.md +3 -0
  10. package/package.json +1 -1
  11. package/vona/packages-cli/cli/package.json +1 -1
  12. package/vona/packages-cli/cli-set-api/cli/templates/tools/crud/boilerplate/src/bean/ssrMenu.{{resourceName}}.ts_ +1 -0
  13. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/boilerplate/src/controller/{{resourceName}}.ts_ +13 -4
  14. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/boilerplate/test/{{resourceName}}.test.ts_ +22 -3
  15. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/boilerplate/src/controller/{{resourceName}}.ts_ +13 -4
  16. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/boilerplate/test/{{resourceName}}.test.ts_ +22 -3
  17. package/vona/packages-cli/cli-set-api/package.json +1 -1
  18. package/vona/packages-vona/vona/package.json +1 -1
  19. package/vona/src/suite/a-home/modules/home-user/src/.metadata/index.ts +2 -2
  20. package/vona/src/suite/a-home/modules/home-user/src/bean/meta.version.ts +10 -8
  21. package/vona/src/suite/a-home/modules/home-user/src/config/config.ts +6 -0
  22. package/vona/src/suite/a-home/modules/home-user/src/config/locale/en-us.ts +2 -0
  23. package/vona/src/suite/a-home/modules/home-user/src/config/locale/zh-cn.ts +2 -0
  24. package/vona/src/suite/a-home/modules/home-user/src/config/roles.ts +24 -0
  25. package/vona/src/suite/a-home/modules/home-user/src/entity/role.ts +7 -0
  26. package/vona/src/suite/a-home/modules/home-user/test/role.test.ts +45 -0
  27. package/vona/src/suite/a-training/modules/training-record/src/controller/record.ts +13 -4
  28. package/vona/src/suite/a-training/modules/training-record/test/record.test.ts +25 -2
  29. package/vona/src/suite/a-training/modules/training-student/src/controller/student.ts +18 -6
  30. package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +33 -5
  31. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/cli/ssrMenuAdmin/boilerplate/{{sceneName}}.{{beanName}}.ts_ +1 -0
  32. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/package.json +1 -1
  33. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/service/ssrHandler.ts +1 -1
  34. package/vona/src/suite-vendor/a-cabloy/package.json +1 -1
  35. package/vona/src/suite-vendor/a-vona/modules/a-user/package.json +1 -1
  36. package/vona/src/suite-vendor/a-vona/modules/a-user/src/types/role.ts +3 -0
  37. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  38. package/zova/packages-cli/cli/package.json +2 -2
  39. package/zova/packages-cli/cli-set-front/package.json +1 -1
  40. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.openapi.generate.ts +4 -0
  41. package/zova/packages-zova/zova/package.json +2 -2
  42. package/zova/src/suite/a-home/modules/home-api/mock/passport.fake.ts +50 -1
  43. package/zova/src/suite/a-home/modules/home-api/src/api/openapi/types.ts +15 -7
  44. package/zova/src/suite/a-home/modules/home-base/src/.metadata/index.ts +10 -0
  45. package/zova/src/suite/a-home/modules/home-base/src/page/errorAccessDenied/controller.tsx +1 -1
  46. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/types.ts +26 -17
  47. package/zova/src/suite/cabloy-basic/modules/basic-file/src/api/openapi/types.ts +26 -17
  48. package/zova/src/suite/cabloy-basic/modules/basic-image/src/api/openapi/types.ts +26 -17
  49. package/zova/src/suite-vendor/a-zova/modules/a-ssrserver/package.json +1 -1
  50. package/zova/src/suite-vendor/a-zova/modules/a-ssrserver/src/service/ssrHandler.ts +1 -1
  51. package/zova/src/suite-vendor/a-zova/package.json +2 -2
@@ -5,7 +5,9 @@ import type { IDecoratorControllerOptions } from 'vona-module-a-web';
5
5
  import { BeanBase } from 'vona';
6
6
  import { Core } from 'vona-module-a-core';
7
7
  import { Api, Resource, v } from 'vona-module-a-openapiutils';
8
+ import { Passport } from 'vona-module-a-user';
8
9
  import { Arg, Controller, Web } from 'vona-module-a-web';
10
+ import { z } from 'zod';
9
11
 
10
12
  import type { ModelRecord } from '../model/record.ts';
11
13
 
@@ -22,6 +24,7 @@ export interface IControllerOptionsRecord extends IDecoratorControllerOptions {}
22
24
  export class ControllerRecord extends BeanBase {
23
25
  @Web.post()
24
26
  @Api.body(v.tableIdentity())
27
+ @Passport.systemAdmin()
25
28
  async create(@Arg.body() record: DtoRecordCreate): Promise<TableIdentity> {
26
29
  return (await this.scope.service.record.create(record)).id;
27
30
  }
@@ -29,6 +32,7 @@ export class ControllerRecord extends BeanBase {
29
32
  @Web.get()
30
33
  @Api.body(DtoRecordSelectRes)
31
34
  @Core.serializer()
35
+ @Passport.systemAdmin()
32
36
  async select(
33
37
  @Arg.filter(DtoRecordSelectReq) params: IQueryParams<ModelRecord>,
34
38
  ): Promise<DtoRecordSelectRes> {
@@ -38,6 +42,7 @@ export class ControllerRecord extends BeanBase {
38
42
  @Web.get(':id')
39
43
  @Api.body(v.optional(), v.object(DtoRecordView))
40
44
  @Core.serializer()
45
+ @Passport.systemAdmin()
41
46
  async view(
42
47
  @Arg.param('id', v.tableIdentity()) id: TableIdentity,
43
48
  ): Promise<DtoRecordView | undefined> {
@@ -45,15 +50,19 @@ export class ControllerRecord extends BeanBase {
45
50
  }
46
51
 
47
52
  @Web.patch(':id')
53
+ @Api.body(z.null())
54
+ @Passport.systemAdmin()
48
55
  async update(
49
56
  @Arg.param('id', v.tableIdentity()) id: TableIdentity,
50
57
  @Arg.body() record: DtoRecordUpdate,
51
- ) {
52
- return await this.scope.service.record.update(id, record);
58
+ ): Promise<void> {
59
+ await this.scope.service.record.update(id, record);
53
60
  }
54
61
 
55
62
  @Web.delete(':id')
56
- async delete(@Arg.param('id', v.tableIdentity()) id: TableIdentity) {
57
- return await this.scope.service.record.delete(id);
63
+ @Api.body(z.null())
64
+ @Passport.systemAdmin()
65
+ async delete(@Arg.param('id', v.tableIdentity()) id: TableIdentity): Promise<void> {
66
+ await this.scope.service.record.delete(id);
58
67
  }
59
68
  }
@@ -160,10 +160,11 @@ describe('record.test.ts', () => {
160
160
  },
161
161
  ],
162
162
  } as any as DtoRecordUpdate;
163
- await app.bean.executor.performAction('patch', '/training/record/:id', {
163
+ const updateRes = await app.bean.executor.performAction('patch', '/training/record/:id', {
164
164
  params: { id: recordId },
165
165
  body: dataUpdate,
166
166
  });
167
+ assert.equal(updateRes, null);
167
168
 
168
169
  record = await app.bean.executor.performAction('get', '/training/record/:id', {
169
170
  params: { id: recordId },
@@ -200,9 +201,10 @@ describe('record.test.ts', () => {
200
201
  assert.equal(studentRecord?.dossierFiles?.length, 2);
201
202
  assert.equal(studentRecord?.trainingRecordSubjects?.length, 2);
202
203
 
203
- await app.bean.executor.performAction('delete', '/training/record/:id', {
204
+ const deleteRes = await app.bean.executor.performAction('delete', '/training/record/:id', {
204
205
  params: { id: recordId },
205
206
  });
207
+ assert.equal(deleteRes, null);
206
208
 
207
209
  record = await app.bean.executor.performAction('get', '/training/record/:id', {
208
210
  params: { id: recordId },
@@ -243,4 +245,25 @@ describe('record.test.ts', () => {
243
245
  }
244
246
  });
245
247
  });
248
+
249
+ it('action:record:systemAdmin', async () => {
250
+ await app.bean.executor.mockCtx(async () => {
251
+ await app.bean.passport.signinMock();
252
+ try {
253
+ app.bean.passport.current!.roles = [];
254
+ const actions = ['create', 'select', 'view', 'update', 'delete'];
255
+ const permissions = await Promise.all(
256
+ actions.map(action =>
257
+ app.bean.permission.retrievePermissionAction('training-record:record', action),
258
+ ),
259
+ );
260
+ assert.deepEqual(
261
+ permissions,
262
+ actions.map(() => false),
263
+ );
264
+ } finally {
265
+ await app.bean.passport.signout();
266
+ }
267
+ });
268
+ });
246
269
  });
@@ -5,7 +5,9 @@ import type { IDecoratorControllerOptions } from 'vona-module-a-web';
5
5
  import { BeanBase } from 'vona';
6
6
  import { Core } from 'vona-module-a-core';
7
7
  import { Api, Resource, v } from 'vona-module-a-openapiutils';
8
+ import { Passport } from 'vona-module-a-user';
8
9
  import { Arg, Controller, Web } from 'vona-module-a-web';
10
+ import { z } from 'zod';
9
11
 
10
12
  import type { ModelStudent } from '../model/student.ts';
11
13
 
@@ -23,6 +25,7 @@ export interface IControllerOptionsStudent extends IDecoratorControllerOptions {
23
25
  export class ControllerStudent extends BeanBase {
24
26
  @Web.post()
25
27
  @Api.body(v.tableIdentity())
28
+ @Passport.systemAdmin()
26
29
  async create(@Arg.body() student: DtoStudentCreate): Promise<TableIdentity> {
27
30
  return (await this.scope.service.student.create(student)).id;
28
31
  }
@@ -30,6 +33,7 @@ export class ControllerStudent extends BeanBase {
30
33
  @Web.get()
31
34
  @Api.body(DtoStudentSelectRes)
32
35
  @Core.serializer()
36
+ @Passport.systemAdmin()
33
37
  async select(
34
38
  @Arg.filter(DtoStudentSelectReq) params: IQueryParams<ModelStudent>,
35
39
  ): Promise<DtoStudentSelectRes> {
@@ -39,6 +43,7 @@ export class ControllerStudent extends BeanBase {
39
43
  @Web.get(':id')
40
44
  @Api.body(v.optional(), v.object(DtoStudentView))
41
45
  @Core.serializer()
46
+ @Passport.systemAdmin()
42
47
  async view(
43
48
  @Arg.param('id', v.tableIdentity()) id: TableIdentity,
44
49
  ): Promise<DtoStudentView | undefined> {
@@ -46,16 +51,19 @@ export class ControllerStudent extends BeanBase {
46
51
  }
47
52
 
48
53
  @Web.patch(':id')
54
+ @Api.body(z.null())
55
+ @Passport.systemAdmin()
49
56
  async update(
50
57
  @Arg.param('id', v.tableIdentity()) id: TableIdentity,
51
58
  @Arg.body() student: DtoStudentUpdate,
52
- ) {
53
- return await this.scope.service.student.update(id, student);
59
+ ): Promise<void> {
60
+ await this.scope.service.student.update(id, student);
54
61
  }
55
62
 
56
63
  @Web.get('summary/:id')
57
64
  @Api.body(v.optional(), v.object(DtoStudentSummary))
58
65
  @Core.serializer()
66
+ @Passport.systemAdmin()
59
67
  async summary(
60
68
  @Arg.param('id', v.tableIdentity()) id: TableIdentity,
61
69
  ): Promise<DtoStudentSummary | undefined> {
@@ -63,12 +71,16 @@ export class ControllerStudent extends BeanBase {
63
71
  }
64
72
 
65
73
  @Web.delete(':id')
66
- async delete(@Arg.param('id', v.tableIdentity()) id: TableIdentity) {
67
- return await this.scope.service.student.delete(id);
74
+ @Api.body(z.null())
75
+ @Passport.systemAdmin()
76
+ async delete(@Arg.param('id', v.tableIdentity()) id: TableIdentity): Promise<void> {
77
+ await this.scope.service.student.delete(id);
68
78
  }
69
79
 
70
80
  @Web.delete('deleteForce/:id')
71
- async deleteForce(@Arg.param('id', v.tableIdentity()) id: TableIdentity) {
72
- return await this.scope.service.student.deleteForce(id);
81
+ @Api.body(z.null())
82
+ @Passport.systemAdmin()
83
+ async deleteForce(@Arg.param('id', v.tableIdentity()) id: TableIdentity): Promise<void> {
84
+ await this.scope.service.student.deleteForce(id);
73
85
  }
74
86
  }
@@ -123,10 +123,11 @@ describe('student.test.ts', () => {
123
123
  },
124
124
  ],
125
125
  } as any as DtoStudentUpdate;
126
- await app.bean.executor.performAction('patch', '/training/student/:id', {
126
+ const updateRes = await app.bean.executor.performAction('patch', '/training/student/:id', {
127
127
  params: { id: studentId },
128
128
  body: dataUpdate,
129
129
  });
130
+ assert.equal(updateRes, null);
130
131
  // findOne after nested update
131
132
  student = await app.bean.executor.performAction('get', '/training/student/:id', {
132
133
  params: { id: studentId },
@@ -168,9 +169,10 @@ describe('student.test.ts', () => {
168
169
  assert.equal(typeof summary.levelTitle, 'string');
169
170
  assert.equal(typeof summary.summaryText, 'string');
170
171
  // delete
171
- await app.bean.executor.performAction('delete', '/training/student/:id', {
172
+ const deleteRes = await app.bean.executor.performAction('delete', '/training/student/:id', {
172
173
  params: { id: student.id },
173
174
  });
175
+ assert.equal(deleteRes, null);
174
176
  // findOne
175
177
  student = await app.bean.executor.performAction('get', '/training/student/:id', {
176
178
  params: { id: student.id },
@@ -180,9 +182,14 @@ describe('student.test.ts', () => {
180
182
  const studentIdForce = await app.bean.executor.performAction('post', '/training/student', {
181
183
  body: data,
182
184
  });
183
- await app.bean.executor.performAction('delete', '/training/student/deleteForce/:id', {
184
- params: { id: studentIdForce },
185
- });
185
+ const deleteForceRes = await app.bean.executor.performAction(
186
+ 'delete',
187
+ '/training/student/deleteForce/:id',
188
+ {
189
+ params: { id: studentIdForce },
190
+ },
191
+ );
192
+ assert.equal(deleteForceRes, null);
186
193
  const studentForce: EntityStudent | undefined = await app.bean
187
194
  .scope('training-student')
188
195
  .model.student.getById(studentIdForce, {
@@ -194,6 +201,27 @@ describe('student.test.ts', () => {
194
201
  });
195
202
  });
196
203
 
204
+ it('action:student:systemAdmin', async () => {
205
+ await app.bean.executor.mockCtx(async () => {
206
+ await app.bean.passport.signinMock();
207
+ try {
208
+ app.bean.passport.current!.roles = [];
209
+ const actions = ['create', 'select', 'view', 'update', 'summary', 'delete', 'deleteForce'];
210
+ const permissions = await Promise.all(
211
+ actions.map(action =>
212
+ app.bean.permission.retrievePermissionAction('training-student:student', action),
213
+ ),
214
+ );
215
+ assert.deepEqual(
216
+ permissions,
217
+ actions.map(() => false),
218
+ );
219
+ } finally {
220
+ await app.bean.passport.signout();
221
+ }
222
+ });
223
+ });
224
+
197
225
  it('action:student:level invalid', async () => {
198
226
  await app.bean.executor.mockCtx(async () => {
199
227
  await app.bean.passport.signinMock();
@@ -14,6 +14,7 @@ export interface ISsrMenuOptions<%=argv.beanNameCapitalize%> extends IDecoratorS
14
14
  icon: undefined,
15
15
  link: undefined,
16
16
  group: '<%=argv.ssrSiteGroupName%>',
17
+ roles: ['systemAdmin'],
17
18
  },
18
19
  site: ['<%=argv.ssrSiteOnionName%>'],
19
20
  })
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-ssr",
3
- "version": "5.1.25",
3
+ "version": "5.1.26",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "keywords": [
@@ -33,7 +33,7 @@ export class ServiceSsrHandler extends BeanBase {
33
33
  return await ssrHandler.resolvePath(filename);
34
34
  }
35
35
 
36
- public async render(options: ISsrHandlerRenderOptionsInner) {
36
+ public async render(options: ISsrHandlerRenderOptionsInner): Promise<true | string | undefined> {
37
37
  const ssrHandler = await this.ensureReady();
38
38
  return await ssrHandler.render(options);
39
39
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-suite-a-cabloy",
3
- "version": "5.1.40",
3
+ "version": "5.1.41",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "author": "",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-user",
3
- "version": "5.1.19",
3
+ "version": "5.1.20",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "keywords": [
@@ -1,4 +1,5 @@
1
1
  import type { TableIdentity } from 'table-identity';
2
+ import type { ILocaleRecord } from 'vona';
2
3
 
3
4
  export interface IRoleNameRecord {
4
5
  registeredUser: never;
@@ -10,6 +11,8 @@ export interface IRoleIdRecord {}
10
11
  export interface IRole {
11
12
  id: TableIdentity;
12
13
  name: string;
14
+ title: string;
15
+ locales?: Partial<Record<keyof ILocaleRecord, string>>;
13
16
  siteIds: string[];
14
17
  }
15
18
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-suite-a-vona",
3
- "version": "5.1.67",
3
+ "version": "5.1.68",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "author": "",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-cli",
3
- "version": "1.2.97",
3
+ "version": "1.2.98",
4
4
  "gitHead": "6f675a8cc46d596142c591c28a40cc4d82fcc6cc",
5
5
  "description": "zova cli",
6
6
  "keywords": [
@@ -44,7 +44,7 @@
44
44
  "@cabloy/process-helper": "^3.1.8",
45
45
  "fs-extra": "^11.3.5",
46
46
  "semver": "^7.6.2",
47
- "zova-cli-set-front": "^1.2.95"
47
+ "zova-cli-set-front": "^1.2.96"
48
48
  },
49
49
  "devDependencies": {
50
50
  "clean-package": "^2.2.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-cli-set-front",
3
- "version": "1.2.95",
3
+ "version": "1.2.96",
4
4
  "gitHead": "6f675a8cc46d596142c591c28a40cc4d82fcc6cc",
5
5
  "description": "zova cli-set-front",
6
6
  "keywords": [
@@ -606,6 +606,10 @@ function _patchOpenapiTSOptions(options?: OpenAPITSOptions) {
606
606
  const res = transformCustom(schemaObject, options);
607
607
  if (res !== undefined) return res;
608
608
  }
609
+ // // null
610
+ // if (schemaObject.type === 'null') {
611
+ // return NULL;
612
+ // }
609
613
  // multipart
610
614
  if (schemaObject.format === 'binary') {
611
615
  if (
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova",
3
- "version": "5.1.135",
3
+ "version": "5.1.136",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A vue3 framework with ioc",
6
6
  "keywords": [
@@ -46,7 +46,7 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "zova-core": "^5.1.78",
49
- "zova-suite-a-zova": "^5.1.134"
49
+ "zova-suite-a-zova": "^5.1.135"
50
50
  },
51
51
  "devDependencies": {
52
52
  "clean-package": "^2.2.0",
@@ -235,8 +235,25 @@ const __sdkSchemaPassportLogin = {
235
235
  type: 'string',
236
236
  title: '角色名',
237
237
  },
238
+ title: {
239
+ type: 'string',
240
+ title: '角色标题',
241
+ },
242
+ locales: {
243
+ type: 'object',
244
+ additionalProperties: {
245
+ type: 'string',
246
+ },
247
+ title: '角色本地化文本',
248
+ },
249
+ siteIds: {
250
+ type: 'array',
251
+ items: {
252
+ type: 'string',
253
+ },
254
+ },
238
255
  },
239
- required: ['createdAt', 'updatedAt', 'id', 'name'],
256
+ required: ['createdAt', 'updatedAt', 'id', 'name', 'title', 'siteIds'],
240
257
  title: '角色',
241
258
  },
242
259
  'a-jwt.dto.jwtToken': {
@@ -393,6 +410,22 @@ export default defineFakeRoute([
393
410
  auth: {
394
411
  id: 1,
395
412
  },
413
+ roles: [
414
+ {
415
+ id: 1,
416
+ name: 'registeredUser',
417
+ title: 'Registered User',
418
+ locales: { 'zh-cn': '注册用户' },
419
+ siteIds: ['web'],
420
+ },
421
+ {
422
+ id: 2,
423
+ name: 'systemAdmin',
424
+ title: 'System Administrator',
425
+ locales: { 'zh-cn': '系统管理员' },
426
+ siteIds: ['web', 'admin'],
427
+ },
428
+ ],
396
429
  },
397
430
  jwt: {
398
431
  accessToken: `accessToken-${user.name}`,
@@ -423,6 +456,22 @@ export default defineFakeRoute([
423
456
  auth: {
424
457
  id: 1,
425
458
  },
459
+ roles: [
460
+ {
461
+ id: 1,
462
+ name: 'registeredUser',
463
+ title: 'Registered User',
464
+ locales: { 'zh-cn': '注册用户' },
465
+ siteIds: ['web'],
466
+ },
467
+ {
468
+ id: 2,
469
+ name: 'systemAdmin',
470
+ title: 'System Administrator',
471
+ locales: { 'zh-cn': '系统管理员' },
472
+ siteIds: ['web', 'admin'],
473
+ },
474
+ ],
426
475
  },
427
476
  };
428
477
  },
@@ -1531,6 +1531,14 @@ export interface components {
1531
1531
  id: number | string;
1532
1532
  /** @description Role Name */
1533
1533
  name: string;
1534
+ /** @description Role Title */
1535
+ title: string;
1536
+ /** @description Role Locales */
1537
+ locales?:
1538
+ | {
1539
+ [key: string]: string;
1540
+ }
1541
+ | undefined;
1534
1542
  siteIds: string[];
1535
1543
  };
1536
1544
  'home-user.dto.passportJwt': {
@@ -3568,7 +3576,7 @@ export interface operations {
3568
3576
  'application/json': {
3569
3577
  code: string;
3570
3578
  message: string;
3571
- data?: unknown;
3579
+ data: undefined;
3572
3580
  };
3573
3581
  };
3574
3582
  };
@@ -3598,7 +3606,7 @@ export interface operations {
3598
3606
  'application/json': {
3599
3607
  code: string;
3600
3608
  message: string;
3601
- data?: unknown;
3609
+ data: undefined;
3602
3610
  };
3603
3611
  };
3604
3612
  };
@@ -3715,7 +3723,7 @@ export interface operations {
3715
3723
  'application/json': {
3716
3724
  code: string;
3717
3725
  message: string;
3718
- data?: unknown;
3726
+ data: undefined;
3719
3727
  };
3720
3728
  };
3721
3729
  };
@@ -3745,7 +3753,7 @@ export interface operations {
3745
3753
  'application/json': {
3746
3754
  code: string;
3747
3755
  message: string;
3748
- data?: unknown;
3756
+ data: undefined;
3749
3757
  };
3750
3758
  };
3751
3759
  };
@@ -3797,7 +3805,7 @@ export interface operations {
3797
3805
  'application/json': {
3798
3806
  code: string;
3799
3807
  message: string;
3800
- data?: unknown;
3808
+ data: undefined;
3801
3809
  };
3802
3810
  };
3803
3811
  };
@@ -4408,7 +4416,7 @@ export interface operations {
4408
4416
  'application/json': {
4409
4417
  code: string;
4410
4418
  message: string;
4411
- data?: unknown;
4419
+ data: undefined;
4412
4420
  };
4413
4421
  };
4414
4422
  };
@@ -4438,7 +4446,7 @@ export interface operations {
4438
4446
  'application/json': {
4439
4447
  code: string;
4440
4448
  message: string;
4441
- data?: unknown;
4449
+ data: undefined;
4442
4450
  };
4443
4451
  };
4444
4452
  };
@@ -83,6 +83,7 @@ declare module 'zova' {
83
83
  export * from '../component/itemLink/controller.jsx';
84
84
  export * from '../component/page/controller.jsx';
85
85
  export * from '../page/authCallback/controller.jsx';
86
+ export * from '../page/errorAccessDenied/controller.jsx';
86
87
  export * from '../page/errorExpired/controller.jsx';
87
88
  export * from '../page/errorNotFound/controller.jsx';
88
89
 
@@ -108,6 +109,11 @@ declare module 'zova-module-home-base' {
108
109
  get scope(): ScopeModuleHomeBase;
109
110
  }
110
111
 
112
+ export interface ControllerPageErrorAccessDenied {
113
+ /** @internal */
114
+ get scope(): ScopeModuleHomeBase;
115
+ }
116
+
111
117
  export interface ControllerPageErrorExpired {
112
118
  /** @internal */
113
119
  get scope(): ScopeModuleHomeBase;
@@ -123,6 +129,7 @@ declare module 'zova-module-home-base' {
123
129
  import { ControllerItemLink } from '../component/itemLink/controller.jsx';
124
130
  import { ControllerPage } from '../component/page/controller.jsx';
125
131
  import { ControllerPageAuthCallback } from '../page/authCallback/controller.jsx';
132
+ import { ControllerPageErrorAccessDenied } from '../page/errorAccessDenied/controller.jsx';
126
133
  import { ControllerPageErrorExpired } from '../page/errorExpired/controller.jsx';
127
134
  import { ControllerPageErrorNotFound } from '../page/errorNotFound/controller.jsx';
128
135
  import 'zova';
@@ -131,6 +138,7 @@ declare module 'zova' {
131
138
  'home-base.controller.itemLink': ControllerItemLink;
132
139
  'home-base.controller.page': ControllerPage;
133
140
  'home-base.controller.pageAuthCallback': ControllerPageAuthCallback;
141
+ 'home-base.controller.pageErrorAccessDenied': ControllerPageErrorAccessDenied;
134
142
  'home-base.controller.pageErrorExpired': ControllerPageErrorExpired;
135
143
  'home-base.controller.pageErrorNotFound': ControllerPageErrorNotFound;
136
144
  }
@@ -139,6 +147,7 @@ declare module 'zova' {
139
147
  /** pages: begin */
140
148
  export * from './page/authCallback.js';
141
149
  import { NSControllerPageAuthCallback } from './page/authCallback.js';
150
+ export * from './page/errorAccessDenied.js';
142
151
  export * from './page/errorExpired.js';
143
152
  import { NSControllerPageErrorExpired } from './page/errorExpired.js';
144
153
  export * from './page/errorNotFound.js';
@@ -148,6 +157,7 @@ import 'zova';
148
157
  declare module 'zova-module-a-router' {
149
158
  export interface IPagePathRecord {
150
159
  '/home/base/authCallback': TypePagePathSchema<undefined,NSControllerPageAuthCallback.QueryInput>;
160
+ '/home/base/errorAccessDenied': TypePagePathSchema<undefined,undefined>;
151
161
  '/home/base/errorExpired': TypePagePathSchema<undefined,NSControllerPageErrorExpired.QueryInput>;
152
162
  '/home/base//:catchAll(.*)*': TypePagePathSchema<undefined,undefined>;
153
163
  }
@@ -31,7 +31,7 @@ export class ControllerPageErrorAccessDenied extends BeanControllerPageBase {
31
31
  this.app.$gotoHome();
32
32
  }}
33
33
  >
34
- Go Home
34
+ {this.scope.locale.GoHome()}
35
35
  </button>
36
36
  </div>
37
37
  </div>