| 
									
										
										
										
											2024-07-17 16:51:48 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |   useCallback, | 
					
						
							|  |  |  |   useState, | 
					
						
							|  |  |  | } from 'react' | 
					
						
							| 
									
										
										
										
											2024-06-25 15:46:12 +08:00
										 |  |  | import { useTranslation } from 'react-i18next' | 
					
						
							| 
									
										
										
										
											2024-08-19 18:11:11 +08:00
										 |  |  | import { useReactFlow, useStoreApi } from 'reactflow' | 
					
						
							|  |  |  | import produce from 'immer' | 
					
						
							|  |  |  | import { useStore, useWorkflowStore } from '../store' | 
					
						
							| 
									
										
										
										
											2024-04-28 17:09:56 +08:00
										 |  |  | import { | 
					
						
							| 
									
										
										
										
											2024-08-19 18:11:11 +08:00
										 |  |  |   CUSTOM_NODE, DSL_EXPORT_CHECK, | 
					
						
							|  |  |  |   WORKFLOW_DATA_UPDATE, | 
					
						
							|  |  |  | } from '../constants' | 
					
						
							| 
									
										
										
										
											2024-09-08 12:14:11 +07:00
										 |  |  | import type { Node, WorkflowDataUpdater } from '../types' | 
					
						
							| 
									
										
										
										
											2024-08-19 18:11:11 +08:00
										 |  |  | import { ControlMode } from '../types' | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   getLayoutByDagre, | 
					
						
							| 
									
										
										
										
											2024-04-28 17:09:56 +08:00
										 |  |  |   initialEdges, | 
					
						
							|  |  |  |   initialNodes, | 
					
						
							|  |  |  | } from '../utils' | 
					
						
							| 
									
										
										
										
											2024-08-19 18:11:11 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |   useNodesReadOnly, | 
					
						
							|  |  |  |   useSelectionInteractions, | 
					
						
							|  |  |  |   useWorkflowReadOnly, | 
					
						
							|  |  |  | } from '../hooks' | 
					
						
							| 
									
										
										
										
											2024-04-28 17:09:56 +08:00
										 |  |  | import { useEdgesInteractions } from './use-edges-interactions' | 
					
						
							|  |  |  | import { useNodesInteractions } from './use-nodes-interactions' | 
					
						
							| 
									
										
										
										
											2024-07-17 16:51:48 +08:00
										 |  |  | import { useNodesSyncDraft } from './use-nodes-sync-draft' | 
					
						
							| 
									
										
										
										
											2024-08-19 18:11:11 +08:00
										 |  |  | import { WorkflowHistoryEvent, useWorkflowHistory } from './use-workflow-history' | 
					
						
							| 
									
										
										
										
											2024-04-28 17:09:56 +08:00
										 |  |  | import { useEventEmitterContextContext } from '@/context/event-emitter' | 
					
						
							| 
									
										
										
										
											2024-05-10 14:48:20 +08:00
										 |  |  | import { fetchWorkflowDraft } from '@/service/workflow' | 
					
						
							| 
									
										
										
										
											2024-06-25 15:46:12 +08:00
										 |  |  | import { exportAppConfig } from '@/service/apps' | 
					
						
							|  |  |  | import { useToastContext } from '@/app/components/base/toast' | 
					
						
							|  |  |  | import { useStore as useAppStore } from '@/app/components/app/store' | 
					
						
							| 
									
										
										
										
											2024-04-28 17:09:56 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | export const useWorkflowInteractions = () => { | 
					
						
							|  |  |  |   const workflowStore = useWorkflowStore() | 
					
						
							|  |  |  |   const { handleNodeCancelRunningStatus } = useNodesInteractions() | 
					
						
							|  |  |  |   const { handleEdgeCancelRunningStatus } = useEdgesInteractions() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const handleCancelDebugAndPreviewPanel = useCallback(() => { | 
					
						
							|  |  |  |     workflowStore.setState({ | 
					
						
							|  |  |  |       showDebugAndPreviewPanel: false, | 
					
						
							| 
									
										
										
										
											2024-04-28 17:51:58 +08:00
										 |  |  |       workflowRunningData: undefined, | 
					
						
							| 
									
										
										
										
											2024-04-28 17:09:56 +08:00
										 |  |  |     }) | 
					
						
							|  |  |  |     handleNodeCancelRunningStatus() | 
					
						
							|  |  |  |     handleEdgeCancelRunningStatus() | 
					
						
							|  |  |  |   }, [workflowStore, handleNodeCancelRunningStatus, handleEdgeCancelRunningStatus]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-10 14:48:20 +08:00
										 |  |  |   return { | 
					
						
							|  |  |  |     handleCancelDebugAndPreviewPanel, | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-19 18:11:11 +08:00
										 |  |  | export const useWorkflowMoveMode = () => { | 
					
						
							|  |  |  |   const setControlMode = useStore(s => s.setControlMode) | 
					
						
							|  |  |  |   const { | 
					
						
							|  |  |  |     getNodesReadOnly, | 
					
						
							|  |  |  |   } = useNodesReadOnly() | 
					
						
							|  |  |  |   const { handleSelectionCancel } = useSelectionInteractions() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const handleModePointer = useCallback(() => { | 
					
						
							|  |  |  |     if (getNodesReadOnly()) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setControlMode(ControlMode.Pointer) | 
					
						
							|  |  |  |   }, [getNodesReadOnly, setControlMode]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const handleModeHand = useCallback(() => { | 
					
						
							|  |  |  |     if (getNodesReadOnly()) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setControlMode(ControlMode.Hand) | 
					
						
							|  |  |  |     handleSelectionCancel() | 
					
						
							|  |  |  |   }, [getNodesReadOnly, setControlMode, handleSelectionCancel]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     handleModePointer, | 
					
						
							|  |  |  |     handleModeHand, | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const useWorkflowOrganize = () => { | 
					
						
							|  |  |  |   const workflowStore = useWorkflowStore() | 
					
						
							|  |  |  |   const store = useStoreApi() | 
					
						
							|  |  |  |   const reactflow = useReactFlow() | 
					
						
							|  |  |  |   const { getNodesReadOnly } = useNodesReadOnly() | 
					
						
							|  |  |  |   const { saveStateToHistory } = useWorkflowHistory() | 
					
						
							|  |  |  |   const { handleSyncWorkflowDraft } = useNodesSyncDraft() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const handleLayout = useCallback(async () => { | 
					
						
							|  |  |  |     if (getNodesReadOnly()) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  |     workflowStore.setState({ nodeAnimation: true }) | 
					
						
							|  |  |  |     const { | 
					
						
							|  |  |  |       getNodes, | 
					
						
							|  |  |  |       edges, | 
					
						
							|  |  |  |       setNodes, | 
					
						
							|  |  |  |     } = store.getState() | 
					
						
							|  |  |  |     const { setViewport } = reactflow | 
					
						
							|  |  |  |     const nodes = getNodes() | 
					
						
							|  |  |  |     const layout = getLayoutByDagre(nodes, edges) | 
					
						
							|  |  |  |     const rankMap = {} as Record<string, Node> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     nodes.forEach((node) => { | 
					
						
							|  |  |  |       if (!node.parentId && node.type === CUSTOM_NODE) { | 
					
						
							|  |  |  |         const rank = layout.node(node.id).rank! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!rankMap[rank]) { | 
					
						
							|  |  |  |           rankMap[rank] = node | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           if (rankMap[rank].position.y > node.position.y) | 
					
						
							|  |  |  |             rankMap[rank] = node | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const newNodes = produce(nodes, (draft) => { | 
					
						
							|  |  |  |       draft.forEach((node) => { | 
					
						
							|  |  |  |         if (!node.parentId && node.type === CUSTOM_NODE) { | 
					
						
							|  |  |  |           const nodeWithPosition = layout.node(node.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           node.position = { | 
					
						
							|  |  |  |             x: nodeWithPosition.x - node.width! / 2, | 
					
						
							|  |  |  |             y: nodeWithPosition.y - node.height! / 2 + rankMap[nodeWithPosition.rank!].height! / 2, | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     setNodes(newNodes) | 
					
						
							|  |  |  |     const zoom = 0.7 | 
					
						
							|  |  |  |     setViewport({ | 
					
						
							|  |  |  |       x: 0, | 
					
						
							|  |  |  |       y: 0, | 
					
						
							|  |  |  |       zoom, | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     saveStateToHistory(WorkflowHistoryEvent.LayoutOrganize) | 
					
						
							|  |  |  |     setTimeout(() => { | 
					
						
							|  |  |  |       handleSyncWorkflowDraft() | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |   }, [getNodesReadOnly, store, reactflow, workflowStore, handleSyncWorkflowDraft, saveStateToHistory]) | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     handleLayout, | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const useWorkflowZoom = () => { | 
					
						
							|  |  |  |   const { handleSyncWorkflowDraft } = useNodesSyncDraft() | 
					
						
							|  |  |  |   const { getWorkflowReadOnly } = useWorkflowReadOnly() | 
					
						
							|  |  |  |   const { | 
					
						
							|  |  |  |     zoomIn, | 
					
						
							|  |  |  |     zoomOut, | 
					
						
							|  |  |  |     zoomTo, | 
					
						
							|  |  |  |     fitView, | 
					
						
							|  |  |  |   } = useReactFlow() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const handleFitView = useCallback(() => { | 
					
						
							|  |  |  |     if (getWorkflowReadOnly()) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fitView() | 
					
						
							|  |  |  |     handleSyncWorkflowDraft() | 
					
						
							|  |  |  |   }, [getWorkflowReadOnly, fitView, handleSyncWorkflowDraft]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const handleBackToOriginalSize = useCallback(() => { | 
					
						
							|  |  |  |     if (getWorkflowReadOnly()) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     zoomTo(1) | 
					
						
							|  |  |  |     handleSyncWorkflowDraft() | 
					
						
							|  |  |  |   }, [getWorkflowReadOnly, zoomTo, handleSyncWorkflowDraft]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const handleSizeToHalf = useCallback(() => { | 
					
						
							|  |  |  |     if (getWorkflowReadOnly()) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     zoomTo(0.5) | 
					
						
							|  |  |  |     handleSyncWorkflowDraft() | 
					
						
							|  |  |  |   }, [getWorkflowReadOnly, zoomTo, handleSyncWorkflowDraft]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const handleZoomOut = useCallback(() => { | 
					
						
							|  |  |  |     if (getWorkflowReadOnly()) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     zoomOut() | 
					
						
							|  |  |  |     handleSyncWorkflowDraft() | 
					
						
							|  |  |  |   }, [getWorkflowReadOnly, zoomOut, handleSyncWorkflowDraft]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const handleZoomIn = useCallback(() => { | 
					
						
							|  |  |  |     if (getWorkflowReadOnly()) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     zoomIn() | 
					
						
							|  |  |  |     handleSyncWorkflowDraft() | 
					
						
							|  |  |  |   }, [getWorkflowReadOnly, zoomIn, handleSyncWorkflowDraft]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     handleFitView, | 
					
						
							|  |  |  |     handleBackToOriginalSize, | 
					
						
							|  |  |  |     handleSizeToHalf, | 
					
						
							|  |  |  |     handleZoomOut, | 
					
						
							|  |  |  |     handleZoomIn, | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-10 14:48:20 +08:00
										 |  |  | export const useWorkflowUpdate = () => { | 
					
						
							|  |  |  |   const reactflow = useReactFlow() | 
					
						
							|  |  |  |   const workflowStore = useWorkflowStore() | 
					
						
							|  |  |  |   const { eventEmitter } = useEventEmitterContextContext() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-08 12:14:11 +07:00
										 |  |  |   const handleUpdateWorkflowCanvas = useCallback((payload: WorkflowDataUpdater) => { | 
					
						
							| 
									
										
										
										
											2024-04-28 17:09:56 +08:00
										 |  |  |     const { | 
					
						
							|  |  |  |       nodes, | 
					
						
							|  |  |  |       edges, | 
					
						
							|  |  |  |       viewport, | 
					
						
							|  |  |  |     } = payload | 
					
						
							|  |  |  |     const { setViewport } = reactflow | 
					
						
							|  |  |  |     eventEmitter?.emit({ | 
					
						
							|  |  |  |       type: WORKFLOW_DATA_UPDATE, | 
					
						
							|  |  |  |       payload: { | 
					
						
							|  |  |  |         nodes: initialNodes(nodes, edges), | 
					
						
							|  |  |  |         edges: initialEdges(edges, nodes), | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     } as any) | 
					
						
							|  |  |  |     setViewport(viewport) | 
					
						
							|  |  |  |   }, [eventEmitter, reactflow]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-10 14:48:20 +08:00
										 |  |  |   const handleRefreshWorkflowDraft = useCallback(() => { | 
					
						
							|  |  |  |     const { | 
					
						
							|  |  |  |       appId, | 
					
						
							|  |  |  |       setSyncWorkflowDraftHash, | 
					
						
							| 
									
										
										
										
											2024-06-12 16:35:19 +08:00
										 |  |  |       setIsSyncingWorkflowDraft, | 
					
						
							| 
									
										
										
										
											2024-07-22 15:29:39 +08:00
										 |  |  |       setEnvironmentVariables, | 
					
						
							|  |  |  |       setEnvSecrets, | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  |       setConversationVariables, | 
					
						
							| 
									
										
										
										
											2024-05-10 14:48:20 +08:00
										 |  |  |     } = workflowStore.getState() | 
					
						
							| 
									
										
										
										
											2024-06-12 16:35:19 +08:00
										 |  |  |     setIsSyncingWorkflowDraft(true) | 
					
						
							| 
									
										
										
										
											2024-05-10 14:48:20 +08:00
										 |  |  |     fetchWorkflowDraft(`/apps/${appId}/workflows/draft`).then((response) => { | 
					
						
							| 
									
										
										
										
											2024-09-08 12:14:11 +07:00
										 |  |  |       handleUpdateWorkflowCanvas(response.graph as WorkflowDataUpdater) | 
					
						
							| 
									
										
										
										
											2024-05-10 14:48:20 +08:00
										 |  |  |       setSyncWorkflowDraftHash(response.hash) | 
					
						
							| 
									
										
										
										
											2024-07-22 15:29:39 +08:00
										 |  |  |       setEnvSecrets((response.environment_variables || []).filter(env => env.value_type === 'secret').reduce((acc, env) => { | 
					
						
							|  |  |  |         acc[env.id] = env.value | 
					
						
							|  |  |  |         return acc | 
					
						
							|  |  |  |       }, {} as Record<string, string>)) | 
					
						
							|  |  |  |       setEnvironmentVariables(response.environment_variables?.map(env => env.value_type === 'secret' ? { ...env, value: '[__HIDDEN__]' } : env) || []) | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  |       // #TODO chatVar sync#
 | 
					
						
							|  |  |  |       setConversationVariables(response.conversation_variables || []) | 
					
						
							| 
									
										
										
										
											2024-06-12 16:35:19 +08:00
										 |  |  |     }).finally(() => setIsSyncingWorkflowDraft(false)) | 
					
						
							| 
									
										
										
										
											2024-05-10 14:48:20 +08:00
										 |  |  |   }, [handleUpdateWorkflowCanvas, workflowStore]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-28 17:09:56 +08:00
										 |  |  |   return { | 
					
						
							|  |  |  |     handleUpdateWorkflowCanvas, | 
					
						
							| 
									
										
										
										
											2024-05-10 14:48:20 +08:00
										 |  |  |     handleRefreshWorkflowDraft, | 
					
						
							| 
									
										
										
										
											2024-04-28 17:09:56 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-06-25 15:46:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | export const useDSL = () => { | 
					
						
							|  |  |  |   const { t } = useTranslation() | 
					
						
							|  |  |  |   const { notify } = useToastContext() | 
					
						
							| 
									
										
										
										
											2024-07-22 15:29:39 +08:00
										 |  |  |   const { eventEmitter } = useEventEmitterContextContext() | 
					
						
							| 
									
										
										
										
											2024-07-17 16:51:48 +08:00
										 |  |  |   const [exporting, setExporting] = useState(false) | 
					
						
							|  |  |  |   const { doSyncWorkflowDraft } = useNodesSyncDraft() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-25 15:46:12 +08:00
										 |  |  |   const appDetail = useAppStore(s => s.appDetail) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-22 15:29:39 +08:00
										 |  |  |   const handleExportDSL = useCallback(async (include = false) => { | 
					
						
							| 
									
										
										
										
											2024-06-25 15:46:12 +08:00
										 |  |  |     if (!appDetail) | 
					
						
							|  |  |  |       return | 
					
						
							| 
									
										
										
										
											2024-07-17 16:51:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (exporting) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-25 15:46:12 +08:00
										 |  |  |     try { | 
					
						
							| 
									
										
										
										
											2024-07-17 16:51:48 +08:00
										 |  |  |       setExporting(true) | 
					
						
							|  |  |  |       await doSyncWorkflowDraft() | 
					
						
							| 
									
										
										
										
											2024-07-22 15:29:39 +08:00
										 |  |  |       const { data } = await exportAppConfig({ | 
					
						
							|  |  |  |         appID: appDetail.id, | 
					
						
							|  |  |  |         include, | 
					
						
							|  |  |  |       }) | 
					
						
							| 
									
										
										
										
											2024-06-25 15:46:12 +08:00
										 |  |  |       const a = document.createElement('a') | 
					
						
							|  |  |  |       const file = new Blob([data], { type: 'application/yaml' }) | 
					
						
							|  |  |  |       a.href = URL.createObjectURL(file) | 
					
						
							|  |  |  |       a.download = `${appDetail.name}.yml` | 
					
						
							|  |  |  |       a.click() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     catch (e) { | 
					
						
							|  |  |  |       notify({ type: 'error', message: t('app.exportFailed') }) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-07-17 16:51:48 +08:00
										 |  |  |     finally { | 
					
						
							|  |  |  |       setExporting(false) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }, [appDetail, notify, t, doSyncWorkflowDraft, exporting]) | 
					
						
							| 
									
										
										
										
											2024-06-25 15:46:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-22 15:29:39 +08:00
										 |  |  |   const exportCheck = useCallback(async () => { | 
					
						
							|  |  |  |     if (!appDetail) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       const workflowDraft = await fetchWorkflowDraft(`/apps/${appDetail?.id}/workflows/draft`) | 
					
						
							|  |  |  |       const list = (workflowDraft.environment_variables || []).filter(env => env.value_type === 'secret') | 
					
						
							|  |  |  |       if (list.length === 0) { | 
					
						
							|  |  |  |         handleExportDSL() | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       eventEmitter?.emit({ | 
					
						
							|  |  |  |         type: DSL_EXPORT_CHECK, | 
					
						
							|  |  |  |         payload: { | 
					
						
							|  |  |  |           data: list, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       } as any) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     catch (e) { | 
					
						
							|  |  |  |       notify({ type: 'error', message: t('app.exportFailed') }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }, [appDetail, eventEmitter, handleExportDSL, notify, t]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-25 15:46:12 +08:00
										 |  |  |   return { | 
					
						
							| 
									
										
										
										
											2024-07-22 15:29:39 +08:00
										 |  |  |     exportCheck, | 
					
						
							| 
									
										
										
										
											2024-06-25 15:46:12 +08:00
										 |  |  |     handleExportDSL, | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |