From def516ba1961e992d7d3ce93af71e3cc67a3622b Mon Sep 17 00:00:00 2001 From: terwer Date: Mon, 18 Mar 2024 14:32:46 +0800 Subject: [PATCH] feat: add partial i18n support --- libs/Universal-PicGo-Core/package.json | 6 +- .../src/core/UniversalPicGo.ts | 17 ++- libs/Universal-PicGo-Core/src/i18n/en.ts | 118 +++++++++++++++++ libs/Universal-PicGo-Core/src/i18n/index.ts | 123 ++++++++++++++++++ libs/Universal-PicGo-Core/src/i18n/zh-CN.ts | 116 +++++++++++++++++ libs/Universal-PicGo-Core/src/i18n/zh-TW.ts | 115 ++++++++++++++++ .../src/utils/browserUtils.ts | 37 ++++++ pnpm-lock.yaml | 17 ++- 8 files changed, 542 insertions(+), 7 deletions(-) create mode 100644 libs/Universal-PicGo-Core/src/i18n/en.ts create mode 100644 libs/Universal-PicGo-Core/src/i18n/index.ts create mode 100644 libs/Universal-PicGo-Core/src/i18n/zh-CN.ts create mode 100644 libs/Universal-PicGo-Core/src/i18n/zh-TW.ts create mode 100644 libs/Universal-PicGo-Core/src/utils/browserUtils.ts diff --git a/libs/Universal-PicGo-Core/package.json b/libs/Universal-PicGo-Core/package.json index 9a73466..64f2418 100644 --- a/libs/Universal-PicGo-Core/package.json +++ b/libs/Universal-PicGo-Core/package.json @@ -30,8 +30,10 @@ "vite-plugin-node-polyfills": "^0.21.0" }, "dependencies": { - "zhi-lib-base": "^0.8.0", - "universal-picgo-store": "workspace:*" + "@picgo/i18n": "^1.0.0", + "js-yaml": "^4.1.0", + "universal-picgo-store": "workspace:*", + "zhi-lib-base": "^0.8.0" }, "publishConfig": { "access": "public" diff --git a/libs/Universal-PicGo-Core/src/core/UniversalPicGo.ts b/libs/Universal-PicGo-Core/src/core/UniversalPicGo.ts index dc3bc94..235c525 100644 --- a/libs/Universal-PicGo-Core/src/core/UniversalPicGo.ts +++ b/libs/Universal-PicGo-Core/src/core/UniversalPicGo.ts @@ -30,6 +30,8 @@ import { IBuildInEvent } from "../utils/enums" import DB from "../utils/db" import { hasNodeEnv, win } from "universal-picgo-store" import { ensureFileSync, pathExistsSync } from "../utils/nodeUtils" +import { I18nManager } from "../i18n" +import { getBrowserDirectoryPath } from "../utils/browserUtils" /* * 通用 PicGO 对象定义 @@ -223,7 +225,11 @@ class UniversalPicGo extends EventEmitter implements IPicGo { } } else { if (this.configPath === "") { + this.baseDir = "" this.configPath = `universal-picgo-config.json` + } else { + // 模拟 path.dirname 的功能,获取路径的目录部分赋值给 baseDir + this.baseDir = getBrowserDirectoryPath(this.configPath) } } } @@ -233,7 +239,16 @@ class UniversalPicGo extends EventEmitter implements IPicGo { this._config = this.db.read(true) as IConfig } - private init(): void {} + private init(): void { + try { + // init 18n at first + this.i18n = new I18nManager(this) + } catch (e: any) { + this.emit(IBuildInEvent.UPLOAD_PROGRESS, -1) + this.log.error(e) + throw e + } + } } export { UniversalPicGo } diff --git a/libs/Universal-PicGo-Core/src/i18n/en.ts b/libs/Universal-PicGo-Core/src/i18n/en.ts new file mode 100644 index 0000000..11d16d0 --- /dev/null +++ b/libs/Universal-PicGo-Core/src/i18n/en.ts @@ -0,0 +1,118 @@ +import { ILocales } from "./zh-CN" + +/* eslint-disable no-template-curly-in-string */ +export const EN: ILocales = { + UPLOAD_FAILED: "Upload failed", + CHECK_SETTINGS: "Please check your settings", + CHECK_SETTINGS_AND_NETWORK: "Please check your settings and network", + UPLOAD_FAILED_REASON: "Error code: ${code}, please open the browser and paste the address to see the reason", + SERVER_ERROR: "Server error, please try again later", + AUTH_FAILED: "Authentication failed", + + // smms + PICBED_SMMS: "SM.MS", + PICBED_SMMS_TOKEN: "Set Token", + PICBED_SMMS_BACKUP_DOMAIN: "Set Backup Upload Domain", + PICBED_SMMS_MESSAGE_BACKUP_DOMAIN: "Ex. smms.app", + + // Ali-cloud + PICBED_ALICLOUD: "Ali Cloud", + PICBED_ALICLOUD_ACCESSKEYID: "Set KeyId", + PICBED_ALICLOUD_ACCESSKEYSECRET: "Set KeySecret", + PICBED_ALICLOUD_BUCKET: "Set Bucket", + PICBED_ALICLOUD_AREA: "Set Area", + PICBED_ALICLOUD_PATH: "Set Path", + PICBED_ALICLOUD_CUSTOMURL: "Set Custom URL", + PICBED_ALICLOUD_OPTIONS: "Set URL Suffix", + PICBED_ALICLOUD_MESSAGE_AREA: "Ex. oss-cn-beijing", + PICBED_ALICLOUD_MESSAGE_PATH: "Ex. test/", + PICBED_ALICLOUD_MESSAGE_OPTIONS: "Ex. ?x-oss-process=xxx", + PICBED_ALICLOUD_MESSAGE_CUSTOMURL: "Ex. https://test.com", + + // Tencent-cloud + PICBED_TENCENTCLOUD: "Tencent Cloud", + PICBED_TENCENTCLOUD_VERSION: "Choose COS version", + PICBED_TENCENTCLOUD_SECRETID: "Set SecretId", + PICBED_TENCENTCLOUD_SECRETKEY: "Set SecretKey", + PICBED_TENCENTCLOUD_APPID: "Set AppId", + PICBED_TENCENTCLOUD_BUCKET: "Set Bucket", + PICBED_TENCENTCLOUD_AREA: "Set Area", + PICBED_TENCENTCLOUD_ENDPOINT: "Set Endpoint", + PICBED_TENCENTCLOUD_PATH: "Set Path", + PICBED_TENCENTCLOUD_OPTIONS: "Set URL Suffix", + PICBED_TENCENTCLOUD_SLIM: "Set ImageSlim", + PICBED_TENCENTCLOUD_SLIM_TIP: + "Image extremely intelligent compression, please refer to the [document description](https://cloud.tencent.com/document/product/436/49259)", + PICBED_TENCENTCLOUD_SLIM_CONFIRM: "OPEN", + PICBED_TENCENTCLOUD_SLIM_CANCEL: "CLOSE", + PICBED_TENCENTCLOUD_CUSTOMURL: "Set Custom URL", + PICBED_TENCENTCLOUD_MESSAGE_APPID: "Ex. 1234567890", + PICBED_TENCENTCLOUD_MESSAGE_AREA: "Ex. ap-beijing", + PICBED_TENCENTCLOUD_MESSAGE_ENDPOINT: "Ex. cos-internal.accelerate.tencentcos.cn", + PICBED_TENCENTCLOUD_MESSAGE_PATH: "Ex. test/", + PICBED_TENCENTCLOUD_MESSAGE_CUSTOMURL: "Ex. http://test.com", + PICBED_TENCENTCLOUD_MESSAGE_OPTIONS: "Ex. ?imageMogr2", + + // GitHub + PICBED_GITHUB: "GitHub", + PICBED_GITHUB_TOKEN: "Set Token", + PICBED_GITHUB_REPO: "Set Repo Name", + PICBED_GITHUB_PATH: "Set Path", + PICBED_GITHUB_BRANCH: "Set Branch", + PICBED_GITHUB_CUSTOMURL: "Set Custom URL", + PICBED_GITHUB_MESSAGE_REPO: "Ex. username/repo", + PICBED_GITHUB_MESSAGE_BRANCH: "Ex. main", + PICBED_GITHUB_MESSAGE_PATH: "Ex. test/", + PICBED_GITHUB_MESSAGE_CUSTOMURL: "Ex. https://test.com", + + // qiniu + PICBED_QINIU: "Qiniu", + PICBED_QINIU_ACCESSKEY: "Set AccessKey", + PICBED_QINIU_SECRETKEY: "Set SecretKey", + PICBED_QINIU_BUCKET: "Set Bucket", + PICBED_QINIU_PATH: "Set Path", + PICBED_QINIU_URL: "Set URL", + PICBED_QINIU_OPTIONS: "Set URL Suffix", + PICBED_QINIU_AREA: "Set Area", + PICBED_QINIU_MESSAGE_PATH: "Ex. test/", + PICBED_QINIU_MESSAGE_AREA: "Ex. z0", + PICBED_QINIU_MESSAGE_OPTIONS: "Ex. ?imageslim", + PICBED_QINIU_MESSAGE_URL: "Ex. https://xxx.yyy.glb.clouddn.com", + + // imgur + PICBED_IMGUR: "Imgur", + PICBED_IMGUR_CLIENTID: "Set ClientId", + PICBED_IMGUR_PROXY: "Set Proxy", + PICBED_IMGUR_MESSAGE_PROXY: "Ex. http://127.0.0.1:1080", + + // upyun + PICBED_UPYUN: "Upyun", + PICBED_UPYUN_BUCKET: "Set Bucket", + PICBED_UPYUN_OPERATOR: "Set Operator", + PICBED_UPYUN_PASSWORD: "Set Operator Password", + PICBED_UPYUN_PATH: "Set Path", + PICBED_UPYUN_URL: "Set URL", + PICBED_UPYUN_OPTIONS: "Set URL Suffix", + PICBED_UPYUN_MESSAGE_OPERATOR: "Ex. me", + PICBED_UPYUN_MESSAGE_PASSWORD: "Please type the operator password", + PICBED_UPYUN_MESSAGE_URL: "Ex. http://xxx.test.upcdn.net", + PICBED_UPYUN_MESSAGE_OPTIONS: "Ex. !imgslim", + PICBED_UPYUN_MESSAGE_PATH: "Ex. test/", + + // Plugin Handler + PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS: "Plugin installed successfully", + PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED: "Plugin installation failed", + PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_REASON: + "Plugin installation failed, error code is ${code}, error log is \n ${data}", + PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_PATH: + "Plugin installation failed, please enter a valid plugin name or valid installation path", + PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS: "Plugin uninstalled successfully", + PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED: "Plugin uninstall failed", + PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_REASON: + "Plugin uninstall failed, error code is ${code}, error log is \n ${data}", + PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID: "Plugin uninstall failed, please enter a valid plugin name", + PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS: "Plugin updated successfully", + PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED: "Plugin update failed", + PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_REASON: "Plugin update failed, error code is ${code}, error log is \n ${data}", + PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_VALID: "Plugin update failed, please enter a valid plugin name", +} diff --git a/libs/Universal-PicGo-Core/src/i18n/index.ts b/libs/Universal-PicGo-Core/src/i18n/index.ts new file mode 100644 index 0000000..2503880 --- /dev/null +++ b/libs/Universal-PicGo-Core/src/i18n/index.ts @@ -0,0 +1,123 @@ +/* + * GNU GENERAL PUBLIC LICENSE + * Version 3, 29 June 2007 + * + * Copyright (C) 2024 Terwer, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ + +import { II18nManager, ILocale, IPicGo, IStringKeyMap } from "../types" +import { ObjectAdapter, I18n } from "@picgo/i18n" +import { ZH_CN, ILocalesKey, ILocales } from "./zh-CN" +import { EN } from "./en" +import { ZH_TW } from "./zh-TW" +import yaml from "js-yaml" +import _ from "lodash-es" +import { hasNodeEnv, win } from "universal-picgo-store" +import { ensureFileSync, pathExistsSync } from "../utils/nodeUtils" +import { browserPathJoin } from "../utils/browserUtils" + +const languageList: IStringKeyMap> = { + "zh-CN": ZH_CN, + "zh-TW": ZH_TW, + en: EN, +} + +class I18nManager implements II18nManager { + private readonly i18n: I18n + private readonly objectAdapter: ObjectAdapter + private readonly ctx: IPicGo + constructor(ctx: IPicGo) { + this.ctx = ctx + this.objectAdapter = new ObjectAdapter(languageList) + let language = this.ctx.getConfig("settings.language") || "zh-CN" + if (!languageList[language]) { + language = "zh-CN" // use default + } + this.i18n = new I18n({ + adapter: this.objectAdapter, + defaultLanguage: language, + }) + this.loadOutterI18n() + } + + translate(key: ILocalesKey | T, args?: IStringKeyMap): string { + return this.i18n.translate(key, args) || key + } + + setLanguage(language: string): void { + this.i18n.setLanguage(language) + this.ctx.saveConfig({ + "settings.language": language, + }) + } + + addLocale(language: string, locales: ILocale): boolean { + const originLocales = this.objectAdapter.getLocale(language) + if (!originLocales) { + return false + } + const newLocales = _.merge(originLocales, locales) + this.objectAdapter.setLocale(language, newLocales) + return true + } + + addLanguage(language: string, locales: ILocale): boolean { + const originLocales = this.objectAdapter.getLocale(language) + if (originLocales) { + return false + } + this.objectAdapter.setLocale(language, locales) + languageList[language] = locales + return true + } + + getLanguageList(): string[] { + return Object.keys(languageList) + } + + // =================================================================================================================== + private getOutterI18nFolder(): string { + let i18nFolder: string + if (hasNodeEnv) { + const fs = win.fs + const path = win.require("path") + i18nFolder = path.join(this.ctx.baseDir, "i18n-cli") + if (!pathExistsSync(fs, path, i18nFolder)) { + ensureFileSync(fs, path, i18nFolder) + } + } else { + i18nFolder = browserPathJoin(this.ctx.baseDir, "i18n-cli") + } + + return i18nFolder + } + + private loadOutterI18n(): void { + const i18nFolder = this.getOutterI18nFolder() + if (hasNodeEnv) { + const fs = win.fs + const path = win.require("path") + const files = fs.readdirSync(i18nFolder, { + withFileTypes: true, + }) + files.forEach((file: any) => { + if (file.isFile() && file.name.endsWith(".yml")) { + const i18nFilePath = path.join(i18nFolder, file.name) + const i18nFile = fs.readFileSync(i18nFilePath, "utf8") + try { + const i18nFileObj = yaml.load(i18nFile) as ILocales + languageList[file.name.replace(/\.yml$/, "")] = i18nFileObj + } catch (e) { + console.error(e) + } + } + }) + } else { + throw new Error("load outer i18n is not support in browser") + } + } +} + +export { I18nManager } diff --git a/libs/Universal-PicGo-Core/src/i18n/zh-CN.ts b/libs/Universal-PicGo-Core/src/i18n/zh-CN.ts new file mode 100644 index 0000000..de17fe5 --- /dev/null +++ b/libs/Universal-PicGo-Core/src/i18n/zh-CN.ts @@ -0,0 +1,116 @@ +/* eslint-disable no-template-curly-in-string */ +export const ZH_CN = { + UPLOAD_FAILED: "上传失败", + CHECK_SETTINGS: "请检查你的配置项是否正确", + CHECK_SETTINGS_AND_NETWORK: "请检查你的配置项以及网络", + UPLOAD_FAILED_REASON: "错误码:${code},请打开浏览器粘贴地址查看相关原因", + SERVER_ERROR: "服务端出错,请重试", + AUTH_FAILED: "认证失败", + + // smms + PICBED_SMMS: "SM.MS", + PICBED_SMMS_TOKEN: "设定Token", + PICBED_SMMS_BACKUP_DOMAIN: "备用上传域名", + PICBED_SMMS_MESSAGE_BACKUP_DOMAIN: "例如 smms.app", + + // Ali-cloud + PICBED_ALICLOUD: "阿里云OSS", + PICBED_ALICLOUD_ACCESSKEYID: "设定KeyId", + PICBED_ALICLOUD_ACCESSKEYSECRET: "设定KeySecret", + PICBED_ALICLOUD_BUCKET: "设定Bucket", + PICBED_ALICLOUD_AREA: "设定存储区域", + PICBED_ALICLOUD_PATH: "设定存储路径", + PICBED_ALICLOUD_CUSTOMURL: "设定自定义域名", + PICBED_ALICLOUD_OPTIONS: "设定网址后缀", + PICBED_ALICLOUD_MESSAGE_AREA: "例如:oss-cn-beijing", + PICBED_ALICLOUD_MESSAGE_PATH: "例如:test/", + PICBED_ALICLOUD_MESSAGE_OPTIONS: "例如:?x-oss-process=xxx", + PICBED_ALICLOUD_MESSAGE_CUSTOMURL: "例如:https://test.com", + + // Tencent-cloud + PICBED_TENCENTCLOUD: "腾讯云COS", + PICBED_TENCENTCLOUD_VERSION: "COS版本", + PICBED_TENCENTCLOUD_SECRETID: "设定SecretId", + PICBED_TENCENTCLOUD_SECRETKEY: "设定SecretKey", + PICBED_TENCENTCLOUD_APPID: "设定AppId", + PICBED_TENCENTCLOUD_BUCKET: "设定Bucket", + PICBED_TENCENTCLOUD_AREA: "设定存储区域", + PICBED_TENCENTCLOUD_ENDPOINT: "设定Endpoint", + PICBED_TENCENTCLOUD_PATH: "设定存储路径", + PICBED_TENCENTCLOUD_OPTIONS: "设定网址后缀", + PICBED_TENCENTCLOUD_CUSTOMURL: "设定自定义域名", + PICBED_TENCENTCLOUD_SLIM: "极智压缩", + PICBED_TENCENTCLOUD_SLIM_TIP: + "图片极智压缩,详情请参考[文档说明](https://cloud.tencent.com/document/product/436/49259)", + PICBED_TENCENTCLOUD_SLIM_CONFIRM: "开启", + PICBED_TENCENTCLOUD_SLIM_CANCEL: "关闭", + PICBED_TENCENTCLOUD_MESSAGE_APPID: "例如:1234567890", + PICBED_TENCENTCLOUD_MESSAGE_AREA: "例如:ap-beijing", + PICBED_TENCENTCLOUD_MESSAGE_ENDPOINT: "例如:cos-internal.accelerate.tencentcos.cn", + PICBED_TENCENTCLOUD_MESSAGE_PATH: "例如:test/", + PICBED_TENCENTCLOUD_MESSAGE_CUSTOMURL: "例如:https://test.com", + PICBED_TENCENTCLOUD_MESSAGE_OPTIONS: "例如:?imageMogr2", + + // GitHub + PICBED_GITHUB: "GitHub", + PICBED_GITHUB_TOKEN: "设定Token", + PICBED_GITHUB_REPO: "设定仓库名", + PICBED_GITHUB_PATH: "设定存储路径", + PICBED_GITHUB_BRANCH: "设定分支名", + PICBED_GITHUB_CUSTOMURL: "设定自定义域名", + PICBED_GITHUB_MESSAGE_REPO: "格式:username/repo", + PICBED_GITHUB_MESSAGE_BRANCH: "例如:main", + PICBED_GITHUB_MESSAGE_PATH: "例如:test/", + PICBED_GITHUB_MESSAGE_CUSTOMURL: "例如:https://test.com", + + // qiniu + PICBED_QINIU: "七牛云", + PICBED_QINIU_ACCESSKEY: "设定AccessKey", + PICBED_QINIU_SECRETKEY: "设定SecretKey", + PICBED_QINIU_BUCKET: "设定Bucket", + PICBED_QINIU_PATH: "设定存储路径", + PICBED_QINIU_URL: "设定访问网址", + PICBED_QINIU_OPTIONS: "设定网址后缀", + PICBED_QINIU_AREA: "设定存储区域", + PICBED_QINIU_MESSAGE_PATH: "例如:test/", + PICBED_QINIU_MESSAGE_AREA: "例如:z0", + PICBED_QINIU_MESSAGE_OPTIONS: "例如:?imageslim", + PICBED_QINIU_MESSAGE_URL: "例如:https://xxx.yyy.glb.clouddn.com", + + // imgur + PICBED_IMGUR: "Imgur", + PICBED_IMGUR_CLIENTID: "设定ClientId", + PICBED_IMGUR_PROXY: "设定代理", + PICBED_IMGUR_MESSAGE_PROXY: "例如:http://127.0.0.1:1080", + + // upyun + PICBED_UPYUN: "又拍云", + PICBED_UPYUN_BUCKET: "设定Bucket", + PICBED_UPYUN_OPERATOR: "设定操作员", + PICBED_UPYUN_PASSWORD: "设定操作员密码", + PICBED_UPYUN_PATH: "设定存储路径", + PICBED_UPYUN_URL: "设定加速域名", + PICBED_UPYUN_OPTIONS: "设定网址后缀", + PICBED_UPYUN_MESSAGE_OPERATOR: "例如:me", + PICBED_UPYUN_MESSAGE_PASSWORD: "输入操作员密码", + PICBED_UPYUN_MESSAGE_URL: "例如:http://xxx.test.upcdn.net", + PICBED_UPYUN_MESSAGE_OPTIONS: "例如:!imgslim", + PICBED_UPYUN_MESSAGE_PATH: "例如:test/", + + // Plugin Handler + PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS: "插件安装成功", + PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED: "插件安装失败", + PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_REASON: "插件安装失败,失败码为${code},错误日志为 \n ${data}", + PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_PATH: "插件安装失败,请输入合法插件名或合法安装路径", + PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS: "插件卸载成功", + PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED: "插件卸载失败", + PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_REASON: "插件卸载失败,失败码为${code},错误日志为 \n ${data}", + PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID: "插件卸载失败,请输入合法插件名", + PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS: "插件更新成功", + PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED: "插件更新失败", + PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_REASON: "插件更新失败,失败码为${code},错误日志为 \n ${data}", + PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_VALID: "插件更新失败,请输入合法插件名", +} + +export type ILocalesKey = keyof typeof ZH_CN +export type ILocales = typeof ZH_CN diff --git a/libs/Universal-PicGo-Core/src/i18n/zh-TW.ts b/libs/Universal-PicGo-Core/src/i18n/zh-TW.ts new file mode 100644 index 0000000..ff7f667 --- /dev/null +++ b/libs/Universal-PicGo-Core/src/i18n/zh-TW.ts @@ -0,0 +1,115 @@ +import { ILocales } from "./zh-CN" + +/* eslint-disable no-template-curly-in-string */ +export const ZH_TW: ILocales = { + UPLOAD_FAILED: "上傳失敗", + CHECK_SETTINGS: "請檢查你的設定是否正確", + CHECK_SETTINGS_AND_NETWORK: "請檢查你的設定及網路", + UPLOAD_FAILED_REASON: "錯誤碼:${code},請打開瀏覽器貼上地址查看相關原因", + SERVER_ERROR: "伺服器出錯,請重試", + AUTH_FAILED: "認證失敗", + + // smms + PICBED_SMMS: "SM.MS", + PICBED_SMMS_TOKEN: "設定Token", + PICBED_SMMS_BACKUP_DOMAIN: "備用上傳網址", + PICBED_SMMS_MESSAGE_BACKUP_DOMAIN: "例如 smms.app", + + // Ali-cloud + PICBED_ALICLOUD: "阿里云OSS", + PICBED_ALICLOUD_ACCESSKEYID: "設定KeyId", + PICBED_ALICLOUD_ACCESSKEYSECRET: "設定KeySecret", + PICBED_ALICLOUD_BUCKET: "設定Bucket", + PICBED_ALICLOUD_AREA: "設定儲存區域", + PICBED_ALICLOUD_PATH: "設定儲存路徑", + PICBED_ALICLOUD_CUSTOMURL: "設定自訂網址", + PICBED_ALICLOUD_OPTIONS: "設定網址後綴", + PICBED_ALICLOUD_MESSAGE_AREA: "例如:oss-cn-beijing", + PICBED_ALICLOUD_MESSAGE_PATH: "例如:test/", + PICBED_ALICLOUD_MESSAGE_OPTIONS: "例如:?x-oss-process=xxx", + PICBED_ALICLOUD_MESSAGE_CUSTOMURL: "例如:https://test.com", + + // Tencent-cloud + PICBED_TENCENTCLOUD: "騰訊云COS", + PICBED_TENCENTCLOUD_VERSION: "COS版本", + PICBED_TENCENTCLOUD_SECRETID: "設定SecretId", + PICBED_TENCENTCLOUD_SECRETKEY: "設定SecretKey", + PICBED_TENCENTCLOUD_APPID: "設定AppId", + PICBED_TENCENTCLOUD_BUCKET: "設定Bucket", + PICBED_TENCENTCLOUD_AREA: "設定儲存區域", + PICBED_TENCENTCLOUD_ENDPOINT: "設定Endpoint", + PICBED_TENCENTCLOUD_PATH: "設定儲存路徑", + PICBED_TENCENTCLOUD_OPTIONS: "設定網址後綴", + PICBED_TENCENTCLOUD_SLIM: "極智壓縮", + PICBED_TENCENTCLOUD_SLIM_CANCEL: "關閉", + PICBED_TENCENTCLOUD_SLIM_CONFIRM: "開啓", + PICBED_TENCENTCLOUD_SLIM_TIP: + "圖片極智壓縮,詳情請參考[文檔說明](https://cloud.tencent.com/document/product/436/49259)", + PICBED_TENCENTCLOUD_CUSTOMURL: "設定自訂網址", + PICBED_TENCENTCLOUD_MESSAGE_APPID: "例如:1234567890", + PICBED_TENCENTCLOUD_MESSAGE_AREA: "例如:ap-beijing", + PICBED_TENCENTCLOUD_MESSAGE_ENDPOINT: "例如:cos-internal.accelerate.tencentcos.cn", + PICBED_TENCENTCLOUD_MESSAGE_PATH: "例如:test/", + PICBED_TENCENTCLOUD_MESSAGE_CUSTOMURL: "例如:https://test.com", + PICBED_TENCENTCLOUD_MESSAGE_OPTIONS: "例如:?imageMogr2", + + // GitHub + PICBED_GITHUB: "GitHub", + PICBED_GITHUB_TOKEN: "設定Token", + PICBED_GITHUB_REPO: "設定倉庫名稱", + PICBED_GITHUB_PATH: "設定儲存路徑", + PICBED_GITHUB_BRANCH: "設定分支名稱", + PICBED_GITHUB_CUSTOMURL: "設定自訂網址", + PICBED_GITHUB_MESSAGE_REPO: "格式:username/repo", + PICBED_GITHUB_MESSAGE_BRANCH: "例如:main", + PICBED_GITHUB_MESSAGE_PATH: "例如:test/", + PICBED_GITHUB_MESSAGE_CUSTOMURL: "例如:https://test.com", + + // qiniu + PICBED_QINIU: "七牛云", + PICBED_QINIU_ACCESSKEY: "設定AccessKey", + PICBED_QINIU_SECRETKEY: "設定SecretKey", + PICBED_QINIU_BUCKET: "設定Bucket", + PICBED_QINIU_PATH: "設定儲存路徑", + PICBED_QINIU_URL: "設定訪問網址", + PICBED_QINIU_OPTIONS: "設定網址後綴", + PICBED_QINIU_AREA: "設定儲存區域", + PICBED_QINIU_MESSAGE_PATH: "例如:test/", + PICBED_QINIU_MESSAGE_AREA: "例如:z0", + PICBED_QINIU_MESSAGE_OPTIONS: "例如:?imageslim", + PICBED_QINIU_MESSAGE_URL: "例如:https://xxx.yyy.glb.clouddn.com", + + // imgur + PICBED_IMGUR: "Imgur", + PICBED_IMGUR_CLIENTID: "設定ClientId", + PICBED_IMGUR_PROXY: "設定PROXY", + PICBED_IMGUR_MESSAGE_PROXY: "例如:http://127.0.0.1:1080", + + // upyun + PICBED_UPYUN: "又拍云", + PICBED_UPYUN_BUCKET: "設定Bucket", + PICBED_UPYUN_OPERATOR: "設定操作員", + PICBED_UPYUN_PASSWORD: "設定操作員密碼", + PICBED_UPYUN_PATH: "設定儲存路徑", + PICBED_UPYUN_URL: "設定加速網址", + PICBED_UPYUN_OPTIONS: "設定網址後綴", + PICBED_UPYUN_MESSAGE_OPERATOR: "例如:me", + PICBED_UPYUN_MESSAGE_PASSWORD: "輸入操作員密碼", + PICBED_UPYUN_MESSAGE_URL: "例如:http://xxx.test.upcdn.net", + PICBED_UPYUN_MESSAGE_OPTIONS: "例如:!imgslim", + PICBED_UPYUN_MESSAGE_PATH: "例如:test/", + + // Plugin Handler + PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS: "插件安裝成功", + PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED: "插件安裝失敗", + PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_REASON: "插件安裝失敗,失敗碼為${code},錯誤紀錄為 \n ${data}", + PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_PATH: "插件安裝失敗,請輸入正確的插件名稱或正確的安裝路徑", + PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS: "插件卸載成功", + PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED: "插件卸載失敗", + PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_REASON: "插件卸載失敗,失敗碼為${code},錯誤紀錄為 \n ${data}", + PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID: "插件卸載失敗,請輸入正確的插件名稱", + PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS: "插件更新成功", + PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED: "插件更新失敗", + PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_REASON: "插件更新失敗,失敗碼為${code},錯誤紀錄為 \n ${data}", + PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_VALID: "插件更新失敗,請輸入正確的插件名稱", +} diff --git a/libs/Universal-PicGo-Core/src/utils/browserUtils.ts b/libs/Universal-PicGo-Core/src/utils/browserUtils.ts new file mode 100644 index 0000000..0919eb6 --- /dev/null +++ b/libs/Universal-PicGo-Core/src/utils/browserUtils.ts @@ -0,0 +1,37 @@ +/* + * GNU GENERAL PUBLIC LICENSE + * Version 3, 29 June 2007 + * + * Copyright (C) 2024 Terwer, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ + +/** + * 获取浏览器目录 + * + * @param path 完整的路径 + */ +export const getBrowserDirectoryPath = (path: string) => { + const parts = path.split("/") + parts.pop() + return parts.join("/") +} + +/** + * 浏览器路径拼接 + * + * @param paths 路径数组 + */ +export const browserPathJoin = (...paths: string[]) => { + // 过滤掉空路径 + const filteredPaths = paths.filter((path) => path && path.trim() !== "") + + // 使用斜杠连接路径 + const joinedPath = filteredPaths.join("/") + + // 处理多余的斜杠 + const normalizedPath = joinedPath.replace(/\/{2,}/g, "/") + + return normalizedPath +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f351601..769df4a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,12 @@ importers: libs/Universal-PicGo-Core: dependencies: + '@picgo/i18n': + specifier: ^1.0.0 + version: 1.0.0 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 universal-picgo-store: specifier: workspace:* version: link:../Universal-PicGo-Store @@ -1246,6 +1252,13 @@ packages: - supports-color dev: true + /@picgo/i18n@1.0.0: + resolution: {integrity: sha512-D0fqwox9AZ1pnvgFqBKQe+16U08FkPLnUW1wQSBEdn+EvI48IC3jIWDTZd1MSQzXeODnh/w4eAiUyARrf2Hzig==} + dependencies: + chalk: 4.1.2 + tslib: 2.6.2 + dev: false + /@pkgr/core@0.1.1: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -2728,7 +2741,6 @@ packages: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - dev: true /chalk@5.3.0: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} @@ -4167,7 +4179,6 @@ packages: /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - dev: true /has-own-prop@2.0.0: resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} @@ -6331,7 +6342,6 @@ packages: engines: {node: '>=8'} dependencies: has-flag: 4.0.0 - dev: true /supports-color@8.1.1: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} @@ -6581,7 +6591,6 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - dev: true /tsutils@3.21.0(typescript@4.9.5): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}