@talex-touch/utils 1.0.40 → 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.
Files changed (235) hide show
  1. package/.eslintcache +1 -0
  2. package/__tests__/cloud-sync-sdk.test.ts +442 -0
  3. package/__tests__/icons/icons.test.ts +84 -0
  4. package/__tests__/plugin-sdk-lifecycle.test.ts +130 -0
  5. package/__tests__/power-sdk.test.ts +143 -0
  6. package/__tests__/preset-export-types.test.ts +108 -0
  7. package/__tests__/search/fuzzy-match.test.ts +137 -0
  8. package/__tests__/transport/port-policy.test.ts +44 -0
  9. package/__tests__/transport-domain-sdks.test.ts +152 -0
  10. package/__tests__/types/update.test.ts +67 -0
  11. package/account/account-sdk.ts +915 -0
  12. package/account/index.ts +2 -0
  13. package/account/types.ts +321 -0
  14. package/analytics/client.ts +136 -0
  15. package/analytics/index.ts +2 -0
  16. package/analytics/types.ts +156 -0
  17. package/animation/auto-resize.ts +322 -0
  18. package/animation/window-node.ts +26 -19
  19. package/auth/clerk-types.ts +12 -30
  20. package/auth/index.ts +0 -2
  21. package/auth/useAuthState.ts +6 -14
  22. package/base/index.ts +2 -0
  23. package/base/log-level.ts +105 -0
  24. package/channel/index.ts +170 -69
  25. package/cloud-sync/cloud-sync-sdk.ts +450 -0
  26. package/cloud-sync/index.ts +1 -0
  27. package/common/file-scan-utils.ts +17 -9
  28. package/common/index.ts +4 -0
  29. package/common/logger/index.ts +46 -0
  30. package/common/logger/logger-manager.ts +303 -0
  31. package/common/logger/module-logger.ts +270 -0
  32. package/common/logger/transport-logger.ts +234 -0
  33. package/common/logger/types.ts +93 -0
  34. package/common/search/gather.ts +48 -6
  35. package/common/search/index.ts +8 -0
  36. package/common/storage/constants.ts +13 -0
  37. package/common/storage/entity/app-settings.ts +245 -0
  38. package/common/storage/entity/index.ts +3 -0
  39. package/common/storage/entity/layout-atom-types.ts +147 -0
  40. package/common/storage/entity/openers.ts +1 -0
  41. package/common/storage/entity/preset-cloud-api.ts +132 -0
  42. package/common/storage/entity/preset-export-types.ts +256 -0
  43. package/common/storage/entity/shortcut-settings.ts +1 -0
  44. package/common/storage/shortcut-storage.ts +11 -0
  45. package/common/utils/clone-diagnostics.ts +105 -0
  46. package/common/utils/file.ts +16 -8
  47. package/common/utils/index.ts +6 -2
  48. package/common/utils/payload-preview.ts +173 -0
  49. package/common/utils/polling.ts +167 -13
  50. package/common/utils/safe-path.ts +103 -0
  51. package/common/utils/safe-shell.ts +115 -0
  52. package/common/utils/task-queue.ts +4 -1
  53. package/core-box/builder/tuff-builder.ts +0 -1
  54. package/core-box/index.ts +1 -1
  55. package/core-box/recommendation.ts +38 -1
  56. package/core-box/tuff/tuff-dsl.ts +97 -0
  57. package/electron/download-manager.ts +10 -7
  58. package/electron/env-tool.ts +42 -40
  59. package/electron/index.ts +0 -1
  60. package/env/index.ts +156 -0
  61. package/eslint.config.js +55 -0
  62. package/i18n/index.ts +62 -0
  63. package/i18n/locales/en.json +226 -0
  64. package/i18n/locales/zh.json +226 -0
  65. package/i18n/message-keys.ts +236 -0
  66. package/i18n/resolver.ts +181 -0
  67. package/icons/index.ts +257 -0
  68. package/icons/svg.ts +69 -0
  69. package/index.ts +9 -1
  70. package/intelligence/client.ts +72 -42
  71. package/market/constants.ts +21 -3
  72. package/market/index.ts +1 -1
  73. package/market/types.ts +20 -5
  74. package/package.json +15 -5
  75. package/permission/index.ts +143 -46
  76. package/permission/legacy.ts +26 -0
  77. package/permission/registry.ts +304 -0
  78. package/permission/types.ts +164 -0
  79. package/plugin/channel.ts +68 -39
  80. package/plugin/index.ts +82 -8
  81. package/plugin/install.ts +3 -0
  82. package/plugin/log/types.ts +22 -5
  83. package/plugin/node/logger-manager.ts +11 -3
  84. package/plugin/node/logger.ts +24 -17
  85. package/plugin/preload.ts +25 -2
  86. package/plugin/providers/index.ts +4 -0
  87. package/plugin/providers/market-client.ts +218 -0
  88. package/plugin/providers/npm-provider.ts +228 -0
  89. package/plugin/providers/tpex-provider.ts +297 -0
  90. package/plugin/providers/tpex-types.ts +34 -0
  91. package/plugin/sdk/box-items.ts +14 -0
  92. package/plugin/sdk/box-sdk.ts +64 -0
  93. package/plugin/sdk/channel.ts +119 -4
  94. package/plugin/sdk/clipboard.ts +26 -12
  95. package/plugin/sdk/cloud-sync.ts +113 -0
  96. package/plugin/sdk/common.ts +19 -11
  97. package/plugin/sdk/core-box.ts +6 -15
  98. package/plugin/sdk/division-box.ts +160 -65
  99. package/plugin/sdk/examples/storage-onDidChange-example.js +5 -2
  100. package/plugin/sdk/feature-sdk.ts +111 -76
  101. package/plugin/sdk/flow.ts +146 -45
  102. package/plugin/sdk/hooks/bridge.ts +113 -49
  103. package/plugin/sdk/hooks/life-cycle.ts +35 -16
  104. package/plugin/sdk/index.ts +14 -3
  105. package/plugin/sdk/intelligence.ts +87 -0
  106. package/plugin/sdk/meta/README.md +179 -0
  107. package/plugin/sdk/meta-sdk.ts +244 -0
  108. package/plugin/sdk/notification.ts +9 -0
  109. package/plugin/sdk/performance.ts +1 -16
  110. package/plugin/sdk/plugin-info.ts +64 -0
  111. package/plugin/sdk/power.ts +155 -0
  112. package/plugin/sdk/recommend.ts +21 -0
  113. package/plugin/sdk/service/index.ts +12 -8
  114. package/plugin/sdk/sqlite.ts +141 -0
  115. package/plugin/sdk/storage.ts +2 -6
  116. package/plugin/sdk/system.ts +2 -9
  117. package/plugin/sdk/temp-files.ts +41 -0
  118. package/plugin/sdk/touch-sdk.ts +18 -0
  119. package/plugin/sdk/types.ts +44 -4
  120. package/plugin/sdk/window/index.ts +12 -9
  121. package/plugin/sdk-version.ts +231 -0
  122. package/preload/renderer.ts +3 -2
  123. package/renderer/hooks/arg-mapper.ts +34 -6
  124. package/renderer/hooks/index.ts +13 -0
  125. package/renderer/hooks/initialize.ts +2 -1
  126. package/renderer/hooks/use-agent-market-sdk.ts +7 -0
  127. package/renderer/hooks/use-agent-market.ts +106 -0
  128. package/renderer/hooks/use-agents-sdk.ts +7 -0
  129. package/renderer/hooks/use-app-sdk.ts +7 -0
  130. package/renderer/hooks/use-channel.ts +33 -4
  131. package/renderer/hooks/use-download-sdk.ts +21 -0
  132. package/renderer/hooks/use-intelligence-sdk.ts +7 -0
  133. package/renderer/hooks/use-intelligence-stats.ts +290 -0
  134. package/renderer/hooks/use-intelligence.ts +202 -104
  135. package/renderer/hooks/use-market-sdk.ts +16 -0
  136. package/renderer/hooks/use-notification-sdk.ts +7 -0
  137. package/renderer/hooks/use-permission-sdk.ts +7 -0
  138. package/renderer/hooks/use-permission.ts +325 -0
  139. package/renderer/hooks/use-platform-sdk.ts +7 -0
  140. package/renderer/hooks/use-plugin-sdk.ts +16 -0
  141. package/renderer/hooks/use-settings-sdk.ts +7 -0
  142. package/renderer/hooks/use-update-sdk.ts +21 -0
  143. package/renderer/index.ts +1 -0
  144. package/renderer/ref.ts +19 -10
  145. package/renderer/shared/components/SharedPluginDetailContent.vue +84 -0
  146. package/renderer/shared/components/SharedPluginDetailHeader.vue +116 -0
  147. package/renderer/shared/components/SharedPluginDetailMetaList.vue +39 -0
  148. package/renderer/shared/components/SharedPluginDetailReadme.vue +45 -0
  149. package/renderer/shared/components/SharedPluginDetailVersions.vue +98 -0
  150. package/renderer/shared/components/index.ts +5 -0
  151. package/renderer/shared/components/shims-vue.d.ts +5 -0
  152. package/renderer/shared/index.ts +2 -0
  153. package/renderer/shared/plugin-detail.ts +62 -0
  154. package/renderer/storage/app-settings.ts +3 -1
  155. package/renderer/storage/base-storage.ts +508 -82
  156. package/renderer/storage/intelligence-storage.ts +37 -46
  157. package/renderer/storage/openers.ts +3 -1
  158. package/renderer/storage/storage-subscription.ts +126 -42
  159. package/renderer/touch-sdk/env.ts +10 -10
  160. package/renderer/touch-sdk/index.ts +114 -18
  161. package/renderer/touch-sdk/terminal.ts +24 -13
  162. package/search/feature-matcher.ts +279 -0
  163. package/search/fuzzy-match.ts +64 -34
  164. package/search/index.ts +10 -0
  165. package/search/levenshtein-utils.ts +17 -11
  166. package/transport/errors.ts +310 -0
  167. package/transport/event/builder.ts +378 -0
  168. package/transport/event/index.ts +7 -0
  169. package/transport/event/types.ts +292 -0
  170. package/transport/events/index.ts +2670 -0
  171. package/transport/events/meta-overlay.ts +79 -0
  172. package/transport/events/types/agents.ts +177 -0
  173. package/transport/events/types/app-index.ts +9 -0
  174. package/transport/events/types/app.ts +475 -0
  175. package/transport/events/types/box-item.ts +222 -0
  176. package/transport/events/types/clipboard.ts +80 -0
  177. package/transport/events/types/core-box.ts +534 -0
  178. package/transport/events/types/device-idle.ts +7 -0
  179. package/transport/events/types/division-box.ts +99 -0
  180. package/transport/events/types/download.ts +115 -0
  181. package/transport/events/types/file-index.ts +73 -0
  182. package/transport/events/types/flow.ts +149 -0
  183. package/transport/events/types/index.ts +70 -0
  184. package/transport/events/types/market.ts +39 -0
  185. package/transport/events/types/meta-overlay.ts +184 -0
  186. package/transport/events/types/notification.ts +140 -0
  187. package/transport/events/types/permission.ts +90 -0
  188. package/transport/events/types/platform.ts +8 -0
  189. package/transport/events/types/plugin.ts +620 -0
  190. package/transport/events/types/sentry.ts +20 -0
  191. package/transport/events/types/storage.ts +208 -0
  192. package/transport/events/types/transport.ts +60 -0
  193. package/transport/events/types/tray.ts +16 -0
  194. package/transport/events/types/update.ts +78 -0
  195. package/transport/index.ts +139 -0
  196. package/transport/main.ts +2 -0
  197. package/transport/sdk/constants.ts +29 -0
  198. package/transport/sdk/domains/agents-market.ts +47 -0
  199. package/transport/sdk/domains/agents.ts +62 -0
  200. package/transport/sdk/domains/app.ts +48 -0
  201. package/transport/sdk/domains/disposable.ts +35 -0
  202. package/transport/sdk/domains/download.ts +139 -0
  203. package/transport/sdk/domains/index.ts +13 -0
  204. package/transport/sdk/domains/intelligence.ts +616 -0
  205. package/transport/sdk/domains/market.ts +35 -0
  206. package/transport/sdk/domains/notification.ts +62 -0
  207. package/transport/sdk/domains/permission.ts +85 -0
  208. package/transport/sdk/domains/platform.ts +19 -0
  209. package/transport/sdk/domains/plugin.ts +144 -0
  210. package/transport/sdk/domains/settings.ts +92 -0
  211. package/transport/sdk/domains/update.ts +64 -0
  212. package/transport/sdk/index.ts +60 -0
  213. package/transport/sdk/main-transport.ts +710 -0
  214. package/transport/sdk/main.ts +9 -0
  215. package/transport/sdk/plugin-transport.ts +654 -0
  216. package/transport/sdk/port-policy.ts +38 -0
  217. package/transport/sdk/renderer-transport.ts +1165 -0
  218. package/transport/types.ts +605 -0
  219. package/types/agent.ts +399 -0
  220. package/types/cloud-sync.ts +157 -0
  221. package/types/division-box.ts +47 -27
  222. package/types/download.ts +1 -0
  223. package/types/flow.ts +63 -12
  224. package/types/icon.ts +2 -1
  225. package/types/index.ts +5 -0
  226. package/types/intelligence.ts +1492 -81
  227. package/types/modules/base.ts +2 -0
  228. package/types/path-browserify.d.ts +5 -0
  229. package/types/platform.ts +12 -0
  230. package/types/startup-info.ts +32 -0
  231. package/types/touch-app-core.ts +8 -8
  232. package/types/update.ts +94 -1
  233. package/vitest.config.ts +25 -0
  234. package/auth/useClerkConfig.ts +0 -40
  235. package/auth/useClerkProvider.ts +0 -52
@@ -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]
@@ -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 }
package/icons/index.ts ADDED
@@ -0,0 +1,257 @@
1
+ /**
2
+ * Common icon constants for UnoCSS preset-icons
3
+ *
4
+ * @description
5
+ * Defines commonly used icon class names following UnoCSS icones convention.
6
+ * Icons are organized by category for easy discovery and consistent usage.
7
+ *
8
+ * Usage:
9
+ * ```vue
10
+ * <i :class="TuffIcons.Search" />
11
+ * <span :class="TuffIcons.Settings" />
12
+ * ```
13
+ *
14
+ * @see https://icones.js.org for icon explorer
15
+ * @see https://unocss.dev/presets/icons for UnoCSS icons preset
16
+ */
17
+
18
+ import type { ITuffIcon } from '../types/icon'
19
+
20
+ export * from './svg'
21
+
22
+ /**
23
+ * Create a class-type ITuffIcon from an icon class name
24
+ */
25
+ export function classIcon(iconClass: string): ITuffIcon {
26
+ return {
27
+ type: 'class',
28
+ value: iconClass,
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Common icon constants using UnoCSS class names
34
+ *
35
+ * @description
36
+ * Icon naming convention: i-{collection}-{icon-name}
37
+ * - ri: Remix Icon (outline style)
38
+ * - carbon: Carbon Design System icons
39
+ * - simple-icons: Brand/logo icons
40
+ */
41
+ export const TuffIcons = {
42
+ // ============ Navigation ============
43
+ Home: 'i-ri-home-line',
44
+ HomeFill: 'i-ri-home-fill',
45
+ Back: 'i-ri-arrow-left-line',
46
+ Forward: 'i-ri-arrow-right-line',
47
+ Up: 'i-ri-arrow-up-line',
48
+ Down: 'i-ri-arrow-down-line',
49
+ Menu: 'i-ri-menu-line',
50
+ MenuFold: 'i-ri-menu-fold-line',
51
+ MenuUnfold: 'i-ri-menu-unfold-line',
52
+
53
+ // ============ Actions ============
54
+ Search: 'i-ri-search-line',
55
+ SearchFill: 'i-ri-search-fill',
56
+ Add: 'i-ri-add-line',
57
+ AddCircle: 'i-ri-add-circle-line',
58
+ Remove: 'i-ri-subtract-line',
59
+ Delete: 'i-ri-delete-bin-line',
60
+ Edit: 'i-ri-edit-line',
61
+ Copy: 'i-ri-file-copy-line',
62
+ Paste: 'i-ri-clipboard-line',
63
+ Cut: 'i-ri-scissors-line',
64
+ Save: 'i-ri-save-line',
65
+ Download: 'i-ri-download-line',
66
+ Upload: 'i-ri-upload-line',
67
+ Refresh: 'i-ri-refresh-line',
68
+ Sync: 'i-ri-loop-left-line',
69
+
70
+ // ============ Status ============
71
+ Check: 'i-ri-check-line',
72
+ CheckCircle: 'i-ri-checkbox-circle-line',
73
+ CheckCircleFill: 'i-ri-checkbox-circle-fill',
74
+ Close: 'i-ri-close-line',
75
+ CloseCircle: 'i-ri-close-circle-line',
76
+ CloseCircleFill: 'i-ri-close-circle-fill',
77
+ Warning: 'i-ri-error-warning-line',
78
+ WarningFill: 'i-ri-error-warning-fill',
79
+ Error: 'i-ri-close-circle-line',
80
+ ErrorFill: 'i-ri-close-circle-fill',
81
+ Info: 'i-ri-information-line',
82
+ InfoFill: 'i-ri-information-fill',
83
+ Question: 'i-ri-question-line',
84
+ QuestionFill: 'i-ri-question-fill',
85
+
86
+ // ============ Files & Folders ============
87
+ File: 'i-ri-file-line',
88
+ FileFill: 'i-ri-file-fill',
89
+ FileText: 'i-ri-file-text-line',
90
+ FileCode: 'i-ri-file-code-line',
91
+ FileImage: 'i-ri-image-line',
92
+ FileVideo: 'i-ri-video-line',
93
+ FileAudio: 'i-ri-music-line',
94
+ FilePdf: 'i-ri-file-pdf-line',
95
+ FileZip: 'i-ri-file-zip-line',
96
+
97
+ // ============ Folders ============
98
+ Folder: 'i-ri-folder-line',
99
+ FolderFill: 'i-ri-folder-fill',
100
+ FolderOpen: 'i-ri-folder-open-line',
101
+ FolderAdd: 'i-ri-folder-add-line',
102
+
103
+ // ============ UI Elements ============
104
+ Settings: 'i-ri-settings-3-line',
105
+ SettingsFill: 'i-ri-settings-3-fill',
106
+ User: 'i-ri-user-line',
107
+ UserFill: 'i-ri-user-fill',
108
+ Users: 'i-ri-group-line',
109
+ Notification: 'i-ri-notification-line',
110
+ NotificationFill: 'i-ri-notification-fill',
111
+ Bell: 'i-ri-notification-3-line',
112
+ Star: 'i-ri-star-line',
113
+ StarFill: 'i-ri-star-fill',
114
+ Heart: 'i-ri-heart-line',
115
+ HeartFill: 'i-ri-heart-fill',
116
+ Bookmark: 'i-ri-bookmark-line',
117
+ BookmarkFill: 'i-ri-bookmark-fill',
118
+ Pin: 'i-ri-pushpin-line',
119
+ PinFill: 'i-ri-pushpin-fill',
120
+ Lock: 'i-ri-lock-line',
121
+ LockFill: 'i-ri-lock-fill',
122
+ Unlock: 'i-ri-lock-unlock-line',
123
+ Eye: 'i-ri-eye-line',
124
+ EyeOff: 'i-ri-eye-off-line',
125
+
126
+ // ============ Media Controls ============
127
+ Play: 'i-ri-play-line',
128
+ PlayFill: 'i-ri-play-fill',
129
+ Pause: 'i-ri-pause-line',
130
+ PauseFill: 'i-ri-pause-fill',
131
+ Stop: 'i-ri-stop-line',
132
+ SkipBack: 'i-ri-skip-back-line',
133
+ SkipForward: 'i-ri-skip-forward-line',
134
+ Volume: 'i-ri-volume-up-line',
135
+ VolumeMute: 'i-ri-volume-mute-line',
136
+ Fullscreen: 'i-ri-fullscreen-line',
137
+ ExitFullscreen: 'i-ri-fullscreen-exit-line',
138
+
139
+ // ============ Communication ============
140
+ Mail: 'i-ri-mail-line',
141
+ MailFill: 'i-ri-mail-fill',
142
+ Chat: 'i-ri-chat-3-line',
143
+ ChatFill: 'i-ri-chat-3-fill',
144
+ Send: 'i-ri-send-plane-line',
145
+ Share: 'i-ri-share-line',
146
+ Link: 'i-ri-link',
147
+ Unlink: 'i-ri-link-unlink',
148
+ ExternalLink: 'i-ri-external-link-line',
149
+
150
+ // ============ Data & Analytics ============
151
+ Chart: 'i-ri-bar-chart-line',
152
+ ChartPie: 'i-ri-pie-chart-line',
153
+ Dashboard: 'i-ri-dashboard-line',
154
+ Database: 'i-ri-database-line',
155
+ Cloud: 'i-ri-cloud-line',
156
+ CloudUpload: 'i-ri-cloud-upload-line',
157
+ CloudDownload: 'i-ri-cloud-download-line',
158
+
159
+ // ============ Development ============
160
+ Code: 'i-ri-code-line',
161
+ Terminal: 'i-ri-terminal-line',
162
+ Bug: 'i-ri-bug-line',
163
+ Git: 'i-ri-git-branch-line',
164
+ Cpu: 'i-ri-cpu-line',
165
+ Plugin: 'i-ri-plug-line',
166
+ Api: 'i-ri-code-s-slash-line',
167
+
168
+ // ============ System ============
169
+ Apps: 'i-ri-apps-line',
170
+ AppsFill: 'i-ri-apps-fill',
171
+ Grid: 'i-ri-grid-line',
172
+ List: 'i-ri-list-unordered',
173
+ Filter: 'i-ri-filter-line',
174
+ Sort: 'i-ri-sort-asc',
175
+ More: 'i-ri-more-line',
176
+ MoreVertical: 'i-ri-more-2-line',
177
+ Drag: 'i-ri-drag-move-line',
178
+ Expand: 'i-ri-expand-diagonal-line',
179
+ Collapse: 'i-ri-contract-left-right-line',
180
+
181
+ // ============ Time ============
182
+ Time: 'i-ri-time-line',
183
+ Calendar: 'i-ri-calendar-line',
184
+ CalendarEvent: 'i-ri-calendar-event-line',
185
+ History: 'i-ri-history-line',
186
+ Timer: 'i-ri-timer-line',
187
+
188
+ // ============ Theme ============
189
+ Sun: 'i-ri-sun-line',
190
+ Moon: 'i-ri-moon-line',
191
+ Palette: 'i-ri-palette-line',
192
+
193
+ // ============ Misc ============
194
+ Rocket: 'i-ri-rocket-line',
195
+ RocketFill: 'i-ri-rocket-fill',
196
+ Magic: 'i-ri-magic-line',
197
+ Lightbulb: 'i-ri-lightbulb-line',
198
+ Award: 'i-ri-award-line',
199
+ Trophy: 'i-ri-trophy-line',
200
+ Gift: 'i-ri-gift-line',
201
+ Fire: 'i-ri-fire-line',
202
+ Sparkles: 'i-ri-sparkles-line',
203
+ Loader: 'i-ri-loader-4-line',
204
+ Loading: 'i-ri-loader-line',
205
+ } as const
206
+
207
+ /**
208
+ * Icon type derived from TuffIcons keys
209
+ */
210
+ export type TuffIconKey = keyof typeof TuffIcons
211
+
212
+ /**
213
+ * Icon class type derived from TuffIcons values
214
+ */
215
+ export type TuffIconClass = (typeof TuffIcons)[TuffIconKey]
216
+
217
+ /**
218
+ * Get ITuffIcon from icon key
219
+ */
220
+ export function getIcon(key: TuffIconKey): ITuffIcon {
221
+ return classIcon(TuffIcons[key])
222
+ }
223
+
224
+ /**
225
+ * Platform-specific application icons (Carbon icons)
226
+ */
227
+ export const AppIcons = {
228
+ // macOS
229
+ Finder: 'i-carbon-folder',
230
+ Safari: 'i-simple-icons-safari',
231
+ Terminal: 'i-carbon-terminal',
232
+ Xcode: 'i-simple-icons-xcode',
233
+
234
+ // Windows
235
+ Explorer: 'i-carbon-folder',
236
+ Edge: 'i-simple-icons-microsoftedge',
237
+ PowerShell: 'i-carbon-terminal',
238
+ VisualStudio: 'i-simple-icons-visualstudio',
239
+
240
+ // Cross-platform
241
+ Chrome: 'i-simple-icons-googlechrome',
242
+ Firefox: 'i-simple-icons-firefox',
243
+ VSCode: 'i-simple-icons-visualstudiocode',
244
+ Slack: 'i-simple-icons-slack',
245
+ Discord: 'i-simple-icons-discord',
246
+ Spotify: 'i-simple-icons-spotify',
247
+ GitHub: 'i-simple-icons-github',
248
+ GitLab: 'i-simple-icons-gitlab',
249
+ Docker: 'i-simple-icons-docker',
250
+ Figma: 'i-simple-icons-figma',
251
+ Notion: 'i-simple-icons-notion',
252
+ } as const
253
+
254
+ /**
255
+ * App icon type
256
+ */
257
+ export type AppIconKey = keyof typeof AppIcons