@lark-apaas/client-toolkit 1.2.17-alpha.2 → 1.2.17-alpha.20
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/apis/utils/resolveAppUrl.d.ts +1 -0
- package/lib/apis/utils/resolveAppUrl.js +2 -0
- package/lib/components/AppContainer/index.js +8 -2
- package/lib/components/AppContainer/safety.js +5 -2
- package/lib/components/AppContainer/utils/getLarkUser.js +4 -2
- package/lib/components/AppContainer/utils/observable.js +7 -1
- package/lib/hooks/useCurrentUserProfile.js +22 -29
- package/lib/hooks/useLogout.js +2 -17
- package/lib/index.js +7 -0
- package/lib/integrations/dataloom.d.ts +3 -1
- package/lib/integrations/dataloom.js +14 -8
- package/lib/integrations/services/DepartmentService.js +3 -2
- package/lib/integrations/services/UserProfileService.js +3 -2
- package/lib/integrations/services/UserService.js +4 -3
- package/lib/logger/intercept-global-error.js +18 -11
- package/lib/utils/apiPath.d.ts +5 -0
- package/lib/utils/apiPath.js +5 -0
- package/lib/utils/axiosConfig.js +20 -0
- package/lib/utils/getAppId.d.ts +2 -4
- package/lib/utils/getAppId.js +2 -9
- package/lib/utils/getInitialInfo.d.ts +4 -3
- package/lib/utils/getInitialInfo.js +17 -8
- package/lib/utils/getUserProfile.js +4 -12
- package/lib/utils/postMessage.d.ts +0 -1
- package/lib/utils/postMessage.js +19 -6
- package/lib/utils/resolveAppUrl.d.ts +27 -0
- package/lib/utils/resolveAppUrl.js +19 -0
- package/lib/utils/scopedStorage.js +1 -1
- package/package.json +9 -8
- package/lib/apis/tools/generateImage.d.ts +0 -1
- package/lib/apis/tools/generateImage.js +0 -1
- package/lib/apis/tools/generateTextStream.d.ts +0 -1
- package/lib/apis/tools/generateTextStream.js +0 -1
- package/lib/integrations/generateImage.d.ts +0 -1
- package/lib/integrations/generateImage.js +0 -47
- package/lib/integrations/generateTextStream.d.ts +0 -21
- package/lib/integrations/generateTextStream.js +0 -98
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { resolveAppUrl } from '../../utils/resolveAppUrl';
|
|
@@ -11,6 +11,7 @@ import { useAppInfo } from "../../hooks/index.js";
|
|
|
11
11
|
import { TrackKey } from "../../types/tea.js";
|
|
12
12
|
import safety from "./safety.js";
|
|
13
13
|
import { getAppId } from "../../utils/getAppId.js";
|
|
14
|
+
import { isNewPathEnabled } from "../../utils/apiPath.js";
|
|
14
15
|
import QueryProvider from "../QueryProvider/index.js";
|
|
15
16
|
import { AuthProvider } from "@lark-apaas/auth-sdk";
|
|
16
17
|
import "../../runtime/index.js";
|
|
@@ -40,15 +41,20 @@ const App = (props)=>{
|
|
|
40
41
|
if ('production' === process.env.NODE_ENV) reportTeaEvent({
|
|
41
42
|
trackKey: TrackKey.VIEW,
|
|
42
43
|
trackParams: {
|
|
43
|
-
artifact_uid: getAppId(
|
|
44
|
+
artifact_uid: getAppId(),
|
|
44
45
|
agent_id: 'agent_miaoda',
|
|
45
46
|
url: window.location.href
|
|
46
47
|
}
|
|
47
48
|
});
|
|
48
49
|
}, []);
|
|
50
|
+
const appId = getAppId();
|
|
51
|
+
const permissionApiUrl = isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/permissions/roles` : `/spark/app/${appId}/runtime/api/v1/permissions/roles`;
|
|
49
52
|
return /*#__PURE__*/ jsxs(AuthProvider, {
|
|
50
53
|
config: {
|
|
51
|
-
enable: enableAuth
|
|
54
|
+
enable: enableAuth,
|
|
55
|
+
permissionApi: {
|
|
56
|
+
url: permissionApiUrl
|
|
57
|
+
}
|
|
52
58
|
},
|
|
53
59
|
children: [
|
|
54
60
|
!disableToaster && true !== appFlags.customToaster && /*#__PURE__*/ jsx(Toaster, {}),
|
|
@@ -3,11 +3,12 @@ import { useEffect, useRef, useState } from "react";
|
|
|
3
3
|
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover.js";
|
|
4
4
|
import { getCsrfToken } from "../../utils/getCsrfToken.js";
|
|
5
5
|
import { getAppId } from "../../utils/getAppId.js";
|
|
6
|
+
import { isNewPathEnabled } from "../../utils/apiPath.js";
|
|
6
7
|
import { useIsMobile } from "../../hooks/index.js";
|
|
7
8
|
import { X } from "lucide-react";
|
|
8
9
|
import { Sheet, SheetContent, SheetTrigger } from "../ui/drawer.js";
|
|
9
10
|
const Component = ()=>{
|
|
10
|
-
const HasClosedKey = `miaoda-creatByMiaoda-has-closed-${getAppId(
|
|
11
|
+
const HasClosedKey = `miaoda-creatByMiaoda-has-closed-${getAppId()}`;
|
|
11
12
|
const [visible, setVisible] = useState(!window.localStorage?.getItem(HasClosedKey));
|
|
12
13
|
const [open, setOpen] = useState(false);
|
|
13
14
|
const isMobile = useIsMobile();
|
|
@@ -15,7 +16,9 @@ const Component = ()=>{
|
|
|
15
16
|
const [isInternetVisible, setIsInternetVisible] = useState(false);
|
|
16
17
|
const timeoutRef = useRef(null);
|
|
17
18
|
useEffect(()=>{
|
|
18
|
-
|
|
19
|
+
const appId = getAppId();
|
|
20
|
+
const tenantInfoUrl = isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/studio/tenant_info` : `/spark/b/${appId}/tenant_info`;
|
|
21
|
+
fetch(tenantInfoUrl, {
|
|
19
22
|
headers: {
|
|
20
23
|
'X-Suda-Csrf-Token': getCsrfToken()
|
|
21
24
|
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { getAppId } from "../../../utils/getAppId.js";
|
|
2
2
|
import { getCsrfToken } from "../../../utils/getCsrfToken.js";
|
|
3
|
+
import { isNewPathEnabled } from "../../../utils/apiPath.js";
|
|
3
4
|
async function getLarkUserInfo() {
|
|
4
|
-
const appId = getAppId(
|
|
5
|
+
const appId = getAppId();
|
|
5
6
|
if (!appId) return {
|
|
6
7
|
code: 1,
|
|
7
8
|
msg: 'appId is required',
|
|
8
9
|
data: {}
|
|
9
10
|
};
|
|
10
|
-
const
|
|
11
|
+
const url = isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/studio/lark/user_info` : `/spark/b/${appId}/lark/user_info`;
|
|
12
|
+
const response = await fetch(url, {
|
|
11
13
|
headers: {
|
|
12
14
|
'X-Suda-Csrf-Token': getCsrfToken()
|
|
13
15
|
}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { AppEnv, observable } from "@lark-apaas/observable-web";
|
|
2
|
+
import { isNewPathEnabled } from "../../../utils/apiPath.js";
|
|
2
3
|
const initObservable = ()=>{
|
|
3
4
|
try {
|
|
4
5
|
const appId = window.appId;
|
|
5
6
|
observable.start({
|
|
6
7
|
serviceName: "app",
|
|
7
8
|
env: 'development' === process.env.NODE_ENV ? AppEnv.Dev : AppEnv.Prod,
|
|
8
|
-
collectorUrl: {
|
|
9
|
+
collectorUrl: isNewPathEnabled() ? {
|
|
10
|
+
log: `/app/${appId}/__runtime__/api/v1/observability/logs/collect`,
|
|
11
|
+
trace: `/app/${appId}/__runtime__/api/v1/observability/traces/collect`,
|
|
12
|
+
metric: `/app/${appId}/__runtime__/api/v1/observability/metrics/collect`,
|
|
13
|
+
time: `/app/${appId}/__runtime__/api/v1/observability/current_server_timestamp`
|
|
14
|
+
} : {
|
|
9
15
|
log: `/spark/app/${appId}/runtime/api/v1/observability/logs/collect`,
|
|
10
16
|
trace: `/spark/app/${appId}/runtime/api/v1/observability/traces/collect`,
|
|
11
17
|
metric: `/spark/app/${appId}/runtime/api/v1/observability/metrics/collect`,
|
|
@@ -19,37 +19,29 @@ function getCompatibilityUserProfile() {
|
|
|
19
19
|
const useCurrentUserProfile = ()=>{
|
|
20
20
|
const [userInfo, setUserInfo] = useState(()=>getCompatibilityUserProfile());
|
|
21
21
|
useEffect(()=>{
|
|
22
|
+
let cancelled = false;
|
|
23
|
+
const fetchAndSetUserInfo = async ()=>{
|
|
24
|
+
const dataloom = await getDataloom();
|
|
25
|
+
const result = await dataloom?.service?.session?.getUserInfo();
|
|
26
|
+
if (cancelled) return;
|
|
27
|
+
const info = result?.data?.user_info;
|
|
28
|
+
const userName = getNameFromArray(info?.name);
|
|
29
|
+
const newUserInfo = {
|
|
30
|
+
user_id: info?.user_id?.toString(),
|
|
31
|
+
email: info?.email,
|
|
32
|
+
name: userName,
|
|
33
|
+
avatar: info?.avatar?.image?.large,
|
|
34
|
+
userName: userName,
|
|
35
|
+
userAvatar: info?.avatar?.image?.large
|
|
36
|
+
};
|
|
37
|
+
if ('development' === process.env.NODE_ENV) logger.info('MiaoDaMetaInfoChanged', newUserInfo);
|
|
38
|
+
setUserInfo(newUserInfo);
|
|
39
|
+
};
|
|
22
40
|
let handleMetaInfoChanged;
|
|
23
41
|
if (isSparkRuntime()) {
|
|
24
|
-
(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const userInfo = result?.data?.user_info;
|
|
28
|
-
const userName = getNameFromArray(userInfo?.name);
|
|
29
|
-
setUserInfo({
|
|
30
|
-
user_id: userInfo?.user_id?.toString(),
|
|
31
|
-
email: userInfo?.email,
|
|
32
|
-
name: userName,
|
|
33
|
-
avatar: userInfo?.avatar?.image?.large,
|
|
34
|
-
userName: userName,
|
|
35
|
-
userAvatar: userInfo?.avatar?.image?.large
|
|
36
|
-
});
|
|
37
|
-
})();
|
|
38
|
-
handleMetaInfoChanged = async ()=>{
|
|
39
|
-
const dataloom = await getDataloom();
|
|
40
|
-
const result = await dataloom?.service?.session?.getUserInfo();
|
|
41
|
-
const userInfo = result?.data?.user_info;
|
|
42
|
-
const userName = getNameFromArray(userInfo?.name);
|
|
43
|
-
const newUserInfo = {
|
|
44
|
-
user_id: userInfo?.user_id?.toString(),
|
|
45
|
-
email: userInfo?.email,
|
|
46
|
-
name: userName,
|
|
47
|
-
avatar: userInfo?.avatar?.image?.large,
|
|
48
|
-
userName: userName,
|
|
49
|
-
userAvatar: userInfo?.avatar?.image?.large
|
|
50
|
-
};
|
|
51
|
-
if ('development' === process.env.NODE_ENV) logger.info('MiaoDaMetaInfoChanged', newUserInfo);
|
|
52
|
-
setUserInfo(newUserInfo);
|
|
42
|
+
fetchAndSetUserInfo();
|
|
43
|
+
handleMetaInfoChanged = ()=>{
|
|
44
|
+
fetchAndSetUserInfo();
|
|
53
45
|
};
|
|
54
46
|
} else handleMetaInfoChanged = ()=>{
|
|
55
47
|
if ('development' === process.env.NODE_ENV) logger.info('MiaoDaMetaInfoChanged', getCompatibilityUserProfile());
|
|
@@ -57,6 +49,7 @@ const useCurrentUserProfile = ()=>{
|
|
|
57
49
|
};
|
|
58
50
|
window.addEventListener('MiaoDaMetaInfoChanged', handleMetaInfoChanged);
|
|
59
51
|
return ()=>{
|
|
52
|
+
cancelled = true;
|
|
60
53
|
window.removeEventListener('MiaoDaMetaInfoChanged', handleMetaInfoChanged);
|
|
61
54
|
};
|
|
62
55
|
}, []);
|
package/lib/hooks/useLogout.js
CHANGED
|
@@ -1,28 +1,13 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
2
|
import { getDataloom } from "../integrations/dataloom.js";
|
|
3
|
-
import { isSparkRuntime } from "../utils/utils.js";
|
|
4
3
|
function useLogout() {
|
|
5
4
|
const [isLoading, setIsLoading] = useState(false);
|
|
6
5
|
async function handlerLogout() {
|
|
7
6
|
if ('production' !== process.env.NODE_ENV) return void console.log('只有生产环境才执行登出');
|
|
8
|
-
if (isSparkRuntime()) {
|
|
9
|
-
setIsLoading(true);
|
|
10
|
-
try {
|
|
11
|
-
const dataloom = await getDataloom();
|
|
12
|
-
await dataloom.service.session.signOut();
|
|
13
|
-
} catch (error) {
|
|
14
|
-
console.error('登出失败', error);
|
|
15
|
-
} finally{
|
|
16
|
-
setIsLoading(false);
|
|
17
|
-
}
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
7
|
setIsLoading(true);
|
|
21
8
|
try {
|
|
22
|
-
await
|
|
23
|
-
|
|
24
|
-
});
|
|
25
|
-
window.location.reload();
|
|
9
|
+
const dataloom = await getDataloom();
|
|
10
|
+
await dataloom.service.session.signOut();
|
|
26
11
|
} catch (error) {
|
|
27
12
|
console.error('登出失败', error);
|
|
28
13
|
} finally{
|
package/lib/index.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { createClient } from "@lark-apaas/client-capability";
|
|
2
2
|
import { normalizeBasePath } from "./utils/utils.js";
|
|
3
|
+
import { getAppId } from "./utils/getAppId.js";
|
|
4
|
+
import { isNewPathEnabled } from "./utils/apiPath.js";
|
|
3
5
|
import { logger } from "./logger/index.js";
|
|
4
6
|
import { showToast } from "./components/ui/toast.js";
|
|
5
7
|
import { version } from "../package.json";
|
|
8
|
+
const _appId = getAppId();
|
|
9
|
+
const _acquireUploadUrl = isNewPathEnabled() ? `/app/${_appId}/__runtime__/api/v1/studio/plugins/tmp_files/acquire_upload_url` : "/af/api/v1/studio/plugins/tmp_files/acquire_upload_url";
|
|
10
|
+
const _acquireDownloadUrl = isNewPathEnabled() ? `/app/${_appId}/__runtime__/api/v1/studio/plugins/tmp_files/acquire_download_url` : "/af/api/v1/studio/plugins/tmp_files/acquire_download_url";
|
|
6
11
|
const capabilityClient = createClient({
|
|
7
12
|
baseURL: normalizeBasePath(process.env.CLIENT_BASE_PATH),
|
|
13
|
+
acquireUploadUrl: _acquireUploadUrl,
|
|
14
|
+
acquireDownloadUrl: _acquireDownloadUrl,
|
|
8
15
|
fetchOptions: {
|
|
9
16
|
headers: {
|
|
10
17
|
'X-Suda-Csrf-Token': window.csrfToken ?? ''
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
+
declare const createDataLoomClient: (url?: string, pat?: string) => import("@data-loom/js").DataloomClient<any, "public", any>;
|
|
1
2
|
/** 获取dataloom实例 */
|
|
2
|
-
export declare function getDataloom(): Promise<
|
|
3
|
+
export declare function getDataloom(): Promise<ReturnType<typeof createDataLoomClient>>;
|
|
4
|
+
export {};
|
|
@@ -7,7 +7,7 @@ const createDataLoomClient = (url, pat)=>{
|
|
|
7
7
|
baseUrl: '',
|
|
8
8
|
workspace: ''
|
|
9
9
|
};
|
|
10
|
-
const appId = getAppId(
|
|
10
|
+
const appId = getAppId();
|
|
11
11
|
return createClient(baseUrl, pat, workspace, {
|
|
12
12
|
global: {
|
|
13
13
|
enableDataloomLog: 'production' !== process.env.NODE_ENV,
|
|
@@ -23,12 +23,18 @@ const createDataLoomClient = (url, pat)=>{
|
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
25
|
let dataloom = null;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
let pendingPromise = null;
|
|
27
|
+
function getDataloom() {
|
|
28
|
+
if (dataloom) return Promise.resolve(dataloom);
|
|
29
|
+
if (pendingPromise) return pendingPromise;
|
|
30
|
+
pendingPromise = getInitialInfo().then((info)=>{
|
|
31
|
+
const DATALOOM_CLIENT_URL = info?.app_runtime_extra?.url;
|
|
32
|
+
const DATALOOM_PAT = info?.app_runtime_extra?.token;
|
|
33
|
+
dataloom = createDataLoomClient(DATALOOM_CLIENT_URL, DATALOOM_PAT);
|
|
34
|
+
return dataloom;
|
|
35
|
+
}).finally(()=>{
|
|
36
|
+
pendingPromise = null;
|
|
37
|
+
});
|
|
38
|
+
return pendingPromise;
|
|
33
39
|
}
|
|
34
40
|
export { getDataloom };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { getAppId } from "../../utils/getAppId.js";
|
|
2
|
+
import { isNewPathEnabled } from "../../utils/apiPath.js";
|
|
2
3
|
const DEFAULT_CONFIG = {
|
|
3
|
-
getAppId: ()=>getAppId(
|
|
4
|
-
searchDepartmentUrl: (appId)
|
|
4
|
+
getAppId: ()=>getAppId(),
|
|
5
|
+
searchDepartmentUrl: (appId)=>isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/account/search_department` : `/af/app/${appId}/runtime/api/v1/account/search_department`
|
|
5
6
|
};
|
|
6
7
|
class DepartmentService {
|
|
7
8
|
config;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { getAppId } from "../../utils/getAppId.js";
|
|
2
|
+
import { isNewPathEnabled } from "../../utils/apiPath.js";
|
|
2
3
|
const CDN_HOST = 'https://lf3-static.bytednsdoc.com';
|
|
3
4
|
function getAssetsUrl(path) {
|
|
4
5
|
return `${CDN_HOST}${path}`;
|
|
5
6
|
}
|
|
6
7
|
const DEFAULT_CONFIG = {
|
|
7
|
-
getAppId: ()=>getAppId(
|
|
8
|
-
userProfileUrl: (appId)
|
|
8
|
+
getAppId: ()=>getAppId(),
|
|
9
|
+
userProfileUrl: (appId)=>isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/account/user_profile` : `/af/app/${appId}/runtime/api/v1/account/user_profile`
|
|
9
10
|
};
|
|
10
11
|
class UserProfileService {
|
|
11
12
|
config;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { getAppId } from "../../utils/getAppId.js";
|
|
2
|
+
import { isNewPathEnabled } from "../../utils/apiPath.js";
|
|
2
3
|
const DEFAULT_CONFIG = {
|
|
3
|
-
getAppId: ()=>getAppId(
|
|
4
|
-
searchUserUrl: (appId)
|
|
5
|
-
listUsersUrl: (appId)
|
|
4
|
+
getAppId: ()=>getAppId(),
|
|
5
|
+
searchUserUrl: (appId)=>isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/account/search_user` : `/af/app/${appId}/runtime/api/v1/account/search_user`,
|
|
6
|
+
listUsersUrl: (appId)=>isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/account/list_users` : `/af/app/${appId}/runtime/api/v1/account/list_users`
|
|
6
7
|
};
|
|
7
8
|
class UserService {
|
|
8
9
|
config;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { slardar } from "@lark-apaas/internal-slardar";
|
|
1
2
|
import { getHmrApi } from "../utils/hmr-api.js";
|
|
2
|
-
import { submitPostMessage
|
|
3
|
+
import { submitPostMessage } from "../utils/postMessage.js";
|
|
3
4
|
import { levelSchema } from "./log-types.js";
|
|
4
5
|
import { logger } from "./logger.js";
|
|
5
6
|
let devServerDisconnectInfo = null;
|
|
@@ -19,22 +20,26 @@ function processDevServerLog(log) {
|
|
|
19
20
|
status: 'disconnected'
|
|
20
21
|
}
|
|
21
22
|
});
|
|
22
|
-
|
|
23
|
+
slardar.sendEvent({
|
|
23
24
|
name: 'sandbox-devServer',
|
|
24
|
-
|
|
25
|
-
type: 'disconnected',
|
|
25
|
+
metrics: {
|
|
26
26
|
time
|
|
27
|
+
},
|
|
28
|
+
categories: {
|
|
29
|
+
type: 'disconnected'
|
|
27
30
|
}
|
|
28
31
|
});
|
|
29
32
|
return;
|
|
30
33
|
}
|
|
31
34
|
if (!devServerDisconnectInfo) return;
|
|
32
35
|
if (devFlag && log.includes('Trying to reconnect')) {
|
|
33
|
-
if (retryCount)
|
|
36
|
+
if (retryCount) slardar.sendEvent({
|
|
34
37
|
name: 'sandbox-devServer',
|
|
35
|
-
|
|
36
|
-
type: 'reconnect-failed',
|
|
38
|
+
metrics: {
|
|
37
39
|
retryCount: retryCount + 1
|
|
40
|
+
},
|
|
41
|
+
categories: {
|
|
42
|
+
type: 'reconnect-failed'
|
|
38
43
|
}
|
|
39
44
|
});
|
|
40
45
|
retryCount++;
|
|
@@ -52,12 +57,14 @@ function processDevServerLog(log) {
|
|
|
52
57
|
const startTime = devServerDisconnectInfo.time;
|
|
53
58
|
const duration = Date.now() - startTime;
|
|
54
59
|
devServerDisconnectInfo = null;
|
|
55
|
-
|
|
60
|
+
slardar.sendEvent({
|
|
56
61
|
name: 'sandbox-devServer',
|
|
57
|
-
|
|
58
|
-
type: 'devServer-reconnected',
|
|
62
|
+
metrics: {
|
|
59
63
|
startTime,
|
|
60
64
|
duration
|
|
65
|
+
},
|
|
66
|
+
categories: {
|
|
67
|
+
type: 'devServer-reconnected'
|
|
61
68
|
}
|
|
62
69
|
});
|
|
63
70
|
}
|
|
@@ -76,7 +83,7 @@ function listenModuleHmr() {
|
|
|
76
83
|
});
|
|
77
84
|
hmr.onError((error)=>{
|
|
78
85
|
console.warn('hmr apply failed', error);
|
|
79
|
-
|
|
86
|
+
slardar.sendEvent({
|
|
80
87
|
name: 'sandbox-devServer',
|
|
81
88
|
categories: {
|
|
82
89
|
type: 'hmr-apply-failed',
|
package/lib/utils/axiosConfig.js
CHANGED
|
@@ -3,6 +3,7 @@ import { observable } from "@lark-apaas/observable-web";
|
|
|
3
3
|
import { logger } from "../apis/logger.js";
|
|
4
4
|
import { getStacktrace } from "../logger/selected-logs.js";
|
|
5
5
|
import { safeStringify } from "./safeStringify.js";
|
|
6
|
+
import { slardar } from "@lark-apaas/internal-slardar";
|
|
6
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;
|
|
7
8
|
async function logResponse(ok, responseOrError) {
|
|
8
9
|
if (isValidResponse(responseOrError)) {
|
|
@@ -193,6 +194,10 @@ AxiosProto.request = function(configOrUrl, config) {
|
|
|
193
194
|
return response;
|
|
194
195
|
}, (error)=>{
|
|
195
196
|
handleSpanEnd(error.config || finalConfig, null, error);
|
|
197
|
+
slardar.captureException(error, {
|
|
198
|
+
source: 'toolkit',
|
|
199
|
+
module: 'axios-request'
|
|
200
|
+
});
|
|
196
201
|
throw error;
|
|
197
202
|
});
|
|
198
203
|
};
|
|
@@ -253,9 +258,24 @@ function initAxiosConfig(axiosInstance) {
|
|
|
253
258
|
],
|
|
254
259
|
meta: {}
|
|
255
260
|
});
|
|
261
|
+
slardar.sendEvent({
|
|
262
|
+
name: 'toolkit_axios_403_downgrade',
|
|
263
|
+
categories: {
|
|
264
|
+
url: String(error.config?.url || ''),
|
|
265
|
+
method: String(error.config?.method || '')
|
|
266
|
+
}
|
|
267
|
+
});
|
|
256
268
|
return error.response;
|
|
257
269
|
}
|
|
258
270
|
} catch (e) {}
|
|
271
|
+
slardar.sendEvent({
|
|
272
|
+
name: 'toolkit_axios_response_error',
|
|
273
|
+
categories: {
|
|
274
|
+
url: String(error.config?.url || ''),
|
|
275
|
+
method: String(error.config?.method || ''),
|
|
276
|
+
status: String(error.response?.status || '')
|
|
277
|
+
}
|
|
278
|
+
});
|
|
259
279
|
return Promise.reject(error);
|
|
260
280
|
});
|
|
261
281
|
'production' !== process.env.NODE_ENV && instance.interceptors.response.use((response)=>{
|
package/lib/utils/getAppId.d.ts
CHANGED
package/lib/utils/getAppId.js
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
function getAppId(
|
|
2
|
-
if (window.MIAODA_APP_ID) return window.MIAODA_APP_ID;
|
|
3
|
-
let prefix;
|
|
4
|
-
prefix = path.includes('/ai/feida/runtime/') ? '/ai/feida/runtime/' : path.includes('/spark/r/') ? '/spark/r/' : '/ai/miaoda/';
|
|
1
|
+
function getAppId() {
|
|
5
2
|
const windowAppId = window.appId || null;
|
|
6
|
-
|
|
7
|
-
const remainder = path.substring(prefix.length);
|
|
8
|
-
const nextSlashIndex = remainder.indexOf('/');
|
|
9
|
-
if (-1 === nextSlashIndex) return remainder || windowAppId;
|
|
10
|
-
return remainder.substring(0, nextSlashIndex) || windowAppId;
|
|
3
|
+
return windowAppId;
|
|
11
4
|
}
|
|
12
5
|
export { getAppId };
|
|
@@ -13,9 +13,10 @@ interface AppRuntimePublished {
|
|
|
13
13
|
interface BucketConfig {
|
|
14
14
|
default_bucket_id?: string;
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
export declare function getInitialInfo(refresh?: boolean): Promise<{
|
|
16
|
+
declare let initialInfo: {
|
|
18
17
|
app_info?: AppRuntimePublished;
|
|
19
18
|
app_runtime_extra?: AppRuntimeExtra;
|
|
20
|
-
}
|
|
19
|
+
} | undefined;
|
|
20
|
+
/** 获取应用初始化信息(仅全栈沙箱模式下使用) */
|
|
21
|
+
export declare function getInitialInfo(refresh?: boolean): Promise<typeof initialInfo>;
|
|
21
22
|
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getAppId } from "./getAppId.js";
|
|
2
2
|
import { getCsrfToken } from "./getCsrfToken.js";
|
|
3
|
+
import { isNewPathEnabled } from "./apiPath.js";
|
|
3
4
|
async function getAppPublished() {
|
|
4
5
|
try {
|
|
5
6
|
const headers = {
|
|
@@ -8,25 +9,33 @@ async function getAppPublished() {
|
|
|
8
9
|
'x-miaoda-token': window.MIAODA_BUILTIN_TTT,
|
|
9
10
|
'X-Suda-Csrf-Token': getCsrfToken()
|
|
10
11
|
};
|
|
11
|
-
const appId = getAppId(
|
|
12
|
-
const
|
|
12
|
+
const appId = getAppId();
|
|
13
|
+
const path = isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/studio/get_published` : `/spark/b/${appId}/get_published`;
|
|
14
|
+
const url = `${window.location.origin}${path}`;
|
|
13
15
|
const response = await fetch(url, {
|
|
14
16
|
method: 'GET',
|
|
15
17
|
headers,
|
|
16
18
|
credentials: 'include'
|
|
17
19
|
});
|
|
18
20
|
const res = await response.json();
|
|
19
|
-
if (0 === res.code) return res.data;
|
|
21
|
+
if (0 === res.code || '0' === res.status_code) return res.data;
|
|
20
22
|
console.error('Error fetching published app info:', res);
|
|
21
23
|
} catch (error) {
|
|
22
24
|
console.error('Error fetching published app info:', error);
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
27
|
let initialInfo;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
initialInfo
|
|
29
|
-
if (
|
|
30
|
-
|
|
28
|
+
let pendingPromise = null;
|
|
29
|
+
function getInitialInfo(refresh = false) {
|
|
30
|
+
if (initialInfo && !refresh) return Promise.resolve(initialInfo);
|
|
31
|
+
if (pendingPromise && !refresh) return pendingPromise;
|
|
32
|
+
pendingPromise = getAppPublished().then((info)=>{
|
|
33
|
+
initialInfo = info;
|
|
34
|
+
if (initialInfo) window._bucket_id = initialInfo.app_runtime_extra?.bucket?.default_bucket_id;
|
|
35
|
+
return initialInfo;
|
|
36
|
+
}).finally(()=>{
|
|
37
|
+
pendingPromise = null;
|
|
38
|
+
});
|
|
39
|
+
return pendingPromise;
|
|
31
40
|
}
|
|
32
41
|
export { getInitialInfo };
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { getAppId } from "./getAppId.js";
|
|
2
2
|
import { getCsrfToken } from "./getCsrfToken.js";
|
|
3
|
-
import {
|
|
4
|
-
import { isSparkRuntime } from "./utils.js";
|
|
3
|
+
import { isNewPathEnabled } from "./apiPath.js";
|
|
5
4
|
async function getUserProfile(request, headers = {}) {
|
|
6
|
-
const appId = getAppId(
|
|
5
|
+
const appId = getAppId();
|
|
7
6
|
if (!appId) return {
|
|
8
7
|
code: 1,
|
|
9
8
|
msg: 'appId is required',
|
|
@@ -15,17 +14,10 @@ async function getUserProfile(request, headers = {}) {
|
|
|
15
14
|
const mergedHeaders = {
|
|
16
15
|
...defaultHeaders,
|
|
17
16
|
...headers,
|
|
18
|
-
'X-Kunlun-Token': window.token,
|
|
19
|
-
'x-miaoda-token': window.MIAODA_BUILTIN_TTT,
|
|
20
|
-
'x-lgw-csrf-token': window.lgw_csrf_token,
|
|
21
17
|
...window.CSRF_HEADERS || {}
|
|
22
18
|
};
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
if (isSparkRuntime()) {
|
|
26
|
-
endpoint = `/spark/b/${appId}/user/profile`;
|
|
27
|
-
mergedHeaders['X-Suda-Csrf-Token'] = getCsrfToken();
|
|
28
|
-
} else endpoint = `/ai/api/${envPath}/v1/apps/${appId}/user/profile`;
|
|
19
|
+
const endpoint = isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/studio/user/profile` : `/spark/b/${appId}/user/profile`;
|
|
20
|
+
mergedHeaders['X-Suda-Csrf-Token'] = getCsrfToken();
|
|
29
21
|
const response = await fetch(`${window.location.origin}${endpoint}`, {
|
|
30
22
|
method: 'POST',
|
|
31
23
|
headers: mergedHeaders,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { IncomingMessage, OutgoingMessage } from '../types/iframe-events';
|
|
2
2
|
export declare function resolveParentOrigin(): string;
|
|
3
3
|
export declare function submitPostMessage<T extends OutgoingMessage>(message: T, targetOrigin?: string): void;
|
|
4
|
-
export declare function submitSlardarEvent(event: unknown): void;
|
|
5
4
|
export declare function isOutgoingMessage<T extends OutgoingMessage['type']>(msg: OutgoingMessage, type: T): msg is Extract<OutgoingMessage, {
|
|
6
5
|
type: T;
|
|
7
6
|
}>;
|
package/lib/utils/postMessage.js
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
const PARENT_ORIGIN_KEY = '__parentOrigin';
|
|
2
|
+
function getParentOriginFromParams() {
|
|
3
|
+
try {
|
|
4
|
+
const params = new URLSearchParams(window.location.search);
|
|
5
|
+
const origin = params.get(PARENT_ORIGIN_KEY);
|
|
6
|
+
if (origin) {
|
|
7
|
+
sessionStorage.setItem(PARENT_ORIGIN_KEY, origin);
|
|
8
|
+
return origin;
|
|
9
|
+
}
|
|
10
|
+
} catch {}
|
|
11
|
+
try {
|
|
12
|
+
return sessionStorage.getItem(PARENT_ORIGIN_KEY) || void 0;
|
|
13
|
+
} catch {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
1
17
|
function getLegacyParentOrigin() {
|
|
2
18
|
const { origin } = window.location;
|
|
3
19
|
if (origin.includes('force.feishuapp.net')) return 'https://force.feishu.cn';
|
|
@@ -8,6 +24,8 @@ function getLegacyParentOrigin() {
|
|
|
8
24
|
return 'https://miaoda.feishu-boe.cn';
|
|
9
25
|
}
|
|
10
26
|
function resolveParentOrigin() {
|
|
27
|
+
const paramOrigin = getParentOriginFromParams();
|
|
28
|
+
if (paramOrigin) return paramOrigin;
|
|
11
29
|
return process.env?.FORCE_FRAMEWORK_DOMAIN_MAIN ?? getLegacyParentOrigin();
|
|
12
30
|
}
|
|
13
31
|
function submitPostMessage(message, targetOrigin) {
|
|
@@ -20,15 +38,10 @@ function submitPostMessage(message, targetOrigin) {
|
|
|
20
38
|
console.error('postMessage error', e);
|
|
21
39
|
}
|
|
22
40
|
}
|
|
23
|
-
function submitSlardarEvent(event) {
|
|
24
|
-
const slardar = window.KSlardarWeb;
|
|
25
|
-
if ('function' == typeof slardar) slardar('sendEvent', event);
|
|
26
|
-
else console.warn('hmr listen function not found');
|
|
27
|
-
}
|
|
28
41
|
function isOutgoingMessage(msg, type) {
|
|
29
42
|
return msg.type === type;
|
|
30
43
|
}
|
|
31
44
|
function isIncomingMessage(msg, type) {
|
|
32
45
|
return msg.type === type;
|
|
33
46
|
}
|
|
34
|
-
export { isIncomingMessage, isOutgoingMessage, resolveParentOrigin, submitPostMessage
|
|
47
|
+
export { isIncomingMessage, isOutgoingMessage, resolveParentOrigin, submitPostMessage };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 解析应用内路径,自动补全 CLIENT_BASE_PATH 前缀,返回完整 URL
|
|
3
|
+
* 适用于生成分享链接、二维码等需要完整 URL 的场景
|
|
4
|
+
*
|
|
5
|
+
* - 相对路径:补全前缀 + 当前域名
|
|
6
|
+
* - 当前域名的完整 URL:修正路径部分,补全前缀
|
|
7
|
+
* - 其他域名的 URL:原样返回,不做处理
|
|
8
|
+
*
|
|
9
|
+
* @param path - 应用内相对路径或完整 URL
|
|
10
|
+
* @returns 完整的 URL 字符串
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // 假设 CLIENT_BASE_PATH = '/app/abc',当前域名为 https://example.com
|
|
14
|
+
*
|
|
15
|
+
* resolveAppUrl('/detail/123')
|
|
16
|
+
* // => 'https://example.com/app/abc/detail/123'
|
|
17
|
+
*
|
|
18
|
+
* resolveAppUrl('https://example.com/detail/123')
|
|
19
|
+
* // => 'https://example.com/app/abc/detail/123'
|
|
20
|
+
*
|
|
21
|
+
* resolveAppUrl('https://example.com/app/abc/detail/123')
|
|
22
|
+
* // => 'https://example.com/app/abc/detail/123' (已有前缀,不重复添加)
|
|
23
|
+
*
|
|
24
|
+
* resolveAppUrl('https://other-site.com/page')
|
|
25
|
+
* // => 'https://other-site.com/page' (非当前域名,原样返回)
|
|
26
|
+
*/
|
|
27
|
+
export declare function resolveAppUrl(path: string): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { normalizeBasePath } from "./utils.js";
|
|
2
|
+
function ensureBasePath(pathname, basePath) {
|
|
3
|
+
if (!basePath) return pathname;
|
|
4
|
+
if (pathname.startsWith(basePath)) return pathname;
|
|
5
|
+
return `${basePath}${pathname.startsWith('/') ? '' : '/'}${pathname}`;
|
|
6
|
+
}
|
|
7
|
+
function resolveAppUrl(path) {
|
|
8
|
+
const basePath = normalizeBasePath(process.env.CLIENT_BASE_PATH);
|
|
9
|
+
try {
|
|
10
|
+
const url = new URL(path);
|
|
11
|
+
if (url.origin !== window.location.origin) return path;
|
|
12
|
+
url.pathname = ensureBasePath(url.pathname, basePath);
|
|
13
|
+
return url.toString();
|
|
14
|
+
} catch {}
|
|
15
|
+
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
16
|
+
const resolvedPath = ensureBasePath(normalizedPath, basePath);
|
|
17
|
+
return `${window.location.origin}${resolvedPath}`;
|
|
18
|
+
}
|
|
19
|
+
export { resolveAppUrl };
|
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.20",
|
|
4
4
|
"types": "./lib/index.d.ts",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -98,12 +98,13 @@
|
|
|
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": "
|
|
103
|
-
"@lark-apaas/auth-sdk": "^0.1.
|
|
104
|
-
"@lark-apaas/client-capability": "^0.1.
|
|
105
|
-
"@lark-apaas/
|
|
106
|
-
"@lark-apaas/
|
|
101
|
+
"@data-loom/js": "0.4.11",
|
|
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
|
+
"@lark-apaas/miaoda-inspector": "^1.0.20",
|
|
107
|
+
"@lark-apaas/observable-web": "^1.0.4",
|
|
107
108
|
"@radix-ui/react-avatar": "^1.1.10",
|
|
108
109
|
"@radix-ui/react-popover": "^1.1.15",
|
|
109
110
|
"@radix-ui/react-slot": "^1.2.3",
|
|
@@ -174,4 +175,4 @@
|
|
|
174
175
|
"react-router-dom": ">=6.26.2",
|
|
175
176
|
"styled-jsx": ">=5.0.0"
|
|
176
177
|
}
|
|
177
|
-
}
|
|
178
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '../../integrations/generateImage';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "../../integrations/generateImage.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '../../integrations/generateTextStream';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "../../integrations/generateTextStream.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function generateImage(prompt: string, size?: string, headers?: Record<string, string>): Promise<any>;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { getAppId } from "../utils/getAppId.js";
|
|
2
|
-
import { getCsrfToken } from "../utils/getCsrfToken.js";
|
|
3
|
-
import { getEnvPath } from "../utils/getEnvPath.js";
|
|
4
|
-
import { isSparkRuntime } from "../utils/utils.js";
|
|
5
|
-
async function generateImage(prompt, size = '1024x1024', headers = {}) {
|
|
6
|
-
const appId = getAppId(window.location.pathname);
|
|
7
|
-
if (!appId) return {
|
|
8
|
-
code: 1,
|
|
9
|
-
msg: 'appId is required',
|
|
10
|
-
data: {}
|
|
11
|
-
};
|
|
12
|
-
const defaultHeaders = {
|
|
13
|
-
'Content-Type': 'application/json'
|
|
14
|
-
};
|
|
15
|
-
const mergedHeaders = {
|
|
16
|
-
...defaultHeaders,
|
|
17
|
-
...headers,
|
|
18
|
-
'X-Kunlun-Token': window.token,
|
|
19
|
-
'x-miaoda-token': window.MIAODA_BUILTIN_TTT,
|
|
20
|
-
'x-lgw-csrf-token': window.lgw_csrf_token,
|
|
21
|
-
...window.CSRF_HEADERS || {}
|
|
22
|
-
};
|
|
23
|
-
if (isSparkRuntime()) {
|
|
24
|
-
mergedHeaders['X-Suda-Csrf-Token'] = getCsrfToken();
|
|
25
|
-
const response = await fetch(`${window.location.origin}/spark/b/${appId}/text2image`, {
|
|
26
|
-
method: 'POST',
|
|
27
|
-
headers: mergedHeaders,
|
|
28
|
-
credentials: 'include',
|
|
29
|
-
body: JSON.stringify({
|
|
30
|
-
prompt,
|
|
31
|
-
size
|
|
32
|
-
})
|
|
33
|
-
});
|
|
34
|
-
return await response.json();
|
|
35
|
-
}
|
|
36
|
-
const response = await fetch(`${window.location.origin}/ai/api/${getEnvPath()}/v1/apps/${appId}/text2image`, {
|
|
37
|
-
method: 'POST',
|
|
38
|
-
headers: mergedHeaders,
|
|
39
|
-
credentials: 'include',
|
|
40
|
-
body: JSON.stringify({
|
|
41
|
-
prompt,
|
|
42
|
-
size
|
|
43
|
-
})
|
|
44
|
-
});
|
|
45
|
-
return await response.json();
|
|
46
|
-
}
|
|
47
|
-
export { generateImage };
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
interface GenerateTextOptions {
|
|
2
|
-
text: string;
|
|
3
|
-
thinking_type?: 'enabled' | 'disabled';
|
|
4
|
-
headers?: Record<string, string>;
|
|
5
|
-
}
|
|
6
|
-
interface GenerateTextResult {
|
|
7
|
-
content: string;
|
|
8
|
-
reasoning_content: string;
|
|
9
|
-
success: boolean;
|
|
10
|
-
error?: string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* 文生文 - 流式版本
|
|
14
|
-
* 支持实时接收生成内容的回调
|
|
15
|
-
*/
|
|
16
|
-
export declare function generateTextStream(options: GenerateTextOptions, onChunk?: (chunk: {
|
|
17
|
-
content: string;
|
|
18
|
-
reasoning_content: string;
|
|
19
|
-
finished: boolean;
|
|
20
|
-
}) => void): Promise<GenerateTextResult>;
|
|
21
|
-
export {};
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { getAppId } from "../utils/getAppId.js";
|
|
2
|
-
import { getCsrfToken } from "../utils/getCsrfToken.js";
|
|
3
|
-
import { getEnvPath } from "../utils/getEnvPath.js";
|
|
4
|
-
import { isSparkRuntime } from "../utils/utils.js";
|
|
5
|
-
async function generateTextStream(options, onChunk) {
|
|
6
|
-
const { text, thinking_type = 'disabled', headers = {} } = options;
|
|
7
|
-
const appId = getAppId(window.location.pathname);
|
|
8
|
-
if (!appId) return {
|
|
9
|
-
content: '',
|
|
10
|
-
reasoning_content: '',
|
|
11
|
-
success: false,
|
|
12
|
-
error: 'appId is required'
|
|
13
|
-
};
|
|
14
|
-
try {
|
|
15
|
-
const mergedHeaders = {
|
|
16
|
-
'Content-Type': 'application/json',
|
|
17
|
-
...headers,
|
|
18
|
-
'X-Kunlun-Token': window.token,
|
|
19
|
-
'x-miaoda-token': window.MIAODA_BUILTIN_TTT,
|
|
20
|
-
'x-lgw-csrf-token': window.lgw_csrf_token,
|
|
21
|
-
...window.CSRF_HEADERS || {}
|
|
22
|
-
};
|
|
23
|
-
let response;
|
|
24
|
-
if (isSparkRuntime()) {
|
|
25
|
-
mergedHeaders['X-Suda-Csrf-Token'] = getCsrfToken();
|
|
26
|
-
response = await fetch(`${window.location.origin}/spark/b/${appId}/text/generate`, {
|
|
27
|
-
method: 'POST',
|
|
28
|
-
headers: mergedHeaders,
|
|
29
|
-
credentials: 'include',
|
|
30
|
-
body: JSON.stringify({
|
|
31
|
-
text,
|
|
32
|
-
thinking_type
|
|
33
|
-
})
|
|
34
|
-
});
|
|
35
|
-
} else response = await fetch(`${window.location.origin}/ai/api/${getEnvPath()}/v1/apps/${appId}/text/generate`, {
|
|
36
|
-
method: 'POST',
|
|
37
|
-
headers: mergedHeaders,
|
|
38
|
-
credentials: 'include',
|
|
39
|
-
body: JSON.stringify({
|
|
40
|
-
text,
|
|
41
|
-
thinking_type
|
|
42
|
-
})
|
|
43
|
-
});
|
|
44
|
-
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
|
45
|
-
const reader = response.body?.getReader();
|
|
46
|
-
if (!reader) throw new Error('无法获取响应流');
|
|
47
|
-
let fullContent = '';
|
|
48
|
-
let fullReasoningContent = '';
|
|
49
|
-
const decoder = new TextDecoder();
|
|
50
|
-
while(true){
|
|
51
|
-
const { done, value } = await reader.read();
|
|
52
|
-
if (done) break;
|
|
53
|
-
const chunk = decoder.decode(value, {
|
|
54
|
-
stream: true
|
|
55
|
-
});
|
|
56
|
-
const lines = chunk.split('\n').filter((line)=>line.trim());
|
|
57
|
-
for (const line of lines)if (line.startsWith('data: ')) {
|
|
58
|
-
const jsonStr = line.slice(6);
|
|
59
|
-
try {
|
|
60
|
-
const data = JSON.parse(jsonStr);
|
|
61
|
-
if (0 !== data.code) return {
|
|
62
|
-
content: '',
|
|
63
|
-
reasoning_content: '',
|
|
64
|
-
success: false,
|
|
65
|
-
error: data.msg || '生成失败'
|
|
66
|
-
};
|
|
67
|
-
if (data.data.content) fullContent += data.data.content;
|
|
68
|
-
if (data.data.reasoning_content) fullReasoningContent += data.data.reasoning_content;
|
|
69
|
-
if (onChunk) onChunk({
|
|
70
|
-
content: data.data.content || '',
|
|
71
|
-
reasoning_content: data.data.reasoning_content || '',
|
|
72
|
-
finished: data.finished
|
|
73
|
-
});
|
|
74
|
-
if (data.finished) return {
|
|
75
|
-
content: fullContent,
|
|
76
|
-
reasoning_content: fullReasoningContent,
|
|
77
|
-
success: true
|
|
78
|
-
};
|
|
79
|
-
} catch (parseError) {
|
|
80
|
-
console.error(`解析JSON失败: ${jsonStr}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
content: fullContent,
|
|
86
|
-
reasoning_content: fullReasoningContent,
|
|
87
|
-
success: true
|
|
88
|
-
};
|
|
89
|
-
} catch (error) {
|
|
90
|
-
return {
|
|
91
|
-
content: '',
|
|
92
|
-
reasoning_content: '',
|
|
93
|
-
success: false,
|
|
94
|
-
error: error instanceof Error ? error.message : '未知错误'
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
export { generateTextStream };
|