From 46398d1365e25afceca60b7783a02fa19061c381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=AD=90=E9=BB=98?= <925456043@qq.com> Date: Mon, 3 Aug 2026 16:20:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=A8=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E8=BE=93=E5=85=A5=E8=BE=93=E5=87=BA=E6=99=BA?= =?UTF-8?q?=E8=83=BD=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 为 JavaScript 和 Python 新节点生成 main 与显式调用脚手架 - 同步输入签名、静态返回字段和输出参数并推断受支持类型 - 增加安全改写边界与 Tinyflow 定向测试 --- .../src/components/core/OutputDefItem.svelte | 59 +- .../src/components/core/OutputDefList.svelte | 14 +- .../components/core/RefParameterItem.svelte | 37 +- .../components/core/RefParameterList.svelte | 6 +- .../src/components/nodes/CodeNode.svelte | 202 ++- .../src/components/utils/codeNodeScaffold.ts | 168 +++ .../src/components/utils/codeNodeSync.test.ts | 544 ++++++++ .../src/components/utils/codeNodeSync.ts | 1121 +++++++++++++++++ .../src/components/utils/nodePalette.ts | 8 + .../packages/tinyflow-ui/src/types.ts | 18 +- 10 files changed, 2107 insertions(+), 70 deletions(-) create mode 100644 easyflow-ui-admin/packages/tinyflow-ui/src/components/utils/codeNodeScaffold.ts create mode 100644 easyflow-ui-admin/packages/tinyflow-ui/src/components/utils/codeNodeSync.test.ts create mode 100644 easyflow-ui-admin/packages/tinyflow-ui/src/components/utils/codeNodeSync.ts diff --git a/easyflow-ui-admin/packages/tinyflow-ui/src/components/core/OutputDefItem.svelte b/easyflow-ui-admin/packages/tinyflow-ui/src/components/core/OutputDefItem.svelte index 4e94d154..3a4685ae 100644 --- a/easyflow-ui-admin/packages/tinyflow-ui/src/components/core/OutputDefItem.svelte +++ b/easyflow-ui-admin/packages/tinyflow-ui/src/components/core/OutputDefItem.svelte @@ -5,14 +5,21 @@ import {useNodesData, useSvelteFlow} from '@xyflow/svelte'; import {parameterDataTypes} from '#consts'; import {genShortId} from '../utils/IdGen'; - import type {Parameter} from '#types'; + import type {Parameter, ParameterChangeHandler} from '#types'; import {deepClone} from '../utils/deepClone'; - const { parameter, position, dataKeyName, placeholder = '请输入参数值' }: { + const { + parameter, + position, + dataKeyName, + placeholder = '请输入参数值', + onParametersChange, + }: { parameter: Parameter, position: number[], dataKeyName: string, placeholder?: string, + onParametersChange?: ParameterChangeHandler, } = $props(); @@ -50,9 +57,12 @@ const updateAttribute = (key: string, value: any) => { updateNodeData(currentNodeId, (node) => { - const parameters = node.data?.[dataKeyName] as Array; - if (parameters && position.length > 0) { - let params = parameters as Parameter[]; + const previousParameters = deepClone( + (node.data?.[dataKeyName] as Array) || [] + ); + const nextParameters = deepClone(previousParameters); + if (nextParameters.length > 0 && position.length > 0) { + let params = nextParameters; for (let i = 0; i < position.length; i++) { const pos = position[i]; if (i == position.length - 1) { @@ -66,7 +76,12 @@ } } return { - [dataKeyName]: [...deepClone(parameters)] + [dataKeyName]: nextParameters, + ...onParametersChange?.( + previousParameters, + nextParameters, + node.data + ) }; }); }; @@ -87,9 +102,12 @@ let triggerObject: any; const handleDelete = () => { updateNodeData(currentNodeId, (node) => { - let parameters = node.data?.[dataKeyName] as Array; - if (parameters && position.length > 0) { - let params = parameters as Array; + const previousParameters = deepClone( + (node.data?.[dataKeyName] as Array) || [] + ); + const nextParameters = deepClone(previousParameters); + if (nextParameters.length > 0 && position.length > 0) { + let params = nextParameters; for (let i = 0; i < position.length; i++) { const pos = position[i]; if (i == position.length - 1) { @@ -100,7 +118,12 @@ } } return { - [dataKeyName]: [...deepClone(parameters)] + [dataKeyName]: nextParameters, + ...onParametersChange?.( + previousParameters, + nextParameters, + node.data + ) }; }); triggerObject?.hide(); @@ -109,9 +132,12 @@ const handleAddChildParameter = () => { updateNodeData(currentNodeId, (node) => { - let parameters = node.data?.[dataKeyName] as Array; - if (parameters && position.length > 0) { - let params = parameters as Array; + const previousParameters = deepClone( + (node.data?.[dataKeyName] as Array) || [] + ); + const nextParameters = deepClone(previousParameters); + if (nextParameters.length > 0 && position.length > 0) { + let params = nextParameters; for (let i = 0; i < position.length; i++) { const pos = position[i]; if (i == position.length - 1) { @@ -137,7 +163,12 @@ } return { - [dataKeyName]: [...deepClone(parameters)] + [dataKeyName]: nextParameters, + ...onParametersChange?.( + previousParameters, + nextParameters, + node.data + ) }; }); }; diff --git a/easyflow-ui-admin/packages/tinyflow-ui/src/components/core/OutputDefList.svelte b/easyflow-ui-admin/packages/tinyflow-ui/src/components/core/OutputDefList.svelte index 276d9930..1e649a82 100644 --- a/easyflow-ui-admin/packages/tinyflow-ui/src/components/core/OutputDefList.svelte +++ b/easyflow-ui-admin/packages/tinyflow-ui/src/components/core/OutputDefList.svelte @@ -1,17 +1,19 @@ @@ -109,19 +228,14 @@ Python 示例 - + 代码
执行引擎