camstreamerlib 4.0.0-beta.99 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/README.md +44 -15
  2. package/cjs/CamOverlayAPI.d.ts +145 -107
  3. package/cjs/CamOverlayAPI.js +14 -63
  4. package/cjs/CamScripterAPI.d.ts +5 -8
  5. package/cjs/CamScripterAPI.js +11 -29
  6. package/cjs/CamStreamerAPI.d.ts +2362 -806
  7. package/cjs/CamStreamerAPI.js +68 -76
  8. package/cjs/CamSwitcherAPI.d.ts +23 -22
  9. package/cjs/CamSwitcherAPI.js +30 -88
  10. package/cjs/PlaneTrackerAPI.d.ts +28 -30
  11. package/cjs/PlaneTrackerAPI.js +20 -75
  12. package/cjs/VapixAPI.d.ts +36 -23
  13. package/cjs/VapixAPI.js +227 -106
  14. package/cjs/errors/errors.d.ts +11 -5
  15. package/cjs/errors/errors.js +5 -1
  16. package/cjs/index.d.ts +1 -0
  17. package/cjs/index.js +1 -0
  18. package/cjs/internal/BasicAPI.d.ts +15 -0
  19. package/cjs/internal/BasicAPI.js +93 -0
  20. package/cjs/internal/WsEvents.d.ts +1 -0
  21. package/cjs/internal/WsEvents.js +5 -0
  22. package/cjs/internal/constants.d.ts +1 -0
  23. package/cjs/internal/constants.js +2 -1
  24. package/cjs/internal/convertors.d.ts +6 -0
  25. package/cjs/internal/convertors.js +115 -0
  26. package/cjs/internal/transformers.js +8 -8
  27. package/cjs/internal/types.d.ts +3 -0
  28. package/cjs/internal/versionCompare.d.ts +2 -2
  29. package/cjs/types/CamOverlayAPI/CamOverlayAPI.d.ts +878 -358
  30. package/cjs/types/CamOverlayAPI/CamOverlayAPI.js +54 -11
  31. package/cjs/types/CamOverlayAPI/accuweatherSchema.d.ts +10 -10
  32. package/cjs/types/CamOverlayAPI/customGraphicsSchema.d.ts +28 -28
  33. package/cjs/types/CamOverlayAPI/htmlOverlaySchema.d.ts +81 -0
  34. package/cjs/types/CamOverlayAPI/htmlOverlaySchema.js +21 -0
  35. package/cjs/types/CamOverlayAPI/imagesSchema.d.ts +10 -10
  36. package/cjs/types/CamOverlayAPI/index.d.ts +1 -0
  37. package/cjs/types/CamOverlayAPI/index.js +1 -0
  38. package/cjs/types/CamOverlayAPI/infotickerSchema.d.ts +8 -8
  39. package/cjs/types/CamOverlayAPI/pipSchema.d.ts +8 -8
  40. package/cjs/types/CamOverlayAPI/ptzCompassSchema.d.ts +10 -10
  41. package/cjs/types/CamOverlayAPI/ptzSchema.d.ts +13 -13
  42. package/cjs/types/CamOverlayAPI/scoreBoardSchema.d.ts +18 -18
  43. package/cjs/types/CamOverlayAPI/screenSharingSchema.d.ts +8 -8
  44. package/cjs/types/CamOverlayAPI/serviceCommonTypes.d.ts +17 -16
  45. package/cjs/types/CamOverlayAPI/serviceCommonTypes.js +6 -3
  46. package/cjs/types/CamOverlayAPI/webCameraSharingSchema.d.ts +8 -8
  47. package/cjs/types/CamScripterAPI.d.ts +0 -11
  48. package/cjs/types/CamScripterAPI.js +1 -5
  49. package/cjs/types/CamStreamerAPI/CamStreamerAPI.d.ts +17745 -4940
  50. package/cjs/types/CamStreamerAPI/CamStreamerAPI.js +126 -57
  51. package/cjs/types/CamStreamerAPI/facebookSchema.d.ts +395 -86
  52. package/cjs/types/CamStreamerAPI/facebookSchema.js +13 -1
  53. package/cjs/types/CamStreamerAPI/index.d.ts +1 -3
  54. package/cjs/types/CamStreamerAPI/index.js +1 -3
  55. package/cjs/types/CamStreamerAPI/oldStreamSchema.d.ts +47 -47
  56. package/cjs/types/CamStreamerAPI/oldStreamSchema.js +1 -1
  57. package/cjs/types/CamStreamerAPI/streamCommonTypes.d.ts +392 -304
  58. package/cjs/types/CamStreamerAPI/streamCommonTypes.js +116 -76
  59. package/cjs/types/CamStreamerAPI/streamsSchema.d.ts +8812 -0
  60. package/cjs/types/CamStreamerAPI/streamsSchema.js +81 -0
  61. package/cjs/types/CamStreamerAPI/windySchema.d.ts +356 -87
  62. package/cjs/types/CamStreamerAPI/windySchema.js +9 -1
  63. package/cjs/types/CamStreamerAPI/youtubeSchema.d.ts +351 -119
  64. package/cjs/types/CamStreamerAPI/youtubeSchema.js +5 -9
  65. package/cjs/types/CamSwitcherAPI.d.ts +96 -91
  66. package/cjs/types/CamSwitcherAPI.js +9 -9
  67. package/cjs/types/GenetecAgent.d.ts +2 -2
  68. package/cjs/types/PlaneTrackerAPI.d.ts +60 -47
  69. package/cjs/types/PlaneTrackerAPI.js +5 -2
  70. package/cjs/types/VapixAPI.d.ts +51 -32
  71. package/cjs/types/VapixAPI.js +10 -3
  72. package/cjs/types/common.d.ts +27 -0
  73. package/cjs/types/common.js +13 -1
  74. package/cjs/types/ws/CamStreamerEvents.d.ts +110 -77
  75. package/cjs/types/ws/CamStreamerEvents.js +11 -7
  76. package/cjs/types/ws/CamSwitcherEvents.d.ts +8 -8
  77. package/cjs/types/ws/PlaneTrackerEvents.d.ts +3 -3
  78. package/esm/CamOverlayAPI.js +16 -65
  79. package/esm/CamScripterAPI.js +9 -30
  80. package/esm/CamStreamerAPI.js +70 -78
  81. package/esm/CamSwitcherAPI.js +31 -89
  82. package/esm/PlaneTrackerAPI.js +21 -76
  83. package/esm/VapixAPI.js +228 -107
  84. package/esm/errors/errors.js +5 -1
  85. package/esm/index.js +1 -0
  86. package/esm/internal/BasicAPI.js +89 -0
  87. package/esm/internal/WsEvents.js +5 -0
  88. package/esm/internal/constants.js +1 -0
  89. package/esm/internal/convertors.js +108 -0
  90. package/esm/internal/transformers.js +1 -1
  91. package/esm/types/CamOverlayAPI/CamOverlayAPI.js +47 -10
  92. package/esm/types/CamOverlayAPI/htmlOverlaySchema.js +18 -0
  93. package/esm/types/CamOverlayAPI/index.js +1 -0
  94. package/esm/types/CamOverlayAPI/serviceCommonTypes.js +6 -3
  95. package/esm/types/CamScripterAPI.js +0 -4
  96. package/esm/types/CamStreamerAPI/CamStreamerAPI.js +109 -41
  97. package/esm/types/CamStreamerAPI/facebookSchema.js +13 -1
  98. package/esm/types/CamStreamerAPI/index.js +1 -3
  99. package/esm/types/CamStreamerAPI/oldStreamSchema.js +1 -1
  100. package/esm/types/CamStreamerAPI/streamCommonTypes.js +116 -76
  101. package/esm/types/CamStreamerAPI/streamsSchema.js +75 -0
  102. package/esm/types/CamStreamerAPI/windySchema.js +9 -1
  103. package/esm/types/CamStreamerAPI/youtubeSchema.js +5 -9
  104. package/esm/types/CamSwitcherAPI.js +8 -8
  105. package/esm/types/PlaneTrackerAPI.js +5 -2
  106. package/esm/types/VapixAPI.js +9 -2
  107. package/esm/types/common.js +12 -0
  108. package/esm/types/ws/CamStreamerEvents.js +11 -7
  109. package/package.json +4 -4
  110. package/types/CamOverlayAPI.d.ts +145 -107
  111. package/types/CamScripterAPI.d.ts +5 -8
  112. package/types/CamStreamerAPI.d.ts +2362 -806
  113. package/types/CamSwitcherAPI.d.ts +23 -22
  114. package/types/PlaneTrackerAPI.d.ts +28 -30
  115. package/types/VapixAPI.d.ts +36 -23
  116. package/types/errors/errors.d.ts +11 -5
  117. package/types/index.d.ts +1 -0
  118. package/types/internal/BasicAPI.d.ts +15 -0
  119. package/types/internal/WsEvents.d.ts +1 -0
  120. package/types/internal/constants.d.ts +1 -0
  121. package/types/internal/convertors.d.ts +6 -0
  122. package/types/internal/types.d.ts +3 -0
  123. package/types/internal/versionCompare.d.ts +2 -2
  124. package/types/types/CamOverlayAPI/CamOverlayAPI.d.ts +878 -358
  125. package/types/types/CamOverlayAPI/accuweatherSchema.d.ts +10 -10
  126. package/types/types/CamOverlayAPI/customGraphicsSchema.d.ts +28 -28
  127. package/types/types/CamOverlayAPI/htmlOverlaySchema.d.ts +81 -0
  128. package/types/types/CamOverlayAPI/imagesSchema.d.ts +10 -10
  129. package/types/types/CamOverlayAPI/index.d.ts +1 -0
  130. package/types/types/CamOverlayAPI/infotickerSchema.d.ts +8 -8
  131. package/types/types/CamOverlayAPI/pipSchema.d.ts +8 -8
  132. package/types/types/CamOverlayAPI/ptzCompassSchema.d.ts +10 -10
  133. package/types/types/CamOverlayAPI/ptzSchema.d.ts +13 -13
  134. package/types/types/CamOverlayAPI/scoreBoardSchema.d.ts +18 -18
  135. package/types/types/CamOverlayAPI/screenSharingSchema.d.ts +8 -8
  136. package/types/types/CamOverlayAPI/serviceCommonTypes.d.ts +17 -16
  137. package/types/types/CamOverlayAPI/webCameraSharingSchema.d.ts +8 -8
  138. package/types/types/CamScripterAPI.d.ts +0 -11
  139. package/types/types/CamStreamerAPI/CamStreamerAPI.d.ts +17745 -4940
  140. package/types/types/CamStreamerAPI/facebookSchema.d.ts +395 -86
  141. package/types/types/CamStreamerAPI/index.d.ts +1 -3
  142. package/types/types/CamStreamerAPI/oldStreamSchema.d.ts +47 -47
  143. package/types/types/CamStreamerAPI/streamCommonTypes.d.ts +392 -304
  144. package/types/types/CamStreamerAPI/streamsSchema.d.ts +8812 -0
  145. package/types/types/CamStreamerAPI/windySchema.d.ts +356 -87
  146. package/types/types/CamStreamerAPI/youtubeSchema.d.ts +351 -119
  147. package/types/types/CamSwitcherAPI.d.ts +96 -91
  148. package/types/types/GenetecAgent.d.ts +2 -2
  149. package/types/types/PlaneTrackerAPI.d.ts +60 -47
  150. package/types/types/VapixAPI.d.ts +51 -32
  151. package/types/types/common.d.ts +27 -0
  152. package/types/types/ws/CamStreamerEvents.d.ts +110 -77
  153. package/types/types/ws/CamSwitcherEvents.d.ts +8 -8
  154. package/types/types/ws/PlaneTrackerEvents.d.ts +3 -3
  155. package/cjs/types/CamStreamerAPI/churchSchema.d.ts +0 -275
  156. package/cjs/types/CamStreamerAPI/churchSchema.js +0 -11
  157. package/cjs/types/CamStreamerAPI/daCastSchema.d.ts +0 -275
  158. package/cjs/types/CamStreamerAPI/daCastSchema.js +0 -11
  159. package/cjs/types/CamStreamerAPI/dailymotionSchema.d.ts +0 -275
  160. package/cjs/types/CamStreamerAPI/dailymotionSchema.js +0 -11
  161. package/cjs/types/CamStreamerAPI/gameChangerSchema.d.ts +0 -275
  162. package/cjs/types/CamStreamerAPI/gameChangerSchema.js +0 -11
  163. package/cjs/types/CamStreamerAPI/hlsPullSchema.d.ts +0 -275
  164. package/cjs/types/CamStreamerAPI/hlsPullSchema.js +0 -11
  165. package/cjs/types/CamStreamerAPI/hlsPushSchema.d.ts +0 -275
  166. package/cjs/types/CamStreamerAPI/hlsPushSchema.js +0 -11
  167. package/cjs/types/CamStreamerAPI/ibmSchema.d.ts +0 -275
  168. package/cjs/types/CamStreamerAPI/ibmSchema.js +0 -11
  169. package/cjs/types/CamStreamerAPI/microsoftAzureSchema.d.ts +0 -275
  170. package/cjs/types/CamStreamerAPI/microsoftAzureSchema.js +0 -11
  171. package/cjs/types/CamStreamerAPI/microsoftStreamSchema.d.ts +0 -275
  172. package/cjs/types/CamStreamerAPI/microsoftStreamSchema.js +0 -11
  173. package/cjs/types/CamStreamerAPI/mpegDvbSchema.d.ts +0 -323
  174. package/cjs/types/CamStreamerAPI/mpegDvbSchema.js +0 -27
  175. package/cjs/types/CamStreamerAPI/rtmpSchema.d.ts +0 -284
  176. package/cjs/types/CamStreamerAPI/rtmpSchema.js +0 -14
  177. package/cjs/types/CamStreamerAPI/sdCardSchema.d.ts +0 -275
  178. package/cjs/types/CamStreamerAPI/sdCardSchema.js +0 -11
  179. package/cjs/types/CamStreamerAPI/srtSchema.d.ts +0 -275
  180. package/cjs/types/CamStreamerAPI/srtSchema.js +0 -11
  181. package/cjs/types/CamStreamerAPI/twitchSchema.d.ts +0 -275
  182. package/cjs/types/CamStreamerAPI/twitchSchema.js +0 -11
  183. package/cjs/types/CamStreamerAPI/vimeoSchema.d.ts +0 -275
  184. package/cjs/types/CamStreamerAPI/vimeoSchema.js +0 -11
  185. package/cjs/types/CamStreamerAPI/wowzaSchema.d.ts +0 -275
  186. package/cjs/types/CamStreamerAPI/wowzaSchema.js +0 -11
  187. package/esm/types/CamStreamerAPI/churchSchema.js +0 -5
  188. package/esm/types/CamStreamerAPI/daCastSchema.js +0 -5
  189. package/esm/types/CamStreamerAPI/dailymotionSchema.js +0 -5
  190. package/esm/types/CamStreamerAPI/gameChangerSchema.js +0 -5
  191. package/esm/types/CamStreamerAPI/hlsPullSchema.js +0 -5
  192. package/esm/types/CamStreamerAPI/hlsPushSchema.js +0 -5
  193. package/esm/types/CamStreamerAPI/ibmSchema.js +0 -5
  194. package/esm/types/CamStreamerAPI/microsoftAzureSchema.js +0 -5
  195. package/esm/types/CamStreamerAPI/microsoftStreamSchema.js +0 -5
  196. package/esm/types/CamStreamerAPI/mpegDvbSchema.js +0 -21
  197. package/esm/types/CamStreamerAPI/rtmpSchema.js +0 -8
  198. package/esm/types/CamStreamerAPI/sdCardSchema.js +0 -5
  199. package/esm/types/CamStreamerAPI/srtSchema.js +0 -5
  200. package/esm/types/CamStreamerAPI/twitchSchema.js +0 -5
  201. package/esm/types/CamStreamerAPI/vimeoSchema.js +0 -5
  202. package/esm/types/CamStreamerAPI/wowzaSchema.js +0 -5
  203. package/types/types/CamStreamerAPI/churchSchema.d.ts +0 -275
  204. package/types/types/CamStreamerAPI/daCastSchema.d.ts +0 -275
  205. package/types/types/CamStreamerAPI/dailymotionSchema.d.ts +0 -275
  206. package/types/types/CamStreamerAPI/gameChangerSchema.d.ts +0 -275
  207. package/types/types/CamStreamerAPI/hlsPullSchema.d.ts +0 -275
  208. package/types/types/CamStreamerAPI/hlsPushSchema.d.ts +0 -275
  209. package/types/types/CamStreamerAPI/ibmSchema.d.ts +0 -275
  210. package/types/types/CamStreamerAPI/microsoftAzureSchema.d.ts +0 -275
  211. package/types/types/CamStreamerAPI/microsoftStreamSchema.d.ts +0 -275
  212. package/types/types/CamStreamerAPI/mpegDvbSchema.d.ts +0 -323
  213. package/types/types/CamStreamerAPI/rtmpSchema.d.ts +0 -284
  214. package/types/types/CamStreamerAPI/sdCardSchema.d.ts +0 -275
  215. package/types/types/CamStreamerAPI/srtSchema.d.ts +0 -275
  216. package/types/types/CamStreamerAPI/twitchSchema.d.ts +0 -275
  217. package/types/types/CamStreamerAPI/vimeoSchema.d.ts +0 -275
  218. package/types/types/CamStreamerAPI/wowzaSchema.d.ts +0 -275
package/esm/VapixAPI.js CHANGED
@@ -1,19 +1,15 @@
1
1
  import { arrayToUrl, isNullish, paramToUrl } from './internal/utils';
2
- import { sdCardWatchedStatuses, APP_IDS, maxFpsResponseSchema, dateTimeinfoSchema, audioDeviceRequestSchema, audioSampleRatesResponseSchema, timeZoneSchema, getPortsResponseSchema, guardTourSchema, ptzOverviewSchema, cameraPTZItemDataSchema, applicationListSchema, sdCardInfoSchema, } from './types/VapixAPI';
2
+ import { sdCardWatchedStatuses, maxFpsResponseSchema, dateTimeinfoSchema, audioDeviceRequestSchema, audioSampleRatesResponseSchema, timeZoneSchema, getPortsResponseSchema, guardTourSchema, ptzOverviewSchema, cameraPTZItemDataSchema, applicationListSchema, sdCardInfoSchema, ALL_APP_IDS, } from './types/VapixAPI';
3
3
  import { ApplicationAPIError, MaxFPSError, NoDeviceInfoError, PtzNotSupportedError, ErrorWithResponse, SDCardActionError, SDCardJobError, SettingParameterError, TimezoneFetchError, TimezoneNotSetupError, } from './errors/errors';
4
- import { ProxyClient } from './internal/ProxyClient';
5
4
  import { z } from 'zod';
6
5
  import { XMLParser } from 'fast-xml-parser';
7
- export class VapixAPI {
8
- client;
6
+ import { BasicAPI } from './internal/BasicAPI';
7
+ export class VapixAPI extends BasicAPI {
9
8
  CustomFormData;
10
9
  constructor(client, CustomFormData = FormData) {
11
- this.client = client;
10
+ super(client);
12
11
  this.CustomFormData = CustomFormData;
13
12
  }
14
- getClient(proxyParams) {
15
- return proxyParams ? new ProxyClient(this.client, proxyParams) : this.client;
16
- }
17
13
  async postUrlEncoded(path, parameters, headers, options) {
18
14
  const data = paramToUrl(parameters);
19
15
  const head = { ...headers, 'Content-Type': 'application/x-www-form-urlencoded' };
@@ -24,11 +20,15 @@ export class VapixAPI {
24
20
  }
25
21
  return res;
26
22
  }
27
- async postJson(path, jsonData, headers, options) {
28
- const data = JSON.stringify(jsonData);
29
- const head = { ...headers, 'Content-Type': 'application/json' };
23
+ async postJson(path, data, headers, options) {
30
24
  const agent = this.getClient(options?.proxyParams);
31
- const res = await agent.post({ path, data, headers: head, timeout: options?.timeout });
25
+ const jsonData = JSON.stringify(data);
26
+ const res = await agent.post({
27
+ path,
28
+ data: jsonData,
29
+ headers: { ...headers, 'Content-Type': 'application/json' },
30
+ timeout: options?.timeout,
31
+ });
32
32
  if (!res.ok) {
33
33
  throw new ErrorWithResponse(res);
34
34
  }
@@ -36,11 +36,18 @@ export class VapixAPI {
36
36
  }
37
37
  async getCameraImage(parameters, options) {
38
38
  const agent = this.getClient(options?.proxyParams);
39
- return (await agent.get({
39
+ const res = await agent.get({
40
40
  path: '/axis-cgi/jpg/image.cgi',
41
41
  parameters,
42
42
  timeout: options?.timeout,
43
- }));
43
+ });
44
+ if (!res.ok) {
45
+ throw new ErrorWithResponse(res);
46
+ }
47
+ if (res.headers.get('content-type') !== 'image/jpeg') {
48
+ throw new Error(`Unexpected content-type: ${res.headers.get('content-type')}`);
49
+ }
50
+ return res;
44
51
  }
45
52
  async getEventDeclarations(options) {
46
53
  const data = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' +
@@ -63,7 +70,7 @@ export class VapixAPI {
63
70
  async getSupportedAudioSampleRate(options) {
64
71
  const path = '/axis-cgi/audio/streamingcapabilities.cgi';
65
72
  const jsonData = { apiVersion: '1.0', method: 'list' };
66
- const res = await this.postJson(path, jsonData, undefined, options);
73
+ const res = await this._postJsonEncoded(path, jsonData, undefined, options);
67
74
  const encoders = audioSampleRatesResponseSchema.parse(await res.json()).data.encoders;
68
75
  const data = encoders.aac ?? encoders.AAC ?? [];
69
76
  return data.map((item) => {
@@ -86,83 +93,25 @@ export class VapixAPI {
86
93
  ],
87
94
  },
88
95
  };
89
- await this.postJson('/axis-cgi/opticscontrol.cgi', data, undefined, options);
96
+ await this._postJsonEncoded('/axis-cgi/opticscontrol.cgi', data, undefined, options);
90
97
  }
91
98
  catch (err) {
92
- await this.postUrlEncoded('/axis-cgi/opticssetup.cgi', {
99
+ await this._postUrlEncoded('/axis-cgi/opticssetup.cgi', {
93
100
  autofocus: 'perform',
94
101
  source: '1',
95
- }, undefined, options);
96
- }
97
- }
98
- async checkSDCard(options) {
99
- const res = await this.postUrlEncoded('/axis-cgi/disks/list.cgi', {
100
- diskid: 'SD_DISK',
101
- }, undefined, options);
102
- const xmlText = await res.text();
103
- const parser = new XMLParser({
104
- ignoreAttributes: false,
105
- attributeNamePrefix: '',
106
- allowBooleanAttributes: true,
107
- });
108
- const result = parser.parse(xmlText);
109
- const data = result.root.disks.disk;
110
- return sdCardInfoSchema.parse({
111
- totalSize: parseInt(data.totalsize),
112
- freeSize: parseInt(data.freesize),
113
- status: sdCardWatchedStatuses.includes(data.status) ? data.status : 'disconnected',
114
- });
115
- }
116
- mountSDCard(options) {
117
- return this._doSDCardMountAction('MOUNT', options);
118
- }
119
- unmountSDCard(options) {
120
- return this._doSDCardMountAction('UNMOUNT', options);
121
- }
122
- async _doSDCardMountAction(action, options) {
123
- const res = await this.postUrlEncoded('/axis-cgi/disks/mount.cgi', {
124
- action: action,
125
- diskid: 'SD_DISK',
126
- }, undefined, options);
127
- const textXml = await res.text();
128
- const parser = new XMLParser({
129
- ignoreAttributes: false,
130
- attributeNamePrefix: '',
131
- allowBooleanAttributes: true,
132
- });
133
- const result = parser.parse(textXml);
134
- const job = result.root.job;
135
- if (job.result !== 'OK') {
136
- throw new SDCardActionError(action, job.description);
102
+ }, options);
137
103
  }
138
- return Number(job.jobid);
139
- }
140
- async fetchSDCardJobProgress(jobId, options) {
141
- const res = await this.postUrlEncoded('/disks/job.cgi', {
142
- jobid: String(jobId),
143
- diskid: 'SD_DISK',
144
- }, undefined, options);
145
- const textXml = await res.text();
146
- const parser = new XMLParser({
147
- ignoreAttributes: false,
148
- attributeNamePrefix: '',
149
- allowBooleanAttributes: true,
150
- });
151
- const job = parser.parse(textXml).root.job;
152
- if (job.result !== 'OK') {
153
- throw new SDCardJobError(job.description);
154
- }
155
- return Number(job.progress);
156
104
  }
157
105
  downloadCameraReport(options) {
158
- return this.postUrlEncoded('/axis-cgi/serverreport.cgi', { mode: 'text' }, undefined, options);
106
+ return this._getText('/axis-cgi/serverreport.cgi', { mode: 'text' }, options);
159
107
  }
160
- getSystemLog(options) {
161
- return this.postUrlEncoded('/axis-cgi/admin/systemlog.cgi', undefined, undefined, options);
108
+ async getSystemLog(options) {
109
+ const res = await this._postUrlEncoded('/axis-cgi/admin/systemlog.cgi', {}, options);
110
+ return res.text();
162
111
  }
163
112
  async getMaxFps(channel, options) {
164
113
  const data = { apiVersion: '1.0', method: 'getCaptureModes' };
165
- const res = await this.postJson('/axis-cgi/capturemode.cgi', data, undefined, options);
114
+ const res = await this._postJsonEncoded('/axis-cgi/capturemode.cgi', data, undefined, options);
166
115
  const response = maxFpsResponseSchema.parse(await res.json());
167
116
  const channels = response.data;
168
117
  if (channels === undefined) {
@@ -208,12 +157,12 @@ export class VapixAPI {
208
157
  }
209
158
  async getDateTimeInfo(options) {
210
159
  const data = { apiVersion: '1.0', method: 'getDateTimeInfo' };
211
- const res = await this.postJson('/axis-cgi/time.cgi', data, undefined, options);
160
+ const res = await this._postJsonEncoded('/axis-cgi/time.cgi', data, undefined, options);
212
161
  return dateTimeinfoSchema.parse(await res.json());
213
162
  }
214
163
  async getDevicesSettings(options) {
215
164
  const data = { apiVersion: '1.0', method: 'getDevicesSettings' };
216
- const res = await this.postJson('/axis-cgi/audiodevicecontrol.cgi', data, undefined, options);
165
+ const res = await this._postJsonEncoded('/axis-cgi/audiodevicecontrol.cgi', data, undefined, options);
217
166
  const result = audioDeviceRequestSchema.parse(await res.json());
218
167
  return result.data.devices.map((device) => ({
219
168
  ...device,
@@ -222,7 +171,7 @@ export class VapixAPI {
222
171
  }));
223
172
  }
224
173
  async fetchRemoteDeviceInfo(payload, options) {
225
- const res = await this.postJson('/axis-cgi/basicdeviceinfo.cgi', payload, undefined, options);
174
+ const res = await this._postJsonEncoded('/axis-cgi/basicdeviceinfo.cgi', payload, undefined, options);
226
175
  const json = await res.json();
227
176
  if (isNullish(json.data)) {
228
177
  throw new NoDeviceInfoError();
@@ -231,25 +180,84 @@ export class VapixAPI {
231
180
  }
232
181
  async getHeaders(options) {
233
182
  const data = { apiVersion: '1.0', method: 'list' };
234
- const res = await this.postJson('/axis-cgi/customhttpheader.cgi', data, undefined, options);
183
+ const res = await this._postJsonEncoded('/axis-cgi/customhttpheader.cgi', data, undefined, options);
235
184
  return z.object({ data: z.record(z.string()) }).parse(await res.json()).data;
236
185
  }
237
186
  async setHeaders(headers, options) {
238
187
  const data = { apiVersion: '1.0', method: 'set', params: headers };
239
- return this.postJson('/axis-cgi/customhttpheader.cgi', data, undefined, options);
188
+ await this._postJsonEncoded('/axis-cgi/customhttpheader.cgi', data, undefined, options);
189
+ }
190
+ async checkSDCard(options) {
191
+ const res = await this._postUrlEncoded('/axis-cgi/disks/list.cgi', {
192
+ diskid: 'SD_DISK',
193
+ }, options);
194
+ const xmlText = await res.text();
195
+ const parser = new XMLParser({
196
+ ignoreAttributes: false,
197
+ attributeNamePrefix: '',
198
+ allowBooleanAttributes: true,
199
+ });
200
+ const result = parser.parse(xmlText);
201
+ const data = result.root.disks.disk;
202
+ return sdCardInfoSchema.parse({
203
+ totalSize: parseInt(data.totalsize),
204
+ freeSize: parseInt(data.freesize),
205
+ status: sdCardWatchedStatuses.includes(data.status) ? data.status : 'disconnected',
206
+ });
207
+ }
208
+ mountSDCard(options) {
209
+ return this._doSDCardMountAction('MOUNT', options);
210
+ }
211
+ unmountSDCard(options) {
212
+ return this._doSDCardMountAction('UNMOUNT', options);
213
+ }
214
+ async _doSDCardMountAction(action, options) {
215
+ const res = await this._postUrlEncoded('/axis-cgi/disks/mount.cgi', {
216
+ action: action,
217
+ diskid: 'SD_DISK',
218
+ }, options);
219
+ const textXml = await res.text();
220
+ const parser = new XMLParser({
221
+ ignoreAttributes: false,
222
+ attributeNamePrefix: '',
223
+ allowBooleanAttributes: true,
224
+ });
225
+ const result = parser.parse(textXml);
226
+ const job = result.root.job;
227
+ if (job.result !== 'OK') {
228
+ throw new SDCardActionError(action, job.description);
229
+ }
230
+ return Number(job.jobid);
231
+ }
232
+ async fetchSDCardJobProgress(jobId, options) {
233
+ const res = await this._postUrlEncoded('/disks/job.cgi', {
234
+ jobid: String(jobId),
235
+ diskid: 'SD_DISK',
236
+ }, options);
237
+ const textXml = await res.text();
238
+ const parser = new XMLParser({
239
+ ignoreAttributes: false,
240
+ attributeNamePrefix: '',
241
+ allowBooleanAttributes: true,
242
+ });
243
+ const job = parser.parse(textXml).root.job;
244
+ if (job.result !== 'OK') {
245
+ throw new SDCardJobError(job.description);
246
+ }
247
+ return Number(job.progress);
240
248
  }
241
249
  async getParameter(paramNames, options) {
242
- const response = await this.postUrlEncoded('/axis-cgi/param.cgi', {
250
+ const response = await this._postUrlEncoded('/axis-cgi/param.cgi', {
243
251
  action: 'list',
244
252
  group: arrayToUrl(paramNames),
245
- }, undefined, options);
253
+ }, options);
246
254
  return VapixAPI.parseParameters(await response.text());
247
255
  }
248
256
  async setParameter(params, options) {
249
- const res = await this.postUrlEncoded('/axis-cgi/param.cgi', {
257
+ const res = await this._postUrlEncoded('/axis-cgi/param.cgi', {
250
258
  ...params,
251
259
  action: 'update',
252
- }, undefined, options);
260
+ }, options);
253
261
  const responseText = await res.text();
254
262
  if (responseText.startsWith('# Error')) {
255
263
  throw new SettingParameterError(responseText);
@@ -297,10 +305,10 @@ export class VapixAPI {
297
305
  return this.setParameter(params, options);
298
306
  }
299
307
  async getPTZPresetList(channel, options) {
300
- const res = await this.postUrlEncoded('/axis-cgi/com/ptz.cgi', {
308
+ const res = await this._postUrlEncoded('/axis-cgi/com/ptz.cgi', {
301
309
  query: 'presetposcam',
302
310
  camera: channel,
303
- }, undefined, options);
311
+ }, options);
304
312
  const text = await res.text();
305
313
  const lines = text.split(/[\r\n]/);
306
314
  const positions = [];
@@ -317,11 +325,11 @@ export class VapixAPI {
317
325
  }
318
326
  async listPTZ(camera, options) {
319
327
  const url = `/axis-cgi/com/ptz.cgi`;
320
- const response = await this.postUrlEncoded(url, {
328
+ const response = await this._postUrlEncoded(url, {
321
329
  camera,
322
330
  query: 'presetposcamdata',
323
331
  format: 'json',
324
- }, undefined, options);
332
+ }, options);
325
333
  const text = await response.text();
326
334
  if (text === '') {
327
335
  throw new PtzNotSupportedError();
@@ -329,10 +337,10 @@ export class VapixAPI {
329
337
  return VapixAPI.parseCameraPtzResponse(text)[camera] ?? [];
330
338
  }
331
339
  async listPtzVideoSourceOverview(options) {
332
- const response = await this.postUrlEncoded('/axis-cgi/com/ptz.cgi', {
340
+ const response = await this._postUrlEncoded('/axis-cgi/com/ptz.cgi', {
333
341
  query: 'presetposall',
334
342
  format: 'json',
335
- }, undefined, options);
343
+ }, options);
336
344
  const text = await response.text();
337
345
  if (text === '') {
338
346
  throw new PtzNotSupportedError();
@@ -349,17 +357,17 @@ export class VapixAPI {
349
357
  });
350
358
  return ptzOverviewSchema.parse(res);
351
359
  }
352
- goToPreset(channel, presetName, options) {
353
- return this.postUrlEncoded('/axis-cgi/com/ptz.cgi', {
360
+ async goToPreset(channel, presetName, options) {
361
+ await this._postUrlEncoded('/axis-cgi/com/ptz.cgi', {
354
362
  camera: channel.toString(),
355
363
  gotoserverpresetname: presetName,
356
- }, undefined, options);
364
+ }, options);
357
365
  }
358
366
  async getPtzPosition(camera, options) {
359
- const res = await this.postUrlEncoded('/axis-cgi/com/ptz.cgi', {
367
+ const res = await this._postUrlEncoded('/axis-cgi/com/ptz.cgi', {
360
368
  query: 'position',
361
369
  camera: camera.toString(),
362
- }, undefined, options);
370
+ }, options);
363
371
  const params = VapixAPI.parseParameters(await res.text());
364
372
  return cameraPTZItemDataSchema.parse({
365
373
  pan: Number(params.pan),
@@ -368,16 +376,16 @@ export class VapixAPI {
368
376
  });
369
377
  }
370
378
  async getPorts(options) {
371
- const res = await this.postJson('/axis-cgi/io/portmanagement.cgi', {
379
+ const res = await this._postJsonEncoded('/axis-cgi/io/portmanagement.cgi', {
372
380
  apiVersion: '1.0',
373
381
  context: '',
374
382
  method: 'getPorts',
375
383
  }, undefined, options);
376
384
  const portResponseParsed = getPortsResponseSchema.parse(await res.json());
377
- return portResponseParsed.data.items;
385
+ return portResponseParsed.data.items ?? [];
378
386
  }
379
387
  async setPorts(ports, options) {
380
- await this.postJson('/axis-cgi/io/portmanagement.cgi', {
388
+ await this._postJsonEncoded('/axis-cgi/io/portmanagement.cgi', {
381
389
  apiVersion: '1.0',
382
390
  context: '',
383
391
  method: 'setPorts',
@@ -385,13 +393,103 @@ export class VapixAPI {
385
393
  }, undefined, options);
386
394
  }
387
395
  async setPortStateSequence(port, sequence, options) {
388
- await this.postJson('/axis-cgi/io/portmanagement.cgi', {
396
+ await this._postJsonEncoded('/axis-cgi/io/portmanagement.cgi', {
389
397
  apiVersion: '1.0',
390
398
  context: '',
391
399
  method: 'setStateSequence',
392
400
  params: { port, sequence },
393
401
  }, undefined, options);
394
402
  }
403
+ async addCameraUser(username, pass, sgrp, comment, options) {
404
+ const res = await this._postUrlEncoded('/axis-cgi/pwdgrp.cgi', {
405
+ action: 'add',
406
+ user: username,
407
+ pwd: pass,
408
+ grp: 'users',
409
+ sgrp,
410
+ comment,
411
+ }, options);
412
+ await VapixAPI.checkTextResponseForError(res);
413
+ }
414
+ async getCameraUsers(options) {
415
+ const res = await this._postUrlEncoded('/axis-cgi/pwdgrp.cgi', {
416
+ action: 'get',
417
+ }, options);
418
+ const responseText = await VapixAPI.checkTextResponseForError(res);
419
+ const viewersString = responseText.match(/^viewer="([a-z0-9,]*)"/im)?.[1] ?? '';
420
+ return viewersString.split(',');
421
+ }
422
+ async editCameraUser(username, pass, options) {
423
+ const res = await this._postUrlEncoded('/axis-cgi/pwdgrp.cgi', {
424
+ action: 'update',
425
+ user: username,
426
+ pwd: pass,
427
+ }, options);
428
+ await VapixAPI.checkTextResponseForError(res);
429
+ }
430
+ async getRecordingRuleList(options) {
431
+ const res = await this._getText('/axis-cgi/record/continuous/listconfiguration.cgi', undefined, options);
432
+ const resultNode = VapixAPI.parseXmlResponse(res, 'continuousrecordingconfigurations');
433
+ const configurationNodes = resultNode.getElementsByTagName('continuousrecordingconfiguration');
434
+ const configs = [];
435
+ for (const node of configurationNodes) {
436
+ if (isNullish(node)) {
437
+ continue;
438
+ }
439
+ configs.push({
440
+ profile: node.getAttribute('profile') ?? '',
441
+ diskid: node.getAttribute('diskid') ?? '',
442
+ options: VapixAPI.parseQueryString(node.getAttribute('options')),
443
+ eventid: node.getAttribute('eventid') ?? '',
444
+ });
445
+ }
446
+ return configs;
447
+ }
448
+ async addRecordingRule(params, options) {
449
+ const res = await this._getText('/axis-cgi/record/continuous/addconfiguration.cgi', params, options);
450
+ const resultNode = VapixAPI.parseXmlResponse(res, 'configure');
451
+ const result = resultNode.getAttribute('result');
452
+ if (result !== 'OK') {
453
+ throw new Error(resultNode.getAttribute('errormsg') ?? result ?? 'Unknown error');
454
+ }
455
+ return resultNode.getAttribute('profile');
456
+ }
457
+ async removeRecordingRule(profileId, options) {
458
+ const res = await this._getText('/axis-cgi/record/continuous/removeconfiguration.cgi', {
459
+ profile: profileId,
460
+ }, options);
461
+ const resultNode = VapixAPI.parseXmlResponse(res, 'remove');
462
+ const result = resultNode.getAttribute('result');
463
+ if (result !== 'OK') {
464
+ throw new Error(resultNode.getAttribute('errormsg') ?? result ?? 'Unknown error');
465
+ }
466
+ }
467
+ async getDiskInfo(diskId = 'all', options) {
468
+ const res = await this._getText('/axis-cgi/disks/list.cgi', {
469
+ diskid: diskId,
470
+ }, options);
471
+ const resultNode = VapixAPI.parseXmlResponse(res, 'disks');
472
+ const disks = resultNode.getElementsByTagName('disk');
473
+ if (isNullish(disks) || disks.length === 0) {
474
+ return false;
475
+ }
476
+ const requiredReadyProps = {
477
+ status: 'OK',
478
+ locked: 'no',
479
+ readonly: 'no',
480
+ };
481
+ for (const disk of disks) {
482
+ let isReady = true;
483
+ for (const name in requiredReadyProps) {
484
+ const value = disk.getAttribute(name);
485
+ isReady = isReady && requiredReadyProps[name] === value;
486
+ }
487
+ if (isReady) {
488
+ return true;
489
+ }
490
+ }
491
+ return false;
492
+ }
395
493
  async getApplicationList(options) {
396
494
  const agent = this.getClient(options?.proxyParams);
397
495
  const res = await agent.get({ path: '/axis-cgi/applications/list.cgi', timeout: options?.timeout });
@@ -409,7 +507,7 @@ export class VapixAPI {
409
507
  const appList = apps.map((app) => {
410
508
  return {
411
509
  ...app,
412
- appId: APP_IDS.find((id) => id.toLowerCase() === app.Name.toLowerCase()) ?? null,
510
+ appId: ALL_APP_IDS.find((id) => id.toLowerCase() === app.Name.toLowerCase()) ?? null,
413
511
  };
414
512
  });
415
513
  return applicationListSchema.parse(appList);
@@ -469,7 +567,7 @@ export class VapixAPI {
469
567
  headers: {
470
568
  contentType: 'application/octet-stream',
471
569
  },
472
- timeout: options?.timeout ?? 120000,
570
+ timeout: options?.timeout ?? 300000,
473
571
  });
474
572
  if (!res.ok) {
475
573
  throw new ErrorWithResponse(res);
@@ -479,6 +577,21 @@ export class VapixAPI {
479
577
  throw new ApplicationAPIError('INSTALL', text);
480
578
  }
481
579
  }
580
+ static parseQueryString = (queryString) => {
581
+ const entries = queryString
582
+ ?.split('&')
583
+ .filter((x) => x !== '')
584
+ .map((x) => x.split('=', 2));
585
+ return !isNullish(entries) ? Object.fromEntries(entries) : {};
586
+ };
587
+ static checkTextResponseForError = async (response) => {
588
+ const responseText = await response.text();
589
+ const isError = responseText.match(/Error:([^<]*)/);
590
+ if (!isNullish(isError)) {
591
+ throw new ErrorWithResponse(response);
592
+ }
593
+ return responseText;
594
+ };
482
595
  static parseParameters = (response) => {
483
596
  const params = {};
484
597
  const lines = response.split(/[\r\n]/);
@@ -545,4 +658,12 @@ export class VapixAPI {
545
658
  });
546
659
  return res;
547
660
  };
661
+ static parseXmlResponse = (xml, nodeName) => {
662
+ const doc = new DOMParser().parseFromString(xml, 'text/xml');
663
+ const node = doc.getElementsByTagName(nodeName);
664
+ if (node.length !== 1 || isNullish(node[0])) {
665
+ throw new Error('Invalid XML from camera');
666
+ }
667
+ return node[0];
668
+ };
548
669
  }
@@ -176,11 +176,15 @@ export class BadRequestError extends ErrorWithResponse {
176
176
  }
177
177
  export class MigrationError extends Error {
178
178
  valid;
179
+ old;
179
180
  invalid;
180
- constructor(valid, invalid) {
181
+ unknown;
182
+ constructor(valid, old, invalid = [], unknown = []) {
181
183
  super('Migration to newer version is needed: some stream entries failed to parse.');
182
184
  this.name = 'MigrationError';
183
185
  this.valid = valid;
186
+ this.old = old;
184
187
  this.invalid = invalid;
188
+ this.unknown = unknown;
185
189
  }
186
190
  }
package/esm/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './errors/errors';
2
2
  export * from './internal/types';
3
3
  export * from './internal/constants';
4
+ export * from './internal/convertors';
4
5
  export * from './internal/utils';
5
6
  export * from './internal/versionCompare';
6
7
  export * from './internal/ProxyClient';
@@ -0,0 +1,89 @@
1
+ import { ErrorWithResponse, ParsingBlobError } from '../errors/errors';
2
+ import { ProxyClient } from './ProxyClient';
3
+ import { paramToUrl } from './utils';
4
+ export class BasicAPI {
5
+ client;
6
+ constructor(client) {
7
+ this.client = client;
8
+ }
9
+ getClient(proxyParams) {
10
+ return proxyParams ? new ProxyClient(this.client, proxyParams) : this.client;
11
+ }
12
+ async _getJson(path, parameters, options) {
13
+ const agent = this.getClient(options?.proxyParams);
14
+ const res = await agent.get({ path, parameters, timeout: options?.timeout });
15
+ if (res.ok) {
16
+ return await res.json();
17
+ }
18
+ else {
19
+ throw new ErrorWithResponse(res);
20
+ }
21
+ }
22
+ async _getText(path, parameters, options) {
23
+ const agent = this.getClient(options?.proxyParams);
24
+ const res = await agent.get({ path, parameters, timeout: options?.timeout });
25
+ if (res.ok) {
26
+ return await res.text();
27
+ }
28
+ else {
29
+ throw new ErrorWithResponse(res);
30
+ }
31
+ }
32
+ async _getBlob(path, parameters, options) {
33
+ const agent = this.getClient(options?.proxyParams);
34
+ const res = await agent.get({ path, parameters, timeout: options?.timeout });
35
+ if (res.ok) {
36
+ return await this.parseBlobResponse(res);
37
+ }
38
+ else {
39
+ throw new ErrorWithResponse(res);
40
+ }
41
+ }
42
+ async parseBlobResponse(response) {
43
+ try {
44
+ return (await response.blob());
45
+ }
46
+ catch (err) {
47
+ throw new ParsingBlobError(err);
48
+ }
49
+ }
50
+ async _post(path, data, parameters, options, headers) {
51
+ const agent = this.getClient(options?.proxyParams);
52
+ const res = await agent.post({ path, data, parameters, headers, timeout: options?.timeout });
53
+ if (res.ok) {
54
+ return await res.json();
55
+ }
56
+ else {
57
+ throw new ErrorWithResponse(res);
58
+ }
59
+ }
60
+ async _postJsonEncoded(path, data, parameters, options) {
61
+ const agent = this.getClient(options?.proxyParams);
62
+ const jsonData = JSON.stringify(data);
63
+ const res = await agent.post({
64
+ path,
65
+ data: jsonData,
66
+ parameters,
67
+ headers: { 'Content-Type': 'application/json' },
68
+ timeout: options?.timeout,
69
+ });
70
+ if (!res.ok) {
71
+ throw new ErrorWithResponse(res);
72
+ }
73
+ return res;
74
+ }
75
+ async _postUrlEncoded(path, data, options) {
76
+ const encodedData = paramToUrl(data);
77
+ const agent = this.getClient(options?.proxyParams);
78
+ const res = await agent.post({
79
+ path,
80
+ data: encodedData,
81
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
82
+ timeout: options?.timeout,
83
+ });
84
+ if (!res.ok) {
85
+ throw new ErrorWithResponse(res);
86
+ }
87
+ return res;
88
+ }
89
+ }
@@ -34,6 +34,11 @@ export class WsEvents {
34
34
  }
35
35
  }
36
36
  }
37
+ removeAllListenersForId(id) {
38
+ for (const type in this.listeners) {
39
+ this.removeListener(type, id);
40
+ }
41
+ }
37
42
  onMessage(incomeData) {
38
43
  if (this.isDestroyed) {
39
44
  return;
@@ -1 +1,2 @@
1
1
  export const FIRMWARE_WITH_BITRATE_MODES_SUPPORT = '11.11.73';
2
+ export const FIRMWARE_WITH_OVERLAYS_SUPPORT = '10.7.0';