@lark-apaas/client-toolkit-lite 1.1.7-alpha.2 → 1.1.7-alpha.21

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/dist/index.cjs CHANGED
@@ -33,6 +33,7 @@ var index_exports = {};
33
33
  __export(index_exports, {
34
34
  ActiveLink: () => ActiveLink,
35
35
  AppContainer: () => AppContainer_default,
36
+ ErrorRender: () => ErrorRender_default,
36
37
  NavLink: () => NavLink2,
37
38
  PagePlaceholder: () => PagePlaceholder_default,
38
39
  QueryProvider: () => QueryProvider_default,
@@ -42,6 +43,7 @@ __export(index_exports, {
42
43
  avatarImages: () => avatar_exports,
43
44
  axiosForBackend: () => axiosForBackend,
44
45
  bannerImages: () => banner_exports,
46
+ capabilityClient: () => capabilityClient,
45
47
  clsxWithTw: () => clsxWithTw,
46
48
  copyToClipboard: () => copyToClipboard,
47
49
  coverImages: () => cover_exports,
@@ -58,6 +60,7 @@ __export(index_exports, {
58
60
  isIpad: () => isIpad,
59
61
  isMobile: () => isMobile,
60
62
  isPreview: () => isPreview,
63
+ logger: () => logger,
61
64
  normalizeBasePath: () => normalizeBasePath,
62
65
  reportTeaEvent: () => reportTeaEvent,
63
66
  resolveAppUrl: () => resolveAppUrl,
@@ -71,7 +74,8 @@ __export(index_exports, {
71
74
  module.exports = __toCommonJS(index_exports);
72
75
 
73
76
  // src/components/AppContainer/index.tsx
74
- var import_react7 = __toESM(require("react"), 1);
77
+ var import_react9 = __toESM(require("react"), 1);
78
+ var import_miaoda_inspector = require("@lark-apaas/miaoda-inspector");
75
79
 
76
80
  // src/runtime/react-devtools-hook.ts
77
81
  if (typeof window !== "undefined" && process.env.NODE_ENV !== "production") {
@@ -127,29 +131,1002 @@ function initAxiosConfig(axiosInstance2) {
127
131
  if (!axiosInstance2) {
128
132
  axiosInstance2 = import_axios.default;
129
133
  }
130
- axiosInstance2.interceptors.request.use((config) => {
134
+ axiosInstance2.interceptors.request.use((config2) => {
131
135
  const csrfToken = getCsrfToken();
132
136
  if (csrfToken) {
133
- config.headers["X-Suda-Csrf-Token"] = csrfToken;
137
+ config2.headers["X-Suda-Csrf-Token"] = csrfToken;
134
138
  }
135
139
  if (typeof window !== "undefined") {
136
- config.headers["X-Page-Route"] = window.location.pathname;
140
+ config2.headers["X-Page-Route"] = window.location.pathname;
137
141
  }
138
- return config;
142
+ return config2;
139
143
  }, (error) => Promise.reject(error));
140
144
  axiosInstance2.interceptors.response.use((response) => response, (error) => {
141
145
  if (process.env.NODE_ENV !== "production") {
142
146
  console.warn("[axios]", error.config?.method?.toUpperCase(), error.config?.url, error.message);
143
147
  }
144
- return Promise.reject(error);
148
+ return Promise.reject(error);
149
+ });
150
+ }
151
+ __name(initAxiosConfig, "initAxiosConfig");
152
+
153
+ // src/logger/logger.ts
154
+ var import_observable_web = require("@lark-apaas/observable-web");
155
+
156
+ // src/logger/intercept-global-error.ts
157
+ var import_internal_slardar = require("@lark-apaas/internal-slardar");
158
+
159
+ // src/utils/hmr-api.ts
160
+ var import_meta = {};
161
+ function createWebpackHmrApi(hot) {
162
+ return {
163
+ onSuccess(callback) {
164
+ let lastStatus = null;
165
+ const handler = /* @__PURE__ */ __name((status) => {
166
+ if (status === "idle" && lastStatus === "apply") {
167
+ try {
168
+ callback();
169
+ } catch (e) {
170
+ console.error("[HMR] Success callback error:", e);
171
+ }
172
+ }
173
+ lastStatus = status;
174
+ }, "handler");
175
+ hot.addStatusHandler(handler);
176
+ return () => hot.removeStatusHandler(handler);
177
+ },
178
+ onError(callback) {
179
+ const handler = /* @__PURE__ */ __name((status) => {
180
+ if (status === "fail" || status === "abort") {
181
+ try {
182
+ callback(new Error(`HMR ${status}`));
183
+ } catch (e) {
184
+ console.error("[HMR] Error callback error:", e);
185
+ }
186
+ }
187
+ }, "handler");
188
+ hot.addStatusHandler(handler);
189
+ return () => hot.removeStatusHandler(handler);
190
+ }
191
+ };
192
+ }
193
+ __name(createWebpackHmrApi, "createWebpackHmrApi");
194
+ function getHmrApi() {
195
+ if (process.env.NODE_ENV === "production") return null;
196
+ if (import_meta.webpackHot) {
197
+ return createWebpackHmrApi(import_meta.webpackHot);
198
+ }
199
+ if (typeof module !== "undefined" && module.hot) {
200
+ return createWebpackHmrApi(module.hot);
201
+ }
202
+ if (window.__VITE_HMR__) {
203
+ return window.__VITE_HMR__;
204
+ }
205
+ return null;
206
+ }
207
+ __name(getHmrApi, "getHmrApi");
208
+
209
+ // src/utils/postMessage.ts
210
+ var PARENT_ORIGIN_KEY = "__parentOrigin";
211
+ function getParentOriginFromParams() {
212
+ try {
213
+ const params = new URLSearchParams(window.location.search);
214
+ const origin = params.get(PARENT_ORIGIN_KEY);
215
+ if (origin) {
216
+ sessionStorage.setItem(PARENT_ORIGIN_KEY, origin);
217
+ return origin;
218
+ }
219
+ } catch {
220
+ }
221
+ try {
222
+ return sessionStorage.getItem(PARENT_ORIGIN_KEY) || void 0;
223
+ } catch {
224
+ return void 0;
225
+ }
226
+ }
227
+ __name(getParentOriginFromParams, "getParentOriginFromParams");
228
+ function getLegacyParentOrigin() {
229
+ const { origin } = window.location;
230
+ if (origin.includes("force.feishuapp.net")) {
231
+ return "https://force.feishu.cn";
232
+ }
233
+ if (origin.includes("force-pre.feishuapp.net")) {
234
+ return "https://force.feishu-pre.cn";
235
+ }
236
+ if (origin.includes("force.byted.org")) {
237
+ return "https://force.feishu-boe.cn";
238
+ }
239
+ if (origin.includes("feishuapp.cn") || origin.includes("miaoda.feishuapp.net")) {
240
+ return "https://miaoda.feishu.cn";
241
+ }
242
+ if (origin.includes("fsapp.kundou.cn") || origin.includes("miaoda-pre.feishuapp.net")) {
243
+ return "https://miaoda.feishu-pre.cn";
244
+ }
245
+ return "https://miaoda.feishu-boe.cn";
246
+ }
247
+ __name(getLegacyParentOrigin, "getLegacyParentOrigin");
248
+ function resolveParentOrigin() {
249
+ try {
250
+ if (document.referrer) {
251
+ const referrerOrigin = new URL(document.referrer).origin;
252
+ if (referrerOrigin.startsWith("http://localhost") || referrerOrigin.startsWith("http://127.0.0.1")) {
253
+ return referrerOrigin;
254
+ }
255
+ }
256
+ } catch {
257
+ }
258
+ const paramOrigin = getParentOriginFromParams();
259
+ if (paramOrigin) return paramOrigin;
260
+ return process.env?.FORCE_FRAMEWORK_DOMAIN_MAIN ?? getLegacyParentOrigin();
261
+ }
262
+ __name(resolveParentOrigin, "resolveParentOrigin");
263
+ function submitPostMessage(message, targetOrigin) {
264
+ try {
265
+ const parentOrigin = resolveParentOrigin();
266
+ const origin = targetOrigin ?? parentOrigin;
267
+ if (!origin) return;
268
+ window.parent.postMessage(message, origin);
269
+ } catch (e) {
270
+ console.error("postMessage error", e);
271
+ }
272
+ }
273
+ __name(submitPostMessage, "submitPostMessage");
274
+
275
+ // src/logger/log-types.ts
276
+ var LOG_LEVELS = [
277
+ "debug",
278
+ "info",
279
+ "warn",
280
+ "error",
281
+ "success"
282
+ ];
283
+ function isLogLevel(value) {
284
+ return typeof value === "string" && LOG_LEVELS.includes(value);
285
+ }
286
+ __name(isLogLevel, "isLogLevel");
287
+
288
+ // src/logger/intercept-global-error.ts
289
+ var devServerDisconnectInfo = null;
290
+ var retryCount = 0;
291
+ function processDevServerLog(log) {
292
+ if (!log) return;
293
+ const devFlag = log.includes("[webpack-dev-server]") || log.includes("[vite]");
294
+ if (devFlag && log.includes("Disconnected")) {
295
+ const time = Date.now();
296
+ devServerDisconnectInfo = {
297
+ time
298
+ };
299
+ submitPostMessage({
300
+ type: "DevServerMessage",
301
+ data: {
302
+ type: "devServer-status",
303
+ status: "disconnected"
304
+ }
305
+ });
306
+ import_internal_slardar.slardar.sendEvent({
307
+ name: "sandbox-devServer",
308
+ metrics: {
309
+ time
310
+ },
311
+ categories: {
312
+ type: "disconnected"
313
+ }
314
+ });
315
+ return;
316
+ }
317
+ if (!devServerDisconnectInfo) {
318
+ return;
319
+ }
320
+ if (devFlag && log.includes("Trying to reconnect")) {
321
+ if (retryCount) {
322
+ import_internal_slardar.slardar.sendEvent({
323
+ name: "sandbox-devServer",
324
+ metrics: {
325
+ retryCount: retryCount + 1
326
+ },
327
+ categories: {
328
+ type: "reconnect-failed"
329
+ }
330
+ });
331
+ }
332
+ retryCount++;
333
+ return;
334
+ }
335
+ const hmrFlag = log.includes("[HMR]");
336
+ if (hmrFlag || devFlag && (log.includes("Socket connected") || log.includes("App updated") || log.includes("App hot update") || log.includes("connected"))) {
337
+ submitPostMessage({
338
+ type: "DevServerMessage",
339
+ data: {
340
+ type: "devServer-status",
341
+ status: "connected"
342
+ }
343
+ });
344
+ const startTime = devServerDisconnectInfo.time;
345
+ const duration = Date.now() - startTime;
346
+ import_internal_slardar.slardar.sendEvent({
347
+ name: "sandbox-devServer",
348
+ metrics: {
349
+ startTime,
350
+ duration
351
+ },
352
+ categories: {
353
+ type: "devServer-reconnected"
354
+ }
355
+ });
356
+ devServerDisconnectInfo = null;
357
+ retryCount = 0;
358
+ }
359
+ }
360
+ __name(processDevServerLog, "processDevServerLog");
361
+ function listenModuleHmr() {
362
+ const hmr = getHmrApi();
363
+ if (hmr) {
364
+ hmr.onSuccess(() => {
365
+ submitPostMessage({
366
+ type: "DevServerMessage",
367
+ data: {
368
+ type: "devServer-status",
369
+ status: "hmr-apply-success"
370
+ }
371
+ });
372
+ });
373
+ hmr.onError((error) => {
374
+ console.warn("hmr apply failed", error);
375
+ import_internal_slardar.slardar.sendEvent({
376
+ name: "sandbox-devServer",
377
+ categories: {
378
+ type: "hmr-apply-failed",
379
+ error: String(error)
380
+ }
381
+ });
382
+ });
383
+ }
384
+ }
385
+ __name(listenModuleHmr, "listenModuleHmr");
386
+ var PROXY_CONSOLE_METHOD = [
387
+ "log",
388
+ "info",
389
+ "warn",
390
+ "error"
391
+ ];
392
+ function interceptErrors() {
393
+ window.addEventListener("error", (event) => {
394
+ logger.error(event.error);
395
+ });
396
+ window.addEventListener("unhandledrejection", (event) => {
397
+ logger.error(event.reason);
398
+ });
399
+ listenModuleHmr();
400
+ PROXY_CONSOLE_METHOD.forEach((method) => {
401
+ const originalMethod = window.console[method];
402
+ window.console[method] = (...args) => {
403
+ originalMethod(...args);
404
+ const level = method === "log" ? "info" : method;
405
+ const first = args[0];
406
+ if (typeof first === "string") {
407
+ processDevServerLog(first);
408
+ }
409
+ if (typeof first === "string" && first.startsWith("[Dataloom]") && isLogLevel(level)) {
410
+ logger.log({
411
+ level,
412
+ args
413
+ });
414
+ submitPostMessage({
415
+ type: "Console",
416
+ method,
417
+ data: args
418
+ });
419
+ }
420
+ };
421
+ });
422
+ }
423
+ __name(interceptErrors, "interceptErrors");
424
+
425
+ // src/utils/safeStringify.ts
426
+ function safeStringify(obj) {
427
+ const seen = /* @__PURE__ */ new Set();
428
+ try {
429
+ return JSON.stringify(obj, (_key, value) => {
430
+ if (typeof value === "object" && value !== null) {
431
+ if (seen.has(value)) {
432
+ return "[Circular]";
433
+ }
434
+ seen.add(value);
435
+ }
436
+ if (typeof value === "bigint") {
437
+ return value.toString();
438
+ }
439
+ if (value instanceof Date) {
440
+ return value.toISOString();
441
+ }
442
+ if (value instanceof Map) {
443
+ return Object.fromEntries(value);
444
+ }
445
+ if (value instanceof Set) {
446
+ return Array.from(value);
447
+ }
448
+ if (value instanceof Error) {
449
+ return {
450
+ name: value.name,
451
+ message: value.message,
452
+ stack: value.stack
453
+ };
454
+ }
455
+ if (typeof value === "undefined") {
456
+ return "undefined";
457
+ }
458
+ if (typeof value === "symbol") {
459
+ return value.toString();
460
+ }
461
+ return value;
462
+ });
463
+ } catch {
464
+ return "";
465
+ } finally {
466
+ seen.clear();
467
+ }
468
+ }
469
+ __name(safeStringify, "safeStringify");
470
+ function processLogParams(args) {
471
+ return args.map((arg) => {
472
+ if (typeof arg === "string") return arg;
473
+ if (arg instanceof Error) {
474
+ return `${arg.name}: ${arg.message}
475
+ ${arg.stack ?? ""}`;
476
+ }
477
+ if (typeof arg === "object" && arg !== null) {
478
+ return safeStringify(arg);
479
+ }
480
+ return String(arg);
481
+ });
482
+ }
483
+ __name(processLogParams, "processLogParams");
484
+ function mapLogLevel(level) {
485
+ if (level === "warn") return "WARN";
486
+ if (level === "error") return "ERROR";
487
+ return "INFO";
488
+ }
489
+ __name(mapLogLevel, "mapLogLevel");
490
+
491
+ // src/logger/selected-logs.ts
492
+ var import_stacktrace_js = __toESM(require("stacktrace-js"), 1);
493
+
494
+ // src/logger/batch-logger.ts
495
+ var BatchLogger = class {
496
+ static {
497
+ __name(this, "BatchLogger");
498
+ }
499
+ config;
500
+ logQueue = [];
501
+ flushTimer = null;
502
+ isProcessing = false;
503
+ originConsole;
504
+ constructor(console1, config2) {
505
+ this.originConsole = {
506
+ ...console1
507
+ };
508
+ const { userId = "", tenantId = "", appId = "" } = window || {};
509
+ this.config = {
510
+ userId,
511
+ tenantId,
512
+ appId,
513
+ // 需要加请求路径前缀
514
+ endpoint: (process.env.CLIENT_BASE_PATH || "") + "/dev/logs/collect-batch",
515
+ sizeThreshold: 20,
516
+ flushInterval: 1e3,
517
+ maxRetries: 3,
518
+ retryDelay: 500,
519
+ headers: {
520
+ "Content-Type": "application/json"
521
+ },
522
+ ...config2 || {}
523
+ };
524
+ this.startFlushTimer();
525
+ this.setupBeforeUnloadHandler();
526
+ }
527
+ /**
528
+ * 批量记录日志(对外暴露的唯一方法)
529
+ */
530
+ batchLog(level, message, source) {
531
+ const logEntry = {
532
+ id: this.generateId(),
533
+ level,
534
+ message,
535
+ source,
536
+ timestamp: Date.now()
537
+ };
538
+ this.logQueue.push(logEntry);
539
+ if (this.logQueue.length >= this.config.sizeThreshold) {
540
+ this.flush();
541
+ }
542
+ }
543
+ /**
544
+ * 刷新日志队列,全部发送
545
+ */
546
+ async flush() {
547
+ if (this.isProcessing || this.logQueue.length === 0) {
548
+ return;
549
+ }
550
+ this.isProcessing = true;
551
+ const logsToSend = this.logQueue.splice(0, this.logQueue.length);
552
+ try {
553
+ await this.sendBatch(logsToSend);
554
+ } catch (error) {
555
+ this.logQueue.unshift(...logsToSend);
556
+ } finally {
557
+ this.isProcessing = false;
558
+ }
559
+ }
560
+ /**
561
+ * 发送日志批次到后端
562
+ */
563
+ async sendBatch(logs) {
564
+ const collectLogs = logs.map((log) => ({
565
+ level: log.level,
566
+ message: log.message,
567
+ time: new Date(log.timestamp).toISOString(),
568
+ source: log.source,
569
+ user_id: this.config.userId,
570
+ tenant_id: this.config.tenantId,
571
+ app_id: this.config.appId
572
+ }));
573
+ let retries = 0;
574
+ while (retries <= this.config.maxRetries) {
575
+ try {
576
+ await this.execFetch(this.config.endpoint, {
577
+ method: "POST",
578
+ headers: this.config.headers,
579
+ body: JSON.stringify(collectLogs)
580
+ });
581
+ return;
582
+ } catch (error) {
583
+ retries++;
584
+ if (retries > this.config.maxRetries) {
585
+ this.originConsole.error(`Failed to send logs (attempt ${retries}), retrying in ${this.config.retryDelay}ms...`);
586
+ } else {
587
+ this.originConsole.warn(`Failed to send logs (attempt ${retries}), retrying in ${this.config.retryDelay}ms...`);
588
+ }
589
+ await this.delay(this.config.retryDelay * retries);
590
+ }
591
+ }
592
+ }
593
+ /**
594
+ * 执行实际的fetch请求
595
+ */
596
+ async execFetch(url, options) {
597
+ return fetch(url, options);
598
+ }
599
+ /**
600
+ * 启动自动刷新定时器
601
+ */
602
+ startFlushTimer() {
603
+ if (this.flushTimer) {
604
+ clearInterval(this.flushTimer);
605
+ }
606
+ this.flushTimer = setInterval(() => {
607
+ if (this.logQueue.length > 0) {
608
+ this.flush();
609
+ }
610
+ }, this.config.flushInterval);
611
+ }
612
+ /**
613
+ * 设置页面卸载时的处理
614
+ */
615
+ setupBeforeUnloadHandler() {
616
+ if (typeof window !== "undefined") {
617
+ window.addEventListener("beforeunload", () => {
618
+ this.flush().finally(() => {
619
+ this.destroy();
620
+ });
621
+ });
622
+ }
623
+ }
624
+ /**
625
+ * 延迟函数
626
+ */
627
+ delay(ms) {
628
+ return new Promise((resolve) => setTimeout(resolve, ms));
629
+ }
630
+ /**
631
+ * 生成唯一ID
632
+ */
633
+ generateId() {
634
+ return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
635
+ }
636
+ /**
637
+ * 销毁资源
638
+ */
639
+ async destroy() {
640
+ if (this.flushTimer) {
641
+ clearInterval(this.flushTimer);
642
+ this.flushTimer = null;
643
+ }
644
+ if (this.logQueue.length > 0) {
645
+ await this.flush();
646
+ }
647
+ }
648
+ /**
649
+ * 获取队列大小
650
+ */
651
+ getQueueSize() {
652
+ return this.logQueue.length;
653
+ }
654
+ /**
655
+ * 更新配置
656
+ */
657
+ updateConfig(newConfig) {
658
+ this.config = {
659
+ ...this.config,
660
+ ...newConfig
661
+ };
662
+ this.startFlushTimer();
663
+ }
664
+ };
665
+ var defaultBatchLogger = null;
666
+ function batchLogInfo(level, message, source) {
667
+ if (!defaultBatchLogger) {
668
+ return;
669
+ }
670
+ defaultBatchLogger.batchLog(level, message, source);
671
+ }
672
+ __name(batchLogInfo, "batchLogInfo");
673
+ if (process.env.NODE_ENV !== "production" && typeof window !== "undefined") {
674
+ defaultBatchLogger = new BatchLogger(console);
675
+ }
676
+
677
+ // src/logger/selected-logs.ts
678
+ function mapStacktrace(stacktrace) {
679
+ return stacktrace.map((frame) => ({
680
+ functionName: frame.functionName || "",
681
+ fileName: frame.fileName || "",
682
+ lineNumber: frame.lineNumber || 0,
683
+ columnNumber: frame.columnNumber || 0
684
+ }));
685
+ }
686
+ __name(mapStacktrace, "mapStacktrace");
687
+ function reportStacktraceParseError(e, context) {
688
+ if (window.parent === window) return;
689
+ try {
690
+ submitPostMessage({
691
+ type: "STACKTRACE_PARSE_ERROR",
692
+ payload: {
693
+ error: e instanceof Error ? e.message : String(e),
694
+ context
695
+ }
696
+ });
697
+ } catch {
698
+ }
699
+ }
700
+ __name(reportStacktraceParseError, "reportStacktraceParseError");
701
+ async function getStacktrace() {
702
+ const stacktrace = await import_stacktrace_js.default.get();
703
+ return mapStacktrace(stacktrace);
704
+ }
705
+ __name(getStacktrace, "getStacktrace");
706
+ function errorReplacer(_key, value) {
707
+ if (value instanceof Error) {
708
+ return {
709
+ message: value.message,
710
+ stack: value.stack,
711
+ name: value.name
712
+ };
713
+ }
714
+ return value;
715
+ }
716
+ __name(errorReplacer, "errorReplacer");
717
+ function generateLogId() {
718
+ try {
719
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
720
+ return crypto.randomUUID();
721
+ }
722
+ } catch {
723
+ }
724
+ return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
725
+ }
726
+ __name(generateLogId, "generateLogId");
727
+ var lastLogInfo = null;
728
+ async function sendSelectedLog(logWithoutID) {
729
+ try {
730
+ const log = {
731
+ ...logWithoutID,
732
+ id: generateLogId()
733
+ };
734
+ const newParts = [];
735
+ for (let i = 0; i < log.args.length; i++) {
736
+ const item = log.args[i];
737
+ if (item instanceof Error) {
738
+ const newError = {
739
+ message: item.message,
740
+ stack: item.stack,
741
+ name: item.name
742
+ };
743
+ if (!log.meta.stacktrace) {
744
+ try {
745
+ const stacktrace = await import_stacktrace_js.default.fromError(item);
746
+ log.meta.stacktrace = mapStacktrace(stacktrace);
747
+ } catch (e) {
748
+ reportStacktraceParseError(e, "StackTrace.fromError");
749
+ }
750
+ }
751
+ newParts.push(newError.message, newError);
752
+ } else {
753
+ newParts.push(item);
754
+ }
755
+ }
756
+ log.args = newParts;
757
+ if (!log.meta.stacktrace) {
758
+ try {
759
+ const frames = await getStacktrace();
760
+ const firstFrameIndex = frames.findIndex((frame) => !frame.fileName.includes("client-toolkit-lite/dist/logger"));
761
+ log.meta.stacktrace = firstFrameIndex === -1 ? [] : frames.slice(firstFrameIndex);
762
+ } catch (e) {
763
+ reportStacktraceParseError(e, "getStacktrace");
764
+ }
765
+ }
766
+ if (log.meta.skipFrame === void 0) {
767
+ log.meta.skipFrame = 2;
768
+ }
769
+ const logJSON = JSON.stringify(log, errorReplacer);
770
+ const logForDedup = {
771
+ ...log
772
+ };
773
+ delete logForDedup.id;
774
+ const logContentForDedup = JSON.stringify(logForDedup, errorReplacer);
775
+ if (lastLogInfo && lastLogInfo.content === logContentForDedup) {
776
+ lastLogInfo.count++;
777
+ log.meta.isDuplicate = true;
778
+ log.meta.duplicateCount = lastLogInfo.count;
779
+ log.meta.duplicateOfId = lastLogInfo.id;
780
+ const updatedJSON = JSON.stringify(log, errorReplacer);
781
+ try {
782
+ batchLogInfo("info", updatedJSON);
783
+ } catch {
784
+ }
785
+ if (window.parent !== window) {
786
+ try {
787
+ submitPostMessage({
788
+ type: "SELECTED_LOG",
789
+ payload: updatedJSON
790
+ });
791
+ } catch {
792
+ }
793
+ }
794
+ return;
795
+ }
796
+ lastLogInfo = {
797
+ content: logContentForDedup,
798
+ id: log.id,
799
+ count: 1
800
+ };
801
+ try {
802
+ batchLogInfo("info", logJSON);
803
+ } catch {
804
+ }
805
+ if (window.parent !== window) {
806
+ try {
807
+ submitPostMessage({
808
+ type: "SELECTED_LOG",
809
+ payload: logJSON
810
+ });
811
+ } catch {
812
+ }
813
+ }
814
+ } catch {
815
+ }
816
+ }
817
+ __name(sendSelectedLog, "sendSelectedLog");
818
+ function sendTypedLogV2(logWithMeta) {
819
+ void sendSelectedLog({
820
+ type: "typedLogV2",
821
+ level: logWithMeta.level,
822
+ args: logWithMeta.args,
823
+ meta: logWithMeta.meta ?? {}
824
+ });
825
+ }
826
+ __name(sendTypedLogV2, "sendTypedLogV2");
827
+ var typedLogInterceptor = /* @__PURE__ */ __name((originLogger) => ({
828
+ debug: /* @__PURE__ */ __name((message, ...args) => {
829
+ try {
830
+ originLogger.debug(message, ...args);
831
+ } catch {
832
+ }
833
+ sendTypedLogV2({
834
+ level: "info",
835
+ args: [
836
+ message,
837
+ ...args
838
+ ],
839
+ meta: {}
840
+ });
841
+ }, "debug"),
842
+ info: /* @__PURE__ */ __name((message, ...args) => {
843
+ try {
844
+ originLogger.info(message, ...args);
845
+ } catch {
846
+ }
847
+ sendTypedLogV2({
848
+ level: "info",
849
+ args: [
850
+ message,
851
+ ...args
852
+ ],
853
+ meta: {}
854
+ });
855
+ }, "info"),
856
+ warn: /* @__PURE__ */ __name((message, ...args) => {
857
+ try {
858
+ originLogger.warn(message, ...args);
859
+ } catch {
860
+ }
861
+ sendTypedLogV2({
862
+ level: "warn",
863
+ args: [
864
+ message,
865
+ ...args
866
+ ],
867
+ meta: {}
868
+ });
869
+ }, "warn"),
870
+ error: /* @__PURE__ */ __name((message, ...args) => {
871
+ try {
872
+ originLogger.error(message, ...args);
873
+ } catch {
874
+ }
875
+ sendTypedLogV2({
876
+ level: "error",
877
+ args: [
878
+ message,
879
+ ...args
880
+ ],
881
+ meta: {}
882
+ });
883
+ }, "error"),
884
+ success: /* @__PURE__ */ __name((message, ...args) => {
885
+ try {
886
+ originLogger.success(message, ...args);
887
+ } catch {
888
+ }
889
+ sendTypedLogV2({
890
+ level: "success",
891
+ args: [
892
+ message,
893
+ ...args
894
+ ],
895
+ meta: {}
896
+ });
897
+ }, "success"),
898
+ log: /* @__PURE__ */ __name(({ level, args, meta }) => {
899
+ try {
900
+ originLogger.log({
901
+ level,
902
+ args,
903
+ meta
904
+ });
905
+ } catch {
906
+ }
907
+ sendTypedLogV2({
908
+ level,
909
+ args,
910
+ meta: meta ?? {}
911
+ });
912
+ }, "log")
913
+ }), "typedLogInterceptor");
914
+ var interceptors = [
915
+ typedLogInterceptor
916
+ ];
917
+
918
+ // src/logger/logger.ts
919
+ var shouldReportToObservable = process.env.NODE_ENV === "production";
920
+ var ORDERED_LEVELS = [
921
+ "debug",
922
+ "info",
923
+ "warn",
924
+ "error"
925
+ ];
926
+ var defaultConfig = {
927
+ showLevel: false,
928
+ showTimestamp: false,
929
+ level: "info",
930
+ prefix: ""
931
+ };
932
+ var config = {
933
+ ...defaultConfig
934
+ };
935
+ function configureLogger(options) {
936
+ config = {
937
+ ...defaultConfig,
938
+ ...options
939
+ };
940
+ }
941
+ __name(configureLogger, "configureLogger");
942
+ function shouldLog(level) {
943
+ return ORDERED_LEVELS.indexOf(level) >= ORDERED_LEVELS.indexOf(config.level);
944
+ }
945
+ __name(shouldLog, "shouldLog");
946
+ function getFormattedPrefix(level) {
947
+ const parts = [];
948
+ if (config.prefix) {
949
+ parts.push(`[${config.prefix}]`);
950
+ }
951
+ if (config.showLevel) {
952
+ parts.push(`[${level.toUpperCase()}]`);
953
+ }
954
+ return parts;
955
+ }
956
+ __name(getFormattedPrefix, "getFormattedPrefix");
957
+ configureLogger({
958
+ showLevel: true,
959
+ showTimestamp: false,
960
+ level: process.env.NODE_ENV === "development" ? "debug" : "error",
961
+ prefix: "MiaoDa"
962
+ });
963
+ var logger = {
964
+ debug(message, ...args) {
965
+ if (shouldLog("debug")) {
966
+ console.log(...getFormattedPrefix("debug"), message, ...args);
967
+ }
968
+ },
969
+ info(message, ...args) {
970
+ if (shouldLog("info")) {
971
+ console.log(...getFormattedPrefix("info"), message, ...args);
972
+ }
973
+ if (shouldReportToObservable) {
974
+ import_observable_web.observable.log("INFO", processLogParams([
975
+ message,
976
+ ...args
977
+ ]).join(" "));
978
+ }
979
+ },
980
+ warn(message, ...args) {
981
+ if (shouldLog("warn")) {
982
+ console.log(...getFormattedPrefix("warn"), message, ...args);
983
+ }
984
+ if (shouldReportToObservable) {
985
+ import_observable_web.observable.log("WARN", processLogParams([
986
+ message,
987
+ ...args
988
+ ]).join(" "));
989
+ }
990
+ },
991
+ error(message, ...args) {
992
+ if (shouldLog("error")) {
993
+ console.error(...getFormattedPrefix("error"), message, ...args);
994
+ }
995
+ if (shouldReportToObservable) {
996
+ import_observable_web.observable.log("ERROR", processLogParams([
997
+ message,
998
+ ...args
999
+ ]).join(" "));
1000
+ }
1001
+ },
1002
+ success(message, ...args) {
1003
+ if (shouldLog("info")) {
1004
+ console.log(...getFormattedPrefix("success"), message, ...args);
1005
+ }
1006
+ if (shouldReportToObservable) {
1007
+ import_observable_web.observable.log("INFO", processLogParams([
1008
+ message,
1009
+ ...args
1010
+ ]).join(" "));
1011
+ }
1012
+ },
1013
+ log({ level, args }) {
1014
+ if (shouldLog(level)) {
1015
+ console.log(...getFormattedPrefix(level), ...args);
1016
+ }
1017
+ if (shouldReportToObservable && level !== "debug") {
1018
+ import_observable_web.observable.log(mapLogLevel(level), processLogParams(args).join(" "));
1019
+ }
1020
+ }
1021
+ };
1022
+ if (process.env.NODE_ENV !== "production") {
1023
+ window.__RUNTIME_LOGGER__ = {
1024
+ get() {
1025
+ return logger;
1026
+ }
1027
+ };
1028
+ }
1029
+ for (const interceptor of interceptors) {
1030
+ logger = interceptor(logger);
1031
+ }
1032
+ if (process.env.NODE_ENV !== "production") {
1033
+ interceptErrors();
1034
+ }
1035
+
1036
+ // src/runtime/iframe-bridge.ts
1037
+ var import_penpal = require("penpal");
1038
+
1039
+ // src/utils/utils.ts
1040
+ var import_clsx = require("clsx");
1041
+ var import_tailwind_merge = require("tailwind-merge");
1042
+ function clsxWithTw(...inputs) {
1043
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
1044
+ }
1045
+ __name(clsxWithTw, "clsxWithTw");
1046
+ function isPreview() {
1047
+ return window.IS_MIAODA_PREVIEW;
1048
+ }
1049
+ __name(isPreview, "isPreview");
1050
+ function normalizeBasePath(basePath) {
1051
+ if (!basePath || basePath === "/") {
1052
+ return "";
1053
+ }
1054
+ return basePath.replace(/\/+$/, "");
1055
+ }
1056
+ __name(normalizeBasePath, "normalizeBasePath");
1057
+ function getWsPath() {
1058
+ const rawBasePath = process.env.CLIENT_BASE_PATH || "/";
1059
+ const normalizedBasePath = rawBasePath.startsWith("/") ? rawBasePath : `/${rawBasePath}`;
1060
+ const basePathWithoutTrailingSlash = normalizedBasePath.endsWith("/") ? normalizedBasePath.slice(0, -1) : normalizedBasePath;
1061
+ return `${basePathWithoutTrailingSlash}/ws`;
1062
+ }
1063
+ __name(getWsPath, "getWsPath");
1064
+ function isSparkRuntime() {
1065
+ return window._IS_Spark_RUNTIME ?? process.env.runtimeMode === "fullstack";
1066
+ }
1067
+ __name(isSparkRuntime, "isSparkRuntime");
1068
+
1069
+ // src/components/AppContainer/utils/childApi.ts
1070
+ async function getRoutes() {
1071
+ let routes = [
1072
+ {
1073
+ path: "/"
1074
+ }
1075
+ ];
1076
+ try {
1077
+ const basePath = normalizeBasePath(process.env.CLIENT_BASE_PATH);
1078
+ const res = await fetch(`${basePath}/routes.json`);
1079
+ routes = await res.json();
1080
+ } catch (error) {
1081
+ console.warn("get routes.json error", error);
1082
+ }
1083
+ return routes;
1084
+ }
1085
+ __name(getRoutes, "getRoutes");
1086
+ var childApi = {
1087
+ getRoutes,
1088
+ updateAppInfo: /* @__PURE__ */ __name((appInfo) => {
1089
+ dispatchEvent(new CustomEvent("MiaoDaMetaInfoChanged", {
1090
+ detail: appInfo
1091
+ }));
1092
+ }, "updateAppInfo")
1093
+ };
1094
+
1095
+ // src/runtime/iframe-bridge.ts
1096
+ async function connectParent() {
1097
+ submitPostMessage({
1098
+ type: "PreviewReady",
1099
+ data: {}
1100
+ });
1101
+ batchLogInfo("info", JSON.stringify({
1102
+ type: "PreviewReady",
1103
+ timestamp: Date.now(),
1104
+ url: window.location.href
1105
+ }));
1106
+ const parentOrigin = resolveParentOrigin();
1107
+ if (!parentOrigin) return;
1108
+ const connection = (0, import_penpal.connectToParent)({
1109
+ parentOrigin,
1110
+ methods: {
1111
+ ...childApi
1112
+ }
145
1113
  });
1114
+ await connection.promise;
146
1115
  }
147
- __name(initAxiosConfig, "initAxiosConfig");
1116
+ __name(connectParent, "connectParent");
1117
+ function initIframeBridge() {
1118
+ if (window.parent === window) return;
1119
+ connectParent();
1120
+ }
1121
+ __name(initIframeBridge, "initIframeBridge");
148
1122
 
149
1123
  // src/runtime/index.ts
150
1124
  if (!window.__FULLSTACK_RUNTIME_INITIALIZED__) {
151
1125
  window.__FULLSTACK_RUNTIME_INITIALIZED__ = true;
152
1126
  initAxiosConfig();
1127
+ if (process.env.NODE_ENV !== "production") {
1128
+ initIframeBridge();
1129
+ }
153
1130
  }
154
1131
 
155
1132
  // src/components/AppContainer/safety.tsx
@@ -224,36 +1201,6 @@ function getInitialInfo(refresh = false) {
224
1201
  }
225
1202
  __name(getInitialInfo, "getInitialInfo");
226
1203
 
227
- // src/utils/utils.ts
228
- var import_clsx = require("clsx");
229
- var import_tailwind_merge = require("tailwind-merge");
230
- function clsxWithTw(...inputs) {
231
- return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
232
- }
233
- __name(clsxWithTw, "clsxWithTw");
234
- function isPreview() {
235
- return window.IS_MIAODA_PREVIEW;
236
- }
237
- __name(isPreview, "isPreview");
238
- function normalizeBasePath(basePath) {
239
- if (!basePath || basePath === "/") {
240
- return "";
241
- }
242
- return basePath.replace(/\/+$/, "");
243
- }
244
- __name(normalizeBasePath, "normalizeBasePath");
245
- function getWsPath() {
246
- const rawBasePath = process.env.CLIENT_BASE_PATH || "/";
247
- const normalizedBasePath = rawBasePath.startsWith("/") ? rawBasePath : `/${rawBasePath}`;
248
- const basePathWithoutTrailingSlash = normalizedBasePath.endsWith("/") ? normalizedBasePath.slice(0, -1) : normalizedBasePath;
249
- return `${basePathWithoutTrailingSlash}/ws`;
250
- }
251
- __name(getWsPath, "getWsPath");
252
- function isSparkRuntime() {
253
- return window._IS_Spark_RUNTIME ?? process.env.runtimeMode === "fullstack";
254
- }
255
- __name(isSparkRuntime, "isSparkRuntime");
256
-
257
1204
  // src/integrations/getAppInfo.ts
258
1205
  async function getAppInfo(refresh = false) {
259
1206
  let appInfo = typeof window !== "undefined" ? window._appInfo : void 0;
@@ -340,7 +1287,6 @@ var useAppInfo = /* @__PURE__ */ __name(() => {
340
1287
 
341
1288
  // src/hooks/useCurrentUserProfile.tsx
342
1289
  var import_react2 = require("react");
343
- var import_auth_sdk = require("@lark-apaas/auth-sdk");
344
1290
 
345
1291
  // src/integrations/getCurrentUserProfile.ts
346
1292
  function getCurrentUserProfile() {
@@ -348,6 +1294,69 @@ function getCurrentUserProfile() {
348
1294
  }
349
1295
  __name(getCurrentUserProfile, "getCurrentUserProfile");
350
1296
 
1297
+ // src/utils/url.ts
1298
+ function splitWorkspaceUrl(fullUrl) {
1299
+ try {
1300
+ const url = new URL(fullUrl);
1301
+ const pathParts = url.pathname.split("/");
1302
+ const workspacesIndex = pathParts.findIndex((part) => part === "workspaces");
1303
+ if (workspacesIndex === -1) {
1304
+ throw new Error("Invalid workspace URL format");
1305
+ }
1306
+ const basePathParts = pathParts.slice(0, workspacesIndex);
1307
+ const workspace = pathParts[workspacesIndex + 1];
1308
+ return {
1309
+ baseUrl: `${url.origin}${basePathParts.join("/")}`,
1310
+ workspace
1311
+ };
1312
+ } catch (error) {
1313
+ console.error("Error splitting workspace URL:", error);
1314
+ }
1315
+ return {
1316
+ baseUrl: fullUrl,
1317
+ // 兜底给一个,不要给空字符串,不然 createClient 都直接挂了,页面会白屏,体感不太好
1318
+ workspace: "workspace"
1319
+ };
1320
+ }
1321
+ __name(splitWorkspaceUrl, "splitWorkspaceUrl");
1322
+
1323
+ // src/integrations/dataloom.ts
1324
+ var import_dataloom = require("@lark-apaas/dataloom");
1325
+ var createDataLoomClient = /* @__PURE__ */ __name((url, pat) => {
1326
+ const { baseUrl } = url ? splitWorkspaceUrl(url) : {
1327
+ baseUrl: ""
1328
+ };
1329
+ const appId = getAppId() ?? "";
1330
+ return (0, import_dataloom.createClient)(baseUrl, pat ?? "", {
1331
+ global: {
1332
+ enableDataloomLog: process.env.NODE_ENV !== "production",
1333
+ requestRateLimit: process.env.NODE_ENV !== "production" ? 100 : void 0,
1334
+ brandName: "miaoda",
1335
+ appId
1336
+ }
1337
+ });
1338
+ }, "createDataLoomClient");
1339
+ var dataloom = null;
1340
+ var pendingPromise2 = null;
1341
+ function getDataloom() {
1342
+ if (dataloom) {
1343
+ return Promise.resolve(dataloom);
1344
+ }
1345
+ if (pendingPromise2) {
1346
+ return pendingPromise2;
1347
+ }
1348
+ pendingPromise2 = getInitialInfo().then((info) => {
1349
+ const DATALOOM_CLIENT_URL = info?.app_runtime_extra?.url;
1350
+ const DATALOOM_PAT = info?.app_runtime_extra?.token;
1351
+ dataloom = createDataLoomClient(DATALOOM_CLIENT_URL, DATALOOM_PAT);
1352
+ return dataloom;
1353
+ }).finally(() => {
1354
+ pendingPromise2 = null;
1355
+ });
1356
+ return pendingPromise2;
1357
+ }
1358
+ __name(getDataloom, "getDataloom");
1359
+
351
1360
  // src/hooks/useCurrentUserProfile.tsx
352
1361
  function getNameFromArray(nameArray) {
353
1362
  if (!nameArray || nameArray.length === 0) {
@@ -372,7 +1381,8 @@ var useCurrentUserProfile = /* @__PURE__ */ __name(() => {
372
1381
  (0, import_react2.useEffect)(() => {
373
1382
  let cancelled = false;
374
1383
  const fetchAndSetUserInfo = /* @__PURE__ */ __name(async () => {
375
- const result = await import_auth_sdk.authClient.session.getUserInfo();
1384
+ const dataloom2 = await getDataloom();
1385
+ const result = await dataloom2?.service?.session?.getUserInfo();
376
1386
  if (cancelled) return;
377
1387
  const info = result?.data?.user_info;
378
1388
  const userName = getNameFromArray(info?.name);
@@ -436,7 +1446,6 @@ __name(useIsMobile, "useIsMobile");
436
1446
 
437
1447
  // src/hooks/useLogout.ts
438
1448
  var import_react4 = require("react");
439
- var import_auth_sdk2 = require("@lark-apaas/auth-sdk");
440
1449
  function useLogout() {
441
1450
  const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
442
1451
  async function handlerLogout() {
@@ -446,7 +1455,8 @@ function useLogout() {
446
1455
  }
447
1456
  setIsLoading(true);
448
1457
  try {
449
- await import_auth_sdk2.authClient.session.signOut();
1458
+ const dataloom2 = await getDataloom();
1459
+ await dataloom2.service.session.signOut();
450
1460
  } catch (error) {
451
1461
  console.error("\u767B\u51FA\u5931\u8D25", error);
452
1462
  } finally {
@@ -879,6 +1889,7 @@ var Safety = /* @__PURE__ */ __name(() => {
879
1889
  isMobile2
880
1890
  ]);
881
1891
  if (process.env.NODE_ENV !== "production") return null;
1892
+ if (String(process.env.MIAODA_APP_TYPE) === "7") return null;
882
1893
  if (!badgeLoaded) return null;
883
1894
  if (!showBadge) return null;
884
1895
  if (!visible) return null;
@@ -1073,6 +2084,92 @@ var QueryProvider = /* @__PURE__ */ __name(({ children, client }) => {
1073
2084
  }, "QueryProvider");
1074
2085
  var QueryProvider_default = QueryProvider;
1075
2086
 
2087
+ // src/components/AppContainer/IframeBridge.tsx
2088
+ var import_react8 = require("react");
2089
+ var import_react_router_dom = require("react-router-dom");
2090
+
2091
+ // src/hooks/useUpdatingRef.ts
2092
+ var import_react7 = require("react");
2093
+ function useUpdatingRef(value) {
2094
+ const ref = (0, import_react7.useRef)(value);
2095
+ ref.current = value;
2096
+ return ref;
2097
+ }
2098
+ __name(useUpdatingRef, "useUpdatingRef");
2099
+
2100
+ // src/components/AppContainer/IframeBridge.tsx
2101
+ var RouteMessageType = /* @__PURE__ */ (function(RouteMessageType2) {
2102
+ RouteMessageType2["RouteChange"] = "RouteChange";
2103
+ RouteMessageType2["RouteBack"] = "RouteBack";
2104
+ RouteMessageType2["RouteForward"] = "RouteForward";
2105
+ return RouteMessageType2;
2106
+ })(RouteMessageType || {});
2107
+ function isRouteMessageType(type) {
2108
+ return Object.values(RouteMessageType).includes(type);
2109
+ }
2110
+ __name(isRouteMessageType, "isRouteMessageType");
2111
+ function IframeBridge() {
2112
+ const location = (0, import_react_router_dom.useLocation)();
2113
+ const navigate = (0, import_react_router_dom.useNavigate)();
2114
+ const navigateRef = useUpdatingRef(navigate);
2115
+ const isActive = (0, import_react8.useRef)(false);
2116
+ const historyBack = (0, import_react8.useCallback)((_payload) => {
2117
+ navigateRef.current(-1);
2118
+ isActive.current = true;
2119
+ }, [
2120
+ navigateRef
2121
+ ]);
2122
+ const historyForward = (0, import_react8.useCallback)((_payload) => {
2123
+ navigateRef.current(1);
2124
+ isActive.current = true;
2125
+ }, [
2126
+ navigateRef
2127
+ ]);
2128
+ const operatorMessage = (0, import_react8.useMemo)(() => ({
2129
+ ["RouteBack"]: historyBack,
2130
+ ["RouteForward"]: historyForward,
2131
+ ["RouteChange"]: navigateRef.current
2132
+ }), [
2133
+ historyBack,
2134
+ historyForward,
2135
+ navigateRef
2136
+ ]);
2137
+ (0, import_react8.useEffect)(() => {
2138
+ if (isActive.current) {
2139
+ isActive.current = false;
2140
+ return;
2141
+ }
2142
+ submitPostMessage({
2143
+ type: "ChildLocationChange",
2144
+ data: location
2145
+ });
2146
+ }, [
2147
+ location
2148
+ ]);
2149
+ const handleMessage = (0, import_react8.useCallback)((event) => {
2150
+ const data = event.data ?? {};
2151
+ if (typeof data.type === "string" && isRouteMessageType(data.type)) {
2152
+ operatorMessage[data.type](data.data);
2153
+ }
2154
+ }, [
2155
+ operatorMessage
2156
+ ]);
2157
+ (0, import_react8.useEffect)(() => {
2158
+ window.addEventListener("message", handleMessage);
2159
+ return () => {
2160
+ window.removeEventListener("message", handleMessage);
2161
+ };
2162
+ }, [
2163
+ handleMessage
2164
+ ]);
2165
+ return /* @__PURE__ */ (0, import_react8.createElement)("div", {
2166
+ style: {
2167
+ display: "none"
2168
+ }
2169
+ });
2170
+ }
2171
+ __name(IframeBridge, "IframeBridge");
2172
+
1076
2173
  // src/components/AppContainer/utils/tea.ts
1077
2174
  var import_blueimp_md5 = __toESM(require("blueimp-md5"), 1);
1078
2175
  var import_sha1 = __toESM(require("crypto-js/sha1"), 1);
@@ -1184,6 +2281,31 @@ var reportTeaEvent = /* @__PURE__ */ __name(async ({ trackKey, trackParams = {}
1184
2281
  }
1185
2282
  }, "reportTeaEvent");
1186
2283
 
2284
+ // src/components/AppContainer/utils/observable.ts
2285
+ var import_observable_web2 = require("@lark-apaas/observable-web");
2286
+ var initObservable = /* @__PURE__ */ __name(() => {
2287
+ try {
2288
+ const appId = window.appId;
2289
+ import_observable_web2.observable.start({
2290
+ serviceName: "app",
2291
+ env: process.env.NODE_ENV === "development" ? import_observable_web2.AppEnv.Dev : import_observable_web2.AppEnv.Prod,
2292
+ collectorUrl: isNewPathEnabled() ? {
2293
+ log: `/app/${appId}/__runtime__/api/v1/observability/logs/collect`,
2294
+ trace: `/app/${appId}/__runtime__/api/v1/observability/traces/collect`,
2295
+ metric: `/app/${appId}/__runtime__/api/v1/observability/metrics/collect`,
2296
+ time: `/app/${appId}/__runtime__/api/v1/observability/current_server_timestamp`
2297
+ } : {
2298
+ log: `/spark/app/${appId}/runtime/api/v1/observability/logs/collect`,
2299
+ trace: `/spark/app/${appId}/runtime/api/v1/observability/traces/collect`,
2300
+ metric: `/spark/app/${appId}/runtime/api/v1/observability/metrics/collect`,
2301
+ time: `/spark/api/v1/observability/app/${appId}/current_server_timestamp`
2302
+ }
2303
+ });
2304
+ } catch (error) {
2305
+ console.error("Failed to start WebObservableSdk:", error);
2306
+ }
2307
+ }, "initObservable");
2308
+
1187
2309
  // src/types/tea.ts
1188
2310
  var TrackKey = /* @__PURE__ */ (function(TrackKey2) {
1189
2311
  TrackKey2["VIEW"] = "aily_agent_artifact_page_view";
@@ -1193,7 +2315,10 @@ var TrackKey = /* @__PURE__ */ (function(TrackKey2) {
1193
2315
  // src/components/AppContainer/index.tsx
1194
2316
  var AppContainer = /* @__PURE__ */ __name(({ children }) => {
1195
2317
  useAppInfo();
1196
- (0, import_react7.useEffect)(() => {
2318
+ (0, import_react9.useEffect)(() => {
2319
+ initObservable();
2320
+ }, []);
2321
+ (0, import_react9.useEffect)(() => {
1197
2322
  if (process.env.NODE_ENV === "production") {
1198
2323
  reportTeaEvent({
1199
2324
  trackKey: TrackKey.VIEW,
@@ -1205,14 +2330,14 @@ var AppContainer = /* @__PURE__ */ __name(({ children }) => {
1205
2330
  });
1206
2331
  }
1207
2332
  }, []);
1208
- return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.createElement(safety_default, null), /* @__PURE__ */ import_react7.default.createElement(QueryProvider_default, null, children));
2333
+ return /* @__PURE__ */ import_react9.default.createElement(import_react9.default.Fragment, null, /* @__PURE__ */ import_react9.default.createElement(safety_default, null), process.env.NODE_ENV !== "production" && /* @__PURE__ */ import_react9.default.createElement(import_miaoda_inspector.MiaodaInspector, null), process.env.NODE_ENV !== "production" && /* @__PURE__ */ import_react9.default.createElement(IframeBridge, null), /* @__PURE__ */ import_react9.default.createElement(QueryProvider_default, null, children));
1209
2334
  }, "AppContainer");
1210
2335
  var AppContainer_default = AppContainer;
1211
2336
 
1212
2337
  // src/components/Welcome/index.tsx
1213
- var import_react8 = __toESM(require("react"), 1);
2338
+ var import_react10 = __toESM(require("react"), 1);
1214
2339
  var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1", description = "\u9875\u9762\u6682\u672A\u5F00\u53D1\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85..." }) => {
1215
- return /* @__PURE__ */ import_react8.default.createElement("div", {
2340
+ return /* @__PURE__ */ import_react10.default.createElement("div", {
1216
2341
  style: {
1217
2342
  display: "flex",
1218
2343
  flexDirection: "column",
@@ -1223,7 +2348,7 @@ var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1"
1223
2348
  padding: "0 24px",
1224
2349
  textAlign: "center"
1225
2350
  }
1226
- }, /* @__PURE__ */ import_react8.default.createElement("img", {
2351
+ }, /* @__PURE__ */ import_react10.default.createElement("img", {
1227
2352
  style: {
1228
2353
  borderRadius: 6,
1229
2354
  marginBottom: 24
@@ -1232,7 +2357,7 @@ var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1"
1232
2357
  height: "200",
1233
2358
  src: "https://lf3-static.bytednsdoc.com/obj/eden-cn/LMfspH/ljhwZthlaukjlkulzlp/miao/welcome.svg",
1234
2359
  alt: "Welcome"
1235
- }), /* @__PURE__ */ import_react8.default.createElement("div", {
2360
+ }), /* @__PURE__ */ import_react10.default.createElement("div", {
1236
2361
  style: {
1237
2362
  fontSize: 16,
1238
2363
  fontWeight: 500,
@@ -1240,7 +2365,7 @@ var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1"
1240
2365
  marginBottom: 4,
1241
2366
  color: "#1f2329"
1242
2367
  }
1243
- }, title), /* @__PURE__ */ import_react8.default.createElement("div", {
2368
+ }, title), /* @__PURE__ */ import_react10.default.createElement("div", {
1244
2369
  style: {
1245
2370
  fontSize: 16,
1246
2371
  lineHeight: "24px",
@@ -1252,9 +2377,9 @@ var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1"
1252
2377
  var Welcome_default = Welcome;
1253
2378
 
1254
2379
  // src/components/PagePlaceholder/index.tsx
1255
- var import_react9 = __toESM(require("react"), 1);
2380
+ var import_react11 = __toESM(require("react"), 1);
1256
2381
  var PagePlaceholder = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1", description = "\u9875\u9762\u6682\u672A\u5F00\u53D1\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85..." }) => {
1257
- return /* @__PURE__ */ import_react9.default.createElement("div", {
2382
+ return /* @__PURE__ */ import_react11.default.createElement("div", {
1258
2383
  style: {
1259
2384
  display: "flex",
1260
2385
  flexDirection: "column",
@@ -1265,7 +2390,7 @@ var PagePlaceholder = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F0
1265
2390
  height: "calc(100vh - 64px)",
1266
2391
  textAlign: "center"
1267
2392
  }
1268
- }, /* @__PURE__ */ import_react9.default.createElement("img", {
2393
+ }, /* @__PURE__ */ import_react11.default.createElement("img", {
1269
2394
  style: {
1270
2395
  borderRadius: "6px",
1271
2396
  marginBottom: "24px"
@@ -1274,14 +2399,14 @@ var PagePlaceholder = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F0
1274
2399
  height: "200",
1275
2400
  src: "https://lf3-static.bytednsdoc.com/obj/eden-cn/LMfspH/ljhwZthlaukjlkulzlp/miao/welcome.svg",
1276
2401
  alt: "Welcome"
1277
- }), /* @__PURE__ */ import_react9.default.createElement("div", {
2402
+ }), /* @__PURE__ */ import_react11.default.createElement("div", {
1278
2403
  style: {
1279
2404
  fontSize: "16px",
1280
2405
  fontWeight: 500,
1281
2406
  marginBottom: "4px",
1282
2407
  lineHeight: "24px"
1283
2408
  }
1284
- }, title), /* @__PURE__ */ import_react9.default.createElement("div", {
2409
+ }, title), /* @__PURE__ */ import_react11.default.createElement("div", {
1285
2410
  style: {
1286
2411
  color: "#6b7280",
1287
2412
  fontSize: "16px",
@@ -1296,13 +2421,67 @@ var PagePlaceholder = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F0
1296
2421
  }, "PagePlaceholder");
1297
2422
  var PagePlaceholder_default = PagePlaceholder;
1298
2423
 
2424
+ // src/components/ErrorRender/index.tsx
2425
+ var import_react12 = __toESM(require("react"), 1);
2426
+ var ErrorRender = /* @__PURE__ */ __name((props) => {
2427
+ const { error, resetErrorBoundary } = props;
2428
+ (0, import_react12.useEffect)(() => {
2429
+ if (error) {
2430
+ submitPostMessage({
2431
+ type: "RenderError",
2432
+ data: error
2433
+ });
2434
+ logger.log({
2435
+ level: "error",
2436
+ args: [
2437
+ "Render Error",
2438
+ error
2439
+ ],
2440
+ meta: {
2441
+ type: "render-error",
2442
+ repairMessage: "\u9875\u9762\u6E32\u67D3\u65F6\u62A5\u9519\uFF0C\u8BF7\u6839\u636E\u9519\u8BEF\u4FE1\u606F\u4FEE\u590D\u5BF9\u5E94\u9875\u9762\u7684\u4EE3\u7801"
2443
+ }
2444
+ });
2445
+ }
2446
+ }, [
2447
+ error
2448
+ ]);
2449
+ (0, import_react12.useEffect)(() => {
2450
+ if (!resetErrorBoundary) return;
2451
+ const hmr = getHmrApi();
2452
+ if (!hmr) return;
2453
+ return hmr.onSuccess(() => {
2454
+ const isVite = typeof window !== "undefined" && Boolean(window.__VITE_HMR__);
2455
+ if (isVite) {
2456
+ window.location.reload();
2457
+ } else {
2458
+ resetErrorBoundary();
2459
+ }
2460
+ });
2461
+ }, [
2462
+ resetErrorBoundary
2463
+ ]);
2464
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
2465
+ className: "min-h-screen flex items-center justify-center bg-white"
2466
+ }, /* @__PURE__ */ import_react12.default.createElement("div", {
2467
+ className: "flex flex-col justify-center items-center text-center"
2468
+ }, /* @__PURE__ */ import_react12.default.createElement("img", {
2469
+ src: "https://lf3-static.bytednsdoc.com/obj/eden-cn/ylcylz_fsph_ryhs/ljhwZthlaukjlkulzlp/feisuda/template/illustration_empty_negative_error.svg",
2470
+ alt: "render error",
2471
+ className: "mb-3 w-[100px]"
2472
+ }), /* @__PURE__ */ import_react12.default.createElement("p", {
2473
+ className: "text-l/[22px] text-[14px] text-[#1F2329] font-medium"
2474
+ }, "\u9875\u9762\u51FA\u9519\u4E86")));
2475
+ }, "ErrorRender");
2476
+ var ErrorRender_default = ErrorRender;
2477
+
1299
2478
  // src/route-components/ActiveLink.tsx
1300
- var import_react10 = __toESM(require("react"), 1);
1301
- var import_react_router_dom = require("react-router-dom");
1302
- var ActiveLink = /* @__PURE__ */ (0, import_react10.forwardRef)(({ to, onClick, className, style, children, ...rest }, ref) => {
1303
- const [currentHash, setCurrentHash] = (0, import_react10.useState)(() => typeof window !== "undefined" ? window.location.hash : "");
2479
+ var import_react13 = __toESM(require("react"), 1);
2480
+ var import_react_router_dom2 = require("react-router-dom");
2481
+ var ActiveLink = /* @__PURE__ */ (0, import_react13.forwardRef)(({ to, onClick, className, style, children, ...rest }, ref) => {
2482
+ const [currentHash, setCurrentHash] = (0, import_react13.useState)(() => typeof window !== "undefined" ? window.location.hash : "");
1304
2483
  const isHashRoute = typeof to === "string" && to.startsWith("#");
1305
- (0, import_react10.useEffect)(() => {
2484
+ (0, import_react13.useEffect)(() => {
1306
2485
  if (!isHashRoute) return;
1307
2486
  const handleHashChange = /* @__PURE__ */ __name(() => {
1308
2487
  setCurrentHash(window.location.hash);
@@ -1314,7 +2493,7 @@ var ActiveLink = /* @__PURE__ */ (0, import_react10.forwardRef)(({ to, onClick,
1314
2493
  ]);
1315
2494
  const isActive = isHashRoute && currentHash === to;
1316
2495
  if (!isHashRoute) {
1317
- return /* @__PURE__ */ import_react10.default.createElement(import_react_router_dom.NavLink, {
2496
+ return /* @__PURE__ */ import_react13.default.createElement(import_react_router_dom2.NavLink, {
1318
2497
  ref,
1319
2498
  to,
1320
2499
  onClick,
@@ -1355,7 +2534,7 @@ var ActiveLink = /* @__PURE__ */ (0, import_react10.forwardRef)(({ to, onClick,
1355
2534
  isPending: false,
1356
2535
  isTransitioning: false
1357
2536
  }) : children;
1358
- return /* @__PURE__ */ import_react10.default.createElement("a", {
2537
+ return /* @__PURE__ */ import_react13.default.createElement("a", {
1359
2538
  ref,
1360
2539
  href: to,
1361
2540
  onClick: handleHashClick,
@@ -1367,12 +2546,12 @@ var ActiveLink = /* @__PURE__ */ (0, import_react10.forwardRef)(({ to, onClick,
1367
2546
  ActiveLink.displayName = "ActiveLink";
1368
2547
 
1369
2548
  // src/route-components/NavLink.tsx
1370
- var React8 = __toESM(require("react"), 1);
1371
- var import_react_router_dom2 = require("react-router-dom");
1372
- var NavLink2 = /* @__PURE__ */ React8.forwardRef(({ to, children, className, style, ...props }, ref) => {
2549
+ var React9 = __toESM(require("react"), 1);
2550
+ var import_react_router_dom3 = require("react-router-dom");
2551
+ var NavLink2 = /* @__PURE__ */ React9.forwardRef(({ to, children, className, style, ...props }, ref) => {
1373
2552
  const isHashLink = typeof to === "string" && to.startsWith("#");
1374
- const location = (0, import_react_router_dom2.useLocation)();
1375
- const navigate = (0, import_react_router_dom2.useNavigate)();
2553
+ const location = (0, import_react_router_dom3.useLocation)();
2554
+ const navigate = (0, import_react_router_dom3.useNavigate)();
1376
2555
  if (isHashLink) {
1377
2556
  const handleClick = /* @__PURE__ */ __name((e) => {
1378
2557
  e.preventDefault();
@@ -1393,7 +2572,7 @@ var NavLink2 = /* @__PURE__ */ React8.forwardRef(({ to, children, className, sty
1393
2572
  const resolvedClassName = typeof className === "function" ? className(renderProps) : className;
1394
2573
  const resolvedStyle = typeof style === "function" ? style(renderProps) : style;
1395
2574
  const { caseSensitive, end, replace, state, preventScrollReset, relative, viewTransition, ...restProps } = props;
1396
- return /* @__PURE__ */ React8.createElement("a", {
2575
+ return /* @__PURE__ */ React9.createElement("a", {
1397
2576
  href: to,
1398
2577
  onClick: handleClick,
1399
2578
  ref,
@@ -1402,7 +2581,7 @@ var NavLink2 = /* @__PURE__ */ React8.forwardRef(({ to, children, className, sty
1402
2581
  ...restProps
1403
2582
  }, typeof children === "function" ? children(renderProps) : children);
1404
2583
  }
1405
- return /* @__PURE__ */ React8.createElement(import_react_router_dom2.NavLink, {
2584
+ return /* @__PURE__ */ React9.createElement(import_react_router_dom3.NavLink, {
1406
2585
  to,
1407
2586
  ref,
1408
2587
  className,
@@ -1417,8 +2596,8 @@ var NavLink2 = /* @__PURE__ */ React8.forwardRef(({ to, children, className, sty
1417
2596
  NavLink2.displayName = "NavLink";
1418
2597
 
1419
2598
  // src/route-components/UniversalLink.tsx
1420
- var import_react11 = __toESM(require("react"), 1);
1421
- var import_react_router_dom3 = require("react-router-dom");
2599
+ var import_react14 = __toESM(require("react"), 1);
2600
+ var import_react_router_dom4 = require("react-router-dom");
1422
2601
  function isInternalRoute(to) {
1423
2602
  return !to.startsWith("#") && !to.startsWith("http://") && !to.startsWith("https://") && !to.startsWith("//");
1424
2603
  }
@@ -1427,15 +2606,15 @@ function isExternalLink(to) {
1427
2606
  return to.startsWith("http://") || to.startsWith("https://") || to.startsWith("//");
1428
2607
  }
1429
2608
  __name(isExternalLink, "isExternalLink");
1430
- var UniversalLink = /* @__PURE__ */ import_react11.default.forwardRef(/* @__PURE__ */ __name(function UniversalLink2({ to, ...props }, ref) {
2609
+ var UniversalLink = /* @__PURE__ */ import_react14.default.forwardRef(/* @__PURE__ */ __name(function UniversalLink2({ to, ...props }, ref) {
1431
2610
  if (isInternalRoute(to)) {
1432
- return /* @__PURE__ */ import_react11.default.createElement(import_react_router_dom3.Link, {
2611
+ return /* @__PURE__ */ import_react14.default.createElement(import_react_router_dom4.Link, {
1433
2612
  to,
1434
2613
  ref,
1435
2614
  ...props
1436
2615
  });
1437
2616
  }
1438
- return /* @__PURE__ */ import_react11.default.createElement("a", {
2617
+ return /* @__PURE__ */ import_react14.default.createElement("a", {
1439
2618
  href: to,
1440
2619
  ref,
1441
2620
  ...props,
@@ -1581,45 +2760,6 @@ function getEnvPath() {
1581
2760
  }
1582
2761
  __name(getEnvPath, "getEnvPath");
1583
2762
 
1584
- // src/utils/safeStringify.ts
1585
- function safeStringify(obj) {
1586
- const seen = /* @__PURE__ */ new Set();
1587
- try {
1588
- return JSON.stringify(obj, (_key, value) => {
1589
- if (typeof value === "object" && value !== null) {
1590
- if (seen.has(value)) {
1591
- return "[Circular]";
1592
- }
1593
- seen.add(value);
1594
- }
1595
- if (typeof value === "bigint") {
1596
- return value.toString();
1597
- }
1598
- if (value instanceof Date) {
1599
- return value.toISOString();
1600
- }
1601
- if (value instanceof Map) {
1602
- return Object.fromEntries(value);
1603
- }
1604
- if (value instanceof Set) {
1605
- return Array.from(value);
1606
- }
1607
- if (typeof value === "undefined") {
1608
- return "undefined";
1609
- }
1610
- if (typeof value === "symbol") {
1611
- return value.toString();
1612
- }
1613
- return value;
1614
- });
1615
- } catch {
1616
- return "";
1617
- } finally {
1618
- seen.clear();
1619
- }
1620
- }
1621
- __name(safeStringify, "safeStringify");
1622
-
1623
2763
  // src/utils/getAxiosForBackend.ts
1624
2764
  var import_axios2 = __toESM(require("axios"), 1);
1625
2765
  var axiosInstance;
@@ -1699,73 +2839,26 @@ function getAxiosForBackend() {
1699
2839
  __name(getAxiosForBackend, "getAxiosForBackend");
1700
2840
  var axiosForBackend = getAxiosForBackend();
1701
2841
 
1702
- // src/utils/url.ts
1703
- function splitWorkspaceUrl(fullUrl) {
1704
- try {
1705
- const url = new URL(fullUrl);
1706
- const pathParts = url.pathname.split("/");
1707
- const workspacesIndex = pathParts.findIndex((part) => part === "workspaces");
1708
- if (workspacesIndex === -1) {
1709
- throw new Error("Invalid workspace URL format");
1710
- }
1711
- const basePathParts = pathParts.slice(0, workspacesIndex);
1712
- const workspace = pathParts[workspacesIndex + 1];
1713
- return {
1714
- baseUrl: `${url.origin}${basePathParts.join("/")}`,
1715
- workspace
1716
- };
1717
- } catch (error) {
1718
- console.error("Error splitting workspace URL:", error);
1719
- }
1720
- return {
1721
- baseUrl: fullUrl,
1722
- // 兜底给一个,不要给空字符串,不然 createClient 都直接挂了,页面会白屏,体感不太好
1723
- workspace: "workspace"
1724
- };
1725
- }
1726
- __name(splitWorkspaceUrl, "splitWorkspaceUrl");
1727
-
1728
- // src/integrations/dataloom.ts
1729
- var import_dataloom = require("@lark-apaas/dataloom");
1730
- var import_auth_sdk3 = require("@lark-apaas/auth-sdk");
1731
- var createDataLoomClient = /* @__PURE__ */ __name((url, pat) => {
1732
- const { baseUrl } = url ? splitWorkspaceUrl(url) : {
1733
- baseUrl: ""
1734
- };
1735
- const appId = getAppId() ?? "";
1736
- return (0, import_dataloom.createClient)(baseUrl, pat ?? "", {
1737
- global: {
1738
- enableDataloomLog: process.env.NODE_ENV !== "production",
1739
- requestRateLimit: process.env.NODE_ENV !== "production" ? 100 : void 0,
1740
- brandName: "miaoda",
1741
- appId,
1742
- accountServices: {
1743
- user: import_auth_sdk3.authClient.user,
1744
- session: import_auth_sdk3.authClient.session
1745
- }
2842
+ // src/integrations/capabilityClient.ts
2843
+ var import_client_capability = require("@lark-apaas/client-capability");
2844
+ var _appId = getAppId();
2845
+ var _acquireUploadUrl = isNewPathEnabled() ? `/app/${_appId}/__runtime__/api/v1/studio/plugins/tmp_files/acquire_upload_url` : `/af/api/v1/studio/plugins/tmp_files/acquire_upload_url`;
2846
+ var _acquireDownloadUrl = isNewPathEnabled() ? `/app/${_appId}/__runtime__/api/v1/studio/plugins/tmp_files/acquire_download_url` : `/af/api/v1/studio/plugins/tmp_files/acquire_download_url`;
2847
+ var capabilityClient = (0, import_client_capability.createClient)({
2848
+ baseURL: normalizeBasePath(process.env.CLIENT_BASE_PATH ?? "/"),
2849
+ acquireUploadUrl: _acquireUploadUrl,
2850
+ acquireDownloadUrl: _acquireDownloadUrl,
2851
+ fetchOptions: {
2852
+ headers: {
2853
+ "X-Suda-Csrf-Token": window.csrfToken ?? ""
1746
2854
  }
1747
- });
1748
- }, "createDataLoomClient");
1749
- var dataloom = null;
1750
- var pendingPromise2 = null;
1751
- function getDataloom() {
1752
- if (dataloom) {
1753
- return Promise.resolve(dataloom);
1754
- }
1755
- if (pendingPromise2) {
1756
- return pendingPromise2;
2855
+ },
2856
+ central: {
2857
+ enabled: true,
2858
+ // window.appId 由妙搭沙箱 / 线上环境注入;非妙搭场景下 capability 调用本身不可用
2859
+ appId: _appId ?? ""
1757
2860
  }
1758
- pendingPromise2 = getInitialInfo().then((info) => {
1759
- const DATALOOM_CLIENT_URL = info?.app_runtime_extra?.url;
1760
- const DATALOOM_PAT = info?.app_runtime_extra?.token;
1761
- dataloom = createDataLoomClient(DATALOOM_CLIENT_URL, DATALOOM_PAT);
1762
- return dataloom;
1763
- }).finally(() => {
1764
- pendingPromise2 = null;
1765
- });
1766
- return pendingPromise2;
1767
- }
1768
- __name(getDataloom, "getDataloom");
2861
+ });
1769
2862
 
1770
2863
  // src/constants/img-resources/avatar.ts
1771
2864
  var avatar_exports = {};
@@ -1927,6 +3020,7 @@ var abstractArt3dRenderingCoverImg6 = "https://lf3-static.bytednsdoc.com/obj/ede
1927
3020
  0 && (module.exports = {
1928
3021
  ActiveLink,
1929
3022
  AppContainer,
3023
+ ErrorRender,
1930
3024
  NavLink,
1931
3025
  PagePlaceholder,
1932
3026
  QueryProvider,
@@ -1936,6 +3030,7 @@ var abstractArt3dRenderingCoverImg6 = "https://lf3-static.bytednsdoc.com/obj/ede
1936
3030
  avatarImages,
1937
3031
  axiosForBackend,
1938
3032
  bannerImages,
3033
+ capabilityClient,
1939
3034
  clsxWithTw,
1940
3035
  copyToClipboard,
1941
3036
  coverImages,
@@ -1952,6 +3047,7 @@ var abstractArt3dRenderingCoverImg6 = "https://lf3-static.bytednsdoc.com/obj/ede
1952
3047
  isIpad,
1953
3048
  isMobile,
1954
3049
  isPreview,
3050
+ logger,
1955
3051
  normalizeBasePath,
1956
3052
  reportTeaEvent,
1957
3053
  resolveAppUrl,