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
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2960 changed files with 15545 additions and 15545 deletions

View File

@ -83,7 +83,7 @@ const mergedConfig = defineConfig({
source: { source: {
define: { define: {
'process.env.IS_REACT18': JSON.stringify(true), 'process.env.IS_REACT18': JSON.stringify(true),
// arcosite editor sdk 内部使用 // Arcosite editor sdk internal use
'process.env.ARCOSITE_SDK_REGION': JSON.stringify( 'process.env.ARCOSITE_SDK_REGION': JSON.stringify(
GLOBAL_ENVS.IS_OVERSEA ? 'VA' : 'CN', GLOBAL_ENVS.IS_OVERSEA ? 'VA' : 'CN',
), ),
@ -99,7 +99,7 @@ const mergedConfig = defineConfig({
include: [ include: [
path.resolve(__dirname, '../../packages'), path.resolve(__dirname, '../../packages'),
path.resolve(__dirname, '../../infra/flags-devtool'), path.resolve(__dirname, '../../infra/flags-devtool'),
// 以下几个包包含未降级的 ES 2022 语法private methods需要参与打包 // The following packages contain undegraded ES 2022 syntax (private methods) that need to be packaged
/\/node_modules\/(marked|@dagrejs|@tanstack)\//, /\/node_modules\/(marked|@dagrejs|@tanstack)\//,
], ],
alias: { alias: {

View File

@ -31,15 +31,15 @@ const initFlags = () => {
}; };
const main = () => { const main = () => {
// 初始化功能开关的值 // Initialize the value of the function switch
initFlags(); initFlags();
// 初始化i18n // Initialize i18n
initI18nInstance({ initI18nInstance({
lng: (localStorage.getItem('i18next') ?? (IS_OVERSEA ? 'en' : 'zh-CN')) as lng: (localStorage.getItem('i18next') ?? (IS_OVERSEA ? 'en' : 'zh-CN')) as
| 'en' | 'en'
| 'zh-CN', | 'zh-CN',
}); });
// 动态导入mdbox 样式 // Import mdbox styles dynamically
dynamicImportMdBoxStyle(); dynamicImportMdBoxStyle();
const $root = document.getElementById('root'); const $root = document.getElementById('root');

View File

@ -16,128 +16,128 @@
import { lazy } from 'react'; import { lazy } from 'react';
// 登录页面 // login page
export const LoginPage = lazy(() => export const LoginPage = lazy(() =>
import('@coze-foundation/account-ui-adapter').then(res => ({ import('@coze-foundation/account-ui-adapter').then(res => ({
default: res.LoginPage, default: res.LoginPage,
})), })),
); );
// 文档页面 // documentation page
export const Redirect = lazy(() => import('../pages/redirect')); export const Redirect = lazy(() => import('../pages/redirect'));
// 工作空间侧边栏组件 // Workspace Sidebar Component
export const spaceSubMenu = lazy(() => export const spaceSubMenu = lazy(() =>
import('@coze-foundation/space-ui-adapter').then(exps => ({ import('@coze-foundation/space-ui-adapter').then(exps => ({
default: exps.WorkspaceSubMenu, default: exps.WorkspaceSubMenu,
})), })),
); );
// 工作空间布局组件 // Workspace Layout Component
export const SpaceLayout = lazy(() => export const SpaceLayout = lazy(() =>
import('@coze-foundation/space-ui-adapter').then(exps => ({ import('@coze-foundation/space-ui-adapter').then(exps => ({
default: exps.SpaceLayout, default: exps.SpaceLayout,
})), })),
); );
// 某个具体的工作空间布局组件 // A specific workspace layout component
export const SpaceIdLayout = lazy(() => export const SpaceIdLayout = lazy(() =>
import('@coze-foundation/space-ui-base').then(exps => ({ import('@coze-foundation/space-ui-base').then(exps => ({
default: exps.SpaceIdLayout, default: exps.SpaceIdLayout,
})), })),
); );
// 项目开发页面 // project development page
export const Develop = lazy(() => import('../pages/develop')); export const Develop = lazy(() => import('../pages/develop'));
// 资源库页面 // resource library page
export const Library = lazy(() => import('../pages/library')); export const Library = lazy(() => import('../pages/library'));
// Agent IDE布局组件 // Agent IDE Layout Component
export const AgentIDELayout = lazy( export const AgentIDELayout = lazy(
() => import('@coze-agent-ide/layout-adapter'), () => import('@coze-agent-ide/layout-adapter'),
); );
// Agent IDE页面 // Agent IDE page
export const AgentIDE = lazy(() => export const AgentIDE = lazy(() =>
import('@coze-agent-ide/entry-adapter').then(res => ({ import('@coze-agent-ide/entry-adapter').then(res => ({
default: res.BotEditor, default: res.BotEditor,
})), })),
); );
// Agent IDE发布页面 // Agent IDE Release Page
export const AgentPublishPage = lazy(() => export const AgentPublishPage = lazy(() =>
import('@coze-agent-ide/agent-publish').then(exps => ({ import('@coze-agent-ide/agent-publish').then(exps => ({
default: exps.AgentPublishPage, default: exps.AgentPublishPage,
})), })),
); );
// Project IDE页面 // Project IDE Page
export const ProjectIDE = lazy(() => export const ProjectIDE = lazy(() =>
import('@coze-project-ide/main').then(exps => ({ import('@coze-project-ide/main').then(exps => ({
default: exps.IDELayout, default: exps.IDELayout,
})), })),
); );
// Project IDE发布页面 // Project IDE Release Page
export const ProjectIDEPublish = lazy(() => export const ProjectIDEPublish = lazy(() =>
import('@coze-studio/project-publish').then(exps => ({ import('@coze-studio/project-publish').then(exps => ({
default: exps.ProjectPublish, default: exps.ProjectPublish,
})), })),
); );
// 知识库预览页面 // Knowledge Base Preview Page
export const KnowledgePreview = lazy(() => export const KnowledgePreview = lazy(() =>
import('@coze-studio/workspace-base/knowledge-preview').then(exps => ({ import('@coze-studio/workspace-base/knowledge-preview').then(exps => ({
default: exps.KnowledgePreviewPage, default: exps.KnowledgePreviewPage,
})), })),
); );
// 知识库上传页面 // Knowledge base upload page
export const KnowledgeUpload = lazy(() => export const KnowledgeUpload = lazy(() =>
import('@coze-studio/workspace-base/knowledge-upload').then(exps => ({ import('@coze-studio/workspace-base/knowledge-upload').then(exps => ({
default: exps.KnowledgeUploadPage, default: exps.KnowledgeUploadPage,
})), })),
); );
// 数据库资源页面 // database resource page
export const DatabaseDetail = lazy(() => export const DatabaseDetail = lazy(() =>
import('@coze-studio/workspace-base').then(exps => ({ import('@coze-studio/workspace-base').then(exps => ({
default: exps.DatabaseDetailPage, default: exps.DatabaseDetailPage,
})), })),
); );
// 工作流页面 // workflow page
export const WorkflowPage = lazy(() => export const WorkflowPage = lazy(() =>
import('@coze-workflow/playground-adapter').then(res => ({ import('@coze-workflow/playground-adapter').then(res => ({
default: res.WorkflowPage, default: res.WorkflowPage,
})), })),
); );
// 插件资源页面布局组件 // plugin resource page layout component
export const PluginLayout = lazy(() => import('../pages/plugin/layout')); export const PluginLayout = lazy(() => import('../pages/plugin/layout'));
// 插件资源页面 // plugin resource page
export const PluginPage = lazy(() => import('../pages/plugin/page')); export const PluginPage = lazy(() => import('../pages/plugin/page'));
// 插件工具页面 // plugin tool page
export const PluginToolPage = lazy(() => import('../pages/plugin/tool/page')); export const PluginToolPage = lazy(() => import('../pages/plugin/tool/page'));
// 探索体验页面二级导航组件 // Explore the experience page secondary navigation component
export const exploreSubMenu = lazy(() => export const exploreSubMenu = lazy(() =>
import('@coze-community/explore').then(exps => ({ import('@coze-community/explore').then(exps => ({
default: exps.ExploreSubMenu, default: exps.ExploreSubMenu,
})), })),
); );
// 模版页面 // template page
export const ExploreTemplatePage = lazy(() => export const ExploreTemplatePage = lazy(() =>
import('@coze-community/explore').then(exps => ({ import('@coze-community/explore').then(exps => ({
default: exps.TemplatePage, default: exps.TemplatePage,
})), })),
); );
// 插件商店页面 // plugin store page
export const ExplorePluginPage = lazy(() => export const ExplorePluginPage = lazy(() =>
import('@coze-community/explore').then(exps => ({ import('@coze-community/explore').then(exps => ({
default: exps.PluginPage, default: exps.PluginPage,

View File

@ -48,7 +48,7 @@ import {
export const router: ReturnType<typeof createBrowserRouter> = export const router: ReturnType<typeof createBrowserRouter> =
createBrowserRouter([ createBrowserRouter([
// 文档路由 // Document routing
{ {
path: '/open/docs/*', path: '/open/docs/*',
Component: Redirect, Component: Redirect,
@ -73,7 +73,7 @@ export const router: ReturnType<typeof createBrowserRouter> =
requireAuth: false, requireAuth: false,
}), }),
}, },
// 主应用路由 // main application route
{ {
path: '/', path: '/',
Component: Layout, Component: Layout,
@ -83,7 +83,7 @@ export const router: ReturnType<typeof createBrowserRouter> =
index: true, index: true,
element: <Navigate to="/space" replace />, element: <Navigate to="/space" replace />,
}, },
// 登录页路由 // login page routing
{ {
path: 'sign', path: 'sign',
Component: LoginPage, Component: LoginPage,
@ -94,7 +94,7 @@ export const router: ReturnType<typeof createBrowserRouter> =
}), }),
}, },
// 工作空间路由 // Workspace Routing
{ {
path: 'space', path: 'space',
Component: SpaceLayout, Component: SpaceLayout,
@ -114,7 +114,7 @@ export const router: ReturnType<typeof createBrowserRouter> =
element: <Navigate to="develop" replace />, element: <Navigate to="develop" replace />,
}, },
// 项目开发 // Project Development
{ {
path: 'develop', path: 'develop',
Component: Develop, Component: Develop,
@ -171,7 +171,7 @@ export const router: ReturnType<typeof createBrowserRouter> =
}), }),
}, },
// 资源库 // resource library
{ {
path: 'library', path: 'library',
Component: Library, Component: Library,
@ -180,7 +180,7 @@ export const router: ReturnType<typeof createBrowserRouter> =
}), }),
}, },
// 知识库资源 // Knowledge Base Resources
{ {
path: 'knowledge', path: 'knowledge',
children: [ children: [
@ -198,7 +198,7 @@ export const router: ReturnType<typeof createBrowserRouter> =
}), }),
}, },
// 数据库资源 // database resources
{ {
path: 'database', path: 'database',
children: [ children: [
@ -213,7 +213,7 @@ export const router: ReturnType<typeof createBrowserRouter> =
}), }),
}, },
// 插件资源 // plugin resources
{ {
path: 'plugin/:plugin_id', path: 'plugin/:plugin_id',
Component: PluginLayout, Component: PluginLayout,
@ -238,7 +238,7 @@ export const router: ReturnType<typeof createBrowserRouter> =
], ],
}, },
// 工作流路由 // workflow routing
{ {
path: 'work_flow', path: 'work_flow',
Component: WorkflowPage, Component: WorkflowPage,
@ -248,7 +248,7 @@ export const router: ReturnType<typeof createBrowserRouter> =
}), }),
}, },
// 探索 // explore
{ {
path: 'explore', path: 'explore',
Component: null, Component: null,
@ -263,7 +263,7 @@ export const router: ReturnType<typeof createBrowserRouter> =
index: true, index: true,
element: <Navigate to="plugin" replace />, element: <Navigate to="plugin" replace />,
}, },
// 插件商店 // plugin store
{ {
path: 'plugin', path: 'plugin',
element: <ExplorePluginPage />, element: <ExplorePluginPage />,
@ -271,7 +271,7 @@ export const router: ReturnType<typeof createBrowserRouter> =
type: 'plugin', type: 'plugin',
}), }),
}, },
// 模版 // template
{ {
path: 'template', path: 'template',
element: <ExploreTemplatePage />, element: <ExploreTemplatePage />,

View File

@ -27,7 +27,7 @@ console.log(`Got ${contents.length} contents for tailwind`);
export default { export default {
content: contents, content: contents,
// safelist的内容可以允许动态生成tailwind className // Safelist content can allow dynamic tailwind className
safelist: [ safelist: [
{ {
pattern: /(gap-|grid-).+/, pattern: /(gap-|grid-).+/,
@ -47,7 +47,7 @@ export default {
}, },
}, },
corePlugins: { corePlugins: {
preflight: false, // 关闭@tailwind base默认样式避免对现有样式影响 preflight: false, // Turn off @tailwind base default styles to avoid affecting existing styles
}, },
// eslint-disable-next-line @typescript-eslint/no-require-imports // eslint-disable-next-line @typescript-eslint/no-require-imports
plugins: [require('@coze-arch/tailwind-config/coze')], plugins: [require('@coze-arch/tailwind-config/coze')],

View File

@ -5,7 +5,7 @@ module.exports = [
...require('./eslint.config.base.js'), ...require('./eslint.config.base.js'),
{ {
plugins: { plugins: {
// TODO: 需要根据不同类型配置plugin需要阅读源码确认是否影响性能 // TODO: Need to configure plugins according to different types? You need to read the source code to confirm whether it affects performance
'react-hooks': require('eslint-plugin-react-hooks'), 'react-hooks': require('eslint-plugin-react-hooks'),
react: require('eslint-plugin-react'), react: require('eslint-plugin-react'),
risxss: require('eslint-plugin-risxss'), risxss: require('eslint-plugin-risxss'),

View File

@ -28,7 +28,7 @@ const readBlockList = () =>
/** @type {(import('eslint').Linter.Config)[]} */ /** @type {(import('eslint').Linter.Config)[]} */
module.exports = [ module.exports = [
// NOTE: 不能和下一项配置合并 // NOTE: Cannot be merged with the next configuration
{ {
ignores: [ ignores: [
'**/*.d.ts', '**/*.d.ts',
@ -68,7 +68,7 @@ module.exports = [
...require('@coze-arch/eslint-plugin').configs.recommended, ...require('@coze-arch/eslint-plugin').configs.recommended,
require('@coze-arch/eslint-plugin/zustand').configs.recommended, require('@coze-arch/eslint-plugin/zustand').configs.recommended,
{ {
files: ['**/*.?(m|c)?(j|t)s?(x)'], // 排除规则对package.json生效 files: ['**/*.?(m|c)?(j|t)s?(x)'], // Exclusion rules take effect for package.json
plugins: { plugins: {
prettier: require('eslint-plugin-prettier'), prettier: require('eslint-plugin-prettier'),
'@babel': require('@babel/eslint-plugin'), '@babel': require('@babel/eslint-plugin'),

View File

@ -5,7 +5,7 @@ module.exports = [
{ {
files: ['**/*.?(m|c)?(j|t)s?(x)'], files: ['**/*.?(m|c)?(j|t)s?(x)'],
settings: { settings: {
// TODO: 全局保留一份配置 // TODO: Keep a configuration globally
'import/resolver': { 'import/resolver': {
node: { node: {
moduleDirectory: ['node_modules', 'src'], moduleDirectory: ['node_modules', 'src'],
@ -72,8 +72,8 @@ module.exports = [
}, },
}, },
rules: { rules: {
// TODO: 目前由于 edenx 会动态生成一些插件模块,因此启动会报错 // TODO: At present, because edenx will dynamically generate some plug-in modules, an error will be reported when starting.
// 后续需要修复问题,启动下述规则 // You need to fix the problem later, and start the following rules.
// "import/no-unresolved": "error" // "import/no-unresolved": "error"
}, },
}, },

View File

@ -59,9 +59,9 @@ module.exports = [
{ {
vars: 'all', vars: 'all',
args: 'none', // function arguments should not force to match this rule. args: 'none', // function arguments should not force to match this rule.
argsIgnorePattern: '^_', // 规范允许下划线 argsIgnorePattern: '^_', // Specifications allow underlining
ignoreRestSiblings: true, //使用rest语法如 `var { foo, ...rest } = data`) 忽略foo。 ignoreRestSiblings: true, //Use rest syntax (such as'var {foo,... rest} = data ') to ignore foo.
destructuredArrayIgnorePattern: '^_', //结构数组允许使用_ destructuredArrayIgnorePattern: '^_', //Structural arrays allow _
caughtErrors: 'none', caughtErrors: 'none',
// "caughtErrorsIgnorePattern": "^e$" // "caughtErrorsIgnorePattern": "^e$"
}, },
@ -314,7 +314,7 @@ module.exports = [
}, },
}, },
// TODO: 之前overides的内容后需可考虑直接合入上面标准配置 // TODO: The content of overides before can be considered to be directly integrated into the above standard configuration later
{ {
files: ['**/*.?(m|c)ts?(x)'], files: ['**/*.?(m|c)ts?(x)'],
rules: { rules: {
@ -324,8 +324,8 @@ module.exports = [
fixStyle: 'inline-type-imports', fixStyle: 'inline-type-imports',
}, },
], ],
// 这些规则都是从 packages/config/.eslintrc.react.js 复制迁移过来 // These rules are copied and migrated from packages/config/.eslintrc.react.js
// 后续在做调整 // Adjustments are being made later.
'@typescript-eslint/no-redundant-type-constituents': 0, '@typescript-eslint/no-redundant-type-constituents': 0,
'@typescript-eslint/no-throw-literal': 'off', '@typescript-eslint/no-throw-literal': 'off',
'@typescript-eslint/no-unnecessary-condition': 0, '@typescript-eslint/no-unnecessary-condition': 0,
@ -335,14 +335,14 @@ module.exports = [
'@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-function-return-type': 'off',
'no-shadow': 'off', 'no-shadow': 'off',
'@typescript-eslint/no-shadow': 'error', '@typescript-eslint/no-shadow': 'error',
// TODO: 后续开启 // TODO: Follow-up opening
// 'import/no-cycle': 'error', // 'import/no-cycle': 'error',
'@typescript-eslint/prefer-string-starts-ends-with': 0, '@typescript-eslint/prefer-string-starts-ends-with': 0,
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 0, '@typescript-eslint/no-unnecessary-boolean-literal-compare': 0,
'@typescript-eslint/no-implied-eval': 0, // warning '@typescript-eslint/no-implied-eval': 0, // warning
// TODO: 打开下面这些配置 // TODO: Open the following configurations
// fix: https://stackoverflow.com/questions/63961803/eslint-says-all-enums-in-typescript-app-are-already-declared-in-the-upper-scope // fix: https://stackoverflow.com/questions/63961803/eslint-says-all-enums-in-typescript-app-are-already-declared-in-the-upper-scope
// 'no-shadow': 'off', // 'no-shadow': 'off',
// '@typescript-eslint/no-shadow': ['error'], // '@typescript-eslint/no-shadow': ['error'],
@ -364,7 +364,7 @@ module.exports = [
// }, // },
// ], // ],
// complexity: ['error', { max: 15 }], // complexity: ['error', { max: 15 }],
// 后面统一使用CustomError后 再开启 // After using CustomError uniformly later, open it again.
'@coze-arch/no-new-error': 'off', '@coze-arch/no-new-error': 'off',
}, },
}, },

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
BASE_DIR=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") BASE_DIR=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
# 某些系统可能没有 realpath 命令, # Some systems may not have the realpath command.
if ! command -v realpath &>/dev/null; then if ! command -v realpath &>/dev/null; then
echo "未找到 realpath 命令" echo "未找到 realpath 命令"
echo "请执行以下命令安装必要依赖" echo "请执行以下命令安装必要依赖"

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
BASE_DIR=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") BASE_DIR=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
# 某些系统可能没有 realpath 命令, # Some systems may not have the realpath command.
if ! command -v realpath &>/dev/null; then if ! command -v realpath &>/dev/null; then
echo "未找到 realpath 命令" echo "未找到 realpath 命令"
echo "请执行以下命令安装必要依赖" echo "请执行以下命令安装必要依赖"

View File

@ -2,9 +2,9 @@ require('sucrase/register/ts');
const { defineConfig } = require('./define-config'); const { defineConfig } = require('./define-config');
// node@16 没有 structuredClone 方法导致报错: // node@16 no structuredClone method causes an error:
// ReferenceError: Error while loading rule '@typescript-eslint/naming-convention': structuredClone is not defined // ReferenceError: Error while loading rule '@typescript-eslint/naming-convention': structuredClone is not defined
// 此处做个简单 polyfill // Make a simple polyfill here
if (typeof structuredClone === 'undefined') { if (typeof structuredClone === 'undefined') {
global.structuredClone = obj => JSON.parse(JSON.stringify(obj)); global.structuredClone = obj => JSON.parse(JSON.stringify(obj));
} }

View File

@ -28,7 +28,7 @@ import { SemiRspackPlugin } from '@douyinfe/semi-rspack-plugin';
const getDefine = () => { const getDefine = () => {
const define = {}; const define = {};
Object.keys(GLOBAL_ENVS).forEach(key => { Object.keys(GLOBAL_ENVS).forEach(key => {
// 在rspack的define中字符串需要前后拼接上双引号才能在代码中作为字符串使用。 // In the definition of rspack, strings need to be enclosed in double quotes before they can be used as strings in code.
if (typeof GLOBAL_ENVS[key] === 'string') { if (typeof GLOBAL_ENVS[key] === 'string') {
define[key] = `"${GLOBAL_ENVS[key]}"`; define[key] = `"${GLOBAL_ENVS[key]}"`;
} else { } else {
@ -115,7 +115,7 @@ export const defineConfig = (options: Partial<RsbuildConfig>) => {
), ),
}, },
include: [ include: [
// 以下几个包包含未降级的 ES 2022 语法private methods需要参与打包 // The following packages contain undegraded ES 2022 syntax (private methods) that need to be packaged
/\/node_modules\/(marked|@dagrejs|@tanstack)\//, /\/node_modules\/(marked|@dagrejs|@tanstack)\//,
], ],
}, },

View File

@ -6,9 +6,9 @@ module.exports = {
], ],
plugins: ['./plugins/plugin-disallow-nesting-level-one-global.js'], plugins: ['./plugins/plugin-disallow-nesting-level-one-global.js'],
rules: { rules: {
// 变量命名规则,适应仓库内的代码风格 // Variable naming rules to adapt to the code style in the warehouse
'custom-property-pattern': '^([A-Za-z0-9]*)([-_]+[A-Za-z0-9]+)*$', 'custom-property-pattern': '^([A-Za-z0-9]*)([-_]+[A-Za-z0-9]+)*$',
// 对于less函数判断有问题 // There is a problem with judging the less function
'less/no-duplicate-variables': null, 'less/no-duplicate-variables': null,
'media-feature-range-notation': null, 'media-feature-range-notation': null,
'max-nesting-depth': [ 'max-nesting-depth': [

View File

@ -5,7 +5,7 @@ const plugin = require('tailwindcss/plugin');
const lightModeVariables = require('./light'); const lightModeVariables = require('./light');
const darkModeVariables = require('./dark'); const darkModeVariables = require('./dark');
// 用于生成 CSS 变量的帮助函数 // Helper functions for generating CSS variables
function generateCssVariables(variables, theme) { function generateCssVariables(variables, theme) {
return Object.entries(variables).reduce((acc, [key, value]) => { return Object.entries(variables).reduce((acc, [key, value]) => {
acc[`--${key}`] = theme ? theme(value) : value; acc[`--${key}`] = theme ? theme(value) : value;
@ -13,7 +13,7 @@ function generateCssVariables(variables, theme) {
}, {}); }, {});
} }
// 样式语义化 // style semantics
function generateSemanticVariables(semantics, theme, property) { function generateSemanticVariables(semantics, theme, property) {
return Object.entries(semantics).map(([key, value]) => ({ return Object.entries(semantics).map(([key, value]) => ({
[`.${key}`]: { [`.${key}`]: {

View File

@ -1,4 +1,4 @@
// 暗色模式的 CSS 变量 // CSS Variables for Dark Mode
const darkModeVariables = { const darkModeVariables = {
background: '2, 8, 23', background: '2, 8, 23',
foreground: '249, 249, 249', foreground: '249, 249, 249',

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
// 消费者和生产者公共的 tailwind 配置和工具函数 // Common tailwind configurations and tool functions for consumers and producers
export function designTokenToTailwindConfig( export function designTokenToTailwindConfig(
tokenJson: Record<string, unknown>, tokenJson: Record<string, unknown>,
@ -103,6 +103,6 @@ function borderRadiusTransformer(borderRadiusObj: Record<string, string>) {
return res; return res;
} }
// 获取其他packages并且拼接上 /src/**/*.{ts,tsx} // Get other packages and splice /src /**/*.{ ts, tsx}
export { getTailwindContents } from './tailwind-contents'; export { getTailwindContents } from './tailwind-contents';

View File

@ -1,4 +1,4 @@
// 浅色模式的 CSS 变量 // CSS Variables for Light Mode
const lightModeVariables = { const lightModeVariables = {
background: '255, 255, 255', background: '255, 255, 255',
foreground: '28, 28, 35', foreground: '28, 28, 35',
@ -27,7 +27,7 @@ const lightModeVariables = {
'coze-fg-3': '15, 21, 40', 'coze-fg-3': '15, 21, 40',
'coze-fg-2': '32, 41, 69', 'coze-fg-2': '32, 41, 69',
'coze-fg-1': '55, 67, 106', 'coze-fg-1': '55, 67, 106',
// TODO: 需要删除bg9 // TODO: need to remove bg9
'coze-bg-9': '6, 7, 9', 'coze-bg-9': '6, 7, 9',
'coze-bg-8': '68, 83, 130', 'coze-bg-8': '68, 83, 130',
'coze-bg-7': '75, 90, 140', 'coze-bg-7': '75, 90, 140',
@ -151,7 +151,7 @@ const lightModeVariables = {
'coze-3': '3px', 'coze-3': '3px',
'coze-2': '2px', 'coze-2': '2px',
'coze-1': '1px', 'coze-1': '1px',
// TODO: rspress编译不出来,需要通过一些工具处理,目前没有用到,暂时注释处理 // TODO: rspress cannot be compiled, and it needs to be processed by some tools. It is not used at present. Temporary comment processing
// 'coze-0.5': '0.5px', // 'coze-0.5': '0.5px',
'coze-0-5': '0.5px', 'coze-0-5': '0.5px',
@ -174,7 +174,7 @@ const lightModeVariables = {
'coze-bg-6-alpha': '0.13', 'coze-bg-6-alpha': '0.13',
'coze-bg-7-alpha': '0.19', 'coze-bg-7-alpha': '0.19',
'coze-bg-8-alpha': '0.25', 'coze-bg-8-alpha': '0.25',
// TODO: 需要删除bg9 // TODO: need to remove bg9
'coze-bg-9-alpha': '0.16', 'coze-bg-9-alpha': '0.16',
'coze-stroke-5-alpha': '0.13', 'coze-stroke-5-alpha': '0.13',
'coze-stroke-6-alpha': '0.25', 'coze-stroke-6-alpha': '0.25',

View File

@ -46,7 +46,7 @@ export const getTailwindContents = (projectRoot: string) => {
.map(location => path.resolve(location, 'src/**/*.{ts,tsx}')), .map(location => path.resolve(location, 'src/**/*.{ts,tsx}')),
); );
// 兼容 coze-design 内部 tailwind 样式 // Compatible with coze-design internal tailwind style
contents.push('./node_modules/@coze-arch/coze-design/**/*.{js,jsx}'); contents.push('./node_modules/@coze-arch/coze-design/**/*.{js,jsx}');
return contents; return contents;

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
BASE_DIR=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") BASE_DIR=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
# 某些系统可能没有 realpath 命令, # Some systems may not have the realpath command.
if ! command -v realpath &>/dev/null; then if ! command -v realpath &>/dev/null; then
echo "未找到 realpath 命令" echo "未找到 realpath 命令"
echo "请执行以下命令安装必要依赖" echo "请执行以下命令安装必要依赖"

View File

@ -16,7 +16,7 @@
"moduleResolution": "node", "moduleResolution": "node",
"module": "CommonJS", "module": "CommonJS",
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
// bot // This general feedback will make the code verbose, tentatively follow the original bot's settings, close
"noImplicitReturns": false, "noImplicitReturns": false,
"removeComments": false, "removeComments": false,
"resolveJsonModule": true, "resolveJsonModule": true,

View File

@ -46,7 +46,7 @@ const calBasePreset = (preset: string) => {
export interface OtherConfig { export interface OtherConfig {
/** /**
* semi的package.json导出的配置问题 * Used to fix the configuration issue of semi's package.json export
*/ */
fixSemi: boolean; fixSemi: boolean;
} }

View File

@ -20,7 +20,7 @@ import tsconfigPaths from 'vite-tsconfig-paths';
export const defaultVitestConfig: UserConfig = { export const defaultVitestConfig: UserConfig = {
plugins: [tsconfigPaths()], plugins: [tsconfigPaths()],
resolve: { resolve: {
// 优先识别 main如果没有配置 main则识别 module // Priority to identify main, if main is not configured, identify the module
mainFields: ['main', 'module', 'exports'], mainFields: ['main', 'module', 'exports'],
}, },
server: { server: {
@ -38,14 +38,14 @@ export const defaultVitestConfig: UserConfig = {
}, },
}, },
sequence: { sequence: {
// vitest 2.0之后,所有钩子默认串行运行 // After vitest 2.0, all hooks run serially by default
hooks: 'parallel', hooks: 'parallel',
}, },
globals: true, globals: true,
mockReset: false, mockReset: false,
silent: process.env.CI === 'true', silent: process.env.CI === 'true',
coverage: { coverage: {
// 逐步对各包开启 // Gradually open each package
all: false, all: false,
include: ['src/**/*.ts', 'src/**/*.tsx'], include: ['src/**/*.ts', 'src/**/*.tsx'],
exclude: coverageConfigDefaults.exclude, exclude: coverageConfigDefaults.exclude,

View File

@ -1,16 +1,16 @@
[ [
// 使 @vitest/coverage-v8 // Can be replaced by @vitest/coverage-v8
["@vitest/coverage-c8", null, "请使用 @vitest/coverage-v8"], ["@vitest/coverage-c8", null, "请使用 @vitest/coverage-v8"],
"husky", "husky",
"lint-staged", "lint-staged",
"jest", "jest",
["jsdom", null, "请使用 happy-dom 代替"], ["jsdom", null, "请使用 happy-dom 代替"],
// TODO: @tanjizhen // TODO: Open @tanjizhen after waiting for full repair
// "@oceanos/logger", // "@oceanos/logger",
["inquirer", null, "请使用 @inquirer/prompts 代替"], ["inquirer", null, "请使用 @inquirer/prompts 代替"],
["pdfjs-dist", null, "请使用 @coze-arch/pdfjs-shadow 代替"], ["pdfjs-dist", null, "请使用 @coze-arch/pdfjs-shadow 代替"],
// todo: should turn on this // todo: should turn on this
// ["valtio", null, "请使用 zustand"], // ["Valtio", null, "Please use zustand"],
// ["jotai", null, "请使用 zustand"] // ["Jotai", null, "Please use zustand"]
["@flow-web/md-box", null, "请使用 @coze-arch/bot-md-box-adapter 代替"] ["@flow-web/md-box", null, "请使用 @coze-arch/bot-md-box-adapter 代替"]
] ]

View File

@ -48,7 +48,7 @@ export const flowPreset = {
'@coze-arch/tsx-no-leaked-render': 'warn', '@coze-arch/tsx-no-leaked-render': 'warn',
'@coze-arch/no-pkg-dir-import': 'error', '@coze-arch/no-pkg-dir-import': 'error',
'@coze-arch/no-duplicated-deps': 'error', '@coze-arch/no-duplicated-deps': 'error',
// 不允许超过 4 层的相对应用 // Relative applications with more than 4 layers are not allowed
'@coze-arch/no-deep-relative-import': [ '@coze-arch/no-deep-relative-import': [
'error', 'error',
{ {
@ -56,7 +56,7 @@ export const flowPreset = {
}, },
], ],
'@coze-arch/package-require-author': 'error', '@coze-arch/package-require-author': 'error',
// 函数代码行不要超过 150 // Function code lines should not exceed 150.
'@coze-arch/max-line-per-function': [ '@coze-arch/max-line-per-function': [
'error', 'error',
{ {
@ -73,11 +73,11 @@ export const flowPreset = {
files: ['package.json'], files: ['package.json'],
processor: '@coze-arch/json-processor', processor: '@coze-arch/json-processor',
rules: { rules: {
// TODO: 需要重构为直接解析json否则全局规则都会对processor处理后的文件`package.js`生效. // TODO: It needs to be refactored to parse json directly, otherwise the global rules will take effect on the file'package.js' processed by the processor.
//https://github.com/eslint/json //https://github.com/eslint/json
'@coze-arch/package-require-author': 'error', '@coze-arch/package-require-author': 'error',
'@coze-arch/package-disallow-deps': 'error', '@coze-arch/package-disallow-deps': 'error',
// 关闭prettier规则因为该规则lint package.js存在bug // Close the prettier rule because there is a bug in the rule lint package.js
'prettier/prettier': 'off', 'prettier/prettier': 'off',
}, },
}, },

View File

@ -36,7 +36,7 @@ const getStaticStringValue = node => {
* *
* @param node * @param node
* @returns * @returns
* * Why is this judgment necessary for a function such as
* ``` * ```
* var obj1 = { * var obj1 = {
* set * set
@ -46,9 +46,9 @@ const getStaticStringValue = node => {
* } * }
* } * }
*``` *```
* 35. * If you don't use the following judgment, the function judgment will get 3, which should actually be 5. Similarly, there are
* ``` * ```
* //如果不采用下面这个判断函数判断将得到3实际应该为8 * //If the following judgment is not used, the function judgment will get 3, which should actually be 8ing judgment, the function judgment will get 3, which should actually be 8.
* class A { * class A {
static static
[ [
@ -85,14 +85,14 @@ const isEmbedded = node => {
* *
* @param node * @param node
* @returns function name * @returns function name
* Q node.id.value获取函数名称 ? * Q: Why not get the function name directly with node.id?
* A * A: This method is fine for traditional function writing, but for
* const tips = { * const tips = {
* fun: () => {} * fun: () => {}
* }; * };
* * or
* const fun2 = () => {} * const fun2 = () => {}
* null * The name of the function written in the following way is null, so it is obtained in the following way.
* *
*/ */
@ -192,7 +192,7 @@ const getStaticPropertyName = node => {
case 'VariableDeclarator': case 'VariableDeclarator':
prop = node.id; prop = node.id;
break; break;
//TODO CallExpression 场景较为复杂,目前应该没有完全覆盖 //TODO: The CallExpression scenario is more complex and should not be fully covered at present
case 'CallExpression': case 'CallExpression':
prop = node.callee; prop = node.callee;
break; break;
@ -240,7 +240,7 @@ export const maxLinePerFunctionRule: Rule.RuleModule = {
function checkFunctionLength(funcNode) { function checkFunctionLength(funcNode) {
const node = isEmbedded(funcNode) ? funcNode.parent : funcNode; const node = isEmbedded(funcNode) ? funcNode.parent : funcNode;
// 针对函数声明,函数表达式,箭头函数,函数定义四种类型 // Four types of function declarations, function expressions, arrow functions, and function definitions
if ( if (
node.type === 'FunctionDeclaration' || node.type === 'FunctionDeclaration' ||
node.type === 'FunctionExpression' || node.type === 'FunctionExpression' ||

View File

@ -40,7 +40,7 @@ export const noDuplicatedDepsRule: Rule.RuleModule = {
if (!properties) { if (!properties) {
return; return;
} }
// 对比 dependencies 与 devDependencies 之间是否存在重复依赖 // Compare dependencies with devDependencies for duplicate dependencies
const dependencies = properties.find( const dependencies = properties.find(
p => p.key.value === 'dependencies', p => p.key.value === 'dependencies',
); );

View File

@ -40,7 +40,7 @@ export const noPkgDirImport: Rule.RuleModule = {
const modulePath = resolve(importPath, context); const modulePath = resolve(importPath, context);
if (!modulePath) { if (!modulePath) {
// 解析不到的情况,暂不处理 // If it cannot be resolved, it will not be dealt with for the time being.
return; return;
} }
@ -56,15 +56,15 @@ export const noPkgDirImport: Rule.RuleModule = {
return; return;
} }
// 本地link会解析到node_modules目录需要拿到pkg name再次解析。 // The local link will resolve to the node_modules directory, and you need to get the pkg name to resolve it again.
const moduleRealPath = resolve(pkg.name, context); const moduleRealPath = resolve(pkg.name, context);
if ( if (
// 包名称就是引用路径 // The package name is the reference path
pkg.name === importPath || pkg.name === importPath ||
// 解析到其他包,如@type // Parse to other packages, such as @type
!importPath.startsWith(pkg.name) || !importPath.startsWith(pkg.name) ||
// 解析到自己包的文件 // Parse to the file of your own package
currentPkgPath === importPkgPath || currentPkgPath === importPkgPath ||
!moduleRealPath || !moduleRealPath ||
moduleRealPath.includes('node_modules') moduleRealPath.includes('node_modules')

View File

@ -32,7 +32,7 @@ vi.mock('eslint-module-utils/readPkgUp', () => ({
const validCases = [ const validCases = [
{ {
code: 'import "xxx"', code: 'import "xxx"',
modulePath: undefined, // modulePath 为 空 modulePath: undefined, // modulePath is empty
moduleRealPath: undefined, moduleRealPath: undefined,
importPkgPath: 'path/to/import/pkg', importPkgPath: 'path/to/import/pkg',
currentPkgPath: 'path/to/current/pkg', currentPkgPath: 'path/to/current/pkg',
@ -48,7 +48,7 @@ const validCases = [
importPkgPath: 'path/to/import/pkg', importPkgPath: 'path/to/import/pkg',
currentPkgPath: 'path/to/current/pkg', currentPkgPath: 'path/to/current/pkg',
pkg: { pkg: {
name: 'some/pkg', // 包名称与引用路径相同 name: 'some/pkg', // The package name is the same as the reference path
exports: {}, exports: {},
}, },
}, },
@ -59,7 +59,7 @@ const validCases = [
importPkgPath: 'path/to/import/pkg', importPkgPath: 'path/to/import/pkg',
currentPkgPath: 'path/to/current/pkg', currentPkgPath: 'path/to/current/pkg',
pkg: { pkg: {
name: undefined, // 解析到不规范配置的package.json name: undefined, // Parse to the non-canonical package.json
}, },
}, },
{ {
@ -69,7 +69,7 @@ const validCases = [
importPkgPath: 'path/to/import/pkg', importPkgPath: 'path/to/import/pkg',
currentPkgPath: 'path/to/current/pkg', currentPkgPath: 'path/to/current/pkg',
pkg: { pkg: {
name: '@types/pkg', // 解析到类型包 name: '@types/pkg', // Parse to type package
exports: {}, exports: {},
}, },
}, },
@ -77,7 +77,7 @@ const validCases = [
code: "import pkg from 'pkg';", code: "import pkg from 'pkg';",
modulePath: 'path/to/module', modulePath: 'path/to/module',
moduleRealPath: 'path/to/module', moduleRealPath: 'path/to/module',
importPkgPath: 'path/to/same/pkg', // 相同路径 importPkgPath: 'path/to/same/pkg', // same path
currentPkgPath: 'path/to/same/pkg', currentPkgPath: 'path/to/same/pkg',
pkg: { pkg: {
name: '@types/pkg', name: '@types/pkg',
@ -98,7 +98,7 @@ const validCases = [
{ {
code: "import pkg from 'pkg';", code: "import pkg from 'pkg';",
modulePath: 'path/to/module', modulePath: 'path/to/module',
moduleRealPath: 'path/to/node_modules/pkg', // 解析到node_modules moduleRealPath: 'path/to/node_modules/pkg', // Parse to node_modules
importPkgPath: 'path/to/import/pkg', importPkgPath: 'path/to/import/pkg',
currentPkgPath: 'path/to/current/pkg', currentPkgPath: 'path/to/current/pkg',
pkg: { pkg: {
@ -134,7 +134,7 @@ const validCases = [
if (!c.modulePath) { if (!c.modulePath) {
return { return {
code: c.code, code: c.code,
// TODO: 避免eslint duplication检测。可能需要改为其他方式 // TODO: Avoid eslint duplication. It may need to be changed to another way
settings: c, settings: c,
}; };
} }
@ -167,7 +167,7 @@ const invalidCases = [
currentPkgPath: 'path/to/current/pkg', currentPkgPath: 'path/to/current/pkg',
pkg: { pkg: {
name: 'pkg', name: 'pkg',
exports: undefined, // 为空 exports: undefined, // empty
}, },
messageId: 'noExportsCfg', messageId: 'noExportsCfg',
}, },

View File

@ -56,7 +56,7 @@ export const disallowDepRule: Rule.RuleModule = {
return; return;
} }
const [, blockVersion, tips] = definition; const [, blockVersion, tips] = definition;
// 没有提供 version 参数,判定为不允许所有版本号 // No version parameter is provided, and it is determined that all version numbers are not allowed
if (typeof blockVersion !== 'string' || blockVersion.length <= 0) { if (typeof blockVersion !== 'string' || blockVersion.length <= 0) {
context.report({ context.report({
node, node,

View File

@ -20,12 +20,12 @@ import reactPlugin from 'eslint-plugin-react';
const originRule = reactPlugin.rules['jsx-no-leaked-render']; const originRule = reactPlugin.rules['jsx-no-leaked-render'];
// 扩展react/jsx-no-leaked-render。增加判断 「&&」 表达式左边为 boolean 、 null 、 undefined TS类型则不报错。 // Expand the react/jsx-no-leaked-render. If the left side of the "& &" expression is boolean, null, undefined TS type, no error will be reported.
export const tsxNoLeakedRender = ruleComposer.filterReports( export const tsxNoLeakedRender = ruleComposer.filterReports(
originRule, originRule,
problem => { problem => {
const { parent } = problem.node; const { parent } = problem.node;
// 如果表达式是用于jsx属性则不需要修复。 如 <Comp prop={ { foo: 1 } && obj } /> // If the expression is used for jsx properties, it does not need to be fixed. Such as < Comp prop = {{foo: 1} & & obj}/>
if ( if (
parent?.type === AST_NODE_TYPES.JSXExpressionContainer && parent?.type === AST_NODE_TYPES.JSXExpressionContainer &&
parent?.parent?.type === AST_NODE_TYPES.JSXAttribute parent?.parent?.type === AST_NODE_TYPES.JSXAttribute

View File

@ -25,7 +25,7 @@ ruleTester.run('prefer-shallow', preferShallow, {
'new Foo()', 'new Foo()',
'useShallowedFooStore()', 'useShallowedFooStore()',
'useFooStore((s) => s.value)', 'useFooStore((s) => s.value)',
'useFooStore(selector)', // 暂时豁免 'useFooStore(selector)', // Temporary exemption
'useShallowFooStore(() => ({}))', 'useShallowFooStore(() => ({}))',
'useFooStore(useShallow(() => ({})))', 'useFooStore(useShallow(() => ({})))',
'useFooStore(useShallow(() => ([])))', 'useFooStore(useShallow(() => ([])))',

View File

@ -32,8 +32,8 @@ struct UserDeleteDataMap {
We We
*/ */
enum AvatarMetaType { enum AvatarMetaType {
UNKNOWN = 0, // 没有数据, 错误数据或者系统错误降级 UNKNOWN = 0, // No data, incorrect data, or system error downgrade
RANDOM = 1, // 在修改 or 创建时,用户未指定 name 或者选中推荐的文字时,程序随机选择的头像 RANDOM = 1, // When modifying or creating, the user does not specify a name or select the recommended text, the program randomly selects the avatar
} }
`; `;

View File

@ -46,8 +46,8 @@ enum Gender {
} }
// const map<Gender, string> genderMap = { // const map<Gender, string> genderMap = {
// Gender.Male: '男性', // Gender. Male: 'Male',
// Gender.Female: '女性', // Gender. Female: 'Female',
// } // }
union FuncRequest { union FuncRequest {

View File

@ -686,7 +686,7 @@ function convertFieldDefinition(
if (!isProto3) { if (!isProto3) {
requiredness = optional ? 'optional' : 'required'; requiredness = optional ? 'optional' : 'required';
} else if (rule === 'required') { } else if (rule === 'required') {
// TODO: 处理 optional 的情况,需要修改 proto-parser // TODO: Handle optional cases, need to modify proto-parser
requiredness = 'required'; requiredness = 'required';
} }

View File

@ -25,7 +25,7 @@ function requiredWithoutCache(src, onError?) {
// eslint-disable-next-line @typescript-eslint/no-require-imports // eslint-disable-next-line @typescript-eslint/no-require-imports
const { Module } = require('module'); const { Module } = require('module');
try { try {
// disable 了 require 的缓存,这样可以改变了 mock 数据后,无需重启服务。 // Disable the required cache so that you can change the mock data without restarting the service.
const originCache = Module._cache; const originCache = Module._cache;
Module._cache = {}; Module._cache = {};
// eslint-disable-next-line security/detect-non-literal-require, @typescript-eslint/no-require-imports // eslint-disable-next-line security/detect-non-literal-require, @typescript-eslint/no-require-imports

View File

@ -186,7 +186,7 @@ export class FilterTypesPlugin {
} else if (isIdentifier(fieldType)) { } else if (isIdentifier(fieldType)) {
const statement = getStatementById(fieldType, current); const statement = getStatementById(fieldType, current);
if (isEnumDefinition(statement)) { if (isEnumDefinition(statement)) {
// 强制转位 number // Forced indexing number
// @ts-expect-error fixme late // @ts-expect-error fixme late
fieldType.type = SyntaxType.I32Keyword; fieldType.type = SyntaxType.I32Keyword;
let namespace = current.unifyNamespace; let namespace = current.unifyNamespace;

View File

@ -55,15 +55,15 @@ export class MockPlugin implements IPlugin {
if (context) { if (context) {
const { fieldDefinition } = context; const { fieldDefinition } = context;
const fieldName = fieldDefinition.name.value; const fieldName = fieldDefinition.name.value;
// 各类 ID // various types of ID
if (fieldName.toLocaleUpperCase().endsWith('ID')) { if (fieldName.toLocaleUpperCase().endsWith('ID')) {
value = String(faker.number.int()); value = String(faker.number.int());
} }
// email 处理 // Email processing
if (fieldName.includes('Email')) { if (fieldName.includes('Email')) {
value = `${faker.person.lastName()}@foo.com`; value = `${faker.person.lastName()}@foo.com`;
} }
// 直接映射值 // direct mapping value
value = StrMapper[fieldName] || value; value = StrMapper[fieldName] || value;
} }
ctx.output = t.stringLiteral(value); ctx.output = t.stringLiteral(value);
@ -76,20 +76,20 @@ export class MockPlugin implements IPlugin {
const { fieldDefinition } = context; const { fieldDefinition } = context;
const fieldName = fieldDefinition.name.value; const fieldName = fieldDefinition.name.value;
const formatName = fieldName.toLocaleUpperCase(); const formatName = fieldName.toLocaleUpperCase();
// 各类 ID // various types of ID
if (formatName.endsWith('ID')) { if (formatName.endsWith('ID')) {
value = faker.number.int(); value = faker.number.int();
} }
// 时间戳 // timestamp
if (formatName.endsWith('TIME') || formatName.includes('TIMESTAMP')) { if (formatName.endsWith('TIME') || formatName.includes('TIMESTAMP')) {
value = dayjs(faker.date.anytime()).valueOf(); value = dayjs(faker.date.anytime()).valueOf();
} }
// 类型状态 // type state
if (formatName.endsWith('STATUS') || formatName.includes('TYPE')) { if (formatName.endsWith('STATUS') || formatName.includes('TYPE')) {
value = faker.number.int({ min: 0, max: 1 }); value = faker.number.int({ min: 0, max: 1 });
} }
// 直接映射值 // direct mapping value
const mapVal = NumMapper[fieldName]; const mapVal = NumMapper[fieldName];
value = typeof mapVal !== 'undefined' ? mapVal : value; value = typeof mapVal !== 'undefined' ? mapVal : value;
} }

View File

@ -17,27 +17,27 @@
import { type IPlugin } from '@coze-arch/idl2ts-generator'; import { type IPlugin } from '@coze-arch/idl2ts-generator';
export interface ApiConfig { export interface ApiConfig {
// idl 入口 // IDL entrance
entries: Record<string, string>; entries: Record<string, string>;
// idl 根目录 // IDL root directory
idlRoot: string; idlRoot: string;
// 服务别名 // service alias
// 自定义 api 方法 // Custom API method
commonCodePath: string; commonCodePath: string;
// api 产物目录 // API Product Catalog
output: string; output: string;
// 仓库信息设置 // Warehouse information settings
repository?: { repository?: {
// 仓库地址 // Warehouse address
url: string; url: string;
// clone 到本地的位置 // Clone to local location
dest: string; dest: string;
}; };
// 插件 // plugin
plugins?: IPlugin[]; plugins?: IPlugin[];
// 聚合导出的文件名 // aggregate exported filename
aggregationExport?: string; aggregationExport?: string;
// 格式化文件 // Format file
formatter: (name: string, content: string) => string; formatter: (name: string, content: string) => string;
idlFetchConfig?: { idlFetchConfig?: {
source: string; source: string;
@ -48,6 +48,6 @@ export interface ApiConfig {
} }
export interface ApiTypeConfig extends ApiConfig { export interface ApiTypeConfig extends ApiConfig {
// 需要过滤的方法 // Methods that require filtering
filters: Record<string, string[]>; filters: Record<string, string[]>;
} }

View File

@ -163,7 +163,7 @@ export class ClientGenerator {
private processIdlAst(ast: IParseResultItem) { private processIdlAst(ast: IParseResultItem) {
try { try {
// 新的解析器貌似不是按原来位置排序的,这里要重新排序 // The new parser doesn't seem to be sorted by the original position, so it needs to be reordered here.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
ast.statements.sort((a, b) => a.loc!.start.line - b.loc!.start.line); ast.statements.sort((a, b) => a.loc!.start.line - b.loc!.start.line);
} catch (error) { } catch (error) {

View File

@ -139,14 +139,14 @@ export class AdapterPlugin implements IPlugin {
getAnnotation(f.annotations, 'api.converter') === 'atoi_comp_empty' getAnnotation(f.annotations, 'api.converter') === 'atoi_comp_empty'
) { ) {
if (isInt(f.fieldType)) { if (isInt(f.fieldType)) {
// 类型转换为 string // Type conversion to string
f.fieldType.type = SyntaxType.StringKeyword; f.fieldType.type = SyntaxType.StringKeyword;
} }
} }
// api.converter 对 int 以及 map 类型生效 // Api.converter works for int and map types
if (getAnnotation(f.annotations, 'api.converter') === 'itoa') { if (getAnnotation(f.annotations, 'api.converter') === 'itoa') {
if (isInt(f.fieldType)) { if (isInt(f.fieldType)) {
// 类型转换为 string // Type conversion to string
f.fieldType.type = SyntaxType.StringKeyword; f.fieldType.type = SyntaxType.StringKeyword;
} }
if (isMapType(f.fieldType)) { if (isMapType(f.fieldType)) {
@ -156,7 +156,7 @@ export class AdapterPlugin implements IPlugin {
} }
} }
} }
// item_converter 对 list 类型生效 // item_converter for list types
if ( if (
['atoi_comp_empty', 'itoa'].includes( ['atoi_comp_empty', 'itoa'].includes(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
@ -168,24 +168,24 @@ export class AdapterPlugin implements IPlugin {
} }
} }
// 收集 decode encode 注解处理 // Collection decoding encoding annotation processing
if (getTypeFromDynamicJsonAnnotation(f.annotations)) { if (getTypeFromDynamicJsonAnnotation(f.annotations)) {
decodeEncodeFields.push(f.name.value); decodeEncodeFields.push(f.name.value);
} }
// api.json 注解处理 // api.json annotation processing
const jsonAnnotation = getAnnotation(f.annotations, 'api.json'); const jsonAnnotation = getAnnotation(f.annotations, 'api.json');
if (jsonAnnotation) { if (jsonAnnotation) {
f.extensionConfig = f.extensionConfig || {}; f.extensionConfig = f.extensionConfig || {};
f.extensionConfig.key = jsonAnnotation; f.extensionConfig.key = jsonAnnotation;
} }
// api.json_string 注解处理 // API. json_string annotation handling
const jsonStrAnnotation = getAnnotation( const jsonStrAnnotation = getAnnotation(
f.annotations, f.annotations,
'api.json_string', 'api.json_string',
); );
if (jsonStrAnnotation) { if (jsonStrAnnotation) {
if (isInt(f.fieldType)) { if (isInt(f.fieldType)) {
// 类型转换为 string // Type conversion to string
f.fieldType.type = SyntaxType.StringKeyword; f.fieldType.type = SyntaxType.StringKeyword;
f.extensionConfig = f.extensionConfig || {}; f.extensionConfig = f.extensionConfig || {};
f.extensionConfig.key = jsonStrAnnotation; f.extensionConfig.key = jsonStrAnnotation;

View File

@ -403,7 +403,7 @@ export class ClientPlugin implements IPlugin {
}); });
const enumAst = t.tsEnumDeclaration(t.identifier(name.value), enumArr); const enumAst = t.tsEnumDeclaration(t.identifier(name.value), enumArr);
// 从后向前删除枚举项,避免索引变化影响 // Delete enumeration items from back to front to avoid the impact of index changes
enumItemIndexArray enumItemIndexArray
.sort((a, b) => b - a) .sort((a, b) => b - a)
.forEach(index => { .forEach(index => {

View File

@ -21,7 +21,7 @@ import { type Contexts, HOOK } from '../context';
const MAGIC_COMMENT_KEY = '\n*@magic-comment'; const MAGIC_COMMENT_KEY = '\n*@magic-comment';
// 忽略 struct 中的字段 // Ignore fields in struct
export class CommentFormatPlugin { export class CommentFormatPlugin {
apply(p: Program<Contexts>) { apply(p: Program<Contexts>) {
p.register(after('PARSE_ENTRY'), ctx => { p.register(after('PARSE_ENTRY'), ctx => {

View File

@ -26,7 +26,7 @@ interface IPops {
filter: Filter; filter: Filter;
} }
// 忽略 struct 中的字段 // Ignore fields in struct
export class IgnoreStructFiledPlugin { export class IgnoreStructFiledPlugin {
private filter: Filter; private filter: Filter;
constructor({ filter }: IPops) { constructor({ filter }: IPops) {

View File

@ -56,7 +56,7 @@ export class MetaPlugin implements IPlugin {
ctx => { ctx => {
const node = ctx.node as ServiceDefinition; const node = ctx.node as ServiceDefinition;
node.functions.forEach(fun => { node.functions.forEach(fun => {
// 过滤非泛化接口 // Filtering non-generalized interfaces
if (!fun.extensionConfig?.method) { if (!fun.extensionConfig?.method) {
return; return;
} }
@ -103,7 +103,7 @@ export class MetaPlugin implements IPlugin {
schemaRoot: getSchemaRootByPath(ast.idlPath, this.options.idlRoot), schemaRoot: getSchemaRootByPath(ast.idlPath, this.options.idlRoot),
service, service,
} as IMeta; } as IMeta;
// 不是 json 时,需要加上 serializer 标识 // When not json, you need to add the serializer flag.
if (extensionConfig?.serializer && extensionConfig?.serializer !== 'json') { if (extensionConfig?.serializer && extensionConfig?.serializer !== 'json') {
res.serializer = extensionConfig?.serializer; res.serializer = extensionConfig?.serializer;
} }
@ -117,7 +117,7 @@ export class MetaPlugin implements IPlugin {
if (isStructDefinition(statement)) { if (isStructDefinition(statement)) {
const wholeBody = statement.fields.find(isFullBody); const wholeBody = statement.fields.find(isFullBody);
if (wholeBody) { if (wholeBody) {
// 处理 api.body="." 以及 api.full_body='' // Handle api.body = "." and api.full_body = "
return `${id.value}['${getFieldsAlias(wholeBody)}']`; return `${id.value}['${getFieldsAlias(wholeBody)}']`;
} else { } else {
return id.value; return id.value;
@ -184,7 +184,7 @@ export class MetaPlugin implements IPlugin {
} }
}); });
} }
// 如果没有指定根据method默认指定为query 或者 body // If not specified, it is specified as query or body by default according to method.
if (!specificPositionFiled.has(alias)) { if (!specificPositionFiled.has(alias)) {
const filedMapping = mapping[defaultPosition]; const filedMapping = mapping[defaultPosition];
mapping[defaultPosition] = filedMapping mapping[defaultPosition] = filedMapping

View File

@ -110,7 +110,7 @@ export class MockTransformerPlugin implements IPlugin {
nextOrder[name] = index; nextOrder[name] = index;
} }
}); });
// 按照 mock 文件中的顺序优先排序 // Prioritize in order in the mock file
const getOrder = (name: string) => const getOrder = (name: string) =>
typeof mockVarOrder[name] !== 'undefined' typeof mockVarOrder[name] !== 'undefined'
? mockVarOrder[name] ? mockVarOrder[name]
@ -210,7 +210,7 @@ export class MockTransformerPlugin implements IPlugin {
if (isStructDefinition(statement)) { if (isStructDefinition(statement)) {
const wholeBody = statement.fields.find(isFullBody); const wholeBody = statement.fields.find(isFullBody);
if (wholeBody) { if (wholeBody) {
// 处理 api.body="." // Processing api.body = "."
const { annotations } = wholeBody; const { annotations } = wholeBody;
if (hasDynamicJsonAnnotation(annotations)) { if (hasDynamicJsonAnnotation(annotations)) {
return '{}'; return '{}';
@ -273,7 +273,7 @@ export class MockTransformerPlugin implements IPlugin {
if (!fieldNames.has(fieldName)) { if (!fieldNames.has(fieldName)) {
return; return;
} }
// 没有的,需要重新生成 // No, it needs to be regenerated.
newPros.push( newPros.push(
t.objectProperty( t.objectProperty(
fieldName.includes('-') fieldName.includes('-')
@ -351,11 +351,11 @@ export class MockTransformerPlugin implements IPlugin {
const { valueType } = fieldType; const { valueType } = fieldType;
output = t.arrayExpression([this.processValue(valueType)]); output = t.arrayExpression([this.processValue(valueType)]);
} else if (isSetType(fieldType)) { } else if (isSetType(fieldType)) {
// set 处理成array校验 // Set to array validation
const { valueType } = fieldType; const { valueType } = fieldType;
output = t.arrayExpression([this.processValue(valueType)]); output = t.arrayExpression([this.processValue(valueType)]);
} else if (isIdentifier(fieldType)) { } else if (isIdentifier(fieldType)) {
// 引用类型 // reference type
const { refName, namespace } = parseIdFiledType(fieldType); const { refName, namespace } = parseIdFiledType(fieldType);
if (!namespace) { if (!namespace) {
output = t.callExpression(t.identifier(refName), []); output = t.callExpression(t.identifier(refName), []);
@ -375,7 +375,7 @@ export class MockTransformerPlugin implements IPlugin {
throw new Error(`can not process fieldType : ${fieldType.type}`); throw new Error(`can not process fieldType : ${fieldType.type}`);
} }
private processConst(constVal: ConstValue) { private processConst(constVal: ConstValue) {
// 暂时统一处理成0 // Temporarily unified processing to 0
if (isStringLiteral(constVal)) { if (isStringLiteral(constVal)) {
return t.stringLiteral(constVal.value); return t.stringLiteral(constVal.value);
} }
@ -410,11 +410,11 @@ export class MockTransformerPlugin implements IPlugin {
const comment = { type: 'CommentLine', value: commentValues } as any; const comment = { type: 'CommentLine', value: commentValues } as any;
const target = this.findTarget(name.value, ctx); const target = this.findTarget(name.value, ctx);
if (target) { if (target) {
// 需要更新注释 // Comments need to be updated
// target.trailingComments = [comment]; // target.trailingComments = [comment];
return; return;
} }
// 枚举类型统一处理成常量 // Enumeration types are uniformly processed into constants
const builder = template(`var ${name.value}= () => %%value%% `); const builder = template(`var ${name.value}= () => %%value%% `);
const node = builder({ const node = builder({
value: t.numericLiteral(values[0] || 0), value: t.numericLiteral(values[0] || 0),
@ -437,7 +437,7 @@ export class MockTransformerPlugin implements IPlugin {
// const variableDeclaration = t.addComment( // const variableDeclaration = t.addComment(
// , // ,
// 'leading', // 'leading',
// '暂时对const默认处理为0如有需要请自行重新赋值' // 'Temporarily, the default processing for const is 0, please reassign it yourself if necessary '
// ); // );
return node; return node;
} }

View File

@ -29,7 +29,7 @@ import { type Options } from '../types';
import { type Contexts, HOOK } from '../context'; import { type Contexts, HOOK } from '../context';
/** /**
* api * Provide unified API entry
*/ */
export class PkgEntryPlugin implements IPlugin { export class PkgEntryPlugin implements IPlugin {
private options: Options; private options: Options;
@ -52,7 +52,7 @@ export class PkgEntryPlugin implements IPlugin {
); );
this.funcs.set( this.funcs.set(
relativePath, relativePath,
// 只支持单 service // Only single service supported
meta[0].service, meta[0].service,
); );
return ctx; return ctx;

View File

@ -223,7 +223,7 @@ export class SchemaPlugin implements IPlugin {
}; };
return schema; return schema;
} else if (isSetType(fieldType)) { } else if (isSetType(fieldType)) {
// set 处理成array校验 // Set to array validation
const { valueType } = fieldType; const { valueType } = fieldType;
const schema: ListType = { const schema: ListType = {
type: 'array', type: 'array',
@ -231,7 +231,7 @@ export class SchemaPlugin implements IPlugin {
}; };
return schema; return schema;
} else if (isIdentifier(fieldType)) { } else if (isIdentifier(fieldType)) {
// 引用类型 // reference type
const { refName, namespace } = parseIdFiledType(fieldType); const { refName, namespace } = parseIdFiledType(fieldType);
if (!namespace) { if (!namespace) {
const schema: RefType = { $ref: `#/definitions/${refName}` }; const schema: RefType = { $ref: `#/definitions/${refName}` };
@ -249,7 +249,7 @@ export class SchemaPlugin implements IPlugin {
throw new Error(`can not process fieldType : ${fieldType.type}`); throw new Error(`can not process fieldType : ${fieldType.type}`);
} }
private processConst(constVal: ConstValue) { private processConst(constVal: ConstValue) {
// 暂时统一处理成0 // Temporarily unified processing to 0
const schema = {} as ConstType; const schema = {} as ConstType;
if (isStringLiteral(constVal)) { if (isStringLiteral(constVal)) {
schema.const = constVal.value; schema.const = constVal.value;

View File

@ -29,11 +29,11 @@ export interface Options {
genMock: boolean; genMock: boolean;
genClient: boolean; genClient: boolean;
entryName?: string; entryName?: string;
// createAPI 所在文件路径 // createAPI file path
commonCodePath?: string; commonCodePath?: string;
// decode encode 会丢失类型,这里提供一种方式,业务手动补充上对应的类型 // Decoding encoding will lose the type, here provides a way to manually add the corresponding type
patchTypesOutput?: string; patchTypesOutput?: string;
// patchTypesOutput 的别名patch type 需要使用额外的 pkg 组织时需要提供 // PatchTypesOutput alias, patch type needs to be provided when using additional pkg organization
patchTypesAliasOutput?: string; patchTypesAliasOutput?: string;
} }

View File

@ -42,11 +42,11 @@ export interface IMeta {
type Fields = string[]; type Fields = string[];
export interface IHttpRpcMapping { export interface IHttpRpcMapping {
path?: Fields; // path参数 path?: Fields; // path parameter
query?: Fields; // query参数 query?: Fields; // query parameters
body?: Fields; // body 参数 body?: Fields; // Body parameters
header?: Fields; // header 参数 header?: Fields; // header parameter
status_code?: Fields; // http状态码 status_code?: Fields; // HTTP status code
cookie?: Fields; // cookie cookie?: Fields; // cookie
entire_body?: Fields; entire_body?: Fields;
raw_body?: Fields; raw_body?: Fields;

View File

@ -68,7 +68,7 @@ export function formatCode(code: string, root = '.') {
printWidth: 120, printWidth: 120,
singleQuote: true, singleQuote: true,
}; };
const file = path.resolve(process.cwd(), root, './for-prettier-bug'); // 这里一定要加多一级目录 const file = path.resolve(process.cwd(), root, './for-prettier-bug'); // Be sure to add an extra level catalog here.
const config = prettier.resolveConfig(file, { editorconfig: true }); const config = prettier.resolveConfig(file, { editorconfig: true });
return prettier.format(code, { return prettier.format(code, {
...(config || defaultConfig), ...(config || defaultConfig),
@ -166,7 +166,7 @@ export function parseId(id: string) {
export function uniformNs(ns: string) { export function uniformNs(ns: string) {
if (ReservedKeyWord.includes(ns)) { if (ReservedKeyWord.includes(ns)) {
// 命中保留字,处理为下划线开头 // Hit the reserved word, treated as an underscore
return `_${ns}`; return `_${ns}`;
} }
return ns.replace(/\./g, '_'); return ns.replace(/\./g, '_');
@ -182,7 +182,7 @@ export function getValuesFromEnum(params: h.EnumDefinition) {
if (h.isIntegerLiteral(initializer.value)) { if (h.isIntegerLiteral(initializer.value)) {
currentVal = Number(initializer.value.value); currentVal = Number(initializer.value.value);
} else if (h.isHexLiteral(initializer.value)) { } else if (h.isHexLiteral(initializer.value)) {
// 16进制 // hexadecimal
currentVal = Number(initializer.value.value); currentVal = Number(initializer.value.value);
} }
enumArr.push(currentVal); enumArr.push(currentVal);
@ -322,8 +322,8 @@ export function hasDynamicJsonAnnotation(annotations?: h.Annotations) {
} }
/** /**
* api.(request|response).converter * Parse the real type between the front end and the gateway from api. (request | response).converter.
* 😭 * To be able to come up with these two annotations, this protocol is disgusting😭
* @param annotations * @param annotations
* @returns * @returns
*/ */

View File

@ -42,7 +42,7 @@ export class Program<C extends Ctxs = any> {
} = {}; } = {};
/** /**
* * Load plugin
* @param plugins * @param plugins
*/ */
loadPlugins(plugins: IPlugin[]) { loadPlugins(plugins: IPlugin[]) {
@ -51,10 +51,10 @@ export class Program<C extends Ctxs = any> {
} }
} }
/** /**
* * registration hook
* @param event * @param event name
* @param handler * @param handler hook
* @param priority * @Param priority, the smaller the value, the higher the priority
*/ */
register< register<
K extends keyof C, K extends keyof C,
@ -87,7 +87,7 @@ export class Program<C extends Ctxs = any> {
} }
} }
/** /**
* * trigger event
* @param event * @param event
* @param args * @param args
* @returns * @returns

View File

@ -20,20 +20,20 @@ import type { IMeta, CustomAPIMeta } from './types';
export interface ApiLike<T, K, O = unknown, B extends boolean = false> { export interface ApiLike<T, K, O = unknown, B extends boolean = false> {
(req: T, option?: O extends object ? IOptions & O : IOptions): Promise<K>; (req: T, option?: O extends object ? IOptions & O : IOptions): Promise<K>;
meta: IMeta; meta: IMeta;
/** fork 一份实例,该实例具有可中止请求的能力 */ /** Fork an instance that has the ability to abort requests */
withAbort: () => CancelAbleApi<T, K, O, B>; withAbort: () => CancelAbleApi<T, K, O, B>;
} }
export interface CancelAbleApi<T, K, O = unknown, B extends boolean = false> export interface CancelAbleApi<T, K, O = unknown, B extends boolean = false>
extends ApiLike<T, K, O, B> { extends ApiLike<T, K, O, B> {
// 中止请求 // abort request
abort: () => void; abort: () => void;
// 是否是取消 // Is it cancelled?
isAborted: () => boolean; isAborted: () => boolean;
} }
/** /**
* api * Custom build API method
* @param meta * @param meta
* @param cancelable * @param cancelable
* @param useCustom * @param useCustom
@ -56,7 +56,7 @@ export function createAPI<T extends {}, K, O = unknown, B extends boolean = fals
option = { ...(option || {}), ...customOption }; option = { ...(option || {}), ...customOption };
// 这里可以使用传进来的 req 作为默认映射,减少需要在 customAPI 中,需要手动绑定的情况 // Here, you can use the incoming req as the default mapping to reduce the need for manual binding in the customAPI
if (useCustom) { if (useCustom) {
const mappingKeys: string[] = Object.keys(meta.reqMapping) const mappingKeys: string[] = Object.keys(meta.reqMapping)
.map(key => meta.reqMapping[key]) .map(key => meta.reqMapping[key])
@ -98,12 +98,12 @@ export function createAPI<T extends {}, K, O = unknown, B extends boolean = fals
function abort() { function abort() {
/** /**
* pending abortController.signal abortController.abort() * The reason for adding the pending state here is that the state value of abortController.signal is only controlled by the abortController.abort () method;
* abortController.abort(), abortController.signal.aborted true * No matter whether the request is completed or abnormal, as long as abortController.abort () is called, abortController.signal.aborted must be true.
* aborted * This makes it difficult to determine whether the request is really aborted.
* *
* pending abort() * This is changed to abort () only if the request is pending.
* isAborted === true abort * When isAborted === true, the request exception must be caused by manual abort
*/ */
if (pending === true && cancelable && abortController) { if (pending === true && cancelable && abortController) {
abortController.abort(); abortController.abort();
@ -128,7 +128,7 @@ export function createAPI<T extends {}, K, O = unknown, B extends boolean = fals
} }
/** /**
* 使便 * Some non-generalized interfaces can be built using modified methods to facilitate unified management of interfaces
* @param customAPIMeta * @param customAPIMeta
* @param cancelable * @param cancelable
* @returns * @returns

View File

@ -30,11 +30,11 @@ export interface IMeta {
type Fields = string[]; type Fields = string[];
export interface IHttpRpcMapping { export interface IHttpRpcMapping {
path?: Fields; // path参数 path?: Fields; // path parameter
query?: Fields; // query参数 query?: Fields; // query parameters
body?: Fields; // body 参数 body?: Fields; // Body parameters
header?: Fields; // header 参数 header?: Fields; // header parameter
status_code?: Fields; // http状态码 status_code?: Fields; // HTTP status code
cookie?: Fields; // cookie cookie?: Fields; // cookie
entire_body?: Fields; entire_body?: Fields;
raw_body?: Fields; raw_body?: Fields;

View File

@ -27,22 +27,22 @@ export interface ServiceConfig {
} & Omit<IdlConfig, 'clientFactory'>; } & Omit<IdlConfig, 'clientFactory'>;
} }
export interface IdlConfig { export interface IdlConfig {
// client 工厂方法,要求返回一个 fetchClient 函数,使用 meta 总的信息,可实现灵活的 client 配置 // The client factory method requires a fetchClient function to be returned, which uses the meta total information to achieve flexible client configuration
clientFactory?: ( clientFactory?: (
meta: IMeta, meta: IMeta,
) => (uri: string, init: RequestInit, opt: any) => any; ) => (uri: string, init: RequestInit, opt: any) => any;
// uri 前缀,如果 client 中设置了,这里可以不设置 // URI prefix, if set in client, you can leave it unset here
uriPrefix?: string; uriPrefix?: string;
getParams?: (key: string) => string; getParams?: (key: string) => string;
// 服务级别的配置 // Service level configuration
services?: ServiceConfig; services?: ServiceConfig;
// 开发时,如果本地校验失败,这里可回调,通常是弹 toast // During development, if the local verification fails, it can be called back here, usually by playing toast.
onVerifyReqError?: (message: string, ctx: any) => void; onVerifyReqError?: (message: string, ctx: any) => void;
} }
export interface IOptions { export interface IOptions {
config?: IdlConfig; config?: IdlConfig;
// 透传 request options 的选项 // Passthrough request options
requestOptions?: Record<string, any>; requestOptions?: Record<string, any>;
[key: string]: any; [key: string]: any;
} }
@ -52,7 +52,7 @@ export interface PathPrams<T> {
} }
export function getConfig(service: string, method: string): IdlConfig { export function getConfig(service: string, method: string): IdlConfig {
// 手动注册的配置优先级比全局变量高 // Manually registered configuration takes precedence over global variables
let config: IdlConfig | undefined = configCenter.getConfig(service); let config: IdlConfig | undefined = configCenter.getConfig(service);
if (!config) { if (!config) {
config = {}; config = {};
@ -137,7 +137,7 @@ export function normalizeRequest(
); );
const { uriPrefix = '', clientFactory } = config; const { uriPrefix = '', clientFactory } = config;
if (!clientFactory) { if (!clientFactory) {
// todo 这里考虑给个默认的 client防止某些公共 package 在一些异常情况下使用 // Todo here considers giving a default client to prevent some public packages from being used in some abnormal cases
throw new Error('Lack of clientFactory config'); throw new Error('Lack of clientFactory config');
} }
let uri = uriPrefix + apiUri; let uri = uriPrefix + apiUri;
@ -149,11 +149,11 @@ export function normalizeRequest(
: 'application/json'; : 'application/json';
if (option?.requestOptions?.headers) { if (option?.requestOptions?.headers) {
headers = { ...headers, ...option.requestOptions.headers }; headers = { ...headers, ...option.requestOptions.headers };
// 合并了 header可删除 // Merged headers, can be deleted
delete option.requestOptions.headers; delete option.requestOptions.headers;
} }
if (meta.reqMapping.query && meta.reqMapping.query.length > 0) { if (meta.reqMapping.query && meta.reqMapping.query.length > 0) {
// 这里默认 skipNulls网关后端需要忽略 null // The default here is skipNulls, and the gateway backend needs to ignore null.
uri = `${uri}?${qs.stringify(getValue(req, meta.reqMapping.query), { uri = `${uri}?${qs.stringify(getValue(req, meta.reqMapping.query), {
skipNulls: true, skipNulls: true,
arrayFormat: 'comma', arrayFormat: 'comma',
@ -168,7 +168,7 @@ export function normalizeRequest(
if (meta.reqMapping.entire_body && meta.reqMapping.entire_body.length > 0) { if (meta.reqMapping.entire_body && meta.reqMapping.entire_body.length > 0) {
if (meta.reqMapping.entire_body.length === 1) { if (meta.reqMapping.entire_body.length === 1) {
// 默认处理为 json ,如有其他场景需要支持,后需要再支持 // The default processing is json. If there are other scenarios that need to be supported, they need to be supported later.
requestOption.body = req[meta.reqMapping.entire_body[0]]; requestOption.body = req[meta.reqMapping.entire_body[0]];
} else { } else {
throw new Error('idl invalid entire_body should be only one filed'); throw new Error('idl invalid entire_body should be only one filed');
@ -203,7 +203,7 @@ export function normalizeRequest(
}; };
} }
// 旧版的 ferry 中,即使 idl 没有声明body也需要加一个 空的 body // In the old version of ferry, even if idl does not declare body, you need to add an empty body.
if ( if (
!requestOption.body && !requestOption.body &&
['POST', 'PUT', 'PATCH'].includes( ['POST', 'PUT', 'PATCH'].includes(

View File

@ -89,17 +89,17 @@ describe('PkgRootWebpackPlugin', () => {
new PkgRootWebpackPlugin(customOptions); new PkgRootWebpackPlugin(customOptions);
// 注意Object.assign 中后面的对象会覆盖前面的对象,所以默认配置会覆盖用户配置 // Note: Subsequent objects in Object.assign overwrite the preceding objects, so the default configuration overrides the user configuration
expect(OriginPkgRootWebpackPlugin).toHaveBeenCalledWith({ expect(OriginPkgRootWebpackPlugin).toHaveBeenCalledWith({
customProp: 'customValue', customProp: 'customValue',
root: '@', // 被默认值覆盖 root: '@', // Overwritten by default
packagesDirs: [ packagesDirs: [
'packages/project1', 'packages/project1',
'packages/project2', 'packages/project2',
'apps/app1', 'apps/app1',
'apps/app2', 'apps/app2',
], ],
excludeFolders: [], // 被默认值覆盖 excludeFolders: [], // Overwritten by default
}); });
}); });
@ -110,9 +110,9 @@ describe('PkgRootWebpackPlugin', () => {
new PkgRootWebpackPlugin(customOptions); new PkgRootWebpackPlugin(customOptions);
// Object.assign 的行为:后面的对象会覆盖前面的对象属性 // Object.assign behavior: subsequent objects overwrite previous object properties
expect(OriginPkgRootWebpackPlugin).toHaveBeenCalledWith({ expect(OriginPkgRootWebpackPlugin).toHaveBeenCalledWith({
root: '@', // 被默认值覆盖 root: '@', // Overwritten by default
packagesDirs: [ packagesDirs: [
'packages/project1', 'packages/project1',
'packages/project2', 'packages/project2',
@ -139,7 +139,7 @@ describe('PkgRootWebpackPlugin', () => {
}); });
it('验证所有导出都正确', () => { it('验证所有导出都正确', () => {
// 验证模块导出了正确的类和默认导出 // Verify that the module exported the correct class and the default export
expect(PkgRootWebpackPlugin).toBeDefined(); expect(PkgRootWebpackPlugin).toBeDefined();
expect(typeof PkgRootWebpackPlugin).toBe('function'); expect(typeof PkgRootWebpackPlugin).toBe('function');
}); });
@ -147,7 +147,7 @@ describe('PkgRootWebpackPlugin', () => {
it('应该正确处理 Rush 配置中的项目文件夹', () => { it('应该正确处理 Rush 配置中的项目文件夹', () => {
new PkgRootWebpackPlugin(); new PkgRootWebpackPlugin();
// 验证传递给父类的 packagesDirs 包含所有项目文件夹 // Verify that the packagesDirs passed to the parent class contain all project folders
const call = (OriginPkgRootWebpackPlugin as any).mock.calls[0]; const call = (OriginPkgRootWebpackPlugin as any).mock.calls[0];
const options = call[0]; const options = call[0];
@ -160,10 +160,10 @@ describe('PkgRootWebpackPlugin', () => {
}); });
it('测试插件基本功能正常工作', () => { it('测试插件基本功能正常工作', () => {
// 这个测试验证插件能正常实例化并调用父类构造函数 // This test verifies that the plugin can instantiate and call the parent class constructor normally
new PkgRootWebpackPlugin(); new PkgRootWebpackPlugin();
// 验证确实调用了父类构造函数 // Verify that the parent class constructor is indeed called
expect(OriginPkgRootWebpackPlugin).toHaveBeenCalled(); expect(OriginPkgRootWebpackPlugin).toHaveBeenCalled();
}); });
}); });

View File

@ -38,7 +38,7 @@ class PkgRootWebpackPlugin extends pkg_root_webpack_plugin_origin_1.default {
const mergedOptions = Object.assign({}, options || {}, { const mergedOptions = Object.assign({}, options || {}, {
root: '@', root: '@',
packagesDirs: rushJsonPackagesDir, packagesDirs: rushJsonPackagesDir,
// 排除apps/*,减少处理时间 // Exclude apps/* to reduce processing time
excludeFolders: [], excludeFolders: [],
}); });
super(mergedOptions); super(mergedOptions);

View File

@ -41,7 +41,7 @@ class PkgRootWebpackPlugin extends OriginPkgRootWebpackPlugin {
const mergedOptions = Object.assign({}, options || {}, { const mergedOptions = Object.assign({}, options || {}, {
root: '@', root: '@',
packagesDirs: rushJsonPackagesDir, packagesDirs: rushJsonPackagesDir,
// 排除apps/*,减少处理时间 // Exclude apps/* to reduce processing time
excludeFolders: [], excludeFolders: [],
}); });
super(mergedOptions); super(mergedOptions);

View File

@ -1,79 +1,79 @@
# @coze-arch/monorepo-kits # @coze-arch/monorepo-kits
## 功能概述 /* Function Overview */
`@coze-arch/monorepo-kits` 是一个用于管理 monorepo 项目的工具包,提供了基于 Rush 框架的项目查找、依赖分析和配置管理功能。 /* "@Coze-arch/monorepo-kits" is a toolkit for managing monorepo projects, providing project lookup, dependency analysis, and configuration management capabilities based on the Rush framework. */
## 主要功能模块 /* Main Functional Modules */
### 1. 子包管理 (sub-packages.ts) /* ###1. Subpackage management (sub-packages.ts) */
#### lookupSubPackages(packageName: string): string[] #### lookupSubPackages(packageName: string): string[]
- **功能**: 递归查找指定包的所有子依赖包 /* - ** Function **: Recursively find all child dependencies of the specified package */
- **特性**: 使用缓存机制避免重复计算 /* - ** Features **: Use caching mechanism to avoid double counting */
- **返回**: 所有依赖包的名称数组(去重后) /* - ** Returns **: Array of names of all dependent packages (after deduplicate) */
#### getPackageLocation(packageName: string): string #### getPackageLocation(packageName: string): string
- **功能**: 获取指定包的文件系统路径 /* - ** Function **: Get the file system path of the specified package */
- **返回**: 包的项目文件夹路径 /* - ** return **: the project folder path of the package */
#### getPackageJson(packageName: string): RushConfigurationProject['packageJson'] #### getPackageJson(packageName: string): RushConfigurationProject['packageJson']
- **功能**: 获取指定包的 package.json 配置信息 /* - ** Function **: Get the package.json configuration information of the specified package */
- **返回**: 包的 package.json 对象 /* - ** returns **: package's package.json object */
### 2. Rush 配置管理 (rush-config.ts) /* ###2. Rush configuration management (rush-config.ts) */
#### getRushConfiguration(): RushConfiguration #### getRushConfiguration(): RushConfiguration
- **功能**: 获取 Rush 配置实例 /* - ** Features **: Get Rush Configuration Instance */
- **特性**: 单例模式,首次调用时从默认位置加载配置,后续调用复用实例 /* - ** Features **: Singleton mode, first call loads configuration from default location, subsequent calls reuse instance */
- **返回**: RushConfiguration 对象 /* - ** returns **: RushConfiguration object */
### 3. 项目查找 (lookup.ts) /* ###3. Project lookup (lookup.ts) */
#### lookupTo(to: string): string[] #### lookupTo(to: string): string[]
- **功能**: 查找指定包的直接依赖项 /* - ** Features **: Find direct dependencies of a specified package */
- **参数**: 目标包名称 /* - ** Parameter **: Target package name */
- **返回**: 依赖包名称数组 /* - ** Returns **: Array of dependency package names */
#### lookupFrom(from: string): void #### lookupFrom(from: string): void
- **功能**: 查找从指定包出发的相关信息(当前实现不完整) /* - ** Features **: Find information about outgoing from a specified package (current implementation is incomplete) */
- **参数**: 源包名称 /* - ** parameter **: source package name */
#### lookupOnly(packageName: string): RushConfigurationProject #### lookupOnly(packageName: string): RushConfigurationProject
- **功能**: 查找并返回指定包的项目配置对象 /* - ** Features **: Find and return the project configuration object of the specified package */
- **参数**: 包名称 /* - ** parameter **: package name */
- **返回**: 完整的项目配置对象 /* - ** Return **: complete project configuration object */
## 依赖关系 /* ##dependencies */
- **主要依赖**: `@rushstack/rush-sdk@5.100.2` /* - ** Major dependencies **: '@rushstack/rush-sdk@5.100.2' */
- **开发依赖**: 包含 ESLint、TypeScript、Vitest 等工具链 /* - ** Development dependencies **: Includes ESLint, TypeScript, Vitest and other toolchains */
## 使用场景 /* ##usage scenario */
1. **依赖分析**: 分析 monorepo 中包之间的依赖关系 /* 1. ** Dependency Analysis **: Analyze the dependencies between packages in Monorepo */
2. **路径解析**: 获取包在文件系统中的实际位置 /* 2. ** Path parsing **: Get the actual location of the package in the file system */
3. **配置查询**: 查询包的配置信息和元数据 /* 3. ** Configuration query **: Query the configuration information and metadata of the package */
4. **自动化工具**: 为构建脚本、部署工具等提供 monorepo 项目信息 /* 4. ** Automation Tools **: Provide monorepo project information for build scripts, deployment tools, etc */
## 架构特点 /* ##Architecture Features */
- **缓存优化**: 对递归依赖查找进行缓存,提高性能 /* - ** Cache optimization **: Cache recursive dependency lookups to improve performance */
- **错误处理**: 包含完善的包不存在异常处理 /* - ** Error Handling **: Includes perfect package without exception handling */
- **单例模式**: Rush 配置采用单例模式,避免重复加载 /* - ** Singleton mode **: Rush configuration adopts singleton mode to avoid repeated loading */
- **类型安全**: 基于 TypeScript提供完整的类型定义 /* Type safety: Based on TypeScript, complete type definition is provided */
## 代码结构 /* ##Code structure */
``` ```
src/ src/
├── index.ts # 主入口文件,导出所有公共 API /* < unk > ─ index.ts #Main entry file, export all public APIs */
├── sub-packages.ts # 子包管理和依赖查找功能 /* < unk > ─ Sub-packages.ts #Subpackage management and dependency lookup function */
├── rush-config.ts # Rush 配置管理 /* 🥰 ─ rush-config.ts #Rush configuration management */
└── lookup.ts # 项目查找相关功能 /* 🥰 ─ ─ lookup.ts #Project lookup related functions */
``` ```
## API 导出 /* ##API export */
```typescript ```typescript
export { export {
@ -87,4 +87,4 @@ export { getRushConfiguration } from './rush-config';
export { lookupTo, lookupFrom, lookupOnly } from './lookup'; export { lookupTo, lookupFrom, lookupOnly } from './lookup';
``` ```
这个工具包为 monorepo 环境下的包管理、依赖分析和自动化工具开发提供了基础支持。 /* This toolkit provides fundamental support for package management, dependency analysis, and automated tool development in Monorepo environments. */

View File

@ -80,5 +80,5 @@ const logger = new Logger();
export { logger }; export { logger };
/** @deprecated 该使用方式已废弃,请使用`import { logger } from '@coze-arch/rush-logger' */ /** @Deprecated This usage is deprecated, please use'import {logger} from '@code-arch/rush-logger' */
export default logger; export default logger;

View File

@ -22,7 +22,7 @@ import { I18n } from '@coze-arch/i18n';
import { UIModal } from '@coze-arch/bot-semi'; import { UIModal } from '@coze-arch/bot-semi';
import { useResetLocationState } from '@coze-arch/bot-hooks'; import { useResetLocationState } from '@coze-arch/bot-hooks';
// 三方授权失败callback至发布页需要显式阻塞弹窗 // Tripartite authorization failed, callback to the release page needs to explicitly block the pop-up window
export const useAuthFail = () => { export const useAuthFail = () => {
const { state } = useLocation(); const { state } = useLocation();
const { authFailMessage = '', authStatus } = (state ?? const { authFailMessage = '', authStatus } = (state ??

View File

@ -41,7 +41,7 @@ const DEFAULT_BOT_INFO: PublisherBotInfo = {
prompt: '', prompt: '',
}; };
// 获取plugin收费插件信息 // Get plugin charging plugin information
const getPricingRules: ( const getPricingRules: (
pluginApiDetailMap?: Record<string | number, PluginAPIDetal>, pluginApiDetailMap?: Record<string | number, PluginAPIDetal>,
) => Promise<PluginPricingRule[] | undefined> = async pluginApiDetailMap => { ) => Promise<PluginPricingRule[] | undefined> = async pluginApiDetailMap => {
@ -58,7 +58,7 @@ const getPricingRules: (
return pricing_rules; return pricing_rules;
}; };
// 是否有plugin // Is there a plugin?
const hasPluginApi: ( const hasPluginApi: (
pluginApiDetailMap?: Record<string | number, PluginAPIDetal>, pluginApiDetailMap?: Record<string | number, PluginAPIDetal>,
) => boolean = pluginApiDetailMap => ) => boolean = pluginApiDetailMap =>
@ -113,7 +113,7 @@ export const useGetPublisherInitInfo: () => {
bot_option_data, bot_option_data,
} = botInfoResp?.data ?? {}; } = botInfoResp?.data ?? {};
// 获取plugin扣费信息 // Get plugin deduction information
let pluginPricingRules: Array<PluginPricingRule> = []; let pluginPricingRules: Array<PluginPricingRule> = [];
if ( if (
hasPluginApi(bot_option_data?.plugin_api_detail_map) && hasPluginApi(bot_option_data?.plugin_api_detail_map) &&

View File

@ -126,7 +126,7 @@ export const AgentPublishPage = () => {
const publishBtn = ( const publishBtn = (
<UIButton <UIButton
theme="solid" theme="solid"
//解决异步请求botInfo未返回时可以点击publish产生的错误 //Resolve the error caused by clicking publish when the asynchronous request botInfo is not returned
disabled={Boolean(publishDisabled) || !botInfo.name} disabled={Boolean(publishDisabled) || !botInfo.name}
loading={publishLoading} loading={publishLoading}
onClick={handlePublish} onClick={handlePublish}

View File

@ -51,7 +51,7 @@ import { PublishResultArea } from './component/publish-result-area';
import styles from '../index.module.less'; import styles from '../index.module.less';
interface PublishResultProps { interface PublishResultProps {
// 隐藏Banner // Hidden Banner
hiddenBanner?: boolean; hiddenBanner?: boolean;
publishResult?: PublishResultInfo; publishResult?: PublishResultInfo;
} }
@ -212,7 +212,7 @@ export const PublishResult = ({
? `⚠️ ${I18n.t('publish_result_all_failed')}` ? `⚠️ ${I18n.t('publish_result_all_failed')}`
: `🎉 ${I18n.t('publish_success')}`} : `🎉 ${I18n.t('publish_success')}`}
</div> </div>
{/* 开源版暂不支持该功能 */} {/* The open-source version does not currently support this function */}
{IS_OVERSEA && !publishResult?.monetizeConfigSuccess ? ( {IS_OVERSEA && !publishResult?.monetizeConfigSuccess ? (
<div className="mt-[12px] flex items-center gap-[8px] coz-fg-primary"> <div className="mt-[12px] flex items-center gap-[8px] coz-fg-primary">
<IconCozInfoCircleFill className="coz-fg-hglt-yellow" /> <IconCozInfoCircleFill className="coz-fg-hglt-yellow" />
@ -221,7 +221,7 @@ export const PublishResult = ({
</span> </span>
</div> </div>
) : null} ) : null}
{/* 开源版暂不支持该功能 */} {/* The open-source version does not currently support this function */}
{FLAGS['bot.studio.publish_management'] && !IS_OPEN_SOURCE ? ( {FLAGS['bot.studio.publish_management'] && !IS_OPEN_SOURCE ? (
<div className="coz-fg-dim text-[12px]"> <div className="coz-fg-dim text-[12px]">
{I18n.t('release_management_detail1', { {I18n.t('release_management_detail1', {

View File

@ -100,8 +100,8 @@ export const PublishConnectorAction: React.FC<ActionColumnProps> = ({
const action = (() => { const action = (() => {
switch (record.bind_type) { switch (record.bind_type) {
case BindType.KvBind: //仅绑定 case BindType.KvBind: //bind only
case BindType.KvAuthBind: //绑定+授权,取消绑定后自动取消授权 case BindType.KvAuthBind: //Bind + authorization, automatically cancel the authorization after unbinding
return ( return (
<KvBindButton <KvBindButton
record={record} record={record}
@ -181,7 +181,7 @@ export const ConfigStatusColumn: React.FC<ActionColumnProps> = props => {
tagProps={{ tagProps={{
color, color,
style: { margin: 0 }, style: { margin: 0 },
// 覆盖原来的orange-tag // Overwrite the original orange-tag.
className: styles['common-tag'], className: styles['common-tag'],
}} }}
/> />

View File

@ -96,7 +96,7 @@ export const StoreBind: React.FC<StoreBindProps> = ({
setSourceConfig(true); setSourceConfig(true);
} else { } else {
setSourceConfig(false); setSourceConfig(false);
// 兜底逻辑:如果出错,或不在白名单中,则自动更改为“私有配置”发布 // Fallback logic: if there is an error, or it is not in the whitelist, it is automatically changed to "private configuration" publishing
handleSelect('open_source', BotSubmitStatus.Private); handleSelect('open_source', BotSubmitStatus.Private);
} }
}, },
@ -107,7 +107,7 @@ export const StoreBind: React.FC<StoreBindProps> = ({
async () => { async () => {
const res = await ProductApi.PublicGetProductCategoryList( const res = await ProductApi.PublicGetProductCategoryList(
{ {
// 代表含义:无商品也返回类型,即为全量的类型 // Representative meaning: no goods also return the type, that is, the type of the full amount
need_empty_category: true, need_empty_category: true,
entity_type: ProductEntityType.Bot, entity_type: ProductEntityType.Bot,
}, },

View File

@ -20,7 +20,7 @@ import { useEffect } from 'react';
import { AuthStatus } from '@coze-arch/idl/developer_api'; import { AuthStatus } from '@coze-arch/idl/developer_api';
import { useResetLocationState } from '@coze-arch/bot-hooks'; import { useResetLocationState } from '@coze-arch/bot-hooks';
// 三方授权成功,调用成功回调 // The three-party authorization is successful, and the callback is successful.
export const useAuthSuccess = (bindSuccess: (id: string) => void) => { export const useAuthSuccess = (bindSuccess: (id: string) => void) => {
const { state } = useLocation(); const { state } = useLocation();
const { oauth2, authStatus } = (state ?? history.state ?? {}) as Record< const { oauth2, authStatus } = (state ?? history.state ?? {}) as Record<

View File

@ -103,7 +103,7 @@ const getCheckboxProps = (record: PublishConnectorInfo, disabled: boolean) => {
return { return {
disabled: !!disableTip || disabled, disabled: !!disableTip || disabled,
id: record.id, id: record.id,
// Offline状态没有tooltip // Offline status No tooltip
children: disableTip ? ( children: disableTip ? (
<Tooltip content={disableTip}> <Tooltip content={disableTip}>
<span className={styles['disable-tooltip']} /> <span className={styles['disable-tooltip']} />
@ -152,7 +152,7 @@ export const TableCollection = (props: PublishTableProps) => {
[dataSourceForChannel, connectorBrandInfoMap], [dataSourceForChannel, connectorBrandInfoMap],
); );
// 无全选按钮因此所有表格使用相同check配置 // There is no select all button, so all tables use the same check configuration
const baseConfigForChecker = { const baseConfigForChecker = {
hidden: true, hidden: true,
fixed: 'left' as const, fixed: 'left' as const,
@ -212,9 +212,9 @@ export const TableCollection = (props: PublishTableProps) => {
: [record.id, ...ids], : [record.id, ...ids],
); );
} }
}, // 点击行选中 }, // Click on the line to select
onMouseEnter: () => onMouseEnter(record), // 鼠标移入行 onMouseEnter: () => onMouseEnter(record), // mouseover
onMouseLeave: () => onMouseLeave(record), // 鼠标移出行 onMouseLeave: () => onMouseLeave(record), // mouse movement
}); });
const tableCommonProps = { const tableCommonProps = {
className: classNames(styles['publish-table']), className: classNames(styles['publish-table']),
@ -285,7 +285,7 @@ function TableTittleExtra({
platforms: PublishConnectorInfo[]; platforms: PublishConnectorInfo[];
botInfo: PublisherBotInfo; botInfo: PublisherBotInfo;
}) { }) {
// 付费墙 // paywall
const isAvailable = useBenefitAvailable({ const isAvailable = useBenefitAvailable({
scene: PremiumPaywallScene.API, scene: PremiumPaywallScene.API,
}); });

View File

@ -24,7 +24,7 @@ import { I18n } from '@coze-arch/i18n';
import { Typography } from '@coze-arch/coze-design'; import { Typography } from '@coze-arch/coze-design';
import { type PluginPricingRule } from '@coze-arch/bot-api/plugin_develop'; import { type PluginPricingRule } from '@coze-arch/bot-api/plugin_develop';
// 发布页提示 // release page tip
export const PluginPricingInfo: FC<{ export const PluginPricingInfo: FC<{
pluginPricingRules?: Array<PluginPricingRule>; pluginPricingRules?: Array<PluginPricingRule>;
}> = ({ pluginPricingRules }) => { }> = ({ pluginPricingRules }) => {

View File

@ -32,7 +32,7 @@ export function SingleAgentModelView(props: SingleAgentModelViewProps) {
<SingleAgentModelViewBase <SingleAgentModelViewBase
{...props} {...props}
triggerRender={m => ( triggerRender={m => (
// 模型临期时强制完整展示临期提示 // Forced full display of Advent prompts during model Advent
<Collapsible <Collapsible
itemKey={itemKey} itemKey={itemKey}
fullContent={ fullContent={

View File

@ -21,7 +21,7 @@ export function isValidUrl(url: string): boolean {
// cp-disable-next-line // cp-disable-next-line
const urlObject = new URL(`https://${url}`); const urlObject = new URL(`https://${url}`);
return DOMAIN_REGEXP.test(urlObject.hostname); return DOMAIN_REGEXP.test(urlObject.hostname);
// eslint-disable-next-line @coze-arch/use-error-in-catch -- 根据函数功能无需 throw error // eslint-disable-next-line @coze-arch/use-error-in-catch -- no need to throw error according to function function
} catch { } catch {
return false; return false;
} }

View File

@ -35,8 +35,8 @@ const getDefaultState = (): DraftBotDataSetStoreState => ({
datasetsMap: {}, datasetsMap: {},
}); });
// 目前 work_info 里的 dataset 只包含了很少量的元信息, // At present, the dataset in the work_info contains only a small amount of meta information.
// 为了方便判断引入的 dataset 类型(用于分组、模型能力检查等等),这里统一缓存当下使用的 dataset // In order to facilitate the determination of the type of dataset introduced (for grouping, model capability checking, etc.), the dataset currently in use is cached here
export const createDraftBotDatasetsStore = () => export const createDraftBotDatasetsStore = () =>
create<DraftBotDataSetStoreState & DraftBotDataSetStoreAction>()( create<DraftBotDataSetStoreState & DraftBotDataSetStoreAction>()(
devtools( devtools(

View File

@ -19,7 +19,7 @@ import { create } from 'zustand';
import { produce } from 'immer'; import { produce } from 'immer';
export interface FreeGrabModalHierarchyState { export interface FreeGrabModalHierarchyState {
// modal 的 key list // Modal key list
modalHierarchyList: string[]; modalHierarchyList: string[];
} }
@ -31,7 +31,7 @@ export interface FreeGrabModalHierarchyAction {
} }
/** /**
* * Hierarchical relationship between pop-ups that can be dragged and dropped freely
*/ */
export const createFreeGrabModalHierarchyStore = () => export const createFreeGrabModalHierarchyStore = () =>
create<FreeGrabModalHierarchyState & FreeGrabModalHierarchyAction>()( create<FreeGrabModalHierarchyState & FreeGrabModalHierarchyAction>()(

View File

@ -24,15 +24,15 @@ import { type ModelPresetValues } from './type';
import { getModelPresetValues } from './helpers/get-model-preset-values'; import { getModelPresetValues } from './helpers/get-model-preset-values';
export interface ModelState { export interface ModelState {
// 当前环境所有合法的模型列表 // List of all valid models in the current environment
onlineModelList: Model[]; onlineModelList: Model[];
/* key === modelId /* Special models that do not belong to the current environment key === modelId
* 例如: cn-inhouse GPT , cn-release, bot = + 1(GPT) * For example: select the GPT model in cn-inhouse, then switch to cn-release, the current bot model list = normal model list + 1 special model (GPT)
* MultiAgent , Agent = + 1() * In MultiAgent mode, each Agent model list = normal model list + 1 special model (may exist)
* , * After switching from the special model to the normal model, it is not allowed to switch back to the special model
*/ */
offlineModelMap: Record<string, Model>; offlineModelMap: Record<string, Model>;
// 纯计算属性, 由 specialModel 和 baseModel 计算而来 key === modelId // Pure computational properties, calculated from specialModel and baseModel key === modelId
// key === modelId // key === modelId
modelPresetValuesMap: Record<string, ModelPresetValues>; modelPresetValuesMap: Record<string, ModelPresetValues>;
} }

View File

@ -37,7 +37,7 @@ export interface OnboardingDirtyLogicCompatibilityAction {
} }
/** /**
* bot onboarding * Complex, dirty business logic for handling bot edit page onboarding
*/ */
export const createOnboardingDirtyLogicCompatibilityStore = () => export const createOnboardingDirtyLogicCompatibilityStore = () =>
create< create<

View File

@ -32,7 +32,7 @@ export type TGetModelCapabilityConfig = (params: {
getModelById: (id: string) => Model | undefined; getModelById: (id: string) => Model | undefined;
}) => ModelCapabilityConfig; }) => ModelCapabilityConfig;
// 模型能力配置的 fallback没有配置的能力按支持处理 // Fallback of model capability configuration, capability without configuration is handled as supported
export const defaultModelCapConfig = Object.values(ModelFuncConfigType).reduce( export const defaultModelCapConfig = Object.values(ModelFuncConfigType).reduce(
(res, type) => ({ (res, type) => ({
...res, ...res,
@ -56,7 +56,7 @@ const mergeModelCapabilityConfig = (
target target
? Object.entries(target).reduce<ModelCapabilityConfig>( ? Object.entries(target).reduce<ModelCapabilityConfig>(
(merged, [key, status]) => { (merged, [key, status]) => {
// 未配置的能力视为完全支持 // Unconfigured capabilities are considered fully supported
const [preStatus, preName] = merged[ const [preStatus, preName] = merged[
key as unknown as ModelFuncConfigType key as unknown as ModelFuncConfigType
] ?? [ModelFuncConfigStatus.FullSupport, []]; ] ?? [ModelFuncConfigStatus.FullSupport, []];

View File

@ -41,7 +41,7 @@ export function convertModelValueType(
return Number(value); return Number(value);
} }
// 理论上不走这里 // Theoretically not going here
primitiveExhaustiveCheck(type); primitiveExhaustiveCheck(type);
return value; return value;
} }

View File

@ -22,13 +22,13 @@ import {
} from '../src/services/type'; } from '../src/services/type';
import { BotInputLengthService, botInputLengthService } from '../src/services'; import { BotInputLengthService, botInputLengthService } from '../src/services';
// 模拟 SuggestedQuestionsShowMode 枚举 // Analog SuggestedQuestionsShowMode Enumeration
enum SuggestedQuestionsShowMode { enum SuggestedQuestionsShowMode {
Random = 0, Random = 0,
All = 1, All = 1,
} }
// 模拟配置 // simulation configuration
const mockConfig: BotInputLengthConfig = { const mockConfig: BotInputLengthConfig = {
botName: 10, botName: 10,
botDescription: 100, botDescription: 100,
@ -39,16 +39,16 @@ const mockConfig: BotInputLengthConfig = {
projectDescription: 100, projectDescription: 100,
}; };
// 模拟获取配置的函数 // Function to simulate acquisition configuration
const mockGetConfig = vi.fn().mockReturnValue(mockConfig); const mockGetConfig = vi.fn().mockReturnValue(mockConfig);
describe('BotInputLengthService', () => { describe('BotInputLengthService', () => {
let service: BotInputLengthService; let service: BotInputLengthService;
beforeEach(() => { beforeEach(() => {
// 重置模拟 // Reset simulation
vi.clearAllMocks(); vi.clearAllMocks();
// 创建服务实例 // Create a service instance
service = new BotInputLengthService(mockGetConfig); service = new BotInputLengthService(mockGetConfig);
}); });
@ -62,23 +62,23 @@ describe('BotInputLengthService', () => {
expect(service.getInputLengthLimit('projectName')).toBe(10); expect(service.getInputLengthLimit('projectName')).toBe(10);
expect(service.getInputLengthLimit('projectDescription')).toBe(100); expect(service.getInputLengthLimit('projectDescription')).toBe(100);
// 验证配置获取函数被调用 // Verify that the configuration get function is called
expect(mockGetConfig).toHaveBeenCalledTimes(7); expect(mockGetConfig).toHaveBeenCalledTimes(7);
}); });
}); });
describe('getValueLength', () => { describe('getValueLength', () => {
it('应该返回字符串的字形簇数量', () => { it('应该返回字符串的字形簇数量', () => {
// 普通字符串 // Normal string
expect(service.getValueLength('hello')).toBe(5); expect(service.getValueLength('hello')).toBe(5);
// 包含表情符号的字符串(表情符号算作一个字形簇) // A string containing the emoji (the emoji counts as a glyph cluster)
expect(service.getValueLength('hi😊')).toBe(3); expect(service.getValueLength('hi😊')).toBe(3);
// 包含组合字符的字符串 // A string containing combined characters
expect(service.getValueLength('café')).toBe(4); expect(service.getValueLength('café')).toBe(4);
// 空字符串 // empty string
expect(service.getValueLength('')).toBe(0); expect(service.getValueLength('')).toBe(0);
// undefined // undefined
@ -88,12 +88,12 @@ describe('BotInputLengthService', () => {
describe('sliceStringByMaxLength', () => { describe('sliceStringByMaxLength', () => {
it('应该根据字段限制截取字符串', () => { it('应该根据字段限制截取字符串', () => {
// 字符串长度小于限制 // String length less than limit
expect( expect(
service.sliceStringByMaxLength({ value: 'hello', field: 'botName' }), service.sliceStringByMaxLength({ value: 'hello', field: 'botName' }),
).toBe('hello'); ).toBe('hello');
// 字符串长度等于限制 // String length equals limit
expect( expect(
service.sliceStringByMaxLength({ service.sliceStringByMaxLength({
value: '1234567890', value: '1234567890',
@ -101,7 +101,7 @@ describe('BotInputLengthService', () => {
}), }),
).toBe('1234567890'); ).toBe('1234567890');
// 字符串长度大于限制 // String length is greater than limit
expect( expect(
service.sliceStringByMaxLength({ service.sliceStringByMaxLength({
value: '12345678901234567890', value: '12345678901234567890',
@ -109,7 +109,7 @@ describe('BotInputLengthService', () => {
}), }),
).toBe('1234567890'); ).toBe('1234567890');
// 包含表情符号的字符串 // A string containing emoji
expect( expect(
service.sliceStringByMaxLength({ service.sliceStringByMaxLength({
value: 'hello😊world', value: 'hello😊world',
@ -117,7 +117,7 @@ describe('BotInputLengthService', () => {
}), }),
).toBe('hello😊worl'); ).toBe('hello😊worl');
// 验证配置获取函数被调用 // Verify that the configuration get function is called
expect(mockGetConfig).toHaveBeenCalledTimes(4); expect(mockGetConfig).toHaveBeenCalledTimes(4);
}); });
}); });
@ -147,13 +147,13 @@ describe('BotInputLengthService', () => {
const result = service.sliceWorkInfoOnboardingByMaxLength(workInfo); const result = service.sliceWorkInfoOnboardingByMaxLength(workInfo);
// 验证开场白被截取 // Verify that the opening statement was intercepted
expect(result.prologue).toBe( expect(result.prologue).toBe(
'This is a very long prologue that exceeds the limi', 'This is a very long prologue that exceeds the limi',
); );
expect(result.prologue.length).toBeLessThanOrEqual(50); expect(result.prologue.length).toBeLessThanOrEqual(50);
// 验证建议问题被截取 // Validation suggestion problem intercepted
expect(result.suggested_questions[0]?.content).toBe( expect(result.suggested_questions[0]?.content).toBe(
'This is a very long ', 'This is a very long ',
); );
@ -175,7 +175,7 @@ describe('BotInputLengthService', () => {
expect(result.suggested_questions[2]?.id).toBe('3'); expect(result.suggested_questions[2]?.id).toBe('3');
expect(result.suggested_questions[2]?.highlight).toBe(false); expect(result.suggested_questions[2]?.highlight).toBe(false);
// 验证显示模式保持不变 // Verify that the display mode remains unchanged
expect(result.suggested_questions_show_mode).toBe( expect(result.suggested_questions_show_mode).toBe(
SuggestedQuestionsShowMode.All, SuggestedQuestionsShowMode.All,
); );
@ -199,10 +199,10 @@ describe('BotInputLengthService', () => {
}); });
}); });
// 测试导出的单例 // Test Exported Singletons
describe('botInputLengthService', () => { describe('botInputLengthService', () => {
it('应该导出一个 BotInputLengthService 的实例', () => { it('应该导出一个 BotInputLengthService 的实例', () => {
// 验证导出的单例是 BotInputLengthService 的实例 // Verify that the exported singleton is an instance of BotInputLengthService
expect(botInputLengthService).toBeInstanceOf(BotInputLengthService); expect(botInputLengthService).toBeInstanceOf(BotInputLengthService);
}); });
}); });

View File

@ -17,19 +17,19 @@
import { type SuggestedQuestionsShowMode } from '@coze-arch/bot-api/playground_api'; import { type SuggestedQuestionsShowMode } from '@coze-arch/bot-api/playground_api';
export interface BotInputLengthConfig { export interface BotInputLengthConfig {
/** Agent 名称的长度 */ /** Length of Agent Name */
botName: number; botName: number;
/** Agent 描述的长度 */ /** Length of Agent Description */
botDescription: number; botDescription: number;
/** Agent 开场白的长度 */ /** Length of Agent's opening statement */
onboarding: number; onboarding: number;
/** Agent 单条开场白建议的长度 */ /** Agent, the length of a single opening line suggestion */
onboardingSuggestion: number; onboardingSuggestion: number;
/** 用户问题建议自定义 prompt 长度 */ /** User question Suggested custom prompt length */
suggestionPrompt: number; suggestionPrompt: number;
/** Project 名称的长度 */ /** Length of Project Name */
projectName: number; projectName: number;
/** Project 描述的长度 */ /** Project Description Length */
projectDescription: number; projectDescription: number;
} }

View File

@ -52,8 +52,8 @@ vi.mock('@coze-arch/bot-tea', () => ({
}, },
ParamsTypeDefine: {}, ParamsTypeDefine: {},
PluginMockDataGenerateMode: { PluginMockDataGenerateMode: {
MANUAL: 0, // 手动创建 MANUAL: 0, // create manually
RANDOM: 1, // 随机生成 RANDOM: 1, // random generation
LLM: 2, LLM: 2,
}, },
})); }));
@ -61,21 +61,21 @@ vi.mock('@coze-arch/bot-tea', () => ({
vi.mock('@coze-arch/bot-hooks', () => ({ vi.mock('@coze-arch/bot-hooks', () => ({
SceneType: { SceneType: {
BOT__VIEW__WORKFLOW: 'botViewWorkflow', BOT__VIEW__WORKFLOW: 'botViewWorkflow',
/** bot 详情页查看 workflow或新建 workflow 但未发布,点击返回 */ /** View the workflow on the bot details page, or create a new workflow but not published, click Return */
WORKFLOW__BACK__BOT: 'workflowBackBot', WORKFLOW__BACK__BOT: 'workflowBackBot',
/** bot 详情页创建 workflow在 workflow 发布后返回 */ /** The bot details page creates a workflow and returns it after the workflow is published */
WORKFLOW_PUBLISHED__BACK__BOT: 'workflowPublishedBackBot', WORKFLOW_PUBLISHED__BACK__BOT: 'workflowPublishedBackBot',
/** bot 详情页进入 mock data 页面 */ /** Bot details page Enter the mock data page */
BOT__TO__PLUGIN_MOCK_DATA: 'botToPluginMockData', BOT__TO__PLUGIN_MOCK_DATA: 'botToPluginMockData',
/** workflow 详情页进入 mock data 页面 */ /** Workflow details page Enter the mock data page */
WORKFLOW__TO__PLUGIN_MOCK_DATA: 'workflowToPluginMockData', WORKFLOW__TO__PLUGIN_MOCK_DATA: 'workflowToPluginMockData',
/** mock set 页进入 mock data 页面 */ /** Mock set page Enter the mock data page */
PLUGIN_MOCK_SET__TO__PLUGIN_MOCK_DATA: 'pluginMockSetToPluginMockData', PLUGIN_MOCK_SET__TO__PLUGIN_MOCK_DATA: 'pluginMockSetToPluginMockData',
/** bot 详情页进入 knowledge 页面 */ /** Bot details page Enter the knowledge page */
BOT__VIEW__KNOWLEDGE: 'botViewKnowledge', BOT__VIEW__KNOWLEDGE: 'botViewKnowledge',
/** knowledge 页面点击退出返回 bot 详情页(未点击添加) */ /** Knowledge page Click Exit to return to bot details page (not clicked Add) */
KNOWLEDGE__BACK__BOT: 'knowledgeBackBot', KNOWLEDGE__BACK__BOT: 'knowledgeBackBot',
/** knowledge 页面点击返回 bot 详情页,并添加到 bot */ /** Knowledge page Click to return to bot details page and add to bot */
KNOWLEDGE__ADD_TO__BOT: 'knowledgeAddToBot', KNOWLEDGE__ADD_TO__BOT: 'knowledgeAddToBot',
}, },
usePageJumpService: vi.fn().mockReturnValue({ usePageJumpService: vi.fn().mockReturnValue({

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
// 引入我们的被测方法 // Introducing our test method
import { describe, expect, it, vi } from 'vitest'; import { describe, expect, it, vi } from 'vitest';
@ -23,39 +23,39 @@ import { getEnv } from '@/util/get-env';
describe('getEnv function', () => { describe('getEnv function', () => {
it('should return "cn-boe" when not in production', () => { it('should return "cn-boe" when not in production', () => {
vi.stubGlobal('IS_PROD', undefined); vi.stubGlobal('IS_PROD', undefined);
// 不设置IS_PROD默认为非生产环境 // Do not set IS_PROD, default to non-production environment
const env = getEnv(); const env = getEnv();
expect(env).toBe('cn-boe'); expect(env).toBe('cn-boe');
}); });
it('should return "cn-release" when in production, not overseas, and is release version', () => { it('should return "cn-release" when in production, not overseas, and is release version', () => {
vi.stubGlobal('IS_PROD', true); // 设置为生产环境 vi.stubGlobal('IS_PROD', true); // Set to production environment
vi.stubGlobal('IS_OVERSEA', false); // 不是海外 vi.stubGlobal('IS_OVERSEA', false); // Not overseas.
vi.stubGlobal('IS_RELEASE_VERSION', true); // 是发布版本 vi.stubGlobal('IS_RELEASE_VERSION', true); // Is the release version
const env = getEnv(); const env = getEnv();
expect(env).toBe('cn-release'); expect(env).toBe('cn-release');
}); });
it('should return "cn-inhouse" when in production, not overseas, and is not release version', () => { it('should return "cn-inhouse" when in production, not overseas, and is not release version', () => {
vi.stubGlobal('IS_PROD', true); // 设置为生产环境 vi.stubGlobal('IS_PROD', true); // Set to production environment
vi.stubGlobal('IS_OVERSEA', false); // 不是海外 vi.stubGlobal('IS_OVERSEA', false); // Not overseas.
vi.stubGlobal('IS_RELEASE_VERSION', false); // 不是发布版本 vi.stubGlobal('IS_RELEASE_VERSION', false); // Not the release version
const env = getEnv(); const env = getEnv();
expect(env).toBe('cn-inhouse'); expect(env).toBe('cn-inhouse');
}); });
it('should return "oversea-release" when in production, overseas, and is release version', () => { it('should return "oversea-release" when in production, overseas, and is release version', () => {
vi.stubGlobal('IS_PROD', true); // 设置为生产环境 vi.stubGlobal('IS_PROD', true); // Set to production environment
vi.stubGlobal('IS_OVERSEA', true); // 是海外 vi.stubGlobal('IS_OVERSEA', true); // Is overseas
vi.stubGlobal('IS_RELEASE_VERSION', true); // 是发布版本 vi.stubGlobal('IS_RELEASE_VERSION', true); // Is the release version
const env = getEnv(); const env = getEnv();
expect(env).toBe('oversea-release'); expect(env).toBe('oversea-release');
}); });
it('should return "oversea-inhouse" when in production, overseas, and is not release version', () => { it('should return "oversea-inhouse" when in production, overseas, and is not release version', () => {
vi.stubGlobal('IS_PROD', true); // 设置为生产环境 vi.stubGlobal('IS_PROD', true); // Set to production environment
vi.stubGlobal('IS_OVERSEA', true); // 是海外 vi.stubGlobal('IS_OVERSEA', true); // Is overseas
vi.stubGlobal('IS_RELEASE_VERSION', false); // 不是发布版本 vi.stubGlobal('IS_RELEASE_VERSION', false); // Not the release version
const env = getEnv(); const env = getEnv();
expect(env).toBe('oversea-inhouse'); expect(env).toBe('oversea-inhouse');
}); });

View File

@ -61,7 +61,7 @@ export const PluginModal: React.FC<PluginModalProps> = ({
return openMode === OpenModeType.OnlyOnceAdd ? [] : pluginApis; return openMode === OpenModeType.OnlyOnceAdd ? [] : pluginApis;
}; };
const { sider, filter, content } = usePluginModalParts({ const { sider, filter, content } = usePluginModalParts({
// 如果是仅添加一次,清空默认选中 // If it is added only once, clear the default selection.
pluginApiList: getPluginApiList(), pluginApiList: getPluginApiList(),
onPluginApiListChange: updateSkillPluginApis, onPluginApiListChange: updateSkillPluginApis,
openMode, openMode,

View File

@ -36,7 +36,7 @@ export const usePluginApisModal = (props?: PluginModalModeProps) => {
const _initQuery = isNumber(params) ? undefined : params?.initQuery; const _initQuery = isNumber(params) ? undefined : params?.initQuery;
setVisible(true); setVisible(true);
setInitQuery(_initQuery); setInitQuery(_initQuery);
// 0 也有效 // 0 is also valid
if (isNumber(openType)) { if (isNumber(openType)) {
setType(openType); setType(openType);
} }

View File

@ -54,17 +54,17 @@ export interface ToolDetailPageProps
onDebugSuccessCallback?: () => void; onDebugSuccessCallback?: () => void;
} }
// 页面-编辑插件API // Page - Edit Plugin API
export const ToolDetailPage: FC<ToolDetailPageProps> = ({ export const ToolDetailPage: FC<ToolDetailPageProps> = ({
toolID, toolID,
onDebugSuccessCallback, onDebugSuccessCallback,
renderDescComponent, renderDescComponent,
renderParamsComponent, renderParamsComponent,
}) => { }) => {
//捕获错误信息,跳转统一落地页 //Capture error messages and jump to the unified landing page
const capture = useErrorHandler(); const capture = useErrorHandler();
const [editVersion, setEditVersion] = useState<number>(); const [editVersion, setEditVersion] = useState<number>();
//插件-API详情 //Plugin-API Details
const [apiInfo, setApiInfo] = useState<PluginAPIInfo>(); const [apiInfo, setApiInfo] = useState<PluginAPIInfo>();
const [debugApiInfo, setDebugApiInfo] = useState<PluginAPIInfo>(); const [debugApiInfo, setDebugApiInfo] = useState<PluginAPIInfo>();
const [loading, setLoading] = useState<boolean>(true); const [loading, setLoading] = useState<boolean>(true);
@ -104,7 +104,7 @@ export const ToolDetailPage: FC<ToolDetailPageProps> = ({
}); });
}; };
// 重置 request 参数 // Reset request parameters
const resetRequestParams = (data: PluginAPIInfo) => { const resetRequestParams = (data: PluginAPIInfo) => {
const requestParams = cloneDeep(data.request_params as APIParameter[]); const requestParams = cloneDeep(data.request_params as APIParameter[]);
if ( if (
@ -120,7 +120,7 @@ export const ToolDetailPage: FC<ToolDetailPageProps> = ({
return requestParams; return requestParams;
}; };
// 设置接口信息(回显和置空) // Set interface information (echo and empty)
const handleInit = async (useloading = false) => { const handleInit = async (useloading = false) => {
setApiInfo({ setApiInfo({
...apiInfo, ...apiInfo,
@ -140,12 +140,12 @@ export const ToolDetailPage: FC<ToolDetailPageProps> = ({
if (api_info.length > 0) { if (api_info.length > 0) {
const apiInfoTemp = api_info.length > 0 ? api_info[0] : {}; const apiInfoTemp = api_info.length > 0 ? api_info[0] : {};
// debug 的数据 如果有 example 需要回显 入参数据额外处理 // Debug data, if there is an example, the imported parameter data needs to be echoed for additional processing
setDebugApiInfo({ setDebugApiInfo({
...apiInfoTemp, ...apiInfoTemp,
request_params: resetRequestParams(apiInfoTemp), request_params: resetRequestParams(apiInfoTemp),
}); });
// 给对象增加层级标识 // Adding hierarchical identifiers to objects
addDepthAndValue(apiInfoTemp.request_params); addDepthAndValue(apiInfoTemp.request_params);
addDepthAndValue(apiInfoTemp.response_params); addDepthAndValue(apiInfoTemp.response_params);
setApiInfo(apiInfoTemp); setApiInfo(apiInfoTemp);
@ -170,7 +170,7 @@ export const ToolDetailPage: FC<ToolDetailPageProps> = ({
useloading && setLoading(false); useloading && setLoading(false);
}; };
// 1.基本信息 // 1. Basic information
const { const {
isBaseInfoDisabled, isBaseInfoDisabled,
header: baseInfoHeader, header: baseInfoHeader,
@ -190,7 +190,7 @@ export const ToolDetailPage: FC<ToolDetailPageProps> = ({
renderDescComponent, renderDescComponent,
}); });
// 2 更多设置 // 2 more settings
const { const {
isBaseMoreDisabled, isBaseMoreDisabled,
header: baseMoreHeader, header: baseMoreHeader,
@ -211,7 +211,7 @@ export const ToolDetailPage: FC<ToolDetailPageProps> = ({
onSuccess: handleSuccess, onSuccess: handleSuccess,
}); });
// 3.设置 request // 3. Set request
const { const {
isRequestParamsDisabled, isRequestParamsDisabled,
itemKey: requestItemKey, itemKey: requestItemKey,
@ -233,7 +233,7 @@ export const ToolDetailPage: FC<ToolDetailPageProps> = ({
renderParamsComponent, renderParamsComponent,
}); });
// 4.设置 response // 4. Set up the response
const { const {
isResponseParamsDisabled, isResponseParamsDisabled,
itemKey: responseItemKey, itemKey: responseItemKey,
@ -298,7 +298,7 @@ export const ToolDetailPage: FC<ToolDetailPageProps> = ({
}; };
}, []); }, []);
// 预览状态解锁,如果有一步为编辑态,则不解锁 // The preview state is unlocked. If there is an edit state, it will not be unlocked.
useUpdateEffect(() => { useUpdateEffect(() => {
if ( if (
!isBaseInfoDisabled || !isBaseInfoDisabled ||

View File

@ -69,7 +69,7 @@ const ToolHeader: FC<ToolHeaderProps> = ({
unlockPlugin(); unlockPlugin();
}; };
// 管理模拟集 // management simulation set
const handleManageMockset = () => { const handleManageMockset = () => {
resourceNavigate.mocksetList?.(tool_id); resourceNavigate.mocksetList?.(tool_id);
}; };
@ -119,7 +119,7 @@ const ToolHeader: FC<ToolHeaderProps> = ({
/> />
<span className={s.title}>{I18n.t('plugin_edit_tool_title')}</span> <span className={s.title}>{I18n.t('plugin_edit_tool_title')}</span>
<OauthButtonAction /> <OauthButtonAction />
{/* 即将支持,敬请期待 */} {/* Support soon, so stay tuned. */}
{FLAGS['bot.devops.plugin_mockset'] ? ( {FLAGS['bot.devops.plugin_mockset'] ? (
<Tooltip <Tooltip
style={{ display: mocksetDisabled ? 'block' : 'none' }} style={{ display: mocksetDisabled ? 'block' : 'none' }}

View File

@ -54,12 +54,12 @@ export const useContentBaseMore = ({
editVersion, editVersion,
onSuccess, onSuccess,
}: UseContentBaseInfoProps) => { }: UseContentBaseInfoProps) => {
// 是否显示安全检查失败信息 // Is the security check failure message displayed?
const [showSecurityCheckFailedMsg, setShowSecurityCheckFailedMsg] = const [showSecurityCheckFailedMsg, setShowSecurityCheckFailedMsg] =
useState(false); useState(false);
const [isBaseMoreDisabled, setIsBaseMoreDisabled] = useState(true); const [isBaseMoreDisabled, setIsBaseMoreDisabled] = useState(true);
// 基本信息 // Basic information
const { baseInfoNode, submitBaseInfo } = useBaseMore({ const { baseInfoNode, submitBaseInfo } = useBaseMore({
pluginId: plugin_id || '', pluginId: plugin_id || '',
pluginMeta: pluginInfo?.meta_info || {}, pluginMeta: pluginInfo?.meta_info || {},
@ -101,7 +101,7 @@ export const useContentBaseMore = ({
onClick={async e => { onClick={async e => {
e.stopPropagation(); e.stopPropagation();
const status = await submitBaseInfo(); const status = await submitBaseInfo();
// 更新成功后进入下一步 // After the update is successful, proceed to the next step
if (status) { if (status) {
handleInit(); handleInit();
} }

View File

@ -48,12 +48,12 @@ export const useContentBaseInfo = ({
editVersion, editVersion,
renderDescComponent, renderDescComponent,
}: UseContentBaseInfoProps) => { }: UseContentBaseInfoProps) => {
// 是否显示安全检查失败信息 // Is the security check failure message displayed?
const [showSecurityCheckFailedMsg, setShowSecurityCheckFailedMsg] = const [showSecurityCheckFailedMsg, setShowSecurityCheckFailedMsg] =
useState(false); useState(false);
const [isBaseInfoDisabled, setIsBaseInfoDisabled] = useState(true); const [isBaseInfoDisabled, setIsBaseInfoDisabled] = useState(true);
// 基本信息 // Basic information
const { baseInfoNode, submitBaseInfo } = useBaseInfo({ const { baseInfoNode, submitBaseInfo } = useBaseInfo({
pluginId: plugin_id || '', pluginId: plugin_id || '',
apiId: tool_id, apiId: tool_id,
@ -93,7 +93,7 @@ export const useContentBaseInfo = ({
onClick={async e => { onClick={async e => {
e.stopPropagation(); e.stopPropagation();
const status = await submitBaseInfo(); const status = await submitBaseInfo();
// 更新成功后进入下一步 // After the update is successful, proceed to the next step
if (status) { if (status) {
handleInit(); handleInit();
} }

View File

@ -77,7 +77,7 @@ export const useContentDebug = ({
debugApiInfo && tool_id ? ( debugApiInfo && tool_id ? (
<Debug <Debug
pluginType={pluginInfo?.plugin_type} pluginType={pluginInfo?.plugin_type}
disabled={false} // 是否可调试 disabled={false} // Is it debuggable?
setDebugStatus={setDebugStatus} setDebugStatus={setDebugStatus}
pluginId={String(plugin_id)} pluginId={String(plugin_id)}
apiId={String(tool_id)} apiId={String(tool_id)}
@ -113,7 +113,7 @@ export const useContentDebug = ({
> >
<Debug <Debug
pluginType={pluginInfo?.plugin_type} pluginType={pluginInfo?.plugin_type}
disabled={false} // 是否可调试 disabled={false} // Is it debuggable?
setDebugStatus={setDebugStatus} setDebugStatus={setDebugStatus}
pluginId={String(plugin_id)} pluginId={String(plugin_id)}
apiId={String(tool_id)} apiId={String(tool_id)}

View File

@ -58,11 +58,11 @@ export const useContentRequest = ({
onSuccess, onSuccess,
renderParamsComponent, renderParamsComponent,
}: UseContentRequestProps) => { }: UseContentRequestProps) => {
// 是否显示安全检查失败信息 // Is the security check failure message displayed?
const [showSecurityCheckFailedMsg, setShowSecurityCheckFailedMsg] = const [showSecurityCheckFailedMsg, setShowSecurityCheckFailedMsg] =
useState(false); useState(false);
const [isRequestParamsDisabled, setIsRequestParamsDisabled] = useState(true); const [isRequestParamsDisabled, setIsRequestParamsDisabled] = useState(true);
// 设置请求参数 // Set request parameters
const { requestParamsNode, submitRequestParams, nlTool } = useRequestParams({ const { requestParamsNode, submitRequestParams, nlTool } = useRequestParams({
apiInfo, apiInfo,
pluginId: plugin_id || '', pluginId: plugin_id || '',
@ -107,7 +107,7 @@ export const useContentRequest = ({
onClick={async e => { onClick={async e => {
e.stopPropagation(); e.stopPropagation();
const status = await submitRequestParams(); const status = await submitRequestParams();
// 更新成功后进入下一步 // After the update is successful, proceed to the next step
if (status) { if (status) {
handleInit(); handleInit();
setIsRequestParamsDisabled(true); setIsRequestParamsDisabled(true);

View File

@ -66,12 +66,12 @@ export const useContentResponse = ({
onSuccess, onSuccess,
renderParamsComponent, renderParamsComponent,
}: UseContentResponseProps) => { }: UseContentResponseProps) => {
// 是否显示安全检查失败信息 // Is the security check failure message displayed?
const [showSecurityCheckFailedMsg, setShowSecurityCheckFailedMsg] = const [showSecurityCheckFailedMsg, setShowSecurityCheckFailedMsg] =
useState(false); useState(false);
const [isResponseParamsDisabled, setIsResponseParamsDisabled] = const [isResponseParamsDisabled, setIsResponseParamsDisabled] =
useState(true); useState(true);
// 第三步设置相应参数的hooks组件 // The third step is to set the corresponding parameters of the hooks component
const { responseParamsNode, submitResponseParams, extra } = useResponseParams( const { responseParamsNode, submitResponseParams, extra } = useResponseParams(
{ {
apiInfo, apiInfo,
@ -94,7 +94,7 @@ export const useContentResponse = ({
}, },
); );
// 处理 debug 时 example数据先显示后隐藏的问题 // When dealing with debugging, the example data is displayed first and then hidden
useEffect(() => { useEffect(() => {
if (!isResponseParamsDisabled) { if (!isResponseParamsDisabled) {
setDebugApiInfo({ setDebugApiInfo({
@ -133,7 +133,7 @@ export const useContentResponse = ({
onClick={async e => { onClick={async e => {
e.stopPropagation(); e.stopPropagation();
const status = await submitResponseParams(); const status = await submitResponseParams();
// 更新成功后进入下一步 // After the update is successful, proceed to the next step
if (status) { if (status) {
handleInit(); handleInit();
setIsResponseParamsDisabled(true); setIsResponseParamsDisabled(true);

View File

@ -78,8 +78,8 @@ const useAuthForApiTool = () => {
return { return {
canEdit, canEdit,
needAuth, // 需要 auth 授权 needAuth, // Requires auth authorization
isHasAuth, // 是否完成了授权 isHasAuth, // Has the authorization been completed?
doCancelOauth, doCancelOauth,
isUpdateLoading, isUpdateLoading,
doOauth, doOauth,

View File

@ -42,7 +42,7 @@
& svg { & svg {
width: 16px; width: 16px;
height: 16px; height: 16px;
/* stylelint-disable-next-line declaration-no-important -- 覆盖icon颜色 */ /* stylelint-disable-next-line declaration-no-important -- Override icon color */
color: var(--semi-color-text-2) !important; color: var(--semi-color-text-2) !important;
} }
} }

View File

@ -66,9 +66,9 @@ enum PageSource {
} }
enum PageMode { enum PageMode {
/** 整页 UI类似全覆盖浮层 */ /** Full page UI similar to full coverage floating layer */
FULL_PAGE = 'full_page', FULL_PAGE = 'full_page',
/** 嵌入(左侧有菜单栏) */ /** Embed (with menu bar on the left) */
EMBED = 'embed', EMBED = 'embed',
} }
@ -87,16 +87,16 @@ const MockSetDetail: FC<{
[], [],
); );
const routeResponse = usePageJumpResponse(PageType.PLUGIN_MOCK_DATA); const routeResponse = usePageJumpResponse(PageType.PLUGIN_MOCK_DATA);
// API 详情 // API Details
const [apiInfo, setApiInfo] = useState<PluginAPIInfo>({ const [apiInfo, setApiInfo] = useState<PluginAPIInfo>({
name: routeResponse?.toolName, name: routeResponse?.toolName,
}); });
// mock set 详情 // Mock set details
const [mockSetInfo, setMockSetInfo] = useState<MockSet>({ const [mockSetInfo, setMockSetInfo] = useState<MockSet>({
id: mocksetID, id: mocksetID,
name: routeResponse?.mockSetName, name: routeResponse?.mockSetName,
}); });
// API 对应 schema // API correspondence schema
const [toolSchema, setToolSchema] = useState<string>(''); const [toolSchema, setToolSchema] = useState<string>('');
const [perm, setPerm] = useState<{ const [perm, setPerm] = useState<{
readOnly: boolean; readOnly: boolean;
@ -109,9 +109,9 @@ const MockSetDetail: FC<{
const listRef = useRef<MockDataListActions>(null); const listRef = useRef<MockDataListActions>(null);
const contentEleRef = useRef<HTMLDivElement>(null); const contentEleRef = useRef<HTMLDivElement>(null);
// 页面展示模式 // page display mode
const pageMode = params.hideMenu ? PageMode.FULL_PAGE : PageMode.EMBED; const pageMode = params.hideMenu ? PageMode.FULL_PAGE : PageMode.EMBED;
// 页面来源 // page source
const fromSource = routeResponse?.fromSource const fromSource = routeResponse?.fromSource
? (routeResponse.fromSource as PageSource) ? (routeResponse.fromSource as PageSource)
: PageSource.FROM_MOCK_SET; : PageSource.FROM_MOCK_SET;
@ -142,7 +142,7 @@ const MockSetDetail: FC<{
[toolID, pluginID], [toolID, pluginID],
); );
// 获取当前 tool 信息 // Get current tool information
const getPluginToolInfo = async () => { const getPluginToolInfo = async () => {
try { try {
const { api_info = [] } = await PluginDevelopApi.GetPluginAPIs( const { api_info = [] } = await PluginDevelopApi.GetPluginAPIs(
@ -164,7 +164,7 @@ const MockSetDetail: FC<{
} }
}; };
// 获取当前 mock set 信息 // Get current mock set information
const getMockSetInfo = async () => { const getMockSetInfo = async () => {
if (!mocksetID) { if (!mocksetID) {
return; return;

View File

@ -65,7 +65,7 @@ import { getDisplayCols } from './get-col';
import styles from './index.module.less'; import styles from './index.module.less';
interface ListParams { interface ListParams {
pageNo?: number; // 用于前端计算数量 pageNo?: number; // Quantity for front-end computing
pageSize?: number; pageSize?: number;
pageToken?: string; pageToken?: string;
order?: { order?: {
@ -80,13 +80,13 @@ const TOOL_NOT_FOUND_CODE = '600303108';
const MockSetList: FC<{ toolID: string }> = ({ toolID }) => { const MockSetList: FC<{ toolID: string }> = ({ toolID }) => {
const resourceNavigate = usePluginNavigate(); const resourceNavigate = usePluginNavigate();
// user信息 // User information
const userInfo = userStoreService.useUserInfo(); const userInfo = userStoreService.useUserInfo();
// 路由信息 // routing information
const [params, setParams] = useState<ListParams>({ const [params, setParams] = useState<ListParams>({
//请求参数 //request parameters
pageSize: PAGE_SIZE, pageSize: PAGE_SIZE,
pageNo: 1, pageNo: 1,
}); });
@ -101,11 +101,11 @@ const MockSetList: FC<{ toolID: string }> = ({ toolID }) => {
})), })),
); );
// space信息 // Space information
const space = useSpace(spaceID); const space = useSpace(spaceID);
const isPersonal = space?.space_type === SpaceType.Personal; const isPersonal = space?.space_type === SpaceType.Personal;
// API 详情 // API Details
const [apiInfo, setApiInfo] = useState<PluginAPIInfo>(); const [apiInfo, setApiInfo] = useState<PluginAPIInfo>();
const [showCreateModal, setShowCreateModal] = useState(false); const [showCreateModal, setShowCreateModal] = useState(false);
@ -118,7 +118,7 @@ const MockSetList: FC<{ toolID: string }> = ({ toolID }) => {
const [editDisabled, setEditDisabled] = useState(false); const [editDisabled, setEditDisabled] = useState(false);
// 后端需要的mock上下文信息 // The mock context information required by the backend
const ctxInfo = { const ctxInfo = {
bizCtx: { bizCtx: {
trafficScene: TrafficScene.Undefined, trafficScene: TrafficScene.Undefined,
@ -216,7 +216,7 @@ const MockSetList: FC<{ toolID: string }> = ({ toolID }) => {
} }
}; };
// 获取当前tool信息 // Get current tool information
const getPluginToolInfo = async () => { const getPluginToolInfo = async () => {
try { try {
const { api_info = [] } = await PluginDevelopApi.GetPluginAPIs({ const { api_info = [] } = await PluginDevelopApi.GetPluginAPIs({
@ -351,13 +351,13 @@ const MockSetList: FC<{ toolID: string }> = ({ toolID }) => {
if (!editDisabled) { if (!editDisabled) {
handleEdit(record); handleEdit(record);
} }
}, // 点击行 }, // Click line
}), }),
onChange: e => { onChange: e => {
if (e.sorter?.sortOrder) { if (e.sorter?.sortOrder) {
tableRef.current?.reset(); tableRef.current?.reset();
//时间排序 //chronological sorting
setParams(p => ({ setParams(p => ({
...p, ...p,
pageSize: PAGE_SIZE, pageSize: PAGE_SIZE,
@ -410,7 +410,7 @@ const MockSetList: FC<{ toolID: string }> = ({ toolID }) => {
></MockSetEditModal> ></MockSetEditModal>
) : null} ) : null}
{ {
// 删除弹窗 // Delete pop-up window
deleteMockSet ? ( deleteMockSet ? (
<MockSetDeleteModal <MockSetDeleteModal
visible={!!deleteMockSet} visible={!!deleteMockSet}

View File

@ -35,8 +35,8 @@ interface UseCreateToolProps {
plugin_id: string; plugin_id: string;
onClickWrapper?: (fn: () => void) => () => Promise<void>; onClickWrapper?: (fn: () => void) => () => Promise<void>;
/** /**
* * The callback function before clicking the Create Tool button
* @returns {boolean | void} false时将阻止后续动作 * @Returns {boolean | void} returns false to block subsequent actions
*/ */
onBeforeClick?: () => void; onBeforeClick?: () => void;
disabled: boolean; disabled: boolean;
@ -151,7 +151,7 @@ export const useCreateTool = ({
}; };
/** /**
* @description * @description creation tool
*/ */
export const CreateTool: FC<CreateToolProps> = props => { export const CreateTool: FC<CreateToolProps> = props => {
const { content } = useCreateTool({ const { content } = useCreateTool({

View File

@ -155,7 +155,7 @@ const PluginDetailPage = ({
); );
const [params, setParams] = useState<GetPluginAPIsRequest>({ const [params, setParams] = useState<GetPluginAPIsRequest>({
//请求参数 //request parameters
page: 1, page: 1,
size: 10, size: 10,
plugin_id: pluginID, plugin_id: pluginID,
@ -236,7 +236,7 @@ const PluginDetailPage = ({
const dataSource = data?.api_info; const dataSource = data?.api_info;
/** 不再提示 */ /** no longer prompt */
const noTips = async () => { const noTips = async () => {
const res = await PluginDevelopApi.NoUpdatedPrompt({ const res = await PluginDevelopApi.NoUpdatedPrompt({
plugin_id: pluginID, plugin_id: pluginID,
@ -248,7 +248,7 @@ const PluginDetailPage = ({
const checkPublish = async () => { const checkPublish = async () => {
if (!pluginInfo?.published) { if (!pluginInfo?.published) {
//未发布过点击直接发布 //It has not been published. Click to publish directly.
setPublishPopShow(true); setPublishPopShow(true);
return; return;
} }
@ -264,7 +264,7 @@ const PluginDetailPage = ({
setPublishPopData(res); setPublishPopData(res);
setShowPublishCheckPop(true); setShowPublishCheckPop(true);
} else { } else {
//没有修改api直接发布 //Publish directly without modifying the api
setPublishPopShow(true); setPublishPopShow(true);
} }
}; };
@ -308,14 +308,14 @@ const PluginDetailPage = ({
onStatusChange?.('error'); onStatusChange?.('error');
} }
}, [initSuccessed]); }, [initSuccessed]);
// 区分ide的跳转 // Differentiate IDE jumps
const handleIdeJump = ( const handleIdeJump = (
initialAction = InitialAction.DEFAULT, initialAction = InitialAction.DEFAULT,
toolId = '', toolId = '',
) => { ) => {
// ide 逻辑 // IDE logic
if (isCloudIDEPlugin) { if (isCloudIDEPlugin) {
// 改变路由地址 返回的时候会清掉 // Change the routing address and it will be cleared when returning.
preloadIDE?.handleShowIde({ initialAction, toolId }); preloadIDE?.handleShowIde({ initialAction, toolId });
} else if (toolId) { } else if (toolId) {
resourceNavigate.tool?.(toolId); resourceNavigate.tool?.(toolId);
@ -337,7 +337,7 @@ const PluginDetailPage = ({
canEdit ? { mode: 'preview' } : {}, canEdit ? { mode: 'preview' } : {},
); );
} }
}, // 点击行 }, // Click line
}); });
const { exampleNode, openExample } = useEditExample({ const { exampleNode, openExample } = useEditExample({
@ -445,7 +445,7 @@ const PluginDetailPage = ({
) : null} ) : null}
<Layout.Content className={s['layout-content']}> <Layout.Content className={s['layout-content']}>
{/* 已发布且有更新展示 */} {/* Published and updated */}
{pluginInfo?.status && {pluginInfo?.status &&
pluginInfo?.published && pluginInfo?.published &&
canEdit && canEdit &&
@ -470,7 +470,7 @@ const PluginDetailPage = ({
} }
/> />
) : null} ) : null}
{/* plugin简介 */} {/* Plugin Introduction */}
{pluginInfo ? ( {pluginInfo ? (
<PluginHeader <PluginHeader
pluginInfo={pluginInfo} pluginInfo={pluginInfo}
@ -502,7 +502,7 @@ const PluginDetailPage = ({
onBeforeClick={() => { onBeforeClick={() => {
setShowDropDownItem(undefined); setShowDropDownItem(undefined);
if (isCloudIDEPlugin) { if (isCloudIDEPlugin) {
// 改变路由地址 返回的时候会清掉 // Change the routing address and it will be cleared when returning.
preloadIDE?.handleShowIde({ preloadIDE?.handleShowIde({
initialAction: InitialAction.CREATE_TOOL, initialAction: InitialAction.CREATE_TOOL,
toolId: '', toolId: '',
@ -529,7 +529,7 @@ const PluginDetailPage = ({
{I18n.t('import')} {I18n.t('import')}
</Button> </Button>
) : null} ) : null}
{/* ! 发布按钮 */} {/* ! Post button */}
{isRenderIDEPublishButton ? ( {isRenderIDEPublishButton ? (
<Tooltip <Tooltip
position="left" position="left"
@ -598,7 +598,7 @@ const PluginDetailPage = ({
} }
/> />
) : null} ) : null}
{/* 工具列表表格 */} {/* Tool List Form */}
{!!dataSource?.length && ( {!!dataSource?.length && (
<div className="mb-[24px] mt-[36px] text-[18px] weight-[600]"> <div className="mb-[24px] mt-[36px] text-[18px] weight-[600]">
{I18n.t('plugin_api_list_table_name')} {I18n.t('plugin_api_list_table_name')}
@ -615,7 +615,7 @@ const PluginDetailPage = ({
onRow, onRow,
onChange: e => { onChange: e => {
if (e.sorter?.sortOrder) { if (e.sorter?.sortOrder) {
//时间排序 //chronological sorting
setParams(p => ({ setParams(p => ({
...p, ...p,
page: 1, page: 1,
@ -634,7 +634,7 @@ const PluginDetailPage = ({
btnText: canEdit ? createToolText : undefined, btnText: canEdit ? createToolText : undefined,
btnOnClick: () => { btnOnClick: () => {
if (isCloudIDEPlugin) { if (isCloudIDEPlugin) {
// 改变路由地址 返回的时候会清掉 // Change the routing address and it will be cleared when returning.
preloadIDE?.handleShowIde({ preloadIDE?.handleShowIde({
initialAction: InitialAction.CREATE_TOOL, initialAction: InitialAction.CREATE_TOOL,
toolId: '', toolId: '',

View File

@ -51,7 +51,7 @@ export interface PluginModalContentProps extends PluginModalModeProps {
setQuery: (value: Partial<PluginQuery>, refreshPage?: boolean) => void; setQuery: (value: Partial<PluginQuery>, refreshPage?: boolean) => void;
} }
export type PluginModalContentListItem = PluginInfoForPlayground & { export type PluginModalContentListItem = PluginInfoForPlayground & {
// 当前数据属于列表的第几页 // The current data belongs to the page of the list
belong_page?: number; belong_page?: number;
}; };
@ -99,7 +99,7 @@ export const PluginModalContent: FC<PluginModalContentProps> = ({
onCopyPluginCallback, onCopyPluginCallback,
clickProjectPluginCallback, clickProjectPluginCallback,
}) => { }) => {
// 状态hook // Status hook
const { const {
type, type,
mineActive, mineActive,
@ -112,9 +112,9 @@ export const PluginModalContent: FC<PluginModalContentProps> = ({
pluginType, pluginType,
} = query; } = query;
const id = useSpaceStore(store => store.space.id); const id = useSpaceStore(store => store.space.id);
// scroll的container // Scroll container
const scrollContainerRef = useRef<HTMLDivElement | null>(null); const scrollContainerRef = useRef<HTMLDivElement | null>(null);
// 当前active的key // Currently active key
const [activeKey, setActivekey] = useState<string | string[] | undefined>([]); const [activeKey, setActivekey] = useState<string | string[] | undefined>([]);
const refInfiniteScroll = useRef<InfiniteListRef>(null); const refInfiniteScroll = useRef<InfiniteListRef>(null);
const { const {
@ -140,10 +140,10 @@ export const PluginModalContent: FC<PluginModalContentProps> = ({
nodes: state.nodes, nodes: state.nodes,
})), })),
); );
// 首次effect不执行这个是切换状态的effect // The first effect is not executed, this is the effect of switching the state
useUpdateEffect(() => { useUpdateEffect(() => {
scroll2Top(); // 当筛选项改变时,回到顶部 scroll2Top(); // When the filter item changes, return to the top
// 只要是query中非page改变就执行此effect // Perform this effect whenever a non-page change is made in the query
}, []); }, []);
return ( return (
<UICompositionModalMain> <UICompositionModalMain>

View File

@ -53,24 +53,24 @@ export interface UsePluginModalPartsProp extends PluginModalModeProps {
} }
/** /**
* * Get initialization type
* @param from * @Param from source
* @param spaceType * @param spaceType
* @returns * @Returns initialization type
*/ */
const getInitType = (from?: From, spaceType?: SpaceType) => { const getInitType = (from?: From, spaceType?: SpaceType) => {
// 项目workflow引用插件默认选中项目插件 // Project workflow reference plug-in, the project plug-in is selected by default
if (from === From.ProjectWorkflow) { if (from === From.ProjectWorkflow) {
return ''; return '';
} }
if (from !== From.ProjectIde || !spaceType || !from) { if (from !== From.ProjectIde || !spaceType || !from) {
return ''; return '';
} }
// projectIDE下并且是个人空间选中Mine // Under projectIDE, and it is personal space, select Mine.
if (spaceType === SpaceType.Personal) { if (spaceType === SpaceType.Personal) {
return PluginFilterType.Mine; return PluginFilterType.Mine;
} }
// projectIDE下并且是团队空间选中Team // Under projectIDE, and is a team space, select Team
if (spaceType === SpaceType.Team && from === From.ProjectIde) { if (spaceType === SpaceType.Team && from === From.ProjectIde) {
return PluginFilterType.Team; return PluginFilterType.Team;
} }
@ -94,7 +94,7 @@ export const usePluginModalParts = ({
hideCreateBtn, hideCreateBtn,
initQuery, initQuery,
}: UsePluginModalPartsProp) => { }: UsePluginModalPartsProp) => {
// 获取devId // Get devId
const userInfo = userStoreService.useUserInfo(); const userInfo = userStoreService.useUserInfo();
const spaceType = useSpaceStore(store => store.space.space_type); const spaceType = useSpaceStore(store => store.space.space_type);
const [query, setQuery] = useState<PluginQuery>({ const [query, setQuery] = useState<PluginQuery>({
@ -103,14 +103,14 @@ export const usePluginModalParts = ({
devId: userInfo?.user_id_str || '', devId: userInfo?.user_id_str || '',
search: '', search: '',
page: DEFAULT_PAGE, page: DEFAULT_PAGE,
// 项目IDE插件仅展示我的插件 // Project IDE plugins only show my plugins
type: initQuery?.type ?? getInitType(from, spaceType), type: initQuery?.type ?? getInitType(from, spaceType),
orderBy: OrderBy.CreateTime, orderBy: OrderBy.CreateTime,
orderByPublic: SortType.Heat, orderByPublic: SortType.Heat,
orderByFavorite: SortType.Newest, orderByFavorite: SortType.Newest,
mineActive: MineActiveEnum.All, mineActive: MineActiveEnum.All,
isOfficial: initQuery?.isOfficial ?? undefined, isOfficial: initQuery?.isOfficial ?? undefined,
// project workflow添加插件只展示云插件 // Add plugins to project workflow, only show cloud plugins
pluginType: pluginType:
from === From.ProjectWorkflow ? PluginType.CLoudPlugin : undefined, from === From.ProjectWorkflow ? PluginType.CLoudPlugin : undefined,
}); });

View File

@ -85,11 +85,11 @@ export const PluginModalSider: FC<PluginModalSiderProp> = ({
maxLength={MAX_SEARCH_LENGTH} maxLength={MAX_SEARCH_LENGTH}
onSearch={search => { onSearch={search => {
if (!search) { if (!search) {
// 如果search清空了那么立即更新query // If the search is empty, update the query immediately
cancel(); cancel();
updateSearchQuery(search); updateSearchQuery(search);
} else { } else {
// 如果search有值那么防抖更新 // If search has a value, then anti-shake update
debounceChangeSearch(search); debounceChangeSearch(search);
} }
}} }}
@ -102,7 +102,7 @@ export const PluginModalSider: FC<PluginModalSiderProp> = ({
className={s.addbtn} className={s.addbtn}
theme="solid" theme="solid"
onClick={() => { onClick={() => {
// TODO: 其他场景应该也统一创建方式如果创建成功回调存在则打开插件modal否则打开新tab // TODO: Other scenes should also be created in a unified way. If the creation success callback exists, open the plugin modal, otherwise open a new tab.
if ( if (
onCreateSuccess && onCreateSuccess &&
(from === From.ProjectIde || from === From.ProjectWorkflow) (from === From.ProjectIde || from === From.ProjectWorkflow)

View File

@ -169,7 +169,7 @@ export function useInfiniteScrollCacheLoad<
] = true; ] = true;
}); });
//数据去重 //Data deduplicated
const uniqList = (list || []).filter(item => { const uniqList = (list || []).filter(item => {
const pluginId = (item as unknown as { pluginInfo: { id: string } }) const pluginId = (item as unknown as { pluginInfo: { id: string } })
?.pluginInfo?.id; ?.pluginInfo?.id;

Some files were not shown because too many files have changed in this diff Show More