@tacoreai/web-sdk 1.3.0 → 1.5.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.
@@ -33,8 +33,9 @@ class AppsTokenManager {
33
33
  export class AppsAuthManager extends BaseAppsClient {
34
34
  constructor(appId, config = {}) {
35
35
  super(appId, config);
36
+ const isPreviewMode = isBackend && process.env.TACORE_APPSERVER_PREVIEW_MODE === "true";
36
37
 
37
- if (isBackend && !this.config.tacoreServerInteropAppServerApiKey) {
38
+ if (isBackend && !isPreviewMode && !this.config.tacoreServerInteropAppServerApiKey) {
38
39
  throw new Error("tacoreServerInteropAppServerApiKey is required for backend environment. Provide it in config or via TACORE_SERVER_INTEROP_APP_SERVER_API_KEY env var.");
39
40
  }
40
41
 
@@ -333,4 +334,4 @@ export class AppsAuthManager extends BaseAppsClient {
333
334
  clearAccessToken() {
334
335
  AppsTokenManager.clearAccessToken();
335
336
  }
336
- }
337
+ }
@@ -2,6 +2,20 @@ import { env, isDevelopmentBrowser, isProductionBrowser, isBackend } from "../..
2
2
 
3
3
  const appServerAPIMap = new Map();
4
4
 
5
+ const isBrowserPreviewRuntime = () => {
6
+ if (typeof window === "undefined") {
7
+ return false;
8
+ }
9
+
10
+ const explicitFlag = window.__TACORE_PREVIEW_MODE__;
11
+ if (explicitFlag === true || explicitFlag === "true") {
12
+ return true;
13
+ }
14
+
15
+ const pathname = typeof window.location?.pathname === "string" ? window.location.pathname : "";
16
+ return pathname.startsWith("/app-run/");
17
+ };
18
+
5
19
  /**
6
20
  * 注册一个 App Server API。
7
21
  * - 在开发态浏览器中:有效,用于本地调用。
@@ -17,9 +31,51 @@ const registerAppServerAPI = (appServerAPIName, appServerAPIHandler) => {
17
31
  // 在生产态浏览器中,这是一个空操作。
18
32
  };
19
33
 
34
+ const invokeByPlatformProxy = async function(appServerAPIName, payload) {
35
+ const endpoint = `/apps/invokeAppServerAPI?appId=${encodeURIComponent(this.appId)}&apiName=${encodeURIComponent(appServerAPIName)}`;
36
+ const res = await this._post(endpoint, payload);
37
+ if (res.success) {
38
+ return res.data;
39
+ }
40
+ throw new Error(res.error || res.message || `AppServer invocation failed: ${res.code || "UNKNOWN_ERROR"}`);
41
+ };
42
+
43
+ const invokeByPreviewProxy = async function(appServerAPIName, payload) {
44
+ const endpoint = `/appserver-preview/invokeAppServerAPI?appId=${encodeURIComponent(this.appId)}&apiName=${encodeURIComponent(appServerAPIName)}`;
45
+
46
+ const response = await fetch(endpoint, {
47
+ method: "POST",
48
+ headers: {
49
+ "Content-Type": "application/json",
50
+ },
51
+ body: JSON.stringify(payload || {}),
52
+ });
53
+
54
+ const contentType = response.headers.get("content-type") || "";
55
+ const responseData = contentType.includes("application/json")
56
+ ? await response.json()
57
+ : await response.text();
58
+
59
+ if (!response.ok) {
60
+ const errorMessage = typeof responseData === "object"
61
+ ? (responseData?.error || responseData?.message || JSON.stringify(responseData))
62
+ : String(responseData || "");
63
+ throw new Error(`[AppServer-DevBridge] status: ${response.status}, message: ${errorMessage}`);
64
+ }
65
+
66
+ if (responseData && typeof responseData === "object" && Object.prototype.hasOwnProperty.call(responseData, "success")) {
67
+ if (responseData.success) {
68
+ return responseData.data;
69
+ }
70
+ throw new Error(responseData.error || "AppServer invocation failed in dev bridge");
71
+ }
72
+
73
+ return responseData;
74
+ };
75
+
20
76
  /**
21
77
  * 调用一个 App Server API。
22
- * - 在开发态浏览器中:本地执行。
78
+ * - 在开发态浏览器中:预览页(/app-run/*)走本地预览代理,其余开发页直接走平台转发。
23
79
  * - 在生产态浏览器中:统一走平台转发(/apps/invokeAppServerAPI)。
24
80
  * - 在后端云函数中:本地执行 (由云函数入口调用)。
25
81
  * - 跨应用调用:仅后端场景可直连目标 AppServer(需 appServerBaseUrl + appServerApiKey)。
@@ -61,24 +117,25 @@ const invokeAppServerAPI = async function(appServerAPIName, payload) {
61
117
  }
62
118
  }
63
119
 
64
- // 场景一:生产环境的浏览器,必须发起网络请求
65
- if (isProductionBrowser) {
66
- // 浏览器端统一走平台转发,由平台负责组织/应用上下文与内部鉴权链路
67
- const endpoint = `/apps/invokeAppServerAPI?appId=${encodeURIComponent(this.appId)}&apiName=${encodeURIComponent(appServerAPIName)}`;
120
+ // 场景一:开发环境浏览器
121
+ if (isDevelopmentBrowser) {
122
+ if (isBrowserPreviewRuntime()) {
123
+ return await invokeByPreviewProxy.call(this, appServerAPIName, payload);
124
+ }
125
+ return await invokeByPlatformProxy.call(this, appServerAPIName, payload);
126
+ }
68
127
 
128
+ // 场景二:生产环境的浏览器,统一走平台转发
129
+ if (isProductionBrowser) {
69
130
  try {
70
- const res = await this._post(endpoint, payload);
71
- if (res.success) {
72
- return res.data;
73
- }
74
- throw new Error(res.error || res.message || `AppServer invocation failed: ${res.code || "UNKNOWN_ERROR"}`);
131
+ return await invokeByPlatformProxy.call(this, appServerAPIName, payload);
75
132
  } catch (error) {
76
133
  console.error(`[AppServer-Prod] Failed to invoke "${appServerAPIName}" via appsClient:`, error);
77
134
  throw error;
78
135
  }
79
136
  }
80
137
 
81
- // 场景二:开发环境的浏览器 或 后端云函数环境,都从本地 Map 执行
138
+ // 场景三:后端云函数环境,从本地 Map 执行
82
139
  const appServerAPIHandler = appServerAPIMap.get(appServerAPIName);
83
140
  if (!appServerAPIHandler) {
84
141
  throw new Error(`[AppServer-${env}] AppServer "${appServerAPIName}" not found or not registered.`);
@@ -38,8 +38,9 @@ class AppsClient extends BaseAppsClient {
38
38
 
39
39
  constructor(appId, config = {}) {
40
40
  super(appId, config);
41
+ const isPreviewMode = isBackend && process.env.TACORE_APPSERVER_PREVIEW_MODE === "true";
41
42
 
42
- if (isBackend && !this.config.tacoreServerInteropAppServerApiKey) {
43
+ if (isBackend && !isPreviewMode && !this.config.tacoreServerInteropAppServerApiKey) {
43
44
  throw new Error(
44
45
  "tacoreServerInteropAppServerApiKey is required for backend environment. Provide it in config or via TACORE_SERVER_INTEROP_APP_SERVER_API_KEY env var."
45
46
  );
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tacoreai/web-sdk",
3
3
  "description": "This file is for app server package, not the real npm package",
4
- "version": "1.3.0",
4
+ "version": "1.5.0",
5
5
  "type": "module",
6
6
  "publishConfig": {
7
7
  "access": "public",