@tx5dr/contracts 1.7.11 → 2.0.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.
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/schema/__tests__/android-operator-audio.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/android-operator-audio.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/android-operator-audio.schema.test.js +27 -0
- package/dist/schema/__tests__/android-operator-audio.schema.test.js.map +1 -0
- package/dist/schema/__tests__/assisted-queue.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/assisted-queue.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/assisted-queue.schema.test.js +113 -0
- package/dist/schema/__tests__/assisted-queue.schema.test.js.map +1 -0
- package/dist/schema/__tests__/audio-sidecar.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/audio-sidecar.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/audio-sidecar.schema.test.js +42 -0
- package/dist/schema/__tests__/audio-sidecar.schema.test.js.map +1 -0
- package/dist/schema/__tests__/audio.schema.test.js +92 -1
- package/dist/schema/__tests__/audio.schema.test.js.map +1 -1
- package/dist/schema/__tests__/diagnostics.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/diagnostics.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/diagnostics.schema.test.js +31 -0
- package/dist/schema/__tests__/diagnostics.schema.test.js.map +1 -0
- package/dist/schema/__tests__/logbook-health.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/logbook-health.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/logbook-health.schema.test.js +104 -0
- package/dist/schema/__tests__/logbook-health.schema.test.js.map +1 -0
- package/dist/schema/__tests__/observability.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/observability.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/observability.schema.test.js +12 -0
- package/dist/schema/__tests__/observability.schema.test.js.map +1 -0
- package/dist/schema/__tests__/operator.schema.test.js +9 -3
- package/dist/schema/__tests__/operator.schema.test.js.map +1 -1
- package/dist/schema/__tests__/plugin-market.schema.test.js +43 -1
- package/dist/schema/__tests__/plugin-market.schema.test.js.map +1 -1
- package/dist/schema/__tests__/radio-power-support.test.js +12 -0
- package/dist/schema/__tests__/radio-power-support.test.js.map +1 -1
- package/dist/schema/__tests__/radio-profile.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/radio-profile.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/radio-profile.schema.test.js +36 -0
- package/dist/schema/__tests__/radio-profile.schema.test.js.map +1 -0
- package/dist/schema/__tests__/radio.schema.test.js +41 -1
- package/dist/schema/__tests__/radio.schema.test.js.map +1 -1
- package/dist/schema/__tests__/realtime-settings.schema.test.js +2 -1
- package/dist/schema/__tests__/realtime-settings.schema.test.js.map +1 -1
- package/dist/schema/__tests__/remote-access.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/remote-access.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/remote-access.schema.test.js +18 -0
- package/dist/schema/__tests__/remote-access.schema.test.js.map +1 -0
- package/dist/schema/android-operator-audio.schema.d.ts +174 -0
- package/dist/schema/android-operator-audio.schema.d.ts.map +1 -0
- package/dist/schema/android-operator-audio.schema.js +38 -0
- package/dist/schema/android-operator-audio.schema.js.map +1 -0
- package/dist/schema/api-response.schema.d.ts +268 -44
- package/dist/schema/api-response.schema.d.ts.map +1 -1
- package/dist/schema/audio-sidecar.schema.d.ts +75 -0
- package/dist/schema/audio-sidecar.schema.d.ts.map +1 -1
- package/dist/schema/audio-sidecar.schema.js +32 -0
- package/dist/schema/audio-sidecar.schema.js.map +1 -1
- package/dist/schema/audio.schema.d.ts +4749 -3
- package/dist/schema/audio.schema.d.ts.map +1 -1
- package/dist/schema/audio.schema.js +101 -2
- package/dist/schema/audio.schema.js.map +1 -1
- package/dist/schema/auth.schema.d.ts +171 -12
- package/dist/schema/auth.schema.d.ts.map +1 -1
- package/dist/schema/auth.schema.js +65 -1
- package/dist/schema/auth.schema.js.map +1 -1
- package/dist/schema/cpu-profile.schema.d.ts +2 -2
- package/dist/schema/cw-decoder.schema.d.ts +74 -74
- package/dist/schema/cw-keyer.schema.d.ts +20 -14
- package/dist/schema/cw-keyer.schema.d.ts.map +1 -1
- package/dist/schema/cw-keyer.schema.js +3 -0
- package/dist/schema/cw-keyer.schema.js.map +1 -1
- package/dist/schema/desktop-https.schema.d.ts +6 -6
- package/dist/schema/device-ui.schema.d.ts +6 -6
- package/dist/schema/diagnostics.schema.d.ts +163 -0
- package/dist/schema/diagnostics.schema.d.ts.map +1 -0
- package/dist/schema/diagnostics.schema.js +46 -0
- package/dist/schema/diagnostics.schema.js.map +1 -0
- package/dist/schema/ft8.schema.d.ts +12 -2
- package/dist/schema/ft8.schema.d.ts.map +1 -1
- package/dist/schema/ft8.schema.js +8 -0
- package/dist/schema/ft8.schema.js.map +1 -1
- package/dist/schema/logbook.schema.d.ts +1940 -18
- package/dist/schema/logbook.schema.d.ts.map +1 -1
- package/dist/schema/logbook.schema.js +158 -1
- package/dist/schema/logbook.schema.js.map +1 -1
- package/dist/schema/mode.schema.d.ts +2 -6
- package/dist/schema/mode.schema.d.ts.map +1 -1
- package/dist/schema/mode.schema.js +2 -6
- package/dist/schema/mode.schema.js.map +1 -1
- package/dist/schema/observability.schema.d.ts +66 -0
- package/dist/schema/observability.schema.d.ts.map +1 -0
- package/dist/schema/observability.schema.js +20 -0
- package/dist/schema/observability.schema.js.map +1 -0
- package/dist/schema/operator.schema.d.ts +6 -6
- package/dist/schema/operator.schema.d.ts.map +1 -1
- package/dist/schema/operator.schema.js +6 -1
- package/dist/schema/operator.schema.js.map +1 -1
- package/dist/schema/plugin.schema.d.ts +258 -78
- package/dist/schema/plugin.schema.d.ts.map +1 -1
- package/dist/schema/plugin.schema.js +57 -2
- package/dist/schema/plugin.schema.js.map +1 -1
- package/dist/schema/process-monitor.schema.d.ts +132 -132
- package/dist/schema/pskreporter.schema.d.ts +1 -3
- package/dist/schema/pskreporter.schema.d.ts.map +1 -1
- package/dist/schema/pskreporter.schema.js +1 -3
- package/dist/schema/pskreporter.schema.js.map +1 -1
- package/dist/schema/qso.schema.d.ts +7 -0
- package/dist/schema/qso.schema.d.ts.map +1 -1
- package/dist/schema/qso.schema.js +7 -0
- package/dist/schema/qso.schema.js.map +1 -1
- package/dist/schema/radio-capability.schema.d.ts +31 -40
- package/dist/schema/radio-capability.schema.d.ts.map +1 -1
- package/dist/schema/radio-capability.schema.js +7 -15
- package/dist/schema/radio-capability.schema.js.map +1 -1
- package/dist/schema/radio-power-support.d.ts.map +1 -1
- package/dist/schema/radio-power-support.js +3 -0
- package/dist/schema/radio-power-support.js.map +1 -1
- package/dist/schema/radio-power.schema.d.ts +87 -13
- package/dist/schema/radio-power.schema.d.ts.map +1 -1
- package/dist/schema/radio-power.schema.js +15 -8
- package/dist/schema/radio-power.schema.js.map +1 -1
- package/dist/schema/radio-profile.schema.d.ts +1240 -97
- package/dist/schema/radio-profile.schema.d.ts.map +1 -1
- package/dist/schema/radio.schema.d.ts +271 -48
- package/dist/schema/radio.schema.d.ts.map +1 -1
- package/dist/schema/radio.schema.js +44 -5
- package/dist/schema/radio.schema.js.map +1 -1
- package/dist/schema/realtime.schema.d.ts +60 -52
- package/dist/schema/realtime.schema.d.ts.map +1 -1
- package/dist/schema/realtime.schema.js +9 -1
- package/dist/schema/realtime.schema.js.map +1 -1
- package/dist/schema/slot-info.schema.d.ts +15 -9
- package/dist/schema/slot-info.schema.d.ts.map +1 -1
- package/dist/schema/slot-info.schema.js +15 -9
- package/dist/schema/slot-info.schema.js.map +1 -1
- package/dist/schema/spectrum.schema.d.ts +12 -12
- package/dist/schema/station-info.schema.d.ts +5 -0
- package/dist/schema/station-info.schema.d.ts.map +1 -1
- package/dist/schema/station-info.schema.js +5 -0
- package/dist/schema/station-info.schema.js.map +1 -1
- package/dist/schema/system.schema.d.ts +56 -6
- package/dist/schema/system.schema.d.ts.map +1 -1
- package/dist/schema/system.schema.js +22 -0
- package/dist/schema/system.schema.js.map +1 -1
- package/dist/schema/transmission.schema.d.ts +1 -7
- package/dist/schema/transmission.schema.d.ts.map +1 -1
- package/dist/schema/transmission.schema.js +2 -7
- package/dist/schema/transmission.schema.js.map +1 -1
- package/dist/schema/update.schema.d.ts +3 -0
- package/dist/schema/update.schema.d.ts.map +1 -1
- package/dist/schema/update.schema.js +1 -0
- package/dist/schema/update.schema.js.map +1 -1
- package/dist/schema/voice-keyer.schema.d.ts +16 -16
- package/dist/schema/websocket.schema.d.ts +3582 -555
- package/dist/schema/websocket.schema.d.ts.map +1 -1
- package/dist/schema/websocket.schema.js +160 -3
- package/dist/schema/websocket.schema.js.map +1 -1
- package/package.json +6 -1
- package/src/index.ts +3 -0
- package/src/schema/__tests__/android-operator-audio.schema.test.ts +31 -0
- package/src/schema/__tests__/assisted-queue.schema.test.ts +121 -0
- package/src/schema/__tests__/audio-sidecar.schema.test.ts +48 -0
- package/src/schema/__tests__/audio.schema.test.ts +102 -0
- package/src/schema/__tests__/diagnostics.schema.test.ts +32 -0
- package/src/schema/__tests__/logbook-health.schema.test.ts +117 -0
- package/src/schema/__tests__/observability.schema.test.ts +15 -0
- package/src/schema/__tests__/operator.schema.test.ts +11 -3
- package/src/schema/__tests__/plugin-market.schema.test.ts +49 -0
- package/src/schema/__tests__/radio-power-support.test.ts +14 -0
- package/src/schema/__tests__/radio-profile.schema.test.ts +44 -0
- package/src/schema/__tests__/radio.schema.test.ts +49 -1
- package/src/schema/__tests__/realtime-settings.schema.test.ts +2 -1
- package/src/schema/__tests__/remote-access.schema.test.ts +22 -0
- package/src/schema/android-operator-audio.schema.ts +49 -0
- package/src/schema/audio-sidecar.schema.ts +35 -0
- package/src/schema/audio.schema.ts +115 -2
- package/src/schema/auth.schema.ts +79 -1
- package/src/schema/cw-keyer.schema.ts +5 -0
- package/src/schema/diagnostics.schema.ts +55 -0
- package/src/schema/ft8.schema.ts +8 -0
- package/src/schema/logbook.schema.ts +204 -1
- package/src/schema/mode.schema.ts +2 -6
- package/src/schema/observability.schema.ts +26 -0
- package/src/schema/operator.schema.ts +7 -1
- package/src/schema/plugin.schema.ts +67 -2
- package/src/schema/pskreporter.schema.ts +1 -3
- package/src/schema/qso.schema.ts +7 -0
- package/src/schema/radio-capability.schema.ts +7 -15
- package/src/schema/radio-power-support.ts +3 -0
- package/src/schema/radio-power.schema.ts +15 -8
- package/src/schema/radio.schema.ts +55 -5
- package/src/schema/realtime.schema.ts +9 -1
- package/src/schema/slot-info.schema.ts +16 -10
- package/src/schema/station-info.schema.ts +5 -0
- package/src/schema/system.schema.ts +29 -0
- package/src/schema/transmission.schema.ts +2 -7
- package/src/schema/update.schema.ts +1 -0
- package/src/schema/websocket.schema.ts +223 -6
- package/test/radio-capability-schema.test.ts +44 -0
|
@@ -17,6 +17,11 @@ export const PluginTypeSchema = z.enum(['strategy', 'utility']);
|
|
|
17
17
|
*/
|
|
18
18
|
export type PluginType = z.infer<typeof PluginTypeSchema>;
|
|
19
19
|
|
|
20
|
+
export const StrategyFeaturesSchema = z.object({
|
|
21
|
+
targetQueue: z.literal(1).optional(),
|
|
22
|
+
}).optional();
|
|
23
|
+
export type StrategyFeatures = z.infer<typeof StrategyFeaturesSchema>;
|
|
24
|
+
|
|
20
25
|
/**
|
|
21
26
|
* Runtime instance scope for a plugin.
|
|
22
27
|
*
|
|
@@ -38,10 +43,16 @@ export type PluginInstanceScope = z.infer<typeof PluginInstanceScopeSchema>;
|
|
|
38
43
|
*/
|
|
39
44
|
export const PluginPermissionSchema = z.enum([
|
|
40
45
|
'network',
|
|
46
|
+
'plugin:event-bus',
|
|
41
47
|
'host:hamlib',
|
|
48
|
+
'operator:transmit-control',
|
|
42
49
|
'radio:read',
|
|
43
50
|
'radio:control',
|
|
51
|
+
'radio:tuner-control',
|
|
44
52
|
'radio:power',
|
|
53
|
+
'logbook:read',
|
|
54
|
+
'logbook:write',
|
|
55
|
+
'logbook:sync',
|
|
45
56
|
'settings:ft8',
|
|
46
57
|
'settings:decode-windows',
|
|
47
58
|
'settings:realtime',
|
|
@@ -74,7 +85,17 @@ export type PluginPanelComponent = z.infer<typeof PluginPanelComponentSchema>;
|
|
|
74
85
|
* These values control both validation expectations and default frontend
|
|
75
86
|
* rendering in plugin settings UIs.
|
|
76
87
|
*/
|
|
77
|
-
export const PluginSettingTypeSchema = z.enum([
|
|
88
|
+
export const PluginSettingTypeSchema = z.enum([
|
|
89
|
+
'boolean',
|
|
90
|
+
'number',
|
|
91
|
+
'string',
|
|
92
|
+
'string[]',
|
|
93
|
+
'object[]',
|
|
94
|
+
'keyedStringArrays',
|
|
95
|
+
'keyedObjectArrays',
|
|
96
|
+
'keyedObjects',
|
|
97
|
+
'info',
|
|
98
|
+
]);
|
|
78
99
|
|
|
79
100
|
/**
|
|
80
101
|
* Supported generated-form field types for plugin settings.
|
|
@@ -94,6 +115,11 @@ export const PluginSettingOptionSchema = z.object({
|
|
|
94
115
|
*/
|
|
95
116
|
export type PluginSettingOption = z.infer<typeof PluginSettingOptionSchema>;
|
|
96
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Field descriptor used for each item in an `object[]` or `keyedObjectArrays`
|
|
120
|
+
* setting editor. `key` becomes the object property; `type` controls the Host
|
|
121
|
+
* input; `required` and `default` are applied per item.
|
|
122
|
+
*/
|
|
97
123
|
export const PluginObjectArrayFieldSchema = z.object({
|
|
98
124
|
key: z.string(),
|
|
99
125
|
type: z.enum(['string', 'number', 'boolean']).optional().default('string'),
|
|
@@ -101,9 +127,14 @@ export const PluginObjectArrayFieldSchema = z.object({
|
|
|
101
127
|
description: z.string().optional(),
|
|
102
128
|
placeholder: z.string().optional(),
|
|
103
129
|
required: z.boolean().optional(),
|
|
130
|
+
default: z.unknown().optional(),
|
|
104
131
|
});
|
|
105
132
|
export type PluginObjectArrayField = z.infer<typeof PluginObjectArrayFieldSchema>;
|
|
106
133
|
|
|
134
|
+
/**
|
|
135
|
+
* Fixed key exposed by keyed setting editors. `key` is persisted in the value;
|
|
136
|
+
* `label` and `description` are literal text or plugin locale keys.
|
|
137
|
+
*/
|
|
107
138
|
export const PluginKeyedStringArrayKeySchema = z.object({
|
|
108
139
|
key: z.string(),
|
|
109
140
|
label: z.string(),
|
|
@@ -111,10 +142,18 @@ export const PluginKeyedStringArrayKeySchema = z.object({
|
|
|
111
142
|
});
|
|
112
143
|
export type PluginKeyedStringArrayKey = z.infer<typeof PluginKeyedStringArrayKeySchema>;
|
|
113
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Declarative condition evaluated against values in the same settings form.
|
|
147
|
+
* A leaf compares one `setting` with `equals` or `notEquals`; `allOf` requires
|
|
148
|
+
* every nested condition and `anyOf` requires at least one. Nested groups may
|
|
149
|
+
* be combined recursively.
|
|
150
|
+
*/
|
|
114
151
|
export interface PluginSettingCondition {
|
|
115
152
|
/** Single setting key to compare. Preserves the original condition shape. */
|
|
116
153
|
setting?: string;
|
|
154
|
+
/** Match when the referenced value is strictly equal to this value. */
|
|
117
155
|
equals?: unknown;
|
|
156
|
+
/** Match when the referenced value is not strictly equal to this value. */
|
|
118
157
|
notEquals?: unknown;
|
|
119
158
|
/** All nested conditions must match. */
|
|
120
159
|
allOf?: PluginSettingCondition[];
|
|
@@ -130,6 +169,7 @@ export const PluginSettingConditionSchema: z.ZodType<PluginSettingCondition> = z
|
|
|
130
169
|
anyOf: z.array(PluginSettingConditionSchema).optional(),
|
|
131
170
|
}));
|
|
132
171
|
|
|
172
|
+
/** Description override selected when its condition matches. */
|
|
133
173
|
export const PluginSettingConditionalDescriptionSchema = z.object({
|
|
134
174
|
when: PluginSettingConditionSchema,
|
|
135
175
|
description: z.string(),
|
|
@@ -156,6 +196,17 @@ export type PluginSettingScope = z.infer<typeof PluginSettingScopeSchema>;
|
|
|
156
196
|
*
|
|
157
197
|
* The host uses this schema to generate configuration forms, validate updates
|
|
158
198
|
* and resolve default values before injecting them into `ctx.config`.
|
|
199
|
+
*
|
|
200
|
+
* Collection defaults must match the selected renderer:
|
|
201
|
+
* - `string[]` -> `string[]`
|
|
202
|
+
* - `object[]` -> `Array<Record<string, unknown>>` described by `itemFields`
|
|
203
|
+
* - `keyedStringArrays` -> `Record<string, string[]>`
|
|
204
|
+
* - `keyedObjectArrays` -> `Record<string, Array<Record<string, unknown>>>`
|
|
205
|
+
* - `keyedObjects` -> `Record<string, Record<string, unknown>>`
|
|
206
|
+
*
|
|
207
|
+
* Keyed editors use `keys` for their fixed outer keys; object-based editors use
|
|
208
|
+
* `itemFields` for the nested shape. `info` is display-only and cannot be used
|
|
209
|
+
* by `quickSettings`.
|
|
159
210
|
*/
|
|
160
211
|
export const PluginSettingDescriptorSchema = z.object({
|
|
161
212
|
type: PluginSettingTypeSchema,
|
|
@@ -167,7 +218,7 @@ export const PluginSettingDescriptorSchema = z.object({
|
|
|
167
218
|
options: z.array(PluginSettingOptionSchema).optional(),
|
|
168
219
|
/** Field schema used by generated editors for `object[]` settings. */
|
|
169
220
|
itemFields: z.array(PluginObjectArrayFieldSchema).optional(),
|
|
170
|
-
/** Fixed key list used by generated
|
|
221
|
+
/** Fixed key list used by generated keyed setting editors. */
|
|
171
222
|
keys: z.array(PluginKeyedStringArrayKeySchema).optional(),
|
|
172
223
|
/** Conditionally show the field based on another setting in the same form. */
|
|
173
224
|
visibleWhen: PluginSettingConditionSchema.optional(),
|
|
@@ -231,6 +282,7 @@ export type PluginQuickSetting = z.infer<typeof PluginQuickSettingSchema>;
|
|
|
231
282
|
* about plugin roles without hard-coding specific plugin names.
|
|
232
283
|
*/
|
|
233
284
|
export const PluginCapabilitySchema = z.enum([
|
|
285
|
+
'auto_call_control',
|
|
234
286
|
'auto_call_candidate',
|
|
235
287
|
'auto_call_execution',
|
|
236
288
|
]);
|
|
@@ -354,6 +406,10 @@ export const PluginPanelDescriptorSchema = z.object({
|
|
|
354
406
|
*/
|
|
355
407
|
export type PluginPanelDescriptor = z.infer<typeof PluginPanelDescriptorSchema>;
|
|
356
408
|
|
|
409
|
+
/**
|
|
410
|
+
* Plugin instance that owns a runtime panel contribution: the single global
|
|
411
|
+
* instance or one explicitly identified operator instance.
|
|
412
|
+
*/
|
|
357
413
|
export const PluginUIPanelContributionTargetSchema = z.discriminatedUnion('kind', [
|
|
358
414
|
z.object({ kind: z.literal('global') }),
|
|
359
415
|
z.object({ kind: z.literal('operator'), operatorId: z.string() }),
|
|
@@ -455,9 +511,11 @@ export type PluginStorageConfig = z.infer<typeof PluginStorageConfigSchema>;
|
|
|
455
511
|
* host can expose to management UI and diagnostics.
|
|
456
512
|
*/
|
|
457
513
|
export const PluginManifestSchema = z.object({
|
|
514
|
+
apiVersion: z.literal(2).optional(),
|
|
458
515
|
name: z.string(),
|
|
459
516
|
version: z.string(),
|
|
460
517
|
type: PluginTypeSchema,
|
|
518
|
+
strategyFeatures: StrategyFeaturesSchema,
|
|
461
519
|
instanceScope: PluginInstanceScopeSchema.optional().default('operator'),
|
|
462
520
|
description: z.string().optional(),
|
|
463
521
|
permissions: z.array(PluginPermissionSchema).optional(),
|
|
@@ -503,6 +561,7 @@ export type PluginLocales = z.infer<typeof PluginLocalesSchema>;
|
|
|
503
561
|
export const PluginStatusSchema = z.object({
|
|
504
562
|
name: z.string(),
|
|
505
563
|
type: PluginTypeSchema,
|
|
564
|
+
strategyFeatures: StrategyFeaturesSchema,
|
|
506
565
|
instanceScope: PluginInstanceScopeSchema.optional().default('operator'),
|
|
507
566
|
version: z.string(),
|
|
508
567
|
description: z.string().optional(),
|
|
@@ -521,6 +580,8 @@ export const PluginStatusSchema = z.object({
|
|
|
521
580
|
panels: z.array(PluginPanelDescriptorSchema).optional(),
|
|
522
581
|
permissions: z.array(PluginPermissionSchema).optional(),
|
|
523
582
|
capabilities: z.array(PluginCapabilitySchema).optional(),
|
|
583
|
+
autoCallEnabledOperatorIds: z.array(z.string()).optional(),
|
|
584
|
+
pausedOperatorIds: z.array(z.string()).optional(),
|
|
524
585
|
ui: PluginUIConfigSchema.optional(),
|
|
525
586
|
locales: PluginLocalesSchema.optional(),
|
|
526
587
|
source: PluginSourceSchema.optional(),
|
|
@@ -620,6 +681,8 @@ export const PluginMarketCatalogEntrySchema = z.object({
|
|
|
620
681
|
name: z.string(),
|
|
621
682
|
title: z.string(),
|
|
622
683
|
description: z.string(),
|
|
684
|
+
readmeMarkdown: z.string().max(100 * 1024).optional(),
|
|
685
|
+
readmeSourceUrl: z.string().url().optional(),
|
|
623
686
|
locales: PluginLocalesSchema.optional(),
|
|
624
687
|
latestVersion: z.string(),
|
|
625
688
|
minHostVersion: z.string(),
|
|
@@ -686,6 +749,8 @@ export const PluginsConfigSchema = z.object({
|
|
|
686
749
|
z.string(),
|
|
687
750
|
z.record(z.string(), z.record(z.string(), z.unknown()))
|
|
688
751
|
).optional().default({}),
|
|
752
|
+
/** 每操作员暂停的 transmit-control 插件:operatorId → pluginName[] */
|
|
753
|
+
operatorPluginPauses: z.record(z.string(), z.array(z.string())).optional().default({}),
|
|
689
754
|
});
|
|
690
755
|
export type PluginsConfig = z.infer<typeof PluginsConfigSchema>;
|
|
691
756
|
|
|
@@ -16,9 +16,7 @@ export const PSKReporterStatsSchema = z.object({
|
|
|
16
16
|
consecutiveFailures: z.number().default(0),
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
/**
|
|
20
|
-
* PSKReporter 配置 Schema
|
|
21
|
-
*/
|
|
19
|
+
/** PSK Reporter publishing identity, antenna metadata, interval and counters. */
|
|
22
20
|
export const PSKReporterConfigSchema = z.object({
|
|
23
21
|
/** 是否启用 PSKReporter 上报 */
|
|
24
22
|
enabled: z.boolean().default(false),
|
package/src/schema/qso.schema.ts
CHANGED
|
@@ -91,6 +91,13 @@ export const QslSimpleStatusSchema = z.enum(['Y', 'N']).optional();
|
|
|
91
91
|
* - DXCC enrichment and review metadata;
|
|
92
92
|
* - LoTW / QRZ confirmation state;
|
|
93
93
|
* - station-location metadata used when exporting ADIF-like records.
|
|
94
|
+
*
|
|
95
|
+
* `frequency` is the RF frequency in hertz; `startTime`/`endTime` and QSL dates
|
|
96
|
+
* are Unix epoch milliseconds. `mode` is the ADIF main mode and `submode` is the
|
|
97
|
+
* optional ADIF submode. `messageHistory` contains the raw digital-mode exchange.
|
|
98
|
+
* Sync providers update the service-specific LoTW/QRZ fields using ADIF status
|
|
99
|
+
* codes (`Y`, `N`, `R`, `Q`, `I`, and received-only `V`) rather than a generic
|
|
100
|
+
* `qslStatus` field.
|
|
94
101
|
*/
|
|
95
102
|
export const QSORecordSchema = z.object({
|
|
96
103
|
id: z.string(),
|
|
@@ -36,9 +36,7 @@ export type CapabilityUpdateMode = z.infer<typeof CapabilityUpdateModeSchema>;
|
|
|
36
36
|
export const CapabilityOptionValueSchema = z.union([z.string(), z.number()]);
|
|
37
37
|
export type CapabilityOptionValue = z.infer<typeof CapabilityOptionValueSchema>;
|
|
38
38
|
|
|
39
|
-
/**
|
|
40
|
-
* 运行时能力值。
|
|
41
|
-
*/
|
|
39
|
+
/** Runtime value carried by a radio capability state. */
|
|
42
40
|
export const CapabilityValueSchema = z.union([z.boolean(), z.number(), z.string()]);
|
|
43
41
|
export type CapabilityValue = z.infer<typeof CapabilityValueSchema>;
|
|
44
42
|
|
|
@@ -84,10 +82,7 @@ export const CapabilityDisplaySchema = z.object({
|
|
|
84
82
|
});
|
|
85
83
|
export type CapabilityDisplay = z.infer<typeof CapabilityDisplaySchema>;
|
|
86
84
|
|
|
87
|
-
/**
|
|
88
|
-
* 能力描述符
|
|
89
|
-
* 由服务端在运行时下发,作为当前连接会话的真源。
|
|
90
|
-
*/
|
|
85
|
+
/** Host-provided descriptor that defines one capability for the current session. */
|
|
91
86
|
export const CapabilityDescriptorSchema = z.object({
|
|
92
87
|
/** 全局唯一能力 ID,如 'tuner_switch', 'rf_power', 'lock_mode' */
|
|
93
88
|
id: z.string(),
|
|
@@ -165,10 +160,7 @@ export const CapabilityDescriptorSchema = z.object({
|
|
|
165
160
|
|
|
166
161
|
export type CapabilityDescriptor = z.infer<typeof CapabilityDescriptorSchema>;
|
|
167
162
|
|
|
168
|
-
/**
|
|
169
|
-
* 能力运行时状态
|
|
170
|
-
* 动态数据,通过 WebSocket 实时同步到前端。
|
|
171
|
-
*/
|
|
163
|
+
/** Dynamic support, availability and value state for one capability. */
|
|
172
164
|
export const CapabilityStateSchema = z.object({
|
|
173
165
|
/** 能力 ID,与 CapabilityDescriptor.id 对应 */
|
|
174
166
|
id: z.string(),
|
|
@@ -209,9 +201,7 @@ export const CapabilityStateSchema = z.object({
|
|
|
209
201
|
|
|
210
202
|
export type CapabilityState = z.infer<typeof CapabilityStateSchema>;
|
|
211
203
|
|
|
212
|
-
/**
|
|
213
|
-
* 能力列表快照(radioCapabilityList WS 消息 / REST 响应的 data 部分)
|
|
214
|
-
*/
|
|
204
|
+
/** Complete descriptor/state snapshot returned by radio capability APIs. */
|
|
215
205
|
export const CapabilityListSchema = z.object({
|
|
216
206
|
descriptors: z.array(CapabilityDescriptorSchema),
|
|
217
207
|
capabilities: z.array(CapabilityStateSchema),
|
|
@@ -220,7 +210,8 @@ export const CapabilityListSchema = z.object({
|
|
|
220
210
|
export type CapabilityList = z.infer<typeof CapabilityListSchema>;
|
|
221
211
|
|
|
222
212
|
/**
|
|
223
|
-
*
|
|
213
|
+
* Legacy WebSocket payload for writing a generic radio capability.
|
|
214
|
+
* Plugin API v2 uses explicit radio/tuner command ports instead.
|
|
224
215
|
*/
|
|
225
216
|
export const WriteCapabilityPayloadSchema = z.object({
|
|
226
217
|
/** 能力 ID */
|
|
@@ -284,6 +275,7 @@ export const CAPABILITY_IDS = [
|
|
|
284
275
|
'agc_mode',
|
|
285
276
|
'preamp',
|
|
286
277
|
'attenuator',
|
|
278
|
+
'radio_mode',
|
|
287
279
|
'mode_bandwidth',
|
|
288
280
|
'split_enabled',
|
|
289
281
|
'vfo_select',
|
|
@@ -111,6 +111,9 @@ export function decidePowerSupport(
|
|
|
111
111
|
// ICOM WLAN 的 CI-V-over-UDP 通道在电台关机后无法维持;即便已连接
|
|
112
112
|
// 发送 powerstat(off) 也不能可靠恢复。整体不暴露电源控制。
|
|
113
113
|
return { canPowerOn: false, canPowerOff: false, supportedStates: [], reason: 'model-unsupported' };
|
|
114
|
+
case 'tci':
|
|
115
|
+
// TCI/ExpertSDR does not expose a safe physical power-on path here.
|
|
116
|
+
return { canPowerOn: false, canPowerOff: false, supportedStates: [], reason: 'model-unsupported' };
|
|
114
117
|
case 'serial': {
|
|
115
118
|
if (!rigInfo) {
|
|
116
119
|
return { canPowerOn: false, canPowerOff: false, supportedStates: [], reason: 'model-unsupported' };
|
|
@@ -37,7 +37,9 @@ export const RadioPowerStageSchema = z.enum([
|
|
|
37
37
|
export type RadioPowerStage = z.infer<typeof RadioPowerStageSchema>;
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* Last known power transition state exposed through WebSocket events and
|
|
41
|
+
* `ctx.radioPower.getState()`. `state` is the controller's high-level state;
|
|
42
|
+
* `stage` is finer progress; errors use a localized key plus diagnostic detail.
|
|
41
43
|
*/
|
|
42
44
|
export const RadioPowerStateEventSchema = z.object({
|
|
43
45
|
profileId: z.string().optional(),
|
|
@@ -51,12 +53,17 @@ export const RadioPowerStateEventSchema = z.object({
|
|
|
51
53
|
export type RadioPowerStateEvent = z.infer<typeof RadioPowerStateEventSchema>;
|
|
52
54
|
|
|
53
55
|
/**
|
|
54
|
-
*
|
|
56
|
+
* Power targets accepted by Host commands. `on`/`off` control physical power;
|
|
57
|
+
* `standby`/`operate` switch a responding radio between controller states.
|
|
55
58
|
*/
|
|
56
|
-
/** Allowed physical radio target states for a power request. */
|
|
57
59
|
export const RadioPowerTargetSchema = z.enum(['on', 'off', 'standby', 'operate']);
|
|
58
60
|
export type RadioPowerTarget = z.infer<typeof RadioPowerTargetSchema>;
|
|
59
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Request to transition one radio profile to a physical/controller power state.
|
|
64
|
+
* `profileId` selects the profile, `state` is the requested target, and
|
|
65
|
+
* `autoEngine` controls whether TX-5DR starts after a successful power-on.
|
|
66
|
+
*/
|
|
60
67
|
export const RadioPowerRequestSchema = z.object({
|
|
61
68
|
profileId: z.string().min(1),
|
|
62
69
|
/** Physical radio power target. This is not the TX-5DR software engine state. */
|
|
@@ -66,9 +73,7 @@ export const RadioPowerRequestSchema = z.object({
|
|
|
66
73
|
});
|
|
67
74
|
export type RadioPowerRequest = z.infer<typeof RadioPowerRequestSchema>;
|
|
68
75
|
|
|
69
|
-
/**
|
|
70
|
-
* REST response: POST /api/radio/power
|
|
71
|
-
*/
|
|
76
|
+
/** Result returned by the REST endpoint and `ctx.radioPowerCommands.submit()`. */
|
|
72
77
|
export const RadioPowerResponseSchema = z.object({
|
|
73
78
|
success: z.boolean(),
|
|
74
79
|
target: RadioPowerTargetSchema,
|
|
@@ -77,8 +82,10 @@ export const RadioPowerResponseSchema = z.object({
|
|
|
77
82
|
export type RadioPowerResponse = z.infer<typeof RadioPowerResponseSchema>;
|
|
78
83
|
|
|
79
84
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
85
|
+
* Power operations supported by one radio profile, returned by REST and
|
|
86
|
+
* `ctx.radioPower.getSupport()`. `reason` explains why wake is unavailable;
|
|
87
|
+
* `supportedStates` lists connected-state transitions the Host may accept.
|
|
88
|
+
* The Host resolves manufacturer/model names through Hamlib.
|
|
82
89
|
*/
|
|
83
90
|
export const RadioPowerSupportInfoSchema = z.object({
|
|
84
91
|
profileId: z.string(),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { CWKeyActiveLevelSchema } from './cw-keyer.schema.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* 中继差频方向
|
|
@@ -10,9 +11,7 @@ export const RepeaterShiftSchema = z.enum(['none', 'minus', 'plus']);
|
|
|
10
11
|
*/
|
|
11
12
|
export const ToneSquelchModeSchema = z.enum(['none', 'ctcss', 'dcs']);
|
|
12
13
|
|
|
13
|
-
/**
|
|
14
|
-
* 预设频率Schema
|
|
15
|
-
*/
|
|
14
|
+
/** Saved dial-frequency preset with band, digital mode and radio modulation. */
|
|
16
15
|
export const PresetFrequencySchema = z.object({
|
|
17
16
|
band: z.string(),
|
|
18
17
|
mode: z.string(), // 协议模式,如 FT8, FT4
|
|
@@ -192,11 +191,26 @@ export const IcomWlanConfigSchema = z.object({
|
|
|
192
191
|
dataMode: z.boolean().optional().default(true),
|
|
193
192
|
});
|
|
194
193
|
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* TCI / SunSDR 连接配置Schema
|
|
197
|
+
*/
|
|
198
|
+
export const TciConfigSchema = z.object({
|
|
199
|
+
host: z.string().default('127.0.0.1'),
|
|
200
|
+
port: z.number().int().min(1).max(65535).default(40001),
|
|
201
|
+
receiver: z.number().int().min(0).default(0),
|
|
202
|
+
trx: z.number().int().min(0).default(0),
|
|
203
|
+
vfo: z.number().int().min(0).default(0),
|
|
204
|
+
audioEnabled: z.boolean().optional().default(true),
|
|
205
|
+
audioSampleRate: z.number().int().min(8000).max(48000).optional().default(12000),
|
|
206
|
+
});
|
|
207
|
+
|
|
195
208
|
/**
|
|
196
209
|
* 串口连接配置Schema
|
|
197
210
|
*/
|
|
198
211
|
export const SerialConnectionConfigSchema = z.object({
|
|
199
212
|
path: z.string(),
|
|
213
|
+
serialNumber: z.string().optional(),
|
|
200
214
|
rigModel: z.number().int(),
|
|
201
215
|
serialConfig: SerialConfigSchema.optional(),
|
|
202
216
|
backendConfig: HamlibBackendConfigSchema.optional(),
|
|
@@ -206,6 +220,15 @@ export const HamlibSpectrumConfigSchema = z.object({
|
|
|
206
220
|
speed: z.number().int().min(0).max(255).optional(),
|
|
207
221
|
});
|
|
208
222
|
|
|
223
|
+
/**
|
|
224
|
+
* FT8/FT4 数字模式切换频率时的电台 CAT 模式偏好。
|
|
225
|
+
*
|
|
226
|
+
* - none: 只切换频率,不主动设置电台模式
|
|
227
|
+
* - usb: 设置普通 USB
|
|
228
|
+
* - usb-data: 设置 USB-DATA / PKTUSB 类数据模式
|
|
229
|
+
*/
|
|
230
|
+
export const DigitalModeRadioModePreferenceSchema = z.enum(['none', 'usb', 'usb-data']);
|
|
231
|
+
|
|
209
232
|
/**
|
|
210
233
|
* PTT (Push-to-Talk) 方法Schema
|
|
211
234
|
*
|
|
@@ -216,6 +239,15 @@ export const HamlibSpectrumConfigSchema = z.object({
|
|
|
216
239
|
*/
|
|
217
240
|
export const PttMethodSchema = z.enum(['cat', 'vox', 'dtr', 'rts']);
|
|
218
241
|
|
|
242
|
+
/**
|
|
243
|
+
* 虚拟频差(Virtual Frequency Offset / "Fake It" Split)配置Schema
|
|
244
|
+
* 目标音频频率与滞回区间目前由服务端常量控制(~1500Hz),此处仅暴露开关,预留扩展位。
|
|
245
|
+
*/
|
|
246
|
+
export const FakeFrequencyConfigSchema = z.object({
|
|
247
|
+
enabled: z.boolean(),
|
|
248
|
+
});
|
|
249
|
+
export type FakeFrequencyConfig = z.infer<typeof FakeFrequencyConfigSchema>;
|
|
250
|
+
|
|
219
251
|
/**
|
|
220
252
|
* Hamlib配置Schema - 嵌套对象结构
|
|
221
253
|
*
|
|
@@ -226,7 +258,7 @@ export const PttMethodSchema = z.enum(['cat', 'vox', 'dtr', 'rts']);
|
|
|
226
258
|
* - 根据 type 字段读取对应的配置对象
|
|
227
259
|
*/
|
|
228
260
|
export const HamlibConfigSchema = z.object({
|
|
229
|
-
type: z.enum(['none', 'network', 'serial', 'icom-wlan']),
|
|
261
|
+
type: z.enum(['none', 'network', 'serial', 'icom-wlan', 'tci']),
|
|
230
262
|
|
|
231
263
|
// 网络模式配置
|
|
232
264
|
network: NetworkConfigSchema.optional(),
|
|
@@ -234,17 +266,29 @@ export const HamlibConfigSchema = z.object({
|
|
|
234
266
|
// ICOM WLAN 模式配置
|
|
235
267
|
icomWlan: IcomWlanConfigSchema.optional(),
|
|
236
268
|
|
|
269
|
+
// TCI / SunSDR 模式配置
|
|
270
|
+
tci: TciConfigSchema.optional(),
|
|
271
|
+
|
|
237
272
|
// 串口模式配置
|
|
238
273
|
serial: SerialConnectionConfigSchema.optional(),
|
|
239
274
|
|
|
240
275
|
// Hamlib 频谱配置(当前仅用于官方频谱流 speed)
|
|
241
276
|
spectrum: HamlibSpectrumConfigSchema.optional(),
|
|
242
277
|
|
|
278
|
+
// FT8/FT4 切换频率时是否主动设置电台 CAT 模式;未设置时按 none 处理
|
|
279
|
+
digitalModeRadioMode: DigitalModeRadioModePreferenceSchema.optional(),
|
|
280
|
+
|
|
243
281
|
// 发射时序补偿(毫秒)- 用于补偿电台和网络的处理延迟
|
|
244
282
|
// 正值表示提前发射,负值表示延后发射
|
|
245
283
|
// 范围限制:-1000~1000ms,适用于各种网络和设备延迟场景
|
|
246
284
|
transmitCompensationMs: z.number().int().min(-1000).max(1000).optional(),
|
|
247
285
|
|
|
286
|
+
// 虚拟频差(Virtual Frequency Offset / WSJT-X "Fake It" Split)
|
|
287
|
+
// 启用后,发射时临时反向平移电台 dial 频率,使送进电台的音频载波保持在甜区(~1500Hz),
|
|
288
|
+
// 而打到空中的实际 RF 位置与用户设定的发射频点完全一致。
|
|
289
|
+
// 用于规避部分电台在音频频率过高/过低时发射功率衰减的问题;对用户透明(接收 dial、TX 标记不变)。
|
|
290
|
+
fakeFrequency: FakeFrequencyConfigSchema.optional(),
|
|
291
|
+
|
|
248
292
|
// PTT 方法(默认 'cat',即 Hamlib RIG 类型)
|
|
249
293
|
// 仅对 network 和 serial 连接类型有效,icom-wlan 固定使用 CI-V PTT
|
|
250
294
|
pttMethod: PttMethodSchema.optional(),
|
|
@@ -258,6 +302,9 @@ export const HamlibConfigSchema = z.object({
|
|
|
258
302
|
|
|
259
303
|
// CW 键控引脚类型(dtr 或 rts)
|
|
260
304
|
cwKeyMethod: z.enum(['dtr', 'rts']).optional(),
|
|
305
|
+
|
|
306
|
+
// CW 键控有效电平(默认 high,即高电平按下;部分接口为低电平按下)
|
|
307
|
+
cwKeyActiveLevel: CWKeyActiveLevelSchema.optional(),
|
|
261
308
|
});
|
|
262
309
|
|
|
263
310
|
/**
|
|
@@ -303,7 +350,7 @@ export const RadioInfoSchema = z.object({
|
|
|
303
350
|
/** Hamlib 电台型号 ID (serial/network 模式使用,icom-wlan 模式可选) */
|
|
304
351
|
rigModel: z.number().optional(),
|
|
305
352
|
/** 连接类型 */
|
|
306
|
-
connectionType: z.enum(['serial', 'network', 'icom-wlan']),
|
|
353
|
+
connectionType: z.enum(['serial', 'network', 'icom-wlan', 'tci']),
|
|
307
354
|
/** 固件版本 (如果可获取) */
|
|
308
355
|
firmwareVersion: z.string().optional(),
|
|
309
356
|
/** 序列号 (如果可获取) */
|
|
@@ -315,6 +362,7 @@ export const RadioInfoSchema = z.object({
|
|
|
315
362
|
*/
|
|
316
363
|
export const SerialPortSchema = z.object({
|
|
317
364
|
path: z.string(),
|
|
365
|
+
friendlyName: z.string().optional(),
|
|
318
366
|
manufacturer: z.string().optional(),
|
|
319
367
|
serialNumber: z.string().optional(),
|
|
320
368
|
pnpId: z.string().optional(),
|
|
@@ -461,8 +509,10 @@ export type HamlibConfigFieldType = z.infer<typeof HamlibConfigFieldTypeSchema>;
|
|
|
461
509
|
export type HamlibConfigField = z.infer<typeof HamlibConfigFieldSchema>;
|
|
462
510
|
export type NetworkConfig = z.infer<typeof NetworkConfigSchema>;
|
|
463
511
|
export type IcomWlanConfig = z.infer<typeof IcomWlanConfigSchema>;
|
|
512
|
+
export type TciConfig = z.infer<typeof TciConfigSchema>;
|
|
464
513
|
export type SerialConnectionConfig = z.infer<typeof SerialConnectionConfigSchema>;
|
|
465
514
|
export type HamlibSpectrumConfig = z.infer<typeof HamlibSpectrumConfigSchema>;
|
|
515
|
+
export type DigitalModeRadioModePreference = z.infer<typeof DigitalModeRadioModePreferenceSchema>;
|
|
466
516
|
export type PttMethod = z.infer<typeof PttMethodSchema>;
|
|
467
517
|
export type HamlibConfig = z.infer<typeof HamlibConfigSchema>;
|
|
468
518
|
export type RadioConfigResponse = z.infer<typeof RadioConfigResponseSchema>;
|
|
@@ -3,7 +3,7 @@ import { z } from 'zod';
|
|
|
3
3
|
export const RealtimeScopeSchema = z.enum(['radio', 'openwebrx-preview']);
|
|
4
4
|
export type RealtimeScope = z.infer<typeof RealtimeScopeSchema>;
|
|
5
5
|
|
|
6
|
-
export const RealtimeTransportKindSchema = z.enum(['rtc-data-audio', 'ws-compat']);
|
|
6
|
+
export const RealtimeTransportKindSchema = z.enum(['rtc-data-audio', 'ws-compat', 'android-native']);
|
|
7
7
|
export type RealtimeTransportKind = z.infer<typeof RealtimeTransportKindSchema>;
|
|
8
8
|
|
|
9
9
|
export const RealtimeSessionDirectionSchema = z.enum(['recv', 'send']);
|
|
@@ -307,6 +307,13 @@ export const RealtimeSessionResponseSchema = z.object({
|
|
|
307
307
|
|
|
308
308
|
export type RealtimeSessionResponse = z.infer<typeof RealtimeSessionResponseSchema>;
|
|
309
309
|
|
|
310
|
+
/**
|
|
311
|
+
* Persisted realtime-audio transport preferences.
|
|
312
|
+
*
|
|
313
|
+
* `transportPolicy` selects automatic or explicit transport behavior. The
|
|
314
|
+
* optional public host/UDP port advertise an RTC data-audio endpoint to remote
|
|
315
|
+
* clients; null/omitted values disable that public candidate.
|
|
316
|
+
*/
|
|
310
317
|
export const RealtimeSettingsSchema = z.object({
|
|
311
318
|
transportPolicy: RealtimeTransportPolicySchema.optional(),
|
|
312
319
|
rtcDataAudioPublicHost: RtcDataAudioPublicHostSchema.optional(),
|
|
@@ -333,6 +340,7 @@ export const RealtimeSettingsRuntimeSchema = z.object({
|
|
|
333
340
|
|
|
334
341
|
export type RealtimeSettingsRuntime = z.infer<typeof RealtimeSettingsRuntimeSchema>;
|
|
335
342
|
|
|
343
|
+
/** Realtime settings plus the Host's current resolved runtime projection. */
|
|
336
344
|
export const RealtimeSettingsResponseDataSchema = RealtimeSettingsSchema.extend({
|
|
337
345
|
runtime: RealtimeSettingsRuntimeSchema.optional(),
|
|
338
346
|
});
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { DxccStatusSchema, SubdivisionConfidenceSchema } from './qso.schema.js';
|
|
3
3
|
|
|
4
|
+
/** Number of non-empty slot packs retained for live FT8/FT4 message history. */
|
|
5
|
+
export const SLOT_PACK_HISTORY_LIMIT = 1000;
|
|
6
|
+
|
|
4
7
|
/**
|
|
5
8
|
* Frequency context captured when a slot pack is created.
|
|
6
9
|
* Fields are optional so older persisted slot packs remain valid.
|
|
@@ -16,11 +19,12 @@ export const SlotPackFrequencyContextSchema = z.object({
|
|
|
16
19
|
export type SlotPackFrequencyContext = z.infer<typeof SlotPackFrequencyContextSchema>;
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
|
-
*
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
*
|
|
22
|
+
* Timing and identity of one FT8/FT4 receive or transmit slot.
|
|
23
|
+
*
|
|
24
|
+
* `startMs` is the calibrated Unix epoch start in milliseconds; `phaseMs` is
|
|
25
|
+
* elapsed time inside the slot; `driftMs` is the clock correction; `cycleNumber`
|
|
26
|
+
* is the absolute slot index (use modulo two for even/odd); and `utcSeconds` is
|
|
27
|
+
* the integer epoch-second form used for display and logs.
|
|
24
28
|
*/
|
|
25
29
|
export const SlotInfoSchema = z.object({
|
|
26
30
|
/** 时隙唯一标识符 */
|
|
@@ -41,9 +45,7 @@ export const SlotInfoSchema = z.object({
|
|
|
41
45
|
|
|
42
46
|
export type SlotInfo = z.infer<typeof SlotInfoSchema>;
|
|
43
47
|
|
|
44
|
-
/**
|
|
45
|
-
* 基于日志本的消息分析结果
|
|
46
|
-
*/
|
|
48
|
+
/** Logbook-derived enrichment attached to a decoded message when available. */
|
|
47
49
|
export const LogbookAnalysisSchema = z.object({
|
|
48
50
|
/** 是否为新呼号(之前没有通联过) */
|
|
49
51
|
isNewCallsign: z.boolean().optional(),
|
|
@@ -76,7 +78,9 @@ export const LogbookAnalysisSchema = z.object({
|
|
|
76
78
|
export type LogbookAnalysis = z.infer<typeof LogbookAnalysisSchema>;
|
|
77
79
|
|
|
78
80
|
/**
|
|
79
|
-
*
|
|
81
|
+
* Original decoder frame with RF metrics and unparsed message text.
|
|
82
|
+
* `snr` is dB, `freq` is audio offset in hertz, `dt` is seconds, and
|
|
83
|
+
* `confidence` is normalized to 0..1.
|
|
80
84
|
*/
|
|
81
85
|
export const FrameMessageSchema = z.object({
|
|
82
86
|
/** 信号强度 (dB) */
|
|
@@ -157,7 +161,9 @@ export const DecodeResultSchema = z.object({
|
|
|
157
161
|
export type DecodeResult = z.infer<typeof DecodeResultSchema>;
|
|
158
162
|
|
|
159
163
|
/**
|
|
160
|
-
*
|
|
164
|
+
* Deduplicated best-frame collection for one slot, including decode statistics,
|
|
165
|
+
* history and the dial-frequency context captured when the slot began.
|
|
166
|
+
* `startMs`, `endMs` and history timestamps use Unix epoch milliseconds.
|
|
161
167
|
*/
|
|
162
168
|
export const SlotPackSchema = z.object({
|
|
163
169
|
/** 时隙ID */
|
|
@@ -16,6 +16,11 @@ export const StationQthSchema = z.object({
|
|
|
16
16
|
longitude: z.number().min(-180).max(180).optional(),
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Public station profile shown to clients and exposed through plugin settings.
|
|
21
|
+
* It contains optional display identity, callsign, Markdown description and QTH
|
|
22
|
+
* coordinates/grid; it never contains authentication or radio credentials.
|
|
23
|
+
*/
|
|
19
24
|
export const StationInfoSchema = z.object({
|
|
20
25
|
/** Station display name, e.g. "BG7XXX Remote Station" */
|
|
21
26
|
name: z.string().max(100).optional(),
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { RemoteAccessPresetSchema } from './auth.schema.js';
|
|
3
|
+
import { PluginDistributionSchema } from './plugin.schema.js';
|
|
2
4
|
|
|
3
5
|
// ===== 网络信息 =====
|
|
4
6
|
|
|
@@ -13,10 +15,35 @@ export const NetworkInfoSchema = z.object({
|
|
|
13
15
|
addresses: z.array(NetworkAddressSchema),
|
|
14
16
|
hostname: z.string(),
|
|
15
17
|
webPort: z.number(),
|
|
18
|
+
exposure: RemoteAccessPresetSchema.default('lan'),
|
|
19
|
+
listenHost: z.string().default('0.0.0.0'),
|
|
20
|
+
runtimeManagement: z.enum(['electron', 'external']).default('external'),
|
|
21
|
+
distribution: PluginDistributionSchema.default('generic-server'),
|
|
22
|
+
supportsLocalOnly: z.boolean().default(false),
|
|
23
|
+
supportedPresets: z.array(RemoteAccessPresetSchema).min(1).default(['lan', 'public']),
|
|
24
|
+
activeConnections: z.number().int().nonnegative().default(0),
|
|
25
|
+
maxConnections: z.number().int().positive().default(32),
|
|
16
26
|
});
|
|
17
27
|
|
|
18
28
|
export type NetworkInfo = z.infer<typeof NetworkInfoSchema>;
|
|
19
29
|
|
|
30
|
+
// ===== 日志设置 =====
|
|
31
|
+
|
|
32
|
+
export const SystemLogLevelSchema = z.enum(['debug', 'info', 'warn', 'error']);
|
|
33
|
+
export type SystemLogLevel = z.infer<typeof SystemLogLevelSchema>;
|
|
34
|
+
|
|
35
|
+
export const SystemLoggingSettingsSchema = z.object({
|
|
36
|
+
level: SystemLogLevelSchema.optional(),
|
|
37
|
+
effectiveLevel: SystemLogLevelSchema,
|
|
38
|
+
logsDir: z.string(),
|
|
39
|
+
});
|
|
40
|
+
export type SystemLoggingSettings = z.infer<typeof SystemLoggingSettingsSchema>;
|
|
41
|
+
|
|
42
|
+
export const UpdateSystemLoggingSettingsSchema = z.object({
|
|
43
|
+
level: SystemLogLevelSchema,
|
|
44
|
+
});
|
|
45
|
+
export type UpdateSystemLoggingSettingsRequest = z.infer<typeof UpdateSystemLoggingSettingsSchema>;
|
|
46
|
+
|
|
20
47
|
// ===== 时钟状态 =====
|
|
21
48
|
|
|
22
49
|
export const ClockSyncStateSchema = z.enum(['synced', 'stale', 'never', 'failed']);
|
|
@@ -115,12 +142,14 @@ const NtpServerArraySchema = z.array(NtpServerHostSchema).min(1).superRefine((se
|
|
|
115
142
|
}
|
|
116
143
|
});
|
|
117
144
|
|
|
145
|
+
/** Active NTP server list together with the Host-provided default list. */
|
|
118
146
|
export const NtpServerListSettingsSchema = z.object({
|
|
119
147
|
servers: NtpServerArraySchema,
|
|
120
148
|
defaultServers: NtpServerArraySchema,
|
|
121
149
|
});
|
|
122
150
|
export type NtpServerListSettings = z.infer<typeof NtpServerListSettingsSchema>;
|
|
123
151
|
|
|
152
|
+
/** Complete replacement list accepted by `ctx.settings.ntp.update()`. */
|
|
124
153
|
export const UpdateNtpServerListRequestSchema = z.object({
|
|
125
154
|
servers: NtpServerArraySchema,
|
|
126
155
|
});
|