@smarthome.exchange/integrations 2.0.0 → 4.0.0

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 (251) hide show
  1. package/changelog.md +46 -0
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/core/classes.nativeintegrationowner.d.ts +2 -0
  4. package/dist_ts/core/classes.nativeintegrationowner.js +5 -1
  5. package/dist_ts/core/classes.runtimemanager.d.ts +2 -0
  6. package/dist_ts/core/classes.runtimemanager.js +11 -3
  7. package/dist_ts/core/types.d.ts +2 -0
  8. package/dist_ts/integrations/deconz/deconz.classes.client.d.ts +37 -29
  9. package/dist_ts/integrations/deconz/deconz.classes.client.js +521 -294
  10. package/dist_ts/integrations/deconz/deconz.classes.configflow.d.ts +6 -1
  11. package/dist_ts/integrations/deconz/deconz.classes.configflow.js +63 -33
  12. package/dist_ts/integrations/deconz/deconz.classes.integration.d.ts +4 -3
  13. package/dist_ts/integrations/deconz/deconz.classes.integration.js +85 -40
  14. package/dist_ts/integrations/deconz/deconz.mapper.d.ts +1 -0
  15. package/dist_ts/integrations/deconz/deconz.mapper.js +24 -6
  16. package/dist_ts/integrations/deconz/deconz.types.d.ts +43 -6
  17. package/dist_ts/integrations/deconz/deconz.validation.d.ts +7 -1
  18. package/dist_ts/integrations/deconz/deconz.validation.js +215 -4
  19. package/dist_ts/integrations/esphome/esphome.classes.client.d.ts +19 -7
  20. package/dist_ts/integrations/esphome/esphome.classes.client.js +183 -89
  21. package/dist_ts/integrations/esphome/esphome.classes.configflow.d.ts +5 -2
  22. package/dist_ts/integrations/esphome/esphome.classes.configflow.js +43 -33
  23. package/dist_ts/integrations/esphome/esphome.classes.integration.d.ts +8 -6
  24. package/dist_ts/integrations/esphome/esphome.classes.integration.js +71 -43
  25. package/dist_ts/integrations/esphome/esphome.discovery.js +4 -12
  26. package/dist_ts/integrations/esphome/esphome.mapper.d.ts +2 -2
  27. package/dist_ts/integrations/esphome/esphome.mapper.js +6 -4
  28. package/dist_ts/integrations/esphome/esphome.types.d.ts +31 -6
  29. package/dist_ts/integrations/esphome/esphome.types.js +1 -1
  30. package/dist_ts/integrations/esphome/esphome.validation.d.ts +7 -0
  31. package/dist_ts/integrations/esphome/esphome.validation.js +66 -0
  32. package/dist_ts/integrations/homeassistant/homeassistant.classes.client.d.ts +32 -4
  33. package/dist_ts/integrations/homeassistant/homeassistant.classes.client.js +345 -116
  34. package/dist_ts/integrations/homeassistant/homeassistant.classes.integration.d.ts +8 -5
  35. package/dist_ts/integrations/homeassistant/homeassistant.classes.integration.js +34 -8
  36. package/dist_ts/integrations/homeassistant/homeassistant.classes.runtime.d.ts +7 -4
  37. package/dist_ts/integrations/homeassistant/homeassistant.classes.runtime.js +44 -56
  38. package/dist_ts/integrations/homeassistant/homeassistant.types.d.ts +12 -1
  39. package/dist_ts/integrations/hue/hue.classes.client.d.ts +32 -4
  40. package/dist_ts/integrations/hue/hue.classes.client.js +331 -57
  41. package/dist_ts/integrations/hue/hue.classes.configflow.d.ts +6 -1
  42. package/dist_ts/integrations/hue/hue.classes.configflow.js +79 -27
  43. package/dist_ts/integrations/hue/hue.classes.integration.d.ts +3 -1
  44. package/dist_ts/integrations/hue/hue.classes.integration.js +83 -62
  45. package/dist_ts/integrations/hue/hue.mapper.d.ts +2 -0
  46. package/dist_ts/integrations/hue/hue.mapper.js +8 -6
  47. package/dist_ts/integrations/hue/hue.types.d.ts +32 -1
  48. package/dist_ts/integrations/hue/hue.validation.d.ts +9 -3
  49. package/dist_ts/integrations/hue/hue.validation.js +112 -11
  50. package/dist_ts/integrations/mqtt/mqtt.classes.client.d.ts +15 -2
  51. package/dist_ts/integrations/mqtt/mqtt.classes.client.js +173 -23
  52. package/dist_ts/integrations/mqtt/mqtt.classes.configflow.d.ts +5 -1
  53. package/dist_ts/integrations/mqtt/mqtt.classes.configflow.js +53 -33
  54. package/dist_ts/integrations/mqtt/mqtt.classes.integration.d.ts +4 -1
  55. package/dist_ts/integrations/mqtt/mqtt.classes.integration.js +127 -56
  56. package/dist_ts/integrations/mqtt/mqtt.classes.session.d.ts +13 -0
  57. package/dist_ts/integrations/mqtt/mqtt.classes.session.js +130 -0
  58. package/dist_ts/integrations/mqtt/mqtt.mapper.d.ts +3 -0
  59. package/dist_ts/integrations/mqtt/mqtt.mapper.js +44 -1
  60. package/dist_ts/integrations/mqtt/mqtt.types.d.ts +46 -0
  61. package/dist_ts/integrations/mqtt/mqtt.validation.d.ts +7 -0
  62. package/dist_ts/integrations/mqtt/mqtt.validation.js +180 -0
  63. package/dist_ts/integrations/samsungtv/samsungtv.classes.client.d.ts +4 -2
  64. package/dist_ts/integrations/samsungtv/samsungtv.classes.client.js +41 -16
  65. package/dist_ts/integrations/samsungtv/samsungtv.classes.configflow.d.ts +5 -0
  66. package/dist_ts/integrations/samsungtv/samsungtv.classes.configflow.js +20 -7
  67. package/dist_ts/integrations/samsungtv/samsungtv.classes.integration.d.ts +1 -0
  68. package/dist_ts/integrations/samsungtv/samsungtv.classes.integration.js +53 -50
  69. package/dist_ts/integrations/samsungtv/samsungtv.types.d.ts +4 -1
  70. package/dist_ts/integrations/shelly/shelly.classes.client.d.ts +26 -30
  71. package/dist_ts/integrations/shelly/shelly.classes.client.js +504 -276
  72. package/dist_ts/integrations/shelly/shelly.classes.configflow.d.ts +8 -3
  73. package/dist_ts/integrations/shelly/shelly.classes.configflow.js +43 -38
  74. package/dist_ts/integrations/shelly/shelly.classes.integration.d.ts +6 -6
  75. package/dist_ts/integrations/shelly/shelly.classes.integration.js +103 -101
  76. package/dist_ts/integrations/shelly/shelly.classes.subscription.d.ts +4 -0
  77. package/dist_ts/integrations/shelly/shelly.classes.subscription.js +24 -2
  78. package/dist_ts/integrations/shelly/shelly.mapper.d.ts +1 -2
  79. package/dist_ts/integrations/shelly/shelly.mapper.js +21 -20
  80. package/dist_ts/integrations/shelly/shelly.rpc.js +4 -1
  81. package/dist_ts/integrations/shelly/shelly.types.d.ts +42 -2
  82. package/dist_ts/integrations/shelly/shelly.types.js +11 -2
  83. package/dist_ts/integrations/shelly/shelly.validation.d.ts +7 -0
  84. package/dist_ts/integrations/shelly/shelly.validation.js +79 -0
  85. package/dist_ts/integrations/sonos/sonos.classes.client.d.ts +79 -22
  86. package/dist_ts/integrations/sonos/sonos.classes.client.js +427 -139
  87. package/dist_ts/integrations/sonos/sonos.classes.configflow.d.ts +9 -2
  88. package/dist_ts/integrations/sonos/sonos.classes.configflow.js +26 -28
  89. package/dist_ts/integrations/sonos/sonos.classes.integration.d.ts +7 -6
  90. package/dist_ts/integrations/sonos/sonos.classes.integration.js +289 -224
  91. package/dist_ts/integrations/sonos/sonos.config.d.ts +6 -1
  92. package/dist_ts/integrations/sonos/sonos.config.js +23 -2
  93. package/dist_ts/integrations/sonos/sonos.mapper.d.ts +1 -1
  94. package/dist_ts/integrations/sonos/sonos.mapper.js +14 -9
  95. package/dist_ts/integrations/sonos/sonos.matchers.js +3 -3
  96. package/dist_ts/integrations/sonos/sonos.types.d.ts +26 -1
  97. package/dist_ts/integrations/tasmota/tasmota.classes.integration.d.ts +5 -0
  98. package/dist_ts/integrations/tasmota/tasmota.classes.integration.js +23 -7
  99. package/dist_ts/integrations/tasmota/tasmota.classes.runtime.d.ts +19 -5
  100. package/dist_ts/integrations/tasmota/tasmota.classes.runtime.js +115 -41
  101. package/dist_ts/integrations/tasmota/tasmota.config.js +23 -1
  102. package/dist_ts/integrations/tasmota/tasmota.credentials.d.ts +11 -0
  103. package/dist_ts/integrations/tasmota/tasmota.credentials.js +97 -0
  104. package/dist_ts/integrations/tasmota/tasmota.discovery.d.ts +7 -1
  105. package/dist_ts/integrations/tasmota/tasmota.discovery.js +108 -30
  106. package/dist_ts/integrations/tasmota/tasmota.mapper.d.ts +2 -2
  107. package/dist_ts/integrations/tasmota/tasmota.mapper.js +7 -7
  108. package/dist_ts/integrations/tasmota/tasmota.types.d.ts +41 -2
  109. package/dist_ts/integrations/tuya/tuya.classes.integration.d.ts +4 -1
  110. package/dist_ts/integrations/tuya/tuya.classes.integration.js +79 -110
  111. package/dist_ts/integrations/tuya/tuya.classes.runtime.d.ts +5 -2
  112. package/dist_ts/integrations/tuya/tuya.classes.runtime.js +73 -26
  113. package/dist_ts/integrations/tuya/tuya.mapper.js +2 -2
  114. package/dist_ts/integrations/tuya/tuya.types.d.ts +3 -0
  115. package/dist_ts/integrations/tuya/tuya.validation.d.ts +2 -2
  116. package/dist_ts/integrations/tuya/tuya.validation.js +6 -11
  117. package/dist_ts/integrations/webostv/webostv.classes.client.d.ts +6 -5
  118. package/dist_ts/integrations/webostv/webostv.classes.client.js +147 -76
  119. package/dist_ts/integrations/webostv/webostv.classes.configflow.d.ts +7 -2
  120. package/dist_ts/integrations/webostv/webostv.classes.configflow.js +36 -20
  121. package/dist_ts/integrations/webostv/webostv.classes.integration.d.ts +4 -4
  122. package/dist_ts/integrations/webostv/webostv.classes.integration.js +46 -54
  123. package/dist_ts/integrations/webostv/webostv.mapper.js +5 -5
  124. package/dist_ts/integrations/webostv/webostv.types.d.ts +16 -3
  125. package/dist_ts/integrations/webostv/webostv.types.js +1 -1
  126. package/dist_ts/integrations/webostv/webostv.validation.d.ts +3 -1
  127. package/dist_ts/integrations/webostv/webostv.validation.js +23 -1
  128. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.d.ts +6 -1
  129. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.js +18 -8
  130. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.d.ts +4 -1
  131. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.js +54 -6
  132. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.d.ts +12 -6
  133. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.js +73 -59
  134. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.d.ts +3 -2
  135. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.js +17 -12
  136. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.types.d.ts +31 -2
  137. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.d.ts +9 -1
  138. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.js +57 -7
  139. package/dist_ts/integrations/zwave_js/zwave_js.classes.client.d.ts +10 -4
  140. package/dist_ts/integrations/zwave_js/zwave_js.classes.client.js +167 -31
  141. package/dist_ts/integrations/zwave_js/zwave_js.classes.configflow.d.ts +6 -1
  142. package/dist_ts/integrations/zwave_js/zwave_js.classes.configflow.js +57 -35
  143. package/dist_ts/integrations/zwave_js/zwave_js.classes.integration.d.ts +3 -1
  144. package/dist_ts/integrations/zwave_js/zwave_js.classes.integration.js +59 -37
  145. package/dist_ts/integrations/zwave_js/zwave_js.discovery.js +3 -3
  146. package/dist_ts/integrations/zwave_js/zwave_js.mapper.js +41 -24
  147. package/dist_ts/integrations/zwave_js/zwave_js.types.d.ts +25 -3
  148. package/dist_ts/integrations/zwave_js/zwave_js.validation.d.ts +6 -2
  149. package/dist_ts/integrations/zwave_js/zwave_js.validation.js +52 -17
  150. package/dist_ts/plugins.d.ts +2 -1
  151. package/dist_ts/plugins.js +3 -2
  152. package/package.json +10 -10
  153. package/readme.md +25 -6
  154. package/ts/00_commitinfo_data.ts +1 -1
  155. package/ts/core/classes.nativeintegrationowner.ts +5 -0
  156. package/ts/core/classes.runtimemanager.ts +11 -2
  157. package/ts/core/types.ts +2 -0
  158. package/ts/integrations/deconz/deconz.classes.client.ts +348 -252
  159. package/ts/integrations/deconz/deconz.classes.configflow.ts +57 -29
  160. package/ts/integrations/deconz/deconz.classes.integration.ts +69 -37
  161. package/ts/integrations/deconz/deconz.mapper.ts +22 -5
  162. package/ts/integrations/deconz/deconz.types.ts +49 -6
  163. package/ts/integrations/deconz/deconz.validation.ts +177 -4
  164. package/ts/integrations/deconz/readme.md +15 -1
  165. package/ts/integrations/esphome/esphome.classes.client.ts +179 -94
  166. package/ts/integrations/esphome/esphome.classes.configflow.ts +40 -33
  167. package/ts/integrations/esphome/esphome.classes.integration.ts +63 -36
  168. package/ts/integrations/esphome/esphome.discovery.ts +3 -12
  169. package/ts/integrations/esphome/esphome.mapper.ts +9 -7
  170. package/ts/integrations/esphome/esphome.types.ts +35 -6
  171. package/ts/integrations/esphome/esphome.validation.ts +66 -0
  172. package/ts/integrations/esphome/readme.md +20 -6
  173. package/ts/integrations/homeassistant/homeassistant.classes.client.ts +353 -125
  174. package/ts/integrations/homeassistant/homeassistant.classes.integration.ts +35 -18
  175. package/ts/integrations/homeassistant/homeassistant.classes.runtime.ts +50 -63
  176. package/ts/integrations/homeassistant/homeassistant.types.ts +17 -1
  177. package/ts/integrations/homeassistant/readme.md +22 -6
  178. package/ts/integrations/hue/hue.classes.client.ts +288 -55
  179. package/ts/integrations/hue/hue.classes.configflow.ts +68 -25
  180. package/ts/integrations/hue/hue.classes.integration.ts +75 -54
  181. package/ts/integrations/hue/hue.mapper.ts +8 -5
  182. package/ts/integrations/hue/hue.types.ts +37 -1
  183. package/ts/integrations/hue/hue.validation.ts +102 -13
  184. package/ts/integrations/hue/readme.md +49 -12
  185. package/ts/integrations/mqtt/mqtt.classes.client.ts +136 -19
  186. package/ts/integrations/mqtt/mqtt.classes.configflow.ts +45 -32
  187. package/ts/integrations/mqtt/mqtt.classes.integration.ts +99 -38
  188. package/ts/integrations/mqtt/mqtt.classes.session.ts +118 -0
  189. package/ts/integrations/mqtt/mqtt.mapper.ts +43 -1
  190. package/ts/integrations/mqtt/mqtt.types.ts +52 -0
  191. package/ts/integrations/mqtt/mqtt.validation.ts +157 -0
  192. package/ts/integrations/mqtt/readme.md +12 -3
  193. package/ts/integrations/samsungtv/readme.md +11 -5
  194. package/ts/integrations/samsungtv/samsungtv.classes.client.ts +40 -15
  195. package/ts/integrations/samsungtv/samsungtv.classes.configflow.ts +21 -6
  196. package/ts/integrations/samsungtv/samsungtv.classes.integration.ts +53 -38
  197. package/ts/integrations/samsungtv/samsungtv.types.ts +4 -1
  198. package/ts/integrations/shelly/readme.md +22 -7
  199. package/ts/integrations/shelly/shelly.classes.client.ts +386 -269
  200. package/ts/integrations/shelly/shelly.classes.configflow.ts +43 -38
  201. package/ts/integrations/shelly/shelly.classes.integration.ts +92 -111
  202. package/ts/integrations/shelly/shelly.classes.subscription.ts +24 -1
  203. package/ts/integrations/shelly/shelly.mapper.ts +19 -20
  204. package/ts/integrations/shelly/shelly.rpc.ts +2 -0
  205. package/ts/integrations/shelly/shelly.types.ts +50 -2
  206. package/ts/integrations/shelly/shelly.validation.ts +76 -0
  207. package/ts/integrations/sonos/readme.md +117 -38
  208. package/ts/integrations/sonos/sonos.classes.client.ts +392 -123
  209. package/ts/integrations/sonos/sonos.classes.configflow.ts +25 -28
  210. package/ts/integrations/sonos/sonos.classes.integration.ts +211 -186
  211. package/ts/integrations/sonos/sonos.config.ts +24 -2
  212. package/ts/integrations/sonos/sonos.mapper.ts +13 -8
  213. package/ts/integrations/sonos/sonos.matchers.ts +2 -2
  214. package/ts/integrations/sonos/sonos.types.ts +30 -1
  215. package/ts/integrations/tasmota/readme.md +16 -5
  216. package/ts/integrations/tasmota/tasmota.classes.integration.ts +24 -6
  217. package/ts/integrations/tasmota/tasmota.classes.runtime.ts +112 -43
  218. package/ts/integrations/tasmota/tasmota.config.ts +17 -0
  219. package/ts/integrations/tasmota/tasmota.credentials.ts +92 -0
  220. package/ts/integrations/tasmota/tasmota.discovery.ts +87 -24
  221. package/ts/integrations/tasmota/tasmota.mapper.ts +6 -6
  222. package/ts/integrations/tasmota/tasmota.types.ts +43 -2
  223. package/ts/integrations/tuya/readme.md +52 -10
  224. package/ts/integrations/tuya/tuya.classes.integration.ts +69 -98
  225. package/ts/integrations/tuya/tuya.classes.runtime.ts +70 -24
  226. package/ts/integrations/tuya/tuya.mapper.ts +1 -1
  227. package/ts/integrations/tuya/tuya.types.ts +4 -0
  228. package/ts/integrations/tuya/tuya.validation.ts +5 -8
  229. package/ts/integrations/webostv/readme.md +115 -22
  230. package/ts/integrations/webostv/webostv.classes.client.ts +123 -50
  231. package/ts/integrations/webostv/webostv.classes.configflow.ts +35 -15
  232. package/ts/integrations/webostv/webostv.classes.integration.ts +44 -37
  233. package/ts/integrations/webostv/webostv.mapper.ts +4 -4
  234. package/ts/integrations/webostv/webostv.types.ts +18 -3
  235. package/ts/integrations/webostv/webostv.validation.ts +22 -1
  236. package/ts/integrations/zigbee2mqtt/readme.md +22 -27
  237. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.ts +16 -7
  238. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.ts +53 -6
  239. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.ts +62 -49
  240. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.ts +17 -11
  241. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.types.ts +35 -2
  242. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.ts +53 -7
  243. package/ts/integrations/zwave_js/readme.md +42 -9
  244. package/ts/integrations/zwave_js/zwave_js.classes.client.ts +155 -31
  245. package/ts/integrations/zwave_js/zwave_js.classes.configflow.ts +55 -31
  246. package/ts/integrations/zwave_js/zwave_js.classes.integration.ts +57 -35
  247. package/ts/integrations/zwave_js/zwave_js.discovery.ts +2 -2
  248. package/ts/integrations/zwave_js/zwave_js.mapper.ts +37 -23
  249. package/ts/integrations/zwave_js/zwave_js.types.ts +26 -3
  250. package/ts/integrations/zwave_js/zwave_js.validation.ts +52 -18
  251. package/ts/plugins.ts +2 -1
@@ -1,342 +1,570 @@
1
1
  import * as plugins from '../../plugins.js';
2
+ import { NativeHomeAdmission } from '../../core/classes.nativehomeadmission.js';
2
3
  import { AuthenticationError, DeviceCommunicationError } from '../../core/errors.js';
3
4
  import { ShellySubscription } from './shelly.classes.subscription.js';
4
- import { createShellyDigest, isShellyRecord, mergeShellyStatus, parseShellyConfig, parseShellyDeviceInfo, parseShellyHttpChallenge, parseShellyRpcResult, parseShellyStatus, } from './shelly.rpc.js';
5
+ import { createShellyDigest, isShellyRecord, mergeShellyStatus, parseShellyConfig, parseShellyDeviceInfo, parseShellyHttpChallenge, parseShellyRpcResult, parseShellyStatus } from './shelly.rpc.js';
6
+ import { normalizeShellyConfig, normalizeShellyOptions } from './shelly.validation.js';
7
+ import { ShellyOperationError } from './shelly.types.js';
5
8
  export class ShellyClient {
6
- logger;
7
- requestId = 1;
8
- nonceCount = 0;
9
- digestChallenge;
10
- deviceId;
11
- snapshot;
12
- subscription;
13
- subscribers = new Set();
14
- lifetime = new AbortController();
15
- lifetimeSignal;
16
- // Firmware tracks increasing digest nonce counts, so HTTP calls must arrive in order.
17
- requestQueue = Promise.resolve();
18
- timeoutMs;
19
- endpoint;
20
- config;
21
- healthy = false;
22
- destroyed = false;
23
- constructor(configArg, abortSignalArg, logger) {
24
- this.logger = logger;
25
- const config = {
26
- host: configArg.host,
27
- port: configArg.port,
28
- protocol: configArg.protocol,
29
- username: configArg.username,
30
- password: configArg.password,
31
- requestTimeoutMs: configArg.requestTimeoutMs,
32
- };
33
- this.config = config;
34
- this.timeoutMs = config.requestTimeoutMs ?? 10000;
35
- if (!Number.isSafeInteger(this.timeoutMs) || this.timeoutMs < 10 || this.timeoutMs > 60000) {
36
- throw new Error('Shelly requestTimeoutMs must be an integer between 10 and 60000.');
37
- }
38
- if (config.username !== undefined && config.username !== 'admin')
39
- throw new AuthenticationError('Shelly authentication username must be admin.');
40
- if (config.password !== undefined && typeof config.password !== 'string')
41
- throw new AuthenticationError('Shelly password must be a string.');
42
- if (config.protocol !== undefined && config.protocol !== 'http' && config.protocol !== 'https')
43
- throw new Error('Shelly protocol must be http or https.');
44
- if (config.port !== undefined && (!Number.isSafeInteger(config.port) || config.port < 1 || config.port > 65535))
45
- throw new Error('Shelly port must be between 1 and 65535.');
46
- if (config.host === undefined)
47
- throw new Error('Shelly host is required for live requests.');
48
- if (typeof config.host !== 'string' || !config.host || /[\s\/?#@]/.test(config.host))
49
- throw new Error('Shelly host must be a hostname or IP address.');
50
- const host = config.host.includes(':') && !config.host.startsWith('[') ? `[${config.host}]` : config.host;
51
- try {
52
- this.endpoint = new URL(`${config.protocol ?? 'http'}://${host}${config.port === undefined ? '' : `:${config.port}`}`);
53
- }
54
- catch {
55
- throw new Error('Shelly host must be a hostname or IP address.');
56
- }
57
- this.lifetimeSignal = AbortSignal.any([this.lifetime.signal, ...(abortSignalArg ? [abortSignalArg] : [])]);
9
+ #config;
10
+ #context;
11
+ #endpoint;
12
+ #lifetime = new AbortController();
13
+ #tasks = new Set();
14
+ #credentials = new Set();
15
+ #credentialOperations = new Map();
16
+ #credentialFailures = new Set();
17
+ #requests = new Set();
18
+ #sockets = new Set();
19
+ #drains = new Set();
20
+ #subscribers = new Set();
21
+ #subscriptions = new Set();
22
+ #parentAbort;
23
+ #resolvePassword;
24
+ #tail = Promise.resolve();
25
+ #requestId = 1;
26
+ #nonceCount = 0;
27
+ #challenge;
28
+ #snapshot;
29
+ #subscription;
30
+ #healthy = false;
31
+ #closed = false;
32
+ #closePromise;
33
+ #cleanupPromise;
34
+ #retryPromise;
35
+ #cleanupFailed = false;
36
+ constructor(configArg, contextArg, optionsArg = {}) {
37
+ this.#config = normalizeShellyConfig(configArg);
38
+ const options = normalizeShellyOptions(optionsArg);
39
+ this.#context = new NativeHomeAdmission('shelly', { homeId: options.homeId }).admit(contextArg, this.#config.homeId);
40
+ this.#resolvePassword = options.resolvePassword;
41
+ if (this.#config.credentialRef !== undefined && !this.#resolvePassword)
42
+ throw new TypeError('Shelly credential reference requires a caller-owned password resolver.');
43
+ const host = this.#config.host.includes(':') && !this.#config.host.startsWith('[') ? `[${this.#config.host}]` : this.#config.host;
44
+ this.#endpoint = new URL(`${this.#config.protocol}://${host}:${this.#config.port}`);
45
+ this.#parentAbort = () => { void this.destroy().catch(() => undefined); };
46
+ this.#context.abortSignal?.addEventListener('abort', this.#parentAbort, { once: true });
47
+ if (this.#context.abortSignal?.aborted)
48
+ this.#parentAbort();
58
49
  }
59
50
  isHealthy() {
60
- return !this.destroyed && !this.lifetimeSignal.aborted && this.healthy && (!this.subscription || this.subscription.isHealthy);
51
+ return !this.#closed && this.#healthy && (!this.#subscription || this.#subscription.isHealthy);
61
52
  }
62
- async getSnapshot(abortSignalArg) {
63
- this.assertActive(abortSignalArg);
64
- if (this.snapshot && this.subscription?.isHealthy)
65
- return structuredClone(this.snapshot);
66
- const deviceInfo = await this.getDeviceInfo(abortSignalArg);
67
- const status = await this.getStatus(abortSignalArg);
68
- const deviceConfig = await this.getDeviceConfig(abortSignalArg);
69
- this.snapshot = { deviceInfo, status, deviceConfig };
70
- return structuredClone(this.snapshot);
53
+ /** Validated push observations may satisfy reads; controls always call read() afresh. */
54
+ getSnapshot(signalArg) {
55
+ try {
56
+ this.assertOpen();
57
+ if (signalArg !== undefined && !(signalArg instanceof AbortSignal))
58
+ throw new TypeError('Shelly cancellation requires an AbortSignal.');
59
+ if (signalArg?.aborted)
60
+ throw new DOMException('Shelly operation cancelled.', 'AbortError');
61
+ if (this.#snapshot && this.#healthy && this.#subscription?.isHealthy)
62
+ return Promise.resolve(structuredClone(this.#snapshot));
63
+ }
64
+ catch (errorArg) {
65
+ return Promise.reject(errorArg);
66
+ }
67
+ return this.run((operationArg) => this.read(operationArg), signalArg);
71
68
  }
72
- async getDeviceInfo(abortSignalArg) {
73
- this.assertActive(abortSignalArg);
74
- const response = await this.requestJson('/shelly', undefined, abortSignalArg);
75
- const deviceInfo = this.parseResponse(() => {
76
- const info = parseShellyDeviceInfo(response);
77
- if (this.deviceId !== undefined && this.deviceId !== info.id)
78
- throw new DeviceCommunicationError('Shelly endpoint device identity changed.');
79
- return info;
80
- });
81
- this.deviceId = deviceInfo.id;
82
- return deviceInfo;
69
+ getDeviceInfo(signalArg) {
70
+ return this.run(async (operationArg) => { await this.bootstrap(operationArg); return this.identity(await this.rpc(operationArg, 'Shelly.GetDeviceInfo')); }, signalArg);
83
71
  }
84
- async getStatus(abortSignalArg) {
85
- this.assertActive(abortSignalArg);
86
- const response = await this.callRpc('Shelly.GetStatus', undefined, abortSignalArg);
87
- const status = this.parseResponse(() => parseShellyStatus(response));
88
- this.healthy = true;
89
- if (this.snapshot)
90
- this.updateStatus(status, true, Date.now());
91
- return status;
72
+ getStatus(signalArg) {
73
+ return this.run(async (operationArg) => (await this.read(operationArg)).status, signalArg);
92
74
  }
93
- async getDeviceConfig(abortSignalArg) {
94
- this.assertActive(abortSignalArg);
95
- const response = await this.callRpc('Shelly.GetConfig', undefined, abortSignalArg);
96
- return this.parseResponse(() => parseShellyConfig(response));
75
+ getDeviceConfig(signalArg) {
76
+ return this.run(async (operationArg) => (await this.read(operationArg)).deviceConfig ?? {}, signalArg);
97
77
  }
98
- async setSwitchOutput(switchIdArg, onArg, abortSignalArg) {
99
- if (!Number.isSafeInteger(switchIdArg) || switchIdArg < 0 || typeof onArg !== 'boolean')
100
- throw new Error('Shelly switch writes require a non-negative integer id and boolean output.');
101
- const snapshot = await this.getSnapshot(abortSignalArg);
102
- if (!isShellyRecord(snapshot.status[`switch:${switchIdArg}`]))
103
- throw new Error('Shelly switch is not present on the connected device.');
104
- const result = await this.callRpc('Switch.Set', { id: switchIdArg, on: onArg }, abortSignalArg);
105
- this.parseResponse(() => {
78
+ setSwitchOutput(idArg, onArg, signalArg) {
79
+ if (!Number.isSafeInteger(idArg) || idArg < 0 || typeof onArg !== 'boolean')
80
+ return Promise.reject(new ShellyOperationError('Shelly switch writes require a non-negative integer id and boolean output.'));
81
+ if (!this.#config.allowControl)
82
+ return Promise.reject(new ShellyOperationError('Shelly output controls are disabled.'));
83
+ return this.run(async (operationArg) => {
84
+ const before = await this.read(operationArg);
85
+ if (!before.methods.includes('Switch.Set') || !before.methods.includes('Switch.GetStatus'))
86
+ throw new ShellyOperationError('Shelly does not currently allow the required switch methods.');
87
+ if (!isShellyRecord(before.status[`switch:${idArg}`]))
88
+ throw new ShellyOperationError('Shelly switch is not present on the connected device.');
89
+ parseShellyStatus({ [`switch:${idArg}`]: await this.rpc(operationArg, 'Switch.GetStatus', { id: idArg }) });
90
+ const result = await this.rpc(operationArg, 'Switch.Set', { id: idArg, on: onArg }, true);
106
91
  if (typeof result.was_on !== 'boolean')
107
92
  throw new DeviceCommunicationError('Shelly returned an invalid switch response.');
108
- });
109
- await this.getStatus(abortSignalArg);
93
+ operationArg.acknowledged = true;
94
+ this.identity(await this.rpc(operationArg, 'Shelly.GetDeviceInfo'));
95
+ const status = parseShellyStatus({ [`switch:${idArg}`]: await this.rpc(operationArg, 'Switch.GetStatus', { id: idArg }) });
96
+ const component = status[`switch:${idArg}`];
97
+ if (!isShellyRecord(component))
98
+ throw new DeviceCommunicationError('Shelly returned an invalid switch readback.');
99
+ const snapshot = { ...before, status: { ...before.status, ...status } };
100
+ this.observe(snapshot);
101
+ return { componentId: idArg, requested: onArg, wasOn: result.was_on, commandAcknowledged: true,
102
+ causalityConfirmed: false, outcome: component.output === onArg ? 'observed-target' : 'indeterminate',
103
+ snapshot: structuredClone(snapshot) };
104
+ }, signalArg);
110
105
  }
111
- async subscribe(handlerArg, abortSignalArg) {
112
- this.assertActive(abortSignalArg);
113
- if (!this.snapshot)
114
- await this.getSnapshot(abortSignalArg);
115
- let rejectCancelled;
116
- const cancellation = new Promise((_, rejectArg) => { rejectCancelled = rejectArg; });
117
- const subscriber = {
118
- handler: handlerArg,
119
- signal: abortSignalArg,
120
- abort: () => {
121
- rejectCancelled?.(new DOMException('Shelly subscription cancelled.', 'AbortError'));
122
- void unsubscribe().catch(() => {
123
- this.logger?.log('error', 'Shelly subscription cleanup failed.');
124
- this.emit({ type: 'error', error: new DeviceCommunicationError('Shelly subscription cleanup failed.'), timestamp: Date.now() });
125
- });
126
- },
127
- };
128
- let removed = false;
129
- const unsubscribe = async () => {
130
- if (!removed) {
131
- removed = true;
132
- subscriber.signal?.removeEventListener('abort', subscriber.abort);
133
- this.subscribers.delete(subscriber);
134
- }
135
- if (this.subscribers.size === 0 && this.subscription) {
136
- const subscription = this.subscription;
137
- await subscription.stop();
138
- if (this.subscription === subscription)
139
- this.subscription = undefined;
140
- }
141
- };
142
- this.subscribers.add(subscriber);
143
- abortSignalArg?.addEventListener('abort', subscriber.abort, { once: true });
144
- if (abortSignalArg?.aborted)
145
- subscriber.abort();
106
+ subscribe(handlerArg, signalArg) {
146
107
  try {
147
- await Promise.race([this.connectSubscription(), cancellation]);
148
- this.assertActive(abortSignalArg);
149
- rejectCancelled = undefined;
150
- return unsubscribe;
108
+ this.assertOpen();
109
+ if (typeof handlerArg !== 'function' || signalArg !== undefined && !(signalArg instanceof AbortSignal))
110
+ throw new TypeError('Shelly subscription requires a callback and optional AbortSignal.');
111
+ if (signalArg?.aborted)
112
+ throw new DOMException('Shelly subscription cancelled.', 'AbortError');
113
+ if (this.#subscribers.size >= 32)
114
+ throw new Error('Shelly subscriber capacity reached.');
151
115
  }
152
116
  catch (errorArg) {
153
- await unsubscribe();
117
+ return Promise.reject(errorArg);
118
+ }
119
+ const aborted = () => { void subscriber.stop().catch(() => undefined); };
120
+ const subscriber = { handler: handlerArg, active: true, failed: false,
121
+ detach: () => { subscriber.active = false; signalArg?.removeEventListener('abort', aborted); },
122
+ stop: async () => {
123
+ subscriber.detach();
124
+ if (!subscriber.failed)
125
+ this.#subscribers.delete(subscriber);
126
+ if (![...this.#subscribers].some((entryArg) => entryArg.active) && this.#subscription) {
127
+ const subscription = this.#subscription;
128
+ await subscription.stop();
129
+ if (this.#subscription === subscription)
130
+ this.#subscription = undefined;
131
+ this.#subscriptions.delete(subscription);
132
+ }
133
+ if (subscriber.failed)
134
+ throw new Error('Shelly subscriber callback failed.');
135
+ } };
136
+ this.#subscribers.add(subscriber);
137
+ signalArg?.addEventListener('abort', aborted, { once: true });
138
+ if (signalArg?.aborted)
139
+ aborted();
140
+ return this.run(async (operationArg) => {
141
+ if (!this.#snapshot)
142
+ await this.read(operationArg);
143
+ else
144
+ await this.resolveCredential(operationArg);
145
+ this.active(operationArg);
146
+ await this.connectSubscription(operationArg);
147
+ this.active(operationArg);
148
+ return subscriber.stop;
149
+ }, signalArg).catch(async (errorArg) => {
150
+ try {
151
+ await subscriber.stop();
152
+ }
153
+ catch (cleanupArg) {
154
+ throw new AggregateError([errorArg, cleanupArg], 'Shelly subscription and cleanup failed.');
155
+ }
154
156
  throw errorArg;
157
+ });
158
+ }
159
+ /** Memo precedes abort and all foreign callbacks. */
160
+ destroy() {
161
+ if (!this.#closePromise) {
162
+ this.#closed = true;
163
+ this.#healthy = false;
164
+ this.#closePromise = Promise.resolve().then(() => this.drainCleanup(false));
165
+ this.#cleanupPromise = this.#closePromise;
166
+ this.#context.abortSignal?.removeEventListener('abort', this.#parentAbort);
167
+ for (const subscriber of this.#subscribers)
168
+ subscriber.detach();
169
+ this.#lifetime.abort(new DOMException('Shelly operation cancelled.', 'AbortError'));
170
+ for (const request of this.#requests)
171
+ request.destroy();
172
+ for (const socket of this.#sockets)
173
+ socket.destroy();
155
174
  }
175
+ return this.#closePromise;
156
176
  }
157
- async destroy() {
158
- this.destroyed = true;
159
- this.healthy = false;
160
- for (const subscriber of this.subscribers)
161
- subscriber.signal?.removeEventListener('abort', subscriber.abort);
162
- this.subscribers.clear();
163
- this.lifetime.abort();
164
- await this.requestQueue;
165
- if (this.subscription) {
166
- await this.subscription.stop();
167
- this.subscription = undefined;
177
+ /** Terminal cleanup retry never resolves credentials or replays transport. */
178
+ retryCleanup() {
179
+ if (!this.#closePromise)
180
+ return this.destroy();
181
+ if (!this.#cleanupFailed)
182
+ return this.#cleanupPromise ?? this.#closePromise;
183
+ if (!this.#retryPromise) {
184
+ this.#retryPromise = Promise.resolve().then(() => this.drainCleanup(true));
185
+ this.#cleanupPromise = this.#retryPromise;
186
+ const settled = () => { this.#retryPromise = undefined; };
187
+ void this.#retryPromise.then(settled, settled);
168
188
  }
189
+ return this.#retryPromise;
169
190
  }
170
- async connectSubscription() {
171
- if (this.subscription?.isStopping) {
172
- const previous = this.subscription;
173
- await previous.stop();
174
- if (this.subscription === previous)
175
- this.subscription = undefined;
191
+ async drainCleanup(retryArg) {
192
+ const cleanup = [...this.#subscriptions].map((entryArg) => Promise.resolve().then(() => retryArg ? entryArg.retryCleanup() : entryArg.stop()));
193
+ const results = await Promise.allSettled(cleanup);
194
+ while (this.#tasks.size || this.#credentials.size || this.#drains.size)
195
+ await Promise.allSettled([...this.#tasks, ...this.#credentials, ...this.#drains]);
196
+ const late = await Promise.allSettled([...this.#subscriptions].map((entryArg) => retryArg ? entryArg.retryCleanup() : entryArg.stop()));
197
+ const failures = [...results, ...late].filter((entryArg) => entryArg.status === 'rejected').map((entryArg) => entryArg.reason);
198
+ if (!retryArg) {
199
+ failures.push(...this.#credentialFailures);
200
+ for (const subscriber of this.#subscribers)
201
+ if (subscriber.failed)
202
+ failures.push(new Error('Shelly subscriber callback failed.'));
176
203
  }
177
- this.assertActive();
178
- if (!this.subscription || this.subscription.isClosed) {
179
- if (!this.deviceId)
180
- throw new Error('Shelly subscription requires a validated device.');
181
- const url = new URL('/rpc', this.endpoint);
182
- url.protocol = this.endpoint.protocol === 'https:' ? 'wss:' : 'ws:';
183
- this.subscription = new ShellySubscription({
184
- url: url.toString(),
185
- deviceId: this.deviceId,
186
- source: `shx-${plugins.crypto.randomUUID()}`,
187
- password: this.config.password,
188
- timeoutMs: this.timeoutMs,
189
- abortSignal: this.lifetimeSignal,
204
+ else
205
+ this.#credentialFailures.clear();
206
+ for (const subscription of this.#subscriptions)
207
+ if (subscription.isClosed)
208
+ this.#subscriptions.delete(subscription);
209
+ if (retryArg || !failures.length)
210
+ this.#subscribers.clear();
211
+ this.#resolvePassword = undefined;
212
+ this.#snapshot = undefined;
213
+ this.#cleanupFailed = failures.length > 0;
214
+ if (failures.length)
215
+ throw new AggregateError([...new Set(failures)], 'Shelly owned cleanup failed.');
216
+ }
217
+ async read(operationArg) {
218
+ await this.bootstrap(operationArg);
219
+ const deviceInfo = this.identity(await this.rpc(operationArg, 'Shelly.GetDeviceInfo'));
220
+ const allowed = await this.rpc(operationArg, 'Shelly.ListMethods');
221
+ if (!Array.isArray(allowed.methods) || allowed.methods.length > 512 ||
222
+ !allowed.methods.every((methodArg) => typeof methodArg === 'string' && /^[A-Za-z][A-Za-z0-9]*\.[A-Za-z][A-Za-z0-9]*$/.test(methodArg)))
223
+ throw new DeviceCommunicationError('Shelly returned invalid allowed methods.');
224
+ const methods = [...new Set(allowed.methods)];
225
+ if (!methods.includes('Shelly.GetStatus') || !methods.includes('Shelly.GetConfig') || !methods.includes('Shelly.GetDeviceInfo'))
226
+ throw new DeviceCommunicationError('Shelly does not currently allow the required observation methods.');
227
+ const status = parseShellyStatus(await this.rpc(operationArg, 'Shelly.GetStatus'));
228
+ if (status.sys?.mac !== undefined && status.sys.mac.toUpperCase() !== this.#config.expectedMacAddress)
229
+ throw new DeviceCommunicationError('Shelly endpoint device identity changed.');
230
+ const deviceConfig = parseShellyConfig(await this.rpc(operationArg, 'Shelly.GetConfig'));
231
+ const snapshot = { homeId: this.#context.homeId, deviceInfo, status, deviceConfig, methods, controlEnabled: this.#config.allowControl };
232
+ this.observe(snapshot);
233
+ return structuredClone(snapshot);
234
+ }
235
+ async bootstrap(operationArg) {
236
+ this.identity(await this.requestJson(operationArg, '/shelly'));
237
+ await this.resolveCredential(operationArg);
238
+ }
239
+ identity(valueArg) {
240
+ const info = parseShellyDeviceInfo(valueArg);
241
+ if (info.id !== this.#config.expectedDeviceId || info.mac?.toUpperCase() !== this.#config.expectedMacAddress || info.model !== this.#config.expectedModel || info.gen !== this.#config.expectedGeneration)
242
+ throw new DeviceCommunicationError('Shelly endpoint device identity changed.');
243
+ return info;
244
+ }
245
+ observe(snapshotArg) {
246
+ this.assertOpen();
247
+ this.#snapshot = structuredClone(snapshotArg);
248
+ this.#healthy = true;
249
+ this.emit({ type: 'status', snapshot: structuredClone(snapshotArg), timestamp: Date.now() });
250
+ }
251
+ async connectSubscription(operationArg) {
252
+ if (this.#subscription?.isStopping) {
253
+ await this.#subscription.stop();
254
+ this.#subscriptions.delete(this.#subscription);
255
+ this.#subscription = undefined;
256
+ }
257
+ this.active(operationArg);
258
+ if (!this.#subscription || this.#subscription.isClosed) {
259
+ const url = new URL('/rpc', this.#endpoint);
260
+ url.protocol = this.#config.protocol === 'https' ? 'wss:' : 'ws:';
261
+ const subscription = new ShellySubscription({ url: url.toString(), deviceId: this.#config.expectedDeviceId,
262
+ source: `shx-${plugins.crypto.randomUUID()}`, password: operationArg.password,
263
+ timeoutMs: this.#config.requestTimeoutMs, abortSignal: this.#lifetime.signal,
190
264
  onStatus: (statusArg, fullArg, timestampArg) => this.updateStatus(statusArg, fullArg, timestampArg),
191
265
  onEvent: (eventArg, timestampArg) => {
192
266
  this.emit({ type: 'event', event: eventArg, timestamp: timestampArg });
193
267
  if (eventArg.event === 'config_changed')
194
- void this.refreshConfig(timestampArg);
268
+ void this.run((operationArg) => this.read(operationArg)).catch(() => {
269
+ if (!this.#closed)
270
+ this.emit({ type: 'error', error: new DeviceCommunicationError('Shelly configuration refresh failed.'), timestamp: Date.now() });
271
+ });
195
272
  },
196
273
  onAvailability: (availableArg) => this.emit({ type: 'availability', available: availableArg, timestamp: Date.now() }),
197
- onError: (errorArg) => this.emit({ type: 'error', error: errorArg, timestamp: Date.now() }),
198
- });
274
+ onError: (errorArg) => this.emit({ type: 'error', error: errorArg, timestamp: Date.now() }) });
275
+ this.#subscriptions.add(subscription);
276
+ this.#subscription = subscription;
277
+ }
278
+ const subscription = this.#subscription;
279
+ let cancelled = () => { };
280
+ const cancellation = new Promise((_resolveArg, rejectArg) => {
281
+ cancelled = () => { try {
282
+ this.active(operationArg);
283
+ }
284
+ catch (errorArg) {
285
+ rejectArg(errorArg);
286
+ } };
287
+ operationArg.signal.addEventListener('abort', cancelled, { once: true });
288
+ });
289
+ try {
290
+ await Promise.race([subscription.start(), cancellation]);
291
+ }
292
+ finally {
293
+ operationArg.signal.removeEventListener('abort', cancelled);
199
294
  }
200
- await this.subscription.start();
201
295
  }
202
296
  updateStatus(statusArg, fullArg, timestampArg) {
203
- if (!this.snapshot || this.destroyed)
297
+ if (!this.#snapshot || this.#closed)
204
298
  return;
205
- this.snapshot = { ...this.snapshot, status: fullArg ? statusArg : mergeShellyStatus(this.snapshot.status, statusArg) };
206
- this.emit({ type: 'status', snapshot: structuredClone(this.snapshot), timestamp: timestampArg });
299
+ const status = fullArg ? statusArg : mergeShellyStatus(this.#snapshot.status, statusArg);
300
+ if (status.sys?.mac !== undefined && status.sys.mac.toUpperCase() !== this.#config.expectedMacAddress)
301
+ throw new DeviceCommunicationError('Shelly notification identity changed.');
302
+ this.#snapshot = { ...this.#snapshot, status };
303
+ this.emit({ type: 'status', snapshot: structuredClone(this.#snapshot), timestamp: timestampArg });
207
304
  }
208
305
  emit(eventArg) {
209
- for (const subscriber of [...this.subscribers]) {
210
- if (!this.subscribers.has(subscriber))
306
+ if (this.#closed)
307
+ return;
308
+ for (const subscriber of [...this.#subscribers]) {
309
+ if (this.#closed)
310
+ break;
311
+ if (!subscriber.active)
211
312
  continue;
212
313
  try {
213
314
  subscriber.handler(structuredClone(eventArg));
214
315
  }
215
316
  catch {
216
- this.logger?.log('error', 'Shelly subscriber callback failed.');
217
- subscriber.abort();
317
+ subscriber.failed = true;
318
+ subscriber.detach();
319
+ try {
320
+ this.#context.logger?.log('error', 'Shelly subscriber callback failed.');
321
+ }
322
+ catch { /* Failure remains retained. */ }
218
323
  this.emit({ type: 'error', error: new DeviceCommunicationError('Shelly subscriber callback failed.'), timestamp: Date.now() });
219
324
  }
220
325
  }
221
326
  }
222
- async refreshConfig(timestampArg) {
223
- try {
224
- const deviceConfig = await this.getDeviceConfig();
225
- if (this.snapshot && !this.destroyed) {
226
- this.snapshot = { ...this.snapshot, deviceConfig };
227
- this.emit({ type: 'status', snapshot: structuredClone(this.snapshot), timestamp: timestampArg });
327
+ async resolveCredential(operationArg) {
328
+ if (this.#config.credentialRef === undefined)
329
+ return;
330
+ this.active(operationArg);
331
+ const resolver = this.#resolvePassword;
332
+ if (!resolver)
333
+ throw new AuthenticationError('Shelly credential resolver is unavailable.');
334
+ const credential = Promise.resolve().then(() => {
335
+ this.active(operationArg);
336
+ return resolver(Object.freeze({ homeId: this.#context.homeId, credentialRef: this.#config.credentialRef, signal: operationArg.signal, deadline: operationArg.deadline }));
337
+ });
338
+ this.#credentials.add(credential);
339
+ this.#credentialOperations.set(credential, operationArg.task);
340
+ void credential.then(() => { this.#credentials.delete(credential); this.#credentialOperations.delete(credential); }, (errorArg) => {
341
+ this.#credentials.delete(credential);
342
+ this.#credentialOperations.delete(credential);
343
+ if (operationArg.signal.aborted && errorArg !== operationArg.signal.reason)
344
+ this.#credentialFailures.add(new Error('Shelly caller credential resolution failed.'));
345
+ });
346
+ let cancel = () => { };
347
+ const cancelled = new Promise((_resolveArg, rejectArg) => {
348
+ cancel = () => { try {
349
+ this.active(operationArg);
228
350
  }
351
+ catch (errorArg) {
352
+ rejectArg(errorArg);
353
+ } };
354
+ operationArg.signal.addEventListener('abort', cancel, { once: true });
355
+ });
356
+ try {
357
+ const password = await Promise.race([credential, cancelled]);
358
+ this.active(operationArg);
359
+ if (typeof password !== 'string' || !password || password.length > 1024)
360
+ throw new AuthenticationError('Shelly caller credential resolution failed.');
361
+ operationArg.password = password;
229
362
  }
230
363
  catch {
231
- if (!this.destroyed && !this.lifetimeSignal.aborted)
232
- this.emit({ type: 'error', error: new DeviceCommunicationError('Shelly configuration refresh failed.'), timestamp: Date.now() });
364
+ this.active(operationArg);
365
+ throw new AuthenticationError('Shelly caller credential resolution failed.');
366
+ }
367
+ finally {
368
+ operationArg.signal.removeEventListener('abort', cancel);
233
369
  }
234
370
  }
235
- parseResponse(parserArg) {
371
+ rpc(operationArg, methodArg, paramsArg, effectArg = false) {
372
+ const id = this.#requestId++;
373
+ const source = 'smarthome.exchange';
374
+ return this.requestJson(operationArg, '/rpc', { id, src: source, method: methodArg, ...(paramsArg ? { params: paramsArg } : {}) }, effectArg).then((frameArg) => parseShellyRpcResult(frameArg, id, this.#config.expectedDeviceId, source));
375
+ }
376
+ async requestJson(operationArg, pathArg, bodyArg, effectArg = false) {
377
+ this.active(operationArg);
378
+ let response = await this.request(operationArg, pathArg, bodyArg, effectArg);
379
+ if (response.status === 401 && !effectArg) {
380
+ if (!operationArg.password)
381
+ throw new AuthenticationError('Shelly authentication requires a password.');
382
+ this.#challenge = parseShellyHttpChallenge(response.challenge ?? null, this.#config.expectedDeviceId);
383
+ this.#nonceCount = 0;
384
+ response = await this.request(operationArg, pathArg, bodyArg);
385
+ }
386
+ if (response.status !== 200) {
387
+ if (response.status === 401)
388
+ throw new AuthenticationError('Shelly authentication failed.');
389
+ throw new DeviceCommunicationError('Shelly HTTP request was rejected.');
390
+ }
236
391
  try {
237
- return parserArg();
392
+ return JSON.parse(response.body);
238
393
  }
239
- catch (errorArg) {
240
- this.healthy = false;
241
- throw errorArg;
394
+ catch {
395
+ throw new DeviceCommunicationError('Shelly returned invalid JSON.');
242
396
  }
243
397
  }
244
- async callRpc(methodArg, paramsArg, abortSignalArg) {
245
- if (!this.deviceId)
246
- await this.getDeviceInfo(abortSignalArg);
247
- const id = this.requestId++;
248
- const source = 'smarthome.exchange';
249
- const frame = await this.requestJson('/rpc', { id, src: source, method: methodArg, params: paramsArg }, abortSignalArg);
250
- return this.parseResponse(() => parseShellyRpcResult(frame, id, this.deviceId, source));
251
- }
252
- async requestJson(pathArg, bodyArg, abortSignalArg) {
253
- this.assertActive(abortSignalArg);
254
- const deadline = new AbortController();
255
- let timedOut = false;
256
- const timer = setTimeout(() => { timedOut = true; deadline.abort(); }, this.timeoutMs);
257
- const signal = AbortSignal.any([deadline.signal, this.lifetimeSignal, ...(abortSignalArg ? [abortSignalArg] : [])]);
258
- const cancelled = () => timedOut ? new DeviceCommunicationError('Shelly request timed out.') : new DOMException('Shelly request cancelled.', 'AbortError');
259
- let rejectCancelled;
260
- const cancellation = new Promise((_, rejectArg) => { rejectCancelled = rejectArg; });
261
- const handleAbort = () => rejectCancelled?.(cancelled());
262
- signal.addEventListener('abort', handleAbort, { once: true });
263
- if (signal.aborted)
264
- handleAbort();
265
- const operation = this.requestQueue.then(async () => {
266
- if (signal.aborted)
267
- throw cancelled();
268
- const method = bodyArg ? 'POST' : 'GET';
269
- let response = await this.fetchPath(pathArg, method, bodyArg, signal);
270
- if (response.status === 401) {
271
- await response.body?.cancel();
272
- if (!this.config.password)
273
- throw new AuthenticationError('Shelly authentication requires a password.');
274
- this.digestChallenge = parseShellyHttpChallenge(response.headers.get('www-authenticate'), this.deviceId);
275
- this.nonceCount = 0;
276
- response = await this.fetchPath(pathArg, method, bodyArg, signal);
277
- }
278
- if (!response.ok) {
279
- await response.body?.cancel();
280
- if (response.status === 401)
281
- throw new AuthenticationError('Shelly authentication failed.');
282
- throw new DeviceCommunicationError(`Shelly request failed with HTTP ${response.status}.`);
283
- }
284
- if (!response.body)
285
- throw new DeviceCommunicationError('Shelly returned an empty response.');
286
- const reader = response.body.getReader();
287
- const chunks = [];
288
- let size = 0;
289
- try {
290
- while (true) {
291
- const { done, value } = await reader.read();
292
- if (done)
293
- break;
294
- size += value.byteLength;
295
- if (size > 1024 * 1024) {
296
- await reader.cancel();
297
- throw new DeviceCommunicationError('Shelly response exceeds the size limit.');
398
+ async request(operationArg, pathArg, bodyArg, effectArg = false) {
399
+ this.active(operationArg);
400
+ const method = bodyArg ? 'POST' : 'GET';
401
+ const payload = bodyArg ? JSON.stringify(bodyArg) : undefined;
402
+ const headers = { connection: 'close', 'accept-encoding': 'identity' };
403
+ if (payload) {
404
+ headers['content-type'] = 'application/json';
405
+ headers['content-length'] = Buffer.byteLength(payload);
406
+ }
407
+ if (this.#challenge && operationArg.password) {
408
+ const digest = createShellyDigest(this.#challenge, operationArg.password, ++this.#nonceCount, method, pathArg);
409
+ headers.authorization = `Digest username="admin", realm="${this.#challenge.realm}", nonce="${this.#challenge.nonce}", uri="${pathArg}", algorithm=SHA-256, response="${digest.response}", qop=auth, nc=${digest.nc}, cnonce="${digest.cnonce}"${this.#challenge.opaque ? `, opaque="${this.#challenge.opaque}"` : ''}`;
410
+ }
411
+ let request;
412
+ let socketDrain = Promise.resolve();
413
+ let resolveRequestClose = () => { };
414
+ const requestDrain = new Promise((resolveArg) => { resolveRequestClose = resolveArg; });
415
+ const abort = () => { request?.destroy(); };
416
+ operationArg.signal.addEventListener('abort', abort, { once: true });
417
+ let failure;
418
+ let result;
419
+ try {
420
+ result = await new Promise((resolveArg, rejectArg) => {
421
+ const transport = this.#config.protocol === 'https' ? plugins.https : plugins.http;
422
+ request = transport.request(new URL(pathArg, this.#endpoint), { method, headers, agent: false, maxHeaderSize: 8192 }, (responseArg) => {
423
+ const fail = (messageArg) => { rejectArg(new DeviceCommunicationError(messageArg)); responseArg.destroy(); };
424
+ if (responseArg.rawHeaders.length > 128 || responseArg.headers['content-encoding'] && responseArg.headers['content-encoding'] !== 'identity') {
425
+ fail('Shelly returned unsupported response headers.');
426
+ return;
298
427
  }
299
- chunks.push(value);
428
+ const status = responseArg.statusCode ?? 0;
429
+ if (status === 200 && !/^application\/json(?:\s*;\s*charset=utf-8)?$/i.test(responseArg.headers['content-type'] ?? '')) {
430
+ fail('Shelly returned unsupported response content.');
431
+ return;
432
+ }
433
+ const chunks = [];
434
+ let size = 0;
435
+ responseArg.on('data', (chunkArg) => {
436
+ if (!Buffer.isBuffer(chunkArg)) {
437
+ fail('Shelly returned invalid response bytes.');
438
+ return;
439
+ }
440
+ size += chunkArg.length;
441
+ if (size > this.#config.maxResponseBytes) {
442
+ fail('Shelly response exceeds the size limit.');
443
+ return;
444
+ }
445
+ chunks.push(chunkArg);
446
+ });
447
+ responseArg.once('error', () => rejectArg(new DeviceCommunicationError('Shelly response transport failed.')));
448
+ responseArg.once('end', () => {
449
+ if (!responseArg.complete) {
450
+ fail('Shelly response was truncated.');
451
+ return;
452
+ }
453
+ try {
454
+ resolveArg({ status, challenge: responseArg.headers['www-authenticate'], body: new TextDecoder('utf-8', { fatal: true }).decode(Buffer.concat(chunks)) });
455
+ }
456
+ catch {
457
+ fail('Shelly returned invalid UTF-8.');
458
+ }
459
+ });
460
+ });
461
+ this.#requests.add(request);
462
+ this.#drains.add(requestDrain);
463
+ request.once('close', () => { this.#requests.delete(request); this.#drains.delete(requestDrain); resolveRequestClose(); });
464
+ request.once('error', () => rejectArg(new DeviceCommunicationError('Shelly request transport failed.')));
465
+ request.once('socket', (socketArg) => {
466
+ this.#sockets.add(socketArg);
467
+ socketDrain = new Promise((resolveArg) => socketArg.once('close', () => { this.#sockets.delete(socketArg); this.#drains.delete(socketDrain); resolveArg(); }));
468
+ this.#drains.add(socketDrain);
469
+ if (this.#closed || operationArg.signal.aborted)
470
+ socketArg.destroy();
471
+ });
472
+ try {
473
+ this.active(operationArg);
474
+ if (effectArg)
475
+ operationArg.dispatched = true;
476
+ request.end(payload);
300
477
  }
301
- }
302
- finally {
303
- reader.releaseLock();
304
- }
305
- return JSON.parse(Buffer.concat(chunks).toString('utf8'));
306
- });
307
- this.requestQueue = operation.then(() => undefined, () => undefined);
308
- try {
309
- return await Promise.race([operation, cancellation]);
478
+ catch (errorArg) {
479
+ request.destroy();
480
+ rejectArg(errorArg);
481
+ }
482
+ });
310
483
  }
311
484
  catch (errorArg) {
312
- this.healthy = false;
313
- if (signal.aborted)
314
- throw cancelled();
315
- if (errorArg instanceof AuthenticationError || errorArg instanceof DeviceCommunicationError)
316
- throw errorArg;
317
- throw new DeviceCommunicationError('Shelly request failed or returned invalid JSON.');
485
+ failure = errorArg;
486
+ request?.destroy();
318
487
  }
319
488
  finally {
320
- clearTimeout(timer);
321
- signal.removeEventListener('abort', handleAbort);
322
- rejectCancelled = undefined;
489
+ if (request)
490
+ await Promise.allSettled([requestDrain, socketDrain]);
491
+ operationArg.signal.removeEventListener('abort', abort);
323
492
  }
493
+ this.active(operationArg);
494
+ if (failure !== undefined)
495
+ throw failure;
496
+ if (!result)
497
+ throw new DeviceCommunicationError('Shelly request failed.');
498
+ return result;
324
499
  }
325
- async fetchPath(pathArg, methodArg, bodyArg, signalArg) {
326
- const headers = {};
327
- if (bodyArg)
328
- headers['content-type'] = 'application/json';
329
- if (this.digestChallenge && this.config.password) {
330
- const digest = createShellyDigest(this.digestChallenge, this.config.password, ++this.nonceCount, methodArg, pathArg);
331
- headers.authorization = `Digest username="admin", realm="${this.digestChallenge.realm}", nonce="${this.digestChallenge.nonce}", uri="${pathArg}", algorithm=SHA-256, response="${digest.response}", qop=auth, nc=${digest.nc}, cnonce="${digest.cnonce}"${this.digestChallenge.opaque ? `, opaque="${this.digestChallenge.opaque}"` : ''}`;
500
+ run(workArg, signalArg) {
501
+ try {
502
+ this.assertOpen();
503
+ if (signalArg !== undefined && !(signalArg instanceof AbortSignal))
504
+ throw new TypeError('Shelly cancellation requires an AbortSignal.');
505
+ if (signalArg?.aborted)
506
+ throw new DOMException('Shelly operation cancelled.', 'AbortError');
507
+ const retainedCredentials = [...this.#credentialOperations.values()].filter((entryArg) => !this.#tasks.has(entryArg)).length;
508
+ if (this.#tasks.size + retainedCredentials + this.#credentialFailures.size >= this.#config.maxPendingOperations)
509
+ throw new ShellyOperationError('Shelly operation capacity reached.');
510
+ }
511
+ catch (errorArg) {
512
+ return Promise.reject(errorArg);
332
513
  }
333
- return globalThis.fetch(new URL(pathArg, this.endpoint), { method: methodArg, headers, body: bodyArg ? JSON.stringify(bodyArg) : undefined, signal: signalArg, redirect: 'error' });
514
+ const controller = new AbortController();
515
+ const operation = { signal: AbortSignal.any([controller.signal, this.#lifetime.signal]), deadline: performance.now() + this.#config.requestTimeoutMs, dispatched: false, acknowledged: false };
516
+ const cancel = () => controller.abort(new DOMException('Shelly operation cancelled.', 'AbortError'));
517
+ signalArg?.addEventListener('abort', cancel, { once: true });
518
+ const timer = setTimeout(() => controller.abort(new DeviceCommunicationError('Shelly request timed out.')), this.#config.requestTimeoutMs);
519
+ let rejectCancelled = () => { };
520
+ const cancellation = new Promise((_resolveArg, rejectArg) => {
521
+ rejectCancelled = () => { try {
522
+ this.active(operation);
523
+ }
524
+ catch (errorArg) {
525
+ rejectArg(this.operationError(errorArg, operation));
526
+ } };
527
+ operation.signal.addEventListener('abort', rejectCancelled, { once: true });
528
+ });
529
+ const task = this.#tail.then(async () => {
530
+ this.active(operation);
531
+ try {
532
+ return await workArg(operation);
533
+ }
534
+ catch (errorArg) {
535
+ this.#healthy = false;
536
+ throw this.operationError(errorArg, operation);
537
+ }
538
+ finally {
539
+ operation.password = undefined;
540
+ }
541
+ });
542
+ this.#tasks.add(task);
543
+ operation.task = task;
544
+ this.#tail = task.then(() => undefined, () => undefined);
545
+ const settled = () => { this.#tasks.delete(task); clearTimeout(timer); signalArg?.removeEventListener('abort', cancel); operation.signal.removeEventListener('abort', rejectCancelled); };
546
+ void task.then(settled, settled);
547
+ if (signalArg?.aborted)
548
+ cancel();
549
+ return Promise.race([task, cancellation]);
334
550
  }
335
- assertActive(abortSignalArg) {
336
- if (this.destroyed)
337
- throw new Error('Shelly client has been destroyed.');
338
- if (this.lifetimeSignal.aborted || abortSignalArg?.aborted)
551
+ operationError(errorArg, operationArg) {
552
+ if (operationArg.dispatched)
553
+ return new ShellyOperationError('Shelly control outcome is indeterminate.', 'indeterminate', operationArg.acknowledged);
554
+ return errorArg instanceof AuthenticationError || errorArg instanceof DeviceCommunicationError || errorArg instanceof ShellyOperationError || errorArg instanceof DOMException && errorArg.name === 'AbortError' ? errorArg : new ShellyOperationError('Shelly operation failed.');
555
+ }
556
+ active(operationArg) {
557
+ if (operationArg.signal.aborted)
558
+ throw operationArg.signal.reason;
559
+ this.assertOpen();
560
+ if (performance.now() >= operationArg.deadline)
561
+ throw new DeviceCommunicationError('Shelly request timed out.');
562
+ }
563
+ assertOpen() {
564
+ if (this.#context.abortSignal?.aborted)
339
565
  throw new DOMException('Shelly operation cancelled.', 'AbortError');
566
+ if (this.#closed)
567
+ throw new Error('Shelly client has been destroyed.');
340
568
  }
341
569
  }
342
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hlbGx5LmNsYXNzZXMuY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvaW50ZWdyYXRpb25zL3NoZWxseS9zaGVsbHkuY2xhc3Nlcy5jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVyRixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUN0RSxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLGNBQWMsRUFDZCxpQkFBaUIsRUFDakIsaUJBQWlCLEVBQ2pCLHFCQUFxQixFQUNyQix3QkFBd0IsRUFDeEIsb0JBQW9CLEVBQ3BCLGlCQUFpQixHQUNsQixNQUFNLGlCQUFpQixDQUFDO0FBVXpCLE1BQU0sT0FBTyxZQUFZO0lBa0I4RCxNQUFNO0lBakJuRixTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsVUFBVSxHQUFHLENBQUMsQ0FBQztJQUNmLGVBQWUsQ0FBMEI7SUFDekMsUUFBUSxDQUFVO0lBQ2xCLFFBQVEsQ0FBbUI7SUFDM0IsWUFBWSxDQUFzQjtJQUN6QixXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQXFCLENBQUM7SUFDM0MsUUFBUSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7SUFDakMsY0FBYyxDQUFjO0lBQzdDLHNGQUFzRjtJQUM5RSxZQUFZLEdBQWtCLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUN2QyxTQUFTLENBQVM7SUFDbEIsUUFBUSxDQUFNO0lBQ2QsTUFBTSxDQUFnQjtJQUMvQixPQUFPLEdBQUcsS0FBSyxDQUFDO0lBQ2hCLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFFMUIsWUFBWSxTQUF3QixFQUFFLGNBQTRCLEVBQW1CLE1BQWdCO3NCQUFoQixNQUFNO1FBQ3pGLE1BQU0sTUFBTSxHQUFrQjtZQUM1QixJQUFJLEVBQUUsU0FBUyxDQUFDLElBQUk7WUFDcEIsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJO1lBQ3BCLFFBQVEsRUFBRSxTQUFTLENBQUMsUUFBUTtZQUM1QixRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVE7WUFDNUIsUUFBUSxFQUFFLFNBQVMsQ0FBQyxRQUFRO1lBQzVCLGdCQUFnQixFQUFFLFNBQVMsQ0FBQyxnQkFBZ0I7U0FDN0MsQ0FBQztRQUNGLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixJQUFJLEtBQUssQ0FBQztRQUNsRCxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLElBQUksSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLEVBQUUsQ0FBQztZQUMzRixNQUFNLElBQUksS0FBSyxDQUFDLGtFQUFrRSxDQUFDLENBQUM7UUFDdEYsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLFFBQVEsS0FBSyxTQUFTLElBQUksTUFBTSxDQUFDLFFBQVEsS0FBSyxPQUFPO1lBQUUsTUFBTSxJQUFJLG1CQUFtQixDQUFDLCtDQUErQyxDQUFDLENBQUM7UUFDakosSUFBSSxNQUFNLENBQUMsUUFBUSxLQUFLLFNBQVMsSUFBSSxPQUFPLE1BQU0sQ0FBQyxRQUFRLEtBQUssUUFBUTtZQUFFLE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO1FBQzdJLElBQUksTUFBTSxDQUFDLFFBQVEsS0FBSyxTQUFTLElBQUksTUFBTSxDQUFDLFFBQVEsS0FBSyxNQUFNLElBQUksTUFBTSxDQUFDLFFBQVEsS0FBSyxPQUFPO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQzFKLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO1FBQzdLLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxTQUFTO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO1FBQzdGLElBQUksT0FBTyxNQUFNLENBQUMsSUFBSSxLQUFLLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO1FBQ3ZKLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO1FBQzFHLElBQUksQ0FBQztZQUFDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsUUFBUSxJQUFJLE1BQU0sTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQUMsQ0FBQztRQUMvSCxNQUFNLENBQUM7WUFBQyxNQUFNLElBQUksS0FBSyxDQUFDLCtDQUErQyxDQUFDLENBQUM7UUFBQyxDQUFDO1FBQzNFLElBQUksQ0FBQyxjQUFjLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMs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
570
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hlbGx5LmNsYXNzZXMuY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvaW50ZWdyYXRpb25zL3NoZWxseS9zaGVsbHkuY2xhc3Nlcy5jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEVBQUUsbUJBQW1CLEVBQWdDLE1BQU0sMkNBQTJDLENBQUM7QUFFOUcsT0FBTyxFQUFFLG1CQUFtQixFQUFFLHdCQUF3QixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDckYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBRSxxQkFBcUIsRUFDdEcsd0JBQXdCLEVBQUUsb0JBQW9CLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUU3RixPQUFPLEVBQUUscUJBQXFCLEVBQUUsc0JBQXNCLEVBQWdDLE1BQU0sd0JBQXdCLENBQUM7QUFDckgsT0FBTyxFQUFFLG9CQUFvQixFQUVGLE1BQU0sbUJBQW1CLENBQUM7QUFtQnJELE1BQU0sT0FBTyxZQUFZO0lBQ2QsT0FBTyxDQUEwQjtJQUNqQyxRQUFRLENBQTBCO0lBQ2xDLFNBQVMsQ0FBTTtJQUNmLFNBQVMsR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO0lBQ2xDLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBb0IsQ0FBQztJQUNyQyxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQW9CLENBQUM7SUFDM0MscUJBQXFCLEdBQUcsSUFBSSxHQUFHLEVBQXNDLENBQUM7SUFDdEUsbUJBQW1CLEdBQUcsSUFBSSxHQUFHLEVBQVMsQ0FBQztJQUN2QyxTQUFTLEdBQUcsSUFBSSxHQUFHLEVBQThCLENBQUM7SUFDbEQsUUFBUSxHQUFHLElBQUksR0FBRyxFQUFzQixD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