Files
coze-studio/frontend/packages/workflow/feature-encapsulate/src/validate/encapsulate-validate-service.ts
fanlv 890153324f feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
2025-07-20 17:36:12 +08:00

113 lines
3.4 KiB
TypeScript

/*
* 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 StandardNodeType } from '@coze-workflow/base/types';
import {
type WorkflowJSON,
type WorkflowNodeEntity,
} from '@flowgram-adapter/free-layout-editor';
import { excludeStartEnd } from '../utils/exclude-start-end';
import { EncapsulateGenerateService } from '../generate';
import {
EncapsulateValidateManager,
type EncapsulateValidateService,
type EncapsulateValidateResult,
EncapsulateValidateResultFactory,
} from './types';
@injectable()
export class EncapsulateValidateServiceImpl
implements EncapsulateValidateService
{
@inject(EncapsulateValidateManager)
private encapsulateValidateManager: EncapsulateValidateManager;
@inject(EncapsulateValidateResultFactory)
private encapsulateValidateResultFactory: EncapsulateValidateResultFactory;
@inject(EncapsulateGenerateService)
private encapsulateGenerateService: EncapsulateGenerateService;
async validate(nodes: WorkflowNodeEntity[]) {
const validateResult: EncapsulateValidateResult =
this.encapsulateValidateResultFactory();
this.validateNodes(nodes, validateResult);
for (const node of nodes) {
await this.validateNode(node, validateResult);
}
if (validateResult.hasError()) {
return validateResult;
}
const workflowJSON =
await this.encapsulateGenerateService.generateWorkflowJSON(
excludeStartEnd(nodes),
);
await this.validateWorkflowJSON(workflowJSON, validateResult);
return validateResult;
}
private async validateWorkflowJSON(
workflowJSON: WorkflowJSON,
validateResult: EncapsulateValidateResult,
) {
const workflowJSONValidators =
this.encapsulateValidateManager.getWorkflowJSONValidators();
await Promise.all(
workflowJSONValidators.map(workflowJSONValidator =>
workflowJSONValidator.validate(workflowJSON, validateResult),
),
);
}
private validateNodes(
nodes: WorkflowNodeEntity[],
validateResult: EncapsulateValidateResult,
) {
const nodesValidators =
this.encapsulateValidateManager.getNodesValidators();
for (const nodesValidator of nodesValidators) {
// 如果节点校验器需要包含起始节点和结束节点,则直接校验
// 否则需要排除起始节点和结束节点
nodesValidator.validate(
nodesValidator.includeStartEnd ? nodes : excludeStartEnd(nodes),
validateResult,
);
}
}
private async validateNode(
node: WorkflowNodeEntity,
validateResult: EncapsulateValidateResult,
) {
const nodeValidators =
this.encapsulateValidateManager.getNodeValidatorsByType(
node.flowNodeType as StandardNodeType,
);
for (const nodeValidator of nodeValidators) {
await nodeValidator.validate(node, validateResult);
}
}
}