cabloy 5.1.179 → 5.1.180

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 (58) hide show
  1. package/.cabloy-version +1 -1
  2. package/.claude/scheduled_tasks.lock +1 -1
  3. package/CHANGELOG.md +19 -0
  4. package/package.json +1 -1
  5. package/repo-docs/.vitepress/config.mjs +1 -0
  6. package/repo-docs/backend/controller-aop-guide.md +1 -1
  7. package/repo-docs/backend/demonstration-mode-guide.md +130 -0
  8. package/repo-docs/frontend/page-meta-guide.md +91 -13
  9. package/repo-docs/frontend/router-view-hosts-guide.md +37 -0
  10. package/repo-docs/fullstack/framework-performance.md +3 -3
  11. package/vona/packages-cli/cli/package.json +1 -1
  12. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/boilerplate/src/controller/{{resourceName}}.ts_ +7 -7
  13. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/boilerplate/test/{{resourceName}}.test.ts_ +93 -39
  14. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/snippets/3-en-us.ts +1 -1
  15. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/snippets/4-zh-cn.ts +1 -1
  16. package/vona/packages-cli/cli-set-api/package.json +1 -1
  17. package/vona/packages-vona/vona/package.json +1 -1
  18. package/vona/pnpm-lock.yaml +1862 -2223
  19. package/vona/src/suite/a-demo/modules/demo-demonstration/package.json +55 -0
  20. package/vona/src/suite/a-demo/modules/demo-demonstration/src/.metadata/index.ts +68 -0
  21. package/vona/src/suite/a-demo/modules/demo-demonstration/src/.metadata/locales.ts +18 -0
  22. package/vona/src/suite/a-demo/modules/demo-demonstration/src/.metadata/this.ts +2 -0
  23. package/vona/src/suite/a-demo/modules/demo-demonstration/src/bean/guard.demonstration.ts +68 -0
  24. package/vona/src/suite/a-demo/modules/demo-demonstration/src/config/errors.ts +6 -0
  25. package/vona/src/suite/a-demo/modules/demo-demonstration/src/config/locale/en-us.ts +3 -0
  26. package/vona/src/suite/a-demo/modules/demo-demonstration/src/config/locale/zh-cn.ts +3 -0
  27. package/vona/src/suite/a-demo/modules/demo-demonstration/src/index.ts +3 -0
  28. package/vona/src/suite/a-demo/modules/demo-demonstration/src/types/index.ts +8 -0
  29. package/vona/src/suite/a-demo/modules/demo-demonstration/test/guardDemonstration.test.ts +121 -0
  30. package/vona/src/suite/a-demo/modules/demo-demonstration/tsconfig.build.json +11 -0
  31. package/vona/src/suite/a-demo/modules/demo-demonstration/tsconfig.json +7 -0
  32. package/vona/src/suite/a-demo/package.json +2 -1
  33. package/vona/src/suite/a-demo/tsconfig.json +3 -0
  34. package/vona/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +9 -0
  35. package/vona/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +9 -0
  36. package/vona/src/suite/a-training/modules/training-student/src/controller/student.ts +19 -17
  37. package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +47 -27
  38. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/package.json +1 -1
  39. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/bean/bean.rbacScope.ts +13 -7
  40. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/test/rbacScopeCurrent.test.ts +28 -0
  41. package/vona/src/suite-vendor/a-cabloy/package.json +2 -2
  42. package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
  43. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  44. package/zova/packages-utils/zova-jsx/package.json +2 -2
  45. package/zova/packages-zova/zova/package.json +3 -3
  46. package/zova/packages-zova/zova-core/package.json +1 -1
  47. package/zova/packages-zova/zova-core/src/bean/type.ts +1 -0
  48. package/zova/packages-zova/zova-core/src/composables/useController.ts +1 -1
  49. package/zova/src/suite/a-home/modules/home-indexadmin/src/page/dashboard/controller.tsx +26 -7
  50. package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
  51. package/zova/src/suite-vendor/a-zova/modules/a-router/src/lib/const.ts +1 -0
  52. package/zova/src/suite-vendor/a-zova/modules/a-router/src/monkey.ts +39 -2
  53. package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/index.ts +1 -0
  54. package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/pageHost.ts +9 -0
  55. package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/router.ts +2 -0
  56. package/zova/src/suite-vendor/a-zova/modules/a-router/test/lib/pageHost.test.ts +53 -0
  57. package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
  58. package/zova/src/suite-vendor/a-zova/package.json +3 -3
@@ -11,10 +11,12 @@ import { getRbacDecision, hasRbacAllScope, rbacActionKey } from '../lib/rbac.ts'
11
11
 
12
12
  @Bean()
13
13
  export class BeanRbacScope extends BeanBase {
14
- private _scopeAdapter: IRbacScopeAdapter | undefined;
14
+ private _scopeAdapter: IRbacScopeAdapter | null | undefined;
15
15
 
16
16
  async isUnrestricted(): Promise<boolean> {
17
- return await this.scopeAdapter.isUnrestricted();
17
+ const scopeAdapter = this.scopeAdapter;
18
+ if (scopeAdapter) return await scopeAdapter.isUnrestricted();
19
+ return await this.bean.passport.isSystemAdmin();
18
20
  }
19
21
 
20
22
  async current(actionKey?: string): Promise<IRbacScopeAccess> {
@@ -26,19 +28,21 @@ export class BeanRbacScope extends BeanBase {
26
28
 
27
29
  const unrestricted = hasRbacAllScope(decision);
28
30
  const ownerValues =
29
- action.action === 'create'
31
+ action.action === 'create' && action.options.dataScope
30
32
  ? await this.prepareOwnerValues(action, decision, unrestricted)
31
33
  : undefined;
32
34
  return this.createAccess(action, decision, unrestricted, ownerValues);
33
35
  }
34
36
 
35
- private get scopeAdapter(): IRbacScopeAdapter {
36
- if (!this._scopeAdapter) {
37
+ private get scopeAdapter(): IRbacScopeAdapter | null {
38
+ if (this._scopeAdapter === undefined) {
37
39
  const beanFullName = beanFullNameFromOnionName(
38
40
  this.scope.config.adapter.rbacScope,
39
41
  'service',
40
42
  );
41
- this._scopeAdapter = this.bean._getBean(beanFullName) as unknown as IRbacScopeAdapter;
43
+ this._scopeAdapter =
44
+ (this.bean._getBean(beanFullName) as unknown as IRbacScopeAdapter | null | undefined) ??
45
+ null;
42
46
  }
43
47
  return this._scopeAdapter;
44
48
  }
@@ -48,7 +52,9 @@ export class BeanRbacScope extends BeanBase {
48
52
  decision: IRbacPolicyDecision,
49
53
  unrestricted: boolean,
50
54
  ): Promise<Record<string, TableIdentity | null | undefined>> {
51
- const values = await this.scopeAdapter.ownerValues(action, decision);
55
+ const scopeAdapter = this.scopeAdapter;
56
+ if (!scopeAdapter) this.app.throw(403);
57
+ const values = await scopeAdapter.ownerValues(action, decision);
52
58
  const departmentField = action.options.dataScopeField ?? 'departmentId';
53
59
  const ownerField = action.options.dataScopeMineField ?? 'userIdOwner';
54
60
  const ownerValues = {
@@ -90,6 +90,21 @@ describe('rbacScopeCurrent.test.ts', { concurrency: false }, () => {
90
90
  access.checkEntries([{ departmentId: 'one' }, { departmentId: 'two' }]);
91
91
  });
92
92
 
93
+ it('falls back to the system-admin passport check without a configured adapter', async () => {
94
+ let systemAdmin = false;
95
+ const scope = Object.create(BeanRbacScope.prototype) as BeanRbacScope;
96
+ Object.defineProperties(scope, {
97
+ bean: {
98
+ value: { passport: { isSystemAdmin: async () => systemAdmin } },
99
+ },
100
+ _scopeAdapter: { value: null, writable: true },
101
+ });
102
+
103
+ assert.equal(await scope.isUnrestricted(), false);
104
+ systemAdmin = true;
105
+ assert.equal(await scope.isUnrestricted(), true);
106
+ });
107
+
93
108
  it('does not expose the decision to a child context sharing caller state', () => {
94
109
  const action = createAction();
95
110
  const ctx = { route: action.route, state: {} } as VonaContext;
@@ -146,6 +161,19 @@ describe('rbacScopeCurrent.test.ts', { concurrency: false }, () => {
146
161
  await assertForbidden(() => scope.current());
147
162
  });
148
163
 
164
+ it('does not require adapter owner values for an unscoped create action', async () => {
165
+ const action = { ...createAction('create'), options: {} };
166
+ const { scope, ctx } = createScope(action, null as never);
167
+ setRbacDecision(ctx, createDecision(action, [{ dataScope: 'all' }]));
168
+
169
+ const access = await scope.current();
170
+ assert.equal(access.unrestricted, true);
171
+ assert.throws(
172
+ () => access.ownerValues(),
173
+ error => (error as { code?: number }).code === 500,
174
+ );
175
+ });
176
+
149
177
  it('derives create owner values from the configured adapter', async () => {
150
178
  const action = createAction('create');
151
179
  const adapter: IRbacScopeAdapter = {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-suite-a-cabloy",
3
- "version": "5.1.54",
3
+ "version": "5.1.55",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "author": "",
@@ -10,7 +10,7 @@
10
10
  "vona-module-a-cabloy": "workspace:^",
11
11
  "vona-module-a-layoutprofile": "^5.0.2",
12
12
  "vona-module-a-markdown": "^5.0.3",
13
- "vona-module-a-rbac": "^5.0.6",
13
+ "vona-module-a-rbac": "^5.0.7",
14
14
  "vona-module-a-socket": "workspace:^",
15
15
  "vona-module-a-ssr": "workspace:^",
16
16
  "vona-module-a-ssrhmr": "workspace:^"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-permission",
3
- "version": "5.1.22",
3
+ "version": "5.1.23",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-suite-a-vona",
3
- "version": "5.1.87",
3
+ "version": "5.1.88",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "author": "",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-jsx",
3
- "version": "1.1.91",
3
+ "version": "1.1.92",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "Zova JSX",
6
6
  "keywords": [
@@ -50,7 +50,7 @@
50
50
  "@cabloy/word-utils": "^2.1.14",
51
51
  "typestyle": "^2.4.0",
52
52
  "vue": "^3.5.38",
53
- "zova-core": "^5.1.91"
53
+ "zova-core": "^5.1.92"
54
54
  },
55
55
  "devDependencies": {
56
56
  "clean-package": "^2.2.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova",
3
- "version": "5.1.165",
3
+ "version": "5.1.166",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A vue3 framework with ioc",
6
6
  "keywords": [
@@ -45,8 +45,8 @@
45
45
  "postpack": "clean-package restore"
46
46
  },
47
47
  "dependencies": {
48
- "zova-core": "^5.1.91",
49
- "zova-suite-a-zova": "^5.1.164"
48
+ "zova-core": "^5.1.92",
49
+ "zova-suite-a-zova": "^5.1.165"
50
50
  },
51
51
  "devDependencies": {
52
52
  "clean-package": "^2.2.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-core",
3
- "version": "5.1.91",
3
+ "version": "5.1.92",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A vue3 framework with ioc",
6
6
  "keywords": [
@@ -62,6 +62,7 @@ export type TypeAllErrorCodes = TypeScopesErrorCodes | keyof TypeErrorsInternal;
62
62
 
63
63
  export interface IControllerDataContext {
64
64
  slots?: object;
65
+ page?: boolean;
65
66
  }
66
67
 
67
68
  export interface IControllerData {
@@ -39,7 +39,7 @@ export function useControllerPage(
39
39
  styleBeanFullName?: Constructable | string,
40
40
  ) {
41
41
  // controllerData
42
- const controllerData = { context: {} };
42
+ const controllerData = { context: { page: true } };
43
43
  // use controller
44
44
  _useController(controllerData, controllerBeanFullName, renderBeanFullName, styleBeanFullName);
45
45
  }
@@ -10,10 +10,17 @@ export class ControllerPageDashboard extends BeanControllerPageBase {
10
10
  protected __init__() {
11
11
  if (!this.$pageRoute) return;
12
12
  this.$ssr.handleDirectOrOnHydrated(() => {
13
- this.currentTime = new Date().toLocaleTimeString();
14
- this._timer = window.setInterval(() => {
15
- this.currentTime = new Date().toLocaleTimeString();
16
- }, 1000);
13
+ this.$watch(
14
+ () => this.$pageHost?.active,
15
+ active => {
16
+ if (active) {
17
+ this._startTimer();
18
+ } else {
19
+ this._stopTimer();
20
+ }
21
+ },
22
+ { immediate: true },
23
+ );
17
24
  });
18
25
  this.$router.setPageMeta(this.$pageRoute, {
19
26
  onCustomRenderIsolate: () => (
@@ -29,10 +36,22 @@ export class ControllerPageDashboard extends BeanControllerPageBase {
29
36
  });
30
37
  }
31
38
 
39
+ private _startTimer() {
40
+ if (this._timer !== undefined) return;
41
+ this.currentTime = new Date().toLocaleTimeString();
42
+ this._timer = window.setInterval(() => {
43
+ this.currentTime = new Date().toLocaleTimeString();
44
+ }, 1000);
45
+ }
46
+
47
+ private _stopTimer() {
48
+ if (this._timer === undefined) return;
49
+ window.clearInterval(this._timer);
50
+ this._timer = undefined;
51
+ }
52
+
32
53
  protected __dispose__() {
33
- if (this._timer !== undefined) {
34
- window.clearInterval(this._timer);
35
- }
54
+ this._stopTimer();
36
55
  }
37
56
 
38
57
  protected render() {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-router",
3
- "version": "5.1.40",
3
+ "version": "5.1.41",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "router",
6
6
  "keywords": [
@@ -1,2 +1,3 @@
1
1
  export const pageRouteKey = '$$pageRoute';
2
+ export const pageHostKey = '$$pageHost';
2
3
  export const routerViewKey = '$$routerView';
@@ -18,14 +18,15 @@ import type {
18
18
  import type { ErrorSSR } from 'zova-module-a-ssr';
19
19
 
20
20
  import * as ModuleInfo from '@cabloy/module-info';
21
- import { shallowReactive } from 'vue';
21
+ import { onActivated, onBeforeUnmount, onDeactivated, shallowReactive } from 'vue';
22
22
  import { BeanControllerPageBase, BeanSimple, cast, useComputed } from 'zova';
23
23
 
24
24
  import type { BeanRouter } from './bean/bean.router.js';
25
25
  import type { SysRouter } from './bean/sys.router.js';
26
+ import type { IPageHost } from './types/pageHost.js';
26
27
  import type { TypePageSchema } from './types/router.js';
27
28
 
28
- import { routerViewKey } from './lib/const.js';
29
+ import { pageHostKey, routerViewKey } from './lib/const.js';
29
30
  import { getCurrentRoute, getPageRoute, getRealRouteName, getRouteMatched } from './lib/utils.js';
30
31
  import { ServiceRouterGuards } from './service/routerGuards.js';
31
32
  import { SymbolRouterHistory } from './types/utils.js';
@@ -42,6 +43,7 @@ export class Monkey
42
43
  {
43
44
  private _beanRouter: BeanRouter;
44
45
  private _sysRouter: SysRouter;
46
+ private _pageHosts = new WeakMap<ZovaContext, IPageHost>();
45
47
  serviceRouterGuards: ServiceRouterGuards;
46
48
 
47
49
  private async _getSysRouter() {
@@ -149,6 +151,13 @@ export class Monkey
149
151
  });
150
152
  },
151
153
  });
154
+ bean.defineProperty(beanInstance, '$pageHost', {
155
+ enumerable: false,
156
+ configurable: true,
157
+ get() {
158
+ return bean._getBeanFromHost({ name: pageHostKey }) ?? undefined;
159
+ },
160
+ });
152
161
  bean.defineProperty(beanInstance, '$currentRoute', {
153
162
  enumerable: false,
154
163
  configurable: true,
@@ -161,9 +170,37 @@ export class Monkey
161
170
  }
162
171
 
163
172
  controllerDataPrepare(controllerData: IControllerData, ctx: ZovaContext) {
173
+ if (controllerData.context.page) {
174
+ this._initPageHost(ctx);
175
+ }
164
176
  controllerData.context.route = getPageRoute(ctx);
165
177
  }
166
178
 
179
+ private _initPageHost(ctx: ZovaContext) {
180
+ const existing = this._pageHosts.get(ctx);
181
+ if (existing) {
182
+ ctx.bean._setBean(pageHostKey, existing);
183
+ return;
184
+ }
185
+
186
+ const pageHost = shallowReactive({ active: true });
187
+ this._pageHosts.set(ctx, pageHost);
188
+ ctx.bean._setBean(pageHostKey, pageHost);
189
+ if (!process.env.CLIENT) return;
190
+
191
+ ctx.util.instanceScope(() => {
192
+ onActivated(() => {
193
+ pageHost.active = true;
194
+ });
195
+ onDeactivated(() => {
196
+ pageHost.active = false;
197
+ });
198
+ onBeforeUnmount(() => {
199
+ pageHost.active = false;
200
+ });
201
+ });
202
+ }
203
+
167
204
  controllerDataInit(controllerData: IControllerData, controller: BeanBase) {
168
205
  // only for controller page
169
206
  if (!(controller instanceof BeanControllerPageBase)) return;
@@ -1,3 +1,4 @@
1
+ export * from './pageHost.js';
1
2
  export * from './pageMeta.js';
2
3
  export * from './router.js';
3
4
  export * from './routerView.js';
@@ -0,0 +1,9 @@
1
+ export interface IPageHost {
2
+ /**
3
+ * Whether the concrete routed page instance is currently activated.
4
+ *
5
+ * This does not describe route selection, cache membership, visibility, or
6
+ * data readiness.
7
+ */
8
+ readonly active: boolean;
9
+ }
@@ -17,6 +17,7 @@ import type {
17
17
 
18
18
  import type { BeanRouter } from '../bean/bean.router.js';
19
19
  import type { BeanRouterViewBase } from '../lib/routerViewBase.js';
20
+ import type { IPageHost } from './pageHost.js';
20
21
  import type { IGetPagePathOptions, IGotoPageOptions } from './utils.js';
21
22
  import 'vue-router';
22
23
 
@@ -72,6 +73,7 @@ declare module 'zova' {
72
73
  $router: BeanRouter;
73
74
  $routerView: BeanRouterViewBase;
74
75
  $pageRoute: RouteLocationNormalizedLoadedGeneric | undefined;
76
+ $pageHost: IPageHost | undefined;
75
77
  $currentRoute: RouteLocationNormalizedLoadedGeneric | undefined;
76
78
  }
77
79
 
@@ -0,0 +1,53 @@
1
+ import type { BeanBase, BeanContainer } from 'zova';
2
+
3
+ import assert from 'node:assert/strict';
4
+ import test from 'node:test';
5
+
6
+ import { pageHostKey } from '../../src/lib/const.js';
7
+ import { Monkey } from '../../src/monkey.js';
8
+
9
+ function createBean() {
10
+ const lookups: string[] = [];
11
+ let pageHost: object | undefined;
12
+ const beanContainer = {
13
+ defineProperty<T>(beanInstance: T, prop: string, attributes: PropertyDescriptor) {
14
+ return Object.defineProperty(beanInstance, prop, attributes);
15
+ },
16
+ _getBeanFromHost<T>({ name }: { name: string }) {
17
+ lookups.push(name);
18
+ return pageHost as T | undefined;
19
+ },
20
+ } as unknown as BeanContainer;
21
+ const beanInstance = {} as BeanBase;
22
+ const monkey = new Monkey();
23
+
24
+ return {
25
+ beanInstance,
26
+ beanContainer,
27
+ lookups,
28
+ monkey,
29
+ setPageHost(value: object | undefined) {
30
+ pageHost = value;
31
+ },
32
+ };
33
+ }
34
+
35
+ test('$pageHost reads the current page host from the bean host', async () => {
36
+ const { beanInstance, beanContainer, lookups, monkey, setPageHost } = createBean();
37
+ await monkey.beanInit(beanContainer, beanInstance);
38
+
39
+ assert.equal(beanInstance.$pageHost, undefined);
40
+
41
+ const firstPageHost = { active: true };
42
+ setPageHost(firstPageHost);
43
+ assert.equal(beanInstance.$pageHost, firstPageHost);
44
+
45
+ const secondPageHost = { active: false };
46
+ setPageHost(secondPageHost);
47
+ assert.equal(beanInstance.$pageHost, secondPageHost);
48
+
49
+ assert.deepEqual(lookups, [pageHostKey, pageHostKey, pageHostKey]);
50
+ const descriptor = Object.getOwnPropertyDescriptor(beanInstance, '$pageHost');
51
+ assert.equal(descriptor?.enumerable, false);
52
+ assert.equal(descriptor?.configurable, true);
53
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-zova",
3
- "version": "5.1.107",
3
+ "version": "5.1.108",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "zova",
6
6
  "keywords": [
@@ -43,7 +43,7 @@
43
43
  "@cabloy/word-utils": "^2.1.14",
44
44
  "defu": "^6.1.7",
45
45
  "luxon": "^3.7.2",
46
- "zova-jsx": "^1.1.91"
46
+ "zova-jsx": "^1.1.92"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@cabloy/cli": "^3.1.29",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-suite-a-zova",
3
- "version": "5.1.164",
3
+ "version": "5.1.165",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "zova",
6
6
  "license": "MIT",
@@ -22,7 +22,7 @@
22
22
  "zova-module-a-meta": "^5.1.22",
23
23
  "zova-module-a-model": "^5.1.37",
24
24
  "zova-module-a-openapi": "^5.1.54",
25
- "zova-module-a-router": "^5.1.40",
25
+ "zova-module-a-router": "^5.1.41",
26
26
  "zova-module-a-routerstack": "^5.1.29",
27
27
  "zova-module-a-routertabs": "^5.1.34",
28
28
  "zova-module-a-ssr": "^5.1.40",
@@ -31,7 +31,7 @@
31
31
  "zova-module-a-style": "^5.1.35",
32
32
  "zova-module-a-table": "^5.1.43",
33
33
  "zova-module-a-zod": "^5.1.37",
34
- "zova-module-a-zova": "^5.1.107"
34
+ "zova-module-a-zova": "^5.1.108"
35
35
  },
36
36
  "title": "a-zova"
37
37
  }