camstreamerlib 4.0.17-dev-milestone.0 → 4.0.17-dev-milestone.1

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.
@@ -1,5 +1,5 @@
1
1
  import { IClient, TResponse } from './internal/types';
2
- import { ICAO, TBlackList, TCameraSettings, TExportDataType, TGetIcaoByOption, TImportDataType, TPriorityList, TTrackingMode, TWhiteList, TZones } from './types/PlaneTrackerAPI';
2
+ import { ICAO, TBlackList, TCameraSettings, TConnection, TExportDataType, TGetIcaoByOption, TImportDataType, TMilestoneCameraOption, TPriorityList, TTrackingMode, TWhiteList, TZones } from './types/PlaneTrackerAPI';
3
3
  import { THttpRequestOptions } from './types/common';
4
4
  import { BasicAPI } from './internal/BasicAPI';
5
5
  import { TApiUser } from './types/ws/PlaneTrackerEvents';
@@ -259,5 +259,7 @@ export declare class PlaneTrackerAPI<Client extends IClient<TResponse, any>> ext
259
259
  }>;
260
260
  setZones(zones: TZones, options?: THttpRequestOptions): Promise<void>;
261
261
  goToCoordinates(lat: number, lon: number, alt?: number, options?: THttpRequestOptions): Promise<void>;
262
+ checkMilestoneConnection(params: TConnection, options?: THttpRequestOptions): Promise<boolean>;
263
+ getMilestoneCameraList(params: TConnection, options?: THttpRequestOptions): Promise<TMilestoneCameraOption[]>;
262
264
  downloadReport(options?: THttpRequestOptions): Promise<string>;
263
265
  }
@@ -196,6 +196,19 @@ class PlaneTrackerAPI extends BasicAPI_1.BasicAPI {
196
196
  }
197
197
  }
198
198
  }
199
+ async checkMilestoneConnection(params, options) {
200
+ try {
201
+ await this._postUrlEncoded(`${BASE_PATH}/package/checkMilestoneConnection.cgi`, { ...params }, options);
202
+ return true;
203
+ }
204
+ catch {
205
+ return false;
206
+ }
207
+ }
208
+ async getMilestoneCameraList(params, options) {
209
+ const res = await this._postUrlEncoded(`${BASE_PATH}/package/getMilestoneCameraList.cgi`, { ...params }, options);
210
+ return PlaneTrackerAPI_1.milestoneCameraListSchema.parse(await res.json());
211
+ }
199
212
  downloadReport(options) {
200
213
  return this._getText(`${BASE_PATH}/report.cgi`, undefined, options);
201
214
  }
@@ -33,6 +33,21 @@ export declare const connectionSchema: z.ZodObject<{
33
33
  user: string;
34
34
  protocol: "https" | "http" | "https_insecure";
35
35
  }>;
36
+ export type TConnection = z.infer<typeof connectionSchema>;
37
+ export declare const milestoneCameraListSchema: z.ZodArray<z.ZodObject<{
38
+ index: z.ZodNumber;
39
+ value: z.ZodString;
40
+ label: z.ZodString;
41
+ }, "strip", z.ZodTypeAny, {
42
+ value: string;
43
+ label: string;
44
+ index: number;
45
+ }, {
46
+ value: string;
47
+ label: string;
48
+ index: number;
49
+ }>, "many">;
50
+ export type TMilestoneCameraOption = z.infer<typeof milestoneCameraListSchema>[number];
36
51
  export declare const widgetSchema: z.ZodObject<{
37
52
  enabled: z.ZodDefault<z.ZodBoolean>;
38
53
  coord: z.ZodUnion<[z.ZodLiteral<"top_left">, z.ZodLiteral<"top_right">, z.ZodLiteral<"bottom_left">, z.ZodLiteral<"bottom_right">]>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.REMOTE_ID_CATEGORY_IDS = exports.ADSB_CATEGORY_IDS = exports.domainListSchema = exports.domainIdSchema = exports.zonesSchema = exports.mapInfoSchema = exports.mapTypeSchema = exports.priorityListSchema = exports.blackListSchema = exports.whiteListSchema = exports.priorityListEntrySchema = exports.listEntrySchema = exports.listEntryIdTypeSchema = exports.listEntryDomainSchema = exports.flightInfoSchema = exports.trackingModeSchema = exports.getIcaoSchema = exports.serverSettingsSchema = exports.cameraSettingsSchema = exports.widgetSchema = exports.connectionSchema = exports.wsAliasResponseSchema = void 0;
3
+ exports.REMOTE_ID_CATEGORY_IDS = exports.ADSB_CATEGORY_IDS = exports.domainListSchema = exports.domainIdSchema = exports.zonesSchema = exports.mapInfoSchema = exports.mapTypeSchema = exports.priorityListSchema = exports.blackListSchema = exports.whiteListSchema = exports.priorityListEntrySchema = exports.listEntrySchema = exports.listEntryIdTypeSchema = exports.listEntryDomainSchema = exports.flightInfoSchema = exports.trackingModeSchema = exports.getIcaoSchema = exports.serverSettingsSchema = exports.cameraSettingsSchema = exports.widgetSchema = exports.milestoneCameraListSchema = exports.connectionSchema = exports.wsAliasResponseSchema = void 0;
4
4
  const zod_1 = require("zod");
5
5
  exports.wsAliasResponseSchema = zod_1.z.object({
6
6
  alias: zod_1.z.string(),
@@ -14,6 +14,13 @@ exports.connectionSchema = zod_1.z.object({
14
14
  user: zod_1.z.string(),
15
15
  pass: zod_1.z.string(),
16
16
  });
17
+ exports.milestoneCameraListSchema = zod_1.z
18
+ .object({
19
+ index: zod_1.z.number(),
20
+ value: zod_1.z.string(),
21
+ label: zod_1.z.string(),
22
+ })
23
+ .array();
17
24
  exports.widgetSchema = zod_1.z.object({
18
25
  enabled: zod_1.z.boolean().default(true),
19
26
  coord: zod_1.z.union([
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { blackListSchema, cameraSettingsSchema, domainListSchema, flightInfoSchema, getIcaoSchema, mapInfoSchema, priorityListSchema, serverSettingsSchema, trackingModeSchema, whiteListSchema, wsAliasResponseSchema, zonesSchema, } from './types/PlaneTrackerAPI';
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
5
  const BASE_PATH = '/local/planetracker';
@@ -193,6 +193,19 @@ export class PlaneTrackerAPI extends BasicAPI {
193
193
  }
194
194
  }
195
195
  }
196
+ async checkMilestoneConnection(params, options) {
197
+ try {
198
+ await this._postUrlEncoded(`${BASE_PATH}/package/checkMilestoneConnection.cgi`, { ...params }, options);
199
+ return true;
200
+ }
201
+ catch {
202
+ return false;
203
+ }
204
+ }
205
+ async getMilestoneCameraList(params, options) {
206
+ const res = await this._postUrlEncoded(`${BASE_PATH}/package/getMilestoneCameraList.cgi`, { ...params }, options);
207
+ return milestoneCameraListSchema.parse(await res.json());
208
+ }
196
209
  downloadReport(options) {
197
210
  return this._getText(`${BASE_PATH}/report.cgi`, undefined, options);
198
211
  }
@@ -11,6 +11,13 @@ export const connectionSchema = z.object({
11
11
  user: z.string(),
12
12
  pass: z.string(),
13
13
  });
14
+ export const milestoneCameraListSchema = z
15
+ .object({
16
+ index: z.number(),
17
+ value: z.string(),
18
+ label: z.string(),
19
+ })
20
+ .array();
14
21
  export const widgetSchema = z.object({
15
22
  enabled: z.boolean().default(true),
16
23
  coord: z.union([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstreamerlib",
3
- "version": "4.0.17-dev-milestone.0",
3
+ "version": "4.0.17-dev-milestone.1",
4
4
  "description": "Helper library for CamStreamer ACAP applications.",
5
5
  "prettier": "@camstreamer/prettier-config",
6
6
  "engine": {
@@ -1,5 +1,5 @@
1
1
  import { IClient, TResponse } from './internal/types';
2
- import { ICAO, TBlackList, TCameraSettings, TExportDataType, TGetIcaoByOption, TImportDataType, TPriorityList, TTrackingMode, TWhiteList, TZones } from './types/PlaneTrackerAPI';
2
+ import { ICAO, TBlackList, TCameraSettings, TConnection, TExportDataType, TGetIcaoByOption, TImportDataType, TMilestoneCameraOption, TPriorityList, TTrackingMode, TWhiteList, TZones } from './types/PlaneTrackerAPI';
3
3
  import { THttpRequestOptions } from './types/common';
4
4
  import { BasicAPI } from './internal/BasicAPI';
5
5
  import { TApiUser } from './types/ws/PlaneTrackerEvents';
@@ -259,5 +259,7 @@ export declare class PlaneTrackerAPI<Client extends IClient<TResponse, any>> ext
259
259
  }>;
260
260
  setZones(zones: TZones, options?: THttpRequestOptions): Promise<void>;
261
261
  goToCoordinates(lat: number, lon: number, alt?: number, options?: THttpRequestOptions): Promise<void>;
262
+ checkMilestoneConnection(params: TConnection, options?: THttpRequestOptions): Promise<boolean>;
263
+ getMilestoneCameraList(params: TConnection, options?: THttpRequestOptions): Promise<TMilestoneCameraOption[]>;
262
264
  downloadReport(options?: THttpRequestOptions): Promise<string>;
263
265
  }
@@ -33,6 +33,21 @@ export declare const connectionSchema: z.ZodObject<{
33
33
  user: string;
34
34
  protocol: "https" | "http" | "https_insecure";
35
35
  }>;
36
+ export type TConnection = z.infer<typeof connectionSchema>;
37
+ export declare const milestoneCameraListSchema: z.ZodArray<z.ZodObject<{
38
+ index: z.ZodNumber;
39
+ value: z.ZodString;
40
+ label: z.ZodString;
41
+ }, "strip", z.ZodTypeAny, {
42
+ value: string;
43
+ label: string;
44
+ index: number;
45
+ }, {
46
+ value: string;
47
+ label: string;
48
+ index: number;
49
+ }>, "many">;
50
+ export type TMilestoneCameraOption = z.infer<typeof milestoneCameraListSchema>[number];
36
51
  export declare const widgetSchema: z.ZodObject<{
37
52
  enabled: z.ZodDefault<z.ZodBoolean>;
38
53
  coord: z.ZodUnion<[z.ZodLiteral<"top_left">, z.ZodLiteral<"top_right">, z.ZodLiteral<"bottom_left">, z.ZodLiteral<"bottom_right">]>;
@@ -1 +0,0 @@
1
- export {};
@@ -1,102 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const globals_1 = require("@jest/globals");
4
- const HttpRequestSender_1 = require("../HttpRequestSender");
5
- const MilestoneAgent_1 = require("./MilestoneAgent");
6
- globals_1.jest.mock('../HttpRequestSender');
7
- function jsonResponse(body, status = 200) {
8
- return {
9
- ok: status >= 200 && status < 300,
10
- status,
11
- statusText: 'OK',
12
- text: () => Promise.resolve(JSON.stringify(body)),
13
- };
14
- }
15
- const TOKEN_BODY = { access_token: 'abc123', expires_in: 3600, token_type: 'Bearer', scope: 'managementserver' };
16
- (0, globals_1.describe)('MilestoneAgent', () => {
17
- const MockedSender = globals_1.jest.mocked(HttpRequestSender_1.HttpRequestSender);
18
- let sendRequest;
19
- (0, globals_1.beforeEach)(() => {
20
- sendRequest = globals_1.jest.fn();
21
- MockedSender.mockImplementation(() => ({ sendRequest }));
22
- });
23
- function callsTo(prefix) {
24
- return sendRequest.mock.calls.filter((c) => c[0].path.startsWith(prefix));
25
- }
26
- function routeByPath(handlers) {
27
- sendRequest.mockImplementation((...args) => {
28
- const options = args[0];
29
- if (options.path === '/idp/connect/token') {
30
- return Promise.resolve(jsonResponse(TOKEN_BODY));
31
- }
32
- for (const [prefix, handler] of Object.entries(handlers)) {
33
- if (options.path.startsWith(prefix)) {
34
- if (typeof handler === 'function') {
35
- const page = Number(new URLSearchParams(options.path.split('?')[1]).get('page'));
36
- return Promise.resolve(handler(page));
37
- }
38
- return Promise.resolve(handler);
39
- }
40
- }
41
- throw new Error(`Unexpected path ${options.path}`);
42
- });
43
- }
44
- (0, globals_1.test)('fetches a bearer token before listing cameras and sends it in the header', async () => {
45
- routeByPath({ '/api/rest/v1/cameras': jsonResponse({ array: [{ id: 'cam-1', displayName: 'Cam 1' }] }) });
46
- const agent = new MilestoneAgent_1.MilestoneAgent({ ip: '1.2.3.4' });
47
- const cameras = await agent.getAllCameras();
48
- (0, globals_1.expect)(cameras).toEqual([{ id: 'cam-1', displayName: 'Cam 1' }]);
49
- const tokenCalls = callsTo('/idp/connect/token');
50
- (0, globals_1.expect)(tokenCalls.length).toBe(1);
51
- (0, globals_1.expect)(tokenCalls[0][0].method).toBe('POST');
52
- const camerasCall = callsTo('/api/rest/v1/cameras')[0];
53
- (0, globals_1.expect)(camerasCall[0].headers.Authorization).toBe('Bearer abc123');
54
- });
55
- (0, globals_1.test)('reuses the cached token across calls', async () => {
56
- routeByPath({ '/api/rest/v1/cameras': jsonResponse({ array: [] }) });
57
- const agent = new MilestoneAgent_1.MilestoneAgent({ ip: '1.2.3.4' });
58
- await agent.getAllCameras();
59
- await agent.getAllCameras();
60
- (0, globals_1.expect)(callsTo('/idp/connect/token').length).toBe(1);
61
- });
62
- (0, globals_1.test)('pages through cameras until a non-full page is returned', async () => {
63
- const fullPage = (page) => jsonResponse({ array: Array.from({ length: 100 }, (_, i) => ({ id: `p${page}-${i}` })) });
64
- routeByPath({
65
- '/api/rest/v1/cameras': (page) => page < 3 ? fullPage(page) : jsonResponse({ array: [{ id: 'last' }] }),
66
- });
67
- const agent = new MilestoneAgent_1.MilestoneAgent({ ip: '1.2.3.4' });
68
- const cameras = await agent.getAllCameras();
69
- (0, globals_1.expect)(cameras.length).toBe(201);
70
- (0, globals_1.expect)(cameras[cameras.length - 1]).toEqual({ id: 'last' });
71
- });
72
- (0, globals_1.test)('sends a bookmark with the camera devicePath', async () => {
73
- routeByPath({ '/api/rest/v1/bookmarks': jsonResponse({ result: {} }, 201) });
74
- const agent = new MilestoneAgent_1.MilestoneAgent({ ip: '1.2.3.4' });
75
- await agent.sendBookmark('cam-guid', {
76
- header: 'Airbus A320',
77
- description: 'ICAO BC4AA',
78
- timeBegin: '2026-04-16T10:25:00.000Z',
79
- timeEnd: '2026-04-16T10:25:00.000Z',
80
- timeTriggered: '2026-04-16T10:25:00.000Z',
81
- reference: 'BC4AA',
82
- });
83
- const call = callsTo('/api/rest/v1/bookmarks')[0];
84
- (0, globals_1.expect)(call).toBeDefined();
85
- const body = JSON.parse(call[1]);
86
- (0, globals_1.expect)(body.devicePath).toEqual({ type: 'cameras', id: 'cam-guid' });
87
- (0, globals_1.expect)(body.header).toBe('Airbus A320');
88
- (0, globals_1.expect)(body.description).toBe('ICAO BC4AA');
89
- });
90
- (0, globals_1.test)('throws on a non-ok bookmark response', async () => {
91
- routeByPath({ '/api/rest/v1/bookmarks': jsonResponse({ error: 'nope' }, 500) });
92
- const agent = new MilestoneAgent_1.MilestoneAgent({ ip: '1.2.3.4' });
93
- await (0, globals_1.expect)(agent.sendBookmark('cam-guid', {
94
- header: 'h',
95
- description: 'd',
96
- timeBegin: 't',
97
- timeEnd: 't',
98
- timeTriggered: 't',
99
- reference: 'r',
100
- })).rejects.toThrow();
101
- });
102
- });
@@ -1,100 +0,0 @@
1
- import { describe, test, expect, beforeEach, jest } from '@jest/globals';
2
- import { HttpRequestSender } from '../HttpRequestSender';
3
- import { MilestoneAgent } from './MilestoneAgent';
4
- jest.mock('../HttpRequestSender');
5
- function jsonResponse(body, status = 200) {
6
- return {
7
- ok: status >= 200 && status < 300,
8
- status,
9
- statusText: 'OK',
10
- text: () => Promise.resolve(JSON.stringify(body)),
11
- };
12
- }
13
- const TOKEN_BODY = { access_token: 'abc123', expires_in: 3600, token_type: 'Bearer', scope: 'managementserver' };
14
- describe('MilestoneAgent', () => {
15
- const MockedSender = jest.mocked(HttpRequestSender);
16
- let sendRequest;
17
- beforeEach(() => {
18
- sendRequest = jest.fn();
19
- MockedSender.mockImplementation(() => ({ sendRequest }));
20
- });
21
- function callsTo(prefix) {
22
- return sendRequest.mock.calls.filter((c) => c[0].path.startsWith(prefix));
23
- }
24
- function routeByPath(handlers) {
25
- sendRequest.mockImplementation((...args) => {
26
- const options = args[0];
27
- if (options.path === '/idp/connect/token') {
28
- return Promise.resolve(jsonResponse(TOKEN_BODY));
29
- }
30
- for (const [prefix, handler] of Object.entries(handlers)) {
31
- if (options.path.startsWith(prefix)) {
32
- if (typeof handler === 'function') {
33
- const page = Number(new URLSearchParams(options.path.split('?')[1]).get('page'));
34
- return Promise.resolve(handler(page));
35
- }
36
- return Promise.resolve(handler);
37
- }
38
- }
39
- throw new Error(`Unexpected path ${options.path}`);
40
- });
41
- }
42
- test('fetches a bearer token before listing cameras and sends it in the header', async () => {
43
- routeByPath({ '/api/rest/v1/cameras': jsonResponse({ array: [{ id: 'cam-1', displayName: 'Cam 1' }] }) });
44
- const agent = new MilestoneAgent({ ip: '1.2.3.4' });
45
- const cameras = await agent.getAllCameras();
46
- expect(cameras).toEqual([{ id: 'cam-1', displayName: 'Cam 1' }]);
47
- const tokenCalls = callsTo('/idp/connect/token');
48
- expect(tokenCalls.length).toBe(1);
49
- expect(tokenCalls[0][0].method).toBe('POST');
50
- const camerasCall = callsTo('/api/rest/v1/cameras')[0];
51
- expect(camerasCall[0].headers.Authorization).toBe('Bearer abc123');
52
- });
53
- test('reuses the cached token across calls', async () => {
54
- routeByPath({ '/api/rest/v1/cameras': jsonResponse({ array: [] }) });
55
- const agent = new MilestoneAgent({ ip: '1.2.3.4' });
56
- await agent.getAllCameras();
57
- await agent.getAllCameras();
58
- expect(callsTo('/idp/connect/token').length).toBe(1);
59
- });
60
- test('pages through cameras until a non-full page is returned', async () => {
61
- const fullPage = (page) => jsonResponse({ array: Array.from({ length: 100 }, (_, i) => ({ id: `p${page}-${i}` })) });
62
- routeByPath({
63
- '/api/rest/v1/cameras': (page) => page < 3 ? fullPage(page) : jsonResponse({ array: [{ id: 'last' }] }),
64
- });
65
- const agent = new MilestoneAgent({ ip: '1.2.3.4' });
66
- const cameras = await agent.getAllCameras();
67
- expect(cameras.length).toBe(201);
68
- expect(cameras[cameras.length - 1]).toEqual({ id: 'last' });
69
- });
70
- test('sends a bookmark with the camera devicePath', async () => {
71
- routeByPath({ '/api/rest/v1/bookmarks': jsonResponse({ result: {} }, 201) });
72
- const agent = new MilestoneAgent({ ip: '1.2.3.4' });
73
- await agent.sendBookmark('cam-guid', {
74
- header: 'Airbus A320',
75
- description: 'ICAO BC4AA',
76
- timeBegin: '2026-04-16T10:25:00.000Z',
77
- timeEnd: '2026-04-16T10:25:00.000Z',
78
- timeTriggered: '2026-04-16T10:25:00.000Z',
79
- reference: 'BC4AA',
80
- });
81
- const call = callsTo('/api/rest/v1/bookmarks')[0];
82
- expect(call).toBeDefined();
83
- const body = JSON.parse(call[1]);
84
- expect(body.devicePath).toEqual({ type: 'cameras', id: 'cam-guid' });
85
- expect(body.header).toBe('Airbus A320');
86
- expect(body.description).toBe('ICAO BC4AA');
87
- });
88
- test('throws on a non-ok bookmark response', async () => {
89
- routeByPath({ '/api/rest/v1/bookmarks': jsonResponse({ error: 'nope' }, 500) });
90
- const agent = new MilestoneAgent({ ip: '1.2.3.4' });
91
- await expect(agent.sendBookmark('cam-guid', {
92
- header: 'h',
93
- description: 'd',
94
- timeBegin: 't',
95
- timeEnd: 't',
96
- timeTriggered: 't',
97
- reference: 'r',
98
- })).rejects.toThrow();
99
- });
100
- });
@@ -1 +0,0 @@
1
- export {};