@windrun-huaiin/third-ui 30.1.0 → 31.0.0

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 (91) hide show
  1. package/README.md +109 -143
  2. package/dist/ai/ai-prompt-textarea.js +5 -5
  3. package/dist/ai/ai-prompt-textarea.mjs +5 -5
  4. package/dist/clerk/clerk-auth-appearance.d.ts +13 -0
  5. package/dist/clerk/clerk-auth-appearance.js +19 -0
  6. package/dist/clerk/clerk-auth-appearance.mjs +15 -0
  7. package/dist/clerk/clerk-auth-modal-appearance.d.ts +12 -0
  8. package/dist/clerk/clerk-auth-modal-appearance.js +17 -0
  9. package/dist/clerk/clerk-auth-modal-appearance.mjs +14 -0
  10. package/dist/clerk/clerk-page-context-generator.js +3 -3
  11. package/dist/clerk/clerk-page-context-generator.mjs +3 -3
  12. package/dist/clerk/clerk-page-generator.js +4 -4
  13. package/dist/clerk/clerk-page-generator.mjs +4 -4
  14. package/dist/clerk/clerk-user-client.js +2 -1
  15. package/dist/clerk/clerk-user-client.mjs +2 -1
  16. package/dist/clerk/fingerprint/fingerprint-client.d.ts +10 -10
  17. package/dist/clerk/fingerprint/fingerprint-client.js +20 -20
  18. package/dist/clerk/fingerprint/fingerprint-client.mjs +20 -20
  19. package/dist/clerk/fingerprint/fingerprint-provider.d.ts +3 -3
  20. package/dist/clerk/fingerprint/fingerprint-provider.js +8 -8
  21. package/dist/clerk/fingerprint/fingerprint-provider.mjs +8 -8
  22. package/dist/clerk/fingerprint/fingerprint-server.d.ts +12 -12
  23. package/dist/clerk/fingerprint/fingerprint-server.js +17 -17
  24. package/dist/clerk/fingerprint/fingerprint-server.mjs +17 -17
  25. package/dist/clerk/fingerprint/fingerprint-shared.d.ts +3 -3
  26. package/dist/clerk/fingerprint/fingerprint-shared.js +10 -10
  27. package/dist/clerk/fingerprint/fingerprint-shared.mjs +10 -10
  28. package/dist/clerk/fingerprint/types.d.ts +0 -1
  29. package/dist/clerk/fingerprint/use-fingerprint.js +7 -7
  30. package/dist/clerk/fingerprint/use-fingerprint.mjs +7 -7
  31. package/dist/clerk/signin-with-fingerprint-client.d.ts +2 -2
  32. package/dist/clerk/signin-with-fingerprint-client.js +7 -6
  33. package/dist/clerk/signin-with-fingerprint-client.mjs +7 -6
  34. package/dist/clerk/signup-button-with-fingerprint-client.js +6 -4
  35. package/dist/clerk/signup-button-with-fingerprint-client.mjs +6 -4
  36. package/dist/clerk/signup-with-fingerprint-client.d.ts +2 -2
  37. package/dist/clerk/signup-with-fingerprint-client.js +7 -6
  38. package/dist/clerk/signup-with-fingerprint-client.mjs +7 -6
  39. package/dist/fuma/heavy/mermaid.js +1 -1
  40. package/dist/fuma/heavy/mermaid.mjs +1 -1
  41. package/dist/fuma/site-x.js +0 -1
  42. package/dist/fuma/site-x.mjs +0 -1
  43. package/dist/main/calendar/calendar-date-range-input.js +1 -1
  44. package/dist/main/calendar/calendar-date-range-input.mjs +1 -1
  45. package/dist/main/credit/types.d.ts +8 -8
  46. package/dist/main/money-price/index.d.ts +1 -1
  47. package/dist/main/money-price/money-price-button.js +10 -10
  48. package/dist/main/money-price/money-price-button.mjs +10 -10
  49. package/dist/main/money-price/money-price-config-util.d.ts +30 -30
  50. package/dist/main/money-price/money-price-config-util.js +48 -48
  51. package/dist/main/money-price/money-price-config-util.mjs +48 -48
  52. package/dist/main/money-price/money-price-interactive.js +30 -18
  53. package/dist/main/money-price/money-price-interactive.mjs +30 -18
  54. package/dist/main/money-price/money-price-types.d.ts +7 -1
  55. package/dist/main/money-price/money-price-types.js +2 -2
  56. package/dist/main/money-price/money-price-types.mjs +2 -2
  57. package/dist/main/money-price/server.d.ts +1 -1
  58. package/dist/main/pill-select/x-pill-select.js +2 -2
  59. package/dist/main/pill-select/x-pill-select.mjs +2 -2
  60. package/dist/main/server.d.ts +1 -1
  61. package/package.json +13 -7
  62. package/src/ai/ai-prompt-textarea.tsx +6 -6
  63. package/src/clerk/clerk-auth-appearance.ts +16 -0
  64. package/src/clerk/clerk-page-context-generator.tsx +3 -5
  65. package/src/clerk/clerk-page-generator.tsx +9 -8
  66. package/src/clerk/clerk-user-client.tsx +14 -5
  67. package/src/clerk/fingerprint/fingerprint-client.ts +20 -20
  68. package/src/clerk/fingerprint/fingerprint-provider.tsx +11 -11
  69. package/src/clerk/fingerprint/fingerprint-server.ts +17 -17
  70. package/src/clerk/fingerprint/fingerprint-shared.ts +10 -10
  71. package/src/clerk/fingerprint/types.ts +0 -1
  72. package/src/clerk/fingerprint/use-fingerprint.ts +7 -7
  73. package/src/clerk/signin-with-fingerprint-client.tsx +7 -7
  74. package/src/clerk/signup-button-with-fingerprint-client.tsx +7 -5
  75. package/src/clerk/signup-with-fingerprint-client.tsx +7 -7
  76. package/src/fuma/base/custom-home-layout.tsx +4 -4
  77. package/src/fuma/heavy/mermaid.tsx +1 -1
  78. package/src/fuma/site-x.tsx +0 -1
  79. package/src/main/calendar/calendar-date-range-input.tsx +1 -1
  80. package/src/main/credit/types.ts +8 -8
  81. package/src/main/gallery/gallery-mobile-swiper.tsx +0 -1
  82. package/src/main/gallery/gallery-server.tsx +2 -2
  83. package/src/main/money-price/index.ts +2 -0
  84. package/src/main/money-price/money-price-button.tsx +10 -10
  85. package/src/main/money-price/money-price-config-util.ts +49 -49
  86. package/src/main/money-price/money-price-interactive.tsx +40 -20
  87. package/src/main/money-price/money-price-types.ts +21 -14
  88. package/src/main/money-price/server.ts +2 -0
  89. package/src/main/pill-select/x-pill-select.tsx +2 -2
  90. package/src/main/server.ts +3 -1
  91. package/src/styles/third-ui.css +8 -0
@@ -29,21 +29,21 @@ export interface CreditCTAConfig {
29
29
  }
30
30
  export type CreditBucketStatus = 'active' | 'expiringSoon' | 'expired';
31
31
  export interface CreditBucket {
32
- /** 业务方自定义的积分类型标识,用于映射翻译或埋点 */
32
+ /** Business-defined credit type identifier for translation mapping or analytics. */
33
33
  kind: string;
34
- /** 若提供则使用该名称,否则由组件根据 kind 使用默认翻译 */
34
+ /** Display name override; otherwise the component uses the default translation for kind. */
35
35
  label?: string;
36
- /** 当前积分余额 */
36
+ /** Current credit balance. */
37
37
  balance: number;
38
- /** 该类型积分的额度上限 */
38
+ /** Credit limit for this credit type. */
39
39
  limit: number;
40
- /** 可选状态标签,用于强调过期等状态 */
40
+ /** Optional status label for highlighting states such as expiration. */
41
41
  status?: CreditBucketStatus;
42
- /** 积分过期时间(本地时区字符串),用于组件内部推导状态 */
42
+ /** Credit expiration time as a local time string, used to derive component state. */
43
43
  expiresAt?: string;
44
- /** 进度百分比(0-100);未提供时组件按 balance/limit 计算 */
44
+ /** Progress percentage from 0 to 100; computed from balance/limit when omitted. */
45
45
  progressPercent?: number;
46
- /** 任何额外说明,如剩余天数、使用限制等 */
46
+ /** Additional details, such as remaining days or usage limits. */
47
47
  description?: string;
48
48
  }
49
49
  export interface SubscriptionInfo {
@@ -1,4 +1,4 @@
1
1
  export { MoneyPriceInteractive } from './money-price-interactive';
2
2
  export { MoneyPriceButton } from './money-price-button';
3
- export type { MoneyPriceConfig, MoneyPriceData, InitUserContext, MoneyPriceInteractiveProps, MoneyPriceButtonProps, PaymentProvider, PaymentProviderConfig, EnhancePricePlan, SubscriptionProductConfig, CreditPackProductConfig, UserContext, } from './money-price-types';
3
+ export type { MoneyPriceConfig, MoneyPriceData, MoneyPriceAnimeTone, MoneyPriceStrictDiffAnime, InitUserContext, MoneyPriceInteractiveProps, MoneyPriceButtonProps, PaymentProvider, PaymentProviderConfig, EnhancePricePlan, SubscriptionProductConfig, CreditPackProductConfig, UserContext, } from './money-price-types';
4
4
  export { UserState } from './money-price-types';
@@ -26,9 +26,9 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
26
26
  return billing === 'monthly' ? 2 : 4;
27
27
  return 0;
28
28
  };
29
- // OneTime 模式的按钮配置
29
+ // Button configuration for one-time mode.
30
30
  const getOnetimeButtonConfig = () => {
31
- // 匿名用户:所有卡片都显示登录按钮
31
+ // Anonymous users: show the sign-in button on every card.
32
32
  if (!isAuthenticated) {
33
33
  return {
34
34
  text: texts.getStarted,
@@ -38,11 +38,11 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
38
38
  };
39
39
  }
40
40
  if (subscriptionStatus === moneyPriceTypes.UserState.Anonymous) {
41
- // 已登录但状态未知 视为 FreeUser
41
+ // Signed in but status unknown: treat as FreeUser.
42
42
  console.warn('Clerk is authed OK but user is anonymous!');
43
43
  return { text: '', disabled: true, hidden: true };
44
44
  }
45
- // 登录用户:OneTime 模式下所有卡片都显示购买积分按钮
45
+ // Signed-in users: show the buy-credits button on every card in one-time mode.
46
46
  return {
47
47
  text: texts.buyCredits || texts.upgrade,
48
48
  onClick: () => onAction(planKey, billingType),
@@ -50,9 +50,9 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
50
50
  hidden: false
51
51
  };
52
52
  };
53
- // 订阅模式的按钮配置
53
+ // Button configuration for subscription mode.
54
54
  const getSubscriptionButtonConfig = () => {
55
- // 匿名用户
55
+ // Anonymous users.
56
56
  if (!isAuthenticated) {
57
57
  const getButtonText = () => {
58
58
  switch (planKey) {
@@ -73,7 +73,7 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
73
73
  hidden: false
74
74
  };
75
75
  }
76
- // 已登录用户
76
+ // Signed-in users.
77
77
  switch (subscriptionStatus) {
78
78
  case moneyPriceTypes.UserState.FreeUser: {
79
79
  if (planTier === 'F1') {
@@ -91,7 +91,7 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
91
91
  };
92
92
  }
93
93
  case moneyPriceTypes.UserState.ProUser: {
94
- // 不允许降级到 Free
94
+ // Do not allow downgrades to Free.
95
95
  if (planTier === 'F1') {
96
96
  return { hidden: true };
97
97
  }
@@ -169,12 +169,12 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
169
169
  return { hidden: true };
170
170
  }
171
171
  default:
172
- // 已登录但状态未知 视为 FreeUser
172
+ // Signed in but status unknown: treat as FreeUser.
173
173
  console.warn('Clerk is authed OK but user is anonymous!');
174
174
  return { text: '', disabled: true, hidden: true };
175
175
  }
176
176
  };
177
- // 主要的按钮配置函数
177
+ // Main button configuration function.
178
178
  const getButtonConfig = () => {
179
179
  if (billingType === 'onetime') {
180
180
  return getOnetimeButtonConfig();
@@ -24,9 +24,9 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
24
24
  return billing === 'monthly' ? 2 : 4;
25
25
  return 0;
26
26
  };
27
- // OneTime 模式的按钮配置
27
+ // Button configuration for one-time mode.
28
28
  const getOnetimeButtonConfig = () => {
29
- // 匿名用户:所有卡片都显示登录按钮
29
+ // Anonymous users: show the sign-in button on every card.
30
30
  if (!isAuthenticated) {
31
31
  return {
32
32
  text: texts.getStarted,
@@ -36,11 +36,11 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
36
36
  };
37
37
  }
38
38
  if (subscriptionStatus === UserState.Anonymous) {
39
- // 已登录但状态未知 视为 FreeUser
39
+ // Signed in but status unknown: treat as FreeUser.
40
40
  console.warn('Clerk is authed OK but user is anonymous!');
41
41
  return { text: '', disabled: true, hidden: true };
42
42
  }
43
- // 登录用户:OneTime 模式下所有卡片都显示购买积分按钮
43
+ // Signed-in users: show the buy-credits button on every card in one-time mode.
44
44
  return {
45
45
  text: texts.buyCredits || texts.upgrade,
46
46
  onClick: () => onAction(planKey, billingType),
@@ -48,9 +48,9 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
48
48
  hidden: false
49
49
  };
50
50
  };
51
- // 订阅模式的按钮配置
51
+ // Button configuration for subscription mode.
52
52
  const getSubscriptionButtonConfig = () => {
53
- // 匿名用户
53
+ // Anonymous users.
54
54
  if (!isAuthenticated) {
55
55
  const getButtonText = () => {
56
56
  switch (planKey) {
@@ -71,7 +71,7 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
71
71
  hidden: false
72
72
  };
73
73
  }
74
- // 已登录用户
74
+ // Signed-in users.
75
75
  switch (subscriptionStatus) {
76
76
  case UserState.FreeUser: {
77
77
  if (planTier === 'F1') {
@@ -89,7 +89,7 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
89
89
  };
90
90
  }
91
91
  case UserState.ProUser: {
92
- // 不允许降级到 Free
92
+ // Do not allow downgrades to Free.
93
93
  if (planTier === 'F1') {
94
94
  return { hidden: true };
95
95
  }
@@ -167,12 +167,12 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
167
167
  return { hidden: true };
168
168
  }
169
169
  default:
170
- // 已登录但状态未知 视为 FreeUser
170
+ // Signed in but status unknown: treat as FreeUser.
171
171
  console.warn('Clerk is authed OK but user is anonymous!');
172
172
  return { text: '', disabled: true, hidden: true };
173
173
  }
174
174
  };
175
- // 主要的按钮配置函数
175
+ // Main button configuration function.
176
176
  const getButtonConfig = () => {
177
177
  if (billingType === 'onetime') {
178
178
  return getOnetimeButtonConfig();
@@ -1,52 +1,52 @@
1
1
  /**
2
2
  * Money Price Configuration
3
- * 价格组件配置文件
3
+ * Pricing component configuration.
4
4
  */
5
5
  import type { MoneyPriceConfig, PaymentProviderConfig, EnhancePricePlan } from './money-price-types';
6
6
  /**
7
- * 获取当前激活的支付供应商配置
7
+ * Get the currently active payment provider configuration.
8
8
  *
9
- * 🔒 安全设计:
10
- * - util层负责从config中提取激活的provider配置
11
- * - 只返回提取的结果,不暴露任何config结构
12
- * - 调用方(应用层)通过wrapper隐藏config对象
9
+ * Security design:
10
+ * - The utility layer extracts the active provider configuration from the config.
11
+ * - Only the extracted result is returned; the full config structure is not exposed.
12
+ * - Application-level wrappers hide the config object from callers.
13
13
  *
14
- * @param config - MoneyPriceConfig对象(由应用层提供)
15
- * @returns 当前激活的支付供应商配置
14
+ * @param config - MoneyPriceConfig object provided by the application layer.
15
+ * @returns The currently active payment provider configuration.
16
16
  */
17
17
  export declare function getActiveProviderConfigUtil(config: MoneyPriceConfig): PaymentProviderConfig;
18
18
  export declare function getProductPricing(productKey: 'F1' | 'P2' | 'U3', billingType: string, provider: string, config: MoneyPriceConfig): EnhancePricePlan;
19
19
  /**
20
- * 根据 priceId 获取对应的积分数量
20
+ * Get the credit amount for a price ID.
21
21
  *
22
- * 🔒 安全设计:
23
- * - util层负责解析config,提取所需数据
24
- * - 只返回查询结果,不暴露任何config结构
25
- * - 调用方(应用层)通过wrapper隐藏config对象
22
+ * Security design:
23
+ * - The utility layer parses the config and extracts only the required data.
24
+ * - Only the query result is returned; the full config structure is not exposed.
25
+ * - Application-level wrappers hide the config object from callers.
26
26
  *
27
- * @param priceId - 查询的价格ID
28
- * @param config - MoneyPriceConfig对象(由应用层提供)
29
- * @returns 对应的积分数量,或null
27
+ * @param priceId - Price ID to query.
28
+ * @param config - MoneyPriceConfig object provided by the application layer.
29
+ * @returns The matching credit amount, or null.
30
30
  */
31
31
  export declare function getCreditsFromPriceIdUtil(priceId: string | undefined, config: MoneyPriceConfig): number | null;
32
32
  /**
33
- * 根据查询参数获取价格配置
33
+ * Get price configuration by query parameters.
34
34
  *
35
- * 支持三种查询方式:
36
- * 1. priceId 直接查询
37
- * 2. plan + billingType 查询
38
- * 3. plan 查询
35
+ * Supported query modes:
36
+ * 1. Query directly by priceId.
37
+ * 2. Query by plan and billingType.
38
+ * 3. Query by plan.
39
39
  *
40
- * 🔒 安全设计:
41
- * - util层负责解析config,提取和匹配数据
42
- * - 只返回查询结果,不暴露任何config结构
43
- * - 调用方(应用层)通过wrapper隐藏config对象
40
+ * Security design:
41
+ * - The utility layer parses the config and extracts only matching data.
42
+ * - Only the query result is returned; the full config structure is not exposed.
43
+ * - Application-level wrappers hide the config object from callers.
44
44
  *
45
- * @param priceId - 查询的价格ID(可选)
46
- * @param plan - 查询的套餐名称如'P2''U3'(可选)
47
- * @param billingType - 查询的计费类型如'monthly''yearly'(可选)
48
- * @param config - MoneyPriceConfig对象(由应用层提供)
49
- * @returns 匹配的价格配置,包含计算好的元数据(priceNamedescriptioninterval
45
+ * @param priceId - Optional price ID to query.
46
+ * @param plan - Optional plan name, such as 'P2' or 'U3'.
47
+ * @param billingType - Optional billing type, such as 'monthly' or 'yearly'.
48
+ * @param config - MoneyPriceConfig object provided by the application layer.
49
+ * @returns The matching price config with derived metadata: priceName, description, and interval.
50
50
  */
51
51
  export declare function getPriceConfigUtil(priceId: string | undefined, plan: string | undefined, billingType: string | undefined, config: MoneyPriceConfig): (EnhancePricePlan & {
52
52
  priceName: string;
@@ -2,30 +2,30 @@
2
2
 
3
3
  /**
4
4
  * Money Price Configuration
5
- * 价格组件配置文件
5
+ * Pricing component configuration.
6
6
  */
7
7
  /**
8
- * 获取当前激活的支付供应商配置
8
+ * Get the currently active payment provider configuration.
9
9
  *
10
- * 🔒 安全设计:
11
- * - util层负责从config中提取激活的provider配置
12
- * - 只返回提取的结果,不暴露任何config结构
13
- * - 调用方(应用层)通过wrapper隐藏config对象
10
+ * Security design:
11
+ * - The utility layer extracts the active provider configuration from the config.
12
+ * - Only the extracted result is returned; the full config structure is not exposed.
13
+ * - Application-level wrappers hide the config object from callers.
14
14
  *
15
- * @param config - MoneyPriceConfig对象(由应用层提供)
16
- * @returns 当前激活的支付供应商配置
15
+ * @param config - MoneyPriceConfig object provided by the application layer.
16
+ * @returns The currently active payment provider configuration.
17
17
  */
18
18
  function getActiveProviderConfigUtil(config) {
19
19
  const provider = config.activeProvider;
20
20
  return config.paymentProviders[provider];
21
21
  }
22
- // 辅助函数:获取特定产品的价格信息
22
+ // Helper: get pricing information for a specific product.
23
23
  function getProductPricing(productKey, billingType, provider, config) {
24
24
  const providerConfig = config.paymentProviders[provider];
25
- // 如果是 onetime 类型,尝试从积分包中获取
25
+ // For one-time billing, try to resolve pricing from credit packs.
26
26
  if (billingType === 'onetime') {
27
27
  const creditPacks = providerConfig.creditPackProducts;
28
- // 直接使用相同的 keyF1->F1, P2->P2, U3->U3
28
+ // Use the same product key directly: F1 -> F1, P2 -> P2, U3 -> U3.
29
29
  if (creditPacks && creditPacks[productKey]) {
30
30
  const pack = creditPacks[productKey];
31
31
  return {
@@ -36,33 +36,33 @@ function getProductPricing(productKey, billingType, provider, config) {
36
36
  };
37
37
  }
38
38
  }
39
- // 否则从订阅产品中获取
39
+ // Otherwise resolve pricing from subscription products.
40
40
  const products = providerConfig.subscriptionProducts || providerConfig.products;
41
41
  if (products && products[productKey] && products[productKey].plans[billingType]) {
42
42
  return products[productKey].plans[billingType];
43
43
  }
44
44
  throw new Error(`Product pricing not found for ${productKey} ${billingType}`);
45
45
  }
46
- // ============ 安全的util函数 - 只接收简单的映射表参数,不暴露任何config细节 ============
46
+ // ============ Safe utility functions: accept only simple mapping inputs and do not expose config internals ============
47
47
  /**
48
- * 根据 priceId 获取对应的积分数量
48
+ * Get the credit amount for a price ID.
49
49
  *
50
- * 🔒 安全设计:
51
- * - util层负责解析config,提取所需数据
52
- * - 只返回查询结果,不暴露任何config结构
53
- * - 调用方(应用层)通过wrapper隐藏config对象
50
+ * Security design:
51
+ * - The utility layer parses the config and extracts only the required data.
52
+ * - Only the query result is returned; the full config structure is not exposed.
53
+ * - Application-level wrappers hide the config object from callers.
54
54
  *
55
- * @param priceId - 查询的价格ID
56
- * @param config - MoneyPriceConfig对象(由应用层提供)
57
- * @returns 对应的积分数量,或null
55
+ * @param priceId - Price ID to query.
56
+ * @param config - MoneyPriceConfig object provided by the application layer.
57
+ * @returns The matching credit amount, or null.
58
58
  */
59
59
  function getCreditsFromPriceIdUtil(priceId, config) {
60
60
  if (!priceId) {
61
61
  return null;
62
62
  }
63
- // 遍历所有支付提供商
63
+ // Iterate through all payment providers.
64
64
  for (const provider of Object.values(config.paymentProviders)) {
65
- // 遍历订阅产品
65
+ // Iterate through subscription products.
66
66
  const subscriptionProducts = (provider.subscriptionProducts || provider.products);
67
67
  if (subscriptionProducts) {
68
68
  for (const product of Object.values(subscriptionProducts)) {
@@ -76,7 +76,7 @@ function getCreditsFromPriceIdUtil(priceId, config) {
76
76
  }
77
77
  }
78
78
  }
79
- // 遍历积分包产品
79
+ // Iterate through credit pack products.
80
80
  const creditPacks = provider.creditPackProducts;
81
81
  if (creditPacks) {
82
82
  for (const pack of Object.values(creditPacks)) {
@@ -90,46 +90,46 @@ function getCreditsFromPriceIdUtil(priceId, config) {
90
90
  return null;
91
91
  }
92
92
  /**
93
- * 根据查询参数获取价格配置
93
+ * Get price configuration by query parameters.
94
94
  *
95
- * 支持三种查询方式:
96
- * 1. priceId 直接查询
97
- * 2. plan + billingType 查询
98
- * 3. plan 查询
95
+ * Supported query modes:
96
+ * 1. Query directly by priceId.
97
+ * 2. Query by plan and billingType.
98
+ * 3. Query by plan.
99
99
  *
100
- * 🔒 安全设计:
101
- * - util层负责解析config,提取和匹配数据
102
- * - 只返回查询结果,不暴露任何config结构
103
- * - 调用方(应用层)通过wrapper隐藏config对象
100
+ * Security design:
101
+ * - The utility layer parses the config and extracts only matching data.
102
+ * - Only the query result is returned; the full config structure is not exposed.
103
+ * - Application-level wrappers hide the config object from callers.
104
104
  *
105
- * @param priceId - 查询的价格ID(可选)
106
- * @param plan - 查询的套餐名称如'P2''U3'(可选)
107
- * @param billingType - 查询的计费类型如'monthly''yearly'(可选)
108
- * @param config - MoneyPriceConfig对象(由应用层提供)
109
- * @returns 匹配的价格配置,包含计算好的元数据(priceNamedescriptioninterval
105
+ * @param priceId - Optional price ID to query.
106
+ * @param plan - Optional plan name, such as 'P2' or 'U3'.
107
+ * @param billingType - Optional billing type, such as 'monthly' or 'yearly'.
108
+ * @param config - MoneyPriceConfig object provided by the application layer.
109
+ * @returns The matching price config with derived metadata: priceName, description, and interval.
110
110
  */
111
111
  function getPriceConfigUtil(priceId, plan, billingType, config) {
112
- // 遍历所有支付提供商
112
+ // Iterate through all payment providers.
113
113
  for (const provider of Object.values(config.paymentProviders)) {
114
- // 遍历订阅产品
114
+ // Iterate through subscription products.
115
115
  const subscriptionProducts = (provider.subscriptionProducts || provider.products);
116
116
  if (subscriptionProducts) {
117
117
  for (const [productKey, product] of Object.entries(subscriptionProducts)) {
118
118
  if (product.plans) {
119
119
  for (const [billingKey, planConfig] of Object.entries(product.plans)) {
120
120
  const plan_config = planConfig;
121
- // 匹配逻辑:按优先级尝试
122
- // 1. priceId精确匹配(优先级最高)
121
+ // Matching order by priority.
122
+ // 1. Exact priceId match with highest priority.
123
123
  if (priceId && plan_config.priceId === priceId) {
124
124
  return Object.assign(Object.assign({}, plan_config), { priceName: `${productKey} ${billingKey}`, description: `${productKey} plan - ${billingKey} billing`, interval: billingKey === 'yearly' ? 'year' : 'month' });
125
125
  }
126
- // 2. planbillingType同时匹配
126
+ // 2. Match by both plan and billingType.
127
127
  if (!priceId && plan && billingType) {
128
128
  if (productKey === plan && billingKey === billingType) {
129
129
  return Object.assign(Object.assign({}, plan_config), { priceName: `${productKey} ${billingKey}`, description: `${productKey} plan - ${billingKey} billing`, interval: billingKey === 'yearly' ? 'year' : 'month' });
130
130
  }
131
131
  }
132
- // 3. plan匹配(billingType为空时)
132
+ // 3. Match by plan when billingType is empty.
133
133
  if (!priceId && !billingType && plan && productKey === plan) {
134
134
  return Object.assign(Object.assign({}, plan_config), { priceName: `${productKey} ${billingKey}`, description: `${productKey} plan - ${billingKey} billing`, interval: billingKey === 'yearly' ? 'year' : 'month' });
135
135
  }
@@ -137,12 +137,12 @@ function getPriceConfigUtil(priceId, plan, billingType, config) {
137
137
  }
138
138
  }
139
139
  }
140
- // 遍历积分包产品
140
+ // Iterate through credit pack products.
141
141
  const creditPacks = provider.creditPackProducts;
142
142
  if (creditPacks) {
143
143
  for (const [packKey, pack] of Object.entries(creditPacks)) {
144
144
  const pack_typed = pack;
145
- // 积分包匹配
145
+ // Credit pack match.
146
146
  if (priceId && pack_typed.priceId === priceId) {
147
147
  return {
148
148
  priceId: pack_typed.priceId,
@@ -154,7 +154,7 @@ function getPriceConfigUtil(priceId, plan, billingType, config) {
154
154
  interval: 'onetime',
155
155
  };
156
156
  }
157
- // plan和onetime匹配
157
+ // Match by plan and one-time billing.
158
158
  if (!priceId && plan && billingType === 'onetime') {
159
159
  if (packKey === plan) {
160
160
  return {
@@ -168,7 +168,7 @@ function getPriceConfigUtil(priceId, plan, billingType, config) {
168
168
  };
169
169
  }
170
170
  }
171
- // plan匹配(billingType为空时也能找到first积分包)
171
+ // Match by plan; also resolves the first credit pack when billingType is empty.
172
172
  if (!priceId && !billingType && plan && packKey === plan) {
173
173
  return {
174
174
  priceId: pack_typed.priceId,