chore: replace all cn comments of fe to en version by volc api (#320)

This commit is contained in:
tecvan
2025-07-31 10:32:15 +08:00
committed by GitHub
parent 716ec0cba8
commit 71f6245a01
2960 changed files with 15545 additions and 15545 deletions

View File

@@ -24,12 +24,12 @@ export class CustomArrayType extends ArrayType {
// const [curr, ...rest] = keyPath || [];
// if (curr === '0' && this.canDrilldownItems) {
// // 数组第 0 项
// //Array item 0
// return this.items.getByKeyPath(rest);
// }
if (this.canDrilldownItems) {
// Coze 中兜底为第 0 项
// The bottom line in Coze is item 0
return this.items.getByKeyPath(keyPath);
}

View File

@@ -41,7 +41,7 @@ export interface RefExpressionJSON extends KeyPathExpressionJSON {
}
/**
* 业务重新定义 KeyPath 的实现方式
* Business redefines how KeyPath is implemented
*/
export class CustomKeyPathExpression extends KeyPathExpression<RefExpressionJSON> {
get renameService(): VariableFieldKeyRenameService {
@@ -51,7 +51,7 @@ export class CustomKeyPathExpression extends KeyPathExpression<RefExpressionJSON
_rawMeta?: RefExpressionJSON['rawMeta'];
/**
* 重载 getRefFields 方法
* Overloading the getRefFields method
* @returns
*/
getRefFields(): WorkflowVariableField[] {
@@ -60,9 +60,9 @@ export class CustomKeyPathExpression extends KeyPathExpression<RefExpressionJSON
node: this.scope.meta?.node,
});
// 刷新引用时,检测循环引用,如果存在循环引用则不引用该变量
// When refreshing the reference, the circular reference is detected, and the variable is not referenced if there is a circular reference
if (checkRefCycle(this, [ref])) {
// 提示存在循环引用
// Prompt for a circular reference
console.warn(
'[CustomKeyPathExpression] checkRefCycle: Reference Cycle Existed',
getParentFields(this)
@@ -85,8 +85,8 @@ export class CustomKeyPathExpression extends KeyPathExpression<RefExpressionJSON
super.fromJSON(json);
}
// 直接生成新的 returnType 节点而不是直接复用
// 确保不同的 keyPath 不指向同一个 Field
// Generate new returnType nodes directly instead of directly reusing them
// Make sure that different keypaths do not point to the same Field.
_returnType: BaseType;
get returnType() {
@@ -114,11 +114,11 @@ export class CustomKeyPathExpression extends KeyPathExpression<RefExpressionJSON
if (this._rawMeta?.type) {
const shouldUseRawMeta =
// 1. 没有引用变量时,使用 rawMeta 的类型
// 1. When no variable is referenced, use the type of rawMeta
!ref ||
// 2. Object Array<Object>,使用 rawMeta 的类型
// 2. Non-Object and Array < Object >, using the type of rawMeta
!ViewVariableType.canDrilldown(this._rawMeta.type) ||
// 3. 如果是可下钻的类型,需要判断引用的变量类型和 rawMeta 的类型是否一致,不一致时使用 rawMeta 的数据
// 3. If it is a drillable type, you need to determine whether the referenced variable type is the same as the type of rawMeta. If it is inconsistent, use the data of rawMeta
getViewVariableTypeByAST(ref.type).type !== this._rawMeta.type;
if (shouldUseRawMeta) {
@@ -156,7 +156,7 @@ export class CustomKeyPathExpression extends KeyPathExpression<RefExpressionJSON
this.toDispose.pushAll([
Disposable.create(() => subscription.unsubscribe()),
// 当前引用被 rename 时,刷新一下引用
// When the current reference is renamed, refresh the reference
this.renameService.onRename(({ before, after }) => {
const field = this.refs?.[0];

View File

@@ -58,7 +58,7 @@ export class MergeGroupExpression extends BaseExpression {
fromJSON(json: MergeGroupExpressionJSON): void {
const {
// 默认使用“首个非空”策略
// The "first non-empty" policy is used by default
mergeStrategy = MergeStrategy.FirstNotEmpty,
expressions = [],
} = json || {};
@@ -68,13 +68,13 @@ export class MergeGroupExpression extends BaseExpression {
this.fireChange();
}
// 超出长度的 expressions 需要被销毁
// Expressions that exceed their length need to be destroyed
this._expressions.slice(expressions.length).forEach(_item => {
_item.dispose();
this.fireChange();
});
// 剩余 expressions 的处理
// Processing of residual expressions
this._expressions = expressions.map((_item, idx) => {
const prevItem = this._expressions[idx];
@@ -89,7 +89,7 @@ export class MergeGroupExpression extends BaseExpression {
});
}
// 获取聚合变量的类型
// Get the type of the aggregate variable
protected syncReturnType(): ASTNodeJSON | undefined {
if (this._mergeStrategy === MergeStrategy.FirstNotEmpty) {
const nextTypeJSON = this._expressions[0]?.returnType?.toJSON();
@@ -103,12 +103,12 @@ export class MergeGroupExpression extends BaseExpression {
for (const _expr of this._expressions.slice(1)) {
const _returnType = _expr.returnType;
// 该引用没有类型,则聚合类型为首个变量类型不下钻
// If the reference has no type, the aggregate type is the first variable type
if (!_returnType) {
return nextWeakTypeJSON;
}
// 该引用和第一个变量没有强一致,则聚合类型为首个变量类型不下钻
// If the reference is not strongly consistent with the first variable, the aggregate type is the first variable type
if (!_returnType.isTypeEqual(nextTypeJSON)) {
return nextWeakTypeJSON;
}
@@ -122,7 +122,7 @@ export class MergeGroupExpression extends BaseExpression {
getWeakTypeJSON(fullType?: ASTNodeJSON | undefined) {
if (fullType?.kind === ASTKind.Object) {
// Object 不下钻
// Object no drill
return { kind: ASTKind.Object, weak: true };
}
if (fullType?.kind === ASTKind.Array) {
@@ -142,7 +142,7 @@ export class MergeGroupExpression extends BaseExpression {
triggerOnInit: true,
selector: curr => [
curr._mergeStrategy,
// 表达式 hash 是否发生变更
// Has the expression hash changed?
...curr._expressions.map(_expr => _expr.hash),
],
},

View File

@@ -26,7 +26,7 @@ import {
} from './custom-key-path-expression';
/**
* 遍历表达式,对列表进行遍历,获取遍历后的变量类型
* Traverse the expression, traverse the list, and get the traversed variable type
*/
export class WrapArrayExpression extends CustomKeyPathExpression {
static kind = 'WrapArrayExpression';

View File

@@ -21,5 +21,5 @@ export {
} from './utils/create-ast';
export { WorkflowVariableFacadeService } from './workflow-variable-facade-service';
// 重命名为 WorkflowVariable,便于业务理解
// Rename to WorkflowVariable for easier business understanding
export { WorkflowVariableFacade as WorkflowVariable } from './workflow-variable-facade';

View File

@@ -34,14 +34,14 @@ export interface RenameInfo {
prevKeyPath: string[];
nextKeyPath: string[];
// rename 的位置,及对应的 key 值
// The location of the rename, and the corresponding key value
modifyIndex: number;
modifyKey: string;
}
export interface GetKeyPathCtx {
// 当前所在的节点
// The current node
node?: FlowNodeEntity;
// 验证变量是否在作用域内
// Verify that the variable is in scope
checkScope?: boolean;
}

View File

@@ -33,14 +33,14 @@ import { createExtendBaseType } from '../extend-ast/extend-base-type';
import { createRefExpression } from '../extend-ast/custom-key-path-expression';
/**
* ViewVariableType AST
* @param type 类型
* @param properties 下钻字段
* ViewVariableType to AST
* @param type
* @param properties drill down fields
* @returns
*/
export const createASTFromType = (
type: ViewVariableType,
// 下钻字段
// drill down field
properties?: PropertyJSON[],
): ASTNodeJSON | undefined => {
if (ViewVariableType.isArrayType(type)) {
@@ -66,13 +66,13 @@ export const createASTFromType = (
properties,
});
default:
// 其余扩展的基础类型
// The basic types of the remaining extensions
return createExtendBaseType({ type });
}
};
/**
* ViewVariableTreeNode 转属性
* ViewVariableTreeNode properties
* @param treeNode
* @returns
*/
@@ -99,7 +99,7 @@ export const createASTPropertyFromViewVariable = (
};
/**
* 节点输出变量生成
* Node output variable generation
* @param rootKey
* @param variables
* @returns
@@ -111,7 +111,7 @@ export const parseNodeOutputByViewVariableMeta = (
const list = uniqBy(
isArray(value) ? value : [value],
_child => _child?.name,
// Preset 变量没有开启 enable 时不生成变量
// No variable is generated when the Preset variable is not enabled
).filter(v => v && v.name && !(v.isPreset && !v.enabled));
if (list.length > 0) {
@@ -131,7 +131,7 @@ export const parseNodeOutputByViewVariableMeta = (
};
/**
* Batch 输出变量生成
* Batch output variable generation
* @param rootKey
* @param inputList
* @returns

View File

@@ -22,7 +22,7 @@ import {
ASTNodeFlags,
} from '@flowgram-adapter/free-layout-editor';
// 获取所有的子 AST 节点
// Get all child AST nodes
export function getAllChildren(ast: ASTNode): ASTNode[] {
return [
...ast.children,
@@ -30,7 +30,7 @@ export function getAllChildren(ast: ASTNode): ASTNode[] {
];
}
// 获取父 Fields
// Get Parent Fields
export function getParentFields(ast: ASTNode): BaseVariableField[] {
let curr = ast.parent;
const res: BaseVariableField[] = [];
@@ -45,7 +45,7 @@ export function getParentFields(ast: ASTNode): BaseVariableField[] {
return res;
}
// 获取所有子 AST 引用的变量
// Get all variables referenced by the child AST
export function getAllRefs(ast: ASTNode): BaseVariableField[] {
return getAllChildren(ast)
.filter(_child => _child.flags & ASTNodeFlags.Expression)
@@ -55,16 +55,16 @@ export function getAllRefs(ast: ASTNode): BaseVariableField[] {
}
/**
* 检测是否成环
* @param curr 当前表达式
* @param refNode 引用的变量节点
* @returns 是否成环
* Check if it is a ring.
* @param curr current expression
* Variable node referenced by @param refNode
* @Returns is a loop
*/
export function checkRefCycle(
curr: BaseExpression,
refNodes: (BaseVariableField | undefined)[],
): boolean {
// 作用域没有成环,则不可能成环
// If the scope is not cyclic, it cannot be cyclic
if (
intersection(
curr.scope.coverScopes,
@@ -74,7 +74,7 @@ export function checkRefCycle(
return false;
}
// BFS 遍历
// BFS Traversal
const visited = new Set<BaseVariableField>();
const queue = [...refNodes];
@@ -90,6 +90,6 @@ export function checkRefCycle(
}
}
// 引用的变量中,包含表达式的父变量,则成环
// If the referenced variable contains the parent variable of the expression, it forms a ring
return intersection(Array.from(visited), getParentFields(curr)).length > 0;
}

View File

@@ -46,7 +46,7 @@ export function getByNamePath(
...(node?.getData(FlowNodeVariableData)?.private?.depScopes || []),
]);
// 节点的依赖作用域中是否存在 nodeId 的 private
// Is there a private nodeId in the node's dependency scope?
if (nodeDepScopes?.find(_scope => _scope.id === `${nodeId}_private`)) {
return variableEngine.globalVariableTable.getByKeyPath([
`${nodeId}.locals`,
@@ -54,7 +54,7 @@ export function getByNamePath(
]);
}
// 节点的依赖作用域是否存在 nodeId 的 public
// Does the node's dependency scope have a public nodeId?
if (nodeDepScopes?.find(_scope => _scope.id === `${nodeId}`)) {
return variableEngine.globalVariableTable.getByKeyPath([
`${nodeId}.outputs`,
@@ -62,7 +62,7 @@ export function getByNamePath(
]);
}
// 如果业务验证是否在作用域内,不在作用域内直接返回结果
// If the business verification is in scope, return the result directly if it is not in scope
if (checkScope) {
return;
}

View File

@@ -41,7 +41,7 @@ export const getViewVariableTypeByAST = (
return {
type:
// 暂时不支持二维数组
// Two-dimensional arrays are temporarily not supported
type && !ViewVariableType.isArrayType(type)
? ViewVariableType.wrapToArrayType(type)
: type,

View File

@@ -33,7 +33,7 @@ import { getByNamePath } from './utils/name-path';
import { type GetKeyPathCtx, type WorkflowVariableField } from './types';
/**
* 引擎内部接口,针对 Coze Workflow 封装变量外观接口
* Engine internal interface, wrapping variable appearance interface for Coze Workflow
*/
@injectable()
export class WorkflowVariableFacadeService {
@@ -48,13 +48,13 @@ export class WorkflowVariableFacadeService {
@postConstruct()
init() {
// 变量引用 rename, 确保节点 UI 不渲染时也 rename 变量引用
// Variable reference rename, ensure that the node UI is not rendered when the variable reference is also renamed
this.fieldRenameService.onRename(({ before, after }) => {
// 覆盖的节点
// covered nodes
const coverNodes: FlowNodeEntity[] = uniq(
before.scope.coverScopes.map(_scope => _scope.meta?.node),
);
// 所有覆盖节点表单中引用的变量更新
// All variables referenced in the override node form are updated
coverNodes.forEach(_node => {
const formData = _node.getData(FlowNodeFormData);
const fullData = formData.formModel.getFormItemValueByPath('/');
@@ -67,7 +67,7 @@ export class WorkflowVariableFacadeService {
},
{
onDataRenamed: () => {
// rename 触发当前节点表单 onChange
// Rename triggers the current node form onChange
formData.fireChange();
},
node: _node,
@@ -79,7 +79,7 @@ export class WorkflowVariableFacadeService {
}
/**
* 根据变量的 AST 查找其 Facade
* Find the Facade of a Variable by Its AST
* @param field
* @returns
*/
@@ -91,10 +91,10 @@ export class WorkflowVariableFacadeService {
return cache;
}
// 新建该变量对应的 Facade
// Create a new facade corresponding to this variable.
const facade = new WorkflowVariableFacade(field, this);
// 被删除的节点,清空其缓存
// Deleted node, clear its cache
field.toDispose.push(
Disposable.create(() => {
this.cache.delete(field);
@@ -120,7 +120,7 @@ export class WorkflowVariableFacadeService {
}
/**
* 根据 keyPath 找到变量的外观
* Find the appearance of a variable according to keyPath
* @param keyPath
* @returns
*/
@@ -139,10 +139,10 @@ export class WorkflowVariableFacadeService {
}
/**
* @deprecated 变量销毁存在部分 Bad Case
* - 全局变量因切换 Project 销毁后,变量引用会被置空,导致变量引用失效
* @Deprecated Variable Destruction Partial Bad Case
* - After the global variable is destroyed due to the switch Project, the variable reference will be set empty, resulting in the invalidation of the variable reference
*
* 监听变量删除
* Listen variable removal
*/
listenKeyPathDispose(
keyPath?: string[],
@@ -152,14 +152,14 @@ export class WorkflowVariableFacadeService {
const facade = this.getVariableFacadeByKeyPath(keyPath, ctx);
if (facade) {
// 所有在 keyPath 链路上的 Field
// All Fields on the keyPath Link
return facade.onDispose(cb);
}
return Disposable.create(() => null);
}
// 监听类型变化
// Monitor type change
listenKeyPathTypeChange(
keyPath?: string[],
cb?: (v?: ViewVariableMeta | null) => void,
@@ -179,7 +179,7 @@ export class WorkflowVariableFacadeService {
return Disposable.create(() => null);
}
// 监听任意变量变化
// Monitor arbitrary variable changes
listenKeyPathVarChange(
keyPath?: string[],
cb?: (v?: ViewVariableMeta | null) => void,
@@ -199,7 +199,7 @@ export class WorkflowVariableFacadeService {
return Disposable.create(() => null);
}
// 根据 Scope 获取 Scope 上所有的 VariableFacade
// Get all VariableFacades on Scope by Scope
getVariableFacadesByScope(scope: Scope): WorkflowVariableFacade[] {
return scope.output.variables
.map(_variable => {

View File

@@ -55,7 +55,7 @@ export class WorkflowVariableFacade {
// do nothing
}
// 获取 variableMeta 结构
// Get the variableMeta structure
get viewMeta(): ViewVariableMeta | undefined {
if (this._fieldVersion !== this.field.version) {
this._variableMeta = getViewVariableByField(this.field);
@@ -123,7 +123,7 @@ export class WorkflowVariableFacade {
return {
key: this.globalVariableKey,
label: GLOBAL_VAR_ALIAS_MAP[this.globalVariableKey],
// 全局变量 icon url
// Global variable icon no url
icon: '',
};
}
@@ -166,7 +166,7 @@ export class WorkflowVariableFacade {
};
}
// 当前变量所处的节点
// The node where the current variable is located
get node(): FlowNodeEntity {
return this.field.scope.meta?.node;
}
@@ -181,7 +181,7 @@ export class WorkflowVariableFacade {
return;
}
// 获取 keyPath 路径
// Get the keyPath path
get keyPath(): string[] {
if (!this._keyPath) {
this._keyPath = getNamePathByField(this.field);
@@ -189,21 +189,21 @@ export class WorkflowVariableFacade {
return this._keyPath;
}
// 对应节点是否可以访问它
// Whether the corresponding node can access it
canAccessByNode(nodeId: string) {
return !!this.field.scope.coverScopes.find(_scope => _scope.id === nodeId);
}
/**
* @deprecated 变量销毁存在部分 Bad Case
* - 全局变量因切换 Project 销毁后,变量引用会被置空,导致变量引用失效
* @Deprecated Variable Destruction Partial Bad Case
* - After the global variable is destroyed due to the switch Project, the variable reference will be set empty, resulting in the invalidation of the variable reference
*
* 监听变量删除
* Listen variable removal
*/
onDispose(cb?: () => void): Disposable {
const toDispose = new DisposableCollection();
// 删除回调只要执行一次
// Delete the callback only once
let cbCalled = false;
const cbOnce = () => {
if (!cbCalled) {
@@ -220,7 +220,7 @@ export class WorkflowVariableFacade {
}
toDispose.pushAll([
// 遍历除 Rename 外的所有 Dispose 情况
// Traverse All Dispose Cases Except Rename
this._facadeService.fieldRenameService.onDisposeInList(_disposeField => {
if (allASTs.includes(_disposeField)) {
cbOnce();
@@ -229,7 +229,7 @@ export class WorkflowVariableFacade {
this.field.scope.event.on('DisposeAST', ({ ast }) => {
if (
ast &&
// TODO Object 删除也有可能是 Rename 导致的,需要重新判断
// TODO Object deletion may also be caused by Rename and needs to be re-judged.
[ASTKind.VariableDeclarationList].includes(ast?.kind as ASTKind) &&
allASTs.includes(ast)
) {
@@ -267,7 +267,7 @@ export class WorkflowVariableFacade {
onTypeChange(cb?: (facade: WorkflowVariableFacade) => void): Disposable {
return this.field.subscribe(() => cb?.(this), {
// 当前层级的类型发时变化时,才触发 onTypeChange
// onTypeChange is only triggered when the type of the current level changes
selector: field => {
const { type } = getViewVariableTypeByAST(field.type);
return type;

View File

@@ -102,7 +102,7 @@ export const createWorkflowVariablePlugins = () => [
extendASTNodes,
layoutConfig: {
transformCovers(scopes, { scope, variableEngine }) {
// 全局变量作用域覆盖所有其他作用域
// Global variable scope covers all other scopes
if (scope.id === GLOBAL_VARIABLE_SCOPE_ID) {
return variableEngine
.getAllScopes()
@@ -114,7 +114,7 @@ export const createWorkflowVariablePlugins = () => [
return scopes;
}
// private 只能访问当前节点的子节点和自己的 public
// Private can only access the sub-node of the current node and its own public.
// if (scope.meta?.type === 'private' && scope.meta?.node) {
// const visibleNodes = [
// scope.meta?.node,
@@ -125,7 +125,7 @@ export const createWorkflowVariablePlugins = () => [
// );
// }
// 特化:父节点的 public 可以访问子节点的 public用于聚合输出
// Specialization: The public of the parent node can access the public of the sub-node (for aggregating output).
const parentPublic = getParentPublic(node);
if (parentPublic) {
return [...scopes, parentPublic];
@@ -148,7 +148,7 @@ export const createWorkflowVariablePlugins = () => [
return scopes;
}
// 特化:父节点的 public 可以访问子节点的 public用于聚合输出, 且不能选择全局变量
// Specialization: The public of the parent node can access the public of the sub-node (for aggregate output), and cannot select global variables
if (scope.meta?.type === 'public' && hasChildCanvas(node)) {
return getHasChildCanvasNodePublicDeps(node);
}

View File

@@ -47,7 +47,7 @@ export class WorkflowNodeInputVariablesData extends EntityData {
}
/**
* 获取输入的表单值
* Get the entered form value
*/
get inputParameters(): InputValueVO[] {
const registry = this.entity.getNodeRegister() as WorkflowNodeRegistry;
@@ -65,7 +65,7 @@ export class WorkflowNodeInputVariablesData extends EntityData {
}
/**
* 获取所有的输入变量,包括变量名和引用的变量实例
* Get all input variables, including variable names and referenced variable instances
*/
get inputVariables(): InputVariable[] {

View File

@@ -110,21 +110,21 @@ export class WorkflowNodeRefVariablesData extends EntityData {
}
/**
* 批量更新变量引用
* @param updateInfos 变更的 KeyPath 信息
* Batch update variable references
* @param updateInfos changed KeyPath information
*/
batchUpdateRefs(updateInfos: UpdateRefInfo[]) {
let needUpdate = false;
const fullData = this.formData.formModel.getFormItemValueByPath('/');
const setValueIn = (path: string, nextValue: unknown) => {
// 新表单引擎更新数据
// New form engine updates data
if (isFormV2(this.entity)) {
(this.formData.formModel as FormModelV2).setValueIn(path, nextValue);
return;
}
// 老表单引擎更新数据
// Old form engine updates data
set(fullData, path, nextValue);
return;
};
@@ -138,9 +138,9 @@ export class WorkflowNodeRefVariablesData extends EntityData {
if (updateInfo) {
needUpdate = true;
// 没有传入更新后的 KeyPath则更新 content
// No updated KeyPath is passed in, the content is updated
if (!updateInfo.afterKeyPath) {
// rehaje 更新 bug设置值时需要 setter 内值局部更新,不能更改 setter 整体值
// Rehaje update bug: When setting the value, the value in the setter needs to be updated locally, and the overall value of the setter cannot be changed
setValueIn(
`${dataPath}.content`,
updateInfo.afterExpression?.content,
@@ -150,10 +150,10 @@ export class WorkflowNodeRefVariablesData extends EntityData {
}
/**
* 获取更新后的 KeyPath
* 假设要替换:[A, B] -> [C, D, E]
* 当前 KeyPath [A, B, F, G]
* nextPath [C, D, E] + [F, G] = [C, D, E, F, G]
* Get the updated KeyPath
* Suppose you want to replace: [A, B] - > [C, D, E]
* Current KeyPath is [A, B, F, G]
* Then nextPath is [C, D, E] + [F, G] = [C, D, E, F, G]
*/
const nextPath = [
...updateInfo.afterKeyPath,
@@ -170,7 +170,7 @@ export class WorkflowNodeRefVariablesData extends EntityData {
}
}
// 拥有全局变量的引用
// References to global variables
get hasGlobalRef(): boolean {
return Object.values(this.refs).some(_keyPath =>
(allGlobalVariableKeys as string[]).includes(_keyPath[0]),

View File

@@ -18,7 +18,7 @@ import { ASTFactory, type ASTNode } from '@flowgram-adapter/free-layout-editor';
import { type VariableConsumerAbilityOptions } from '@flowgram-adapter/free-layout-editor';
/**
* TODO 数组内 variable-consumer 拿不到 value
* The variable-consumer in the TODO array cannot get the value value.
*/
export const consumeRefValueExpression: VariableConsumerAbilityOptions = {
key: 'consume-ref-value-expression',

View File

@@ -46,7 +46,7 @@ export const parseLoopInputsByViewVariableMeta = (
);
const variableProperties = uniqInputs(variableParameters).map(_input => {
// 没有 rawMeta 时,可能是历史数据,走下面的兜底逻辑
// Without rawMeta, it may be historical data, follow the fallback logic below
if (_input?.input?.rawMeta?.type) {
return ASTFactory.createProperty({
key: _input?.name,
@@ -65,7 +65,7 @@ export const parseLoopInputsByViewVariableMeta = (
meta: {
mutable: true,
},
// 直接引用变量
// Direct reference to variables
initializer: ASTFactory.createKeyPathExpression({
keyPath: _input?.input?.content?.keyPath || [],
}),
@@ -105,7 +105,7 @@ export const parseLoopInputsByViewVariableMeta = (
};
/**
* 循环输入变量同步
* loop input variable synchronization
*/
export const provideLoopInputsVariables: VariableProviderAbilityOptions = {
key: 'provide-loop-input-variables',

View File

@@ -26,11 +26,11 @@ export const parseLoopOutputsByViewVariableMeta = (
) => {
const properties = uniqInputs(value || []).map(_input => {
const keyPath = _input?.input?.content?.keyPath;
// 如果选择的是 Loop 的 Variable 内的变量
// If you choose a variable in the Variable of the Loop
if (keyPath?.[0] === nodeId) {
return ASTFactory.createProperty({
key: _input?.name,
// 直接引用变量
// Direct reference to variables
initializer: ASTFactory.createKeyPathExpression({
keyPath: _input?.input?.content?.keyPath || [],
}),
@@ -39,7 +39,7 @@ export const parseLoopOutputsByViewVariableMeta = (
return ASTFactory.createProperty({
key: _input?.name,
// 输出类型包一层 Array
// Output Type Packet Layer Array
initializer: createWrapArrayExpression({
keyPath: _input?.input?.content?.keyPath || [],
}),
@@ -57,7 +57,7 @@ export const parseLoopOutputsByViewVariableMeta = (
};
/**
* 循环输出变量同步
* loop output variable synchronization
*/
export const provideLoopOutputsVariables: VariableProviderAbilityOptions = {
key: 'provide-loop-output-variables',

View File

@@ -38,7 +38,7 @@ interface MergeGroup {
}
/**
* 合并组变量同步
* merge group variable synchronization
*/
export const provideMergeGroupVariables: VariableProviderAbilityOptions = {
key: 'provide-merge-group-variables',
@@ -72,7 +72,7 @@ export const provideMergeGroupVariables: VariableProviderAbilityOptions = {
const facadeService = ctx.node.getService(WorkflowVariableFacadeService);
return ctx.scope.ast.subscribe(() => {
// 监听输出变量变化,回填到表单的 outputs
// Monitor output variable changes and backfill to the form's outputs.
const outputVariable = ctx.scope.output.variables[0];
if (outputVariable?.type?.kind === ASTKind.Object) {
const { properties } = outputVariable.type as ObjectType;
@@ -80,7 +80,7 @@ export const provideMergeGroupVariables: VariableProviderAbilityOptions = {
const nextOutputs = properties
.map(
_property =>
// OutputTree 组件中,所有树节点的 key 需要保证是唯一的
// In the OutputTree component, the keys of all tree nodes need to be guaranteed to be unique
facadeService.getVariableFacadeByField(_property)
.viewMetaWithUniqKey,
)

View File

@@ -42,7 +42,7 @@ export function useAvailableWorkflowVariables(): WorkflowVariable[] {
return scope.available.variables
.map(_variable => {
// 第一层为变量,因此需要分层处理
// The first layer is a variable, so it requires hierarchical processing
if (_variable.type.kind === ASTKind.Object) {
return ((_variable.type as ObjectType)?.properties || []).map(
_property => facadeService.getVariableFacadeByField(_property),

View File

@@ -25,7 +25,7 @@ import {
} from '../services/global-variable-service';
interface Params {
// 是否监听变量加载完成事件(变量下钻可能发生变化)
// Whether to listen for variable load completion events (variable drill-down may change)
listenVariableLoaded?: boolean;
}

View File

@@ -29,8 +29,8 @@ interface HooksParams {
}
/**
* @deprecated 变量销毁存在部分 Bad Case
* - 全局变量因切换 Project 销毁后,变量引用会被置空,导致变量引用失效
* @Deprecated Variable Destruction Partial Bad Case
* - After the global variable is destroyed due to the switch Project, the variable reference will be set empty, resulting in the invalidation of the variable reference
*/
export function useVariableDispose(params: HooksParams) {
const { keyPath, onDispose } = params;

View File

@@ -71,7 +71,7 @@ export function useVariableTypeChange(params: HooksParams) {
toDispose.push(
variable.onRename(({ modifyIndex, modifyKey }) => {
if (keyPathRef.current) {
// 更改 keyPath 并刷新,重新监听变量变化
// Change keyPath and refresh, re-listen for variable changes
keyPathRef.current[modifyIndex] = modifyKey;
}
refresh();

View File

@@ -17,7 +17,7 @@
/* eslint-disable @coze-arch/no-batch-import-or-export */
export { FlowNodeVariableData } from '@flowgram-adapter/free-layout-editor';
export * from './hooks';
// 老变量引擎代码,等待替换中。。。
// Old variable engine code, waiting to be replaced.........
export * from './legacy';
export * from './typings';
export * from './core';

View File

@@ -73,7 +73,7 @@ export namespace variableUtils {
}, {});
/**
* 转换处 list 之外的类型
* Types other than the conversion list
* @param type·
* @private
*/
@@ -106,7 +106,7 @@ export namespace variableUtils {
case VariableTypeDTO.object:
return ViewVariableType.Object;
// 原后端 type: image 兼容
// Original backend type: image compatible
case VariableTypeDTO.image:
return ViewVariableType.Image;
case VariableTypeDTO.list:
@@ -151,7 +151,7 @@ export namespace variableUtils {
assistType?: AssistTypeDTO;
subAssistType?: AssistTypeDTO;
} {
// 如果是数组类型的变量
// If it is a variable of array type
if (ViewVariableType.isArrayType(type)) {
const subViewType = ViewVariableType.getArraySubType(type);
const { type: subType, assistType: subAssistType } =
@@ -164,7 +164,7 @@ export namespace variableUtils {
};
}
// AssistType 映射
// AssistType Mapping
const assistType = VIEW_TYPE_TO_ASSIST_TYPE[type];
if (assistType) {
return {
@@ -173,7 +173,7 @@ export namespace variableUtils {
};
}
// 普通类型映射
// Normal type mapping
switch (type) {
case ViewVariableType.String:
return { type: VariableTypeDTO.string };
@@ -201,7 +201,7 @@ export namespace variableUtils {
export const ARRAY_TYPES = ViewVariableType.ArrayTypes;
/**
* 校验下Meta合法性不合法上报错误
* Check the legitimacy of Meta, and report an error if it is not legal.
* @param meta
*/
function checkDtoMetaValid(meta: VariableMetaDTO) {
@@ -209,7 +209,7 @@ export namespace variableUtils {
return;
}
// object和list类型schema有值的场景上报, 比如 { type: 'string', schema: []}
// Non-object and list types, schema scenarios with values are reported, such as {type: 'string', schema: []}
if (
![VariableTypeDTO.list, VariableTypeDTO.object].includes(meta.type) &&
meta.schema
@@ -224,7 +224,7 @@ export namespace variableUtils {
}
/**
* 后端变量转前端变量,并补齐 key
* Back-end variable to front-end variable, and fill in the key
* @param meta
*/
export function dtoMetaToViewMeta(meta: VariableMetaDTO): ViewVariableMeta {
@@ -238,7 +238,7 @@ export namespace variableUtils {
assistType: meta.schema?.assistType,
}),
name: meta.name,
// 数组要多下钻一层
// The array needs to be drilled down one more layer.
children: meta.schema?.schema?.map(subMeta =>
dtoMetaToViewMeta(subMeta),
),
@@ -271,7 +271,7 @@ export namespace variableUtils {
let schema: any = meta.children?.map(child => viewMetaToDTOMeta(child));
if (subType) {
if (!schema || schema.length === 0) {
// 空的object 需要加上空数组
// Empty objects need to add empty arrays
if (subType === VariableTypeDTO.object) {
schema = [];
} else {
@@ -284,7 +284,7 @@ export namespace variableUtils {
schema,
};
} else if (type === VariableTypeDTO.object && !schema) {
// object 需要加上空数组
// Empty object needs to add empty array
schema = [];
}
return {
@@ -300,7 +300,7 @@ export namespace variableUtils {
}
/**
* @deprecated 使用 viewTypeToDTOType
* @deprecated using viewTypeToDTOType
* @param type
* @returns
*/
@@ -318,7 +318,7 @@ export namespace variableUtils {
}
/**
* 前端表达式转后端数据
* Front-end expression to back-end data
* @param value
*/
export function valueExpressionToDTO(
@@ -336,7 +336,7 @@ export namespace variableUtils {
} = viewTypeToDTOType(viewType);
if (value.type === ValueExpressionType.LITERAL) {
let schema: any = undefined;
// Array<T> 类型的 schema 指定 array 的泛型类型
// A schema of type Array < T > specifies the generic type of an array
if (dtoType === VariableTypeDTO.list) {
schema = {
type: subType,
@@ -345,11 +345,11 @@ export namespace variableUtils {
if (subType === VariableTypeDTO.object) {
schema.schema = [];
}
// object 类型的 schema 指定成空数组,字面量没有下钻字段信息
// The schema of the object type is specified as an empty array, and the literal has no drill-down field information
} else if (dtoType === VariableTypeDTO.object) {
schema = [];
}
// 其他基础类型(stringintnumberboolean)以及 image 等带 assistType 额类型,不传 schema
// Other base types (string, int, number, boolean), as well as image types with an auxType amount, do not pass schema.
const res: ValueExpressionDTO = {
type: dtoType,
assistType,
@@ -377,13 +377,13 @@ export namespace variableUtils {
}
: refExpression.schema;
// 变量选择复杂类型再将类型手动改成简单类型会有schema残留
// 只有 object list 类型才需要 schema
// Variable select complex type, and then manually change the type to simple type, there will be schema residue
// Only object and list types require schemas.
if (![VariableTypeDTO.object, VariableTypeDTO.list].includes(dtoType)) {
schema = undefined;
}
// rawMeta 里有类型时,使用 rawMeta 里的类型,后端会对引用变量进行类型转换
// When there is a type in rawMeta, using the type in rawMeta, the backend will perform type conversion on the reference variable
return {
type: dtoType,
assistType,
@@ -395,11 +395,11 @@ export namespace variableUtils {
};
}
}
// rawMeta 不存在时,需要走兜底逻辑
// When rawMeta does not exist, fallback logic is required
if (value && value.type === ValueExpressionType.LITERAL) {
const assistType = getAssistTypeByViewType(value?.rawMeta?.type);
// TODO 这里获取不到变量类型,只能简单先这么处理,需要重构解决
// TODO can't get the variable type here, so it can only be handled this way first, and it needs to be refactored.
if (Array.isArray(value.content)) {
const listRes: ValueExpressionDTO = {
type: 'list',
@@ -478,7 +478,7 @@ export namespace variableUtils {
);
const refVariableType = workflowVariable?.viewType;
// 如果 rawMetaType 不存在或者 rawMetaType 与 refVariableType 相同,则直接返回 workflowVariable?.dtoMeta
// If rawMetaType does not exist or rawMetaType is the same as refVariableType, return workflowVariable? .dtoMeta directly
if (!rawMetaType || refVariableType === rawMetaType) {
return workflowVariable?.dtoMeta;
}
@@ -486,7 +486,7 @@ export namespace variableUtils {
if (!rawMetaType) {
return undefined;
}
// 如果 rawMetaType 存在但与 refVariableType 不同,说明发生了类型转换,则需要根据 rawMetaType 转换为 VariableMetaDTO
// If rawMetaType exists but is different from refVariableType, a type conversion has occurred and needs to be converted to VariableMetaDTO according to rawMetaType
return viewMetaToDTOMeta({
key: nanoid(),
name: String(value.content ?? ''),
@@ -495,7 +495,7 @@ export namespace variableUtils {
}
/**
* 优先使用 literalExpression rawMeta.type 字段获取 literal 类型, 参考 variableUtils.valueExpressionToDTO
* Priority is given to using the literalExpression rawMeta.type field to obtain the literal type, refer to variableUtils.valueExpressionToDTO
* @param content
* @returns
*/
@@ -529,14 +529,14 @@ export namespace variableUtils {
}
/**
* 后端表达式转前端数据
* Back-end expression to front-end data
* @param value
*/
export function valueExpressionToVO(
value: ValueExpressionDTO,
service: WorkflowVariableService,
): ValueExpression {
// 空数据兜底
// empty data bottom line
if (!value?.value?.type) {
return {} as any;
}
@@ -636,7 +636,7 @@ export namespace variableUtils {
}
/**
* input-type-value 前端格式转后端格式
* input-type-value front-end format to back-end format
*/
export function inputTypeValueVOToDTO(
value: InputTypeValueVO[],
@@ -654,7 +654,7 @@ export namespace variableUtils {
}
/**
* input-type-value 后端格式转前端格式
* input-type-value backend format to frontend format
*/
export function inputTypeValueDTOToVO(
value: InputTypeValueDTO[],

View File

@@ -31,7 +31,7 @@ import { type WorkflowVariable, WorkflowVariableFacadeService } from '../core';
import { type GlobalVariableKey, isGlobalVariableKey } from '../constants';
/**
* 变量相关服务
* Variable related services
*/
@injectable()
export class WorkflowVariableService {
@@ -41,8 +41,8 @@ export class WorkflowVariableService {
protected readonly variableFacadeService: WorkflowVariableFacadeService;
/**
* 表达式引用转后端,如果无数据,默认给一个空的 ref 引用
* 输入:
* The expression reference is transferred to the backend. If there is no data, an empty ref reference is given by default.
* Input:
* {
* type: ValueExpressionType.REF,
* content: {
@@ -62,14 +62,14 @@ export class WorkflowVariableService {
const dtoMeta = workflowVariable?.dtoMeta;
// 如果引用的变量,属于全局变量
// If the referenced variable is a global variable
if (isGlobalVariableKey(keyPath[0])) {
const path = workflowVariable
? [
...workflowVariable.parentVariables
.slice(1)
.map(_variable => {
// Hack: 全局变量特化逻辑,后端要求数组下钻把数组的下标也带上
// Hack: Global variable specialization logic, the backend requires the array to drill down and bring the index of the array
if (
_variable.viewType &&
ViewVariableType.isArrayType(_variable.viewType)
@@ -82,7 +82,7 @@ export class WorkflowVariableService {
.flat(),
workflowVariable.key,
]
: // 没有 workflowVariable,则直接使用原来的 keyPath
: // If there is no workflowVariable, use the original keyPath directly.
keyPath.slice(1);
return {
@@ -117,7 +117,7 @@ export class WorkflowVariableService {
}
/**
* 表达式引用转前端
* expression reference to frontend
* @param value
*/
refExpressionToVO(valueDTO: ValueExpressionDTO): RefExpression {
@@ -142,7 +142,7 @@ export class WorkflowVariableService {
content: {
keyPath: [
source,
// Hack: 全局变量特化逻辑,后端要求数组下钻把数组的下标也带上,前端不需要 [0] 下钻,因此转化时过滤掉
// Hack: Global variable specialization logic, the backend requires the array to drill down and bring the index of the array. The front end does not need [0] to drill down, so it is filtered out during conversion.
...(path || []).filter(_v => !['[0]'].includes(_v)),
],
},
@@ -150,9 +150,9 @@ export class WorkflowVariableService {
}
const name = value.content?.name || '';
const nameList = name.split('.').filter(Boolean); // 过滤空字符串
const nameList = name.split('.').filter(Boolean); // Filter empty strings
// 灰度命中时,直接使用 namePath
// When grey releases hits, use namePath directly
return {
type: ValueExpressionType.REF,
content: {
@@ -162,8 +162,8 @@ export class WorkflowVariableService {
}
/**
* 直接返回 Variable 或者 SubVariable 的 ViewVariableMeta
* @param keyPath ViewVariableMeta keyPath 路径
* Directly returns the ViewVariableMeta of Variable or SubVariable
* @param keyPath ViewVariableMeta keyPath
* @returns
*/
getViewVariableByKeyPath(
@@ -184,7 +184,7 @@ export class WorkflowVariableService {
}
/**
* 监听指定 keyPath 变量类型变化
* Listens for changes in the specified keyPath variable type
* @param keyPath
* @param cb
* @returns
@@ -198,10 +198,10 @@ export class WorkflowVariableService {
}
/**
* @deprecated 变量销毁存在部分 Bad Case
* - 全局变量因切换 Project 销毁后,变量引用会被置空,导致变量引用失效
* @Deprecated Variable Destruction Partial Bad Case
* - After the global variable is destroyed due to the switch Project, the variable reference will be set empty, resulting in the invalidation of the variable reference
*
* 监听指定 keyPath 变量类型变化
* Listens for changes in the specified keyPath variable type
* @param keyPath
* @param cb
* @returns
@@ -215,7 +215,7 @@ export class WorkflowVariableService {
}
/**
* 监听指定 keyPath 变量的变化
* Listens for changes in the specified keyPath variable
* @param keyPath
* @param cb
* @returns

View File

@@ -88,7 +88,7 @@ export class GlobalVariableService {
}
/**
* 拉取最新的变量数据
* Pull the latest variable data
*/
protected async fetchGlobalVariableMetas(
connectorType: 'project' | 'bot',
@@ -121,7 +121,7 @@ export class GlobalVariableService {
_latestFetchId = 0;
/**
* 触发刷新事件
* trigger refresh event
*/
async loadGlobalVariables(
connectorType: 'project' | 'bot',
@@ -142,12 +142,12 @@ export class GlobalVariableService {
const res = await this.fetchGlobalVariableMetas(connectorType, connectorId);
// 有新的请求,则直接丢弃结果
// If there is a new request, the result will be discarded directly.
if (fetchId !== this._latestFetchId) {
return;
}
// 同步最新的变量数据到 AST
// Sync the latest variable data to AST
allGlobalVariableKeys.forEach(_key => {
if (!res[_key]?.length) {
this.globalScope.ast.remove(_key);
@@ -207,7 +207,7 @@ export class GlobalVariableService {
type: string,
schema?: GlobalVariableTreeNode,
): ASTNodeJSON | undefined {
// 参考协议:
// Reference Agreement:
switch (type) {
case 'string':
return ASTFactory.createString();
@@ -216,7 +216,7 @@ export class GlobalVariableService {
case 'integer':
return ASTFactory.createInteger();
case 'float':
case 'number': // number 为历史数据,标准为 float
case 'number': // Number is historical data, standard is float
return ASTFactory.createNumber();
case 'object':

View File

@@ -28,13 +28,13 @@ export function setValueIn(
nextValue: unknown,
) {
const formData = node.getData(FlowNodeFormData);
// 新表单引擎更新数据
// New form engine updates data
if (isFormV2(node)) {
(formData.formModel as FormModelV2).setValueIn(path, nextValue);
return;
}
// 老表单引擎更新数据
// Old form engine updates data
const fullData = formData.formModel.getFormItemValueByPath('/');
set(fullData, path, nextValue);

View File

@@ -23,7 +23,7 @@ import {
AssistTypeDTO,
} from '@coze-workflow/base';
// 需要转化的类型映射
// Type mapping to be converted
const VariableType2JsonSchemaProps = {
[VariableTypeDTO.object]: {
type: 'object',
@@ -78,7 +78,7 @@ const inputToJsonSchema = (
items: inputToJsonSchema(_input.schema, level + 1, transformer),
};
}
// 基础类型不需要生成jsonSchema, 图片类型不需要jsonSchema, 直接抛异常跳出递归
// The basic type does not need to generate jsonSchema, and the image type does not need jsonSchema. It directly throws an exception and jumps out of recursion.
if (
level === 0 ||
type === 'image' ||

View File

@@ -22,7 +22,7 @@ import { type FlowNodeEntity } from '@flowgram-adapter/free-layout-editor';
import { type WorkflowNodeMeta } from '@flowgram-adapter/free-layout-editor';
/**
* 获取实际的父节点
* Get the actual parent node
* @param node
* @returns
*/
@@ -44,7 +44,7 @@ export function getParentNode(
}
/**
* 获取实际的子节点
* Get the actual sub-node
* @param node
* @returns
*/
@@ -53,7 +53,7 @@ export function getChildrenNode(node: FlowNodeEntity): FlowNodeEntity[] {
const subCanvas = nodeMeta.subCanvas?.(node);
if (subCanvas) {
// 子画布本身不存在 children
// There is no child on the canvas itself.
if (subCanvas.isCanvas) {
return [];
} else {
@@ -65,7 +65,7 @@ export function getChildrenNode(node: FlowNodeEntity): FlowNodeEntity[] {
}
/**
* 节点是否包含子画布
* Does the node contain a child canvas?
* @param node
* @returns
*/
@@ -77,7 +77,7 @@ export function hasChildCanvas(node: FlowNodeEntity): boolean {
}
/**
* 获取子节点所有输出变量的作用域链
* Get the scope chain of all output variables of the sub-node
* @param node
* @returns
*/
@@ -93,7 +93,7 @@ export function getHasChildCanvasNodePublicDeps(
}
/**
* 获取父节点的
* Get the parent node's
* @param node
* @returns
*/

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { type VariableProviderAbilityOptions } from '@flowgram-adapter/free-layout-editor';
import {
ASTKind,
@@ -26,7 +26,7 @@ import {
} from '@flowgram-adapter/free-layout-editor';
/**
* 根据 VariableProvider 生成 FormV2 的 Effect
* Generating FormV2 Effects from VariableProvider
* @param options
* @returns
*/
@@ -75,12 +75,12 @@ export function createEffectFromVariableProvider(
scope,
options,
formItem: undefined,
// @ts-expect-error 新表单引擎不支持
// @ts-expect-error New form engine not supported
triggerSync: undefined,
});
if (disposable) {
// 作用域销毁时同时销毁该监听
// Destroy the listener at the same time when the scope is destroyed
scope.toDispose.push(disposable);
}