@tx5dr/contracts 1.2.0

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 (180) hide show
  1. package/CLAUDE.md +41 -0
  2. package/dist/index.d.ts +55 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +86 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/schema/__tests__/plugin-runtime-log.schema.test.d.ts +2 -0
  7. package/dist/schema/__tests__/plugin-runtime-log.schema.test.d.ts.map +1 -0
  8. package/dist/schema/__tests__/plugin-runtime-log.schema.test.js +78 -0
  9. package/dist/schema/__tests__/plugin-runtime-log.schema.test.js.map +1 -0
  10. package/dist/schema/ability.d.ts +85 -0
  11. package/dist/schema/ability.d.ts.map +1 -0
  12. package/dist/schema/ability.js +119 -0
  13. package/dist/schema/ability.js.map +1 -0
  14. package/dist/schema/api-response.schema.d.ts +1017 -0
  15. package/dist/schema/api-response.schema.d.ts.map +1 -0
  16. package/dist/schema/api-response.schema.js +137 -0
  17. package/dist/schema/api-response.schema.js.map +1 -0
  18. package/dist/schema/audio-sidecar.schema.d.ts +106 -0
  19. package/dist/schema/audio-sidecar.schema.d.ts.map +1 -0
  20. package/dist/schema/audio-sidecar.schema.js +47 -0
  21. package/dist/schema/audio-sidecar.schema.js.map +1 -0
  22. package/dist/schema/audio.schema.d.ts +227 -0
  23. package/dist/schema/audio.schema.d.ts.map +1 -0
  24. package/dist/schema/audio.schema.js +56 -0
  25. package/dist/schema/audio.schema.js.map +1 -0
  26. package/dist/schema/auth.schema.d.ts +738 -0
  27. package/dist/schema/auth.schema.d.ts.map +1 -0
  28. package/dist/schema/auth.schema.js +161 -0
  29. package/dist/schema/auth.schema.js.map +1 -0
  30. package/dist/schema/cycle.schema.d.ts +33 -0
  31. package/dist/schema/cycle.schema.d.ts.map +1 -0
  32. package/dist/schema/cycle.schema.js +23 -0
  33. package/dist/schema/cycle.schema.js.map +1 -0
  34. package/dist/schema/desktop-https.schema.d.ts +146 -0
  35. package/dist/schema/desktop-https.schema.d.ts.map +1 -0
  36. package/dist/schema/desktop-https.schema.js +31 -0
  37. package/dist/schema/desktop-https.schema.js.map +1 -0
  38. package/dist/schema/ft8.schema.d.ts +1107 -0
  39. package/dist/schema/ft8.schema.d.ts.map +1 -0
  40. package/dist/schema/ft8.schema.js +268 -0
  41. package/dist/schema/ft8.schema.js.map +1 -0
  42. package/dist/schema/hello.schema.d.ts +10 -0
  43. package/dist/schema/hello.schema.d.ts.map +1 -0
  44. package/dist/schema/hello.schema.js +5 -0
  45. package/dist/schema/hello.schema.js.map +1 -0
  46. package/dist/schema/logbook.schema.d.ts +1472 -0
  47. package/dist/schema/logbook.schema.d.ts.map +1 -0
  48. package/dist/schema/logbook.schema.js +256 -0
  49. package/dist/schema/logbook.schema.js.map +1 -0
  50. package/dist/schema/mode.schema.d.ts +130 -0
  51. package/dist/schema/mode.schema.d.ts.map +1 -0
  52. package/dist/schema/mode.schema.js +141 -0
  53. package/dist/schema/mode.schema.js.map +1 -0
  54. package/dist/schema/openwebrx.schema.d.ts +352 -0
  55. package/dist/schema/openwebrx.schema.d.ts.map +1 -0
  56. package/dist/schema/openwebrx.schema.js +139 -0
  57. package/dist/schema/openwebrx.schema.js.map +1 -0
  58. package/dist/schema/operator.schema.d.ts +883 -0
  59. package/dist/schema/operator.schema.d.ts.map +1 -0
  60. package/dist/schema/operator.schema.js +97 -0
  61. package/dist/schema/operator.schema.js.map +1 -0
  62. package/dist/schema/plugin.schema.d.ts +1579 -0
  63. package/dist/schema/plugin.schema.d.ts.map +1 -0
  64. package/dist/schema/plugin.schema.js +336 -0
  65. package/dist/schema/plugin.schema.js.map +1 -0
  66. package/dist/schema/process-monitor.schema.d.ts +282 -0
  67. package/dist/schema/process-monitor.schema.d.ts.map +1 -0
  68. package/dist/schema/process-monitor.schema.js +31 -0
  69. package/dist/schema/process-monitor.schema.js.map +1 -0
  70. package/dist/schema/pskreporter.schema.d.ts +185 -0
  71. package/dist/schema/pskreporter.schema.d.ts.map +1 -0
  72. package/dist/schema/pskreporter.schema.js +80 -0
  73. package/dist/schema/pskreporter.schema.js.map +1 -0
  74. package/dist/schema/qso.schema.d.ts +419 -0
  75. package/dist/schema/qso.schema.d.ts.map +1 -0
  76. package/dist/schema/qso.schema.js +137 -0
  77. package/dist/schema/qso.schema.js.map +1 -0
  78. package/dist/schema/radio-capability.schema.d.ts +625 -0
  79. package/dist/schema/radio-capability.schema.d.ts.map +1 -0
  80. package/dist/schema/radio-capability.schema.js +191 -0
  81. package/dist/schema/radio-capability.schema.js.map +1 -0
  82. package/dist/schema/radio-power-support.d.ts +45 -0
  83. package/dist/schema/radio-power-support.d.ts.map +1 -0
  84. package/dist/schema/radio-power-support.js +64 -0
  85. package/dist/schema/radio-power-support.js.map +1 -0
  86. package/dist/schema/radio-power.schema.d.ts +319 -0
  87. package/dist/schema/radio-power.schema.d.ts.map +1 -0
  88. package/dist/schema/radio-power.schema.js +87 -0
  89. package/dist/schema/radio-power.schema.js.map +1 -0
  90. package/dist/schema/radio-profile.schema.d.ts +2694 -0
  91. package/dist/schema/radio-profile.schema.d.ts.map +1 -0
  92. package/dist/schema/radio-profile.schema.js +71 -0
  93. package/dist/schema/radio-profile.schema.js.map +1 -0
  94. package/dist/schema/radio.schema.d.ts +1438 -0
  95. package/dist/schema/radio.schema.d.ts.map +1 -0
  96. package/dist/schema/radio.schema.js +314 -0
  97. package/dist/schema/radio.schema.js.map +1 -0
  98. package/dist/schema/realtime.schema.d.ts +1299 -0
  99. package/dist/schema/realtime.schema.d.ts.map +1 -0
  100. package/dist/schema/realtime.schema.js +184 -0
  101. package/dist/schema/realtime.schema.js.map +1 -0
  102. package/dist/schema/rigctld.schema.d.ts +151 -0
  103. package/dist/schema/rigctld.schema.d.ts.map +1 -0
  104. package/dist/schema/rigctld.schema.js +42 -0
  105. package/dist/schema/rigctld.schema.js.map +1 -0
  106. package/dist/schema/server-message-keys.d.ts +21 -0
  107. package/dist/schema/server-message-keys.d.ts.map +1 -0
  108. package/dist/schema/server-message-keys.js +22 -0
  109. package/dist/schema/server-message-keys.js.map +1 -0
  110. package/dist/schema/slot-info.schema.d.ts +696 -0
  111. package/dist/schema/slot-info.schema.d.ts.map +1 -0
  112. package/dist/schema/slot-info.schema.js +144 -0
  113. package/dist/schema/slot-info.schema.js.map +1 -0
  114. package/dist/schema/spectrum.schema.d.ts +716 -0
  115. package/dist/schema/spectrum.schema.d.ts.map +1 -0
  116. package/dist/schema/spectrum.schema.js +128 -0
  117. package/dist/schema/spectrum.schema.js.map +1 -0
  118. package/dist/schema/station-info.schema.d.ts +202 -0
  119. package/dist/schema/station-info.schema.d.ts.map +1 -0
  120. package/dist/schema/station-info.schema.js +32 -0
  121. package/dist/schema/station-info.schema.js.map +1 -0
  122. package/dist/schema/system.schema.d.ts +113 -0
  123. package/dist/schema/system.schema.d.ts.map +1 -0
  124. package/dist/schema/system.schema.js +95 -0
  125. package/dist/schema/system.schema.js.map +1 -0
  126. package/dist/schema/transmission.schema.d.ts +413 -0
  127. package/dist/schema/transmission.schema.d.ts.map +1 -0
  128. package/dist/schema/transmission.schema.js +78 -0
  129. package/dist/schema/transmission.schema.js.map +1 -0
  130. package/dist/schema/voice.schema.d.ts +38 -0
  131. package/dist/schema/voice.schema.d.ts.map +1 -0
  132. package/dist/schema/voice.schema.js +24 -0
  133. package/dist/schema/voice.schema.js.map +1 -0
  134. package/dist/schema/websocket.schema.d.ts +16916 -0
  135. package/dist/schema/websocket.schema.d.ts.map +1 -0
  136. package/dist/schema/websocket.schema.js +1050 -0
  137. package/dist/schema/websocket.schema.js.map +1 -0
  138. package/dist/utils/grid.d.ts +13 -0
  139. package/dist/utils/grid.d.ts.map +1 -0
  140. package/dist/utils/grid.js +71 -0
  141. package/dist/utils/grid.js.map +1 -0
  142. package/eslint.config.js +15 -0
  143. package/package.json +28 -0
  144. package/src/index.ts +152 -0
  145. package/src/schema/__tests__/plugin-runtime-log.schema.test.ts +90 -0
  146. package/src/schema/ability.ts +205 -0
  147. package/src/schema/api-response.schema.ts +187 -0
  148. package/src/schema/audio-sidecar.schema.ts +53 -0
  149. package/src/schema/audio.schema.ts +73 -0
  150. package/src/schema/auth.schema.ts +224 -0
  151. package/src/schema/cycle.schema.ts +25 -0
  152. package/src/schema/desktop-https.schema.ts +43 -0
  153. package/src/schema/ft8.schema.ts +362 -0
  154. package/src/schema/hello.schema.ts +7 -0
  155. package/src/schema/logbook.schema.ts +310 -0
  156. package/src/schema/mode.schema.ts +158 -0
  157. package/src/schema/openwebrx.schema.ts +160 -0
  158. package/src/schema/operator.schema.ts +112 -0
  159. package/src/schema/plugin.schema.ts +503 -0
  160. package/src/schema/process-monitor.schema.ts +41 -0
  161. package/src/schema/pskreporter.schema.ts +102 -0
  162. package/src/schema/qso.schema.ts +173 -0
  163. package/src/schema/radio-capability.schema.ts +244 -0
  164. package/src/schema/radio-power-support.ts +107 -0
  165. package/src/schema/radio-power.schema.ts +101 -0
  166. package/src/schema/radio-profile.schema.ts +91 -0
  167. package/src/schema/radio.schema.ts +385 -0
  168. package/src/schema/realtime.schema.ts +262 -0
  169. package/src/schema/rigctld.schema.ts +51 -0
  170. package/src/schema/server-message-keys.ts +26 -0
  171. package/src/schema/slot-info.schema.ts +162 -0
  172. package/src/schema/spectrum.schema.ts +166 -0
  173. package/src/schema/station-info.schema.ts +40 -0
  174. package/src/schema/system.schema.ts +121 -0
  175. package/src/schema/transmission.schema.ts +105 -0
  176. package/src/schema/voice.schema.ts +28 -0
  177. package/src/schema/websocket.schema.ts +1480 -0
  178. package/src/utils/grid.ts +94 -0
  179. package/test/mode-schema.test.ts +48 -0
  180. package/tsconfig.json +9 -0
package/CLAUDE.md ADDED
@@ -0,0 +1,41 @@
1
+ # CLAUDE.md - Contracts
2
+
3
+ Zod Schema 和 TypeScript 类型定义包,为整个 TX-5DR 系统提供数据契约。
4
+
5
+ ## 核心文件
6
+ - **websocket.schema.ts**: WebSocket 消息类型
7
+ - **radio/audio.schema.ts**: 电台和音频控制
8
+ - **ft8/operator.schema.ts**: FT8 消息和操作员
9
+ - **logbook/qso.schema.ts**: 日志本和联络记录
10
+ - **其他**: slot-info, mode, cycle, hello
11
+
12
+ ## 开发规范
13
+
14
+ ### 新增 Schema
15
+ 1. `src/schema/` 创建 `.schema.ts` 文件
16
+ 2. 定义 Zod Schema:
17
+ ```typescript
18
+ export const DataSchema = z.object({
19
+ id: z.string(),
20
+ value: z.number().optional(),
21
+ });
22
+ export type Data = z.infer<typeof DataSchema>;
23
+ ```
24
+ 3. `src/index.ts` 导出
25
+ 4. `yarn build` 生成类型
26
+
27
+ ### WebSocket 消息
28
+ ```typescript
29
+ export const WSMessageType = {
30
+ COMMAND_NAME: 'command_name', // 客户端→服务端
31
+ EVENT_NAME: 'event_name', // 服务端→客户端
32
+ } as const;
33
+ ```
34
+
35
+ ### 设计原则
36
+ - 严格验证,新字段用 `.optional()` 保证兼容性
37
+ - 复用现有 Schema,避免重复定义
38
+ - 使用语义化的命名
39
+
40
+ ## 命令
41
+ `yarn build` - 构建类型定义
@@ -0,0 +1,55 @@
1
+ export * from './schema/server-message-keys.js';
2
+ export * from './schema/hello.schema.js';
3
+ export * from './schema/audio.schema.js';
4
+ export * from './schema/ft8.schema.js';
5
+ export * from './schema/spectrum.schema.js';
6
+ export * from './schema/websocket.schema.js';
7
+ export * from './schema/mode.schema.js';
8
+ export * from './schema/qso.schema.js';
9
+ export * from './schema/cycle.schema.js';
10
+ export { SlotPackSchema, FrameMessageSchema, DecodeRequestSchema, DecodeResultSchema, SlotInfoSchema } from './schema/slot-info.schema.js';
11
+ export type { SlotPack, FrameMessage, DecodeRequest, DecodeResult, SlotInfo } from './schema/slot-info.schema.js';
12
+ export type { ModeDescriptor } from './schema/mode.schema.js';
13
+ export { WSMessageType } from './schema/websocket.schema.js';
14
+ export type { OperatorStatus, WSGetOperatorsMessage, WSOperatorsListMessage, WSOperatorStatusUpdateMessage, WSSetOperatorContextMessage, WSSetOperatorRuntimeStateMessage, WSSetOperatorRuntimeSlotContentMessage, WSSetOperatorTransmitCyclesMessage, } from './schema/websocket.schema.js';
15
+ export * from './schema/ft8.schema.js';
16
+ export * from './schema/spectrum.schema.js';
17
+ export * from './schema/qso.schema.js';
18
+ export * from './schema/websocket.schema.js';
19
+ export * from './schema/slot-info.schema.js';
20
+ export * from './schema/audio.schema.js';
21
+ export * from './schema/hello.schema.js';
22
+ export * from './schema/cycle.schema.js';
23
+ export * from './schema/mode.schema.js';
24
+ export * from './schema/audio.schema.js';
25
+ export * from './schema/cycle.schema.js';
26
+ export * from './schema/ft8.schema.js';
27
+ export * from './schema/hello.schema.js';
28
+ export * from './schema/mode.schema.js';
29
+ export * from './schema/operator.schema.js';
30
+ export * from './schema/qso.schema.js';
31
+ export * from './schema/slot-info.schema.js';
32
+ export * from './schema/websocket.schema.js';
33
+ export * from './schema/logbook.schema.js';
34
+ export * from './schema/radio.schema.js';
35
+ export * from './schema/api-response.schema.js';
36
+ export * from './schema/transmission.schema.js';
37
+ export * from './schema/pskreporter.schema.js';
38
+ export * from './schema/radio-profile.schema.js';
39
+ export * from './schema/ability.js';
40
+ export * from './schema/auth.schema.js';
41
+ export * from './schema/system.schema.js';
42
+ export * from './schema/voice.schema.js';
43
+ export * from './schema/station-info.schema.js';
44
+ export * from './utils/grid.js';
45
+ export * from './schema/process-monitor.schema.js';
46
+ export * from './schema/openwebrx.schema.js';
47
+ export * from './schema/radio-capability.schema.js';
48
+ export * from './schema/radio-power.schema.js';
49
+ export * from './schema/radio-power-support.js';
50
+ export * from './schema/audio-sidecar.schema.js';
51
+ export * from './schema/rigctld.schema.js';
52
+ export * from './schema/realtime.schema.js';
53
+ export * from './schema/desktop-https.schema.js';
54
+ export * from './schema/plugin.schema.js';
55
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,iCAAiC,CAAC;AAChD,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AAGzC,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACf,MAAM,8BAA8B,CAAC;AAGtC,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,QAAQ,EACT,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EACV,cAAc,EACf,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,aAAa,EACd,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EACV,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,EAC7B,2BAA2B,EAC3B,gCAAgC,EAChC,sCAAsC,EACtC,kCAAkC,GAEnC,MAAM,8BAA8B,CAAC;AAGtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AAGzC,cAAc,0BAA0B,CAAC;AAGzC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,0BAA0B,CAAC;AAGzC,cAAc,0BAA0B,CAAC;AAGzC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,0BAA0B,CAAC;AAGzC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,6BAA6B,CAAC;AAG5C,cAAc,wBAAwB,CAAC;AAGvC,cAAc,8BAA8B,CAAC;AAG7C,cAAc,8BAA8B,CAAC;AAG7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,0BAA0B,CAAC;AAGzC,cAAc,iCAAiC,CAAC;AAGhD,cAAc,iCAAiC,CAAC;AAGhD,cAAc,gCAAgC,CAAC;AAG/C,cAAc,kCAAkC,CAAC;AAGjD,cAAc,qBAAqB,CAAC;AAGpC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,2BAA2B,CAAC;AAG1C,cAAc,0BAA0B,CAAC;AAGzC,cAAc,iCAAiC,CAAC;AAGhD,cAAc,iBAAiB,CAAC;AAGhC,cAAc,oCAAoC,CAAC;AAGnD,cAAc,8BAA8B,CAAC;AAG7C,cAAc,qCAAqC,CAAC;AAGpD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAGhD,cAAc,kCAAkC,CAAC;AAGjD,cAAc,4BAA4B,CAAC;AAG3C,cAAc,6BAA6B,CAAC;AAG5C,cAAc,kCAAkC,CAAC;AAGjD,cAAc,2BAA2B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,86 @@
1
+ // Schema exports
2
+ export * from './schema/server-message-keys.js';
3
+ export * from './schema/hello.schema.js';
4
+ export * from './schema/audio.schema.js';
5
+ export * from './schema/ft8.schema.js';
6
+ export * from './schema/spectrum.schema.js';
7
+ export * from './schema/websocket.schema.js';
8
+ export * from './schema/mode.schema.js';
9
+ export * from './schema/qso.schema.js';
10
+ export * from './schema/cycle.schema.js';
11
+ // 显式导出slot-info.schema.js以避免与websocket.schema.js的冲突
12
+ export { SlotPackSchema, FrameMessageSchema, DecodeRequestSchema, DecodeResultSchema, SlotInfoSchema } from './schema/slot-info.schema.js';
13
+ export { WSMessageType } from './schema/websocket.schema.js';
14
+ // 导出所有schema中定义的类型
15
+ export * from './schema/ft8.schema.js';
16
+ export * from './schema/spectrum.schema.js';
17
+ export * from './schema/qso.schema.js';
18
+ export * from './schema/websocket.schema.js';
19
+ export * from './schema/slot-info.schema.js';
20
+ export * from './schema/audio.schema.js';
21
+ export * from './schema/hello.schema.js';
22
+ // 导出周期相关类型
23
+ export * from './schema/cycle.schema.js';
24
+ // 导出模式相关的类型
25
+ export * from './schema/mode.schema.js';
26
+ // Audio Schema
27
+ export * from './schema/audio.schema.js';
28
+ // Cycle Schema
29
+ export * from './schema/cycle.schema.js';
30
+ // FT8 Schema
31
+ export * from './schema/ft8.schema.js';
32
+ // Hello Schema
33
+ export * from './schema/hello.schema.js';
34
+ // Mode Schema
35
+ export * from './schema/mode.schema.js';
36
+ // Operator Schema
37
+ export * from './schema/operator.schema.js';
38
+ // QSO Schema
39
+ export * from './schema/qso.schema.js';
40
+ // Slot Info Schema
41
+ export * from './schema/slot-info.schema.js';
42
+ // WebSocket Schema
43
+ export * from './schema/websocket.schema.js';
44
+ // Logbook Schema
45
+ export * from './schema/logbook.schema.js';
46
+ export * from './schema/radio.schema.js';
47
+ // API Response Schema
48
+ export * from './schema/api-response.schema.js';
49
+ // Transmission Strategy Schema
50
+ export * from './schema/transmission.schema.js';
51
+ // PSKReporter Schema
52
+ export * from './schema/pskreporter.schema.js';
53
+ // Radio Profile Schema
54
+ export * from './schema/radio-profile.schema.js';
55
+ // Ability Schema (must be before auth.schema which imports from it)
56
+ export * from './schema/ability.js';
57
+ // Auth Schema
58
+ export * from './schema/auth.schema.js';
59
+ // System Schema
60
+ export * from './schema/system.schema.js';
61
+ // Voice Schema
62
+ export * from './schema/voice.schema.js';
63
+ // Station Info Schema
64
+ export * from './schema/station-info.schema.js';
65
+ // Grid Utils
66
+ export * from './utils/grid.js';
67
+ // Process Monitor Schema
68
+ export * from './schema/process-monitor.schema.js';
69
+ // OpenWebRX Schema
70
+ export * from './schema/openwebrx.schema.js';
71
+ // Radio Capability Schema
72
+ export * from './schema/radio-capability.schema.js';
73
+ // Radio Power Schema
74
+ export * from './schema/radio-power.schema.js';
75
+ export * from './schema/radio-power-support.js';
76
+ // Audio Sidecar Schema
77
+ export * from './schema/audio-sidecar.schema.js';
78
+ // rigctld bridge schema
79
+ export * from './schema/rigctld.schema.js';
80
+ // Realtime Schema
81
+ export * from './schema/realtime.schema.js';
82
+ // Desktop HTTPS Schema
83
+ export * from './schema/desktop-https.schema.js';
84
+ // Plugin Schema
85
+ export * from './schema/plugin.schema.js';
86
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,cAAc,iCAAiC,CAAC;AAChD,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AAEzC,oDAAoD;AACpD,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACf,MAAM,8BAA8B,CAAC;AAetC,OAAO,EACL,aAAa,EACd,MAAM,8BAA8B,CAAC;AActC,mBAAmB;AACnB,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AAEzC,WAAW;AACX,cAAc,0BAA0B,CAAC;AAEzC,YAAY;AACZ,cAAc,yBAAyB,CAAC;AAExC,eAAe;AACf,cAAc,0BAA0B,CAAC;AAEzC,eAAe;AACf,cAAc,0BAA0B,CAAC;AAEzC,aAAa;AACb,cAAc,wBAAwB,CAAC;AAEvC,eAAe;AACf,cAAc,0BAA0B,CAAC;AAEzC,cAAc;AACd,cAAc,yBAAyB,CAAC;AAExC,kBAAkB;AAClB,cAAc,6BAA6B,CAAC;AAE5C,eAAe;AACf,cAAc,wBAAwB,CAAC;AAEvC,mBAAmB;AACnB,cAAc,8BAA8B,CAAC;AAE7C,mBAAmB;AACnB,cAAc,8BAA8B,CAAC;AAE7C,iBAAiB;AACjB,cAAc,4BAA4B,CAAC;AAC3C,cAAc,0BAA0B,CAAC;AAEzC,sBAAsB;AACtB,cAAc,iCAAiC,CAAC;AAEhD,+BAA+B;AAC/B,cAAc,iCAAiC,CAAC;AAEhD,qBAAqB;AACrB,cAAc,gCAAgC,CAAC;AAE/C,uBAAuB;AACvB,cAAc,kCAAkC,CAAC;AAEjD,oEAAoE;AACpE,cAAc,qBAAqB,CAAC;AAEpC,cAAc;AACd,cAAc,yBAAyB,CAAC;AAExC,gBAAgB;AAChB,cAAc,2BAA2B,CAAC;AAE1C,eAAe;AACf,cAAc,0BAA0B,CAAC;AAEzC,sBAAsB;AACtB,cAAc,iCAAiC,CAAC;AAEhD,aAAa;AACb,cAAc,iBAAiB,CAAC;AAEhC,yBAAyB;AACzB,cAAc,oCAAoC,CAAC;AAEnD,mBAAmB;AACnB,cAAc,8BAA8B,CAAC;AAE7C,0BAA0B;AAC1B,cAAc,qCAAqC,CAAC;AAEpD,qBAAqB;AACrB,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAEhD,uBAAuB;AACvB,cAAc,kCAAkC,CAAC;AAEjD,wBAAwB;AACxB,cAAc,4BAA4B,CAAC;AAE3C,kBAAkB;AAClB,cAAc,6BAA6B,CAAC;AAE5C,uBAAuB;AACvB,cAAc,kCAAkC,CAAC;AAEjD,gBAAgB;AAChB,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plugin-runtime-log.schema.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-runtime-log.schema.test.d.ts","sourceRoot":"","sources":["../../../src/schema/__tests__/plugin-runtime-log.schema.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,78 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { PluginRuntimeLogHistoryPayloadSchema, PluginRuntimeLogEntrySchema, WSMessageSchema, WSMessageType, } from '../../index.js';
3
+ describe('plugin runtime log schema', () => {
4
+ it('accepts a valid pluginRuntimeLog entry', () => {
5
+ const entry = PluginRuntimeLogEntrySchema.parse({
6
+ source: 'system',
7
+ stage: 'load',
8
+ level: 'error',
9
+ message: 'No entry file found',
10
+ timestamp: Date.now(),
11
+ directoryName: 'broken-plugin',
12
+ details: {
13
+ candidates: ['plugin.js', 'plugin.mjs', 'index.js', 'index.mjs'],
14
+ },
15
+ });
16
+ expect(entry.source).toBe('system');
17
+ expect(entry.stage).toBe('load');
18
+ expect(entry.directoryName).toBe('broken-plugin');
19
+ });
20
+ it('rejects unsupported runtime stage', () => {
21
+ expect(() => PluginRuntimeLogEntrySchema.parse({
22
+ source: 'system',
23
+ stage: 'boot',
24
+ level: 'info',
25
+ message: 'invalid stage',
26
+ timestamp: Date.now(),
27
+ })).toThrow();
28
+ });
29
+ it('accepts websocket message envelope for pluginRuntimeLog', () => {
30
+ const parsed = WSMessageSchema.parse({
31
+ type: WSMessageType.PLUGIN_RUNTIME_LOG,
32
+ timestamp: new Date().toISOString(),
33
+ data: {
34
+ source: 'system',
35
+ stage: 'reload',
36
+ level: 'info',
37
+ message: 'Plugin reload started: all plugins',
38
+ timestamp: Date.now(),
39
+ },
40
+ });
41
+ expect(parsed.type).toBe(WSMessageType.PLUGIN_RUNTIME_LOG);
42
+ });
43
+ it('accepts runtime log history payload and websocket envelopes', () => {
44
+ const payload = PluginRuntimeLogHistoryPayloadSchema.parse({
45
+ entries: [
46
+ {
47
+ source: 'system',
48
+ stage: 'scan',
49
+ level: 'info',
50
+ message: 'Scanning plugin directory',
51
+ timestamp: Date.now() - 1000,
52
+ },
53
+ {
54
+ source: 'system',
55
+ stage: 'load',
56
+ level: 'error',
57
+ message: 'No entry file found',
58
+ timestamp: Date.now(),
59
+ directoryName: 'broken-plugin',
60
+ },
61
+ ],
62
+ });
63
+ expect(payload.entries).toHaveLength(2);
64
+ const requestMessage = WSMessageSchema.parse({
65
+ type: WSMessageType.GET_PLUGIN_RUNTIME_LOG_HISTORY,
66
+ timestamp: new Date().toISOString(),
67
+ data: { limit: 200 },
68
+ });
69
+ expect(requestMessage.type).toBe(WSMessageType.GET_PLUGIN_RUNTIME_LOG_HISTORY);
70
+ const historyMessage = WSMessageSchema.parse({
71
+ type: WSMessageType.PLUGIN_RUNTIME_LOG_HISTORY,
72
+ timestamp: new Date().toISOString(),
73
+ data: payload,
74
+ });
75
+ expect(historyMessage.type).toBe(WSMessageType.PLUGIN_RUNTIME_LOG_HISTORY);
76
+ });
77
+ });
78
+ //# sourceMappingURL=plugin-runtime-log.schema.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-runtime-log.schema.test.js","sourceRoot":"","sources":["../../../src/schema/__tests__/plugin-runtime-log.schema.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ import { z } from 'zod';
2
+ import { UserRole } from './auth.schema.js';
3
+ export type AppAction = 'manage' | 'read' | 'create' | 'update' | 'delete' | 'execute';
4
+ /**
5
+ * Domain subjects - entity-level access with instance conditions
6
+ * - Operator: condition { id: string }
7
+ * - Transmission: condition { operatorId: string }
8
+ * - Token / AuthConfig: admin-only management
9
+ */
10
+ export type DomainSubject = 'Operator' | 'Transmission' | 'Token' | 'AuthConfig';
11
+ /**
12
+ * Capability subjects - delegatable atomic permissions
13
+ * Each Permission enum value maps to exactly one CapabilitySubject
14
+ */
15
+ export type CapabilitySubject = 'RadioFrequency' | 'RadioTuner' | 'RadioTune' | 'RadioConfig' | 'RadioReconnect' | 'RadioControl' | 'RadioPower' | 'RigctldBridge' | 'Engine' | 'ModeSwitch' | 'SettingsDecodeWindows' | 'SettingsFrequencyPresets' | 'StationInfo';
16
+ export type AppSubject = DomainSubject | CapabilitySubject | 'all';
17
+ /** CASL generic type parameter: [Action, Subject] */
18
+ export type AppAbilities = [AppAction, AppSubject];
19
+ export declare enum Permission {
20
+ RADIO_SET_FREQUENCY = "radio:set_frequency",
21
+ RADIO_SET_TUNER = "radio:set_tuner",
22
+ RADIO_TUNE = "radio:tune",
23
+ RADIO_CONFIG = "radio:config",
24
+ RADIO_RECONNECT = "radio:reconnect",
25
+ /** 统一电台控制能力写命令(AF增益、静噪、发射功率等)*/
26
+ RADIO_CONTROL = "radio:control",
27
+ /** 电台电源管理(开机/关机)— 独立于 RADIO_CONTROL,影响物理设备可达性 */
28
+ RADIO_POWER = "radio:power",
29
+ /** 启停 rigctld TCP 桥接(允许外部软件如 N1MM / WSJT-X 接入当前电台)*/
30
+ RIGCTLD_BRIDGE = "rigctld:bridge",
31
+ ENGINE_START_STOP = "engine:start_stop",
32
+ MODE_SWITCH = "mode:switch",
33
+ SETTINGS_DECODE_WINDOWS = "settings:decode_windows",
34
+ SETTINGS_FREQUENCY_PRESETS = "settings:frequency_presets",
35
+ STATION_UPDATE = "station:update"
36
+ }
37
+ export declare const PermissionSchema: z.ZodNativeEnum<typeof Permission>;
38
+ export declare const PERMISSION_RULE_MAP: Record<Permission, {
39
+ action: AppAction;
40
+ subject: CapabilitySubject;
41
+ }>;
42
+ export declare const PermissionGrantSchema: z.ZodObject<{
43
+ permission: z.ZodNativeEnum<typeof Permission>;
44
+ /** MongoDB-style conditions for CASL, e.g. { frequency: { $in: [14074000] } } */
45
+ conditions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
46
+ }, "strip", z.ZodTypeAny, {
47
+ permission: Permission;
48
+ conditions?: Record<string, unknown> | undefined;
49
+ }, {
50
+ permission: Permission;
51
+ conditions?: Record<string, unknown> | undefined;
52
+ }>;
53
+ export type PermissionGrant = z.infer<typeof PermissionGrantSchema>;
54
+ export interface RawRule {
55
+ action: AppAction | AppAction[];
56
+ subject: AppSubject | AppSubject[];
57
+ conditions?: Record<string, unknown>;
58
+ inverted?: boolean;
59
+ }
60
+ /**
61
+ * Build CASL-compatible rules from role + operatorIds + permission grants.
62
+ * Three layers stacked:
63
+ * Layer 1: Role-based defaults
64
+ * Layer 2: Operator data scope (operatorIds → conditions)
65
+ * Layer 3: Custom permission grants
66
+ *
67
+ * Returns pure JSON — server/web each call createMongoAbility() with these rules.
68
+ */
69
+ export declare function buildAbilityRules(params: {
70
+ role: UserRole;
71
+ operatorIds?: string[];
72
+ permissionGrants?: PermissionGrant[];
73
+ }): RawRule[];
74
+ export interface PermissionGroupDef {
75
+ key: string;
76
+ permissions: Permission[];
77
+ }
78
+ export declare const PERMISSION_GROUPS: PermissionGroupDef[];
79
+ /** Permissions that support condition constraints (UI shows condition editor) */
80
+ export declare const CONDITIONAL_PERMISSIONS: Partial<Record<Permission, {
81
+ conditionField: string;
82
+ conditionOperator: '$in';
83
+ labelKey: string;
84
+ }>>;
85
+ //# sourceMappingURL=ability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ability.d.ts","sourceRoot":"","sources":["../../src/schema/ability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAI5C,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAIvF;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GACrB,UAAU,GACV,cAAc,GACd,OAAO,GACP,YAAY,CAAC;AAEjB;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GACzB,gBAAgB,GAChB,YAAY,GACZ,WAAW,GACX,aAAa,GACb,gBAAgB,GAChB,cAAc,GACd,YAAY,GACZ,eAAe,GACf,QAAQ,GACR,YAAY,GACZ,uBAAuB,GACvB,0BAA0B,GAC1B,aAAa,CAAC;AAElB,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,iBAAiB,GAAG,KAAK,CAAC;AAEnE,qDAAqD;AACrD,MAAM,MAAM,YAAY,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAInD,oBAAY,UAAU;IACpB,mBAAmB,wBAAwB;IAC3C,eAAe,oBAAoB;IACnC,UAAU,eAAe;IACzB,YAAY,iBAAiB;IAC7B,eAAe,oBAAoB;IACnC,gCAAgC;IAChC,aAAa,kBAAkB;IAC/B,iDAAiD;IACjD,WAAW,gBAAgB;IAC3B,qDAAqD;IACrD,cAAc,mBAAmB;IACjC,iBAAiB,sBAAsB;IACvC,WAAW,gBAAgB;IAC3B,uBAAuB,4BAA4B;IACnD,0BAA0B,+BAA+B;IACzD,cAAc,mBAAmB;CAClC;AAED,eAAO,MAAM,gBAAgB,oCAA2B,CAAC;AAIzD,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,CAcrG,CAAC;AAIF,eAAO,MAAM,qBAAqB;;IAEhC,iFAAiF;;;;;;;;EAEjF,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAIpE,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;IAChC,OAAO,EAAE,UAAU,GAAG,UAAU,EAAE,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAID;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;CACtC,GAAG,OAAO,EAAE,CAsCZ;AAID,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED,eAAO,MAAM,iBAAiB,EAAE,kBAAkB,EAwBjD,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE;IAC/D,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,KAAK,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAMD,CAAC"}
@@ -0,0 +1,119 @@
1
+ import { z } from 'zod';
2
+ import { UserRole } from './auth.schema.js';
3
+ // ===== Permission enum (storage & UI identifier) =====
4
+ export var Permission;
5
+ (function (Permission) {
6
+ Permission["RADIO_SET_FREQUENCY"] = "radio:set_frequency";
7
+ Permission["RADIO_SET_TUNER"] = "radio:set_tuner";
8
+ Permission["RADIO_TUNE"] = "radio:tune";
9
+ Permission["RADIO_CONFIG"] = "radio:config";
10
+ Permission["RADIO_RECONNECT"] = "radio:reconnect";
11
+ /** 统一电台控制能力写命令(AF增益、静噪、发射功率等)*/
12
+ Permission["RADIO_CONTROL"] = "radio:control";
13
+ /** 电台电源管理(开机/关机)— 独立于 RADIO_CONTROL,影响物理设备可达性 */
14
+ Permission["RADIO_POWER"] = "radio:power";
15
+ /** 启停 rigctld TCP 桥接(允许外部软件如 N1MM / WSJT-X 接入当前电台)*/
16
+ Permission["RIGCTLD_BRIDGE"] = "rigctld:bridge";
17
+ Permission["ENGINE_START_STOP"] = "engine:start_stop";
18
+ Permission["MODE_SWITCH"] = "mode:switch";
19
+ Permission["SETTINGS_DECODE_WINDOWS"] = "settings:decode_windows";
20
+ Permission["SETTINGS_FREQUENCY_PRESETS"] = "settings:frequency_presets";
21
+ Permission["STATION_UPDATE"] = "station:update";
22
+ })(Permission || (Permission = {}));
23
+ export const PermissionSchema = z.nativeEnum(Permission);
24
+ // ===== Permission → CASL rule mapping =====
25
+ export const PERMISSION_RULE_MAP = {
26
+ [Permission.RADIO_SET_FREQUENCY]: { action: 'execute', subject: 'RadioFrequency' },
27
+ [Permission.RADIO_SET_TUNER]: { action: 'execute', subject: 'RadioTuner' },
28
+ [Permission.RADIO_TUNE]: { action: 'execute', subject: 'RadioTune' },
29
+ [Permission.RADIO_CONFIG]: { action: 'update', subject: 'RadioConfig' },
30
+ [Permission.RADIO_RECONNECT]: { action: 'execute', subject: 'RadioReconnect' },
31
+ [Permission.RADIO_CONTROL]: { action: 'execute', subject: 'RadioControl' },
32
+ [Permission.RADIO_POWER]: { action: 'execute', subject: 'RadioPower' },
33
+ [Permission.RIGCTLD_BRIDGE]: { action: 'execute', subject: 'RigctldBridge' },
34
+ [Permission.ENGINE_START_STOP]: { action: 'execute', subject: 'Engine' },
35
+ [Permission.MODE_SWITCH]: { action: 'execute', subject: 'ModeSwitch' },
36
+ [Permission.SETTINGS_DECODE_WINDOWS]: { action: 'update', subject: 'SettingsDecodeWindows' },
37
+ [Permission.SETTINGS_FREQUENCY_PRESETS]: { action: 'update', subject: 'SettingsFrequencyPresets' },
38
+ [Permission.STATION_UPDATE]: { action: 'update', subject: 'StationInfo' },
39
+ };
40
+ // ===== PermissionGrant (stored on token) =====
41
+ export const PermissionGrantSchema = z.object({
42
+ permission: PermissionSchema,
43
+ /** MongoDB-style conditions for CASL, e.g. { frequency: { $in: [14074000] } } */
44
+ conditions: z.record(z.unknown()).optional(),
45
+ });
46
+ // ===== Ability rules builder =====
47
+ /**
48
+ * Build CASL-compatible rules from role + operatorIds + permission grants.
49
+ * Three layers stacked:
50
+ * Layer 1: Role-based defaults
51
+ * Layer 2: Operator data scope (operatorIds → conditions)
52
+ * Layer 3: Custom permission grants
53
+ *
54
+ * Returns pure JSON — server/web each call createMongoAbility() with these rules.
55
+ */
56
+ export function buildAbilityRules(params) {
57
+ const { role, operatorIds = [], permissionGrants = [] } = params;
58
+ // ADMIN: full access
59
+ if (role === UserRole.ADMIN) {
60
+ return [{ action: 'manage', subject: 'all' }];
61
+ }
62
+ const rules = [];
63
+ // Layer 1: role defaults
64
+ rules.push({ action: 'read', subject: 'all' });
65
+ if (role === UserRole.OPERATOR) {
66
+ // Operators can manage their own operators and transmissions
67
+ if (operatorIds.length > 0) {
68
+ rules.push({ action: 'manage', subject: 'Operator', conditions: { id: { $in: operatorIds } } }, { action: 'manage', subject: 'Transmission', conditions: { operatorId: { $in: operatorIds } } });
69
+ }
70
+ // Operators can create new operators (maxOperators checked separately)
71
+ rules.push({ action: 'create', subject: 'Operator' });
72
+ }
73
+ // Layer 2: custom permission grants
74
+ for (const grant of permissionGrants) {
75
+ const mapping = PERMISSION_RULE_MAP[grant.permission];
76
+ if (mapping) {
77
+ rules.push({
78
+ action: mapping.action,
79
+ subject: mapping.subject,
80
+ ...(grant.conditions ? { conditions: grant.conditions } : {}),
81
+ });
82
+ }
83
+ }
84
+ return rules;
85
+ }
86
+ export const PERMISSION_GROUPS = [
87
+ {
88
+ key: 'radio',
89
+ permissions: [
90
+ Permission.RADIO_SET_FREQUENCY,
91
+ Permission.RADIO_SET_TUNER,
92
+ Permission.RADIO_TUNE,
93
+ Permission.RADIO_CONFIG,
94
+ Permission.RADIO_RECONNECT,
95
+ Permission.RADIO_CONTROL,
96
+ Permission.RADIO_POWER,
97
+ Permission.RIGCTLD_BRIDGE,
98
+ ],
99
+ },
100
+ { key: 'engine', permissions: [Permission.ENGINE_START_STOP] },
101
+ { key: 'mode', permissions: [Permission.MODE_SWITCH] },
102
+ {
103
+ key: 'settings',
104
+ permissions: [
105
+ Permission.SETTINGS_DECODE_WINDOWS,
106
+ Permission.SETTINGS_FREQUENCY_PRESETS,
107
+ ],
108
+ },
109
+ { key: 'station', permissions: [Permission.STATION_UPDATE] },
110
+ ];
111
+ /** Permissions that support condition constraints (UI shows condition editor) */
112
+ export const CONDITIONAL_PERMISSIONS = {
113
+ [Permission.RADIO_SET_FREQUENCY]: {
114
+ conditionField: 'frequency',
115
+ conditionOperator: '$in',
116
+ labelKey: 'auth:permissions.frequencyRestriction',
117
+ },
118
+ };
119
+ //# sourceMappingURL=ability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ability.js","sourceRoot":"","sources":["../../src/schema/ability.ts"],"names":[],"mappings":"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"}