@talex-touch/utils 1.0.42 → 1.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintcache +1 -0
- package/__tests__/cloud-sync-sdk.test.ts +442 -0
- package/__tests__/icons/icons.test.ts +84 -0
- package/__tests__/plugin-sdk-lifecycle.test.ts +130 -0
- package/__tests__/power-sdk.test.ts +143 -0
- package/__tests__/preset-export-types.test.ts +108 -0
- package/__tests__/search/fuzzy-match.test.ts +137 -0
- package/__tests__/transport/port-policy.test.ts +44 -0
- package/__tests__/transport-domain-sdks.test.ts +152 -0
- package/__tests__/types/update.test.ts +67 -0
- package/account/account-sdk.ts +915 -0
- package/account/index.ts +2 -0
- package/account/types.ts +321 -0
- package/analytics/client.ts +136 -0
- package/analytics/index.ts +2 -0
- package/analytics/types.ts +156 -0
- package/animation/auto-resize.ts +322 -0
- package/animation/window-node.ts +26 -19
- package/auth/clerk-types.ts +12 -30
- package/auth/index.ts +0 -2
- package/auth/useAuthState.ts +6 -14
- package/base/index.ts +2 -0
- package/base/log-level.ts +105 -0
- package/channel/index.ts +170 -69
- package/cloud-sync/cloud-sync-sdk.ts +450 -0
- package/cloud-sync/index.ts +1 -0
- package/common/file-scan-utils.ts +17 -9
- package/common/index.ts +4 -0
- package/common/logger/index.ts +46 -0
- package/common/logger/logger-manager.ts +303 -0
- package/common/logger/module-logger.ts +270 -0
- package/common/logger/transport-logger.ts +234 -0
- package/common/logger/types.ts +93 -0
- package/common/search/gather.ts +48 -6
- package/common/search/index.ts +8 -0
- package/common/storage/constants.ts +13 -0
- package/common/storage/entity/app-settings.ts +245 -0
- package/common/storage/entity/index.ts +3 -0
- package/common/storage/entity/layout-atom-types.ts +147 -0
- package/common/storage/entity/openers.ts +1 -0
- package/common/storage/entity/preset-cloud-api.ts +132 -0
- package/common/storage/entity/preset-export-types.ts +256 -0
- package/common/storage/entity/shortcut-settings.ts +1 -0
- package/common/storage/shortcut-storage.ts +11 -0
- package/common/utils/clone-diagnostics.ts +105 -0
- package/common/utils/file.ts +16 -8
- package/common/utils/index.ts +6 -2
- package/common/utils/payload-preview.ts +173 -0
- package/common/utils/polling.ts +167 -13
- package/common/utils/safe-path.ts +103 -0
- package/common/utils/safe-shell.ts +115 -0
- package/common/utils/task-queue.ts +4 -1
- package/core-box/builder/tuff-builder.ts +0 -1
- package/core-box/index.ts +1 -1
- package/core-box/recommendation.ts +38 -1
- package/core-box/tuff/tuff-dsl.ts +32 -0
- package/electron/download-manager.ts +10 -7
- package/electron/env-tool.ts +42 -40
- package/electron/index.ts +0 -1
- package/env/index.ts +156 -0
- package/eslint.config.js +55 -0
- package/i18n/index.ts +62 -0
- package/i18n/locales/en.json +226 -0
- package/i18n/locales/zh.json +226 -0
- package/i18n/message-keys.ts +236 -0
- package/i18n/resolver.ts +181 -0
- package/icons/index.ts +257 -0
- package/icons/svg.ts +69 -0
- package/index.ts +9 -1
- package/intelligence/client.ts +72 -42
- package/market/constants.ts +9 -5
- package/market/index.ts +1 -1
- package/market/types.ts +19 -4
- package/package.json +15 -5
- package/permission/index.ts +143 -46
- package/permission/legacy.ts +26 -0
- package/permission/registry.ts +304 -0
- package/permission/types.ts +164 -0
- package/plugin/channel.ts +68 -39
- package/plugin/index.ts +80 -7
- package/plugin/install.ts +3 -0
- package/plugin/log/types.ts +22 -5
- package/plugin/node/logger-manager.ts +11 -3
- package/plugin/node/logger.ts +24 -17
- package/plugin/preload.ts +25 -2
- package/plugin/providers/index.ts +4 -4
- package/plugin/providers/market-client.ts +6 -3
- package/plugin/providers/npm-provider.ts +22 -7
- package/plugin/providers/tpex-provider.ts +22 -8
- package/plugin/sdk/box-items.ts +14 -0
- package/plugin/sdk/box-sdk.ts +64 -0
- package/plugin/sdk/channel.ts +119 -4
- package/plugin/sdk/clipboard.ts +26 -12
- package/plugin/sdk/cloud-sync.ts +113 -0
- package/plugin/sdk/common.ts +19 -11
- package/plugin/sdk/core-box.ts +6 -15
- package/plugin/sdk/division-box.ts +160 -65
- package/plugin/sdk/examples/storage-onDidChange-example.js +5 -2
- package/plugin/sdk/feature-sdk.ts +111 -76
- package/plugin/sdk/flow.ts +146 -45
- package/plugin/sdk/hooks/bridge.ts +13 -6
- package/plugin/sdk/hooks/life-cycle.ts +35 -16
- package/plugin/sdk/index.ts +14 -3
- package/plugin/sdk/intelligence.ts +87 -0
- package/plugin/sdk/meta/README.md +179 -0
- package/plugin/sdk/meta-sdk.ts +244 -0
- package/plugin/sdk/notification.ts +9 -0
- package/plugin/sdk/plugin-info.ts +64 -0
- package/plugin/sdk/power.ts +155 -0
- package/plugin/sdk/recommend.ts +21 -0
- package/plugin/sdk/service/index.ts +12 -8
- package/plugin/sdk/sqlite.ts +141 -0
- package/plugin/sdk/storage.ts +2 -6
- package/plugin/sdk/system.ts +2 -9
- package/plugin/sdk/temp-files.ts +41 -0
- package/plugin/sdk/touch-sdk.ts +18 -0
- package/plugin/sdk/types.ts +44 -4
- package/plugin/sdk/window/index.ts +12 -9
- package/plugin/sdk-version.ts +231 -0
- package/preload/renderer.ts +3 -2
- package/renderer/hooks/arg-mapper.ts +16 -2
- package/renderer/hooks/index.ts +13 -0
- package/renderer/hooks/initialize.ts +2 -1
- package/renderer/hooks/use-agent-market-sdk.ts +7 -0
- package/renderer/hooks/use-agent-market.ts +106 -0
- package/renderer/hooks/use-agents-sdk.ts +7 -0
- package/renderer/hooks/use-app-sdk.ts +7 -0
- package/renderer/hooks/use-channel.ts +33 -4
- package/renderer/hooks/use-download-sdk.ts +21 -0
- package/renderer/hooks/use-intelligence-sdk.ts +7 -0
- package/renderer/hooks/use-intelligence-stats.ts +290 -0
- package/renderer/hooks/use-intelligence.ts +55 -214
- package/renderer/hooks/use-market-sdk.ts +16 -0
- package/renderer/hooks/use-notification-sdk.ts +7 -0
- package/renderer/hooks/use-permission-sdk.ts +7 -0
- package/renderer/hooks/use-permission.ts +325 -0
- package/renderer/hooks/use-platform-sdk.ts +7 -0
- package/renderer/hooks/use-plugin-sdk.ts +16 -0
- package/renderer/hooks/use-settings-sdk.ts +7 -0
- package/renderer/hooks/use-update-sdk.ts +21 -0
- package/renderer/index.ts +1 -0
- package/renderer/ref.ts +19 -10
- package/renderer/shared/components/SharedPluginDetailContent.vue +84 -0
- package/renderer/shared/components/SharedPluginDetailHeader.vue +116 -0
- package/renderer/shared/components/SharedPluginDetailMetaList.vue +39 -0
- package/renderer/shared/components/SharedPluginDetailReadme.vue +45 -0
- package/renderer/shared/components/SharedPluginDetailVersions.vue +98 -0
- package/renderer/shared/components/index.ts +5 -0
- package/renderer/shared/components/shims-vue.d.ts +5 -0
- package/renderer/shared/index.ts +2 -0
- package/renderer/shared/plugin-detail.ts +62 -0
- package/renderer/storage/app-settings.ts +3 -1
- package/renderer/storage/base-storage.ts +508 -82
- package/renderer/storage/intelligence-storage.ts +31 -40
- package/renderer/storage/openers.ts +3 -1
- package/renderer/storage/storage-subscription.ts +126 -42
- package/renderer/touch-sdk/env.ts +10 -10
- package/renderer/touch-sdk/index.ts +114 -18
- package/renderer/touch-sdk/terminal.ts +24 -13
- package/search/feature-matcher.ts +279 -0
- package/search/fuzzy-match.ts +64 -34
- package/search/index.ts +10 -0
- package/search/levenshtein-utils.ts +17 -11
- package/transport/errors.ts +310 -0
- package/transport/event/builder.ts +378 -0
- package/transport/event/index.ts +7 -0
- package/transport/event/types.ts +292 -0
- package/transport/events/index.ts +2670 -0
- package/transport/events/meta-overlay.ts +79 -0
- package/transport/events/types/agents.ts +177 -0
- package/transport/events/types/app-index.ts +9 -0
- package/transport/events/types/app.ts +475 -0
- package/transport/events/types/box-item.ts +222 -0
- package/transport/events/types/clipboard.ts +80 -0
- package/transport/events/types/core-box.ts +534 -0
- package/transport/events/types/device-idle.ts +7 -0
- package/transport/events/types/division-box.ts +99 -0
- package/transport/events/types/download.ts +115 -0
- package/transport/events/types/file-index.ts +73 -0
- package/transport/events/types/flow.ts +149 -0
- package/transport/events/types/index.ts +70 -0
- package/transport/events/types/market.ts +39 -0
- package/transport/events/types/meta-overlay.ts +184 -0
- package/transport/events/types/notification.ts +140 -0
- package/transport/events/types/permission.ts +90 -0
- package/transport/events/types/platform.ts +8 -0
- package/transport/events/types/plugin.ts +620 -0
- package/transport/events/types/sentry.ts +20 -0
- package/transport/events/types/storage.ts +208 -0
- package/transport/events/types/transport.ts +60 -0
- package/transport/events/types/tray.ts +16 -0
- package/transport/events/types/update.ts +78 -0
- package/transport/index.ts +139 -0
- package/transport/main.ts +2 -0
- package/transport/sdk/constants.ts +29 -0
- package/transport/sdk/domains/agents-market.ts +47 -0
- package/transport/sdk/domains/agents.ts +62 -0
- package/transport/sdk/domains/app.ts +48 -0
- package/transport/sdk/domains/disposable.ts +35 -0
- package/transport/sdk/domains/download.ts +139 -0
- package/transport/sdk/domains/index.ts +13 -0
- package/transport/sdk/domains/intelligence.ts +616 -0
- package/transport/sdk/domains/market.ts +35 -0
- package/transport/sdk/domains/notification.ts +62 -0
- package/transport/sdk/domains/permission.ts +85 -0
- package/transport/sdk/domains/platform.ts +19 -0
- package/transport/sdk/domains/plugin.ts +144 -0
- package/transport/sdk/domains/settings.ts +92 -0
- package/transport/sdk/domains/update.ts +64 -0
- package/transport/sdk/index.ts +60 -0
- package/transport/sdk/main-transport.ts +710 -0
- package/transport/sdk/main.ts +9 -0
- package/transport/sdk/plugin-transport.ts +654 -0
- package/transport/sdk/port-policy.ts +38 -0
- package/transport/sdk/renderer-transport.ts +1165 -0
- package/transport/types.ts +605 -0
- package/types/agent.ts +399 -0
- package/types/cloud-sync.ts +157 -0
- package/types/division-box.ts +31 -31
- package/types/download.ts +1 -0
- package/types/flow.ts +63 -12
- package/types/icon.ts +2 -1
- package/types/index.ts +5 -0
- package/types/intelligence.ts +166 -173
- package/types/modules/base.ts +2 -0
- package/types/path-browserify.d.ts +5 -0
- package/types/platform.ts +12 -0
- package/types/startup-info.ts +32 -0
- package/types/touch-app-core.ts +8 -8
- package/types/update.ts +94 -1
- package/vitest.config.ts +25 -0
- package/auth/useClerkConfig.ts +0 -40
- package/auth/useClerkProvider.ts +0 -52
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
{
|
|
2
|
+
"devServer": {
|
|
3
|
+
"disconnected": "开发服务器已断开",
|
|
4
|
+
"disconnectedDesc": "与开发服务器的连接已断开,可能是服务器崩溃或网络中断。",
|
|
5
|
+
"reconnected": "开发服务器已重连",
|
|
6
|
+
"reconnecting": "正在重连开发服务器...",
|
|
7
|
+
"checkServer": "请检查开发服务器是否正常运行,或尝试手动重连。",
|
|
8
|
+
"connectionLost": "开发服务器连接已断开",
|
|
9
|
+
"connectionRestored": "开发服务器连接已恢复"
|
|
10
|
+
},
|
|
11
|
+
"flowTransfer": {
|
|
12
|
+
"shareComplete": "分享完成",
|
|
13
|
+
"shareFailed": "分享失败",
|
|
14
|
+
"copiedToClipboard": "已复制到剪贴板",
|
|
15
|
+
"fileRevealed": "文件已显示",
|
|
16
|
+
"airdropReady": "AirDrop 已就绪",
|
|
17
|
+
"mailReady": "邮件已打开",
|
|
18
|
+
"messagesReady": "信息已打开"
|
|
19
|
+
},
|
|
20
|
+
"plugin": {
|
|
21
|
+
"loadFailed": "插件加载失败",
|
|
22
|
+
"manifestInvalid": "清单文件无效",
|
|
23
|
+
"dependencyMissing": "缺少依赖",
|
|
24
|
+
"versionMismatch": "版本不匹配",
|
|
25
|
+
"permissionDenied": "权限被拒绝",
|
|
26
|
+
"sdkVersionMissing": "插件未声明 SDK 版本",
|
|
27
|
+
"sdkVersionOutdated": "插件 SDK 版本过旧",
|
|
28
|
+
"permissionMissing": "缺少必需权限"
|
|
29
|
+
},
|
|
30
|
+
"permission": {
|
|
31
|
+
"category": {
|
|
32
|
+
"fs": "文件系统",
|
|
33
|
+
"clipboard": "剪贴板",
|
|
34
|
+
"network": "网络",
|
|
35
|
+
"system": "系统",
|
|
36
|
+
"intelligence": "Intelligence 能力",
|
|
37
|
+
"storage": "存储",
|
|
38
|
+
"window": "窗口"
|
|
39
|
+
},
|
|
40
|
+
"risk": {
|
|
41
|
+
"low": "低风险",
|
|
42
|
+
"medium": "中风险",
|
|
43
|
+
"high": "高风险"
|
|
44
|
+
},
|
|
45
|
+
"fs": {
|
|
46
|
+
"read": { "name": "读取文件", "desc": "读取用户文件系统中的文件" },
|
|
47
|
+
"write": { "name": "写入文件", "desc": "创建、修改或删除用户文件" },
|
|
48
|
+
"execute": { "name": "执行文件", "desc": "运行可执行文件或脚本" }
|
|
49
|
+
},
|
|
50
|
+
"clipboard": {
|
|
51
|
+
"read": { "name": "读取剪贴板", "desc": "访问剪贴板中的内容" },
|
|
52
|
+
"write": { "name": "写入剪贴板", "desc": "将内容复制到剪贴板" }
|
|
53
|
+
},
|
|
54
|
+
"network": {
|
|
55
|
+
"local": { "name": "本地网络", "desc": "访问本地网络资源" },
|
|
56
|
+
"internet": { "name": "互联网访问", "desc": "发送和接收互联网请求" },
|
|
57
|
+
"download": { "name": "下载文件", "desc": "从互联网下载文件到本地" }
|
|
58
|
+
},
|
|
59
|
+
"system": {
|
|
60
|
+
"shell": { "name": "执行命令", "desc": "运行系统命令或脚本" },
|
|
61
|
+
"notification": { "name": "系统通知", "desc": "发送系统通知" },
|
|
62
|
+
"tray": { "name": "托盘交互", "desc": "访问系统托盘功能" }
|
|
63
|
+
},
|
|
64
|
+
"intelligence": {
|
|
65
|
+
"basic": { "name": "基础 Intelligence", "desc": "使用基础 Intelligence 能力" },
|
|
66
|
+
"admin": { "name": "Intelligence 管理", "desc": "使用高风险 Intelligence 能力" },
|
|
67
|
+
"agents": { "name": "智能体", "desc": "调用智能体系统" }
|
|
68
|
+
},
|
|
69
|
+
"storage": {
|
|
70
|
+
"plugin": { "name": "插件存储", "desc": "使用插件私有存储空间" },
|
|
71
|
+
"shared": { "name": "共享存储", "desc": "访问跨插件共享存储" },
|
|
72
|
+
"sqlite": { "name": "插件 SQLite", "desc": "读写插件本地 SQLite 数据库" }
|
|
73
|
+
},
|
|
74
|
+
"window": {
|
|
75
|
+
"create": { "name": "创建窗口", "desc": "创建新窗口或视图" },
|
|
76
|
+
"capture": { "name": "屏幕截图", "desc": "捕获屏幕内容" }
|
|
77
|
+
},
|
|
78
|
+
"grant": "授予",
|
|
79
|
+
"revoke": "撤销",
|
|
80
|
+
"granted": "已授予",
|
|
81
|
+
"denied": "已拒绝",
|
|
82
|
+
"required": "必需",
|
|
83
|
+
"optional": "可选",
|
|
84
|
+
"allowOnce": "仅本次",
|
|
85
|
+
"allowAlways": "始终允许",
|
|
86
|
+
"requestTitle": "权限请求",
|
|
87
|
+
"requestDesc": "{plugin} 请求 {permission} 权限",
|
|
88
|
+
"enforcementDisabled": "权限校验已禁用",
|
|
89
|
+
"legacyPluginWarning": "此插件使用旧版 SDK,权限校验已跳过"
|
|
90
|
+
},
|
|
91
|
+
"widget": {
|
|
92
|
+
"compileFailed": "Widget 编译失败",
|
|
93
|
+
"unsupportedType": "不支持的 Widget 类型",
|
|
94
|
+
"invalidDependency": "无效的依赖",
|
|
95
|
+
"loadFailed": "Widget 加载失败"
|
|
96
|
+
},
|
|
97
|
+
"system": {
|
|
98
|
+
"networkError": "网络错误",
|
|
99
|
+
"timeout": "请求超时",
|
|
100
|
+
"unknownError": "未知错误",
|
|
101
|
+
"operationCancelled": "操作已取消"
|
|
102
|
+
},
|
|
103
|
+
"intelligence": {
|
|
104
|
+
"search": {
|
|
105
|
+
"placeholder": "搜索提供商...",
|
|
106
|
+
"clear": "清除"
|
|
107
|
+
},
|
|
108
|
+
"config": {
|
|
109
|
+
"api": {
|
|
110
|
+
"apiKeyRequired": "API Key 是必需的",
|
|
111
|
+
"baseUrlInvalid": "无效的 base URL 格式"
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"usage": {
|
|
115
|
+
"requests": "请求数",
|
|
116
|
+
"tokens": "Token 数",
|
|
117
|
+
"cost": "花销",
|
|
118
|
+
"successRate": "成功率",
|
|
119
|
+
"success": "成功",
|
|
120
|
+
"failure": "失败",
|
|
121
|
+
"promptTokens": "提示 Token",
|
|
122
|
+
"completionTokens": "完成 Token",
|
|
123
|
+
"today": "今天",
|
|
124
|
+
"thisMonth": "本月"
|
|
125
|
+
},
|
|
126
|
+
"audit": {
|
|
127
|
+
"records": "条记录",
|
|
128
|
+
"noLogs": "暂无审计日志"
|
|
129
|
+
},
|
|
130
|
+
"agents": {
|
|
131
|
+
"enabled": "已启用",
|
|
132
|
+
"disabled": "已禁用",
|
|
133
|
+
"empty": "暂无可用智能体",
|
|
134
|
+
"active": "活跃",
|
|
135
|
+
"inactive": "未激活",
|
|
136
|
+
"description": "描述",
|
|
137
|
+
"capabilities": "能力",
|
|
138
|
+
"task_success": "任务执行成功",
|
|
139
|
+
"task_failed": "任务执行失败"
|
|
140
|
+
},
|
|
141
|
+
"landing": {
|
|
142
|
+
"prompts": {
|
|
143
|
+
"title": "提示词管理",
|
|
144
|
+
"desc": "管理各种任务的 AI 提示词",
|
|
145
|
+
"editTitle": "编辑提示词",
|
|
146
|
+
"editDesc": "创建和管理自定义提示词",
|
|
147
|
+
"editButton": "打开编辑器",
|
|
148
|
+
"folderTitle": "提示词文件夹",
|
|
149
|
+
"folderDesc": "直接访问提示词文件",
|
|
150
|
+
"folderButton": "打开文件夹",
|
|
151
|
+
"statsTitle": "{count} 个提示词",
|
|
152
|
+
"statsDesc": "约 {words} 字",
|
|
153
|
+
"newPromptButton": "新建提示词",
|
|
154
|
+
"folderOpenSuccess": "提示词文件夹已打开",
|
|
155
|
+
"folderOpenFailed": "打开提示词文件夹失败",
|
|
156
|
+
"createPromptHint": "在编辑器中创建新提示词"
|
|
157
|
+
},
|
|
158
|
+
"capabilities": {
|
|
159
|
+
"title": "能力配置",
|
|
160
|
+
"desc": "配置 AI 能力和路由",
|
|
161
|
+
"manageTitle": "管理能力",
|
|
162
|
+
"manageDesc": "配置提供商绑定和模型",
|
|
163
|
+
"manageButton": "配置",
|
|
164
|
+
"auditTitle": "审计日志",
|
|
165
|
+
"auditDesc": "查看能力调用历史",
|
|
166
|
+
"auditButton": "查看日志",
|
|
167
|
+
"statsTitle": "{count} 次调用",
|
|
168
|
+
"statsDesc": "{total} 个能力,{bound} 个已绑定,平均 {freq} 次/天",
|
|
169
|
+
"statsButton": "查看指标"
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
"settings": {
|
|
174
|
+
"intelligence": {
|
|
175
|
+
"selectProvider": "选择默认模型",
|
|
176
|
+
"selectProviderPlaceholder": "选择提供商",
|
|
177
|
+
"selectProviderHint": "选择提供商以查看可用模型",
|
|
178
|
+
"testCapability": "测试能力",
|
|
179
|
+
"testing": "测试中...",
|
|
180
|
+
"testSuccess": "测试成功",
|
|
181
|
+
"testFailed": "测试失败",
|
|
182
|
+
"selectModel": "选择模型",
|
|
183
|
+
"defaultModel": "默认模型",
|
|
184
|
+
"latency": "延迟",
|
|
185
|
+
"capabilitySearchPlaceholder": "搜索能力...",
|
|
186
|
+
"capabilityListEmpty": "未找到能力",
|
|
187
|
+
"capabilitySummary": "{count} 个可用能力",
|
|
188
|
+
"providers": "提供商",
|
|
189
|
+
"addChannel": "添加通道",
|
|
190
|
+
"emptyProviders": "未配置提供商。点击添加通道开始。",
|
|
191
|
+
"promptFilterAll": "所有提示词",
|
|
192
|
+
"builtin": "内置",
|
|
193
|
+
"custom": "自定义",
|
|
194
|
+
"promptMetaDescription": "暂无描述",
|
|
195
|
+
"promptNewDefaultName": "新提示词 {index}",
|
|
196
|
+
"promptDescriptionPlaceholder": "输入提示词描述...",
|
|
197
|
+
"promptCreateSuccess": "提示词创建成功",
|
|
198
|
+
"promptDuplicateSuffix": "(副本)",
|
|
199
|
+
"promptDuplicateSuccess": "提示词复制成功",
|
|
200
|
+
"promptSaveSuccess": "提示词保存成功",
|
|
201
|
+
"promptSaveFailed": "提示词保存失败",
|
|
202
|
+
"promptDeleteConfirm": "确定要删除此提示词吗?",
|
|
203
|
+
"promptDeleteSuccess": "提示词删除成功",
|
|
204
|
+
"promptDeleteFailed": "提示词删除失败",
|
|
205
|
+
"promptCopySuccess": "提示词已复制到剪贴板",
|
|
206
|
+
"promptImportSuccess": "成功导入 {count} 个提示词",
|
|
207
|
+
"promptImportFailed": "提示词导入失败",
|
|
208
|
+
"promptExportEmpty": "没有可导出的自定义提示词",
|
|
209
|
+
"promptExportSuccess": "成功导出 {count} 个提示词",
|
|
210
|
+
"promptTimestampUnknown": "未知",
|
|
211
|
+
"promptSearchPlaceholder": "搜索提示词...",
|
|
212
|
+
"promptListEmpty": "未找到提示词",
|
|
213
|
+
"promptStatsLabel": "{builtin} 个内置,{custom} 个自定义",
|
|
214
|
+
"promptPageTitle": "提示词管理",
|
|
215
|
+
"promptPageDesc": "创建和管理各种任务的 AI 提示词",
|
|
216
|
+
"landing": {
|
|
217
|
+
"prompts": {
|
|
218
|
+
"folderOpenSuccess": "提示词文件夹已打开",
|
|
219
|
+
"folderOpenFailed": "打开提示词文件夹失败",
|
|
220
|
+
"statsDesc": "约 {words} 字",
|
|
221
|
+
"newPromptButton": "新建提示词"
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* I18n Message Keys
|
|
3
|
+
*
|
|
4
|
+
* Centralized message keys for backend-to-frontend communication.
|
|
5
|
+
* Backend sends `$i18n:key` format, frontend resolves to localized string.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* Backend: { message: '$i18n:devServer.disconnected' }
|
|
9
|
+
* Frontend: resolveI18nMessage(message) => '开发服务器连接已断开'
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* I18n message key prefix
|
|
14
|
+
*/
|
|
15
|
+
export const I18N_PREFIX = '$i18n:'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Dev Server related message keys
|
|
19
|
+
*/
|
|
20
|
+
export const DevServerKeys = {
|
|
21
|
+
DISCONNECTED: 'devServer.disconnected',
|
|
22
|
+
DISCONNECTED_DESC: 'devServer.disconnectedDesc',
|
|
23
|
+
RECONNECTED: 'devServer.reconnected',
|
|
24
|
+
RECONNECTING: 'devServer.reconnecting',
|
|
25
|
+
CHECK_SERVER: 'devServer.checkServer',
|
|
26
|
+
CONNECTION_LOST: 'devServer.connectionLost',
|
|
27
|
+
CONNECTION_RESTORED: 'devServer.connectionRestored',
|
|
28
|
+
} as const
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Flow Transfer related message keys
|
|
32
|
+
*/
|
|
33
|
+
export const FlowTransferKeys = {
|
|
34
|
+
SHARE_COMPLETE: 'flowTransfer.shareComplete',
|
|
35
|
+
SHARE_FAILED: 'flowTransfer.shareFailed',
|
|
36
|
+
COPIED_TO_CLIPBOARD: 'flowTransfer.copiedToClipboard',
|
|
37
|
+
FILE_REVEALED: 'flowTransfer.fileRevealed',
|
|
38
|
+
AIRDROP_READY: 'flowTransfer.airdropReady',
|
|
39
|
+
MAIL_READY: 'flowTransfer.mailReady',
|
|
40
|
+
MESSAGES_READY: 'flowTransfer.messagesReady',
|
|
41
|
+
} as const
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Plugin related message keys
|
|
45
|
+
*/
|
|
46
|
+
export const PluginKeys = {
|
|
47
|
+
LOAD_FAILED: 'plugin.loadFailed',
|
|
48
|
+
MANIFEST_INVALID: 'plugin.manifestInvalid',
|
|
49
|
+
DEPENDENCY_MISSING: 'plugin.dependencyMissing',
|
|
50
|
+
VERSION_MISMATCH: 'plugin.versionMismatch',
|
|
51
|
+
PERMISSION_DENIED: 'plugin.permissionDenied',
|
|
52
|
+
SDK_VERSION_MISSING: 'plugin.sdkVersionMissing',
|
|
53
|
+
SDK_VERSION_OUTDATED: 'plugin.sdkVersionOutdated',
|
|
54
|
+
PERMISSION_MISSING: 'plugin.permissionMissing',
|
|
55
|
+
} as const
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Permission related message keys
|
|
59
|
+
*/
|
|
60
|
+
export const PermissionKeys = {
|
|
61
|
+
// Categories
|
|
62
|
+
CATEGORY_FS: 'permission.category.fs',
|
|
63
|
+
CATEGORY_CLIPBOARD: 'permission.category.clipboard',
|
|
64
|
+
CATEGORY_NETWORK: 'permission.category.network',
|
|
65
|
+
CATEGORY_SYSTEM: 'permission.category.system',
|
|
66
|
+
CATEGORY_INTELLIGENCE: 'permission.category.intelligence',
|
|
67
|
+
CATEGORY_STORAGE: 'permission.category.storage',
|
|
68
|
+
CATEGORY_WINDOW: 'permission.category.window',
|
|
69
|
+
|
|
70
|
+
// Risk levels
|
|
71
|
+
RISK_LOW: 'permission.risk.low',
|
|
72
|
+
RISK_MEDIUM: 'permission.risk.medium',
|
|
73
|
+
RISK_HIGH: 'permission.risk.high',
|
|
74
|
+
|
|
75
|
+
// Filesystem permissions
|
|
76
|
+
FS_READ_NAME: 'permission.fs.read.name',
|
|
77
|
+
FS_READ_DESC: 'permission.fs.read.desc',
|
|
78
|
+
FS_WRITE_NAME: 'permission.fs.write.name',
|
|
79
|
+
FS_WRITE_DESC: 'permission.fs.write.desc',
|
|
80
|
+
FS_EXECUTE_NAME: 'permission.fs.execute.name',
|
|
81
|
+
FS_EXECUTE_DESC: 'permission.fs.execute.desc',
|
|
82
|
+
FS_TFILE_NAME: 'permission.fs.tfile.name',
|
|
83
|
+
FS_TFILE_DESC: 'permission.fs.tfile.desc',
|
|
84
|
+
|
|
85
|
+
// Clipboard permissions
|
|
86
|
+
CLIPBOARD_READ_NAME: 'permission.clipboard.read.name',
|
|
87
|
+
CLIPBOARD_READ_DESC: 'permission.clipboard.read.desc',
|
|
88
|
+
CLIPBOARD_WRITE_NAME: 'permission.clipboard.write.name',
|
|
89
|
+
CLIPBOARD_WRITE_DESC: 'permission.clipboard.write.desc',
|
|
90
|
+
|
|
91
|
+
// Network permissions
|
|
92
|
+
NETWORK_LOCAL_NAME: 'permission.network.local.name',
|
|
93
|
+
NETWORK_LOCAL_DESC: 'permission.network.local.desc',
|
|
94
|
+
NETWORK_INTERNET_NAME: 'permission.network.internet.name',
|
|
95
|
+
NETWORK_INTERNET_DESC: 'permission.network.internet.desc',
|
|
96
|
+
NETWORK_DOWNLOAD_NAME: 'permission.network.download.name',
|
|
97
|
+
NETWORK_DOWNLOAD_DESC: 'permission.network.download.desc',
|
|
98
|
+
|
|
99
|
+
// System permissions
|
|
100
|
+
SYSTEM_SHELL_NAME: 'permission.system.shell.name',
|
|
101
|
+
SYSTEM_SHELL_DESC: 'permission.system.shell.desc',
|
|
102
|
+
SYSTEM_NOTIFICATION_NAME: 'permission.system.notification.name',
|
|
103
|
+
SYSTEM_NOTIFICATION_DESC: 'permission.system.notification.desc',
|
|
104
|
+
SYSTEM_TRAY_NAME: 'permission.system.tray.name',
|
|
105
|
+
SYSTEM_TRAY_DESC: 'permission.system.tray.desc',
|
|
106
|
+
|
|
107
|
+
// Intelligence permissions
|
|
108
|
+
INTELLIGENCE_BASIC_NAME: 'permission.intelligence.basic.name',
|
|
109
|
+
INTELLIGENCE_BASIC_DESC: 'permission.intelligence.basic.desc',
|
|
110
|
+
INTELLIGENCE_ADMIN_NAME: 'permission.intelligence.admin.name',
|
|
111
|
+
INTELLIGENCE_ADMIN_DESC: 'permission.intelligence.admin.desc',
|
|
112
|
+
INTELLIGENCE_AGENTS_NAME: 'permission.intelligence.agents.name',
|
|
113
|
+
INTELLIGENCE_AGENTS_DESC: 'permission.intelligence.agents.desc',
|
|
114
|
+
|
|
115
|
+
// Storage permissions
|
|
116
|
+
STORAGE_PLUGIN_NAME: 'permission.storage.plugin.name',
|
|
117
|
+
STORAGE_PLUGIN_DESC: 'permission.storage.plugin.desc',
|
|
118
|
+
STORAGE_SHARED_NAME: 'permission.storage.shared.name',
|
|
119
|
+
STORAGE_SHARED_DESC: 'permission.storage.shared.desc',
|
|
120
|
+
STORAGE_SQLITE_NAME: 'permission.storage.sqlite.name',
|
|
121
|
+
STORAGE_SQLITE_DESC: 'permission.storage.sqlite.desc',
|
|
122
|
+
|
|
123
|
+
// Window permissions
|
|
124
|
+
WINDOW_CREATE_NAME: 'permission.window.create.name',
|
|
125
|
+
WINDOW_CREATE_DESC: 'permission.window.create.desc',
|
|
126
|
+
WINDOW_CAPTURE_NAME: 'permission.window.capture.name',
|
|
127
|
+
WINDOW_CAPTURE_DESC: 'permission.window.capture.desc',
|
|
128
|
+
|
|
129
|
+
// UI messages
|
|
130
|
+
GRANT: 'permission.grant',
|
|
131
|
+
REVOKE: 'permission.revoke',
|
|
132
|
+
GRANTED: 'permission.granted',
|
|
133
|
+
DENIED: 'permission.denied',
|
|
134
|
+
REQUIRED: 'permission.required',
|
|
135
|
+
OPTIONAL: 'permission.optional',
|
|
136
|
+
ALLOW_ONCE: 'permission.allowOnce',
|
|
137
|
+
ALLOW_ALWAYS: 'permission.allowAlways',
|
|
138
|
+
REQUEST_TITLE: 'permission.requestTitle',
|
|
139
|
+
REQUEST_DESC: 'permission.requestDesc',
|
|
140
|
+
ENFORCEMENT_DISABLED: 'permission.enforcementDisabled',
|
|
141
|
+
LEGACY_PLUGIN_WARNING: 'permission.legacyPluginWarning',
|
|
142
|
+
} as const
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Widget related message keys
|
|
146
|
+
*/
|
|
147
|
+
export const WidgetKeys = {
|
|
148
|
+
COMPILE_FAILED: 'widget.compileFailed',
|
|
149
|
+
UNSUPPORTED_TYPE: 'widget.unsupportedType',
|
|
150
|
+
INVALID_DEPENDENCY: 'widget.invalidDependency',
|
|
151
|
+
LOAD_FAILED: 'widget.loadFailed',
|
|
152
|
+
} as const
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* System related message keys
|
|
156
|
+
*/
|
|
157
|
+
export const SystemKeys = {
|
|
158
|
+
NETWORK_ERROR: 'system.networkError',
|
|
159
|
+
TIMEOUT: 'system.timeout',
|
|
160
|
+
UNKNOWN_ERROR: 'system.unknownError',
|
|
161
|
+
OPERATION_CANCELLED: 'system.operationCancelled',
|
|
162
|
+
} as const
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* All message keys
|
|
166
|
+
*/
|
|
167
|
+
export const MessageKeys = {
|
|
168
|
+
devServer: DevServerKeys,
|
|
169
|
+
flowTransfer: FlowTransferKeys,
|
|
170
|
+
plugin: PluginKeys,
|
|
171
|
+
permission: PermissionKeys,
|
|
172
|
+
widget: WidgetKeys,
|
|
173
|
+
system: SystemKeys,
|
|
174
|
+
} as const
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Create i18n message string
|
|
178
|
+
* @param key Message key (e.g., 'devServer.disconnected')
|
|
179
|
+
* @returns Formatted i18n message (e.g., '$i18n:devServer.disconnected')
|
|
180
|
+
*/
|
|
181
|
+
export function i18nMsg(key: string): string {
|
|
182
|
+
return `${I18N_PREFIX}${key}`
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Create i18n message with parameters
|
|
187
|
+
* @param key Message key
|
|
188
|
+
* @param params Parameters to pass to the message
|
|
189
|
+
* @returns Formatted i18n message with params
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* i18nMsgWithParams('plugin.loadFailed', { name: 'my-plugin' })
|
|
193
|
+
* // => '$i18n:plugin.loadFailed|{"name":"my-plugin"}'
|
|
194
|
+
*/
|
|
195
|
+
export function i18nMsgWithParams(key: string, params: Record<string, unknown>): string {
|
|
196
|
+
return `${I18N_PREFIX}${key}|${JSON.stringify(params)}`
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Check if a string is an i18n message
|
|
201
|
+
*/
|
|
202
|
+
export function isI18nMessage(str: string): boolean {
|
|
203
|
+
return str.startsWith(I18N_PREFIX)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Parse i18n message to extract key and params
|
|
208
|
+
*/
|
|
209
|
+
export function parseI18nMessage(str: string): { key: string, params?: Record<string, unknown> } | null {
|
|
210
|
+
if (!isI18nMessage(str)) {
|
|
211
|
+
return null
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const content = str.slice(I18N_PREFIX.length)
|
|
215
|
+
const pipeIndex = content.indexOf('|')
|
|
216
|
+
|
|
217
|
+
if (pipeIndex === -1) {
|
|
218
|
+
return { key: content }
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const key = content.slice(0, pipeIndex)
|
|
222
|
+
try {
|
|
223
|
+
const params = JSON.parse(content.slice(pipeIndex + 1))
|
|
224
|
+
return { key, params }
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
return { key }
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export type DevServerKey = typeof DevServerKeys[keyof typeof DevServerKeys]
|
|
232
|
+
export type FlowTransferKey = typeof FlowTransferKeys[keyof typeof FlowTransferKeys]
|
|
233
|
+
export type PluginKey = typeof PluginKeys[keyof typeof PluginKeys]
|
|
234
|
+
export type PermissionKey = typeof PermissionKeys[keyof typeof PermissionKeys]
|
|
235
|
+
export type WidgetKey = typeof WidgetKeys[keyof typeof WidgetKeys]
|
|
236
|
+
export type SystemKey = typeof SystemKeys[keyof typeof SystemKeys]
|
package/i18n/resolver.ts
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* I18n Message Resolver
|
|
3
|
+
*
|
|
4
|
+
* Frontend utility to resolve $i18n:key messages to localized strings.
|
|
5
|
+
* Works with both Vue i18n and standalone usage.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import enMessages from './locales/en.json'
|
|
9
|
+
import zhMessages from './locales/zh.json'
|
|
10
|
+
import { I18N_PREFIX, isI18nMessage, parseI18nMessage } from './message-keys'
|
|
11
|
+
|
|
12
|
+
type MessageLocale = 'en' | 'zh'
|
|
13
|
+
type Messages = typeof enMessages
|
|
14
|
+
|
|
15
|
+
const locales: Record<MessageLocale, Messages> = {
|
|
16
|
+
en: enMessages,
|
|
17
|
+
zh: zhMessages,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get nested value from object by dot-separated path
|
|
22
|
+
*/
|
|
23
|
+
function getNestedValue(obj: Record<string, unknown>, path: string): string | undefined {
|
|
24
|
+
const keys = path.split('.')
|
|
25
|
+
let current: unknown = obj
|
|
26
|
+
|
|
27
|
+
for (const key of keys) {
|
|
28
|
+
if (current === null || current === undefined || typeof current !== 'object') {
|
|
29
|
+
return undefined
|
|
30
|
+
}
|
|
31
|
+
current = (current as Record<string, unknown>)[key]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return typeof current === 'string' ? current : undefined
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Interpolate parameters into message
|
|
39
|
+
* @param message Message with placeholders like {name}
|
|
40
|
+
* @param params Parameters to interpolate
|
|
41
|
+
*/
|
|
42
|
+
function interpolate(message: string, params?: Record<string, unknown>): string {
|
|
43
|
+
if (!params)
|
|
44
|
+
return message
|
|
45
|
+
|
|
46
|
+
return message.replace(/\{(\w+)\}/g, (_, key) => {
|
|
47
|
+
return params[key] !== undefined ? String(params[key]) : `{${key}}`
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* I18n Message Resolver
|
|
53
|
+
*
|
|
54
|
+
* Resolves $i18n:key format messages to localized strings.
|
|
55
|
+
*/
|
|
56
|
+
export class I18nResolver {
|
|
57
|
+
private locale: MessageLocale = 'en'
|
|
58
|
+
private customMessages: Partial<Record<MessageLocale, Record<string, unknown>>> = {}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Set current locale
|
|
62
|
+
*/
|
|
63
|
+
setLocale(locale: MessageLocale): void {
|
|
64
|
+
this.locale = locale
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get current locale
|
|
69
|
+
*/
|
|
70
|
+
getLocale(): MessageLocale {
|
|
71
|
+
return this.locale
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Add custom messages for a locale
|
|
76
|
+
*/
|
|
77
|
+
addMessages(locale: MessageLocale, messages: Record<string, unknown>): void {
|
|
78
|
+
this.customMessages[locale] = {
|
|
79
|
+
...this.customMessages[locale],
|
|
80
|
+
...messages,
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Resolve a message string
|
|
86
|
+
*
|
|
87
|
+
* If the string starts with $i18n:, it will be resolved to a localized string.
|
|
88
|
+
* Otherwise, the original string is returned.
|
|
89
|
+
*
|
|
90
|
+
* @param str The message string to resolve
|
|
91
|
+
* @param fallbackLocale Fallback locale if message not found in current locale
|
|
92
|
+
*/
|
|
93
|
+
resolve(str: string, fallbackLocale: MessageLocale = 'en'): string {
|
|
94
|
+
if (!isI18nMessage(str)) {
|
|
95
|
+
return str
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const parsed = parseI18nMessage(str)
|
|
99
|
+
if (!parsed) {
|
|
100
|
+
return str
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const { key, params } = parsed
|
|
104
|
+
|
|
105
|
+
// Try current locale
|
|
106
|
+
let message = this.getMessage(key, this.locale)
|
|
107
|
+
|
|
108
|
+
// Try fallback locale
|
|
109
|
+
if (!message && this.locale !== fallbackLocale) {
|
|
110
|
+
message = this.getMessage(key, fallbackLocale)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Return key if no message found
|
|
114
|
+
if (!message) {
|
|
115
|
+
return key
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return interpolate(message, params)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Get message from locale
|
|
123
|
+
*/
|
|
124
|
+
private getMessage(key: string, locale: MessageLocale): string | undefined {
|
|
125
|
+
// Try custom messages first
|
|
126
|
+
const customMessage = getNestedValue(
|
|
127
|
+
this.customMessages[locale] as Record<string, unknown> || {},
|
|
128
|
+
key,
|
|
129
|
+
)
|
|
130
|
+
if (customMessage) {
|
|
131
|
+
return customMessage
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Try built-in messages
|
|
135
|
+
return getNestedValue(locales[locale] as unknown as Record<string, unknown>, key)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Singleton resolver instance
|
|
141
|
+
*/
|
|
142
|
+
export const i18nResolver = new I18nResolver()
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Resolve i18n message shorthand
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* resolveI18nMessage('$i18n:devServer.disconnected') // => 'Dev Server Disconnected'
|
|
149
|
+
* resolveI18nMessage('Hello World') // => 'Hello World' (unchanged)
|
|
150
|
+
*/
|
|
151
|
+
export function resolveI18nMessage(str: string): string {
|
|
152
|
+
return i18nResolver.resolve(str)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Create i18n message for backend use
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* createI18nMessage('devServer.disconnected') // => '$i18n:devServer.disconnected'
|
|
160
|
+
*/
|
|
161
|
+
export function createI18nMessage(key: string, params?: Record<string, unknown>): string {
|
|
162
|
+
if (params) {
|
|
163
|
+
return `${I18N_PREFIX}${key}|${JSON.stringify(params)}`
|
|
164
|
+
}
|
|
165
|
+
return `${I18N_PREFIX}${key}`
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Vue composable for i18n message resolution
|
|
170
|
+
*/
|
|
171
|
+
export function useI18nResolver() {
|
|
172
|
+
return {
|
|
173
|
+
resolve: resolveI18nMessage,
|
|
174
|
+
setLocale: (locale: MessageLocale) => i18nResolver.setLocale(locale),
|
|
175
|
+
getLocale: () => i18nResolver.getLocale(),
|
|
176
|
+
addMessages: (locale: MessageLocale, messages: Record<string, unknown>) =>
|
|
177
|
+
i18nResolver.addMessages(locale, messages),
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export type { MessageLocale, Messages }
|