@lark-apaas/client-toolkit-lite 1.1.7 → 1.1.8-alpha.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.
package/dist/index.js CHANGED
@@ -6,8 +6,7 @@ var __export = (target, all) => {
6
6
  };
7
7
 
8
8
  // src/components/AppContainer/index.tsx
9
- import React4, { useEffect as useEffect5 } from "react";
10
- import { MiaodaInspector } from "@lark-apaas/miaoda-inspector";
9
+ import React4, { useEffect as useEffect4 } from "react";
11
10
 
12
11
  // src/runtime/react-devtools-hook.ts
13
12
  if (typeof window !== "undefined" && process.env.NODE_ENV !== "production") {
@@ -63,15 +62,15 @@ function initAxiosConfig(axiosInstance2) {
63
62
  if (!axiosInstance2) {
64
63
  axiosInstance2 = axios;
65
64
  }
66
- axiosInstance2.interceptors.request.use((config2) => {
65
+ axiosInstance2.interceptors.request.use((config) => {
67
66
  const csrfToken = getCsrfToken();
68
67
  if (csrfToken) {
69
- config2.headers["X-Suda-Csrf-Token"] = csrfToken;
68
+ config.headers["X-Suda-Csrf-Token"] = csrfToken;
70
69
  }
71
70
  if (typeof window !== "undefined") {
72
- config2.headers["X-Page-Route"] = window.location.pathname;
71
+ config.headers["X-Page-Route"] = window.location.pathname;
73
72
  }
74
- return config2;
73
+ return config;
75
74
  }, (error) => Promise.reject(error));
76
75
  axiosInstance2.interceptors.response.use((response) => response, (error) => {
77
76
  if (process.env.NODE_ENV !== "production") {
@@ -82,1017 +81,10 @@ function initAxiosConfig(axiosInstance2) {
82
81
  }
83
82
  __name(initAxiosConfig, "initAxiosConfig");
84
83
 
85
- // src/runtime/observable.ts
86
- import { observable, AppEnv } from "@lark-apaas/observable-web";
87
-
88
- // src/utils/apiPath.ts
89
- function isNewPathEnabled() {
90
- const basePath = process.env.CLIENT_BASE_PATH || "/";
91
- return /^\/app\/[^/]/.test(basePath);
92
- }
93
- __name(isNewPathEnabled, "isNewPathEnabled");
94
-
95
- // src/runtime/observable.ts
96
- var initObservable = /* @__PURE__ */ __name(() => {
97
- try {
98
- const appId = window.appId;
99
- observable.start({
100
- serviceName: "app",
101
- env: process.env.NODE_ENV === "development" ? AppEnv.Dev : AppEnv.Prod,
102
- collectorUrl: isNewPathEnabled() ? {
103
- log: `/app/${appId}/__runtime__/api/v1/observability/logs/collect`,
104
- trace: `/app/${appId}/__runtime__/api/v1/observability/traces/collect`,
105
- metric: `/app/${appId}/__runtime__/api/v1/observability/metrics/collect`,
106
- time: `/app/${appId}/__runtime__/api/v1/observability/current_server_timestamp`
107
- } : {
108
- log: `/spark/app/${appId}/runtime/api/v1/observability/logs/collect`,
109
- trace: `/spark/app/${appId}/runtime/api/v1/observability/traces/collect`,
110
- metric: `/spark/app/${appId}/runtime/api/v1/observability/metrics/collect`,
111
- time: `/spark/api/v1/observability/app/${appId}/current_server_timestamp`
112
- }
113
- });
114
- } catch (error) {
115
- console.error("Failed to start WebObservableSdk:", error);
116
- }
117
- }, "initObservable");
118
-
119
- // src/logger/logger.ts
120
- import { observable as observable2 } from "@lark-apaas/observable-web";
121
-
122
- // src/logger/intercept-global-error.ts
123
- import { slardar } from "@lark-apaas/internal-slardar";
124
-
125
- // src/utils/hmr-api.ts
126
- function createWebpackHmrApi(hot) {
127
- return {
128
- onSuccess(callback) {
129
- let lastStatus = null;
130
- const handler = /* @__PURE__ */ __name((status) => {
131
- if (status === "idle" && lastStatus === "apply") {
132
- try {
133
- callback();
134
- } catch (e) {
135
- console.error("[HMR] Success callback error:", e);
136
- }
137
- }
138
- lastStatus = status;
139
- }, "handler");
140
- hot.addStatusHandler(handler);
141
- return () => hot.removeStatusHandler(handler);
142
- },
143
- onError(callback) {
144
- const handler = /* @__PURE__ */ __name((status) => {
145
- if (status === "fail" || status === "abort") {
146
- try {
147
- callback(new Error(`HMR ${status}`));
148
- } catch (e) {
149
- console.error("[HMR] Error callback error:", e);
150
- }
151
- }
152
- }, "handler");
153
- hot.addStatusHandler(handler);
154
- return () => hot.removeStatusHandler(handler);
155
- }
156
- };
157
- }
158
- __name(createWebpackHmrApi, "createWebpackHmrApi");
159
- function getHmrApi() {
160
- if (process.env.NODE_ENV === "production") return null;
161
- if (import.meta.webpackHot) {
162
- return createWebpackHmrApi(import.meta.webpackHot);
163
- }
164
- if (typeof module !== "undefined" && module.hot) {
165
- return createWebpackHmrApi(module.hot);
166
- }
167
- if (window.__VITE_HMR__) {
168
- return window.__VITE_HMR__;
169
- }
170
- return null;
171
- }
172
- __name(getHmrApi, "getHmrApi");
173
-
174
- // src/utils/postMessage.ts
175
- var PARENT_ORIGIN_KEY = "__parentOrigin";
176
- function getParentOriginFromParams() {
177
- try {
178
- const params = new URLSearchParams(window.location.search);
179
- const origin = params.get(PARENT_ORIGIN_KEY);
180
- if (origin) {
181
- sessionStorage.setItem(PARENT_ORIGIN_KEY, origin);
182
- return origin;
183
- }
184
- } catch {
185
- }
186
- try {
187
- return sessionStorage.getItem(PARENT_ORIGIN_KEY) || void 0;
188
- } catch {
189
- return void 0;
190
- }
191
- }
192
- __name(getParentOriginFromParams, "getParentOriginFromParams");
193
- function getLegacyParentOrigin() {
194
- const { origin } = window.location;
195
- if (origin.includes("force.feishuapp.net")) {
196
- return "https://force.feishu.cn";
197
- }
198
- if (origin.includes("force-pre.feishuapp.net")) {
199
- return "https://force.feishu-pre.cn";
200
- }
201
- if (origin.includes("force.byted.org")) {
202
- return "https://force.feishu-boe.cn";
203
- }
204
- if (origin.includes("feishuapp.cn") || origin.includes("miaoda.feishuapp.net")) {
205
- return "https://miaoda.feishu.cn";
206
- }
207
- if (origin.includes("fsapp.kundou.cn") || origin.includes("miaoda-pre.feishuapp.net")) {
208
- return "https://miaoda.feishu-pre.cn";
209
- }
210
- return "https://miaoda.feishu-boe.cn";
211
- }
212
- __name(getLegacyParentOrigin, "getLegacyParentOrigin");
213
- function resolveParentOrigin() {
214
- try {
215
- if (document.referrer) {
216
- const referrerOrigin = new URL(document.referrer).origin;
217
- if (referrerOrigin.startsWith("http://localhost") || referrerOrigin.startsWith("http://127.0.0.1")) {
218
- return referrerOrigin;
219
- }
220
- }
221
- } catch {
222
- }
223
- const paramOrigin = getParentOriginFromParams();
224
- if (paramOrigin) return paramOrigin;
225
- return process.env?.FORCE_FRAMEWORK_DOMAIN_MAIN ?? getLegacyParentOrigin();
226
- }
227
- __name(resolveParentOrigin, "resolveParentOrigin");
228
- function submitPostMessage(message, targetOrigin) {
229
- try {
230
- const parentOrigin = resolveParentOrigin();
231
- const origin = targetOrigin ?? parentOrigin;
232
- if (!origin) return;
233
- window.parent.postMessage(message, origin);
234
- } catch (e) {
235
- console.error("postMessage error", e);
236
- }
237
- }
238
- __name(submitPostMessage, "submitPostMessage");
239
-
240
- // src/logger/log-types.ts
241
- var LOG_LEVELS = [
242
- "debug",
243
- "info",
244
- "warn",
245
- "error",
246
- "success"
247
- ];
248
- function isLogLevel(value) {
249
- return typeof value === "string" && LOG_LEVELS.includes(value);
250
- }
251
- __name(isLogLevel, "isLogLevel");
252
-
253
- // src/logger/intercept-global-error.ts
254
- var devServerDisconnectInfo = null;
255
- var retryCount = 0;
256
- function processDevServerLog(log) {
257
- if (!log) return;
258
- const devFlag = log.includes("[webpack-dev-server]") || log.includes("[vite]");
259
- if (devFlag && log.includes("Disconnected")) {
260
- const time = Date.now();
261
- devServerDisconnectInfo = {
262
- time
263
- };
264
- submitPostMessage({
265
- type: "DevServerMessage",
266
- data: {
267
- type: "devServer-status",
268
- status: "disconnected"
269
- }
270
- });
271
- slardar.sendEvent({
272
- name: "sandbox-devServer",
273
- metrics: {
274
- time
275
- },
276
- categories: {
277
- type: "disconnected"
278
- }
279
- });
280
- return;
281
- }
282
- if (!devServerDisconnectInfo) {
283
- return;
284
- }
285
- if (devFlag && log.includes("Trying to reconnect")) {
286
- if (retryCount) {
287
- slardar.sendEvent({
288
- name: "sandbox-devServer",
289
- metrics: {
290
- retryCount: retryCount + 1
291
- },
292
- categories: {
293
- type: "reconnect-failed"
294
- }
295
- });
296
- }
297
- retryCount++;
298
- return;
299
- }
300
- const hmrFlag = log.includes("[HMR]");
301
- if (hmrFlag || devFlag && (log.includes("Socket connected") || log.includes("App updated") || log.includes("App hot update") || log.includes("connected"))) {
302
- submitPostMessage({
303
- type: "DevServerMessage",
304
- data: {
305
- type: "devServer-status",
306
- status: "connected"
307
- }
308
- });
309
- const startTime = devServerDisconnectInfo.time;
310
- const duration = Date.now() - startTime;
311
- slardar.sendEvent({
312
- name: "sandbox-devServer",
313
- metrics: {
314
- startTime,
315
- duration
316
- },
317
- categories: {
318
- type: "devServer-reconnected"
319
- }
320
- });
321
- devServerDisconnectInfo = null;
322
- retryCount = 0;
323
- }
324
- }
325
- __name(processDevServerLog, "processDevServerLog");
326
- function listenModuleHmr() {
327
- const hmr = getHmrApi();
328
- if (hmr) {
329
- hmr.onSuccess(() => {
330
- submitPostMessage({
331
- type: "DevServerMessage",
332
- data: {
333
- type: "devServer-status",
334
- status: "hmr-apply-success"
335
- }
336
- });
337
- });
338
- hmr.onError((error) => {
339
- console.warn("hmr apply failed", error);
340
- slardar.sendEvent({
341
- name: "sandbox-devServer",
342
- categories: {
343
- type: "hmr-apply-failed",
344
- error: String(error)
345
- }
346
- });
347
- });
348
- }
349
- }
350
- __name(listenModuleHmr, "listenModuleHmr");
351
- var PROXY_CONSOLE_METHOD = [
352
- "log",
353
- "info",
354
- "warn",
355
- "error"
356
- ];
357
- function interceptErrors() {
358
- window.addEventListener("error", (event) => {
359
- logger.error(event.error);
360
- });
361
- window.addEventListener("unhandledrejection", (event) => {
362
- logger.error(event.reason);
363
- });
364
- listenModuleHmr();
365
- PROXY_CONSOLE_METHOD.forEach((method) => {
366
- const originalMethod = window.console[method];
367
- window.console[method] = (...args) => {
368
- originalMethod(...args);
369
- const level = method === "log" ? "info" : method;
370
- const first = args[0];
371
- if (typeof first === "string") {
372
- processDevServerLog(first);
373
- }
374
- if (typeof first === "string" && first.startsWith("[Dataloom]") && isLogLevel(level)) {
375
- logger.log({
376
- level,
377
- args
378
- });
379
- submitPostMessage({
380
- type: "Console",
381
- method,
382
- data: args
383
- });
384
- }
385
- };
386
- });
387
- }
388
- __name(interceptErrors, "interceptErrors");
389
-
390
- // src/utils/safeStringify.ts
391
- function safeStringify(obj) {
392
- const seen = /* @__PURE__ */ new Set();
393
- try {
394
- return JSON.stringify(obj, (_key, value) => {
395
- if (typeof value === "object" && value !== null) {
396
- if (seen.has(value)) {
397
- return "[Circular]";
398
- }
399
- seen.add(value);
400
- }
401
- if (typeof value === "bigint") {
402
- return value.toString();
403
- }
404
- if (value instanceof Date) {
405
- return value.toISOString();
406
- }
407
- if (value instanceof Map) {
408
- return Object.fromEntries(value);
409
- }
410
- if (value instanceof Set) {
411
- return Array.from(value);
412
- }
413
- if (value instanceof Error) {
414
- return {
415
- name: value.name,
416
- message: value.message,
417
- stack: value.stack
418
- };
419
- }
420
- if (typeof value === "undefined") {
421
- return "undefined";
422
- }
423
- if (typeof value === "symbol") {
424
- return value.toString();
425
- }
426
- return value;
427
- });
428
- } catch {
429
- return "";
430
- } finally {
431
- seen.clear();
432
- }
433
- }
434
- __name(safeStringify, "safeStringify");
435
- function processLogParams(args) {
436
- return args.map((arg) => {
437
- if (typeof arg === "string") return arg;
438
- if (arg instanceof Error) {
439
- return `${arg.name}: ${arg.message}
440
- ${arg.stack ?? ""}`;
441
- }
442
- if (typeof arg === "object" && arg !== null) {
443
- return safeStringify(arg);
444
- }
445
- return String(arg);
446
- });
447
- }
448
- __name(processLogParams, "processLogParams");
449
- function mapLogLevel(level) {
450
- if (level === "warn") return "WARN";
451
- if (level === "error") return "ERROR";
452
- return "INFO";
453
- }
454
- __name(mapLogLevel, "mapLogLevel");
455
-
456
- // src/logger/selected-logs.ts
457
- import StackTrace from "stacktrace-js";
458
-
459
- // src/logger/batch-logger.ts
460
- var BatchLogger = class {
461
- static {
462
- __name(this, "BatchLogger");
463
- }
464
- config;
465
- logQueue = [];
466
- flushTimer = null;
467
- isProcessing = false;
468
- originConsole;
469
- constructor(console1, config2) {
470
- this.originConsole = {
471
- ...console1
472
- };
473
- const { userId = "", tenantId = "", appId = "" } = window || {};
474
- this.config = {
475
- userId,
476
- tenantId,
477
- appId,
478
- // 需要加请求路径前缀
479
- endpoint: (process.env.CLIENT_BASE_PATH || "") + "/dev/logs/collect-batch",
480
- sizeThreshold: 20,
481
- flushInterval: 1e3,
482
- maxRetries: 3,
483
- retryDelay: 500,
484
- headers: {
485
- "Content-Type": "application/json"
486
- },
487
- ...config2 || {}
488
- };
489
- this.startFlushTimer();
490
- this.setupBeforeUnloadHandler();
491
- }
492
- /**
493
- * 批量记录日志(对外暴露的唯一方法)
494
- */
495
- batchLog(level, message, source) {
496
- const logEntry = {
497
- id: this.generateId(),
498
- level,
499
- message,
500
- source,
501
- timestamp: Date.now()
502
- };
503
- this.logQueue.push(logEntry);
504
- if (this.logQueue.length >= this.config.sizeThreshold) {
505
- this.flush();
506
- }
507
- }
508
- /**
509
- * 刷新日志队列,全部发送
510
- */
511
- async flush() {
512
- if (this.isProcessing || this.logQueue.length === 0) {
513
- return;
514
- }
515
- this.isProcessing = true;
516
- const logsToSend = this.logQueue.splice(0, this.logQueue.length);
517
- try {
518
- await this.sendBatch(logsToSend);
519
- } catch (error) {
520
- this.logQueue.unshift(...logsToSend);
521
- } finally {
522
- this.isProcessing = false;
523
- }
524
- }
525
- /**
526
- * 发送日志批次到后端
527
- */
528
- async sendBatch(logs) {
529
- const collectLogs = logs.map((log) => ({
530
- level: log.level,
531
- message: log.message,
532
- time: new Date(log.timestamp).toISOString(),
533
- source: log.source,
534
- user_id: this.config.userId,
535
- tenant_id: this.config.tenantId,
536
- app_id: this.config.appId
537
- }));
538
- let retries = 0;
539
- while (retries <= this.config.maxRetries) {
540
- try {
541
- await this.execFetch(this.config.endpoint, {
542
- method: "POST",
543
- headers: this.config.headers,
544
- body: JSON.stringify(collectLogs)
545
- });
546
- return;
547
- } catch (error) {
548
- retries++;
549
- if (retries > this.config.maxRetries) {
550
- this.originConsole.error(`Failed to send logs (attempt ${retries}), retrying in ${this.config.retryDelay}ms...`);
551
- } else {
552
- this.originConsole.warn(`Failed to send logs (attempt ${retries}), retrying in ${this.config.retryDelay}ms...`);
553
- }
554
- await this.delay(this.config.retryDelay * retries);
555
- }
556
- }
557
- }
558
- /**
559
- * 执行实际的fetch请求
560
- */
561
- async execFetch(url, options) {
562
- return fetch(url, options);
563
- }
564
- /**
565
- * 启动自动刷新定时器
566
- */
567
- startFlushTimer() {
568
- if (this.flushTimer) {
569
- clearInterval(this.flushTimer);
570
- }
571
- this.flushTimer = setInterval(() => {
572
- if (this.logQueue.length > 0) {
573
- this.flush();
574
- }
575
- }, this.config.flushInterval);
576
- }
577
- /**
578
- * 设置页面卸载时的处理
579
- */
580
- setupBeforeUnloadHandler() {
581
- if (typeof window !== "undefined") {
582
- window.addEventListener("beforeunload", () => {
583
- this.flush().finally(() => {
584
- this.destroy();
585
- });
586
- });
587
- }
588
- }
589
- /**
590
- * 延迟函数
591
- */
592
- delay(ms) {
593
- return new Promise((resolve) => setTimeout(resolve, ms));
594
- }
595
- /**
596
- * 生成唯一ID
597
- */
598
- generateId() {
599
- return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
600
- }
601
- /**
602
- * 销毁资源
603
- */
604
- async destroy() {
605
- if (this.flushTimer) {
606
- clearInterval(this.flushTimer);
607
- this.flushTimer = null;
608
- }
609
- if (this.logQueue.length > 0) {
610
- await this.flush();
611
- }
612
- }
613
- /**
614
- * 获取队列大小
615
- */
616
- getQueueSize() {
617
- return this.logQueue.length;
618
- }
619
- /**
620
- * 更新配置
621
- */
622
- updateConfig(newConfig) {
623
- this.config = {
624
- ...this.config,
625
- ...newConfig
626
- };
627
- this.startFlushTimer();
628
- }
629
- };
630
- var defaultBatchLogger = null;
631
- function batchLogInfo(level, message, source) {
632
- if (!defaultBatchLogger) {
633
- return;
634
- }
635
- defaultBatchLogger.batchLog(level, message, source);
636
- }
637
- __name(batchLogInfo, "batchLogInfo");
638
- if (process.env.NODE_ENV !== "production" && typeof window !== "undefined") {
639
- defaultBatchLogger = new BatchLogger(console);
640
- }
641
-
642
- // src/logger/selected-logs.ts
643
- function mapStacktrace(stacktrace) {
644
- return stacktrace.map((frame) => ({
645
- functionName: frame.functionName || "",
646
- fileName: frame.fileName || "",
647
- lineNumber: frame.lineNumber || 0,
648
- columnNumber: frame.columnNumber || 0
649
- }));
650
- }
651
- __name(mapStacktrace, "mapStacktrace");
652
- function reportStacktraceParseError(e, context) {
653
- if (window.parent === window) return;
654
- try {
655
- submitPostMessage({
656
- type: "STACKTRACE_PARSE_ERROR",
657
- payload: {
658
- error: e instanceof Error ? e.message : String(e),
659
- context
660
- }
661
- });
662
- } catch {
663
- }
664
- }
665
- __name(reportStacktraceParseError, "reportStacktraceParseError");
666
- async function getStacktrace() {
667
- const stacktrace = await StackTrace.get();
668
- return mapStacktrace(stacktrace);
669
- }
670
- __name(getStacktrace, "getStacktrace");
671
- function errorReplacer(_key, value) {
672
- if (value instanceof Error) {
673
- return {
674
- message: value.message,
675
- stack: value.stack,
676
- name: value.name
677
- };
678
- }
679
- return value;
680
- }
681
- __name(errorReplacer, "errorReplacer");
682
- function generateLogId() {
683
- try {
684
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
685
- return crypto.randomUUID();
686
- }
687
- } catch {
688
- }
689
- return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
690
- }
691
- __name(generateLogId, "generateLogId");
692
- var lastLogInfo = null;
693
- async function sendSelectedLog(logWithoutID) {
694
- try {
695
- const log = {
696
- ...logWithoutID,
697
- id: generateLogId()
698
- };
699
- const newParts = [];
700
- for (let i = 0; i < log.args.length; i++) {
701
- const item = log.args[i];
702
- if (item instanceof Error) {
703
- const newError = {
704
- message: item.message,
705
- stack: item.stack,
706
- name: item.name
707
- };
708
- if (!log.meta.stacktrace) {
709
- try {
710
- const stacktrace = await StackTrace.fromError(item);
711
- log.meta.stacktrace = mapStacktrace(stacktrace);
712
- } catch (e) {
713
- reportStacktraceParseError(e, "StackTrace.fromError");
714
- }
715
- }
716
- newParts.push(newError.message, newError);
717
- } else {
718
- newParts.push(item);
719
- }
720
- }
721
- log.args = newParts;
722
- if (!log.meta.stacktrace) {
723
- try {
724
- const frames = await getStacktrace();
725
- const firstFrameIndex = frames.findIndex((frame) => !frame.fileName.includes("client-toolkit-lite/dist/logger"));
726
- log.meta.stacktrace = firstFrameIndex === -1 ? [] : frames.slice(firstFrameIndex);
727
- } catch (e) {
728
- reportStacktraceParseError(e, "getStacktrace");
729
- }
730
- }
731
- if (log.meta.skipFrame === void 0) {
732
- log.meta.skipFrame = 2;
733
- }
734
- const logJSON = JSON.stringify(log, errorReplacer);
735
- const logForDedup = {
736
- ...log
737
- };
738
- delete logForDedup.id;
739
- const logContentForDedup = JSON.stringify(logForDedup, errorReplacer);
740
- if (lastLogInfo && lastLogInfo.content === logContentForDedup) {
741
- lastLogInfo.count++;
742
- log.meta.isDuplicate = true;
743
- log.meta.duplicateCount = lastLogInfo.count;
744
- log.meta.duplicateOfId = lastLogInfo.id;
745
- const updatedJSON = JSON.stringify(log, errorReplacer);
746
- try {
747
- batchLogInfo("info", updatedJSON);
748
- } catch {
749
- }
750
- if (window.parent !== window) {
751
- try {
752
- submitPostMessage({
753
- type: "SELECTED_LOG",
754
- payload: updatedJSON
755
- });
756
- } catch {
757
- }
758
- }
759
- return;
760
- }
761
- lastLogInfo = {
762
- content: logContentForDedup,
763
- id: log.id,
764
- count: 1
765
- };
766
- try {
767
- batchLogInfo("info", logJSON);
768
- } catch {
769
- }
770
- if (window.parent !== window) {
771
- try {
772
- submitPostMessage({
773
- type: "SELECTED_LOG",
774
- payload: logJSON
775
- });
776
- } catch {
777
- }
778
- }
779
- } catch {
780
- }
781
- }
782
- __name(sendSelectedLog, "sendSelectedLog");
783
- function sendTypedLogV2(logWithMeta) {
784
- void sendSelectedLog({
785
- type: "typedLogV2",
786
- level: logWithMeta.level,
787
- args: logWithMeta.args,
788
- meta: logWithMeta.meta ?? {}
789
- });
790
- }
791
- __name(sendTypedLogV2, "sendTypedLogV2");
792
- var typedLogInterceptor = /* @__PURE__ */ __name((originLogger) => ({
793
- debug: /* @__PURE__ */ __name((message, ...args) => {
794
- try {
795
- originLogger.debug(message, ...args);
796
- } catch {
797
- }
798
- sendTypedLogV2({
799
- level: "info",
800
- args: [
801
- message,
802
- ...args
803
- ],
804
- meta: {}
805
- });
806
- }, "debug"),
807
- info: /* @__PURE__ */ __name((message, ...args) => {
808
- try {
809
- originLogger.info(message, ...args);
810
- } catch {
811
- }
812
- sendTypedLogV2({
813
- level: "info",
814
- args: [
815
- message,
816
- ...args
817
- ],
818
- meta: {}
819
- });
820
- }, "info"),
821
- warn: /* @__PURE__ */ __name((message, ...args) => {
822
- try {
823
- originLogger.warn(message, ...args);
824
- } catch {
825
- }
826
- sendTypedLogV2({
827
- level: "warn",
828
- args: [
829
- message,
830
- ...args
831
- ],
832
- meta: {}
833
- });
834
- }, "warn"),
835
- error: /* @__PURE__ */ __name((message, ...args) => {
836
- try {
837
- originLogger.error(message, ...args);
838
- } catch {
839
- }
840
- sendTypedLogV2({
841
- level: "error",
842
- args: [
843
- message,
844
- ...args
845
- ],
846
- meta: {}
847
- });
848
- }, "error"),
849
- success: /* @__PURE__ */ __name((message, ...args) => {
850
- try {
851
- originLogger.success(message, ...args);
852
- } catch {
853
- }
854
- sendTypedLogV2({
855
- level: "success",
856
- args: [
857
- message,
858
- ...args
859
- ],
860
- meta: {}
861
- });
862
- }, "success"),
863
- log: /* @__PURE__ */ __name(({ level, args, meta }) => {
864
- try {
865
- originLogger.log({
866
- level,
867
- args,
868
- meta
869
- });
870
- } catch {
871
- }
872
- sendTypedLogV2({
873
- level,
874
- args,
875
- meta: meta ?? {}
876
- });
877
- }, "log")
878
- }), "typedLogInterceptor");
879
- var interceptors = [
880
- typedLogInterceptor
881
- ];
882
-
883
- // src/logger/logger.ts
884
- var shouldReportToObservable = process.env.NODE_ENV === "production";
885
- var ORDERED_LEVELS = [
886
- "debug",
887
- "info",
888
- "warn",
889
- "error"
890
- ];
891
- var defaultConfig = {
892
- showLevel: false,
893
- showTimestamp: false,
894
- level: "info",
895
- prefix: ""
896
- };
897
- var config = {
898
- ...defaultConfig
899
- };
900
- function configureLogger(options) {
901
- config = {
902
- ...defaultConfig,
903
- ...options
904
- };
905
- }
906
- __name(configureLogger, "configureLogger");
907
- function shouldLog(level) {
908
- return ORDERED_LEVELS.indexOf(level) >= ORDERED_LEVELS.indexOf(config.level);
909
- }
910
- __name(shouldLog, "shouldLog");
911
- function getFormattedPrefix(level) {
912
- const parts = [];
913
- if (config.prefix) {
914
- parts.push(`[${config.prefix}]`);
915
- }
916
- if (config.showLevel) {
917
- parts.push(`[${level.toUpperCase()}]`);
918
- }
919
- return parts;
920
- }
921
- __name(getFormattedPrefix, "getFormattedPrefix");
922
- configureLogger({
923
- showLevel: true,
924
- showTimestamp: false,
925
- level: process.env.NODE_ENV === "development" ? "debug" : "error",
926
- prefix: "MiaoDa"
927
- });
928
- var logger = {
929
- debug(message, ...args) {
930
- if (shouldLog("debug")) {
931
- console.log(...getFormattedPrefix("debug"), message, ...args);
932
- }
933
- },
934
- info(message, ...args) {
935
- if (shouldLog("info")) {
936
- console.log(...getFormattedPrefix("info"), message, ...args);
937
- }
938
- if (shouldReportToObservable) {
939
- observable2.log("INFO", processLogParams([
940
- message,
941
- ...args
942
- ]).join(" "));
943
- }
944
- },
945
- warn(message, ...args) {
946
- if (shouldLog("warn")) {
947
- console.log(...getFormattedPrefix("warn"), message, ...args);
948
- }
949
- if (shouldReportToObservable) {
950
- observable2.log("WARN", processLogParams([
951
- message,
952
- ...args
953
- ]).join(" "));
954
- }
955
- },
956
- error(message, ...args) {
957
- if (shouldLog("error")) {
958
- console.error(...getFormattedPrefix("error"), message, ...args);
959
- }
960
- if (shouldReportToObservable) {
961
- observable2.log("ERROR", processLogParams([
962
- message,
963
- ...args
964
- ]).join(" "));
965
- }
966
- },
967
- success(message, ...args) {
968
- if (shouldLog("info")) {
969
- console.log(...getFormattedPrefix("success"), message, ...args);
970
- }
971
- if (shouldReportToObservable) {
972
- observable2.log("INFO", processLogParams([
973
- message,
974
- ...args
975
- ]).join(" "));
976
- }
977
- },
978
- log({ level, args }) {
979
- if (shouldLog(level)) {
980
- console.log(...getFormattedPrefix(level), ...args);
981
- }
982
- if (shouldReportToObservable && level !== "debug") {
983
- observable2.log(mapLogLevel(level), processLogParams(args).join(" "));
984
- }
985
- }
986
- };
987
- if (process.env.NODE_ENV !== "production") {
988
- window.__RUNTIME_LOGGER__ = {
989
- get() {
990
- return logger;
991
- }
992
- };
993
- }
994
- for (const interceptor of interceptors) {
995
- logger = interceptor(logger);
996
- }
997
- if (process.env.NODE_ENV !== "production") {
998
- interceptErrors();
999
- }
1000
-
1001
- // src/runtime/iframe-bridge.ts
1002
- import { connectToParent } from "penpal";
1003
-
1004
- // src/utils/utils.ts
1005
- import { clsx } from "clsx";
1006
- import { twMerge } from "tailwind-merge";
1007
- function clsxWithTw(...inputs) {
1008
- return twMerge(clsx(inputs));
1009
- }
1010
- __name(clsxWithTw, "clsxWithTw");
1011
- function isPreview() {
1012
- return window.IS_MIAODA_PREVIEW;
1013
- }
1014
- __name(isPreview, "isPreview");
1015
- function normalizeBasePath(basePath) {
1016
- if (!basePath || basePath === "/") {
1017
- return "";
1018
- }
1019
- return basePath.replace(/\/+$/, "");
1020
- }
1021
- __name(normalizeBasePath, "normalizeBasePath");
1022
- function getWsPath() {
1023
- const rawBasePath = process.env.CLIENT_BASE_PATH || "/";
1024
- const normalizedBasePath = rawBasePath.startsWith("/") ? rawBasePath : `/${rawBasePath}`;
1025
- const basePathWithoutTrailingSlash = normalizedBasePath.endsWith("/") ? normalizedBasePath.slice(0, -1) : normalizedBasePath;
1026
- return `${basePathWithoutTrailingSlash}/ws`;
1027
- }
1028
- __name(getWsPath, "getWsPath");
1029
- function isSparkRuntime() {
1030
- return window._IS_Spark_RUNTIME ?? process.env.runtimeMode === "fullstack";
1031
- }
1032
- __name(isSparkRuntime, "isSparkRuntime");
1033
-
1034
- // src/components/AppContainer/utils/childApi.ts
1035
- async function getRoutes() {
1036
- let routes = [
1037
- {
1038
- path: "/"
1039
- }
1040
- ];
1041
- try {
1042
- const basePath = normalizeBasePath(process.env.CLIENT_BASE_PATH);
1043
- const res = await fetch(`${basePath}/routes.json`);
1044
- routes = await res.json();
1045
- } catch (error) {
1046
- console.warn("get routes.json error", error);
1047
- }
1048
- return routes;
1049
- }
1050
- __name(getRoutes, "getRoutes");
1051
- var childApi = {
1052
- getRoutes,
1053
- updateAppInfo: /* @__PURE__ */ __name((appInfo) => {
1054
- dispatchEvent(new CustomEvent("MiaoDaMetaInfoChanged", {
1055
- detail: appInfo
1056
- }));
1057
- }, "updateAppInfo")
1058
- };
1059
-
1060
- // src/runtime/iframe-bridge.ts
1061
- async function connectParent() {
1062
- submitPostMessage({
1063
- type: "PreviewReady",
1064
- data: {}
1065
- });
1066
- batchLogInfo("info", JSON.stringify({
1067
- type: "PreviewReady",
1068
- timestamp: Date.now(),
1069
- url: window.location.href
1070
- }));
1071
- const parentOrigin = resolveParentOrigin();
1072
- if (!parentOrigin) return;
1073
- const connection = connectToParent({
1074
- parentOrigin,
1075
- methods: {
1076
- ...childApi
1077
- }
1078
- });
1079
- await connection.promise;
1080
- }
1081
- __name(connectParent, "connectParent");
1082
- function initIframeBridge() {
1083
- if (window.parent === window) return;
1084
- connectParent();
1085
- }
1086
- __name(initIframeBridge, "initIframeBridge");
1087
-
1088
84
  // src/runtime/index.ts
1089
85
  if (!window.__FULLSTACK_RUNTIME_INITIALIZED__) {
1090
86
  window.__FULLSTACK_RUNTIME_INITIALIZED__ = true;
1091
87
  initAxiosConfig();
1092
- initObservable();
1093
- if (process.env.NODE_ENV !== "production") {
1094
- initIframeBridge();
1095
- }
1096
88
  }
1097
89
 
1098
90
  // src/components/AppContainer/safety.tsx
@@ -1107,6 +99,16 @@ function getAppId() {
1107
99
  }
1108
100
  __name(getAppId, "getAppId");
1109
101
 
102
+ // src/utils/apiPath.ts
103
+ function isNewPathEnabled() {
104
+ const basePath = process.env.CLIENT_BASE_PATH || "/";
105
+ return /^\/app\/[^/]/.test(basePath);
106
+ }
107
+ __name(isNewPathEnabled, "isNewPathEnabled");
108
+
109
+ // src/hooks/useAppInfo.tsx
110
+ import { useEffect, useState } from "react";
111
+
1110
112
  // src/utils/getInitialInfo.ts
1111
113
  async function getAppPublished() {
1112
114
  try {
@@ -1157,46 +159,35 @@ function getInitialInfo(refresh = false) {
1157
159
  }
1158
160
  __name(getInitialInfo, "getInitialInfo");
1159
161
 
1160
- // src/utils/getTenantInfo.ts
1161
- async function fetchTenantInfo() {
1162
- try {
1163
- const appId = getAppId();
1164
- const path = isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/studio/tenant_info` : `/spark/b/${appId}/tenant_info`;
1165
- const response = await fetch(`${window.location.origin}${path}`, {
1166
- method: "GET",
1167
- headers: {
1168
- "X-Suda-Csrf-Token": getCsrfToken() ?? ""
1169
- },
1170
- credentials: "include"
1171
- });
1172
- const res = await response.json();
1173
- return res?.data;
1174
- } catch {
1175
- return void 0;
1176
- }
162
+ // src/utils/utils.ts
163
+ import { clsx } from "clsx";
164
+ import { twMerge } from "tailwind-merge";
165
+ function clsxWithTw(...inputs) {
166
+ return twMerge(clsx(inputs));
1177
167
  }
1178
- __name(fetchTenantInfo, "fetchTenantInfo");
1179
- var tenantInfo;
1180
- var pendingPromise2 = null;
1181
- function getTenantInfo() {
1182
- if (tenantInfo) {
1183
- return Promise.resolve(tenantInfo);
1184
- }
1185
- if (pendingPromise2) {
1186
- return pendingPromise2;
168
+ __name(clsxWithTw, "clsxWithTw");
169
+ function isPreview() {
170
+ return window.IS_MIAODA_PREVIEW;
171
+ }
172
+ __name(isPreview, "isPreview");
173
+ function normalizeBasePath(basePath) {
174
+ if (!basePath || basePath === "/") {
175
+ return "";
1187
176
  }
1188
- pendingPromise2 = fetchTenantInfo().then((info) => {
1189
- tenantInfo = info;
1190
- return tenantInfo;
1191
- }).finally(() => {
1192
- pendingPromise2 = null;
1193
- });
1194
- return pendingPromise2;
177
+ return basePath.replace(/\/+$/, "");
1195
178
  }
1196
- __name(getTenantInfo, "getTenantInfo");
1197
-
1198
- // src/hooks/useAppInfo.tsx
1199
- import { useEffect, useState } from "react";
179
+ __name(normalizeBasePath, "normalizeBasePath");
180
+ function getWsPath() {
181
+ const rawBasePath = process.env.CLIENT_BASE_PATH || "/";
182
+ const normalizedBasePath = rawBasePath.startsWith("/") ? rawBasePath : `/${rawBasePath}`;
183
+ const basePathWithoutTrailingSlash = normalizedBasePath.endsWith("/") ? normalizedBasePath.slice(0, -1) : normalizedBasePath;
184
+ return `${basePathWithoutTrailingSlash}/ws`;
185
+ }
186
+ __name(getWsPath, "getWsPath");
187
+ function isSparkRuntime() {
188
+ return window._IS_Spark_RUNTIME ?? process.env.runtimeMode === "fullstack";
189
+ }
190
+ __name(isSparkRuntime, "isSparkRuntime");
1200
191
 
1201
192
  // src/integrations/getAppInfo.ts
1202
193
  async function getAppInfo(refresh = false) {
@@ -1267,92 +258,30 @@ var useAppInfo = /* @__PURE__ */ __name(() => {
1267
258
  }, "handleMetaInfoChanged");
1268
259
  handleMetaInfoChanged(void 0, false);
1269
260
  const onUpdate = /* @__PURE__ */ __name((e) => {
1270
- const info = e.detail;
1271
- handleMetaInfoChanged(info);
1272
- }, "onUpdate");
1273
- window.addEventListener("MiaoDaMetaInfoChanged", onUpdate);
1274
- return () => {
1275
- window.removeEventListener("MiaoDaMetaInfoChanged", onUpdate);
1276
- };
1277
- }, []);
1278
- return {
1279
- ...appInfo,
1280
- appName: appInfo.name,
1281
- appLogo: appInfo.avatar
1282
- };
1283
- }, "useAppInfo");
1284
-
1285
- // src/hooks/useCurrentUserProfile.tsx
1286
- import { useEffect as useEffect2, useState as useState2 } from "react";
1287
-
1288
- // src/integrations/getCurrentUserProfile.ts
1289
- function getCurrentUserProfile() {
1290
- return window._userInfo || {};
1291
- }
1292
- __name(getCurrentUserProfile, "getCurrentUserProfile");
1293
-
1294
- // src/utils/url.ts
1295
- function splitWorkspaceUrl(fullUrl) {
1296
- try {
1297
- const url = new URL(fullUrl);
1298
- const pathParts = url.pathname.split("/");
1299
- const workspacesIndex = pathParts.findIndex((part) => part === "workspaces");
1300
- if (workspacesIndex === -1) {
1301
- throw new Error("Invalid workspace URL format");
1302
- }
1303
- const basePathParts = pathParts.slice(0, workspacesIndex);
1304
- const workspace = pathParts[workspacesIndex + 1];
1305
- return {
1306
- baseUrl: `${url.origin}${basePathParts.join("/")}`,
1307
- workspace
261
+ const info = e.detail;
262
+ handleMetaInfoChanged(info);
263
+ }, "onUpdate");
264
+ window.addEventListener("MiaoDaMetaInfoChanged", onUpdate);
265
+ return () => {
266
+ window.removeEventListener("MiaoDaMetaInfoChanged", onUpdate);
1308
267
  };
1309
- } catch (error) {
1310
- console.error("Error splitting workspace URL:", error);
1311
- }
268
+ }, []);
1312
269
  return {
1313
- baseUrl: fullUrl,
1314
- // 兜底给一个,不要给空字符串,不然 createClient 都直接挂了,页面会白屏,体感不太好
1315
- workspace: "workspace"
270
+ ...appInfo,
271
+ appName: appInfo.name,
272
+ appLogo: appInfo.avatar
1316
273
  };
1317
- }
1318
- __name(splitWorkspaceUrl, "splitWorkspaceUrl");
274
+ }, "useAppInfo");
1319
275
 
1320
- // src/integrations/dataloom.ts
1321
- import { createClient } from "@lark-apaas/dataloom";
1322
- var createDataLoomClient = /* @__PURE__ */ __name((url, pat) => {
1323
- const { baseUrl } = url ? splitWorkspaceUrl(url) : {
1324
- baseUrl: ""
1325
- };
1326
- const appId = getAppId() ?? "";
1327
- return createClient(baseUrl, pat ?? "", {
1328
- global: {
1329
- enableDataloomLog: process.env.NODE_ENV !== "production",
1330
- requestRateLimit: process.env.NODE_ENV !== "production" ? 100 : void 0,
1331
- brandName: "miaoda",
1332
- appId
1333
- }
1334
- });
1335
- }, "createDataLoomClient");
1336
- var dataloom = null;
1337
- var pendingPromise3 = null;
1338
- function getDataloom() {
1339
- if (dataloom) {
1340
- return Promise.resolve(dataloom);
1341
- }
1342
- if (pendingPromise3) {
1343
- return pendingPromise3;
1344
- }
1345
- pendingPromise3 = getInitialInfo().then((info) => {
1346
- const DATALOOM_CLIENT_URL = info?.app_runtime_extra?.url;
1347
- const DATALOOM_PAT = info?.app_runtime_extra?.token;
1348
- dataloom = createDataLoomClient(DATALOOM_CLIENT_URL, DATALOOM_PAT);
1349
- return dataloom;
1350
- }).finally(() => {
1351
- pendingPromise3 = null;
1352
- });
1353
- return pendingPromise3;
276
+ // src/hooks/useCurrentUserProfile.tsx
277
+ import { useEffect as useEffect2, useState as useState2 } from "react";
278
+ import { authClient } from "@lark-apaas/auth-sdk";
279
+
280
+ // src/integrations/getCurrentUserProfile.ts
281
+ function getCurrentUserProfile() {
282
+ return window._userInfo || {};
1354
283
  }
1355
- __name(getDataloom, "getDataloom");
284
+ __name(getCurrentUserProfile, "getCurrentUserProfile");
1356
285
 
1357
286
  // src/hooks/useCurrentUserProfile.tsx
1358
287
  function getNameFromArray(nameArray) {
@@ -1378,8 +307,7 @@ var useCurrentUserProfile = /* @__PURE__ */ __name(() => {
1378
307
  useEffect2(() => {
1379
308
  let cancelled = false;
1380
309
  const fetchAndSetUserInfo = /* @__PURE__ */ __name(async () => {
1381
- const dataloom2 = await getDataloom();
1382
- const result = await dataloom2?.service?.session?.getUserInfo();
310
+ const result = await authClient.session.getUserInfo();
1383
311
  if (cancelled) return;
1384
312
  const info = result?.data?.user_info;
1385
313
  const userName = getNameFromArray(info?.name);
@@ -1443,6 +371,7 @@ __name(useIsMobile, "useIsMobile");
1443
371
 
1444
372
  // src/hooks/useLogout.ts
1445
373
  import { useState as useState3 } from "react";
374
+ import { authClient as authClient2 } from "@lark-apaas/auth-sdk";
1446
375
  function useLogout() {
1447
376
  const [isLoading, setIsLoading] = useState3(false);
1448
377
  async function handlerLogout() {
@@ -1452,8 +381,7 @@ function useLogout() {
1452
381
  }
1453
382
  setIsLoading(true);
1454
383
  try {
1455
- const dataloom2 = await getDataloom();
1456
- await dataloom2.service.session.signOut();
384
+ await authClient2.session.signOut();
1457
385
  } catch (error) {
1458
386
  console.error("\u767B\u51FA\u5931\u8D25", error);
1459
387
  } finally {
@@ -1470,11 +398,6 @@ __name(useLogout, "useLogout");
1470
398
 
1471
399
  // src/locales/messages.ts
1472
400
  var messages = {
1473
- // ── Index / 通用 ──────────────────────────────────────────────
1474
- "index.rateLimitError": {
1475
- zh: "\u5E94\u7528\u989D\u5EA6\u5DF2\u8017\u5C3D\uFF0C\u8BF7\u8054\u7CFB\u5E94\u7528\u5F00\u53D1\u8005",
1476
- en: "Application quota exhausted, please contact the app developer"
1477
- },
1478
401
  // ── Safety 组件 ──────────────────────────────────────────────
1479
402
  "safety.badge.label": {
1480
403
  zh: "\u5999\u642D",
@@ -1854,14 +777,24 @@ var Safety = /* @__PURE__ */ __name(() => {
1854
777
  const [badgeLoaded, setBadgeLoaded] = useState4(false);
1855
778
  const timeoutRef = useRef(null);
1856
779
  useEffect3(() => {
1857
- if (process.env.NODE_ENV !== "production") return;
1858
- getTenantInfo().then((data) => {
1859
- setUserinfo(data?.tenant_info ?? null);
1860
- setIsInternetVisible(!!data?.is_internet_visible);
780
+ const appId = getAppId();
781
+ const csrfToken = getCsrfToken() ?? "";
782
+ const csrfHeaders = {
783
+ "X-Suda-Csrf-Token": csrfToken
784
+ };
785
+ const tenantInfoUrl = isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/studio/tenant_info` : `/spark/b/${appId}/tenant_info`;
786
+ fetch(tenantInfoUrl, {
787
+ headers: csrfHeaders
788
+ }).then((res) => res.json()).then((data) => {
789
+ setUserinfo(data?.data?.tenant_info);
790
+ setIsInternetVisible(data?.data?.is_internet_visible);
1861
791
  }).catch(() => {
1862
792
  });
1863
- getInitialInfo().then((info) => {
1864
- const badge = info?.app_info?.show_badge;
793
+ const getPublishedUrl = isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/studio/get_published` : `/spark/b/${appId}/get_published`;
794
+ fetch(getPublishedUrl, {
795
+ headers: csrfHeaders
796
+ }).then((res) => res.json()).then((data) => {
797
+ const badge = data?.data?.app_info?.show_badge;
1865
798
  setShowBadge(badge !== false);
1866
799
  }).catch(() => {
1867
800
  setShowBadge(true);
@@ -2075,92 +1008,6 @@ var QueryProvider = /* @__PURE__ */ __name(({ children, client }) => {
2075
1008
  }, "QueryProvider");
2076
1009
  var QueryProvider_default = QueryProvider;
2077
1010
 
2078
- // src/components/AppContainer/IframeBridge.tsx
2079
- import { useEffect as useEffect4, useCallback, useRef as useRef3, useMemo, createElement } from "react";
2080
- import { useLocation, useNavigate } from "react-router-dom";
2081
-
2082
- // src/hooks/useUpdatingRef.ts
2083
- import { useRef as useRef2 } from "react";
2084
- function useUpdatingRef(value) {
2085
- const ref = useRef2(value);
2086
- ref.current = value;
2087
- return ref;
2088
- }
2089
- __name(useUpdatingRef, "useUpdatingRef");
2090
-
2091
- // src/components/AppContainer/IframeBridge.tsx
2092
- var RouteMessageType = /* @__PURE__ */ (function(RouteMessageType2) {
2093
- RouteMessageType2["RouteChange"] = "RouteChange";
2094
- RouteMessageType2["RouteBack"] = "RouteBack";
2095
- RouteMessageType2["RouteForward"] = "RouteForward";
2096
- return RouteMessageType2;
2097
- })(RouteMessageType || {});
2098
- function isRouteMessageType(type) {
2099
- return Object.values(RouteMessageType).includes(type);
2100
- }
2101
- __name(isRouteMessageType, "isRouteMessageType");
2102
- function IframeBridge() {
2103
- const location = useLocation();
2104
- const navigate = useNavigate();
2105
- const navigateRef = useUpdatingRef(navigate);
2106
- const isActive = useRef3(false);
2107
- const historyBack = useCallback((_payload) => {
2108
- navigateRef.current(-1);
2109
- isActive.current = true;
2110
- }, [
2111
- navigateRef
2112
- ]);
2113
- const historyForward = useCallback((_payload) => {
2114
- navigateRef.current(1);
2115
- isActive.current = true;
2116
- }, [
2117
- navigateRef
2118
- ]);
2119
- const operatorMessage = useMemo(() => ({
2120
- ["RouteBack"]: historyBack,
2121
- ["RouteForward"]: historyForward,
2122
- ["RouteChange"]: navigateRef.current
2123
- }), [
2124
- historyBack,
2125
- historyForward,
2126
- navigateRef
2127
- ]);
2128
- useEffect4(() => {
2129
- if (isActive.current) {
2130
- isActive.current = false;
2131
- return;
2132
- }
2133
- submitPostMessage({
2134
- type: "ChildLocationChange",
2135
- data: location
2136
- });
2137
- }, [
2138
- location
2139
- ]);
2140
- const handleMessage = useCallback((event) => {
2141
- const data = event.data ?? {};
2142
- if (typeof data.type === "string" && isRouteMessageType(data.type)) {
2143
- operatorMessage[data.type](data.data);
2144
- }
2145
- }, [
2146
- operatorMessage
2147
- ]);
2148
- useEffect4(() => {
2149
- window.addEventListener("message", handleMessage);
2150
- return () => {
2151
- window.removeEventListener("message", handleMessage);
2152
- };
2153
- }, [
2154
- handleMessage
2155
- ]);
2156
- return /* @__PURE__ */ createElement("div", {
2157
- style: {
2158
- display: "none"
2159
- }
2160
- });
2161
- }
2162
- __name(IframeBridge, "IframeBridge");
2163
-
2164
1011
  // src/components/AppContainer/utils/tea.ts
2165
1012
  import md5 from "blueimp-md5";
2166
1013
  import sha1 from "crypto-js/sha1";
@@ -2281,7 +1128,7 @@ var TrackKey = /* @__PURE__ */ (function(TrackKey2) {
2281
1128
  // src/components/AppContainer/index.tsx
2282
1129
  var AppContainer = /* @__PURE__ */ __name(({ children }) => {
2283
1130
  useAppInfo();
2284
- useEffect5(() => {
1131
+ useEffect4(() => {
2285
1132
  if (process.env.NODE_ENV === "production") {
2286
1133
  reportTeaEvent({
2287
1134
  trackKey: TrackKey.VIEW,
@@ -2293,7 +1140,7 @@ var AppContainer = /* @__PURE__ */ __name(({ children }) => {
2293
1140
  });
2294
1141
  }
2295
1142
  }, []);
2296
- return /* @__PURE__ */ React4.createElement(React4.Fragment, null, String(process.env.MIAODA_APP_TYPE) !== "7" && /* @__PURE__ */ React4.createElement(safety_default, null), process.env.NODE_ENV !== "production" && /* @__PURE__ */ React4.createElement(MiaodaInspector, null), process.env.NODE_ENV !== "production" && /* @__PURE__ */ React4.createElement(IframeBridge, null), /* @__PURE__ */ React4.createElement(QueryProvider_default, null, children));
1143
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(safety_default, null), /* @__PURE__ */ React4.createElement(QueryProvider_default, null, children));
2297
1144
  }, "AppContainer");
2298
1145
  var AppContainer_default = AppContainer;
2299
1146
 
@@ -2384,67 +1231,13 @@ var PagePlaceholder = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F0
2384
1231
  }, "PagePlaceholder");
2385
1232
  var PagePlaceholder_default = PagePlaceholder;
2386
1233
 
2387
- // src/components/ErrorRender/index.tsx
2388
- import React7, { useEffect as useEffect6 } from "react";
2389
- var ErrorRender = /* @__PURE__ */ __name((props) => {
2390
- const { error, resetErrorBoundary } = props;
2391
- useEffect6(() => {
2392
- if (error) {
2393
- submitPostMessage({
2394
- type: "RenderError",
2395
- data: error
2396
- });
2397
- logger.log({
2398
- level: "error",
2399
- args: [
2400
- "Render Error",
2401
- error
2402
- ],
2403
- meta: {
2404
- type: "render-error",
2405
- 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"
2406
- }
2407
- });
2408
- }
2409
- }, [
2410
- error
2411
- ]);
2412
- useEffect6(() => {
2413
- if (!resetErrorBoundary) return;
2414
- const hmr = getHmrApi();
2415
- if (!hmr) return;
2416
- return hmr.onSuccess(() => {
2417
- const isVite = typeof window !== "undefined" && Boolean(window.__VITE_HMR__);
2418
- if (isVite) {
2419
- window.location.reload();
2420
- } else {
2421
- resetErrorBoundary();
2422
- }
2423
- });
2424
- }, [
2425
- resetErrorBoundary
2426
- ]);
2427
- return /* @__PURE__ */ React7.createElement("div", {
2428
- className: "min-h-screen flex items-center justify-center bg-white"
2429
- }, /* @__PURE__ */ React7.createElement("div", {
2430
- className: "flex flex-col justify-center items-center text-center"
2431
- }, /* @__PURE__ */ React7.createElement("img", {
2432
- src: "https://lf3-static.bytednsdoc.com/obj/eden-cn/ylcylz_fsph_ryhs/ljhwZthlaukjlkulzlp/feisuda/template/illustration_empty_negative_error.svg",
2433
- alt: "render error",
2434
- className: "mb-3 w-[100px]"
2435
- }), /* @__PURE__ */ React7.createElement("p", {
2436
- className: "text-l/[22px] text-[14px] text-[#1F2329] font-medium"
2437
- }, "\u9875\u9762\u51FA\u9519\u4E86")));
2438
- }, "ErrorRender");
2439
- var ErrorRender_default = ErrorRender;
2440
-
2441
1234
  // src/route-components/ActiveLink.tsx
2442
- import React8, { forwardRef, useEffect as useEffect7, useState as useState5 } from "react";
1235
+ import React7, { forwardRef, useEffect as useEffect5, useState as useState5 } from "react";
2443
1236
  import { NavLink } from "react-router-dom";
2444
1237
  var ActiveLink = /* @__PURE__ */ forwardRef(({ to, onClick, className, style, children, ...rest }, ref) => {
2445
1238
  const [currentHash, setCurrentHash] = useState5(() => typeof window !== "undefined" ? window.location.hash : "");
2446
1239
  const isHashRoute = typeof to === "string" && to.startsWith("#");
2447
- useEffect7(() => {
1240
+ useEffect5(() => {
2448
1241
  if (!isHashRoute) return;
2449
1242
  const handleHashChange = /* @__PURE__ */ __name(() => {
2450
1243
  setCurrentHash(window.location.hash);
@@ -2456,7 +1249,7 @@ var ActiveLink = /* @__PURE__ */ forwardRef(({ to, onClick, className, style, ch
2456
1249
  ]);
2457
1250
  const isActive = isHashRoute && currentHash === to;
2458
1251
  if (!isHashRoute) {
2459
- return /* @__PURE__ */ React8.createElement(NavLink, {
1252
+ return /* @__PURE__ */ React7.createElement(NavLink, {
2460
1253
  ref,
2461
1254
  to,
2462
1255
  onClick,
@@ -2497,7 +1290,7 @@ var ActiveLink = /* @__PURE__ */ forwardRef(({ to, onClick, className, style, ch
2497
1290
  isPending: false,
2498
1291
  isTransitioning: false
2499
1292
  }) : children;
2500
- return /* @__PURE__ */ React8.createElement("a", {
1293
+ return /* @__PURE__ */ React7.createElement("a", {
2501
1294
  ref,
2502
1295
  href: to,
2503
1296
  onClick: handleHashClick,
@@ -2509,12 +1302,12 @@ var ActiveLink = /* @__PURE__ */ forwardRef(({ to, onClick, className, style, ch
2509
1302
  ActiveLink.displayName = "ActiveLink";
2510
1303
 
2511
1304
  // src/route-components/NavLink.tsx
2512
- import * as React9 from "react";
2513
- import { NavLink as OriginalNavLink, useLocation as useLocation2, useNavigate as useNavigate2 } from "react-router-dom";
2514
- var NavLink2 = /* @__PURE__ */ React9.forwardRef(({ to, children, className, style, ...props }, ref) => {
1305
+ import * as React8 from "react";
1306
+ import { NavLink as OriginalNavLink, useLocation, useNavigate } from "react-router-dom";
1307
+ var NavLink2 = /* @__PURE__ */ React8.forwardRef(({ to, children, className, style, ...props }, ref) => {
2515
1308
  const isHashLink = typeof to === "string" && to.startsWith("#");
2516
- const location = useLocation2();
2517
- const navigate = useNavigate2();
1309
+ const location = useLocation();
1310
+ const navigate = useNavigate();
2518
1311
  if (isHashLink) {
2519
1312
  const handleClick = /* @__PURE__ */ __name((e) => {
2520
1313
  e.preventDefault();
@@ -2535,7 +1328,7 @@ var NavLink2 = /* @__PURE__ */ React9.forwardRef(({ to, children, className, sty
2535
1328
  const resolvedClassName = typeof className === "function" ? className(renderProps) : className;
2536
1329
  const resolvedStyle = typeof style === "function" ? style(renderProps) : style;
2537
1330
  const { caseSensitive, end, replace, state, preventScrollReset, relative, viewTransition, ...restProps } = props;
2538
- return /* @__PURE__ */ React9.createElement("a", {
1331
+ return /* @__PURE__ */ React8.createElement("a", {
2539
1332
  href: to,
2540
1333
  onClick: handleClick,
2541
1334
  ref,
@@ -2544,7 +1337,7 @@ var NavLink2 = /* @__PURE__ */ React9.forwardRef(({ to, children, className, sty
2544
1337
  ...restProps
2545
1338
  }, typeof children === "function" ? children(renderProps) : children);
2546
1339
  }
2547
- return /* @__PURE__ */ React9.createElement(OriginalNavLink, {
1340
+ return /* @__PURE__ */ React8.createElement(OriginalNavLink, {
2548
1341
  to,
2549
1342
  ref,
2550
1343
  className,
@@ -2559,7 +1352,7 @@ var NavLink2 = /* @__PURE__ */ React9.forwardRef(({ to, children, className, sty
2559
1352
  NavLink2.displayName = "NavLink";
2560
1353
 
2561
1354
  // src/route-components/UniversalLink.tsx
2562
- import React10 from "react";
1355
+ import React9 from "react";
2563
1356
  import { Link as RouterLink } from "react-router-dom";
2564
1357
  function isInternalRoute(to) {
2565
1358
  return !to.startsWith("#") && !to.startsWith("http://") && !to.startsWith("https://") && !to.startsWith("//");
@@ -2569,15 +1362,15 @@ function isExternalLink(to) {
2569
1362
  return to.startsWith("http://") || to.startsWith("https://") || to.startsWith("//");
2570
1363
  }
2571
1364
  __name(isExternalLink, "isExternalLink");
2572
- var UniversalLink = /* @__PURE__ */ React10.forwardRef(/* @__PURE__ */ __name(function UniversalLink2({ to, ...props }, ref) {
1365
+ var UniversalLink = /* @__PURE__ */ React9.forwardRef(/* @__PURE__ */ __name(function UniversalLink2({ to, ...props }, ref) {
2573
1366
  if (isInternalRoute(to)) {
2574
- return /* @__PURE__ */ React10.createElement(RouterLink, {
1367
+ return /* @__PURE__ */ React9.createElement(RouterLink, {
2575
1368
  to,
2576
1369
  ref,
2577
1370
  ...props
2578
1371
  });
2579
1372
  }
2580
- return /* @__PURE__ */ React10.createElement("a", {
1373
+ return /* @__PURE__ */ React9.createElement("a", {
2581
1374
  href: to,
2582
1375
  ref,
2583
1376
  ...props,
@@ -2723,6 +1516,45 @@ function getEnvPath() {
2723
1516
  }
2724
1517
  __name(getEnvPath, "getEnvPath");
2725
1518
 
1519
+ // src/utils/safeStringify.ts
1520
+ function safeStringify(obj) {
1521
+ const seen = /* @__PURE__ */ new Set();
1522
+ try {
1523
+ return JSON.stringify(obj, (_key, value) => {
1524
+ if (typeof value === "object" && value !== null) {
1525
+ if (seen.has(value)) {
1526
+ return "[Circular]";
1527
+ }
1528
+ seen.add(value);
1529
+ }
1530
+ if (typeof value === "bigint") {
1531
+ return value.toString();
1532
+ }
1533
+ if (value instanceof Date) {
1534
+ return value.toISOString();
1535
+ }
1536
+ if (value instanceof Map) {
1537
+ return Object.fromEntries(value);
1538
+ }
1539
+ if (value instanceof Set) {
1540
+ return Array.from(value);
1541
+ }
1542
+ if (typeof value === "undefined") {
1543
+ return "undefined";
1544
+ }
1545
+ if (typeof value === "symbol") {
1546
+ return value.toString();
1547
+ }
1548
+ return value;
1549
+ });
1550
+ } catch {
1551
+ return "";
1552
+ } finally {
1553
+ seen.clear();
1554
+ }
1555
+ }
1556
+ __name(safeStringify, "safeStringify");
1557
+
2726
1558
  // src/utils/getAxiosForBackend.ts
2727
1559
  import axios2 from "axios";
2728
1560
  var axiosInstance;
@@ -2802,93 +1634,73 @@ function getAxiosForBackend() {
2802
1634
  __name(getAxiosForBackend, "getAxiosForBackend");
2803
1635
  var axiosForBackend = getAxiosForBackend();
2804
1636
 
2805
- // src/integrations/capabilityClient.ts
2806
- import { createClient as createClient2 } from "@lark-apaas/client-capability";
2807
-
2808
- // src/components/ui/toast.tsx
2809
- function showToast2(message, duration = 3e3) {
2810
- return new Promise((resolve) => {
2811
- const toast = document.createElement("div");
2812
- const iconSvg = `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2813
- <path fill-rule="evenodd" clip-rule="evenodd" d="M8 1.333a6.667 6.667 0 1 1 0 13.334A6.667 6.667 0 0 1 8 1.333ZM8 10a.667.667 0 1 0 0 1.333A.667.667 0 0 0 8 10Zm0-5.333a.667.667 0 0 0-.667.666v3.334a.667.667 0 0 0 1.334 0V5.333A.667.667 0 0 0 8 4.667Z" fill="#ff811a"/>
2814
- </svg>`;
2815
- const iconWrapper = document.createElement("span");
2816
- iconWrapper.innerHTML = iconSvg;
2817
- Object.assign(iconWrapper.style, {
2818
- display: "flex",
2819
- alignItems: "center",
2820
- marginRight: "8px",
2821
- flexShrink: "0"
2822
- });
2823
- const textWrapper = document.createElement("span");
2824
- textWrapper.textContent = message;
2825
- toast.appendChild(iconWrapper);
2826
- toast.appendChild(textWrapper);
2827
- Object.assign(toast.style, {
2828
- position: "fixed",
2829
- top: "32px",
2830
- left: "50%",
2831
- transform: "translate(-50%, -50%)",
2832
- display: "flex",
2833
- alignItems: "center",
2834
- padding: "12px 16px",
2835
- backgroundColor: "#fff",
2836
- color: "#1f2329",
2837
- border: "1px solid #dee0e3",
2838
- borderRadius: "6px",
2839
- fontSize: "14px",
2840
- lineHeight: "1.5",
2841
- zIndex: "99999",
2842
- maxWidth: "80vw",
2843
- wordBreak: "break-word",
2844
- boxShadow: "0 4px 8px rgba(0, 0, 0, 0.03), 0 3px 6px rgba(0, 0, 0, 0.05), 0 6px 18px rgba(0, 0, 0, 0.03)",
2845
- opacity: "0",
2846
- transition: "opacity 0.3s ease"
2847
- });
2848
- document.body.appendChild(toast);
2849
- requestAnimationFrame(() => {
2850
- toast.style.opacity = "1";
2851
- });
2852
- setTimeout(() => {
2853
- toast.style.opacity = "0";
2854
- setTimeout(() => {
2855
- document.body.removeChild(toast);
2856
- resolve();
2857
- }, 300);
2858
- }, duration);
2859
- });
1637
+ // src/utils/url.ts
1638
+ function splitWorkspaceUrl(fullUrl) {
1639
+ try {
1640
+ const url = new URL(fullUrl);
1641
+ const pathParts = url.pathname.split("/");
1642
+ const workspacesIndex = pathParts.findIndex((part) => part === "workspaces");
1643
+ if (workspacesIndex === -1) {
1644
+ throw new Error("Invalid workspace URL format");
1645
+ }
1646
+ const basePathParts = pathParts.slice(0, workspacesIndex);
1647
+ const workspace = pathParts[workspacesIndex + 1];
1648
+ return {
1649
+ baseUrl: `${url.origin}${basePathParts.join("/")}`,
1650
+ workspace
1651
+ };
1652
+ } catch (error) {
1653
+ console.error("Error splitting workspace URL:", error);
1654
+ }
1655
+ return {
1656
+ baseUrl: fullUrl,
1657
+ // 兜底给一个,不要给空字符串,不然 createClient 都直接挂了,页面会白屏,体感不太好
1658
+ workspace: "workspace"
1659
+ };
2860
1660
  }
2861
- __name(showToast2, "showToast");
1661
+ __name(splitWorkspaceUrl, "splitWorkspaceUrl");
2862
1662
 
2863
- // src/integrations/capabilityClient.ts
2864
- var _appId = getAppId();
2865
- var _archType = process.env.MIAODA_APP_ARCH_TYPE;
2866
- var _isFrontendOnly = _archType === "2" || _archType === "3" || _archType === "4";
2867
- var capabilityClient = createClient2({
2868
- baseURL: normalizeBasePath(process.env.CLIENT_BASE_PATH ?? "/"),
2869
- acquireUploadUrl: `/app/${_appId}/__runtime__/api/v1/studio/plugins/tmp_files/acquire_upload_url`,
2870
- acquireDownloadUrl: `/app/${_appId}/__runtime__/api/v1/studio/plugins/tmp_files/acquire_download_url`,
2871
- fetchOptions: {
2872
- headers: {
2873
- "X-Suda-Csrf-Token": window.csrfToken ?? ""
2874
- }
2875
- },
2876
- logger,
2877
- onRateLimitError: /* @__PURE__ */ __name(() => {
2878
- showToast2(t("index.rateLimitError"));
2879
- }, "onRateLimitError"),
2880
- ..._isFrontendOnly ? {
2881
- central: {
2882
- enabled: true,
2883
- // window.appId 由妙搭沙箱 / 线上环境注入;非妙搭场景下 capability 调用本身不可用
2884
- appId: _appId ?? ""
1663
+ // src/integrations/dataloom.ts
1664
+ import { createClient } from "@lark-apaas/dataloom";
1665
+ import { authClient as authClient3 } from "@lark-apaas/auth-sdk";
1666
+ var createDataLoomClient = /* @__PURE__ */ __name((url, pat) => {
1667
+ const { baseUrl } = url ? splitWorkspaceUrl(url) : {
1668
+ baseUrl: ""
1669
+ };
1670
+ const appId = getAppId() ?? "";
1671
+ return createClient(baseUrl, pat ?? "", {
1672
+ global: {
1673
+ enableDataloomLog: process.env.NODE_ENV !== "production",
1674
+ requestRateLimit: process.env.NODE_ENV !== "production" ? 100 : void 0,
1675
+ brandName: "miaoda",
1676
+ appId,
1677
+ accountServices: {
1678
+ user: authClient3.user,
1679
+ session: authClient3.session
1680
+ }
2885
1681
  }
2886
- } : {}
2887
- });
2888
-
2889
- // src/trace/index.ts
2890
- import { observable as observable3 } from "@lark-apaas/observable-web";
2891
- var trace = /* @__PURE__ */ __name((...args) => observable3.trace(...args), "trace");
1682
+ });
1683
+ }, "createDataLoomClient");
1684
+ var dataloom = null;
1685
+ var pendingPromise2 = null;
1686
+ function getDataloom() {
1687
+ if (dataloom) {
1688
+ return Promise.resolve(dataloom);
1689
+ }
1690
+ if (pendingPromise2) {
1691
+ return pendingPromise2;
1692
+ }
1693
+ pendingPromise2 = getInitialInfo().then((info) => {
1694
+ const DATALOOM_CLIENT_URL = info?.app_runtime_extra?.url;
1695
+ const DATALOOM_PAT = info?.app_runtime_extra?.token;
1696
+ dataloom = createDataLoomClient(DATALOOM_CLIENT_URL, DATALOOM_PAT);
1697
+ return dataloom;
1698
+ }).finally(() => {
1699
+ pendingPromise2 = null;
1700
+ });
1701
+ return pendingPromise2;
1702
+ }
1703
+ __name(getDataloom, "getDataloom");
2892
1704
 
2893
1705
  // src/constants/img-resources/avatar.ts
2894
1706
  var avatar_exports = {};
@@ -3049,7 +1861,6 @@ var abstractArt3dRenderingCoverImg6 = "https://lf3-static.bytednsdoc.com/obj/ede
3049
1861
  export {
3050
1862
  ActiveLink,
3051
1863
  AppContainer_default as AppContainer,
3052
- ErrorRender_default as ErrorRender,
3053
1864
  NavLink2 as NavLink,
3054
1865
  PagePlaceholder_default as PagePlaceholder,
3055
1866
  QueryProvider_default as QueryProvider,
@@ -3059,7 +1870,6 @@ export {
3059
1870
  avatar_exports as avatarImages,
3060
1871
  axiosForBackend,
3061
1872
  banner_exports as bannerImages,
3062
- capabilityClient,
3063
1873
  clsxWithTw,
3064
1874
  copyToClipboard,
3065
1875
  cover_exports as coverImages,
@@ -3072,18 +1882,15 @@ export {
3072
1882
  getEnvPath,
3073
1883
  getWsPath,
3074
1884
  initAxiosConfig,
3075
- initObservable,
3076
1885
  isIOS,
3077
1886
  isIpad,
3078
1887
  isMobile,
3079
1888
  isPreview,
3080
- logger,
3081
1889
  normalizeBasePath,
3082
1890
  reportTeaEvent,
3083
1891
  resolveAppUrl,
3084
1892
  safeStringify,
3085
1893
  scopedStorage,
3086
- trace,
3087
1894
  useAppInfo,
3088
1895
  useCurrentUserProfile,
3089
1896
  useIsMobile,