@digitalsee-ai/rcs 1.0.16 → 1.1.1
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/components/digitalsee/workflow/Canvas/NextConfigModalWrapper.d.ts +1 -1
- package/dist/components/digitalsee/workflow/Canvas/actionItemToNodeData.d.ts +14 -0
- package/dist/components/digitalsee/workflow/Canvas/constants.d.ts +1 -14
- package/dist/components/digitalsee/workflow/Canvas/constants.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Canvas/hooks/classicNodeAddConnection.d.ts +31 -0
- package/dist/components/digitalsee/workflow/Canvas/hooks/classicNodeAddConnection.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Canvas/hooks/createNodeAddHandlerNext.d.ts +5 -16
- package/dist/components/digitalsee/workflow/Canvas/hooks/useNodeAddCallback.d.ts +5 -17
- package/dist/components/digitalsee/workflow/Canvas/hooks/useWorkflowCanvasState.d.ts +3 -1
- package/dist/components/digitalsee/workflow/Handles/CustomHandle.d.ts +3 -0
- package/dist/components/digitalsee/workflow/Handles/customHandleConnectable.d.ts +35 -0
- package/dist/components/digitalsee/workflow/Handles/customHandleConnectable.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Nodes/ActionNode.d.ts +1 -1
- package/dist/components/digitalsee/workflow/Nodes/ConditionNode.d.ts +1 -1
- package/dist/components/digitalsee/workflow/Nodes/NextNodeFactory.d.ts +2 -1
- package/dist/components/digitalsee/workflow/Nodes/NextNodes/NextBaseNode.d.ts +2 -1
- package/dist/components/digitalsee/workflow/Nodes/NodeFactory.d.ts +1 -1
- package/dist/components/digitalsee/workflow/Nodes/SuperBaseNode.d.ts +8 -3
- package/dist/components/digitalsee/workflow/Nodes/SwitchNode.d.ts +1 -1
- package/dist/components/digitalsee/workflow/Nodes/classicNodePackageNodes.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Nodes/classicNodePackagePortLayout.d.ts +23 -0
- package/dist/components/digitalsee/workflow/Nodes/classicNodePackagePortLayout.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Nodes/components/NextNodeOperations.d.ts +1 -1
- package/dist/components/digitalsee/workflow/Nodes/useClassicNodePackagePorts.d.ts +26 -0
- package/dist/components/digitalsee/workflow/Nodes/useClassicNodePackagePorts.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/NodesConfig/ActionNodeConfig/index.d.ts +2 -0
- package/dist/components/digitalsee/workflow/NodesConfig/NextNodeConfig/index.d.ts +4 -2
- package/dist/components/digitalsee/workflow/NodesConfig/components/FormFieldRenderer/index.d.ts +2 -0
- package/dist/components/digitalsee/workflow/NodesConfig/submitPayload.d.ts +23 -0
- package/dist/components/digitalsee/workflow/NodesConfig/submitPayload.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/components/ActionItem.d.ts +1 -1
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/components/EntryTypeSelector.d.ts +8 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/components/NodeCardList.d.ts +19 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/hooks/useActions.d.ts +2 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/hooks/useCategories.d.ts +7 -4
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/hooks/useConnectableNodeSelector.d.ts +40 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/hooks/useNavigation.d.ts +4 -2
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/hooks/useNavigation.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/hooks/useNodeActionState.d.ts +30 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/hooks/useNodeSelectorPresentation.d.ts +24 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/types.d.ts +26 -6
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/connectableActionLoader.d.ts +16 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/connectableActionLoader.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/connectableFallback.d.ts +2 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/connectableFallback.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/connectableQuery.d.ts +40 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/connectableQuery.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/connectableResponse.d.ts +35 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/connectableResponse.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/dataTransformers.d.ts +13 -2
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/filterEdgeInsertActions.d.ts +62 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/filterEdgeInsertActions.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/nodeAddContext.d.ts +26 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/nodeAddContext.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/queryParams.d.ts +18 -0
- package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/utils/queryParams.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/Panels/SimpleNodeSelectorPanel/index.d.ts +2 -1
- package/dist/components/digitalsee/workflow/api/connectable.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/api/connectable.types.d.ts +75 -0
- package/dist/components/digitalsee/workflow/api/dip.types.d.ts +38 -4
- package/dist/components/digitalsee/workflow/api/index.d.ts +11 -2
- package/dist/components/digitalsee/workflow/config/defaultCanvasEngineConfig.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/config/defaultNodeSelectorConfig.d.ts +9 -0
- package/dist/components/digitalsee/workflow/enums/canvas.d.ts +5 -2
- package/dist/components/digitalsee/workflow/enums/node.d.ts +4 -0
- package/dist/components/digitalsee/workflow/events/eventBus.d.ts +2 -12
- package/dist/components/digitalsee/workflow/hooks/use-nodes-interaction.d.ts +1 -1
- package/dist/components/digitalsee/workflow/hooks/usePanel.d.ts +3 -17
- package/dist/components/digitalsee/workflow/index.d.ts +2 -1
- package/dist/components/digitalsee/workflow/store/panelSlice.d.ts +122 -25
- package/dist/components/digitalsee/workflow/types/Node.d.ts +1 -1
- package/dist/components/digitalsee/workflow/types/NodeAddContext.d.ts +31 -0
- package/dist/components/digitalsee/workflow/types/engine.d.ts +17 -0
- package/dist/components/digitalsee/workflow/utils/classicNodeActionIdentity.d.ts +7 -0
- package/dist/components/digitalsee/workflow/utils/classicNodeActionIdentity.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/utils/classicNodePackageConnection.d.ts +28 -0
- package/dist/components/digitalsee/workflow/utils/classicNodePackageConnection.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/utils/classicNodePackageGraphValidation.d.ts +29 -0
- package/dist/components/digitalsee/workflow/utils/classicNodePackageGraphValidation.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/utils/compatiblePortSelection.d.ts +79 -0
- package/dist/components/digitalsee/workflow/utils/compatiblePortSelection.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/utils/mcpCanvas.d.ts +33 -0
- package/dist/components/digitalsee/workflow/utils/mcpCanvas.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/utils/nextNodeSchemaCache.d.ts +8 -0
- package/dist/components/digitalsee/workflow/utils/nodeDataFormatter.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/utils/portConnectionValidationMessages.d.ts +48 -0
- package/dist/components/digitalsee/workflow/utils/portConnectionValidationMessages.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/utils/portConnectionValidator.d.ts +66 -0
- package/dist/components/digitalsee/workflow/utils/portConnectionValidator.test.d.ts +1 -0
- package/dist/components/digitalsee/workflow/utils/workflowConnectionValidator.d.ts +20 -0
- package/dist/components/digitalsee/workflow/utils/workflowConnectionValidator.test.d.ts +1 -0
- package/dist/locales/en-US/link/flow.d.ts +22 -0
- package/dist/locales/en-US.d.ts +22 -0
- package/dist/locales/zh-CN/link/flow.d.ts +22 -0
- package/dist/locales/zh-CN.d.ts +22 -0
- package/dist/locales/zh-TW/link/flow.d.ts +22 -0
- package/dist/locales/zh-TW.d.ts +22 -0
- package/dist/rcs.css +1 -1
- package/dist/rcs.es.js +19972 -17600
- package/dist/rcs.es.js.map +1 -1
- package/dist/rcs.umd.js +60 -60
- package/dist/rcs.umd.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { NodeData as NodeFactoryData } from '../Nodes/NodeFactory';
|
|
2
|
+
import { ActionItem } from '../Panels/ModernNodeSelectorPanel/types';
|
|
3
|
+
type ConvertibleActionItem = Partial<ActionItem> & {
|
|
4
|
+
status?: string;
|
|
5
|
+
protocol?: string;
|
|
6
|
+
} & Record<string, unknown>;
|
|
7
|
+
/** 将节点动作转换为 CLASSIC 画布节点数据。 */
|
|
8
|
+
export declare const convertActionItemToNodeData: (actionItem: ConvertibleActionItem) => NodeFactoryData;
|
|
9
|
+
/**
|
|
10
|
+
* NEXT 模式专用转换函数(暂废保留分支):额外保留 name 字段。
|
|
11
|
+
* 当前 nodepackage 节点仍走 CLASSIC 的 convertActionItemToNodeData。
|
|
12
|
+
*/
|
|
13
|
+
export declare const convertActionItemToNodeDataNext: (actionItem: ConvertibleActionItem) => NodeFactoryData;
|
|
14
|
+
export {};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { EdgeType } from '../enums/edge';
|
|
2
|
-
import { NodeData as NodeFactoryData } from '../Nodes/NodeFactory';
|
|
3
|
-
import { ActionItem } from '../Panels/ModernNodeSelectorPanel/types';
|
|
4
2
|
import { CanvasAPI } from '../types/engine';
|
|
5
3
|
import { NodeType } from '../types/Node';
|
|
6
4
|
import { Edge, MarkerType, Node, Viewport } from '@xyflow/react';
|
|
5
|
+
export { convertActionItemToNodeData, convertActionItemToNodeDataNext, } from './actionItemToNodeData';
|
|
7
6
|
export declare const startNode: {
|
|
8
7
|
type: NodeType;
|
|
9
8
|
id: string;
|
|
@@ -19,18 +18,6 @@ export declare const startNode: {
|
|
|
19
18
|
description: string;
|
|
20
19
|
};
|
|
21
20
|
};
|
|
22
|
-
export declare const convertActionItemToNodeData: (actionItem: Partial<ActionItem> & {
|
|
23
|
-
status?: string;
|
|
24
|
-
protocol?: string;
|
|
25
|
-
} & Record<string, any>) => NodeFactoryData;
|
|
26
|
-
/**
|
|
27
|
-
* NEXT 模式专用转换函数:在 convertActionItemToNodeData 基础上额外保留 name 字段
|
|
28
|
-
* name 在 NEXT 模式下作为节点实例的唯一显示名称
|
|
29
|
-
*/
|
|
30
|
-
export declare const convertActionItemToNodeDataNext: (actionItem: Partial<ActionItem> & {
|
|
31
|
-
status?: string;
|
|
32
|
-
protocol?: string;
|
|
33
|
-
} & Record<string, any>) => NodeFactoryData;
|
|
34
21
|
export declare const nodeTypes: Record<NodeType, import('react').ComponentType<any>>;
|
|
35
22
|
export declare const edgeTypes: {
|
|
36
23
|
main: import('react').FC<import('../Edges/BaseEdge').CustomEdgeProps>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { NodeData as NodeFactoryData } from '../../Nodes/NodeFactory';
|
|
2
|
+
import { NodeAddInfo } from '../../types/NodeAddContext';
|
|
3
|
+
import { EdgeConfig } from '../../types/engine';
|
|
4
|
+
import { Edge, Node } from '@xyflow/react';
|
|
5
|
+
type ReportConnectable = (messageId: string, details: Record<string, unknown>) => void;
|
|
6
|
+
type ReportAmbiguousPorts = (details: Record<string, unknown>) => void;
|
|
7
|
+
export interface TryConnectClassicNodePackageParams {
|
|
8
|
+
info: NodeAddInfo;
|
|
9
|
+
newNode: Node<NodeFactoryData>;
|
|
10
|
+
currentNodes: Node[];
|
|
11
|
+
currentEdges: Edge[];
|
|
12
|
+
canUseConnectablePorts: boolean;
|
|
13
|
+
addEdges: (edges: Edge[]) => void;
|
|
14
|
+
removeEdges: (edgeIds: string[]) => void;
|
|
15
|
+
handleEdgeAddNode: (position: {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
}, edge?: Edge) => void;
|
|
19
|
+
saveFlow: () => Promise<void>;
|
|
20
|
+
reportConnectableFallback: ReportConnectable;
|
|
21
|
+
reportAmbiguousPorts: ReportAmbiguousPorts;
|
|
22
|
+
validateConnectionAgainstSnapshot: (edge: EdgeConfig, nodes: Node[], edges: Edge[]) => boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 尝试按 NodePackage Schema 连接新建节点。
|
|
26
|
+
*
|
|
27
|
+
* 返回 true 表示该上下文已完整处理(成功连线或保留独立节点并给出提示);
|
|
28
|
+
* 返回 false 时调用方继续 legacy 固定 handle 流程。
|
|
29
|
+
*/
|
|
30
|
+
export declare function tryConnectClassicNodePackage({ info, newNode, currentNodes, currentEdges, canUseConnectablePorts, addEdges, removeEdges, handleEdgeAddNode, saveFlow, reportConnectableFallback, reportAmbiguousPorts, validateConnectionAgainstSnapshot, }: TryConnectClassicNodePackageParams): Promise<boolean>;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,29 +1,15 @@
|
|
|
1
1
|
import { WorkflowCanvasStrategy } from '../types';
|
|
2
2
|
import { NodeData as NodeFactoryData } from '../../Nodes/NodeFactory';
|
|
3
3
|
import { ActionItem } from '../../Panels/ModernNodeSelectorPanel/types';
|
|
4
|
+
import { NodeAddInfo } from '../../types/NodeAddContext';
|
|
4
5
|
import { Edge, Node } from '@xyflow/react';
|
|
5
|
-
interface NodeAddInfo {
|
|
6
|
-
sourceNodeId?: string;
|
|
7
|
-
sourceHandle?: string;
|
|
8
|
-
targetNodeId?: string;
|
|
9
|
-
targetHandle?: string;
|
|
10
|
-
position?: {
|
|
11
|
-
x: number;
|
|
12
|
-
y: number;
|
|
13
|
-
};
|
|
14
|
-
trigger?: boolean;
|
|
15
|
-
edge?: any;
|
|
16
|
-
sourceNode?: any;
|
|
17
|
-
targetNode?: any;
|
|
18
|
-
protocol?: string;
|
|
19
|
-
refresh?: boolean;
|
|
20
|
-
}
|
|
21
6
|
interface CreateNodeAddHandlerNextParams {
|
|
22
7
|
workflowId?: string;
|
|
23
8
|
strategy: WorkflowCanvasStrategy;
|
|
24
9
|
store: {
|
|
25
10
|
getState: () => {
|
|
26
11
|
nodes: Node[];
|
|
12
|
+
edges: Edge[];
|
|
27
13
|
};
|
|
28
14
|
};
|
|
29
15
|
addNodes: (nodes: Node<NodeFactoryData>[]) => void;
|
|
@@ -40,6 +26,9 @@ interface CreateNodeAddHandlerNextParams {
|
|
|
40
26
|
/**
|
|
41
27
|
* 创建 NEXT 模式的节点添加处理函数(纯函数,非 Hook)
|
|
42
28
|
*
|
|
29
|
+
* 该分支目前暂废保留;当前 AI 连接流里的 nodepackage 节点是在
|
|
30
|
+
* CLASSIC 画布中兼容渲染新版 NodeSchema,不走这里的添加逻辑。
|
|
31
|
+
*
|
|
43
32
|
* 与 Classic 模式的关键区别:
|
|
44
33
|
* 1. 端口名称完全由 DIP Schema 动态定义(通过 getCachedNextNodeSchema 获取)
|
|
45
34
|
* 2. 使用 convertActionItemToNodeDataNext 转换数据(保留 name 字段)
|
|
@@ -2,29 +2,16 @@ import { WorkflowCanvasStrategy } from '../types';
|
|
|
2
2
|
import { EngineMode } from '../../enums/workflow';
|
|
3
3
|
import { NodeData as NodeFactoryData } from '../../Nodes/NodeFactory';
|
|
4
4
|
import { ActionItem } from '../../Panels/ModernNodeSelectorPanel/types';
|
|
5
|
+
import { EdgeConfig } from '../../types/engine';
|
|
6
|
+
import { NodeAddInfo } from '../../types/NodeAddContext';
|
|
5
7
|
import { Edge, Node } from '@xyflow/react';
|
|
6
|
-
interface NodeAddInfo {
|
|
7
|
-
sourceNodeId?: string;
|
|
8
|
-
sourceHandle?: string;
|
|
9
|
-
targetNodeId?: string;
|
|
10
|
-
targetHandle?: string;
|
|
11
|
-
position?: {
|
|
12
|
-
x: number;
|
|
13
|
-
y: number;
|
|
14
|
-
};
|
|
15
|
-
trigger?: boolean;
|
|
16
|
-
edge?: any;
|
|
17
|
-
sourceNode?: any;
|
|
18
|
-
targetNode?: any;
|
|
19
|
-
protocol?: string;
|
|
20
|
-
refresh?: boolean;
|
|
21
|
-
}
|
|
22
8
|
interface UseNodeAddCallbackParams {
|
|
23
9
|
workflowId?: string;
|
|
24
10
|
strategy: WorkflowCanvasStrategy;
|
|
25
11
|
store: {
|
|
26
12
|
getState: () => {
|
|
27
13
|
nodes: Node[];
|
|
14
|
+
edges: Edge[];
|
|
28
15
|
};
|
|
29
16
|
};
|
|
30
17
|
addNodes: (nodes: Node<NodeFactoryData>[]) => void;
|
|
@@ -37,8 +24,9 @@ interface UseNodeAddCallbackParams {
|
|
|
37
24
|
}, edge?: Edge) => void;
|
|
38
25
|
setNodeConfigVisible: (nodeId: string | null) => void;
|
|
39
26
|
setNodeFitHumanView: (nodeId: string) => void;
|
|
27
|
+
validateConnectionAgainstSnapshot: (edge: EdgeConfig, nodes: Node[], edges: Edge[]) => boolean;
|
|
40
28
|
saveFlow: () => Promise<void>;
|
|
41
29
|
engineMode: EngineMode;
|
|
42
30
|
}
|
|
43
|
-
export declare function useNodeAddCallback({ workflowId, strategy, store, addNodes, addEdges, removeEdges, setNodeAddCallback, handleEdgeAddNode, setNodeConfigVisible, setNodeFitHumanView, saveFlow, engineMode, }: UseNodeAddCallbackParams): void;
|
|
31
|
+
export declare function useNodeAddCallback({ workflowId, strategy, store, addNodes, addEdges, removeEdges, setNodeAddCallback, handleEdgeAddNode, setNodeConfigVisible, setNodeFitHumanView, validateConnectionAgainstSnapshot, saveFlow, engineMode, }: UseNodeAddCallbackParams): void;
|
|
44
32
|
export {};
|
|
@@ -6,7 +6,7 @@ import { useNodesInteraction } from '../../hooks/use-nodes-interaction';
|
|
|
6
6
|
import { usePanel } from '../../hooks/usePanel';
|
|
7
7
|
import { useWorkflow } from '../../hooks/useWorkflow';
|
|
8
8
|
import { useAppDispatch } from '../../store';
|
|
9
|
-
import { CanvasAPI } from '../../types/engine';
|
|
9
|
+
import { CanvasAPI, EdgeConfig as EngineEdgeConfig } from '../../types/engine';
|
|
10
10
|
import { Connection, Edge, EdgeChange, Node, NodeChange, useEdgesState, useNodesState, useReactFlow, useStoreApi } from '@xyflow/react';
|
|
11
11
|
import { default as React } from 'react';
|
|
12
12
|
export interface WorkflowCanvasStateResult {
|
|
@@ -35,6 +35,8 @@ export interface WorkflowCanvasStateResult {
|
|
|
35
35
|
onNodesChange: (changes: NodeChange[]) => void;
|
|
36
36
|
handleEdgesChange: (changes: EdgeChange[]) => void;
|
|
37
37
|
handleConnect: (params: Connection) => void;
|
|
38
|
+
isValidConnection: (params: Connection | Edge) => boolean;
|
|
39
|
+
validateConnectionAgainstSnapshot: (edge: EngineEdgeConfig, nodes: Node[], edges: Edge[]) => boolean;
|
|
38
40
|
handleEdgeAddNode: (position: {
|
|
39
41
|
x: number;
|
|
40
42
|
y: number;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DipPortSchema } from '../api/dip';
|
|
1
2
|
import { Connection, HandleType as FlowHandleType, Position, IsValidConnection as ReactFlowIsValidConnection } from '@xyflow/react';
|
|
2
3
|
import { default as React } from 'react';
|
|
3
4
|
import { NodeStatus } from '../types/Node';
|
|
@@ -20,6 +21,8 @@ interface CustomHandleProps {
|
|
|
20
21
|
square?: boolean;
|
|
21
22
|
shape?: 'square' | 'circle' | 'rhombus';
|
|
22
23
|
protocol?: string;
|
|
24
|
+
/** NodePackage 真实端口 Schema;仅用于保留端口元数据,不改变 input 只接收连线的语义。 */
|
|
25
|
+
portSchema?: DipPortSchema;
|
|
23
26
|
}
|
|
24
27
|
/**
|
|
25
28
|
* @description 自定义连接桩组件,统一输出 11×11px 菱形桩点并同步节点状态色。
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Node } from '@xyflow/react';
|
|
2
|
+
import { NodeAddInfo } from '../types/NodeAddContext';
|
|
3
|
+
interface HandleExtenderVisibilityOptions {
|
|
4
|
+
type: 'source' | 'target';
|
|
5
|
+
isFull: boolean;
|
|
6
|
+
connectionInProgress: boolean;
|
|
7
|
+
canEdit: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 判断连接桩是否展示快捷新增入口。
|
|
11
|
+
*
|
|
12
|
+
* 画布连线始终由 output/source 发起,input/target 只接收连线,
|
|
13
|
+
* 因此快捷新增入口只允许展示在输出桩。连接数达到上限时隐藏入口。
|
|
14
|
+
*/
|
|
15
|
+
export declare function shouldShowHandleExtender(options: HandleExtenderVisibilityOptions): boolean;
|
|
16
|
+
/** output 只能发起连线,input 只能接收连线;空间布局不改变端口语义。 */
|
|
17
|
+
export declare function getHandleConnectionPermissions(type: 'source' | 'target', canEdit: boolean): {
|
|
18
|
+
isConnectableStart: boolean;
|
|
19
|
+
isConnectableEnd: boolean;
|
|
20
|
+
};
|
|
21
|
+
interface BuildHandleNodeAddInfoOptions {
|
|
22
|
+
type: 'source' | 'target';
|
|
23
|
+
nodeId: string;
|
|
24
|
+
handleId: string;
|
|
25
|
+
position: {
|
|
26
|
+
x: number;
|
|
27
|
+
y: number;
|
|
28
|
+
};
|
|
29
|
+
protocol?: string;
|
|
30
|
+
anchorNode?: Node;
|
|
31
|
+
refresh: boolean;
|
|
32
|
+
}
|
|
33
|
+
/** 构造连接桩快捷新增上下文,避免输入桩误带 source/protocol 语义。 */
|
|
34
|
+
export declare function buildHandleNodeAddInfo(options: BuildHandleNodeAddInfoOptions): NodeAddInfo;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { NodeData, NodeStatus } from '../types/Node';
|
|
1
2
|
import { Node, NodeProps } from '@xyflow/react';
|
|
2
3
|
import { default as React } from 'react';
|
|
3
|
-
import { NodeData, NodeStatus } from '../types/Node';
|
|
4
4
|
interface ActionNodeProps extends NodeProps<Node<NodeData>> {
|
|
5
5
|
status?: NodeStatus;
|
|
6
6
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ComponentType } from 'react';
|
|
2
2
|
/**
|
|
3
|
-
* NEXT
|
|
3
|
+
* NEXT 模式专属节点工厂(暂废保留分支)
|
|
4
4
|
*
|
|
5
5
|
* 提供 NEXT 模式的 nodeTypes 映射,所有节点基于 DIP Schema 动态渲染锚点
|
|
6
6
|
* 与 classic 模式完全隔离,直接使用 DIP 端口名,无需适配层
|
|
7
|
+
* 当前 nodepackage 节点使用 Classic NodeFactory,并在配置面板兼容新版 NodeSchema。
|
|
7
8
|
*/
|
|
8
9
|
declare class NextNodeFactory {
|
|
9
10
|
static getNodeTypes(): Record<string, ComponentType<any>>;
|
|
@@ -6,10 +6,11 @@ interface NextBaseNodeProps extends NodeProps {
|
|
|
6
6
|
className?: string;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
* NEXT
|
|
9
|
+
* NEXT 模式基础节点组件(暂废保留分支)
|
|
10
10
|
*
|
|
11
11
|
* 根据 DIP Schema 动态渲染锚点,直接使用 DIP 端口名作为 handle ID
|
|
12
12
|
* 不再需要端口适配层,实现 NEXT 模式与 classic 模式的完全隔离
|
|
13
|
+
* 当前 nodepackage 节点仍复用 Classic 节点外观,仅配置面板兼容新版 NodeSchema。
|
|
13
14
|
*/
|
|
14
15
|
declare const NextBaseNode: React.FC<NextBaseNodeProps>;
|
|
15
16
|
export default NextBaseNode;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { NodeData, NodeType } from '../types/Node';
|
|
1
2
|
import { Node, XYPosition } from '@xyflow/react';
|
|
2
3
|
import { ComponentType } from 'react';
|
|
3
|
-
import { NodeData, NodeType } from '../types/Node';
|
|
4
4
|
export type { NodeData } from '../types/Node';
|
|
5
5
|
export interface BackendNodeData {
|
|
6
6
|
node_type: string;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { default as React } from 'react';
|
|
1
|
+
import { DipPortSchema } from '../api/dip';
|
|
3
2
|
import { HandleType } from '../types/Handle';
|
|
4
3
|
import { NodeData, NodeStatus, NodeType } from '../types/Node';
|
|
4
|
+
import { Position } from '@xyflow/react';
|
|
5
|
+
import { default as React } from 'react';
|
|
5
6
|
export interface HandleConfig {
|
|
6
7
|
id: string;
|
|
7
8
|
position: Position;
|
|
8
9
|
type: HandleType;
|
|
9
10
|
isMain?: boolean;
|
|
10
|
-
label?:
|
|
11
|
+
label?: React.ReactNode;
|
|
11
12
|
maxConnections?: number;
|
|
13
|
+
/** NodePackage 端口的连接类型;与 legacy protocol 语义保持隔离。 */
|
|
14
|
+
connectionType?: string;
|
|
15
|
+
/** 原始端口 Schema,供统一连线校验器读取 type/required/黑白名单等约束。 */
|
|
16
|
+
portSchema?: DipPortSchema;
|
|
12
17
|
style?: React.CSSProperties;
|
|
13
18
|
category?: string;
|
|
14
19
|
protocol?: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DipNodeSchema } from '../api/dip';
|
|
2
|
+
import { HandleConfig } from './SuperBaseNode';
|
|
3
|
+
export interface ClassicNodePackagePortLayout {
|
|
4
|
+
inputs: HandleConfig[];
|
|
5
|
+
outputs: HandleConfig[];
|
|
6
|
+
height: number;
|
|
7
|
+
compact: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 按端口较多的一侧计算 CLASSIC nodepackage 节点高度。
|
|
11
|
+
*
|
|
12
|
+
* 1–6 个端口保持 72px;7–12 个端口按 24px 递增;超过 12 个端口
|
|
13
|
+
* 使用 16px 紧凑步长,并在极端 Schema 下限制节点最大高度。
|
|
14
|
+
*/
|
|
15
|
+
export declare function getClassicNodePackageHeight(portCount: number): {
|
|
16
|
+
height: number;
|
|
17
|
+
compact: boolean;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* 将 NodeSchema 的 inputs/outputs 转为 SuperBaseNode 所需的 handle 配置。
|
|
21
|
+
* 不补造默认端口,空数组即代表该方向没有端口。
|
|
22
|
+
*/
|
|
23
|
+
export declare function createClassicNodePackagePortLayout(schema: Pick<DipNodeSchema, 'inputs' | 'outputs'>): ClassicNodePackagePortLayout;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { DipNodeSchema } from '../api/dip';
|
|
2
|
+
import { HandleConfig } from './SuperBaseNode';
|
|
3
|
+
import { NodeData, NodeType } from '../types/Node';
|
|
4
|
+
type PortLoadStatus = 'legacy' | 'loading' | 'ready' | 'error';
|
|
5
|
+
interface UseClassicNodePackagePortsOptions {
|
|
6
|
+
nodeType: NodeType;
|
|
7
|
+
data: NodeData;
|
|
8
|
+
legacyInputs: HandleConfig[];
|
|
9
|
+
legacyOutputs: HandleConfig[];
|
|
10
|
+
}
|
|
11
|
+
interface ClassicNodePackagePortsResult {
|
|
12
|
+
inputs: HandleConfig[];
|
|
13
|
+
outputs: HandleConfig[];
|
|
14
|
+
height?: number;
|
|
15
|
+
status: PortLoadStatus;
|
|
16
|
+
isNodePackage: boolean;
|
|
17
|
+
schema: DipNodeSchema | null;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 为 CLASSIC nodepackage 节点加载 NodeSchema 并生成动态端口。
|
|
21
|
+
*
|
|
22
|
+
* 仅当宿主开启 connectable 能力、引擎是 CLASSIC 且
|
|
23
|
+
* isClassicNextCompatibleNode 返回 true 时生效;其它节点完整保留 legacy 端口。
|
|
24
|
+
*/
|
|
25
|
+
export declare function useClassicNodePackagePorts({ nodeType, data, legacyInputs, legacyOutputs, }: UseClassicNodePackagePortsOptions): ClassicNodePackagePortsResult;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* EngineMode.NEXT 配置组件(暂废保留分支)
|
|
3
3
|
*
|
|
4
|
-
* 根据 nodeKey 获取 NodeSchema,用 DynamicForm 渲染配置表单。
|
|
4
|
+
* 根据 nodeKey 从 DIP 获取 NodeSchema,用 DynamicForm 渲染配置表单。
|
|
5
5
|
* 当 NodeSchema.credentials 非空时,显示凭据选择器。
|
|
6
|
+
* 当前日常说的“新版节点”一般指 CLASSIC 兼容渲染 NodeSchema 的 nodepackage 节点,
|
|
7
|
+
* 不走这个组件。
|
|
6
8
|
*/
|
|
7
9
|
interface NextNodeConfigProps {
|
|
8
10
|
nodeId: string;
|
package/dist/components/digitalsee/workflow/NodesConfig/components/FormFieldRenderer/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { ExecuteAction } from '../../define/actions';
|
|
2
|
+
import { NodeType } from '../../../types/Node';
|
|
2
3
|
interface IFormFieldRendererProps {
|
|
3
4
|
action: ExecuteAction & {
|
|
4
5
|
proxy_id?: string;
|
|
5
6
|
};
|
|
7
|
+
nodeType?: NodeType | string;
|
|
6
8
|
connector?: {
|
|
7
9
|
id: string;
|
|
8
10
|
deployment_type?: string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { NodeType } from '../types/Node';
|
|
2
|
+
type AnyRecord = Record<string, any>;
|
|
3
|
+
export declare function isMcpGatewayNodeType(nodeType?: string | null): nodeType is NodeType;
|
|
4
|
+
export declare function getMcpGatewayActionKey(nodeType?: string | null): string;
|
|
5
|
+
export declare function isNextCompatibleNodeType(nodeType?: string | null): nodeType is NodeType;
|
|
6
|
+
/**
|
|
7
|
+
* 判断 classic 画布中的节点是否需要用新版 NodeSchema 渲染/保存。
|
|
8
|
+
*
|
|
9
|
+
* 返回 true 的含义不是 EngineMode.NEXT 节点,而是 nodepackage 节点:
|
|
10
|
+
* classic 配置面板里要启用 DynamicForm + NodeSchema 兼容链路。
|
|
11
|
+
* 判定顺序按后端数据可信度从强到弱:
|
|
12
|
+
*
|
|
13
|
+
* 1. `config_schema/properties.sub_params` 是旧节点强信号,直接走旧表单。
|
|
14
|
+
* 2. `action_id/id > 0` 是旧节点强信号;`action_id/id <= 0` 才可能是新版节点。
|
|
15
|
+
* 3. 没有 `action_key/nodeKey` 的节点不能拉新版 schema,仍走旧表单。
|
|
16
|
+
* 4. 老 Loop/If/Switch 保存后没有 `sub_params`,但会出现控制节点业务配置,
|
|
17
|
+
* 这些也必须继续走专用控制表单。
|
|
18
|
+
*/
|
|
19
|
+
export declare function isClassicNextCompatibleNode(nodeType: string | undefined, data?: AnyRecord): boolean;
|
|
20
|
+
export declare function unwrapNextCompatiblePropertiesEnvelope(value: unknown): AnyRecord;
|
|
21
|
+
export declare function getNextCompatibleSubmittedProperties(values: unknown): AnyRecord;
|
|
22
|
+
export declare function getNextCompatibleAccountId(values: unknown): any;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type EntryMode = 'automation' | 'mcp' | null;
|
|
3
|
+
interface EntryTypeSelectorProps {
|
|
4
|
+
onSelect: (mode: Exclude<EntryMode, null>) => void;
|
|
5
|
+
}
|
|
6
|
+
/** @description 首节点入口类型选择。 */
|
|
7
|
+
declare const EntryTypeSelector: React.FC<EntryTypeSelectorProps>;
|
|
8
|
+
export default EntryTypeSelector;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { NodeActionMeta } from '../hooks/useNodeActionState';
|
|
2
|
+
import { ActionItem, NodeTypeItem } from '../types';
|
|
3
|
+
import { default as React } from 'react';
|
|
4
|
+
interface NodeCardListProps {
|
|
5
|
+
isSearching: boolean;
|
|
6
|
+
visibleNodes: NodeTypeItem[];
|
|
7
|
+
useConnectableDataSource: boolean;
|
|
8
|
+
expandedNodeIds: string[];
|
|
9
|
+
nodeActionsMap: Record<string, NodeActionMeta>;
|
|
10
|
+
searchText: string;
|
|
11
|
+
isLoadingNodes: boolean;
|
|
12
|
+
hasMore: boolean;
|
|
13
|
+
onNodeToggle: (node: NodeTypeItem) => void;
|
|
14
|
+
onActionSelect: (node: NodeTypeItem, action: ActionItem) => void;
|
|
15
|
+
onLoadAllActions: (node: NodeTypeItem) => void;
|
|
16
|
+
}
|
|
17
|
+
/** @description 节点卡片集合及其加载、空态和分页尾部。 */
|
|
18
|
+
declare const NodeCardList: React.FC<NodeCardListProps>;
|
|
19
|
+
export default NodeCardList;
|
package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/hooks/useCategories.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import { CategoryItem } from '../types';
|
|
1
|
+
import { CategoryItem, CategoryRequestType } from '../types';
|
|
2
|
+
import { NodeAddInfo } from '../../../types/NodeAddContext';
|
|
2
3
|
interface UseCategoriesProps {
|
|
3
|
-
onFetchCategories: (type?:
|
|
4
|
+
onFetchCategories: (type?: CategoryRequestType) => Promise<CategoryItem[]>;
|
|
4
5
|
restrictToCategory?: string;
|
|
5
6
|
nodeSelectorVisible: boolean;
|
|
6
|
-
nodeAddInfo?:
|
|
7
|
+
nodeAddInfo?: NodeAddInfo | null;
|
|
7
8
|
fallbackCategories?: CategoryItem[];
|
|
9
|
+
requestContextKey: string;
|
|
8
10
|
}
|
|
9
|
-
export declare const useCategories: ({ onFetchCategories, restrictToCategory, nodeSelectorVisible, nodeAddInfo, fallbackCategories, }: UseCategoriesProps) => {
|
|
11
|
+
export declare const useCategories: ({ onFetchCategories, restrictToCategory, nodeSelectorVisible, nodeAddInfo, fallbackCategories, requestContextKey, }: UseCategoriesProps) => {
|
|
10
12
|
categories: CategoryItem[];
|
|
13
|
+
categoriesReady: boolean;
|
|
11
14
|
isLoadingCategories: boolean;
|
|
12
15
|
setCategories: import('react').Dispatch<import('react').SetStateAction<CategoryItem[]>>;
|
|
13
16
|
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ActionItem, LinkSearchParams, ModernNodeSelectorProps, NodeFetchResult, NodeTypeItem } from '../types';
|
|
2
|
+
import { NodeAddInfo } from '../../../types/NodeAddContext';
|
|
3
|
+
type SearchHandler = NonNullable<ModernNodeSelectorProps['onSearch']>;
|
|
4
|
+
type CategoryHandler = NonNullable<ModernNodeSelectorProps['onFetchCategories']>;
|
|
5
|
+
type NodeCategoryHandler = NonNullable<ModernNodeSelectorProps['onFetchNodesByCategory']>;
|
|
6
|
+
type EntryMode = 'automation' | 'mcp' | null;
|
|
7
|
+
interface FetchNodeActionOptions {
|
|
8
|
+
suppressLoading?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface UseConnectableNodeSelectorProps {
|
|
11
|
+
nodeSelectorVisible: boolean;
|
|
12
|
+
entryMode: EntryMode;
|
|
13
|
+
effectiveNodeAddInfo?: NodeAddInfo | null;
|
|
14
|
+
workflowId?: string;
|
|
15
|
+
onSearch?: SearchHandler;
|
|
16
|
+
onFetchCategories?: CategoryHandler;
|
|
17
|
+
onFetchNodesByCategory?: NodeCategoryHandler;
|
|
18
|
+
fetchLegacyNodeActions: (node: NodeTypeItem, options?: FetchNodeActionOptions) => Promise<ActionItem[]>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* @description 为 NodePackage 连线场景选择数据源,并封装查询、边中插入求交与旧接口回退。
|
|
22
|
+
*/
|
|
23
|
+
export declare function useConnectableNodeSelector({ nodeSelectorVisible, entryMode, effectiveNodeAddInfo, workflowId, onSearch, onFetchCategories, onFetchNodesByCategory, fetchLegacyNodeActions, }: UseConnectableNodeSelectorProps): {
|
|
24
|
+
actionRequestContextKey: string;
|
|
25
|
+
connectableContext: import('../utils/connectableQuery').ConnectableQueryContext;
|
|
26
|
+
useConnectableDataSource: boolean;
|
|
27
|
+
onSearch: (params?: LinkSearchParams) => Promise<NodeFetchResult>;
|
|
28
|
+
onFetchCategories: (type?: import('../types').CategoryRequestType) => Promise<import('../types').CategoryItem[] | {
|
|
29
|
+
id: any;
|
|
30
|
+
name: any;
|
|
31
|
+
description: any;
|
|
32
|
+
icon: any;
|
|
33
|
+
search_action: any;
|
|
34
|
+
children: any;
|
|
35
|
+
nodes: any[];
|
|
36
|
+
}[]>;
|
|
37
|
+
onFetchNodesByCategory: (params?: LinkSearchParams) => Promise<NodeFetchResult>;
|
|
38
|
+
fetchNodeActions: (node: NodeTypeItem, options?: FetchNodeActionOptions) => Promise<ActionItem[]>;
|
|
39
|
+
};
|
|
40
|
+
export {};
|
package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/hooks/useNavigation.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { CategoryItem, LinkSearchParams, NodeFetchResult, NodeTypeItem } from '../types';
|
|
2
|
+
import { NodeAddInfo } from '../../../types/NodeAddContext';
|
|
2
3
|
interface UseNavigationProps {
|
|
3
4
|
categories: CategoryItem[];
|
|
5
|
+
categoriesReady: boolean;
|
|
4
6
|
initialCategory?: string;
|
|
5
7
|
nodeSelectorVisible: boolean;
|
|
6
|
-
nodeAddInfo?:
|
|
8
|
+
nodeAddInfo?: NodeAddInfo | null;
|
|
7
9
|
onFetchNodesByCategory: (params?: LinkSearchParams) => Promise<NodeFetchResult>;
|
|
8
10
|
defaultPageSize?: number;
|
|
9
11
|
flowId?: string;
|
|
10
12
|
}
|
|
11
|
-
export declare const useNavigation: ({ categories, initialCategory, nodeSelectorVisible, nodeAddInfo, onFetchNodesByCategory, defaultPageSize, flowId, }: UseNavigationProps) => {
|
|
13
|
+
export declare const useNavigation: ({ categories, categoriesReady, initialCategory, nodeSelectorVisible, nodeAddInfo, onFetchNodesByCategory, defaultPageSize, flowId, }: UseNavigationProps) => {
|
|
12
14
|
categoryNodes: NodeTypeItem[];
|
|
13
15
|
currentCategory: CategoryItem;
|
|
14
16
|
isLoadingNodes: boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ActionItem, NodeTypeItem } from '../types';
|
|
2
|
+
export interface NodeActionMeta {
|
|
3
|
+
actions: ActionItem[];
|
|
4
|
+
loading: boolean;
|
|
5
|
+
source?: 'search-partial' | 'full';
|
|
6
|
+
}
|
|
7
|
+
interface UseNodeActionStateProps {
|
|
8
|
+
actionRequestContextKey: string;
|
|
9
|
+
contextMode?: string;
|
|
10
|
+
fetchNodeActions: (node: NodeTypeItem, options?: {
|
|
11
|
+
suppressLoading?: boolean;
|
|
12
|
+
}) => Promise<ActionItem[]>;
|
|
13
|
+
isMcpServerEntryMode: boolean;
|
|
14
|
+
visibleNodes: NodeTypeItem[];
|
|
15
|
+
searchResults: NodeTypeItem[];
|
|
16
|
+
searchText: string;
|
|
17
|
+
activeCategoryId?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* @description 管理连接器的展开状态、动作缓存,以及异步动作请求的竞态保护。
|
|
21
|
+
*/
|
|
22
|
+
export declare function useNodeActionState({ actionRequestContextKey, contextMode, fetchNodeActions, isMcpServerEntryMode, visibleNodes, searchResults, searchText, activeCategoryId, }: UseNodeActionStateProps): {
|
|
23
|
+
expandedNodeIds: string[];
|
|
24
|
+
nodeActionsMap: Record<string, NodeActionMeta>;
|
|
25
|
+
handleNodeToggle: (node: NodeTypeItem) => Promise<void>;
|
|
26
|
+
handleLoadAllActions: (node: NodeTypeItem) => Promise<void>;
|
|
27
|
+
resetNodeActionState: () => void;
|
|
28
|
+
setExpandedNodeIds: import('react').Dispatch<import('react').SetStateAction<string[]>>;
|
|
29
|
+
};
|
|
30
|
+
export {};
|