chore: replace all cn comments of fe to en version by volc api (#320)
This commit is contained in:
parent
716ec0cba8
commit
71f6245a01
|
|
@ -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: {
|
||||||
|
|
|
||||||
|
|
@ -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');
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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 />,
|
||||||
|
|
|
||||||
|
|
@ -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')],
|
||||||
|
|
|
||||||
|
|
@ -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'),
|
||||||
|
|
|
||||||
|
|
@ -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'),
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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 "请执行以下命令安装必要依赖"
|
||||||
|
|
|
||||||
|
|
@ -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 "请执行以下命令安装必要依赖"
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)\//,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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': [
|
||||||
|
|
|
||||||
|
|
@ -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}`]: {
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
|
|
|
||||||
|
|
@ -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';
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 "请执行以下命令安装必要依赖"
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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 代替"]
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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 => {
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*```
|
*```
|
||||||
* 如果不采用下面这个判断,函数判断将得到3,实际应该为5. 类似的还有
|
* 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' ||
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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')
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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(() => ([])))',
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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[]>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 => {
|
||||||
|
|
|
||||||
|
|
@ -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 => {
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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. */
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 ??
|
||||||
|
|
|
||||||
|
|
@ -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) &&
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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', {
|
||||||
|
|
|
||||||
|
|
@ -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'],
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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<
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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 }) => {
|
||||||
|
|
|
||||||
|
|
@ -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={
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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>()(
|
||||||
|
|
|
||||||
|
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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<
|
||||||
|
|
|
||||||
|
|
@ -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, []];
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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({
|
||||||
|
|
|
||||||
|
|
@ -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');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 ||
|
||||||
|
|
|
||||||
|
|
@ -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' }}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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({
|
||||||
|
|
|
||||||
|
|
@ -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: '',
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
Loading…
Reference in New Issue