[feat] Add ESLint i18n enforcement and fix hardcoded strings (#4327)

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Christian Byrne
2025-07-02 00:41:46 -07:00
committed by GitHub
parent 35ff882ff2
commit 959ab3b3ec
17 changed files with 394 additions and 157 deletions

View File

@@ -1,4 +1,5 @@
import pluginJs from '@eslint/js'
import pluginI18n from '@intlify/eslint-plugin-vue-i18n'
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'
import unusedImports from 'eslint-plugin-unused-imports'
import pluginVue from 'eslint-plugin-vue'
@@ -45,7 +46,8 @@ export default [
},
{
plugins: {
'unused-imports': unusedImports
'unused-imports': unusedImports,
'@intlify/vue-i18n': pluginI18n
},
rules: {
'@typescript-eslint/no-floating-promises': 'error',
@@ -53,7 +55,41 @@ export default [
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/prefer-as-const': 'off',
'unused-imports/no-unused-imports': 'error',
'vue/no-v-html': 'off'
'vue/no-v-html': 'off',
// i18n rules
'@intlify/vue-i18n/no-raw-text': [
'error',
{
// Ignore strings that are:
// 1. Less than 2 characters
// 2. Only symbols/numbers/whitespace (no letters)
// 3. Match specific patterns
ignorePattern:
'^[^a-zA-Z]*$|^.{0,1}$|^[\\w._%+-]+@[\\w.-]+\\.[A-Za-z]{2,}$',
ignoreNodes: ['md-icon', 'v-icon', 'pre', 'code', 'script', 'style'],
// Brand names and technical terms that shouldn't be translated
ignoreText: [
'ComfyUI',
'GitHub',
'OpenAI',
'API',
'URL',
'JSON',
'YAML',
'GPU',
'CPU',
'RAM',
'GB',
'MB',
'KB',
'ms',
'fps',
'px',
'App Data:',
'App Path:'
]
}
]
}
}
]

411
package-lock.json generated
View File

@@ -53,6 +53,7 @@
"@eslint/js": "^9.8.0",
"@executeautomation/playwright-mcp-server": "^1.0.5",
"@iconify/json": "^2.2.245",
"@intlify/eslint-plugin-vue-i18n": "^3.2.0",
"@lobehub/i18n-cli": "^1.20.0",
"@pinia/testing": "^0.1.5",
"@playwright/test": "^1.52.0",
@@ -2349,6 +2350,106 @@
"url": "https://github.com/sponsors/kazupon"
}
},
"node_modules/@intlify/eslint-plugin-vue-i18n": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@intlify/eslint-plugin-vue-i18n/-/eslint-plugin-vue-i18n-3.2.0.tgz",
"integrity": "sha512-TOIrD4tJE48WMyVIB8bNeQJJPYo1Prpqnm9Xpn1UZmcqlELhm8hmP8QyJnkgesfbG7hyiX/kvo63W7ClEQmhpg==",
"dev": true,
"dependencies": {
"@eslint/eslintrc": "^3.0.0",
"@intlify/core-base": "^9.12.0",
"@intlify/message-compiler": "^9.12.0",
"debug": "^4.3.4",
"eslint-compat-utils": "^0.6.0",
"glob": "^10.3.3",
"globals": "^15.0.0",
"ignore": "^6.0.0",
"import-fresh": "^3.3.0",
"is-language-code": "^3.1.0",
"js-yaml": "^4.1.0",
"json5": "^2.2.3",
"jsonc-eslint-parser": "^2.3.0",
"lodash": "^4.17.21",
"parse5": "^7.1.2",
"semver": "^7.5.4",
"synckit": "^0.9.0",
"vue-eslint-parser": "^9.3.1",
"yaml-eslint-parser": "^1.2.2"
},
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"eslint": "^8.0.0 || ^9.0.0-0"
}
},
"node_modules/@intlify/eslint-plugin-vue-i18n/node_modules/@pkgr/core": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.2.tgz",
"integrity": "sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==",
"dev": true,
"engines": {
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/unts"
}
},
"node_modules/@intlify/eslint-plugin-vue-i18n/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
"node_modules/@intlify/eslint-plugin-vue-i18n/node_modules/ignore": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz",
"integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/@intlify/eslint-plugin-vue-i18n/node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/@intlify/eslint-plugin-vue-i18n/node_modules/semver": {
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@intlify/eslint-plugin-vue-i18n/node_modules/synckit": {
"version": "0.9.3",
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.3.tgz",
"integrity": "sha512-JJoOEKTfL1urb1mDoEblhD9NhEbWmq9jHEMEnxoC4ujUaZ4itA8vKgwkFAyNClgxplLi9tsUKX+EduK0p/l7sg==",
"dev": true,
"dependencies": {
"@pkgr/core": "^0.1.0",
"tslib": "^2.6.2"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/unts"
}
},
"node_modules/@intlify/message-compiler": {
"version": "9.14.3",
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.14.3.tgz",
@@ -2702,53 +2803,6 @@
"react": ">=18"
}
},
"node_modules/@lobehub/i18n-cli/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/@lobehub/i18n-cli/node_modules/glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dev": true,
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@lobehub/i18n-cli/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@microsoft/api-extractor": {
"version": "7.48.0",
"resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.48.0.tgz",
@@ -7672,6 +7726,33 @@
}
}
},
"node_modules/eslint-compat-utils": {
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.5.tgz",
"integrity": "sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==",
"dev": true,
"dependencies": {
"semver": "^7.5.4"
},
"engines": {
"node": ">=12"
},
"peerDependencies": {
"eslint": ">=6.0.0"
}
},
"node_modules/eslint-compat-utils/node_modules/semver": {
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/eslint-config-prettier": {
"version": "10.1.2",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.2.tgz",
@@ -8818,6 +8899,26 @@
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
}
},
"node_modules/glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dev": true,
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@@ -8830,6 +8931,30 @@
"node": ">= 6"
}
},
"node_modules/glob/node_modules/brace-expansion": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/glob/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/global-directory": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz",
@@ -9668,6 +9793,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-language-code": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/is-language-code/-/is-language-code-3.1.0.tgz",
"integrity": "sha512-zJdQ3QTeLye+iphMeK3wks+vXSRFKh68/Pnlw7aOfApFSEIOhYa8P9vwwa6QrImNNBMJTiL1PpYF0f4BxDuEgA==",
"dev": true,
"dependencies": {
"@babel/runtime": "^7.14.0"
}
},
"node_modules/is-lower-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz",
@@ -9926,53 +10060,6 @@
"node": ">=14"
}
},
"node_modules/js-beautify/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/js-beautify/node_modules/glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dev": true,
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/js-beautify/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/js-cookie": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
@@ -10150,6 +10237,65 @@
"node": ">=6"
}
},
"node_modules/jsonc-eslint-parser": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz",
"integrity": "sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==",
"dev": true,
"dependencies": {
"acorn": "^8.5.0",
"eslint-visitor-keys": "^3.0.0",
"espree": "^9.0.0",
"semver": "^7.3.5"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ota-meshi"
}
},
"node_modules/jsonc-eslint-parser/node_modules/eslint-visitor-keys": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/jsonc-eslint-parser/node_modules/espree": {
"version": "9.6.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
"integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
"dev": true,
"dependencies": {
"acorn": "^8.9.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/jsonc-eslint-parser/node_modules/semver": {
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/jsondiffpatch": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/jsondiffpatch/-/jsondiffpatch-0.6.0.tgz",
@@ -12635,8 +12781,6 @@
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
"integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"entities": "^4.4.0"
},
@@ -14723,15 +14867,6 @@
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/sucrase/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/sucrase/node_modules/commander": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
@@ -14741,44 +14876,6 @@
"node": ">= 6"
}
},
"node_modules/sucrase/node_modules/glob": {
"version": "10.4.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz",
"integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==",
"dev": true,
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"engines": {
"node": ">=16 || 14 >=14.18"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/sucrase/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/superjson": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
@@ -17478,6 +17575,34 @@
"node": ">= 14"
}
},
"node_modules/yaml-eslint-parser": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.3.0.tgz",
"integrity": "sha512-E/+VitOorXSLiAqtTd7Yqax0/pAS3xaYMP+AUUJGOK1OZG3rhcj9fcJOM5HJ2VrP1FrStVCWr1muTfQCdj4tAA==",
"dev": true,
"dependencies": {
"eslint-visitor-keys": "^3.0.0",
"yaml": "^2.0.0"
},
"engines": {
"node": "^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ota-meshi"
}
},
"node_modules/yaml-eslint-parser/node_modules/eslint-visitor-keys": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",

View File

@@ -31,6 +31,7 @@
"@eslint/js": "^9.8.0",
"@executeautomation/playwright-mcp-server": "^1.0.5",
"@iconify/json": "^2.2.245",
"@intlify/eslint-plugin-vue-i18n": "^3.2.0",
"@lobehub/i18n-cli": "^1.20.0",
"@pinia/testing": "^0.1.5",
"@playwright/test": "^1.52.0",

View File

@@ -50,7 +50,7 @@
<Suspense v-for="panel in panels" :key="panel.node.key">
<component :is="panel.component" />
<template #fallback>
<div>Loading {{ panel.node.label }} panel...</div>
<div>{{ $t('g.loadingPanel', { panel: panel.node.label }) }}</div>
</template>
</Suspense>
</TabPanels>

View File

@@ -98,7 +98,7 @@
@keydown.stop.prevent="captureKeybinding"
/>
<Message v-if="existingKeybindingOnCombo" severity="warn">
Keybinding already exists on
{{ $t('g.keybindingAlreadyExists') }}
<Tag
severity="secondary"
:value="existingKeybindingOnCombo.commandId"

View File

@@ -22,7 +22,7 @@
</div>
<div class="flex items-center gap-4">
<span v-if="isInProgress" class="text-xs font-bold text-neutral-600">
{{ comfyManagerStore.uncompletedCount }} of
{{ comfyManagerStore.uncompletedCount }} {{ $t('g.progressCountOf') }}
{{ comfyManagerStore.taskLogs.length }}
</span>
<div class="flex items-center">

View File

@@ -65,7 +65,12 @@
<i class="pi pi-refresh help-menu-icon" aria-hidden="true" />
<div class="release-content">
<span class="release-title">
Comfy {{ release.version }} Release
{{
$t('g.releaseTitle', {
package: 'Comfy',
version: release.version
})
}}
</span>
<time class="release-date" :datetime="release.published_at">
<span class="normal-state">

View File

@@ -15,7 +15,7 @@ https://github.com/Nuked88/ComfyUI-N-Sidebar/blob/7ae7da4a9761009fb6629bc04c6830
<div class="_sb_dot headdot" />
{{ nodeDef.display_name }}
</div>
<div class="_sb_preview_badge">PREVIEW</div>
<div class="_sb_preview_badge">{{ $t('g.preview') }}</div>
<!-- Node slot I/O -->
<div

View File

@@ -27,7 +27,7 @@
@hide="reFocusInput"
>
<template #header>
<h3>Add node filter condition</h3>
<h3>{{ $t('g.addNodeFilterCondition') }}</h3>
</template>
<div class="_dialog-body">
<NodeSearchFilter @add-filter="onAddFilter" />

View File

@@ -8,11 +8,11 @@
{{ modelDef.file_name }}
</div>
<div v-if="modelDef.architecture_id" class="model_preview_architecture">
<span class="model_preview_prefix">Architecture: </span>
<span class="model_preview_prefix">{{ $t('g.architecture') }}: </span>
{{ modelDef.architecture_id }}
</div>
<div v-if="modelDef.author" class="model_preview_author">
<span class="model_preview_prefix">Author: </span>
<span class="model_preview_prefix">{{ $t('g.author') }}: </span>
{{ modelDef.author }}
</div>
</div>
@@ -20,15 +20,15 @@
<img :src="modelDef.image" />
</div>
<div v-if="modelDef.usage_hint" class="model_preview_usage_hint">
<span class="model_preview_prefix">Usage hint: </span>
<span class="model_preview_prefix">{{ $t('g.usageHint') }}: </span>
{{ modelDef.usage_hint }}
</div>
<div v-if="modelDef.trigger_phrase" class="model_preview_trigger_phrase">
<span class="model_preview_prefix">Trigger phrase: </span>
<span class="model_preview_prefix">{{ $t('g.triggerPhrase') }}: </span>
{{ modelDef.trigger_phrase }}
</div>
<div v-if="modelDef.description" class="model_preview_description">
<span class="model_preview_prefix">Description: </span>
<span class="model_preview_prefix">{{ $t('g.description') }}: </span>
{{ modelDef.description }}
</div>
</div>

View File

@@ -32,6 +32,13 @@
"error": "Error",
"help": "Help",
"loading": "Loading",
"loadingPanel": "Loading {panel} panel...",
"preview": "PREVIEW",
"addNodeFilterCondition": "Add node filter condition",
"architecture": "Architecture",
"author": "Author",
"usageHint": "Usage hint",
"triggerPhrase": "Trigger phrase",
"findIssues": "Find Issues",
"reportIssue": "Send Report",
"reportIssueTooltip": "Submit the error report to Comfy Org",
@@ -123,7 +130,10 @@
"copy": "Copy",
"imageUrl": "Image URL",
"clear": "Clear",
"copyURL": "Copy URL"
"copyURL": "Copy URL",
"releaseTitle": "{package} {version} Release",
"progressCountOf": "of",
"keybindingAlreadyExists": "Keybinding already exists on"
},
"manager": {
"title": "Custom Nodes Manager",

View File

@@ -253,10 +253,13 @@
"g": {
"about": "Acerca de",
"add": "Añadir",
"addNodeFilterCondition": "Agregar condición de filtro de nodo",
"all": "Todo",
"amount": "Cantidad",
"apply": "Aplicar",
"architecture": "Arquitectura",
"audioFailedToLoad": "No se pudo cargar el audio",
"author": "Autor",
"back": "Atrás",
"cancel": "Cancelar",
"capture": "captura",
@@ -314,10 +317,12 @@
"installing": "Instalando",
"interrupted": "Interrumpido",
"keybinding": "Combinación de teclas",
"keybindingAlreadyExists": "La combinación de teclas ya existe en",
"learnMore": "Aprende más",
"loadAllFolders": "Cargar todas las carpetas",
"loadWorkflow": "Cargar flujo de trabajo",
"loading": "Cargando",
"loadingPanel": "Cargando panel {panel}...",
"login": "Iniciar sesión",
"logs": "Registros",
"migrate": "Migrar",
@@ -334,9 +339,12 @@
"ok": "OK",
"openNewIssue": "Abrir nuevo problema",
"overwrite": "Sobrescribir",
"preview": "VISTA PREVIA",
"progressCountOf": "de",
"reconnected": "Reconectado",
"reconnecting": "Reconectando",
"refresh": "Actualizar",
"releaseTitle": "Lanzamiento de {package} {version}",
"reloadToApplyChanges": "Recargar para aplicar cambios",
"rename": "Renombrar",
"reportIssue": "Enviar informe",
@@ -366,12 +374,14 @@
"systemInfo": "Información del sistema",
"terminal": "Terminal",
"title": "Título",
"triggerPhrase": "Frase de activación",
"unknownError": "Error desconocido",
"update": "Actualizar",
"updateAvailable": "Actualización Disponible",
"updated": "Actualizado",
"updating": "Actualizando",
"upload": "Subir",
"usageHint": "Sugerencia de uso",
"user": "Usuario",
"videoFailedToLoad": "Falló la carga del video",
"workflow": "Flujo de trabajo"

View File

@@ -253,10 +253,13 @@
"g": {
"about": "À propos",
"add": "Ajouter",
"addNodeFilterCondition": "Ajouter une condition de filtre de nœud",
"all": "Tout",
"amount": "Quantité",
"apply": "Appliquer",
"architecture": "Architecture",
"audioFailedToLoad": "Échec du chargement de l'audio",
"author": "Auteur",
"back": "Retour",
"cancel": "Annuler",
"capture": "capture",
@@ -314,10 +317,12 @@
"installing": "Installation",
"interrupted": "Interrompu",
"keybinding": "Raccourci clavier",
"keybindingAlreadyExists": "Le raccourci clavier existe déjà",
"learnMore": "En savoir plus",
"loadAllFolders": "Charger tous les dossiers",
"loadWorkflow": "Charger le flux de travail",
"loading": "Chargement",
"loadingPanel": "Chargement du panneau {panel}...",
"login": "Connexion",
"logs": "Journaux",
"migrate": "Migrer",
@@ -334,9 +339,12 @@
"ok": "OK",
"openNewIssue": "Ouvrir un nouveau problème",
"overwrite": "Écraser",
"preview": "APERÇU",
"progressCountOf": "sur",
"reconnected": "Reconnecté",
"reconnecting": "Reconnexion",
"refresh": "Rafraîchir",
"releaseTitle": "Publication de {package} {version}",
"reloadToApplyChanges": "Recharger pour appliquer les modifications",
"rename": "Renommer",
"reportIssue": "Envoyer le rapport",
@@ -366,12 +374,14 @@
"systemInfo": "Informations système",
"terminal": "Terminal",
"title": "Titre",
"triggerPhrase": "Phrase déclencheuse",
"unknownError": "Erreur inconnue",
"update": "Mettre à jour",
"updateAvailable": "Mise à jour disponible",
"updated": "Mis à jour",
"updating": "Mise à jour",
"upload": "Téléverser",
"usageHint": "Conseil d'utilisation",
"user": "Utilisateur",
"videoFailedToLoad": "Échec du chargement de la vidéo",
"workflow": "Flux de travail"

View File

@@ -253,10 +253,13 @@
"g": {
"about": "情報",
"add": "追加",
"addNodeFilterCondition": "ノードフィルター条件を追加",
"all": "すべて",
"amount": "量",
"apply": "適用する",
"architecture": "アーキテクチャ",
"audioFailedToLoad": "オーディオの読み込みに失敗しました",
"author": "作者",
"back": "戻る",
"cancel": "キャンセル",
"capture": "キャプチャ",
@@ -314,10 +317,12 @@
"installing": "インストール中",
"interrupted": "中断されました",
"keybinding": "キーバインディング",
"keybindingAlreadyExists": "このキー割り当てはすでに存在します",
"learnMore": "詳細を学ぶ",
"loadAllFolders": "すべてのフォルダーを読み込む",
"loadWorkflow": "ワークフローを読み込む",
"loading": "読み込み中",
"loadingPanel": "{panel} パネルを読み込み中...",
"login": "ログイン",
"logs": "ログ",
"migrate": "移行する",
@@ -334,9 +339,12 @@
"ok": "OK",
"openNewIssue": "新しい問題を開く",
"overwrite": "上書き",
"preview": "プレビュー",
"progressCountOf": "の",
"reconnected": "再接続されました",
"reconnecting": "再接続中",
"refresh": "更新",
"releaseTitle": "{package} {version} リリース",
"reloadToApplyChanges": "変更を適用するには再読み込みしてください",
"rename": "名前を変更",
"reportIssue": "報告する",
@@ -366,12 +374,14 @@
"systemInfo": "システム情報",
"terminal": "ターミナル",
"title": "タイトル",
"triggerPhrase": "トリガーフレーズ",
"unknownError": "不明なエラー",
"update": "更新",
"updateAvailable": "更新が利用可能",
"updated": "更新済み",
"updating": "更新中",
"upload": "アップロード",
"usageHint": "使用ヒント",
"user": "ユーザー",
"videoFailedToLoad": "ビデオの読み込みに失敗しました",
"workflow": "ワークフロー"

View File

@@ -253,10 +253,13 @@
"g": {
"about": "정보",
"add": "추가",
"addNodeFilterCondition": "노드 필터 조건 추가",
"all": "모두",
"amount": "수량",
"apply": "적용",
"architecture": "아키텍처",
"audioFailedToLoad": "오디오를 불러오지 못했습니다",
"author": "작성자",
"back": "뒤로",
"cancel": "취소",
"capture": "캡처",
@@ -314,10 +317,12 @@
"installing": "설치 중",
"interrupted": "중단됨",
"keybinding": "키 바인딩",
"keybindingAlreadyExists": "단축키가 이미 존재합니다",
"learnMore": "더 알아보기",
"loadAllFolders": "모든 폴더 로드",
"loadWorkflow": "워크플로 로드",
"loading": "로딩 중",
"loadingPanel": "{panel} 패널 불러오는 중...",
"login": "로그인",
"logs": "로그",
"migrate": "이전(migrate)",
@@ -334,9 +339,12 @@
"ok": "확인",
"openNewIssue": "새 문제 열기",
"overwrite": "덮어쓰기",
"preview": "미리보기",
"progressCountOf": "중",
"reconnected": "재연결됨",
"reconnecting": "재연결 중",
"refresh": "새로 고침",
"releaseTitle": "{package} {version} 릴리스",
"reloadToApplyChanges": "변경 사항을 적용하려면 새로 고침하세요.",
"rename": "이름 바꾸기",
"reportIssue": "보고서 보내기",
@@ -366,12 +374,14 @@
"systemInfo": "시스템 정보",
"terminal": "터미널",
"title": "제목",
"triggerPhrase": "트리거 문구",
"unknownError": "알 수 없는 오류",
"update": "업데이트",
"updateAvailable": "업데이트 가능",
"updated": "업데이트 됨",
"updating": "업데이트 중",
"upload": "업로드",
"usageHint": "사용 힌트",
"user": "사용자",
"videoFailedToLoad": "비디오를 로드하지 못했습니다.",
"workflow": "워크플로"

View File

@@ -253,10 +253,13 @@
"g": {
"about": "О программе",
"add": "Добавить",
"addNodeFilterCondition": "Добавить условие фильтрации узла",
"all": "Все",
"amount": "Количество",
"apply": "Применить",
"architecture": "Архитектура",
"audioFailedToLoad": "Не удалось загрузить аудио",
"author": "Автор",
"back": "Назад",
"cancel": "Отмена",
"capture": "захват",
@@ -314,10 +317,12 @@
"installing": "Установка",
"interrupted": "Прервано",
"keybinding": "Привязка клавиш",
"keybindingAlreadyExists": "Горячая клавиша уже существует",
"learnMore": "Узнать больше",
"loadAllFolders": "Загрузить все папки",
"loadWorkflow": "Загрузить рабочий процесс",
"loading": "Загрузка",
"loadingPanel": "Загрузка панели {panel}...",
"login": "Вход",
"logs": "Логи",
"migrate": "Мигрировать",
@@ -334,9 +339,12 @@
"ok": "ОК",
"openNewIssue": "Открыть новую проблему",
"overwrite": "Перезаписать",
"preview": "ПРЕДПРОСМОТР",
"progressCountOf": "из",
"reconnected": "Переподключено",
"reconnecting": "Переподключение",
"refresh": "Обновить",
"releaseTitle": "Релиз {package} {version}",
"reloadToApplyChanges": "Перезагрузите, чтобы применить изменения",
"rename": "Переименовать",
"reportIssue": "Отправить отчёт",
@@ -366,12 +374,14 @@
"systemInfo": "Информация о системе",
"terminal": "Терминал",
"title": "Заголовок",
"triggerPhrase": "Триггерная фраза",
"unknownError": "Неизвестная ошибка",
"update": "Обновить",
"updateAvailable": "Доступно обновление",
"updated": "Обновлено",
"updating": "Обновление",
"upload": "Загрузить",
"usageHint": "Подсказка по использованию",
"user": "Пользователь",
"videoFailedToLoad": "Не удалось загрузить видео",
"workflow": "Рабочий процесс"

View File

@@ -253,10 +253,13 @@
"g": {
"about": "关于",
"add": "添加",
"addNodeFilterCondition": "添加节点筛选条件",
"all": "全部",
"amount": "数量",
"apply": "应用",
"architecture": "架构",
"audioFailedToLoad": "音频加载失败",
"author": "作者",
"back": "返回",
"cancel": "取消",
"capture": "捕获",
@@ -314,10 +317,12 @@
"installing": "正在安装",
"interrupted": "已中断",
"keybinding": "按键绑定",
"keybindingAlreadyExists": "快捷键已存在",
"learnMore": "了解更多",
"loadAllFolders": "加载所有文件夹",
"loadWorkflow": "加载工作流",
"loading": "加载中",
"loadingPanel": "正在加载{panel}面板...",
"login": "登录",
"logs": "日志",
"migrate": "迁移",
@@ -334,9 +339,12 @@
"ok": "确定",
"openNewIssue": "打开新问题",
"overwrite": "覆盖",
"preview": "预览",
"progressCountOf": "共",
"reconnected": "已重新连接",
"reconnecting": "重新连接中",
"refresh": "刷新",
"releaseTitle": "{package} {version} 发布",
"reloadToApplyChanges": "重新加载以应用更改",
"rename": "重命名",
"reportIssue": "发送报告",
@@ -366,12 +374,14 @@
"systemInfo": "系统信息",
"terminal": "终端",
"title": "标题",
"triggerPhrase": "触发短语",
"unknownError": "未知错误",
"update": "更新",
"updateAvailable": "有更新可用",
"updated": "已更新",
"updating": "更新中",
"upload": "上传",
"usageHint": "使用提示",
"user": "用户",
"videoFailedToLoad": "视频加载失败",
"workflow": "工作流"