发布 v1.10 #5

Merged
czm merged 147 commits from develop into main 2026-08-20 11:36:27 +08:00
3 changed files with 43 additions and 14 deletions
Showing only changes of commit 2abff304ed - Show all commits

View File

@@ -22,22 +22,25 @@
let currentNode = useNodesData(currentNodeId);
const { addParameter } = useAddParameter();
const { updateNodeData } = useSvelteFlow();
const codeNodeHelp = `结果如何返回
- 请把代码执行结果写到 _result 中
- JS_result.answer = 'ok'
- Python_result['answer'] = 'ok'
const codeNodeHelp = `JavaScript 如何返回结果
- 定义 main 函数并返回对象,系统会自动执行
- main 接收由输入参数组成的对象。
输出参数如何配置
- 在“输出参数”中新增字段(如 answer、score
- 字段名建议与 _result 的 key 保持一致,便于下游节点引用
- 字段名与 main 返回对象的 key 保持一致。
- 下游节点可引用代码节点ID.输出参数名。
示例
- 代码里写:
_result.answer = '你好';
_result.score = 95;
function main({ input }) {
return { answer: input, score: 95 };
}
- 输出参数配置answer(String)、score(Number)
- 结束节点输出参数可引用代码节点ID.answer、代码节点ID.score`;
- 结束节点输出参数可引用代码节点ID.answer、代码节点ID.score
兼容说明
- 历史 JavaScript、Python 的 _result 写法仍然支持。`;
const editorParameters = $derived.by(() => {
return (currentNode?.current?.data?.parameters as Array<any>) || data.parameters || [];
@@ -115,7 +118,7 @@
<CodeScriptEditor
mode="textarea"
rows={10}
placeholder="请输入执行代码,输出内容需添加到_result中_result['key'] = value 或者 _result.key = value"
placeholder={'请输入代码,例如function main({ input }) { return { output: input }; }'}
style="width: 100%"
engine={(data.engine as string) || (defaultEngine as string)}
parameters={editorParameters}

View File

@@ -52,6 +52,25 @@ describe('codeCompletion utils', () => {
).toBe(true);
});
it('should prefer main return snippets for javascript output', () => {
const completions = createBusinessCompletions('javascript', []);
const mainCompletion = completions.find((item) => item.label === 'main');
const resultCompletion = completions.find(
(item) => item.label === 'result-object',
);
expect(mainCompletion).toMatchObject({
type: 'snippet',
detail: '代码节点入口',
boost: 1000,
});
expect(String(mainCompletion?.apply)).toContain('function main');
expect(String(mainCompletion?.apply)).toContain('return {');
expect(String(resultCompletion?.apply)).toBe(
"return { message: 'ok', data };",
);
});
it('should detect blocked nodes for comment/string/property contexts', () => {
expect(shouldSkipBusinessCompletion('Comment')).toBe(true);
expect(shouldSkipBusinessCompletion('LineComment')).toBe(true);

View File

@@ -30,21 +30,28 @@ const BLOCKED_NODE_NAMES = new Set([
]);
const JS_SNIPPETS: Array<{ label: string; insert: string; detail: string }> = [
{
label: 'main',
detail: '代码节点入口',
insert:
'function main({ input }) {\n return {\n output: input,\n };\n}',
},
{
label: 'if-else',
detail: '条件分支',
insert:
'if (condition) {\n _result.value = value;\n} else {\n _result.value = null;\n}',
'if (condition) {\n return { value };\n}\nreturn { value: null };',
},
{
label: 'for-of',
detail: '遍历数组',
insert: 'for (const item of items) {\n // TODO\n}\n_result.done = true;',
insert:
'const result = [];\nfor (const item of items) {\n result.push(item);\n}\nreturn { result };',
},
{
label: 'result-object',
detail: '返回对象',
insert: "_result.message = 'ok';\n_result.data = data;",
insert: "return { message: 'ok', data };",
},
];
@@ -99,7 +106,7 @@ export function createBusinessCompletions(
const resultCompletion: Completion = {
label: '_result',
type: 'variable',
detail: '代码节点输出对象',
detail: '兼容旧版输出对象',
boost: 900,
};
@@ -118,7 +125,7 @@ export function createBusinessCompletions(
type: 'snippet',
detail: snippet.detail,
apply: snippet.insert,
boost: 500,
boost: snippet.label === 'main' ? 1000 : 500,
}));
return dedupeCompletions([