feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv
2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 入参路径,试运行等功能依赖该路径提取参数
export const INPUT_PATH = 'inputs.inputParameters';

View File

@@ -0,0 +1,17 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { SetTags } from './set-tags';

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useWorkflowNode } from '@coze-workflow/base';
import { I18n } from '@coze-arch/i18n';
import { VariableTagList } from '@/components/node-render/node-render-new/fields/variable-tag-list';
import { Field } from '@/components/node-render/node-render-new/fields';
import { useSetTags } from './use-set-tags';
export function SetTags() {
const { inputParameters } = useWorkflowNode();
const variableTags = useSetTags(inputParameters);
const isEmpty = !variableTags || variableTags.length === 0;
return (
<Field label={I18n.t('workflow_loop_set_variable_set')} isEmpty={isEmpty}>
<VariableTagList value={variableTags} />
</Field>
);
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useCurrentEntity } from '@flowgram-adapter/free-layout-editor';
import { type InputValueVO, type RefExpression } from '@coze-workflow/base';
import { useVariableService } from '@/hooks';
import { type VariableTagProps } from '@/components/node-render/node-render-new/fields/variable-tag-list';
export function useSetTags(
inputParameters: InputValueVO[] | Record<string, InputValueVO['input']> = [],
): VariableTagProps[] {
const node = useCurrentEntity();
const variableService = useVariableService();
if (!Array.isArray(inputParameters)) {
return [];
}
const setVariableInputs = inputParameters as unknown as {
left: RefExpression;
right: RefExpression;
}[];
return setVariableInputs
.map(({ left }) => {
const variable = variableService.getWorkflowVariableByKeyPath(
left?.content?.keyPath,
{ node, checkScope: true },
);
if (!variable) {
const pathLabel = left?.content?.keyPath[1];
if (pathLabel) {
// 有值但找不到变量
return {
label: pathLabel,
invalid: true,
};
} else {
// 没有值
return;
}
}
const viewType = left?.rawMeta?.type ?? variable.viewType;
const variableTag: VariableTagProps = {
label: variable.viewMeta?.name ?? variable.keyPath[1],
type: viewType,
};
return variableTag;
})
.filter(Boolean) as VariableTagProps[];
}

View File

@@ -0,0 +1,157 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable @typescript-eslint/no-explicit-any */
import { variableUtils } from '@coze-workflow/variable';
import {
ValueExpressionType,
type NodeDataDTO,
type RefExpression,
type ValueExpression,
type ValueExpressionDTO,
} from '@coze-workflow/base';
/**
* 节点后端数据 -> 前端表单数据
*/
export const transformOnInit = (formData: any, ctx: any) => {
const inputParameterDTOs: {
left: ValueExpressionDTO;
right: ValueExpressionDTO;
}[] = formData?.inputs?.inputParameters ?? [];
const inputParameterVOs: {
left: ValueExpression;
right: ValueExpression;
}[] = inputParameterDTOs
.map(inputParameterDTO => {
const leftVariableDTO = inputParameterDTO?.left;
const rightVariableDTO = inputParameterDTO?.right;
if (!leftVariableDTO || !rightVariableDTO) {
return;
}
const leftVariableVO = variableUtils.valueExpressionToVO(
leftVariableDTO,
ctx.playgroundContext.variableService,
);
const rightVariableVO = variableUtils.valueExpressionToVO(
rightVariableDTO,
ctx.playgroundContext.variableService,
);
return {
left: leftVariableVO,
right: rightVariableVO,
};
})
.filter(Boolean) as {
left: ValueExpression;
right: ValueExpression;
}[];
const defaultInputParameterVOs = [
{
left: {
type: ValueExpressionType.REF,
},
right: {
type: ValueExpressionType.REF,
},
},
];
return {
...(formData ?? {}),
inputs: {
...(formData?.inputs ?? {}),
inputParameters:
inputParameterVOs.length === 0
? defaultInputParameterVOs
: inputParameterVOs,
},
};
};
/**
* 前端表单数据 -> 节点后端数据
* @param value
* @returns
*/
export const transformOnSubmit = (formData: any, ctx: any): NodeDataDTO => {
const inputParameterVOs: {
left: ValueExpression;
right: ValueExpression;
}[] = formData?.inputs?.inputParameters ?? [];
const inputParameterDTOs: {
left: ValueExpressionDTO;
right: ValueExpressionDTO;
}[] = inputParameterVOs
.map(inputParameterVO => {
const leftVariableVO = inputParameterVO?.left as RefExpression;
const rightVariableVO = inputParameterVO?.right as RefExpression;
if (!leftVariableVO || !rightVariableVO) {
return;
}
const leftKeyPath = leftVariableVO.content?.keyPath;
const rightKeyPath = rightVariableVO.content?.keyPath;
if (
!leftKeyPath ||
!rightKeyPath ||
!leftKeyPath[0] ||
!rightKeyPath[0]
) {
return;
}
const leftVariableDTO = variableUtils.valueExpressionToDTO(
leftVariableVO,
ctx.playgroundContext.variableService,
{ node: ctx.node },
);
const rightVariableDTO = variableUtils.valueExpressionToDTO(
rightVariableVO,
ctx.playgroundContext.variableService,
{ node: ctx.node },
);
if (!leftVariableDTO || !rightVariableDTO) {
return;
}
return {
left: leftVariableDTO,
right: rightVariableDTO,
};
})
.filter(Boolean) as {
left: ValueExpressionDTO;
right: ValueExpressionDTO;
}[];
return {
...(formData ?? {}),
inputs: {
...(formData?.inputs ?? {}),
inputParameters: inputParameterDTOs,
},
};
};

View File

@@ -0,0 +1,17 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { SetVariableField } from './set-variable';

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useCurrentEntity } from '@flowgram-adapter/free-layout-editor';
import { type RefExpression, useNodeTestId } from '@coze-workflow/base';
import { MutableVariableAssign } from '@/form-extensions/components/mutable-variable-assign';
import { useField, withField } from '@/form';
import type { SetVariableItem } from '../types';
interface MutableVariableAssignFieldProps {
right: RefExpression;
inputParameters: SetVariableItem[];
index: number;
}
export const MutableVariableAssignField =
withField<MutableVariableAssignFieldProps>(
({ right, inputParameters, index }) => {
const node = useCurrentEntity();
const { name, value, onChange, readonly } = useField<RefExpression>();
const { getNodeSetterId } = useNodeTestId();
const testId = getNodeSetterId(name);
return (
<MutableVariableAssign
value={value}
onChange={onChange}
readonly={readonly}
right={right}
inputParameters={inputParameters}
index={index}
node={node}
testId={testId}
/>
);
},
);

View File

@@ -0,0 +1,131 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable @typescript-eslint/consistent-type-assertions */
import {
FieldArray,
type FieldArrayRenderProps,
} from '@flowgram-adapter/free-layout-editor';
import { type RefExpression } from '@coze-workflow/base';
import { I18n } from '@coze-arch/i18n';
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
import { ValueExpressionInputField } from '@/node-registries/common/fields';
import { ColumnsTitleWithAction } from '@/form-extensions/components/columns-title-with-action';
import {
AddButton,
FieldArrayItem,
FieldRows,
Section,
type FieldProps,
} from '@/form';
import { type SetVariableItem } from '../types';
import { MutableVariableAssignField } from './mutable-variable-assign';
interface SetVariableFieldProps extends FieldProps<SetVariableItem[]> {
title?: string;
nthCannotDeleted?: number;
}
export const SetVariableField = ({
name,
defaultValue,
title = I18n.t('workflow_loop_set_variable_set'),
tooltip,
nthCannotDeleted = 1,
}: SetVariableFieldProps) => {
const readonly = useReadonly();
return (
<FieldArray<SetVariableItem> name={name} defaultValue={defaultValue ?? []}>
{({ field }: FieldArrayRenderProps<SetVariableItem>) => {
const { value = [], delete: remove, append } = field;
const length = value?.length ?? 0;
const isEmpty = !length;
const disableRemove = nthCannotDeleted === length;
return (
<Section
title={title}
tooltip={tooltip}
actions={
!readonly
? [
<AddButton
onClick={() => {
append({
left: {} as RefExpression,
right: {} as RefExpression,
});
}}
/>,
]
: []
}
isEmpty={isEmpty}
emptyText={I18n.t('workflow_inputs_empty')}
>
<ColumnsTitleWithAction
columns={[
{
title: I18n.t('workflow_loop_set_variable_loopvariable'),
style: {
width: '50%',
},
},
{
title: I18n.t('workflow_loop_set_variable_variable'),
style: {
width: '50%',
},
},
]}
readonly={readonly}
className="mb-[8px]"
style={{
display: isEmpty ? 'none' : 'flex',
}}
/>
<FieldRows>
{field.map((item, index) => (
<FieldArrayItem
key={item.key}
disableRemove={disableRemove}
hiddenRemove={readonly}
onRemove={() => remove(index)}
>
<div style={{ width: '50%' }}>
<MutableVariableAssignField
name={`${item.name}.left`}
right={item.value.right}
inputParameters={value}
index={index}
/>
</div>
<div style={{ width: '50%' }}>
<ValueExpressionInputField
name={`${item.name}.right`}
literalDisabled={true}
/>
</div>
</FieldArrayItem>
))}
</FieldRows>
</Section>
);
}}
</FieldArray>
);
};

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
ValidateTrigger,
type FormMetaV2,
} from '@flowgram-adapter/free-layout-editor';
import { nodeMetaValidate } from '@/nodes-v2/materials/node-meta-validate';
import {
fireNodeTitleChange,
provideNodeOutputVariablesEffect,
} from '@/node-registries/common/effects';
import {
VariableAssignLeftValidator,
VariableAssignRightValidator,
} from './validators';
import { type FormData } from './types';
import { FormRender } from './form';
import { transformOnInit, transformOnSubmit } from './data-transformer';
export const SET_VARIABLE_FORM_META: FormMetaV2<FormData> = {
// 节点表单渲染
render: () => <FormRender />,
// 验证触发时机
validateTrigger: ValidateTrigger.onChange,
// 验证规则
validate: {
nodeMeta: nodeMetaValidate,
'inputs.inputParameters.*.left': VariableAssignLeftValidator,
'inputs.inputParameters.*.right': VariableAssignRightValidator,
},
// 副作用管理
effect: {
nodeMeta: fireNodeTitleChange,
outputs: provideNodeOutputVariablesEffect,
},
// 节点后端数据 -> 前端表单数据
formatOnInit: transformOnInit,
// 前端表单数据 -> 节点后端数据
formatOnSubmit: transformOnSubmit,
};

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NodeConfigForm } from '@/node-registries/common/components';
import { INPUT_PATH } from './constants';
import { SetVariableField } from './fields';
export const FormRender = () => (
<NodeConfigForm>
<SetVariableField name={INPUT_PATH} />
</NodeConfigForm>
);

View File

@@ -0,0 +1,18 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { SET_VARIABLE_NODE_REGISTRY } from './node-registry';
export { SetVariableContent } from './node-content';

View File

@@ -0,0 +1,25 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SetTags } from './content';
export function SetVariableContent() {
return (
<>
<SetTags />
</>
);
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
DEFAULT_NODE_META_PATH,
DEFAULT_OUTPUTS_PATH,
} from '@coze-workflow/nodes';
import {
StandardNodeType,
type WorkflowNodeRegistry,
} from '@coze-workflow/base';
import { SET_VARIABLE_FORM_META } from './form-meta';
import { INPUT_PATH } from './constants';
export const SET_VARIABLE_NODE_REGISTRY: WorkflowNodeRegistry = {
type: StandardNodeType.SetVariable,
meta: {
hideTest: true,
nodeDTOType: StandardNodeType.SetVariable,
size: { width: 360, height: 87.86 },
nodeMetaPath: DEFAULT_NODE_META_PATH,
outputsPath: DEFAULT_OUTPUTS_PATH,
inputParametersPath: INPUT_PATH, // 入参路径,试运行等功能依赖该路径提取参数
},
variablesMeta: {
outputsPathList: [],
inputsPathList: [],
},
formMeta: SET_VARIABLE_FORM_META,
};

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { RefExpression } from '@coze-workflow/base';
export interface SetVariableItem {
left: RefExpression;
right: RefExpression;
}
export interface FormData {
inputs: { inputParameters: SetVariableItem[] };
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type {
PlaygroundContext,
WorkflowNodeEntity,
} from '@flowgram-adapter/free-layout-editor';
import {
type RefExpression,
type ViewVariableMeta,
type ViewVariableType,
WorkflowNode,
} from '@coze-workflow/base';
export const getLeftRightVariable = (params: {
node: WorkflowNodeEntity;
name: string;
playgroundContext: PlaygroundContext;
}): {
left: ViewVariableMeta;
right: ViewVariableMeta;
leftPath?: string[];
rightPath?: string[];
leftType?: ViewVariableType;
rightType?: ViewVariableType;
} => {
const { node, playgroundContext, name } = params;
const workflowNode = new WorkflowNode(node);
const index = Number(name.slice(23, 24));
const left = workflowNode.getValueByPath<RefExpression>(
`inputs.inputParameters.${index}.left`,
);
const right = workflowNode.getValueByPath<RefExpression>(
`inputs.inputParameters.${index}.right`,
);
const leftKeyPath = left?.content?.keyPath ?? [];
const rightKeyPath = right?.content?.keyPath ?? [];
const leftVariable =
playgroundContext.variableService.getViewVariableByKeyPath(leftKeyPath, {
node,
});
const rightVariable =
playgroundContext.variableService.getViewVariableByKeyPath(rightKeyPath, {
node,
});
return {
left: leftVariable,
right: rightVariable,
leftPath: left?.content?.keyPath,
rightPath: right?.content?.keyPath,
leftType: left.rawMeta?.type ?? leftVariable?.type,
rightType: right.rawMeta?.type ?? rightVariable?.type,
};
};

View File

@@ -0,0 +1,17 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { getLeftRightVariable } from './get-left-right-variable';

View File

@@ -0,0 +1,18 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { VariableAssignLeftValidator } from './variable-assign-left';
export { VariableAssignRightValidator } from './variable-assign-right';

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable @typescript-eslint/naming-convention*/
import { type Validate } from '@flowgram-adapter/free-layout-editor';
import type { RefExpression } from '@coze-workflow/base';
import { I18n } from '@coze-arch/i18n';
import { valueExpressionValidator } from '@/form-extensions/validators';
import { getLeftRightVariable } from '../utils';
export const VariableAssignLeftValidator: Validate<RefExpression> = (params => {
const { context, value, name } = params;
const { playgroundContext, node } = context;
const valueExpressionValid = valueExpressionValidator({
value,
playgroundContext,
node,
required: true,
});
if (valueExpressionValid) {
return valueExpressionValid;
}
const { left, right, leftPath, rightPath, leftType, rightType } =
getLeftRightVariable({
node,
name,
playgroundContext,
});
if (!left) {
return I18n.t('workflow_detail_node_error_empty');
}
if (right && leftType !== rightType) {
return I18n.t('workflow_loop_set_variable_typewrong');
}
if (leftPath && rightPath && leftPath.join('.') === rightPath.join('.')) {
return I18n.t('workflow_loop_set_variable_samewrong');
}
return true;
}) as Validate<RefExpression>;

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable @typescript-eslint/naming-convention*/
import { type Validate } from '@flowgram-adapter/free-layout-editor';
import type { RefExpression } from '@coze-workflow/base';
import { I18n } from '@coze-arch/i18n';
import { valueExpressionValidator } from '@/form-extensions/validators';
import { getLeftRightVariable } from '../utils';
export const VariableAssignRightValidator: Validate<RefExpression> =
(params => {
const { context, value, name } = params;
const { playgroundContext, node } = context;
const valueExpressionValid = valueExpressionValidator({
value,
playgroundContext,
node,
required: true,
});
if (valueExpressionValid) {
return valueExpressionValid;
}
const { right } = getLeftRightVariable({ node, name, playgroundContext });
if (!right) {
return I18n.t('workflow_detail_node_error_empty');
}
return true;
}) as Validate<RefExpression>;