cabloy 5.1.134 → 5.1.136

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 (185) hide show
  1. package/.cabloy-version +1 -1
  2. package/.claude/skills/cabloy-backend-scaffold/SKILL.md +9 -0
  3. package/.claude/skills/cabloy-zova-source-reading/SKILL.md +24 -1
  4. package/.claude/skills/cabloy-zova-source-reading/references/analysis-modes.md +12 -0
  5. package/.claude/skills/cabloy-zova-source-reading/references/core-reading-paths.md +28 -0
  6. package/.github/workflows/playwright-e2e.yml +2 -2
  7. package/.github/workflows/vona-test-pg.yml +1 -1
  8. package/.github/workflows/vona-test-sqlite3.yml +1 -1
  9. package/CHANGELOG.md +38 -0
  10. package/CLAUDE.md +1 -0
  11. package/cabloy-docs/.vitepress/config.mjs +7 -0
  12. package/cabloy-docs/backend/markdown-guide.md +189 -0
  13. package/cabloy-docs/frontend/component-guide.md +6 -0
  14. package/cabloy-docs/frontend/css-in-js-guide.md +6 -0
  15. package/cabloy-docs/frontend/markdown-guide.md +258 -0
  16. package/cabloy-docs/frontend/page-guide.md +48 -0
  17. package/cabloy-docs/frontend/page-params-guide.md +4 -2
  18. package/cabloy-docs/frontend/page-route-guide.md +2 -2
  19. package/cabloy-docs/frontend/zova-router-under-the-hood.md +2 -0
  20. package/cabloy-docs/frontend/zova-source-reading-map.md +53 -9
  21. package/cabloy-docs/fullstack/a-pay-payment-suite.md +333 -0
  22. package/cabloy-docs/fullstack/payment-sandbox-configuration.md +285 -0
  23. package/e2e/specs/a-commerce/commerce.spec.ts +503 -47
  24. package/e2e/specs/cabloy-basic/basic.spec.ts +30 -0
  25. package/package.json +1 -1
  26. package/vona/env/.env +2 -0
  27. package/vona/packages-cli/cli/package.json +1 -1
  28. package/vona/packages-cli/cli-set-api/cli/templates/init/error/boilerplate/config/errors.ts +6 -1
  29. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/boilerplate/src/entity/{{resourceName}}.tsx_ +2 -0
  30. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/boilerplate/src/entity/{{resourceName}}.tsx_ +2 -0
  31. package/vona/packages-cli/cli-set-api/package.json +1 -1
  32. package/vona/packages-utils/localeutil/package.json +1 -1
  33. package/vona/packages-utils/localeutil/src/util.ts +1 -1
  34. package/vona/packages-vona/vona/package.json +1 -1
  35. package/vona/packages-vona/vona-core/package.json +1 -1
  36. package/vona/packages-vona/vona-mock/package.json +1 -1
  37. package/vona/patches/{zova-core@5.1.82.patch → zova-core@5.1.84.patch} +2 -2
  38. package/vona/pnpm-lock.yaml +826 -270
  39. package/vona/pnpm-workspace.yaml +1 -1
  40. package/vona/src/suite/a-commerce/modules/commerce-catalog/package.json +1 -1
  41. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/index.ts +99 -1
  42. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/meta.index.ts +1 -0
  43. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/meta.version.ts +19 -0
  44. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/en-us.ts +3 -0
  45. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/zh-cn.ts +3 -0
  46. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/controller/product.ts +3 -3
  47. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productContentUpdate.tsx +14 -0
  48. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productContentView.tsx +19 -0
  49. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productCreate.tsx +48 -3
  50. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productPublicDetail.tsx +15 -0
  51. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productUpdate.tsx +48 -3
  52. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productView.tsx +52 -3
  53. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/entity/productContent.tsx +36 -0
  54. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/model/product.ts +6 -0
  55. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/model/productContent.ts +22 -0
  56. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/product.ts +82 -6
  57. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/productContent.test.ts +271 -0
  58. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/productPresentation.test.ts +81 -2
  59. package/vona/src/suite/a-commerce/modules/commerce-payment/package.json +4 -1
  60. package/vona/src/suite/a-commerce/modules/commerce-payment/src/bean/payScene.commerceOrder.ts +32 -15
  61. package/vona/src/suite/a-commerce/modules/commerce-payment/test/paymentAttempt.test.ts +8 -2
  62. package/vona/src/suite/a-commerce/modules/commerce-siteweb/src/.metadata/index.ts +8 -2
  63. package/vona/src/suite/a-commerce/modules/commerce-siteweb/src/.metadata/locales.ts +18 -0
  64. package/vona/src/suite/a-commerce/modules/commerce-siteweb/src/bean/ssrMenu.home.ts +3 -1
  65. package/vona/src/suite/a-commerce/modules/commerce-siteweb/src/config/locale/en-us.ts +3 -0
  66. package/vona/src/suite/a-commerce/modules/commerce-siteweb/src/config/locale/zh-cn.ts +3 -0
  67. package/vona/src/suite/a-commerce/modules/commerce-siteweb/src/index.ts +1 -0
  68. package/vona/src/suite/a-commerce/modules/commerce-trade/src/controller/checkout.ts +13 -2
  69. package/vona/src/suite/a-commerce/modules/commerce-trade/src/lib/providerReference.ts +18 -0
  70. package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/order.ts +43 -8
  71. package/vona/src/suite/a-commerce/modules/commerce-trade/test/paymentOutcome.test.ts +74 -0
  72. package/vona/src/suite/a-commerce/modules/commerce-trade/test/providerReference.test.ts +33 -0
  73. package/vona/src/suite/a-commerce/modules/commerce-trade/test/refundLifecycle.test.ts +73 -0
  74. package/vona/src/suite/a-commerce/modules/commerce-trade/test/reservationExpiry.test.ts +2 -0
  75. package/vona/src/suite/a-home/modules/home-user/src/.metadata/index.ts +30 -0
  76. package/vona/src/suite/a-home/modules/home-user/src/bean/meta.version.ts +7 -2
  77. package/vona/src/suite/a-home/modules/home-user/src/config/locale/en-us.ts +4 -1
  78. package/vona/src/suite/a-home/modules/home-user/src/config/locale/zh-cn.ts +4 -1
  79. package/vona/src/suite/a-home/modules/home-user/src/config/roles.ts +4 -4
  80. package/vona/src/suite/a-home/modules/home-user/src/entity/role.ts +2 -2
  81. package/vona/src/suite/a-home/modules/home-user/src/entity/user.ts +8 -1
  82. package/vona/src/suite/a-home/modules/home-user/src/service/userAdapter.ts +6 -2
  83. package/vona/src/suite/a-home/modules/home-user/test/passportTest.test.ts +1 -0
  84. package/vona/src/suite/a-home/modules/home-user/test/role.test.ts +4 -4
  85. package/vona/src/suite-vendor/a-cabloy/modules/a-markdown/package.json +64 -0
  86. package/vona/src/suite-vendor/a-cabloy/modules/a-markdown/src/.metadata/index.ts +54 -0
  87. package/vona/src/suite-vendor/a-cabloy/modules/a-markdown/src/.metadata/this.ts +2 -0
  88. package/vona/src/suite-vendor/a-cabloy/modules/a-markdown/src/bean/bean.markdown.ts +137 -0
  89. package/vona/src/suite-vendor/a-cabloy/modules/a-markdown/src/index.ts +1 -0
  90. package/vona/src/suite-vendor/a-cabloy/modules/a-markdown/tsconfig.build.json +11 -0
  91. package/vona/src/suite-vendor/a-cabloy/modules/a-markdown/tsconfig.json +7 -0
  92. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/package.json +1 -1
  93. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/bean/bean.ssr.ts +17 -0
  94. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/lib/beanSsrSiteBase.ts +11 -3
  95. package/vona/src/suite-vendor/a-cabloy/package.json +2 -1
  96. package/vona/src/suite-vendor/a-cabloy/tsconfig.json +3 -0
  97. package/vona/src/suite-vendor/a-pay/modules/a-pay/package.json +1 -1
  98. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/bean/meta.version.ts +1 -0
  99. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/entity/providerOperation.tsx +8 -1
  100. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/lib/index.ts +1 -0
  101. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/lib/providerOperationFailure.ts +8 -0
  102. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/service/providerOperation.ts +187 -29
  103. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/types/payment.ts +4 -0
  104. package/vona/src/suite-vendor/a-pay/modules/pay-mock/package.json +1 -1
  105. package/vona/src/suite-vendor/a-pay/modules/pay-paypal/package.json +1 -1
  106. package/vona/src/suite-vendor/a-pay/modules/pay-paypal/src/bean/payProvider.paypal.ts +0 -6
  107. package/vona/src/suite-vendor/a-pay/modules/pay-paypal/src/index.ts +1 -0
  108. package/vona/src/suite-vendor/a-pay/modules/pay-stripe/package.json +2 -1
  109. package/vona/src/suite-vendor/a-pay/modules/pay-stripe/src/bean/payProvider.stripe.ts +458 -22
  110. package/vona/src/suite-vendor/a-pay/modules/pay-stripe/src/index.ts +1 -0
  111. package/vona/src/suite-vendor/a-pay/modules/pay-stripe/src/lib/stripeGateway.ts +85 -0
  112. package/vona/src/suite-vendor/a-pay/modules/pay-stripe/src/types/index.ts +2 -0
  113. package/vona/src/suite-vendor/a-pay/package.json +5 -5
  114. package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
  115. package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
  116. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +1 -0
  117. package/vona/src/suite-vendor/a-vona/modules/a-user/package.json +1 -1
  118. package/vona/src/suite-vendor/a-vona/modules/a-user/src/bean/bean.passport.ts +14 -0
  119. package/vona/src/suite-vendor/a-vona/modules/a-user/src/bean/guard.passport.ts +4 -0
  120. package/vona/src/suite-vendor/a-vona/modules/a-user/src/types/role.ts +3 -2
  121. package/vona/src/suite-vendor/a-vona/modules/a-user/src/types/user.ts +4 -0
  122. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  123. package/zova/packages-utils/logger/package.json +2 -2
  124. package/zova/packages-utils/zova-jsx/package.json +2 -2
  125. package/zova/packages-zova/zova/package.json +3 -3
  126. package/zova/packages-zova/zova-core/package.json +3 -3
  127. package/zova/packages-zova/zova-core/src/core/sys/resource.ts +1 -1
  128. package/zova/packages-zova/zova-core/src/core/sys/util.ts +8 -0
  129. package/zova/pnpm-lock.yaml +570 -11
  130. package/zova/src/front/config/config/config.cabloyCommerce.ts +0 -6
  131. package/zova/src/suite/a-commerce/modules/commerce-catalog/package.json +3 -1
  132. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/schemas.ts +236 -36
  133. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/types.ts +4962 -2402
  134. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/en-us.ts +1 -0
  135. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/zh-cn.ts +1 -0
  136. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/page/product/controller.tsx +8 -3
  137. package/zova/src/suite/a-commerce/modules/commerce-member/src/.metadata/index.ts +6 -7
  138. package/zova/src/suite/a-commerce/modules/commerce-member/src/page/address/controller.tsx +1 -3
  139. package/zova/src/suite/a-commerce/modules/commerce-member/src/routes.ts +2 -3
  140. package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +13 -20
  141. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/cart/controller.tsx +3 -9
  142. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/checkout/controller.tsx +9 -11
  143. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/order/controller.tsx +0 -1
  144. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/orders/controller.tsx +6 -4
  145. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/payment/controller.tsx +78 -17
  146. package/zova/src/suite/a-commerce/modules/commerce-trade/src/routes.ts +10 -13
  147. package/zova/src/suite/a-home/modules/home-api/mock/passport.fake.ts +3 -3
  148. package/zova/src/suite/a-home/modules/home-api/src/.metadata/index.ts +31 -1
  149. package/zova/src/suite/a-home/modules/home-api/src/api/homeBaseSiteCatalog.ts +24 -0
  150. package/zova/src/suite/a-home/modules/home-api/src/api/openapi/schemas.ts +329 -17
  151. package/zova/src/suite/a-home/modules/home-api/src/api/openapi/types.ts +5866 -1829
  152. package/zova/src/suite/a-home/modules/home-api/src/apiSchema/homeBaseSiteCatalog.ts +13 -0
  153. package/zova/src/suite/a-home/modules/home-base/src/component/page/controller.tsx +1 -0
  154. package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.header.tsx +0 -1
  155. package/zova/src/suite/cabloy-basic/modules/basic-details/src/types/detail.ts +1 -0
  156. package/zova/src/suite/cabloy-basic/modules/basic-markdown/package.json +61 -0
  157. package/zova/src/suite/cabloy-basic/modules/basic-markdown/src/.metadata/component/formFieldMarkdown.ts +36 -0
  158. package/zova/src/suite/cabloy-basic/modules/basic-markdown/src/.metadata/component/markdownHtml.ts +36 -0
  159. package/zova/src/suite/cabloy-basic/modules/basic-markdown/src/.metadata/index.ts +147 -0
  160. package/zova/src/suite/cabloy-basic/modules/basic-markdown/src/.metadata/this.ts +2 -0
  161. package/zova/src/suite/cabloy-basic/modules/basic-markdown/src/component/formFieldMarkdown/controller.tsx +111 -0
  162. package/zova/src/suite/cabloy-basic/modules/basic-markdown/src/component/formFieldMarkdown/render.tsx +40 -0
  163. package/zova/src/suite/cabloy-basic/modules/basic-markdown/src/component/formFieldMarkdown/style.ts +13 -0
  164. package/zova/src/suite/cabloy-basic/modules/basic-markdown/src/component/markdownHtml/controller.tsx +17 -0
  165. package/zova/src/suite/cabloy-basic/modules/basic-markdown/src/component/markdownHtml/render.tsx +9 -0
  166. package/zova/src/suite/cabloy-basic/modules/basic-markdown/src/component/markdownHtml/style.ts +13 -0
  167. package/zova/src/suite/cabloy-basic/modules/basic-markdown/src/index.ts +1 -0
  168. package/zova/src/suite/cabloy-basic/modules/basic-markdown/src/lib/richTextContentStyle.ts +142 -0
  169. package/zova/src/suite/cabloy-basic/modules/basic-markdown/tsconfig.build.json +13 -0
  170. package/zova/src/suite/cabloy-basic/modules/basic-markdown/tsconfig.json +5 -0
  171. package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockPage/controller.tsx +25 -3
  172. package/zova/src/suite/cabloy-basic/modules/basic-page/src/types/page.ts +1 -0
  173. package/zova/src/suite/cabloy-basic/modules/basic-pageentry/src/types/pageEntry.ts +1 -0
  174. package/zova/src/suite/cabloy-basic/package.json +1 -0
  175. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  176. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +7 -0
  177. package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
  178. package/zova/src/suite-vendor/a-zova/modules/a-logger/package.json +2 -2
  179. package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
  180. package/zova/src/suite-vendor/a-zova/modules/a-router/src/bean/sys.router.ts +3 -2
  181. package/zova/src/suite-vendor/a-zova/modules/a-ssr/package.json +1 -1
  182. package/zova/src/suite-vendor/a-zova/modules/a-ssr/test/lib/ssrProfile.test.ts +88 -0
  183. package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
  184. package/zova/src/suite-vendor/a-zova/package.json +5 -5
  185. package/.claude/scheduled_tasks.lock +0 -1
@@ -11,7 +11,10 @@ export default {
11
11
  UserAvatar: '头像',
12
12
  UserEmail: '电子邮件',
13
13
  UserMobile: '手机号',
14
- UserActivated: '已激活',
14
+ UserActivated: '身份已激活',
15
+ UserAccountStatus: '账户状态',
16
+ UserAccountStatusActive: '启用',
17
+ UserAccountStatusDisabled: '停用',
15
18
  UserLocale: '语言',
16
19
  UserTz: '时区',
17
20
  UsernameExists: '用户名已存在',
@@ -1,22 +1,22 @@
1
- import type { ILocaleRecord } from 'vona';
1
+ import type { LocalizedTextMap } from 'vona-module-a-user';
2
2
 
3
3
  export interface IRoleConfig {
4
4
  title: string;
5
- locales?: Partial<Record<keyof ILocaleRecord, string>>;
5
+ titleLocales?: LocalizedTextMap;
6
6
  siteIds: string[];
7
7
  }
8
8
 
9
9
  export const builtinRoles: Record<string, IRoleConfig> = {
10
10
  registeredUser: {
11
11
  title: 'Registered User',
12
- locales: {
12
+ titleLocales: {
13
13
  'zh-cn': '注册用户',
14
14
  },
15
15
  siteIds: ['web'],
16
16
  },
17
17
  systemAdmin: {
18
18
  title: 'System Administrator',
19
- locales: {
19
+ titleLocales: {
20
20
  'zh-cn': '系统管理员',
21
21
  },
22
22
  siteIds: ['web', 'admin'],
@@ -1,5 +1,5 @@
1
- import type { ILocaleRecord } from 'vona';
2
1
  import type { IDecoratorEntityOptions } from 'vona-module-a-orm';
2
+ import type { LocalizedTextMap } from 'vona-module-a-user';
3
3
  import type { IRole } from 'vona-module-a-user';
4
4
 
5
5
  import { Api, v } from 'vona-module-a-openapiutils';
@@ -19,7 +19,7 @@ export class EntityRole extends EntityBase implements IRole {
19
19
  title: string;
20
20
 
21
21
  @Api.field(v.title($locale('RoleLocales')), v.optional(), z.record(z.string(), z.string()))
22
- locales?: Partial<Record<keyof ILocaleRecord, string>>;
22
+ titleLocales?: LocalizedTextMap;
23
23
 
24
24
  @Api.field(v.array(z.string()))
25
25
  siteIds: string[];
@@ -1,6 +1,6 @@
1
1
  import type { ILocaleRecord } from 'vona';
2
2
  import type { IDecoratorEntityOptions } from 'vona-module-a-orm';
3
- import type { IUser } from 'vona-module-a-user';
3
+ import type { IUser, TypeAccountStatus } from 'vona-module-a-user';
4
4
 
5
5
  import { Api, v } from 'vona-module-a-openapiutils';
6
6
  import { Entity, EntityBase } from 'vona-module-a-orm';
@@ -27,6 +27,13 @@ export class EntityUser extends EntityBase implements IUser {
27
27
  @Api.field(v.title($locale('UserActivated')), v.default(false))
28
28
  activated?: boolean;
29
29
 
30
+ @Api.field(
31
+ v.title($locale('UserAccountStatus')),
32
+ v.default('active'),
33
+ z.enum(['active', 'disabled']),
34
+ )
35
+ accountStatus: TypeAccountStatus;
36
+
30
37
  @Api.field(v.title($locale('UserLocale')), z.string().optional())
31
38
  locale?: keyof ILocaleRecord | undefined;
32
39
 
@@ -1,5 +1,5 @@
1
1
  import type { TableIdentity } from 'table-identity';
2
- import type { IAuthUserProfile, IUser, IUserAdapter } from 'vona-module-a-user';
2
+ import type { IAuthUserProfile, IUser, IUserAdapter, TypeAccountStatus } from 'vona-module-a-user';
3
3
 
4
4
  import { BeanBase } from 'vona';
5
5
  import { Service } from 'vona-module-a-bean';
@@ -7,7 +7,7 @@ import { Service } from 'vona-module-a-bean';
7
7
  @Service()
8
8
  export class ServiceUserAdapter extends BeanBase implements IUserAdapter {
9
9
  async create(user: Partial<IUser>): Promise<IUser> {
10
- return await this.scope.model.user.insert(user);
10
+ return await this.scope.model.user.insert({ accountStatus: 'active', ...user });
11
11
  }
12
12
 
13
13
  async userOfProfile(profile: IAuthUserProfile): Promise<Partial<IUser>> {
@@ -43,4 +43,8 @@ export class ServiceUserAdapter extends BeanBase implements IUserAdapter {
43
43
  async setActivated(id: TableIdentity, activated: boolean): Promise<void> {
44
44
  await this.scope.model.user.update({ id, activated });
45
45
  }
46
+
47
+ async setAccountStatus(id: TableIdentity, accountStatus: TypeAccountStatus): Promise<void> {
48
+ await this.scope.model.user.update({ id, accountStatus });
49
+ }
46
50
  }
@@ -15,6 +15,7 @@ describe('passportTest.test.ts', () => {
15
15
  });
16
16
  userId = user.id as string;
17
17
  assert.equal(user.activated, false);
18
+ assert.equal(user.accountStatus, 'active');
18
19
 
19
20
  const [_, error] = await catchError(() => {
20
21
  return app.bean.executor.performAction('post', activateCurrentPath, {
@@ -8,12 +8,12 @@ describe('role.test.ts', () => {
8
8
  const scope = app.scope('home-user');
9
9
  const roleRegisteredUser = await scope.model.role.getByName('registeredUser');
10
10
  assert.equal(roleRegisteredUser?.title, 'Registered User');
11
- assert.deepEqual(roleRegisteredUser?.locales, { 'zh-cn': '注册用户' });
11
+ assert.deepEqual(roleRegisteredUser?.titleLocales, { 'zh-cn': '注册用户' });
12
12
  assert.ok(roleRegisteredUser?.siteIds.includes('web'));
13
13
 
14
14
  const roleSystemAdmin = await scope.model.role.getByName('systemAdmin');
15
15
  assert.equal(roleSystemAdmin?.title, 'System Administrator');
16
- assert.deepEqual(roleSystemAdmin?.locales, { 'zh-cn': '系统管理员' });
16
+ assert.deepEqual(roleSystemAdmin?.titleLocales, { 'zh-cn': '系统管理员' });
17
17
  assert.ok(roleSystemAdmin?.siteIds.includes('web'));
18
18
  assert.ok(roleSystemAdmin?.siteIds.includes('admin'));
19
19
 
@@ -23,12 +23,12 @@ describe('role.test.ts', () => {
23
23
  (role: any) => role.name === 'registeredUser',
24
24
  );
25
25
  assert.equal(passportRegisteredUser?.title, 'Registered User');
26
- assert.deepEqual(passportRegisteredUser?.locales, { 'zh-cn': '注册用户' });
26
+ assert.deepEqual(passportRegisteredUser?.titleLocales, { 'zh-cn': '注册用户' });
27
27
  assert.ok(passportRegisteredUser?.siteIds.includes('web'));
28
28
 
29
29
  const passportSystemAdmin = passport.roles.find((role: any) => role.name === 'systemAdmin');
30
30
  assert.equal(passportSystemAdmin?.title, 'System Administrator');
31
- assert.deepEqual(passportSystemAdmin?.locales, { 'zh-cn': '系统管理员' });
31
+ assert.deepEqual(passportSystemAdmin?.titleLocales, { 'zh-cn': '系统管理员' });
32
32
  assert.ok(passportSystemAdmin?.siteIds.includes('web'));
33
33
  assert.ok(passportSystemAdmin?.siteIds.includes('admin'));
34
34
  });
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "vona-module-a-markdown",
3
+ "version": "5.0.1",
4
+ "description": "",
5
+ "keywords": [
6
+ "Vona Module"
7
+ ],
8
+ "author": "",
9
+ "files": [
10
+ "assets",
11
+ "dist",
12
+ "src"
13
+ ],
14
+ "type": "module",
15
+ "exports": {
16
+ ".": {
17
+ "types": [
18
+ "./src/index.ts",
19
+ "./dist/index.d.ts"
20
+ ],
21
+ "import": "./src/index.ts",
22
+ "default": "./dist/index.js"
23
+ },
24
+ "./package.json": "./package.json"
25
+ },
26
+ "scripts": {
27
+ "clean": "rimraf dist tsconfig.build.tsbuildinfo",
28
+ "tsc:publish": "npm run clean && node ../../../../../packages-cli/cli/src/bin/vona.ts :bin:buildModule --sourcemap && tsc -p tsconfig.build.json",
29
+ "prepublishOnly": "npm run tsc:publish",
30
+ "prepack": "clean-package",
31
+ "postpack": "clean-package restore"
32
+ },
33
+ "dependencies": {
34
+ "@tiptap/core": "^3.30.0",
35
+ "@tiptap/extension-highlight": "^3.30.0",
36
+ "@tiptap/extension-image": "^3.30.0",
37
+ "@tiptap/extension-list": "^3.30.0",
38
+ "@tiptap/extension-table": "^3.30.0",
39
+ "@tiptap/extension-youtube": "^3.30.0",
40
+ "@tiptap/markdown": "^3.30.0",
41
+ "@tiptap/starter-kit": "^3.30.0",
42
+ "@tiptap/static-renderer": "^3.30.0",
43
+ "sanitize-html": "^2.17.6"
44
+ },
45
+ "devDependencies": {
46
+ "@types/sanitize-html": "^2.16.1",
47
+ "clean-package": "^2.2.0",
48
+ "rimraf": "^6.1.3"
49
+ },
50
+ "clean-package": {
51
+ "indent": 2,
52
+ "remove": [
53
+ "clean-package",
54
+ "devDependencies",
55
+ "exports.\\..import"
56
+ ]
57
+ },
58
+ "title": "a-markdown",
59
+ "vonaModule": {
60
+ "dependencies": {
61
+ "a-vona": "5.0.0"
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,54 @@
1
+ // eslint-disable
2
+ /** bean: begin */
3
+ export * from '../bean/bean.markdown.ts';
4
+
5
+ import 'vona';
6
+ declare module 'vona' {
7
+
8
+
9
+ }
10
+ declare module 'vona-module-a-markdown' {
11
+
12
+ export interface BeanMarkdown {
13
+ /** @internal */
14
+ get scope(): ScopeModuleAMarkdown;
15
+ }
16
+ }
17
+ /** bean: end */
18
+ /** bean: begin */
19
+ import type { BeanMarkdown } from '../bean/bean.markdown.ts';
20
+ import 'vona';
21
+ declare module 'vona' {
22
+ export interface IBeanRecordGlobal {
23
+ 'markdown': BeanMarkdown;
24
+ }
25
+ }
26
+ /** bean: end */
27
+ /** scope: begin */
28
+ import { BeanScopeBase, type BeanScopeUtil } from 'vona';
29
+ import { Scope } from 'vona-module-a-bean';
30
+
31
+ @Scope()
32
+ export class ScopeModuleAMarkdown extends BeanScopeBase {}
33
+
34
+ export interface ScopeModuleAMarkdown {
35
+ util: BeanScopeUtil;
36
+ }
37
+
38
+ import 'vona';
39
+ declare module 'vona' {
40
+ export interface IBeanScopeRecord {
41
+ 'a-markdown': ScopeModuleAMarkdown;
42
+ }
43
+
44
+ export interface IBeanScopeContainer {
45
+ markdown: ScopeModuleAMarkdown;
46
+ }
47
+
48
+
49
+
50
+
51
+
52
+
53
+ }
54
+ /** scope: end */
@@ -0,0 +1,2 @@
1
+ export const __ThisModule__ = 'a-markdown';
2
+ export { ScopeModuleAMarkdown as ScopeModule } from './index.ts';
@@ -0,0 +1,137 @@
1
+ import type { AnyExtension } from '@tiptap/core';
2
+
3
+ import { Highlight } from '@tiptap/extension-highlight';
4
+ import { Image } from '@tiptap/extension-image';
5
+ import { TaskItem, TaskList } from '@tiptap/extension-list';
6
+ import { TableKit } from '@tiptap/extension-table';
7
+ import Youtube from '@tiptap/extension-youtube';
8
+ import { Markdown, MarkdownManager } from '@tiptap/markdown';
9
+ import StarterKit from '@tiptap/starter-kit';
10
+ import { renderToHTMLString } from '@tiptap/static-renderer';
11
+ import sanitizeHtml from 'sanitize-html';
12
+ import { BeanBase } from 'vona';
13
+ import { Bean } from 'vona-module-a-bean';
14
+
15
+ const extensions: AnyExtension[] = [
16
+ Markdown,
17
+ StarterKit,
18
+ TaskList,
19
+ TaskItem.configure({ nested: true }),
20
+ Image,
21
+ TableKit,
22
+ Highlight,
23
+ Youtube.configure({
24
+ addPasteHandler: false,
25
+ nocookie: true,
26
+ }),
27
+ ];
28
+
29
+ const markdownManager = new MarkdownManager({
30
+ extensions,
31
+ markedOptions: { gfm: true },
32
+ indentation: { style: 'space', size: 2 },
33
+ });
34
+
35
+ const sanitizeOptions: sanitizeHtml.IOptions = {
36
+ allowedTags: [
37
+ 'a',
38
+ 'blockquote',
39
+ 'br',
40
+ 'code',
41
+ 'del',
42
+ 'div',
43
+ 'em',
44
+ 'iframe',
45
+ 'h1',
46
+ 'h2',
47
+ 'h3',
48
+ 'h4',
49
+ 'h5',
50
+ 'h6',
51
+ 'hr',
52
+ 'img',
53
+ 'input',
54
+ 'label',
55
+ 'li',
56
+ 'ol',
57
+ 'p',
58
+ 'pre',
59
+ 's',
60
+ 'span',
61
+ 'strong',
62
+ 'table',
63
+ 'tbody',
64
+ 'td',
65
+ 'th',
66
+ 'thead',
67
+ 'tr',
68
+ 'ul',
69
+ ],
70
+ allowedAttributes: {
71
+ a: ['href', 'rel', 'target', 'title'],
72
+ code: ['class'],
73
+ div: ['data-youtube-video'],
74
+ iframe: ['allowfullscreen', 'height', 'src', 'width'],
75
+ img: ['alt', 'height', 'src', 'title', 'width'],
76
+ input: ['checked', 'disabled', 'type'],
77
+ li: ['data-checked', 'data-type'],
78
+ span: ['class'],
79
+ ul: ['data-type'],
80
+ },
81
+ allowedClasses: {
82
+ code: ['language-*'],
83
+ span: ['hljs-*'],
84
+ },
85
+ allowedSchemes: ['http', 'https', 'mailto'],
86
+ allowedSchemesByTag: {
87
+ iframe: ['https'],
88
+ img: ['http', 'https'],
89
+ },
90
+ allowedIframeHostnames: ['www.youtube-nocookie.com'],
91
+ allowedSchemesAppliedToAttributes: ['href', 'src'],
92
+ allowProtocolRelative: false,
93
+ exclusiveFilter: frame => frame.tag === 'iframe' && !frame.attribs.src,
94
+ transformTags: {
95
+ a: sanitizeHtml.simpleTransform('a', { rel: 'noopener noreferrer' }),
96
+ input: (_tagName, attribs) => {
97
+ if (attribs.type !== 'checkbox') {
98
+ return { tagName: 'span', attribs: {} };
99
+ }
100
+ return {
101
+ tagName: 'input',
102
+ attribs: {
103
+ type: 'checkbox',
104
+ ...(attribs.checked !== undefined ? { checked: 'checked' } : {}),
105
+ disabled: 'disabled',
106
+ },
107
+ };
108
+ },
109
+ li: (_tagName, attribs) => {
110
+ const taskAttribs: sanitizeHtml.Attributes = {};
111
+ if (attribs['data-type'] === 'taskItem') {
112
+ taskAttribs['data-type'] = 'taskItem';
113
+ if (attribs['data-checked'] === 'true' || attribs['data-checked'] === 'false') {
114
+ taskAttribs['data-checked'] = attribs['data-checked'];
115
+ }
116
+ }
117
+ return { tagName: 'li', attribs: taskAttribs };
118
+ },
119
+ ul: (_tagName, attribs) => {
120
+ const taskAttribs: sanitizeHtml.Attributes = {};
121
+ if (attribs['data-type'] === 'taskList') {
122
+ taskAttribs['data-type'] = 'taskList';
123
+ }
124
+ return { tagName: 'ul', attribs: taskAttribs };
125
+ },
126
+ },
127
+ };
128
+
129
+ @Bean()
130
+ export class BeanMarkdown extends BeanBase {
131
+ renderHtml(markdown?: string): string {
132
+ if (!markdown?.trim()) return '';
133
+ const json = markdownManager.parse(markdown);
134
+ const html = renderToHTMLString({ content: json, extensions });
135
+ return sanitizeHtml(html, sanitizeOptions);
136
+ }
137
+ }
@@ -0,0 +1 @@
1
+ export * from './.metadata/index.ts';
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../../tsconfig.base",
3
+ "compilerOptions": {
4
+ "rootDir": "src",
5
+ "declaration": true,
6
+ "declarationMap": true,
7
+ "emitDeclarationOnly": true,
8
+ "outDir": "dist"
9
+ },
10
+ "include": ["src", "src/.metadata/*.ts", "src/**/*.json"]
11
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "../../tsconfig.base",
3
+ "compilerOptions": {
4
+ "noEmit": true
5
+ },
6
+ "include": ["src", "src/.metadata/*.ts", "src/**/*.json", "test"]
7
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-ssr",
3
- "version": "5.1.28",
3
+ "version": "5.1.29",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "keywords": [
@@ -1,3 +1,4 @@
1
+ import type { IParamsAndQuery } from '@cabloy/utils';
1
2
  import type { IMenus } from 'vona-module-a-menu';
2
3
  import type { TypeEventResolvePathResult } from 'vona-module-a-static';
3
4
 
@@ -13,6 +14,22 @@ import type {
13
14
 
14
15
  @Bean()
15
16
  export class BeanSsr extends BeanBase {
17
+ getPagePath<
18
+ SITE extends keyof ISsrSiteRecord,
19
+ PAGEPATH extends keyof ISsrSiteRecord[SITE]['pages'],
20
+ PAGEOPTIONS extends Omit<ISsrSiteRecord[SITE]['pages'][PAGEPATH], 'data'>,
21
+ >(site: SITE, pagePath: PAGEPATH, pageOptions?: PAGEOPTIONS): string | undefined;
22
+ getPagePath(site: string, pagePath: string, pageOptions?: IParamsAndQuery): string | undefined;
23
+ getPagePath(site: string, pagePath: string, pageOptions?: IParamsAndQuery): string | undefined {
24
+ // site bean
25
+ const beanInstance = this.bean._getBean(
26
+ beanFullNameFromOnionName(site as any, 'ssrSite'),
27
+ ) as BeanSsrSiteBase;
28
+ if (!beanInstance) return;
29
+ // page path
30
+ return beanInstance.getPagePath(pagePath as any, pageOptions as any);
31
+ }
32
+
16
33
  async redirect<
17
34
  SITE extends keyof ISsrSiteRecord,
18
35
  PAGEPATH extends keyof ISsrSiteRecord[SITE]['pages'],
@@ -66,10 +66,10 @@ export class BeanSsrSiteBase<
66
66
  return await this.render(undefined, undefined, { req, res });
67
67
  }
68
68
 
69
- async redirect<
69
+ getPagePath<
70
70
  PAGEPATH extends keyof SsrSiteOptions['pages'],
71
71
  PAGEOPTIONS extends Omit<SsrSiteOptions['pages'][PAGEPATH], 'data'>,
72
- >(pagePath?: PAGEPATH, pageOptions?: PAGEOPTIONS): Promise<undefined | never> {
72
+ >(pagePath?: PAGEPATH, pageOptions?: PAGEOPTIONS): string {
73
73
  // pagePath
74
74
  pagePath = this.$scope.ssr.service.ssr.prepareMenuLink(pagePath as any) as any;
75
75
  // pagePathFull
@@ -77,11 +77,19 @@ export class BeanSsrSiteBase<
77
77
  if (this.siteOptions.publicPath) {
78
78
  pagePathFull = `/${this.siteOptions.publicPath}${pagePathFull as string}`;
79
79
  }
80
+ return pagePathFull as string;
81
+ }
82
+
83
+ async redirect<
84
+ PAGEPATH extends keyof SsrSiteOptions['pages'],
85
+ PAGEOPTIONS extends Omit<SsrSiteOptions['pages'][PAGEPATH], 'data'>,
86
+ >(pagePath?: PAGEPATH, pageOptions?: PAGEOPTIONS): Promise<undefined | never> {
87
+ const pagePathFull = this.getPagePath(pagePath, pageOptions);
80
88
  if (this.siteOptions.apiType === 'dev') {
81
89
  const url = `${this.siteOptions.dev.host}${pagePathFull}`;
82
90
  this.ctx.redirect(url);
83
91
  } else {
84
- this.ctx.redirect(pagePathFull as string);
92
+ this.ctx.redirect(pagePathFull);
85
93
  }
86
94
  }
87
95
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-suite-a-cabloy",
3
- "version": "5.1.43",
3
+ "version": "5.1.44",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "author": "",
@@ -8,6 +8,7 @@
8
8
  "type": "module",
9
9
  "dependencies": {
10
10
  "vona-module-a-cabloy": "workspace:^",
11
+ "vona-module-a-markdown": "^5.0.1",
11
12
  "vona-module-a-socket": "workspace:^",
12
13
  "vona-module-a-ssr": "workspace:^",
13
14
  "vona-module-a-ssrhmr": "workspace:^"
@@ -22,6 +22,9 @@
22
22
  },
23
23
  {
24
24
  "path": "modules/a-ssrhmr/tsconfig.build.json"
25
+ },
26
+ {
27
+ "path": "modules/a-markdown/tsconfig.build.json"
25
28
  }
26
29
  ],
27
30
  "exclude": ["modules"]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-pay",
3
- "version": "5.0.5",
3
+ "version": "5.0.6",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "Vona Module"
@@ -40,6 +40,7 @@ export class MetaVersion extends BeanBase implements IMetaVersionUpdate {
40
40
  table.string(providerOperation.state, 32);
41
41
  table.string(providerOperation.idempotencyKey, 100);
42
42
  table.string(providerOperation.correlationId, 100);
43
+ table.json(providerOperation.startInputSnapshot);
43
44
  table.string(providerOperation.providerRequestId, 255);
44
45
  table.string(providerOperation.providerResourceId, 255);
45
46
  table.integer(providerOperation.attemptCount);
@@ -5,7 +5,11 @@ import { Api, v } from 'vona-module-a-openapiutils';
5
5
  import { Entity, EntityBase } from 'vona-module-a-orm';
6
6
  import { z } from 'zod';
7
7
 
8
- import type { TypeProviderOperationKind, TypeProviderOperationState } from '../types/payment.ts';
8
+ import type {
9
+ IPayProviderOperationStartInputSnapshot,
10
+ TypeProviderOperationKind,
11
+ TypeProviderOperationState,
12
+ } from '../types/payment.ts';
9
13
 
10
14
  export interface IEntityOptionsProviderOperation extends IDecoratorEntityOptions {}
11
15
 
@@ -31,6 +35,9 @@ export class EntityProviderOperation extends EntityBase {
31
35
  @Api.field(v.required(), v.min(1), v.max(100))
32
36
  correlationId: string;
33
37
 
38
+ @Api.field(v.optional())
39
+ startInputSnapshot?: IPayProviderOperationStartInputSnapshot;
40
+
34
41
  @Api.field(v.optional(), v.max(255))
35
42
  providerRequestId?: string;
36
43
 
@@ -1,2 +1,3 @@
1
1
  export * from './payProvider.ts';
2
2
  export * from './payScene.ts';
3
+ export * from './providerOperationFailure.ts';
@@ -0,0 +1,8 @@
1
+ export class ProviderOperationFailure extends Error {
2
+ constructor(
3
+ readonly failureCode: string,
4
+ readonly summary: string,
5
+ ) {
6
+ super(summary);
7
+ }
8
+ }