@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
@@ -380,6 +380,7 @@ export interface TuffCustomRender {
380
380
 
381
381
  /**
382
382
  * Icon definition
383
+ * @deprecated
383
384
  *
384
385
  * @description
385
386
  * Unified icon type supporting only ITuffIcon object format
@@ -803,6 +804,65 @@ export interface TuffContext {
803
804
  tags?: string[]
804
805
  }
805
806
 
807
+ // ==================== Footer Hints 配置 ====================
808
+
809
+ /**
810
+ * Footer hint 单项配置
811
+ */
812
+ export interface TuffFooterHintItem {
813
+ /** 快捷键显示文本 */
814
+ key: string
815
+ /** 提示标签 */
816
+ label: string
817
+ /** 是否显示此提示 */
818
+ visible?: boolean
819
+ /** 触发的事件名称 */
820
+ event?: string
821
+ /** 事件携带的数据 */
822
+ eventData?: Record<string, unknown>
823
+ }
824
+
825
+ /**
826
+ * Footer hints 配置
827
+ * @description 控制 CoreBox 底部快捷键提示的显示和行为
828
+ */
829
+ export interface TuffFooterHints {
830
+ /**
831
+ * 主操作提示(回车键)
832
+ * @description 自定义回车键的文案,如 "发送"、"执行"、"打开" 等
833
+ */
834
+ primary?: {
835
+ /** 自定义标签文案 */
836
+ label?: string
837
+ /** 是否显示 */
838
+ visible?: boolean
839
+ }
840
+
841
+ /**
842
+ * 辅助操作提示(Meta+K)
843
+ * @description 控制 Meta+K 快捷键的显示和行为
844
+ */
845
+ secondary?: {
846
+ /** 自定义标签文案 */
847
+ label?: string
848
+ /** 是否显示,默认 false(隐藏) */
849
+ visible?: boolean
850
+ /** 触发的事件名称 */
851
+ event?: string
852
+ /** 事件携带的数据 */
853
+ eventData?: Record<string, unknown>
854
+ }
855
+
856
+ /**
857
+ * 快速选择提示(Meta+1-0)
858
+ * @description 控制快速选择快捷键的显示
859
+ */
860
+ quickSelect?: {
861
+ /** 是否显示,默认根据场景自动判断 */
862
+ visible?: boolean
863
+ }
864
+ }
865
+
806
866
  // ==================== 扩展元数据 ====================
807
867
 
808
868
  /**
@@ -1030,6 +1090,12 @@ export interface TuffMeta {
1030
1090
  * @warning 不建议添加太多关键词(建议 <= 10),过多会影响搜索性能
1031
1091
  */
1032
1092
  keywords?: string[]
1093
+
1094
+ /**
1095
+ * Footer hints 配置
1096
+ * @description 控制 CoreBox 底部快捷键提示的显示和行为
1097
+ */
1098
+ footerHints?: TuffFooterHints
1033
1099
  }
1034
1100
 
1035
1101
  // ==================== 前端展示结构 ====================
@@ -1304,6 +1370,8 @@ export interface TuffContainerLayout {
1304
1370
  export interface TuffSectionMeta {
1305
1371
  /** 是否为智能推荐分组 */
1306
1372
  intelligence?: boolean
1373
+ /** 是否为置顶分组 */
1374
+ pinned?: boolean
1307
1375
  /** 扩展字段 */
1308
1376
  [key: string]: unknown
1309
1377
  }
@@ -1355,6 +1423,18 @@ export interface IProviderActivate {
1355
1423
  icon?: TuffIcon
1356
1424
  time?: number
1357
1425
  meta?: Record<string, any>
1426
+ /**
1427
+ * Whether the results area should be hidden when this provider is active.
1428
+ * - true: Hide results (webcontent mode - plugin UI view is attached)
1429
+ * - false/undefined: Show results (push mode - plugin pushes items to list)
1430
+ */
1431
+ hideResults?: boolean
1432
+ /**
1433
+ * Whether the input box should be shown when this provider is active.
1434
+ * - true: Show input (feature accepts input via acceptedInputTypes or allowInput)
1435
+ * - false/undefined: Hide input in webcontent mode, show in push mode
1436
+ */
1437
+ showInput?: boolean
1358
1438
  }
1359
1439
 
1360
1440
  /**
@@ -1417,6 +1497,23 @@ export interface ISearchProvider<C> {
1417
1497
  */
1418
1498
  readonly supportedInputTypes?: TuffInputType[]
1419
1499
 
1500
+ /**
1501
+ * Search priority layer
1502
+ * @description Determines when this provider's results are returned:
1503
+ * - 'fast': Results are returned immediately with the first batch (blocking)
1504
+ * - 'deferred': Results are appended asynchronously after fast layer completes
1505
+ * @default 'deferred'
1506
+ */
1507
+ readonly priority?: 'fast' | 'deferred'
1508
+
1509
+ /**
1510
+ * Expected search duration in milliseconds
1511
+ * @description Used for sorting providers within the same layer and timeout estimation.
1512
+ * Providers with lower expected duration run first within their layer.
1513
+ * @default 1000
1514
+ */
1515
+ readonly expectedDuration?: number
1516
+
1420
1517
  /**
1421
1518
  * Core search method (PULL mode).
1422
1519
  * The engine calls this method to get results from the provider.
@@ -1,6 +1,9 @@
1
1
  import path from 'node:path'
2
2
  import { net } from 'electron'
3
3
  import fse from 'fs-extra'
4
+ import { getLogger } from '../common/logger'
5
+
6
+ const downloadLog = getLogger('download-manager')
4
7
 
5
8
  interface DownloadItem {
6
9
  url: string
@@ -52,16 +55,16 @@ export class DownloadManager {
52
55
  const item = this.downloadQueue.shift()!
53
56
 
54
57
  try {
55
- console.log(`[DownloadManager] Starting to download ${item.filename} from ${item.url}`)
58
+ downloadLog.info(`Starting to download ${item.filename} from ${item.url}`)
56
59
  const filePath = await this.downloadFile(item.url, item.filename)
57
- console.log(`[DownloadManager] Download ${item.filename} completed`)
60
+ downloadLog.info(`Download ${item.filename} completed`)
58
61
 
59
62
  if (item.apply) {
60
63
  item.apply(filePath)
61
64
  }
62
65
  }
63
66
  catch (error) {
64
- console.error(`[DownloadManager] Download ${item.filename} failed:`, error)
67
+ downloadLog.error(`Download ${item.filename} failed`, { error })
65
68
  }
66
69
 
67
70
  this.processQueue()
@@ -78,10 +81,10 @@ export class DownloadManager {
78
81
  const request = net.request(url)
79
82
  const filePath = this.basePath ? path.join(this.basePath, filename) : filename
80
83
 
81
- console.log(`[DownloadManager] File download request sent for ${filename}.`)
84
+ downloadLog.info(`File download request sent for ${filename}.`)
82
85
 
83
86
  request.addListener('error', (error) => {
84
- console.error(`[DownloadManager] Download request error for ${filename}:`, error)
87
+ downloadLog.error(`Download request error for ${filename}`, { error })
85
88
  reject(error)
86
89
  })
87
90
 
@@ -89,12 +92,12 @@ export class DownloadManager {
89
92
  fse.createFileSync(filePath)
90
93
 
91
94
  response.addListener('data', (chunk: any) => {
92
- console.log(`[DownloadManager] Downloading ${filename}...`)
95
+ downloadLog.debug(`Downloading ${filename}...`)
93
96
  fse.appendFile(filePath, chunk, 'utf8')
94
97
  })
95
98
 
96
99
  response.addListener('end', () => {
97
- console.log(`[DownloadManager] Download ${filename} finished.`)
100
+ downloadLog.info(`Download ${filename} finished.`)
98
101
  resolve(filePath)
99
102
  })
100
103
  })
@@ -1,6 +1,8 @@
1
1
  import type { ExecException } from 'node:child_process'
2
- import { exec } from 'node:child_process'
3
2
  import { platform } from 'node:process'
3
+ import { execFileSafe } from '../common/utils/safe-shell'
4
+
5
+ type ExecError = { error?: unknown }
4
6
 
5
7
  export interface IGlobalPkgResult {
6
8
  exist: boolean
@@ -9,53 +11,53 @@ export interface IGlobalPkgResult {
9
11
  version?: string
10
12
  }
11
13
 
12
- export function checkGlobalPackageExist(packageName: string): Promise<IGlobalPkgResult> {
13
- return new Promise((resolve, reject) => {
14
- exec(`npm list -g ${packageName}`, (error, stdout, stderr) => {
15
- if (error) {
16
- reject({
17
- exits: false,
18
- error,
19
- })
20
- return
21
- }
22
- if (stderr) {
23
- reject({
24
- exits: false,
25
- error: stderr,
26
- })
27
- return
28
- }
14
+ export async function checkGlobalPackageExist(packageName: string): Promise<IGlobalPkgResult> {
15
+ const name = packageName.trim()
16
+ if (!name) {
17
+ throw new Error('Package name is required')
18
+ }
29
19
 
30
- const lines = stdout.split('\n')
31
- const lastLine = lines[lines.length - 3]
32
- const match = lastLine.match(/(\S+)@(\S+)/)
33
- if (match) {
34
- resolve({
35
- exist: true,
36
- name: match[1],
37
- version: match[2],
38
- } as IGlobalPkgResult)
39
- return
40
- }
20
+ try {
21
+ const { stdout, stderr } = await execFileSafe('npm', ['list', '-g', name])
22
+ if (stderr) {
23
+ const stderrError = Object.assign(new Error('Failed to check global package'), {
24
+ error: stderr
25
+ })
26
+ throw stderrError
27
+ }
41
28
 
42
- resolve({
43
- exist: false,
44
- } as IGlobalPkgResult)
29
+ const lines = stdout.split('\n')
30
+ const lastLine = lines[lines.length - 3]
31
+ const match = lastLine.match(/([^@\s]+)@(\S+)/)
32
+ if (match) {
33
+ return {
34
+ exist: true,
35
+ name: match[1],
36
+ version: match[2]
37
+ } as IGlobalPkgResult
38
+ }
39
+
40
+ return {
41
+ exist: false
42
+ } as IGlobalPkgResult
43
+ } catch (error) {
44
+ const execError = Object.assign(new Error('Failed to check global package'), {
45
+ error: error as ExecError
45
46
  })
46
- })
47
+ return Promise.reject(execError)
48
+ }
47
49
  }
48
50
 
49
51
  // Check npm version
50
52
  export function getNpmVersion(): Promise<string | null> {
51
- return new Promise((resolve) => {
52
- exec(`npm --version`, (error, stdout, stderr) => {
53
- if (error || stderr)
54
- resolve(null)
55
-
56
- resolve(stdout.trim())
53
+ return execFileSafe('npm', ['--version'])
54
+ .then(({ stdout, stderr }) => {
55
+ if (stderr) {
56
+ return null
57
+ }
58
+ return stdout.trim()
57
59
  })
58
- })
60
+ .catch(() => null)
59
61
  }
60
62
 
61
63
  export interface OSAdapter<R, T> {
package/electron/index.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  export * from './download-manager'
2
2
  export * from './env-tool'
3
-
package/env/index.ts ADDED
@@ -0,0 +1,156 @@
1
+ export const NEXUS_BASE_URL = 'https://tuff.tagzxia.com'
2
+
3
+ export interface EnvLike {
4
+ [key: string]: unknown
5
+ }
6
+
7
+ function getProcess(): any {
8
+ return (globalThis as any)?.process
9
+ }
10
+
11
+ function readGlobalEnv(): Record<string, string | undefined> {
12
+ const g: any = globalThis as any
13
+ const fromGlobal = g.__TUFF_ENV && typeof g.__TUFF_ENV === 'object' ? g.__TUFF_ENV : null
14
+ const record: Record<string, string | undefined> = {}
15
+
16
+ if (fromGlobal) {
17
+ for (const [k, v] of Object.entries(fromGlobal)) {
18
+ if (typeof v === 'string') {
19
+ record[k] = v
20
+ }
21
+ else if (typeof v === 'number' || typeof v === 'boolean') {
22
+ record[k] = String(v)
23
+ }
24
+ }
25
+ }
26
+
27
+ const p: any = getProcess()
28
+ if (p && p.env && typeof p.env === 'object') {
29
+ for (const [k, v] of Object.entries(p.env)) {
30
+ if (typeof v === 'string') {
31
+ record[k] = v
32
+ }
33
+ else if (typeof v === 'number' || typeof v === 'boolean') {
34
+ record[k] = String(v)
35
+ }
36
+ }
37
+ }
38
+
39
+ return record
40
+ }
41
+
42
+ export function setRuntimeEnv(env: Record<string, string | undefined>): void {
43
+ const g: any = globalThis as any
44
+ const normalized: Record<string, string | undefined> = {}
45
+ for (const [k, v] of Object.entries(env ?? {})) {
46
+ if (typeof v === 'string') {
47
+ normalized[k] = v
48
+ }
49
+ else if (typeof v === 'number' || typeof v === 'boolean') {
50
+ normalized[k] = String(v)
51
+ }
52
+ }
53
+ g.__TUFF_ENV = { ...(g.__TUFF_ENV || {}), ...normalized }
54
+ }
55
+
56
+ export function getEnv(key: string): string | undefined {
57
+ return readGlobalEnv()[key]
58
+ }
59
+
60
+ export function getEnvOrDefault(key: string, fallback: string): string {
61
+ return getEnv(key) ?? fallback
62
+ }
63
+
64
+ export function getBooleanEnv(key: string, fallback = false): boolean {
65
+ const raw = getEnv(key)
66
+ if (raw === undefined)
67
+ return fallback
68
+ if (raw === '1' || raw === 'true')
69
+ return true
70
+ if (raw === '0' || raw === 'false')
71
+ return false
72
+ return fallback
73
+ }
74
+
75
+ export function hasWindow(): boolean {
76
+ return typeof window !== 'undefined'
77
+ }
78
+
79
+ export function hasDocument(): boolean {
80
+ return typeof document !== 'undefined'
81
+ }
82
+
83
+ export function hasNavigator(): boolean {
84
+ return typeof navigator !== 'undefined'
85
+ }
86
+
87
+ export function isBrowserRuntime(): boolean {
88
+ return hasWindow() && hasDocument()
89
+ }
90
+
91
+ export function isNodeRuntime(): boolean {
92
+ const proc: any = getProcess()
93
+ return typeof proc !== 'undefined'
94
+ && Boolean(proc?.versions?.node)
95
+ }
96
+
97
+ export function isElectronRuntime(): boolean {
98
+ const proc: any = getProcess()
99
+ return Boolean(proc?.versions?.electron)
100
+ }
101
+
102
+ export function isElectronRenderer(): boolean {
103
+ const proc: any = getProcess()
104
+ return Boolean(proc?.versions?.electron)
105
+ && proc?.type === 'renderer'
106
+ }
107
+
108
+ export function isElectronMain(): boolean {
109
+ const proc: any = getProcess()
110
+ return Boolean(proc?.versions?.electron)
111
+ && (proc?.type === 'browser' || !proc?.type)
112
+ }
113
+
114
+ export function isDevEnv(): boolean {
115
+ const nodeEnv = getEnv('NODE_ENV')
116
+ if (nodeEnv) {
117
+ return nodeEnv === 'development' || nodeEnv === 'test'
118
+ }
119
+ const mode = getEnv('MODE') || getEnv('VITE_MODE')
120
+ if (mode) {
121
+ return mode === 'development'
122
+ }
123
+ return getBooleanEnv('DEV', false)
124
+ }
125
+
126
+ export function isProdEnv(): boolean {
127
+ const nodeEnv = getEnv('NODE_ENV')
128
+ if (nodeEnv) {
129
+ return nodeEnv === 'production'
130
+ }
131
+ const mode = getEnv('MODE') || getEnv('VITE_MODE')
132
+ if (mode) {
133
+ return mode === 'production'
134
+ }
135
+ return getBooleanEnv('PROD', false)
136
+ }
137
+
138
+ export function normalizeBaseUrl(input: string): string {
139
+ return input.replace(/\/$/, '')
140
+ }
141
+
142
+ export function getTuffBaseUrl(): string {
143
+ return normalizeBaseUrl(getEnvOrDefault('VITE_NEXUS_URL', NEXUS_BASE_URL))
144
+ }
145
+
146
+ export function getTelemetryApiBase(): string {
147
+ const url = normalizeBaseUrl(getEnvOrDefault('NEXUS_API_BASE', NEXUS_BASE_URL))
148
+ if (!url) {
149
+ throw new Error('Telemetry API base URL is not configured')
150
+ }
151
+ return url
152
+ }
153
+
154
+ export function getTpexApiBase(): string {
155
+ return normalizeBaseUrl(getEnvOrDefault('TPEX_API_BASE', NEXUS_BASE_URL))
156
+ }
@@ -0,0 +1,55 @@
1
+ const antfu = require('@antfu/eslint-config').default
2
+
3
+ module.exports = antfu(
4
+ {
5
+ type: 'lib',
6
+ typescript: true,
7
+ stylistic: false,
8
+ unicorn: false,
9
+ test: false,
10
+ markdown: false,
11
+ regexp: false,
12
+ ignores: [
13
+ 'plugin/sdk/examples/**',
14
+ ],
15
+ },
16
+ {
17
+ rules: {
18
+ 'antfu/if-newline': 'off',
19
+ 'jsdoc/check-param-names': 'off',
20
+ 'jsdoc/empty-tags': 'off',
21
+ 'import/consistent-type-specifier-style': 'off',
22
+ 'import/first': 'off',
23
+ 'node/prefer-global/buffer': 'off',
24
+ 'node/prefer-global/process': 'off',
25
+ 'no-console': 'off',
26
+ 'no-useless-return': 'off',
27
+ 'perfectionist/sort-exports': 'off',
28
+ 'perfectionist/sort-imports': 'off',
29
+ 'perfectionist/sort-named-exports': 'off',
30
+ 'perfectionist/sort-named-imports': 'off',
31
+ 'prefer-promise-reject-errors': 'off',
32
+ 'test/prefer-lowercase-title': 'off',
33
+ 'ts/consistent-type-definitions': 'off',
34
+ 'ts/ban-ts-comment': 'off',
35
+ 'ts/explicit-function-return-type': 'off',
36
+ 'ts/method-signature-style': 'off',
37
+ 'ts/no-namespace': 'off',
38
+ 'ts/no-empty-object-type': 'off',
39
+ 'ts/no-require-imports': 'off',
40
+ 'ts/no-unsafe-function-type': 'off',
41
+ 'ts/no-use-before-define': 'off',
42
+ 'unicorn/escape-case': 'off',
43
+ 'unicorn/new-for-builtins': 'off',
44
+ 'unicorn/no-instanceof-builtins': 'off',
45
+ 'unicorn/no-new-array': 'off',
46
+ 'vars-on-top': 'off',
47
+ },
48
+ },
49
+ {
50
+ files: ['plugin/channel.ts'],
51
+ rules: {
52
+ 'no-eval': 'off',
53
+ },
54
+ },
55
+ )
package/i18n/index.ts ADDED
@@ -0,0 +1,62 @@
1
+ /**
2
+ * I18n Utilities
3
+ *
4
+ * Shared i18n utilities for backend-frontend communication.
5
+ *
6
+ * ## Backend Usage (Main Process)
7
+ * ```typescript
8
+ * import { i18nMsg, DevServerKeys } from '@talex-touch/utils/i18n'
9
+ *
10
+ * // Send i18n message to frontend
11
+ * win.webContents.send('notification', {
12
+ * message: i18nMsg(DevServerKeys.DISCONNECTED)
13
+ * })
14
+ * ```
15
+ *
16
+ * ## Frontend Usage (Renderer)
17
+ * ```typescript
18
+ * import { resolveI18nMessage, i18nResolver } from '@talex-touch/utils/i18n'
19
+ *
20
+ * // Set locale
21
+ * i18nResolver.setLocale('zh')
22
+ *
23
+ * // Resolve message
24
+ * const text = resolveI18nMessage('$i18n:devServer.disconnected')
25
+ * // => '开发服务器已断开'
26
+ * ```
27
+ */
28
+
29
+ // Locale data
30
+ export { default as enMessages } from './locales/en.json'
31
+
32
+ export { default as zhMessages } from './locales/zh.json'
33
+
34
+ // Message keys and utilities for backend
35
+ export {
36
+ type DevServerKey,
37
+ DevServerKeys,
38
+ type FlowTransferKey,
39
+ FlowTransferKeys,
40
+ I18N_PREFIX,
41
+ i18nMsg,
42
+ i18nMsgWithParams,
43
+ isI18nMessage,
44
+ MessageKeys,
45
+ parseI18nMessage,
46
+ type PluginKey,
47
+ PluginKeys,
48
+ type SystemKey,
49
+ SystemKeys,
50
+ type WidgetKey,
51
+ WidgetKeys,
52
+ } from './message-keys'
53
+ // Resolver for frontend
54
+ export {
55
+ createI18nMessage,
56
+ I18nResolver,
57
+ i18nResolver,
58
+ type MessageLocale,
59
+ type Messages,
60
+ resolveI18nMessage,
61
+ useI18nResolver,
62
+ } from './resolver'