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.
- package/cjs/PlaneTrackerAPI.d.ts +1 -18
- package/cjs/PlaneTrackerAPI.js +0 -9
- package/cjs/internal/transformers.js +47 -15
- package/cjs/internal/transformers.test.d.ts +1 -0
- package/cjs/internal/transformers.test.js +96 -0
- package/cjs/types/PlaneTrackerAPI.d.ts +0 -54
- package/cjs/types/PlaneTrackerAPI.js +0 -18
- package/esm/PlaneTrackerAPI.js +0 -9
- package/esm/internal/transformers.js +47 -15
- package/esm/internal/transformers.test.js +94 -0
- package/esm/types/PlaneTrackerAPI.js +0 -18
- package/package.json +1 -3
- package/types/PlaneTrackerAPI.d.ts +1 -18
- package/types/internal/transformers.test.d.ts +1 -0
- package/types/types/PlaneTrackerAPI.d.ts +0 -54
package/cjs/PlaneTrackerAPI.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IClient,
|
|
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
|
}
|
package/cjs/PlaneTrackerAPI.js
CHANGED
|
@@ -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
|
|
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,
|
|
7
|
+
return mapKeysDeep(o, camelCase);
|
|
9
8
|
};
|
|
10
9
|
exports.toCamelCaseDeep = toCamelCaseDeep;
|
|
11
|
-
const toSnakeCase = (o) =>
|
|
10
|
+
const toSnakeCase = (o) => mapKeys(o, snakeCase);
|
|
12
11
|
exports.toSnakeCase = toSnakeCase;
|
|
13
12
|
const toSnakeCaseDeep = (o) => {
|
|
14
|
-
return mapKeysDeep(o,
|
|
13
|
+
return mapKeysDeep(o, snakeCase);
|
|
15
14
|
};
|
|
16
15
|
exports.toSnakeCaseDeep = toSnakeCaseDeep;
|
|
17
|
-
const
|
|
18
|
-
|
|
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 (
|
|
56
|
+
if (!isPlainObject(obj)) {
|
|
26
57
|
return obj;
|
|
27
58
|
}
|
|
28
|
-
const result =
|
|
29
|
-
|
|
30
|
-
|
|
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(),
|
package/esm/PlaneTrackerAPI.js
CHANGED
|
@@ -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
|
-
|
|
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,
|
|
3
|
+
return mapKeysDeep(o, camelCase);
|
|
5
4
|
};
|
|
6
|
-
export const toSnakeCase = (o) => mapKeys(o,
|
|
5
|
+
export const toSnakeCase = (o) => mapKeys(o, snakeCase);
|
|
7
6
|
export const toSnakeCaseDeep = (o) => {
|
|
8
|
-
return mapKeysDeep(o,
|
|
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 (
|
|
49
|
+
if (!isPlainObject(obj)) {
|
|
19
50
|
return obj;
|
|
20
51
|
}
|
|
21
|
-
const result =
|
|
22
|
-
|
|
23
|
-
|
|
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.
|
|
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,
|
|
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;
|