camstreamerlib 4.0.0-beta.3 → 4.0.0-beta.30

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.
Files changed (192) hide show
  1. package/README.md +8 -2
  2. package/cjs/CamOverlayAPI.d.ts +47 -26
  3. package/cjs/CamOverlayAPI.js +171 -88
  4. package/cjs/CamOverlayDrawingAPI.d.ts +2 -47
  5. package/cjs/CamOverlayDrawingAPI.js +6 -3
  6. package/cjs/CamOverlayPainter/Frame.d.ts +8 -37
  7. package/cjs/CamOverlayPainter/Frame.js +33 -0
  8. package/cjs/CamOverlayPainter/Painter.d.ts +16 -10
  9. package/cjs/CamOverlayPainter/Painter.js +6 -5
  10. package/cjs/CamOverlayPainter/ResourceManager.d.ts +3 -2
  11. package/cjs/CamOverlayPainter/ResourceManager.js +8 -11
  12. package/cjs/CamScripterAPI.d.ts +33 -16
  13. package/cjs/CamScripterAPI.js +50 -41
  14. package/cjs/CamScripterAPICameraEventsGenerator.d.ts +1 -1
  15. package/cjs/CamScripterAPICameraEventsGenerator.js +6 -3
  16. package/cjs/CamStreamerAPI.d.ts +16 -14
  17. package/cjs/CamStreamerAPI.js +32 -32
  18. package/cjs/CamSwitcherAPI.d.ts +42 -37
  19. package/cjs/CamSwitcherAPI.js +123 -114
  20. package/cjs/CamSwitcherEvents.d.ts +1 -1
  21. package/cjs/PlaneTrackerAPI.d.ts +42 -0
  22. package/cjs/PlaneTrackerAPI.js +211 -0
  23. package/cjs/VapixAPI.d.ts +56 -43
  24. package/cjs/VapixAPI.js +305 -216
  25. package/cjs/VapixEvents.d.ts +1 -1
  26. package/cjs/VapixEvents.js +3 -3
  27. package/cjs/errors/errors.d.ts +3 -0
  28. package/cjs/errors/errors.js +8 -1
  29. package/cjs/events/AxisCameraStationEvents.d.ts +5 -4
  30. package/cjs/events/AxisCameraStationEvents.js +23 -18
  31. package/cjs/events/GenetecAgent.d.ts +6 -3
  32. package/cjs/events/GenetecAgent.js +30 -19
  33. package/cjs/index.d.ts +14 -1
  34. package/cjs/index.js +23 -2
  35. package/cjs/internal/Digest.js +6 -6
  36. package/cjs/internal/ProxyClient.d.ts +8 -9
  37. package/cjs/internal/ProxyClient.js +25 -29
  38. package/cjs/internal/types.d.ts +42 -0
  39. package/cjs/internal/types.js +2 -0
  40. package/cjs/internal/utils.d.ts +4 -1
  41. package/cjs/internal/utils.js +22 -3
  42. package/cjs/internal/versionCompare.d.ts +2 -2
  43. package/cjs/node/DefaultClient.d.ts +5 -6
  44. package/cjs/node/DefaultClient.js +12 -14
  45. package/cjs/node/HttpRequestSender.d.ts +1 -0
  46. package/cjs/node/HttpRequestSender.js +13 -3
  47. package/cjs/node/HttpServer.js +1 -1
  48. package/cjs/node/WsClient.d.ts +2 -1
  49. package/cjs/node/WsEventClient.d.ts +1 -1
  50. package/cjs/node/index.d.ts +2 -0
  51. package/cjs/node/index.js +18 -1
  52. package/cjs/types/CamOverlayAPI/CamOverlayAPI.d.ts +3073 -0
  53. package/cjs/types/CamOverlayAPI/CamOverlayAPI.js +127 -0
  54. package/cjs/types/CamOverlayAPI/accuweatherSchema.d.ts +114 -0
  55. package/cjs/types/CamOverlayAPI/accuweatherSchema.js +50 -0
  56. package/cjs/types/CamOverlayAPI/customGraphicsSchema.d.ts +783 -0
  57. package/cjs/types/CamOverlayAPI/customGraphicsSchema.js +75 -0
  58. package/cjs/types/CamOverlayAPI/imagesSchema.d.ts +122 -0
  59. package/cjs/types/CamOverlayAPI/imagesSchema.js +12 -0
  60. package/cjs/types/CamOverlayAPI/index.d.ts +9 -0
  61. package/cjs/types/CamOverlayAPI/index.js +25 -0
  62. package/cjs/types/CamOverlayAPI/infotickerSchema.d.ts +130 -0
  63. package/cjs/types/CamOverlayAPI/infotickerSchema.js +29 -0
  64. package/cjs/types/CamOverlayAPI/pipSchema.d.ts +166 -0
  65. package/cjs/types/CamOverlayAPI/pipSchema.js +42 -0
  66. package/cjs/types/CamOverlayAPI/ptzCompassSchema.d.ts +126 -0
  67. package/cjs/types/CamOverlayAPI/ptzCompassSchema.js +28 -0
  68. package/cjs/types/CamOverlayAPI/ptzSchema.d.ts +146 -0
  69. package/cjs/types/CamOverlayAPI/ptzSchema.js +15 -0
  70. package/cjs/types/CamOverlayAPI/screenSharingSchema.d.ts +79 -0
  71. package/cjs/types/CamOverlayAPI/screenSharingSchema.js +11 -0
  72. package/cjs/types/CamOverlayAPI/webCameraSharingSchema.d.ts +79 -0
  73. package/cjs/types/CamOverlayAPI/webCameraSharingSchema.js +11 -0
  74. package/cjs/types/CamOverlayDrawingAPI.d.ts +58 -0
  75. package/cjs/types/CamOverlayDrawingAPI.js +2 -0
  76. package/cjs/types/CamOverlayPainter.d.ts +74 -0
  77. package/cjs/types/CamOverlayPainter.js +2 -0
  78. package/cjs/types/CamScripterAPI.d.ts +82 -17
  79. package/cjs/types/CamScripterAPI.js +22 -7
  80. package/cjs/types/CamStreamerAPI.d.ts +16 -5
  81. package/cjs/types/CamStreamerAPI.js +5 -1
  82. package/cjs/types/CamSwitcherAPI.d.ts +5 -5
  83. package/cjs/types/CamSwitcherEvents.d.ts +77 -0
  84. package/cjs/types/CamSwitcherEvents.js +8 -0
  85. package/cjs/types/PlaneTrackerAPI.d.ts +8 -0
  86. package/cjs/types/PlaneTrackerAPI.js +2 -0
  87. package/cjs/types/VapixAPI.d.ts +636 -519
  88. package/cjs/types/VapixAPI.js +62 -24
  89. package/cjs/types/common.d.ts +14 -5
  90. package/cjs/web/DefaultClient.d.ts +5 -5
  91. package/cjs/web/DefaultClient.js +22 -10
  92. package/cjs/web/WsClient.js +2 -2
  93. package/esm/CamOverlayAPI.d.ts +47 -26
  94. package/esm/CamOverlayAPI.js +169 -86
  95. package/esm/CamOverlayDrawingAPI.d.ts +2 -47
  96. package/esm/CamOverlayDrawingAPI.js +6 -3
  97. package/esm/CamOverlayPainter/Frame.d.ts +8 -37
  98. package/esm/CamOverlayPainter/Frame.js +33 -0
  99. package/esm/CamOverlayPainter/Painter.d.ts +16 -10
  100. package/esm/CamOverlayPainter/Painter.js +5 -3
  101. package/esm/CamOverlayPainter/ResourceManager.d.ts +3 -2
  102. package/esm/CamOverlayPainter/ResourceManager.js +7 -11
  103. package/esm/CamScripterAPI.d.ts +33 -16
  104. package/esm/CamScripterAPI.js +46 -37
  105. package/esm/CamScripterAPICameraEventsGenerator.d.ts +1 -1
  106. package/esm/CamScripterAPICameraEventsGenerator.js +6 -3
  107. package/esm/CamStreamerAPI.d.ts +16 -14
  108. package/esm/CamStreamerAPI.js +32 -32
  109. package/esm/CamSwitcherAPI.d.ts +42 -37
  110. package/esm/CamSwitcherAPI.js +116 -107
  111. package/esm/CamSwitcherEvents.d.ts +1 -1
  112. package/esm/PlaneTrackerAPI.d.ts +42 -0
  113. package/esm/PlaneTrackerAPI.js +207 -0
  114. package/esm/VapixAPI.d.ts +56 -43
  115. package/esm/VapixAPI.js +297 -208
  116. package/esm/VapixEvents.d.ts +1 -1
  117. package/esm/VapixEvents.js +3 -3
  118. package/esm/errors/errors.d.ts +3 -0
  119. package/esm/errors/errors.js +6 -0
  120. package/esm/events/AxisCameraStationEvents.d.ts +5 -4
  121. package/esm/events/AxisCameraStationEvents.js +18 -13
  122. package/esm/events/GenetecAgent.d.ts +6 -3
  123. package/esm/events/GenetecAgent.js +20 -9
  124. package/esm/index.d.ts +14 -1
  125. package/esm/index.js +14 -1
  126. package/esm/internal/Digest.js +6 -6
  127. package/esm/internal/ProxyClient.d.ts +8 -9
  128. package/esm/internal/ProxyClient.js +25 -29
  129. package/esm/internal/types.d.ts +42 -0
  130. package/esm/internal/types.js +1 -0
  131. package/esm/internal/utils.d.ts +4 -1
  132. package/esm/internal/utils.js +17 -1
  133. package/esm/internal/versionCompare.d.ts +2 -2
  134. package/esm/node/DefaultClient.d.ts +5 -6
  135. package/esm/node/DefaultClient.js +12 -14
  136. package/esm/node/HttpRequestSender.d.ts +1 -0
  137. package/esm/node/HttpRequestSender.js +13 -3
  138. package/esm/node/HttpServer.js +1 -1
  139. package/esm/node/WsClient.d.ts +2 -1
  140. package/esm/node/WsEventClient.d.ts +1 -1
  141. package/esm/node/index.d.ts +2 -0
  142. package/esm/node/index.js +2 -0
  143. package/esm/types/CamOverlayAPI/CamOverlayAPI.d.ts +3073 -0
  144. package/esm/types/CamOverlayAPI/CamOverlayAPI.js +124 -0
  145. package/esm/types/CamOverlayAPI/accuweatherSchema.d.ts +114 -0
  146. package/esm/types/CamOverlayAPI/accuweatherSchema.js +46 -0
  147. package/esm/types/CamOverlayAPI/customGraphicsSchema.d.ts +783 -0
  148. package/esm/types/CamOverlayAPI/customGraphicsSchema.js +71 -0
  149. package/esm/types/CamOverlayAPI/imagesSchema.d.ts +122 -0
  150. package/esm/types/CamOverlayAPI/imagesSchema.js +8 -0
  151. package/esm/types/CamOverlayAPI/index.d.ts +9 -0
  152. package/esm/types/CamOverlayAPI/index.js +9 -0
  153. package/esm/types/CamOverlayAPI/infotickerSchema.d.ts +130 -0
  154. package/esm/types/CamOverlayAPI/infotickerSchema.js +25 -0
  155. package/esm/types/CamOverlayAPI/pipSchema.d.ts +166 -0
  156. package/esm/types/CamOverlayAPI/pipSchema.js +38 -0
  157. package/esm/types/CamOverlayAPI/ptzCompassSchema.d.ts +126 -0
  158. package/esm/types/CamOverlayAPI/ptzCompassSchema.js +24 -0
  159. package/esm/types/CamOverlayAPI/ptzSchema.d.ts +146 -0
  160. package/esm/types/CamOverlayAPI/ptzSchema.js +11 -0
  161. package/esm/types/CamOverlayAPI/screenSharingSchema.d.ts +79 -0
  162. package/esm/types/CamOverlayAPI/screenSharingSchema.js +7 -0
  163. package/esm/types/CamOverlayAPI/webCameraSharingSchema.d.ts +79 -0
  164. package/esm/types/CamOverlayAPI/webCameraSharingSchema.js +7 -0
  165. package/esm/types/CamOverlayDrawingAPI.d.ts +58 -0
  166. package/esm/types/CamOverlayDrawingAPI.js +1 -0
  167. package/esm/types/CamOverlayPainter.d.ts +74 -0
  168. package/esm/types/CamOverlayPainter.js +1 -0
  169. package/esm/types/CamScripterAPI.d.ts +82 -17
  170. package/esm/types/CamScripterAPI.js +21 -6
  171. package/esm/types/CamStreamerAPI.d.ts +16 -5
  172. package/esm/types/CamStreamerAPI.js +4 -0
  173. package/esm/types/CamSwitcherAPI.d.ts +5 -5
  174. package/esm/types/CamSwitcherEvents.d.ts +77 -0
  175. package/esm/types/CamSwitcherEvents.js +8 -0
  176. package/esm/types/PlaneTrackerAPI.d.ts +8 -0
  177. package/esm/types/PlaneTrackerAPI.js +1 -0
  178. package/esm/types/VapixAPI.d.ts +636 -519
  179. package/esm/types/VapixAPI.js +61 -23
  180. package/esm/types/common.d.ts +14 -5
  181. package/esm/web/DefaultClient.d.ts +5 -5
  182. package/esm/web/DefaultClient.js +22 -10
  183. package/esm/web/WsClient.js +2 -2
  184. package/package.json +9 -8
  185. package/cjs/internal/common.d.ts +0 -39
  186. package/cjs/internal/common.js +0 -27
  187. package/cjs/types/CamOverlayAPI.d.ts +0 -188
  188. package/cjs/types/CamOverlayAPI.js +0 -47
  189. package/esm/internal/common.d.ts +0 -39
  190. package/esm/internal/common.js +0 -20
  191. package/esm/types/CamOverlayAPI.d.ts +0 -188
  192. package/esm/types/CamOverlayAPI.js +0 -44
package/cjs/VapixAPI.js CHANGED
@@ -2,57 +2,64 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VapixAPI = void 0;
4
4
  const prettifyXml = require("prettify-xml");
5
- const xml2js_1 = require("xml2js");
6
- const common_1 = require("./internal/common");
5
+ const utils_1 = require("./internal/utils");
7
6
  const VapixAPI_1 = require("./types/VapixAPI");
8
7
  const errors_1 = require("./errors/errors");
9
8
  const ProxyClient_1 = require("./internal/ProxyClient");
10
- const utils_1 = require("./internal/utils");
11
9
  const zod_1 = require("zod");
10
+ const fast_xml_parser_1 = require("fast-xml-parser");
12
11
  class VapixAPI {
13
12
  client;
14
- constructor(client, getProxyUrl) {
15
- this.client = new ProxyClient_1.ProxyClient(client, getProxyUrl);
13
+ constructor(client) {
14
+ this.client = client;
16
15
  }
17
- async getUrlEncoded(proxy = null, path, parameters, headers = {}) {
16
+ async postUrlEncoded(path, parameters, headers, options) {
18
17
  const data = (0, utils_1.paramToUrl)(parameters);
19
18
  const head = { ...headers, 'Content-Type': 'application/x-www-form-urlencoded' };
20
- const res = await this.client.post(proxy, path, data, {}, head);
19
+ const agent = this.getAgent(options?.proxyParams);
20
+ const res = await agent.post({ path, data, headers: head, timeout: options?.timeout });
21
21
  if (!res.ok) {
22
- throw new Error(await (0, common_1.responseStringify)(res));
22
+ throw new Error(await (0, utils_1.responseStringify)(res));
23
23
  }
24
24
  return res;
25
25
  }
26
- async postJson(proxy = null, path, jsonData, headers = {}) {
26
+ async postJson(path, jsonData, headers, options) {
27
27
  const data = JSON.stringify(jsonData);
28
28
  const head = { ...headers, 'Content-Type': 'application/json' };
29
- const res = await this.client.post(proxy, path, data, {}, head);
29
+ const agent = this.getAgent(options?.proxyParams);
30
+ const res = await agent.post({ path, data, headers: head, timeout: options?.timeout });
30
31
  if (!res.ok) {
31
- throw new Error(await (0, common_1.responseStringify)(res));
32
+ throw new Error(await (0, utils_1.responseStringify)(res));
32
33
  }
33
34
  return res;
34
35
  }
35
- async getCameraImage(params, proxy = null) {
36
- return await this.client.get(proxy, '/axis-cgi/jpg/image.cgi', params);
36
+ async getCameraImage(parameters, options) {
37
+ const agent = this.getAgent(options?.proxyParams);
38
+ return await agent.get({ path: '/axis-cgi/jpg/image.cgi', parameters, timeout: options?.timeout });
37
39
  }
38
- async getEventDeclarations(proxy = null) {
40
+ async getEventDeclarations(options) {
39
41
  const data = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' +
40
42
  '<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
41
43
  'xmlns:xsd="http://www.w3.org/2001/XMLSchema">' +
42
44
  '<GetEventInstances xmlns="http://www.axis.com/vapix/ws/event1"/>' +
43
45
  '</s:Body>' +
44
46
  '</s:Envelope>';
45
- const res = await this.client.post(proxy, '/vapix/services', data, { 'Content-Type': 'application/soap+xml' });
47
+ const agent = this.getAgent(options?.proxyParams);
48
+ const res = await agent.post({
49
+ path: '/vapix/services',
50
+ data,
51
+ headers: { 'Content-Type': 'application/soap+xml' },
52
+ });
46
53
  if (!res.ok) {
47
- throw new Error(await (0, common_1.responseStringify)(res));
54
+ throw new Error(await (0, utils_1.responseStringify)(res));
48
55
  }
49
56
  const declarations = await res.text();
50
57
  return prettifyXml(declarations);
51
58
  }
52
- async getSupportedAudioSampleRate(proxy = null) {
53
- const url = '/axis-cgi/audio/streamingcapabilities.cgi';
54
- const formData = { apiVersion: '1.0', method: 'list' };
55
- const res = await this.postJson(proxy, url, formData);
59
+ async getSupportedAudioSampleRate(options) {
60
+ const path = '/axis-cgi/audio/streamingcapabilities.cgi';
61
+ const jsonData = { apiVersion: '1.0', method: 'list' };
62
+ const res = await this.postJson(path, jsonData, undefined, options);
56
63
  const encoders = VapixAPI_1.audioSampleRatesResponseSchema.parse(await res.json()).data.encoders;
57
64
  const data = encoders.aac ?? encoders.AAC ?? [];
58
65
  return data.map((item) => {
@@ -62,7 +69,7 @@ class VapixAPI {
62
69
  };
63
70
  });
64
71
  }
65
- async performAutofocus(proxy = null) {
72
+ async performAutofocus(options) {
66
73
  try {
67
74
  const data = {
68
75
  apiVersion: '1',
@@ -75,24 +82,26 @@ class VapixAPI {
75
82
  ],
76
83
  },
77
84
  };
78
- await this.postJson(proxy, '/axis-cgi/opticscontrol.cgi', data);
85
+ await this.postJson('/axis-cgi/opticscontrol.cgi', data, undefined, options);
79
86
  }
80
87
  catch (err) {
81
- await this.postJson(proxy, '/axis-cgi/opticssetup.cgi', {
88
+ await this.postUrlEncoded('/axis-cgi/opticssetup.cgi', {
82
89
  autofocus: 'perform',
83
90
  source: '1',
84
- });
91
+ }, undefined, options);
85
92
  }
86
93
  }
87
- async checkSDCard(proxy = null) {
88
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/disks/list.cgi', {
94
+ async checkSDCard(options) {
95
+ const res = await this.postUrlEncoded('/axis-cgi/disks/list.cgi', {
89
96
  diskid: 'SD_DISK',
97
+ }, undefined, options);
98
+ const xmlText = await res.text();
99
+ const parser = new fast_xml_parser_1.XMLParser({
100
+ ignoreAttributes: false,
101
+ attributeNamePrefix: '',
102
+ allowBooleanAttributes: true,
90
103
  });
91
- const result = await (0, xml2js_1.parseStringPromise)(await res.text(), {
92
- ignoreAttrs: false,
93
- mergeAttrs: true,
94
- explicitArray: false,
95
- });
104
+ const result = parser.parse(xmlText);
96
105
  const data = result.root.disks.disk;
97
106
  return {
98
107
  totalSize: parseInt(data.totalsize),
@@ -100,53 +109,56 @@ class VapixAPI {
100
109
  status: VapixAPI_1.sdCardWatchedStatuses.includes(data.status) ? data.status : 'disconnected',
101
110
  };
102
111
  }
103
- mountSDCard(proxy = null) {
104
- return this._doSDCardMountAction('MOUNT', proxy);
112
+ mountSDCard(options) {
113
+ return this._doSDCardMountAction('MOUNT', options);
105
114
  }
106
- unmountSDCard(proxy = null) {
107
- return this._doSDCardMountAction('UNMOUNT', proxy);
115
+ unmountSDCard(options) {
116
+ return this._doSDCardMountAction('UNMOUNT', options);
108
117
  }
109
- async _doSDCardMountAction(action, proxy = null) {
110
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/disks/mount.cgi', {
118
+ async _doSDCardMountAction(action, options) {
119
+ const res = await this.postUrlEncoded('/axis-cgi/disks/mount.cgi', {
111
120
  action: action,
112
121
  diskid: 'SD_DISK',
122
+ }, undefined, options);
123
+ const textXml = await res.text();
124
+ const parser = new fast_xml_parser_1.XMLParser({
125
+ ignoreAttributes: false,
126
+ attributeNamePrefix: '',
127
+ allowBooleanAttributes: true,
113
128
  });
114
- const result = await (0, xml2js_1.parseStringPromise)(await res.text(), {
115
- ignoreAttrs: false,
116
- mergeAttrs: true,
117
- explicitArray: false,
118
- });
129
+ const result = parser.parse(textXml);
119
130
  const job = result.root.job;
120
131
  if (job.result !== 'OK') {
121
- throw new errors_1.SDCardActionError(action, await (0, common_1.responseStringify)(res));
132
+ throw new errors_1.SDCardActionError(action, await (0, utils_1.responseStringify)(res));
122
133
  }
123
134
  return Number(job.jobid);
124
135
  }
125
- async fetchSDCardJobProgress(jobId, proxy = null) {
126
- const res = await this.getUrlEncoded(proxy, '/disks/job.cgi', {
136
+ async fetchSDCardJobProgress(jobId, options) {
137
+ const res = await this.postUrlEncoded('/disks/job.cgi', {
127
138
  jobid: String(jobId),
128
139
  diskid: 'SD_DISK',
140
+ }, undefined, options);
141
+ const textXml = await res.text();
142
+ const parser = new fast_xml_parser_1.XMLParser({
143
+ ignoreAttributes: false,
144
+ attributeNamePrefix: '',
145
+ allowBooleanAttributes: true,
129
146
  });
130
- const result = await (0, xml2js_1.parseStringPromise)(await res.text(), {
131
- ignoreAttrs: false,
132
- mergeAttrs: true,
133
- explicitArray: false,
134
- });
135
- const job = result.root.job;
147
+ const job = parser.parse(textXml).root.job;
136
148
  if (job.result !== 'OK') {
137
149
  throw new errors_1.SDCardJobError();
138
150
  }
139
151
  return Number(job.progress);
140
152
  }
141
- downloadCameraReport(proxy = null) {
142
- return this.getUrlEncoded(proxy, '/axis-cgi/serverreport.cgi', { mode: 'text' });
153
+ downloadCameraReport(options) {
154
+ return this.postUrlEncoded('/axis-cgi/serverreport.cgi', { mode: 'text' }, undefined, options);
143
155
  }
144
- getSystemLog(proxy = null) {
145
- return this.getUrlEncoded(proxy, '/axis-cgi/admin/systemlog.cgi');
156
+ getSystemLog(options) {
157
+ return this.postUrlEncoded('/axis-cgi/admin/systemlog.cgi', undefined, undefined, options);
146
158
  }
147
- async getMaxFps(channel, proxy = null) {
159
+ async getMaxFps(channel, options) {
148
160
  const data = { apiVersion: '1.0', method: 'getCaptureModes' };
149
- const res = await this.postJson(proxy, '/axis-cgi/capturemode.cgi', data);
161
+ const res = await this.postJson('/axis-cgi/capturemode.cgi', data, undefined, options);
150
162
  const response = VapixAPI_1.maxFpsResponseSchema.parse(await res.json());
151
163
  const channels = response.data;
152
164
  if (channels === undefined) {
@@ -161,82 +173,97 @@ class VapixAPI {
161
173
  if (captureMode === undefined) {
162
174
  throw new errors_1.MaxFPSError('CAPTURE_MODE_NOT_FOUND');
163
175
  }
164
- if ((0, common_1.isNullish)(captureMode.maxFPS)) {
176
+ if ((0, utils_1.isNullish)(captureMode.maxFPS)) {
165
177
  throw new errors_1.MaxFPSError('FPS_NOT_SPECIFIED');
166
178
  }
167
179
  return captureMode.maxFPS;
168
180
  }
169
- async getTimezone(proxy = null) {
170
- const data = { apiVersion: '1.0', method: 'getDateTimeInfo' };
171
- const res = await this.postJson(proxy, '/axis-cgi/time.cgi', data);
172
- return (await res.json())?.timeZone ?? 'Europe/Prague';
181
+ async getTimezone(options) {
182
+ try {
183
+ const agent = this.getAgent(options?.proxyParams);
184
+ const resV2 = await agent.get({ path: '/config/rest/time/v2/timeZone', timeout: options?.timeout });
185
+ if (!resV2.ok) {
186
+ throw new Error(await (0, utils_1.responseStringify)(resV2));
187
+ }
188
+ const json = await resV2.json();
189
+ const data = VapixAPI_1.timeZoneSchema.parse(json);
190
+ if (data.status === 'error') {
191
+ throw new Error(data.error.message);
192
+ }
193
+ return data.data.activeTimeZone;
194
+ }
195
+ catch (error) {
196
+ console.warn('Failed to fetch time zone data from time API v2:', error instanceof Error ? error.message : JSON.stringify(error));
197
+ console.warn('Falling back to deprecated time API v1');
198
+ }
199
+ const data = await this.getDateTimeInfo(options);
200
+ if (data.data.timeZone === undefined) {
201
+ throw new Error('Time zone not setup on the device');
202
+ }
203
+ return data.data.timeZone;
173
204
  }
174
- async getDateTimeInfo(proxy = null) {
205
+ async getDateTimeInfo(options) {
175
206
  const data = { apiVersion: '1.0', method: 'getDateTimeInfo' };
176
- const res = await this.postJson(proxy, '/axis-cgi/time.cgi', data);
207
+ const res = await this.postJson('/axis-cgi/time.cgi', data, undefined, options);
177
208
  return VapixAPI_1.dateTimeinfoSchema.parse(await res.json());
178
209
  }
179
- async getDevicesSettings(proxy = null) {
210
+ async getDevicesSettings(options) {
180
211
  const data = { apiVersion: '1.0', method: 'getDevicesSettings' };
181
- const res = await this.postJson(proxy, '/axis-cgi/audiodevicecontrol.cgi', data);
212
+ const res = await this.postJson('/axis-cgi/audiodevicecontrol.cgi', data, undefined, options);
182
213
  const result = VapixAPI_1.audioDeviceRequestSchema.parse(await res.json());
183
- return result.devices.map((device) => ({
214
+ return result.data.devices.map((device) => ({
184
215
  ...device,
185
216
  inputs: (device.inputs || []).sort((a, b) => a.id.localeCompare(b.id)),
186
217
  outputs: (device.outputs || []).sort((a, b) => a.id.localeCompare(b.id)),
187
218
  }));
188
219
  }
189
- async fetchRemoteDeviceInfo(payload, proxy = null) {
190
- const res = await this.postJson(proxy, '/axis-cgi/basicdeviceinfo.cgi', payload);
191
- const result = await (0, xml2js_1.parseStringPromise)(await res.text(), {
192
- ignoreAttrs: false,
193
- mergeAttrs: true,
194
- explicitArray: false,
195
- });
196
- if ((0, common_1.isNullish)(result.body.data)) {
220
+ async fetchRemoteDeviceInfo(payload, options) {
221
+ const res = await this.postJson('/axis-cgi/basicdeviceinfo.cgi', payload, undefined, options);
222
+ const json = await res.json();
223
+ if ((0, utils_1.isNullish)(json.data)) {
197
224
  throw new errors_1.NoDeviceInfoError();
198
225
  }
199
- return result.data;
226
+ return json.data;
200
227
  }
201
- async getHeaders(proxy = null) {
228
+ async getHeaders(options) {
202
229
  const data = { apiVersion: '1.0', method: 'list' };
203
- const res = await this.postJson(proxy, '/axis-cgi/customhttpheader.cgi', data);
230
+ const res = await this.postJson('/axis-cgi/customhttpheader.cgi', data, undefined, options);
204
231
  return zod_1.z.object({ data: zod_1.z.record(zod_1.z.string()) }).parse(await res.json()).data;
205
232
  }
206
- async setHeaders(headers, proxy = null) {
233
+ async setHeaders(headers, options) {
207
234
  const data = { apiVersion: '1.0', method: 'set', params: headers };
208
- return this.postJson(proxy, '/axis-cgi/customhttpheader.cgi', data);
235
+ return this.postJson('/axis-cgi/customhttpheader.cgi', data, undefined, options);
209
236
  }
210
- async getParameter(paramNames, proxy = null) {
211
- const response = await this.getUrlEncoded(proxy, '/axis-cgi/param.cgi', {
237
+ async getParameter(paramNames, options) {
238
+ const response = await this.postUrlEncoded('/axis-cgi/param.cgi', {
212
239
  action: 'list',
213
240
  group: (0, utils_1.arrayToUrl)(paramNames),
214
- });
215
- return parseParameters(await response.text());
241
+ }, undefined, options);
242
+ return VapixAPI.parseParameters(await response.text());
216
243
  }
217
- async setParameter(params, proxy = null) {
218
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/param.cgi', {
244
+ async setParameter(params, options) {
245
+ const res = await this.postUrlEncoded('/axis-cgi/param.cgi', {
219
246
  ...params,
220
247
  action: 'update',
221
- });
248
+ }, undefined, options);
222
249
  const responseText = await res.text();
223
250
  if (responseText.startsWith('# Error')) {
224
251
  throw new Error(responseText);
225
252
  }
226
253
  return true;
227
254
  }
228
- async getGuardTourList(proxy = null) {
255
+ async getGuardTourList(options) {
229
256
  const gTourList = new Array();
230
- const response = await this.getParameter('GuardTour', proxy);
257
+ const response = await this.getParameter('GuardTour', options);
231
258
  for (let i = 0; i < 20; i++) {
232
259
  const gTourBaseName = 'root.GuardTour.G' + i;
233
260
  if (gTourBaseName + '.CamNbr' in response) {
234
261
  const gTour = {
235
262
  id: gTourBaseName,
236
263
  camNbr: response[gTourBaseName + '.CamNbr'],
237
- name: response[gTourBaseName + '.Name'],
264
+ name: response[gTourBaseName + '.Name'] ?? 'Guard Tour ' + (i + 1),
238
265
  randomEnabled: response[gTourBaseName + '.RandomEnabled'],
239
- running: response[gTourBaseName + '.Running'],
266
+ running: response[gTourBaseName + '.Running'] ?? 'no',
240
267
  timeBetweenSequences: response[gTourBaseName + '.TimeBetweenSequences'],
241
268
  tour: [],
242
269
  };
@@ -261,16 +288,16 @@ class VapixAPI {
261
288
  }
262
289
  return gTourList;
263
290
  }
264
- setGuardTourEnabled(guardTourID, enable, proxy = null) {
265
- const options = {};
266
- options[guardTourID + '.Running'] = enable ? 'yes' : 'no';
267
- return this.setParameter(options, proxy);
291
+ setGuardTourEnabled(guardTourID, enable, options) {
292
+ const params = {};
293
+ params[guardTourID + '.Running'] = enable ? 'yes' : 'no';
294
+ return this.setParameter(params, options);
268
295
  }
269
- async getPTZPresetList(channel, proxy = null) {
270
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/com/ptz.cgi', {
296
+ async getPTZPresetList(channel, options) {
297
+ const res = await this.postUrlEncoded('/axis-cgi/com/ptz.cgi', {
271
298
  query: 'presetposcam',
272
299
  camera: channel.toString(),
273
- });
300
+ }, undefined, options);
274
301
  const text = await res.text();
275
302
  const lines = text.split(/[\r\n]/);
276
303
  const positions = [];
@@ -285,174 +312,236 @@ class VapixAPI {
285
312
  }
286
313
  return positions;
287
314
  }
288
- async listPTZ(camera, proxy = null) {
315
+ async listPTZ(camera, options) {
289
316
  const url = `/axis-cgi/com/ptz.cgi`;
290
- const response = await this.getUrlEncoded(proxy, url, {
317
+ const response = await this.postUrlEncoded(url, {
291
318
  camera,
292
319
  query: 'presetposcamdata',
293
320
  format: 'json',
294
- });
295
- return parseCameraPtzResponse(await response.text())[camera] ?? [];
321
+ }, undefined, options);
322
+ const text = await response.text();
323
+ if (text === '') {
324
+ throw new errors_1.PtzNotSupportedError();
325
+ }
326
+ return VapixAPI.parseCameraPtzResponse(text)[camera] ?? [];
296
327
  }
297
- async listPtzVideoSourceOverview(proxy = null) {
298
- const response = await this.getUrlEncoded(proxy, '/axis-cgi/com/ptz.cgi', {
328
+ async listPtzVideoSourceOverview(options) {
329
+ const response = await this.postUrlEncoded('/axis-cgi/com/ptz.cgi', {
299
330
  query: 'presetposall',
300
331
  format: 'json',
301
- });
302
- const data = parseCameraPtzResponse(await response.text());
332
+ }, undefined, options);
333
+ const text = await response.text();
334
+ if (text === '') {
335
+ throw new errors_1.PtzNotSupportedError();
336
+ }
337
+ const data = VapixAPI.parseCameraPtzResponse(text);
303
338
  const res = {};
304
- Object.keys(data).forEach((camera) => {
305
- res[Number(camera) - 1] = data[Number(camera)].map(({ data: itemData, ...d }) => d);
339
+ Object.keys(data)
340
+ .map(Number)
341
+ .forEach((camera) => {
342
+ if (data[camera] !== undefined) {
343
+ res[camera - 1] = data[camera]?.map(({ data: itemData, ...d }) => d);
344
+ }
306
345
  });
307
346
  return res;
308
347
  }
309
- goToPreset(channel, presetName, proxy = null) {
310
- return this.getUrlEncoded(proxy, '/axis-cgi/com/ptz.cgi', {
348
+ goToPreset(channel, presetName, options) {
349
+ return this.postUrlEncoded('/axis-cgi/com/ptz.cgi', {
311
350
  camera: channel.toString(),
312
351
  gotoserverpresetname: presetName,
313
- });
352
+ }, undefined, options);
314
353
  }
315
- async getPtzPosition(camera, proxy = null) {
316
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/com/ptz.cgi', {
354
+ async getPtzPosition(camera, options) {
355
+ const res = await this.postUrlEncoded('/axis-cgi/com/ptz.cgi', {
317
356
  query: 'position',
318
357
  camera: camera.toString(),
319
- });
320
- const params = parseParameters(await res.text());
358
+ }, undefined, options);
359
+ const params = VapixAPI.parseParameters(await res.text());
321
360
  return {
322
361
  pan: Number(params.pan),
323
362
  tilt: Number(params.tilt),
324
363
  zoom: Number(params.zoom),
325
364
  };
326
365
  }
327
- async getInputState(port, proxy = null) {
328
- const response = await (await this.getUrlEncoded(proxy, '/axis-cgi/io/port.cgi', { checkactive: port.toString() })).text();
329
- return response.split('=')[1].indexOf('active') === 0;
330
- }
331
- async setOutputState(port, active, proxy = null) {
332
- return this.getUrlEncoded(proxy, '/axis-cgi/io/port.cgi', { action: active ? `${port}:/` : `${port}:\\` });
333
- }
334
- async getApplicationList(proxy = null) {
335
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/applications/list.cgi');
366
+ async getPorts(options) {
367
+ const res = await this.postJson('/axis-cgi/io/portmanagement.cgi', {
368
+ apiVersion: '1.0',
369
+ context: '',
370
+ method: 'getPorts',
371
+ }, undefined, options);
372
+ const portResponseParsed = await VapixAPI_1.getPortsResponseSchema.parse(res.json());
373
+ return portResponseParsed.data.items;
374
+ }
375
+ async setPorts(ports, options) {
376
+ await this.postJson('/axis-cgi/io/portmanagement.cgi', {
377
+ apiVersion: '1.0',
378
+ context: '',
379
+ method: 'setPorts',
380
+ params: { ports },
381
+ }, undefined, options);
382
+ }
383
+ async setPortStateSequence(port, sequence, options) {
384
+ await this.postJson('/axis-cgi/io/portmanagement.cgi', {
385
+ apiVersion: '1.0',
386
+ context: '',
387
+ method: 'setStateSequence',
388
+ params: { port, sequence },
389
+ }, undefined, options);
390
+ }
391
+ async getApplicationList(options) {
392
+ const agent = this.getAgent(options?.proxyParams);
393
+ const res = await agent.get({ path: '/axis-cgi/applications/list.cgi', timeout: options?.timeout });
336
394
  const xml = await res.text();
337
- const result = (await (0, xml2js_1.parseStringPromise)(xml));
338
- const apps = [];
339
- for (let i = 0; i < result.reply.application.length; i++) {
340
- apps.push({
341
- ...result.reply.application[i].$,
342
- appId: VapixAPI_1.APP_IDS.find((id) => id.toLowerCase() === result.reply.application[i].$.Name.toLowerCase()) ?? null,
343
- });
395
+ const parser = new fast_xml_parser_1.XMLParser({
396
+ ignoreAttributes: false,
397
+ attributeNamePrefix: '',
398
+ allowBooleanAttributes: true,
399
+ });
400
+ const result = parser.parse(xml);
401
+ let apps = result.reply.application ?? [];
402
+ if (!Array.isArray(apps)) {
403
+ apps = [apps];
344
404
  }
345
- return apps;
405
+ return apps.map((app) => {
406
+ return {
407
+ ...app,
408
+ appId: VapixAPI_1.APP_IDS.find((id) => id.toLowerCase() === app.Name.toLowerCase()) ?? null,
409
+ };
410
+ });
346
411
  }
347
- async startApplication(applicationID, proxy = null) {
348
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/applications/control.cgi', {
349
- package: applicationID.toLowerCase(),
350
- action: 'start',
412
+ async startApplication(applicationID, options) {
413
+ const agent = this.getAgent(options?.proxyParams);
414
+ const res = await agent.get({
415
+ path: '/axis-cgi/applications/control.cgi',
416
+ parameters: {
417
+ package: applicationID.toLowerCase(),
418
+ action: 'start',
419
+ },
420
+ timeout: options?.timeout,
351
421
  });
352
422
  const text = (await res.text()).trim().toLowerCase();
353
423
  if (text !== 'ok' && !(text.startsWith('error:') && text.substring(7) === '6')) {
354
- throw new errors_1.ApplicationAPIError('START', await (0, common_1.responseStringify)(res));
424
+ throw new errors_1.ApplicationAPIError('START', await (0, utils_1.responseStringify)(res));
355
425
  }
356
426
  }
357
- async restartApplication(applicationID, proxy = null) {
358
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/applications/control.cgi', {
359
- package: applicationID.toLowerCase(),
360
- action: 'restart',
427
+ async restartApplication(applicationID, options) {
428
+ const agent = this.getAgent(options?.proxyParams);
429
+ const res = await agent.get({
430
+ path: '/axis-cgi/applications/control.cgi',
431
+ parameters: {
432
+ package: applicationID.toLowerCase(),
433
+ action: 'restart',
434
+ },
435
+ timeout: options?.timeout,
361
436
  });
362
437
  const text = (await res.text()).trim().toLowerCase();
363
438
  if (text !== 'ok') {
364
- throw new errors_1.ApplicationAPIError('RESTART', await (0, common_1.responseStringify)(res));
439
+ throw new errors_1.ApplicationAPIError('RESTART', await (0, utils_1.responseStringify)(res));
365
440
  }
366
441
  }
367
- async stopApplication(applicationID, proxy = null) {
368
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/applications/control.cgi', {
369
- package: applicationID.toLowerCase(),
370
- action: 'stop',
442
+ async stopApplication(applicationID, options) {
443
+ const agent = this.getAgent(options?.proxyParams);
444
+ const res = await agent.get({
445
+ path: '/axis-cgi/applications/control.cgi',
446
+ parameters: {
447
+ package: applicationID.toLowerCase(),
448
+ action: 'stop',
449
+ },
450
+ timeout: options?.timeout,
371
451
  });
372
452
  const text = (await res.text()).trim().toLowerCase();
373
453
  if (text !== 'ok' && !(text.startsWith('error:') && text.substring(7) === '6')) {
374
- throw new errors_1.ApplicationAPIError('STOP', await (0, common_1.responseStringify)(res));
454
+ throw new errors_1.ApplicationAPIError('STOP', await (0, utils_1.responseStringify)(res));
375
455
  }
376
456
  }
377
- async installApplication(data, fileName) {
457
+ async installApplication(data, fileName, options) {
378
458
  const formData = new FormData();
379
459
  formData.append('packfil', data, fileName);
380
- const res = await this.client.post(null, '/axis-cgi/applications/upload.cgi', formData, {}, {
381
- contentType: 'application/octet-stream',
460
+ const agent = this.getAgent(options?.proxyParams);
461
+ const res = await agent.post({
462
+ path: '/axis-cgi/applications/upload.cgi',
463
+ data: formData,
464
+ headers: {
465
+ contentType: 'application/octet-stream',
466
+ },
467
+ timeout: options?.timeout ?? 120000,
382
468
  });
383
469
  if (!res.ok) {
384
- throw new Error(await (0, common_1.responseStringify)(res));
470
+ throw new Error(await (0, utils_1.responseStringify)(res));
385
471
  }
386
472
  const text = await res.text();
387
473
  if (text.length > 5) {
388
474
  throw new Error('installing error: ' + text);
389
475
  }
390
476
  }
391
- }
392
- exports.VapixAPI = VapixAPI;
393
- const parseParameters = (response) => {
394
- const params = {};
395
- const lines = response.split(/[\r\n]/);
396
- for (let i = 0; i < lines.length; i++) {
397
- if (lines[i].length === 0 || lines[i].substring(0, 7) === '# Error') {
398
- continue;
399
- }
400
- const delimiterPos = lines[i].indexOf('=');
401
- if (delimiterPos !== -1) {
402
- const paramName = lines[i].substring(0, delimiterPos);
403
- const paramValue = lines[i].substring(delimiterPos + 1);
404
- params[paramName] = paramValue;
405
- }
406
- }
407
- return params;
408
- };
409
- const parseCameraPtzResponse = (response) => {
410
- const json = JSON.parse(response);
411
- const parsed = {};
412
- Object.keys(json).forEach((key) => {
413
- if (!key.startsWith('Camera ')) {
414
- return;
415
- }
416
- const camera = Number(key.replace('Camera ', ''));
417
- if (json[key].presets !== undefined) {
418
- parsed[camera] = parsePtz(json[key].presets);
419
- }
420
- });
421
- return parsed;
422
- };
423
- const parsePtz = (parsed) => {
424
- const res = [];
425
- parsed.forEach((value) => {
426
- const delimiterPos = value.indexOf('=');
427
- if (delimiterPos === -1) {
428
- return;
429
- }
430
- if (!value.startsWith('presetposno')) {
431
- return;
432
- }
433
- const id = Number(value.substring(11, delimiterPos));
434
- if (Number.isNaN(id)) {
435
- return;
477
+ static parseParameters = (response) => {
478
+ const params = {};
479
+ const lines = response.split(/[\r\n]/);
480
+ for (const line of lines) {
481
+ if (line.length === 0 || line.substring(0, 7) === '# Error') {
482
+ continue;
483
+ }
484
+ const delimiterPos = line.indexOf('=');
485
+ if (delimiterPos !== -1) {
486
+ const paramName = line.substring(0, delimiterPos).replace('root.', '');
487
+ const paramValue = line.substring(delimiterPos + 1);
488
+ params[paramName] = paramValue;
489
+ }
436
490
  }
437
- const data = value.substring(delimiterPos + 1).split(':');
438
- const getValue = (valueName) => {
439
- for (const d of data) {
440
- const p = d.split('=');
441
- if (p[0] === valueName) {
442
- return Number(p[1]);
443
- }
491
+ return params;
492
+ };
493
+ static parseCameraPtzResponse = (response) => {
494
+ const json = JSON.parse(response);
495
+ const parsed = {};
496
+ Object.keys(json).forEach((key) => {
497
+ if (!key.startsWith('Camera ')) {
498
+ return;
444
499
  }
445
- return 0;
446
- };
447
- res.push({
448
- id,
449
- name: data[0],
450
- data: {
451
- pan: getValue('pan'),
452
- tilt: getValue('tilt'),
453
- zoom: getValue('zoom'),
454
- },
500
+ const camera = Number(key.replace('Camera ', ''));
501
+ if (json[key].presets !== undefined) {
502
+ parsed[camera] = VapixAPI.parsePtz(json[key].presets);
503
+ }
504
+ });
505
+ return parsed;
506
+ };
507
+ static parsePtz = (parsed) => {
508
+ const res = [];
509
+ parsed.forEach((value) => {
510
+ const delimiterPos = value.indexOf('=');
511
+ if (delimiterPos === -1) {
512
+ return;
513
+ }
514
+ if (!value.startsWith('presetposno')) {
515
+ return;
516
+ }
517
+ const id = Number(value.substring(11, delimiterPos));
518
+ if (Number.isNaN(id)) {
519
+ return;
520
+ }
521
+ const data = value.substring(delimiterPos + 1).split(':');
522
+ const getValue = (valueName) => {
523
+ for (const d of data) {
524
+ const p = d.split('=');
525
+ if (p[0] === valueName) {
526
+ return Number(p[1]);
527
+ }
528
+ }
529
+ return 0;
530
+ };
531
+ res.push({
532
+ id,
533
+ name: data[0] ?? 'Preset ' + id,
534
+ data: {
535
+ pan: getValue('pan'),
536
+ tilt: getValue('tilt'),
537
+ zoom: getValue('zoom'),
538
+ },
539
+ });
455
540
  });
456
- });
457
- return res;
458
- };
541
+ return res;
542
+ };
543
+ getAgent(proxyParams) {
544
+ return proxyParams ? new ProxyClient_1.ProxyClient(this.client, proxyParams) : this.client;
545
+ }
546
+ }
547
+ exports.VapixAPI = VapixAPI;