cabloy 5.1.187 → 5.1.188

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 (22) hide show
  1. package/.cabloy-version +1 -1
  2. package/CHANGELOG.md +12 -0
  3. package/package.json +1 -1
  4. package/repo-e2e/specs/markdown.spec.ts +46 -1
  5. package/vona/packages-vona/vona/package.json +1 -1
  6. package/vona/pnpm-lock.yaml +14 -136
  7. package/vona/src/suite-vendor/a-vona/modules/a-version/package.json +1 -1
  8. package/vona/src/suite-vendor/a-vona/modules/a-version/src/lib/databaseTestName.ts +47 -0
  9. package/vona/src/suite-vendor/a-vona/modules/a-version/src/service/database.ts +8 -3
  10. package/vona/src/suite-vendor/a-vona/modules/a-version/test/databaseName.test.ts +72 -0
  11. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  12. package/zova/packages-cli/cli/package.json +2 -2
  13. package/zova/packages-cli/cli-set-front/package.json +2 -2
  14. package/zova/packages-utils/zova-vite/package.json +1 -1
  15. package/zova/packages-utils/zova-vite/src/collect-css-ssr.ts +7 -5
  16. package/zova/src/suite/a-home/modules/home-base/src/config/config.ts +0 -8
  17. package/zova/src/suite/a-home/modules/home-base/src/service/ssrLayout.ts +2 -3
  18. package/zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/controller.tsx +1 -0
  19. package/zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/render.sidebar.tsx +1 -4
  20. package/zova/src/suite/a-home/modules/home-layoutadmin/src/config/config.ts +4 -0
  21. package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/controller.tsx +1 -0
  22. package/zova/src/suite/cabloy-basic/modules/basic-markdown/src/lib/richTextContentStyle.ts +16 -2
package/.cabloy-version CHANGED
@@ -1 +1 @@
1
- 5.1.187
1
+ 5.1.188
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.1.188
4
+
5
+ ### Bug Fixes
6
+
7
+ - Enforce database name length limits.
8
+ - Correct markdown task list item rendering.
9
+
10
+ ### Improvements
11
+
12
+ - Refactor the layout implementation.
13
+ - Update SSR CSS collection handling.
14
+
3
15
  ## 5.1.187
4
16
 
5
17
  ### Improvements
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cabloy",
3
- "version": "5.1.187",
3
+ "version": "5.1.188",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A Node.js fullstack framework",
6
6
  "keywords": [
@@ -1,4 +1,4 @@
1
- import type { Page } from '@playwright/test';
1
+ import type { Locator, Page } from '@playwright/test';
2
2
 
3
3
  import { expect, test } from '@playwright/test';
4
4
 
@@ -35,6 +35,49 @@ function expectTableIdentity(value: unknown) {
35
35
  expect(['string', 'number']).toContain(typeof value);
36
36
  }
37
37
 
38
+ async function expectTaskCheckboxLayout(root: Locator) {
39
+ const layout = await root.locator('ul[data-type="taskList"] li').evaluateAll(taskItems =>
40
+ taskItems.map(taskItem => {
41
+ const checkbox = taskItem.querySelector<HTMLInputElement>('label > input[type="checkbox"]');
42
+ const label = taskItem.querySelector<HTMLElement>('label');
43
+ const text = taskItem.querySelector<HTMLElement>('div > p');
44
+ if (!checkbox || !label || !text) return null;
45
+
46
+ const checkboxRect = checkbox.getBoundingClientRect();
47
+ const textRect = text.getBoundingClientRect();
48
+ const checkboxStyle = getComputedStyle(checkbox);
49
+ const labelStyle = getComputedStyle(label);
50
+ const itemStyle = getComputedStyle(taskItem);
51
+ return {
52
+ checkboxHeight: checkboxRect.height,
53
+ checkboxWidth: checkboxRect.width,
54
+ checkboxCenter: checkboxRect.top + checkboxRect.height / 2,
55
+ checkboxMarginBlockEnd: checkboxStyle.marginBlockEnd,
56
+ checkboxMarginBlockStart: checkboxStyle.marginBlockStart,
57
+ checkboxMarginInlineEnd: checkboxStyle.marginInlineEnd,
58
+ checkboxMarginInlineStart: checkboxStyle.marginInlineStart,
59
+ itemDisplay: itemStyle.display,
60
+ labelDisplay: labelStyle.display,
61
+ textCenter: textRect.top + Number.parseFloat(getComputedStyle(text).lineHeight) / 2,
62
+ };
63
+ }),
64
+ );
65
+
66
+ expect(layout).toHaveLength(2);
67
+ for (const task of layout) {
68
+ expect(task).not.toBeNull();
69
+ expect(task?.itemDisplay).toBe('flex');
70
+ expect(task?.labelDisplay).toBe('flex');
71
+ expect(task?.checkboxWidth).toBeGreaterThan(0);
72
+ expect(task?.checkboxHeight).toBe(task?.checkboxWidth);
73
+ expect(task?.checkboxMarginBlockStart).toBe('0px');
74
+ expect(task?.checkboxMarginBlockEnd).toBe('0px');
75
+ expect(task?.checkboxMarginInlineStart).toBe('0px');
76
+ expect(task?.checkboxMarginInlineEnd).toBe('0px');
77
+ expect(Math.abs((task?.checkboxCenter ?? 0) - (task?.textCenter ?? 0))).toBeLessThanOrEqual(2);
78
+ }
79
+ }
80
+
38
81
  async function login(
39
82
  page: Page,
40
83
  path: string,
@@ -181,6 +224,7 @@ test(
181
224
  await expect(description.locator('input[type="checkbox"]').nth(0)).toBeDisabled();
182
225
  await expect(description.locator('input[type="checkbox"]').nth(1)).toBeChecked();
183
226
  await expect(description.locator('input[type="checkbox"]').nth(1)).toBeDisabled();
227
+ await expectTaskCheckboxLayout(description);
184
228
  expect(webPageErrors).toEqual([]);
185
229
  expect(webConsoleErrors).toEqual([]);
186
230
  } finally {
@@ -353,6 +397,7 @@ const product = '${suffix}';
353
397
  await expect(editor.locator('input[type="checkbox"]')).toHaveCount(2);
354
398
  await expect(editor.locator('input[type="checkbox"]').nth(0)).not.toBeChecked();
355
399
  await expect(editor.locator('input[type="checkbox"]').nth(1)).toBeChecked();
400
+ await expectTaskCheckboxLayout(editor);
356
401
  await expect(editor.locator('blockquote')).toHaveCSS('border-left-width', '4px');
357
402
  await expect(editor.locator('pre')).toHaveCSS('overflow-x', 'auto');
358
403
  await expect(editor.locator('table th').first()).toHaveCSS('font-weight', '600');
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona",
3
- "version": "5.1.98",
3
+ "version": "5.1.99",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "Vona is an intuitive, elegant and powerful Node.js framework for rapidly developing enterprise applications of any size",
6
6
  "keywords": [
@@ -741,11 +741,11 @@ importers:
741
741
  specifier: npm:@cabloy/zod@4.3.8
742
742
  version: '@cabloy/zod@4.3.8'
743
743
  zova:
744
- specifier: ^5.1.164
745
- version: 5.1.165(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
744
+ specifier: ^5.1.166
745
+ version: 5.1.166(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
746
746
  zova-jsx:
747
- specifier: ^1.1.90
748
- version: 1.1.91(typescript@5.9.3)
747
+ specifier: ^1.1.92
748
+ version: 1.1.92(typescript@5.9.3)
749
749
  zova-module-a-api:
750
750
  specifier: ^5.1.22
751
751
  version: 5.1.22
@@ -777,11 +777,11 @@ importers:
777
777
  specifier: ^5.1.54
778
778
  version: 5.1.54
779
779
  zova-module-a-pay:
780
- specifier: ^5.0.8
780
+ specifier: ^5.0.9
781
781
  version: 5.0.9
782
782
  zova-module-a-router:
783
- specifier: ^5.1.39
784
- version: 5.1.40
783
+ specifier: ^5.1.41
784
+ version: 5.1.41
785
785
  zova-module-a-routertabs:
786
786
  specifier: ^5.1.34
787
787
  version: 5.1.34
@@ -825,11 +825,11 @@ importers:
825
825
  specifier: npm:@cabloy/zod@4.3.8
826
826
  version: '@cabloy/zod@4.3.8'
827
827
  zova:
828
- specifier: ^5.1.164
829
- version: 5.1.165(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
828
+ specifier: ^5.1.166
829
+ version: 5.1.166(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
830
830
  zova-jsx:
831
- specifier: ^1.1.90
832
- version: 1.1.91(typescript@5.9.3)
831
+ specifier: ^1.1.92
832
+ version: 1.1.92(typescript@5.9.3)
833
833
  zova-module-a-api:
834
834
  specifier: ^5.1.22
835
835
  version: 5.1.22
@@ -861,11 +861,11 @@ importers:
861
861
  specifier: ^5.1.54
862
862
  version: 5.1.54
863
863
  zova-module-a-pay:
864
- specifier: ^5.0.8
864
+ specifier: ^5.0.9
865
865
  version: 5.0.9
866
866
  zova-module-a-router:
867
- specifier: ^5.1.39
868
- version: 5.1.40
867
+ specifier: ^5.1.41
868
+ version: 5.1.41
869
869
  zova-module-a-routertabs:
870
870
  specifier: ^5.1.34
871
871
  version: 5.1.34
@@ -8890,15 +8890,9 @@ packages:
8890
8890
  resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
8891
8891
  engines: {node: '>=10'}
8892
8892
 
8893
- zova-core@5.1.91:
8894
- resolution: {integrity: sha512-5e4EgInhcU7LUMhl6x7oOQnsF2X3lk1HMRvbo882FZrwTB3lvIz/ejOOdpRxoId29hqxvX5HFiKcb9aZi/cHog==}
8895
-
8896
8893
  zova-core@5.1.92:
8897
8894
  resolution: {integrity: sha512-Y6j3YCMlVCZ5f9JGRX79mFRYW96stGgnhTyMmo0LZCD/P3CqjIlNwyL8edK8e/DBzQ+JYFj65CuBf/n/lIcl7Q==}
8898
8895
 
8899
- zova-jsx@1.1.91:
8900
- resolution: {integrity: sha512-VIScqEFG6jwzNqjW7MvBvZdLJAqpkzchop6Q/g2ttGBKXMGjyTZnaISrB3gWv/feReGnUb0BFPzDgmrOdFnQgA==}
8901
-
8902
8896
  zova-jsx@1.1.92:
8903
8897
  resolution: {integrity: sha512-cbjpwK8qI3ufIKNXlYuWsbljfIbxZ3ISQXKKXn199V7A4IDRz0CNUmffPHU0EX3uZ1mMvqkt9HUJxaVseFb0qQ==}
8904
8898
 
@@ -8950,9 +8944,6 @@ packages:
8950
8944
  zova-module-a-pay@5.0.9:
8951
8945
  resolution: {integrity: sha512-Chl6EKp30HBOGFCJXbla2/lS19WhzQyTZwgYmsL3nnG9Vt2TeUlb82vsYCVuDcy0cgmxVaWjPF7dzKL/r3Pfng==}
8952
8946
 
8953
- zova-module-a-router@5.1.40:
8954
- resolution: {integrity: sha512-X8sOcMqDrNju+J+kjpyRwUkecMdnXIq2MFbl3KLY1lb641sXLEmdJMSJBmVWCrGVBA+kA6nGnI//wtMGXTVIyg==}
8955
-
8956
8947
  zova-module-a-router@5.1.41:
8957
8948
  resolution: {integrity: sha512-oSv4S+9bAx79X8oUBARFKs4n56FNG/bbqdyxP10CXxlVue8WU7CmNKN4ckzLJ2mleVIezijZk/1aHS1Fl5rk+g==}
8958
8949
 
@@ -8980,9 +8971,6 @@ packages:
8980
8971
  zova-module-a-zod@5.1.37:
8981
8972
  resolution: {integrity: sha512-rXHN9rKbum9w3gDSnC/pIusG2d2FGJOcIauf8jrbT96f+Olk4Q3iV3t2V92mxiLCh9kMvBJPfcOgJFW7pRB5Fw==}
8982
8973
 
8983
- zova-module-a-zova@5.1.107:
8984
- resolution: {integrity: sha512-apqfQ2DSDd/2witE+qeVXOC5pxG4cqt0hfiXfJVHcfLeius4h9lpnLFQqFswkyAgCaXrcPk329Nq6FGSij8RKw==}
8985
-
8986
8974
  zova-module-a-zova@5.1.108:
8987
8975
  resolution: {integrity: sha512-K6ZmbuKPScDXOmmNuDxrMtoo3n+YTgbf9BSVJcen++CVuHPXNSdr+kQTpOa+B12O+PxUKCfmwwCSh7T9RrjiEA==}
8988
8976
 
@@ -8992,15 +8980,9 @@ packages:
8992
8980
  zova-module-rest-resource@5.1.55:
8993
8981
  resolution: {integrity: sha512-Kk3oJIcxM5EbeTLl+ucJSeI2kT0We8YilXBaX8Z7QWCbZ0fHoQDy/Ac4YsVSWIXUrC2SQ267+nMl3sHXnE9G0Q==}
8994
8982
 
8995
- zova-suite-a-zova@5.1.164:
8996
- resolution: {integrity: sha512-0o/mBzx6fiPsPIKEltIRW2Hfntza2Hc8q/n7y+BQYXdoNN3WdvDpE6XrbG5Lu/+AXlHn42n49bgEgawNSYb/Xw==}
8997
-
8998
8983
  zova-suite-a-zova@5.1.165:
8999
8984
  resolution: {integrity: sha512-hXjFEx9MXrtvPgAv28VF2UbgM45hzz7B7ZAsElJloBNWB3zyz2HUHYxNWDbCrrKfrw5zM3Mbr9i+dzyy3/6LQw==}
9000
8985
 
9001
- zova@5.1.165:
9002
- resolution: {integrity: sha512-oz67Qkzx+u/xE3hVOkIDEFFr7IwImfWIurmxdSpWA3UuzC+9bVDaDu3CDj/3l0n/0LIYnjmbff66k5gKikYWzg==}
9003
-
9004
8986
  zova@5.1.166:
9005
8987
  resolution: {integrity: sha512-2qh4Na6G8JYHWIyX7+NNfMLzzgHsheQFUgeH6KVsMp66kxpdR9YSr5Ivz+dJepthtmnlCB7R+WWczhURx4wYYA==}
9006
8988
 
@@ -15081,37 +15063,6 @@ snapshots:
15081
15063
 
15082
15064
  yocto-queue@0.1.0: {}
15083
15065
 
15084
- zova-core@5.1.91(typescript@5.9.3):
15085
- dependencies:
15086
- '@cabloy/compose': link:packages-utils/compose
15087
- '@cabloy/extend': link:packages-utils/extend
15088
- '@cabloy/json5': link:packages-utils/json5
15089
- '@cabloy/localeutil': link:packages-utils/localeutil
15090
- '@cabloy/logger': 1.1.25
15091
- '@cabloy/module-info': 2.0.3
15092
- '@cabloy/utils': link:packages-utils/utils
15093
- '@cabloy/vue-compiler-sfc': 3.5.14
15094
- '@cabloy/vue-reactivity': 3.5.16
15095
- '@cabloy/vue-router': 4.4.18(vue@3.5.43(typescript@5.9.3))
15096
- '@cabloy/vue-runtime-core': 3.5.57
15097
- '@cabloy/vue-runtime-dom': 3.5.13
15098
- '@cabloy/vue-server-renderer': 3.5.18(vue@3.5.43(typescript@5.9.3))
15099
- '@cabloy/word-utils': 2.1.14
15100
- '@cabloy/zod-errors-custom': link:packages-utils/zod-errors-custom
15101
- '@cabloy/zod-openapi': link:packages-utils/zod-openapi
15102
- '@cabloy/zod-query': link:packages-utils/zod-query
15103
- '@types/js-cookie': 3.0.6
15104
- '@types/ms': 2.1.0
15105
- '@vue/shared': 3.5.36
15106
- deep-equal: 2.2.3
15107
- ms: 2.1.3
15108
- reflect-metadata: 0.2.2
15109
- vue: 3.5.43(typescript@5.9.3)
15110
- vue-plugin-render-freeze: 2.0.4(vue@3.5.43(typescript@5.9.3))
15111
- zod: '@cabloy/zod@4.3.8'
15112
- transitivePeerDependencies:
15113
- - typescript
15114
-
15115
15066
  zova-core@5.1.92(patch_hash=144450bd7a567a6067e5857c0cf4c780981b7e90bc48745c09e1696a9b6f1b97)(typescript@5.9.3):
15116
15067
  dependencies:
15117
15068
  '@cabloy/compose': link:packages-utils/compose
@@ -15143,17 +15094,6 @@ snapshots:
15143
15094
  transitivePeerDependencies:
15144
15095
  - typescript
15145
15096
 
15146
- zova-jsx@1.1.91(typescript@5.9.3):
15147
- dependencies:
15148
- '@cabloy/compose': link:packages-utils/compose
15149
- '@cabloy/utils': link:packages-utils/utils
15150
- '@cabloy/word-utils': 2.1.14
15151
- typestyle: 2.4.0
15152
- vue: 3.5.43(typescript@5.9.3)
15153
- zova-core: 5.1.91(typescript@5.9.3)
15154
- transitivePeerDependencies:
15155
- - typescript
15156
-
15157
15097
  zova-jsx@1.1.92(typescript@5.9.3):
15158
15098
  dependencies:
15159
15099
  '@cabloy/compose': link:packages-utils/compose
@@ -15226,8 +15166,6 @@ snapshots:
15226
15166
 
15227
15167
  zova-module-a-pay@5.0.9: {}
15228
15168
 
15229
- zova-module-a-router@5.1.40: {}
15230
-
15231
15169
  zova-module-a-router@5.1.41: {}
15232
15170
 
15233
15171
  zova-module-a-routerstack@5.1.29: {}
@@ -15267,22 +15205,6 @@ snapshots:
15267
15205
  '@cabloy/zod-query': link:packages-utils/zod-query
15268
15206
  zod: '@cabloy/zod@4.3.8'
15269
15207
 
15270
- zova-module-a-zova@5.1.107(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3)):
15271
- dependencies:
15272
- '@cabloy/compose': link:packages-utils/compose
15273
- '@cabloy/deps': link:packages-utils/deps
15274
- '@cabloy/json5': link:packages-utils/json5
15275
- '@cabloy/module-info': 2.0.3
15276
- '@cabloy/utils': link:packages-utils/utils
15277
- '@cabloy/vue-router': 4.4.18(vue@3.5.43(typescript@5.9.3))
15278
- '@cabloy/word-utils': 2.1.14
15279
- defu: 6.1.7
15280
- luxon: 3.7.2
15281
- zova-jsx: 1.1.91(typescript@5.9.3)
15282
- transitivePeerDependencies:
15283
- - typescript
15284
- - vue
15285
-
15286
15208
  zova-module-a-zova@5.1.108(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3)):
15287
15209
  dependencies:
15288
15210
  '@cabloy/compose': link:packages-utils/compose
@@ -15303,39 +15225,6 @@ snapshots:
15303
15225
 
15304
15226
  zova-module-rest-resource@5.1.55: {}
15305
15227
 
15306
- zova-suite-a-zova@5.1.164(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3)):
15307
- dependencies:
15308
- zova-module-a-api: 5.1.22
15309
- zova-module-a-app: 5.1.26
15310
- zova-module-a-bean: 5.1.36
15311
- zova-module-a-behavior: 5.1.26
15312
- zova-module-a-behaviors: 5.1.22
15313
- zova-module-a-command: 5.1.35
15314
- zova-module-a-fetch: 5.1.25
15315
- zova-module-a-form: 5.1.51(vue@3.5.43(typescript@5.9.3))
15316
- zova-module-a-icon: 5.1.27
15317
- zova-module-a-interceptor: 5.1.31
15318
- zova-module-a-logger: 5.1.28
15319
- zova-module-a-meta: 5.1.22
15320
- zova-module-a-model: 5.1.37(vue@3.5.43(typescript@5.9.3))
15321
- zova-module-a-openapi: 5.1.54
15322
- zova-module-a-router: 5.1.40
15323
- zova-module-a-routerstack: 5.1.29
15324
- zova-module-a-routertabs: 5.1.34
15325
- zova-module-a-ssr: 5.1.40
15326
- zova-module-a-ssrhmr: 5.1.23
15327
- zova-module-a-ssrserver: 5.1.26
15328
- zova-module-a-style: 5.1.35
15329
- zova-module-a-table: 5.1.43(vue@3.5.43(typescript@5.9.3))
15330
- zova-module-a-zod: 5.1.37
15331
- zova-module-a-zova: 5.1.107(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
15332
- transitivePeerDependencies:
15333
- - '@vue/composition-api'
15334
- - debug
15335
- - supports-color
15336
- - typescript
15337
- - vue
15338
-
15339
15228
  zova-suite-a-zova@5.1.165(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3)):
15340
15229
  dependencies:
15341
15230
  zova-module-a-api: 5.1.22
@@ -15369,17 +15258,6 @@ snapshots:
15369
15258
  - typescript
15370
15259
  - vue
15371
15260
 
15372
- zova@5.1.165(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3)):
15373
- dependencies:
15374
- zova-core: 5.1.91(typescript@5.9.3)
15375
- zova-suite-a-zova: 5.1.164(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
15376
- transitivePeerDependencies:
15377
- - '@vue/composition-api'
15378
- - debug
15379
- - supports-color
15380
- - typescript
15381
- - vue
15382
-
15383
15261
  zova@5.1.166(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3)):
15384
15262
  dependencies:
15385
15263
  zova-core: 5.1.92(patch_hash=144450bd7a567a6067e5857c0cf4c780981b7e90bc48745c09e1696a9b6f1b97)(typescript@5.9.3)
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-version",
3
- "version": "5.1.16",
3
+ "version": "5.1.17",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "vona-module-a-version",
6
6
  "keywords": [
@@ -0,0 +1,47 @@
1
+ import { createHash } from 'node:crypto';
2
+
3
+ const DATABASE_NAME_MAX_BYTES = 63;
4
+ const APP_NAME_MAX_BYTES = 13;
5
+ const HASH_LENGTH = 10;
6
+ const TIMESTAMP_LENGTH = 15;
7
+
8
+ export function getDatabaseTestPrefix(appName: string, scope: string): string {
9
+ const readablePrefix = getReadablePrefix(appName, scope);
10
+ if (Buffer.byteLength(readablePrefix, 'utf8') + TIMESTAMP_LENGTH <= DATABASE_NAME_MAX_BYTES) {
11
+ return readablePrefix;
12
+ }
13
+
14
+ const appHead = truncateUtf8(appName, APP_NAME_MAX_BYTES);
15
+ const scopeKind = scope === 'share' ? 's' : 'i';
16
+ const namespaceHash = hash(`${appName}\0${scope}`);
17
+ return `vona-test-${appHead}-${scopeKind}-${namespaceHash}-`;
18
+ }
19
+
20
+ export function createDatabaseTestName(databasePrefix: string, timestamp: string): string {
21
+ const databaseName = `${databasePrefix}${timestamp}`;
22
+ if (Buffer.byteLength(databaseName, 'utf8') > DATABASE_NAME_MAX_BYTES) {
23
+ throw new Error(`test database name exceeds ${DATABASE_NAME_MAX_BYTES} bytes`);
24
+ }
25
+ return databaseName;
26
+ }
27
+
28
+ function getReadablePrefix(appName: string, scope: string): string {
29
+ if (scope === 'share') return `vona-test-${appName}-s-`;
30
+ return `vona-test-${appName}-i-${scope.slice('isolate-'.length)}-`;
31
+ }
32
+
33
+ function hash(value: string): string {
34
+ return createHash('sha256').update(value).digest('base64url').slice(0, HASH_LENGTH);
35
+ }
36
+
37
+ function truncateUtf8(value: string, maxBytes: number): string {
38
+ let result = '';
39
+ let bytes = 0;
40
+ for (const char of value) {
41
+ const charBytes = Buffer.byteLength(char, 'utf8');
42
+ if (bytes + charBytes > maxBytes) break;
43
+ result += char;
44
+ bytes += charBytes;
45
+ }
46
+ return result;
47
+ }
@@ -7,6 +7,8 @@ import { DateTime } from 'luxon';
7
7
  import { BeanBase } from 'vona';
8
8
  import { Service } from 'vona-module-a-bean';
9
9
 
10
+ import { createDatabaseTestName, getDatabaseTestPrefix } from '../lib/databaseTestName.ts';
11
+
10
12
  const __separator = '-';
11
13
  const __timeFormat = `yyyyMMdd${__separator}HHmmss`;
12
14
 
@@ -20,8 +22,8 @@ export class ServiceDatabase extends BeanBase {
20
22
  instanceName?: keyof IInstanceRecord,
21
23
  configInstanceBase?: ConfigInstanceBase,
22
24
  ) {
23
- const prefix = configInstanceBase?.isolate ? `isolate${__separator}${instanceName}` : 'share';
24
- return `vona${__separator}test${__separator}${this.app.name}${__separator}${prefix}${__separator}`;
25
+ const scope = configInstanceBase?.isolate ? `isolate${__separator}${instanceName}` : 'share';
26
+ return getDatabaseTestPrefix(this.app.name, scope);
25
27
  }
26
28
 
27
29
  public async databaseInitStartup() {
@@ -60,7 +62,10 @@ export class ServiceDatabase extends BeanBase {
60
62
  configInstanceBase?: ConfigInstanceBase,
61
63
  ) {
62
64
  const databasePrefix = this.getDatabasePrefix(instanceName, configInstanceBase);
63
- const databaseName = `${databasePrefix}${DateTime.now().toFormat(__timeFormat)}`;
65
+ const databaseName = createDatabaseTestName(
66
+ databasePrefix,
67
+ DateTime.now().toFormat(__timeFormat),
68
+ );
64
69
  return await client.connection.schema.createDatabase(databaseName);
65
70
  }
66
71
 
@@ -0,0 +1,72 @@
1
+ import assert from 'node:assert';
2
+ import { describe, it } from 'node:test';
3
+
4
+ import { createDatabaseTestName, getDatabaseTestPrefix } from '../src/lib/databaseTestName.ts';
5
+
6
+ const timestamp = '20260923-104500';
7
+
8
+ describe('databaseTestName', () => {
9
+ it('keeps a short shared app name readable with its shared marker', () => {
10
+ const prefix = getDatabaseTestPrefix('cabloy-start', 'share');
11
+ const databaseName = createDatabaseTestName(prefix, timestamp);
12
+
13
+ assert.equal(prefix, 'vona-test-cabloy-start-s-');
14
+ assert.equal(databaseName, 'vona-test-cabloy-start-s-20260923-104500');
15
+ assert.ok(Buffer.byteLength(databaseName, 'utf8') <= 63);
16
+ });
17
+
18
+ it('keeps a short isolated app name readable with its isolate identity', () => {
19
+ const sharedPrefix = getDatabaseTestPrefix('cabloy-start', 'share');
20
+ const isolatedPrefix = getDatabaseTestPrefix('cabloy-start', 'isolate-isolateTest');
21
+
22
+ assert.equal(isolatedPrefix, 'vona-test-cabloy-start-i-isolateTest-');
23
+ assert.notEqual(sharedPrefix, isolatedPrefix);
24
+ });
25
+
26
+ it('uses the readable format through 63 bytes and the fallback at 64 bytes', () => {
27
+ const readableAppName = 'a'.repeat(35);
28
+ const fallbackAppName = `${readableAppName}a`;
29
+ const readablePrefix = getDatabaseTestPrefix(readableAppName, 'share');
30
+ const fallbackPrefix = getDatabaseTestPrefix(fallbackAppName, 'share');
31
+ const readableName = createDatabaseTestName(readablePrefix, timestamp);
32
+ const fallbackName = createDatabaseTestName(fallbackPrefix, timestamp);
33
+
34
+ assert.equal(readablePrefix, `vona-test-${readableAppName}-s-`);
35
+ assert.equal(Buffer.byteLength(readableName, 'utf8'), 63);
36
+ assert.match(fallbackPrefix, /^vona-test-a{13}-s-[\w-]{10}-$/);
37
+ assert.ok(Buffer.byteLength(fallbackName, 'utf8') <= 63);
38
+ });
39
+
40
+ it('uses UTF-8 byte length and preserves code points in the fallback', () => {
41
+ const readableAppName = '商'.repeat(11);
42
+ const fallbackAppName = `${readableAppName}店`;
43
+ const readablePrefix = getDatabaseTestPrefix(readableAppName, 'share');
44
+ const fallbackPrefix = getDatabaseTestPrefix(fallbackAppName, 'share');
45
+ const fallbackName = createDatabaseTestName(fallbackPrefix, timestamp);
46
+
47
+ assert.equal(readablePrefix, `vona-test-${readableAppName}-s-`);
48
+ assert.match(fallbackPrefix, /^vona-test-商{4}-s-[\w-]{10}-$/);
49
+ assert.ok(!fallbackPrefix.includes('�'));
50
+ assert.ok(Buffer.byteLength(fallbackName, 'utf8') <= 63);
51
+ });
52
+
53
+ it('distinguishes fallback namespaces with the same visible app head and distinct scopes', () => {
54
+ const appHead = 'same-readable';
55
+ const first = getDatabaseTestPrefix(
56
+ `${appHead}-worktree-one-that-overflows`,
57
+ 'isolate-isolateTest',
58
+ );
59
+ const second = getDatabaseTestPrefix(
60
+ `${appHead}-worktree-two-that-overflows`,
61
+ 'isolate-isolateTest',
62
+ );
63
+ const third = getDatabaseTestPrefix(
64
+ `${appHead}-worktree-one-that-overflows`,
65
+ 'isolate-isolatePeerTest',
66
+ );
67
+
68
+ assert.notEqual(first, second);
69
+ assert.notEqual(first, third);
70
+ assert.match(first, /-i-[\w-]{10}-$/);
71
+ });
72
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-suite-a-vona",
3
- "version": "5.1.89",
3
+ "version": "5.1.90",
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.110",
3
+ "version": "1.2.111",
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.108"
47
+ "zova-cli-set-front": "^1.2.109"
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.108",
3
+ "version": "1.2.109",
4
4
  "gitHead": "6f675a8cc46d596142c591c28a40cc4d82fcc6cc",
5
5
  "description": "zova cli-set-front",
6
6
  "keywords": [
@@ -70,7 +70,7 @@
70
70
  "vite": "^8.0.14",
71
71
  "yaml": "^2.8.3",
72
72
  "zova-openapi": "^1.1.17",
73
- "zova-vite": "^1.1.46"
73
+ "zova-vite": "^1.1.47"
74
74
  },
75
75
  "devDependencies": {
76
76
  "clean-package": "^2.2.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-vite",
3
- "version": "1.1.46",
3
+ "version": "1.1.47",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "zova vite",
6
6
  "keywords": [
@@ -58,11 +58,13 @@ function _collectCss(
58
58
  }
59
59
  });
60
60
 
61
- styles.forEach((content, id) => {
62
- result = result.concat(
63
- `<style vite-css-module-id="${hashCode(id)}">${(content || '').replaceAll('\n', '')}</style>`,
64
- );
65
- });
61
+ Array.from(styles.entries())
62
+ .reverse()
63
+ .forEach(([id, content]) => {
64
+ result = result.concat(
65
+ `<style vite-css-module-id="${hashCode(id)}">${(content || '').replaceAll('\n', '')}</style>`,
66
+ );
67
+ });
66
68
 
67
69
  return result;
68
70
  }
@@ -4,14 +4,6 @@ import AvatarUser from '../../assets/img/avatar_user.png';
4
4
 
5
5
  export const config = (_sys: ZovaSys) => {
6
6
  return {
7
- layout: {
8
- sidebar: {
9
- width: 300,
10
- },
11
- navbar: {
12
- height: 132,
13
- },
14
- },
15
7
  avatar: {
16
8
  empty: AvatarUser,
17
9
  },
@@ -4,6 +4,7 @@ import { getBodyReadyObserverScript } from 'zova-module-a-ssr';
4
4
 
5
5
  export interface IServiceSsrLayoutOptions {
6
6
  bodyReadyObserver?: boolean;
7
+ sidebarWidth?: number;
7
8
  sidebarBreakpoint?: number;
8
9
  sidebarLeftOpenPCCapability?: boolean;
9
10
  sidebarLeftOpenPCFallback?: boolean;
@@ -81,12 +82,10 @@ export class ServiceSsrLayout extends BeanBase {
81
82
  }
82
83
  const __domDrawerContainer=__targets?.drawerContainer;
83
84
  const __domDrawer=__targets?.drawer;
84
- const sidebarWidth = '${this.scope.config.layout.sidebar.width}px';
85
- const navbarHeight = '${this.scope.config.layout.navbar.height}px';
86
85
  if(!__domDrawerContainer||!__domDrawer)return;
87
86
  if(__leftDrawerOpen){
88
87
  __domDrawer.style.transform='translateX(0px)';
89
- __domDrawer.style.width=sidebarWidth;
88
+ ${this.options?.sidebarWidth !== undefined ? `__domDrawer.style.width='${this.options.sidebarWidth}px';` : ''}
90
89
  __domDrawerContainer.classList.add('drawer-open');
91
90
  }else{
92
91
  }
@@ -27,6 +27,7 @@ export class ControllerLayoutAdmin extends BeanControllerBase {
27
27
  const sidebar = this.scope.config.layout.sidebar;
28
28
  return usePrepareArg({
29
29
  bodyReadyObserver: sidebar.bodyReadyObserver,
30
+ sidebarWidth: sidebar.width,
30
31
  sidebarBreakpoint: sidebar.breakpoint,
31
32
  sidebarLeftOpenPCCapability: sidebar.leftOpenPCCapability,
32
33
  sidebarLeftOpenPCFallback: sidebar.leftOpenPCFallback,
@@ -10,10 +10,7 @@ export class RenderSidebar extends BeanRenderBase {
10
10
 
11
11
  public render() {
12
12
  return (
13
- <div
14
- class="drawer-side"
15
- style={{ width: `${this.$scopeBase.config.layout.sidebar.width}px` }}
16
- >
13
+ <div class="drawer-side" style={{ width: `${this.scope.config.layout.sidebar.width}px` }}>
17
14
  <label htmlFor="my-drawer-2" aria-label="close sidebar" class="drawer-overlay"></label>
18
15
  {this.$$r.$$renderMenu.render()}
19
16
  </div>
@@ -4,11 +4,15 @@ export const config = (_sys: ZovaSys) => {
4
4
  return {
5
5
  layout: {
6
6
  sidebar: {
7
+ width: 300,
7
8
  bodyReadyObserver: true,
8
9
  breakpoint: 1023,
9
10
  leftOpenPCCapability: true,
10
11
  leftOpenPCFallback: true,
11
12
  },
13
+ navbar: {
14
+ height: 132,
15
+ },
12
16
  },
13
17
  tabs: {
14
18
  scene: '',
@@ -26,6 +26,7 @@ export class ControllerLayoutWeb extends BeanControllerBase {
26
26
  const sidebar = this.scope.config.layout.sidebar;
27
27
  return usePrepareArg({
28
28
  bodyReadyObserver: sidebar.bodyReadyObserver,
29
+ sidebarWidth: sidebar.width,
29
30
  sidebarBreakpoint: sidebar.breakpoint,
30
31
  sidebarLeftOpenPCCapability: sidebar.leftOpenPCCapability,
31
32
  sidebarLeftOpenPCFallback: sidebar.leftOpenPCFallback,
@@ -61,8 +61,22 @@ export function richTextContentStyle(): NestedCSSProperties {
61
61
  gap: '0.5rem',
62
62
  },
63
63
  '& ul[data-type="taskList"] li > label': {
64
- lineHeight: 1.65,
65
- paddingTop: '0.2rem',
64
+ blockSize: '1em',
65
+ display: 'flex',
66
+ flex: '0 0 1em',
67
+ inlineSize: '1em',
68
+ lineHeight: 1,
69
+ margin: 0,
70
+ marginBlockStart: '0.325em',
71
+ padding: 0,
72
+ },
73
+ '& ul[data-type="taskList"] li > label > input[type="checkbox"]': {
74
+ blockSize: '1em',
75
+ boxSizing: 'border-box',
76
+ display: 'block',
77
+ flex: '0 0 1em',
78
+ inlineSize: '1em',
79
+ margin: 0,
66
80
  },
67
81
  '& ul[data-type="taskList"] li > div': {
68
82
  flex: 1,