@lark-apaas/client-toolkit 1.1.21-alpha.auth.dev.0 → 1.1.21-alpha.auth.dev.10

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 (42) hide show
  1. package/README.md +68 -0
  2. package/lib/antd-table.d.ts +4 -0
  3. package/lib/antd-table.js +2 -0
  4. package/lib/apis/utils/getAxiosForBackend.d.ts +1 -0
  5. package/lib/apis/utils/getAxiosForBackend.js +1 -0
  6. package/lib/auth.d.ts +1 -0
  7. package/lib/auth.js +2 -0
  8. package/lib/components/AppContainer/index.js +179 -8
  9. package/lib/components/AppContainer/safety.js +16 -16
  10. package/lib/components/AppContainer/utils/getLarkUser.d.ts +1 -0
  11. package/lib/components/AppContainer/utils/getLarkUser.js +17 -0
  12. package/lib/components/AppContainer/utils/tea.d.ts +8 -0
  13. package/lib/components/AppContainer/utils/tea.js +51 -0
  14. package/lib/components/ErrorRender/index.js +17 -10
  15. package/lib/components/User/UserDisplay.d.ts +3 -2
  16. package/lib/components/User/UserDisplay.js +24 -23
  17. package/lib/components/User/index.d.ts +1 -1
  18. package/lib/components/ui/badge.d.ts +1 -1
  19. package/lib/components/ui/button.d.ts +1 -1
  20. package/lib/hooks/useCurrentUserProfile.js +4 -4
  21. package/lib/logger/selected-logs.js +11 -3
  22. package/lib/server-log/index.d.ts +9 -0
  23. package/lib/server-log/index.js +2 -0
  24. package/lib/server-log/poller.d.ts +87 -0
  25. package/lib/server-log/poller.js +135 -0
  26. package/lib/server-log/types.d.ts +166 -0
  27. package/lib/server-log/types.js +0 -0
  28. package/lib/types/index.d.ts +1 -0
  29. package/lib/types/tea.d.ts +7 -0
  30. package/lib/types/tea.js +5 -0
  31. package/lib/utils/axiosConfig.js +118 -48
  32. package/lib/utils/deviceType.d.ts +3 -0
  33. package/lib/utils/deviceType.js +13 -0
  34. package/lib/utils/getAxiosForBackend.d.ts +11 -0
  35. package/lib/utils/getAxiosForBackend.js +21 -0
  36. package/lib/utils/getParentOrigin.d.ts +2 -1
  37. package/lib/utils/getParentOrigin.js +8 -1
  38. package/lib/utils/requestManager.d.ts +2 -0
  39. package/lib/utils/requestManager.js +26 -0
  40. package/lib/utils/userProfileCache.d.ts +12 -0
  41. package/lib/utils/userProfileCache.js +26 -0
  42. package/package.json +20 -5
@@ -1,59 +1,129 @@
1
1
  import axios from "axios";
2
2
  import { logger } from "../apis/logger.js";
3
3
  import { getStacktrace } from "../logger/selected-logs.js";
4
- async function logResponse(ok, response) {
5
- const okToTextMap = {
6
- success: '请求成功:',
7
- error: '请求失败:'
8
- };
9
- const realOK = 'success' === ok && response.status >= 200 && response.status < 300;
10
- const parts = [
11
- okToTextMap[realOK ? 'success' : 'error'],
12
- (response.config.url || '').split('?')[0].replace(/^\/spark\/p\/app_\w+/, ''),
13
- ' - ',
14
- Date.now() - response.config._startTime,
15
- 'ms'
16
- ];
17
- const logTraceID = response.headers['x-log-trace-id'];
18
- const queryParams = {};
19
- const url = response.config.url || '';
20
- const queryString = url.split('?')[1];
21
- if (queryString) {
22
- const urlParams = new URLSearchParams(queryString);
23
- urlParams.forEach((value, key)=>{
24
- queryParams[key] = value;
4
+ const isValidResponse = (resp)=>null != resp && 'object' == typeof resp && 'config' in resp && null !== resp.config && void 0 !== resp.config && 'object' == typeof resp.config && 'status' in resp && 'number' == typeof resp.status && 'data' in resp;
5
+ async function logResponse(ok, responseOrError) {
6
+ if (isValidResponse(responseOrError)) {
7
+ const response = responseOrError;
8
+ const okToTextMap = {
9
+ success: '请求成功:',
10
+ error: '请求失败:'
11
+ };
12
+ const realOK = 'success' === ok && response.status >= 200 && response.status < 300;
13
+ const method = (response.config.method || 'GET').toUpperCase();
14
+ const parts = [
15
+ okToTextMap[realOK ? 'success' : 'error'],
16
+ method,
17
+ ' ',
18
+ (response.config.url || '').split('?')[0].replace(/^\/spark\/p\/app_\w+/, ''),
19
+ ' - ',
20
+ Date.now() - response.config._startTime,
21
+ 'ms'
22
+ ];
23
+ const logTraceID = response.headers?.['x-log-trace-id'];
24
+ const queryParams = {};
25
+ const url = response.config.url || '';
26
+ const queryString = url.split('?')[1];
27
+ if (queryString) {
28
+ const urlParams = new URLSearchParams(queryString);
29
+ urlParams.forEach((value, key)=>{
30
+ queryParams[key] = value;
31
+ });
32
+ }
33
+ if (response.config.params) Object.assign(queryParams, response.config.params);
34
+ const args = [
35
+ {
36
+ 请求参数: response.config.data,
37
+ ...Object.keys(queryParams).length > 0 && {
38
+ 查询参数: queryParams
39
+ },
40
+ 返回数据: response.data,
41
+ 请求摘要: {
42
+ 方法: method,
43
+ TraceID: logTraceID,
44
+ 状态: `${response.statusText}[状态码${response.status}]`,
45
+ 时间: `${new Date().toLocaleString()}`
46
+ }
47
+ }
48
+ ];
49
+ const requestUUID = response.config._requestUUID;
50
+ const stacktrace = await requestStacktraceMap.get(requestUUID);
51
+ const logMeta = {
52
+ logTraceID
53
+ };
54
+ if (stacktrace) logMeta.stacktrace = stacktrace;
55
+ logger.log({
56
+ level: ok,
57
+ args: [
58
+ parts.join(''),
59
+ ...args
60
+ ],
61
+ meta: logMeta
25
62
  });
63
+ return;
26
64
  }
27
- if (response.config.params) Object.assign(queryParams, response.config.params);
28
- const args = [
29
- {
30
- '请求参数:': response.config.data,
31
- ...Object.keys(queryParams).length > 0 && {
32
- '查询参数:': queryParams
33
- },
34
- '返回数据:': response.data,
35
- '请求摘要:': {
36
- TraceID: logTraceID,
37
- 状态: `${response.statusText}[状态码${response.status}]`,
38
- 时间: `${new Date().toLocaleString()}`
39
- }
65
+ const error = responseOrError;
66
+ if (error && error.config && 'object' == typeof error.config) {
67
+ const errorType = error.code || 'UNKNOWN_ERROR';
68
+ const errorMessage = error.message || '未知错误';
69
+ const method = (error.config.method || 'GET').toUpperCase();
70
+ const url = error.config.url || '';
71
+ const startTime = error.config._startTime;
72
+ const duration = startTime ? Date.now() - startTime : 0;
73
+ const parts = [
74
+ '网络请求失败:',
75
+ method,
76
+ ' ',
77
+ url.split('?')[0].replace(/^\/spark\/p\/app_\w+/, ''),
78
+ ' - ',
79
+ errorType,
80
+ duration > 0 ? ` (${duration}ms)` : ''
81
+ ];
82
+ const queryParams = {};
83
+ const queryString = url.split('?')[1];
84
+ if (queryString) {
85
+ const urlParams = new URLSearchParams(queryString);
86
+ urlParams.forEach((value, key)=>{
87
+ queryParams[key] = value;
88
+ });
40
89
  }
41
- ];
42
- const requestUUID = response.config._requestUUID;
43
- const stacktrace = await requestStacktraceMap.get(requestUUID);
44
- const logMeta = {
45
- logTraceID
46
- };
47
- if (stacktrace) logMeta.stacktrace = stacktrace;
90
+ if (error.config.params) Object.assign(queryParams, error.config.params);
91
+ const args = [
92
+ {
93
+ 请求参数: error.config.data,
94
+ ...Object.keys(queryParams).length > 0 && {
95
+ 查询参数: queryParams
96
+ },
97
+ 错误信息: errorMessage,
98
+ 请求摘要: {
99
+ 方法: method,
100
+ 错误类型: errorType,
101
+ 错误代码: error.code,
102
+ 超时设置: error.config.timeout,
103
+ 时间: `${new Date().toLocaleString()}`
104
+ }
105
+ }
106
+ ];
107
+ const requestUUID = error.config._requestUUID;
108
+ const stacktrace = await requestStacktraceMap.get(requestUUID);
109
+ const logMeta = {};
110
+ if (stacktrace) logMeta.stacktrace = stacktrace;
111
+ logger.log({
112
+ level: 'error',
113
+ args: [
114
+ parts.join(''),
115
+ ...args
116
+ ],
117
+ meta: logMeta
118
+ });
119
+ return;
120
+ }
48
121
  logger.log({
49
- level: ok,
122
+ level: 'error',
50
123
  args: [
51
- parts.join(''),
52
- ...args
124
+ '请求失败:无响应对象或配置信息'
53
125
  ],
54
- meta: {
55
- logTraceID
56
- }
126
+ meta: {}
57
127
  });
58
128
  }
59
129
  const requestStacktraceMap = new Map();
@@ -73,7 +143,7 @@ function initAxiosConfig(axiosInstance) {
73
143
  logResponse('success', response);
74
144
  return response;
75
145
  }, (error)=>{
76
- logResponse('error', error.response);
146
+ logResponse('error', error.response || error);
77
147
  return Promise.reject(error);
78
148
  });
79
149
  }
@@ -0,0 +1,3 @@
1
+ export declare const isIpad: () => boolean;
2
+ export declare const isMobile: () => boolean;
3
+ export declare const isIOS: () => boolean;
@@ -0,0 +1,13 @@
1
+ const isIpad = ()=>{
2
+ const _isIpad = /iPad|Tab|Tablet/i.test(navigator.userAgent) && navigator.maxTouchPoints && navigator.maxTouchPoints > 1;
3
+ return Boolean(_isIpad);
4
+ };
5
+ const isMobile = ()=>{
6
+ const isPhone = /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i.test(navigator.userAgent);
7
+ return isPhone || isIpad();
8
+ };
9
+ const isIOS = ()=>{
10
+ if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) return true;
11
+ return false;
12
+ };
13
+ export { isIOS, isIpad, isMobile };
@@ -0,0 +1,11 @@
1
+ import { AxiosInstance } from 'axios';
2
+ declare module 'axios' {
3
+ interface AxiosRequestConfig {
4
+ meta?: {
5
+ autoJumpToLogin?: boolean;
6
+ };
7
+ }
8
+ }
9
+ /** 获取axios实例 */
10
+ export declare function getAxiosForBackend(): AxiosInstance;
11
+ export declare const axiosForBackend: AxiosInstance;
@@ -0,0 +1,21 @@
1
+ import axios from "axios";
2
+ import { initAxiosConfig } from "./axiosConfig.js";
3
+ let axiosInstance;
4
+ function getAxiosForBackend() {
5
+ if (!axiosInstance) {
6
+ axiosInstance = axios.create({
7
+ baseURL: process.env.CLIENT_BASE_PATH || '/'
8
+ });
9
+ axiosInstance.interceptors.response.use(null, (err)=>{
10
+ if (err.config.meta?.autoJumpToLogin !== false) {
11
+ const loginUrl = err.response?.headers?.['x-login-url'];
12
+ if (loginUrl) window.location.href = loginUrl;
13
+ }
14
+ return Promise.reject(err);
15
+ });
16
+ initAxiosConfig(axiosInstance);
17
+ }
18
+ return axiosInstance;
19
+ }
20
+ const axiosForBackend = getAxiosForBackend();
21
+ export { axiosForBackend, getAxiosForBackend };
@@ -1,5 +1,6 @@
1
+ export declare function getEnv(): 'BOE' | 'PRE' | 'ONLINE';
1
2
  /**
2
3
  * @internal
3
4
  * 获取预览环境父级域名
4
5
  */
5
- export declare function getPreviewParentOrigin(): "https://miaoda.feishu.cn" | "https://miaoda.feishu-pre.cn" | "https://miaoda.feishu-boe.cn";
6
+ export declare function getPreviewParentOrigin(): "https://force.feishu-boe.cn" | "https://miaoda.feishu.cn" | "https://miaoda.feishu-pre.cn" | "https://miaoda.feishu-boe.cn";
@@ -1,7 +1,14 @@
1
+ function getEnv() {
2
+ const { origin } = window.location;
3
+ if (origin.includes('feishuapp.cn') || origin.includes('miaoda.feishuapp.net')) return 'ONLINE';
4
+ if (origin.includes('fsapp.kundou.cn') || origin.includes('miaoda-pre.feishuapp.net')) return 'PRE';
5
+ return 'BOE';
6
+ }
1
7
  function getPreviewParentOrigin() {
2
8
  const { origin } = window.location;
9
+ if (origin.includes('force.byted.org')) return 'https://force.feishu-boe.cn';
3
10
  if (origin.includes('feishuapp.cn') || origin.includes('miaoda.feishuapp.net')) return 'https://miaoda.feishu.cn';
4
11
  if (origin.includes('fsapp.kundou.cn') || origin.includes('miaoda-pre.feishuapp.net')) return 'https://miaoda.feishu-pre.cn';
5
12
  return 'https://miaoda.feishu-boe.cn';
6
13
  }
7
- export { getPreviewParentOrigin };
14
+ export { getEnv, getPreviewParentOrigin };
@@ -0,0 +1,2 @@
1
+ import type { IUserProfile } from '../apis/udt-types';
2
+ export declare function fetchWithDeduplication(ids: string[]): Promise<IUserProfile[] | null>;
@@ -0,0 +1,26 @@
1
+ import { getDataloom } from "../integrations/dataloom.js";
2
+ const pendingRequests = new Map();
3
+ async function fetchUserProfilesByIds(ids) {
4
+ try {
5
+ const dataloom = await getDataloom();
6
+ if (!dataloom) throw new Error('Dataloom client is unavailable');
7
+ const numericIds = ids.map(Number).filter(Number.isFinite);
8
+ if (0 === numericIds.length) return [];
9
+ const response = await dataloom.service.user.getByIds(numericIds);
10
+ return Array.isArray(response?.data) ? response.data : response?.data?.user_list || [];
11
+ } catch (error) {
12
+ console.error(`Failed to fetch profiles for user IDs ${ids.join(', ')}:`, error);
13
+ return null;
14
+ }
15
+ }
16
+ function fetchWithDeduplication(ids) {
17
+ const key = ids.sort().join(',');
18
+ if (pendingRequests.has(key)) return pendingRequests.get(key);
19
+ const fetchPromise = fetchUserProfilesByIds(ids);
20
+ pendingRequests.set(key, fetchPromise);
21
+ fetchPromise.finally(()=>{
22
+ pendingRequests.delete(key);
23
+ });
24
+ return fetchPromise;
25
+ }
26
+ export { fetchWithDeduplication };
@@ -0,0 +1,12 @@
1
+ import type { IUserProfile } from '../apis/udt-types';
2
+ export interface ICachedUserProfile {
3
+ profile: IUserProfile;
4
+ timestamp: number;
5
+ }
6
+ export declare const cache: Map<string, ICachedUserProfile>;
7
+ export declare const cacheExpiry: number;
8
+ export declare function setCachedUserProfiles(profiles: IUserProfile[]): void;
9
+ export declare function getCachedUserProfiles(ids: string[]): {
10
+ cachedProfiles: IUserProfile[];
11
+ remainingIds: string[];
12
+ };
@@ -0,0 +1,26 @@
1
+ const cache = new Map();
2
+ const cacheExpiry = 1 / 0;
3
+ function setCachedUserProfiles(profiles) {
4
+ const now = Date.now();
5
+ profiles.forEach((profile)=>{
6
+ if (profile && profile.user_id) cache.set(String(profile.user_id), {
7
+ profile,
8
+ timestamp: now
9
+ });
10
+ });
11
+ }
12
+ function getCachedUserProfiles(ids) {
13
+ const cachedProfiles = [];
14
+ const remainingIds = [];
15
+ const now = Date.now();
16
+ ids.forEach((id)=>{
17
+ const cachedItem = cache.get(id);
18
+ if (cachedItem && now - cachedItem.timestamp < cacheExpiry) cachedProfiles.push(cachedItem.profile);
19
+ else remainingIds.push(id);
20
+ });
21
+ return {
22
+ cachedProfiles,
23
+ remainingIds
24
+ };
25
+ }
26
+ export { cache, cacheExpiry, getCachedUserProfiles, setCachedUserProfiles };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/client-toolkit",
3
- "version": "1.1.21-alpha.auth.dev.0",
3
+ "version": "1.1.21-alpha.auth.dev.10",
4
4
  "types": "./lib/index.d.ts",
5
5
  "main": "./lib/index.js",
6
6
  "files": [
@@ -15,6 +15,11 @@
15
15
  "require": "./lib/index.js",
16
16
  "types": "./lib/index.d.ts"
17
17
  },
18
+ "./antd-table": {
19
+ "import": "./lib/antd-table.js",
20
+ "require": "./lib/antd-table.js",
21
+ "types": "./lib/antd-table.d.ts"
22
+ },
18
23
  "./lib/index.css": "./lib/index.css",
19
24
  "./dataloom": {
20
25
  "import": "./lib/apis/dataloom.js",
@@ -55,6 +60,11 @@
55
60
  "import": "./lib/apis/utils/*.js",
56
61
  "require": "./lib/apis/utils/*.js",
57
62
  "types": "./lib/apis/utils/*.d.ts"
63
+ },
64
+ "./auth": {
65
+ "import": "./lib/auth.js",
66
+ "require": "./lib/auth.js",
67
+ "types": "./lib/auth.d.ts"
58
68
  }
59
69
  },
60
70
  "scripts": {
@@ -75,17 +85,19 @@
75
85
  "dependencies": {
76
86
  "@ant-design/colors": "^7.2.1",
77
87
  "@ant-design/cssinjs": "^1.24.0",
78
- "@data-loom/js": "^0.4.0",
79
- "@lark-apaas/auth-sdk": "^0.1.0-alpha.3",
80
- "@lark-apaas/miaoda-inspector": "^1.0.4",
88
+ "@data-loom/js": "0.4.4-auth-alpha.11",
89
+ "@lark-apaas/auth-sdk": "0.1.0-alpha.13",
90
+ "@lark-apaas/miaoda-inspector": "^1.0.5",
81
91
  "@radix-ui/react-avatar": "^1.1.10",
82
92
  "@radix-ui/react-popover": "^1.1.15",
83
93
  "@radix-ui/react-slot": "^1.2.3",
84
94
  "@radix-ui/react-tooltip": "^1.2.8",
85
95
  "@zumer/snapdom": "^1.9.14",
86
96
  "axios": "^1.12.2",
97
+ "blueimp-md5": "2.10.0",
87
98
  "class-variance-authority": "^0.7.1",
88
99
  "clsx": "~2.0.1",
100
+ "crypto-js": "3.1.9-1",
89
101
  "dayjs": "^1.11.13",
90
102
  "echarts": "^6.0.0",
91
103
  "lodash": "^4.17.21",
@@ -118,6 +130,8 @@
118
130
  "@tailwindcss/postcss": "^4.1.0",
119
131
  "@testing-library/jest-dom": "^6.6.4",
120
132
  "@testing-library/react": "^16.3.0",
133
+ "@types/blueimp-md5": "^2.18.2",
134
+ "@types/crypto-js": "^4.2.2",
121
135
  "@types/lodash": "^4.17.20",
122
136
  "@types/node": "^22.10.2",
123
137
  "@types/react": "^18.3.23",
@@ -143,6 +157,7 @@
143
157
  "antd": ">=5.26.6",
144
158
  "react": ">=16.14.0",
145
159
  "react-dom": ">=16.14.0",
146
- "react-router-dom": ">=6.26.2"
160
+ "react-router-dom": ">=6.26.2",
161
+ "styled-jsx": ">=5.0.0"
147
162
  }
148
163
  }