@iobroker/adapter-react-v5 7.0.2 → 7.1.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 (307) hide show
  1. package/Components/404.d.ts +3 -2
  2. package/Components/404.js +3 -2
  3. package/Components/ColorPicker.d.ts +22 -8
  4. package/Components/ColorPicker.js +34 -17
  5. package/Components/ComplexCron.js +24 -24
  6. package/Components/CopyToClipboard.d.ts +10 -1
  7. package/Components/CopyToClipboard.js +17 -8
  8. package/Components/CustomModal.d.ts +1 -1
  9. package/Components/CustomModal.js +8 -8
  10. package/Components/FileBrowser.d.ts +11 -11
  11. package/Components/FileBrowser.js +135 -152
  12. package/Components/FileViewer.js +34 -23
  13. package/Components/Icon.d.ts +16 -2
  14. package/Components/Icon.js +19 -8
  15. package/Components/IconPicker.js +10 -14
  16. package/Components/IconSelector.d.ts +1 -1
  17. package/Components/IconSelector.js +64 -74
  18. package/Components/Image.d.ts +8 -4
  19. package/Components/Image.js +13 -32
  20. package/Components/Loader.d.ts +2 -2
  21. package/Components/Loader.js +21 -18
  22. package/Components/Loaders/MV.d.ts +6 -1
  23. package/Components/Loaders/MV.js +23 -7
  24. package/Components/Loaders/PT.d.ts +7 -2
  25. package/Components/Loaders/PT.js +20 -7
  26. package/Components/Loaders/Vendor.d.ts +2 -2
  27. package/Components/Loaders/Vendor.js +15 -7
  28. package/Components/Logo.js +16 -18
  29. package/Components/MDUtils.d.ts +1 -1
  30. package/Components/MDUtils.js +8 -4
  31. package/Components/ObjectBrowser.d.ts +40 -39
  32. package/Components/ObjectBrowser.js +550 -435
  33. package/Components/Router.d.ts +1 -3
  34. package/Components/Router.js +3 -1
  35. package/Components/SaveCloseButtons.d.ts +3 -3
  36. package/Components/SaveCloseButtons.js +3 -3
  37. package/Components/Schedule.d.ts +15 -15
  38. package/Components/Schedule.js +177 -154
  39. package/Components/SelectWithIcon.d.ts +2 -2
  40. package/Components/SelectWithIcon.js +45 -34
  41. package/Components/SimpleCron/index.js +83 -43
  42. package/Components/TabContainer.js +2 -2
  43. package/Components/TabContent.js +1 -1
  44. package/Components/TabHeader.js +1 -1
  45. package/Components/TableResize.d.ts +2 -2
  46. package/Components/TableResize.js +5 -5
  47. package/Components/TextWithIcon.d.ts +1 -1
  48. package/Components/TextWithIcon.js +10 -8
  49. package/Components/ToggleThemeMenu.d.ts +2 -2
  50. package/Components/ToggleThemeMenu.js +3 -3
  51. package/Components/TreeTable.d.ts +18 -18
  52. package/Components/TreeTable.js +76 -72
  53. package/Components/UploadImage.d.ts +2 -2
  54. package/Components/UploadImage.js +25 -21
  55. package/Components/Utils.d.ts +42 -22
  56. package/Components/Utils.js +66 -65
  57. package/Components/withWidth.d.ts +2 -2
  58. package/Components/withWidth.js +10 -6
  59. package/Dialogs/ComplexCron.d.ts +2 -2
  60. package/Dialogs/ComplexCron.js +3 -3
  61. package/Dialogs/Confirm.d.ts +4 -4
  62. package/Dialogs/Confirm.js +18 -8
  63. package/Dialogs/Cron.d.ts +3 -3
  64. package/Dialogs/Cron.js +21 -17
  65. package/Dialogs/Error.d.ts +3 -3
  66. package/Dialogs/Error.js +6 -4
  67. package/Dialogs/Message.d.ts +3 -3
  68. package/Dialogs/Message.js +6 -4
  69. package/Dialogs/SelectFile.d.ts +4 -4
  70. package/Dialogs/SelectFile.js +6 -4
  71. package/Dialogs/SelectID.d.ts +12 -10
  72. package/Dialogs/SelectID.js +12 -8
  73. package/Dialogs/SimpleCron.d.ts +2 -2
  74. package/Dialogs/SimpleCron.js +2 -2
  75. package/Dialogs/TextInput.d.ts +2 -2
  76. package/Dialogs/TextInput.js +3 -3
  77. package/GenericApp.d.ts +19 -13
  78. package/GenericApp.js +128 -85
  79. package/LegacyConnection.d.ts +240 -248
  80. package/LegacyConnection.js +500 -525
  81. package/README.md +1264 -1171
  82. package/Theme.d.ts +1 -1
  83. package/Theme.js +9 -12
  84. package/assets/devices.json +1 -0
  85. package/assets/rooms.json +1 -0
  86. package/craco-module-federation.js +3 -12
  87. package/i18n/de.json +434 -434
  88. package/i18n/en.json +434 -434
  89. package/i18n/es.json +434 -434
  90. package/i18n/fr.json +434 -434
  91. package/i18n/it.json +434 -434
  92. package/i18n/nl.json +434 -434
  93. package/i18n/pl.json +434 -434
  94. package/i18n/pt.json +434 -434
  95. package/i18n/ru.json +434 -434
  96. package/i18n/uk.json +434 -434
  97. package/i18n/zh-cn.json +434 -434
  98. package/i18n.d.ts +26 -19
  99. package/i18n.js +28 -22
  100. package/icons/IconAdapter.js +2 -2
  101. package/icons/IconAlias.js +2 -2
  102. package/icons/IconChannel.js +2 -2
  103. package/icons/IconClearFilter.js +2 -2
  104. package/icons/IconClosed.js +2 -2
  105. package/icons/IconCopy.js +2 -2
  106. package/icons/IconDevice.js +2 -2
  107. package/icons/IconDocument.js +2 -2
  108. package/icons/IconDocumentReadOnly.js +2 -2
  109. package/icons/IconExpert.js +2 -2
  110. package/icons/IconFx.js +2 -2
  111. package/icons/IconInstance.js +2 -2
  112. package/icons/IconLogout.js +2 -2
  113. package/icons/IconNoIcon.js +2 -2
  114. package/icons/IconOpen.d.ts +2 -2
  115. package/icons/IconOpen.js +2 -2
  116. package/icons/IconProps.d.ts +4 -3
  117. package/icons/IconState.d.ts +2 -2
  118. package/icons/IconState.js +2 -2
  119. package/index.css +3 -2
  120. package/package.json +4 -4
  121. package/src/Components/404.tsx +32 -31
  122. package/src/Components/ColorPicker.tsx +142 -114
  123. package/src/Components/ComplexCron.tsx +174 -137
  124. package/src/Components/CopyToClipboard.tsx +22 -9
  125. package/src/Components/CustomModal.tsx +76 -69
  126. package/src/Components/FileBrowser.tsx +959 -852
  127. package/src/Components/FileViewer.tsx +146 -127
  128. package/src/Components/Icon.tsx +80 -52
  129. package/src/Components/IconPicker.tsx +83 -67
  130. package/src/Components/IconSelector.tsx +159 -141
  131. package/src/Components/Image.tsx +43 -26
  132. package/src/Components/Loader.tsx +56 -32
  133. package/src/Components/Logo.tsx +62 -52
  134. package/src/Components/MDUtils.tsx +10 -6
  135. package/src/Components/ObjectBrowser.tsx +3198 -2478
  136. package/src/Components/Router.tsx +11 -11
  137. package/src/Components/SaveCloseButtons.tsx +43 -39
  138. package/src/Components/Schedule.tsx +1091 -853
  139. package/src/Components/SelectWithIcon.tsx +135 -93
  140. package/src/Components/TabContainer.tsx +22 -20
  141. package/src/Components/TabContent.tsx +13 -12
  142. package/src/Components/TabHeader.tsx +10 -9
  143. package/src/Components/TableResize.tsx +52 -37
  144. package/src/Components/TextWithIcon.tsx +30 -19
  145. package/src/Components/ToggleThemeMenu.tsx +31 -13
  146. package/src/Components/TreeTable.tsx +468 -385
  147. package/src/Components/UploadImage.tsx +153 -121
  148. package/src/Components/Utils.tsx +135 -127
  149. package/src/Components/loader.css +40 -31
  150. package/src/Components/withWidth.tsx +23 -12
  151. package/src/Connection.tsx +1 -3
  152. package/src/Dialogs/ComplexCron.tsx +55 -61
  153. package/src/Dialogs/Confirm.tsx +88 -65
  154. package/src/Dialogs/Cron.tsx +122 -112
  155. package/src/Dialogs/Error.tsx +37 -42
  156. package/src/Dialogs/Message.tsx +39 -37
  157. package/src/Dialogs/SelectFile.tsx +95 -85
  158. package/src/Dialogs/SelectID.tsx +141 -129
  159. package/src/Dialogs/SimpleCron.tsx +44 -44
  160. package/src/Dialogs/TextInput.tsx +60 -68
  161. package/src/GenericApp.tsx +342 -242
  162. package/src/LegacyConnection.tsx +972 -842
  163. package/src/Prompt.tsx +3 -1
  164. package/src/Theme.tsx +19 -26
  165. package/src/icons/IconAdapter.tsx +16 -14
  166. package/src/icons/IconAlias.tsx +16 -14
  167. package/src/icons/IconChannel.tsx +55 -16
  168. package/src/icons/IconClearFilter.tsx +17 -15
  169. package/src/icons/IconClosed.tsx +16 -11
  170. package/src/icons/IconCopy.tsx +16 -11
  171. package/src/icons/IconDevice.tsx +121 -22
  172. package/src/icons/IconDocument.tsx +16 -11
  173. package/src/icons/IconDocumentReadOnly.tsx +21 -12
  174. package/src/icons/IconExpert.tsx +20 -12
  175. package/src/icons/IconFx.tsx +16 -14
  176. package/src/icons/IconInstance.tsx +16 -14
  177. package/src/icons/IconLogout.tsx +20 -18
  178. package/src/icons/IconNoIcon.tsx +16 -14
  179. package/src/icons/IconOpen.tsx +17 -12
  180. package/src/icons/IconProps.tsx +4 -3
  181. package/src/icons/IconState.tsx +34 -13
  182. package/src/index.css +3 -2
  183. package/tasks.js +91 -0
  184. package/types.d.ts +141 -0
  185. package/Components/Loaders/PT.css +0 -109
  186. package/Components/Loaders/Vendor.css +0 -13
  187. package/Components/loader.css +0 -222
  188. package/Components/types.d.ts +0 -82
  189. package/assets/devices/Alarm Systems.svg +0 -19
  190. package/assets/devices/Amplifier.svg +0 -22
  191. package/assets/devices/Awnings.svg +0 -5
  192. package/assets/devices/Battery Status.svg +0 -5
  193. package/assets/devices/Ceiling Spotlights.svg +0 -16
  194. package/assets/devices/Chandelier.svg +0 -7
  195. package/assets/devices/Climate.svg +0 -12
  196. package/assets/devices/Coffee Makers.svg +0 -6
  197. package/assets/devices/Cold Water.svg +0 -31
  198. package/assets/devices/Computer.svg +0 -21
  199. package/assets/devices/Consumption.svg +0 -8
  200. package/assets/devices/Curtains.svg +0 -43
  201. package/assets/devices/Dishwashers.svg +0 -12
  202. package/assets/devices/Doors.svg +0 -6
  203. package/assets/devices/Doorstep.svg +0 -35
  204. package/assets/devices/Dryer.svg +0 -14
  205. package/assets/devices/Fan.svg +0 -20
  206. package/assets/devices/Floor Lamps.svg +0 -5
  207. package/assets/devices/Garage Doors.svg +0 -9
  208. package/assets/devices/Gates.svg +0 -32
  209. package/assets/devices/Hairdryer.svg +0 -23
  210. package/assets/devices/Handle.svg +0 -6
  211. package/assets/devices/Hanging Lamps.svg +0 -9
  212. package/assets/devices/Heater.svg +0 -44
  213. package/assets/devices/Hoods.svg +0 -12
  214. package/assets/devices/Hot Water.svg +0 -10
  215. package/assets/devices/Humidity.svg +0 -41
  216. package/assets/devices/Iron.svg +0 -5
  217. package/assets/devices/Irrigation.svg +0 -23
  218. package/assets/devices/Led Strip.svg +0 -31
  219. package/assets/devices/Light.svg +0 -30
  220. package/assets/devices/Lightings.svg +0 -46
  221. package/assets/devices/Lock.svg +0 -19
  222. package/assets/devices/Louvre.svg +0 -7
  223. package/assets/devices/Mowing Machine.svg +0 -9
  224. package/assets/devices/Music.svg +0 -13
  225. package/assets/devices/Outdoor Blinds.svg +0 -7
  226. package/assets/devices/People.svg +0 -19
  227. package/assets/devices/Pool.svg +0 -8
  228. package/assets/devices/Power Consumption.svg +0 -13
  229. package/assets/devices/Printer.svg +0 -10
  230. package/assets/devices/Pump.svg +0 -10
  231. package/assets/devices/Receiver.svg +0 -19
  232. package/assets/devices/Sconces.svg +0 -10
  233. package/assets/devices/Security.svg +0 -34
  234. package/assets/devices/Shading.svg +0 -5
  235. package/assets/devices/Shutters.svg +0 -11
  236. package/assets/devices/SmokeDetector.svg +0 -13
  237. package/assets/devices/Sockets.svg +0 -13
  238. package/assets/devices/Speaker.svg +0 -35
  239. package/assets/devices/Stove.svg +0 -12
  240. package/assets/devices/Table Lamps.svg +0 -12
  241. package/assets/devices/Temperature Sensors.svg +0 -28
  242. package/assets/devices/Tv.svg +0 -8
  243. package/assets/devices/Vacuum Cleaner.svg +0 -16
  244. package/assets/devices/Ventilation.svg +0 -12
  245. package/assets/devices/Washing Machines.svg +0 -16
  246. package/assets/devices/Water Consumption.svg +0 -6
  247. package/assets/devices/Water Heater.svg +0 -8
  248. package/assets/devices/Water.svg +0 -40
  249. package/assets/devices/Weather.svg +0 -28
  250. package/assets/devices/Window.svg +0 -8
  251. package/assets/rooms/Anteroom.svg +0 -53
  252. package/assets/rooms/Attic.svg +0 -21
  253. package/assets/rooms/Balcony.svg +0 -13
  254. package/assets/rooms/Barn.svg +0 -6
  255. package/assets/rooms/Basement.svg +0 -5
  256. package/assets/rooms/Bathroom.svg +0 -38
  257. package/assets/rooms/Bedroom.svg +0 -5
  258. package/assets/rooms/Boiler Room.svg +0 -13
  259. package/assets/rooms/Carport.svg +0 -17
  260. package/assets/rooms/Cellar.svg +0 -89
  261. package/assets/rooms/Chamber.svg +0 -9
  262. package/assets/rooms/Corridor.svg +0 -53
  263. package/assets/rooms/Dining Area.svg +0 -37
  264. package/assets/rooms/Dining Room.svg +0 -37
  265. package/assets/rooms/Dining.svg +0 -37
  266. package/assets/rooms/Dressing Room.svg +0 -5
  267. package/assets/rooms/Driveway.svg +0 -15
  268. package/assets/rooms/Entrance.svg +0 -44
  269. package/assets/rooms/Equipment Room.svg +0 -15
  270. package/assets/rooms/Front Yard.svg +0 -64
  271. package/assets/rooms/Gallery.svg +0 -14
  272. package/assets/rooms/Garage.svg +0 -20
  273. package/assets/rooms/Garden.svg +0 -13
  274. package/assets/rooms/Ground Floor.svg +0 -95
  275. package/assets/rooms/Guest Bathroom.svg +0 -33
  276. package/assets/rooms/Guest Room.svg +0 -5
  277. package/assets/rooms/Gym.svg +0 -5
  278. package/assets/rooms/Hall.svg +0 -19
  279. package/assets/rooms/Home Theater.svg +0 -8
  280. package/assets/rooms/Kitchen.svg +0 -18
  281. package/assets/rooms/Laundry Room.svg +0 -12
  282. package/assets/rooms/Living Area.svg +0 -11
  283. package/assets/rooms/Living Room.svg +0 -10
  284. package/assets/rooms/Locker Room.svg +0 -17
  285. package/assets/rooms/Nursery.svg +0 -5
  286. package/assets/rooms/Office.svg +0 -8
  287. package/assets/rooms/Outdoors.svg +0 -7
  288. package/assets/rooms/Playroom.svg +0 -6
  289. package/assets/rooms/Pool.svg +0 -8
  290. package/assets/rooms/Rear Wall.svg +0 -30
  291. package/assets/rooms/Second Floor.svg +0 -95
  292. package/assets/rooms/Shed.svg +0 -16
  293. package/assets/rooms/Sleeping Area.svg +0 -22
  294. package/assets/rooms/Stairway.svg +0 -5
  295. package/assets/rooms/Stairwell.svg +0 -15
  296. package/assets/rooms/Storeroom.svg +0 -5
  297. package/assets/rooms/Summer House.svg +0 -27
  298. package/assets/rooms/Swimming Pool.svg +0 -21
  299. package/assets/rooms/Terrace.svg +0 -7
  300. package/assets/rooms/Toilet.svg +0 -10
  301. package/assets/rooms/Upstairs.svg +0 -6
  302. package/assets/rooms/Wardrobe.svg +0 -60
  303. package/assets/rooms/Washroom.svg +0 -20
  304. package/assets/rooms/Wc.svg +0 -10
  305. package/assets/rooms/Windscreen.svg +0 -60
  306. package/assets/rooms/Workshop.svg +0 -23
  307. package/assets/rooms/Workspace.svg +0 -8
@@ -3,10 +3,11 @@
3
3
  *
4
4
  * MIT License
5
5
  *
6
- * */
6
+ */
7
7
 
8
8
  import { type HostInfo } from '@iobroker/js-controller-common-db/build/esm/lib/common/tools';
9
9
  import { type FilteredNotificationInformation } from '@iobroker/js-controller-common/build/esm/lib/common/notificationHandler';
10
+ import type { IoBJson } from '@iobroker/types/build/config';
10
11
 
11
12
  declare global {
12
13
  interface Window {
@@ -18,6 +19,32 @@ declare global {
18
19
  }
19
20
  }
20
21
 
22
+ export type CompactSystemRepositoryEntry = {
23
+ link: string;
24
+ hash?: string;
25
+ stable?: boolean;
26
+ json:
27
+ | {
28
+ _repoInfo: {
29
+ stable?: boolean;
30
+ name?: ioBroker.StringOrTranslated;
31
+ };
32
+ }
33
+ | null
34
+ | undefined;
35
+ };
36
+
37
+ export type CompactSystemRepository = {
38
+ _id: ioBroker.HostObject['_id'];
39
+ common: {
40
+ name: ioBroker.HostCommon['name'];
41
+ dontDelete: boolean;
42
+ };
43
+ native: {
44
+ repositories: Record<string, CompactSystemRepositoryEntry>;
45
+ };
46
+ };
47
+
21
48
  /** Possible progress states. */
22
49
  export const PROGRESS = {
23
50
  /** The socket is connecting. */
@@ -33,7 +60,7 @@ export const PROGRESS = {
33
60
  };
34
61
 
35
62
  const PERMISSION_ERROR = 'permissionError';
36
- const NOT_CONNECTED = 'notConnectedError';
63
+ const NOT_CONNECTED = 'notConnectedError';
37
64
  const TIMEOUT_FOR_ADMIN4 = 1300;
38
65
 
39
66
  export const ERRORS = {
@@ -41,10 +68,7 @@ export const ERRORS = {
41
68
  NOT_CONNECTED,
42
69
  };
43
70
 
44
- export type BinaryStateChangeHandler = (
45
- id: string,
46
- base64: string | null,
47
- ) => void;
71
+ export type BinaryStateChangeHandler = (id: string, base64: string | null) => void;
48
72
 
49
73
  function fixAdminUI(obj: ioBroker.AdapterObject): ioBroker.AdapterObject {
50
74
  // @ts-expect-error it is deprecated, but still could appear
@@ -98,7 +122,12 @@ function fixAdminUI(obj: ioBroker.AdapterObject): ioBroker.AdapterObject {
98
122
  }
99
123
 
100
124
  // @ts-expect-error it is deprecated, but still could appear
101
- obj.common.adminUI && console.debug(`Please add to "${obj._id.replace(/\.\d+$/, '')}" common.adminUI=${JSON.stringify(obj.common.adminUI)}`);
125
+ if (obj.common.adminUI) {
126
+ console.debug(
127
+ // @ts-expect-error it is deprecated, but still could appear
128
+ `Please add to "${obj._id.replace(/\.\d+$/, '')}" common.adminUI=${JSON.stringify(obj.common.adminUI)}`,
129
+ );
130
+ }
102
131
  }
103
132
  return obj;
104
133
  }
@@ -110,9 +139,7 @@ export function pattern2RegEx(pattern: string): string {
110
139
  const startsWithWildcard = pattern[0] === '*';
111
140
  const endsWithWildcard = pattern[pattern.length - 1] === '*';
112
141
 
113
- pattern = pattern
114
- .replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&')
115
- .replace(/\*/g, '.*');
142
+ pattern = pattern.replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '.*');
116
143
 
117
144
  return (startsWithWildcard ? '' : '^') + pattern + (endsWithWildcard ? '' : '$');
118
145
  }
@@ -166,7 +193,7 @@ export interface ConnectOptions {
166
193
  uuid?: string;
167
194
  }
168
195
 
169
- export interface SocketClient{
196
+ export interface SocketClient {
170
197
  connect(url?: string, options?: ConnectOptions): void;
171
198
  close(): void;
172
199
  destroy(): void;
@@ -200,7 +227,7 @@ interface Promises {
200
227
  cert?: Promise<{ name: string; type: 'public' | 'private' | 'chained' | '' }[]> | null;
201
228
  webName?: Promise<string> | null;
202
229
  compactInstances?: Promise<Record<string, ioBroker.InstanceObject>> | null;
203
- getCompactSystemRepositories?: Promise<ioBroker.Object> | null;
230
+ getCompactSystemRepositories?: Promise<CompactSystemRepository> | null;
204
231
  systemConfigPromise?: Promise<ioBroker.SystemConfigObject> | null;
205
232
  hostsCompact?: Promise<ioBroker.HostObject[]> | null;
206
233
  uuid?: Promise<string | undefined>;
@@ -229,7 +256,13 @@ class Connection {
229
256
 
230
257
  private _promises: Promises = {};
231
258
 
232
- private readonly _instanceSubscriptions: Record<string, {messageType: string; callback: (data: Record<string, any>, sourceInstance: string, messageType: string) => void }[]>;
259
+ private readonly _instanceSubscriptions: Record<
260
+ string,
261
+ {
262
+ messageType: string;
263
+ callback: (data: Record<string, any>, sourceInstance: string, messageType: string) => void;
264
+ }[]
265
+ >;
233
266
 
234
267
  private props: ConnectionProps;
235
268
 
@@ -251,24 +284,40 @@ class Connection {
251
284
 
252
285
  private connected: boolean = false;
253
286
 
254
- private readonly statesSubscribes: Record<string, { reg: RegExp; cbs: (ioBroker.StateChangeHandler | BinaryStateChangeHandler)[] }> = {};
287
+ private readonly statesSubscribes: Record<
288
+ string,
289
+ { reg: RegExp; cbs: (ioBroker.StateChangeHandler | BinaryStateChangeHandler)[] }
290
+ > = {};
255
291
 
256
- private readonly objectsSubscribes: Record<string, { reg: RegExp; cbs: ((id: string, obj: ioBroker.Object | null | undefined, oldObj?: ioBroker.Object | null) => void)[] }> = {};
292
+ private readonly objectsSubscribes: Record<
293
+ string,
294
+ {
295
+ reg: RegExp;
296
+ cbs: ((id: string, obj: ioBroker.Object | null | undefined, oldObj?: ioBroker.Object | null) => void)[];
297
+ }
298
+ > = {};
257
299
 
258
- private readonly filesSubscribes: Record<string, { regId: RegExp; cbs: ioBroker.FileChangeHandler[]; regFilePattern: RegExp }> = {};
300
+ private readonly filesSubscribes: Record<
301
+ string,
302
+ { regId: RegExp; cbs: ioBroker.FileChangeHandler[]; regFilePattern: RegExp }
303
+ > = {};
259
304
 
260
305
  private onConnectionHandlers: ((connected: boolean) => void)[] = [];
261
306
 
262
307
  private onLogHandlers: ((message: string) => void)[] = [];
263
308
 
264
- private readonly onProgress: ((progress: number) => void);
309
+ private readonly onProgress: (progress: number) => void;
265
310
 
266
- private readonly onError: ((err: string | {
267
- message: string;
268
- operation: string;
269
- type: string;
270
- id: string;
271
- }) => void);
311
+ private readonly onError: (
312
+ err:
313
+ | string
314
+ | {
315
+ message: string;
316
+ operation: string;
317
+ type: string;
318
+ id: string;
319
+ },
320
+ ) => void;
272
321
 
273
322
  private loaded: boolean = false;
274
323
 
@@ -299,34 +348,42 @@ class Connection {
299
348
  public systemConfig: ioBroker.SystemConfigObject | null = null;
300
349
 
301
350
  constructor(props: ConnectionProps) {
302
- props = props || { protocol: window.location.protocol, host: window.location.hostname };
303
- this.props = props;
351
+ props = props || { protocol: window.location.protocol, host: window.location.hostname };
352
+ this.props = props;
304
353
 
305
- this.autoSubscribes = this.props.autoSubscribes || [];
354
+ this.autoSubscribes = this.props.autoSubscribes || [];
306
355
  this.autoSubscribeLog = this.props.autoSubscribeLog || false;
307
356
 
308
- this.props.protocol = this.props.protocol || window.location.protocol;
309
- this.props.host = this.props.host || window.location.hostname;
310
- this.props.port = this.props.port || (window.location.port === '3000' ? (Connection.isWeb() ? 8082 : 8081) : window.location.port);
311
- this.props.ioTimeout = Math.max(this.props.ioTimeout || 20000, 20000);
357
+ this.props.protocol = this.props.protocol || window.location.protocol;
358
+ this.props.host = this.props.host || window.location.hostname;
359
+ this.props.port =
360
+ this.props.port ||
361
+ (window.location.port === '3000' ? (Connection.isWeb() ? 8082 : 8081) : window.location.port);
362
+ this.props.ioTimeout = Math.max(this.props.ioTimeout || 20000, 20000);
312
363
  this.props.cmdTimeout = Math.max(this.props.cmdTimeout || 5000, 5000);
313
364
  this._instanceSubscriptions = {};
314
365
 
315
366
  // breaking change. Do not load all objects by default is true
316
367
  this.doNotLoadAllObjects = this.props.doNotLoadAllObjects === undefined ? true : this.props.doNotLoadAllObjects;
317
- this.doNotLoadACL = this.props.doNotLoadACL === undefined ? true : this.props.doNotLoadACL;
368
+ this.doNotLoadACL = this.props.doNotLoadACL === undefined ? true : this.props.doNotLoadACL;
318
369
 
319
370
  this.states = {};
320
371
  this._waitForFirstConnection = new Promise(resolve => {
321
372
  this._waitForFirstConnectionResolve = resolve;
322
373
  });
323
374
  this.onProgress = this.props.onProgress || (() => {});
324
- this.onError = this.props.onError || ((err: string | {
325
- message: string;
326
- operation: string;
327
- type: string;
328
- id: string;
329
- }) => console.error(err));
375
+ this.onError =
376
+ this.props.onError ||
377
+ ((
378
+ err:
379
+ | string
380
+ | {
381
+ message: string;
382
+ operation: string;
383
+ type: string;
384
+ id: string;
385
+ },
386
+ ) => console.error(err));
330
387
  this.admin5only = this.props.admin5only || false;
331
388
 
332
389
  this.startSocket();
@@ -334,15 +391,18 @@ class Connection {
334
391
 
335
392
  /**
336
393
  * Checks if this connection is running in a web adapter and not in an admin.
337
- * @returns {boolean} True if running in a web adapter or in a socketio adapter.
394
+ *
395
+ * @returns True if running in a web adapter or in a socketio adapter.
338
396
  */
339
397
  static isWeb(): boolean {
340
398
  const adapterName: string | undefined = window.adapterName;
341
- return adapterName === 'material' ||
399
+ return (
400
+ adapterName === 'material' ||
342
401
  adapterName === 'vis' ||
343
402
  adapterName?.startsWith('vis-') ||
344
403
  adapterName === 'echarts-show' ||
345
- window.socketUrl !== undefined;
404
+ window.socketUrl !== undefined
405
+ );
346
406
  }
347
407
 
348
408
  /**
@@ -379,15 +439,12 @@ class Connection {
379
439
  let protocol = this.props.protocol.replace(':', '');
380
440
  let path = window.location.pathname;
381
441
 
382
- if (
383
- window.location.hostname === 'iobroker.net' ||
384
- window.location.hostname === 'iobroker.pro'
385
- ) {
442
+ if (window.location.hostname === 'iobroker.net' || window.location.hostname === 'iobroker.pro') {
386
443
  path = '';
387
444
  } else {
388
445
  // if web adapter, socket io could be on another port or even host
389
446
  if (window.socketUrl) {
390
- const parsed = new URL(window.socketUrl as string);
447
+ const parsed = new URL((window as any).socketUrl as string);
391
448
  host = parsed.hostname;
392
449
  port = parsed.port;
393
450
  protocol = parsed.protocol.replace(':', '');
@@ -418,23 +475,20 @@ class Connection {
418
475
 
419
476
  const url = port ? `${protocol}://${host}:${port}${path}` : `${protocol}://${host}${path}`;
420
477
 
421
- this._socket = window.io.connect(
422
- url,
423
- {
424
- path: path.endsWith('/') ? `${path}socket.io` : `${path}/socket.io`,
425
- query: 'ws=true',
426
- name: this.props.name,
427
- timeout: this.props.ioTimeout,
428
- uuid: this.props.uuid,
429
- },
430
- );
478
+ this._socket = window.io.connect(url, {
479
+ path: path.endsWith('/') ? `${path}socket.io` : `${path}/socket.io`,
480
+ query: 'ws=true',
481
+ name: this.props.name,
482
+ timeout: this.props.ioTimeout,
483
+ uuid: this.props.uuid,
484
+ });
431
485
 
432
486
  this._socket.on('connect', (noTimeout: boolean | undefined) => {
433
487
  // If the user is not admin, it takes some time to install the handlers, because all rights must be checked
434
488
  if (noTimeout !== true) {
435
- setTimeout(() =>
436
- this.getVersion()
437
- .then(info => {
489
+ setTimeout(
490
+ () =>
491
+ this.getVersion().then(info => {
438
492
  const [major, minor, patch] = info.version.split('.');
439
493
  const v = parseInt(major, 10) * 10000 + parseInt(minor, 10) * 100 + parseInt(patch, 10);
440
494
  if (v < 40102) {
@@ -442,12 +496,18 @@ class Connection {
442
496
  // possible this is an old version of admin
443
497
  this.onPreConnect(false, false);
444
498
  } else {
445
- this._socket.emit('authenticate', (isOk: boolean, isSecure: boolean) => this.onPreConnect(isOk, isSecure));
499
+ this._socket.emit('authenticate', (isOk: boolean, isSecure: boolean) =>
500
+ this.onPreConnect(isOk, isSecure),
501
+ );
446
502
  }
447
- }), 500);
503
+ }),
504
+ 500,
505
+ );
448
506
  } else {
449
507
  // iobroker websocket waits, till all handlers are installed
450
- this._socket.emit('authenticate', (isOk: boolean, isSecure: boolean) => this.onPreConnect(isOk, isSecure));
508
+ this._socket.emit('authenticate', (isOk: boolean, isSecure: boolean) =>
509
+ this.onPreConnect(isOk, isSecure),
510
+ );
451
511
  }
452
512
  });
453
513
 
@@ -464,14 +524,13 @@ class Connection {
464
524
  });
465
525
 
466
526
  this._socket.on('disconnect', () => {
467
- this.connected = false;
527
+ this.connected = false;
468
528
  this.subscribed = false;
469
529
  this.onProgress(PROGRESS.CONNECTING);
470
530
  this.onConnectionHandlers.forEach(cb => cb(false));
471
531
  });
472
532
 
473
- this._socket.on('reauthenticate', () =>
474
- Connection.authenticate());
533
+ this._socket.on('reauthenticate', () => Connection.authenticate());
475
534
 
476
535
  this._socket.on('log', message => {
477
536
  this.props.onLog && this.props.onLog(message);
@@ -492,8 +551,7 @@ class Connection {
492
551
  }
493
552
  });
494
553
 
495
- this._socket.on('connect_error', (err: string) =>
496
- console.error(`Connect error: ${err}`));
554
+ this._socket.on('connect_error', (err: string) => console.error(`Connect error: ${err}`));
497
555
 
498
556
  this._socket.on('permissionError', (err: { operation: string; type: string; id?: string }) =>
499
557
  this.onError({
@@ -501,34 +559,43 @@ class Connection {
501
559
  operation: err.operation,
502
560
  type: err.type,
503
561
  id: err.id || '',
504
- }));
562
+ }),
563
+ );
505
564
 
506
565
  this._socket.on('objectChange', (id: string, obj: ioBroker.Object | null) =>
507
- setTimeout(() => this.objectChange(id, obj), 0));
566
+ setTimeout(() => this.objectChange(id, obj), 0),
567
+ );
508
568
 
509
- this._socket.on('stateChange', (id: string, state) =>
510
- setTimeout(() => this.stateChange(id, state), 0));
569
+ this._socket.on('stateChange', (id: string, state) => setTimeout(() => this.stateChange(id, state), 0));
511
570
 
512
571
  this._socket.on('im', (messageType: string, from: string, data) =>
513
- setTimeout(() => this.instanceMessage(messageType, from, data), 0));
572
+ setTimeout(() => this.instanceMessage(messageType, from, data), 0),
573
+ );
514
574
 
515
575
  this._socket.on('fileChange', (id: string, fileName: string, size: number | null) =>
516
- setTimeout(() => this.fileChange(id, fileName, size), 0));
576
+ setTimeout(() => this.fileChange(id, fileName, size), 0),
577
+ );
517
578
 
518
- this._socket.on('cmdStdout', (id: string, text: string) =>
519
- this.onCmdStdoutHandler && this.onCmdStdoutHandler(id, text));
579
+ this._socket.on(
580
+ 'cmdStdout',
581
+ (id: string, text: string) => this.onCmdStdoutHandler && this.onCmdStdoutHandler(id, text),
582
+ );
520
583
 
521
- this._socket.on('cmdStderr', (id: string, text: string) =>
522
- this.onCmdStderrHandler && this.onCmdStderrHandler(id, text));
584
+ this._socket.on(
585
+ 'cmdStderr',
586
+ (id: string, text: string) => this.onCmdStderrHandler && this.onCmdStderrHandler(id, text),
587
+ );
523
588
 
524
- this._socket.on('cmdExit', (id: string, exitCode: number) =>
525
- this.onCmdExitHandler && this.onCmdExitHandler(id, exitCode));
589
+ this._socket.on(
590
+ 'cmdExit',
591
+ (id: string, exitCode: number) => this.onCmdExitHandler && this.onCmdExitHandler(id, exitCode),
592
+ );
526
593
  }
527
594
 
528
595
  /**
529
596
  * Called internally.
530
597
  */
531
- private onPreConnect(isOk: boolean, isSecure: boolean): void {
598
+ private onPreConnect(_isOk: boolean, isSecure: boolean): void {
532
599
  if (this._authTimer) {
533
600
  clearTimeout(this._authTimer);
534
601
  this._authTimer = null;
@@ -546,12 +613,12 @@ class Connection {
546
613
  this.loadTimer = null;
547
614
  this.loadCounter++;
548
615
  if (this.loadCounter < 10) {
549
- this.onConnect();
616
+ void this.onConnect().catch(e => this.onError(e));
550
617
  }
551
618
  }, 1000);
552
619
 
553
620
  if (!this.loaded) {
554
- this.onConnect();
621
+ void this.onConnect().catch(e => this.onError(e));
555
622
  }
556
623
  } else {
557
624
  this.onProgress(PROGRESS.READY);
@@ -571,19 +638,13 @@ class Connection {
571
638
  * Checks if running in ioBroker cloud
572
639
  */
573
640
  static isCloud(): boolean {
574
- if (
575
- window.location.hostname.includes('amazonaws.com') ||
576
- window.location.hostname.includes('iobroker.in')
577
- ) {
641
+ if (window.location.hostname.includes('amazonaws.com') || window.location.hostname.includes('iobroker.in')) {
578
642
  return true;
579
643
  }
580
644
  if (typeof window.socketUrl === 'undefined') {
581
645
  return false;
582
646
  }
583
- return (
584
- window.socketUrl.includes('iobroker.in') ||
585
- window.socketUrl.includes('amazonaws')
586
- );
647
+ return window.socketUrl.includes('iobroker.in') || window.socketUrl.includes('amazonaws');
587
648
  }
588
649
 
589
650
  /**
@@ -610,19 +671,21 @@ class Connection {
610
671
  }
611
672
  return new Promise((resolve, reject) => {
612
673
  this._socket.emit('getUserPermissions', (err: string | null, acl: Record<string, any> | null) =>
613
- (err ? reject(err) : resolve(acl)));
674
+ err ? reject(new Error(err)) : resolve(acl),
675
+ );
614
676
  });
615
677
  }
616
678
 
617
679
  /**
618
680
  * Called internally.
619
681
  */
620
- private async onConnect() {
682
+ private async onConnect(): Promise<void> {
621
683
  let acl: Record<string, any> | null | undefined;
622
684
  try {
623
685
  acl = await this._getUserPermissions();
624
- } catch (err) {
625
- this.onError(`Cannot read user permissions: ${err}`);
686
+ } catch (e) {
687
+ const knownError = e as Error;
688
+ this.onError(`Cannot read user permissions: ${knownError.message}`);
626
689
  return;
627
690
  }
628
691
  if (!this.doNotLoadACL) {
@@ -668,9 +731,7 @@ class Connection {
668
731
 
669
732
  if (/^(en|de|ru|pt|nl|fr|it|es|pl|uk)-?/.test(this.systemLang)) {
670
733
  this.systemLang = this.systemLang.substr(0, 2) as ioBroker.Languages;
671
- } else if (
672
- !/^(en|de|ru|pt|nl|fr|it|es|pl|uk|zh-cn)$/.test(this.systemLang)
673
- ) {
734
+ } else if (!/^(en|de|ru|pt|nl|fr|it|es|pl|uk|zh-cn)$/.test(this.systemLang)) {
674
735
  this.systemLang = 'en';
675
736
  }
676
737
  }
@@ -693,9 +754,8 @@ class Connection {
693
754
 
694
755
  /**
695
756
  * Called internally.
696
- * @private
697
757
  */
698
- static authenticate() {
758
+ private static authenticate(): void {
699
759
  if (window.location.search.includes('&href=')) {
700
760
  window.location.href = `${window.location.protocol}//${window.location.host}${window.location.pathname}${window.location.search}${window.location.hash}`;
701
761
  } else {
@@ -705,13 +765,14 @@ class Connection {
705
765
 
706
766
  /**
707
767
  * Subscribe to changes of the given state.
768
+ *
769
+ * @param id The ioBroker state ID or array of states
770
+ * @param binary Set to true if the given state is binary and requires Base64 decoding
771
+ * @param cb The callback
708
772
  */
709
773
  subscribeState(
710
- /** The ioBroker state ID. */
711
774
  id: string | string[],
712
- /** Set to true if the given state is binary and requires Base64 decoding. */
713
775
  binary: boolean | ioBroker.StateChangeHandler | BinaryStateChangeHandler,
714
- /** The callback. */
715
776
  cb?: ioBroker.StateChangeHandler | BinaryStateChangeHandler,
716
777
  ): void {
717
778
  if (typeof binary === 'function') {
@@ -749,8 +810,7 @@ class Connection {
749
810
  toSubscribe.push(_id);
750
811
  }
751
812
  } else {
752
- !this.statesSubscribes[_id].cbs.includes(cb) &&
753
- this.statesSubscribes[_id].cbs.push(cb);
813
+ !this.statesSubscribes[_id].cbs.includes(cb) && this.statesSubscribes[_id].cbs.push(cb);
754
814
  }
755
815
  }
756
816
 
@@ -770,10 +830,14 @@ class Connection {
770
830
  .catch(e => console.error(`Cannot getBinaryState "${ids[i]}": ${JSON.stringify(e)}`));
771
831
  }
772
832
  } else {
773
- this._socket.emit(Connection.isWeb() ? 'getStates' : 'getForeignStates', id, (err: string | null, states: Record<string, ioBroker.State>) => {
774
- err && console.error(`Cannot getForeignStates "${id}": ${JSON.stringify(err)}`);
775
- states && Object.keys(states).forEach(_id => (cb as ioBroker.StateChangeHandler)(_id, states[_id]));
776
- });
833
+ this._socket.emit(
834
+ Connection.isWeb() ? 'getStates' : 'getForeignStates',
835
+ id,
836
+ (err: string | null, states: Record<string, ioBroker.State>) => {
837
+ err && console.error(`Cannot getForeignStates "${id}": ${JSON.stringify(err)}`);
838
+ states && Object.keys(states).forEach(_id => (cb as ioBroker.StateChangeHandler)(_id, states[_id]));
839
+ },
840
+ );
777
841
  }
778
842
  }
779
843
 
@@ -825,11 +889,17 @@ class Connection {
825
889
 
826
890
  return new Promise((resolve, reject) => {
827
891
  if (typeof cb === 'function' && this.connected) {
828
- this._socket.emit(Connection.isWeb() ? 'getStates' : 'getForeignStates', id, (err: string | null, states: Record<string, ioBroker.State>) => {
829
- err && console.error(`Cannot getForeignStates "${id}": ${JSON.stringify(err)}`);
830
- states && Object.keys(states).forEach(_id => cb(_id, states[_id]));
831
- states ? resolve() : reject(new Error(`Cannot getForeignStates "${id}": ${JSON.stringify(err)}`));
832
- });
892
+ this._socket.emit(
893
+ Connection.isWeb() ? 'getStates' : 'getForeignStates',
894
+ id,
895
+ (err: string | null, states: Record<string, ioBroker.State>) => {
896
+ err && console.error(`Cannot getForeignStates "${id}": ${JSON.stringify(err)}`);
897
+ states && Object.keys(states).forEach(_id => cb(_id, states[_id]));
898
+ states
899
+ ? resolve()
900
+ : reject(new Error(`Cannot getForeignStates "${id}": ${JSON.stringify(err)}`));
901
+ },
902
+ );
833
903
  } else {
834
904
  this.connected ? reject(new Error('callback is not a function')) : reject(new Error('not connected'));
835
905
  }
@@ -880,13 +950,11 @@ class Connection {
880
950
 
881
951
  /**
882
952
  * Subscribe to changes of the given object.
953
+ *
954
+ * @param id The ioBroker object ID or array of objects
955
+ * @param cb The callback
883
956
  */
884
- subscribeObject(
885
- /** The ioBroker object ID. */
886
- id: string | string[],
887
- /** The callback. */
888
- cb: ioBroker.ObjectChangeHandler,
889
- ): Promise<void> {
957
+ subscribeObject(id: string | string[], cb: ioBroker.ObjectChangeHandler): Promise<void> {
890
958
  let ids: string[];
891
959
  if (!Array.isArray(id)) {
892
960
  ids = [id];
@@ -904,8 +972,7 @@ class Connection {
904
972
  this.objectsSubscribes[_id] = { reg: new RegExp(reg), cbs: [cb] };
905
973
  toSubscribe.push(_id);
906
974
  } else {
907
- !this.objectsSubscribes[_id].cbs.includes(cb) &&
908
- this.objectsSubscribes[_id].cbs.push(cb);
975
+ !this.objectsSubscribes[_id].cbs.includes(cb) && this.objectsSubscribes[_id].cbs.push(cb);
909
976
  }
910
977
  }
911
978
  if (this.connected && toSubscribe.length) {
@@ -917,13 +984,11 @@ class Connection {
917
984
 
918
985
  /**
919
986
  * Unsubscribes all or the given callback from changes of the given object.
987
+ *
988
+ * @param id The ioBroker object ID or array of objects
989
+ * @param cb The callback
920
990
  */
921
- unsubscribeObject(
922
- /** The ioBroker object ID. */
923
- id: string | string[],
924
- /** The callback. */
925
- cb?: ioBroker.ObjectChangeHandler,
926
- ): Promise<void> {
991
+ unsubscribeObject(id: string | string[], cb?: ioBroker.ObjectChangeHandler): Promise<void> {
927
992
  let ids: string[];
928
993
  if (!Array.isArray(id)) {
929
994
  ids = [id];
@@ -958,20 +1023,14 @@ class Connection {
958
1023
  /**
959
1024
  * Called internally.
960
1025
  */
961
- private fileChange(
962
- id: string,
963
- fileName: string,
964
- size: number | null,
965
- ) {
1026
+ private fileChange(id: string, fileName: string, size: number | null): void {
966
1027
  for (const sub of Object.values(this.filesSubscribes)) {
967
1028
  if (sub.regId.test(id) && sub.regFilePattern.test(fileName)) {
968
1029
  for (const cb of sub.cbs) {
969
1030
  try {
970
1031
  cb(id, fileName, size);
971
1032
  } catch (e) {
972
- console.error(
973
- `Error by callback of fileChange: ${e}`,
974
- );
1033
+ console.error(`Error by callback of fileChange: ${e}`);
975
1034
  }
976
1035
  }
977
1036
  }
@@ -980,9 +1039,10 @@ class Connection {
980
1039
 
981
1040
  /**
982
1041
  * Subscribe to changes of the files.
983
- * @param {string} id The ioBroker state ID for meta-object. Could be a pattern
984
- * @param {string} filePattern Pattern or file name, like 'main/*' or 'main/visViews.json`
985
- * @param {function} cb The callback.
1042
+ *
1043
+ * @param id The ioBroker state ID for meta-object. Could be a pattern
1044
+ * @param filePattern Pattern or file name, like 'main/*' or 'main/visViews.json`
1045
+ * @param cb The callback.
986
1046
  */
987
1047
  async subscribeFiles(
988
1048
  /** The ioBroker state ID for meta-object. Could be a pattern */
@@ -991,7 +1051,7 @@ class Connection {
991
1051
  filePattern: string | string[],
992
1052
  /** The callback. */
993
1053
  cb: ioBroker.FileChangeHandler,
994
- ) {
1054
+ ): Promise<void> {
995
1055
  if (typeof cb !== 'function') {
996
1056
  throw new Error('The state change handler must be a function!');
997
1057
  }
@@ -1015,26 +1075,23 @@ class Connection {
1015
1075
 
1016
1076
  toSubscribe.push(pattern);
1017
1077
  } else {
1018
- !this.filesSubscribes[key].cbs.includes(cb) &&
1019
- this.filesSubscribes[key].cbs.push(cb);
1078
+ !this.filesSubscribes[key].cbs.includes(cb) && this.filesSubscribes[key].cbs.push(cb);
1020
1079
  }
1021
1080
  }
1022
1081
  if (this.connected && toSubscribe.length) {
1023
1082
  this._socket.emit('subscribeFiles', id, toSubscribe);
1024
1083
  }
1084
+ return Promise.resolve();
1025
1085
  }
1026
1086
 
1027
1087
  /**
1028
1088
  * Unsubscribes the given callback from changes of files.
1029
- * @param {string} id The ioBroker state ID.
1030
- * @param {string} filePattern Pattern or file name, like 'main/*' or 'main/visViews.json`
1031
- * @param {function} cb The callback.
1089
+ *
1090
+ * @param id The ioBroker state ID.
1091
+ * @param filePattern Pattern or file name, like 'main/*' or 'main/visViews.json`
1092
+ * @param cb The callback.
1032
1093
  */
1033
- unsubscribeFiles(
1034
- id: string,
1035
- filePattern: string,
1036
- cb?: ioBroker.FileChangeHandler,
1037
- ): void {
1094
+ unsubscribeFiles(id: string, filePattern: string, cb?: ioBroker.FileChangeHandler): void {
1038
1095
  let filePatterns: string[];
1039
1096
  if (Array.isArray(filePattern)) {
1040
1097
  filePatterns = filePattern;
@@ -1056,8 +1113,7 @@ class Connection {
1056
1113
 
1057
1114
  if (!sub.cbs || !sub.cbs.length) {
1058
1115
  delete this.filesSubscribes[key];
1059
- this.connected &&
1060
- toUnsubscribe.push(pattern);
1116
+ this.connected && toUnsubscribe.push(pattern);
1061
1117
  }
1062
1118
  }
1063
1119
  }
@@ -1070,10 +1126,7 @@ class Connection {
1070
1126
  /**
1071
1127
  * Called internally.
1072
1128
  */
1073
- private objectChange(
1074
- id: string,
1075
- obj: ioBroker.Object | null,
1076
- ) {
1129
+ private objectChange(id: string, obj: ioBroker.Object | null): void {
1077
1130
  // update main.objects cache
1078
1131
  if (!this.objects) {
1079
1132
  return;
@@ -1112,24 +1165,25 @@ class Connection {
1112
1165
  });
1113
1166
 
1114
1167
  if (changed && this.props.onObjectChange) {
1115
- this.props.onObjectChange(id, obj);
1168
+ void this.props.onObjectChange(id, obj);
1116
1169
  }
1117
1170
  }
1118
1171
 
1119
1172
  /**
1120
1173
  * Called internally.
1121
1174
  */
1122
- private stateChange(
1123
- id: string,
1124
- state: ioBroker.State | null,
1125
- ): void {
1175
+ private stateChange(id: string, state: ioBroker.State | null): void {
1126
1176
  for (const task in this.statesSubscribes) {
1127
- if (Object.prototype.hasOwnProperty.call(this.statesSubscribes, task) && this.statesSubscribes[task].reg.test(id)) {
1177
+ if (
1178
+ Object.prototype.hasOwnProperty.call(this.statesSubscribes, task) &&
1179
+ this.statesSubscribes[task].reg.test(id)
1180
+ ) {
1128
1181
  this.statesSubscribes[task].cbs.forEach(cb => {
1129
1182
  try {
1130
- (cb as ioBroker.StateChangeHandler)(id, state);
1183
+ void (cb as ioBroker.StateChangeHandler)(id, state);
1131
1184
  } catch (e) {
1132
- console.error(`Error by callback of stateChange: ${e}`);
1185
+ const knownError = e as Error;
1186
+ console.error(`Error by callback of stateChange: ${knownError?.message}`);
1133
1187
  }
1134
1188
  });
1135
1189
  }
@@ -1138,11 +1192,12 @@ class Connection {
1138
1192
 
1139
1193
  /**
1140
1194
  * Called internally.
1141
- * @param {string} messageType
1142
- * @param {string} sourceInstance
1143
- * @param {object} data
1195
+ *
1196
+ * @param messageType The message type
1197
+ * @param sourceInstance The source instance
1198
+ * @param data Payload
1144
1199
  */
1145
- instanceMessage(messageType: string, sourceInstance: string, data: Record<string, any>) {
1200
+ instanceMessage(messageType: string, sourceInstance: string, data: Record<string, any>): void {
1146
1201
  if (this._instanceSubscriptions[sourceInstance]) {
1147
1202
  this._instanceSubscriptions[sourceInstance].forEach(sub => {
1148
1203
  if (sub.messageType === messageType) {
@@ -1154,15 +1209,13 @@ class Connection {
1154
1209
 
1155
1210
  /**
1156
1211
  * Gets all states.
1212
+ *
1213
+ * @param pattern The pattern to filter states
1214
+ * @param disableProgressUpdate Don't call onProgress() when done
1157
1215
  */
1158
- getStates(
1159
- /** The pattern to filter states. */
1160
- pattern?: string | boolean,
1161
- /** don't call onProgress() when done */
1162
- disableProgressUpdate?: boolean,
1163
- ): Promise<Record<string, ioBroker.State>> {
1216
+ getStates(pattern?: string | boolean, disableProgressUpdate?: boolean): Promise<Record<string, ioBroker.State>> {
1164
1217
  if (!this.connected) {
1165
- return Promise.reject(NOT_CONNECTED);
1218
+ return Promise.reject(new Error(NOT_CONNECTED));
1166
1219
  }
1167
1220
 
1168
1221
  if (typeof pattern === 'boolean') {
@@ -1174,83 +1227,79 @@ class Connection {
1174
1227
  this._socket.emit('getStates', pattern, (err: string | null, res: Record<string, ioBroker.State>) => {
1175
1228
  this.states = res;
1176
1229
  !disableProgressUpdate && this.onProgress(PROGRESS.STATES_LOADED);
1177
- err ? reject(err) : resolve(this.states);
1230
+ err ? reject(new Error(err)) : resolve(this.states);
1178
1231
  });
1179
1232
  });
1180
1233
  }
1181
1234
 
1182
1235
  /**
1183
1236
  * Gets the given state.
1237
+ *
1238
+ * @param id The state ID
1184
1239
  */
1185
- getState(
1186
- /** The state ID. */
1187
- id: string,
1188
- ): Promise<ioBroker.State | null> {
1240
+ getState(id: string): Promise<ioBroker.State | null> {
1189
1241
  if (!this.connected) {
1190
- return Promise.reject(NOT_CONNECTED);
1242
+ return Promise.reject(new Error(NOT_CONNECTED));
1191
1243
  }
1192
1244
  if (id && id === this.ignoreState) {
1193
- return Promise.resolve(this.simStates[id] || { val: null, ack: true } as ioBroker.State);
1245
+ return Promise.resolve(this.simStates[id] || ({ val: null, ack: true } as ioBroker.State));
1194
1246
  }
1195
1247
  return new Promise((resolve, reject) => {
1196
1248
  this._socket.emit('getState', id, (err: string | null, state: ioBroker.State) =>
1197
- (err ? reject(err) : resolve(state)));
1249
+ err ? reject(new Error(err)) : resolve(state),
1250
+ );
1198
1251
  });
1199
1252
  }
1200
1253
 
1201
1254
  /**
1202
- * @deprecated since js-controller 5.0. Use files instead.
1203
1255
  * Get the given binary state.
1256
+ *
1257
+ * @deprecated since js-controller 5.0. Use files instead.
1258
+ * @param id The state ID.
1204
1259
  */
1205
- getBinaryState(
1206
- /** The state ID. */
1207
- id: string,
1208
- ): Promise<string> {
1260
+ getBinaryState(id: string): Promise<string> {
1209
1261
  if (!this.connected) {
1210
- return Promise.reject(NOT_CONNECTED);
1262
+ return Promise.reject(new Error(NOT_CONNECTED));
1211
1263
  }
1212
1264
 
1213
1265
  // the data will come in base64
1214
1266
  return new Promise((resolve, reject) => {
1215
1267
  this._socket.emit('getBinaryState', id, (err: string | null, base64: string) =>
1216
- (err ? reject(err) : resolve(base64)));
1268
+ err ? reject(new Error(err)) : resolve(base64),
1269
+ );
1217
1270
  });
1218
1271
  }
1219
1272
 
1220
1273
  /**
1221
- * @deprecated since js-controller 5.0. Use files instead.
1222
1274
  * Set the given binary state.
1275
+ *
1276
+ * @deprecated since js-controller 5.0. Use files instead.
1277
+ * @param id The state ID.
1278
+ * @param base64 The Base64 encoded binary data.
1223
1279
  */
1224
- setBinaryState(
1225
- /** The state ID. */
1226
- id: string,
1227
- /** The Base64 encoded binary data. */
1228
- base64: string,
1229
- ): Promise<void> {
1280
+ setBinaryState(id: string, base64: string): Promise<void> {
1230
1281
  if (!this.connected) {
1231
- return Promise.reject(NOT_CONNECTED);
1282
+ return Promise.reject(new Error(NOT_CONNECTED));
1232
1283
  }
1233
1284
 
1234
1285
  // the data will come in base64
1235
1286
  return new Promise((resolve, reject) => {
1236
1287
  this._socket.emit('setBinaryState', id, base64, (err: string | null) =>
1237
- ((err ? reject(err) : resolve())));
1288
+ err ? reject(new Error(err)) : resolve(),
1289
+ );
1238
1290
  });
1239
1291
  }
1240
1292
 
1241
1293
  /**
1242
1294
  * Sets the given state value.
1295
+ *
1296
+ * @param id The state ID
1297
+ * @param val The state value
1298
+ * @param ack The acknowledgment flag
1243
1299
  */
1244
- setState(
1245
- /** The state ID. */
1246
- id: string,
1247
- /** The state value. */
1248
- val: string | number | boolean | ioBroker.SettableState | null,
1249
- /** The acknowledgment flag. */
1250
- ack?: boolean,
1251
- ): Promise<void> {
1300
+ setState(id: string, val: string | number | boolean | ioBroker.SettableState | null, ack?: boolean): Promise<void> {
1252
1301
  if (!this.connected) {
1253
- return Promise.reject(NOT_CONNECTED);
1302
+ return Promise.reject(new Error(NOT_CONNECTED));
1254
1303
  }
1255
1304
 
1256
1305
  // extra handling for "nothing_selected" state for vis
@@ -1276,11 +1325,9 @@ class Connection {
1276
1325
  if (this.statesSubscribes[id]) {
1277
1326
  for (const cb of this.statesSubscribes[id].cbs) {
1278
1327
  try {
1279
- (cb as ioBroker.StateChangeHandler)(id, state as ioBroker.State);
1328
+ void (cb as ioBroker.StateChangeHandler)(id, state);
1280
1329
  } catch (e) {
1281
- console.error(
1282
- `Error by callback of stateChanged: ${e}`,
1283
- );
1330
+ console.error(`Error by callback of stateChanged: ${e}`);
1284
1331
  }
1285
1332
  }
1286
1333
  }
@@ -1289,50 +1336,50 @@ class Connection {
1289
1336
  }
1290
1337
 
1291
1338
  return new Promise((resolve, reject) => {
1292
- this._socket.emit('setState', id, val, (err: string | null) =>
1293
- (err ? reject(err) : resolve()));
1339
+ this._socket.emit('setState', id, val, (err: string | null) => (err ? reject(new Error(err)) : resolve()));
1294
1340
  });
1295
1341
  }
1296
1342
 
1297
1343
  /**
1298
1344
  * Gets all objects.
1345
+ *
1346
+ * @param update Set to true to retrieve all objects from the server (instead of using the local cache)
1347
+ * @param disableProgressUpdate Don't call onProgress() when done
1299
1348
  */
1300
- getObjects(
1301
- /** Set to true to retrieve all objects from the server (instead of using the local cache). */
1302
- update?: boolean,
1303
- /** don't call onProgress() when done */
1304
- disableProgressUpdate?: boolean,
1305
- ): Promise<Record<string, ioBroker.Object>> {
1349
+ getObjects(update?: boolean, disableProgressUpdate?: boolean): Promise<Record<string, ioBroker.Object>> {
1306
1350
  if (!this.connected) {
1307
- return Promise.reject(NOT_CONNECTED);
1351
+ return Promise.reject(new Error(NOT_CONNECTED));
1308
1352
  }
1309
1353
  return new Promise((resolve, reject) => {
1310
1354
  if (!update && this.objects) {
1311
1355
  resolve(this.objects);
1312
1356
  } else {
1313
- this._socket.emit(Connection.isWeb() ? 'getObjects' : 'getAllObjects', (err: string | null, res: Record<string, ioBroker.Object>) => {
1314
- this.objects = res;
1315
- disableProgressUpdate && this.onProgress(PROGRESS.OBJECTS_LOADED);
1316
- err ? reject(err) : resolve(this.objects);
1317
- });
1357
+ this._socket.emit(
1358
+ Connection.isWeb() ? 'getObjects' : 'getAllObjects',
1359
+ (err: string | null, res: Record<string, ioBroker.Object>) => {
1360
+ this.objects = res;
1361
+ disableProgressUpdate && this.onProgress(PROGRESS.OBJECTS_LOADED);
1362
+ err ? reject(new Error(err)) : resolve(this.objects);
1363
+ },
1364
+ );
1318
1365
  }
1319
1366
  });
1320
1367
  }
1321
1368
 
1322
1369
  /**
1323
1370
  * Gets objects by list of IDs.
1371
+ *
1372
+ * @param list Array of object IDs to retrieve
1324
1373
  */
1325
- getObjectsById(
1326
- /** Array of object IDs to retrieve. */
1327
- list: string[],
1328
- ): Promise<Record<string, ioBroker.Object>> {
1374
+ getObjectsById(list: string[]): Promise<Record<string, ioBroker.Object>> {
1329
1375
  if (!this.connected) {
1330
- return Promise.reject(NOT_CONNECTED);
1376
+ return Promise.reject(new Error(NOT_CONNECTED));
1331
1377
  }
1332
1378
 
1333
1379
  return new Promise((resolve, reject) => {
1334
1380
  this._socket.emit('getObjects', list, (err: string | null, res: Record<string, ioBroker.Object>) =>
1335
- (err ? reject(err) : resolve(res)));
1381
+ err ? reject(new Error(err)) : resolve(res),
1382
+ );
1336
1383
  });
1337
1384
  }
1338
1385
 
@@ -1350,11 +1397,16 @@ class Connection {
1350
1397
  // re-subscribe states
1351
1398
  const ids = Object.keys(this.statesSubscribes);
1352
1399
  ids.forEach(id => this._socket.emit('subscribe', id));
1353
- ids.length && this._socket.emit(Connection.isWeb() ? 'getStates' : 'getForeignStates', ids, (err: string | null, states: Record<string, ioBroker.State>) => {
1354
- err && console.error(`Cannot getForeignStates: ${JSON.stringify(err)}`);
1355
- // inform about states
1356
- states && Object.keys(states).forEach(id => this.stateChange(id, states[id]));
1357
- });
1400
+ ids.length &&
1401
+ this._socket.emit(
1402
+ Connection.isWeb() ? 'getStates' : 'getForeignStates',
1403
+ ids,
1404
+ (err: string | null, states: Record<string, ioBroker.State>) => {
1405
+ err && console.error(`Cannot getForeignStates: ${JSON.stringify(err)}`);
1406
+ // inform about states
1407
+ states && Object.keys(states).forEach(id => this.stateChange(id, states[id]));
1408
+ },
1409
+ );
1358
1410
  } else if (!isEnable && this.subscribed) {
1359
1411
  this.subscribed = false;
1360
1412
  // un-subscribe objects
@@ -1370,53 +1422,51 @@ class Connection {
1370
1422
 
1371
1423
  /**
1372
1424
  * Requests log updates.
1425
+ *
1426
+ * @param isEnabled Set to true to get logs
1373
1427
  */
1374
- requireLog(
1375
- /** Set to true to get logs. */
1376
- isEnabled: boolean,
1377
- ): Promise<void> {
1428
+ requireLog(isEnabled: boolean): Promise<void> {
1378
1429
  if (!this.connected) {
1379
- return Promise.reject(NOT_CONNECTED);
1430
+ return Promise.reject(new Error(NOT_CONNECTED));
1380
1431
  }
1381
1432
  return new Promise((resolve, reject) => {
1382
1433
  this._socket.emit('requireLog', isEnabled, (err: string | null) =>
1383
- (err ? reject(err) : resolve()));
1434
+ err ? reject(new Error(err)) : resolve(),
1435
+ );
1384
1436
  });
1385
1437
  }
1386
1438
 
1387
1439
  /**
1388
1440
  * Deletes the given object.
1441
+ *
1442
+ * @param id The object ID
1443
+ * @param maintenance Force deletion of non-conform IDs
1389
1444
  */
1390
- delObject(
1391
- /** The object ID. */
1392
- id: string,
1393
- /** Force deletion of non-conform IDs. */
1394
- maintenance?: boolean,
1395
- ): Promise<void> {
1445
+ delObject(id: string, maintenance?: boolean): Promise<void> {
1396
1446
  if (!this.connected) {
1397
- return Promise.reject(NOT_CONNECTED);
1447
+ return Promise.reject(new Error(NOT_CONNECTED));
1398
1448
  }
1399
1449
  return new Promise((resolve, reject) => {
1400
1450
  this._socket.emit('delObject', id, { maintenance: !!maintenance }, (err: string | null) =>
1401
- (err ? reject(err) : resolve()));
1451
+ err ? reject(new Error(err)) : resolve(),
1452
+ );
1402
1453
  });
1403
1454
  }
1404
1455
 
1405
1456
  /**
1406
1457
  * Deletes the given object and all its children.
1458
+ *
1459
+ * @param id The object ID
1460
+ * @param maintenance Force deletion of non-conform IDs
1407
1461
  */
1408
- delObjects(
1409
- /** The object ID. */
1410
- id: string,
1411
- /** Force deletion of non-conform IDs. */
1412
- maintenance?: boolean,
1413
- ): Promise<void> {
1462
+ delObjects(id: string, maintenance?: boolean): Promise<void> {
1414
1463
  if (!this.connected) {
1415
- return Promise.reject(NOT_CONNECTED);
1464
+ return Promise.reject(new Error(NOT_CONNECTED));
1416
1465
  }
1417
1466
  return new Promise((resolve, reject) => {
1418
1467
  this._socket.emit('delObjects', id, { maintenance: !!maintenance }, (err: string | null) =>
1419
- (err ? reject(err) : resolve()));
1468
+ err ? reject(new Error(err)) : resolve(),
1469
+ );
1420
1470
  });
1421
1471
  }
1422
1472
 
@@ -1425,11 +1475,11 @@ class Connection {
1425
1475
  */
1426
1476
  setObject(id: string, obj: ioBroker.SettableObject): Promise<void> {
1427
1477
  if (!this.connected) {
1428
- return Promise.reject(NOT_CONNECTED);
1478
+ return Promise.reject(new Error(NOT_CONNECTED));
1429
1479
  }
1430
1480
 
1431
1481
  if (!obj) {
1432
- return Promise.reject('Null object is not allowed');
1482
+ return Promise.reject(new Error('Null object is not allowed'));
1433
1483
  }
1434
1484
 
1435
1485
  obj = JSON.parse(JSON.stringify(obj));
@@ -1445,8 +1495,7 @@ class Connection {
1445
1495
  }
1446
1496
 
1447
1497
  return new Promise((resolve, reject) => {
1448
- this._socket.emit('setObject', id, obj, (err: string | null) =>
1449
- (err ? reject(err) : resolve()));
1498
+ this._socket.emit('setObject', id, obj, (err: string | null) => (err ? reject(new Error(err)) : resolve()));
1450
1499
  });
1451
1500
  }
1452
1501
 
@@ -1455,7 +1504,7 @@ class Connection {
1455
1504
  */
1456
1505
  getObject(id: string): Promise<ioBroker.Object> {
1457
1506
  if (!this.connected) {
1458
- return Promise.reject(NOT_CONNECTED);
1507
+ return Promise.reject(new Error(NOT_CONNECTED));
1459
1508
  }
1460
1509
  if (id && id === this.ignoreState) {
1461
1510
  return Promise.resolve({
@@ -1474,19 +1523,18 @@ class Connection {
1474
1523
 
1475
1524
  return new Promise((resolve, reject) => {
1476
1525
  this._socket.emit('getObject', id, (err: string | null, obj: ioBroker.Object) =>
1477
- (err ? reject(err) : resolve(obj)));
1526
+ err ? reject(new Error(err)) : resolve(obj),
1527
+ );
1478
1528
  });
1479
1529
  }
1480
1530
 
1481
1531
  /**
1482
1532
  * Get all instances of the given adapter or all instances of all adapters.
1533
+ *
1534
+ * @param adapter The name of the adapter
1535
+ * @param update Force update
1483
1536
  */
1484
- getAdapterInstances(
1485
- /** The name of the adapter. */
1486
- adapter?: string | boolean,
1487
- /** Force update. */
1488
- update?: boolean,
1489
- ): Promise<ioBroker.InstanceObject[]> {
1537
+ getAdapterInstances(adapter?: string | boolean, update?: boolean): Promise<ioBroker.InstanceObject[]> {
1490
1538
  if (typeof adapter === 'boolean') {
1491
1539
  update = adapter;
1492
1540
  adapter = '';
@@ -1498,7 +1546,7 @@ class Connection {
1498
1546
  }
1499
1547
 
1500
1548
  if (!this.connected) {
1501
- return Promise.reject(NOT_CONNECTED);
1549
+ return Promise.reject(new Error(NOT_CONNECTED));
1502
1550
  }
1503
1551
 
1504
1552
  this._promises[`instances_${adapter}`] = new Promise((resolve, reject) => {
@@ -1509,17 +1557,23 @@ class Connection {
1509
1557
  `system.adapter.${adapter ? `${adapter}.` : ''}\u9999`,
1510
1558
  'instance',
1511
1559
  )
1512
- .then(items => resolve(Object.keys(items).map(id => fixAdminUI(items[id] as ioBroker.AdapterObject))))
1513
- .catch(e => reject(e));
1560
+ .then(items =>
1561
+ resolve(Object.keys(items).map(id => fixAdminUI(items[id] as ioBroker.AdapterObject))),
1562
+ )
1563
+ .catch(e => reject(new Error(e)));
1514
1564
  }, TIMEOUT_FOR_ADMIN4);
1515
1565
 
1516
- this._socket.emit('getAdapterInstances', adapter, (err: string | null, instances: ioBroker.InstanceObject[]) => {
1517
- if (timeout) {
1518
- clearTimeout(timeout);
1519
- timeout = null;
1520
- err ? reject(err) : resolve(instances);
1521
- }
1522
- });
1566
+ this._socket.emit(
1567
+ 'getAdapterInstances',
1568
+ adapter,
1569
+ (err: string | null, instances: ioBroker.InstanceObject[]) => {
1570
+ if (timeout) {
1571
+ clearTimeout(timeout);
1572
+ timeout = null;
1573
+ err ? reject(new Error(err)) : resolve(instances);
1574
+ }
1575
+ },
1576
+ );
1523
1577
  });
1524
1578
 
1525
1579
  return this._promises[`instances_${adapter}`] as Promise<ioBroker.InstanceObject[]>;
@@ -1527,15 +1581,13 @@ class Connection {
1527
1581
 
1528
1582
  /**
1529
1583
  * Get adapters with the given name or all adapters.
1584
+ *
1585
+ * @param adapter The name of the adapter
1586
+ * @param update Force update
1530
1587
  */
1531
- getAdapters(
1532
- /** The name of the adapter. */
1533
- adapter?: string | boolean,
1534
- /** Force update. */
1535
- update?: boolean,
1536
- ): Promise<ioBroker.AdapterObject[]> {
1588
+ getAdapters(adapter?: string | boolean, update?: boolean): Promise<ioBroker.AdapterObject[]> {
1537
1589
  if (Connection.isWeb()) {
1538
- return Promise.reject('Allowed only in admin');
1590
+ return Promise.reject(new Error('Allowed only in admin'));
1539
1591
  }
1540
1592
 
1541
1593
  if (typeof adapter === 'boolean') {
@@ -1550,28 +1602,24 @@ class Connection {
1550
1602
  }
1551
1603
 
1552
1604
  if (!this.connected) {
1553
- return Promise.reject(NOT_CONNECTED);
1605
+ return Promise.reject(new Error(NOT_CONNECTED));
1554
1606
  }
1555
1607
 
1556
1608
  this._promises[`adapter_${adapter}`] = new Promise((resolve, reject) => {
1557
1609
  let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
1558
1610
  timeout = null;
1559
- this.getObjectView(
1560
- `system.adapter.${adapter}.`,
1561
- `system.adapter.${adapter}.\u9999`,
1562
- 'adapter',
1563
- )
1611
+ this.getObjectView(`system.adapter.${adapter}.`, `system.adapter.${adapter}.\u9999`, 'adapter')
1564
1612
  .then(items => {
1565
1613
  resolve(Object.keys(items).map(id => fixAdminUI(items[id] as ioBroker.AdapterObject)));
1566
1614
  })
1567
- .catch(e => reject(e));
1615
+ .catch(e => reject(new Error(e)));
1568
1616
  }, TIMEOUT_FOR_ADMIN4);
1569
1617
 
1570
1618
  this._socket.emit('getAdapters', adapter, (err: string | null, adapters: ioBroker.AdapterObject[]) => {
1571
1619
  if (timeout) {
1572
1620
  clearTimeout(timeout);
1573
1621
  timeout = null;
1574
- err ? reject(err) : resolve(adapters);
1622
+ err ? reject(new Error(err)) : resolve(adapters);
1575
1623
  }
1576
1624
  });
1577
1625
  });
@@ -1582,10 +1630,7 @@ class Connection {
1582
1630
  /**
1583
1631
  * Called internally.
1584
1632
  */
1585
- private _renameGroups(
1586
- objs: RenameGroupObject[],
1587
- cb: (err: string | null) => void,
1588
- ) {
1633
+ private _renameGroups(objs: RenameGroupObject[], cb: (err: string | null) => void): void {
1589
1634
  if (!objs || !objs.length) {
1590
1635
  cb && cb(null);
1591
1636
  } else {
@@ -1607,20 +1652,22 @@ class Connection {
1607
1652
 
1608
1653
  /**
1609
1654
  * Rename a group.
1655
+ *
1610
1656
  * @param id The id.
1611
- * @param newId The new id.
1612
- * @param {string | { [lang in ioBroker.Languages]?: string; }} newName The new name.
1657
+ * @param newId The new id.
1658
+ * @param newName The new name.
1613
1659
  */
1614
1660
  async renameGroup(id: string, newId: string, newName: ioBroker.StringOrTranslated): Promise<void> {
1615
1661
  if (Connection.isWeb()) {
1616
- return Promise.reject('Allowed only in admin');
1662
+ return Promise.reject(new Error('Allowed only in admin'));
1617
1663
  }
1618
1664
 
1619
1665
  const groups = await this.getGroups(true);
1620
1666
  if (groups.length) {
1621
1667
  // find all elements
1622
- const groupsToRename: RenameGroupObject[] = (groups as RenameGroupObject[])
1623
- .filter(group => group._id.startsWith(`${id}.`));
1668
+ const groupsToRename: RenameGroupObject[] = (groups as RenameGroupObject[]).filter(group =>
1669
+ group._id.startsWith(`${id}.`),
1670
+ );
1624
1671
 
1625
1672
  groupsToRename.forEach(group => {
1626
1673
  group.newId = (newId + group._id.substring(id.length)) as ioBroker.ObjectIDs.Group;
@@ -1628,7 +1675,8 @@ class Connection {
1628
1675
 
1629
1676
  await new Promise((resolve, reject) => {
1630
1677
  this._renameGroups(groupsToRename, (err: string | null) =>
1631
- (err ? reject(err) : resolve(null)));
1678
+ err ? reject(new Error(err)) : resolve(null),
1679
+ );
1632
1680
  });
1633
1681
  const obj = groups.find(group => group._id === id);
1634
1682
 
@@ -1640,8 +1688,7 @@ class Connection {
1640
1688
  obj.common.name = newName;
1641
1689
  }
1642
1690
 
1643
- return this.setObject(obj._id, obj)
1644
- .then(() => this.delObject(id));
1691
+ return this.setObject(obj._id, obj).then(() => this.delObject(id));
1645
1692
  }
1646
1693
  }
1647
1694
 
@@ -1650,36 +1697,31 @@ class Connection {
1650
1697
 
1651
1698
  /**
1652
1699
  * Sends a message to a specific instance or all instances of some specific adapter.
1653
- * @returns {Promise<ioBroker.Message | undefined>}
1654
- */
1655
- sendTo(
1656
- /** The instance to send this message to. */
1657
- instance: string,
1658
- /** Command name of the target instance. */
1659
- command: string,
1660
- /** The message data to send. */
1661
- data: any,
1662
- ): Promise<{ result?: any; error?: string }> {
1700
+ *
1701
+ * @param instance The instance to send this message to.
1702
+ * @param command Command name of the target instance.
1703
+ * @param data The message data to send.
1704
+ */
1705
+ sendTo(instance: string, command: string, data: any): Promise<{ result?: any; error?: string }> {
1663
1706
  if (!this.connected) {
1664
- return Promise.reject(NOT_CONNECTED);
1707
+ return Promise.reject(new Error(NOT_CONNECTED));
1665
1708
  }
1666
1709
  return new Promise(resolve => {
1667
1710
  this._socket.emit('sendTo', instance, command, data, (result: { result?: any; error?: string }) =>
1668
- resolve(result));
1711
+ resolve(result),
1712
+ );
1669
1713
  });
1670
1714
  }
1671
1715
 
1672
1716
  /**
1673
1717
  * Extend an object and create it if it might not exist.
1718
+ *
1719
+ * @param id The id.
1720
+ * @param obj The object.
1674
1721
  */
1675
- extendObject(
1676
- /** The id. */
1677
- id: string,
1678
- /** The object. */
1679
- obj: ioBroker.PartialObject,
1680
- ): Promise<void> {
1722
+ extendObject(id: string, obj: ioBroker.PartialObject): Promise<void> {
1681
1723
  if (!this.connected) {
1682
- return Promise.reject(NOT_CONNECTED);
1724
+ return Promise.reject(new Error(NOT_CONNECTED));
1683
1725
  }
1684
1726
 
1685
1727
  obj = JSON.parse(JSON.stringify(obj));
@@ -1696,7 +1738,8 @@ class Connection {
1696
1738
 
1697
1739
  return new Promise((resolve, reject) => {
1698
1740
  this._socket.emit('extendObject', id, obj, (err: string | null) =>
1699
- ((err ? reject(err) : resolve())));
1741
+ err ? reject(new Error(err)) : resolve(),
1742
+ );
1700
1743
  });
1701
1744
  }
1702
1745
 
@@ -1732,7 +1775,8 @@ class Connection {
1732
1775
 
1733
1776
  /**
1734
1777
  * Set the handler for standard output of a command.
1735
- * @param {(id: string, text: string) => void} handler The handler.
1778
+ *
1779
+ * @param handler The handler.
1736
1780
  */
1737
1781
  registerCmdStdoutHandler(handler: (id: string, text: string) => void): void {
1738
1782
  this.onCmdStdoutHandler = handler;
@@ -1747,7 +1791,8 @@ class Connection {
1747
1791
 
1748
1792
  /**
1749
1793
  * Set the handler for standard error of a command.
1750
- * @param {(id: string, text: string) => void} handler The handler.
1794
+ *
1795
+ * @param handler The handler.
1751
1796
  */
1752
1797
  registerCmdStderrHandler(handler: (id: string, text: string) => void): void {
1753
1798
  this.onCmdStderrHandler = handler;
@@ -1756,7 +1801,7 @@ class Connection {
1756
1801
  /**
1757
1802
  * Unset the handler for standard error of a command.
1758
1803
  */
1759
- unregisterCmdStderrHandler() {
1804
+ unregisterCmdStderrHandler(): void {
1760
1805
  this.onCmdStderrHandler = undefined;
1761
1806
  }
1762
1807
 
@@ -1788,7 +1833,7 @@ class Connection {
1788
1833
  }
1789
1834
 
1790
1835
  if (!this.connected) {
1791
- return Promise.reject(NOT_CONNECTED);
1836
+ return Promise.reject(new Error(NOT_CONNECTED));
1792
1837
  }
1793
1838
 
1794
1839
  this._promises[`enums_${_enum || 'all'}`] = new Promise((resolve, reject) => {
@@ -1807,8 +1852,10 @@ class Connection {
1807
1852
  _res[res.rows[i].id] = res.rows[i].value;
1808
1853
  }
1809
1854
  resolve(_res);
1855
+ } else if (err) {
1856
+ reject(new Error(err));
1810
1857
  } else {
1811
- reject(err);
1858
+ reject(new Error('Invalid response while getting enums'));
1812
1859
  }
1813
1860
  },
1814
1861
  );
@@ -1819,10 +1866,11 @@ class Connection {
1819
1866
 
1820
1867
  /**
1821
1868
  * Query a predefined object view.
1869
+ *
1822
1870
  * @param design design - 'system' or other designs like `custom`.
1823
1871
  * @param type The type of object.
1824
1872
  * @param start The start ID.
1825
- * @param [end] The end ID.
1873
+ * @param end The end ID.
1826
1874
  */
1827
1875
  getObjectViewCustom(
1828
1876
  /** The design: 'system' or other designs like `custom`. */
@@ -1835,34 +1883,38 @@ class Connection {
1835
1883
  end?: string,
1836
1884
  ): Promise<Record<string, ioBroker.Object>> {
1837
1885
  return new Promise((resolve, reject) => {
1838
- this._socket.emit('getObjectView', design, type, { startkey: start, endkey: end }, (err: string | null, res: { rows: { value: ioBroker.Object; id: string }[] }) => {
1839
- if (!err) {
1840
- const _res: Record<string, ioBroker.Object> = {};
1841
- if (res && res.rows) {
1842
- for (let i = 0; i < res.rows.length; i++) {
1843
- _res[res.rows[i].id] = res.rows[i].value;
1886
+ this._socket.emit(
1887
+ 'getObjectView',
1888
+ design,
1889
+ type,
1890
+ { startkey: start, endkey: end },
1891
+ (err: string | null, res: { rows: { value: ioBroker.Object; id: string }[] }) => {
1892
+ if (!err) {
1893
+ const _res: Record<string, ioBroker.Object> = {};
1894
+ if (res && res.rows) {
1895
+ for (let i = 0; i < res.rows.length; i++) {
1896
+ _res[res.rows[i].id] = res.rows[i].value;
1897
+ }
1844
1898
  }
1899
+ resolve(_res);
1900
+ } else {
1901
+ reject(new Error(err));
1845
1902
  }
1846
- resolve(_res);
1847
- } else {
1848
- reject(err);
1849
- }
1850
- });
1903
+ },
1904
+ );
1851
1905
  });
1852
1906
  }
1853
1907
 
1854
1908
  /**
1855
1909
  * Query a predefined object view.
1910
+ *
1856
1911
  * @param type The type of object.
1857
1912
  * @param start The start ID.
1858
- * @param [end] The end ID.
1913
+ * @param end The end ID.
1859
1914
  */
1860
1915
  getObjectViewSystem(
1861
- /** The type of object. */
1862
1916
  type: ioBroker.ObjectType,
1863
- /** The start ID. */
1864
1917
  start: string,
1865
- /** The end ID. */
1866
1918
  end?: string,
1867
1919
  ): Promise<Record<string, ioBroker.Object>> {
1868
1920
  return this.getObjectViewCustom('system', type, start, end);
@@ -1870,31 +1922,30 @@ class Connection {
1870
1922
 
1871
1923
  /**
1872
1924
  * @deprecated since version 1.1.15, cause parameter order does not match backend
1925
+ *
1873
1926
  * Query a predefined object view.
1874
- * @param {string} start The start ID.
1875
- * @param {string} end The end ID.
1876
- * @param {string} type The type of object.
1877
- * @returns {Promise<Record<string, ioBroker.Object>>}
1927
+ * @param start The start ID.
1928
+ * @param end The end ID.
1929
+ * @param type The type of object.
1878
1930
  */
1879
1931
  getObjectView(start: string, end: string, type: ioBroker.ObjectType): Promise<Record<string, ioBroker.Object>> {
1880
1932
  if (!this.connected) {
1881
- return Promise.reject(NOT_CONNECTED);
1933
+ return Promise.reject(new Error(NOT_CONNECTED));
1882
1934
  }
1883
1935
 
1884
1936
  start = start || '';
1885
- end = end || '\u9999';
1937
+ end = end || '\u9999';
1886
1938
  return this.getObjectViewCustom('system', type, start, end);
1887
1939
  }
1888
1940
 
1889
1941
  /**
1890
1942
  * Get the stored certificates.
1943
+ *
1944
+ * @param update Force update.
1891
1945
  */
1892
- getCertificates(
1893
- /** Force update. */
1894
- update?: boolean,
1895
- ): Promise<{ name: string; type: 'public' | 'private' | 'chained' | '' }[]> {
1946
+ getCertificates(update?: boolean): Promise<{ name: string; type: 'public' | 'private' | 'chained' | '' }[]> {
1896
1947
  if (Connection.isWeb()) {
1897
- return Promise.reject('Allowed only in admin');
1948
+ return Promise.reject(new Error('Allowed only in admin'));
1898
1949
  }
1899
1950
 
1900
1951
  if (this._promises.cert && !update) {
@@ -1902,50 +1953,53 @@ class Connection {
1902
1953
  }
1903
1954
 
1904
1955
  if (!this.connected) {
1905
- return Promise.reject(NOT_CONNECTED);
1956
+ return Promise.reject(new Error(NOT_CONNECTED));
1906
1957
  }
1907
1958
 
1908
- this._promises.cert = this.getObject('system.certificates')
1909
- .then(res => {
1910
- const certs: { name: string; type: 'public' | 'private' | 'chained' | '' }[] = [];
1911
- if (res && res.native && res.native.certificates) {
1912
- Object.keys(res.native.certificates).forEach(c => {
1913
- const cert: string = res.native.certificates[c];
1914
- if (!cert) {
1915
- return;
1959
+ this._promises.cert = this.getObject('system.certificates').then(res => {
1960
+ const certs: { name: string; type: 'public' | 'private' | 'chained' | '' }[] = [];
1961
+ if (res && res.native && res.native.certificates) {
1962
+ Object.keys(res.native.certificates).forEach(c => {
1963
+ const cert: string = res.native.certificates[c];
1964
+ if (!cert) {
1965
+ return;
1966
+ }
1967
+ const _cert: { name: string; type: 'public' | 'private' | 'chained' | '' } = {
1968
+ name: c,
1969
+ type: '',
1970
+ };
1971
+ // If it is a filename, it could be everything
1972
+ if (cert.length < 700 && (cert.includes('/') || cert.includes('\\'))) {
1973
+ if (c.toLowerCase().includes('private')) {
1974
+ _cert.type = 'private';
1975
+ } else if (cert.toLowerCase().includes('private')) {
1976
+ _cert.type = 'private';
1977
+ } else if (c.toLowerCase().includes('public')) {
1978
+ _cert.type = 'public';
1979
+ } else if (cert.toLowerCase().includes('public')) {
1980
+ _cert.type = 'public';
1916
1981
  }
1917
- const _cert: { name: string; type: 'public' | 'private' | 'chained' | '' } = {
1918
- name: c,
1919
- type: '',
1920
- };
1921
- // If it is a filename, it could be everything
1922
- if (cert.length < 700 && (cert.includes('/') || cert.includes('\\'))) {
1923
- if (c.toLowerCase().includes('private')) {
1924
- _cert.type = 'private';
1925
- } else if (cert.toLowerCase().includes('private')) {
1926
- _cert.type = 'private';
1927
- } else if (c.toLowerCase().includes('public')) {
1928
- _cert.type = 'public';
1929
- } else if (cert.toLowerCase().includes('public')) {
1930
- _cert.type = 'public';
1931
- }
1932
- certs.push(_cert);
1933
- } else {
1934
- _cert.type = (cert.substring(0, '-----BEGIN RSA PRIVATE KEY'.length) === '-----BEGIN RSA PRIVATE KEY' || cert.substring(0, '-----BEGIN PRIVATE KEY'.length) === '-----BEGIN PRIVATE KEY') ? 'private' : 'public';
1935
-
1936
- if (_cert.type === 'public') {
1937
- const m = cert.split('-----END CERTIFICATE-----');
1938
- if (m.filter((t: string) => t.replace(/\r\n|\r|\n/, '').trim()).length > 1) {
1939
- _cert.type = 'chained';
1940
- }
1982
+ certs.push(_cert);
1983
+ } else {
1984
+ _cert.type =
1985
+ cert.substring(0, '-----BEGIN RSA PRIVATE KEY'.length) === '-----BEGIN RSA PRIVATE KEY' ||
1986
+ cert.substring(0, '-----BEGIN PRIVATE KEY'.length) === '-----BEGIN PRIVATE KEY'
1987
+ ? 'private'
1988
+ : 'public';
1989
+
1990
+ if (_cert.type === 'public') {
1991
+ const m = cert.split('-----END CERTIFICATE-----');
1992
+ if (m.filter((t: string) => t.replace(/\r\n|\r|\n/, '').trim()).length > 1) {
1993
+ _cert.type = 'chained';
1941
1994
  }
1942
-
1943
- certs.push(_cert);
1944
1995
  }
1945
- });
1946
- }
1947
- return certs;
1948
- });
1996
+
1997
+ certs.push(_cert);
1998
+ }
1999
+ });
2000
+ }
2001
+ return certs;
2002
+ });
1949
2003
 
1950
2004
  return this._promises.cert;
1951
2005
  }
@@ -1953,21 +2007,17 @@ class Connection {
1953
2007
  /**
1954
2008
  * Get the logs from a host (only for admin connection).
1955
2009
  */
1956
- getLogs(
1957
- host: string,
1958
- linesNumber?: number,
1959
- ): Promise<string[]> {
2010
+ getLogs(host: string, linesNumber?: number): Promise<string[]> {
1960
2011
  if (Connection.isWeb()) {
1961
- return Promise.reject('Allowed only in admin');
2012
+ return Promise.reject(new Error('Allowed only in admin'));
1962
2013
  }
1963
2014
 
1964
2015
  if (!this.connected) {
1965
- return Promise.reject(NOT_CONNECTED);
2016
+ return Promise.reject(new Error(NOT_CONNECTED));
1966
2017
  }
1967
2018
 
1968
2019
  return new Promise(resolve => {
1969
- this._socket.emit('sendToHost', host, 'getLogs', linesNumber || 200, (lines: string[]) =>
1970
- resolve(lines));
2020
+ this._socket.emit('sendToHost', host, 'getLogs', linesNumber || 200, (lines: string[]) => resolve(lines));
1971
2021
  });
1972
2022
  }
1973
2023
 
@@ -1976,14 +2026,15 @@ class Connection {
1976
2026
  */
1977
2027
  getLogsFiles(host: string): Promise<string[]> {
1978
2028
  if (Connection.isWeb()) {
1979
- return Promise.reject('Allowed only in admin');
2029
+ return Promise.reject(new Error('Allowed only in admin'));
1980
2030
  }
1981
2031
  if (!this.connected) {
1982
- return Promise.reject(NOT_CONNECTED);
2032
+ return Promise.reject(new Error(NOT_CONNECTED));
1983
2033
  }
1984
2034
  return new Promise((resolve, reject) => {
1985
2035
  this._socket.emit('readLogs', host, (err: string | null, files: string[]) =>
1986
- (err ? reject(err) : resolve(files)));
2036
+ err ? reject(new Error(err)) : resolve(files),
2037
+ );
1987
2038
  });
1988
2039
  }
1989
2040
 
@@ -1992,14 +2043,15 @@ class Connection {
1992
2043
  */
1993
2044
  delLogs(host: string): Promise<void> {
1994
2045
  if (Connection.isWeb()) {
1995
- return Promise.reject('Allowed only in admin');
2046
+ return Promise.reject(new Error('Allowed only in admin'));
1996
2047
  }
1997
2048
  if (!this.connected) {
1998
- return Promise.reject(NOT_CONNECTED);
2049
+ return Promise.reject(new Error(NOT_CONNECTED));
1999
2050
  }
2000
2051
  return new Promise((resolve, reject) => {
2001
2052
  this._socket.emit('sendToHost', host, 'delLogs', null, (error: string | null) =>
2002
- (error ? reject(error) : resolve()));
2053
+ error ? reject(new Error(error)) : resolve(),
2054
+ );
2003
2055
  });
2004
2056
  }
2005
2057
 
@@ -2008,139 +2060,144 @@ class Connection {
2008
2060
  */
2009
2061
  readMetaItems(): Promise<ioBroker.MetaObject[]> {
2010
2062
  if (!this.connected) {
2011
- return Promise.reject(NOT_CONNECTED);
2063
+ return Promise.reject(new Error(NOT_CONNECTED));
2012
2064
  }
2013
2065
  return new Promise((resolve, reject) => {
2014
- this._socket.emit('getObjectView', 'system', 'meta', { startkey: '', endkey: '\u9999' }, (err: string | null, objs: { rows: { value: ioBroker.MetaObject; id: string }[] }) =>
2015
- (err ? reject(err) : resolve(objs.rows && objs.rows.map((obj: { value: ioBroker.MetaObject; id: string }) => obj.value))));
2066
+ this._socket.emit(
2067
+ 'getObjectView',
2068
+ 'system',
2069
+ 'meta',
2070
+ { startkey: '', endkey: '\u9999' },
2071
+ (err: string | null, objs: { rows: { value: ioBroker.MetaObject; id: string }[] }) =>
2072
+ err
2073
+ ? reject(new Error(err))
2074
+ : resolve(
2075
+ objs.rows &&
2076
+ objs.rows.map((obj: { value: ioBroker.MetaObject; id: string }) => obj.value),
2077
+ ),
2078
+ );
2016
2079
  });
2017
2080
  }
2018
2081
 
2019
2082
  /**
2020
2083
  * Read the directory of an adapter.
2084
+ *
2085
+ * @param adapter The adapter name.
2086
+ * @param fileName The directory name.
2021
2087
  */
2022
- readDir(
2023
- /** The adapter name. */
2024
- adapter: string,
2025
- /** The directory name. */
2026
- fileName: string,
2027
- ): Promise<ioBroker.ReadDirResult[]> {
2088
+ readDir(adapter: string, fileName: string): Promise<ioBroker.ReadDirResult[]> {
2028
2089
  if (!this.connected) {
2029
- return Promise.reject(NOT_CONNECTED);
2090
+ return Promise.reject(new Error(NOT_CONNECTED));
2030
2091
  }
2031
2092
  return new Promise((resolve, reject) => {
2032
2093
  this._socket.emit('readDir', adapter, fileName, (err: string | null, files: ioBroker.ReadDirResult[]) =>
2033
- (err ? reject(err) : resolve(files)));
2094
+ err ? reject(new Error(err)) : resolve(files),
2095
+ );
2034
2096
  });
2035
2097
  }
2036
2098
 
2037
2099
  /**
2038
2100
  * Read a file of an adapter.
2101
+ *
2102
+ * @param adapter The adapter name.
2103
+ * @param fileName The file name.
2104
+ * @param base64 If it must be a base64 format.
2039
2105
  */
2040
- readFile(
2041
- /** The adapter name. */
2042
- adapter: string,
2043
- /** The file name. */
2044
- fileName: string,
2045
- /** If it must be a base64 format */
2046
- base64?: boolean,
2047
- ): Promise<string | { data: string; type: string }> {
2106
+ readFile(adapter: string, fileName: string, base64?: boolean): Promise<string | { data: string; type: string }> {
2048
2107
  if (!this.connected) {
2049
- return Promise.reject(NOT_CONNECTED);
2108
+ return Promise.reject(new Error(NOT_CONNECTED));
2050
2109
  }
2051
2110
  return new Promise((resolve, reject) => {
2052
2111
  if (!base64) {
2053
2112
  this._socket.emit('readFile', adapter, fileName, (err: string | null, data: string, type: string) => {
2054
- err ? reject(err) : resolve({ data, type });
2113
+ err ? reject(new Error(err)) : resolve({ data, type });
2055
2114
  });
2056
2115
  } else {
2057
2116
  this._socket.emit('readFile64', adapter, fileName, base64, (err: string | null, data: string) =>
2058
- (err ? reject(err) : resolve(data)));
2117
+ err ? reject(new Error(err)) : resolve(data),
2118
+ );
2059
2119
  }
2060
2120
  });
2061
2121
  }
2062
2122
 
2063
2123
  /**
2064
2124
  * Write a file of an adapter.
2125
+ *
2126
+ * @param adapter The adapter name.
2127
+ * @param fileName The file name.
2128
+ * @param data The data (if it's a Buffer, it will be converted to Base64)
2065
2129
  */
2066
- writeFile64(
2067
- /** The adapter name. */
2068
- adapter: string,
2069
- /** The file name. */
2070
- fileName: string,
2071
- /** The data (if it's a Buffer, it will be converted to Base64). */
2072
- data: Buffer | string,
2073
- ): Promise<void> {
2130
+ writeFile64(adapter: string, fileName: string, data: Buffer | string): Promise<void> {
2074
2131
  if (!this.connected) {
2075
- return Promise.reject(NOT_CONNECTED);
2132
+ return Promise.reject(new Error(NOT_CONNECTED));
2076
2133
  }
2077
2134
  return new Promise((resolve, reject) => {
2078
2135
  if (typeof data === 'string') {
2079
2136
  this._socket.emit('writeFile', adapter, fileName, data, (err: string | null) =>
2080
- (err ? reject(err) : resolve()));
2137
+ err ? reject(new Error(err)) : resolve(),
2138
+ );
2081
2139
  } else {
2082
2140
  const base64 = btoa(
2083
- new Uint8Array(data)
2084
- .reduce((_data, byte) => _data + String.fromCharCode(byte), ''),
2141
+ new Uint8Array(data).reduce((_data, byte) => _data + String.fromCharCode(byte), ''),
2085
2142
  );
2086
2143
 
2087
2144
  this._socket.emit('writeFile64', adapter, fileName, base64, (err: string | null) =>
2088
- (err ? reject(err) : resolve()));
2145
+ err ? reject(new Error(err)) : resolve(),
2146
+ );
2089
2147
  }
2090
2148
  });
2091
2149
  }
2092
2150
 
2093
2151
  /**
2094
2152
  * Delete a file of an adapter.
2153
+ *
2154
+ * @param adapter The adapter name.
2155
+ * @param fileName The file name.
2095
2156
  */
2096
- deleteFile(
2097
- /** The adapter name. */
2098
- adapter: string,
2099
- /** The file name. */
2100
- fileName: string,
2101
- ): Promise<void> {
2157
+ deleteFile(adapter: string, fileName: string): Promise<void> {
2102
2158
  if (!this.connected) {
2103
- return Promise.reject(NOT_CONNECTED);
2159
+ return Promise.reject(new Error(NOT_CONNECTED));
2104
2160
  }
2105
2161
  return new Promise((resolve, reject) => {
2106
2162
  this._socket.emit('unlink', adapter, fileName, (err: string | null) =>
2107
- (err ? reject(err) : resolve()));
2163
+ err ? reject(new Error(err)) : resolve(),
2164
+ );
2108
2165
  });
2109
2166
  }
2110
2167
 
2111
2168
  /**
2112
2169
  * Delete a folder of an adapter.
2113
2170
  * All files in folder will be deleted.
2171
+ *
2172
+ * @param adapter The adapter name.
2173
+ * @param folderName The folder name.
2114
2174
  */
2115
- deleteFolder(
2116
- /** The adapter name. */
2117
- adapter: string,
2118
- /** The file name. */
2119
- folderName: string,
2120
- ): Promise<void> {
2175
+ deleteFolder(adapter: string, folderName: string): Promise<void> {
2121
2176
  if (!this.connected) {
2122
- return Promise.reject(NOT_CONNECTED);
2177
+ return Promise.reject(new Error(NOT_CONNECTED));
2123
2178
  }
2124
2179
  return new Promise((resolve, reject) => {
2125
2180
  this._socket.emit('deleteFolder', adapter, folderName, (err: string | null) =>
2126
- (err ? reject(err) : resolve()));
2181
+ err ? reject(new Error(err)) : resolve(),
2182
+ );
2127
2183
  });
2128
2184
  }
2129
2185
 
2130
2186
  /**
2131
2187
  * Get the list of all hosts.
2132
- * @param {boolean} [update] Force update.
2188
+ *
2189
+ * @param update Force update.
2133
2190
  */
2134
2191
  getHosts(update?: boolean): Promise<ioBroker.HostObject[]> {
2135
2192
  if (Connection.isWeb()) {
2136
- return Promise.reject('Allowed only in admin');
2193
+ return Promise.reject(new Error('Allowed only in admin'));
2137
2194
  }
2138
2195
  if (!update && this._promises.hosts) {
2139
2196
  return this._promises.hosts;
2140
2197
  }
2141
2198
 
2142
2199
  if (!this.connected) {
2143
- return Promise.reject(NOT_CONNECTED);
2200
+ return Promise.reject(new Error(NOT_CONNECTED));
2144
2201
  }
2145
2202
 
2146
2203
  this._promises.hosts = new Promise((resolve, reject) => {
@@ -2149,9 +2206,9 @@ class Connection {
2149
2206
  'system',
2150
2207
  'host',
2151
2208
  { startkey: 'system.host.', endkey: 'system.host.\u9999' },
2152
- (err: string | null, doc: { rows: { value: ioBroker.HostObject; id: string }[]}) => {
2209
+ (err: string | null, doc: { rows: { value: ioBroker.HostObject; id: string }[] }) => {
2153
2210
  if (err) {
2154
- reject(err);
2211
+ reject(new Error(err));
2155
2212
  } else {
2156
2213
  resolve(doc.rows.map(item => item.value));
2157
2214
  }
@@ -2164,19 +2221,18 @@ class Connection {
2164
2221
 
2165
2222
  /**
2166
2223
  * Get the list of all users.
2224
+ *
2225
+ * @param update Force update.
2167
2226
  */
2168
- getUsers(
2169
- /** Force update. */
2170
- update?: boolean,
2171
- ): Promise<ioBroker.UserObject[]> {
2227
+ getUsers(update?: boolean): Promise<ioBroker.UserObject[]> {
2172
2228
  if (Connection.isWeb()) {
2173
- return Promise.reject('Allowed only in admin');
2229
+ return Promise.reject(new Error('Allowed only in admin'));
2174
2230
  }
2175
2231
  if (!update && this._promises.users) {
2176
2232
  return this._promises.users;
2177
2233
  }
2178
2234
  if (!this.connected) {
2179
- return Promise.reject(NOT_CONNECTED);
2235
+ return Promise.reject(new Error(NOT_CONNECTED));
2180
2236
  }
2181
2237
 
2182
2238
  this._promises.users = new Promise((resolve, reject) => {
@@ -2187,7 +2243,7 @@ class Connection {
2187
2243
  { startkey: 'system.user.', endkey: 'system.user.\u9999' },
2188
2244
  (err: string | null, doc: { rows: { value: ioBroker.UserObject; id: string }[] }) => {
2189
2245
  if (err) {
2190
- reject(err);
2246
+ reject(new Error(err));
2191
2247
  } else {
2192
2248
  resolve(doc.rows.map(item => item.value));
2193
2249
  }
@@ -2200,16 +2256,15 @@ class Connection {
2200
2256
 
2201
2257
  /**
2202
2258
  * Get the list of all groups.
2259
+ *
2260
+ * @param update Force update.
2203
2261
  */
2204
- getGroups(
2205
- /** Force update. */
2206
- update?: boolean,
2207
- ): Promise<ioBroker.GroupObject[]> {
2262
+ getGroups(update?: boolean): Promise<ioBroker.GroupObject[]> {
2208
2263
  if (!update && this._promises.groups) {
2209
2264
  return this._promises.groups;
2210
2265
  }
2211
2266
  if (!this.connected) {
2212
- return Promise.reject(NOT_CONNECTED);
2267
+ return Promise.reject(new Error(NOT_CONNECTED));
2213
2268
  }
2214
2269
 
2215
2270
  this._promises.groups = new Promise((resolve, reject) => {
@@ -2220,7 +2275,7 @@ class Connection {
2220
2275
  { startkey: 'system.group.', endkey: 'system.group.\u9999' },
2221
2276
  (err: string | null, doc: { rows: { value: ioBroker.GroupObject; id: string }[] }) => {
2222
2277
  if (err) {
2223
- reject(err);
2278
+ reject(new Error(err));
2224
2279
  } else {
2225
2280
  resolve(doc.rows.map(item => item.value));
2226
2281
  }
@@ -2233,16 +2288,14 @@ class Connection {
2233
2288
 
2234
2289
  /**
2235
2290
  * Get the host information.
2291
+ *
2292
+ * @param host The host name.
2293
+ * @param update Force update.
2294
+ * @param timeoutMs Optional read timeout.
2236
2295
  */
2237
- getHostInfo(
2238
- host: string,
2239
- /** Force update. */
2240
- update?: boolean,
2241
- /** optional read timeout. */
2242
- timeoutMs?: number,
2243
- ): Promise<HostInfo> {
2296
+ getHostInfo(host: string, update?: boolean, timeoutMs?: number): Promise<HostInfo> {
2244
2297
  if (Connection.isWeb()) {
2245
- return Promise.reject('Allowed only in admin');
2298
+ return Promise.reject(new Error('Allowed only in admin'));
2246
2299
  }
2247
2300
  if (!host.startsWith('system.host.')) {
2248
2301
  host += `system.host.${host}`;
@@ -2253,14 +2306,14 @@ class Connection {
2253
2306
  }
2254
2307
 
2255
2308
  if (!this.connected) {
2256
- return Promise.reject(NOT_CONNECTED);
2309
+ return Promise.reject(new Error(NOT_CONNECTED));
2257
2310
  }
2258
2311
 
2259
2312
  this._promises[`hostInfo_${host}`] = new Promise((resolve, reject) => {
2260
2313
  let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
2261
2314
  if (timeout) {
2262
2315
  timeout = null;
2263
- reject('getHostInfo timeout');
2316
+ reject(new Error('getHostInfo timeout'));
2264
2317
  }
2265
2318
  }, timeoutMs || this.props.cmdTimeout);
2266
2319
 
@@ -2269,9 +2322,9 @@ class Connection {
2269
2322
  clearTimeout(timeout);
2270
2323
  timeout = null;
2271
2324
  if (data === PERMISSION_ERROR) {
2272
- reject('May not read "getHostInfo"');
2325
+ reject(new Error('May not read "getHostInfo"'));
2273
2326
  } else if (!data || typeof data !== 'object') {
2274
- reject('Cannot read "getHostInfo"');
2327
+ reject(new Error('Cannot read "getHostInfo"'));
2275
2328
  } else {
2276
2329
  resolve(data);
2277
2330
  }
@@ -2284,16 +2337,14 @@ class Connection {
2284
2337
 
2285
2338
  /**
2286
2339
  * Get the host information (short version).
2340
+ *
2341
+ * @param host The host name.
2342
+ * @param update Force update.
2343
+ * @param timeoutMs Optional read timeout.
2287
2344
  */
2288
- getHostInfoShort(
2289
- host: string,
2290
- /** Force update. */
2291
- update?: boolean,
2292
- /** optional read timeout. */
2293
- timeoutMs?: number,
2294
- ): Promise<HostInfo> {
2345
+ getHostInfoShort(host: string, update?: boolean, timeoutMs?: number): Promise<HostInfo> {
2295
2346
  if (Connection.isWeb()) {
2296
- return Promise.reject('Allowed only in admin');
2347
+ return Promise.reject(new Error('Allowed only in admin'));
2297
2348
  }
2298
2349
  if (!host.startsWith('system.host.')) {
2299
2350
  host += `system.host.${host}`;
@@ -2303,14 +2354,14 @@ class Connection {
2303
2354
  }
2304
2355
 
2305
2356
  if (!this.connected) {
2306
- return Promise.reject(NOT_CONNECTED);
2357
+ return Promise.reject(new Error(NOT_CONNECTED));
2307
2358
  }
2308
2359
 
2309
2360
  this._promises[`hostInfoShort_${host}`] = new Promise((resolve, reject) => {
2310
2361
  let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
2311
2362
  if (timeout) {
2312
2363
  timeout = null;
2313
- reject('hostInfoShort timeout');
2364
+ reject(new Error('hostInfoShort timeout'));
2314
2365
  }
2315
2366
  }, timeoutMs || this.props.cmdTimeout);
2316
2367
 
@@ -2319,9 +2370,9 @@ class Connection {
2319
2370
  clearTimeout(timeout);
2320
2371
  timeout = null;
2321
2372
  if (data === PERMISSION_ERROR) {
2322
- reject('May not read "getHostInfoShort"');
2373
+ reject(new Error('May not read "getHostInfoShort"'));
2323
2374
  } else if (!data || typeof data !== 'object') {
2324
- reject('Cannot read "getHostInfoShort"');
2375
+ reject(new Error('Cannot read "getHostInfoShort"'));
2325
2376
  } else {
2326
2377
  resolve(data);
2327
2378
  }
@@ -2334,24 +2385,27 @@ class Connection {
2334
2385
 
2335
2386
  /**
2336
2387
  * Get the repository.
2388
+ *
2389
+ * @param host The host name.
2390
+ * @param options Options.
2391
+ * @param update Force update.
2392
+ * @param timeoutMs Timeout in ms.
2337
2393
  */
2338
2394
  getRepository(
2339
2395
  host: string,
2340
2396
  options?: { update: boolean; repo: string } | string,
2341
- /** Force update. */
2342
2397
  update?: boolean,
2343
- /** timeout in ms. */
2344
2398
  timeoutMs?: number,
2345
2399
  ): Promise<Record<string, ioBroker.AdapterObject>> {
2346
2400
  if (Connection.isWeb()) {
2347
- return Promise.reject('Allowed only in admin');
2401
+ return Promise.reject(new Error('Allowed only in admin'));
2348
2402
  }
2349
2403
  if (!update && this._promises.repo) {
2350
2404
  return this._promises.repo;
2351
2405
  }
2352
2406
 
2353
2407
  if (!this.connected) {
2354
- return Promise.reject(NOT_CONNECTED);
2408
+ return Promise.reject(new Error(NOT_CONNECTED));
2355
2409
  }
2356
2410
 
2357
2411
  if (!host.startsWith('system.host.')) {
@@ -2362,23 +2416,29 @@ class Connection {
2362
2416
  let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
2363
2417
  if (timeout) {
2364
2418
  timeout = null;
2365
- reject('getRepository timeout');
2419
+ reject(new Error('getRepository timeout'));
2366
2420
  }
2367
2421
  }, timeoutMs || this.props.cmdTimeout);
2368
2422
 
2369
- this._socket.emit('sendToHost', host, 'getRepository', options, (data: string | Record<string, ioBroker.AdapterObject>) => {
2370
- if (timeout) {
2371
- clearTimeout(timeout);
2372
- timeout = null;
2373
- if (data === PERMISSION_ERROR) {
2374
- reject('May not read "getRepository"');
2375
- } else if (!data || typeof data !== 'object') {
2376
- reject('Cannot read "getRepository"');
2377
- } else {
2378
- resolve(data);
2423
+ this._socket.emit(
2424
+ 'sendToHost',
2425
+ host,
2426
+ 'getRepository',
2427
+ options,
2428
+ (data: string | Record<string, ioBroker.AdapterObject>) => {
2429
+ if (timeout) {
2430
+ clearTimeout(timeout);
2431
+ timeout = null;
2432
+ if (data === PERMISSION_ERROR) {
2433
+ reject(new Error('May not read "getRepository"'));
2434
+ } else if (!data || typeof data !== 'object') {
2435
+ reject(new Error('Cannot read "getRepository"'));
2436
+ } else {
2437
+ resolve(data);
2438
+ }
2379
2439
  }
2380
- }
2381
- });
2440
+ },
2441
+ );
2382
2442
  });
2383
2443
 
2384
2444
  return this._promises.repo;
@@ -2386,16 +2446,14 @@ class Connection {
2386
2446
 
2387
2447
  /**
2388
2448
  * Get the installed.
2449
+ *
2450
+ * @param host The host name.
2451
+ * @param update Force update.
2452
+ * @param cmdTimeout Timeout in ms.
2389
2453
  */
2390
- getInstalled(
2391
- host: string,
2392
- /** Force update. */
2393
- update?: boolean,
2394
- /** timeout in ms */
2395
- cmdTimeout?: number,
2396
- ): Promise<Record<string, ioBroker.AdapterObject>> {
2454
+ getInstalled(host: string, update?: boolean, cmdTimeout?: number): Promise<Record<string, ioBroker.AdapterObject>> {
2397
2455
  if (Connection.isWeb()) {
2398
- return Promise.reject('Allowed only in admin');
2456
+ return Promise.reject(new Error('Allowed only in admin'));
2399
2457
  }
2400
2458
 
2401
2459
  this._promises.installed = this._promises.installed || {};
@@ -2405,7 +2463,7 @@ class Connection {
2405
2463
  }
2406
2464
 
2407
2465
  if (!this.connected) {
2408
- return Promise.reject(NOT_CONNECTED);
2466
+ return Promise.reject(new Error(NOT_CONNECTED));
2409
2467
  }
2410
2468
 
2411
2469
  if (!host.startsWith('system.host.')) {
@@ -2416,23 +2474,29 @@ class Connection {
2416
2474
  let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
2417
2475
  if (timeout) {
2418
2476
  timeout = null;
2419
- reject('getInstalled timeout');
2477
+ reject(new Error('getInstalled timeout'));
2420
2478
  }
2421
2479
  }, cmdTimeout || this.props.cmdTimeout);
2422
2480
 
2423
- this._socket.emit('sendToHost', host, 'getInstalled', null, (data: string | Record<string, ioBroker.AdapterObject>) => {
2424
- if (timeout) {
2425
- clearTimeout(timeout);
2426
- timeout = null;
2427
- if (data === PERMISSION_ERROR) {
2428
- reject('May not read "getInstalled"');
2429
- } else if (!data || typeof data !== 'object') {
2430
- reject('Cannot read "getInstalled"');
2431
- } else {
2432
- resolve(data);
2481
+ this._socket.emit(
2482
+ 'sendToHost',
2483
+ host,
2484
+ 'getInstalled',
2485
+ null,
2486
+ (data: string | Record<string, ioBroker.AdapterObject>) => {
2487
+ if (timeout) {
2488
+ clearTimeout(timeout);
2489
+ timeout = null;
2490
+ if (data === PERMISSION_ERROR) {
2491
+ reject(new Error('May not read "getInstalled"'));
2492
+ } else if (!data || typeof data !== 'object') {
2493
+ reject(new Error('Cannot read "getInstalled"'));
2494
+ } else {
2495
+ resolve(data);
2496
+ }
2433
2497
  }
2434
- }
2435
- });
2498
+ },
2499
+ );
2436
2500
  });
2437
2501
 
2438
2502
  return this._promises.installed[host] as Promise<Record<string, ioBroker.AdapterObject>>;
@@ -2440,21 +2504,19 @@ class Connection {
2440
2504
 
2441
2505
  /**
2442
2506
  * Rename file or folder in ioBroker DB
2507
+ *
2508
+ * @param adapter Instance name, like `vis-2.0`.
2509
+ * @param oldName The current file name, e.g., main/vis-views.json
2510
+ * @param newName The new file name, e.g., main/vis-views-new.json
2443
2511
  */
2444
- rename(
2445
- /** instance name */
2446
- adapter: string,
2447
- /** current file name, e.g., main/vis-views.json */
2448
- oldName: string,
2449
- /** new file name, e.g., main/vis-views-new.json */
2450
- newName: string,
2451
- ): Promise<void> {
2512
+ rename(adapter: string, oldName: string, newName: string): Promise<void> {
2452
2513
  if (!this.connected) {
2453
- return Promise.reject(NOT_CONNECTED);
2514
+ return Promise.reject(new Error(NOT_CONNECTED));
2454
2515
  }
2455
2516
  return new Promise((resolve, reject) => {
2456
2517
  this._socket.emit('rename', adapter, oldName, newName, (err: string | null) =>
2457
- (err ? reject(err) : resolve()));
2518
+ err ? reject(new Error(err)) : resolve(),
2519
+ );
2458
2520
  });
2459
2521
  }
2460
2522
 
@@ -2470,11 +2532,12 @@ class Connection {
2470
2532
  newName: string,
2471
2533
  ): Promise<void> {
2472
2534
  if (!this.connected) {
2473
- return Promise.reject(NOT_CONNECTED);
2535
+ return Promise.reject(new Error(NOT_CONNECTED));
2474
2536
  }
2475
2537
  return new Promise((resolve, reject) => {
2476
2538
  this._socket.emit('renameFile', adapter, oldName, newName, (err: string | null) =>
2477
- (err ? reject(err) : resolve()));
2539
+ err ? reject(new Error(err)) : resolve(),
2540
+ );
2478
2541
  });
2479
2542
  }
2480
2543
 
@@ -2492,10 +2555,10 @@ class Connection {
2492
2555
  cmdTimeout: number,
2493
2556
  ): Promise<void> {
2494
2557
  if (Connection.isWeb()) {
2495
- return Promise.reject('Allowed only in admin');
2558
+ return Promise.reject(new Error('Allowed only in admin'));
2496
2559
  }
2497
2560
  if (!this.connected) {
2498
- return Promise.reject(NOT_CONNECTED);
2561
+ return Promise.reject(new Error(NOT_CONNECTED));
2499
2562
  }
2500
2563
 
2501
2564
  if (!host.startsWith(host)) {
@@ -2503,19 +2566,21 @@ class Connection {
2503
2566
  }
2504
2567
 
2505
2568
  return new Promise((resolve, reject) => {
2506
- let timeout: ReturnType<typeof setTimeout> | null = cmdTimeout ? setTimeout(() => {
2507
- if (timeout) {
2508
- timeout = null;
2509
- reject('cmdExec timeout');
2510
- }
2511
- }, cmdTimeout) : null;
2569
+ let timeout: ReturnType<typeof setTimeout> | null = cmdTimeout
2570
+ ? setTimeout(() => {
2571
+ if (timeout) {
2572
+ timeout = null;
2573
+ reject(new Error('cmdExec timeout'));
2574
+ }
2575
+ }, cmdTimeout)
2576
+ : null;
2512
2577
 
2513
2578
  this._socket.emit('cmdExec', host, cmdId, cmd, null, (err: string | null) => {
2514
2579
  if (!cmdTimeout || timeout) {
2515
2580
  timeout && clearTimeout(timeout);
2516
2581
  timeout = null;
2517
2582
  if (err) {
2518
- reject(err);
2583
+ reject(new Error(err));
2519
2584
  } else {
2520
2585
  resolve();
2521
2586
  }
@@ -2538,12 +2603,13 @@ class Connection {
2538
2603
  }
2539
2604
 
2540
2605
  if (!this.connected) {
2541
- return Promise.reject(NOT_CONNECTED);
2606
+ return Promise.reject(new Error(NOT_CONNECTED));
2542
2607
  }
2543
2608
 
2544
2609
  this._promises[`supportedFeatures_${feature}`] = new Promise((resolve, reject) => {
2545
2610
  this._socket.emit('checkFeatureSupported', feature, (err: string | null, supported: boolean) =>
2546
- (err ? reject(err) : resolve(supported)));
2611
+ err ? reject(new Error(err)) : resolve(supported),
2612
+ );
2547
2613
  });
2548
2614
 
2549
2615
  return this._promises[`supportedFeatures_${feature}`] as Promise<boolean>;
@@ -2554,18 +2620,18 @@ class Connection {
2554
2620
  */
2555
2621
  async readBaseSettings(host: string): Promise<Record<string, any>> {
2556
2622
  if (Connection.isWeb()) {
2557
- return Promise.reject('Allowed only in admin');
2623
+ return Promise.reject(new Error('Allowed only in admin'));
2558
2624
  }
2559
2625
  const result = await this.checkFeatureSupported('CONTROLLER_READWRITE_BASE_SETTINGS');
2560
2626
  if (result) {
2561
2627
  if (!this.connected) {
2562
- return Promise.reject(NOT_CONNECTED);
2628
+ return Promise.reject(new Error(NOT_CONNECTED));
2563
2629
  }
2564
2630
  return new Promise((resolve, reject) => {
2565
2631
  let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
2566
2632
  if (timeout) {
2567
2633
  timeout = null;
2568
- reject('readBaseSettings timeout');
2634
+ reject(new Error('readBaseSettings timeout'));
2569
2635
  }
2570
2636
  }, this.props.cmdTimeout);
2571
2637
 
@@ -2573,50 +2639,60 @@ class Connection {
2573
2639
  host = host.replace(/^system\.host\./, '');
2574
2640
  }
2575
2641
 
2576
- this._socket.emit('sendToHost', host, 'readBaseSettings', null, (data: Record<string, any> | string) => {
2577
- if (timeout) {
2578
- clearTimeout(timeout);
2579
- timeout = null;
2580
-
2581
- if (data === PERMISSION_ERROR) {
2582
- reject('May not read "BaseSettings"');
2583
- } else if (!data || typeof data !== 'object') {
2584
- reject('Cannot read "BaseSettings"');
2585
- } else {
2586
- resolve(data);
2642
+ this._socket.emit(
2643
+ 'sendToHost',
2644
+ host,
2645
+ 'readBaseSettings',
2646
+ null,
2647
+ (data: Record<string, any> | string) => {
2648
+ if (timeout) {
2649
+ clearTimeout(timeout);
2650
+ timeout = null;
2651
+
2652
+ if (data === PERMISSION_ERROR) {
2653
+ reject(new Error('May not read "BaseSettings"'));
2654
+ } else if (!data || typeof data !== 'object') {
2655
+ reject(new Error('Cannot read "BaseSettings"'));
2656
+ } else {
2657
+ resolve(data);
2658
+ }
2587
2659
  }
2588
- }
2589
- });
2660
+ },
2661
+ );
2590
2662
  });
2591
2663
  }
2592
- return Promise.reject('Not supported');
2664
+ return Promise.reject(new Error('Not supported'));
2593
2665
  }
2594
2666
 
2595
2667
  /**
2596
2668
  * Write the base settings of a given host.
2597
- * @param {string} host
2598
- * @param {any} config
2599
- * @returns {Promise<any>}
2669
+ *
2670
+ * @param host The host name.
2671
+ * @param config The new base settings.
2600
2672
  */
2601
- writeBaseSettings(host: string, config: Record<string, any>): Promise<{ result?: 'ok'; error?: string }> {
2673
+ writeBaseSettings(host: string, config: IoBJson): Promise<{ result?: 'ok'; error?: string }> {
2602
2674
  if (Connection.isWeb()) {
2603
- return Promise.reject('Allowed only in admin');
2675
+ return Promise.reject(new Error('Allowed only in admin'));
2604
2676
  }
2605
- return this.checkFeatureSupported('CONTROLLER_READWRITE_BASE_SETTINGS')
2606
- .then(result => {
2607
- if (result) {
2608
- if (!this.connected) {
2609
- return Promise.reject(NOT_CONNECTED);
2610
- }
2611
- return new Promise((resolve, reject) => {
2612
- let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
2613
- if (timeout) {
2614
- timeout = null;
2615
- reject('writeBaseSettings timeout');
2616
- }
2617
- }, this.props.cmdTimeout);
2618
-
2619
- this._socket.emit('sendToHost', host, 'writeBaseSettings', config, (data: { result?: 'ok'; error?: string } | string) => {
2677
+ return this.checkFeatureSupported('CONTROLLER_READWRITE_BASE_SETTINGS').then(result => {
2678
+ if (result) {
2679
+ if (!this.connected) {
2680
+ return Promise.reject(new Error(NOT_CONNECTED));
2681
+ }
2682
+ return new Promise((resolve, reject) => {
2683
+ let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
2684
+ if (timeout) {
2685
+ timeout = null;
2686
+ reject(new Error('writeBaseSettings timeout'));
2687
+ }
2688
+ }, this.props.cmdTimeout);
2689
+
2690
+ this._socket.emit(
2691
+ 'sendToHost',
2692
+ host,
2693
+ 'writeBaseSettings',
2694
+ config,
2695
+ (data: { result?: 'ok'; error?: string } | string) => {
2620
2696
  if (timeout) {
2621
2697
  clearTimeout(timeout);
2622
2698
  timeout = null;
@@ -2629,12 +2705,13 @@ class Connection {
2629
2705
  resolve(data as { result?: 'ok'; error?: string });
2630
2706
  }
2631
2707
  }
2632
- });
2633
- });
2634
- }
2708
+ },
2709
+ );
2710
+ });
2711
+ }
2635
2712
 
2636
- return Promise.reject(new Error('Not supported'));
2637
- });
2713
+ return Promise.reject(new Error('Not supported'));
2714
+ });
2638
2715
  }
2639
2716
 
2640
2717
  /**
@@ -2642,31 +2719,29 @@ class Connection {
2642
2719
  */
2643
2720
  restartController(host: string): Promise<boolean> {
2644
2721
  if (Connection.isWeb()) {
2645
- return Promise.reject('Allowed only in admin');
2722
+ return Promise.reject(new Error('Allowed only in admin'));
2646
2723
  }
2647
2724
  return new Promise((resolve, reject) => {
2648
2725
  this._socket.emit('sendToHost', host, 'restartController', null, (error: string | null) => {
2649
- error ? reject(error) : resolve(true);
2726
+ error ? reject(new Error(error)) : resolve(true);
2650
2727
  });
2651
2728
  });
2652
2729
  }
2653
2730
 
2654
2731
  /**
2655
2732
  * Read statistics information from host
2656
- * @param {string} host
2657
- * @param {string} typeOfDiag one of none, normal, no-city, extended
2658
- * @returns {Promise<any>}
2733
+ *
2734
+ * @param host Host name
2735
+ * @param typeOfDiag one of none, normal, no-city, extended
2659
2736
  */
2660
- getDiagData(
2661
- host: string,
2662
- typeOfDiag: 'none' | 'normal' | 'no-city' | 'extended',
2663
- ): Promise<Record<string, any>> {
2737
+ getDiagData(host: string, typeOfDiag: 'none' | 'normal' | 'no-city' | 'extended'): Promise<Record<string, any>> {
2664
2738
  if (Connection.isWeb()) {
2665
- return Promise.reject('Allowed only in admin');
2739
+ return Promise.reject(new Error('Allowed only in admin'));
2666
2740
  }
2667
2741
  return new Promise(resolve => {
2668
2742
  this._socket.emit('sendToHost', host, 'getDiagData', typeOfDiag, (result: Record<string, any>) =>
2669
- resolve(result));
2743
+ resolve(result),
2744
+ );
2670
2745
  });
2671
2746
  }
2672
2747
 
@@ -2675,43 +2750,55 @@ class Connection {
2675
2750
  */
2676
2751
  getForeignStates(pattern?: string): Promise<Record<string, ioBroker.State>> {
2677
2752
  if (!this.connected) {
2678
- return Promise.reject(NOT_CONNECTED);
2753
+ return Promise.reject(new Error(NOT_CONNECTED));
2679
2754
  }
2680
2755
  if (Connection.isWeb()) {
2681
2756
  return new Promise((resolve, reject) => {
2682
- this._socket.emit('getStates', pattern || '*', (err: string | null, states: Record<string, ioBroker.State>) =>
2683
- (err ? reject(err) : resolve(states)));
2757
+ this._socket.emit(
2758
+ 'getStates',
2759
+ pattern || '*',
2760
+ (err: string | null, states: Record<string, ioBroker.State>) =>
2761
+ err ? reject(new Error(err)) : resolve(states),
2762
+ );
2684
2763
  });
2685
2764
  }
2686
2765
 
2687
2766
  return new Promise((resolve, reject) => {
2688
- this._socket.emit('getForeignStates', pattern || '*', (err: string | null, states: Record<string, ioBroker.State>) =>
2689
- (err ? reject(err) : resolve(states)));
2767
+ this._socket.emit(
2768
+ 'getForeignStates',
2769
+ pattern || '*',
2770
+ (err: string | null, states: Record<string, ioBroker.State>) =>
2771
+ err ? reject(new Error(err)) : resolve(states),
2772
+ );
2690
2773
  });
2691
2774
  }
2692
2775
 
2693
2776
  /**
2694
2777
  * Get foreign objects by pattern, by specific type and resolve their enums. (Only admin)
2695
- * @returns {ioBroker.GetObjectsPromise}
2696
2778
  */
2697
2779
  getForeignObjects(pattern: string, type?: ioBroker.ObjectType): Promise<Record<string, ioBroker.State>> {
2698
2780
  if (Connection.isWeb()) {
2699
- return Promise.reject('Allowed only in admin');
2781
+ return Promise.reject(new Error('Allowed only in admin'));
2700
2782
  }
2701
2783
 
2702
2784
  if (!this.connected) {
2703
- return Promise.reject(NOT_CONNECTED);
2785
+ return Promise.reject(new Error(NOT_CONNECTED));
2704
2786
  }
2705
2787
  return new Promise((resolve, reject) => {
2706
- this._socket.emit('getForeignObjects', pattern || '*', type, (err: string | null, states: Record<string, ioBroker.State>) =>
2707
- (err ? reject(err) : resolve(states)));
2788
+ this._socket.emit(
2789
+ 'getForeignObjects',
2790
+ pattern || '*',
2791
+ type,
2792
+ (err: string | null, states: Record<string, ioBroker.State>) =>
2793
+ err ? reject(new Error(err)) : resolve(states),
2794
+ );
2708
2795
  });
2709
2796
  }
2710
2797
 
2711
2798
  /**
2712
2799
  * Gets the system configuration.
2713
- * @param {boolean} [update] Force update.
2714
- * @returns {Promise<ioBroker.OtherObject>}
2800
+ *
2801
+ * @param update Force update.
2715
2802
  */
2716
2803
  getSystemConfig(update?: boolean): Promise<ioBroker.SystemConfigObject> {
2717
2804
  if (!update && this._promises.systemConfig) {
@@ -2719,16 +2806,15 @@ class Connection {
2719
2806
  }
2720
2807
 
2721
2808
  if (!this.connected) {
2722
- return Promise.reject(NOT_CONNECTED);
2809
+ return Promise.reject(new Error(NOT_CONNECTED));
2723
2810
  }
2724
2811
 
2725
- this._promises.systemConfig = this.getObject('system.config')
2726
- .then(obj => {
2727
- const systemConfig: ioBroker.SystemConfigObject = (obj || {}) as ioBroker.SystemConfigObject;
2728
- systemConfig.common = systemConfig.common || {} as ioBroker.SystemConfigCommon;
2729
- systemConfig.native = systemConfig.native || {};
2730
- return systemConfig;
2731
- });
2812
+ this._promises.systemConfig = this.getObject('system.config').then(obj => {
2813
+ const systemConfig: ioBroker.SystemConfigObject = (obj || {}) as ioBroker.SystemConfigObject;
2814
+ systemConfig.common = systemConfig.common || ({} as ioBroker.SystemConfigCommon);
2815
+ systemConfig.native = systemConfig.native || {};
2816
+ return systemConfig;
2817
+ });
2732
2818
 
2733
2819
  return this._promises.systemConfig;
2734
2820
  }
@@ -2736,9 +2822,12 @@ class Connection {
2736
2822
  /**
2737
2823
  * Sets the system configuration.
2738
2824
  */
2739
- setSystemConfig(obj: ioBroker.SettableObjectWorker<ioBroker.SystemConfigObject>): Promise<ioBroker.SystemConfigObject> {
2740
- return this.setObject('system.config', obj)
2741
- .then(() => this._promises.systemConfig = Promise.resolve(obj as ioBroker.SystemConfigObject));
2825
+ setSystemConfig(
2826
+ obj: ioBroker.SettableObjectWorker<ioBroker.SystemConfigObject>,
2827
+ ): Promise<ioBroker.SystemConfigObject> {
2828
+ return this.setObject('system.config', obj).then(
2829
+ () => (this._promises.systemConfig = Promise.resolve(obj as ioBroker.SystemConfigObject)),
2830
+ );
2742
2831
  }
2743
2832
 
2744
2833
  /**
@@ -2751,17 +2840,15 @@ class Connection {
2751
2840
  /**
2752
2841
  * Get the history of a given state.
2753
2842
  */
2754
- getHistory(
2755
- id: string,
2756
- options: ioBroker.GetHistoryOptions,
2757
- ): Promise<ioBroker.GetHistoryResult> {
2843
+ getHistory(id: string, options: ioBroker.GetHistoryOptions): Promise<ioBroker.GetHistoryResult> {
2758
2844
  if (!this.connected) {
2759
- return Promise.reject(NOT_CONNECTED);
2845
+ return Promise.reject(new Error(NOT_CONNECTED));
2760
2846
  }
2761
2847
 
2762
2848
  return new Promise((resolve, reject) => {
2763
2849
  this._socket.emit('getHistory', id, options, (err: string | null, values: ioBroker.GetHistoryResult) =>
2764
- (err ? reject(err) : resolve(values)));
2850
+ err ? reject(new Error(err)) : resolve(values),
2851
+ );
2765
2852
  });
2766
2853
  }
2767
2854
 
@@ -2773,28 +2860,31 @@ class Connection {
2773
2860
  options: ioBroker.GetHistoryOptions,
2774
2861
  ): Promise<{ values: ioBroker.GetHistoryResult; sessionId: string; stepIgnore: number }> {
2775
2862
  if (!this.connected) {
2776
- return Promise.reject(NOT_CONNECTED);
2863
+ return Promise.reject(new Error(NOT_CONNECTED));
2777
2864
  }
2778
2865
 
2779
2866
  return new Promise((resolve, reject) => {
2780
- this._socket.emit('getHistory', id, options, (err: string | null, values: ioBroker.GetHistoryResult, stepIgnore: number, sessionId: string) =>
2781
- (err ? reject(err) : resolve({ values, sessionId, stepIgnore })));
2867
+ this._socket.emit(
2868
+ 'getHistory',
2869
+ id,
2870
+ options,
2871
+ (err: string | null, values: ioBroker.GetHistoryResult, stepIgnore: number, sessionId: string) =>
2872
+ err ? reject(new Error(err)) : resolve({ values, sessionId, stepIgnore }),
2873
+ );
2782
2874
  });
2783
2875
  }
2784
2876
 
2785
2877
  /**
2786
2878
  * Change the password of the given user.
2787
2879
  */
2788
- changePassword(
2789
- user: string,
2790
- password: string,
2791
- ): Promise<void> {
2880
+ changePassword(user: string, password: string): Promise<void> {
2792
2881
  if (Connection.isWeb()) {
2793
- return Promise.reject('Allowed only in admin');
2882
+ return Promise.reject(new Error('Allowed only in admin'));
2794
2883
  }
2795
2884
  return new Promise((resolve, reject) => {
2796
2885
  this._socket.emit('changePassword', user, password, (err: string | null) =>
2797
- (err ? reject(err) : resolve()));
2886
+ err ? reject(new Error(err)) : resolve(),
2887
+ );
2798
2888
  });
2799
2889
  }
2800
2890
 
@@ -2807,7 +2897,7 @@ class Connection {
2807
2897
  update?: boolean,
2808
2898
  ): Promise<string[]> {
2809
2899
  if (Connection.isWeb()) {
2810
- return Promise.reject('Allowed only in admin');
2900
+ return Promise.reject(new Error('Allowed only in admin'));
2811
2901
  }
2812
2902
  if (!host.startsWith('system.host.')) {
2813
2903
  host = `system.host.${host}`;
@@ -2816,8 +2906,7 @@ class Connection {
2816
2906
  if (!update && this._promises[`IPs_${host}`]) {
2817
2907
  return this._promises[`IPs_${host}`] as Promise<string[]>;
2818
2908
  }
2819
- this._promises[`IPs_${host}`] = this.getObject(host)
2820
- .then(obj => (obj?.common ? obj.common.address || [] : []));
2909
+ this._promises[`IPs_${host}`] = this.getObject(host).then(obj => (obj?.common ? obj.common.address || [] : []));
2821
2910
 
2822
2911
  return this._promises[`IPs_${host}`] as Promise<string[]>;
2823
2912
  }
@@ -2831,14 +2920,16 @@ class Connection {
2831
2920
  update?: boolean,
2832
2921
  ): Promise<{ name: string; address: string; family: 'ipv4' | 'ipv6' }[]> {
2833
2922
  if (Connection.isWeb()) {
2834
- return Promise.reject('Allowed only in admin');
2923
+ return Promise.reject(new Error('Allowed only in admin'));
2835
2924
  }
2836
2925
  if (ipOrHostName.startsWith('system.host.')) {
2837
2926
  ipOrHostName = ipOrHostName.replace(/^system\.host\./, '');
2838
2927
  }
2839
2928
 
2840
2929
  if (!update && this._promises[`rIPs_${ipOrHostName}`]) {
2841
- return this._promises[`rIPs_${ipOrHostName}`] as Promise<{ name: string; address: string; family: 'ipv4' | 'ipv6' }[]>;
2930
+ return this._promises[`rIPs_${ipOrHostName}`] as Promise<
2931
+ { name: string; address: string; family: 'ipv4' | 'ipv6' }[]
2932
+ >;
2842
2933
  }
2843
2934
  this._promises[`rIPs_${ipOrHostName}`] = new Promise(resolve => {
2844
2935
  this._socket.emit('getHostByIp', ipOrHostName, (ip: string, host: any) => {
@@ -2881,7 +2972,9 @@ class Connection {
2881
2972
  });
2882
2973
  });
2883
2974
 
2884
- return this._promises[`rIPs_${ipOrHostName}`] as Promise<{ name: string; address: string; family: 'ipv4' | 'ipv6' }[]>;
2975
+ return this._promises[`rIPs_${ipOrHostName}`] as Promise<
2976
+ { name: string; address: string; family: 'ipv4' | 'ipv6' }[]
2977
+ >;
2885
2978
  }
2886
2979
 
2887
2980
  /**
@@ -2889,11 +2982,12 @@ class Connection {
2889
2982
  */
2890
2983
  encrypt(text: string): Promise<string> {
2891
2984
  if (Connection.isWeb()) {
2892
- return Promise.reject('Allowed only in admin');
2985
+ return Promise.reject(new Error('Allowed only in admin'));
2893
2986
  }
2894
2987
  return new Promise((resolve, reject) => {
2895
2988
  this._socket.emit('encrypt', text, (err: string | null, _text: string) =>
2896
- (err ? reject(err) : resolve(_text)));
2989
+ err ? reject(new Error(err)) : resolve(_text),
2990
+ );
2897
2991
  });
2898
2992
  }
2899
2993
 
@@ -2902,52 +2996,57 @@ class Connection {
2902
2996
  */
2903
2997
  decrypt(encryptedText: string): Promise<string> {
2904
2998
  if (Connection.isWeb()) {
2905
- return Promise.reject('Allowed only in admin');
2999
+ return Promise.reject(new Error('Allowed only in admin'));
2906
3000
  }
2907
3001
  return new Promise((resolve, reject) => {
2908
3002
  this._socket.emit('decrypt', encryptedText, (err: string | null, text: string) =>
2909
- (err ? reject(err) : resolve(text)));
3003
+ err ? reject(new Error(err)) : resolve(text),
3004
+ );
2910
3005
  });
2911
3006
  }
2912
3007
 
2913
3008
  /**
2914
3009
  * Gets the version.
2915
- * @returns {Promise<{version: string; serverName: string}>}
2916
3010
  */
2917
3011
  getVersion(update?: boolean): Promise<{ version: string; serverName: string }> {
2918
3012
  if (update && this._promises.version) {
2919
3013
  delete this._promises.version;
2920
3014
  }
2921
3015
 
2922
- this._promises.version = this._promises.version || new Promise((resolve, reject) => {
2923
- this._socket.emit('getVersion', (err: string | null, version: string, serverName: string) => {
2924
- // support of old socket.io
2925
- if (err && !version && typeof err === 'string' && err.match(/\d+\.\d+\.\d+/)) {
2926
- resolve({ version: err, serverName: 'socketio' });
2927
- } else {
2928
- err ? reject(err) : resolve({ version, serverName });
2929
- }
3016
+ this._promises.version =
3017
+ this._promises.version ||
3018
+ new Promise((resolve, reject) => {
3019
+ this._socket.emit('getVersion', (err: string | null, version: string, serverName: string) => {
3020
+ // support of old socket.io
3021
+ if (err && !version && typeof err === 'string' && err.match(/\d+\.\d+\.\d+/)) {
3022
+ resolve({ version: err, serverName: 'socketio' });
3023
+ } else {
3024
+ err ? reject(new Error(err)) : resolve({ version, serverName });
3025
+ }
3026
+ });
2930
3027
  });
2931
- });
2932
3028
 
2933
3029
  return this._promises.version;
2934
3030
  }
2935
3031
 
2936
3032
  /**
2937
3033
  * Gets the web server name.
2938
- * @returns {Promise<string>}
2939
3034
  */
2940
3035
  getWebServerName(): Promise<string> {
2941
- this._promises.webName = this._promises.webName || new Promise((resolve, reject) => {
2942
- this._socket.emit('getAdapterName', (err: string | null, name: string) =>
2943
- (err ? reject(err) : resolve(name)));
2944
- });
3036
+ this._promises.webName =
3037
+ this._promises.webName ||
3038
+ new Promise((resolve, reject) => {
3039
+ this._socket.emit('getAdapterName', (err: string | null, name: string) =>
3040
+ err ? reject(new Error(err)) : resolve(name),
3041
+ );
3042
+ });
2945
3043
 
2946
3044
  return this._promises.webName;
2947
3045
  }
2948
3046
 
2949
3047
  /**
2950
3048
  * Gets the admin version.
3049
+ *
2951
3050
  * @deprecated use getVersion()
2952
3051
  */
2953
3052
  getAdminVersion(): Promise<{ version: string; serverName: string }> {
@@ -2956,112 +3055,128 @@ class Connection {
2956
3055
  }
2957
3056
 
2958
3057
  /**
2959
- * Change access rights for file
3058
+ * Change access rights for a file
3059
+ *
3060
+ * @param adapter The adapter name.
3061
+ * @param fileName file name with a full path. It could be like vis.0/*
3062
+ * @param options like {mode: 0x644}
3063
+ * @param options.mode Access rights. Default is 0x644
2960
3064
  */
2961
3065
  chmodFile(
2962
- /** adapter name */
2963
3066
  adapter: string,
2964
- /** file name with a full path. It could be like vis.0/* */
2965
- filename: string,
2966
- /** like {mode: 0x644} */
3067
+ fileName: string,
2967
3068
  options?: { mode: number },
2968
3069
  ): Promise<{ entries: ioBroker.ChownFileResult[]; id: string }> {
2969
3070
  if (Connection.isWeb()) {
2970
- return Promise.reject('Allowed only in admin');
3071
+ return Promise.reject(new Error('Allowed only in admin'));
2971
3072
  }
2972
3073
  if (!this.connected) {
2973
- return Promise.reject(NOT_CONNECTED);
3074
+ return Promise.reject(new Error(NOT_CONNECTED));
2974
3075
  }
2975
3076
 
2976
3077
  return new Promise((resolve, reject) => {
2977
- this._socket.emit('chmodFile', adapter, filename, options, (err: string | null, entries: ioBroker.ChownFileResult[], id: string) =>
2978
- (err ? reject(err) : resolve({ entries, id })));
3078
+ this._socket.emit(
3079
+ 'chmodFile',
3080
+ adapter,
3081
+ fileName,
3082
+ options,
3083
+ (err: string | null, entries: ioBroker.ChownFileResult[], id: string) =>
3084
+ err ? reject(new Error(err)) : resolve({ entries, id }),
3085
+ );
2979
3086
  });
2980
3087
  }
2981
3088
 
2982
3089
  /**
2983
- * Change an owner or/and owner group for file
3090
+ * Change an owner or/and owner group for a file
3091
+ *
3092
+ * @param adapter The adapter name.
3093
+ * @param fileName file name with a full path. It could be like vis.0/*
3094
+ * @param options like {owner: 'user', ownerGroup: 'group'}
3095
+ * @param options.owner User name
3096
+ * @param options.ownerGroup Group name
2984
3097
  */
2985
3098
  chownFile(
2986
- /** adapter name */
2987
3099
  adapter: string,
2988
- /** file name with a full path. It could be like vis.0/* */
2989
3100
  fileName: string,
2990
3101
  options: { owner?: string; ownerGroup?: string },
2991
3102
  ): Promise<{ entries: ioBroker.ChownFileResult[]; id: string }> {
2992
3103
  if (Connection.isWeb()) {
2993
- return Promise.reject('Allowed only in admin');
3104
+ return Promise.reject(new Error('Allowed only in admin'));
2994
3105
  }
2995
3106
  if (!this.connected) {
2996
- return Promise.reject(NOT_CONNECTED);
3107
+ return Promise.reject(new Error(NOT_CONNECTED));
2997
3108
  }
2998
3109
 
2999
3110
  return new Promise((resolve, reject) => {
3000
- this._socket.emit('chownFile', adapter, fileName, options, (err: string | null, entries: ioBroker.ChownFileResult[], id: string) =>
3001
- (err ? reject(err) : resolve({ entries, id })));
3111
+ this._socket.emit(
3112
+ 'chownFile',
3113
+ adapter,
3114
+ fileName,
3115
+ options,
3116
+ (err: string | null, entries: ioBroker.ChownFileResult[], id: string) =>
3117
+ err ? reject(new Error(err)) : resolve({ entries, id }),
3118
+ );
3002
3119
  });
3003
3120
  }
3004
3121
 
3005
3122
  /**
3006
3123
  * Check if the file exists
3124
+ *
3125
+ * @param adapter The adapter name.
3126
+ * @param fileName file name with a full path. It could be like vis.0/*
3007
3127
  */
3008
- fileExists(
3009
- /** adapter name */
3010
- adapter: string,
3011
- /** file name with a full path. It could be like vis.0/* */
3012
- fileName: string,
3013
- ): Promise<boolean> {
3128
+ fileExists(adapter: string, fileName: string): Promise<boolean> {
3014
3129
  if (!this.connected) {
3015
- return Promise.reject(NOT_CONNECTED);
3130
+ return Promise.reject(new Error(NOT_CONNECTED));
3016
3131
  }
3017
3132
 
3018
3133
  return new Promise((resolve, reject) => {
3019
3134
  this._socket.emit('fileExists', adapter, fileName, (err: string | null, exists: boolean) =>
3020
- (err ? reject(err) : resolve(exists)));
3135
+ err ? reject(new Error(err)) : resolve(exists),
3136
+ );
3021
3137
  });
3022
3138
  }
3023
3139
 
3024
3140
  /**
3025
3141
  * Get the alarm notifications from a host (only for admin connection).
3026
- * @returns {Promise<any>}
3027
3142
  */
3028
- getNotifications(
3029
- host: string,
3030
- category?: string,
3031
- ): Promise<FilteredNotificationInformation> {
3143
+ getNotifications(host: string, category?: string): Promise<FilteredNotificationInformation> {
3032
3144
  if (Connection.isWeb()) {
3033
- return Promise.reject('Allowed only in admin');
3145
+ return Promise.reject(new Error('Allowed only in admin'));
3034
3146
  }
3035
3147
 
3036
3148
  if (!this.connected) {
3037
- return Promise.reject(NOT_CONNECTED);
3149
+ return Promise.reject(new Error(NOT_CONNECTED));
3038
3150
  }
3039
3151
  return new Promise(resolve => {
3040
- this._socket.emit('sendToHost', host, 'getNotifications', { category }, (notifications: FilteredNotificationInformation) =>
3041
- resolve(notifications));
3152
+ this._socket.emit(
3153
+ 'sendToHost',
3154
+ host,
3155
+ 'getNotifications',
3156
+ { category },
3157
+ (notifications: FilteredNotificationInformation) => resolve(notifications),
3158
+ );
3042
3159
  });
3043
3160
  }
3044
3161
 
3045
3162
  /**
3046
3163
  * Clear the alarm notifications on a host (only for admin connection).
3047
- * @param {string} host
3048
- * @param {string} [category] - optional
3049
- * @returns {Promise<any>}
3164
+ *
3165
+ * @param host The host name.
3166
+ * @param category optional
3050
3167
  */
3051
- clearNotifications(
3052
- host: string,
3053
- category?: string,
3054
- ): Promise<{ result: 'ok' }> {
3168
+ clearNotifications(host: string, category?: string): Promise<{ result: 'ok' }> {
3055
3169
  if (Connection.isWeb()) {
3056
- return Promise.reject('Allowed only in admin');
3170
+ return Promise.reject(new Error('Allowed only in admin'));
3057
3171
  }
3058
3172
 
3059
3173
  if (!this.connected) {
3060
- return Promise.reject(NOT_CONNECTED);
3174
+ return Promise.reject(new Error(NOT_CONNECTED));
3061
3175
  }
3062
3176
  return new Promise(resolve => {
3063
3177
  this._socket.emit('sendToHost', host, 'clearNotifications', { category }, (result: { result: 'ok' }) =>
3064
- resolve(result));
3178
+ resolve(result),
3179
+ );
3065
3180
  });
3066
3181
  }
3067
3182
 
@@ -3070,52 +3185,51 @@ class Connection {
3070
3185
  */
3071
3186
  getIsEasyModeStrict(): Promise<boolean> {
3072
3187
  if (Connection.isWeb()) {
3073
- return Promise.reject('Allowed only in admin');
3188
+ return Promise.reject(new Error('Allowed only in admin'));
3074
3189
  }
3075
3190
  if (!this.connected) {
3076
- return Promise.reject(NOT_CONNECTED);
3191
+ return Promise.reject(new Error(NOT_CONNECTED));
3077
3192
  }
3078
3193
  return new Promise((resolve, reject) => {
3079
3194
  this._socket.emit('getIsEasyModeStrict', (error: null | string, isStrict: boolean) =>
3080
- (error ? reject(error) : resolve(isStrict)));
3195
+ error ? reject(new Error(error)) : resolve(isStrict),
3196
+ );
3081
3197
  });
3082
3198
  }
3083
3199
 
3084
3200
  /**
3085
3201
  * Read easy mode configuration (only for admin connection).
3086
- * @returns {Promise<any>}
3087
3202
  */
3088
3203
  getEasyMode(): Promise<any> {
3089
3204
  if (Connection.isWeb()) {
3090
- return Promise.reject('Allowed only in admin');
3205
+ return Promise.reject(new Error('Allowed only in admin'));
3091
3206
  }
3092
3207
  if (!this.connected) {
3093
- return Promise.reject(NOT_CONNECTED);
3208
+ return Promise.reject(new Error(NOT_CONNECTED));
3094
3209
  }
3095
3210
  return new Promise((resolve, reject) => {
3096
3211
  this._socket.emit('getEasyMode', (error: string | null, config: any) =>
3097
- (error ? reject(error) : resolve(config)));
3212
+ error ? reject(new Error(error)) : resolve(config),
3213
+ );
3098
3214
  });
3099
3215
  }
3100
3216
 
3101
3217
  /**
3102
3218
  * Read current user
3103
- * @returns {Promise<string>}
3104
3219
  */
3105
3220
  getCurrentUser(): Promise<string> {
3106
3221
  if (!this.connected) {
3107
- return Promise.reject(NOT_CONNECTED);
3222
+ return Promise.reject(new Error(NOT_CONNECTED));
3108
3223
  }
3109
3224
 
3110
3225
  return new Promise(resolve => {
3111
- this._socket.emit('authEnabled', (isSecure: boolean, user: string) =>
3112
- resolve(user));
3226
+ this._socket.emit('authEnabled', (isSecure: boolean, user: string) => resolve(user));
3113
3227
  });
3114
3228
  }
3115
3229
 
3116
- getCurrentSession(cmdTimeout?: number) {
3230
+ getCurrentSession(cmdTimeout?: number): Promise<{ expireInSec: number }> {
3117
3231
  if (!this.connected) {
3118
- return Promise.reject(NOT_CONNECTED);
3232
+ return Promise.reject(new Error(NOT_CONNECTED));
3119
3233
  }
3120
3234
 
3121
3235
  return new Promise((resolve, reject) => {
@@ -3125,7 +3239,7 @@ class Connection {
3125
3239
  if (timeout) {
3126
3240
  timeout = null;
3127
3241
  controller.abort();
3128
- reject('getCurrentSession timeout');
3242
+ reject(new Error('getCurrentSession timeout'));
3129
3243
  }
3130
3244
  }, cmdTimeout || 5000);
3131
3245
 
@@ -3138,25 +3252,24 @@ class Connection {
3138
3252
  resolve(json);
3139
3253
  }
3140
3254
  })
3141
- .catch(e =>
3142
- reject(`getCurrentSession: ${e}`));
3255
+ .catch(e => reject(new Error(`getCurrentSession: ${e}`)));
3143
3256
  });
3144
3257
  }
3145
3258
 
3146
3259
  /**
3147
3260
  * Read adapter ratings
3148
- * @returns {Promise<any>}
3149
3261
  */
3150
3262
  getRatings(update?: boolean): Promise<any> {
3151
3263
  if (Connection.isWeb()) {
3152
- return Promise.reject('Allowed only in admin');
3264
+ return Promise.reject(new Error('Allowed only in admin'));
3153
3265
  }
3154
3266
  if (!this.connected) {
3155
- return Promise.reject(NOT_CONNECTED);
3267
+ return Promise.reject(new Error(NOT_CONNECTED));
3156
3268
  }
3157
3269
  return new Promise((resolve, reject) => {
3158
3270
  this._socket.emit('getRatings', update, (err: string | null, ratings: any) =>
3159
- (err ? reject(err) : resolve(ratings)));
3271
+ err ? reject(new Error(err)) : resolve(ratings),
3272
+ );
3160
3273
  });
3161
3274
  }
3162
3275
 
@@ -3165,13 +3278,15 @@ class Connection {
3165
3278
  */
3166
3279
  getCurrentInstance(): Promise<string> {
3167
3280
  if (!this.connected) {
3168
- return Promise.reject(NOT_CONNECTED);
3281
+ return Promise.reject(new Error(NOT_CONNECTED));
3169
3282
  }
3170
3283
 
3171
- this._promises.currentInstance = this._promises.currentInstance ||
3284
+ this._promises.currentInstance =
3285
+ this._promises.currentInstance ||
3172
3286
  new Promise((resolve, reject) => {
3173
3287
  this._socket.emit('getCurrentInstance', (err: string | null, namespace: string) =>
3174
- (err ? reject(err) : resolve(namespace)));
3288
+ err ? reject(new Error(err)) : resolve(namespace),
3289
+ );
3175
3290
  });
3176
3291
 
3177
3292
  return this._promises.currentInstance;
@@ -3180,17 +3295,20 @@ class Connection {
3180
3295
  // returns very optimized information for adapters to minimize a connection load
3181
3296
  getCompactAdapters(update?: boolean): Promise<Record<string, ioBroker.AdapterObject>> {
3182
3297
  if (Connection.isWeb()) {
3183
- return Promise.reject('Allowed only in admin');
3298
+ return Promise.reject(new Error('Allowed only in admin'));
3184
3299
  }
3185
3300
  if (!update && this._promises.compactAdapters) {
3186
3301
  return this._promises.compactAdapters;
3187
3302
  }
3188
3303
  if (!this.connected) {
3189
- return Promise.reject(NOT_CONNECTED);
3304
+ return Promise.reject(new Error(NOT_CONNECTED));
3190
3305
  }
3191
3306
  this._promises.compactAdapters = new Promise((resolve, reject) => {
3192
- this._socket.emit('getCompactAdapters', (err: string | null, adapters: Record<string, ioBroker.AdapterObject>) =>
3193
- (err ? reject(err) : resolve(adapters)));
3307
+ this._socket.emit(
3308
+ 'getCompactAdapters',
3309
+ (err: string | null, adapters: Record<string, ioBroker.AdapterObject>) =>
3310
+ err ? reject(new Error(err)) : resolve(adapters),
3311
+ );
3194
3312
  });
3195
3313
 
3196
3314
  return this._promises.compactAdapters;
@@ -3205,24 +3323,27 @@ class Connection {
3205
3323
  // returns very optimized information for adapters to minimize a connection load
3206
3324
  getCompactInstances(update?: boolean): Promise<Record<string, ioBroker.InstanceObject>> {
3207
3325
  if (Connection.isWeb()) {
3208
- return Promise.reject('Allowed only in admin');
3326
+ return Promise.reject(new Error('Allowed only in admin'));
3209
3327
  }
3210
3328
  if (!update && this._promises.compactInstances) {
3211
3329
  return this._promises.compactInstances;
3212
3330
  }
3213
3331
  if (!this.connected) {
3214
- return Promise.reject(NOT_CONNECTED);
3332
+ return Promise.reject(new Error(NOT_CONNECTED));
3215
3333
  }
3216
3334
 
3217
3335
  this._promises.compactInstances = new Promise((resolve, reject) => {
3218
- this._socket.emit('getCompactInstances', (err: string | null, instances: Record<string, ioBroker.InstanceObject>) =>
3219
- (err ? reject(err) : resolve(instances)));
3336
+ this._socket.emit(
3337
+ 'getCompactInstances',
3338
+ (err: string | null, instances: Record<string, ioBroker.InstanceObject>) =>
3339
+ err ? reject(new Error(err)) : resolve(instances),
3340
+ );
3220
3341
  });
3221
3342
 
3222
3343
  return this._promises.compactInstances;
3223
3344
  }
3224
3345
 
3225
- getAdapternInstancesResetCache(adapter?: string) {
3346
+ getAdapternInstancesResetCache(adapter?: string): void {
3226
3347
  adapter = adapter || '';
3227
3348
  delete this._promises.compactInstances;
3228
3349
  delete this._promises[`instances_${adapter}`];
@@ -3238,7 +3359,7 @@ class Connection {
3238
3359
  cmdTimeout?: number,
3239
3360
  ): Promise<Record<string, ioBroker.AdapterObject>> {
3240
3361
  if (Connection.isWeb()) {
3241
- return Promise.reject('Allowed only in admin');
3362
+ return Promise.reject(new Error('Allowed only in admin'));
3242
3363
  }
3243
3364
 
3244
3365
  this._promises.installedCompact = this._promises.installedCompact || {};
@@ -3248,7 +3369,7 @@ class Connection {
3248
3369
  }
3249
3370
 
3250
3371
  if (!this.connected) {
3251
- return Promise.reject(NOT_CONNECTED);
3372
+ return Promise.reject(new Error(NOT_CONNECTED));
3252
3373
  }
3253
3374
 
3254
3375
  if (!host.startsWith('system.host.')) {
@@ -3259,7 +3380,7 @@ class Connection {
3259
3380
  let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
3260
3381
  if (timeout) {
3261
3382
  timeout = null;
3262
- reject('getCompactInstalled timeout');
3383
+ reject(new Error('getCompactInstalled timeout'));
3263
3384
  }
3264
3385
  }, cmdTimeout || this.props.cmdTimeout);
3265
3386
 
@@ -3268,9 +3389,9 @@ class Connection {
3268
3389
  clearTimeout(timeout);
3269
3390
  timeout = null;
3270
3391
  if (data === PERMISSION_ERROR) {
3271
- reject('May not read "getCompactInstalled"');
3392
+ reject(new Error('May not read "getCompactInstalled"'));
3272
3393
  } else if (!data || typeof data !== 'object') {
3273
- reject('Cannot read "getCompactInstalled"');
3394
+ reject(new Error('Cannot read "getCompactInstalled"'));
3274
3395
  } else {
3275
3396
  resolve(data);
3276
3397
  }
@@ -3283,38 +3404,35 @@ class Connection {
3283
3404
 
3284
3405
  // returns very optimized information for adapters to minimize a connection load.
3285
3406
  // reads only version of installed adapter
3286
- getCompactSystemRepositories(
3287
- update?: boolean,
3288
- cmdTimeout?: number,
3289
- ): Promise<ioBroker.Object> {
3407
+ getCompactSystemRepositories(update?: boolean, cmdTimeout?: number): Promise<CompactSystemRepository> {
3290
3408
  if (Connection.isWeb()) {
3291
- return Promise.reject('Allowed only in admin');
3409
+ return Promise.reject(new Error('Allowed only in admin'));
3292
3410
  }
3293
3411
 
3294
3412
  if (!update && this._promises.getCompactSystemRepositories) {
3295
- return this._promises.getCompactSystemRepositories as Promise<ioBroker.Object>;
3413
+ return this._promises.getCompactSystemRepositories;
3296
3414
  }
3297
3415
 
3298
3416
  if (!this.connected) {
3299
- return Promise.reject(NOT_CONNECTED);
3417
+ return Promise.reject(new Error(NOT_CONNECTED));
3300
3418
  }
3301
3419
 
3302
3420
  this._promises.getCompactSystemRepositories = new Promise((resolve, reject) => {
3303
3421
  let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
3304
3422
  if (timeout) {
3305
3423
  timeout = null;
3306
- reject('getCompactSystemRepositories timeout');
3424
+ reject(new Error('getCompactSystemRepositories timeout'));
3307
3425
  }
3308
3426
  }, cmdTimeout || this.props.cmdTimeout);
3309
3427
 
3310
- this._socket.emit('getCompactSystemRepositories', (data: ioBroker.Object | string) => {
3428
+ this._socket.emit('getCompactSystemRepositories', (data: CompactSystemRepository | string) => {
3311
3429
  if (timeout) {
3312
3430
  clearTimeout(timeout);
3313
3431
  timeout = null;
3314
3432
  if (data === PERMISSION_ERROR) {
3315
- reject('May not read "getCompactSystemRepositories"');
3433
+ reject(new Error('May not read "getCompactSystemRepositories"'));
3316
3434
  } else if (!data || typeof data !== 'object') {
3317
- reject('Cannot read "getCompactSystemRepositories"');
3435
+ reject(new Error('Cannot read "getCompactSystemRepositories"'));
3318
3436
  } else {
3319
3437
  resolve(data);
3320
3438
  }
@@ -3332,12 +3450,15 @@ class Connection {
3332
3450
  }
3333
3451
 
3334
3452
  if (!this.connected) {
3335
- return Promise.reject(NOT_CONNECTED);
3453
+ return Promise.reject(new Error(NOT_CONNECTED));
3336
3454
  }
3337
3455
 
3338
3456
  this._promises.systemConfigPromise = new Promise((resolve, reject) => {
3339
- this._socket.emit('getCompactSystemConfig', (err: string | null, systemConfig: ioBroker.SystemConfigObject) =>
3340
- (err ? reject(err) : resolve(systemConfig)));
3457
+ this._socket.emit(
3458
+ 'getCompactSystemConfig',
3459
+ (err: string | null, systemConfig: ioBroker.SystemConfigObject) =>
3460
+ err ? reject(new Error(err)) : resolve(systemConfig),
3461
+ );
3341
3462
  });
3342
3463
 
3343
3464
  return this._promises.systemConfigPromise;
@@ -3345,10 +3466,10 @@ class Connection {
3345
3466
 
3346
3467
  /**
3347
3468
  * Get the repository in compact form (only version and icon).
3348
- * @param {string} host
3349
- * @param {boolean} [update] Force update.
3350
- * @param {number} [timeoutMs] timeout in ms.
3351
- * @returns {Promise<any>}
3469
+ *
3470
+ * @param host The host name.
3471
+ * @param update Force update.
3472
+ * @param timeoutMs timeout in ms.
3352
3473
  */
3353
3474
  getCompactRepository(
3354
3475
  host: string,
@@ -3356,7 +3477,7 @@ class Connection {
3356
3477
  timeoutMs?: number,
3357
3478
  ): Promise<Record<string, { version: string; icon: string }>> {
3358
3479
  if (Connection.isWeb()) {
3359
- return Promise.reject('Allowed only in admin');
3480
+ return Promise.reject(new Error('Allowed only in admin'));
3360
3481
  }
3361
3482
 
3362
3483
  if (!update && this._promises.repoCompact) {
@@ -3364,7 +3485,7 @@ class Connection {
3364
3485
  }
3365
3486
 
3366
3487
  if (!this.connected) {
3367
- return Promise.reject(NOT_CONNECTED);
3488
+ return Promise.reject(new Error(NOT_CONNECTED));
3368
3489
  }
3369
3490
 
3370
3491
  if (!host.startsWith('system.host.')) {
@@ -3375,29 +3496,33 @@ class Connection {
3375
3496
  let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
3376
3497
  if (timeout) {
3377
3498
  timeout = null;
3378
- reject('getCompactRepository timeout');
3499
+ reject(new Error('getCompactRepository timeout'));
3379
3500
  }
3380
3501
  }, timeoutMs || this.props.cmdTimeout);
3381
3502
 
3382
- this._socket.emit('getCompactRepository', host, (data: Record<string, { version: string; icon: string }> | string) => {
3383
- if (timeout) {
3384
- clearTimeout(timeout);
3385
- timeout = null;
3386
- if (data === PERMISSION_ERROR) {
3387
- reject('May not read "getCompactRepository"');
3388
- } else if (!data) {
3389
- reject('Cannot read "getCompactRepository"');
3390
- } else {
3391
- resolve(data);
3503
+ this._socket.emit(
3504
+ 'getCompactRepository',
3505
+ host,
3506
+ (data: Record<string, { version: string; icon: string }> | string) => {
3507
+ if (timeout) {
3508
+ clearTimeout(timeout);
3509
+ timeout = null;
3510
+ if (data === PERMISSION_ERROR) {
3511
+ reject(new Error('May not read "getCompactRepository"'));
3512
+ } else if (!data) {
3513
+ reject(new Error('Cannot read "getCompactRepository"'));
3514
+ } else {
3515
+ resolve(data);
3516
+ }
3392
3517
  }
3393
- }
3394
- });
3518
+ },
3519
+ );
3395
3520
  });
3396
3521
 
3397
3522
  return this._promises.repoCompact;
3398
3523
  }
3399
3524
 
3400
- getInstalledResetCache() {
3525
+ getInstalledResetCache(): void {
3401
3526
  delete this._promises.repoCompact;
3402
3527
  delete this._promises.repo;
3403
3528
  }
@@ -3407,19 +3532,20 @@ class Connection {
3407
3532
  */
3408
3533
  getCompactHosts(update?: boolean): Promise<ioBroker.HostObject[]> {
3409
3534
  if (Connection.isWeb()) {
3410
- return Promise.reject('Allowed only in admin');
3535
+ return Promise.reject(new Error('Allowed only in admin'));
3411
3536
  }
3412
3537
  if (!update && this._promises.hostsCompact) {
3413
3538
  return this._promises.hostsCompact;
3414
3539
  }
3415
3540
 
3416
3541
  if (!this.connected) {
3417
- return Promise.reject(NOT_CONNECTED);
3542
+ return Promise.reject(new Error(NOT_CONNECTED));
3418
3543
  }
3419
3544
 
3420
3545
  this._promises.hostsCompact = new Promise((resolve, reject) => {
3421
3546
  this._socket.emit('getCompactHosts', (err: string | null, hosts: ioBroker.HostObject[]) =>
3422
- (err ? reject(err) : resolve(hosts)));
3547
+ err ? reject(new Error(err)) : resolve(hosts),
3548
+ );
3423
3549
  });
3424
3550
 
3425
3551
  return this._promises.hostsCompact;
@@ -3434,34 +3560,30 @@ class Connection {
3434
3560
  }
3435
3561
 
3436
3562
  if (!this.connected) {
3437
- return Promise.reject(NOT_CONNECTED);
3563
+ return Promise.reject(new Error(NOT_CONNECTED));
3438
3564
  }
3439
3565
 
3440
- this._promises.uuid = this.getObject('system.meta.uuid')
3441
- .then(obj => obj?.native?.uuid);
3566
+ this._promises.uuid = this.getObject('system.meta.uuid').then(obj => obj?.native?.uuid);
3442
3567
 
3443
3568
  return this._promises.uuid;
3444
3569
  }
3445
3570
 
3446
3571
  /**
3447
3572
  * Subscribe on instance message
3448
- * @param {string} [targetInstance] instance, like 'cameras.0'
3449
- * @param {string} [messageType] message type like 'startCamera/cam3'
3450
- * @param {object} [data] optional data object
3451
- * @param {function} [callback] message handler
3452
- * @returns {Promise<null>}
3573
+ *
3574
+ * @param targetInstance instance, like 'cameras.0'
3575
+ * @param messageType message type like 'startCamera/cam3'
3576
+ * @param data optional data object
3577
+ * @param callback message handler
3453
3578
  */
3454
3579
  subscribeOnInstance(
3455
- /** instance, like 'cameras.0' */
3456
3580
  targetInstance: string,
3457
- /** message type like 'startCamera/cam3' */
3458
3581
  messageType: string,
3459
3582
  data: any,
3460
- /** message handler. Could be null if all callbacks for this messageType should be unsubscribed */
3461
3583
  callback: (_data: Record<string, any>, sourceInstance: string, _messageType: string) => void,
3462
- ) {
3584
+ ): Promise<{ error?: string; accepted?: boolean; heartbeat?: number }> {
3463
3585
  if (!this.connected) {
3464
- return Promise.reject(NOT_CONNECTED);
3586
+ return Promise.reject(new Error(NOT_CONNECTED));
3465
3587
  }
3466
3588
  return new Promise((resolve, reject) => {
3467
3589
  this._socket.emit(
@@ -3471,18 +3593,19 @@ class Connection {
3471
3593
  data,
3472
3594
  (err: string | null, result: { error?: string; accepted?: boolean; heartbeat?: number }) => {
3473
3595
  if (err) {
3474
- reject(err);
3475
- } else if (result && result.error) {
3476
- reject(result.error);
3596
+ reject(new Error(err));
3597
+ } else if (result?.error) {
3598
+ reject(new Error(result.error));
3477
3599
  } else {
3478
3600
  if (!targetInstance.startsWith('system.adapter.')) {
3479
3601
  targetInstance = `system.adapter.${targetInstance}`;
3480
3602
  }
3481
3603
  // save callback
3482
3604
  this._instanceSubscriptions[targetInstance] = this._instanceSubscriptions[targetInstance] || [];
3483
- if (!this._instanceSubscriptions[targetInstance].find(sub =>
3484
- sub.messageType === messageType &&
3485
- sub.callback === callback)
3605
+ if (
3606
+ !this._instanceSubscriptions[targetInstance].find(
3607
+ sub => sub.messageType === messageType && sub.callback === callback,
3608
+ )
3486
3609
  ) {
3487
3610
  this._instanceSubscriptions[targetInstance].push({
3488
3611
  messageType,
@@ -3498,13 +3621,14 @@ class Connection {
3498
3621
 
3499
3622
  /**
3500
3623
  * Unsubscribe from instance message
3624
+ *
3625
+ * @param targetInstance instance, like 'cameras.0'
3626
+ * @param messageType message type like 'startCamera/cam3'
3627
+ * @param callback message handler. Could be null if all callbacks for this messageType should be unsubscribed
3501
3628
  */
3502
3629
  unsubscribeFromInstance(
3503
- /** instance, like 'cameras.0' */
3504
3630
  targetInstance: string,
3505
- /** message type like 'startCamera/cam3' */
3506
3631
  messageType?: string,
3507
- /** message handler. Could be null if all callbacks for this messageType should be unsubscribed */
3508
3632
  callback?: (data: Record<string, any>, sourceInstance: string, _messageType: string) => void,
3509
3633
  ): Promise<boolean> {
3510
3634
  if (!targetInstance.startsWith('system.adapter.')) {
@@ -3514,14 +3638,14 @@ class Connection {
3514
3638
  const promiseResults: Promise<boolean>[] = [];
3515
3639
  do {
3516
3640
  deleted = false;
3517
- const index = this._instanceSubscriptions[targetInstance]?.findIndex(sub =>
3518
- (!messageType || sub.messageType === messageType) && (!callback || sub.callback === callback));
3641
+ const index = this._instanceSubscriptions[targetInstance]?.findIndex(
3642
+ sub => (!messageType || sub.messageType === messageType) && (!callback || sub.callback === callback),
3643
+ );
3519
3644
 
3520
3645
  if (index !== undefined && index !== null && index !== -1) {
3521
3646
  deleted = true;
3522
3647
  // remember messageType
3523
- const _messageType =
3524
- this._instanceSubscriptions[targetInstance][index].messageType;
3648
+ const _messageType = this._instanceSubscriptions[targetInstance][index].messageType;
3525
3649
 
3526
3650
  this._instanceSubscriptions[targetInstance].splice(index, 1);
3527
3651
  if (!this._instanceSubscriptions[targetInstance].length) {
@@ -3529,26 +3653,33 @@ class Connection {
3529
3653
  }
3530
3654
 
3531
3655
  // try to find another subscription for this instance and messageType
3532
- const found = this._instanceSubscriptions[targetInstance] &&
3656
+ const found =
3657
+ this._instanceSubscriptions[targetInstance] &&
3533
3658
  this._instanceSubscriptions[targetInstance].find(sub => sub.messageType === _messageType);
3534
3659
 
3535
3660
  if (!found) {
3536
- promiseResults.push(new Promise((resolve, reject) => {
3537
- this._socket.emit('clientUnsubscribe', targetInstance, messageType, (err: string | null, wasSubscribed: boolean) => {
3538
- if (err) {
3539
- reject(err);
3540
- } else {
3541
- resolve(wasSubscribed);
3542
- }
3543
- });
3544
- }));
3661
+ promiseResults.push(
3662
+ new Promise((resolve, reject) => {
3663
+ this._socket.emit(
3664
+ 'clientUnsubscribe',
3665
+ targetInstance,
3666
+ messageType,
3667
+ (err: string | null, wasSubscribed: boolean) => {
3668
+ if (err) {
3669
+ reject(new Error(err));
3670
+ } else {
3671
+ resolve(wasSubscribed);
3672
+ }
3673
+ },
3674
+ );
3675
+ }),
3676
+ );
3545
3677
  }
3546
3678
  }
3547
3679
  } while (deleted && (!callback || !messageType));
3548
3680
 
3549
3681
  if (promiseResults.length) {
3550
- return Promise.all(promiseResults)
3551
- .then((results: boolean[]) => results.find(result => result) || false);
3682
+ return Promise.all(promiseResults).then((results: boolean[]) => results.find(result => result) || false);
3552
3683
  }
3553
3684
 
3554
3685
  return Promise.resolve(false);
@@ -3563,25 +3694,24 @@ class Connection {
3563
3694
 
3564
3695
  /**
3565
3696
  * Logout current user
3566
- * @returns {Promise<null>}
3567
3697
  */
3568
3698
  logout(): Promise<void> {
3569
3699
  if (!this.connected) {
3570
- return Promise.reject(NOT_CONNECTED);
3700
+ return Promise.reject(new Error(NOT_CONNECTED));
3571
3701
  }
3572
3702
 
3573
3703
  return new Promise((resolve, reject) => {
3574
- this._socket.emit('logout', (err: string | null) =>
3575
- (err ? reject(err) : resolve()));
3704
+ this._socket.emit('logout', (err: string | null) => (err ? reject(new Error(err)) : resolve()));
3576
3705
  });
3577
3706
  }
3578
3707
 
3579
3708
  /**
3580
3709
  * This is a special method for vis.
3581
3710
  * It is used to not send to server the changes about "nothing_selected" state
3711
+ *
3582
3712
  * @param id The state that has to be ignored by communication
3583
3713
  */
3584
- setStateToIgnore(id?: string | null) {
3714
+ setStateToIgnore(id?: string | null): void {
3585
3715
  this.ignoreState = id || '';
3586
3716
  }
3587
3717
  }