@tacoreai/web-sdk 1.10.0 → 1.11.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.
@@ -30,6 +30,20 @@ const getRequestSource = (isPlatformProxyRequest, isSchedulerRequest) => {
30
30
  return isPreviewMode() ? "preview-direct" : "external-direct";
31
31
  };
32
32
 
33
+ const createRequestScopedAppsClient = (env, options = {}) => {
34
+ const { accessToken = null, previewAppServerApiKey = null } = options;
35
+ const config = {
36
+ ...env,
37
+ accessToken: accessToken || null,
38
+ };
39
+
40
+ if (previewAppServerApiKey) {
41
+ config.previewAppServerApiKey = previewAppServerApiKey;
42
+ }
43
+
44
+ return new AppsClient(env.appId, config);
45
+ };
46
+
33
47
  const isPreviewApiKeyShapeValid = (apiKey) => {
34
48
  if (typeof apiKey !== "string") return false;
35
49
  const value = apiKey.trim();
@@ -247,7 +261,6 @@ export const createAppServerRuntime = async (options = {}) => {
247
261
  });
248
262
  }
249
263
 
250
- const appsClient = AppsClient.getInstance(env.appId, { ...env, accessToken: requestAccessToken || null });
251
264
  const previewBridgeInteropToken =
252
265
  process.env.TACORE_APPSERVER_PREVIEW_BRIDGE_INTEROP_TOKEN ||
253
266
  process.env.TACORE_SERVER_INTEROP_APP_SERVER_API_KEY;
@@ -260,6 +273,7 @@ export const createAppServerRuntime = async (options = {}) => {
260
273
  process.env.CLOUDFLARE_WORKER_INTEROP_APP_SERVER_TOKEN
261
274
  );
262
275
  const requestSource = getRequestSource(isPlatformProxyRequest, isSchedulerRequest);
276
+ let previewAppServerApiKey = null;
263
277
 
264
278
  console.log(`[AppServer] invoke api="${apiName}" source="${requestSource}"`);
265
279
 
@@ -283,7 +297,10 @@ export const createAppServerRuntime = async (options = {}) => {
283
297
 
284
298
  let isValidApiKey = false;
285
299
  try {
286
- isValidApiKey = await validateExternalApiKey(appsClient, env.appId, requestApiKey);
300
+ const authClient = createRequestScopedAppsClient(env, {
301
+ accessToken: requestAccessToken || null,
302
+ });
303
+ isValidApiKey = await validateExternalApiKey(authClient, env.appId, requestApiKey);
287
304
  } catch (error) {
288
305
  console.error("[AppServer] Failed to validate external API key:", error);
289
306
  return res.status(500).json({
@@ -300,9 +317,31 @@ export const createAppServerRuntime = async (options = {}) => {
300
317
  error: "Invalid X-API-Key",
301
318
  });
302
319
  }
320
+
321
+ if (isPreviewMode() && !requestAccessToken) {
322
+ previewAppServerApiKey = requestApiKey;
323
+ }
303
324
  }
304
325
 
305
326
  try {
327
+ console.log(`[AppServer Debug] invoke api="${apiName}" auth forwarding`, {
328
+ requestSource,
329
+ hasAuthorization: Boolean(requestAccessToken),
330
+ hasRequestApiKey: Boolean(requestApiKey),
331
+ hasPlatformInteropHeader: Boolean(platformInteropHeader),
332
+ hasSchedulerInteropHeader: Boolean(schedulerInteropHeader),
333
+ willForwardPreviewAppServerApiKey: Boolean(previewAppServerApiKey),
334
+ });
335
+
336
+ const appsClient = createRequestScopedAppsClient(env, {
337
+ accessToken: requestAccessToken || null,
338
+ previewAppServerApiKey,
339
+ });
340
+ console.log(`[AppServer Debug] scoped AppsClient api="${apiName}"`, {
341
+ hasAccessToken: Boolean(appsClient.getAccessToken()),
342
+ hasPreviewAppServerApiKey: Boolean(appsClient.config.previewAppServerApiKey),
343
+ hasInteropKey: Boolean(appsClient.config.tacoreServerInteropAppServerApiKey),
344
+ });
306
345
  const data = await appsClient.invokeAppServerAPI(apiName, payload, {
307
346
  appsClient,
308
347
  req,
@@ -1,6 +1,7 @@
1
1
  import { getAppsApiBaseUrl, isBrowser, isBackend, getGlobalOptions } from "../../../utils/index.js";
2
2
 
3
3
  const ACCESS_TOKEN_STORAGE_KEY = "tacoreai_apps_access_token";
4
+ const PREVIEW_APPSERVER_API_KEY_HEADER = "x-tacore-preview-app-server-api-key";
4
5
 
5
6
  const normalizeAccessToken = (value) => {
6
7
  if (typeof value !== "string") {
@@ -44,6 +45,8 @@ const writePersistedAccessToken = (token) => {
44
45
  }
45
46
  };
46
47
 
48
+ const isBackendPreviewMode = () => isBackend && process.env.TACORE_APPSERVER_PREVIEW_MODE === "true";
49
+
47
50
  /**
48
51
  * Apps SDK 基类
49
52
  * 封装通用的配置管理、Header构建、HTTP请求逻辑
@@ -178,6 +181,13 @@ export class BaseAppsClient {
178
181
 
179
182
  if (isBackend && this.config.tacoreServerInteropAppServerApiKey) {
180
183
  headers["x-tacore-server-interop-app-server-api-key"] = this.config.tacoreServerInteropAppServerApiKey;
184
+ } else if (
185
+ isBackendPreviewMode() &&
186
+ !token &&
187
+ this.config.previewAppServerApiKey &&
188
+ !headers[PREVIEW_APPSERVER_API_KEY_HEADER]
189
+ ) {
190
+ headers[PREVIEW_APPSERVER_API_KEY_HEADER] = this.config.previewAppServerApiKey;
181
191
  }
182
192
 
183
193
  return headers;
@@ -190,6 +200,14 @@ export class BaseAppsClient {
190
200
  const url = `${this.config.apiBaseUrl}${endpoint}`;
191
201
  const headers = this._getRequestHeaders(options.headers);
192
202
 
203
+ if (isBackendPreviewMode()) {
204
+ console.log(`[BaseAppsClient Debug][${this.appId}] endpoint="${endpoint}"`, {
205
+ hasAuthorization: Boolean(headers.Authorization || headers.authorization),
206
+ hasInteropHeader: Boolean(headers["x-tacore-server-interop-app-server-api-key"]),
207
+ hasPreviewAppServerApiKeyHeader: Boolean(headers[PREVIEW_APPSERVER_API_KEY_HEADER]),
208
+ });
209
+ }
210
+
193
211
  const response = await fetch(url, {
194
212
  ...options,
195
213
  headers,
@@ -276,6 +294,7 @@ export class BaseAppsClient {
276
294
  getConfig() {
277
295
  const config = { ...this.config };
278
296
  delete config.accessToken;
297
+ delete config.previewAppServerApiKey;
279
298
  return config;
280
299
  }
281
300
 
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.10.0",
4
+ "version": "1.11.0",
5
5
  "type": "module",
6
6
  "publishConfig": {
7
7
  "access": "public",