camstreamerlib 4.0.2 → 4.0.4

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,4 +1,4 @@
1
- import { IClient, TParameters, TResponse } from './internal/types';
1
+ import { IClient, TResponse } from './internal/types';
2
2
  import { ICAO, TApiUser, TBlackList, TCameraSettings, TExportDataType, TGetIcaoByOption, TImportDataType, TPriorityList, TTrackingMode, TTypePriorityList, TWhiteList, TZones } from './types/PlaneTrackerAPI';
3
3
  import { THttpRequestOptions } from './types/common';
4
4
  import { BasicAPI } from './internal/BasicAPI';
@@ -106,17 +106,6 @@ export declare class PlaneTrackerAPI<Client extends IClient<TResponse, any>> ext
106
106
  protocol: "https" | "http" | "https_insecure";
107
107
  sourceKey: string;
108
108
  };
109
- genetec: {
110
- ip: string;
111
- enabled: boolean;
112
- port: number;
113
- cameraList: string[];
114
- pass: string;
115
- appId: string;
116
- user: string;
117
- protocol: "https" | "http" | "https_insecure";
118
- baseUri: string;
119
- };
120
109
  camstreamerIntegration: {
121
110
  adPlacementEnabled: boolean;
122
111
  adMinIntervalSec: number;
@@ -232,10 +221,4 @@ export declare class PlaneTrackerAPI<Client extends IClient<TResponse, any>> ext
232
221
  setZones(zones: TZones, options?: THttpRequestOptions): Promise<void>;
233
222
  goToCoordinates(lat: number, lon: number, alt?: number, options?: THttpRequestOptions): Promise<void>;
234
223
  downloadReport(options?: THttpRequestOptions): Promise<string>;
235
- checkGenetecConnection(params: TParameters, options?: THttpRequestOptions): Promise<boolean>;
236
- getGenetecCameraList(params: TParameters, options?: THttpRequestOptions): Promise<{
237
- value: string;
238
- label: string;
239
- index: number;
240
- }[]>;
241
224
  }
@@ -4,7 +4,6 @@ exports.PlaneTrackerAPI = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const PlaneTrackerAPI_1 = require("./types/PlaneTrackerAPI");
6
6
  const errors_1 = require("./errors/errors");
7
- const GenetecAgent_1 = require("./types/GenetecAgent");
8
7
  const BasicAPI_1 = require("./internal/BasicAPI");
9
8
  const BASE_PATH = '/local/planetracker';
10
9
  class PlaneTrackerAPI extends BasicAPI_1.BasicAPI {
@@ -187,13 +186,5 @@ class PlaneTrackerAPI extends BasicAPI_1.BasicAPI {
187
186
  downloadReport(options) {
188
187
  return this._getText(`${BASE_PATH}/report.cgi`, undefined, options);
189
188
  }
190
- async checkGenetecConnection(params, options) {
191
- const res = await this._postUrlEncoded(`${BASE_PATH}/package/checkGenetecConnection.cgi`, params, options);
192
- return res.status === 200;
193
- }
194
- async getGenetecCameraList(params, options) {
195
- const res = await this._postUrlEncoded(`${BASE_PATH}/package/getGenetecCameraList.cgi`, params, options);
196
- return GenetecAgent_1.cameraListSchema.parse(await res.json());
197
- }
198
189
  }
199
190
  exports.PlaneTrackerAPI = PlaneTrackerAPI;
@@ -1,32 +1,64 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toSnakeCaseDeep = exports.toSnakeCase = exports.toCamelCaseDeep = exports.toCamelCase = void 0;
4
- const lodash_es_1 = require("lodash-es");
5
- const toCamelCase = (o) => (0, lodash_es_1.mapKeys)(o, camelCaseKey);
4
+ const toCamelCase = (o) => mapKeys(o, camelCase);
6
5
  exports.toCamelCase = toCamelCase;
7
6
  const toCamelCaseDeep = (o) => {
8
- return mapKeysDeep(o, camelCaseKey);
7
+ return mapKeysDeep(o, camelCase);
9
8
  };
10
9
  exports.toCamelCaseDeep = toCamelCaseDeep;
11
- const toSnakeCase = (o) => (0, lodash_es_1.mapKeys)(o, snakeCaseKey);
10
+ const toSnakeCase = (o) => mapKeys(o, snakeCase);
12
11
  exports.toSnakeCase = toSnakeCase;
13
12
  const toSnakeCaseDeep = (o) => {
14
- return mapKeysDeep(o, snakeCaseKey);
13
+ return mapKeysDeep(o, snakeCase);
15
14
  };
16
15
  exports.toSnakeCaseDeep = toSnakeCaseDeep;
17
- const camelCaseKey = (_, key) => (0, lodash_es_1.camelCase)(key);
18
- const snakeCaseKey = (_, key) => (0, lodash_es_1.snakeCase)(key);
16
+ const splitWords = (input) => {
17
+ if (!input) {
18
+ return [];
19
+ }
20
+ return (input
21
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
22
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
23
+ .replace(/[^a-zA-Z0-9]+/g, ' ')
24
+ .trim()
25
+ .split(/\s+/)
26
+ .map((w) => w.toLowerCase())
27
+ .filter((w) => w.length > 0));
28
+ };
29
+ const camelCase = (key) => {
30
+ const words = splitWords(key);
31
+ if (words.length === 0) {
32
+ return '';
33
+ }
34
+ const [first, ...rest] = words;
35
+ return first + rest.map((w) => w[0].toUpperCase() + w.slice(1)).join('');
36
+ };
37
+ const snakeCase = (key) => splitWords(key).join('_');
38
+ const isPlainObject = (value) => {
39
+ if (value === null || typeof value !== 'object') {
40
+ return false;
41
+ }
42
+ const proto = Object.getPrototypeOf(value);
43
+ return proto === null || proto === Object.prototype;
44
+ };
45
+ const mapKeys = (obj, cb) => {
46
+ const result = {};
47
+ for (const key of Object.keys(obj)) {
48
+ result[cb(key)] = obj[key];
49
+ }
50
+ return result;
51
+ };
19
52
  const mapKeysDeep = (obj, cb) => {
20
53
  if (Array.isArray(obj)) {
21
- return obj.map((item) => {
22
- return mapKeysDeep(item, cb);
23
- });
54
+ return obj.map((item) => mapKeysDeep(item, cb));
24
55
  }
25
- if (typeof obj !== 'object' || (0, lodash_es_1.isPlainObject)(obj) === false) {
56
+ if (!isPlainObject(obj)) {
26
57
  return obj;
27
58
  }
28
- const result = (0, lodash_es_1.mapKeys)(obj, cb);
29
- return (0, lodash_es_1.mapValues)(result, (value) => {
30
- return mapKeysDeep(value, cb);
31
- });
59
+ const result = {};
60
+ for (const key of Object.keys(obj)) {
61
+ result[cb(key)] = mapKeysDeep(obj[key], cb);
62
+ }
63
+ return result;
32
64
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const transformers_1 = require("./transformers");
4
+ const globals_1 = require("@jest/globals");
5
+ (0, globals_1.describe)('transformers', () => {
6
+ (0, globals_1.describe)('toCamelCase', () => {
7
+ (0, globals_1.test)('converts snake_case keys to camelCase', () => {
8
+ (0, globals_1.expect)((0, transformers_1.toCamelCase)({ foo_bar: 1, baz_qux_quux: 2 })).toEqual({ fooBar: 1, bazQuxQuux: 2 });
9
+ });
10
+ (0, globals_1.test)('converts kebab-case keys to camelCase', () => {
11
+ (0, globals_1.expect)((0, transformers_1.toCamelCase)({ 'foo-bar': 1, 'baz-qux': 2 })).toEqual({ fooBar: 1, bazQux: 2 });
12
+ });
13
+ (0, globals_1.test)('preserves already-camelCase keys', () => {
14
+ (0, globals_1.expect)((0, transformers_1.toCamelCase)({ fooBar: 1 })).toEqual({ fooBar: 1 });
15
+ });
16
+ (0, globals_1.test)('converts PascalCase keys to camelCase', () => {
17
+ (0, globals_1.expect)((0, transformers_1.toCamelCase)({ FooBar: 1 })).toEqual({ fooBar: 1 });
18
+ });
19
+ (0, globals_1.test)('handles consecutive uppercase runs (acronyms)', () => {
20
+ (0, globals_1.expect)((0, transformers_1.toCamelCase)({ HTTPServer: 1, parseURL: 2 })).toEqual({ httpServer: 1, parseUrl: 2 });
21
+ });
22
+ (0, globals_1.test)('handles dot.case keys', () => {
23
+ (0, globals_1.expect)((0, transformers_1.toCamelCase)({ 'foo.bar.baz': 1 })).toEqual({ fooBarBaz: 1 });
24
+ });
25
+ (0, globals_1.test)('does not recurse into nested objects', () => {
26
+ const input = { outer_key: { inner_key: 1 } };
27
+ (0, globals_1.expect)((0, transformers_1.toCamelCase)(input)).toEqual({ outerKey: { inner_key: 1 } });
28
+ });
29
+ (0, globals_1.test)('handles empty object', () => {
30
+ (0, globals_1.expect)((0, transformers_1.toCamelCase)({})).toEqual({});
31
+ });
32
+ (0, globals_1.test)('handles keys with numbers', () => {
33
+ (0, globals_1.expect)((0, transformers_1.toCamelCase)({ foo_1_bar: 1, v2_api: 2 })).toEqual({ foo1Bar: 1, v2Api: 2 });
34
+ });
35
+ });
36
+ (0, globals_1.describe)('toCamelCaseDeep', () => {
37
+ (0, globals_1.test)('converts nested object keys recursively', () => {
38
+ const input = { outer_key: { inner_key: { deep_key: 1 } } };
39
+ (0, globals_1.expect)((0, transformers_1.toCamelCaseDeep)(input)).toEqual({ outerKey: { innerKey: { deepKey: 1 } } });
40
+ });
41
+ (0, globals_1.test)('converts keys inside arrays of objects', () => {
42
+ const input = { items_list: [{ item_name: 'a' }, { item_name: 'b' }] };
43
+ (0, globals_1.expect)((0, transformers_1.toCamelCaseDeep)(input)).toEqual({ itemsList: [{ itemName: 'a' }, { itemName: 'b' }] });
44
+ });
45
+ (0, globals_1.test)('leaves primitive array values untouched', () => {
46
+ const input = { values_list: [1, 2, 3] };
47
+ (0, globals_1.expect)((0, transformers_1.toCamelCaseDeep)(input)).toEqual({ valuesList: [1, 2, 3] });
48
+ });
49
+ (0, globals_1.test)('does not recurse into non-plain objects (e.g. Date)', () => {
50
+ const date = new Date(0);
51
+ const input = { created_at: date };
52
+ const result = (0, transformers_1.toCamelCaseDeep)(input);
53
+ (0, globals_1.expect)(result.createdAt).toBe(date);
54
+ });
55
+ (0, globals_1.test)('handles null values', () => {
56
+ (0, globals_1.expect)((0, transformers_1.toCamelCaseDeep)({ foo_bar: null })).toEqual({ fooBar: null });
57
+ });
58
+ });
59
+ (0, globals_1.describe)('toSnakeCase', () => {
60
+ (0, globals_1.test)('converts camelCase keys to snake_case', () => {
61
+ (0, globals_1.expect)((0, transformers_1.toSnakeCase)({ fooBar: 1, bazQuxQuux: 2 })).toEqual({ foo_bar: 1, baz_qux_quux: 2 });
62
+ });
63
+ (0, globals_1.test)('converts PascalCase keys to snake_case', () => {
64
+ (0, globals_1.expect)((0, transformers_1.toSnakeCase)({ FooBar: 1 })).toEqual({ foo_bar: 1 });
65
+ });
66
+ (0, globals_1.test)('converts kebab-case keys to snake_case', () => {
67
+ (0, globals_1.expect)((0, transformers_1.toSnakeCase)({ 'foo-bar': 1 })).toEqual({ foo_bar: 1 });
68
+ });
69
+ (0, globals_1.test)('preserves already-snake_case keys', () => {
70
+ (0, globals_1.expect)((0, transformers_1.toSnakeCase)({ foo_bar: 1 })).toEqual({ foo_bar: 1 });
71
+ });
72
+ (0, globals_1.test)('handles acronyms', () => {
73
+ (0, globals_1.expect)((0, transformers_1.toSnakeCase)({ HTTPServer: 1, parseURL: 2 })).toEqual({ http_server: 1, parse_url: 2 });
74
+ });
75
+ (0, globals_1.test)('does not recurse into nested objects', () => {
76
+ const input = { outerKey: { innerKey: 1 } };
77
+ (0, globals_1.expect)((0, transformers_1.toSnakeCase)(input)).toEqual({ outer_key: { innerKey: 1 } });
78
+ });
79
+ });
80
+ (0, globals_1.describe)('toSnakeCaseDeep', () => {
81
+ (0, globals_1.test)('converts nested object keys recursively', () => {
82
+ const input = { outerKey: { innerKey: { deepKey: 1 } } };
83
+ (0, globals_1.expect)((0, transformers_1.toSnakeCaseDeep)(input)).toEqual({ outer_key: { inner_key: { deep_key: 1 } } });
84
+ });
85
+ (0, globals_1.test)('converts keys inside arrays of objects', () => {
86
+ const input = { itemsList: [{ itemName: 'a' }, { itemName: 'b' }] };
87
+ (0, globals_1.expect)((0, transformers_1.toSnakeCaseDeep)(input)).toEqual({ items_list: [{ item_name: 'a' }, { item_name: 'b' }] });
88
+ });
89
+ (0, globals_1.test)('handles null and undefined values', () => {
90
+ (0, globals_1.expect)((0, transformers_1.toSnakeCaseDeep)({ fooBar: null, bazQux: undefined })).toEqual({
91
+ foo_bar: null,
92
+ baz_qux: undefined,
93
+ });
94
+ });
95
+ });
96
+ });
@@ -360,38 +360,6 @@ export declare const cameraSettingsSchema: z.ZodObject<{
360
360
  protocol: "https" | "http" | "https_insecure";
361
361
  sourceKey: string;
362
362
  }>>;
363
- genetec: z.ZodDefault<z.ZodObject<{
364
- protocol: z.ZodUnion<[z.ZodLiteral<"http">, z.ZodLiteral<"https">, z.ZodLiteral<"https_insecure">]>;
365
- ip: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
366
- port: z.ZodNumber;
367
- user: z.ZodString;
368
- pass: z.ZodString;
369
- } & {
370
- enabled: z.ZodBoolean;
371
- baseUri: z.ZodDefault<z.ZodString>;
372
- appId: z.ZodDefault<z.ZodString>;
373
- cameraList: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
374
- }, "strip", z.ZodTypeAny, {
375
- ip: string;
376
- enabled: boolean;
377
- port: number;
378
- cameraList: string[];
379
- pass: string;
380
- appId: string;
381
- user: string;
382
- protocol: "https" | "http" | "https_insecure";
383
- baseUri: string;
384
- }, {
385
- ip: string;
386
- enabled: boolean;
387
- port: number;
388
- pass: string;
389
- user: string;
390
- protocol: "https" | "http" | "https_insecure";
391
- cameraList?: string[] | undefined;
392
- appId?: string | undefined;
393
- baseUri?: string | undefined;
394
- }>>;
395
363
  camstreamerIntegration: z.ZodDefault<z.ZodObject<{
396
364
  adPlacementEnabled: z.ZodBoolean;
397
365
  adMinIntervalSec: z.ZodNumber;
@@ -497,17 +465,6 @@ export declare const cameraSettingsSchema: z.ZodObject<{
497
465
  protocol: "https" | "http" | "https_insecure";
498
466
  sourceKey: string;
499
467
  };
500
- genetec: {
501
- ip: string;
502
- enabled: boolean;
503
- port: number;
504
- cameraList: string[];
505
- pass: string;
506
- appId: string;
507
- user: string;
508
- protocol: "https" | "http" | "https_insecure";
509
- baseUri: string;
510
- };
511
468
  camstreamerIntegration: {
512
469
  adPlacementEnabled: boolean;
513
470
  adMinIntervalSec: number;
@@ -649,17 +606,6 @@ export declare const cameraSettingsSchema: z.ZodObject<{
649
606
  protocol: "https" | "http" | "https_insecure";
650
607
  sourceKey: string;
651
608
  } | undefined;
652
- genetec?: {
653
- ip: string;
654
- enabled: boolean;
655
- port: number;
656
- pass: string;
657
- user: string;
658
- protocol: "https" | "http" | "https_insecure";
659
- cameraList?: string[] | undefined;
660
- appId?: string | undefined;
661
- baseUri?: string | undefined;
662
- } | undefined;
663
609
  camstreamerIntegration?: {
664
610
  adPlacementEnabled: boolean;
665
611
  adMinIntervalSec: number;
@@ -201,24 +201,6 @@ exports.cameraSettingsSchema = zod_1.z.object({
201
201
  pass: '',
202
202
  sourceKey: '',
203
203
  }),
204
- genetec: exports.connectionSchema
205
- .extend({
206
- enabled: zod_1.z.boolean(),
207
- baseUri: zod_1.z.string().default(''),
208
- appId: zod_1.z.string().default(''),
209
- cameraList: zod_1.z.string().array().default([]),
210
- })
211
- .default({
212
- enabled: false,
213
- protocol: 'http',
214
- ip: '',
215
- port: 4590,
216
- user: '',
217
- pass: '',
218
- baseUri: 'WebSdk',
219
- appId: '',
220
- cameraList: [],
221
- }),
222
204
  camstreamerIntegration: zod_1.z
223
205
  .object({
224
206
  adPlacementEnabled: zod_1.z.boolean(),
@@ -1,7 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { blackListSchema, cameraSettingsSchema, flightInfoSchema, getIcaoSchema, mapInfoSchema, priorityListSchema, serverSettingsSchema, trackingModeSchema, typePriorityListSchema, whiteListSchema, wsAliasResponseSchema, zonesSchema, } from './types/PlaneTrackerAPI';
3
3
  import { CannotSetCoordsInAutoModeError, ImportSettingsError, InvalidAltitudeError, InvalidLatLngError, ResetCalibrationError, ServerError, BadRequestError, } from './errors/errors';
4
- import { cameraListSchema } from './types/GenetecAgent';
5
4
  import { BasicAPI } from './internal/BasicAPI';
6
5
  const BASE_PATH = '/local/planetracker';
7
6
  export class PlaneTrackerAPI extends BasicAPI {
@@ -184,12 +183,4 @@ export class PlaneTrackerAPI extends BasicAPI {
184
183
  downloadReport(options) {
185
184
  return this._getText(`${BASE_PATH}/report.cgi`, undefined, options);
186
185
  }
187
- async checkGenetecConnection(params, options) {
188
- const res = await this._postUrlEncoded(`${BASE_PATH}/package/checkGenetecConnection.cgi`, params, options);
189
- return res.status === 200;
190
- }
191
- async getGenetecCameraList(params, options) {
192
- const res = await this._postUrlEncoded(`${BASE_PATH}/package/getGenetecCameraList.cgi`, params, options);
193
- return cameraListSchema.parse(await res.json());
194
- }
195
186
  }
@@ -1,25 +1,57 @@
1
- import { camelCase, snakeCase, isPlainObject, mapKeys, mapValues } from 'lodash-es';
2
- export const toCamelCase = (o) => mapKeys(o, camelCaseKey);
1
+ export const toCamelCase = (o) => mapKeys(o, camelCase);
3
2
  export const toCamelCaseDeep = (o) => {
4
- return mapKeysDeep(o, camelCaseKey);
3
+ return mapKeysDeep(o, camelCase);
5
4
  };
6
- export const toSnakeCase = (o) => mapKeys(o, snakeCaseKey);
5
+ export const toSnakeCase = (o) => mapKeys(o, snakeCase);
7
6
  export const toSnakeCaseDeep = (o) => {
8
- return mapKeysDeep(o, snakeCaseKey);
7
+ return mapKeysDeep(o, snakeCase);
8
+ };
9
+ const splitWords = (input) => {
10
+ if (!input) {
11
+ return [];
12
+ }
13
+ return (input
14
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
15
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
16
+ .replace(/[^a-zA-Z0-9]+/g, ' ')
17
+ .trim()
18
+ .split(/\s+/)
19
+ .map((w) => w.toLowerCase())
20
+ .filter((w) => w.length > 0));
21
+ };
22
+ const camelCase = (key) => {
23
+ const words = splitWords(key);
24
+ if (words.length === 0) {
25
+ return '';
26
+ }
27
+ const [first, ...rest] = words;
28
+ return first + rest.map((w) => w[0].toUpperCase() + w.slice(1)).join('');
29
+ };
30
+ const snakeCase = (key) => splitWords(key).join('_');
31
+ const isPlainObject = (value) => {
32
+ if (value === null || typeof value !== 'object') {
33
+ return false;
34
+ }
35
+ const proto = Object.getPrototypeOf(value);
36
+ return proto === null || proto === Object.prototype;
37
+ };
38
+ const mapKeys = (obj, cb) => {
39
+ const result = {};
40
+ for (const key of Object.keys(obj)) {
41
+ result[cb(key)] = obj[key];
42
+ }
43
+ return result;
9
44
  };
10
- const camelCaseKey = (_, key) => camelCase(key);
11
- const snakeCaseKey = (_, key) => snakeCase(key);
12
45
  const mapKeysDeep = (obj, cb) => {
13
46
  if (Array.isArray(obj)) {
14
- return obj.map((item) => {
15
- return mapKeysDeep(item, cb);
16
- });
47
+ return obj.map((item) => mapKeysDeep(item, cb));
17
48
  }
18
- if (typeof obj !== 'object' || isPlainObject(obj) === false) {
49
+ if (!isPlainObject(obj)) {
19
50
  return obj;
20
51
  }
21
- const result = mapKeys(obj, cb);
22
- return mapValues(result, (value) => {
23
- return mapKeysDeep(value, cb);
24
- });
52
+ const result = {};
53
+ for (const key of Object.keys(obj)) {
54
+ result[cb(key)] = mapKeysDeep(obj[key], cb);
55
+ }
56
+ return result;
25
57
  };
@@ -0,0 +1,94 @@
1
+ import { toCamelCase, toCamelCaseDeep, toSnakeCase, toSnakeCaseDeep } from './transformers';
2
+ import { describe, test, expect } from '@jest/globals';
3
+ describe('transformers', () => {
4
+ describe('toCamelCase', () => {
5
+ test('converts snake_case keys to camelCase', () => {
6
+ expect(toCamelCase({ foo_bar: 1, baz_qux_quux: 2 })).toEqual({ fooBar: 1, bazQuxQuux: 2 });
7
+ });
8
+ test('converts kebab-case keys to camelCase', () => {
9
+ expect(toCamelCase({ 'foo-bar': 1, 'baz-qux': 2 })).toEqual({ fooBar: 1, bazQux: 2 });
10
+ });
11
+ test('preserves already-camelCase keys', () => {
12
+ expect(toCamelCase({ fooBar: 1 })).toEqual({ fooBar: 1 });
13
+ });
14
+ test('converts PascalCase keys to camelCase', () => {
15
+ expect(toCamelCase({ FooBar: 1 })).toEqual({ fooBar: 1 });
16
+ });
17
+ test('handles consecutive uppercase runs (acronyms)', () => {
18
+ expect(toCamelCase({ HTTPServer: 1, parseURL: 2 })).toEqual({ httpServer: 1, parseUrl: 2 });
19
+ });
20
+ test('handles dot.case keys', () => {
21
+ expect(toCamelCase({ 'foo.bar.baz': 1 })).toEqual({ fooBarBaz: 1 });
22
+ });
23
+ test('does not recurse into nested objects', () => {
24
+ const input = { outer_key: { inner_key: 1 } };
25
+ expect(toCamelCase(input)).toEqual({ outerKey: { inner_key: 1 } });
26
+ });
27
+ test('handles empty object', () => {
28
+ expect(toCamelCase({})).toEqual({});
29
+ });
30
+ test('handles keys with numbers', () => {
31
+ expect(toCamelCase({ foo_1_bar: 1, v2_api: 2 })).toEqual({ foo1Bar: 1, v2Api: 2 });
32
+ });
33
+ });
34
+ describe('toCamelCaseDeep', () => {
35
+ test('converts nested object keys recursively', () => {
36
+ const input = { outer_key: { inner_key: { deep_key: 1 } } };
37
+ expect(toCamelCaseDeep(input)).toEqual({ outerKey: { innerKey: { deepKey: 1 } } });
38
+ });
39
+ test('converts keys inside arrays of objects', () => {
40
+ const input = { items_list: [{ item_name: 'a' }, { item_name: 'b' }] };
41
+ expect(toCamelCaseDeep(input)).toEqual({ itemsList: [{ itemName: 'a' }, { itemName: 'b' }] });
42
+ });
43
+ test('leaves primitive array values untouched', () => {
44
+ const input = { values_list: [1, 2, 3] };
45
+ expect(toCamelCaseDeep(input)).toEqual({ valuesList: [1, 2, 3] });
46
+ });
47
+ test('does not recurse into non-plain objects (e.g. Date)', () => {
48
+ const date = new Date(0);
49
+ const input = { created_at: date };
50
+ const result = toCamelCaseDeep(input);
51
+ expect(result.createdAt).toBe(date);
52
+ });
53
+ test('handles null values', () => {
54
+ expect(toCamelCaseDeep({ foo_bar: null })).toEqual({ fooBar: null });
55
+ });
56
+ });
57
+ describe('toSnakeCase', () => {
58
+ test('converts camelCase keys to snake_case', () => {
59
+ expect(toSnakeCase({ fooBar: 1, bazQuxQuux: 2 })).toEqual({ foo_bar: 1, baz_qux_quux: 2 });
60
+ });
61
+ test('converts PascalCase keys to snake_case', () => {
62
+ expect(toSnakeCase({ FooBar: 1 })).toEqual({ foo_bar: 1 });
63
+ });
64
+ test('converts kebab-case keys to snake_case', () => {
65
+ expect(toSnakeCase({ 'foo-bar': 1 })).toEqual({ foo_bar: 1 });
66
+ });
67
+ test('preserves already-snake_case keys', () => {
68
+ expect(toSnakeCase({ foo_bar: 1 })).toEqual({ foo_bar: 1 });
69
+ });
70
+ test('handles acronyms', () => {
71
+ expect(toSnakeCase({ HTTPServer: 1, parseURL: 2 })).toEqual({ http_server: 1, parse_url: 2 });
72
+ });
73
+ test('does not recurse into nested objects', () => {
74
+ const input = { outerKey: { innerKey: 1 } };
75
+ expect(toSnakeCase(input)).toEqual({ outer_key: { innerKey: 1 } });
76
+ });
77
+ });
78
+ describe('toSnakeCaseDeep', () => {
79
+ test('converts nested object keys recursively', () => {
80
+ const input = { outerKey: { innerKey: { deepKey: 1 } } };
81
+ expect(toSnakeCaseDeep(input)).toEqual({ outer_key: { inner_key: { deep_key: 1 } } });
82
+ });
83
+ test('converts keys inside arrays of objects', () => {
84
+ const input = { itemsList: [{ itemName: 'a' }, { itemName: 'b' }] };
85
+ expect(toSnakeCaseDeep(input)).toEqual({ items_list: [{ item_name: 'a' }, { item_name: 'b' }] });
86
+ });
87
+ test('handles null and undefined values', () => {
88
+ expect(toSnakeCaseDeep({ fooBar: null, bazQux: undefined })).toEqual({
89
+ foo_bar: null,
90
+ baz_qux: undefined,
91
+ });
92
+ });
93
+ });
94
+ });
@@ -198,24 +198,6 @@ export const cameraSettingsSchema = z.object({
198
198
  pass: '',
199
199
  sourceKey: '',
200
200
  }),
201
- genetec: connectionSchema
202
- .extend({
203
- enabled: z.boolean(),
204
- baseUri: z.string().default(''),
205
- appId: z.string().default(''),
206
- cameraList: z.string().array().default([]),
207
- })
208
- .default({
209
- enabled: false,
210
- protocol: 'http',
211
- ip: '',
212
- port: 4590,
213
- user: '',
214
- pass: '',
215
- baseUri: 'WebSdk',
216
- appId: '',
217
- cameraList: [],
218
- }),
219
201
  camstreamerIntegration: z
220
202
  .object({
221
203
  adPlacementEnabled: z.boolean(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstreamerlib",
3
- "version": "4.0.2",
3
+ "version": "4.0.4",
4
4
  "description": "Helper library for CamStreamer ACAP applications.",
5
5
  "prettier": "@camstreamer/prettier-config",
6
6
  "engine": {
@@ -10,7 +10,6 @@
10
10
  "adm-zip": "^0.5.9",
11
11
  "eventemitter2": "^5.0.1",
12
12
  "fast-xml-parser": "^5.3.6",
13
- "lodash-es": "^4.18.1",
14
13
  "type-fest": "^4.41.0",
15
14
  "undici": "^6.21.3",
16
15
  "ws": "^8.18.0",
@@ -21,7 +20,6 @@
21
20
  "@camstreamer/prettier-config": "^2.0.4",
22
21
  "@types/adm-zip": "^0.5.5",
23
22
  "@types/jest": "^28.0.0",
24
- "@types/lodash-es": "^4.17.12",
25
23
  "@types/node": "^18.19.127",
26
24
  "@types/ws": "^8.5.10",
27
25
  "@typescript-eslint/eslint-plugin": "^6.8.0",
@@ -1,4 +1,4 @@
1
- import { IClient, TParameters, TResponse } from './internal/types';
1
+ import { IClient, TResponse } from './internal/types';
2
2
  import { ICAO, TApiUser, TBlackList, TCameraSettings, TExportDataType, TGetIcaoByOption, TImportDataType, TPriorityList, TTrackingMode, TTypePriorityList, TWhiteList, TZones } from './types/PlaneTrackerAPI';
3
3
  import { THttpRequestOptions } from './types/common';
4
4
  import { BasicAPI } from './internal/BasicAPI';
@@ -106,17 +106,6 @@ export declare class PlaneTrackerAPI<Client extends IClient<TResponse, any>> ext
106
106
  protocol: "https" | "http" | "https_insecure";
107
107
  sourceKey: string;
108
108
  };
109
- genetec: {
110
- ip: string;
111
- enabled: boolean;
112
- port: number;
113
- cameraList: string[];
114
- pass: string;
115
- appId: string;
116
- user: string;
117
- protocol: "https" | "http" | "https_insecure";
118
- baseUri: string;
119
- };
120
109
  camstreamerIntegration: {
121
110
  adPlacementEnabled: boolean;
122
111
  adMinIntervalSec: number;
@@ -232,10 +221,4 @@ export declare class PlaneTrackerAPI<Client extends IClient<TResponse, any>> ext
232
221
  setZones(zones: TZones, options?: THttpRequestOptions): Promise<void>;
233
222
  goToCoordinates(lat: number, lon: number, alt?: number, options?: THttpRequestOptions): Promise<void>;
234
223
  downloadReport(options?: THttpRequestOptions): Promise<string>;
235
- checkGenetecConnection(params: TParameters, options?: THttpRequestOptions): Promise<boolean>;
236
- getGenetecCameraList(params: TParameters, options?: THttpRequestOptions): Promise<{
237
- value: string;
238
- label: string;
239
- index: number;
240
- }[]>;
241
224
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -360,38 +360,6 @@ export declare const cameraSettingsSchema: z.ZodObject<{
360
360
  protocol: "https" | "http" | "https_insecure";
361
361
  sourceKey: string;
362
362
  }>>;
363
- genetec: z.ZodDefault<z.ZodObject<{
364
- protocol: z.ZodUnion<[z.ZodLiteral<"http">, z.ZodLiteral<"https">, z.ZodLiteral<"https_insecure">]>;
365
- ip: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
366
- port: z.ZodNumber;
367
- user: z.ZodString;
368
- pass: z.ZodString;
369
- } & {
370
- enabled: z.ZodBoolean;
371
- baseUri: z.ZodDefault<z.ZodString>;
372
- appId: z.ZodDefault<z.ZodString>;
373
- cameraList: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
374
- }, "strip", z.ZodTypeAny, {
375
- ip: string;
376
- enabled: boolean;
377
- port: number;
378
- cameraList: string[];
379
- pass: string;
380
- appId: string;
381
- user: string;
382
- protocol: "https" | "http" | "https_insecure";
383
- baseUri: string;
384
- }, {
385
- ip: string;
386
- enabled: boolean;
387
- port: number;
388
- pass: string;
389
- user: string;
390
- protocol: "https" | "http" | "https_insecure";
391
- cameraList?: string[] | undefined;
392
- appId?: string | undefined;
393
- baseUri?: string | undefined;
394
- }>>;
395
363
  camstreamerIntegration: z.ZodDefault<z.ZodObject<{
396
364
  adPlacementEnabled: z.ZodBoolean;
397
365
  adMinIntervalSec: z.ZodNumber;
@@ -497,17 +465,6 @@ export declare const cameraSettingsSchema: z.ZodObject<{
497
465
  protocol: "https" | "http" | "https_insecure";
498
466
  sourceKey: string;
499
467
  };
500
- genetec: {
501
- ip: string;
502
- enabled: boolean;
503
- port: number;
504
- cameraList: string[];
505
- pass: string;
506
- appId: string;
507
- user: string;
508
- protocol: "https" | "http" | "https_insecure";
509
- baseUri: string;
510
- };
511
468
  camstreamerIntegration: {
512
469
  adPlacementEnabled: boolean;
513
470
  adMinIntervalSec: number;
@@ -649,17 +606,6 @@ export declare const cameraSettingsSchema: z.ZodObject<{
649
606
  protocol: "https" | "http" | "https_insecure";
650
607
  sourceKey: string;
651
608
  } | undefined;
652
- genetec?: {
653
- ip: string;
654
- enabled: boolean;
655
- port: number;
656
- pass: string;
657
- user: string;
658
- protocol: "https" | "http" | "https_insecure";
659
- cameraList?: string[] | undefined;
660
- appId?: string | undefined;
661
- baseUri?: string | undefined;
662
- } | undefined;
663
609
  camstreamerIntegration?: {
664
610
  adPlacementEnabled: boolean;
665
611
  adMinIntervalSec: number;