feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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 { inject, injectable } from 'inversify';
|
||||
import { WorkflowNode } from '@coze-workflow/base';
|
||||
import {
|
||||
WorkflowDocument,
|
||||
type WorkflowNodeEntity,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { getSubCanvasParent, isSubCanvasNode } from '../utils/subcanvas';
|
||||
@injectable()
|
||||
export class EncapsulateBaseValidator {
|
||||
@inject(WorkflowDocument)
|
||||
protected workflowDocument: WorkflowDocument;
|
||||
|
||||
protected getLineName(from: string, to: string) {
|
||||
return `${this.getNodeNameById(from)} -> ${this.getNodeNameById(to)}`;
|
||||
}
|
||||
|
||||
protected getLineSource(from: string, to: string) {
|
||||
return `${from}_${to}`;
|
||||
}
|
||||
|
||||
protected getNodeName(node: WorkflowNodeEntity) {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSubCanvasNode(node)) {
|
||||
return this.getSubCanvasName(node);
|
||||
}
|
||||
const workflowNode = new WorkflowNode(node);
|
||||
return workflowNode.title || this.defaultNodeName(node.id);
|
||||
}
|
||||
|
||||
protected getSubCanvasName(node: WorkflowNodeEntity) {
|
||||
const nodeMeta = node.getNodeMeta();
|
||||
const { title = '' } = nodeMeta?.renderSubCanvas?.() ?? {};
|
||||
return title || this.defaultNodeName(node.id);
|
||||
}
|
||||
|
||||
protected getSubCanvasIcon(node: WorkflowNodeEntity) {
|
||||
const parent = getSubCanvasParent(node);
|
||||
return this.getNodeIcon(parent);
|
||||
}
|
||||
|
||||
protected getNodeIcon(node: WorkflowNodeEntity) {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSubCanvasNode(node)) {
|
||||
return this.getSubCanvasIcon(node);
|
||||
}
|
||||
const workflowNode = new WorkflowNode(node);
|
||||
return workflowNode.icon;
|
||||
}
|
||||
|
||||
protected getNodeNameById(id: string) {
|
||||
const node = this.workflowDocument.getNode(id);
|
||||
|
||||
if (!node) {
|
||||
return this.defaultNodeName(id);
|
||||
}
|
||||
|
||||
return this.getNodeName(node);
|
||||
}
|
||||
|
||||
protected defaultNodeName(id: string) {
|
||||
return `Node${id}`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 { inject, injectable } from 'inversify';
|
||||
import { ValidationService } from '@coze-workflow/base/services';
|
||||
import { StandardNodeType } from '@coze-workflow/base';
|
||||
import { type WorkflowNodeEntity } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
type EncapsulateNodeValidator,
|
||||
EncapsulateValidateErrorCode,
|
||||
type EncapsulateValidateResult,
|
||||
} from '../validate';
|
||||
import { EncapsulateBaseValidator } from './encapsulate-base-validator';
|
||||
|
||||
@injectable()
|
||||
export class EncapsulateFormValidator
|
||||
extends EncapsulateBaseValidator
|
||||
implements EncapsulateNodeValidator
|
||||
{
|
||||
@inject(ValidationService)
|
||||
private validationService: ValidationService;
|
||||
|
||||
canHandle(_type: string) {
|
||||
return true;
|
||||
}
|
||||
|
||||
async validate(node: WorkflowNodeEntity, result: EncapsulateValidateResult) {
|
||||
// 注释节点不需要校验
|
||||
if (
|
||||
[StandardNodeType.Comment].includes(node.flowNodeType as StandardNodeType)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const res = await this.validationService.validateNode(node);
|
||||
|
||||
if (!res.hasError) {
|
||||
return;
|
||||
}
|
||||
|
||||
const sourceName = this.getNodeName(node);
|
||||
const sourceIcon = this.getNodeIcon(node);
|
||||
const errors = res.nodeErrorMap[node.id] || [];
|
||||
|
||||
errors.forEach(error => {
|
||||
if (!error.errorInfo || error.errorLevel !== 'error') {
|
||||
return;
|
||||
}
|
||||
|
||||
result.addError({
|
||||
code: EncapsulateValidateErrorCode.INVALID_FORM,
|
||||
message: error.errorInfo,
|
||||
source: node.id,
|
||||
sourceName,
|
||||
sourceIcon,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 { inject, injectable } from 'inversify';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import {
|
||||
EncapsulateValidateErrorCode,
|
||||
type EncapsulateNodesValidator,
|
||||
} from '../validate';
|
||||
import { EncapsulateLinesService } from '../encapsulate';
|
||||
|
||||
@injectable()
|
||||
export class EncapsulateInputLinesValidator
|
||||
implements EncapsulateNodesValidator
|
||||
{
|
||||
@inject(EncapsulateLinesService)
|
||||
private encapsulateLinesService: EncapsulateLinesService;
|
||||
|
||||
validate(nodes, result) {
|
||||
const inputLines =
|
||||
this.encapsulateLinesService.getEncapsulateNodesInputLines(nodes);
|
||||
|
||||
if (inputLines.length === 0) {
|
||||
return;
|
||||
}
|
||||
const valid =
|
||||
this.encapsulateLinesService.validateEncapsulateLines(inputLines);
|
||||
|
||||
if (!valid) {
|
||||
result.addError({
|
||||
code: EncapsulateValidateErrorCode.ENCAPSULATE_LINES,
|
||||
message: I18n.t(
|
||||
'workflow_encapsulate_button_unable_connected',
|
||||
undefined,
|
||||
'框选范围内有中间节点连到框选范围外的节点',
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 { inject, injectable } from 'inversify';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import {
|
||||
EncapsulateValidateErrorCode,
|
||||
type EncapsulateNodesValidator,
|
||||
} from '../validate';
|
||||
import { EncapsulateLinesService } from '../encapsulate';
|
||||
|
||||
@injectable()
|
||||
export class EncapsulateOutputLinesValidator
|
||||
implements EncapsulateNodesValidator
|
||||
{
|
||||
@inject(EncapsulateLinesService)
|
||||
private encapsulateLinesService: EncapsulateLinesService;
|
||||
|
||||
validate(nodes, result) {
|
||||
const outputLines =
|
||||
this.encapsulateLinesService.getEncapsulateNodesOutputLines(nodes);
|
||||
|
||||
if (outputLines.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const valid =
|
||||
this.encapsulateLinesService.validateEncapsulateLines(outputLines);
|
||||
|
||||
if (!valid) {
|
||||
result.addError({
|
||||
code: EncapsulateValidateErrorCode.ENCAPSULATE_LINES,
|
||||
message: I18n.t(
|
||||
'workflow_encapsulate_button_unable_connected',
|
||||
undefined,
|
||||
'框选范围内有中间节点连到框选范围外的节点',
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 { injectable } from 'inversify';
|
||||
import { StandardNodeType } from '@coze-workflow/base';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { FlowNodeBaseType } from '@flowgram-adapter/free-layout-editor';
|
||||
import {
|
||||
type WorkflowNodeEntity,
|
||||
WorkflowNodePortsData,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
EncapsulateValidateErrorCode,
|
||||
type EncapsulateNodesValidator,
|
||||
} from '../validate';
|
||||
import { getNodesWithSubCanvas } from '../utils/get-nodes-with-sub-canvas';
|
||||
import { EncapsulateBaseValidator } from './encapsulate-base-validator';
|
||||
|
||||
@injectable()
|
||||
export class EncapsulatePortsValidator
|
||||
extends EncapsulateBaseValidator
|
||||
implements EncapsulateNodesValidator
|
||||
{
|
||||
validate(nodes: WorkflowNodeEntity[], result) {
|
||||
getNodesWithSubCanvas(nodes).forEach(node => {
|
||||
const ignoreNodes = [
|
||||
StandardNodeType.Comment,
|
||||
FlowNodeBaseType.SUB_CANVAS,
|
||||
];
|
||||
if (ignoreNodes.includes(node.flowNodeType as StandardNodeType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const portsData = node.getData<WorkflowNodePortsData>(
|
||||
WorkflowNodePortsData,
|
||||
);
|
||||
|
||||
const hasNotConnectPort = portsData.allPorts.some(
|
||||
port => port.lines.length === 0,
|
||||
);
|
||||
if (hasNotConnectPort) {
|
||||
const sourceName = this.getNodeName(node);
|
||||
const sourceIcon = this.getNodeIcon(node);
|
||||
|
||||
result.addError({
|
||||
code: EncapsulateValidateErrorCode.INVALID_PORTS,
|
||||
message: I18n.t(
|
||||
'workflow_encapsulate_button_unable_uncomplete',
|
||||
undefined,
|
||||
'封装不应该包含没有输入输出的节点',
|
||||
),
|
||||
source: node.id,
|
||||
sourceName,
|
||||
sourceIcon,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
includeStartEnd: true;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 { inject, injectable } from 'inversify';
|
||||
import { type WorkflowJSON } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
EncapsulateValidateErrorCode,
|
||||
type EncapsulateValidateError,
|
||||
type EncapsulateValidateResult,
|
||||
type EncapsulateWorkflowJSONValidator,
|
||||
} from '../validate';
|
||||
import { EncapsulateApiService } from '../api';
|
||||
import { EncapsulateBaseValidator } from './encapsulate-base-validator';
|
||||
|
||||
@injectable()
|
||||
export class EncapsulateSchemaValidator
|
||||
extends EncapsulateBaseValidator
|
||||
implements EncapsulateWorkflowJSONValidator
|
||||
{
|
||||
@inject(EncapsulateApiService)
|
||||
private encapsulateApiService: EncapsulateApiService;
|
||||
|
||||
async validate(workflow: WorkflowJSON, result: EncapsulateValidateResult) {
|
||||
const validateResult =
|
||||
await this.encapsulateApiService.validateWorkflow(workflow);
|
||||
|
||||
if (!validateResult?.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const errors = validateResult || [];
|
||||
|
||||
errors.forEach(error => {
|
||||
const nodeId = error.node_error?.node_id || error.path_error?.start || '';
|
||||
const node = this.workflowDocument.getNode(nodeId);
|
||||
let sourceName: EncapsulateValidateError['sourceName'] = undefined;
|
||||
let sourceIcon: EncapsulateValidateError['sourceIcon'] = undefined;
|
||||
let source: EncapsulateValidateError['source'] = undefined;
|
||||
|
||||
if (node) {
|
||||
sourceName = this.getNodeName(node);
|
||||
sourceIcon = this.getNodeIcon(node);
|
||||
source = node.id;
|
||||
}
|
||||
|
||||
result.addError({
|
||||
code: EncapsulateValidateErrorCode.INVALID_SCHEMA,
|
||||
message: error.message || '',
|
||||
source,
|
||||
sourceName,
|
||||
sourceIcon,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 { ContainerModule } from 'inversify';
|
||||
import { bindContributions } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
EncapsulateNodesValidator,
|
||||
EncapsulateWorkflowJSONValidator,
|
||||
EncapsulateNodeValidator,
|
||||
} from '../validate';
|
||||
import { SubCanvasValidator } from './sub-canvas-validator';
|
||||
import { StartEndValidator } from './start-end-validator';
|
||||
import { LoopNodesValidator } from './loop-nodes-validator';
|
||||
import { EncapsulateSchemaValidator } from './encapsulate-schema-validator';
|
||||
import { EncapsulatePortsValidator } from './encapsulate-ports-validator';
|
||||
import { EncapsulateOutputLinesValidator } from './encapsulate-output-lines-validator';
|
||||
import { EncapsulateInputLinesValidator } from './encapsulate-input-lines-validator';
|
||||
import { EncapsulateFormValidator } from './encapsulate-form-validator';
|
||||
|
||||
export const EncapsulateValidatorsContainerModule = new ContainerModule(
|
||||
bind => {
|
||||
// json validators
|
||||
bindContributions(bind, EncapsulateSchemaValidator, [
|
||||
EncapsulateWorkflowJSONValidator,
|
||||
]);
|
||||
// nodes validators
|
||||
[
|
||||
EncapsulatePortsValidator,
|
||||
EncapsulateInputLinesValidator,
|
||||
EncapsulateOutputLinesValidator,
|
||||
StartEndValidator,
|
||||
LoopNodesValidator,
|
||||
SubCanvasValidator,
|
||||
].forEach(Validator => {
|
||||
bindContributions(bind, Validator, [EncapsulateNodesValidator]);
|
||||
});
|
||||
// node validator
|
||||
[EncapsulateFormValidator].forEach(Validator => {
|
||||
bindContributions(bind, Validator, [EncapsulateNodeValidator]);
|
||||
});
|
||||
},
|
||||
);
|
||||
@@ -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 * from './encapsulate-validators-container-module';
|
||||
export { EncapsulateBaseValidator } from './encapsulate-base-validator';
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 { injectable } from 'inversify';
|
||||
import { StandardNodeType } from '@coze-workflow/base/types';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import {
|
||||
EncapsulateValidateErrorCode,
|
||||
type EncapsulateNodesValidator,
|
||||
} from '../validate';
|
||||
|
||||
@injectable()
|
||||
export class LoopNodesValidator implements EncapsulateNodesValidator {
|
||||
validate(nodes, result) {
|
||||
const filtered = nodes.filter(node =>
|
||||
[StandardNodeType.Break, StandardNodeType.Continue].includes(
|
||||
node.flowNodeType,
|
||||
),
|
||||
);
|
||||
|
||||
if (filtered.length) {
|
||||
result.addError({
|
||||
code: EncapsulateValidateErrorCode.INVALID_LOOP_NODES,
|
||||
message: I18n.t(
|
||||
'workflow_encapsulate_button_unable_continue_or_teiminate',
|
||||
undefined,
|
||||
'框选范围内包含继续循环/终止循环',
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
import { injectable } from 'inversify';
|
||||
import { StandardNodeType } from '@coze-workflow/base/types';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import {
|
||||
EncapsulateValidateErrorCode,
|
||||
type EncapsulateNodesValidator,
|
||||
} from '../validate';
|
||||
|
||||
@injectable()
|
||||
export class StartEndValidator implements EncapsulateNodesValidator {
|
||||
validate(nodes, result) {
|
||||
const filtered = nodes.filter(node =>
|
||||
[StandardNodeType.Start, StandardNodeType.End].includes(
|
||||
node.flowNodeType,
|
||||
),
|
||||
);
|
||||
|
||||
if (filtered.length) {
|
||||
result.addError({
|
||||
code: EncapsulateValidateErrorCode.NO_START_END,
|
||||
message: I18n.t(
|
||||
'workflow_encapsulate_button_unable_start_or_end',
|
||||
undefined,
|
||||
'框选范围内包含开始/结束',
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
includeStartEnd = true;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 { injectable } from 'inversify';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { type WorkflowNodeEntity } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { getSubCanvasParent, isSubCanvasNode } from '@/utils/subcanvas';
|
||||
|
||||
import {
|
||||
type EncapsulateNodesValidator,
|
||||
EncapsulateValidateErrorCode,
|
||||
type EncapsulateValidateResult,
|
||||
} from '../validate';
|
||||
import { EncapsulateBaseValidator } from './encapsulate-base-validator';
|
||||
|
||||
@injectable()
|
||||
export class SubCanvasValidator
|
||||
extends EncapsulateBaseValidator
|
||||
implements EncapsulateNodesValidator
|
||||
{
|
||||
validate(nodes: WorkflowNodeEntity[], result: EncapsulateValidateResult) {
|
||||
nodes
|
||||
.filter(node => isSubCanvasNode(node))
|
||||
.forEach(subCanvasNode => {
|
||||
const parent = getSubCanvasParent(subCanvasNode);
|
||||
if (!parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
const sourceName = this.getNodeName(subCanvasNode);
|
||||
const sourceIcon = this.getNodeIcon(subCanvasNode);
|
||||
if (!nodes.includes(parent)) {
|
||||
result.addError({
|
||||
code: EncapsulateValidateErrorCode.INVALID_SUB_CANVAS,
|
||||
message: I18n.t('workflow_encapsulate_button_unable_loop_or_batch'),
|
||||
source: subCanvasNode.id,
|
||||
sourceName,
|
||||
sourceIcon,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user