@autional/shared 0.1.0-rc.39 → 0.1.0-rc.41

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autional/shared",
3
- "version": "0.1.0-rc.39",
3
+ "version": "0.1.0-rc.41",
4
4
  "description": "Autional shared layer — API client, auth, types, hooks, utils",
5
5
  "license": "AGPL-3.0",
6
6
  "main": "./src/index.ts",
@@ -4726,6 +4726,7 @@ export interface CheckRoleRequest {
4726
4726
  /** 检查用户名可用性请求 */
4727
4727
  export interface CheckUsernameRequest {
4728
4728
  username: string; // Username | @example john_doe
4729
+ tenantId?: string; // 目标租户(地址栏租户优先)
4729
4730
  }
4730
4731
 
4731
4732
  /** 检查用户名可用性结果 */
@@ -5691,6 +5692,7 @@ export interface ReapplyRegistrationRequest {
5691
5692
  email: string; // Email
5692
5693
  invitationCode?: string; // 邀请码
5693
5694
  reason?: string; // 申请理由
5695
+ tenantId?: string; // 目标租户(地址栏租户优先)
5694
5696
  }
5695
5697
 
5696
5698
  export interface ReapplyRegistrationResponse {
@@ -4,19 +4,36 @@ import { extractApiError, extractApiErrorMessage } from '../error';
4
4
  // UP-17-B 回归锁(AC-401):extractApiError message 键链。
5
5
  // 后端 Problem 契约(service-core/base/dto/problem.go)为 title 必填 / detail / code / i18n_key,无 message;
6
6
  // 只认 message 会把 Problem 类错误整类退化为 defaultMsg。
7
- describe('extractApiError message 键链(UP-17-B / AC-401)', () => {
8
- it('title 优先:Problem 契约(title/detail/code)→ 取 title', () => {
7
+ // U380 回归锁:detail 优先于 title,对齐 Problem.GetMessage()(Detail 非空优先)。
8
+ describe('extractApiError message 键链(UP-17-B / AC-401 / U380)', () => {
9
+ it('detail 优先:Problem 契约(title/detail/code)→ 取 detail', () => {
9
10
  const err = {
10
- response: { data: { code: 403, title: '平台级访问受限', detail: '需要平台角色' } },
11
+ response: { data: { code: 403, title: 'Platform Access Denied', detail: '需要平台角色' } },
11
12
  };
12
13
  const out = extractApiError(err, 'fallback');
13
- expect(out.message).toBe('平台级访问受限');
14
+ expect(out.message).toBe('需要平台角色');
14
15
  expect(out.code).toBe(403);
15
16
  });
16
17
 
17
- it('detail 兜底:无 message/title 时取 detail', () => {
18
- const err = { response: { data: { detail: '令牌已过期' } } };
19
- expect(extractApiError(err, 'fallback').message).toBe('令牌已过期');
18
+ it('title 兜底:无 message/detail 时取 title', () => {
19
+ const err = { response: { data: { title: 'Invalid Request' } } };
20
+ expect(extractApiError(err, 'fallback').message).toBe('Invalid Request');
21
+ });
22
+
23
+ it('U380:英文 title + 中文 detail → 中文 detail 胜出', () => {
24
+ const err = {
25
+ response: {
26
+ data: {
27
+ code: 61040050,
28
+ title: 'push challenge not found',
29
+ detail: '推送挑战未找到',
30
+ i18n_key: 'error.push_challenge_not_found',
31
+ },
32
+ },
33
+ };
34
+ const out = extractApiError(err, 'fallback');
35
+ expect(out.message).toBe('推送挑战未找到');
36
+ expect(out.i18nKey).toBe('error.push_challenge_not_found');
20
37
  });
21
38
 
22
39
  it('皆无回落 err.message,再皆无回落 defaultMsg', () => {
@@ -52,8 +69,8 @@ describe('extractApiError i18n_key 透出(AUTH-46)', () => {
52
69
  };
53
70
  const out = extractApiError(err, 'fallback');
54
71
  expect(out.i18nKey).toBe('error.oauth_state_missing');
55
- // message 键链不回归(title 优先于 detail)
56
- expect(out.message).toBe('Invalid Parameter');
72
+ // U380:键链为 message → detail → title
73
+ expect(out.message).toBe('state not found');
57
74
  });
58
75
 
59
76
  it('响应拦截器深 camel 后(i18nKey)同样识别', () => {
@@ -17,13 +17,15 @@ export function extractApiErrorMessage(err: unknown, defaultMsg: string): string
17
17
 
18
18
  export function extractApiError(err: unknown, defaultMsg: string): ExtractedApiError {
19
19
  // UP-17-B:后端 Problem 契约(service-core/base/dto/problem.go)字段为 title(必填)/ detail / code / i18n_key,
20
- // **没有 message** —— 只认 message 会把整类后端错误退化成 defaultMsg。键链:message → title → detail → err.message。
20
+ // **没有 message** —— 只认 message 会把整类后端错误退化成 defaultMsg。
21
+ // U380:键链 message → detail → title,对齐 Problem.GetMessage()(Detail 非空优先),
22
+ // 避免英文 title 压过本地化 detail。
21
23
  // 继续用 `||`(而非 `??`):空串语义按「缺省」处理,与既有实现一致。
22
24
  // AUTH-46:附加透出 i18n_key(响应拦截器深 camel 后为 i18nKey,两者都认)。
23
25
  const data = (err as any)?.response?.data;
24
26
  return {
25
27
  code: data?.code || 'UNKNOWN',
26
- message: data?.message || data?.title || data?.detail || (err as any)?.message || defaultMsg,
28
+ message: data?.message || data?.detail || data?.title || (err as any)?.message || defaultMsg,
27
29
  i18nKey: data?.i18n_key || data?.i18nKey || undefined,
28
30
  };
29
31
  }