camstreamerlib 4.0.0-beta.2 → 4.0.0-beta.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/CamOverlayAPI.js +176 -0
- package/cjs/CamOverlayDrawingAPI.js +235 -0
- package/cjs/CamOverlayPainter/Frame.js +301 -0
- package/{CamOverlayPainter → cjs/CamOverlayPainter}/Painter.d.ts +14 -3
- package/cjs/CamOverlayPainter/Painter.js +171 -0
- package/cjs/CamOverlayPainter/ResourceManager.js +46 -0
- package/cjs/CamScripterAPI.js +70 -0
- package/cjs/CamScripterAPICameraEventsGenerator.js +162 -0
- package/cjs/CamStreamerAPI.js +65 -0
- package/{CamSwitcherAPI.d.ts → cjs/CamSwitcherAPI.d.ts} +3 -3
- package/cjs/CamSwitcherAPI.js +350 -0
- package/{CamSwitcherEvents.d.ts → cjs/CamSwitcherEvents.d.ts} +1 -1
- package/cjs/CamSwitcherEvents.js +67 -0
- package/cjs/CreatePackage.js +106 -0
- package/{VapixAPI.d.ts → cjs/VapixAPI.d.ts} +9 -9
- package/cjs/VapixAPI.js +462 -0
- package/cjs/VapixEvents.js +88 -0
- package/cjs/errors/errors.js +79 -0
- package/cjs/events/AxisCameraStationEvents.js +48 -0
- package/cjs/events/GenetecAgent.js +123 -0
- package/cjs/index.d.ts +11 -0
- package/cjs/index.js +31 -0
- package/cjs/internal/Digest.js +42 -0
- package/cjs/internal/ProxyClient.js +44 -0
- package/{internal → cjs/internal}/common.d.ts +0 -1
- package/cjs/internal/common.js +27 -0
- package/cjs/internal/constants.js +4 -0
- package/cjs/internal/transformers.js +32 -0
- package/cjs/internal/utils.js +46 -0
- package/cjs/internal/versionCompare.js +53 -0
- package/cjs/node/DefaultClient.js +54 -0
- package/cjs/node/HttpRequestSender.js +89 -0
- package/cjs/node/HttpServer.js +96 -0
- package/cjs/node/WsClient.js +149 -0
- package/cjs/node/WsEventClient.js +22 -0
- package/cjs/node/index.d.ts +2 -0
- package/cjs/node/index.js +7 -0
- package/cjs/types/CamOverlayAPI.js +47 -0
- package/cjs/types/CamScripterAPI.js +20 -0
- package/cjs/types/CamStreamerAPI.js +28 -0
- package/cjs/types/CamSwitcherAPI.js +137 -0
- package/cjs/types/CamSwitcherEvents.js +62 -0
- package/{types → cjs/types}/VapixAPI.d.ts +40 -61
- package/cjs/types/VapixAPI.js +130 -0
- package/cjs/types/common.js +14 -0
- package/cjs/web/DefaultClient.js +20 -0
- package/cjs/web/WsClient.js +62 -0
- package/cjs/web/index.d.ts +2 -0
- package/cjs/web/index.js +7 -0
- package/esm/CamOverlayAPI.d.ts +31 -0
- package/esm/CamOverlayDrawingAPI.d.ts +86 -0
- package/{CamOverlayDrawingAPI.js → esm/CamOverlayDrawingAPI.js} +6 -3
- package/esm/CamOverlayPainter/Frame.d.ts +96 -0
- package/esm/CamOverlayPainter/Painter.d.ts +48 -0
- package/{CamOverlayPainter → esm/CamOverlayPainter}/Painter.js +4 -1
- package/esm/CamOverlayPainter/ResourceManager.d.ts +14 -0
- package/{CamOverlayPainter → esm/CamOverlayPainter}/ResourceManager.js +6 -10
- package/esm/CamScripterAPI.d.ts +19 -0
- package/esm/CamScripterAPICameraEventsGenerator.d.ts +74 -0
- package/{CamScripterAPICameraEventsGenerator.js → esm/CamScripterAPICameraEventsGenerator.js} +6 -3
- package/esm/CamStreamerAPI.d.ts +16 -0
- package/esm/CamSwitcherAPI.d.ts +48 -0
- package/{CamSwitcherAPI.js → esm/CamSwitcherAPI.js} +19 -23
- package/esm/CamSwitcherEvents.d.ts +18 -0
- package/{CamSwitcherEvents.js → esm/CamSwitcherEvents.js} +1 -1
- package/esm/CreatePackage.d.ts +1 -0
- package/esm/VapixAPI.d.ts +66 -0
- package/{VapixAPI.js → esm/VapixAPI.js} +20 -16
- package/esm/VapixEvents.d.ts +43 -0
- package/{VapixEvents.js → esm/VapixEvents.js} +3 -3
- package/esm/errors/errors.d.ts +34 -0
- package/esm/events/AxisCameraStationEvents.d.ts +9 -0
- package/esm/events/GenetecAgent.d.ts +174 -0
- package/esm/index.d.ts +11 -0
- package/esm/index.js +11 -0
- package/esm/internal/Digest.d.ts +4 -0
- package/{internal → esm/internal}/Digest.js +6 -6
- package/esm/internal/ProxyClient.d.ts +11 -0
- package/esm/internal/common.d.ts +39 -0
- package/{internal → esm/internal}/common.js +0 -3
- package/esm/internal/constants.d.ts +1 -0
- package/esm/internal/transformers.d.ts +5 -0
- package/esm/internal/utils.d.ts +11 -0
- package/esm/internal/versionCompare.d.ts +6 -0
- package/esm/node/DefaultClient.d.ts +15 -0
- package/{node → esm/node}/DefaultClient.js +1 -1
- package/esm/node/HttpRequestSender.d.ts +28 -0
- package/esm/node/HttpServer.d.ts +21 -0
- package/{node → esm/node}/HttpServer.js +1 -1
- package/esm/node/WsClient.d.ts +39 -0
- package/esm/node/WsEventClient.d.ts +13 -0
- package/esm/node/index.d.ts +2 -0
- package/esm/node/index.js +2 -0
- package/esm/types/CamOverlayAPI.d.ts +188 -0
- package/esm/types/CamScripterAPI.d.ts +67 -0
- package/esm/types/CamStreamerAPI.d.ts +139 -0
- package/esm/types/CamSwitcherAPI.d.ts +814 -0
- package/esm/types/CamSwitcherEvents.d.ts +491 -0
- package/esm/types/VapixAPI.d.ts +1683 -0
- package/{types → esm/types}/VapixAPI.js +10 -12
- package/esm/types/common.d.ts +37 -0
- package/esm/web/DefaultClient.d.ts +6 -0
- package/esm/web/WsClient.d.ts +13 -0
- package/esm/web/index.d.ts +2 -0
- package/esm/web/index.js +2 -0
- package/package.json +6 -5
- package/README.md +0 -97
- /package/{CamOverlayAPI.d.ts → cjs/CamOverlayAPI.d.ts} +0 -0
- /package/{CamOverlayDrawingAPI.d.ts → cjs/CamOverlayDrawingAPI.d.ts} +0 -0
- /package/{CamOverlayPainter → cjs/CamOverlayPainter}/Frame.d.ts +0 -0
- /package/{CamOverlayPainter → cjs/CamOverlayPainter}/ResourceManager.d.ts +0 -0
- /package/{CamScripterAPI.d.ts → cjs/CamScripterAPI.d.ts} +0 -0
- /package/{CamScripterAPICameraEventsGenerator.d.ts → cjs/CamScripterAPICameraEventsGenerator.d.ts} +0 -0
- /package/{CamStreamerAPI.d.ts → cjs/CamStreamerAPI.d.ts} +0 -0
- /package/{CreatePackage.d.ts → cjs/CreatePackage.d.ts} +0 -0
- /package/{VapixEvents.d.ts → cjs/VapixEvents.d.ts} +0 -0
- /package/{errors → cjs/errors}/errors.d.ts +0 -0
- /package/{events → cjs/events}/AxisCameraStationEvents.d.ts +0 -0
- /package/{events → cjs/events}/GenetecAgent.d.ts +0 -0
- /package/{internal → cjs/internal}/Digest.d.ts +0 -0
- /package/{internal → cjs/internal}/ProxyClient.d.ts +0 -0
- /package/{internal → cjs/internal}/constants.d.ts +0 -0
- /package/{internal → cjs/internal}/transformers.d.ts +0 -0
- /package/{internal → cjs/internal}/utils.d.ts +0 -0
- /package/{internal → cjs/internal}/versionCompare.d.ts +0 -0
- /package/{node → cjs/node}/DefaultClient.d.ts +0 -0
- /package/{node → cjs/node}/HttpRequestSender.d.ts +0 -0
- /package/{node → cjs/node}/HttpServer.d.ts +0 -0
- /package/{node → cjs/node}/WsClient.d.ts +0 -0
- /package/{node → cjs/node}/WsEventClient.d.ts +0 -0
- /package/{types → cjs/types}/CamOverlayAPI.d.ts +0 -0
- /package/{types → cjs/types}/CamScripterAPI.d.ts +0 -0
- /package/{types → cjs/types}/CamStreamerAPI.d.ts +0 -0
- /package/{types → cjs/types}/CamSwitcherAPI.d.ts +0 -0
- /package/{types/CamswitcherEvents.d.ts → cjs/types/CamSwitcherEvents.d.ts} +0 -0
- /package/{types → cjs/types}/common.d.ts +0 -0
- /package/{web → cjs/web}/DefaultClient.d.ts +0 -0
- /package/{web → cjs/web}/WsClient.d.ts +0 -0
- /package/{CamOverlayAPI.js → esm/CamOverlayAPI.js} +0 -0
- /package/{CamOverlayPainter → esm/CamOverlayPainter}/Frame.js +0 -0
- /package/{CamScripterAPI.js → esm/CamScripterAPI.js} +0 -0
- /package/{CamStreamerAPI.js → esm/CamStreamerAPI.js} +0 -0
- /package/{CreatePackage.js → esm/CreatePackage.js} +0 -0
- /package/{errors → esm/errors}/errors.js +0 -0
- /package/{events → esm/events}/AxisCameraStationEvents.js +0 -0
- /package/{events → esm/events}/GenetecAgent.js +0 -0
- /package/{internal → esm/internal}/ProxyClient.js +0 -0
- /package/{internal → esm/internal}/constants.js +0 -0
- /package/{internal → esm/internal}/transformers.js +0 -0
- /package/{internal → esm/internal}/utils.js +0 -0
- /package/{internal → esm/internal}/versionCompare.js +0 -0
- /package/{node → esm/node}/HttpRequestSender.js +0 -0
- /package/{node → esm/node}/WsClient.js +0 -0
- /package/{node → esm/node}/WsEventClient.js +0 -0
- /package/{types → esm/types}/CamOverlayAPI.js +0 -0
- /package/{types → esm/types}/CamScripterAPI.js +0 -0
- /package/{types → esm/types}/CamStreamerAPI.js +0 -0
- /package/{types → esm/types}/CamSwitcherAPI.js +0 -0
- /package/{types/CamswitcherEvents.js → esm/types/CamSwitcherEvents.js} +0 -0
- /package/{types → esm/types}/common.js +0 -0
- /package/{web → esm/web}/DefaultClient.js +0 -0
- /package/{web → esm/web}/WsClient.js +0 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VapixEvents = void 0;
|
|
4
|
+
const eventemitter2_1 = require("eventemitter2");
|
|
5
|
+
const WsClient_1 = require("./node/WsClient");
|
|
6
|
+
class VapixEvents extends eventemitter2_1.EventEmitter2 {
|
|
7
|
+
tls;
|
|
8
|
+
tlsInsecure;
|
|
9
|
+
ip;
|
|
10
|
+
port;
|
|
11
|
+
user;
|
|
12
|
+
pass;
|
|
13
|
+
ws;
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
super();
|
|
16
|
+
this.tls = options.tls ?? false;
|
|
17
|
+
this.tlsInsecure = options.tlsInsecure ?? false;
|
|
18
|
+
this.ip = options.ip ?? '127.0.0.1';
|
|
19
|
+
this.port = options.port ?? (this.tls ? 443 : 80);
|
|
20
|
+
this.user = options.user ?? 'root';
|
|
21
|
+
this.pass = options.pass ?? '';
|
|
22
|
+
this.createWsClient();
|
|
23
|
+
eventemitter2_1.EventEmitter2.call(this);
|
|
24
|
+
}
|
|
25
|
+
connect() {
|
|
26
|
+
this.ws.open();
|
|
27
|
+
}
|
|
28
|
+
disconnect() {
|
|
29
|
+
this.ws.close();
|
|
30
|
+
}
|
|
31
|
+
createWsClient() {
|
|
32
|
+
const options = {
|
|
33
|
+
tls: this.tls,
|
|
34
|
+
tlsInsecure: this.tlsInsecure,
|
|
35
|
+
user: this.user,
|
|
36
|
+
pass: this.pass,
|
|
37
|
+
ip: this.ip,
|
|
38
|
+
port: this.port,
|
|
39
|
+
address: '/vapix/ws-data-stream?sources=events',
|
|
40
|
+
};
|
|
41
|
+
this.ws = new WsClient_1.WsClient(options);
|
|
42
|
+
this.ws.on('open', () => {
|
|
43
|
+
const topics = [];
|
|
44
|
+
const eventNames = this.eventNames();
|
|
45
|
+
for (const eventName of eventNames) {
|
|
46
|
+
if (!this.isReservedEventName(eventName)) {
|
|
47
|
+
const topic = {
|
|
48
|
+
topicFilter: eventName,
|
|
49
|
+
};
|
|
50
|
+
topics.push(topic);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const topicFilter = {
|
|
54
|
+
apiVersion: '1.0',
|
|
55
|
+
method: 'events:configure',
|
|
56
|
+
params: {
|
|
57
|
+
eventFilterList: topics,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
this.ws.send(JSON.stringify(topicFilter));
|
|
61
|
+
});
|
|
62
|
+
this.ws.on('message', (data) => {
|
|
63
|
+
const dataJSON = JSON.parse(data.toString());
|
|
64
|
+
if (dataJSON.method === 'events:configure') {
|
|
65
|
+
if (dataJSON.error === undefined) {
|
|
66
|
+
this.emit('open');
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
this.emit('error', dataJSON.error);
|
|
70
|
+
this.disconnect();
|
|
71
|
+
}
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const eventName = dataJSON.params.notification.topic;
|
|
75
|
+
this.emit(eventName, dataJSON);
|
|
76
|
+
});
|
|
77
|
+
this.ws.on('error', (error) => {
|
|
78
|
+
this.emit('error', error);
|
|
79
|
+
});
|
|
80
|
+
this.ws.on('close', () => {
|
|
81
|
+
this.emit('close');
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
isReservedEventName(eventName) {
|
|
85
|
+
return eventName === 'open' || eventName === 'close' || eventName === 'error';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.VapixEvents = VapixEvents;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AddNewClipError = exports.FetchDeviceInfoError = exports.NoDeviceInfoError = exports.MaxFPSError = exports.SDCardJobError = exports.SDCardActionError = exports.ApplicationAPIError = exports.ParsingBlobError = exports.ServiceNotFoundError = exports.ServiceUnavailableError = void 0;
|
|
4
|
+
class ServiceUnavailableError extends Error {
|
|
5
|
+
constructor() {
|
|
6
|
+
super('Service is unavailable.');
|
|
7
|
+
this.name = 'ServiceUnavailableError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.ServiceUnavailableError = ServiceUnavailableError;
|
|
11
|
+
class ServiceNotFoundError extends Error {
|
|
12
|
+
constructor() {
|
|
13
|
+
super('Service not found.');
|
|
14
|
+
this.name = 'ServiceNotFoundError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.ServiceNotFoundError = ServiceNotFoundError;
|
|
18
|
+
class ParsingBlobError extends Error {
|
|
19
|
+
constructor(err) {
|
|
20
|
+
super('Error parsing response as Blob: ' + err);
|
|
21
|
+
this.name = 'ParsingBlobError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.ParsingBlobError = ParsingBlobError;
|
|
25
|
+
class ApplicationAPIError extends Error {
|
|
26
|
+
constructor(action, res) {
|
|
27
|
+
super(`[APP ${action}] Error: ` + res);
|
|
28
|
+
this.name = 'ApplicationAPIError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.ApplicationAPIError = ApplicationAPIError;
|
|
32
|
+
class SDCardActionError extends Error {
|
|
33
|
+
constructor(action, res) {
|
|
34
|
+
super(`[SD_CARD ${action}] Error: ` + res);
|
|
35
|
+
this.name = 'SDCardActionError';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.SDCardActionError = SDCardActionError;
|
|
39
|
+
class SDCardJobError extends Error {
|
|
40
|
+
constructor() {
|
|
41
|
+
super('Error while fetching SD card job progress');
|
|
42
|
+
this.name = 'SDCardJobError';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.SDCardJobError = SDCardJobError;
|
|
46
|
+
const MAX_FPS_ERROR_MESSAGES = {
|
|
47
|
+
MALFORMED_REPLY: 'Malformed reply from camera',
|
|
48
|
+
CHANNEL_NOT_FOUND: 'Video channel not found.',
|
|
49
|
+
CAPTURE_MODE_NOT_FOUND: 'No enabled capture mode found.',
|
|
50
|
+
FPS_NOT_SPECIFIED: 'Max fps not specified for given capture mode.',
|
|
51
|
+
};
|
|
52
|
+
class MaxFPSError extends Error {
|
|
53
|
+
constructor(state) {
|
|
54
|
+
super(`[MAX_FPS ${state}] Error: ` + MAX_FPS_ERROR_MESSAGES[state]);
|
|
55
|
+
this.name = 'MaxFPSError';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.MaxFPSError = MaxFPSError;
|
|
59
|
+
class NoDeviceInfoError extends Error {
|
|
60
|
+
constructor() {
|
|
61
|
+
super('Did not get any data from remote camera');
|
|
62
|
+
this.name = 'NoDeviceInfoError';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.NoDeviceInfoError = NoDeviceInfoError;
|
|
66
|
+
class FetchDeviceInfoError extends Error {
|
|
67
|
+
constructor(err) {
|
|
68
|
+
super('Error fetching remote camera data: ' + err);
|
|
69
|
+
this.name = 'NoDeviceInfoFromCameraError';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.FetchDeviceInfoError = FetchDeviceInfoError;
|
|
73
|
+
class AddNewClipError extends Error {
|
|
74
|
+
constructor(message) {
|
|
75
|
+
super('Error adding new clip: ' + message);
|
|
76
|
+
this.name = 'AddNewClipError';
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.AddNewClipError = AddNewClipError;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AxisCameraStationEvents = void 0;
|
|
4
|
+
const DefaultClient_1 = require("../node/DefaultClient");
|
|
5
|
+
const common_1 = require("../internal/common");
|
|
6
|
+
class AxisCameraStationEvents {
|
|
7
|
+
sourceKey;
|
|
8
|
+
client;
|
|
9
|
+
constructor(sourceKey, opt = {}) {
|
|
10
|
+
this.sourceKey = sourceKey;
|
|
11
|
+
if ((0, common_1.isClient)(opt)) {
|
|
12
|
+
this.client = opt;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
this.client = new DefaultClient_1.DefaultClient(opt);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async sendEvent(data, eventType) {
|
|
19
|
+
const dateString = this.getDate();
|
|
20
|
+
const event = {
|
|
21
|
+
addExternalDataRequest: {
|
|
22
|
+
occurrenceTime: dateString,
|
|
23
|
+
source: this.sourceKey,
|
|
24
|
+
externalDataType: eventType,
|
|
25
|
+
data: data,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
const eventData = JSON.stringify(event);
|
|
29
|
+
const res = await this.client.post('/Acs/Api/ExternalDataFacade/AddExternalData', eventData, undefined, {
|
|
30
|
+
'Content-Type': 'application/json',
|
|
31
|
+
'Content-Length': eventData.length.toString(),
|
|
32
|
+
});
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
throw new Error(`ACS status code: ${res.status}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
getDate() {
|
|
38
|
+
const date = new Date();
|
|
39
|
+
const year = date.getUTCFullYear();
|
|
40
|
+
const month = (0, common_1.pad)(date.getUTCMonth() + 1, 2);
|
|
41
|
+
const day = (0, common_1.pad)(date.getUTCDate(), 2);
|
|
42
|
+
const hours = (0, common_1.pad)(date.getUTCHours(), 2);
|
|
43
|
+
const minutes = (0, common_1.pad)(date.getUTCMinutes(), 2);
|
|
44
|
+
const seconds = (0, common_1.pad)(date.getUTCSeconds(), 2);
|
|
45
|
+
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.AxisCameraStationEvents = AxisCameraStationEvents;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GenetecAgent = exports.cameraDetailsResponseSchema = exports.cameraDetailSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const common_1 = require("../internal/common");
|
|
6
|
+
const ACTION = 'AddCameraBookmark';
|
|
7
|
+
const GET_CAMERAS_URL = 'report/EntityConfiguration?q=EntityTypes@Camera';
|
|
8
|
+
const GET_CAMERAS_DETAILS_URL = '/entity?q=';
|
|
9
|
+
const cameraGuidsResponseSchema = zod_1.z.object({
|
|
10
|
+
Rsp: zod_1.z.object({
|
|
11
|
+
Status: zod_1.z.string(),
|
|
12
|
+
Result: zod_1.z.array(zod_1.z.object({ Guid: zod_1.z.string() })),
|
|
13
|
+
}),
|
|
14
|
+
});
|
|
15
|
+
const connectionResponseSchema = zod_1.z.object({
|
|
16
|
+
Rsp: zod_1.z.object({
|
|
17
|
+
Status: zod_1.z.string(),
|
|
18
|
+
}),
|
|
19
|
+
});
|
|
20
|
+
exports.cameraDetailSchema = zod_1.z.object({
|
|
21
|
+
Guid: zod_1.z.string().optional(),
|
|
22
|
+
Name: zod_1.z.string().optional(),
|
|
23
|
+
EntityType: zod_1.z.string().optional(),
|
|
24
|
+
});
|
|
25
|
+
exports.cameraDetailsResponseSchema = zod_1.z.object({
|
|
26
|
+
Rsp: zod_1.z.object({
|
|
27
|
+
Status: zod_1.z.string(),
|
|
28
|
+
Result: zod_1.z.union([zod_1.z.array(exports.cameraDetailSchema), exports.cameraDetailSchema]),
|
|
29
|
+
}),
|
|
30
|
+
});
|
|
31
|
+
class GenetecAgent {
|
|
32
|
+
settings;
|
|
33
|
+
baseUrl;
|
|
34
|
+
credentials;
|
|
35
|
+
constructor(options = {}) {
|
|
36
|
+
this.settings = {
|
|
37
|
+
protocol: options.protocol ?? 'http',
|
|
38
|
+
ip: options.ip ?? '127.0.0.1',
|
|
39
|
+
port: options.port ?? 80,
|
|
40
|
+
base_uri: options.base_uri ?? 'WebSdk',
|
|
41
|
+
user: options.user ?? 'root',
|
|
42
|
+
pass: options.pass ?? '',
|
|
43
|
+
app_id: options.app_id ?? '',
|
|
44
|
+
};
|
|
45
|
+
this.baseUrl = `${this.settings.protocol}://${this.settings.ip}:${this.settings.port}/${this.settings.base_uri}`;
|
|
46
|
+
this.credentials = btoa(`${this.settings.user};${this.settings.app_id}:${this.settings.pass}`);
|
|
47
|
+
}
|
|
48
|
+
async checkConnection() {
|
|
49
|
+
const requestOptions = this.getRequestOptions('GET');
|
|
50
|
+
const res = await fetch(`${this.baseUrl}/`, requestOptions);
|
|
51
|
+
if (!res.ok) {
|
|
52
|
+
throw new Error(await (0, common_1.responseStringify)(res));
|
|
53
|
+
}
|
|
54
|
+
return connectionResponseSchema.parse(await res.json());
|
|
55
|
+
}
|
|
56
|
+
async getAllCameraGuids() {
|
|
57
|
+
const requestOptions = this.getRequestOptions('GET');
|
|
58
|
+
const res = await fetch(`${this.baseUrl}/${GET_CAMERAS_URL}`, requestOptions);
|
|
59
|
+
if (!res.ok) {
|
|
60
|
+
throw new Error(await (0, common_1.responseStringify)(res));
|
|
61
|
+
}
|
|
62
|
+
return cameraGuidsResponseSchema.parse(await res.json());
|
|
63
|
+
}
|
|
64
|
+
async getCameraDetails(guids, parameters) {
|
|
65
|
+
const params = parameters.join(',');
|
|
66
|
+
let camerasGuids = [];
|
|
67
|
+
const requestOptions = this.getRequestOptions('GET');
|
|
68
|
+
const allCameras = [];
|
|
69
|
+
const chunkSize = 10;
|
|
70
|
+
while (guids.length > 0) {
|
|
71
|
+
const chunk = guids.slice(0, chunkSize);
|
|
72
|
+
guids.splice(0, chunkSize);
|
|
73
|
+
camerasGuids = chunk.map((item) => item.Guid);
|
|
74
|
+
const camerasDetailsUrl = [];
|
|
75
|
+
for (const guid of camerasGuids) {
|
|
76
|
+
camerasDetailsUrl.push(`entity=${guid},${params}`);
|
|
77
|
+
}
|
|
78
|
+
const res = await fetch(`${this.baseUrl}/${GET_CAMERAS_DETAILS_URL}${camerasDetailsUrl.join(',')}`, requestOptions);
|
|
79
|
+
if (!res.ok) {
|
|
80
|
+
throw new Error(await (0, common_1.responseStringify)(res));
|
|
81
|
+
}
|
|
82
|
+
const data = exports.cameraDetailsResponseSchema.parse(await res.json());
|
|
83
|
+
const resultArray = Array.isArray(data.Rsp.Result) ? data.Rsp.Result : [data.Rsp.Result];
|
|
84
|
+
allCameras.push(...resultArray);
|
|
85
|
+
}
|
|
86
|
+
return allCameras;
|
|
87
|
+
}
|
|
88
|
+
async sendBookmark(guids, bookmarkText) {
|
|
89
|
+
const cameraEntitiesUrl = [];
|
|
90
|
+
const timeStamp = this.getTimeStamp();
|
|
91
|
+
const requestOptions = this.getRequestOptions('POST');
|
|
92
|
+
for (const guid of guids) {
|
|
93
|
+
cameraEntitiesUrl.push(`${ACTION}(${guid},${timeStamp},${bookmarkText})`);
|
|
94
|
+
}
|
|
95
|
+
const res = await fetch(`${this.baseUrl}/action?q=${cameraEntitiesUrl.join(',')}`, requestOptions);
|
|
96
|
+
if (!res.ok) {
|
|
97
|
+
throw new Error(await (0, common_1.responseStringify)(res));
|
|
98
|
+
}
|
|
99
|
+
return res;
|
|
100
|
+
}
|
|
101
|
+
getRequestOptions(method) {
|
|
102
|
+
return {
|
|
103
|
+
method,
|
|
104
|
+
headers: new Headers({
|
|
105
|
+
Authorization: `Basic ${this.credentials}`,
|
|
106
|
+
Accept: 'text/json',
|
|
107
|
+
}),
|
|
108
|
+
redirect: 'follow',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
getTimeStamp() {
|
|
112
|
+
const date = new Date();
|
|
113
|
+
const year = date.getUTCFullYear();
|
|
114
|
+
const month = (0, common_1.pad)(date.getUTCMonth() + 1, 2);
|
|
115
|
+
const day = (0, common_1.pad)(date.getUTCDate(), 2);
|
|
116
|
+
const hours = (0, common_1.pad)(date.getUTCHours(), 2);
|
|
117
|
+
const minutes = (0, common_1.pad)(date.getUTCMinutes(), 2);
|
|
118
|
+
const seconds = (0, common_1.pad)(date.getUTCSeconds(), 2);
|
|
119
|
+
const miliSeconds = (0, common_1.pad)(date.getUTCMilliseconds(), 2);
|
|
120
|
+
return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${miliSeconds}Z`;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.GenetecAgent = GenetecAgent;
|
package/cjs/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './internal/common';
|
|
2
|
+
export * from './internal/constants';
|
|
3
|
+
export * from './internal/utils';
|
|
4
|
+
export * from './internal/versionCompare';
|
|
5
|
+
export * from './types/common';
|
|
6
|
+
export { CamSwitcherAPI } from './CamSwitcherAPI';
|
|
7
|
+
export { CamSwitcherEvents } from './CamSwitcherEvents';
|
|
8
|
+
export { VapixAPI } from './VapixAPI';
|
|
9
|
+
export * from './types/CamSwitcherEvents';
|
|
10
|
+
export * from './types/CamSwitcherAPI';
|
|
11
|
+
export * from './types/VapixAPI';
|
package/cjs/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
exports.VapixAPI = exports.CamSwitcherEvents = exports.CamSwitcherAPI = void 0;
|
|
18
|
+
__exportStar(require("./internal/common"), exports);
|
|
19
|
+
__exportStar(require("./internal/constants"), exports);
|
|
20
|
+
__exportStar(require("./internal/utils"), exports);
|
|
21
|
+
__exportStar(require("./internal/versionCompare"), exports);
|
|
22
|
+
__exportStar(require("./types/common"), exports);
|
|
23
|
+
var CamSwitcherAPI_1 = require("./CamSwitcherAPI");
|
|
24
|
+
Object.defineProperty(exports, "CamSwitcherAPI", { enumerable: true, get: function () { return CamSwitcherAPI_1.CamSwitcherAPI; } });
|
|
25
|
+
var CamSwitcherEvents_1 = require("./CamSwitcherEvents");
|
|
26
|
+
Object.defineProperty(exports, "CamSwitcherEvents", { enumerable: true, get: function () { return CamSwitcherEvents_1.CamSwitcherEvents; } });
|
|
27
|
+
var VapixAPI_1 = require("./VapixAPI");
|
|
28
|
+
Object.defineProperty(exports, "VapixAPI", { enumerable: true, get: function () { return VapixAPI_1.VapixAPI; } });
|
|
29
|
+
__exportStar(require("./types/CamSwitcherEvents"), exports);
|
|
30
|
+
__exportStar(require("./types/CamSwitcherAPI"), exports);
|
|
31
|
+
__exportStar(require("./types/VapixAPI"), exports);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Digest = void 0;
|
|
4
|
+
const crypto = require("crypto");
|
|
5
|
+
class Digest {
|
|
6
|
+
nonceCount = 1;
|
|
7
|
+
getAuthHeader(user, pass, method, uri, wwwAuthenticateHeader) {
|
|
8
|
+
const digestItems = {};
|
|
9
|
+
const digestArr = wwwAuthenticateHeader.substring(wwwAuthenticateHeader.indexOf('Digest') + 6).split(',');
|
|
10
|
+
for (const arg of digestArr) {
|
|
11
|
+
const pos = arg.indexOf('=');
|
|
12
|
+
const key = arg.substring(0, pos).trim();
|
|
13
|
+
const value = arg.substring(pos + 1).trim();
|
|
14
|
+
digestItems[key] = value.replace(/"/g, '');
|
|
15
|
+
}
|
|
16
|
+
const HA1 = crypto.createHash('md5').update(`${user}:${digestItems['realm']}:${pass}`).digest('hex');
|
|
17
|
+
const HA2 = crypto.createHash('md5').update(`${method}:${uri}`).digest('hex');
|
|
18
|
+
const ncValue = ('00000000' + this.nonceCount.toString(16)).slice(-8);
|
|
19
|
+
let response;
|
|
20
|
+
if (digestItems['qop'] !== undefined) {
|
|
21
|
+
response = crypto
|
|
22
|
+
.createHash('md5')
|
|
23
|
+
.update(`${HA1}:${digestItems['nonce']}:${ncValue}:162d50aa594e9648:auth:${HA2}`)
|
|
24
|
+
.digest('hex');
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
response = crypto.createHash('md5').update(`${HA1}:${digestItems['nonce']}:${HA2}`).digest('hex');
|
|
28
|
+
}
|
|
29
|
+
let header = 'Digest ' +
|
|
30
|
+
`username="${user}",` +
|
|
31
|
+
`realm="${digestItems['realm']}",` +
|
|
32
|
+
`nonce="${digestItems['nonce']}",` +
|
|
33
|
+
`uri="${uri}",` +
|
|
34
|
+
`response="${response}"`;
|
|
35
|
+
if (digestItems['qop'] !== undefined) {
|
|
36
|
+
header += `,qop=auth,nc=${ncValue},cnonce="162d50aa594e9648"`;
|
|
37
|
+
}
|
|
38
|
+
this.nonceCount++;
|
|
39
|
+
return header;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.Digest = Digest;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProxyClient = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
class ProxyClient {
|
|
6
|
+
client;
|
|
7
|
+
getProxyUrl;
|
|
8
|
+
constructor(client, getProxyUrl) {
|
|
9
|
+
this.client = client;
|
|
10
|
+
this.getProxyUrl = getProxyUrl;
|
|
11
|
+
}
|
|
12
|
+
get = (proxy, path, parameters, headers = {}) => {
|
|
13
|
+
const url = (0, utils_1.addParametersToPath)(path, parameters);
|
|
14
|
+
const { realUrl, realHeaders } = this.getReal(proxy, url, headers);
|
|
15
|
+
return this.client.get(realUrl, {}, realHeaders);
|
|
16
|
+
};
|
|
17
|
+
post = (proxy, path, data, parameters, headers) => {
|
|
18
|
+
const url = (0, utils_1.addParametersToPath)(path, parameters);
|
|
19
|
+
const { realUrl, realHeaders } = this.getReal(proxy, url, headers);
|
|
20
|
+
return this.client.post(realUrl, data, {}, realHeaders);
|
|
21
|
+
};
|
|
22
|
+
getReal = (proxy, url, headers) => {
|
|
23
|
+
if (proxy !== null) {
|
|
24
|
+
return {
|
|
25
|
+
realUrl: this.getProxyUrl(),
|
|
26
|
+
realHeaders: {
|
|
27
|
+
...(headers ?? {}),
|
|
28
|
+
'x-target-camera-protocol': proxy.port === 443 ? 'https' : 'http',
|
|
29
|
+
'x-target-camera-path': url,
|
|
30
|
+
'x-target-camera-ip': proxy.ip,
|
|
31
|
+
'x-target-camera-mdns': proxy.mdnsName,
|
|
32
|
+
'x-target-camera-port': String(proxy.port),
|
|
33
|
+
'x-target-camera-pass': encodeURIComponent(proxy.pass),
|
|
34
|
+
'x-target-camera-user': encodeURIComponent(proxy.user),
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
realUrl: url,
|
|
40
|
+
realHeaders: headers,
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
exports.ProxyClient = ProxyClient;
|
|
@@ -33,7 +33,6 @@ export interface IWebsocket<Event extends {
|
|
|
33
33
|
send: (data: string) => void;
|
|
34
34
|
}
|
|
35
35
|
export declare function isClient(arg?: Options | IClient): arg is IClient;
|
|
36
|
-
export declare function isBrowserEnvironment(): boolean;
|
|
37
36
|
export declare function responseStringify(res: TResponse): Promise<string>;
|
|
38
37
|
export declare function pad(num: number, size: number): string;
|
|
39
38
|
export declare function isNullish<T>(value: T | undefined | null): value is undefined | null;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isNullish = exports.pad = exports.responseStringify = exports.isClient = void 0;
|
|
4
|
+
function isClient(arg = {}) {
|
|
5
|
+
return 'get' in arg && 'post' in arg;
|
|
6
|
+
}
|
|
7
|
+
exports.isClient = isClient;
|
|
8
|
+
async function responseStringify(res) {
|
|
9
|
+
return JSON.stringify({
|
|
10
|
+
status: res.status,
|
|
11
|
+
body: await res.text(),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
exports.responseStringify = responseStringify;
|
|
15
|
+
function pad(num, size) {
|
|
16
|
+
const sign = Math.sign(num) === -1 ? '-' : '';
|
|
17
|
+
return (sign +
|
|
18
|
+
new Array(size)
|
|
19
|
+
.concat([Math.abs(num)])
|
|
20
|
+
.join('0')
|
|
21
|
+
.slice(-size));
|
|
22
|
+
}
|
|
23
|
+
exports.pad = pad;
|
|
24
|
+
function isNullish(value) {
|
|
25
|
+
return value === null || value === undefined;
|
|
26
|
+
}
|
|
27
|
+
exports.isNullish = isNullish;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toSnakeCaseDeep = exports.toSnakeCase = exports.toCamelCaseDeep = exports.toCamelCase = void 0;
|
|
4
|
+
const lodash_1 = require("lodash");
|
|
5
|
+
const toCamelCase = (o) => (0, lodash_1.mapKeys)(o, camelCaseKey);
|
|
6
|
+
exports.toCamelCase = toCamelCase;
|
|
7
|
+
const toCamelCaseDeep = (o) => {
|
|
8
|
+
return mapKeysDeep(o, camelCaseKey);
|
|
9
|
+
};
|
|
10
|
+
exports.toCamelCaseDeep = toCamelCaseDeep;
|
|
11
|
+
const toSnakeCase = (o) => (0, lodash_1.mapKeys)(o, snakeCaseKey);
|
|
12
|
+
exports.toSnakeCase = toSnakeCase;
|
|
13
|
+
const toSnakeCaseDeep = (o) => {
|
|
14
|
+
return mapKeysDeep(o, snakeCaseKey);
|
|
15
|
+
};
|
|
16
|
+
exports.toSnakeCaseDeep = toSnakeCaseDeep;
|
|
17
|
+
const camelCaseKey = (_, key) => (0, lodash_1.camelCase)(key);
|
|
18
|
+
const snakeCaseKey = (_, key) => (0, lodash_1.snakeCase)(key);
|
|
19
|
+
const mapKeysDeep = (obj, cb) => {
|
|
20
|
+
if (Array.isArray(obj)) {
|
|
21
|
+
return obj.map((item) => {
|
|
22
|
+
return mapKeysDeep(item, cb);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
if (typeof obj !== 'object' || (0, lodash_1.isPlainObject)(obj) === false) {
|
|
26
|
+
return obj;
|
|
27
|
+
}
|
|
28
|
+
const result = (0, lodash_1.mapKeys)(obj, cb);
|
|
29
|
+
return (0, lodash_1.mapValues)(result, (value) => {
|
|
30
|
+
return mapKeysDeep(value, cb);
|
|
31
|
+
});
|
|
32
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isLoopPlayType = exports.isPlaylist = exports.isTracker = exports.isClip = exports.isStream = exports.isCamera = exports.arrayToUrl = exports.paramToUrl = exports.addParametersToPath = void 0;
|
|
4
|
+
const common_1 = require("./common");
|
|
5
|
+
const addParametersToPath = (path, params) => {
|
|
6
|
+
if (params === undefined || Object.keys(params).length === 0) {
|
|
7
|
+
return path;
|
|
8
|
+
}
|
|
9
|
+
const joinChar = path.indexOf('?') === -1 ? '?' : '&';
|
|
10
|
+
return `${path}${joinChar}${(0, exports.paramToUrl)(params)}`;
|
|
11
|
+
};
|
|
12
|
+
exports.addParametersToPath = addParametersToPath;
|
|
13
|
+
const paramToUrl = (params) => {
|
|
14
|
+
if (params === undefined) {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
let output = '';
|
|
18
|
+
for (const key in params) {
|
|
19
|
+
const value = params[key];
|
|
20
|
+
if ((0, common_1.isNullish)(value)) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
output += `${encodeURIComponent(key)}=${encodeURIComponent(value)}&`;
|
|
24
|
+
}
|
|
25
|
+
return output.slice(0, output.length - 1);
|
|
26
|
+
};
|
|
27
|
+
exports.paramToUrl = paramToUrl;
|
|
28
|
+
const arrayToUrl = (arr) => {
|
|
29
|
+
if (Array.isArray(arr)) {
|
|
30
|
+
return arr.join(',');
|
|
31
|
+
}
|
|
32
|
+
return arr;
|
|
33
|
+
};
|
|
34
|
+
exports.arrayToUrl = arrayToUrl;
|
|
35
|
+
const isCamera = (id) => id?.charAt(0) === 'c';
|
|
36
|
+
exports.isCamera = isCamera;
|
|
37
|
+
const isStream = (id) => id?.charAt(0) === 'c' || id?.charAt(0) === 'a';
|
|
38
|
+
exports.isStream = isStream;
|
|
39
|
+
const isClip = (id) => id?.charAt(0) === 's';
|
|
40
|
+
exports.isClip = isClip;
|
|
41
|
+
const isTracker = (id) => id?.charAt(0) === 't';
|
|
42
|
+
exports.isTracker = isTracker;
|
|
43
|
+
const isPlaylist = (id) => id?.charAt(0) === 'p';
|
|
44
|
+
exports.isPlaylist = isPlaylist;
|
|
45
|
+
const isLoopPlayType = (playType) => playType.includes('LOOP');
|
|
46
|
+
exports.isLoopPlayType = isLoopPlayType;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fixVersionToDots = exports.versionCompare = exports.firmwareVersionCompare = exports.isVersionAtLeast = exports.isFirmwareVersionAtLeast = exports.assertVersionString = void 0;
|
|
4
|
+
const assertVersionString = (s, msg) => {
|
|
5
|
+
if (!s.match(/^[0-9]+(\.[0-9]+){1,3}$/)) {
|
|
6
|
+
throw new Error(msg ?? `${s} is not a version`);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
exports.assertVersionString = assertVersionString;
|
|
10
|
+
const isFirmwareVersionAtLeast = (version, compareVersion) => {
|
|
11
|
+
return (0, exports.firmwareVersionCompare)(version, compareVersion) >= 0;
|
|
12
|
+
};
|
|
13
|
+
exports.isFirmwareVersionAtLeast = isFirmwareVersionAtLeast;
|
|
14
|
+
const isVersionAtLeast = (version, compareVersion) => {
|
|
15
|
+
return (0, exports.versionCompare)(version, compareVersion) >= 0;
|
|
16
|
+
};
|
|
17
|
+
exports.isVersionAtLeast = isVersionAtLeast;
|
|
18
|
+
const firmwareVersionCompare = (a, b) => {
|
|
19
|
+
const versions = [a, b];
|
|
20
|
+
const matchBetaFirmwareVersion = (x) => /^CVP-/.test(x) || /^[0-9]+.*beta/.test(x);
|
|
21
|
+
if (versions.every(matchBetaFirmwareVersion)) {
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
if (matchBetaFirmwareVersion(a)) {
|
|
25
|
+
return -1;
|
|
26
|
+
}
|
|
27
|
+
if (matchBetaFirmwareVersion(b)) {
|
|
28
|
+
return 1;
|
|
29
|
+
}
|
|
30
|
+
return (0, exports.versionCompare)(a, b);
|
|
31
|
+
};
|
|
32
|
+
exports.firmwareVersionCompare = firmwareVersionCompare;
|
|
33
|
+
const versionCompare = (a, b) => {
|
|
34
|
+
(0, exports.assertVersionString)(a);
|
|
35
|
+
(0, exports.assertVersionString)(b);
|
|
36
|
+
const aSplit = parseVersion(a);
|
|
37
|
+
const bSplit = parseVersion(b);
|
|
38
|
+
for (let i = 0; i < aSplit.length; i++) {
|
|
39
|
+
if (aSplit[i] !== bSplit[i]) {
|
|
40
|
+
return aSplit[i] < bSplit[i] ? -1 : 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return 0;
|
|
44
|
+
};
|
|
45
|
+
exports.versionCompare = versionCompare;
|
|
46
|
+
const fixVersionToDots = (version) => version.replaceAll('-', '.');
|
|
47
|
+
exports.fixVersionToDots = fixVersionToDots;
|
|
48
|
+
const parseVersion = (version) => {
|
|
49
|
+
(0, exports.assertVersionString)(version);
|
|
50
|
+
const parsed = version.split('.').map((s) => parseInt(s));
|
|
51
|
+
parsed.push(...Array(4 - parsed.length).fill(0));
|
|
52
|
+
return parsed;
|
|
53
|
+
};
|