@lark-apaas/client-toolkit 1.2.17-alpha.17 → 1.2.17-alpha.19
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/lib/components/AppContainer/index.js +0 -2
- package/lib/components/AppContainer/utils/childApi.js +16 -2
- package/lib/utils/axiosConfig.js +4 -76
- package/package.json +6 -6
- package/lib/components/AppContainer/RoutePatternTracker.d.ts +0 -5
- package/lib/components/AppContainer/RoutePatternTracker.js +0 -13
- package/lib/utils/routePattern.d.ts +0 -17
- package/lib/utils/routePattern.js +0 -52
|
@@ -4,7 +4,6 @@ import { ConfigProvider } from "antd";
|
|
|
4
4
|
import { MiaodaInspector } from "@lark-apaas/miaoda-inspector";
|
|
5
5
|
import zh_CN from "antd/locale/zh_CN";
|
|
6
6
|
import IframeBridge from "./IframeBridge.js";
|
|
7
|
-
import RoutePatternTracker from "./RoutePatternTracker.js";
|
|
8
7
|
import { Toaster } from "./sonner.js";
|
|
9
8
|
import { PageHoc } from "./PageHoc.js";
|
|
10
9
|
import { reportTeaEvent } from "./utils/tea.js";
|
|
@@ -61,7 +60,6 @@ const App = (props)=>{
|
|
|
61
60
|
!disableToaster && true !== appFlags.customToaster && /*#__PURE__*/ jsx(Toaster, {}),
|
|
62
61
|
'production' !== process.env.NODE_ENV && /*#__PURE__*/ jsx(MiaodaInspector, {}),
|
|
63
62
|
'production' !== process.env.NODE_ENV && /*#__PURE__*/ jsx(IframeBridge, {}),
|
|
64
|
-
/*#__PURE__*/ jsx(RoutePatternTracker, {}),
|
|
65
63
|
/*#__PURE__*/ jsx(PageHoc, {
|
|
66
64
|
children: props.children
|
|
67
65
|
})
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import { normalizeBasePath } from "../../../utils/utils.js";
|
|
2
2
|
import { api_delete, api_get, api_head, api_options, api_patch, api_post, api_put } from "./api-panel.js";
|
|
3
|
-
|
|
3
|
+
async function getRoutes() {
|
|
4
|
+
let routes = [
|
|
5
|
+
{
|
|
6
|
+
path: '/'
|
|
7
|
+
}
|
|
8
|
+
];
|
|
9
|
+
try {
|
|
10
|
+
const basePath = normalizeBasePath(process.env.CLIENT_BASE_PATH);
|
|
11
|
+
const res = await fetch(`${basePath}/routes.json`);
|
|
12
|
+
routes = await res.json();
|
|
13
|
+
} catch (error) {
|
|
14
|
+
console.warn('get routes.json error', error);
|
|
15
|
+
}
|
|
16
|
+
return routes;
|
|
17
|
+
}
|
|
4
18
|
async function getSourceMap() {
|
|
5
19
|
if ('vite' === process.env.BUILD_TOOL) return '';
|
|
6
20
|
let sourceMapContent = '';
|
|
@@ -14,7 +28,7 @@ async function getSourceMap() {
|
|
|
14
28
|
return sourceMapContent;
|
|
15
29
|
}
|
|
16
30
|
const childApi = {
|
|
17
|
-
getRoutes
|
|
31
|
+
getRoutes,
|
|
18
32
|
updateAppInfo: (appInfo)=>{
|
|
19
33
|
dispatchEvent(new CustomEvent('MiaoDaMetaInfoChanged', {
|
|
20
34
|
detail: appInfo
|
package/lib/utils/axiosConfig.js
CHANGED
|
@@ -4,60 +4,6 @@ import { logger } from "../apis/logger.js";
|
|
|
4
4
|
import { getStacktrace } from "../logger/selected-logs.js";
|
|
5
5
|
import { safeStringify } from "./safeStringify.js";
|
|
6
6
|
import { slardar } from "@lark-apaas/internal-slardar";
|
|
7
|
-
import { getCurrentRoutePattern } from "./routePattern.js";
|
|
8
|
-
import { normalizeBasePath } from "./utils.js";
|
|
9
|
-
const APP_CLIENT_API_LOG_TYPE = 'app_client_api_log';
|
|
10
|
-
function getRefererPath() {
|
|
11
|
-
try {
|
|
12
|
-
return getCurrentRoutePattern();
|
|
13
|
-
} catch {
|
|
14
|
-
return '/';
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
function getApiField(method, response, errorResponse, fallbackPath) {
|
|
18
|
-
const matchRoute = response?.headers?.['x-match-route'] || errorResponse?.headers?.['x-match-route'] || '';
|
|
19
|
-
const routePath = matchRoute || matchApiRoute(method, fallbackPath) || fallbackPath;
|
|
20
|
-
return `${method} ${routePath}`;
|
|
21
|
-
}
|
|
22
|
-
function stripBasePath(urlPath) {
|
|
23
|
-
const base = normalizeBasePath(process.env.CLIENT_BASE_PATH);
|
|
24
|
-
if (base && urlPath.startsWith(base)) return urlPath.slice(base.length) || '/';
|
|
25
|
-
return urlPath;
|
|
26
|
-
}
|
|
27
|
-
let apiRouteDefinitions = null;
|
|
28
|
-
function getApiRouteDefinitions() {
|
|
29
|
-
if (apiRouteDefinitions) return apiRouteDefinitions;
|
|
30
|
-
try {
|
|
31
|
-
const raw = process.env.__API_ROUTE_DEFINITIONS__;
|
|
32
|
-
if (raw) {
|
|
33
|
-
const parsed = JSON.parse(raw);
|
|
34
|
-
if (Array.isArray(parsed)) {
|
|
35
|
-
apiRouteDefinitions = parsed;
|
|
36
|
-
return apiRouteDefinitions;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
} catch {}
|
|
40
|
-
apiRouteDefinitions = [];
|
|
41
|
-
return apiRouteDefinitions;
|
|
42
|
-
}
|
|
43
|
-
function matchApiRoute(method, concretePath) {
|
|
44
|
-
const routes = getApiRouteDefinitions();
|
|
45
|
-
const segments = concretePath.split('/').filter(Boolean);
|
|
46
|
-
for (const route of routes){
|
|
47
|
-
if ('*' !== route.method && route.method !== method) continue;
|
|
48
|
-
const routeSegments = route.path.split('/').filter(Boolean);
|
|
49
|
-
if (routeSegments.length !== segments.length) continue;
|
|
50
|
-
let match = true;
|
|
51
|
-
for(let i = 0; i < routeSegments.length; i++)if (!routeSegments[i].startsWith(':')) {
|
|
52
|
-
if (routeSegments[i] !== segments[i]) {
|
|
53
|
-
match = false;
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
if (match) return route.path;
|
|
58
|
-
}
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
7
|
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;
|
|
62
8
|
async function logResponse(ok, responseOrError) {
|
|
63
9
|
if (isValidResponse(responseOrError)) {
|
|
@@ -193,20 +139,13 @@ function handleSpanEnd(cfg, response, error) {
|
|
|
193
139
|
const errorMessage = error?.message || '未知错误';
|
|
194
140
|
const url = response?.request?.responseURL || errorResponse?.request?.responseURL || cfg.url || "";
|
|
195
141
|
const method = (cfg.method || 'GET').toUpperCase();
|
|
196
|
-
const
|
|
197
|
-
const path = stripBasePath(rawPath);
|
|
198
|
-
const durationMs = startTime ? Date.now() - startTime : void 0;
|
|
199
|
-
const referer_path = getRefererPath();
|
|
200
|
-
const api = getApiField(method, response, errorResponse, path);
|
|
201
|
-
const type = APP_CLIENT_API_LOG_TYPE;
|
|
142
|
+
const path = url.split('?')[0].replace(/^https?:\/\/[^/]+/, '') || '/';
|
|
202
143
|
const logData = {
|
|
203
144
|
method,
|
|
204
145
|
path,
|
|
205
146
|
url,
|
|
206
|
-
duration_ms:
|
|
207
|
-
status: response ? response.status : errorResponse.status || 0
|
|
208
|
-
referer_path,
|
|
209
|
-
type
|
|
147
|
+
duration_ms: startTime ? Date.now() - startTime : void 0,
|
|
148
|
+
status: response ? response.status : errorResponse.status || 0
|
|
210
149
|
};
|
|
211
150
|
if (error) logData.error_message = errorMessage;
|
|
212
151
|
if ('undefined' != typeof navigator) logData.user_agent = navigator.userAgent;
|
|
@@ -219,12 +158,7 @@ function handleSpanEnd(cfg, response, error) {
|
|
|
219
158
|
const responseData = response?.data || errorResponse?.data;
|
|
220
159
|
if (responseData) logData.response = responseData;
|
|
221
160
|
const level = error ? 'ERROR' : 'INFO';
|
|
222
|
-
observable.log(level, safeStringify(logData), {
|
|
223
|
-
referer_path,
|
|
224
|
-
api,
|
|
225
|
-
type,
|
|
226
|
-
duration_ms: durationMs
|
|
227
|
-
}, currentSpan);
|
|
161
|
+
observable.log(level, safeStringify(logData), {}, currentSpan);
|
|
228
162
|
'function' == typeof currentSpan.end && currentSpan.end();
|
|
229
163
|
} catch (e) {
|
|
230
164
|
console.error('[AxiosTrace] Log span failed:', e);
|
|
@@ -306,12 +240,6 @@ function initAxiosConfig(axiosInstance) {
|
|
|
306
240
|
const csrfToken = window.csrfToken;
|
|
307
241
|
if (csrfToken) config.headers['X-Suda-Csrf-Token'] = csrfToken;
|
|
308
242
|
if ('undefined' != typeof window && window.location?.pathname) config.headers['X-Page-Route'] = window.location.pathname;
|
|
309
|
-
const refererPath = getRefererPath();
|
|
310
|
-
config.headers['Rpc-Persist-Apaas-Observability-Referer-Path'] = refererPath;
|
|
311
|
-
const reqMethod = (config.method || 'GET').toUpperCase();
|
|
312
|
-
const requestPath = stripBasePath((config.url || '').split('?')[0]);
|
|
313
|
-
const parameterizedPath = matchApiRoute(reqMethod, requestPath) || requestPath;
|
|
314
|
-
config.headers['Rpc-Persist-Apaas-Observability-Api'] = `${reqMethod} ${parameterizedPath}`;
|
|
315
243
|
return config;
|
|
316
244
|
}, (error)=>Promise.reject(error));
|
|
317
245
|
instance.interceptors.response.use((response)=>response, (error)=>{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lark-apaas/client-toolkit",
|
|
3
|
-
"version": "1.2.17-alpha.
|
|
3
|
+
"version": "1.2.17-alpha.19",
|
|
4
4
|
"types": "./lib/index.d.ts",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -98,11 +98,11 @@
|
|
|
98
98
|
"dependencies": {
|
|
99
99
|
"@ant-design/colors": "^7.2.1",
|
|
100
100
|
"@ant-design/cssinjs": "^1.24.0",
|
|
101
|
-
"@data-loom/js": "0.4.
|
|
102
|
-
"@lark-apaas/aily-web-sdk": "^0.0.
|
|
103
|
-
"@lark-apaas/auth-sdk": "^0.1.
|
|
104
|
-
"@lark-apaas/client-capability": "^0.1.
|
|
105
|
-
"@lark-apaas/internal-slardar": "
|
|
101
|
+
"@data-loom/js": "0.4.10",
|
|
102
|
+
"@lark-apaas/aily-web-sdk": "^0.0.7",
|
|
103
|
+
"@lark-apaas/auth-sdk": "^0.1.2",
|
|
104
|
+
"@lark-apaas/client-capability": "^0.1.6",
|
|
105
|
+
"@lark-apaas/internal-slardar": "^0.0.3",
|
|
106
106
|
"@lark-apaas/miaoda-inspector": "^1.0.20",
|
|
107
107
|
"@lark-apaas/observable-web": "^1.0.4",
|
|
108
108
|
"@radix-ui/react-avatar": "^1.1.10",
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
2
|
-
import { useLocation } from "react-router-dom";
|
|
3
|
-
import { updateRoutePattern } from "../../utils/routePattern.js";
|
|
4
|
-
function RoutePatternTracker() {
|
|
5
|
-
const location = useLocation();
|
|
6
|
-
useEffect(()=>{
|
|
7
|
-
updateRoutePattern(location.pathname);
|
|
8
|
-
}, [
|
|
9
|
-
location.pathname
|
|
10
|
-
]);
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
13
|
-
export { RoutePatternTracker as default };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 获取路由定义列表
|
|
3
|
-
* 供 childApi 等外部模块使用
|
|
4
|
-
*/
|
|
5
|
-
export declare function getRouteDefinitions(): {
|
|
6
|
-
path: string;
|
|
7
|
-
}[];
|
|
8
|
-
/**
|
|
9
|
-
* 根据当前 pathname 匹配路由模式并更新存储
|
|
10
|
-
* 使用 react-router 的 matchPath 确保匹配逻辑与路由一致
|
|
11
|
-
*/
|
|
12
|
-
export declare function updateRoutePattern(pathname: string): void;
|
|
13
|
-
/**
|
|
14
|
-
* 获取当前匹配的参数化路由模式
|
|
15
|
-
* 供 axiosConfig 等非 React 上下文使用
|
|
16
|
-
*/
|
|
17
|
-
export declare function getCurrentRoutePattern(): string;
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { matchPath } from "react-router-dom";
|
|
2
|
-
import { normalizeBasePath } from "./utils.js";
|
|
3
|
-
let currentRoutePattern = '/';
|
|
4
|
-
let routeDefinitions = null;
|
|
5
|
-
function loadRouteDefinitions() {
|
|
6
|
-
if (routeDefinitions) return routeDefinitions;
|
|
7
|
-
try {
|
|
8
|
-
const raw = process.env.__ROUTE_DEFINITIONS__;
|
|
9
|
-
if (raw) {
|
|
10
|
-
const parsed = JSON.parse(raw);
|
|
11
|
-
if (Array.isArray(parsed) && parsed.length > 0) {
|
|
12
|
-
routeDefinitions = parsed;
|
|
13
|
-
return routeDefinitions;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
} catch {}
|
|
17
|
-
routeDefinitions = [
|
|
18
|
-
{
|
|
19
|
-
path: '/'
|
|
20
|
-
}
|
|
21
|
-
];
|
|
22
|
-
return routeDefinitions;
|
|
23
|
-
}
|
|
24
|
-
function getRouteDefinitions() {
|
|
25
|
-
return loadRouteDefinitions();
|
|
26
|
-
}
|
|
27
|
-
function updateRoutePattern(pathname) {
|
|
28
|
-
const routes = loadRouteDefinitions();
|
|
29
|
-
const basePath = normalizeBasePath(process.env.CLIENT_BASE_PATH);
|
|
30
|
-
let relativePath = pathname;
|
|
31
|
-
if (basePath && pathname.startsWith(basePath)) relativePath = pathname.slice(basePath.length) || '/';
|
|
32
|
-
const sortedRoutes = [
|
|
33
|
-
...routes
|
|
34
|
-
].sort((a, b)=>b.path.length - a.path.length);
|
|
35
|
-
for (const route of sortedRoutes){
|
|
36
|
-
let routePath = route.path;
|
|
37
|
-
if (basePath && routePath.startsWith(basePath)) routePath = routePath.slice(basePath.length) || '/';
|
|
38
|
-
const match = matchPath({
|
|
39
|
-
path: routePath,
|
|
40
|
-
end: true
|
|
41
|
-
}, relativePath);
|
|
42
|
-
if (match) {
|
|
43
|
-
currentRoutePattern = routePath;
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
currentRoutePattern = relativePath;
|
|
48
|
-
}
|
|
49
|
-
function getCurrentRoutePattern() {
|
|
50
|
-
return currentRoutePattern;
|
|
51
|
-
}
|
|
52
|
-
export { getCurrentRoutePattern, getRouteDefinitions, updateRoutePattern };
|