@lark-apaas/client-toolkit 1.2.17-alpha.1 → 1.2.17-alpha.10

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.
Files changed (105) hide show
  1. package/lib/antd-table.d.ts +2 -2
  2. package/lib/apis/aily-chat.d.ts +2 -0
  3. package/lib/apis/aily-chat.js +2 -0
  4. package/lib/apis/components/ActiveLink.d.ts +26 -0
  5. package/lib/apis/components/ActiveLink.js +66 -0
  6. package/lib/apis/hooks/useScrollReveal.d.ts +1 -0
  7. package/lib/apis/hooks/useScrollReveal.js +1 -0
  8. package/lib/apis/utils/getEnv.d.ts +1 -0
  9. package/lib/apis/utils/getEnv.js +2 -0
  10. package/lib/apis/utils/resolveAppUrl.d.ts +1 -0
  11. package/lib/apis/utils/resolveAppUrl.js +2 -0
  12. package/lib/apis/utils/scopedStorage.d.ts +1 -0
  13. package/lib/apis/utils/scopedStorage.js +2 -0
  14. package/lib/auth.d.ts +1 -0
  15. package/lib/auth.js +2 -0
  16. package/lib/components/AppContainer/IframeBridge.d.ts +0 -1
  17. package/lib/components/AppContainer/IframeBridge.js +1 -20
  18. package/lib/components/AppContainer/RoutePatternTracker.d.ts +5 -0
  19. package/lib/components/AppContainer/RoutePatternTracker.js +13 -0
  20. package/lib/components/AppContainer/api-proxy/core.js +2 -1
  21. package/lib/components/AppContainer/index.d.ts +9 -2
  22. package/lib/components/AppContainer/index.js +23 -71
  23. package/lib/components/AppContainer/safety.js +5 -2
  24. package/lib/components/AppContainer/utils/childApi.js +1 -0
  25. package/lib/components/AppContainer/utils/getLarkUser.js +4 -2
  26. package/lib/components/AppContainer/utils/observable.js +7 -1
  27. package/lib/components/AppContainer/utils/tea.js +1 -1
  28. package/lib/components/ErrorRender/index.js +5 -11
  29. package/lib/components/User/UserSelect.js +1 -13
  30. package/lib/components/theme/index.d.ts +0 -1
  31. package/lib/components/theme/index.js +0 -1
  32. package/lib/components/theme/util.d.ts +0 -2
  33. package/lib/components/theme/util.js +0 -108
  34. package/lib/components/ui/toast.d.ts +2 -0
  35. package/lib/components/ui/toast.js +53 -0
  36. package/lib/hooks/index.d.ts +1 -0
  37. package/lib/hooks/index.js +1 -0
  38. package/lib/hooks/useCurrentUserProfile.js +22 -29
  39. package/lib/hooks/useLogout.js +2 -17
  40. package/lib/hooks/useScrollReveal.d.ts +61 -0
  41. package/lib/hooks/useScrollReveal.js +37 -0
  42. package/lib/index.js +12 -1
  43. package/lib/integrations/dataloom.d.ts +3 -1
  44. package/lib/integrations/dataloom.js +18 -10
  45. package/lib/integrations/services/DepartmentService.js +3 -2
  46. package/lib/integrations/services/UserProfileService.js +3 -2
  47. package/lib/integrations/services/UserService.js +4 -3
  48. package/lib/integrations/services/types.d.ts +1 -0
  49. package/lib/logger/batch-logger.js +3 -2
  50. package/lib/logger/intercept-global-error.js +34 -25
  51. package/lib/logger/log-types.d.ts +4 -4
  52. package/lib/logger/log-types.js +1 -1
  53. package/lib/logger/selected-logs.js +1 -2
  54. package/lib/runtime/axios.d.ts +5 -0
  55. package/lib/runtime/axios.js +2 -0
  56. package/lib/runtime/dayjs.d.ts +5 -0
  57. package/lib/runtime/dayjs.js +2 -0
  58. package/lib/runtime/iframe-bridge.d.ts +11 -0
  59. package/lib/runtime/iframe-bridge.js +29 -0
  60. package/lib/runtime/index.d.ts +24 -0
  61. package/lib/runtime/index.js +17 -0
  62. package/lib/runtime/observable.d.ts +5 -0
  63. package/lib/runtime/observable.js +2 -0
  64. package/lib/runtime/react-devtools-hook.d.ts +19 -0
  65. package/lib/runtime/react-devtools-hook.js +20 -0
  66. package/lib/runtime/server-log.d.ts +5 -0
  67. package/lib/runtime/server-log.js +41 -0
  68. package/lib/runtime/styles.d.ts +5 -0
  69. package/lib/runtime/styles.js +1 -0
  70. package/lib/theme-layer.css +2 -1
  71. package/lib/utils/apiPath.d.ts +5 -0
  72. package/lib/utils/apiPath.js +5 -0
  73. package/lib/utils/axiosConfig.js +70 -5
  74. package/lib/utils/getAppId.d.ts +2 -4
  75. package/lib/utils/getAppId.js +2 -9
  76. package/lib/utils/getInitialInfo.d.ts +4 -3
  77. package/lib/utils/getInitialInfo.js +17 -8
  78. package/lib/utils/getParentOrigin.js +12 -2
  79. package/lib/utils/getUserProfile.js +4 -12
  80. package/lib/utils/hmr-api.d.ts +39 -0
  81. package/lib/utils/hmr-api.js +36 -0
  82. package/lib/utils/module-hot.d.ts +9 -5
  83. package/lib/utils/module-hot.js +9 -10
  84. package/lib/utils/postMessage.d.ts +0 -1
  85. package/lib/utils/postMessage.js +19 -6
  86. package/lib/utils/requestManager.js +1 -3
  87. package/lib/utils/resolveAppUrl.d.ts +27 -0
  88. package/lib/utils/resolveAppUrl.js +19 -0
  89. package/lib/utils/routePattern.d.ts +10 -0
  90. package/lib/utils/routePattern.js +45 -0
  91. package/lib/utils/scopedStorage.d.ts +5 -0
  92. package/lib/utils/scopedStorage.js +46 -0
  93. package/package.json +9 -8
  94. package/lib/apis/tools/generateImage.d.ts +0 -1
  95. package/lib/apis/tools/generateImage.js +0 -1
  96. package/lib/apis/tools/generateTextStream.d.ts +0 -1
  97. package/lib/apis/tools/generateTextStream.js +0 -1
  98. package/lib/components/AppContainer/utils/listenHot.d.ts +0 -1
  99. package/lib/components/AppContainer/utils/listenHot.js +0 -57
  100. package/lib/components/theme/ui-config.d.ts +0 -1
  101. package/lib/components/theme/ui-config.js +0 -2
  102. package/lib/integrations/generateImage.d.ts +0 -1
  103. package/lib/integrations/generateImage.js +0 -47
  104. package/lib/integrations/generateTextStream.d.ts +0 -21
  105. package/lib/integrations/generateTextStream.js +0 -98
@@ -0,0 +1,2 @@
1
+ /** 显示 toast 提示(兼容 PC/移动端) */
2
+ export declare function showToast(message: string, duration?: number): Promise<void>;
@@ -0,0 +1,53 @@
1
+ function showToast(message, duration = 3000) {
2
+ return new Promise((resolve)=>{
3
+ const toast = document.createElement('div');
4
+ const iconSvg = `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
5
+ <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"/>
6
+ </svg>`;
7
+ const iconWrapper = document.createElement('span');
8
+ iconWrapper.innerHTML = iconSvg;
9
+ Object.assign(iconWrapper.style, {
10
+ display: 'flex',
11
+ alignItems: 'center',
12
+ marginRight: '8px',
13
+ flexShrink: '0'
14
+ });
15
+ const textWrapper = document.createElement('span');
16
+ textWrapper.textContent = message;
17
+ toast.appendChild(iconWrapper);
18
+ toast.appendChild(textWrapper);
19
+ Object.assign(toast.style, {
20
+ position: 'fixed',
21
+ top: '32px',
22
+ left: '50%',
23
+ transform: 'translate(-50%, -50%)',
24
+ display: 'flex',
25
+ alignItems: 'center',
26
+ padding: '12px 16px',
27
+ backgroundColor: '#fff',
28
+ color: '#1f2329',
29
+ border: '1px solid #dee0e3',
30
+ borderRadius: '6px',
31
+ fontSize: '14px',
32
+ lineHeight: '1.5',
33
+ zIndex: '99999',
34
+ maxWidth: '80vw',
35
+ wordBreak: 'break-word',
36
+ 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)',
37
+ opacity: '0',
38
+ transition: 'opacity 0.3s ease'
39
+ });
40
+ document.body.appendChild(toast);
41
+ requestAnimationFrame(()=>{
42
+ toast.style.opacity = '1';
43
+ });
44
+ setTimeout(()=>{
45
+ toast.style.opacity = '0';
46
+ setTimeout(()=>{
47
+ document.body.removeChild(toast);
48
+ resolve();
49
+ }, 300);
50
+ }, duration);
51
+ });
52
+ }
53
+ export { showToast };
@@ -2,3 +2,4 @@ export * from './useAppInfo';
2
2
  export * from './useCurrentUserProfile';
3
3
  export * from './useIsMobile';
4
4
  export * from './useLogout';
5
+ export * from './useScrollReveal';
@@ -2,3 +2,4 @@ export * from "./useAppInfo.js";
2
2
  export * from "./useCurrentUserProfile.js";
3
3
  export * from "./useIsMobile.js";
4
4
  export * from "./useLogout.js";
5
+ export * from "./useScrollReveal.js";
@@ -19,37 +19,29 @@ function getCompatibilityUserProfile() {
19
19
  const useCurrentUserProfile = ()=>{
20
20
  const [userInfo, setUserInfo] = useState(()=>getCompatibilityUserProfile());
21
21
  useEffect(()=>{
22
+ let cancelled = false;
23
+ const fetchAndSetUserInfo = async ()=>{
24
+ const dataloom = await getDataloom();
25
+ const result = await dataloom?.service?.session?.getUserInfo();
26
+ if (cancelled) return;
27
+ const info = result?.data?.user_info;
28
+ const userName = getNameFromArray(info?.name);
29
+ const newUserInfo = {
30
+ user_id: info?.user_id?.toString(),
31
+ email: info?.email,
32
+ name: userName,
33
+ avatar: info?.avatar?.image?.large,
34
+ userName: userName,
35
+ userAvatar: info?.avatar?.image?.large
36
+ };
37
+ if ('development' === process.env.NODE_ENV) logger.info('MiaoDaMetaInfoChanged', newUserInfo);
38
+ setUserInfo(newUserInfo);
39
+ };
22
40
  let handleMetaInfoChanged;
23
41
  if (isSparkRuntime()) {
24
- (async ()=>{
25
- const dataloom = await getDataloom();
26
- const result = await dataloom?.service?.session?.getUserInfo();
27
- const userInfo = result?.data?.user_info;
28
- const userName = getNameFromArray(userInfo?.name);
29
- setUserInfo({
30
- user_id: userInfo?.user_id?.toString(),
31
- email: userInfo?.email,
32
- name: userName,
33
- avatar: userInfo?.avatar?.image?.large,
34
- userName: userName,
35
- userAvatar: userInfo?.avatar?.image?.large
36
- });
37
- })();
38
- handleMetaInfoChanged = async ()=>{
39
- const dataloom = await getDataloom();
40
- const result = await dataloom?.service?.session?.getUserInfo();
41
- const userInfo = result?.data?.user_info;
42
- const userName = getNameFromArray(userInfo?.name);
43
- const newUserInfo = {
44
- user_id: userInfo?.user_id?.toString(),
45
- email: userInfo?.email,
46
- name: userName,
47
- avatar: userInfo?.avatar?.image?.large,
48
- userName: userName,
49
- userAvatar: userInfo?.avatar?.image?.large
50
- };
51
- if ('development' === process.env.NODE_ENV) logger.info('MiaoDaMetaInfoChanged', newUserInfo);
52
- setUserInfo(newUserInfo);
42
+ fetchAndSetUserInfo();
43
+ handleMetaInfoChanged = ()=>{
44
+ fetchAndSetUserInfo();
53
45
  };
54
46
  } else handleMetaInfoChanged = ()=>{
55
47
  if ('development' === process.env.NODE_ENV) logger.info('MiaoDaMetaInfoChanged', getCompatibilityUserProfile());
@@ -57,6 +49,7 @@ const useCurrentUserProfile = ()=>{
57
49
  };
58
50
  window.addEventListener('MiaoDaMetaInfoChanged', handleMetaInfoChanged);
59
51
  return ()=>{
52
+ cancelled = true;
60
53
  window.removeEventListener('MiaoDaMetaInfoChanged', handleMetaInfoChanged);
61
54
  };
62
55
  }, []);
@@ -1,28 +1,13 @@
1
1
  import { useState } from "react";
2
2
  import { getDataloom } from "../integrations/dataloom.js";
3
- import { isSparkRuntime } from "../utils/utils.js";
4
3
  function useLogout() {
5
4
  const [isLoading, setIsLoading] = useState(false);
6
5
  async function handlerLogout() {
7
6
  if ('production' !== process.env.NODE_ENV) return void console.log('只有生产环境才执行登出');
8
- if (isSparkRuntime()) {
9
- setIsLoading(true);
10
- try {
11
- const dataloom = await getDataloom();
12
- await dataloom.service.session.signOut();
13
- } catch (error) {
14
- console.error('登出失败', error);
15
- } finally{
16
- setIsLoading(false);
17
- }
18
- return;
19
- }
20
7
  setIsLoading(true);
21
8
  try {
22
- await fetch('/ai/api/ui/page/logout', {
23
- method: 'GET'
24
- });
25
- window.location.reload();
9
+ const dataloom = await getDataloom();
10
+ await dataloom.service.session.signOut();
26
11
  } catch (error) {
27
12
  console.error('登出失败', error);
28
13
  } finally{
@@ -0,0 +1,61 @@
1
+ import { RefObject } from 'react';
2
+ /**
3
+ * Options for useScrollReveal hook
4
+ */
5
+ export interface UseScrollRevealOptions<T extends HTMLElement = HTMLElement> {
6
+ /** Ref to the container element to scope the query (default: document.body) */
7
+ containerRef?: RefObject<T | null>;
8
+ /** IntersectionObserver threshold - element visibility percentage to trigger (default: 0.1) */
9
+ threshold?: number;
10
+ /** IntersectionObserver rootMargin - margin around root (default: '0px 0px -50px 0px') */
11
+ rootMargin?: string;
12
+ /** CSS class to add when element becomes visible (default: 'visible') */
13
+ visibleClass?: string;
14
+ /** CSS selector for elements to observe (default: '.scroll-reveal') */
15
+ selector?: string;
16
+ }
17
+ /**
18
+ * Hook to enable scroll reveal animations using IntersectionObserver.
19
+ *
20
+ * Observes elements with the specified selector and adds a visibility class
21
+ * when they enter the viewport.
22
+ *
23
+ * @param options - Configuration options
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * // Usage without parameters (queries entire document.body)
28
+ * import { useScrollReveal } from '@lark-apaas/client-toolkit/hooks/useScrollReveal';
29
+ *
30
+ * function MyComponent() {
31
+ * useScrollReveal();
32
+ *
33
+ * return <div className="scroll-reveal">I will fade in on scroll!</div>;
34
+ * }
35
+ * ```
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * // Usage with container ref
40
+ * import { useRef } from 'react';
41
+ * import { useScrollReveal } from '@lark-apaas/client-toolkit/hooks/useScrollReveal';
42
+ *
43
+ * function MyComponent() {
44
+ * const containerRef = useRef<HTMLDivElement>(null);
45
+ * useScrollReveal({ containerRef });
46
+ *
47
+ * return (
48
+ * <div ref={containerRef}>
49
+ * <div className="scroll-reveal">I will fade in on scroll!</div>
50
+ * </div>
51
+ * );
52
+ * }
53
+ * ```
54
+ *
55
+ * @example
56
+ * ```tsx
57
+ * // Usage with custom options
58
+ * useScrollReveal({ threshold: 0.2, visibleClass: 'animate-in' });
59
+ * ```
60
+ */
61
+ export declare function useScrollReveal<T extends HTMLElement = HTMLElement>(options?: UseScrollRevealOptions<T>): void;
@@ -0,0 +1,37 @@
1
+ import { useEffect } from "react";
2
+ const DEFAULT_OPTIONS = {
3
+ threshold: 0.1,
4
+ rootMargin: '0px 0px -50px 0px',
5
+ visibleClass: 'visible',
6
+ selector: '.scroll-reveal'
7
+ };
8
+ function useScrollReveal(options) {
9
+ const { containerRef, threshold, rootMargin, visibleClass, selector } = {
10
+ ...DEFAULT_OPTIONS,
11
+ ...options
12
+ };
13
+ useEffect(()=>{
14
+ const container = containerRef?.current ?? document.body;
15
+ if (!container) return;
16
+ const observer = new IntersectionObserver((entries)=>{
17
+ entries.forEach((entry)=>{
18
+ if (entry.isIntersecting) entry.target.classList.add(visibleClass);
19
+ });
20
+ }, {
21
+ threshold,
22
+ rootMargin
23
+ });
24
+ const elements = container.querySelectorAll(selector);
25
+ elements.forEach((el)=>observer.observe(el));
26
+ return ()=>{
27
+ observer.disconnect();
28
+ };
29
+ }, [
30
+ containerRef,
31
+ threshold,
32
+ rootMargin,
33
+ visibleClass,
34
+ selector
35
+ ]);
36
+ }
37
+ export { useScrollReveal };
package/lib/index.js CHANGED
@@ -1,15 +1,26 @@
1
1
  import { createClient } from "@lark-apaas/client-capability";
2
2
  import { normalizeBasePath } from "./utils/utils.js";
3
+ import { getAppId } from "./utils/getAppId.js";
4
+ import { isNewPathEnabled } from "./utils/apiPath.js";
3
5
  import { logger } from "./logger/index.js";
6
+ import { showToast } from "./components/ui/toast.js";
4
7
  import { version } from "../package.json";
8
+ const _appId = getAppId();
9
+ const _acquireUploadUrl = isNewPathEnabled() ? `/app/${_appId}/__runtime__/api/v1/studio/plugins/tmp_files/acquire_upload_url` : "/af/api/v1/studio/plugins/tmp_files/acquire_upload_url";
10
+ const _acquireDownloadUrl = isNewPathEnabled() ? `/app/${_appId}/__runtime__/api/v1/studio/plugins/tmp_files/acquire_download_url` : "/af/api/v1/studio/plugins/tmp_files/acquire_download_url";
5
11
  const capabilityClient = createClient({
6
12
  baseURL: normalizeBasePath(process.env.CLIENT_BASE_PATH),
13
+ acquireUploadUrl: _acquireUploadUrl,
14
+ acquireDownloadUrl: _acquireDownloadUrl,
7
15
  fetchOptions: {
8
16
  headers: {
9
17
  'X-Suda-Csrf-Token': window.csrfToken ?? ''
10
18
  }
11
19
  },
12
- logger: logger
20
+ logger: logger,
21
+ onRateLimitError: ()=>{
22
+ showToast('应用额度已耗尽,请联系应用开发者');
23
+ }
13
24
  });
14
25
  const src = {
15
26
  version: version
@@ -1,2 +1,4 @@
1
+ declare const createDataLoomClient: (url?: string, pat?: string) => import("@data-loom/js").DataloomClient<any, "public", any>;
1
2
  /** 获取dataloom实例 */
2
- export declare function getDataloom(): Promise<import("@data-loom/js").DataloomClient<any, "public", any>>;
3
+ export declare function getDataloom(): Promise<ReturnType<typeof createDataLoomClient>>;
4
+ export {};
@@ -3,9 +3,11 @@ import { createClient } from "@data-loom/js";
3
3
  import { getAppId } from "../utils/getAppId.js";
4
4
  import { getInitialInfo } from "../utils/getInitialInfo.js";
5
5
  const createDataLoomClient = (url, pat)=>{
6
- if (!url) return null;
7
- const { baseUrl, workspace } = splitWorkspaceUrl(url);
8
- const appId = getAppId(window.location.pathname);
6
+ const { baseUrl, workspace } = url ? splitWorkspaceUrl(url) : {
7
+ baseUrl: '',
8
+ workspace: ''
9
+ };
10
+ const appId = getAppId();
9
11
  return createClient(baseUrl, pat, workspace, {
10
12
  global: {
11
13
  enableDataloomLog: 'production' !== process.env.NODE_ENV,
@@ -21,12 +23,18 @@ const createDataLoomClient = (url, pat)=>{
21
23
  });
22
24
  };
23
25
  let dataloom = null;
24
- async function getDataloom() {
25
- if (dataloom) return dataloom;
26
- const info = await getInitialInfo();
27
- const DATALOOM_CLIENT_URL = info?.app_runtime_extra?.url;
28
- const DATALOOM_PAT = info?.app_runtime_extra?.token;
29
- dataloom = createDataLoomClient(DATALOOM_CLIENT_URL, DATALOOM_PAT);
30
- return dataloom;
26
+ let pendingPromise = null;
27
+ function getDataloom() {
28
+ if (dataloom) return Promise.resolve(dataloom);
29
+ if (pendingPromise) return pendingPromise;
30
+ pendingPromise = getInitialInfo().then((info)=>{
31
+ const DATALOOM_CLIENT_URL = info?.app_runtime_extra?.url;
32
+ const DATALOOM_PAT = info?.app_runtime_extra?.token;
33
+ dataloom = createDataLoomClient(DATALOOM_CLIENT_URL, DATALOOM_PAT);
34
+ return dataloom;
35
+ }).finally(()=>{
36
+ pendingPromise = null;
37
+ });
38
+ return pendingPromise;
31
39
  }
32
40
  export { getDataloom };
@@ -1,7 +1,8 @@
1
1
  import { getAppId } from "../../utils/getAppId.js";
2
+ import { isNewPathEnabled } from "../../utils/apiPath.js";
2
3
  const DEFAULT_CONFIG = {
3
- getAppId: ()=>getAppId(window.location.pathname),
4
- searchDepartmentUrl: (appId)=>`/af/app/${appId}/runtime/api/v1/account/search_department`
4
+ getAppId: ()=>getAppId(),
5
+ searchDepartmentUrl: (appId)=>isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/account/search_department` : `/af/app/${appId}/runtime/api/v1/account/search_department`
5
6
  };
6
7
  class DepartmentService {
7
8
  config;
@@ -1,11 +1,12 @@
1
1
  import { getAppId } from "../../utils/getAppId.js";
2
+ import { isNewPathEnabled } from "../../utils/apiPath.js";
2
3
  const CDN_HOST = 'https://lf3-static.bytednsdoc.com';
3
4
  function getAssetsUrl(path) {
4
5
  return `${CDN_HOST}${path}`;
5
6
  }
6
7
  const DEFAULT_CONFIG = {
7
- getAppId: ()=>getAppId(window.location.pathname),
8
- userProfileUrl: (appId)=>`/af/app/${appId}/runtime/api/v1/account/user_profile`
8
+ getAppId: ()=>getAppId(),
9
+ userProfileUrl: (appId)=>isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/account/user_profile` : `/af/app/${appId}/runtime/api/v1/account/user_profile`
9
10
  };
10
11
  class UserProfileService {
11
12
  config;
@@ -1,8 +1,9 @@
1
1
  import { getAppId } from "../../utils/getAppId.js";
2
+ import { isNewPathEnabled } from "../../utils/apiPath.js";
2
3
  const DEFAULT_CONFIG = {
3
- getAppId: ()=>getAppId(window.location.pathname),
4
- searchUserUrl: (appId)=>`/af/app/${appId}/runtime/api/v1/account/search_user`,
5
- listUsersUrl: (appId)=>`/af/app/${appId}/runtime/api/v1/account/list_users`
4
+ getAppId: ()=>getAppId(),
5
+ searchUserUrl: (appId)=>isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/account/search_user` : `/af/app/${appId}/runtime/api/v1/account/search_user`,
6
+ listUsersUrl: (appId)=>isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/account/list_users` : `/af/app/${appId}/runtime/api/v1/account/list_users`
6
7
  };
7
8
  class UserService {
8
9
  config;
@@ -14,6 +14,7 @@ export type UserInfo = {
14
14
  avatar: string;
15
15
  userType: '_employee' | '_externalUser' | '_anonymousUser';
16
16
  department: DepartmentBasic;
17
+ email?: string;
17
18
  };
18
19
  export type DepartmentInfo = {
19
20
  departmentID: string;
@@ -4,9 +4,9 @@ class BatchLogger {
4
4
  flushTimer = null;
5
5
  isProcessing = false;
6
6
  originConsole;
7
- constructor(console, config){
7
+ constructor(console1, config){
8
8
  this.originConsole = {
9
- ...console
9
+ ...console1
10
10
  };
11
11
  const { userId = '', tenantId = '', appId = '' } = window || {};
12
12
  this.config = {
@@ -131,4 +131,5 @@ function destroyBatchLogger() {
131
131
  defaultBatchLogger = null;
132
132
  }
133
133
  }
134
+ if ('production' !== process.env.NODE_ENV && 'undefined' != typeof window) defaultBatchLogger = new BatchLogger(console);
134
135
  export { BatchLogger, batchLogInfo, destroyBatchLogger, getBatchLogger, initBatchLogger };
@@ -1,5 +1,6 @@
1
- import { createApplyHandle, getModuleHot } from "../utils/module-hot.js";
2
- import { submitPostMessage, submitSlardarEvent } from "../utils/postMessage.js";
1
+ import { slardar } from "@lark-apaas/internal-slardar";
2
+ import { getHmrApi } from "../utils/hmr-api.js";
3
+ import { submitPostMessage } from "../utils/postMessage.js";
3
4
  import { levelSchema } from "./log-types.js";
4
5
  import { logger } from "./logger.js";
5
6
  let devServerDisconnectInfo = null;
@@ -19,22 +20,26 @@ function processDevServerLog(log) {
19
20
  status: 'disconnected'
20
21
  }
21
22
  });
22
- submitSlardarEvent({
23
+ slardar.sendEvent({
23
24
  name: 'sandbox-devServer',
24
- categories: {
25
- type: 'disconnected',
25
+ metrics: {
26
26
  time
27
+ },
28
+ categories: {
29
+ type: 'disconnected'
27
30
  }
28
31
  });
29
32
  return;
30
33
  }
31
34
  if (!devServerDisconnectInfo) return;
32
35
  if (devFlag && log.includes('Trying to reconnect')) {
33
- if (retryCount) submitSlardarEvent({
36
+ if (retryCount) slardar.sendEvent({
34
37
  name: 'sandbox-devServer',
35
- categories: {
36
- type: 'reconnect-failed',
38
+ metrics: {
37
39
  retryCount: retryCount + 1
40
+ },
41
+ categories: {
42
+ type: 'reconnect-failed'
38
43
  }
39
44
  });
40
45
  retryCount++;
@@ -52,37 +57,41 @@ function processDevServerLog(log) {
52
57
  const startTime = devServerDisconnectInfo.time;
53
58
  const duration = Date.now() - startTime;
54
59
  devServerDisconnectInfo = null;
55
- submitSlardarEvent({
60
+ slardar.sendEvent({
56
61
  name: 'sandbox-devServer',
57
- categories: {
58
- type: 'devServer-reconnected',
62
+ metrics: {
59
63
  startTime,
60
64
  duration
65
+ },
66
+ categories: {
67
+ type: 'devServer-reconnected'
61
68
  }
62
69
  });
63
70
  }
64
71
  }
65
72
  function listenModuleHmr() {
66
- const hot = getModuleHot();
67
- if (hot) hot.addStatusHandler(createApplyHandle((success, status)=>{
68
- if (success) submitPostMessage({
69
- type: 'DevServerMessage',
70
- data: {
71
- type: 'devServer-status',
72
- status: 'hmr-apply-success'
73
- }
73
+ const hmr = getHmrApi();
74
+ if (hmr) {
75
+ hmr.onSuccess(()=>{
76
+ submitPostMessage({
77
+ type: 'DevServerMessage',
78
+ data: {
79
+ type: 'devServer-status',
80
+ status: 'hmr-apply-success'
81
+ }
82
+ });
74
83
  });
75
- else {
76
- console.warn('hmr apply failed', status);
77
- submitSlardarEvent({
84
+ hmr.onError((error)=>{
85
+ console.warn('hmr apply failed', error);
86
+ slardar.sendEvent({
78
87
  name: 'sandbox-devServer',
79
88
  categories: {
80
89
  type: 'hmr-apply-failed',
81
- status
90
+ error: String(error)
82
91
  }
83
92
  });
84
- }
85
- }));
93
+ });
94
+ }
86
95
  }
87
96
  function interceptErrors() {
88
97
  window.addEventListener('error', (event)=>{
@@ -1,7 +1,7 @@
1
1
  import z from 'zod';
2
2
  export declare const networkRequestLogSchema: z.ZodObject<{
3
3
  method: z.ZodString;
4
- status: z.ZodInt;
4
+ status: z.ZodNumber;
5
5
  statusText: z.ZodString;
6
6
  path: z.ZodString;
7
7
  requestData: z.ZodOptional<z.ZodUnknown>;
@@ -27,11 +27,11 @@ export declare const logStackFrameSchema: z.ZodObject<{
27
27
  columnNumber: z.ZodNumber;
28
28
  }, z.core.$strip>;
29
29
  export declare const levelSchema: z.ZodEnum<{
30
+ error: "error";
30
31
  success: "success";
31
32
  debug: "debug";
32
33
  info: "info";
33
34
  warn: "warn";
34
- error: "error";
35
35
  }>;
36
36
  export declare const logMeta: z.ZodObject<{
37
37
  stacktrace: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -52,11 +52,11 @@ export declare const logMeta: z.ZodObject<{
52
52
  export declare const selectedLogSchema: z.ZodObject<{
53
53
  type: z.ZodLiteral<"typedLogV2">;
54
54
  level: z.ZodEnum<{
55
+ error: "error";
55
56
  success: "success";
56
57
  debug: "debug";
57
58
  info: "info";
58
59
  warn: "warn";
59
- error: "error";
60
60
  }>;
61
61
  id: z.ZodString;
62
62
  args: z.ZodArray<z.ZodUnknown>;
@@ -80,11 +80,11 @@ export declare const selectedLogSchema: z.ZodObject<{
80
80
  export type LogLevel = z.infer<typeof levelSchema>;
81
81
  export declare const logWithMetaSchema: z.ZodObject<{
82
82
  level: z.ZodEnum<{
83
+ error: "error";
83
84
  success: "success";
84
85
  debug: "debug";
85
86
  info: "info";
86
87
  warn: "warn";
87
- error: "error";
88
88
  }>;
89
89
  args: z.ZodArray<z.ZodUnknown>;
90
90
  meta: z.ZodOptional<z.ZodObject<{
@@ -1,7 +1,7 @@
1
1
  import zod from "zod";
2
2
  const networkRequestLogSchema = zod.object({
3
3
  method: zod.string(),
4
- status: zod.int(),
4
+ status: zod.number().int(),
5
5
  statusText: zod.string(),
6
6
  path: zod.string(),
7
7
  requestData: zod.optional(zod.unknown()),
@@ -2,7 +2,7 @@ import { SourceMapConsumer as external_source_map_SourceMapConsumer } from "sour
2
2
  import "../utils/utils.js";
3
3
  import { mappingText } from "./source-map-mappings-wasm.js";
4
4
  import stacktrace_js from "stacktrace-js";
5
- import { batchLogInfo, initBatchLogger } from "./batch-logger.js";
5
+ import { batchLogInfo } from "./batch-logger.js";
6
6
  function hexToBuffer(hexString) {
7
7
  const hex = hexString.replace(/\s/g, '').toUpperCase();
8
8
  if (!/^[0-9A-F]+$/.test(hex)) throw new Error('Invalid hex string');
@@ -213,7 +213,6 @@ const typedLogInterceptor = (logger)=>({
213
213
  });
214
214
  }
215
215
  });
216
- 'production' !== process.env.NODE_ENV && initBatchLogger(console);
217
216
  const interceptors = 'production' !== process.env.NODE_ENV ? [
218
217
  typedLogInterceptor
219
218
  ] : [];
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Axios 配置初始化
3
+ * 从原有的 axiosConfig.ts 迁移
4
+ */
5
+ export { initAxiosConfig } from '../utils/axiosConfig';
@@ -0,0 +1,2 @@
1
+ import { initAxiosConfig } from "../utils/axiosConfig.js";
2
+ export { initAxiosConfig };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Dayjs 插件注册
3
+ * 从原有的 dayjsPlugins.ts 迁移
4
+ */
5
+ export { registerDayjsPlugins } from '../components/AppContainer/dayjsPlugins';
@@ -0,0 +1,2 @@
1
+ import { registerDayjsPlugins } from "../components/AppContainer/dayjsPlugins.js";
2
+ export { registerDayjsPlugins };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Iframe Bridge Runtime
3
+ *
4
+ * 开发环境下的 iframe 通信初始化:
5
+ * - connectParent - 通过 penpal 连接父页面,建立双向通信
6
+ */
7
+ /**
8
+ * 初始化 iframe bridge(仅开发环境)
9
+ * - 连接父页面
10
+ */
11
+ export declare function initIframeBridge(): void;
@@ -0,0 +1,29 @@
1
+ import { connectToParent } from "penpal";
2
+ import { resolveParentOrigin, submitPostMessage } from "../utils/postMessage.js";
3
+ import { batchLogInfo } from "../logger/batch-logger.js";
4
+ import { childApi } from "../components/AppContainer/utils/childApi.js";
5
+ async function connectParent() {
6
+ submitPostMessage({
7
+ type: 'PreviewReady',
8
+ data: {}
9
+ });
10
+ batchLogInfo('info', JSON.stringify({
11
+ type: 'PreviewReady',
12
+ timestamp: Date.now(),
13
+ url: window.location.href
14
+ }));
15
+ const parentOrigin = resolveParentOrigin();
16
+ if (!parentOrigin) return;
17
+ const connection = connectToParent({
18
+ parentOrigin,
19
+ methods: {
20
+ ...childApi
21
+ }
22
+ });
23
+ await connection.promise;
24
+ }
25
+ function initIframeBridge() {
26
+ if (window.parent === window) return;
27
+ connectParent();
28
+ }
29
+ export { initIframeBridge };