camstreamerlib 4.0.35-bc56d1e → 4.0.36-05711a0
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/cjs/PlaneTrackerAPI.d.ts +3 -0
- package/cjs/VapixAPI.js +15 -11
- package/cjs/VapixAPI.test.d.ts +1 -0
- package/cjs/VapixAPI.test.js +146 -0
- package/cjs/types/PlaneTrackerAPI.d.ts +18 -0
- package/cjs/types/PlaneTrackerAPI.js +11 -1
- package/cjs/types/PlaneTrackerAPI.test.js +27 -0
- package/cjs/types/ws/CamSwitcherEvents.d.ts +8 -8
- package/esm/VapixAPI.js +16 -12
- package/esm/VapixAPI.test.js +144 -0
- package/esm/types/PlaneTrackerAPI.js +11 -1
- package/esm/types/PlaneTrackerAPI.test.js +27 -0
- package/package.json +1 -1
- package/types/PlaneTrackerAPI.d.ts +3 -0
- package/types/VapixAPI.test.d.ts +1 -0
- package/types/types/PlaneTrackerAPI.d.ts +18 -0
- package/types/types/ws/CamSwitcherEvents.d.ts +8 -8
package/cjs/PlaneTrackerAPI.d.ts
CHANGED
|
@@ -87,6 +87,7 @@ export declare class PlaneTrackerAPI<Client extends IClient<TResponse, any>> ext
|
|
|
87
87
|
widget: {
|
|
88
88
|
enabled: boolean;
|
|
89
89
|
scale: number;
|
|
90
|
+
units: "rotate" | "metric" | "imperial";
|
|
90
91
|
coord: "top_left" | "top_right" | "bottom_left" | "bottom_right";
|
|
91
92
|
posX: number;
|
|
92
93
|
posY: number;
|
|
@@ -100,6 +101,8 @@ export declare class PlaneTrackerAPI<Client extends IClient<TResponse, any>> ext
|
|
|
100
101
|
posY: number;
|
|
101
102
|
showWeather: boolean;
|
|
102
103
|
weatherLocationKey: string;
|
|
104
|
+
windSpeedUnits: "rotate" | "metric" | "imperial";
|
|
105
|
+
temperatureUnits: "rotate" | "metric" | "imperial";
|
|
103
106
|
};
|
|
104
107
|
fr24FlightInfoSource: {
|
|
105
108
|
enabled: boolean;
|
package/cjs/VapixAPI.js
CHANGED
|
@@ -565,17 +565,21 @@ class VapixAPI extends BasicAPI_1.BasicAPI {
|
|
|
565
565
|
allowBooleanAttributes: true,
|
|
566
566
|
});
|
|
567
567
|
const result = parser.parse(xml);
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
|
|
568
|
+
const rawApps = result.reply.application ?? [];
|
|
569
|
+
const apps = Array.isArray(rawApps) ? rawApps : [rawApps];
|
|
570
|
+
const appList = [];
|
|
571
|
+
for (const app of apps) {
|
|
572
|
+
const parsedApp = VapixAPI_1.applicationSchema.safeParse(app);
|
|
573
|
+
if (!parsedApp.success) {
|
|
574
|
+
console.debug('Skipping invalid application entry:', app, parsedApp.error.issues);
|
|
575
|
+
continue;
|
|
576
|
+
}
|
|
577
|
+
appList.push({
|
|
578
|
+
...parsedApp.data,
|
|
579
|
+
appId: VapixAPI_1.ALL_APP_IDS.find((id) => id.toLowerCase() === parsedApp.data.Name.toLowerCase()) ?? null,
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
return appList;
|
|
579
583
|
}
|
|
580
584
|
async startApplication(applicationId, options) {
|
|
581
585
|
const agent = this.getClient(options?.proxyParams);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const VapixAPI_1 = require("./VapixAPI");
|
|
4
|
+
const globals_1 = require("@jest/globals");
|
|
5
|
+
const createApi = (xml) => {
|
|
6
|
+
const client = {
|
|
7
|
+
get: () => Promise.resolve(new Response(xml)),
|
|
8
|
+
post: () => Promise.reject(new Error('unused')),
|
|
9
|
+
};
|
|
10
|
+
return new VapixAPI_1.VapixAPI(client);
|
|
11
|
+
};
|
|
12
|
+
(0, globals_1.describe)('VapixAPI', () => {
|
|
13
|
+
(0, globals_1.describe)('getApplicationList', () => {
|
|
14
|
+
(0, globals_1.afterEach)(() => {
|
|
15
|
+
globals_1.jest.restoreAllMocks();
|
|
16
|
+
});
|
|
17
|
+
(0, globals_1.test)('skips the nameless entry of the live camera list', async () => {
|
|
18
|
+
const debugSpy = globals_1.jest.spyOn(console, 'debug').mockImplementation(() => { });
|
|
19
|
+
const api = createApi(`<reply result="ok">
|
|
20
|
+
<application Name="camstreamer" NiceName="CamStreamer App" Vendor="CamStreamer" Version="5.0-15" ApplicationID="413135" License="None" Status="Running" ConfigurationPage="local/camstreamer/settings.html" />
|
|
21
|
+
<application Name="" License="None" Status="Stopped" />
|
|
22
|
+
<application Name="vmd" NiceName="AXIS Video Motion Detection" Vendor="Axis Communications" Version="4.4-5" ApplicationID="143440" License="None" Status="Stopped" ConfigurationPage="local/vmd/config.html" VendorHomePage="http://www.axis.com" LicenseName="Proprietary" />
|
|
23
|
+
</reply>`);
|
|
24
|
+
await (0, globals_1.expect)(api.getApplicationList()).resolves.toEqual([
|
|
25
|
+
{
|
|
26
|
+
Name: 'camstreamer',
|
|
27
|
+
NiceName: 'CamStreamer App',
|
|
28
|
+
Vendor: 'CamStreamer',
|
|
29
|
+
Version: '5.0-15',
|
|
30
|
+
ApplicationID: '413135',
|
|
31
|
+
License: 'None',
|
|
32
|
+
Status: 'Running',
|
|
33
|
+
ConfigurationPage: 'local/camstreamer/settings.html',
|
|
34
|
+
appId: 'CamStreamer',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
Name: 'vmd',
|
|
38
|
+
NiceName: 'AXIS Video Motion Detection',
|
|
39
|
+
Vendor: 'Axis Communications',
|
|
40
|
+
Version: '4.4-5',
|
|
41
|
+
ApplicationID: '143440',
|
|
42
|
+
License: 'None',
|
|
43
|
+
Status: 'Stopped',
|
|
44
|
+
ConfigurationPage: 'local/vmd/config.html',
|
|
45
|
+
VendorHomePage: 'http://www.axis.com',
|
|
46
|
+
LicenseName: 'Proprietary',
|
|
47
|
+
appId: null,
|
|
48
|
+
},
|
|
49
|
+
]);
|
|
50
|
+
(0, globals_1.expect)(debugSpy).toHaveBeenCalledTimes(1);
|
|
51
|
+
(0, globals_1.expect)(debugSpy.mock.calls[0]).toContainEqual({ Name: '', License: 'None', Status: 'Stopped' });
|
|
52
|
+
});
|
|
53
|
+
globals_1.test.each([
|
|
54
|
+
{
|
|
55
|
+
name: 'an entry without a name',
|
|
56
|
+
xml: '<reply result="ok"><application Name="vmd" NiceName="AXIS Video Motion Detection" Vendor="Axis Communications" Version="4.4-5" License="None" Status="Stopped" /><application License="None" Status="Stopped" /></reply>',
|
|
57
|
+
expected: [
|
|
58
|
+
{
|
|
59
|
+
Name: 'vmd',
|
|
60
|
+
NiceName: 'AXIS Video Motion Detection',
|
|
61
|
+
Vendor: 'Axis Communications',
|
|
62
|
+
Version: '4.4-5',
|
|
63
|
+
License: 'None',
|
|
64
|
+
Status: 'Stopped',
|
|
65
|
+
appId: null,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'a named entry missing informational fields',
|
|
71
|
+
xml: '<reply result="ok"><application Name="vmd" NiceName="AXIS Video Motion Detection" Vendor="Axis Communications" Version="4.4-5" License="None" Status="Stopped" /><application Name="broken" License="None" Status="Stopped" /></reply>',
|
|
72
|
+
expected: [
|
|
73
|
+
{
|
|
74
|
+
Name: 'vmd',
|
|
75
|
+
NiceName: 'AXIS Video Motion Detection',
|
|
76
|
+
Vendor: 'Axis Communications',
|
|
77
|
+
Version: '4.4-5',
|
|
78
|
+
License: 'None',
|
|
79
|
+
Status: 'Stopped',
|
|
80
|
+
appId: null,
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
])('skips invalid entries individually: $name', async ({ xml, expected }) => {
|
|
85
|
+
const debugSpy = globals_1.jest.spyOn(console, 'debug').mockImplementation(() => { });
|
|
86
|
+
await (0, globals_1.expect)(createApi(xml).getApplicationList()).resolves.toEqual(expected);
|
|
87
|
+
(0, globals_1.expect)(debugSpy).toHaveBeenCalledTimes(1);
|
|
88
|
+
});
|
|
89
|
+
globals_1.test.each([
|
|
90
|
+
{
|
|
91
|
+
name: 'drops attributes outside the schema',
|
|
92
|
+
xml: '<reply result="ok"><application Name="camoverlay" NiceName="CamOverlay App" Vendor="CamStreamer" Version="3.0-1" License="None" Status="Running" Unexpected="value" /></reply>',
|
|
93
|
+
expected: [
|
|
94
|
+
{
|
|
95
|
+
Name: 'camoverlay',
|
|
96
|
+
NiceName: 'CamOverlay App',
|
|
97
|
+
Vendor: 'CamStreamer',
|
|
98
|
+
Version: '3.0-1',
|
|
99
|
+
License: 'None',
|
|
100
|
+
Status: 'Running',
|
|
101
|
+
appId: 'CamOverlay',
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: 'maps an application outside the core CamStreamer apps to its appId',
|
|
107
|
+
xml: '<reply result="ok"><application Name="sporttracker" NiceName="SportTracker App" Vendor="CamStreamer" Version="1.0-1" License="None" Status="Running" /></reply>',
|
|
108
|
+
expected: [
|
|
109
|
+
{
|
|
110
|
+
Name: 'sporttracker',
|
|
111
|
+
NiceName: 'SportTracker App',
|
|
112
|
+
Vendor: 'CamStreamer',
|
|
113
|
+
Version: '1.0-1',
|
|
114
|
+
License: 'None',
|
|
115
|
+
Status: 'Running',
|
|
116
|
+
appId: 'SportTracker',
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: 'maps a capitalised application name to its appId',
|
|
122
|
+
xml: '<reply result="ok"><application Name="CamOverlay" NiceName="CamOverlay App" Vendor="CamStreamer" Version="3.0-1" License="None" Status="Running" /></reply>',
|
|
123
|
+
expected: [
|
|
124
|
+
{
|
|
125
|
+
Name: 'CamOverlay',
|
|
126
|
+
NiceName: 'CamOverlay App',
|
|
127
|
+
Vendor: 'CamStreamer',
|
|
128
|
+
Version: '3.0-1',
|
|
129
|
+
License: 'None',
|
|
130
|
+
Status: 'Running',
|
|
131
|
+
appId: 'CamOverlay',
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: 'returns an empty list when the camera has no applications',
|
|
137
|
+
xml: '<reply result="ok"></reply>',
|
|
138
|
+
expected: [],
|
|
139
|
+
},
|
|
140
|
+
])('returns every valid entry with its appId and logs nothing: $name', async ({ xml, expected }) => {
|
|
141
|
+
const debugSpy = globals_1.jest.spyOn(console, 'debug').mockImplementation(() => { });
|
|
142
|
+
await (0, globals_1.expect)(createApi(xml).getApplicationList()).resolves.toEqual(expected);
|
|
143
|
+
(0, globals_1.expect)(debugSpy).not.toHaveBeenCalled();
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
});
|
|
@@ -54,6 +54,8 @@ export declare const widgetSchema: z.ZodObject<{
|
|
|
54
54
|
posY: number;
|
|
55
55
|
enabled?: boolean | undefined;
|
|
56
56
|
}>;
|
|
57
|
+
declare const widgetUnitsSchema: z.ZodUnion<[z.ZodLiteral<"metric">, z.ZodLiteral<"imperial">, z.ZodLiteral<"rotate">]>;
|
|
58
|
+
export type TWidgetUnits = z.infer<typeof widgetUnitsSchema>;
|
|
57
59
|
declare const labelOptionsSchema: z.ZodUnion<[z.ZodLiteral<"blank">, z.ZodLiteral<"registration">, z.ZodLiteral<"call_sign">, z.ZodLiteral<"flight_number">, z.ZodLiteral<"icao">]>;
|
|
58
60
|
export type TLabelOption = z.infer<typeof labelOptionsSchema>;
|
|
59
61
|
declare const droneLabelOptionsSchema: z.ZodUnion<[z.ZodLiteral<"blank">, z.ZodLiteral<"remote_id">]>;
|
|
@@ -313,9 +315,12 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
313
315
|
posX: z.ZodNumber;
|
|
314
316
|
posY: z.ZodNumber;
|
|
315
317
|
scale: z.ZodNumber;
|
|
318
|
+
} & {
|
|
319
|
+
units: z.ZodDefault<z.ZodUnion<[z.ZodLiteral<"metric">, z.ZodLiteral<"imperial">, z.ZodLiteral<"rotate">]>>;
|
|
316
320
|
}, "strip", z.ZodTypeAny, {
|
|
317
321
|
enabled: boolean;
|
|
318
322
|
scale: number;
|
|
323
|
+
units: "rotate" | "metric" | "imperial";
|
|
319
324
|
coord: "top_left" | "top_right" | "bottom_left" | "bottom_right";
|
|
320
325
|
posX: number;
|
|
321
326
|
posY: number;
|
|
@@ -325,6 +330,7 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
325
330
|
posX: number;
|
|
326
331
|
posY: number;
|
|
327
332
|
enabled?: boolean | undefined;
|
|
333
|
+
units?: "rotate" | "metric" | "imperial" | undefined;
|
|
328
334
|
}>>;
|
|
329
335
|
airportWidget: z.ZodDefault<z.ZodObject<{
|
|
330
336
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -336,6 +342,8 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
336
342
|
showWeather: z.ZodDefault<z.ZodBoolean>;
|
|
337
343
|
weatherLocationKey: z.ZodDefault<z.ZodString>;
|
|
338
344
|
weatherLocationName: z.ZodDefault<z.ZodString>;
|
|
345
|
+
windSpeedUnits: z.ZodDefault<z.ZodUnion<[z.ZodLiteral<"metric">, z.ZodLiteral<"imperial">, z.ZodLiteral<"rotate">]>>;
|
|
346
|
+
temperatureUnits: z.ZodDefault<z.ZodUnion<[z.ZodLiteral<"metric">, z.ZodLiteral<"imperial">, z.ZodLiteral<"rotate">]>>;
|
|
339
347
|
}, "strip", z.ZodTypeAny, {
|
|
340
348
|
enabled: boolean;
|
|
341
349
|
scale: number;
|
|
@@ -345,6 +353,8 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
345
353
|
posY: number;
|
|
346
354
|
showWeather: boolean;
|
|
347
355
|
weatherLocationKey: string;
|
|
356
|
+
windSpeedUnits: "rotate" | "metric" | "imperial";
|
|
357
|
+
temperatureUnits: "rotate" | "metric" | "imperial";
|
|
348
358
|
}, {
|
|
349
359
|
scale: number;
|
|
350
360
|
coord: "top_left" | "top_right" | "bottom_left" | "bottom_right";
|
|
@@ -354,6 +364,8 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
354
364
|
weatherLocationName?: string | undefined;
|
|
355
365
|
showWeather?: boolean | undefined;
|
|
356
366
|
weatherLocationKey?: string | undefined;
|
|
367
|
+
windSpeedUnits?: "rotate" | "metric" | "imperial" | undefined;
|
|
368
|
+
temperatureUnits?: "rotate" | "metric" | "imperial" | undefined;
|
|
357
369
|
}>>;
|
|
358
370
|
fr24FlightInfoSource: z.ZodDefault<z.ZodObject<{
|
|
359
371
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -614,6 +626,7 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
614
626
|
widget: {
|
|
615
627
|
enabled: boolean;
|
|
616
628
|
scale: number;
|
|
629
|
+
units: "rotate" | "metric" | "imperial";
|
|
617
630
|
coord: "top_left" | "top_right" | "bottom_left" | "bottom_right";
|
|
618
631
|
posX: number;
|
|
619
632
|
posY: number;
|
|
@@ -627,6 +640,8 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
627
640
|
posY: number;
|
|
628
641
|
showWeather: boolean;
|
|
629
642
|
weatherLocationKey: string;
|
|
643
|
+
windSpeedUnits: "rotate" | "metric" | "imperial";
|
|
644
|
+
temperatureUnits: "rotate" | "metric" | "imperial";
|
|
630
645
|
};
|
|
631
646
|
fr24FlightInfoSource: {
|
|
632
647
|
enabled: boolean;
|
|
@@ -802,6 +817,7 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
802
817
|
posX: number;
|
|
803
818
|
posY: number;
|
|
804
819
|
enabled?: boolean | undefined;
|
|
820
|
+
units?: "rotate" | "metric" | "imperial" | undefined;
|
|
805
821
|
} | undefined;
|
|
806
822
|
airportWidget?: {
|
|
807
823
|
scale: number;
|
|
@@ -812,6 +828,8 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
812
828
|
weatherLocationName?: string | undefined;
|
|
813
829
|
showWeather?: boolean | undefined;
|
|
814
830
|
weatherLocationKey?: string | undefined;
|
|
831
|
+
windSpeedUnits?: "rotate" | "metric" | "imperial" | undefined;
|
|
832
|
+
temperatureUnits?: "rotate" | "metric" | "imperial" | undefined;
|
|
815
833
|
} | undefined;
|
|
816
834
|
fr24FlightInfoSource?: {
|
|
817
835
|
enabled?: boolean | undefined;
|
|
@@ -28,6 +28,7 @@ exports.widgetSchema = zod_1.z.object({
|
|
|
28
28
|
posY: zod_1.z.number().nonnegative(),
|
|
29
29
|
scale: zod_1.z.number().positive(),
|
|
30
30
|
});
|
|
31
|
+
const widgetUnitsSchema = zod_1.z.union([zod_1.z.literal('metric'), zod_1.z.literal('imperial'), zod_1.z.literal('rotate')]);
|
|
31
32
|
const labelOptionsSchema = zod_1.z.union([
|
|
32
33
|
zod_1.z.literal('blank'),
|
|
33
34
|
zod_1.z.literal('registration'),
|
|
@@ -189,18 +190,25 @@ exports.cameraSettingsSchema = zod_1.z.object({
|
|
|
189
190
|
displaySystemInfo: zod_1.z.boolean().optional(),
|
|
190
191
|
})
|
|
191
192
|
.optional(),
|
|
192
|
-
widget: exports.widgetSchema
|
|
193
|
+
widget: exports.widgetSchema
|
|
194
|
+
.extend({
|
|
195
|
+
units: widgetUnitsSchema.default('rotate'),
|
|
196
|
+
})
|
|
197
|
+
.default({
|
|
193
198
|
enabled: true,
|
|
194
199
|
coord: 'top_right',
|
|
195
200
|
posX: 10,
|
|
196
201
|
posY: 10,
|
|
197
202
|
scale: 100,
|
|
203
|
+
units: 'rotate',
|
|
198
204
|
}),
|
|
199
205
|
airportWidget: exports.widgetSchema
|
|
200
206
|
.extend({
|
|
201
207
|
showWeather: zod_1.z.boolean().default(false),
|
|
202
208
|
weatherLocationKey: zod_1.z.string().default(''),
|
|
203
209
|
weatherLocationName: zod_1.z.string().default(''),
|
|
210
|
+
windSpeedUnits: widgetUnitsSchema.default('rotate'),
|
|
211
|
+
temperatureUnits: widgetUnitsSchema.default('rotate'),
|
|
204
212
|
})
|
|
205
213
|
.default({
|
|
206
214
|
enabled: true,
|
|
@@ -211,6 +219,8 @@ exports.cameraSettingsSchema = zod_1.z.object({
|
|
|
211
219
|
showWeather: false,
|
|
212
220
|
weatherLocationKey: '',
|
|
213
221
|
weatherLocationName: '',
|
|
222
|
+
windSpeedUnits: 'rotate',
|
|
223
|
+
temperatureUnits: 'rotate',
|
|
214
224
|
}),
|
|
215
225
|
fr24FlightInfoSource: zod_1.z
|
|
216
226
|
.object({
|
|
@@ -88,3 +88,30 @@ const DEFAULT_CAPTURE_CONFIG = { defaultCaptureSizeMeters: 120, captureSizeExten
|
|
|
88
88
|
(0, globals_1.expect)(PlaneTrackerAPI_1.cameraSettingsSchema.safeParse({ cameraConfig }).success).toBe(false);
|
|
89
89
|
});
|
|
90
90
|
});
|
|
91
|
+
(0, globals_1.describe)('cameraSettingsSchema widget units', () => {
|
|
92
|
+
const WIDGET = { coord: 'top_left', posX: 10, posY: 10, scale: 100 };
|
|
93
|
+
(0, globals_1.test)('defaults all widget units to rotate', () => {
|
|
94
|
+
const settings = PlaneTrackerAPI_1.cameraSettingsSchema.parse({});
|
|
95
|
+
(0, globals_1.expect)(settings.widget.units).toBe('rotate');
|
|
96
|
+
(0, globals_1.expect)(settings.airportWidget.windSpeedUnits).toBe('rotate');
|
|
97
|
+
(0, globals_1.expect)(settings.airportWidget.temperatureUnits).toBe('rotate');
|
|
98
|
+
});
|
|
99
|
+
(0, globals_1.test)('defaults missing units of saved widgets to rotate', () => {
|
|
100
|
+
const settings = PlaneTrackerAPI_1.cameraSettingsSchema.parse({ widget: WIDGET, airportWidget: WIDGET });
|
|
101
|
+
(0, globals_1.expect)(settings.widget.units).toBe('rotate');
|
|
102
|
+
(0, globals_1.expect)(settings.airportWidget.windSpeedUnits).toBe('rotate');
|
|
103
|
+
(0, globals_1.expect)(settings.airportWidget.temperatureUnits).toBe('rotate');
|
|
104
|
+
});
|
|
105
|
+
(0, globals_1.test)('parses independent widget units', () => {
|
|
106
|
+
const settings = PlaneTrackerAPI_1.cameraSettingsSchema.parse({
|
|
107
|
+
widget: { ...WIDGET, units: 'imperial' },
|
|
108
|
+
airportWidget: { ...WIDGET, windSpeedUnits: 'rotate', temperatureUnits: 'metric' },
|
|
109
|
+
});
|
|
110
|
+
(0, globals_1.expect)(settings.widget.units).toBe('imperial');
|
|
111
|
+
(0, globals_1.expect)(settings.airportWidget.windSpeedUnits).toBe('rotate');
|
|
112
|
+
(0, globals_1.expect)(settings.airportWidget.temperatureUnits).toBe('metric');
|
|
113
|
+
});
|
|
114
|
+
(0, globals_1.test)('rejects an unknown widget unit', () => {
|
|
115
|
+
(0, globals_1.expect)(PlaneTrackerAPI_1.cameraSettingsSchema.safeParse({ widget: { ...WIDGET, units: 'kelvin' } }).success).toBe(false);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -54,15 +54,15 @@ declare const cswEventsDataSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<
|
|
|
54
54
|
}, "strip", z.ZodTypeAny, {
|
|
55
55
|
type: "StreamSwitchVideoError";
|
|
56
56
|
playlist_name: string;
|
|
57
|
-
playlist_active_stream: number;
|
|
58
57
|
info: string;
|
|
58
|
+
playlist_active_stream: number;
|
|
59
59
|
stream_name?: string | undefined;
|
|
60
60
|
clip_name?: string | undefined;
|
|
61
61
|
}, {
|
|
62
62
|
type: "StreamSwitchVideoError";
|
|
63
63
|
playlist_name: string;
|
|
64
|
-
playlist_active_stream: number;
|
|
65
64
|
info: string;
|
|
65
|
+
playlist_active_stream: number;
|
|
66
66
|
stream_name?: string | undefined;
|
|
67
67
|
clip_name?: string | undefined;
|
|
68
68
|
}>, z.ZodObject<{
|
|
@@ -207,15 +207,15 @@ export declare const cswEventsSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObje
|
|
|
207
207
|
}, "strip", z.ZodTypeAny, {
|
|
208
208
|
type: "StreamSwitchVideoError";
|
|
209
209
|
playlist_name: string;
|
|
210
|
-
playlist_active_stream: number;
|
|
211
210
|
info: string;
|
|
211
|
+
playlist_active_stream: number;
|
|
212
212
|
stream_name?: string | undefined;
|
|
213
213
|
clip_name?: string | undefined;
|
|
214
214
|
}, {
|
|
215
215
|
type: "StreamSwitchVideoError";
|
|
216
216
|
playlist_name: string;
|
|
217
|
-
playlist_active_stream: number;
|
|
218
217
|
info: string;
|
|
218
|
+
playlist_active_stream: number;
|
|
219
219
|
stream_name?: string | undefined;
|
|
220
220
|
clip_name?: string | undefined;
|
|
221
221
|
}>, z.ZodObject<{
|
|
@@ -323,8 +323,8 @@ export declare const cswEventsSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObje
|
|
|
323
323
|
} | {
|
|
324
324
|
type: "StreamSwitchVideoError";
|
|
325
325
|
playlist_name: string;
|
|
326
|
-
playlist_active_stream: number;
|
|
327
326
|
info: string;
|
|
327
|
+
playlist_active_stream: number;
|
|
328
328
|
stream_name?: string | undefined;
|
|
329
329
|
clip_name?: string | undefined;
|
|
330
330
|
} | {
|
|
@@ -376,8 +376,8 @@ export declare const cswEventsSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObje
|
|
|
376
376
|
} | {
|
|
377
377
|
type: "StreamSwitchVideoError";
|
|
378
378
|
playlist_name: string;
|
|
379
|
-
playlist_active_stream: number;
|
|
380
379
|
info: string;
|
|
380
|
+
playlist_active_stream: number;
|
|
381
381
|
stream_name?: string | undefined;
|
|
382
382
|
clip_name?: string | undefined;
|
|
383
383
|
} | {
|
|
@@ -464,15 +464,15 @@ export declare const cswEventsSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObje
|
|
|
464
464
|
}, "strip", z.ZodTypeAny, {
|
|
465
465
|
type: "StreamSwitchVideoError";
|
|
466
466
|
playlist_name: string;
|
|
467
|
-
playlist_active_stream: number;
|
|
468
467
|
info: string;
|
|
468
|
+
playlist_active_stream: number;
|
|
469
469
|
stream_name?: string | undefined;
|
|
470
470
|
clip_name?: string | undefined;
|
|
471
471
|
}, {
|
|
472
472
|
type: "StreamSwitchVideoError";
|
|
473
473
|
playlist_name: string;
|
|
474
|
-
playlist_active_stream: number;
|
|
475
474
|
info: string;
|
|
475
|
+
playlist_active_stream: number;
|
|
476
476
|
stream_name?: string | undefined;
|
|
477
477
|
clip_name?: string | undefined;
|
|
478
478
|
}>, z.ZodObject<{
|
package/esm/VapixAPI.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { arrayToUrl, isNullish, paramToUrl } from './internal/utils';
|
|
2
|
-
import { sdCardWatchedStatuses, maxFpsResponseSchema, dateTimeinfoSchema, audioDeviceRequestSchema, audioSampleRatesResponseSchema, timeZoneSchema, getPortsResponseSchema, guardTourSchema, ptzOverviewSchema, cameraPTZItemDataSchema,
|
|
2
|
+
import { sdCardWatchedStatuses, maxFpsResponseSchema, dateTimeinfoSchema, audioDeviceRequestSchema, audioSampleRatesResponseSchema, applicationSchema, timeZoneSchema, getPortsResponseSchema, guardTourSchema, ptzOverviewSchema, cameraPTZItemDataSchema, sdCardInfoSchema, ALL_APP_IDS, allDateTimeInfoSchema, } from './types/VapixAPI';
|
|
3
3
|
import { ApplicationAPIError, MaxFPSError, NoDeviceInfoError, PtzNotSupportedError, ErrorWithResponse, SDCardActionError, SDCardJobError, SettingParameterError, TimezoneFetchError, } from './errors/errors';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { XMLParser } from 'fast-xml-parser';
|
|
@@ -562,17 +562,21 @@ export class VapixAPI extends BasicAPI {
|
|
|
562
562
|
allowBooleanAttributes: true,
|
|
563
563
|
});
|
|
564
564
|
const result = parser.parse(xml);
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
|
|
565
|
+
const rawApps = result.reply.application ?? [];
|
|
566
|
+
const apps = Array.isArray(rawApps) ? rawApps : [rawApps];
|
|
567
|
+
const appList = [];
|
|
568
|
+
for (const app of apps) {
|
|
569
|
+
const parsedApp = applicationSchema.safeParse(app);
|
|
570
|
+
if (!parsedApp.success) {
|
|
571
|
+
console.debug('Skipping invalid application entry:', app, parsedApp.error.issues);
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
appList.push({
|
|
575
|
+
...parsedApp.data,
|
|
576
|
+
appId: ALL_APP_IDS.find((id) => id.toLowerCase() === parsedApp.data.Name.toLowerCase()) ?? null,
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
return appList;
|
|
576
580
|
}
|
|
577
581
|
async startApplication(applicationId, options) {
|
|
578
582
|
const agent = this.getClient(options?.proxyParams);
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { VapixAPI } from './VapixAPI';
|
|
2
|
+
import { describe, test, expect, jest, afterEach } from '@jest/globals';
|
|
3
|
+
const createApi = (xml) => {
|
|
4
|
+
const client = {
|
|
5
|
+
get: () => Promise.resolve(new Response(xml)),
|
|
6
|
+
post: () => Promise.reject(new Error('unused')),
|
|
7
|
+
};
|
|
8
|
+
return new VapixAPI(client);
|
|
9
|
+
};
|
|
10
|
+
describe('VapixAPI', () => {
|
|
11
|
+
describe('getApplicationList', () => {
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
jest.restoreAllMocks();
|
|
14
|
+
});
|
|
15
|
+
test('skips the nameless entry of the live camera list', async () => {
|
|
16
|
+
const debugSpy = jest.spyOn(console, 'debug').mockImplementation(() => { });
|
|
17
|
+
const api = createApi(`<reply result="ok">
|
|
18
|
+
<application Name="camstreamer" NiceName="CamStreamer App" Vendor="CamStreamer" Version="5.0-15" ApplicationID="413135" License="None" Status="Running" ConfigurationPage="local/camstreamer/settings.html" />
|
|
19
|
+
<application Name="" License="None" Status="Stopped" />
|
|
20
|
+
<application Name="vmd" NiceName="AXIS Video Motion Detection" Vendor="Axis Communications" Version="4.4-5" ApplicationID="143440" License="None" Status="Stopped" ConfigurationPage="local/vmd/config.html" VendorHomePage="http://www.axis.com" LicenseName="Proprietary" />
|
|
21
|
+
</reply>`);
|
|
22
|
+
await expect(api.getApplicationList()).resolves.toEqual([
|
|
23
|
+
{
|
|
24
|
+
Name: 'camstreamer',
|
|
25
|
+
NiceName: 'CamStreamer App',
|
|
26
|
+
Vendor: 'CamStreamer',
|
|
27
|
+
Version: '5.0-15',
|
|
28
|
+
ApplicationID: '413135',
|
|
29
|
+
License: 'None',
|
|
30
|
+
Status: 'Running',
|
|
31
|
+
ConfigurationPage: 'local/camstreamer/settings.html',
|
|
32
|
+
appId: 'CamStreamer',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
Name: 'vmd',
|
|
36
|
+
NiceName: 'AXIS Video Motion Detection',
|
|
37
|
+
Vendor: 'Axis Communications',
|
|
38
|
+
Version: '4.4-5',
|
|
39
|
+
ApplicationID: '143440',
|
|
40
|
+
License: 'None',
|
|
41
|
+
Status: 'Stopped',
|
|
42
|
+
ConfigurationPage: 'local/vmd/config.html',
|
|
43
|
+
VendorHomePage: 'http://www.axis.com',
|
|
44
|
+
LicenseName: 'Proprietary',
|
|
45
|
+
appId: null,
|
|
46
|
+
},
|
|
47
|
+
]);
|
|
48
|
+
expect(debugSpy).toHaveBeenCalledTimes(1);
|
|
49
|
+
expect(debugSpy.mock.calls[0]).toContainEqual({ Name: '', License: 'None', Status: 'Stopped' });
|
|
50
|
+
});
|
|
51
|
+
test.each([
|
|
52
|
+
{
|
|
53
|
+
name: 'an entry without a name',
|
|
54
|
+
xml: '<reply result="ok"><application Name="vmd" NiceName="AXIS Video Motion Detection" Vendor="Axis Communications" Version="4.4-5" License="None" Status="Stopped" /><application License="None" Status="Stopped" /></reply>',
|
|
55
|
+
expected: [
|
|
56
|
+
{
|
|
57
|
+
Name: 'vmd',
|
|
58
|
+
NiceName: 'AXIS Video Motion Detection',
|
|
59
|
+
Vendor: 'Axis Communications',
|
|
60
|
+
Version: '4.4-5',
|
|
61
|
+
License: 'None',
|
|
62
|
+
Status: 'Stopped',
|
|
63
|
+
appId: null,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'a named entry missing informational fields',
|
|
69
|
+
xml: '<reply result="ok"><application Name="vmd" NiceName="AXIS Video Motion Detection" Vendor="Axis Communications" Version="4.4-5" License="None" Status="Stopped" /><application Name="broken" License="None" Status="Stopped" /></reply>',
|
|
70
|
+
expected: [
|
|
71
|
+
{
|
|
72
|
+
Name: 'vmd',
|
|
73
|
+
NiceName: 'AXIS Video Motion Detection',
|
|
74
|
+
Vendor: 'Axis Communications',
|
|
75
|
+
Version: '4.4-5',
|
|
76
|
+
License: 'None',
|
|
77
|
+
Status: 'Stopped',
|
|
78
|
+
appId: null,
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
])('skips invalid entries individually: $name', async ({ xml, expected }) => {
|
|
83
|
+
const debugSpy = jest.spyOn(console, 'debug').mockImplementation(() => { });
|
|
84
|
+
await expect(createApi(xml).getApplicationList()).resolves.toEqual(expected);
|
|
85
|
+
expect(debugSpy).toHaveBeenCalledTimes(1);
|
|
86
|
+
});
|
|
87
|
+
test.each([
|
|
88
|
+
{
|
|
89
|
+
name: 'drops attributes outside the schema',
|
|
90
|
+
xml: '<reply result="ok"><application Name="camoverlay" NiceName="CamOverlay App" Vendor="CamStreamer" Version="3.0-1" License="None" Status="Running" Unexpected="value" /></reply>',
|
|
91
|
+
expected: [
|
|
92
|
+
{
|
|
93
|
+
Name: 'camoverlay',
|
|
94
|
+
NiceName: 'CamOverlay App',
|
|
95
|
+
Vendor: 'CamStreamer',
|
|
96
|
+
Version: '3.0-1',
|
|
97
|
+
License: 'None',
|
|
98
|
+
Status: 'Running',
|
|
99
|
+
appId: 'CamOverlay',
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: 'maps an application outside the core CamStreamer apps to its appId',
|
|
105
|
+
xml: '<reply result="ok"><application Name="sporttracker" NiceName="SportTracker App" Vendor="CamStreamer" Version="1.0-1" License="None" Status="Running" /></reply>',
|
|
106
|
+
expected: [
|
|
107
|
+
{
|
|
108
|
+
Name: 'sporttracker',
|
|
109
|
+
NiceName: 'SportTracker App',
|
|
110
|
+
Vendor: 'CamStreamer',
|
|
111
|
+
Version: '1.0-1',
|
|
112
|
+
License: 'None',
|
|
113
|
+
Status: 'Running',
|
|
114
|
+
appId: 'SportTracker',
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'maps a capitalised application name to its appId',
|
|
120
|
+
xml: '<reply result="ok"><application Name="CamOverlay" NiceName="CamOverlay App" Vendor="CamStreamer" Version="3.0-1" License="None" Status="Running" /></reply>',
|
|
121
|
+
expected: [
|
|
122
|
+
{
|
|
123
|
+
Name: 'CamOverlay',
|
|
124
|
+
NiceName: 'CamOverlay App',
|
|
125
|
+
Vendor: 'CamStreamer',
|
|
126
|
+
Version: '3.0-1',
|
|
127
|
+
License: 'None',
|
|
128
|
+
Status: 'Running',
|
|
129
|
+
appId: 'CamOverlay',
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: 'returns an empty list when the camera has no applications',
|
|
135
|
+
xml: '<reply result="ok"></reply>',
|
|
136
|
+
expected: [],
|
|
137
|
+
},
|
|
138
|
+
])('returns every valid entry with its appId and logs nothing: $name', async ({ xml, expected }) => {
|
|
139
|
+
const debugSpy = jest.spyOn(console, 'debug').mockImplementation(() => { });
|
|
140
|
+
await expect(createApi(xml).getApplicationList()).resolves.toEqual(expected);
|
|
141
|
+
expect(debugSpy).not.toHaveBeenCalled();
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
});
|
|
@@ -25,6 +25,7 @@ export const widgetSchema = z.object({
|
|
|
25
25
|
posY: z.number().nonnegative(),
|
|
26
26
|
scale: z.number().positive(),
|
|
27
27
|
});
|
|
28
|
+
const widgetUnitsSchema = z.union([z.literal('metric'), z.literal('imperial'), z.literal('rotate')]);
|
|
28
29
|
const labelOptionsSchema = z.union([
|
|
29
30
|
z.literal('blank'),
|
|
30
31
|
z.literal('registration'),
|
|
@@ -186,18 +187,25 @@ export const cameraSettingsSchema = z.object({
|
|
|
186
187
|
displaySystemInfo: z.boolean().optional(),
|
|
187
188
|
})
|
|
188
189
|
.optional(),
|
|
189
|
-
widget: widgetSchema
|
|
190
|
+
widget: widgetSchema
|
|
191
|
+
.extend({
|
|
192
|
+
units: widgetUnitsSchema.default('rotate'),
|
|
193
|
+
})
|
|
194
|
+
.default({
|
|
190
195
|
enabled: true,
|
|
191
196
|
coord: 'top_right',
|
|
192
197
|
posX: 10,
|
|
193
198
|
posY: 10,
|
|
194
199
|
scale: 100,
|
|
200
|
+
units: 'rotate',
|
|
195
201
|
}),
|
|
196
202
|
airportWidget: widgetSchema
|
|
197
203
|
.extend({
|
|
198
204
|
showWeather: z.boolean().default(false),
|
|
199
205
|
weatherLocationKey: z.string().default(''),
|
|
200
206
|
weatherLocationName: z.string().default(''),
|
|
207
|
+
windSpeedUnits: widgetUnitsSchema.default('rotate'),
|
|
208
|
+
temperatureUnits: widgetUnitsSchema.default('rotate'),
|
|
201
209
|
})
|
|
202
210
|
.default({
|
|
203
211
|
enabled: true,
|
|
@@ -208,6 +216,8 @@ export const cameraSettingsSchema = z.object({
|
|
|
208
216
|
showWeather: false,
|
|
209
217
|
weatherLocationKey: '',
|
|
210
218
|
weatherLocationName: '',
|
|
219
|
+
windSpeedUnits: 'rotate',
|
|
220
|
+
temperatureUnits: 'rotate',
|
|
211
221
|
}),
|
|
212
222
|
fr24FlightInfoSource: z
|
|
213
223
|
.object({
|
|
@@ -86,3 +86,30 @@ describe('cameraSettingsSchema cameraConfig', () => {
|
|
|
86
86
|
expect(cameraSettingsSchema.safeParse({ cameraConfig }).success).toBe(false);
|
|
87
87
|
});
|
|
88
88
|
});
|
|
89
|
+
describe('cameraSettingsSchema widget units', () => {
|
|
90
|
+
const WIDGET = { coord: 'top_left', posX: 10, posY: 10, scale: 100 };
|
|
91
|
+
test('defaults all widget units to rotate', () => {
|
|
92
|
+
const settings = cameraSettingsSchema.parse({});
|
|
93
|
+
expect(settings.widget.units).toBe('rotate');
|
|
94
|
+
expect(settings.airportWidget.windSpeedUnits).toBe('rotate');
|
|
95
|
+
expect(settings.airportWidget.temperatureUnits).toBe('rotate');
|
|
96
|
+
});
|
|
97
|
+
test('defaults missing units of saved widgets to rotate', () => {
|
|
98
|
+
const settings = cameraSettingsSchema.parse({ widget: WIDGET, airportWidget: WIDGET });
|
|
99
|
+
expect(settings.widget.units).toBe('rotate');
|
|
100
|
+
expect(settings.airportWidget.windSpeedUnits).toBe('rotate');
|
|
101
|
+
expect(settings.airportWidget.temperatureUnits).toBe('rotate');
|
|
102
|
+
});
|
|
103
|
+
test('parses independent widget units', () => {
|
|
104
|
+
const settings = cameraSettingsSchema.parse({
|
|
105
|
+
widget: { ...WIDGET, units: 'imperial' },
|
|
106
|
+
airportWidget: { ...WIDGET, windSpeedUnits: 'rotate', temperatureUnits: 'metric' },
|
|
107
|
+
});
|
|
108
|
+
expect(settings.widget.units).toBe('imperial');
|
|
109
|
+
expect(settings.airportWidget.windSpeedUnits).toBe('rotate');
|
|
110
|
+
expect(settings.airportWidget.temperatureUnits).toBe('metric');
|
|
111
|
+
});
|
|
112
|
+
test('rejects an unknown widget unit', () => {
|
|
113
|
+
expect(cameraSettingsSchema.safeParse({ widget: { ...WIDGET, units: 'kelvin' } }).success).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
});
|
package/package.json
CHANGED
|
@@ -87,6 +87,7 @@ export declare class PlaneTrackerAPI<Client extends IClient<TResponse, any>> ext
|
|
|
87
87
|
widget: {
|
|
88
88
|
enabled: boolean;
|
|
89
89
|
scale: number;
|
|
90
|
+
units: "rotate" | "metric" | "imperial";
|
|
90
91
|
coord: "top_left" | "top_right" | "bottom_left" | "bottom_right";
|
|
91
92
|
posX: number;
|
|
92
93
|
posY: number;
|
|
@@ -100,6 +101,8 @@ export declare class PlaneTrackerAPI<Client extends IClient<TResponse, any>> ext
|
|
|
100
101
|
posY: number;
|
|
101
102
|
showWeather: boolean;
|
|
102
103
|
weatherLocationKey: string;
|
|
104
|
+
windSpeedUnits: "rotate" | "metric" | "imperial";
|
|
105
|
+
temperatureUnits: "rotate" | "metric" | "imperial";
|
|
103
106
|
};
|
|
104
107
|
fr24FlightInfoSource: {
|
|
105
108
|
enabled: boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -54,6 +54,8 @@ export declare const widgetSchema: z.ZodObject<{
|
|
|
54
54
|
posY: number;
|
|
55
55
|
enabled?: boolean | undefined;
|
|
56
56
|
}>;
|
|
57
|
+
declare const widgetUnitsSchema: z.ZodUnion<[z.ZodLiteral<"metric">, z.ZodLiteral<"imperial">, z.ZodLiteral<"rotate">]>;
|
|
58
|
+
export type TWidgetUnits = z.infer<typeof widgetUnitsSchema>;
|
|
57
59
|
declare const labelOptionsSchema: z.ZodUnion<[z.ZodLiteral<"blank">, z.ZodLiteral<"registration">, z.ZodLiteral<"call_sign">, z.ZodLiteral<"flight_number">, z.ZodLiteral<"icao">]>;
|
|
58
60
|
export type TLabelOption = z.infer<typeof labelOptionsSchema>;
|
|
59
61
|
declare const droneLabelOptionsSchema: z.ZodUnion<[z.ZodLiteral<"blank">, z.ZodLiteral<"remote_id">]>;
|
|
@@ -313,9 +315,12 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
313
315
|
posX: z.ZodNumber;
|
|
314
316
|
posY: z.ZodNumber;
|
|
315
317
|
scale: z.ZodNumber;
|
|
318
|
+
} & {
|
|
319
|
+
units: z.ZodDefault<z.ZodUnion<[z.ZodLiteral<"metric">, z.ZodLiteral<"imperial">, z.ZodLiteral<"rotate">]>>;
|
|
316
320
|
}, "strip", z.ZodTypeAny, {
|
|
317
321
|
enabled: boolean;
|
|
318
322
|
scale: number;
|
|
323
|
+
units: "rotate" | "metric" | "imperial";
|
|
319
324
|
coord: "top_left" | "top_right" | "bottom_left" | "bottom_right";
|
|
320
325
|
posX: number;
|
|
321
326
|
posY: number;
|
|
@@ -325,6 +330,7 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
325
330
|
posX: number;
|
|
326
331
|
posY: number;
|
|
327
332
|
enabled?: boolean | undefined;
|
|
333
|
+
units?: "rotate" | "metric" | "imperial" | undefined;
|
|
328
334
|
}>>;
|
|
329
335
|
airportWidget: z.ZodDefault<z.ZodObject<{
|
|
330
336
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -336,6 +342,8 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
336
342
|
showWeather: z.ZodDefault<z.ZodBoolean>;
|
|
337
343
|
weatherLocationKey: z.ZodDefault<z.ZodString>;
|
|
338
344
|
weatherLocationName: z.ZodDefault<z.ZodString>;
|
|
345
|
+
windSpeedUnits: z.ZodDefault<z.ZodUnion<[z.ZodLiteral<"metric">, z.ZodLiteral<"imperial">, z.ZodLiteral<"rotate">]>>;
|
|
346
|
+
temperatureUnits: z.ZodDefault<z.ZodUnion<[z.ZodLiteral<"metric">, z.ZodLiteral<"imperial">, z.ZodLiteral<"rotate">]>>;
|
|
339
347
|
}, "strip", z.ZodTypeAny, {
|
|
340
348
|
enabled: boolean;
|
|
341
349
|
scale: number;
|
|
@@ -345,6 +353,8 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
345
353
|
posY: number;
|
|
346
354
|
showWeather: boolean;
|
|
347
355
|
weatherLocationKey: string;
|
|
356
|
+
windSpeedUnits: "rotate" | "metric" | "imperial";
|
|
357
|
+
temperatureUnits: "rotate" | "metric" | "imperial";
|
|
348
358
|
}, {
|
|
349
359
|
scale: number;
|
|
350
360
|
coord: "top_left" | "top_right" | "bottom_left" | "bottom_right";
|
|
@@ -354,6 +364,8 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
354
364
|
weatherLocationName?: string | undefined;
|
|
355
365
|
showWeather?: boolean | undefined;
|
|
356
366
|
weatherLocationKey?: string | undefined;
|
|
367
|
+
windSpeedUnits?: "rotate" | "metric" | "imperial" | undefined;
|
|
368
|
+
temperatureUnits?: "rotate" | "metric" | "imperial" | undefined;
|
|
357
369
|
}>>;
|
|
358
370
|
fr24FlightInfoSource: z.ZodDefault<z.ZodObject<{
|
|
359
371
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -614,6 +626,7 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
614
626
|
widget: {
|
|
615
627
|
enabled: boolean;
|
|
616
628
|
scale: number;
|
|
629
|
+
units: "rotate" | "metric" | "imperial";
|
|
617
630
|
coord: "top_left" | "top_right" | "bottom_left" | "bottom_right";
|
|
618
631
|
posX: number;
|
|
619
632
|
posY: number;
|
|
@@ -627,6 +640,8 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
627
640
|
posY: number;
|
|
628
641
|
showWeather: boolean;
|
|
629
642
|
weatherLocationKey: string;
|
|
643
|
+
windSpeedUnits: "rotate" | "metric" | "imperial";
|
|
644
|
+
temperatureUnits: "rotate" | "metric" | "imperial";
|
|
630
645
|
};
|
|
631
646
|
fr24FlightInfoSource: {
|
|
632
647
|
enabled: boolean;
|
|
@@ -802,6 +817,7 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
802
817
|
posX: number;
|
|
803
818
|
posY: number;
|
|
804
819
|
enabled?: boolean | undefined;
|
|
820
|
+
units?: "rotate" | "metric" | "imperial" | undefined;
|
|
805
821
|
} | undefined;
|
|
806
822
|
airportWidget?: {
|
|
807
823
|
scale: number;
|
|
@@ -812,6 +828,8 @@ export declare const cameraSettingsSchema: z.ZodObject<{
|
|
|
812
828
|
weatherLocationName?: string | undefined;
|
|
813
829
|
showWeather?: boolean | undefined;
|
|
814
830
|
weatherLocationKey?: string | undefined;
|
|
831
|
+
windSpeedUnits?: "rotate" | "metric" | "imperial" | undefined;
|
|
832
|
+
temperatureUnits?: "rotate" | "metric" | "imperial" | undefined;
|
|
815
833
|
} | undefined;
|
|
816
834
|
fr24FlightInfoSource?: {
|
|
817
835
|
enabled?: boolean | undefined;
|
|
@@ -54,15 +54,15 @@ declare const cswEventsDataSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<
|
|
|
54
54
|
}, "strip", z.ZodTypeAny, {
|
|
55
55
|
type: "StreamSwitchVideoError";
|
|
56
56
|
playlist_name: string;
|
|
57
|
-
playlist_active_stream: number;
|
|
58
57
|
info: string;
|
|
58
|
+
playlist_active_stream: number;
|
|
59
59
|
stream_name?: string | undefined;
|
|
60
60
|
clip_name?: string | undefined;
|
|
61
61
|
}, {
|
|
62
62
|
type: "StreamSwitchVideoError";
|
|
63
63
|
playlist_name: string;
|
|
64
|
-
playlist_active_stream: number;
|
|
65
64
|
info: string;
|
|
65
|
+
playlist_active_stream: number;
|
|
66
66
|
stream_name?: string | undefined;
|
|
67
67
|
clip_name?: string | undefined;
|
|
68
68
|
}>, z.ZodObject<{
|
|
@@ -207,15 +207,15 @@ export declare const cswEventsSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObje
|
|
|
207
207
|
}, "strip", z.ZodTypeAny, {
|
|
208
208
|
type: "StreamSwitchVideoError";
|
|
209
209
|
playlist_name: string;
|
|
210
|
-
playlist_active_stream: number;
|
|
211
210
|
info: string;
|
|
211
|
+
playlist_active_stream: number;
|
|
212
212
|
stream_name?: string | undefined;
|
|
213
213
|
clip_name?: string | undefined;
|
|
214
214
|
}, {
|
|
215
215
|
type: "StreamSwitchVideoError";
|
|
216
216
|
playlist_name: string;
|
|
217
|
-
playlist_active_stream: number;
|
|
218
217
|
info: string;
|
|
218
|
+
playlist_active_stream: number;
|
|
219
219
|
stream_name?: string | undefined;
|
|
220
220
|
clip_name?: string | undefined;
|
|
221
221
|
}>, z.ZodObject<{
|
|
@@ -323,8 +323,8 @@ export declare const cswEventsSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObje
|
|
|
323
323
|
} | {
|
|
324
324
|
type: "StreamSwitchVideoError";
|
|
325
325
|
playlist_name: string;
|
|
326
|
-
playlist_active_stream: number;
|
|
327
326
|
info: string;
|
|
327
|
+
playlist_active_stream: number;
|
|
328
328
|
stream_name?: string | undefined;
|
|
329
329
|
clip_name?: string | undefined;
|
|
330
330
|
} | {
|
|
@@ -376,8 +376,8 @@ export declare const cswEventsSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObje
|
|
|
376
376
|
} | {
|
|
377
377
|
type: "StreamSwitchVideoError";
|
|
378
378
|
playlist_name: string;
|
|
379
|
-
playlist_active_stream: number;
|
|
380
379
|
info: string;
|
|
380
|
+
playlist_active_stream: number;
|
|
381
381
|
stream_name?: string | undefined;
|
|
382
382
|
clip_name?: string | undefined;
|
|
383
383
|
} | {
|
|
@@ -464,15 +464,15 @@ export declare const cswEventsSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObje
|
|
|
464
464
|
}, "strip", z.ZodTypeAny, {
|
|
465
465
|
type: "StreamSwitchVideoError";
|
|
466
466
|
playlist_name: string;
|
|
467
|
-
playlist_active_stream: number;
|
|
468
467
|
info: string;
|
|
468
|
+
playlist_active_stream: number;
|
|
469
469
|
stream_name?: string | undefined;
|
|
470
470
|
clip_name?: string | undefined;
|
|
471
471
|
}, {
|
|
472
472
|
type: "StreamSwitchVideoError";
|
|
473
473
|
playlist_name: string;
|
|
474
|
-
playlist_active_stream: number;
|
|
475
474
|
info: string;
|
|
475
|
+
playlist_active_stream: number;
|
|
476
476
|
stream_name?: string | undefined;
|
|
477
477
|
clip_name?: string | undefined;
|
|
478
478
|
}>, z.ZodObject<{
|