mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-26 11:44:28 +08:00
* chore(i18n): 更新i18n文件为嵌套结构以适应插件 * feat(i18n): 添加自动翻译脚本处理待翻译文本 添加自动翻译脚本auto-translate-i18n.ts,用于处理以[to be translated]开头的待翻译文本 在package.json中添加对应的运行命令auto:i18n * chore(i18n): 更新嵌套结构 * chore(i18n): 更新多语言翻译文件并改进翻译逻辑 更新了多个语言的翻译文件,替换了"[to be translated]"标记为实际翻译内容 改进auto-translate-i18n.ts中的翻译逻辑,添加错误处理和日志输出 部分数组格式的翻译描述自动改为对象格式 * fix(i18n): 修复嵌套结构检查并改进错误处理 添加对嵌套结构中使用点符号的检查,确保使用严格嵌套结构 改进错误处理,在检查失败时输出更清晰的错误信息 * fix(测试): 更新下载失败测试中的翻译键名 * test(下载): 移除重复的下载失败翻译并更新测试 * feat(eslint): 添加规则,警告不建议在t()函数中使用模板字符串 * style: 使用单引号替换模板字符串中的反引号 * docs(.vscode): 添加i18n-ally扩展推荐到vscode配置 * fix: 在自动翻译脚本中停止进度条显示 确保在脚本执行完成后正确停止进度条,避免控制台输出混乱 * fix(i18n): 修复模型列表添加确认对话框的翻译键名 更新多语言文件中模型管理部分的翻译结构,将"add_listed"从字符串改为包含"confirm"和"key"的对象 同时修正EditModelsPopup组件中对应的翻译键引用 * chore: 注释掉i18n-ally命名空间配置 * docs: 添加国际化(i18n)最佳实践文档 添加中英文双语的技术文档,详细介绍项目中的i18n实现方案、工具链和最佳实践 包含i18n ally插件使用指南、自动化脚本说明以及代码规范要求 * docs(国际化): 更新i18n文档中的键名格式示例 将文档中错误的flat格式示例从下划线命名改为点分隔命名,以保持一致性 * refactor(i18n): 统一翻译键名从.key后缀改为.label后缀 * chore(i18n): sort * refactor(locales): 使用 Object.fromEntries 重构 locales 对象 * feat(i18n): 添加机器翻译的语言支持 新增希腊语、西班牙语、法语和葡萄牙语的机器翻译支持,并调整语言资源加载顺序
129 lines
4.5 KiB
JavaScript
129 lines
4.5 KiB
JavaScript
import electronConfigPrettier from '@electron-toolkit/eslint-config-prettier'
|
|
import tseslint from '@electron-toolkit/eslint-config-ts'
|
|
import eslint from '@eslint/js'
|
|
import eslintReact from '@eslint-react/eslint-plugin'
|
|
import { defineConfig } from 'eslint/config'
|
|
import reactHooks from 'eslint-plugin-react-hooks'
|
|
import simpleImportSort from 'eslint-plugin-simple-import-sort'
|
|
import unusedImports from 'eslint-plugin-unused-imports'
|
|
|
|
export default defineConfig([
|
|
eslint.configs.recommended,
|
|
tseslint.configs.recommended,
|
|
electronConfigPrettier,
|
|
eslintReact.configs['recommended-typescript'],
|
|
reactHooks.configs['recommended-latest'],
|
|
{
|
|
plugins: {
|
|
'simple-import-sort': simpleImportSort,
|
|
'unused-imports': unusedImports
|
|
},
|
|
rules: {
|
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
'@typescript-eslint/no-explicit-any': 'off',
|
|
'@typescript-eslint/no-non-null-asserted-optional-chain': 'off',
|
|
'simple-import-sort/imports': 'error',
|
|
'simple-import-sort/exports': 'error',
|
|
'unused-imports/no-unused-imports': 'error',
|
|
'@eslint-react/no-prop-types': 'error',
|
|
'prettier/prettier': ['error']
|
|
}
|
|
},
|
|
// Configuration for ensuring compatibility with the original ESLint(8.x) rules
|
|
{
|
|
rules: {
|
|
'@typescript-eslint/no-require-imports': 'off',
|
|
'@typescript-eslint/no-unused-vars': ['error', { caughtErrors: 'none' }],
|
|
'@typescript-eslint/no-unused-expressions': 'off',
|
|
'@typescript-eslint/no-empty-object-type': 'off',
|
|
'@eslint-react/hooks-extra/no-direct-set-state-in-use-effect': 'off',
|
|
'@eslint-react/web-api/no-leaked-event-listener': 'off',
|
|
'@eslint-react/web-api/no-leaked-timeout': 'off',
|
|
'@eslint-react/no-unknown-property': 'off',
|
|
'@eslint-react/no-nested-component-definitions': 'off',
|
|
'@eslint-react/dom/no-dangerously-set-innerhtml': 'off',
|
|
'@eslint-react/no-array-index-key': 'off',
|
|
'@eslint-react/no-unstable-default-props': 'off',
|
|
'@eslint-react/no-unstable-context-value': 'off',
|
|
'@eslint-react/hooks-extra/prefer-use-state-lazy-initialization': 'off',
|
|
'@eslint-react/hooks-extra/no-unnecessary-use-prefix': 'off',
|
|
'@eslint-react/no-children-to-array': 'off'
|
|
}
|
|
},
|
|
{
|
|
// LoggerService Custom Rules - only apply to src directory
|
|
files: ['src/**/*.{ts,tsx,js,jsx}'],
|
|
ignores: ['src/**/__tests__/**', 'src/**/__mocks__/**', 'src/**/*.test.*'],
|
|
rules: {
|
|
'no-restricted-syntax': [
|
|
'warn',
|
|
{
|
|
selector: 'CallExpression[callee.object.name="console"]',
|
|
message:
|
|
'❗CherryStudio uses unified LoggerService: 📖 docs/technical/how-to-use-logger-en.md\n❗CherryStudio 使用统一的日志服务:📖 docs/technical/how-to-use-logger-zh.md\n\n'
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
files: ['**/*.{ts,tsx,js,jsx}'],
|
|
languageOptions: {
|
|
ecmaVersion: 2022,
|
|
sourceType: 'module'
|
|
},
|
|
plugins: {
|
|
i18n: {
|
|
rules: {
|
|
'no-template-in-t': {
|
|
meta: {
|
|
type: 'problem',
|
|
docs: {
|
|
description: '⚠️不建议在 t() 函数中使用模板字符串,这样会导致渲染结果不可预料',
|
|
recommended: true
|
|
},
|
|
messages: {
|
|
noTemplateInT: '⚠️不建议在 t() 函数中使用模板字符串,这样会导致渲染结果不可预料'
|
|
}
|
|
},
|
|
create(context) {
|
|
return {
|
|
CallExpression(node) {
|
|
const { callee, arguments: args } = node
|
|
const isTFunction =
|
|
(callee.type === 'Identifier' && callee.name === 't') ||
|
|
(callee.type === 'MemberExpression' &&
|
|
callee.property.type === 'Identifier' &&
|
|
callee.property.name === 't')
|
|
|
|
if (isTFunction && args[0]?.type === 'TemplateLiteral') {
|
|
context.report({
|
|
node: args[0],
|
|
messageId: 'noTemplateInT'
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
rules: {
|
|
'i18n/no-template-in-t': 'warn'
|
|
}
|
|
},
|
|
{
|
|
ignores: [
|
|
'node_modules/**',
|
|
'build/**',
|
|
'dist/**',
|
|
'out/**',
|
|
'local/**',
|
|
'.yarn/**',
|
|
'.gitignore',
|
|
'scripts/cloudflare-worker.js',
|
|
'src/main/integration/nutstore/sso/lib/**'
|
|
]
|
|
}
|
|
])
|