camstreamerlib 4.0.32 → 4.0.33-55dd1f0

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/README.md CHANGED
@@ -39,6 +39,15 @@ npm install camstreamerlib
39
39
 
40
40
  </br>
41
41
 
42
+ # Examples
43
+
44
+ | Example | Description | Open in browser |
45
+ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
46
+ | [CamSwitcherEvents](examples/camswitcher-events.html) ([source](https://github.com/CamStreamer/CamStreamerLib/blob/master/examples/camswitcher-events.html)) | Logs every CamSwitcher event. `DeviceConnectClient` (HTTP) backs [CamSwitcherAPI](doc/CamSwitcherAPI.md) to obtain the websocket authorization token, `DeviceConnectWsClient` (websocket) backs [CamSwitcherEvents](doc/ws/CamSwitcherEvents.md), which validates and dispatches the events. Connection state is taken from the `authorization` event. | [open](https://camstreamer.github.io/CamStreamerLib/examples/camswitcher-events.html) |
47
+ | [PlaneTrackerEvents](examples/planetracker-events.html) ([source](https://github.com/CamStreamer/CamStreamerLib/blob/master/examples/planetracker-events.html)) | Logs every PlaneTracker event. PlaneTracker needs no authorization token — [PlaneTrackerEvents](doc/ws/PlaneTrackerEvents.md) announces the connecting user (`userId` / `userName` / `userPriority`, editable in the form) as the init message instead, so only the websocket client is needed. The continuous `CAMERA_POSITION` and `FLIGHT_LIST` events only update the summary line unless the checkbox is ticked. | [open](https://camstreamer.github.io/CamStreamerLib/examples/planetracker-events.html) |
48
+
49
+ </br>
50
+
42
51
  # Breaking Changes
43
52
 
44
53
  <details open>
@@ -5,12 +5,13 @@ const zod_1 = require("zod");
5
5
  const PlaneTrackerAPI_1 = require("./types/PlaneTrackerAPI");
6
6
  const errors_1 = require("./errors/errors");
7
7
  const BasicAPI_1 = require("./internal/BasicAPI");
8
+ const PlaneTrackerEvents_1 = require("./types/ws/PlaneTrackerEvents");
8
9
  const BASE_PATH = '/local/planetracker';
9
10
  class PlaneTrackerAPI extends BasicAPI_1.BasicAPI {
10
11
  apiUser;
11
12
  constructor(client, apiUser) {
12
13
  super(client);
13
- this.apiUser = apiUser;
14
+ this.apiUser = PlaneTrackerEvents_1.apiUserInputSchema.parse(apiUser);
14
15
  }
15
16
  static getProxyPath = () => `${BASE_PATH}/proxy.cgi`;
16
17
  static getWsEventsPath = () => `${BASE_PATH}/package/ws`;
@@ -0,0 +1,2 @@
1
+ export * from './index';
2
+ export * from './web/index';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./index"), exports);
18
+ __exportStar(require("./web/index"), exports);
@@ -2,6 +2,7 @@ import { z } from 'zod';
2
2
  declare const wsApiFlightDataSchema: z.ZodObject<{
3
3
  targetId: z.ZodString;
4
4
  icao: z.ZodString;
5
+ callsign: z.ZodOptional<z.ZodString>;
5
6
  domain: z.ZodEnum<["adsb", "remoteId"]>;
6
7
  categoryId: z.ZodString;
7
8
  groupId: z.ZodOptional<z.ZodString>;
@@ -50,6 +51,7 @@ declare const wsApiFlightDataSchema: z.ZodObject<{
50
51
  emitterCategory: number;
51
52
  emergencyState: boolean;
52
53
  emergencyStatusMessage: string;
54
+ callsign?: string | undefined;
53
55
  groupId?: string | undefined;
54
56
  }, {
55
57
  icao: string;
@@ -74,6 +76,7 @@ declare const wsApiFlightDataSchema: z.ZodObject<{
74
76
  signalQuality: number;
75
77
  emergencyState: boolean;
76
78
  emergencyStatusMessage: string;
79
+ callsign?: string | undefined;
77
80
  groupId?: string | undefined;
78
81
  emitterCategorySet?: number | undefined;
79
82
  emitterCategory?: number | undefined;
@@ -117,6 +120,21 @@ declare const apiUserSchema: z.ZodObject<{
117
120
  userName: string;
118
121
  userPriority: number;
119
122
  }>;
123
+ export declare const USER_PRIORITY_MIN = 1;
124
+ export declare const USER_PRIORITY_MAX = 255;
125
+ export declare const apiUserInputSchema: z.ZodObject<{} & {
126
+ userId: z.ZodString;
127
+ userName: z.ZodString;
128
+ userPriority: z.ZodNumber;
129
+ }, "strip", z.ZodTypeAny, {
130
+ userId: string;
131
+ userName: string;
132
+ userPriority: number;
133
+ }, {
134
+ userId: string;
135
+ userName: string;
136
+ userPriority: number;
137
+ }>;
120
138
  export type TEventType = 'CAMERA_POSITION' | 'TRACKING_START' | 'TRACKING_STOP' | 'FLIGHT_LIST' | 'USER_ACTION' | 'CONNECTED_USERS' | 'FORCE_TRACKING_STATUS' | 'API_LOCK_STATUS';
121
139
  export declare enum EUserActions {
122
140
  TRACK_ICAO = "trackIcao.cgi",
@@ -163,6 +181,7 @@ declare const eventsDataSchema: z.ZodUnion<readonly [z.ZodObject<{
163
181
  type: z.ZodLiteral<"TRACKING_START">;
164
182
  icao: z.ZodString;
165
183
  targetId: z.ZodString;
184
+ callsign: z.ZodOptional<z.ZodString>;
166
185
  domain: z.ZodEnum<["adsb", "remoteId"]>;
167
186
  categoryId: z.ZodString;
168
187
  }, "strip", z.ZodTypeAny, {
@@ -171,12 +190,14 @@ declare const eventsDataSchema: z.ZodUnion<readonly [z.ZodObject<{
171
190
  targetId: string;
172
191
  domain: "adsb" | "remoteId";
173
192
  categoryId: string;
193
+ callsign?: string | undefined;
174
194
  }, {
175
195
  type: "TRACKING_START";
176
196
  icao: string;
177
197
  targetId: string;
178
198
  domain: "adsb" | "remoteId";
179
199
  categoryId: string;
200
+ callsign?: string | undefined;
180
201
  }>, z.ZodObject<{
181
202
  type: z.ZodLiteral<"TRACKING_STOP">;
182
203
  }, "strip", z.ZodTypeAny, {
@@ -188,6 +209,7 @@ declare const eventsDataSchema: z.ZodUnion<readonly [z.ZodObject<{
188
209
  list: z.ZodArray<z.ZodObject<{
189
210
  targetId: z.ZodString;
190
211
  icao: z.ZodString;
212
+ callsign: z.ZodOptional<z.ZodString>;
191
213
  domain: z.ZodEnum<["adsb", "remoteId"]>;
192
214
  categoryId: z.ZodString;
193
215
  groupId: z.ZodOptional<z.ZodString>;
@@ -236,6 +258,7 @@ declare const eventsDataSchema: z.ZodUnion<readonly [z.ZodObject<{
236
258
  emitterCategory: number;
237
259
  emergencyState: boolean;
238
260
  emergencyStatusMessage: string;
261
+ callsign?: string | undefined;
239
262
  groupId?: string | undefined;
240
263
  }, {
241
264
  icao: string;
@@ -260,6 +283,7 @@ declare const eventsDataSchema: z.ZodUnion<readonly [z.ZodObject<{
260
283
  signalQuality: number;
261
284
  emergencyState: boolean;
262
285
  emergencyStatusMessage: string;
286
+ callsign?: string | undefined;
263
287
  groupId?: string | undefined;
264
288
  emitterCategorySet?: number | undefined;
265
289
  emitterCategory?: number | undefined;
@@ -291,6 +315,7 @@ declare const eventsDataSchema: z.ZodUnion<readonly [z.ZodObject<{
291
315
  emitterCategory: number;
292
316
  emergencyState: boolean;
293
317
  emergencyStatusMessage: string;
318
+ callsign?: string | undefined;
294
319
  groupId?: string | undefined;
295
320
  }[];
296
321
  }, {
@@ -318,6 +343,7 @@ declare const eventsDataSchema: z.ZodUnion<readonly [z.ZodObject<{
318
343
  signalQuality: number;
319
344
  emergencyState: boolean;
320
345
  emergencyStatusMessage: string;
346
+ callsign?: string | undefined;
321
347
  groupId?: string | undefined;
322
348
  emitterCategorySet?: number | undefined;
323
349
  emitterCategory?: number | undefined;
@@ -1319,6 +1345,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
1319
1345
  type: z.ZodLiteral<"TRACKING_START">;
1320
1346
  icao: z.ZodString;
1321
1347
  targetId: z.ZodString;
1348
+ callsign: z.ZodOptional<z.ZodString>;
1322
1349
  domain: z.ZodEnum<["adsb", "remoteId"]>;
1323
1350
  categoryId: z.ZodString;
1324
1351
  }, "strip", z.ZodTypeAny, {
@@ -1327,12 +1354,14 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
1327
1354
  targetId: string;
1328
1355
  domain: "adsb" | "remoteId";
1329
1356
  categoryId: string;
1357
+ callsign?: string | undefined;
1330
1358
  }, {
1331
1359
  type: "TRACKING_START";
1332
1360
  icao: string;
1333
1361
  targetId: string;
1334
1362
  domain: "adsb" | "remoteId";
1335
1363
  categoryId: string;
1364
+ callsign?: string | undefined;
1336
1365
  }>, z.ZodObject<{
1337
1366
  type: z.ZodLiteral<"TRACKING_STOP">;
1338
1367
  }, "strip", z.ZodTypeAny, {
@@ -1344,6 +1373,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
1344
1373
  list: z.ZodArray<z.ZodObject<{
1345
1374
  targetId: z.ZodString;
1346
1375
  icao: z.ZodString;
1376
+ callsign: z.ZodOptional<z.ZodString>;
1347
1377
  domain: z.ZodEnum<["adsb", "remoteId"]>;
1348
1378
  categoryId: z.ZodString;
1349
1379
  groupId: z.ZodOptional<z.ZodString>;
@@ -1392,6 +1422,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
1392
1422
  emitterCategory: number;
1393
1423
  emergencyState: boolean;
1394
1424
  emergencyStatusMessage: string;
1425
+ callsign?: string | undefined;
1395
1426
  groupId?: string | undefined;
1396
1427
  }, {
1397
1428
  icao: string;
@@ -1416,6 +1447,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
1416
1447
  signalQuality: number;
1417
1448
  emergencyState: boolean;
1418
1449
  emergencyStatusMessage: string;
1450
+ callsign?: string | undefined;
1419
1451
  groupId?: string | undefined;
1420
1452
  emitterCategorySet?: number | undefined;
1421
1453
  emitterCategory?: number | undefined;
@@ -1447,6 +1479,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
1447
1479
  emitterCategory: number;
1448
1480
  emergencyState: boolean;
1449
1481
  emergencyStatusMessage: string;
1482
+ callsign?: string | undefined;
1450
1483
  groupId?: string | undefined;
1451
1484
  }[];
1452
1485
  }, {
@@ -1474,6 +1507,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
1474
1507
  signalQuality: number;
1475
1508
  emergencyState: boolean;
1476
1509
  emergencyStatusMessage: string;
1510
+ callsign?: string | undefined;
1477
1511
  groupId?: string | undefined;
1478
1512
  emitterCategorySet?: number | undefined;
1479
1513
  emitterCategory?: number | undefined;
@@ -2460,6 +2494,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
2460
2494
  targetId: string;
2461
2495
  domain: "adsb" | "remoteId";
2462
2496
  categoryId: string;
2497
+ callsign?: string | undefined;
2463
2498
  } | {
2464
2499
  type: "TRACKING_STOP";
2465
2500
  } | {
@@ -2489,6 +2524,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
2489
2524
  emitterCategory: number;
2490
2525
  emergencyState: boolean;
2491
2526
  emergencyStatusMessage: string;
2527
+ callsign?: string | undefined;
2492
2528
  groupId?: string | undefined;
2493
2529
  }[];
2494
2530
  } | {
@@ -2723,6 +2759,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
2723
2759
  targetId: string;
2724
2760
  domain: "adsb" | "remoteId";
2725
2761
  categoryId: string;
2762
+ callsign?: string | undefined;
2726
2763
  } | {
2727
2764
  type: "TRACKING_STOP";
2728
2765
  } | {
@@ -2750,6 +2787,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
2750
2787
  signalQuality: number;
2751
2788
  emergencyState: boolean;
2752
2789
  emergencyStatusMessage: string;
2790
+ callsign?: string | undefined;
2753
2791
  groupId?: string | undefined;
2754
2792
  emitterCategorySet?: number | undefined;
2755
2793
  emitterCategory?: number | undefined;
@@ -2999,6 +3037,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
2999
3037
  type: z.ZodLiteral<"TRACKING_START">;
3000
3038
  icao: z.ZodString;
3001
3039
  targetId: z.ZodString;
3040
+ callsign: z.ZodOptional<z.ZodString>;
3002
3041
  domain: z.ZodEnum<["adsb", "remoteId"]>;
3003
3042
  categoryId: z.ZodString;
3004
3043
  }, "strip", z.ZodTypeAny, {
@@ -3007,12 +3046,14 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
3007
3046
  targetId: string;
3008
3047
  domain: "adsb" | "remoteId";
3009
3048
  categoryId: string;
3049
+ callsign?: string | undefined;
3010
3050
  }, {
3011
3051
  type: "TRACKING_START";
3012
3052
  icao: string;
3013
3053
  targetId: string;
3014
3054
  domain: "adsb" | "remoteId";
3015
3055
  categoryId: string;
3056
+ callsign?: string | undefined;
3016
3057
  }>, z.ZodObject<{
3017
3058
  type: z.ZodLiteral<"TRACKING_STOP">;
3018
3059
  }, "strip", z.ZodTypeAny, {
@@ -3024,6 +3065,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
3024
3065
  list: z.ZodArray<z.ZodObject<{
3025
3066
  targetId: z.ZodString;
3026
3067
  icao: z.ZodString;
3068
+ callsign: z.ZodOptional<z.ZodString>;
3027
3069
  domain: z.ZodEnum<["adsb", "remoteId"]>;
3028
3070
  categoryId: z.ZodString;
3029
3071
  groupId: z.ZodOptional<z.ZodString>;
@@ -3072,6 +3114,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
3072
3114
  emitterCategory: number;
3073
3115
  emergencyState: boolean;
3074
3116
  emergencyStatusMessage: string;
3117
+ callsign?: string | undefined;
3075
3118
  groupId?: string | undefined;
3076
3119
  }, {
3077
3120
  icao: string;
@@ -3096,6 +3139,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
3096
3139
  signalQuality: number;
3097
3140
  emergencyState: boolean;
3098
3141
  emergencyStatusMessage: string;
3142
+ callsign?: string | undefined;
3099
3143
  groupId?: string | undefined;
3100
3144
  emitterCategorySet?: number | undefined;
3101
3145
  emitterCategory?: number | undefined;
@@ -3127,6 +3171,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
3127
3171
  emitterCategory: number;
3128
3172
  emergencyState: boolean;
3129
3173
  emergencyStatusMessage: string;
3174
+ callsign?: string | undefined;
3130
3175
  groupId?: string | undefined;
3131
3176
  }[];
3132
3177
  }, {
@@ -3154,6 +3199,7 @@ export declare const ptrEventsSchema: z.ZodUnion<readonly [z.ZodObject<{
3154
3199
  signalQuality: number;
3155
3200
  emergencyState: boolean;
3156
3201
  emergencyStatusMessage: string;
3202
+ callsign?: string | undefined;
3157
3203
  groupId?: string | undefined;
3158
3204
  emitterCategorySet?: number | undefined;
3159
3205
  emitterCategory?: number | undefined;
@@ -4134,4 +4180,5 @@ export type TUserActionDataOfCgi<T extends EUserActions> = Extract<TWsUserAction
4134
4180
  export type TWsApiFlightData = z.infer<typeof wsApiFlightDataSchema>;
4135
4181
  export type TWsApiCameraData = z.infer<typeof wsCameraPositionDataSchema>;
4136
4182
  export type TApiUser = z.infer<typeof apiUserSchema>;
4183
+ export type TApiUserInput = z.infer<typeof apiUserInputSchema>;
4137
4184
  export {};
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ptrEventsSchema = exports.EUserActions = void 0;
3
+ exports.ptrEventsSchema = exports.EUserActions = exports.apiUserInputSchema = exports.USER_PRIORITY_MAX = exports.USER_PRIORITY_MIN = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const PlaneTrackerAPI_1 = require("../PlaneTrackerAPI");
6
6
  const wsApiFlightDataSchema = zod_1.z.object({
7
7
  targetId: zod_1.z.string(),
8
8
  icao: zod_1.z.string(),
9
+ callsign: zod_1.z.string().optional(),
9
10
  domain: PlaneTrackerAPI_1.domainIdSchema,
10
11
  categoryId: zod_1.z.string(),
11
12
  groupId: zod_1.z.string().optional(),
@@ -47,6 +48,18 @@ const apiUserSchema = userSchema.extend({
47
48
  ip: zod_1.z.string(),
48
49
  userPriority: zod_1.z.number(),
49
50
  });
51
+ exports.USER_PRIORITY_MIN = 1;
52
+ exports.USER_PRIORITY_MAX = 255;
53
+ const USER_PRIORITY_ERROR = `userPriority must be an integer between ${exports.USER_PRIORITY_MIN} and ${exports.USER_PRIORITY_MAX}, where ${exports.USER_PRIORITY_MIN} is the highest priority`;
54
+ exports.apiUserInputSchema = apiUserSchema.omit({ ip: true }).extend({
55
+ userId: zod_1.z.string().nonempty(),
56
+ userName: zod_1.z.string().nonempty(),
57
+ userPriority: zod_1.z
58
+ .number()
59
+ .int(USER_PRIORITY_ERROR)
60
+ .min(exports.USER_PRIORITY_MIN, USER_PRIORITY_ERROR)
61
+ .max(exports.USER_PRIORITY_MAX, USER_PRIORITY_ERROR),
62
+ });
50
63
  var EUserActions;
51
64
  (function (EUserActions) {
52
65
  EUserActions["TRACK_ICAO"] = "trackIcao.cgi";
@@ -70,6 +83,7 @@ const eventsDataSchema = zod_1.z.union([
70
83
  type: zod_1.z.literal('TRACKING_START'),
71
84
  icao: zod_1.z.string(),
72
85
  targetId: zod_1.z.string(),
86
+ callsign: zod_1.z.string().optional(),
73
87
  domain: PlaneTrackerAPI_1.domainIdSchema,
74
88
  categoryId: zod_1.z.string(),
75
89
  }),
@@ -3,6 +3,6 @@ import { WsEvents } from '../internal/WsEvents';
3
3
  import { TEventData, TApiUser } from '../types/ws/PlaneTrackerEvents';
4
4
  export declare class PlaneTrackerEvents extends WsEvents<TEventData> {
5
5
  private _apiUser;
6
- constructor(ws: IWsClient, _apiUser: Omit<TApiUser, 'ip'>);
6
+ constructor(ws: IWsClient, apiUser: Omit<TApiUser, 'ip'>);
7
7
  private sendInitMsg;
8
8
  }
@@ -5,9 +5,9 @@ const WsEvents_1 = require("../internal/WsEvents");
5
5
  const PlaneTrackerEvents_1 = require("../types/ws/PlaneTrackerEvents");
6
6
  class PlaneTrackerEvents extends WsEvents_1.WsEvents {
7
7
  _apiUser;
8
- constructor(ws, _apiUser) {
8
+ constructor(ws, apiUser) {
9
9
  super((data) => PlaneTrackerEvents_1.ptrEventsSchema.parse(data), ws);
10
- this._apiUser = _apiUser;
10
+ this._apiUser = PlaneTrackerEvents_1.apiUserInputSchema.parse(apiUser);
11
11
  this.ws.onOpen = this.sendInitMsg;
12
12
  }
13
13
  sendInitMsg = () => {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const PlaneTrackerEvents_1 = require("./PlaneTrackerEvents");
4
+ const PlaneTrackerEvents_2 = require("../types/ws/PlaneTrackerEvents");
5
+ const createWsClient = () => ({
6
+ send: jest.fn(),
7
+ onOpen: undefined,
8
+ onMessage: undefined,
9
+ });
10
+ const VALID_USER = { userId: 'asd', userName: 'Asd', userPriority: 1 };
11
+ describe('PlaneTrackerEvents', () => {
12
+ it.each([0, -1, PlaneTrackerEvents_2.USER_PRIORITY_MAX + 1, 1.5])('rejects userPriority %p', (userPriority) => {
13
+ expect(() => new PlaneTrackerEvents_1.PlaneTrackerEvents(createWsClient(), { ...VALID_USER, userPriority })).toThrow(/userPriority must be an integer/);
14
+ });
15
+ it.each([PlaneTrackerEvents_2.USER_PRIORITY_MIN, PlaneTrackerEvents_2.USER_PRIORITY_MAX])('accepts userPriority %p', (userPriority) => {
16
+ expect(() => new PlaneTrackerEvents_1.PlaneTrackerEvents(createWsClient(), { ...VALID_USER, userPriority })).not.toThrow();
17
+ });
18
+ it('rejects an empty userId', () => {
19
+ expect(() => new PlaneTrackerEvents_1.PlaneTrackerEvents(createWsClient(), { ...VALID_USER, userId: '' })).toThrow();
20
+ });
21
+ it('sends USER_INFO once the socket opens', () => {
22
+ const ws = createWsClient();
23
+ new PlaneTrackerEvents_1.PlaneTrackerEvents(ws, VALID_USER);
24
+ ws.onOpen();
25
+ expect(ws.send).toHaveBeenCalledWith(JSON.stringify({ type: 'USER_INFO', ...VALID_USER }));
26
+ });
27
+ });
@@ -2,12 +2,13 @@ import { z } from 'zod';
2
2
  import { blackListSchema, cameraSettingsSchema, domainListSchema, flightInfoSchema, getIcaoSchema, mapInfoSchema, milestoneCameraListSchema, priorityListSchema, serverSettingsSchema, trackingModeSchema, whiteListSchema, wsAliasResponseSchema, zonesSchema, } from './types/PlaneTrackerAPI';
3
3
  import { CannotSetCoordsInAutoModeError, ImportSettingsError, InvalidAltitudeError, InvalidLatLngError, ResetCalibrationError, ServerError, BadRequestError, } from './errors/errors';
4
4
  import { BasicAPI } from './internal/BasicAPI';
5
+ import { apiUserInputSchema } from './types/ws/PlaneTrackerEvents';
5
6
  const BASE_PATH = '/local/planetracker';
6
7
  export class PlaneTrackerAPI extends BasicAPI {
7
8
  apiUser;
8
9
  constructor(client, apiUser) {
9
10
  super(client);
10
- this.apiUser = apiUser;
11
+ this.apiUser = apiUserInputSchema.parse(apiUser);
11
12
  }
12
13
  static getProxyPath = () => `${BASE_PATH}/proxy.cgi`;
13
14
  static getWsEventsPath = () => `${BASE_PATH}/package/ws`;
@@ -0,0 +1,2 @@
1
+ export * from './index';
2
+ export * from './web/index';
@@ -3,6 +3,7 @@ import { blackListSchema, friendlyListSchema, priorityListSchema, trackingModeSc
3
3
  const wsApiFlightDataSchema = z.object({
4
4
  targetId: z.string(),
5
5
  icao: z.string(),
6
+ callsign: z.string().optional(),
6
7
  domain: domainIdSchema,
7
8
  categoryId: z.string(),
8
9
  groupId: z.string().optional(),
@@ -44,6 +45,18 @@ const apiUserSchema = userSchema.extend({
44
45
  ip: z.string(),
45
46
  userPriority: z.number(),
46
47
  });
48
+ export const USER_PRIORITY_MIN = 1;
49
+ export const USER_PRIORITY_MAX = 255;
50
+ const USER_PRIORITY_ERROR = `userPriority must be an integer between ${USER_PRIORITY_MIN} and ${USER_PRIORITY_MAX}, where ${USER_PRIORITY_MIN} is the highest priority`;
51
+ export const apiUserInputSchema = apiUserSchema.omit({ ip: true }).extend({
52
+ userId: z.string().nonempty(),
53
+ userName: z.string().nonempty(),
54
+ userPriority: z
55
+ .number()
56
+ .int(USER_PRIORITY_ERROR)
57
+ .min(USER_PRIORITY_MIN, USER_PRIORITY_ERROR)
58
+ .max(USER_PRIORITY_MAX, USER_PRIORITY_ERROR),
59
+ });
47
60
  export var EUserActions;
48
61
  (function (EUserActions) {
49
62
  EUserActions["TRACK_ICAO"] = "trackIcao.cgi";
@@ -67,6 +80,7 @@ const eventsDataSchema = z.union([
67
80
  type: z.literal('TRACKING_START'),
68
81
  icao: z.string(),
69
82
  targetId: z.string(),
83
+ callsign: z.string().optional(),
70
84
  domain: domainIdSchema,
71
85
  categoryId: z.string(),
72
86
  }),
@@ -1,10 +1,10 @@
1
1
  import { WsEvents } from '../internal/WsEvents';
2
- import { ptrEventsSchema } from '../types/ws/PlaneTrackerEvents';
2
+ import { ptrEventsSchema, apiUserInputSchema, } from '../types/ws/PlaneTrackerEvents';
3
3
  export class PlaneTrackerEvents extends WsEvents {
4
4
  _apiUser;
5
- constructor(ws, _apiUser) {
5
+ constructor(ws, apiUser) {
6
6
  super((data) => ptrEventsSchema.parse(data), ws);
7
- this._apiUser = _apiUser;
7
+ this._apiUser = apiUserInputSchema.parse(apiUser);
8
8
  this.ws.onOpen = this.sendInitMsg;
9
9
  }
10
10
  sendInitMsg = () => {
@@ -0,0 +1,25 @@
1
+ import { PlaneTrackerEvents } from './PlaneTrackerEvents';
2
+ import { USER_PRIORITY_MAX, USER_PRIORITY_MIN } from '../types/ws/PlaneTrackerEvents';
3
+ const createWsClient = () => ({
4
+ send: jest.fn(),
5
+ onOpen: undefined,
6
+ onMessage: undefined,
7
+ });
8
+ const VALID_USER = { userId: 'asd', userName: 'Asd', userPriority: 1 };
9
+ describe('PlaneTrackerEvents', () => {
10
+ it.each([0, -1, USER_PRIORITY_MAX + 1, 1.5])('rejects userPriority %p', (userPriority) => {
11
+ expect(() => new PlaneTrackerEvents(createWsClient(), { ...VALID_USER, userPriority })).toThrow(/userPriority must be an integer/);
12
+ });
13
+ it.each([USER_PRIORITY_MIN, USER_PRIORITY_MAX])('accepts userPriority %p', (userPriority) => {
14
+ expect(() => new PlaneTrackerEvents(createWsClient(), { ...VALID_USER, userPriority })).not.toThrow();
15
+ });
16
+ it('rejects an empty userId', () => {
17
+ expect(() => new PlaneTrackerEvents(createWsClient(), { ...VALID_USER, userId: '' })).toThrow();
18
+ });
19
+ it('sends USER_INFO once the socket opens', () => {
20
+ const ws = createWsClient();
21
+ new PlaneTrackerEvents(ws, VALID_USER);
22
+ ws.onOpen();
23
+ expect(ws.send).toHaveBeenCalledWith(JSON.stringify({ type: 'USER_INFO', ...VALID_USER }));
24
+ });
25
+ });
@@ -0,0 +1,43 @@
1
+ # Examples
2
+
3
+ Standalone browser examples that use CamStreamerLib directly from a `<script type="module">`,
4
+ without a bundler or a framework.
5
+
6
+ ## Build the browser bundle
7
+
8
+ ```bash
9
+ npm install
10
+ npm run build:browser
11
+ ```
12
+
13
+ ## Run
14
+
15
+ Modules can't be loaded over `file://`, so serve the folder over HTTP:
16
+
17
+ ```bash
18
+ npx serve examples
19
+ ```
20
+
21
+ Both pages connect to a camera through the Device Connect proxy. Fill in the device host
22
+ (`<MAC_ADDRESS>.device-connect.net`) and the device access token in the form, or hardcode them in the
23
+ `DEVICE_HOST` / `DEVICE_ACCESS_TOKEN` constants at the top of the page's script to have the form
24
+ prefilled. See [doc/Client.md](../doc/Client.md).
25
+
26
+ ## camswitcher-events.html
27
+
28
+ Logs every CamSwitcher event. `DeviceConnectClient` (HTTP) backs `CamSwitcherAPI` to obtain the
29
+ websocket authorization token; `DeviceConnectWsClient` (websocket) backs `CamSwitcherEvents`, which
30
+ validates and dispatches the events. Connection state is taken from the `authorization` event.
31
+
32
+ See [doc/ws/CamSwitcherEvents.md](../doc/ws/CamSwitcherEvents.md).
33
+
34
+ ## planetracker-events.html
35
+
36
+ Logs every PlaneTracker event. PlaneTracker needs no authorization token — `PlaneTrackerEvents`
37
+ announces the connecting user (`userId` / `userName` / `userPriority`, editable in the form) as the
38
+ init message instead, so only the websocket client is needed.
39
+
40
+ `CAMERA_POSITION` and `FLIGHT_LIST` arrive continuously, so by default they only update the summary
41
+ line above the log; tick the checkbox to log them as well.
42
+
43
+ See [doc/ws/PlaneTrackerEvents.md](../doc/ws/PlaneTrackerEvents.md).