feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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 { ViewVariableType, getFileAccept } from '@coze-workflow/base';
|
||||
|
||||
interface GenerateFieldComponentOptions {
|
||||
type: ViewVariableType;
|
||||
validateJsonSchema?: any;
|
||||
}
|
||||
|
||||
export const generateFieldComponent = (
|
||||
options: GenerateFieldComponentOptions,
|
||||
) => {
|
||||
const { type, validateJsonSchema } = options;
|
||||
/** 音色类型 */
|
||||
if (ViewVariableType.Voice === type) {
|
||||
return {
|
||||
['x-component']: 'SelectVoice',
|
||||
};
|
||||
}
|
||||
/** 文件类型 */
|
||||
if (ViewVariableType.isFileType(type)) {
|
||||
const fileType = [
|
||||
ViewVariableType.Image,
|
||||
ViewVariableType.ArrayImage,
|
||||
].includes(type)
|
||||
? 'image'
|
||||
: 'object';
|
||||
return {
|
||||
['x-component']: 'TypedFileInput',
|
||||
['x-component-props']: {
|
||||
// 如果是数组类型,则表明是多选的文件选择器
|
||||
multiple: ViewVariableType.isArrayType(type),
|
||||
accept: getFileAccept(type),
|
||||
fileType,
|
||||
},
|
||||
};
|
||||
}
|
||||
/** 排除文件类型的对象类型、数组类型 */
|
||||
if (ViewVariableType.isArrayType(type) || ViewVariableType.Object === type) {
|
||||
return {
|
||||
['x-component']: 'InputJson',
|
||||
['x-component-props']: {
|
||||
jsonSchema: validateJsonSchema,
|
||||
},
|
||||
defaultValue: ViewVariableType.Object === type ? '{}' : '[]',
|
||||
};
|
||||
}
|
||||
if (type === ViewVariableType.Integer) {
|
||||
return {
|
||||
['x-component']: 'InputInteger',
|
||||
};
|
||||
}
|
||||
if (type === ViewVariableType.Number) {
|
||||
return {
|
||||
['x-component']: 'InputNumber',
|
||||
};
|
||||
}
|
||||
if (type === ViewVariableType.Boolean) {
|
||||
return {
|
||||
['x-component']: 'SelectBoolean',
|
||||
defaultValue: true,
|
||||
};
|
||||
}
|
||||
if (type === ViewVariableType.Time) {
|
||||
return {
|
||||
['x-component']: 'InputTime',
|
||||
};
|
||||
}
|
||||
/** string 类型和其它未知类型都渲染普通输入框 */
|
||||
return {
|
||||
['x-component']: 'InputString',
|
||||
};
|
||||
};
|
||||
@@ -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 Ajv from 'ajv';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { type IFormSchemaValidate } from '../form-engine';
|
||||
|
||||
const isEmptyValue = (v: unknown) => v === undefined || v === null || v === '';
|
||||
|
||||
interface GenerateFieldValidatorOptions {
|
||||
name: string;
|
||||
title?: string;
|
||||
required?: boolean;
|
||||
validateJsonSchema?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* ajv 实例缓存
|
||||
* 无需导入创建或者多次创建,优化内存开销
|
||||
*/
|
||||
let ajvCache: undefined | Ajv;
|
||||
|
||||
export const generateFieldValidator = (
|
||||
options: GenerateFieldValidatorOptions,
|
||||
) => {
|
||||
const { required, title, name, validateJsonSchema } = options;
|
||||
|
||||
const validator: IFormSchemaValidate = ({ value }) => {
|
||||
if (required && isEmptyValue(value)) {
|
||||
return I18n.t('workflow_testset_required_tip', {
|
||||
param_name: title || name,
|
||||
});
|
||||
}
|
||||
// 如果有结构化描述,还需要对值进行反序列化校验
|
||||
if (validateJsonSchema && value !== undefined) {
|
||||
if (!ajvCache) {
|
||||
ajvCache = new Ajv();
|
||||
}
|
||||
try {
|
||||
const valueObject = JSON.parse(value);
|
||||
const validate = ajvCache.compile(validateJsonSchema);
|
||||
const valid = validate(valueObject);
|
||||
return valid ? undefined : I18n.t('workflow_debug_wrong_json');
|
||||
} catch {
|
||||
/**
|
||||
* 报错有多种可能,预期结果都是校验不通过
|
||||
* 1. 值反序列化失败
|
||||
* 2. 反序列化的值不合法
|
||||
*/
|
||||
return I18n.t('workflow_debug_wrong_json');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
['x-validator']: validator,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 { ViewVariableType } from '@coze-workflow/base';
|
||||
|
||||
import { type IFormSchema } from '../form-engine';
|
||||
import { generateFieldValidator } from './generate-field-validator';
|
||||
import { generateFieldComponent } from './generate-field-component';
|
||||
|
||||
interface GenerateFieldOptions {
|
||||
type: ViewVariableType;
|
||||
name: string;
|
||||
title?: string;
|
||||
required?: boolean;
|
||||
description?: string;
|
||||
defaultValue?: string;
|
||||
validateJsonSchema?: any;
|
||||
extra?: IFormSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单 Field Schema 计算
|
||||
*/
|
||||
export const generateField = (options: GenerateFieldOptions): IFormSchema => {
|
||||
const {
|
||||
type,
|
||||
name,
|
||||
title,
|
||||
required = true,
|
||||
description,
|
||||
defaultValue,
|
||||
validateJsonSchema,
|
||||
extra,
|
||||
} = options;
|
||||
|
||||
return {
|
||||
name,
|
||||
title,
|
||||
description,
|
||||
required,
|
||||
['x-decorator']: 'FieldItem',
|
||||
['x-decorator-props']: {
|
||||
tag: ViewVariableType.LabelMap[type],
|
||||
},
|
||||
['x-origin-type']: type as unknown as string,
|
||||
...generateFieldValidator(options),
|
||||
// 渲染组件相关
|
||||
...generateFieldComponent({ type, validateJsonSchema }),
|
||||
// component 也自带默认值,入参的默认值优先级更高
|
||||
defaultValue,
|
||||
...extra,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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 { generateField } from './generate-field';
|
||||
export { generateFieldValidator } from './generate-field-validator';
|
||||
export { isFormSchemaPropertyEmpty } from './is-property-empty';
|
||||
export { stringifyFormValuesFromBacked } from './stringify-form-values-from-backed';
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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 { isObject } from 'lodash-es';
|
||||
|
||||
/**
|
||||
* 是否是空的 properties
|
||||
*/
|
||||
export const isFormSchemaPropertyEmpty = (properties: unknown) =>
|
||||
isObject(properties) ? !Object.keys(properties).length : true;
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 { isBoolean } from 'lodash-es';
|
||||
|
||||
export const stringifyFormValuesFromBacked = (value: object) => {
|
||||
if (!value) {
|
||||
return undefined;
|
||||
}
|
||||
return Object.keys(value).reduce((acc, key) => {
|
||||
const val = value[key];
|
||||
if (val === null || val === undefined) {
|
||||
acc[key] = undefined;
|
||||
} else if (typeof val === 'string' || isBoolean(val)) {
|
||||
acc[key] = val;
|
||||
} else {
|
||||
acc[key] = JSON.stringify(value[key]);
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
Reference in New Issue
Block a user