cabloy 5.1.131 → 5.1.133

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 (210) hide show
  1. package/.cabloy-version +1 -1
  2. package/.claude/skills/cabloy-worktree-environment/SKILL.md +6 -6
  3. package/.claude/skills/cabloy-worktree-environment/evals/evals.json +2 -2
  4. package/.github/workflows/vona-test-pg.yml +1 -1
  5. package/.github/workflows/vona-test-sqlite3.yml +1 -1
  6. package/CHANGELOG.md +28 -0
  7. package/cabloy-docs/backend/dto-guide.md +39 -4
  8. package/cabloy-docs/backend/dto-infer-generation.md +29 -0
  9. package/cabloy-docs/backend/openapi-guide.md +16 -0
  10. package/cabloy-docs/backend/validation-guide.md +45 -0
  11. package/cabloy-docs/frontend/environment-config-guide.md +8 -15
  12. package/cabloy-docs/frontend/navigation-guards-guide.md +3 -3
  13. package/cabloy-docs/frontend/page-route-guide.md +4 -4
  14. package/cabloy-docs/frontend/ssr-env.md +22 -29
  15. package/cabloy-docs/frontend/theme-guide.md +4 -4
  16. package/cabloy-docs/frontend/zova-router-under-the-hood.md +1 -1
  17. package/cabloy-docs/fullstack/deploy-cloudflare-docker.md +6 -6
  18. package/cabloy-docs/fullstack/parallel-worktree-environment.md +2 -2
  19. package/e2e/specs/a-commerce/commerce.spec.ts +479 -17
  20. package/e2e/specs/cabloy-basic/basic.spec.ts +30 -5
  21. package/package.json +7 -7
  22. package/vona/.claude/skills/detect-ssr-leak/SKILL.md +1 -1
  23. package/vona/packages-vona/vona/package.json +1 -1
  24. package/vona/pnpm-lock.yaml +120 -10
  25. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuCreate.tsx +3 -1
  26. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectResItem.tsx +13 -1
  27. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuUpdate.tsx +3 -1
  28. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuView.tsx +13 -1
  29. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/entity/sku.tsx +6 -0
  30. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/skuPresentation.test.ts +227 -0
  31. package/vona/src/suite/a-commerce/modules/commerce-member/src/.metadata/index.ts +46 -36
  32. package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressSelectResItem.tsx +5 -13
  33. package/vona/src/suite/a-commerce/modules/commerce-member/src/service/address.ts +16 -1
  34. package/vona/src/suite/a-commerce/modules/commerce-member/test/addressPresentation.test.ts +210 -0
  35. package/vona/src/suite/a-commerce/modules/commerce-payment/src/service/commercePayScene.ts +13 -2
  36. package/vona/src/suite/a-commerce/modules/commerce-payment/test/paymentAttempt.test.ts +12 -0
  37. package/vona/src/suite/a-commerce/modules/commerce-promotion/src/service/coupon.ts +7 -1
  38. package/vona/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +45 -2
  39. package/vona/src/suite/a-commerce/modules/commerce-trade/src/config/locale/en-us.ts +23 -0
  40. package/vona/src/suite/a-commerce/modules/commerce-trade/src/config/locale/zh-cn.ts +23 -0
  41. package/vona/src/suite/a-commerce/modules/commerce-trade/src/controller/order.ts +31 -0
  42. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/orderAdminLineBase.tsx +56 -0
  43. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/orderAdminLineResItem.tsx +17 -0
  44. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/orderAdminLineView.tsx +13 -0
  45. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/orderSelectResItem.tsx +26 -2
  46. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/orderView.tsx +197 -3
  47. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/refundRecoveryAction.tsx +19 -0
  48. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/refundRecoveryView.tsx +70 -0
  49. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditSelectResItem.tsx +7 -1
  50. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditView.tsx +21 -1
  51. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceSelectResItem.tsx +7 -1
  52. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceView.tsx +3 -1
  53. package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/order.tsx +12 -0
  54. package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/order.ts +15 -2
  55. package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/order.ts +215 -3
  56. package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/stockAudit.ts +25 -2
  57. package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/stockBalance.ts +14 -3
  58. package/vona/src/suite/a-commerce/modules/commerce-trade/test/checkoutReservation.test.ts +4 -4
  59. package/vona/src/suite/a-commerce/modules/commerce-trade/test/orderPresentation.test.ts +358 -0
  60. package/vona/src/suite/a-commerce/modules/commerce-trade/test/orderSnapshot.test.ts +8 -8
  61. package/vona/src/suite/a-commerce/modules/commerce-trade/test/paymentOutcome.test.ts +5 -1
  62. package/vona/src/suite/a-commerce/modules/commerce-trade/test/refundLifecycle.test.ts +50 -1
  63. package/vona/src/suite/a-commerce/modules/commerce-trade/test/stockPresentation.test.ts +324 -0
  64. package/vona/src/suite/a-home/modules/home-base/package.json +3 -2
  65. package/vona/src/suite/a-home/modules/home-base/src/.metadata/index.ts +93 -16
  66. package/vona/src/suite/a-home/modules/home-base/src/controller/siteCatalog.ts +21 -0
  67. package/vona/src/suite/a-home/modules/home-base/src/dto/siteCatalogSelectRes.ts +11 -0
  68. package/vona/src/suite/a-home/modules/home-base/src/dto/siteCatalogSelectResItem.ts +15 -0
  69. package/vona/src/suite/a-home/modules/home-base/src/service/siteCatalog.ts +29 -0
  70. package/vona/src/suite/cabloy-basic/modules/basic-siteadmin/src/bean/ssrSite.admin.ts +3 -0
  71. package/vona/src/suite/cabloy-basic/modules/basic-siteadmin/src/config/locale/en-us.ts +1 -0
  72. package/vona/src/suite/cabloy-basic/modules/basic-siteadmin/src/config/locale/zh-cn.ts +1 -0
  73. package/vona/src/suite/cabloy-basic/modules/basic-siteweb/src/bean/ssrSite.web.ts +3 -0
  74. package/vona/src/suite/cabloy-basic/modules/basic-siteweb/src/config/locale/en-us.ts +1 -0
  75. package/vona/src/suite/cabloy-basic/modules/basic-siteweb/src/config/locale/zh-cn.ts +1 -0
  76. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/cli/ssrSite/boilerplate/{{sceneName}}.{{beanName}}.ts_ +1 -0
  77. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/package.json +1 -1
  78. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/env.ts +1 -3
  79. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/ssrSite.ts +2 -1
  80. package/vona/src/suite-vendor/a-cabloy/package.json +1 -1
  81. package/vona/src/suite-vendor/a-pay/modules/a-pay/package.json +1 -1
  82. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/.metadata/index.ts +67 -0
  83. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/bean/bean.payProvider.ts +1 -0
  84. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/bean/bean.payScene.ts +5 -4
  85. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/bean/meta.index.ts +8 -0
  86. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/bean/meta.version.ts +22 -0
  87. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/bean/schedule.providerOperationDispatch.ts +1 -1
  88. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/entity/paymentSession.tsx +6 -0
  89. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/entity/providerOperation.tsx +3 -0
  90. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/entity/providerOperationRecoveryAudit.tsx +53 -0
  91. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/entity/refundOperation.tsx +6 -0
  92. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/model/providerOperationRecoveryAudit.ts +12 -0
  93. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/service/paymentSession.ts +6 -2
  94. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/service/providerOperation.ts +236 -30
  95. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/service/refundOperation.ts +8 -5
  96. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/service/webhook.ts +34 -0
  97. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/types/payProvider.ts +4 -0
  98. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/types/payment.ts +6 -0
  99. package/vona/src/suite-vendor/a-pay/modules/pay-mock/package.json +1 -1
  100. package/vona/src/suite-vendor/a-pay/modules/pay-mock/src/bean/payProvider.mock.ts +15 -7
  101. package/vona/src/suite-vendor/a-pay/modules/pay-mock/src/service/payMock.ts +9 -5
  102. package/vona/src/suite-vendor/a-pay/modules/pay-paypal/package.json +1 -1
  103. package/vona/src/suite-vendor/a-pay/modules/pay-paypal/src/bean/payProvider.paypal.ts +289 -86
  104. package/vona/src/suite-vendor/a-pay/modules/pay-paypal/src/lib/paypalGateway.ts +9 -1
  105. package/vona/src/suite-vendor/a-pay/modules/pay-stripe/package.json +1 -1
  106. package/vona/src/suite-vendor/a-pay/package.json +5 -5
  107. package/vona/src/suite-vendor/a-vona/modules/a-openapi/package.json +1 -1
  108. package/vona/src/suite-vendor/a-vona/modules/a-openapi/src/types/rest.ts +1 -0
  109. package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/package.json +1 -1
  110. package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/src/lib/utils.ts +12 -0
  111. package/vona/src/suite-vendor/a-vona/modules/a-orm/package.json +1 -1
  112. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoCreate.ts +5 -1
  113. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoUpdate.ts +5 -1
  114. package/vona/src/suite-vendor/a-vona/modules/a-validation/package.json +1 -1
  115. package/vona/src/suite-vendor/a-vona/modules/a-validation/src/bean/bean.validator.ts +60 -1
  116. package/vona/src/suite-vendor/a-vona/modules/a-web/package.json +1 -1
  117. package/vona/src/suite-vendor/a-vona/modules/a-web/src/lib/decorator/bean.ts +7 -4
  118. package/vona/src/suite-vendor/a-vona/modules/a-web/src/types/dto.ts +2 -1
  119. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  120. package/zova/env/.env +3 -5
  121. package/zova/env/.env.cabloyBasicAdmin +1 -4
  122. package/zova/env/.env.cabloyBasicWeb +1 -5
  123. package/zova/env/.env.cabloyCommerce +1 -5
  124. package/zova/env/.env.cabloyCommerceAdmin +1 -4
  125. package/zova/env/.env.ssr.admin +1 -4
  126. package/zova/env/.env.ssr.web +1 -5
  127. package/zova/package.original.json +1 -1
  128. package/zova/packages-utils/zova-jsx/package.json +2 -2
  129. package/zova/packages-zova/zova/package.json +3 -3
  130. package/zova/packages-zova/zova-core/package.json +2 -1
  131. package/zova/packages-zova/zova-core/src/core/component/locale.ts +10 -4
  132. package/zova/packages-zova/zova-core/src/core/sys/config.ts +14 -6
  133. package/zova/packages-zova/zova-core/src/types/utils/env.ts +4 -2
  134. package/zova/pnpm-lock.yaml +24 -21
  135. package/zova/src/front/config/config/config.ts +22 -7
  136. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/routes.ts +2 -2
  137. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/schemas.ts +16 -8
  138. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/types.ts +150 -216
  139. package/zova/src/suite/a-commerce/modules/commerce-member/src/model/addressMine.ts +1 -2
  140. package/zova/src/suite/a-commerce/modules/commerce-member/src/page/address/controller.tsx +5 -8
  141. package/zova/src/suite/a-commerce/modules/commerce-member/src/routes.ts +1 -1
  142. package/zova/src/suite/a-commerce/modules/commerce-promotion/src/model/coupon.ts +1 -2
  143. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/routes.ts +3 -1
  144. package/zova/src/suite/a-commerce/modules/commerce-trade/cli/openapi.config.ts +3 -0
  145. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/commerceTradeOrder.ts +72 -0
  146. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/schemas.ts +8 -0
  147. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/types.ts +226 -16
  148. package/zova/src/suite/a-commerce/modules/commerce-trade/src/apiSchema/commerceTradeOrder.ts +15 -0
  149. package/zova/src/suite/a-commerce/modules/commerce-trade/src/component/tableCellActionRefund/controller.tsx +155 -36
  150. package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/en-us.ts +7 -0
  151. package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/zh-cn.ts +7 -0
  152. package/zova/src/suite/a-commerce/modules/commerce-trade/src/model/cart.ts +3 -4
  153. package/zova/src/suite/a-commerce/modules/commerce-trade/src/model/order.ts +42 -0
  154. package/zova/src/suite/a-commerce/modules/commerce-trade/src/model/orderMine.ts +2 -4
  155. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/cart/controller.tsx +5 -1
  156. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/checkout/controller.tsx +14 -10
  157. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/order/controller.tsx +5 -8
  158. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/orders/controller.tsx +5 -8
  159. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/payment/controller.tsx +151 -24
  160. package/zova/src/suite/a-commerce/modules/commerce-trade/src/routes.ts +5 -5
  161. package/zova/src/suite/a-demo/modules/demo-basic/src/routes.ts +26 -7
  162. package/zova/src/suite/a-demo/modules/demo-todo/src/routes.ts +2 -2
  163. package/zova/src/suite/a-devui/modules/devui-adapter/src/bean/meta.themeHandler.ts +1 -1
  164. package/zova/src/suite/a-home/modules/home-base/package.json +1 -0
  165. package/zova/src/suite/a-home/modules/home-base/src/routes.ts +5 -0
  166. package/zova/src/suite/a-home/modules/home-base/src/service/routerGuards.ts +1 -1
  167. package/zova/src/suite/a-home/modules/home-base/src/service/ssrLayout.ts +18 -14
  168. package/zova/src/suite/a-home/modules/home-indexadmin/src/routes.ts +1 -1
  169. package/zova/src/suite/a-home/modules/home-indexweb/src/routes.ts +1 -0
  170. package/zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/controller.tsx +12 -4
  171. package/zova/src/suite/a-home/modules/home-layoutadmin/src/config/config.ts +8 -0
  172. package/zova/src/suite/a-home/modules/home-layoutadmin/src/model/layout.ts +5 -8
  173. package/zova/src/suite/a-home/modules/home-layoutempty/src/.metadata/index.ts +10 -3
  174. package/zova/src/suite/a-home/modules/home-layoutempty/src/component/layoutEmpty/controller.tsx +9 -3
  175. package/zova/src/suite/a-home/modules/home-layoutempty/src/config/config.ts +12 -0
  176. package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/controller.tsx +13 -8
  177. package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.header.tsx +1 -1
  178. package/zova/src/suite/a-home/modules/home-layoutweb/src/config/config.ts +4 -0
  179. package/zova/src/suite/a-home/modules/home-layoutweb/src/model/layout.ts +5 -8
  180. package/zova/src/suite/a-home/modules/home-login/src/routes.ts +1 -0
  181. package/zova/src/suite/a-home/modules/home-passport/src/model/passport.ts +2 -3
  182. package/zova/src/suite/cabloy-basic/modules/basic-metrics/src/routes.ts +3 -1
  183. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  184. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +1 -1
  185. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/routes.ts +3 -0
  186. package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
  187. package/zova/src/suite-vendor/a-pay/modules/a-pay/package.json +1 -1
  188. package/zova/src/suite-vendor/a-pay/modules/a-pay/src/model/paymentSession.ts +2 -2
  189. package/zova/src/suite-vendor/a-pay/package.json +2 -2
  190. package/zova/src/suite-vendor/a-zova/modules/a-interceptor/package.json +1 -1
  191. package/zova/src/suite-vendor/a-zova/modules/a-interceptor/src/bean/interceptor.jwt.ts +1 -1
  192. package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
  193. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/model/sdk.ts +1 -1
  194. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/rest.ts +1 -0
  195. package/zova/src/suite-vendor/a-zova/modules/a-ssr/package.json +1 -1
  196. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/config/config.ts +1 -17
  197. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/bodyReadyObserver.ts +27 -0
  198. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/index.ts +2 -0
  199. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/ssr.ts +33 -0
  200. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/ssrMetaStore.ts +3 -35
  201. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/ssrProfile.ts +38 -0
  202. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/monkey.ts +10 -0
  203. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/types/config.ts +3 -10
  204. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/types/ssr.ts +17 -8
  205. package/zova/src/suite-vendor/a-zova/modules/a-ssrserver/package.json +1 -1
  206. package/zova/src/suite-vendor/a-zova/modules/a-ssrserver/src/service/ssrHandler.ts +33 -18
  207. package/zova/src/suite-vendor/a-zova/modules/a-style/package.json +1 -1
  208. package/zova/src/suite-vendor/a-zova/modules/a-style/src/bean/bean.theme.ts +2 -2
  209. package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
  210. package/zova/src/suite-vendor/a-zova/package.json +7 -7
@@ -0,0 +1,324 @@
1
+ import type { DtoStockAdjust } from 'vona-module-commerce-trade';
2
+
3
+ import assert from 'node:assert';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { after, before, describe, it } from 'node:test';
6
+ import { acquireTestLock, app } from 'vona-mock';
7
+ import {
8
+ DtoStockAuditSelectResItem,
9
+ DtoStockAuditView,
10
+ DtoStockBalanceSelectResItem,
11
+ DtoStockBalanceView,
12
+ } from 'vona-module-commerce-trade';
13
+
14
+ function findComponent(apiJson: any, predicate: (properties: any) => boolean) {
15
+ return Object.values(apiJson.components!.schemas as any).find(item => {
16
+ return predicate((item as any).properties);
17
+ }) as any;
18
+ }
19
+
20
+ function getListFilter(component: any) {
21
+ const page = component?.rest?.blocks?.[0];
22
+ const [filter, table, pager] = page?.options?.blocks ?? [];
23
+ assert.equal(page?.render, 'basic-page:blockPage');
24
+ assert.equal(filter?.render, 'basic-page:blockFilter');
25
+ assert.equal(table?.render, 'basic-page:blockTable');
26
+ assert.equal(pager?.render, 'basic-page:blockPager');
27
+ return filter;
28
+ }
29
+
30
+ function getEntryToolbar(component: any) {
31
+ const pageEntry = component?.rest?.blocks?.[0];
32
+ const formBlock = pageEntry?.options?.blocks?.[0];
33
+ const toolbarBlock = pageEntry?.options?.blocks?.[1];
34
+ assert.equal(pageEntry?.render, 'basic-pageentry:blockPageEntry');
35
+ assert.equal(formBlock?.render, 'basic-pageentry:blockForm');
36
+ assert.equal(toolbarBlock?.render, 'basic-pageentry:blockToolbarRow');
37
+ return toolbarBlock;
38
+ }
39
+
40
+ function assertFilter(component: any) {
41
+ const filter = getListFilter(component);
42
+ const section = filter.options.blocks[0].options.formLayout.children[0];
43
+ assert.equal(section.type, 'section');
44
+ assert.equal(section.layout, 'flow');
45
+ assert.deepEqual(
46
+ section.children.slice(0, 2).map((field: any) => field.name),
47
+ ['skuId', 'createdAt'],
48
+ );
49
+ assert.equal(section.children[2].block.render, 'basic-page:blockFilterActions');
50
+ }
51
+
52
+ interface IStockFixture {
53
+ categoryId: number;
54
+ productId: number;
55
+ skuId: number;
56
+ }
57
+
58
+ type IStockFixturePartial = Partial<IStockFixture>;
59
+
60
+ async function dropStockFixture(fixture: IStockFixturePartial | undefined) {
61
+ if (!fixture) return;
62
+ const trade = app.scope('commerce-trade');
63
+ const catalog = app.scope('commerce-catalog');
64
+ if (fixture.skuId !== undefined) {
65
+ await trade.model.stockAudit.delete({ skuId: fixture.skuId });
66
+ await trade.model.stockReservation.delete({ skuId: fixture.skuId });
67
+ await trade.model.stockBalance.delete({ skuId: fixture.skuId });
68
+ await catalog.model.sku.delete({ id: fixture.skuId });
69
+ }
70
+ if (fixture.productId !== undefined) {
71
+ await catalog.model.product.delete({ id: fixture.productId });
72
+ }
73
+ if (fixture.categoryId !== undefined) {
74
+ await catalog.model.category.delete({ id: fixture.categoryId });
75
+ }
76
+ }
77
+
78
+ async function createSku(suffix: string): Promise<IStockFixture> {
79
+ const fixture: IStockFixturePartial = {};
80
+ try {
81
+ fixture.categoryId = await app.bean.executor.performAction(
82
+ 'post',
83
+ '/commerce/catalog/category',
84
+ {
85
+ body: { name: `presentation-stock-category-${suffix}`, published: true },
86
+ },
87
+ );
88
+ fixture.productId = await app.bean.executor.performAction('post', '/commerce/catalog/product', {
89
+ body: {
90
+ categoryId: fixture.categoryId,
91
+ title: `presentation-stock-product-${suffix}`,
92
+ published: true,
93
+ },
94
+ });
95
+ fixture.skuId = await app.bean.executor.performAction('post', '/commerce/catalog/sku', {
96
+ body: {
97
+ productId: fixture.productId,
98
+ code: `presentation-stock-sku-${suffix}`,
99
+ priceCents: 100,
100
+ lifecycle: 'active',
101
+ },
102
+ });
103
+ return fixture as IStockFixture;
104
+ } catch (error) {
105
+ await dropStockFixture(fixture);
106
+ throw error;
107
+ }
108
+ }
109
+
110
+ function stockAdjust(skuId: number, suffix: string): DtoStockAdjust {
111
+ return {
112
+ skuId,
113
+ delta: 7,
114
+ reason: `presentation stock ${suffix}`,
115
+ correlationId: `presentation-stock-${suffix}`,
116
+ };
117
+ }
118
+
119
+ describe('stockPresentation.test.ts', { concurrency: false }, () => {
120
+ let releaseTestLock: (() => void) | undefined;
121
+
122
+ before(async () => {
123
+ releaseTestLock = await acquireTestLock('a-commerce');
124
+ });
125
+
126
+ after(() => {
127
+ releaseTestLock?.();
128
+ });
129
+
130
+ it('action:stock:presentationMetadata', async () => {
131
+ await app.bean.executor.mockCtx(async () => {
132
+ const balanceListJson = await app.bean.openapi.generateJsonOfClass(
133
+ DtoStockBalanceSelectResItem,
134
+ );
135
+ const balanceList = findComponent(
136
+ balanceListJson,
137
+ properties => properties?._operationsRow && properties?.skuId && properties?.onHand,
138
+ );
139
+ assert.deepEqual(Object.keys(balanceList.properties).sort(), [
140
+ '_operationsRow',
141
+ 'available',
142
+ 'id',
143
+ 'onHand',
144
+ 'reserved',
145
+ 'skuId',
146
+ ]);
147
+ assert.deepEqual(
148
+ balanceList.properties._operationsRow.rest.table.columnProps.actions.map(
149
+ (action: any) => action.render,
150
+ ),
151
+ ['basic-table:actionView'],
152
+ );
153
+ assertFilter(balanceList);
154
+
155
+ const balanceViewJson = await app.bean.openapi.generateJsonOfClass(DtoStockBalanceView);
156
+ const balanceView = findComponent(balanceViewJson, properties => {
157
+ return properties?.available && properties?.createdAt && properties?.updatedAt;
158
+ });
159
+ assert.deepEqual(Object.keys(balanceView.properties).sort(), [
160
+ 'available',
161
+ 'createdAt',
162
+ 'id',
163
+ 'onHand',
164
+ 'reserved',
165
+ 'skuId',
166
+ 'updatedAt',
167
+ ]);
168
+ assert.equal(balanceView.properties.createdAt.rest.table.render, 'basic-date:date');
169
+ assert.equal(balanceView.properties.updatedAt.rest.table.render, 'basic-date:date');
170
+ assert.equal(updatedAtVisible(balanceView), true);
171
+ assert.deepEqual(
172
+ getEntryToolbar(balanceView).options.actions.map((action: any) => action.render),
173
+ ['basic-form:actionBack'],
174
+ );
175
+
176
+ const auditListJson = await app.bean.openapi.generateJsonOfClass(DtoStockAuditSelectResItem);
177
+ const auditList = findComponent(
178
+ auditListJson,
179
+ properties => properties?._operationsRow && properties?.skuId && properties?.operation,
180
+ );
181
+ assert.deepEqual(Object.keys(auditList.properties).sort(), [
182
+ '_operationsRow',
183
+ 'createdAt',
184
+ 'delta',
185
+ 'id',
186
+ 'operation',
187
+ 'skuId',
188
+ ]);
189
+ assert.equal(auditList.properties.id.rest.table.render, 'basic-table:actionView');
190
+ assert.deepEqual(
191
+ auditList.properties._operationsRow.rest.table.columnProps.actions.map(
192
+ (action: any) => action.render,
193
+ ),
194
+ ['basic-table:actionView'],
195
+ );
196
+ assertFilter(auditList);
197
+
198
+ const auditViewJson = await app.bean.openapi.generateJsonOfClass(DtoStockAuditView);
199
+ const auditView = findComponent(auditViewJson, properties => {
200
+ return properties?.stockBalanceId && properties?.priorAvailable && properties?.actorId;
201
+ });
202
+ assert.deepEqual(Object.keys(auditView.properties).sort(), [
203
+ 'actorId',
204
+ 'available',
205
+ 'correlationId',
206
+ 'createdAt',
207
+ 'delta',
208
+ 'id',
209
+ 'onHand',
210
+ 'operation',
211
+ 'priorAvailable',
212
+ 'priorOnHand',
213
+ 'priorReserved',
214
+ 'reason',
215
+ 'reserved',
216
+ 'skuId',
217
+ 'stockBalanceId',
218
+ 'stockReservationId',
219
+ 'updatedAt',
220
+ ]);
221
+ assert.equal(auditView.properties.createdAt.rest.form.render, 'basic-date:formFieldDate');
222
+ assert.equal(auditView.properties.updatedAt.rest.form.render, 'basic-date:formFieldDate');
223
+ assert.deepEqual(
224
+ getEntryToolbar(auditView).options.actions.map((action: any) => action.render),
225
+ ['basic-form:actionBack'],
226
+ );
227
+
228
+ for (const component of [balanceList, balanceView, auditList, auditView]) {
229
+ assert.equal(component.properties.iid, undefined);
230
+ assert.equal(component.properties.deleted, undefined);
231
+ }
232
+ });
233
+ });
234
+
235
+ it('action:stock:runtimeBoundary', async () => {
236
+ await app.bean.executor.mockCtx(async () => {
237
+ let fixture: IStockFixture | undefined;
238
+ const suffix = randomUUID().slice(0, 12);
239
+ await app.bean.passport.signinMock();
240
+ try {
241
+ fixture = await createSku(suffix);
242
+ const balance: any = await app.bean.executor.performAction(
243
+ 'post',
244
+ '/commerce/trade/stockBalance/adjustStock',
245
+ { body: stockAdjust(fixture.skuId, suffix) },
246
+ );
247
+ assert.equal(balance.onHand, 7);
248
+ assert.equal(balance.reserved, 0);
249
+ assert.equal(balance.available, 7);
250
+
251
+ const balanceView: any = await app.bean.executor.performAction(
252
+ 'get',
253
+ '/commerce/trade/stockBalance/:id',
254
+ { params: { id: balance.id } },
255
+ );
256
+ assert.deepEqual(Object.keys(balanceView).sort(), [
257
+ 'available',
258
+ 'createdAt',
259
+ 'id',
260
+ 'onHand',
261
+ 'reserved',
262
+ 'skuId',
263
+ 'updatedAt',
264
+ ]);
265
+ assert.equal(balanceView.available, balanceView.onHand - balanceView.reserved);
266
+
267
+ const auditList: any = await app.bean.executor.performAction(
268
+ 'get',
269
+ '/commerce/trade/stockAudit',
270
+ {
271
+ query: { skuId: fixture.skuId },
272
+ },
273
+ );
274
+ assert.equal(auditList.list.length, 1);
275
+ assert.deepEqual(Object.keys(auditList.list[0]).sort(), [
276
+ 'createdAt',
277
+ 'delta',
278
+ 'id',
279
+ 'operation',
280
+ 'skuId',
281
+ ]);
282
+
283
+ const auditView: any = await app.bean.executor.performAction(
284
+ 'get',
285
+ '/commerce/trade/stockAudit/:id',
286
+ { params: { id: auditList.list[0].id } },
287
+ );
288
+ assert.deepEqual(Object.keys(auditView).sort(), [
289
+ 'actorId',
290
+ 'available',
291
+ 'correlationId',
292
+ 'createdAt',
293
+ 'delta',
294
+ 'id',
295
+ 'onHand',
296
+ 'operation',
297
+ 'priorAvailable',
298
+ 'priorOnHand',
299
+ 'priorReserved',
300
+ 'reason',
301
+ 'reserved',
302
+ 'skuId',
303
+ 'stockBalanceId',
304
+ 'stockReservationId',
305
+ 'updatedAt',
306
+ ]);
307
+ assert.equal(auditView.delta, 7);
308
+ assert.equal(auditView.priorAvailable, 0);
309
+ assert.equal(auditView.available, 7);
310
+ assert.equal(auditView.correlationId, `presentation-stock-${suffix}`);
311
+ assert.equal(auditView.reason, `presentation stock ${suffix}`);
312
+ assert.equal(String(auditView.actorId), String(app.bean.passport.currentUser!.id));
313
+ for (const field of ['iid', 'deleted']) assert.equal(auditView[field], undefined);
314
+ } finally {
315
+ await dropStockFixture(fixture);
316
+ await app.bean.passport.signout();
317
+ }
318
+ });
319
+ });
320
+ });
321
+
322
+ function updatedAtVisible(component: any) {
323
+ return component.properties.updatedAt.rest.visible !== false;
324
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-home-base",
3
- "version": "5.1.6",
3
+ "version": "5.1.5",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "keywords": [
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "scripts": {
28
28
  "clean": "rimraf dist tsconfig.build.tsbuildinfo",
29
- "tsc:publish": "npm run clean && node ../../../../../packages-cli/cli/src/bin/vona.ts :bin:buildModule --sourcemap && tsc -p tsconfig.build.json",
29
+ "tsc:publish": "npm run clean && vona :bin:buildModule --sourcemap && tsc -p tsconfig.build.json",
30
30
  "prepublishOnly": "npm run tsc:publish",
31
31
  "prepack": "clean-package",
32
32
  "postpack": "clean-package restore"
@@ -45,6 +45,7 @@
45
45
  "title": "home-base",
46
46
  "vonaModule": {
47
47
  "dependencies": {
48
+ "a-ssr": "5.0.0",
48
49
  "a-vona": "5.0.0"
49
50
  }
50
51
  }
@@ -1,21 +1,24 @@
1
1
  // eslint-disable
2
- import type { TypeControllerOptionsActions } from 'vona-module-a-openapi';
2
+ import type { TypeSymbolKeyFieldsMore } from 'vona-module-a-orm';
3
+ import type { TypeEntityOptionsFields,TypeControllerOptionsActions } from 'vona-module-a-openapi';
3
4
  /** service: begin */
4
5
  export * from '../service/menu.ts';
5
6
  export * from '../service/permission.ts';
7
+ export * from '../service/siteCatalog.ts';
6
8
 
7
9
  import 'vona-module-a-bean';
8
10
  declare module 'vona-module-a-bean' {
9
-
11
+
10
12
  export interface IServiceRecord {
11
13
  'home-base:menu': never;
12
14
  'home-base:permission': never;
15
+ 'home-base:siteCatalog': never;
13
16
  }
14
17
 
15
-
18
+
16
19
  }
17
20
  declare module 'vona-module-home-base' {
18
-
21
+
19
22
  export interface ServiceMenu {
20
23
  /** @internal */
21
24
  get scope(): ScopeModuleHomeBase;
@@ -24,7 +27,7 @@ declare module 'vona-module-home-base' {
24
27
  export interface ServiceMenu {
25
28
  get $beanFullName(): 'home-base.service.menu';
26
29
  get $onionName(): 'home-base:menu';
27
-
30
+
28
31
  }
29
32
 
30
33
  export interface ServicePermission {
@@ -35,16 +38,29 @@ declare module 'vona-module-home-base' {
35
38
  export interface ServicePermission {
36
39
  get $beanFullName(): 'home-base.service.permission';
37
40
  get $onionName(): 'home-base:permission';
38
-
39
- }
41
+
42
+ }
43
+
44
+ export interface ServiceSiteCatalog {
45
+ /** @internal */
46
+ get scope(): ScopeModuleHomeBase;
47
+ }
48
+
49
+ export interface ServiceSiteCatalog {
50
+ get $beanFullName(): 'home-base.service.siteCatalog';
51
+ get $onionName(): 'home-base:siteCatalog';
52
+
53
+ }
40
54
  }
41
55
  /** service: end */
42
56
  /** service: begin */
43
57
  import type { ServiceMenu } from '../service/menu.ts';
44
58
  import type { ServicePermission } from '../service/permission.ts';
59
+ import type { ServiceSiteCatalog } from '../service/siteCatalog.ts';
45
60
  export interface IModuleService {
46
61
  'menu': ServiceMenu;
47
62
  'permission': ServicePermission;
63
+ 'siteCatalog': ServiceSiteCatalog;
48
64
  }
49
65
  /** service: end */
50
66
  /** service: begin */
@@ -54,26 +70,63 @@ declare module 'vona' {
54
70
  export interface IBeanRecordGeneral {
55
71
  'home-base.service.menu': ServiceMenu;
56
72
  'home-base.service.permission': ServicePermission;
73
+ 'home-base.service.siteCatalog': ServiceSiteCatalog;
57
74
  }
58
75
  }
59
76
  /** service: end */
77
+ /** dto: begin */
78
+ export * from '../dto/siteCatalogSelectRes.ts';
79
+ export * from '../dto/siteCatalogSelectResItem.ts';
80
+ import type { IDtoOptionsSiteCatalogSelectRes } from '../dto/siteCatalogSelectRes.ts';
81
+ import type { IDtoOptionsSiteCatalogSelectResItem } from '../dto/siteCatalogSelectResItem.ts';
82
+ import 'vona-module-a-web';
83
+ declare module 'vona-module-a-web' {
84
+
85
+ export interface IDtoRecord {
86
+ 'home-base:siteCatalogSelectRes': IDtoOptionsSiteCatalogSelectRes;
87
+ 'home-base:siteCatalogSelectResItem': IDtoOptionsSiteCatalogSelectResItem;
88
+ }
89
+
90
+
91
+ }
92
+ declare module 'vona-module-home-base' {
93
+
94
+ }
95
+ /** dto: end */
96
+ /** dto: begin */
97
+ import type { DtoSiteCatalogSelectRes } from '../dto/siteCatalogSelectRes.ts';
98
+ import type { DtoSiteCatalogSelectResItem } from '../dto/siteCatalogSelectResItem.ts';
99
+ declare module 'vona-module-home-base' {
100
+
101
+ export interface IDtoOptionsSiteCatalogSelectRes {
102
+ fields?: TypeEntityOptionsFields<DtoSiteCatalogSelectRes, IDtoOptionsSiteCatalogSelectRes[TypeSymbolKeyFieldsMore]>;
103
+ }
104
+
105
+ export interface IDtoOptionsSiteCatalogSelectResItem {
106
+ fields?: TypeEntityOptionsFields<DtoSiteCatalogSelectResItem, IDtoOptionsSiteCatalogSelectResItem[TypeSymbolKeyFieldsMore]>;
107
+ }
108
+ }
109
+ /** dto: end */
60
110
  /** controller: begin */
61
111
  export * from '../controller/menu.ts';
62
112
  export * from '../controller/permission.ts';
113
+ export * from '../controller/siteCatalog.ts';
63
114
  import type { IControllerOptionsMenu } from '../controller/menu.ts';
64
115
  import type { IControllerOptionsPermission } from '../controller/permission.ts';
116
+ import type { IControllerOptionsSiteCatalog } from '../controller/siteCatalog.ts';
65
117
  import 'vona-module-a-web';
66
118
  declare module 'vona-module-a-web' {
67
-
119
+
68
120
  export interface IControllerRecord {
69
121
  'home-base:menu': IControllerOptionsMenu;
70
122
  'home-base:permission': IControllerOptionsPermission;
123
+ 'home-base:siteCatalog': IControllerOptionsSiteCatalog;
71
124
  }
72
125
 
73
-
126
+
74
127
  }
75
128
  declare module 'vona-module-home-base' {
76
-
129
+
77
130
  export interface ControllerMenu {
78
131
  /** @internal */
79
132
  get scope(): ScopeModuleHomeBase;
@@ -94,7 +147,18 @@ declare module 'vona-module-home-base' {
94
147
  get $beanFullName(): 'home-base.controller.permission';
95
148
  get $onionName(): 'home-base:permission';
96
149
  get $onionOptions(): IControllerOptionsPermission;
97
- }
150
+ }
151
+
152
+ export interface ControllerSiteCatalog {
153
+ /** @internal */
154
+ get scope(): ScopeModuleHomeBase;
155
+ }
156
+
157
+ export interface ControllerSiteCatalog {
158
+ get $beanFullName(): 'home-base.controller.siteCatalog';
159
+ get $onionName(): 'home-base:siteCatalog';
160
+ get $onionOptions(): IControllerOptionsSiteCatalog;
161
+ }
98
162
  }
99
163
  /** controller: end */
100
164
  /** controller: begin */
@@ -102,8 +166,10 @@ declare module 'vona-module-home-base' {
102
166
  import type { ControllerMenu } from '../controller/menu.ts';
103
167
  // @ts-ignore ignore
104
168
  import type { ControllerPermission } from '../controller/permission.ts';
169
+ // @ts-ignore ignore
170
+ import type { ControllerSiteCatalog } from '../controller/siteCatalog.ts';
105
171
  declare module 'vona-module-home-base' {
106
-
172
+
107
173
  export interface IControllerOptionsMenu {
108
174
  actions?: TypeControllerOptionsActions<ControllerMenu>;
109
175
  }
@@ -111,14 +177,25 @@ declare module 'vona-module-home-base' {
111
177
  export interface IControllerOptionsPermission {
112
178
  actions?: TypeControllerOptionsActions<ControllerPermission>;
113
179
  }
180
+
181
+ export interface IControllerOptionsSiteCatalog {
182
+ actions?: TypeControllerOptionsActions<ControllerSiteCatalog>;
183
+ }
114
184
  }
115
185
  declare module 'vona-module-a-web' {
116
186
  export interface IApiPathGetRecord{
117
187
  '/home/base/menu/:publicPath?': undefined;
118
188
  '/home/base/permission/:resource': undefined;
189
+ '/home/base/siteCatalog': undefined;
119
190
  }
120
191
 
121
192
  }
193
+ import 'vona-module-a-openapi';
194
+ declare module 'vona-module-a-openapi' {
195
+ export interface IResourceRecord {
196
+ 'home-base:siteCatalog': never;
197
+ }
198
+ }
122
199
 
123
200
  /** controller: end */
124
201
  /** main: begin */
@@ -145,11 +222,11 @@ declare module 'vona' {
145
222
  export interface IBeanScopeContainer {
146
223
  homeBase: ScopeModuleHomeBase;
147
224
  }
148
-
149
-
150
225
 
151
-
152
226
 
153
-
227
+
228
+
229
+
230
+
154
231
  }
155
232
  /** scope: end */
@@ -0,0 +1,21 @@
1
+ import type { IDecoratorControllerOptions } from 'vona-module-a-web';
2
+
3
+ import { BeanBase } from 'vona';
4
+ import { Api, Resource } from 'vona-module-a-openapiutils';
5
+ import { Passport } from 'vona-module-a-user';
6
+ import { Controller, Web } from 'vona-module-a-web';
7
+
8
+ import { DtoSiteCatalogSelectRes } from '../dto/siteCatalogSelectRes.ts';
9
+
10
+ export interface IControllerOptionsSiteCatalog extends IDecoratorControllerOptions {}
11
+
12
+ @Controller<IControllerOptionsSiteCatalog>('siteCatalog')
13
+ @Resource()
14
+ export class ControllerSiteCatalog extends BeanBase {
15
+ @Web.get()
16
+ @Api.body(DtoSiteCatalogSelectRes)
17
+ @Passport.systemAdmin()
18
+ async select(): Promise<DtoSiteCatalogSelectRes> {
19
+ return await this.scope.service.siteCatalog.select();
20
+ }
21
+ }
@@ -0,0 +1,11 @@
1
+ import type { IDecoratorDtoOptions } from 'vona-module-a-web';
2
+
3
+ import { $Dto } from 'vona-module-a-orm';
4
+ import { Dto } from 'vona-module-a-web';
5
+
6
+ import { DtoSiteCatalogSelectResItem } from './siteCatalogSelectResItem.ts';
7
+
8
+ export interface IDtoOptionsSiteCatalogSelectRes extends IDecoratorDtoOptions {}
9
+
10
+ @Dto<IDtoOptionsSiteCatalogSelectRes>()
11
+ export class DtoSiteCatalogSelectRes extends $Dto.listAndCount(DtoSiteCatalogSelectResItem) {}
@@ -0,0 +1,15 @@
1
+ import type { IDecoratorDtoOptions } from 'vona-module-a-web';
2
+
3
+ import { Api, v } from 'vona-module-a-openapiutils';
4
+ import { Dto } from 'vona-module-a-web';
5
+
6
+ export interface IDtoOptionsSiteCatalogSelectResItem extends IDecoratorDtoOptions {}
7
+
8
+ @Dto<IDtoOptionsSiteCatalogSelectResItem>()
9
+ export class DtoSiteCatalogSelectResItem {
10
+ @Api.field(v.required())
11
+ siteId: string;
12
+
13
+ @Api.field(v.required())
14
+ title: string;
15
+ }
@@ -0,0 +1,29 @@
1
+ import type { IDecoratorSsrSiteOptions } from 'vona-module-a-ssr';
2
+
3
+ import { BeanBase } from 'vona';
4
+ import { Service } from 'vona-module-a-bean';
5
+
6
+ import type { DtoSiteCatalogSelectRes } from '../dto/siteCatalogSelectRes.ts';
7
+
8
+ @Service()
9
+ export class ServiceSiteCatalog extends BeanBase {
10
+ async select(): Promise<DtoSiteCatalogSelectRes> {
11
+ const list = this.app
12
+ .scope('a-ssr')
13
+ .service.ssr.getSitesEnabled()
14
+ .map(site => {
15
+ const options = site.beanOptions.options as IDecoratorSsrSiteOptions;
16
+ return {
17
+ siteId: String(options.siteId),
18
+ title: this.app.meta.text.locale(this.ctx.locale, options.title),
19
+ };
20
+ });
21
+ return {
22
+ list,
23
+ total: String(list.length),
24
+ pageCount: 1,
25
+ pageSize: list.length,
26
+ pageNo: 1,
27
+ } as DtoSiteCatalogSelectRes;
28
+ }
29
+ }
@@ -3,6 +3,8 @@ import type { IIconRecord, IPagePathRecord } from 'zova-rest-cabloy-basic-admin'
3
3
 
4
4
  import { BeanSsrSiteBase, SsrSite } from 'vona-module-a-ssr';
5
5
 
6
+ import { $locale } from '../.metadata/locales.ts';
7
+
6
8
  declare module 'vona-module-a-ssr' {
7
9
  export interface ISsrSiteIdRecord {
8
10
  admin: never;
@@ -25,6 +27,7 @@ export interface ISsrSiteOptionsAdmin extends IDecoratorSsrSiteOptions<
25
27
 
26
28
  @SsrSite<ISsrSiteOptionsAdmin>({
27
29
  siteId: 'admin',
30
+ title: $locale('SiteTitle'),
28
31
  publicPath: 'admin',
29
32
  bundlePath: 'ssr-cabloyBasicAdmin-5.0.0',
30
33
  diagnostics: {
@@ -1,4 +1,5 @@
1
1
  export default {
2
2
  Home: 'Home',
3
+ SiteTitle: 'Admin',
3
4
  Management: 'Management',
4
5
  };
@@ -1,4 +1,5 @@
1
1
  export default {
2
2
  Home: '首页',
3
+ SiteTitle: '管理',
3
4
  Management: '管理',
4
5
  };
@@ -3,6 +3,8 @@ import type { IIconRecord, IPagePathRecord } from 'zova-rest-cabloy-basic-web';
3
3
 
4
4
  import { BeanSsrSiteBase, SsrSite } from 'vona-module-a-ssr';
5
5
 
6
+ import { $locale } from '../.metadata/locales.ts';
7
+
6
8
  declare module 'vona-module-a-ssr' {
7
9
  export interface ISsrSiteIdRecord {
8
10
  web: never;
@@ -25,6 +27,7 @@ export interface ISsrSiteOptionsWeb extends IDecoratorSsrSiteOptions<
25
27
 
26
28
  @SsrSite<ISsrSiteOptionsWeb>({
27
29
  siteId: 'web',
30
+ title: $locale('SiteTitle'),
28
31
  publicPath: '',
29
32
  bundlePath: 'ssr-cabloyBasicWeb-5.0.0',
30
33
  diagnostics: {