hap-nodejs 1.0.0-alpha.22 → 1.0.0-alpha.24

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 (134) hide show
  1. package/dist/BridgedCore.d.ts +2 -0
  2. package/dist/BridgedCore.d.ts.map +1 -0
  3. package/dist/BridgedCore.js +42 -0
  4. package/dist/BridgedCore.js.map +1 -0
  5. package/dist/Core.d.ts +2 -0
  6. package/dist/Core.d.ts.map +1 -0
  7. package/dist/Core.js +49 -0
  8. package/dist/Core.js.map +1 -0
  9. package/dist/accessories/AirConditioner_accessory.js +24 -24
  10. package/dist/accessories/AirConditioner_accessory.js.map +1 -1
  11. package/dist/accessories/AppleTVRemote_accessory.js +23 -23
  12. package/dist/accessories/AppleTVRemote_accessory.js.map +1 -1
  13. package/dist/accessories/Camera_accessory.js +292 -373
  14. package/dist/accessories/Camera_accessory.js.map +1 -1
  15. package/dist/accessories/Fan_accessory.js +15 -21
  16. package/dist/accessories/Fan_accessory.js.map +1 -1
  17. package/dist/accessories/GarageDoorOpener_accessory.js +12 -12
  18. package/dist/accessories/GarageDoorOpener_accessory.js.map +1 -1
  19. package/dist/accessories/Light-AdaptiveLighting_accessory.js +26 -26
  20. package/dist/accessories/Light-AdaptiveLighting_accessory.js.map +1 -1
  21. package/dist/accessories/Light_accessory.js +45 -48
  22. package/dist/accessories/Light_accessory.js.map +1 -1
  23. package/dist/accessories/Lock_accessory.js +11 -11
  24. package/dist/accessories/Lock_accessory.js.map +1 -1
  25. package/dist/accessories/MotionSensor_accessory.js +8 -8
  26. package/dist/accessories/MotionSensor_accessory.js.map +1 -1
  27. package/dist/accessories/Outlet_accessory.js +10 -10
  28. package/dist/accessories/Outlet_accessory.js.map +1 -1
  29. package/dist/accessories/SmartSpeaker_accessory.js +11 -11
  30. package/dist/accessories/SmartSpeaker_accessory.js.map +1 -1
  31. package/dist/accessories/Sprinkler_accessory.js +19 -19
  32. package/dist/accessories/Sprinkler_accessory.js.map +1 -1
  33. package/dist/accessories/TV_accessory.js +17 -17
  34. package/dist/accessories/TV_accessory.js.map +1 -1
  35. package/dist/accessories/TemperatureSensor_accessory.js +6 -6
  36. package/dist/accessories/TemperatureSensor_accessory.js.map +1 -1
  37. package/dist/accessories/Wi-FiRouter_accessory.js +3 -3
  38. package/dist/accessories/Wi-FiRouter_accessory.js.map +1 -1
  39. package/dist/accessories/Wi-FiSatellite_accessory.js +4 -4
  40. package/dist/accessories/Wi-FiSatellite_accessory.js.map +1 -1
  41. package/dist/accessories/gstreamer-audioProducer.js +36 -47
  42. package/dist/accessories/gstreamer-audioProducer.js.map +1 -1
  43. package/dist/accessories/types.js +2 -2
  44. package/dist/accessories/types.js.map +1 -1
  45. package/dist/index.js +5 -5
  46. package/dist/index.js.map +1 -1
  47. package/dist/lib/Accessory.js +779 -1087
  48. package/dist/lib/Accessory.js.map +1 -1
  49. package/dist/lib/AccessoryLoader.js +40 -40
  50. package/dist/lib/AccessoryLoader.js.map +1 -1
  51. package/dist/lib/Advertiser.js +392 -524
  52. package/dist/lib/Advertiser.js.map +1 -1
  53. package/dist/lib/Bridge.js +6 -10
  54. package/dist/lib/Bridge.js.map +1 -1
  55. package/dist/lib/Characteristic.js +1393 -497
  56. package/dist/lib/Characteristic.js.map +1 -1
  57. package/dist/lib/HAPServer.js +215 -265
  58. package/dist/lib/HAPServer.js.map +1 -1
  59. package/dist/lib/Service.js +486 -322
  60. package/dist/lib/Service.js.map +1 -1
  61. package/dist/lib/camera/Camera.js +14 -14
  62. package/dist/lib/camera/Camera.js.map +1 -1
  63. package/dist/lib/camera/RTPProxy.js +112 -104
  64. package/dist/lib/camera/RTPProxy.js.map +1 -1
  65. package/dist/lib/camera/RTPStreamManagement.js +284 -257
  66. package/dist/lib/camera/RTPStreamManagement.js.map +1 -1
  67. package/dist/lib/camera/RecordingManagement.js +318 -381
  68. package/dist/lib/camera/RecordingManagement.js.map +1 -1
  69. package/dist/lib/camera/index.js +1 -1
  70. package/dist/lib/controller/AdaptiveLightingController.js +198 -209
  71. package/dist/lib/controller/AdaptiveLightingController.js.map +1 -1
  72. package/dist/lib/controller/CameraController.js +190 -249
  73. package/dist/lib/controller/CameraController.js.map +1 -1
  74. package/dist/lib/controller/DoorbellController.js +38 -39
  75. package/dist/lib/controller/DoorbellController.js.map +1 -1
  76. package/dist/lib/controller/RemoteController.js +343 -401
  77. package/dist/lib/controller/RemoteController.js.map +1 -1
  78. package/dist/lib/controller/index.js +1 -1
  79. package/dist/lib/datastream/DataStreamManagement.js +56 -57
  80. package/dist/lib/datastream/DataStreamManagement.js.map +1 -1
  81. package/dist/lib/datastream/DataStreamParser.js +259 -304
  82. package/dist/lib/datastream/DataStreamParser.js.map +1 -1
  83. package/dist/lib/datastream/DataStreamServer.d.ts.map +1 -1
  84. package/dist/lib/datastream/DataStreamServer.js +252 -269
  85. package/dist/lib/datastream/DataStreamServer.js.map +1 -1
  86. package/dist/lib/datastream/index.js +1 -1
  87. package/dist/lib/definitions/CharacteristicDefinitions.js +1984 -2708
  88. package/dist/lib/definitions/CharacteristicDefinitions.js.map +1 -1
  89. package/dist/lib/definitions/ServiceDefinitions.js +818 -1035
  90. package/dist/lib/definitions/ServiceDefinitions.js.map +1 -1
  91. package/dist/lib/definitions/generate-definitions.js +383 -679
  92. package/dist/lib/definitions/generate-definitions.js.map +1 -1
  93. package/dist/lib/definitions/generator-configuration.js +29 -29
  94. package/dist/lib/definitions/generator-configuration.js.map +1 -1
  95. package/dist/lib/definitions/index.js +1 -1
  96. package/dist/lib/model/AccessoryInfo.js +101 -136
  97. package/dist/lib/model/AccessoryInfo.js.map +1 -1
  98. package/dist/lib/model/ControllerStorage.js +86 -89
  99. package/dist/lib/model/ControllerStorage.js.map +1 -1
  100. package/dist/lib/model/HAPStorage.js +15 -16
  101. package/dist/lib/model/HAPStorage.js.map +1 -1
  102. package/dist/lib/model/IdentifierCache.js +49 -49
  103. package/dist/lib/model/IdentifierCache.js.map +1 -1
  104. package/dist/lib/tv/AccessControlManagement.js +40 -44
  105. package/dist/lib/tv/AccessControlManagement.js.map +1 -1
  106. package/dist/lib/util/checkName.d.ts +2 -1
  107. package/dist/lib/util/checkName.d.ts.map +1 -1
  108. package/dist/lib/util/checkName.js +5 -10
  109. package/dist/lib/util/checkName.js.map +1 -1
  110. package/dist/lib/util/clone.js +5 -27
  111. package/dist/lib/util/clone.js.map +1 -1
  112. package/dist/lib/util/color-utils.js +8 -12
  113. package/dist/lib/util/color-utils.js.map +1 -1
  114. package/dist/lib/util/eventedhttp.js +294 -391
  115. package/dist/lib/util/eventedhttp.js.map +1 -1
  116. package/dist/lib/util/hapCrypto.js +31 -32
  117. package/dist/lib/util/hapCrypto.js.map +1 -1
  118. package/dist/lib/util/hapStatusError.js +9 -12
  119. package/dist/lib/util/hapStatusError.js.map +1 -1
  120. package/dist/lib/util/net-utils.js +32 -53
  121. package/dist/lib/util/net-utils.js.map +1 -1
  122. package/dist/lib/util/once.js +3 -8
  123. package/dist/lib/util/once.js.map +1 -1
  124. package/dist/lib/util/promise-utils.js +8 -13
  125. package/dist/lib/util/promise-utils.js.map +1 -1
  126. package/dist/lib/util/request-util.js +2 -3
  127. package/dist/lib/util/request-util.js.map +1 -1
  128. package/dist/lib/util/time.js +5 -5
  129. package/dist/lib/util/time.js.map +1 -1
  130. package/dist/lib/util/tlv.js +57 -75
  131. package/dist/lib/util/tlv.js.map +1 -1
  132. package/dist/lib/util/uuid.js +15 -19
  133. package/dist/lib/util/uuid.js.map +1 -1
  134. package/package.json +2 -2
@@ -1,30 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Accessory = exports.AccessoryEventTypes = exports.MDNSAdvertiser = exports.CharacteristicWarningType = exports.Categories = void 0;
4
- var tslib_1 = require("tslib");
5
- var assert_1 = tslib_1.__importDefault(require("assert"));
6
- var crypto_1 = tslib_1.__importDefault(require("crypto"));
7
- var debug_1 = tslib_1.__importDefault(require("debug"));
8
- var events_1 = require("events");
9
- var net_1 = tslib_1.__importDefault(require("net"));
10
- var Advertiser_1 = require("./Advertiser");
4
+ const tslib_1 = require("tslib");
5
+ const assert_1 = tslib_1.__importDefault(require("assert"));
6
+ const crypto_1 = tslib_1.__importDefault(require("crypto"));
7
+ const debug_1 = tslib_1.__importDefault(require("debug"));
8
+ const events_1 = require("events");
9
+ const net_1 = tslib_1.__importDefault(require("net"));
10
+ const Advertiser_1 = require("./Advertiser");
11
11
  // noinspection JSDeprecatedSymbols
12
- var camera_1 = require("./camera");
13
- var Characteristic_1 = require("./Characteristic");
14
- var controller_1 = require("./controller");
15
- var HAPServer_1 = require("./HAPServer");
16
- var AccessoryInfo_1 = require("./model/AccessoryInfo");
17
- var ControllerStorage_1 = require("./model/ControllerStorage");
18
- var IdentifierCache_1 = require("./model/IdentifierCache");
19
- var Service_1 = require("./Service");
20
- var clone_1 = require("./util/clone");
21
- var request_util_1 = require("./util/request-util");
22
- var uuid = tslib_1.__importStar(require("./util/uuid"));
23
- var uuid_1 = require("./util/uuid");
24
- var checkName_1 = require("./util/checkName");
25
- var debug = (0, debug_1.default)("HAP-NodeJS:Accessory");
26
- var MAX_ACCESSORIES = 149; // Maximum number of bridged accessories per bridge.
27
- var MAX_SERVICES = 100;
12
+ const camera_1 = require("./camera");
13
+ const Characteristic_1 = require("./Characteristic");
14
+ const controller_1 = require("./controller");
15
+ const HAPServer_1 = require("./HAPServer");
16
+ const AccessoryInfo_1 = require("./model/AccessoryInfo");
17
+ const ControllerStorage_1 = require("./model/ControllerStorage");
18
+ const IdentifierCache_1 = require("./model/IdentifierCache");
19
+ const Service_1 = require("./Service");
20
+ const clone_1 = require("./util/clone");
21
+ const request_util_1 = require("./util/request-util");
22
+ const uuid = tslib_1.__importStar(require("./util/uuid"));
23
+ const uuid_1 = require("./util/uuid");
24
+ const checkName_1 = require("./util/checkName");
25
+ const debug = (0, debug_1.default)("HAP-NodeJS:Accessory");
26
+ const MAX_ACCESSORIES = 149; // Maximum number of bridged accessories per bridge.
27
+ const MAX_SERVICES = 100;
28
28
  /**
29
29
  * Known category values. Category is a hint to iOS clients about what "type" of Accessory this represents, for UI only.
30
30
  *
@@ -164,71 +164,97 @@ var AccessoryEventTypes;
164
164
  * @group Accessory
165
165
  */
166
166
  // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
167
- var Accessory = /** @class */ (function (_super) {
168
- tslib_1.__extends(Accessory, _super);
169
- function Accessory(displayName, UUID) {
170
- var _this = _super.call(this) || this;
171
- _this.displayName = displayName;
172
- _this.UUID = UUID;
173
- // NOTICE: when adding/changing properties, remember to possibly adjust the serialize/deserialize functions
174
- _this.aid = null; // assigned by us in assignIDs() or by a Bridge
175
- _this._isBridge = false; // true if we are a Bridge (creating a new instance of the Bridge subclass sets this to true)
176
- _this.bridged = false; // true if we are hosted "behind" a Bridge Accessory
177
- _this.bridgedAccessories = []; // If we are a Bridge, these are the Accessories we are bridging
178
- _this.reachable = true;
179
- _this.category = 1 /* Categories.OTHER */;
180
- _this.services = [];
181
- _this.shouldPurgeUnusedIDs = true; // Purge unused ids by default
182
- /**
183
- * Captures if initialization steps inside {@link publish} have been called.
184
- * This is important when calling {@link publish} multiple times (e.g. after calling {@link unpublish}).
185
- * @private Private API
186
- */
187
- _this.initialized = false;
188
- _this.controllers = {};
189
- /**
190
- * @private Private API.
191
- */
192
- _this._setupID = null;
193
- /**
194
- * @private Private API.
195
- */
196
- _this.controllerStorage = new ControllerStorage_1.ControllerStorage(_this);
197
- /**
198
- * This property captures the time when we last served a /accessories request.
199
- * For multiple bursts of /accessories request we don't want to always contact GET handlers
200
- */
201
- _this.lastAccessoriesRequest = 0;
202
- /**
203
- * Returns the bridging accessory if this accessory is bridged.
204
- * Otherwise, returns itself.
205
- *
206
- * @returns the primary accessory
207
- */
208
- _this.getPrimaryAccessory = function () {
209
- return _this.bridged ? _this.bridge : _this;
210
- };
167
+ class Accessory extends events_1.EventEmitter {
168
+ displayName;
169
+ UUID;
170
+ /**
171
+ * @deprecated Please use the Categories const enum above.
172
+ */
173
+ // @ts-expect-error: forceConsistentCasingInFileNames compiler option
174
+ static Categories = Categories;
175
+ /// Timeout in milliseconds until a characteristic warning is issue
176
+ static TIMEOUT_WARNING = 3000;
177
+ /// Timeout in milliseconds after `TIMEOUT_WARNING` until the operation on the characteristic is considered timed out.
178
+ static TIMEOUT_AFTER_WARNING = 6000;
179
+ // NOTICE: when adding/changing properties, remember to possibly adjust the serialize/deserialize functions
180
+ aid = null; // assigned by us in assignIDs() or by a Bridge
181
+ _isBridge = false; // true if we are a Bridge (creating a new instance of the Bridge subclass sets this to true)
182
+ bridged = false; // true if we are hosted "behind" a Bridge Accessory
183
+ bridge; // if accessory is bridged, this property points to the bridge which bridges this accessory
184
+ bridgedAccessories = []; // If we are a Bridge, these are the Accessories we are bridging
185
+ reachable = true;
186
+ lastKnownUsername;
187
+ category = 1 /* Categories.OTHER */;
188
+ services = [];
189
+ primaryService;
190
+ shouldPurgeUnusedIDs = true; // Purge unused ids by default
191
+ /**
192
+ * Captures if initialization steps inside {@link publish} have been called.
193
+ * This is important when calling {@link publish} multiple times (e.g. after calling {@link unpublish}).
194
+ * @private Private API
195
+ */
196
+ initialized = false;
197
+ controllers = {};
198
+ serializedControllers; // store uninitialized controller data after a Accessory.deserialize call
199
+ activeCameraController;
200
+ /**
201
+ * @private Private API.
202
+ */
203
+ _accessoryInfo;
204
+ /**
205
+ * @private Private API.
206
+ */
207
+ _setupID = null;
208
+ /**
209
+ * @private Private API.
210
+ */
211
+ _identifierCache;
212
+ /**
213
+ * @private Private API.
214
+ */
215
+ controllerStorage = new ControllerStorage_1.ControllerStorage(this);
216
+ /**
217
+ * @private Private API.
218
+ */
219
+ _advertiser;
220
+ /**
221
+ * @private Private API.
222
+ */
223
+ _server;
224
+ /**
225
+ * @private Private API.
226
+ */
227
+ _setupURI;
228
+ configurationChangeDebounceTimeout;
229
+ /**
230
+ * This property captures the time when we last served a /accessories request.
231
+ * For multiple bursts of /accessories request we don't want to always contact GET handlers
232
+ */
233
+ lastAccessoriesRequest = 0;
234
+ constructor(displayName, UUID) {
235
+ super();
236
+ this.displayName = displayName;
237
+ this.UUID = UUID;
211
238
  (0, assert_1.default)(displayName, "Accessories must be created with a non-empty displayName.");
212
239
  (0, assert_1.default)(UUID, "Accessories must be created with a valid UUID.");
213
240
  (0, assert_1.default)(uuid.isValid(UUID), "UUID '" + UUID + "' is not a valid UUID. Try using the provided 'generateUUID' function to create a " +
214
241
  "valid UUID from any arbitrary string, like a serial number.");
215
242
  // create our initial "Accessory Information" Service that all Accessories are expected to have
216
- (0, checkName_1.checkName)(_this.displayName, "name", displayName);
217
- _this.addService(Service_1.Service.AccessoryInformation)
243
+ (0, checkName_1.checkName)(this.displayName, "Name", displayName);
244
+ this.addService(Service_1.Service.AccessoryInformation)
218
245
  .setCharacteristic(Characteristic_1.Characteristic.Name, displayName);
219
246
  // sign up for when iOS attempts to "set" the `Identify` characteristic - this means a paired device wishes
220
247
  // for us to identify ourselves (as opposed to an unpaired device - that case is handled by HAPServer 'identify' event)
221
- _this.getService(Service_1.Service.AccessoryInformation)
248
+ this.getService(Service_1.Service.AccessoryInformation)
222
249
  .getCharacteristic(Characteristic_1.Characteristic.Identify)
223
- .on("set" /* CharacteristicEventTypes.SET */, function (value, callback) {
250
+ .on("set" /* CharacteristicEventTypes.SET */, (value, callback) => {
224
251
  if (value) {
225
- var paired = true;
226
- _this.identificationRequest(paired, callback);
252
+ const paired = true;
253
+ this.identificationRequest(paired, callback);
227
254
  }
228
255
  });
229
- return _this;
230
256
  }
231
- Accessory.prototype.identificationRequest = function (paired, callback) {
257
+ identificationRequest(paired, callback) {
232
258
  debug("[%s] Identification request", this.displayName);
233
259
  if (this.listeners("identify" /* AccessoryEventTypes.IDENTIFY */).length > 0) {
234
260
  // allow implementors to identify this Accessory in whatever way is appropriate, and pass along
@@ -239,43 +265,28 @@ var Accessory = /** @class */ (function (_super) {
239
265
  debug("[%s] Identification request ignored; no listeners to 'identify' event", this.displayName);
240
266
  callback();
241
267
  }
242
- };
268
+ }
243
269
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
244
- Accessory.prototype.addService = function (serviceParam) {
245
- var e_1, _a;
246
- var constructorArgs = [];
247
- for (var _i = 1; _i < arguments.length; _i++) {
248
- constructorArgs[_i - 1] = arguments[_i];
249
- }
270
+ addService(serviceParam, ...constructorArgs) {
250
271
  // service might be a constructor like `Service.AccessoryInformation` instead of an instance
251
272
  // of Service. Coerce if necessary.
252
- var service = typeof serviceParam === "function"
273
+ const service = typeof serviceParam === "function"
253
274
  ? new serviceParam(constructorArgs[0], constructorArgs[1], constructorArgs[2])
254
275
  : serviceParam;
255
- try {
256
- // check for UUID+subtype conflict
257
- for (var _b = tslib_1.__values(this.services), _c = _b.next(); !_c.done; _c = _b.next()) {
258
- var existing = _c.value;
259
- if (existing.UUID === service.UUID) {
260
- // OK we have two Services with the same UUID. Check that each defines a `subtype` property and that each is unique.
261
- if (!service.subtype) {
262
- throw new Error("Cannot add a Service with the same UUID '" + existing.UUID +
263
- "' as another Service in this Accessory without also defining a unique 'subtype' property.");
264
- }
265
- if (service.subtype === existing.subtype) {
266
- throw new Error("Cannot add a Service with the same UUID '" + existing.UUID +
267
- "' and subtype '" + existing.subtype + "' as another Service in this Accessory.");
268
- }
276
+ // check for UUID+subtype conflict
277
+ for (const existing of this.services) {
278
+ if (existing.UUID === service.UUID) {
279
+ // OK we have two Services with the same UUID. Check that each defines a `subtype` property and that each is unique.
280
+ if (!service.subtype) {
281
+ throw new Error("Cannot add a Service with the same UUID '" + existing.UUID +
282
+ "' as another Service in this Accessory without also defining a unique 'subtype' property.");
283
+ }
284
+ if (service.subtype === existing.subtype) {
285
+ throw new Error("Cannot add a Service with the same UUID '" + existing.UUID +
286
+ "' and subtype '" + existing.subtype + "' as another Service in this Accessory.");
269
287
  }
270
288
  }
271
289
  }
272
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
273
- finally {
274
- try {
275
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
276
- }
277
- finally { if (e_1) throw e_1.error; }
278
- }
279
290
  if (this.services.length >= MAX_SERVICES) {
280
291
  throw new Error("Cannot add more than " + MAX_SERVICES + " services to a single accessory!");
281
292
  }
@@ -294,15 +305,15 @@ var Accessory = /** @class */ (function (_super) {
294
305
  }
295
306
  this.setupServiceEventHandlers(service);
296
307
  return service;
297
- };
308
+ }
298
309
  /**
299
310
  * @deprecated use {@link Service.setPrimaryService} directly
300
311
  */
301
- Accessory.prototype.setPrimaryService = function (service) {
312
+ setPrimaryService(service) {
302
313
  service.setPrimaryService();
303
- };
304
- Accessory.prototype.removeService = function (service) {
305
- var index = this.services.indexOf(service);
314
+ }
315
+ removeService(service) {
316
+ const index = this.services.indexOf(service);
306
317
  if (index >= 0) {
307
318
  this.services.splice(index, 1);
308
319
  if (this.primaryService === service) { // check if we are removing out primary service
@@ -317,86 +328,60 @@ var Accessory = /** @class */ (function (_super) {
317
328
  }
318
329
  service.removeAllListeners();
319
330
  }
320
- };
321
- Accessory.prototype.removeLinkedService = function (removed) {
322
- var e_2, _a;
323
- try {
324
- for (var _b = tslib_1.__values(this.services), _c = _b.next(); !_c.done; _c = _b.next()) {
325
- var service = _c.value;
326
- service.removeLinkedService(removed);
327
- }
331
+ }
332
+ removeLinkedService(removed) {
333
+ for (const service of this.services) {
334
+ service.removeLinkedService(removed);
328
335
  }
329
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
330
- finally {
331
- try {
332
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
336
+ }
337
+ getService(name) {
338
+ for (const service of this.services) {
339
+ if (typeof name === "string" && (service.displayName === name || service.name === name || service.subtype === name)) {
340
+ return service;
333
341
  }
334
- finally { if (e_2) throw e_2.error; }
335
- }
336
- };
337
- Accessory.prototype.getService = function (name) {
338
- var e_3, _a;
339
- try {
340
- for (var _b = tslib_1.__values(this.services), _c = _b.next(); !_c.done; _c = _b.next()) {
341
- var service = _c.value;
342
- if (typeof name === "string" && (service.displayName === name || service.name === name || service.subtype === name)) {
342
+ else {
343
+ // @ts-expect-error ('UUID' does not exist on type 'never')
344
+ if (typeof name === "function" && ((service instanceof name) || (name.UUID === service.UUID))) {
343
345
  return service;
344
346
  }
345
- else {
346
- // @ts-expect-error ('UUID' does not exist on type 'never')
347
- if (typeof name === "function" && ((service instanceof name) || (name.UUID === service.UUID))) {
348
- return service;
349
- }
350
- }
351
347
  }
352
348
  }
353
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
354
- finally {
355
- try {
356
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
357
- }
358
- finally { if (e_3) throw e_3.error; }
359
- }
360
349
  return undefined;
361
- };
362
- Accessory.prototype.getServiceById = function (uuid, subType) {
363
- var e_4, _a;
364
- try {
365
- for (var _b = tslib_1.__values(this.services), _c = _b.next(); !_c.done; _c = _b.next()) {
366
- var service = _c.value;
367
- if (typeof uuid === "string" && (service.displayName === uuid || service.name === uuid) && service.subtype === subType) {
350
+ }
351
+ getServiceById(uuid, subType) {
352
+ for (const service of this.services) {
353
+ if (typeof uuid === "string" && (service.displayName === uuid || service.name === uuid) && service.subtype === subType) {
354
+ return service;
355
+ }
356
+ else {
357
+ // @ts-expect-error ('UUID' does not exist on type 'never')
358
+ if (typeof uuid === "function" && ((service instanceof uuid) || (uuid.UUID === service.UUID)) && service.subtype === subType) {
368
359
  return service;
369
360
  }
370
- else {
371
- // @ts-expect-error ('UUID' does not exist on type 'never')
372
- if (typeof uuid === "function" && ((service instanceof uuid) || (uuid.UUID === service.UUID)) && service.subtype === subType) {
373
- return service;
374
- }
375
- }
376
- }
377
- }
378
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
379
- finally {
380
- try {
381
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
382
361
  }
383
- finally { if (e_4) throw e_4.error; }
384
362
  }
385
363
  return undefined;
364
+ }
365
+ /**
366
+ * Returns the bridging accessory if this accessory is bridged.
367
+ * Otherwise, returns itself.
368
+ *
369
+ * @returns the primary accessory
370
+ */
371
+ getPrimaryAccessory = () => {
372
+ return this.bridged ? this.bridge : this;
386
373
  };
387
374
  /**
388
375
  * @deprecated Not supported anymore
389
376
  */
390
- Accessory.prototype.updateReachability = function (reachable) {
377
+ updateReachability(reachable) {
391
378
  if (!this.bridged) {
392
379
  throw new Error("Cannot update reachability on non-bridged accessory!");
393
380
  }
394
381
  this.reachable = reachable;
395
382
  debug("Reachability update is no longer being supported.");
396
- };
397
- Accessory.prototype.addBridgedAccessory = function (accessory, deferUpdate) {
398
- var _this = this;
399
- if (deferUpdate === void 0) { deferUpdate = false; }
383
+ }
384
+ addBridgedAccessory(accessory, deferUpdate = false) {
400
385
  if (accessory._isBridge || accessory === this) {
401
386
  throw new Error("Illegal state: either trying to bridge a bridge or trying to bridge itself!");
402
387
  }
@@ -411,7 +396,7 @@ var Accessory = /** @class */ (function (_super) {
411
396
  throw new Error("Cannot Bridge more than " + MAX_ACCESSORIES + " Accessories");
412
397
  }
413
398
  // listen for changes in ANY characteristics of ANY services on this Accessory
414
- accessory.on("service-characteristic-change" /* AccessoryEventTypes.SERVICE_CHARACTERISTIC_CHANGE */, function (change) { return _this.handleCharacteristicChangeEvent(accessory, change.service, change); });
399
+ accessory.on("service-characteristic-change" /* AccessoryEventTypes.SERVICE_CHARACTERISTIC_CHANGE */, change => this.handleCharacteristicChangeEvent(accessory, change.service, change));
415
400
  accessory.on("service-configurationChange" /* AccessoryEventTypes.SERVICE_CONFIGURATION_CHANGE */, this.enqueueConfigurationUpdate.bind(this));
416
401
  accessory.on("characteristic-warning" /* AccessoryEventTypes.CHARACTERISTIC_WARNING */, this.handleCharacteristicWarning.bind(this));
417
402
  accessory.bridged = true;
@@ -422,28 +407,16 @@ var Accessory = /** @class */ (function (_super) {
422
407
  this.enqueueConfigurationUpdate();
423
408
  }
424
409
  return accessory;
425
- };
426
- Accessory.prototype.addBridgedAccessories = function (accessories) {
427
- var e_5, _a;
428
- try {
429
- for (var accessories_1 = tslib_1.__values(accessories), accessories_1_1 = accessories_1.next(); !accessories_1_1.done; accessories_1_1 = accessories_1.next()) {
430
- var accessory = accessories_1_1.value;
431
- this.addBridgedAccessory(accessory, true);
432
- }
433
- }
434
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
435
- finally {
436
- try {
437
- if (accessories_1_1 && !accessories_1_1.done && (_a = accessories_1.return)) _a.call(accessories_1);
438
- }
439
- finally { if (e_5) throw e_5.error; }
410
+ }
411
+ addBridgedAccessories(accessories) {
412
+ for (const accessory of accessories) {
413
+ this.addBridgedAccessory(accessory, true);
440
414
  }
441
415
  this.enqueueConfigurationUpdate();
442
- };
443
- Accessory.prototype.removeBridgedAccessory = function (accessory, deferUpdate) {
444
- if (deferUpdate === void 0) { deferUpdate = false; }
416
+ }
417
+ removeBridgedAccessory(accessory, deferUpdate = false) {
445
418
  // check for UUID conflict
446
- var accessoryIndex = this.bridgedAccessories.indexOf(accessory);
419
+ const accessoryIndex = this.bridgedAccessories.indexOf(accessory);
447
420
  if (accessoryIndex === -1) {
448
421
  throw new Error("Cannot find the bridged Accessory to remove.");
449
422
  }
@@ -454,59 +427,37 @@ var Accessory = /** @class */ (function (_super) {
454
427
  if (!deferUpdate) {
455
428
  this.enqueueConfigurationUpdate();
456
429
  }
457
- };
458
- Accessory.prototype.removeBridgedAccessories = function (accessories) {
459
- var e_6, _a;
460
- try {
461
- for (var accessories_2 = tslib_1.__values(accessories), accessories_2_1 = accessories_2.next(); !accessories_2_1.done; accessories_2_1 = accessories_2.next()) {
462
- var accessory = accessories_2_1.value;
463
- this.removeBridgedAccessory(accessory, true);
464
- }
465
- }
466
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
467
- finally {
468
- try {
469
- if (accessories_2_1 && !accessories_2_1.done && (_a = accessories_2.return)) _a.call(accessories_2);
470
- }
471
- finally { if (e_6) throw e_6.error; }
430
+ }
431
+ removeBridgedAccessories(accessories) {
432
+ for (const accessory of accessories) {
433
+ this.removeBridgedAccessory(accessory, true);
472
434
  }
473
435
  this.enqueueConfigurationUpdate();
474
- };
475
- Accessory.prototype.removeAllBridgedAccessories = function () {
476
- for (var i = this.bridgedAccessories.length - 1; i >= 0; i--) {
436
+ }
437
+ removeAllBridgedAccessories() {
438
+ for (let i = this.bridgedAccessories.length - 1; i >= 0; i--) {
477
439
  this.removeBridgedAccessory(this.bridgedAccessories[i], true);
478
440
  }
479
441
  this.enqueueConfigurationUpdate();
480
- };
481
- Accessory.prototype.getCharacteristicByIID = function (iid) {
482
- var e_7, _a;
483
- try {
484
- for (var _b = tslib_1.__values(this.services), _c = _b.next(); !_c.done; _c = _b.next()) {
485
- var service = _c.value;
486
- var characteristic = service.getCharacteristicByIID(iid);
487
- if (characteristic) {
488
- return characteristic;
489
- }
490
- }
491
- }
492
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
493
- finally {
494
- try {
495
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
442
+ }
443
+ getCharacteristicByIID(iid) {
444
+ for (const service of this.services) {
445
+ const characteristic = service.getCharacteristicByIID(iid);
446
+ if (characteristic) {
447
+ return characteristic;
496
448
  }
497
- finally { if (e_7) throw e_7.error; }
498
449
  }
499
- };
500
- Accessory.prototype.getAccessoryByAID = function (aid) {
450
+ }
451
+ getAccessoryByAID(aid) {
501
452
  if (this.aid === aid) {
502
453
  return this;
503
454
  }
504
- return this.bridgedAccessories.find(function (value) { return value.aid === aid; });
505
- };
506
- Accessory.prototype.findCharacteristic = function (aid, iid) {
507
- var accessory = this.getAccessoryByAID(aid);
455
+ return this.bridgedAccessories.find(value => value.aid === aid);
456
+ }
457
+ findCharacteristic(aid, iid) {
458
+ const accessory = this.getAccessoryByAID(aid);
508
459
  return accessory && accessory.getCharacteristicByIID(iid);
509
- };
460
+ }
510
461
  // noinspection JSDeprecatedSymbols
511
462
  /**
512
463
  * Method is used to configure an old style CameraSource.
@@ -530,34 +481,33 @@ var Accessory = /** @class */ (function (_super) {
530
481
  * @param cameraSource - The instance of the legacy camera source
531
482
  * @deprecated please refer to the new {@link CameraController} API and {@link configureController}
532
483
  */
533
- Accessory.prototype.configureCameraSource = function (cameraSource) {
534
- var _this = this;
484
+ configureCameraSource(cameraSource) {
535
485
  if (cameraSource.streamControllers.length === 0) {
536
486
  throw new Error("Malformed legacy CameraSource. Did not expose any StreamControllers!");
537
487
  }
538
- var options = cameraSource.streamControllers[0].options; // grab options from one of the StreamControllers
539
- var cameraControllerOptions = {
488
+ const options = cameraSource.streamControllers[0].options; // grab options from one of the StreamControllers
489
+ const cameraControllerOptions = {
540
490
  cameraStreamCount: cameraSource.streamControllers.length,
541
491
  streamingOptions: options,
542
492
  delegate: new camera_1.LegacyCameraSourceAdapter(cameraSource),
543
493
  };
544
- var cameraController = new controller_1.CameraController(cameraControllerOptions, true); // create CameraController in legacy mode
494
+ const cameraController = new controller_1.CameraController(cameraControllerOptions, true); // create CameraController in legacy mode
545
495
  this.configureController(cameraController);
546
496
  // we try here to be as good as possibly of keeping current behaviour
547
- cameraSource.services.forEach(function (service) {
497
+ cameraSource.services.forEach(service => {
548
498
  if (service.UUID === Service_1.Service.CameraRTPStreamManagement.UUID || service.UUID === Service_1.Service.CameraOperatingMode.UUID
549
499
  || service.UUID === Service_1.Service.CameraRecordingManagement.UUID) {
550
500
  return; // ignore those services, as they get replaced by the RTPStreamManagement
551
501
  }
552
502
  // all other services get added. We can't really control possibly linking to any of those ignored services
553
503
  // so this is really only half-baked stuff.
554
- _this.addService(service);
504
+ this.addService(service);
555
505
  });
556
506
  // replace stream controllers; basically only to still support the "forceStop" call
557
507
  // noinspection JSDeprecatedSymbols
558
508
  cameraSource.streamControllers = cameraController.streamManagements;
559
509
  return cameraController; // return the reference for the controller (maybe this could be useful?)
560
- };
510
+ }
561
511
  /**
562
512
  * This method is used to set up a new Controller for this accessory. See {@link Controller} for a more detailed
563
513
  * explanation what a Controller is and what it is capable of.
@@ -572,20 +522,19 @@ var Accessory = /** @class */ (function (_super) {
572
522
  *
573
523
  * @param controllerConstructor - The Controller instance or constructor to the Controller with no required arguments.
574
524
  */
575
- Accessory.prototype.configureController = function (controllerConstructor) {
576
- var _this = this;
577
- var controller = typeof controllerConstructor === "function"
525
+ configureController(controllerConstructor) {
526
+ const controller = typeof controllerConstructor === "function"
578
527
  ? new controllerConstructor() // any custom constructor arguments should be passed before using .bind(...)
579
528
  : controllerConstructor;
580
- var id = controller.controllerId();
529
+ const id = controller.controllerId();
581
530
  if (this.controllers[id]) {
582
- throw new Error("A Controller with the type/id '".concat(id, "' was already added to the accessory ").concat(this.displayName));
531
+ throw new Error(`A Controller with the type/id '${id}' was already added to the accessory ${this.displayName}`);
583
532
  }
584
- var savedServiceMap = this.serializedControllers && this.serializedControllers[id];
585
- var serviceMap;
533
+ const savedServiceMap = this.serializedControllers && this.serializedControllers[id];
534
+ let serviceMap;
586
535
  if (savedServiceMap) { // we found data to restore from
587
- var clonedServiceMap = (0, clone_1.clone)(savedServiceMap);
588
- var updatedServiceMap = controller.initWithServices(savedServiceMap); // init controller with existing services
536
+ const clonedServiceMap = (0, clone_1.clone)(savedServiceMap);
537
+ const updatedServiceMap = controller.initWithServices(savedServiceMap); // init controller with existing services
589
538
  serviceMap = updatedServiceMap || savedServiceMap; // initWithServices could return an updated serviceMap, otherwise just use the existing one
590
539
  if (updatedServiceMap) { // controller returned a ServiceMap and thus signaled an updated set of services
591
540
  // clonedServiceMap is altered by this method, should not be touched again after this call (for the future people)
@@ -601,14 +550,14 @@ var Accessory = /** @class */ (function (_super) {
601
550
  else {
602
551
  serviceMap = controller.constructServices(); // let the controller create his services
603
552
  controller.configureServices(); // let the controller setup all its handlers
604
- Object.values(serviceMap).forEach(function (service) {
605
- if (service && !_this.services.includes(service)) {
606
- _this.addService(service);
553
+ Object.values(serviceMap).forEach(service => {
554
+ if (service && !this.services.includes(service)) {
555
+ this.addService(service);
607
556
  }
608
557
  });
609
558
  }
610
559
  // --- init handlers and setup context ---
611
- var context = {
560
+ const context = {
612
561
  controller: controller,
613
562
  serviceMap: serviceMap,
614
563
  };
@@ -619,7 +568,7 @@ var Accessory = /** @class */ (function (_super) {
619
568
  if (controller instanceof controller_1.CameraController) { // save CameraController for Snapshot handling
620
569
  this.activeCameraController = controller;
621
570
  }
622
- };
571
+ }
623
572
  /**
624
573
  * This method will remove a given Controller from this accessory.
625
574
  * The controller object will be restored to its initial state.
@@ -627,10 +576,9 @@ var Accessory = /** @class */ (function (_super) {
627
576
  *
628
577
  * @param controller - The controller which should be removed from the accessory.
629
578
  */
630
- Accessory.prototype.removeController = function (controller) {
631
- var _this = this;
632
- var id = controller.controllerId();
633
- var storedController = this.controllers[id];
579
+ removeController(controller) {
580
+ const id = controller.controllerId();
581
+ const storedController = this.controllers[id];
634
582
  if (storedController) {
635
583
  if (storedController.controller !== controller) {
636
584
  throw new Error("[" + this.displayName + "] tried removing a controller with the id/type '" + id +
@@ -648,114 +596,101 @@ var Accessory = /** @class */ (function (_super) {
648
596
  if (this.activeCameraController === controller) {
649
597
  this.activeCameraController = undefined;
650
598
  }
651
- Object.values(storedController.serviceMap).forEach(function (service) {
599
+ Object.values(storedController.serviceMap).forEach(service => {
652
600
  if (service) {
653
- _this.removeService(service);
601
+ this.removeService(service);
654
602
  }
655
603
  });
656
604
  }
657
605
  if (this.serializedControllers) {
658
606
  delete this.serializedControllers[id];
659
607
  }
660
- };
661
- Accessory.prototype.handleAccessoryUnpairedForControllers = function () {
662
- var e_8, _a;
663
- try {
664
- for (var _b = tslib_1.__values(Object.values(this.controllers)), _c = _b.next(); !_c.done; _c = _b.next()) {
665
- var context = _c.value;
666
- var controller = context.controller;
667
- if (controller.handleFactoryReset) { // if the controller implements handleFactoryReset, setup event handlers for this controller
668
- controller.handleFactoryReset();
669
- }
670
- if ((0, controller_1.isSerializableController)(controller)) {
671
- this.controllerStorage.purgeControllerData(controller);
672
- }
608
+ }
609
+ handleAccessoryUnpairedForControllers() {
610
+ for (const context of Object.values(this.controllers)) {
611
+ const controller = context.controller;
612
+ if (controller.handleFactoryReset) { // if the controller implements handleFactoryReset, setup event handlers for this controller
613
+ controller.handleFactoryReset();
673
614
  }
674
- }
675
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
676
- finally {
677
- try {
678
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
615
+ if ((0, controller_1.isSerializableController)(controller)) {
616
+ this.controllerStorage.purgeControllerData(controller);
679
617
  }
680
- finally { if (e_8) throw e_8.error; }
681
618
  }
682
- };
683
- Accessory.prototype.handleUpdatedControllerServiceMap = function (originalServiceMap, updatedServiceMap) {
684
- var _this = this;
619
+ }
620
+ handleUpdatedControllerServiceMap(originalServiceMap, updatedServiceMap) {
685
621
  updatedServiceMap = (0, clone_1.clone)(updatedServiceMap); // clone it so we can alter it
686
- Object.keys(originalServiceMap).forEach(function (name) {
687
- var service = originalServiceMap[name];
688
- var updatedService = updatedServiceMap[name];
622
+ Object.keys(originalServiceMap).forEach(name => {
623
+ const service = originalServiceMap[name];
624
+ const updatedService = updatedServiceMap[name];
689
625
  if (service && updatedService) { // we check all names contained in both ServiceMaps for changes
690
626
  delete originalServiceMap[name]; // delete from original ServiceMap, so it will only contain deleted services at the end
691
627
  delete updatedServiceMap[name]; // delete from updated ServiceMap, so it will only contain added services at the end
692
628
  if (service !== updatedService) {
693
- _this.removeService(service);
694
- _this.addService(updatedService);
629
+ this.removeService(service);
630
+ this.addService(updatedService);
695
631
  }
696
632
  }
697
633
  });
698
634
  // now originalServiceMap contains only deleted services and updateServiceMap only added services
699
- Object.values(originalServiceMap).forEach(function (service) {
635
+ Object.values(originalServiceMap).forEach(service => {
700
636
  if (service) {
701
- _this.removeService(service);
637
+ this.removeService(service);
702
638
  }
703
639
  });
704
- Object.values(updatedServiceMap).forEach(function (service) {
640
+ Object.values(updatedServiceMap).forEach(service => {
705
641
  if (service) {
706
- _this.addService(service);
642
+ this.addService(service);
707
643
  }
708
644
  });
709
- };
710
- Accessory.prototype.setupURI = function () {
645
+ }
646
+ setupURI() {
711
647
  if (this._setupURI) {
712
648
  return this._setupURI;
713
649
  }
714
650
  (0, assert_1.default)(!!this._accessoryInfo, "Cannot generate setupURI on an accessory that isn't published yet!");
715
- var buffer = Buffer.alloc(8);
716
- var value_low = parseInt(this._accessoryInfo.pincode.replace(/-/g, ""), 10);
717
- var value_high = this._accessoryInfo.category >> 1;
651
+ const buffer = Buffer.alloc(8);
652
+ let value_low = parseInt(this._accessoryInfo.pincode.replace(/-/g, ""), 10);
653
+ const value_high = this._accessoryInfo.category >> 1;
718
654
  value_low |= 1 << 28; // Supports IP;
719
655
  buffer.writeUInt32BE(value_low, 4);
720
656
  if (this._accessoryInfo.category & 1) {
721
657
  buffer[4] = buffer[4] | 1 << 7;
722
658
  }
723
659
  buffer.writeUInt32BE(value_high, 0);
724
- var encodedPayload = (buffer.readUInt32BE(4) + (buffer.readUInt32BE(0) * 0x100000000)).toString(36).toUpperCase();
660
+ let encodedPayload = (buffer.readUInt32BE(4) + (buffer.readUInt32BE(0) * 0x100000000)).toString(36).toUpperCase();
725
661
  if (encodedPayload.length !== 9) {
726
- for (var i = 0; i <= 9 - encodedPayload.length; i++) {
662
+ for (let i = 0; i <= 9 - encodedPayload.length; i++) {
727
663
  encodedPayload = "0" + encodedPayload;
728
664
  }
729
665
  }
730
666
  this._setupURI = "X-HM://" + encodedPayload + this._setupID;
731
667
  return this._setupURI;
732
- };
668
+ }
733
669
  /**
734
670
  * This method is called right before the accessory is published. It should be used to check for common
735
671
  * mistakes in Accessory structured, which may lead to HomeKit rejecting the accessory when pairing.
736
672
  * If it is called on a bridge it will call this method for all bridged accessories.
737
673
  */
738
- Accessory.prototype.validateAccessory = function (mainAccessory) {
739
- var _this = this;
740
- var service = this.getService(Service_1.Service.AccessoryInformation);
674
+ validateAccessory(mainAccessory) {
675
+ const service = this.getService(Service_1.Service.AccessoryInformation);
741
676
  if (!service) {
742
677
  console.log("HAP-NodeJS WARNING: The accessory '" + this.displayName + "' is getting published without a AccessoryInformation service. " +
743
678
  "This might prevent the accessory from being added to the Home app or leading to the accessory being unresponsive!");
744
679
  }
745
680
  else {
746
681
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
747
- var checkValue = function (name, value) {
682
+ const checkValue = (name, value) => {
748
683
  if (!value) {
749
- console.log("HAP-NodeJS WARNING: The accessory '" + _this.displayName + "' is getting published with the characteristic '" + name + "'" +
684
+ console.log("HAP-NodeJS WARNING: The accessory '" + this.displayName + "' is getting published with the characteristic '" + name + "'" +
750
685
  " (of the AccessoryInformation service) not having a value set. " +
751
686
  "This might prevent the accessory from being added to the Home App or leading to the accessory being unresponsive!");
752
687
  }
753
688
  };
754
- var model = service.getCharacteristic(Characteristic_1.Characteristic.Model).value;
755
- var serialNumber = service.getCharacteristic(Characteristic_1.Characteristic.SerialNumber).value;
756
- var firmwareRevision = service.getCharacteristic(Characteristic_1.Characteristic.FirmwareRevision).value;
757
- var name = service.getCharacteristic(Characteristic_1.Characteristic.Name).value;
758
- var manufacturer = service.getCharacteristic(Characteristic_1.Characteristic.Manufacturer).value;
689
+ const model = service.getCharacteristic(Characteristic_1.Characteristic.Model).value;
690
+ const serialNumber = service.getCharacteristic(Characteristic_1.Characteristic.SerialNumber).value;
691
+ const firmwareRevision = service.getCharacteristic(Characteristic_1.Characteristic.FirmwareRevision).value;
692
+ const name = service.getCharacteristic(Characteristic_1.Characteristic.Name).value;
693
+ const manufacturer = service.getCharacteristic(Characteristic_1.Characteristic.Manufacturer).value;
759
694
  checkValue("Model", model);
760
695
  checkValue("SerialNumber", serialNumber);
761
696
  checkValue("FirmwareRevision", firmwareRevision);
@@ -768,16 +703,15 @@ var Accessory = /** @class */ (function (_super) {
768
703
  (0, assert_1.default)(Buffer.from(this.displayName, "utf8").length <= 63, "Accessory displayName cannot be longer than 63 bytes!");
769
704
  }
770
705
  if (this.bridged) {
771
- this.bridgedAccessories.forEach(function (accessory) { return accessory.validateAccessory(); });
706
+ this.bridgedAccessories.forEach(accessory => accessory.validateAccessory());
772
707
  }
773
- };
708
+ }
774
709
  /**
775
710
  * Assigns aid/iid to ourselves, any Accessories we are bridging, and all associated Services+Characteristics. Uses
776
711
  * the provided identifierCache to keep IDs stable.
777
712
  * @private Private API
778
713
  */
779
- Accessory.prototype._assignIDs = function (identifierCache) {
780
- var e_9, _a, e_10, _b;
714
+ _assignIDs(identifierCache) {
781
715
  // if we are responsible for our own identifierCache, start the expiration process
782
716
  // also check weather we want to have an expiration process
783
717
  if (this._identifierCache && this.shouldPurgeUnusedIDs) {
@@ -793,37 +727,17 @@ var Accessory = /** @class */ (function (_super) {
793
727
  // we must have aid = 1
794
728
  this.aid = 1;
795
729
  }
796
- try {
797
- for (var _c = tslib_1.__values(this.services), _d = _c.next(); !_d.done; _d = _c.next()) {
798
- var service = _d.value;
799
- if (this._isBridge) {
800
- service._assignIDs(identifierCache, this.UUID, 2000000000);
801
- }
802
- else {
803
- service._assignIDs(identifierCache, this.UUID);
804
- }
805
- }
806
- }
807
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
808
- finally {
809
- try {
810
- if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
730
+ for (const service of this.services) {
731
+ if (this._isBridge) {
732
+ service._assignIDs(identifierCache, this.UUID, 2000000000);
811
733
  }
812
- finally { if (e_9) throw e_9.error; }
813
- }
814
- try {
815
- // now assign IDs for any Accessories we are bridging
816
- for (var _e = tslib_1.__values(this.bridgedAccessories), _f = _e.next(); !_f.done; _f = _e.next()) {
817
- var accessory = _f.value;
818
- accessory._assignIDs(identifierCache);
734
+ else {
735
+ service._assignIDs(identifierCache, this.UUID);
819
736
  }
820
737
  }
821
- catch (e_10_1) { e_10 = { error: e_10_1 }; }
822
- finally {
823
- try {
824
- if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
825
- }
826
- finally { if (e_10) throw e_10.error; }
738
+ // now assign IDs for any Accessories we are bridging
739
+ for (const accessory of this.bridgedAccessories) {
740
+ accessory._assignIDs(identifierCache);
827
741
  }
828
742
  // expire any now-unused cache keys (for Accessories, Services, or Characteristics
829
743
  // that have been removed since the last call to assignIDs())
@@ -835,94 +749,64 @@ var Accessory = /** @class */ (function (_super) {
835
749
  //Save in case we have new ones
836
750
  this._identifierCache.save();
837
751
  }
838
- };
839
- Accessory.prototype.disableUnusedIDPurge = function () {
752
+ }
753
+ disableUnusedIDPurge() {
840
754
  this.shouldPurgeUnusedIDs = false;
841
- };
842
- Accessory.prototype.enableUnusedIDPurge = function () {
755
+ }
756
+ enableUnusedIDPurge() {
843
757
  this.shouldPurgeUnusedIDs = true;
844
- };
758
+ }
845
759
  /**
846
760
  * Manually purge the unused ids if you like, comes handy
847
761
  * when you have disabled auto purge, so you can do it manually
848
762
  */
849
- Accessory.prototype.purgeUnusedIDs = function () {
763
+ purgeUnusedIDs() {
850
764
  //Cache the state of the purge mechanism and set it to true
851
- var oldValue = this.shouldPurgeUnusedIDs;
765
+ const oldValue = this.shouldPurgeUnusedIDs;
852
766
  this.shouldPurgeUnusedIDs = true;
853
767
  //Reassign all ids
854
768
  this._assignIDs(this._identifierCache);
855
769
  // Revert the purge mechanism state
856
770
  this.shouldPurgeUnusedIDs = oldValue;
857
- };
771
+ }
858
772
  /**
859
773
  * Returns a JSON representation of this accessory suitable for delivering to HAP clients.
860
774
  */
861
- Accessory.prototype.toHAP = function (connection_1) {
862
- return tslib_1.__awaiter(this, arguments, void 0, function (connection, contactGetHandlers) {
863
- var accessory, accessories, _a, _b, _c, _d;
864
- var _e;
865
- if (contactGetHandlers === void 0) { contactGetHandlers = true; }
866
- return tslib_1.__generator(this, function (_f) {
867
- switch (_f.label) {
868
- case 0:
869
- (0, assert_1.default)(this.aid, "aid cannot be undefined for accessory '" + this.displayName + "'");
870
- (0, assert_1.default)(this.services.length, "accessory '" + this.displayName + "' does not have any services!");
871
- _e = {
872
- aid: this.aid
873
- };
874
- return [4 /*yield*/, Promise.all(this.services.map(function (service) { return service.toHAP(connection, contactGetHandlers); }))];
875
- case 1:
876
- accessory = (_e.services = _f.sent(),
877
- _e);
878
- accessories = [accessory];
879
- if (!!this.bridged) return [3 /*break*/, 3];
880
- _b = (_a = accessories.push).apply;
881
- _c = [accessories];
882
- _d = [[]];
883
- return [4 /*yield*/, Promise.all(this.bridgedAccessories
884
- .map(function (accessory) { return accessory.toHAP(connection, contactGetHandlers).then(function (value) { return value[0]; }); }))];
885
- case 2:
886
- _b.apply(_a, _c.concat([tslib_1.__spreadArray.apply(void 0, _d.concat([tslib_1.__read.apply(void 0, [_f.sent()]), false]))]));
887
- _f.label = 3;
888
- case 3: return [2 /*return*/, accessories];
889
- }
890
- });
891
- });
892
- };
775
+ async toHAP(connection, contactGetHandlers = true) {
776
+ (0, assert_1.default)(this.aid, "aid cannot be undefined for accessory '" + this.displayName + "'");
777
+ (0, assert_1.default)(this.services.length, "accessory '" + this.displayName + "' does not have any services!");
778
+ const accessory = {
779
+ aid: this.aid,
780
+ services: await Promise.all(this.services.map(service => service.toHAP(connection, contactGetHandlers))),
781
+ };
782
+ const accessories = [accessory];
783
+ if (!this.bridged) {
784
+ accessories.push(...await Promise.all(this.bridgedAccessories
785
+ .map(accessory => accessory.toHAP(connection, contactGetHandlers).then(value => value[0]))));
786
+ }
787
+ return accessories;
788
+ }
893
789
  /**
894
790
  * Returns a JSON representation of this accessory without characteristic values.
895
791
  */
896
- Accessory.prototype.internalHAPRepresentation = function (assignIds) {
897
- var e_11, _a;
898
- if (assignIds === void 0) { assignIds = true; }
792
+ internalHAPRepresentation(assignIds = true) {
899
793
  if (assignIds) {
900
794
  this._assignIDs(this._identifierCache); // make sure our aid/iid's are all assigned
901
795
  }
902
796
  (0, assert_1.default)(this.aid, "aid cannot be undefined for accessory '" + this.displayName + "'");
903
797
  (0, assert_1.default)(this.services.length, "accessory '" + this.displayName + "' does not have any services!");
904
- var accessory = {
798
+ const accessory = {
905
799
  aid: this.aid,
906
- services: this.services.map(function (service) { return service.internalHAPRepresentation(); }),
800
+ services: this.services.map(service => service.internalHAPRepresentation()),
907
801
  };
908
- var accessories = [accessory];
802
+ const accessories = [accessory];
909
803
  if (!this.bridged) {
910
- try {
911
- for (var _b = tslib_1.__values(this.bridgedAccessories), _c = _b.next(); !_c.done; _c = _b.next()) {
912
- var accessory_1 = _c.value;
913
- accessories.push(accessory_1.internalHAPRepresentation(false)[0]);
914
- }
915
- }
916
- catch (e_11_1) { e_11 = { error: e_11_1 }; }
917
- finally {
918
- try {
919
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
920
- }
921
- finally { if (e_11) throw e_11.error; }
804
+ for (const accessory of this.bridgedAccessories) {
805
+ accessories.push(accessory.internalHAPRepresentation(false)[0]);
922
806
  }
923
807
  }
924
808
  return accessories;
925
- };
809
+ }
926
810
  /**
927
811
  * Publishes this accessory on the local network for iOS clients to communicate with.
928
812
  * - `info.username` - formatted as a MAC address, like `CC:22:3D:E3:CE:F6`, of this accessory.
@@ -940,182 +824,157 @@ var Accessory = /** @class */ (function (_super) {
940
824
  * }} info - Required info for publishing.
941
825
  * @param {boolean} allowInsecureRequest - Will allow unencrypted and unauthenticated access to the http server
942
826
  */
943
- Accessory.prototype.publish = function (info, allowInsecureRequest) {
944
- return tslib_1.__awaiter(this, void 0, void 0, function () {
945
- var service, config, parsed, selectedAdvertiser, _a, _b, _c;
946
- var _this = this;
947
- var _d, _e, _f;
948
- return tslib_1.__generator(this, function (_g) {
949
- switch (_g.label) {
950
- case 0:
951
- if (this.bridged) {
952
- throw new Error("Can't publish in accessory which is bridged by another accessory. Bridged by " + ((_d = this.bridge) === null || _d === void 0 ? void 0 : _d.displayName));
953
- }
954
- // noinspection JSDeprecatedSymbols
955
- if (!info.advertiser && info.useLegacyAdvertiser != null) {
956
- // noinspection JSDeprecatedSymbols
957
- info.advertiser = info.useLegacyAdvertiser ? "bonjour-hap" /* MDNSAdvertiser.BONJOUR */ : "ciao" /* MDNSAdvertiser.CIAO */;
958
- console.warn("DEPRECATED The PublishInfo.useLegacyAdvertiser option has been removed. " +
959
- "Please use the PublishInfo.advertiser property to enable \"ciao\" (useLegacyAdvertiser=false) " +
960
- "or \"bonjour-hap\" (useLegacyAdvertiser=true) mdns advertiser libraries!");
961
- }
962
- // noinspection JSDeprecatedSymbols
963
- if (info.mdns && info.advertiser !== "bonjour-hap" /* MDNSAdvertiser.BONJOUR */) {
964
- console.log("DEPRECATED user supplied a custom 'mdns' option. This option is deprecated and ignored. " +
965
- "Please move to the new 'bind' option.");
966
- }
967
- service = this.getService(Service_1.Service.ProtocolInformation);
968
- if (!service) {
969
- service = this.addService(Service_1.Service.ProtocolInformation); // add the protocol information service to the primary accessory
970
- }
971
- service.setCharacteristic(Characteristic_1.Characteristic.Version, Advertiser_1.CiaoAdvertiser.protocolVersionService);
972
- if (this.lastKnownUsername && this.lastKnownUsername !== info.username) { // username changed since last publish
973
- Accessory.cleanupAccessoryData(this.lastKnownUsername); // delete old Accessory data
974
- }
975
- if (!this.initialized && ((_e = info.addIdentifyingMaterial) !== null && _e !== void 0 ? _e : true)) {
976
- // adding some identifying material to our displayName if it's our first publish() call
977
- this.displayName = this.displayName + " " + crypto_1.default.createHash("sha512")
978
- .update(info.username, "utf8")
979
- .digest("hex").slice(0, 4).toUpperCase();
980
- this.getService(Service_1.Service.AccessoryInformation).updateCharacteristic(Characteristic_1.Characteristic.Name, this.displayName);
981
- }
982
- // attempt to load existing AccessoryInfo from disk
983
- this._accessoryInfo = AccessoryInfo_1.AccessoryInfo.load(info.username);
984
- // if we don't have one, create a new one.
985
- if (!this._accessoryInfo) {
986
- debug("[%s] Creating new AccessoryInfo for our HAP server", this.displayName);
987
- this._accessoryInfo = AccessoryInfo_1.AccessoryInfo.create(info.username);
988
- }
989
- if (info.setupID) {
990
- this._setupID = info.setupID;
991
- }
992
- else if (this._accessoryInfo.setupID === undefined || this._accessoryInfo.setupID === "") {
993
- this._setupID = Accessory._generateSetupID();
994
- }
995
- else {
996
- this._setupID = this._accessoryInfo.setupID;
997
- }
998
- this._accessoryInfo.setupID = this._setupID;
999
- // make sure we have up-to-date values in AccessoryInfo, then save it in case they changed (or if we just created it)
1000
- this._accessoryInfo.displayName = this.displayName;
1001
- this._accessoryInfo.model = this.getService(Service_1.Service.AccessoryInformation).getCharacteristic(Characteristic_1.Characteristic.Model).value;
1002
- this._accessoryInfo.category = info.category || 1 /* Categories.OTHER */;
1003
- this._accessoryInfo.pincode = info.pincode;
1004
- this._accessoryInfo.save();
1005
- // create our IdentifierCache, so we can provide clients with stable aid/iid's
1006
- this._identifierCache = IdentifierCache_1.IdentifierCache.load(info.username);
1007
- // if we don't have one, create a new one.
1008
- if (!this._identifierCache) {
1009
- debug("[%s] Creating new IdentifierCache", this.displayName);
1010
- this._identifierCache = new IdentifierCache_1.IdentifierCache(info.username);
1011
- }
1012
- // If it's bridge and there are no accessories already assigned to the bridge
1013
- // probably purge is not needed since it's going to delete all the ids
1014
- // of accessories that might be added later. Useful when dynamically adding
1015
- // accessories.
1016
- if (this._isBridge && this.bridgedAccessories.length === 0) {
1017
- this.disableUnusedIDPurge();
1018
- this.controllerStorage.purgeUnidentifiedAccessoryData = false;
1019
- }
1020
- if (!this.initialized) { // controller storage is only loaded from disk the first time we publish!
1021
- this.controllerStorage.load(info.username); // initializing controller data
1022
- }
1023
- // assign aid/iid
1024
- this._assignIDs(this._identifierCache);
1025
- config = this.internalHAPRepresentation(false);
1026
- // TODO queue this check until about 5 seconds after startup, allowing some last changes after the publish call
1027
- // without constantly incrementing the current config number
1028
- this._accessoryInfo.checkForCurrentConfigurationNumberIncrement(config, true);
1029
- this.validateAccessory(true);
1030
- parsed = Accessory.parseBindOption(info);
1031
- selectedAdvertiser = (_f = info.advertiser) !== null && _f !== void 0 ? _f : "bonjour-hap" /* MDNSAdvertiser.BONJOUR */;
1032
- _b = info.advertiser === "avahi" /* MDNSAdvertiser.AVAHI */;
1033
- if (!_b) return [3 /*break*/, 2];
1034
- return [4 /*yield*/, Advertiser_1.AvahiAdvertiser.isAvailable()];
1035
- case 1:
1036
- _b = !(_g.sent());
1037
- _g.label = 2;
1038
- case 2:
1039
- _a = (_b);
1040
- if (_a) return [3 /*break*/, 5];
1041
- _c = info.advertiser === "resolved" /* MDNSAdvertiser.RESOLVED */;
1042
- if (!_c) return [3 /*break*/, 4];
1043
- return [4 /*yield*/, Advertiser_1.ResolvedAdvertiser.isAvailable()];
1044
- case 3:
1045
- _c = !(_g.sent());
1046
- _g.label = 4;
1047
- case 4:
1048
- _a = (_c);
1049
- _g.label = 5;
1050
- case 5:
1051
- if (_a) {
1052
- console.error("[".concat(this.displayName, "] The selected advertiser, \"").concat(info.advertiser, "\", isn't available on this platform. ") +
1053
- "Reverting to \"".concat("bonjour-hap" /* MDNSAdvertiser.BONJOUR */, "\""));
1054
- selectedAdvertiser = "bonjour-hap" /* MDNSAdvertiser.BONJOUR */;
1055
- }
1056
- switch (selectedAdvertiser) {
1057
- case "ciao" /* MDNSAdvertiser.CIAO */:
1058
- this._advertiser = new Advertiser_1.CiaoAdvertiser(this._accessoryInfo, {
1059
- interface: parsed.advertiserAddress,
1060
- }, {
1061
- restrictedAddresses: parsed.serviceRestrictedAddress,
1062
- disabledIpv6: parsed.serviceDisableIpv6,
1063
- });
1064
- break;
1065
- case "bonjour-hap" /* MDNSAdvertiser.BONJOUR */:
1066
- // noinspection JSDeprecatedSymbols
1067
- this._advertiser = new Advertiser_1.BonjourHAPAdvertiser(this._accessoryInfo, info.mdns, {
1068
- restrictedAddresses: parsed.serviceRestrictedAddress,
1069
- disabledIpv6: parsed.serviceDisableIpv6,
1070
- });
1071
- break;
1072
- case "avahi" /* MDNSAdvertiser.AVAHI */:
1073
- this._advertiser = new Advertiser_1.AvahiAdvertiser(this._accessoryInfo);
1074
- break;
1075
- case "resolved" /* MDNSAdvertiser.RESOLVED */:
1076
- this._advertiser = new Advertiser_1.ResolvedAdvertiser(this._accessoryInfo);
1077
- break;
1078
- default:
1079
- throw new Error("Unsupported advertiser setting: '" + info.advertiser + "'");
1080
- }
1081
- this._advertiser.on("updated-name" /* AdvertiserEvent.UPDATED_NAME */, function (name) {
1082
- _this.displayName = name;
1083
- if (_this._accessoryInfo) {
1084
- _this._accessoryInfo.displayName = name;
1085
- _this._accessoryInfo.save();
1086
- }
1087
- // bonjour service name MUST match the name in the accessory information service
1088
- _this.getService(Service_1.Service.AccessoryInformation)
1089
- .updateCharacteristic(Characteristic_1.Characteristic.Name, name);
1090
- });
1091
- // create our HAP server which handles all communication between iOS devices and us
1092
- this._server = new HAPServer_1.HAPServer(this._accessoryInfo);
1093
- this._server.allowInsecureRequest = !!allowInsecureRequest;
1094
- this._server.on("listening" /* HAPServerEventTypes.LISTENING */, this.onListening.bind(this));
1095
- this._server.on("identify" /* HAPServerEventTypes.IDENTIFY */, this.identificationRequest.bind(this, false));
1096
- this._server.on("pair" /* HAPServerEventTypes.PAIR */, this.handleInitialPairSetupFinished.bind(this));
1097
- this._server.on("add-pairing" /* HAPServerEventTypes.ADD_PAIRING */, this.handleAddPairing.bind(this));
1098
- this._server.on("remove-pairing" /* HAPServerEventTypes.REMOVE_PAIRING */, this.handleRemovePairing.bind(this));
1099
- this._server.on("list-pairings" /* HAPServerEventTypes.LIST_PAIRINGS */, this.handleListPairings.bind(this));
1100
- this._server.on("accessories" /* HAPServerEventTypes.ACCESSORIES */, this.handleAccessories.bind(this));
1101
- this._server.on("get-characteristics" /* HAPServerEventTypes.GET_CHARACTERISTICS */, this.handleGetCharacteristics.bind(this));
1102
- this._server.on("set-characteristics" /* HAPServerEventTypes.SET_CHARACTERISTICS */, this.handleSetCharacteristics.bind(this));
1103
- this._server.on("connection-closed" /* HAPServerEventTypes.CONNECTION_CLOSED */, this.handleHAPConnectionClosed.bind(this));
1104
- this._server.on("request-resource" /* HAPServerEventTypes.REQUEST_RESOURCE */, this.handleResource.bind(this));
1105
- this._server.listen(info.port, parsed.serverAddress);
1106
- this.initialized = true;
1107
- return [2 /*return*/];
1108
- }
1109
- });
827
+ async publish(info, allowInsecureRequest) {
828
+ if (this.bridged) {
829
+ throw new Error("Can't publish in accessory which is bridged by another accessory. Bridged by " + this.bridge?.displayName);
830
+ }
831
+ // noinspection JSDeprecatedSymbols
832
+ if (!info.advertiser && info.useLegacyAdvertiser != null) {
833
+ // noinspection JSDeprecatedSymbols
834
+ info.advertiser = info.useLegacyAdvertiser ? "bonjour-hap" /* MDNSAdvertiser.BONJOUR */ : "ciao" /* MDNSAdvertiser.CIAO */;
835
+ console.warn("DEPRECATED The PublishInfo.useLegacyAdvertiser option has been removed. " +
836
+ "Please use the PublishInfo.advertiser property to enable \"ciao\" (useLegacyAdvertiser=false) " +
837
+ "or \"bonjour-hap\" (useLegacyAdvertiser=true) mdns advertiser libraries!");
838
+ }
839
+ // noinspection JSDeprecatedSymbols
840
+ if (info.mdns && info.advertiser !== "bonjour-hap" /* MDNSAdvertiser.BONJOUR */) {
841
+ console.log("DEPRECATED user supplied a custom 'mdns' option. This option is deprecated and ignored. " +
842
+ "Please move to the new 'bind' option.");
843
+ }
844
+ let service = this.getService(Service_1.Service.ProtocolInformation);
845
+ if (!service) {
846
+ service = this.addService(Service_1.Service.ProtocolInformation); // add the protocol information service to the primary accessory
847
+ }
848
+ service.setCharacteristic(Characteristic_1.Characteristic.Version, Advertiser_1.CiaoAdvertiser.protocolVersionService);
849
+ if (this.lastKnownUsername && this.lastKnownUsername !== info.username) { // username changed since last publish
850
+ Accessory.cleanupAccessoryData(this.lastKnownUsername); // delete old Accessory data
851
+ }
852
+ if (!this.initialized && (info.addIdentifyingMaterial ?? true)) {
853
+ // adding some identifying material to our displayName if it's our first publish() call
854
+ this.displayName = this.displayName + " " + crypto_1.default.createHash("sha512")
855
+ .update(info.username, "utf8")
856
+ .digest("hex").slice(0, 4).toUpperCase();
857
+ this.getService(Service_1.Service.AccessoryInformation).updateCharacteristic(Characteristic_1.Characteristic.Name, this.displayName);
858
+ }
859
+ // attempt to load existing AccessoryInfo from disk
860
+ this._accessoryInfo = AccessoryInfo_1.AccessoryInfo.load(info.username);
861
+ // if we don't have one, create a new one.
862
+ if (!this._accessoryInfo) {
863
+ debug("[%s] Creating new AccessoryInfo for our HAP server", this.displayName);
864
+ this._accessoryInfo = AccessoryInfo_1.AccessoryInfo.create(info.username);
865
+ }
866
+ if (info.setupID) {
867
+ this._setupID = info.setupID;
868
+ }
869
+ else if (this._accessoryInfo.setupID === undefined || this._accessoryInfo.setupID === "") {
870
+ this._setupID = Accessory._generateSetupID();
871
+ }
872
+ else {
873
+ this._setupID = this._accessoryInfo.setupID;
874
+ }
875
+ this._accessoryInfo.setupID = this._setupID;
876
+ // make sure we have up-to-date values in AccessoryInfo, then save it in case they changed (or if we just created it)
877
+ this._accessoryInfo.displayName = this.displayName;
878
+ this._accessoryInfo.model = this.getService(Service_1.Service.AccessoryInformation).getCharacteristic(Characteristic_1.Characteristic.Model).value;
879
+ this._accessoryInfo.category = info.category || 1 /* Categories.OTHER */;
880
+ this._accessoryInfo.pincode = info.pincode;
881
+ this._accessoryInfo.save();
882
+ // create our IdentifierCache, so we can provide clients with stable aid/iid's
883
+ this._identifierCache = IdentifierCache_1.IdentifierCache.load(info.username);
884
+ // if we don't have one, create a new one.
885
+ if (!this._identifierCache) {
886
+ debug("[%s] Creating new IdentifierCache", this.displayName);
887
+ this._identifierCache = new IdentifierCache_1.IdentifierCache(info.username);
888
+ }
889
+ // If it's bridge and there are no accessories already assigned to the bridge
890
+ // probably purge is not needed since it's going to delete all the ids
891
+ // of accessories that might be added later. Useful when dynamically adding
892
+ // accessories.
893
+ if (this._isBridge && this.bridgedAccessories.length === 0) {
894
+ this.disableUnusedIDPurge();
895
+ this.controllerStorage.purgeUnidentifiedAccessoryData = false;
896
+ }
897
+ if (!this.initialized) { // controller storage is only loaded from disk the first time we publish!
898
+ this.controllerStorage.load(info.username); // initializing controller data
899
+ }
900
+ // assign aid/iid
901
+ this._assignIDs(this._identifierCache);
902
+ // get our accessory information in HAP format and determine if our configuration (that is, our
903
+ // Accessories/Services/Characteristics) has changed since the last time we were published. make
904
+ // sure to omit actual values since these are not part of the "configuration".
905
+ const config = this.internalHAPRepresentation(false); // TODO ensure this stuff is ordered
906
+ // TODO queue this check until about 5 seconds after startup, allowing some last changes after the publish call
907
+ // without constantly incrementing the current config number
908
+ this._accessoryInfo.checkForCurrentConfigurationNumberIncrement(config, true);
909
+ this.validateAccessory(true);
910
+ // create our Advertiser which broadcasts our presence over mdns
911
+ const parsed = Accessory.parseBindOption(info);
912
+ let selectedAdvertiser = info.advertiser ?? "bonjour-hap" /* MDNSAdvertiser.BONJOUR */;
913
+ if ((info.advertiser === "avahi" /* MDNSAdvertiser.AVAHI */ && !await Advertiser_1.AvahiAdvertiser.isAvailable()) ||
914
+ (info.advertiser === "resolved" /* MDNSAdvertiser.RESOLVED */ && !await Advertiser_1.ResolvedAdvertiser.isAvailable())) {
915
+ console.error(`[${this.displayName}] The selected advertiser, "${info.advertiser}", isn't available on this platform. ` +
916
+ `Reverting to "${"bonjour-hap" /* MDNSAdvertiser.BONJOUR */}"`);
917
+ selectedAdvertiser = "bonjour-hap" /* MDNSAdvertiser.BONJOUR */;
918
+ }
919
+ switch (selectedAdvertiser) {
920
+ case "ciao" /* MDNSAdvertiser.CIAO */:
921
+ this._advertiser = new Advertiser_1.CiaoAdvertiser(this._accessoryInfo, {
922
+ interface: parsed.advertiserAddress,
923
+ }, {
924
+ restrictedAddresses: parsed.serviceRestrictedAddress,
925
+ disabledIpv6: parsed.serviceDisableIpv6,
926
+ });
927
+ break;
928
+ case "bonjour-hap" /* MDNSAdvertiser.BONJOUR */:
929
+ // noinspection JSDeprecatedSymbols
930
+ this._advertiser = new Advertiser_1.BonjourHAPAdvertiser(this._accessoryInfo, info.mdns, {
931
+ restrictedAddresses: parsed.serviceRestrictedAddress,
932
+ disabledIpv6: parsed.serviceDisableIpv6,
933
+ });
934
+ break;
935
+ case "avahi" /* MDNSAdvertiser.AVAHI */:
936
+ this._advertiser = new Advertiser_1.AvahiAdvertiser(this._accessoryInfo);
937
+ break;
938
+ case "resolved" /* MDNSAdvertiser.RESOLVED */:
939
+ this._advertiser = new Advertiser_1.ResolvedAdvertiser(this._accessoryInfo);
940
+ break;
941
+ default:
942
+ throw new Error("Unsupported advertiser setting: '" + info.advertiser + "'");
943
+ }
944
+ this._advertiser.on("updated-name" /* AdvertiserEvent.UPDATED_NAME */, name => {
945
+ this.displayName = name;
946
+ if (this._accessoryInfo) {
947
+ this._accessoryInfo.displayName = name;
948
+ this._accessoryInfo.save();
949
+ }
950
+ // bonjour service name MUST match the name in the accessory information service
951
+ this.getService(Service_1.Service.AccessoryInformation)
952
+ .updateCharacteristic(Characteristic_1.Characteristic.Name, name);
1110
953
  });
1111
- };
954
+ // create our HAP server which handles all communication between iOS devices and us
955
+ this._server = new HAPServer_1.HAPServer(this._accessoryInfo);
956
+ this._server.allowInsecureRequest = !!allowInsecureRequest;
957
+ this._server.on("listening" /* HAPServerEventTypes.LISTENING */, this.onListening.bind(this));
958
+ this._server.on("identify" /* HAPServerEventTypes.IDENTIFY */, this.identificationRequest.bind(this, false));
959
+ this._server.on("pair" /* HAPServerEventTypes.PAIR */, this.handleInitialPairSetupFinished.bind(this));
960
+ this._server.on("add-pairing" /* HAPServerEventTypes.ADD_PAIRING */, this.handleAddPairing.bind(this));
961
+ this._server.on("remove-pairing" /* HAPServerEventTypes.REMOVE_PAIRING */, this.handleRemovePairing.bind(this));
962
+ this._server.on("list-pairings" /* HAPServerEventTypes.LIST_PAIRINGS */, this.handleListPairings.bind(this));
963
+ this._server.on("accessories" /* HAPServerEventTypes.ACCESSORIES */, this.handleAccessories.bind(this));
964
+ this._server.on("get-characteristics" /* HAPServerEventTypes.GET_CHARACTERISTICS */, this.handleGetCharacteristics.bind(this));
965
+ this._server.on("set-characteristics" /* HAPServerEventTypes.SET_CHARACTERISTICS */, this.handleSetCharacteristics.bind(this));
966
+ this._server.on("connection-closed" /* HAPServerEventTypes.CONNECTION_CLOSED */, this.handleHAPConnectionClosed.bind(this));
967
+ this._server.on("request-resource" /* HAPServerEventTypes.REQUEST_RESOURCE */, this.handleResource.bind(this));
968
+ this._server.listen(info.port, parsed.serverAddress);
969
+ this.initialized = true;
970
+ }
1112
971
  /**
1113
972
  * Removes this Accessory from the local network
1114
973
  * Accessory object will no longer valid after invoking this method
1115
974
  * Trying to invoke publish() on the object will result undefined behavior
1116
975
  */
1117
- Accessory.prototype.destroy = function () {
1118
- var promise = this.unpublish();
976
+ destroy() {
977
+ const promise = this.unpublish();
1119
978
  if (this._accessoryInfo) {
1120
979
  Accessory.cleanupAccessoryData(this._accessoryInfo.username);
1121
980
  this._accessoryInfo = undefined;
@@ -1124,44 +983,31 @@ var Accessory = /** @class */ (function (_super) {
1124
983
  }
1125
984
  this.removeAllListeners();
1126
985
  return promise;
1127
- };
1128
- Accessory.prototype.unpublish = function () {
1129
- return tslib_1.__awaiter(this, void 0, void 0, function () {
1130
- return tslib_1.__generator(this, function (_a) {
1131
- switch (_a.label) {
1132
- case 0:
1133
- if (this._server) {
1134
- this._server.destroy();
1135
- this._server = undefined;
1136
- }
1137
- if (!this._advertiser) return [3 /*break*/, 2];
1138
- // noinspection JSIgnoredPromiseFromCall
1139
- return [4 /*yield*/, this._advertiser.destroy()];
1140
- case 1:
1141
- // noinspection JSIgnoredPromiseFromCall
1142
- _a.sent();
1143
- this._advertiser = undefined;
1144
- _a.label = 2;
1145
- case 2: return [2 /*return*/];
1146
- }
1147
- });
1148
- });
1149
- };
1150
- Accessory.prototype.enqueueConfigurationUpdate = function () {
1151
- var _this = this;
986
+ }
987
+ async unpublish() {
988
+ if (this._server) {
989
+ this._server.destroy();
990
+ this._server = undefined;
991
+ }
992
+ if (this._advertiser) {
993
+ // noinspection JSIgnoredPromiseFromCall
994
+ await this._advertiser.destroy();
995
+ this._advertiser = undefined;
996
+ }
997
+ }
998
+ enqueueConfigurationUpdate() {
1152
999
  if (this.configurationChangeDebounceTimeout) {
1153
1000
  return; // already enqueued
1154
1001
  }
1155
- this.configurationChangeDebounceTimeout = setTimeout(function () {
1156
- var _a;
1157
- _this.configurationChangeDebounceTimeout = undefined;
1158
- if (_this._advertiser && _this._advertiser) {
1002
+ this.configurationChangeDebounceTimeout = setTimeout(() => {
1003
+ this.configurationChangeDebounceTimeout = undefined;
1004
+ if (this._advertiser && this._advertiser) {
1159
1005
  // get our accessory information in HAP format and determine if our configuration (that is, our
1160
1006
  // Accessories/Services/Characteristics) has changed since the last time we were published. make
1161
1007
  // sure to omit actual values since these are not part of the "configuration".
1162
- var config = _this.internalHAPRepresentation(); // TODO ensure this stuff is ordered
1163
- if ((_a = _this._accessoryInfo) === null || _a === void 0 ? void 0 : _a.checkForCurrentConfigurationNumberIncrement(config)) {
1164
- _this._advertiser.updateAdvertisement();
1008
+ const config = this.internalHAPRepresentation(); // TODO ensure this stuff is ordered
1009
+ if (this._accessoryInfo?.checkForCurrentConfigurationNumberIncrement(config)) {
1010
+ this._advertiser.updateAdvertisement();
1165
1011
  }
1166
1012
  }
1167
1013
  }, 1000);
@@ -1169,23 +1015,22 @@ var Accessory = /** @class */ (function (_super) {
1169
1015
  // 1s is fine, HomeKit is built that with configuration updates no iid or aid conflicts occur.
1170
1016
  // Thus, the only thing happening when the txt update arrives late is already removed accessories/services
1171
1017
  // not responding or new accessories/services not yet shown
1172
- };
1173
- Accessory.prototype.onListening = function (port, hostname) {
1174
- var _this = this;
1018
+ }
1019
+ onListening(port, hostname) {
1175
1020
  (0, assert_1.default)(this._advertiser, "Advertiser wasn't created at onListening!");
1176
1021
  // the HAP server is listening, so we can now start advertising our presence.
1177
1022
  this._advertiser.initPort(port);
1178
1023
  this._advertiser.startAdvertising()
1179
- .then(function () { return _this.emit("advertised" /* AccessoryEventTypes.ADVERTISED */); })
1180
- .catch(function (reason) {
1024
+ .then(() => this.emit("advertised" /* AccessoryEventTypes.ADVERTISED */))
1025
+ .catch(reason => {
1181
1026
  console.error("Could not create mDNS advertisement. The HAP-Server won't be discoverable: " + reason);
1182
1027
  if (reason.stack) {
1183
1028
  debug("Detailed error: " + reason.stack);
1184
1029
  }
1185
1030
  });
1186
1031
  this.emit("listening" /* AccessoryEventTypes.LISTENING */, port, hostname);
1187
- };
1188
- Accessory.prototype.handleInitialPairSetupFinished = function (username, publicKey, callback) {
1032
+ }
1033
+ handleInitialPairSetupFinished(username, publicKey, callback) {
1189
1034
  debug("[%s] Paired with client %s", this.displayName, username);
1190
1035
  this._accessoryInfo && this._accessoryInfo.addPairedClient(username, publicKey, 1 /* PermissionTypes.ADMIN */);
1191
1036
  this._accessoryInfo && this._accessoryInfo.save();
@@ -1193,8 +1038,8 @@ var Accessory = /** @class */ (function (_super) {
1193
1038
  this._advertiser && this._advertiser.updateAdvertisement();
1194
1039
  callback();
1195
1040
  this.emit("paired" /* AccessoryEventTypes.PAIRED */);
1196
- };
1197
- Accessory.prototype.handleAddPairing = function (connection, username, publicKey, permission, callback) {
1041
+ }
1042
+ handleAddPairing(connection, username, publicKey, permission, callback) {
1198
1043
  if (!this._accessoryInfo) {
1199
1044
  callback(6 /* TLVErrorCode.UNAVAILABLE */);
1200
1045
  return;
@@ -1203,7 +1048,7 @@ var Accessory = /** @class */ (function (_super) {
1203
1048
  callback(2 /* TLVErrorCode.AUTHENTICATION */);
1204
1049
  return;
1205
1050
  }
1206
- var existingKey = this._accessoryInfo.getClientPublicKey(username);
1051
+ const existingKey = this._accessoryInfo.getClientPublicKey(username);
1207
1052
  if (existingKey) {
1208
1053
  if (existingKey.toString() !== publicKey.toString()) {
1209
1054
  callback(1 /* TLVErrorCode.UNKNOWN */);
@@ -1217,9 +1062,8 @@ var Accessory = /** @class */ (function (_super) {
1217
1062
  this._accessoryInfo.save();
1218
1063
  // there should be no need to update advertisement
1219
1064
  callback(0);
1220
- };
1221
- Accessory.prototype.handleRemovePairing = function (connection, username, callback) {
1222
- var e_12, _a;
1065
+ }
1066
+ handleRemovePairing(connection, username, callback) {
1223
1067
  if (!this._accessoryInfo) {
1224
1068
  callback(6 /* TLVErrorCode.UNAVAILABLE */);
1225
1069
  return;
@@ -1235,22 +1079,12 @@ var Accessory = /** @class */ (function (_super) {
1235
1079
  this._advertiser && this._advertiser.updateAdvertisement();
1236
1080
  this.emit("unpaired" /* AccessoryEventTypes.UNPAIRED */);
1237
1081
  this.handleAccessoryUnpairedForControllers();
1238
- try {
1239
- for (var _b = tslib_1.__values(this.bridgedAccessories), _c = _b.next(); !_c.done; _c = _b.next()) {
1240
- var accessory = _c.value;
1241
- accessory.handleAccessoryUnpairedForControllers();
1242
- }
1243
- }
1244
- catch (e_12_1) { e_12 = { error: e_12_1 }; }
1245
- finally {
1246
- try {
1247
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1248
- }
1249
- finally { if (e_12) throw e_12.error; }
1082
+ for (const accessory of this.bridgedAccessories) {
1083
+ accessory.handleAccessoryUnpairedForControllers();
1250
1084
  }
1251
1085
  }
1252
- };
1253
- Accessory.prototype.handleListPairings = function (connection, callback) {
1086
+ }
1087
+ handleListPairings(connection, callback) {
1254
1088
  if (!this._accessoryInfo) {
1255
1089
  callback(6 /* TLVErrorCode.UNAVAILABLE */);
1256
1090
  return;
@@ -1260,82 +1094,57 @@ var Accessory = /** @class */ (function (_super) {
1260
1094
  return;
1261
1095
  }
1262
1096
  callback(0, this._accessoryInfo.listPairings());
1263
- };
1264
- Accessory.prototype.handleAccessories = function (connection, callback) {
1265
- var _this = this;
1097
+ }
1098
+ handleAccessories(connection, callback) {
1266
1099
  this._assignIDs(this._identifierCache); // make sure our aid/iid's are all assigned
1267
- var now = Date.now();
1268
- var contactGetHandlers = now - this.lastAccessoriesRequest > 5000; // we query the latest value if last /accessories was more than 5s ago
1100
+ const now = Date.now();
1101
+ const contactGetHandlers = now - this.lastAccessoriesRequest > 5_000; // we query the latest value if last /accessories was more than 5s ago
1269
1102
  this.lastAccessoriesRequest = now;
1270
- this.toHAP(connection, contactGetHandlers).then(function (value) {
1103
+ this.toHAP(connection, contactGetHandlers).then(value => {
1271
1104
  callback(undefined, {
1272
1105
  accessories: value,
1273
1106
  });
1274
- }, function (reason) {
1275
- console.error("[" + _this.displayName + "] /accessories request error with: " + reason.stack);
1107
+ }, reason => {
1108
+ console.error("[" + this.displayName + "] /accessories request error with: " + reason.stack);
1276
1109
  callback({ httpCode: 500 /* HAPHTTPCode.INTERNAL_SERVER_ERROR */, status: -70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */ });
1277
1110
  });
1278
- };
1279
- Accessory.prototype.handleGetCharacteristics = function (connection, request, callback) {
1280
- var e_13, _a;
1281
- var _this = this;
1282
- var characteristics = [];
1283
- var response = { characteristics: characteristics };
1284
- var missingCharacteristics = new Set(request.ids.map(function (id) { return id.aid + "." + id.iid; }));
1111
+ }
1112
+ handleGetCharacteristics(connection, request, callback) {
1113
+ const characteristics = [];
1114
+ const response = { characteristics: characteristics };
1115
+ const missingCharacteristics = new Set(request.ids.map(id => id.aid + "." + id.iid));
1285
1116
  if (missingCharacteristics.size !== request.ids.length) {
1286
1117
  // if those sizes differ, we have duplicates and can't properly handle that
1287
1118
  callback({ httpCode: 422 /* HAPHTTPCode.UNPROCESSABLE_ENTITY */, status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ });
1288
1119
  return;
1289
1120
  }
1290
- var timeout = setTimeout(function () {
1291
- var e_14, _a;
1292
- try {
1293
- for (var missingCharacteristics_1 = tslib_1.__values(missingCharacteristics), missingCharacteristics_1_1 = missingCharacteristics_1.next(); !missingCharacteristics_1_1.done; missingCharacteristics_1_1 = missingCharacteristics_1.next()) {
1294
- var id = missingCharacteristics_1_1.value;
1295
- var split = id.split(".");
1296
- var aid = parseInt(split[0], 10);
1297
- var iid = parseInt(split[1], 10);
1298
- var accessory = _this.getAccessoryByAID(aid);
1299
- var characteristic = accessory.getCharacteristicByIID(iid);
1300
- _this.sendCharacteristicWarning(characteristic, "slow-read" /* CharacteristicWarningType.SLOW_READ */, "The read handler for the characteristic '" +
1301
- characteristic.displayName + "' on the accessory '" + accessory.displayName + "' was slow to respond!");
1302
- }
1303
- }
1304
- catch (e_14_1) { e_14 = { error: e_14_1 }; }
1305
- finally {
1306
- try {
1307
- if (missingCharacteristics_1_1 && !missingCharacteristics_1_1.done && (_a = missingCharacteristics_1.return)) _a.call(missingCharacteristics_1);
1308
- }
1309
- finally { if (e_14) throw e_14.error; }
1121
+ let timeout = setTimeout(() => {
1122
+ for (const id of missingCharacteristics) {
1123
+ const split = id.split(".");
1124
+ const aid = parseInt(split[0], 10);
1125
+ const iid = parseInt(split[1], 10);
1126
+ const accessory = this.getAccessoryByAID(aid);
1127
+ const characteristic = accessory.getCharacteristicByIID(iid);
1128
+ this.sendCharacteristicWarning(characteristic, "slow-read" /* CharacteristicWarningType.SLOW_READ */, "The read handler for the characteristic '" +
1129
+ characteristic.displayName + "' on the accessory '" + accessory.displayName + "' was slow to respond!");
1310
1130
  }
1311
1131
  // after a total of 10s we do no longer wait for a request to appear and just return status code timeout
1312
- timeout = setTimeout(function () {
1313
- var e_15, _a;
1132
+ timeout = setTimeout(() => {
1314
1133
  timeout = undefined;
1315
- try {
1316
- for (var missingCharacteristics_2 = tslib_1.__values(missingCharacteristics), missingCharacteristics_2_1 = missingCharacteristics_2.next(); !missingCharacteristics_2_1.done; missingCharacteristics_2_1 = missingCharacteristics_2.next()) {
1317
- var id = missingCharacteristics_2_1.value;
1318
- var split = id.split(".");
1319
- var aid = parseInt(split[0], 10);
1320
- var iid = parseInt(split[1], 10);
1321
- var accessory = _this.getAccessoryByAID(aid);
1322
- var characteristic = accessory.getCharacteristicByIID(iid);
1323
- _this.sendCharacteristicWarning(characteristic, "timeout-read" /* CharacteristicWarningType.TIMEOUT_READ */, "The read handler for the characteristic '" +
1324
- characteristic.displayName + "' on the accessory '" + accessory.displayName + "' didn't respond at all!. " +
1325
- "Please check that you properly call the callback!");
1326
- characteristics.push({
1327
- aid: aid,
1328
- iid: iid,
1329
- status: -70408 /* HAPStatus.OPERATION_TIMED_OUT */,
1330
- });
1331
- }
1332
- }
1333
- catch (e_15_1) { e_15 = { error: e_15_1 }; }
1334
- finally {
1335
- try {
1336
- if (missingCharacteristics_2_1 && !missingCharacteristics_2_1.done && (_a = missingCharacteristics_2.return)) _a.call(missingCharacteristics_2);
1337
- }
1338
- finally { if (e_15) throw e_15.error; }
1134
+ for (const id of missingCharacteristics) {
1135
+ const split = id.split(".");
1136
+ const aid = parseInt(split[0], 10);
1137
+ const iid = parseInt(split[1], 10);
1138
+ const accessory = this.getAccessoryByAID(aid);
1139
+ const characteristic = accessory.getCharacteristicByIID(iid);
1140
+ this.sendCharacteristicWarning(characteristic, "timeout-read" /* CharacteristicWarningType.TIMEOUT_READ */, "The read handler for the characteristic '" +
1141
+ characteristic.displayName + "' on the accessory '" + accessory.displayName + "' didn't respond at all!. " +
1142
+ "Please check that you properly call the callback!");
1143
+ characteristics.push({
1144
+ aid: aid,
1145
+ iid: iid,
1146
+ status: -70408 /* HAPStatus.OPERATION_TIMED_OUT */,
1147
+ });
1339
1148
  }
1340
1149
  missingCharacteristics.clear();
1341
1150
  callback(undefined, response);
@@ -1343,18 +1152,22 @@ var Accessory = /** @class */ (function (_super) {
1343
1152
  timeout.unref();
1344
1153
  }, Accessory.TIMEOUT_WARNING);
1345
1154
  timeout.unref();
1346
- var _loop_1 = function (id) {
1347
- var name = id.aid + "." + id.iid;
1348
- this_1.handleCharacteristicRead(connection, id, request).then(function (value) {
1349
- return tslib_1.__assign({ aid: id.aid, iid: id.iid }, value);
1350
- }, function (reason) {
1351
- console.error("[".concat(_this.displayName, "] Read request for characteristic ").concat(name, " encountered an error: ").concat(reason.stack));
1155
+ for (const id of request.ids) {
1156
+ const name = id.aid + "." + id.iid;
1157
+ this.handleCharacteristicRead(connection, id, request).then(value => {
1158
+ return {
1159
+ aid: id.aid,
1160
+ iid: id.iid,
1161
+ ...value,
1162
+ };
1163
+ }, reason => {
1164
+ console.error(`[${this.displayName}] Read request for characteristic ${name} encountered an error: ${reason.stack}`);
1352
1165
  return {
1353
1166
  aid: id.aid,
1354
1167
  iid: id.iid,
1355
1168
  status: -70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */,
1356
1169
  };
1357
- }).then(function (value) {
1170
+ }).then(value => {
1358
1171
  if (!timeout) {
1359
1172
  return; // if timeout is undefined, response was already sent out
1360
1173
  }
@@ -1368,82 +1181,60 @@ var Accessory = /** @class */ (function (_super) {
1368
1181
  callback(undefined, response);
1369
1182
  }
1370
1183
  });
1371
- };
1372
- var this_1 = this;
1373
- try {
1374
- for (var _b = tslib_1.__values(request.ids), _c = _b.next(); !_c.done; _c = _b.next()) {
1375
- var id = _c.value;
1376
- _loop_1(id);
1377
- }
1378
1184
  }
1379
- catch (e_13_1) { e_13 = { error: e_13_1 }; }
1380
- finally {
1381
- try {
1382
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1383
- }
1384
- finally { if (e_13) throw e_13.error; }
1385
- }
1386
- };
1387
- Accessory.prototype.handleCharacteristicRead = function (connection, id, request) {
1388
- return tslib_1.__awaiter(this, void 0, void 0, function () {
1389
- var characteristic, verifiable;
1390
- var _this = this;
1391
- return tslib_1.__generator(this, function (_a) {
1392
- characteristic = this.findCharacteristic(id.aid, id.iid);
1393
- if (!characteristic) {
1394
- debug("[%s] Could not find a Characteristic with aid of %s and iid of %s", this.displayName, id.aid, id.iid);
1395
- return [2 /*return*/, { status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }];
1396
- }
1397
- if (!characteristic.props.perms.includes("pr" /* Perms.PAIRED_READ */)) { // check if read is allowed for this characteristic
1398
- debug("[%s] Tried reading from characteristic which does not allow reading (aid of %s and iid of %s)", this.displayName, id.aid, id.iid);
1399
- return [2 /*return*/, { status: -70405 /* HAPStatus.WRITE_ONLY_CHARACTERISTIC */ }];
1400
- }
1401
- if (characteristic.props.adminOnlyAccess && characteristic.props.adminOnlyAccess.includes(0 /* Access.READ */)) {
1402
- verifiable = this._accessoryInfo && connection.username;
1403
- if (!verifiable) {
1404
- debug("[%s] Could not verify admin permissions for Characteristic which requires admin permissions for reading (aid of %s and iid of %s)", this.displayName, id.aid, id.iid);
1405
- }
1406
- if (!verifiable || !this._accessoryInfo.hasAdminPermissions(connection.username)) {
1407
- return [2 /*return*/, { status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }];
1408
- }
1409
- }
1410
- return [2 /*return*/, characteristic.handleGetRequest(connection).then(function (value) {
1411
- value = (0, request_util_1.formatOutgoingCharacteristicValue)(value, characteristic.props);
1412
- debug("[%s] Got Characteristic \"%s\" value: \"%s\"", _this.displayName, characteristic.displayName, value);
1413
- var data = {
1414
- value: value == null ? null : value,
1415
- };
1416
- if (request.includeMeta) {
1417
- data.format = characteristic.props.format;
1418
- data.unit = characteristic.props.unit;
1419
- data.minValue = characteristic.props.minValue;
1420
- data.maxValue = characteristic.props.maxValue;
1421
- data.minStep = characteristic.props.minStep;
1422
- data.maxLen = characteristic.props.maxLen || characteristic.props.maxDataLen;
1423
- }
1424
- if (request.includePerms) {
1425
- data.perms = characteristic.props.perms;
1426
- }
1427
- if (request.includeType) {
1428
- data.type = (0, uuid_1.toShortForm)(characteristic.UUID);
1429
- }
1430
- if (request.includeEvent) {
1431
- data.ev = connection.hasEventNotifications(id.aid, id.iid);
1432
- }
1433
- return data;
1434
- }, function (reason) {
1435
- // @ts-expect-error: preserveConstEnums compiler option
1436
- debug("[%s] Error getting value for characteristic \"%s\": %s", _this.displayName, characteristic.displayName, HAPServer_1.HAPStatus[reason]);
1437
- return { status: reason };
1438
- })];
1439
- });
1185
+ }
1186
+ async handleCharacteristicRead(connection, id, request) {
1187
+ const characteristic = this.findCharacteristic(id.aid, id.iid);
1188
+ if (!characteristic) {
1189
+ debug("[%s] Could not find a Characteristic with aid of %s and iid of %s", this.displayName, id.aid, id.iid);
1190
+ return { status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ };
1191
+ }
1192
+ if (!characteristic.props.perms.includes("pr" /* Perms.PAIRED_READ */)) { // check if read is allowed for this characteristic
1193
+ debug("[%s] Tried reading from characteristic which does not allow reading (aid of %s and iid of %s)", this.displayName, id.aid, id.iid);
1194
+ return { status: -70405 /* HAPStatus.WRITE_ONLY_CHARACTERISTIC */ };
1195
+ }
1196
+ if (characteristic.props.adminOnlyAccess && characteristic.props.adminOnlyAccess.includes(0 /* Access.READ */)) {
1197
+ const verifiable = this._accessoryInfo && connection.username;
1198
+ if (!verifiable) {
1199
+ debug("[%s] Could not verify admin permissions for Characteristic which requires admin permissions for reading (aid of %s and iid of %s)", this.displayName, id.aid, id.iid);
1200
+ }
1201
+ if (!verifiable || !this._accessoryInfo.hasAdminPermissions(connection.username)) {
1202
+ return { status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ };
1203
+ }
1204
+ }
1205
+ return characteristic.handleGetRequest(connection).then(value => {
1206
+ value = (0, request_util_1.formatOutgoingCharacteristicValue)(value, characteristic.props);
1207
+ debug("[%s] Got Characteristic \"%s\" value: \"%s\"", this.displayName, characteristic.displayName, value);
1208
+ const data = {
1209
+ value: value == null ? null : value,
1210
+ };
1211
+ if (request.includeMeta) {
1212
+ data.format = characteristic.props.format;
1213
+ data.unit = characteristic.props.unit;
1214
+ data.minValue = characteristic.props.minValue;
1215
+ data.maxValue = characteristic.props.maxValue;
1216
+ data.minStep = characteristic.props.minStep;
1217
+ data.maxLen = characteristic.props.maxLen || characteristic.props.maxDataLen;
1218
+ }
1219
+ if (request.includePerms) {
1220
+ data.perms = characteristic.props.perms;
1221
+ }
1222
+ if (request.includeType) {
1223
+ data.type = (0, uuid_1.toShortForm)(characteristic.UUID);
1224
+ }
1225
+ if (request.includeEvent) {
1226
+ data.ev = connection.hasEventNotifications(id.aid, id.iid);
1227
+ }
1228
+ return data;
1229
+ }, (reason) => {
1230
+ // @ts-expect-error: preserveConstEnums compiler option
1231
+ debug("[%s] Error getting value for characteristic \"%s\": %s", this.displayName, characteristic.displayName, HAPServer_1.HAPStatus[reason]);
1232
+ return { status: reason };
1440
1233
  });
1441
- };
1442
- Accessory.prototype.handleSetCharacteristics = function (connection, writeRequest, callback) {
1443
- var e_16, _a;
1444
- var _this = this;
1234
+ }
1235
+ handleSetCharacteristics(connection, writeRequest, callback) {
1445
1236
  debug("[%s] Processing characteristic set: %s", this.displayName, JSON.stringify(writeRequest));
1446
- var writeState = 0 /* WriteRequestState.REGULAR_REQUEST */;
1237
+ let writeState = 0 /* WriteRequestState.REGULAR_REQUEST */;
1447
1238
  if (writeRequest.pid !== undefined) { // check for timed writes
1448
1239
  if (connection.timedWritePid === writeRequest.pid) {
1449
1240
  writeState = 1 /* WriteRequestState.TIMED_WRITE_AUTHENTICATED */;
@@ -1457,64 +1248,42 @@ var Accessory = /** @class */ (function (_super) {
1457
1248
  debug("[%s] TTL for timed write request has probably expired for pid %d", this.displayName, writeRequest.pid);
1458
1249
  }
1459
1250
  }
1460
- var characteristics = [];
1461
- var response = { characteristics: characteristics };
1462
- var missingCharacteristics = new Set(writeRequest.characteristics
1463
- .map(function (characteristic) { return characteristic.aid + "." + characteristic.iid; }));
1251
+ const characteristics = [];
1252
+ const response = { characteristics: characteristics };
1253
+ const missingCharacteristics = new Set(writeRequest.characteristics
1254
+ .map(characteristic => characteristic.aid + "." + characteristic.iid));
1464
1255
  if (missingCharacteristics.size !== writeRequest.characteristics.length) {
1465
1256
  // if those sizes differ, we have duplicates and can't properly handle that
1466
1257
  callback({ httpCode: 422 /* HAPHTTPCode.UNPROCESSABLE_ENTITY */, status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ });
1467
1258
  return;
1468
1259
  }
1469
- var timeout = setTimeout(function () {
1470
- var e_17, _a;
1471
- try {
1472
- for (var missingCharacteristics_3 = tslib_1.__values(missingCharacteristics), missingCharacteristics_3_1 = missingCharacteristics_3.next(); !missingCharacteristics_3_1.done; missingCharacteristics_3_1 = missingCharacteristics_3.next()) {
1473
- var id = missingCharacteristics_3_1.value;
1474
- var split = id.split(".");
1475
- var aid = parseInt(split[0], 10);
1476
- var iid = parseInt(split[1], 10);
1477
- var accessory = _this.getAccessoryByAID(aid);
1478
- var characteristic = accessory.getCharacteristicByIID(iid);
1479
- _this.sendCharacteristicWarning(characteristic, "slow-write" /* CharacteristicWarningType.SLOW_WRITE */, "The write handler for the characteristic '" +
1480
- characteristic.displayName + "' on the accessory '" + accessory.displayName + "' was slow to respond!");
1481
- }
1482
- }
1483
- catch (e_17_1) { e_17 = { error: e_17_1 }; }
1484
- finally {
1485
- try {
1486
- if (missingCharacteristics_3_1 && !missingCharacteristics_3_1.done && (_a = missingCharacteristics_3.return)) _a.call(missingCharacteristics_3);
1487
- }
1488
- finally { if (e_17) throw e_17.error; }
1260
+ let timeout = setTimeout(() => {
1261
+ for (const id of missingCharacteristics) {
1262
+ const split = id.split(".");
1263
+ const aid = parseInt(split[0], 10);
1264
+ const iid = parseInt(split[1], 10);
1265
+ const accessory = this.getAccessoryByAID(aid);
1266
+ const characteristic = accessory.getCharacteristicByIID(iid);
1267
+ this.sendCharacteristicWarning(characteristic, "slow-write" /* CharacteristicWarningType.SLOW_WRITE */, "The write handler for the characteristic '" +
1268
+ characteristic.displayName + "' on the accessory '" + accessory.displayName + "' was slow to respond!");
1489
1269
  }
1490
1270
  // after a total of 10s we do no longer wait for a request to appear and just return status code timeout
1491
- timeout = setTimeout(function () {
1492
- var e_18, _a;
1271
+ timeout = setTimeout(() => {
1493
1272
  timeout = undefined;
1494
- try {
1495
- for (var missingCharacteristics_4 = tslib_1.__values(missingCharacteristics), missingCharacteristics_4_1 = missingCharacteristics_4.next(); !missingCharacteristics_4_1.done; missingCharacteristics_4_1 = missingCharacteristics_4.next()) {
1496
- var id = missingCharacteristics_4_1.value;
1497
- var split = id.split(".");
1498
- var aid = parseInt(split[0], 10);
1499
- var iid = parseInt(split[1], 10);
1500
- var accessory = _this.getAccessoryByAID(aid);
1501
- var characteristic = accessory.getCharacteristicByIID(iid);
1502
- _this.sendCharacteristicWarning(characteristic, "timeout-write" /* CharacteristicWarningType.TIMEOUT_WRITE */, "The write handler for the characteristic '" +
1503
- characteristic.displayName + "' on the accessory '" + accessory.displayName + "' didn't respond at all!. " +
1504
- "Please check that you properly call the callback!");
1505
- characteristics.push({
1506
- aid: aid,
1507
- iid: iid,
1508
- status: -70408 /* HAPStatus.OPERATION_TIMED_OUT */,
1509
- });
1510
- }
1511
- }
1512
- catch (e_18_1) { e_18 = { error: e_18_1 }; }
1513
- finally {
1514
- try {
1515
- if (missingCharacteristics_4_1 && !missingCharacteristics_4_1.done && (_a = missingCharacteristics_4.return)) _a.call(missingCharacteristics_4);
1516
- }
1517
- finally { if (e_18) throw e_18.error; }
1273
+ for (const id of missingCharacteristics) {
1274
+ const split = id.split(".");
1275
+ const aid = parseInt(split[0], 10);
1276
+ const iid = parseInt(split[1], 10);
1277
+ const accessory = this.getAccessoryByAID(aid);
1278
+ const characteristic = accessory.getCharacteristicByIID(iid);
1279
+ this.sendCharacteristicWarning(characteristic, "timeout-write" /* CharacteristicWarningType.TIMEOUT_WRITE */, "The write handler for the characteristic '" +
1280
+ characteristic.displayName + "' on the accessory '" + accessory.displayName + "' didn't respond at all!. " +
1281
+ "Please check that you properly call the callback!");
1282
+ characteristics.push({
1283
+ aid: aid,
1284
+ iid: iid,
1285
+ status: -70408 /* HAPStatus.OPERATION_TIMED_OUT */,
1286
+ });
1518
1287
  }
1519
1288
  missingCharacteristics.clear();
1520
1289
  callback(undefined, response);
@@ -1522,18 +1291,22 @@ var Accessory = /** @class */ (function (_super) {
1522
1291
  timeout.unref();
1523
1292
  }, Accessory.TIMEOUT_WARNING);
1524
1293
  timeout.unref();
1525
- var _loop_2 = function (data) {
1526
- var name = data.aid + "." + data.iid;
1527
- this_2.handleCharacteristicWrite(connection, data, writeState).then(function (value) {
1528
- return tslib_1.__assign({ aid: data.aid, iid: data.iid }, value);
1529
- }, function (reason) {
1530
- console.error("[".concat(_this.displayName, "] Write request for characteristic ").concat(name, " encountered an error: ").concat(reason.stack));
1294
+ for (const data of writeRequest.characteristics) {
1295
+ const name = data.aid + "." + data.iid;
1296
+ this.handleCharacteristicWrite(connection, data, writeState).then(value => {
1297
+ return {
1298
+ aid: data.aid,
1299
+ iid: data.iid,
1300
+ ...value,
1301
+ };
1302
+ }, reason => {
1303
+ console.error(`[${this.displayName}] Write request for characteristic ${name} encountered an error: ${reason.stack}`);
1531
1304
  return {
1532
1305
  aid: data.aid,
1533
1306
  iid: data.iid,
1534
1307
  status: -70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */,
1535
1308
  };
1536
- }).then(function (value) {
1309
+ }).then(value => {
1537
1310
  if (!timeout) {
1538
1311
  return; // if timeout is undefined, response was already sent out
1539
1312
  }
@@ -1547,119 +1320,100 @@ var Accessory = /** @class */ (function (_super) {
1547
1320
  callback(undefined, response);
1548
1321
  }
1549
1322
  });
1550
- };
1551
- var this_2 = this;
1552
- try {
1553
- for (var _b = tslib_1.__values(writeRequest.characteristics), _c = _b.next(); !_c.done; _c = _b.next()) {
1554
- var data = _c.value;
1555
- _loop_2(data);
1556
- }
1557
1323
  }
1558
- catch (e_16_1) { e_16 = { error: e_16_1 }; }
1559
- finally {
1560
- try {
1561
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1324
+ }
1325
+ async handleCharacteristicWrite(connection, data, writeState) {
1326
+ const characteristic = this.findCharacteristic(data.aid, data.iid);
1327
+ if (!characteristic) {
1328
+ debug("[%s] Could not find a Characteristic with aid of %s and iid of %s", this.displayName, data.aid, data.iid);
1329
+ return { status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ };
1330
+ }
1331
+ if (writeState === 2 /* WriteRequestState.TIMED_WRITE_REJECTED */) {
1332
+ return { status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ };
1333
+ }
1334
+ if (data.ev == null && data.value == null) {
1335
+ return { status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ };
1336
+ }
1337
+ if (data.ev != null) { // register/unregister event notifications
1338
+ if (!characteristic.props.perms.includes("ev" /* Perms.NOTIFY */)) { // check if notify is allowed for this characteristic
1339
+ debug("[%s] Tried %s notifications for Characteristic which does not allow notify (aid of %s and iid of %s)", this.displayName, data.ev ? "enabling" : "disabling", data.aid, data.iid);
1340
+ return { status: -70406 /* HAPStatus.NOTIFICATION_NOT_SUPPORTED */ };
1341
+ }
1342
+ if (characteristic.props.adminOnlyAccess && characteristic.props.adminOnlyAccess.includes(2 /* Access.NOTIFY */)) {
1343
+ const verifiable = connection.username && this._accessoryInfo;
1344
+ if (!verifiable) {
1345
+ debug("[%s] Could not verify admin permissions for Characteristic which requires admin permissions for notify (aid of %s and iid of %s)", this.displayName, data.aid, data.iid);
1346
+ }
1347
+ if (!verifiable || !this._accessoryInfo.hasAdminPermissions(connection.username)) {
1348
+ return { status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ };
1349
+ }
1350
+ }
1351
+ const notificationsEnabled = connection.hasEventNotifications(data.aid, data.iid);
1352
+ if (data.ev && !notificationsEnabled) {
1353
+ connection.enableEventNotifications(data.aid, data.iid);
1354
+ characteristic.subscribe();
1355
+ debug("[%s] Registered Characteristic \"%s\" on \"%s\" for events", connection.remoteAddress, characteristic.displayName, this.displayName);
1562
1356
  }
1563
- finally { if (e_16) throw e_16.error; }
1357
+ else if (!data.ev && notificationsEnabled) {
1358
+ characteristic.unsubscribe();
1359
+ connection.disableEventNotifications(data.aid, data.iid);
1360
+ debug("[%s] Unregistered Characteristic \"%s\" on \"%s\" for events", connection.remoteAddress, characteristic.displayName, this.displayName);
1361
+ }
1362
+ // response is returned below in the else block
1564
1363
  }
1565
- };
1566
- Accessory.prototype.handleCharacteristicWrite = function (connection, data, writeState) {
1567
- return tslib_1.__awaiter(this, void 0, void 0, function () {
1568
- var characteristic, verifiable, notificationsEnabled, verifiable, allowWrite;
1569
- var _this = this;
1570
- return tslib_1.__generator(this, function (_a) {
1571
- characteristic = this.findCharacteristic(data.aid, data.iid);
1572
- if (!characteristic) {
1573
- debug("[%s] Could not find a Characteristic with aid of %s and iid of %s", this.displayName, data.aid, data.iid);
1574
- return [2 /*return*/, { status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }];
1364
+ if (data.value != null) {
1365
+ if (!characteristic.props.perms.includes("pw" /* Perms.PAIRED_WRITE */)) { // check if write is allowed for this characteristic
1366
+ debug("[%s] Tried writing to Characteristic which does not allow writing (aid of %s and iid of %s)", this.displayName, data.aid, data.iid);
1367
+ return { status: -70404 /* HAPStatus.READ_ONLY_CHARACTERISTIC */ };
1368
+ }
1369
+ if (characteristic.props.adminOnlyAccess && characteristic.props.adminOnlyAccess.includes(1 /* Access.WRITE */)) {
1370
+ const verifiable = connection.username && this._accessoryInfo;
1371
+ if (!verifiable) {
1372
+ debug("[%s] Could not verify admin permissions for Characteristic which requires admin permissions for write (aid of %s and iid of %s)", this.displayName, data.aid, data.iid);
1575
1373
  }
1576
- if (writeState === 2 /* WriteRequestState.TIMED_WRITE_REJECTED */) {
1577
- return [2 /*return*/, { status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }];
1374
+ if (!verifiable || !this._accessoryInfo.hasAdminPermissions(connection.username)) {
1375
+ return { status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ };
1578
1376
  }
1579
- if (data.ev == null && data.value == null) {
1580
- return [2 /*return*/, { status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }];
1377
+ }
1378
+ if (characteristic.props.perms.includes("aa" /* Perms.ADDITIONAL_AUTHORIZATION */) && characteristic.additionalAuthorizationHandler) {
1379
+ // if the characteristic "supports additional authorization" but doesn't define a handler for the check
1380
+ // we conclude that the characteristic doesn't want to check the authData (currently) and just allows access for everybody
1381
+ let allowWrite;
1382
+ try {
1383
+ allowWrite = characteristic.additionalAuthorizationHandler(data.authData);
1581
1384
  }
1582
- if (data.ev != null) { // register/unregister event notifications
1583
- if (!characteristic.props.perms.includes("ev" /* Perms.NOTIFY */)) { // check if notify is allowed for this characteristic
1584
- debug("[%s] Tried %s notifications for Characteristic which does not allow notify (aid of %s and iid of %s)", this.displayName, data.ev ? "enabling" : "disabling", data.aid, data.iid);
1585
- return [2 /*return*/, { status: -70406 /* HAPStatus.NOTIFICATION_NOT_SUPPORTED */ }];
1586
- }
1587
- if (characteristic.props.adminOnlyAccess && characteristic.props.adminOnlyAccess.includes(2 /* Access.NOTIFY */)) {
1588
- verifiable = connection.username && this._accessoryInfo;
1589
- if (!verifiable) {
1590
- debug("[%s] Could not verify admin permissions for Characteristic which requires admin permissions for notify (aid of %s and iid of %s)", this.displayName, data.aid, data.iid);
1591
- }
1592
- if (!verifiable || !this._accessoryInfo.hasAdminPermissions(connection.username)) {
1593
- return [2 /*return*/, { status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }];
1594
- }
1595
- }
1596
- notificationsEnabled = connection.hasEventNotifications(data.aid, data.iid);
1597
- if (data.ev && !notificationsEnabled) {
1598
- connection.enableEventNotifications(data.aid, data.iid);
1599
- characteristic.subscribe();
1600
- debug("[%s] Registered Characteristic \"%s\" on \"%s\" for events", connection.remoteAddress, characteristic.displayName, this.displayName);
1601
- }
1602
- else if (!data.ev && notificationsEnabled) {
1603
- characteristic.unsubscribe();
1604
- connection.disableEventNotifications(data.aid, data.iid);
1605
- debug("[%s] Unregistered Characteristic \"%s\" on \"%s\" for events", connection.remoteAddress, characteristic.displayName, this.displayName);
1606
- }
1607
- // response is returned below in the else block
1385
+ catch (error) {
1386
+ console.warn("[" + this.displayName + "] Additional authorization handler has thrown an error when checking authData: " + error.stack);
1387
+ allowWrite = false;
1608
1388
  }
1609
- if (data.value != null) {
1610
- if (!characteristic.props.perms.includes("pw" /* Perms.PAIRED_WRITE */)) { // check if write is allowed for this characteristic
1611
- debug("[%s] Tried writing to Characteristic which does not allow writing (aid of %s and iid of %s)", this.displayName, data.aid, data.iid);
1612
- return [2 /*return*/, { status: -70404 /* HAPStatus.READ_ONLY_CHARACTERISTIC */ }];
1613
- }
1614
- if (characteristic.props.adminOnlyAccess && characteristic.props.adminOnlyAccess.includes(1 /* Access.WRITE */)) {
1615
- verifiable = connection.username && this._accessoryInfo;
1616
- if (!verifiable) {
1617
- debug("[%s] Could not verify admin permissions for Characteristic which requires admin permissions for write (aid of %s and iid of %s)", this.displayName, data.aid, data.iid);
1618
- }
1619
- if (!verifiable || !this._accessoryInfo.hasAdminPermissions(connection.username)) {
1620
- return [2 /*return*/, { status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }];
1621
- }
1622
- }
1623
- if (characteristic.props.perms.includes("aa" /* Perms.ADDITIONAL_AUTHORIZATION */) && characteristic.additionalAuthorizationHandler) {
1624
- allowWrite = void 0;
1625
- try {
1626
- allowWrite = characteristic.additionalAuthorizationHandler(data.authData);
1627
- }
1628
- catch (error) {
1629
- console.warn("[" + this.displayName + "] Additional authorization handler has thrown an error when checking authData: " + error.stack);
1630
- allowWrite = false;
1631
- }
1632
- if (!allowWrite) {
1633
- return [2 /*return*/, { status: -70411 /* HAPStatus.INSUFFICIENT_AUTHORIZATION */ }];
1634
- }
1635
- }
1636
- if (characteristic.props.perms.includes("tw" /* Perms.TIMED_WRITE */) && writeState !== 1 /* WriteRequestState.TIMED_WRITE_AUTHENTICATED */) {
1637
- debug("[%s] Tried writing to a timed write only Characteristic without properly preparing (iid of %s and aid of %s)", this.displayName, data.aid, data.iid);
1638
- return [2 /*return*/, { status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }];
1639
- }
1640
- return [2 /*return*/, characteristic.handleSetRequest(data.value, connection).then(function (value) {
1641
- debug("[%s] Setting Characteristic \"%s\" to value %s", _this.displayName, characteristic.displayName, data.value);
1642
- return {
1643
- // if write response is requests and value is provided, return that
1644
- value: data.r && value ? (0, request_util_1.formatOutgoingCharacteristicValue)(value, characteristic.props) : undefined,
1645
- status: 0 /* HAPStatus.SUCCESS */,
1646
- };
1647
- }, function (status) {
1648
- // @ts-expect-error: forceConsistentCasingInFileNames compiler option
1649
- debug("[%s] Error setting Characteristic \"%s\" to value %s: ", _this.displayName, characteristic.displayName, data.value, HAPServer_1.HAPStatus[status]);
1650
- return { status: status };
1651
- })];
1389
+ if (!allowWrite) {
1390
+ return { status: -70411 /* HAPStatus.INSUFFICIENT_AUTHORIZATION */ };
1652
1391
  }
1653
- return [2 /*return*/, { status: 0 /* HAPStatus.SUCCESS */ }];
1392
+ }
1393
+ if (characteristic.props.perms.includes("tw" /* Perms.TIMED_WRITE */) && writeState !== 1 /* WriteRequestState.TIMED_WRITE_AUTHENTICATED */) {
1394
+ debug("[%s] Tried writing to a timed write only Characteristic without properly preparing (iid of %s and aid of %s)", this.displayName, data.aid, data.iid);
1395
+ return { status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ };
1396
+ }
1397
+ return characteristic.handleSetRequest(data.value, connection).then(value => {
1398
+ debug("[%s] Setting Characteristic \"%s\" to value %s", this.displayName, characteristic.displayName, data.value);
1399
+ return {
1400
+ // if write response is requests and value is provided, return that
1401
+ value: data.r && value ? (0, request_util_1.formatOutgoingCharacteristicValue)(value, characteristic.props) : undefined,
1402
+ status: 0 /* HAPStatus.SUCCESS */,
1403
+ };
1404
+ }, (status) => {
1405
+ // @ts-expect-error: forceConsistentCasingInFileNames compiler option
1406
+ debug("[%s] Error setting Characteristic \"%s\" to value %s: ", this.displayName, characteristic.displayName, data.value, HAPServer_1.HAPStatus[status]);
1407
+ return { status: status };
1654
1408
  });
1655
- });
1656
- };
1657
- Accessory.prototype.handleResource = function (data, callback) {
1658
- var _a;
1409
+ }
1410
+ return { status: 0 /* HAPStatus.SUCCESS */ };
1411
+ }
1412
+ handleResource(data, callback) {
1659
1413
  if (data["resource-type"] === "image" /* ResourceRequestType.IMAGE */) {
1660
- var aid = data.aid; // aid is optionally supplied by HomeKit (for example when camera is bridged, multiple cams, etc)
1661
- var accessory = undefined;
1662
- var controller = undefined;
1414
+ const aid = data.aid; // aid is optionally supplied by HomeKit (for example when camera is bridged, multiple cams, etc)
1415
+ let accessory = undefined;
1416
+ let controller = undefined;
1663
1417
  if (aid) {
1664
1418
  accessory = this.getAccessoryByAID(aid);
1665
1419
  if (accessory && accessory.activeCameraController) {
@@ -1676,44 +1430,33 @@ var Accessory = /** @class */ (function (_super) {
1676
1430
  callback({ httpCode: 404 /* HAPHTTPCode.NOT_FOUND */, status: -70409 /* HAPStatus.RESOURCE_DOES_NOT_EXIST */ });
1677
1431
  return;
1678
1432
  }
1679
- controller.handleSnapshotRequest(data["image-height"], data["image-width"], accessory === null || accessory === void 0 ? void 0 : accessory.displayName, data.reason)
1680
- .then(function (buffer) {
1433
+ controller.handleSnapshotRequest(data["image-height"], data["image-width"], accessory?.displayName, data.reason)
1434
+ .then(buffer => {
1681
1435
  callback(undefined, buffer);
1682
- }, function (status) {
1436
+ }, (status) => {
1683
1437
  callback({ httpCode: 207 /* HAPHTTPCode.MULTI_STATUS */, status: status });
1684
1438
  });
1685
1439
  return;
1686
1440
  }
1687
- debug("[%s] received request for unsupported image type: " + data["resource-type"], (_a = this._accessoryInfo) === null || _a === void 0 ? void 0 : _a.username);
1441
+ debug("[%s] received request for unsupported image type: " + data["resource-type"], this._accessoryInfo?.username);
1688
1442
  callback({ httpCode: 404 /* HAPHTTPCode.NOT_FOUND */, status: -70409 /* HAPStatus.RESOURCE_DOES_NOT_EXIST */ });
1689
- };
1690
- Accessory.prototype.handleHAPConnectionClosed = function (connection) {
1691
- var e_19, _a;
1443
+ }
1444
+ handleHAPConnectionClosed(connection) {
1692
1445
  if (this.activeCameraController) {
1693
1446
  this.activeCameraController.handleCloseConnection(connection.sessionID);
1694
1447
  }
1695
- try {
1696
- for (var _b = tslib_1.__values(connection.getRegisteredEvents()), _c = _b.next(); !_c.done; _c = _b.next()) {
1697
- var event = _c.value;
1698
- var ids = event.split(".");
1699
- var aid = parseInt(ids[0], 10);
1700
- var iid = parseInt(ids[1], 10);
1701
- var characteristic = this.findCharacteristic(aid, iid);
1702
- if (characteristic) {
1703
- characteristic.unsubscribe();
1704
- }
1448
+ for (const event of connection.getRegisteredEvents()) {
1449
+ const ids = event.split(".");
1450
+ const aid = parseInt(ids[0], 10);
1451
+ const iid = parseInt(ids[1], 10);
1452
+ const characteristic = this.findCharacteristic(aid, iid);
1453
+ if (characteristic) {
1454
+ characteristic.unsubscribe();
1705
1455
  }
1706
1456
  }
1707
- catch (e_19_1) { e_19 = { error: e_19_1 }; }
1708
- finally {
1709
- try {
1710
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1711
- }
1712
- finally { if (e_19) throw e_19.error; }
1713
- }
1714
1457
  connection.clearRegisteredEvents();
1715
- };
1716
- Accessory.prototype.handleServiceConfigurationChangeEvent = function (service) {
1458
+ }
1459
+ handleServiceConfigurationChangeEvent(service) {
1717
1460
  if (!service.isPrimaryService && service === this.primaryService) {
1718
1461
  // service changed form primary to non-primary service
1719
1462
  this.primaryService = undefined;
@@ -1731,10 +1474,10 @@ var Accessory = /** @class */ (function (_super) {
1731
1474
  else {
1732
1475
  this.enqueueConfigurationUpdate();
1733
1476
  }
1734
- };
1735
- Accessory.prototype.handleCharacteristicChangeEvent = function (accessory, service, change) {
1477
+ }
1478
+ handleCharacteristicChangeEvent(accessory, service, change) {
1736
1479
  if (this.bridged) { // forward this to our main accessory
1737
- this.emit("service-characteristic-change" /* AccessoryEventTypes.SERVICE_CHARACTERISTIC_CHANGE */, tslib_1.__assign(tslib_1.__assign({}, change), { service: service }));
1480
+ this.emit("service-characteristic-change" /* AccessoryEventTypes.SERVICE_CHARACTERISTIC_CHANGE */, { ...change, service: service });
1738
1481
  }
1739
1482
  else {
1740
1483
  if (!this._server) {
@@ -1757,14 +1500,14 @@ var Accessory = /** @class */ (function (_super) {
1757
1500
  // otherwise we ignore this change event (with the return below)
1758
1501
  return;
1759
1502
  }
1760
- var uuid_2 = change.characteristic.UUID;
1761
- var immediateDelivery = uuid_2 === Characteristic_1.Characteristic.ButtonEvent.UUID || uuid_2 === Characteristic_1.Characteristic.ProgrammableSwitchEvent.UUID
1762
- || uuid_2 === Characteristic_1.Characteristic.MotionDetected.UUID || uuid_2 === Characteristic_1.Characteristic.ContactSensorState.UUID;
1763
- var value = (0, request_util_1.formatOutgoingCharacteristicValue)(change.newValue, change.characteristic.props);
1503
+ const uuid = change.characteristic.UUID;
1504
+ const immediateDelivery = uuid === Characteristic_1.Characteristic.ButtonEvent.UUID || uuid === Characteristic_1.Characteristic.ProgrammableSwitchEvent.UUID
1505
+ || uuid === Characteristic_1.Characteristic.MotionDetected.UUID || uuid === Characteristic_1.Characteristic.ContactSensorState.UUID;
1506
+ const value = (0, request_util_1.formatOutgoingCharacteristicValue)(change.newValue, change.characteristic.props);
1764
1507
  this._server.sendEventNotifications(accessory.aid, change.characteristic.iid, value, change.originator, immediateDelivery);
1765
1508
  }
1766
- };
1767
- Accessory.prototype.sendCharacteristicWarning = function (characteristic, type, message) {
1509
+ }
1510
+ sendCharacteristicWarning(characteristic, type, message) {
1768
1511
  this.handleCharacteristicWarning({
1769
1512
  characteristic: characteristic,
1770
1513
  type: type,
@@ -1772,13 +1515,12 @@ var Accessory = /** @class */ (function (_super) {
1772
1515
  originatorChain: [characteristic.displayName], // we are missing the service displayName, but that's okay
1773
1516
  stack: new Error().stack,
1774
1517
  });
1775
- };
1776
- Accessory.prototype.handleCharacteristicWarning = function (warning) {
1777
- var _a;
1778
- warning.originatorChain = tslib_1.__spreadArray([this.displayName], tslib_1.__read(warning.originatorChain), false);
1779
- var emitted = this.emit("characteristic-warning" /* AccessoryEventTypes.CHARACTERISTIC_WARNING */, warning);
1518
+ }
1519
+ handleCharacteristicWarning(warning) {
1520
+ warning.originatorChain = [this.displayName, ...warning.originatorChain];
1521
+ const emitted = this.emit("characteristic-warning" /* AccessoryEventTypes.CHARACTERISTIC_WARNING */, warning);
1780
1522
  if (!emitted) {
1781
- var message = "[".concat(warning.originatorChain.join("@"), "] ").concat(warning.message);
1523
+ const message = `[${warning.originatorChain.join("@")}] ${warning.message}`;
1782
1524
  if (warning.type === "error-message" /* CharacteristicWarningType.ERROR_MESSAGE */
1783
1525
  || warning.type === "timeout-read" /* CharacteristicWarningType.TIMEOUT_READ */ || warning.type === "timeout-write" /* CharacteristicWarningType.TIMEOUT_WRITE */) {
1784
1526
  console.error(message);
@@ -1786,67 +1528,55 @@ var Accessory = /** @class */ (function (_super) {
1786
1528
  else {
1787
1529
  console.warn(message);
1788
1530
  }
1789
- debug("[%s] Above characteristic warning was thrown at: %s", this.displayName, (_a = warning.stack) !== null && _a !== void 0 ? _a : "unknown");
1531
+ debug("[%s] Above characteristic warning was thrown at: %s", this.displayName, warning.stack ?? "unknown");
1790
1532
  }
1791
- };
1792
- Accessory.prototype.setupServiceEventHandlers = function (service) {
1533
+ }
1534
+ setupServiceEventHandlers(service) {
1793
1535
  service.on("service-configurationChange" /* ServiceEventTypes.SERVICE_CONFIGURATION_CHANGE */, this.handleServiceConfigurationChangeEvent.bind(this, service));
1794
1536
  service.on("characteristic-change" /* ServiceEventTypes.CHARACTERISTIC_CHANGE */, this.handleCharacteristicChangeEvent.bind(this, this, service));
1795
1537
  service.on("characteristic-warning" /* ServiceEventTypes.CHARACTERISTIC_WARNING */, this.handleCharacteristicWarning.bind(this));
1796
- };
1797
- Accessory.prototype._sideloadServices = function (targetServices) {
1798
- var e_20, _a;
1799
- var _this = this;
1800
- try {
1801
- for (var targetServices_1 = tslib_1.__values(targetServices), targetServices_1_1 = targetServices_1.next(); !targetServices_1_1.done; targetServices_1_1 = targetServices_1.next()) {
1802
- var service = targetServices_1_1.value;
1803
- this.setupServiceEventHandlers(service);
1804
- }
1805
- }
1806
- catch (e_20_1) { e_20 = { error: e_20_1 }; }
1807
- finally {
1808
- try {
1809
- if (targetServices_1_1 && !targetServices_1_1.done && (_a = targetServices_1.return)) _a.call(targetServices_1);
1810
- }
1811
- finally { if (e_20) throw e_20.error; }
1538
+ }
1539
+ _sideloadServices(targetServices) {
1540
+ for (const service of targetServices) {
1541
+ this.setupServiceEventHandlers(service);
1812
1542
  }
1813
1543
  this.services = targetServices.slice();
1814
1544
  // Fix Identify
1815
1545
  this
1816
1546
  .getService(Service_1.Service.AccessoryInformation)
1817
1547
  .getCharacteristic(Characteristic_1.Characteristic.Identify)
1818
- .on("set" /* CharacteristicEventTypes.SET */, function (value, callback) {
1548
+ .on("set" /* CharacteristicEventTypes.SET */, (value, callback) => {
1819
1549
  if (value) {
1820
- var paired = true;
1821
- _this.identificationRequest(paired, callback);
1550
+ const paired = true;
1551
+ this.identificationRequest(paired, callback);
1822
1552
  }
1823
1553
  });
1824
- };
1825
- Accessory._generateSetupID = function () {
1826
- var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1827
- var max = chars.length;
1828
- var setupID = "";
1829
- for (var i = 0; i < 4; i++) {
1830
- var index = Math.floor(Math.random() * max);
1554
+ }
1555
+ static _generateSetupID() {
1556
+ const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1557
+ const max = chars.length;
1558
+ let setupID = "";
1559
+ for (let i = 0; i < 4; i++) {
1560
+ const index = Math.floor(Math.random() * max);
1831
1561
  setupID += chars.charAt(index);
1832
1562
  }
1833
1563
  return setupID;
1834
- };
1564
+ }
1835
1565
  // serialization and deserialization functions, mainly designed for homebridge to create a json copy to store on disk
1836
- Accessory.serialize = function (accessory) {
1837
- var json = {
1566
+ static serialize(accessory) {
1567
+ const json = {
1838
1568
  displayName: accessory.displayName,
1839
1569
  UUID: accessory.UUID,
1840
1570
  lastKnownUsername: accessory._accessoryInfo ? accessory._accessoryInfo.username : undefined,
1841
1571
  category: accessory.category,
1842
1572
  services: [],
1843
1573
  };
1844
- var linkedServices = {};
1845
- var hasLinkedServices = false;
1846
- accessory.services.forEach(function (service) {
1574
+ const linkedServices = {};
1575
+ let hasLinkedServices = false;
1576
+ accessory.services.forEach(service => {
1847
1577
  json.services.push(Service_1.Service.serialize(service));
1848
- var linkedServicesPresentation = [];
1849
- service.linkedServices.forEach(function (linkedService) {
1578
+ const linkedServicesPresentation = [];
1579
+ service.linkedServices.forEach(linkedService => {
1850
1580
  linkedServicesPresentation.push(linkedService.getServiceId());
1851
1581
  });
1852
1582
  if (linkedServicesPresentation.length > 0) {
@@ -1857,17 +1587,16 @@ var Accessory = /** @class */ (function (_super) {
1857
1587
  if (hasLinkedServices) {
1858
1588
  json.linkedServices = linkedServices;
1859
1589
  }
1860
- var controllers = [];
1590
+ const controllers = [];
1861
1591
  // save controllers
1862
- Object.values(accessory.controllers).forEach(function (context) {
1592
+ Object.values(accessory.controllers).forEach((context) => {
1863
1593
  controllers.push({
1864
1594
  type: context.controller.controllerId(),
1865
1595
  services: Accessory.serializeServiceMap(context.serviceMap),
1866
1596
  });
1867
1597
  });
1868
1598
  // also save controller which didn't get initialized (could lead to service duplication if we throw that data away)
1869
- accessory.serializedControllers && Object.entries(accessory.serializedControllers).forEach(function (_a) {
1870
- var _b = tslib_1.__read(_a, 2), id = _b[0], serviceMap = _b[1];
1599
+ accessory.serializedControllers && Object.entries(accessory.serializedControllers).forEach(([id, serviceMap]) => {
1871
1600
  controllers.push({
1872
1601
  type: id,
1873
1602
  services: Accessory.serializeServiceMap(serviceMap),
@@ -1877,89 +1606,72 @@ var Accessory = /** @class */ (function (_super) {
1877
1606
  json.controllers = controllers;
1878
1607
  }
1879
1608
  return json;
1880
- };
1881
- Accessory.deserialize = function (json) {
1882
- var e_21, _a;
1883
- var accessory = new Accessory(json.displayName, json.UUID);
1609
+ }
1610
+ static deserialize(json) {
1611
+ const accessory = new Accessory(json.displayName, json.UUID);
1884
1612
  accessory.lastKnownUsername = json.lastKnownUsername;
1885
1613
  accessory.category = json.category;
1886
- var services = [];
1887
- var servicesMap = {};
1888
- json.services.forEach(function (serialized) {
1889
- var service = Service_1.Service.deserialize(serialized);
1614
+ const services = [];
1615
+ const servicesMap = {};
1616
+ json.services.forEach(serialized => {
1617
+ const service = Service_1.Service.deserialize(serialized);
1890
1618
  services.push(service);
1891
1619
  servicesMap[service.getServiceId()] = service;
1892
1620
  });
1893
1621
  if (json.linkedServices) {
1894
- var _loop_3 = function (serviceId, linkedServicesKeys) {
1895
- var primaryService = servicesMap[serviceId];
1622
+ for (const [serviceId, linkedServicesKeys] of Object.entries(json.linkedServices)) {
1623
+ const primaryService = servicesMap[serviceId];
1896
1624
  if (!primaryService) {
1897
- return "continue";
1625
+ continue;
1898
1626
  }
1899
- linkedServicesKeys.forEach(function (linkedServiceKey) {
1900
- var linkedService = servicesMap[linkedServiceKey];
1627
+ linkedServicesKeys.forEach(linkedServiceKey => {
1628
+ const linkedService = servicesMap[linkedServiceKey];
1901
1629
  if (linkedService) {
1902
1630
  primaryService.addLinkedService(linkedService);
1903
1631
  }
1904
1632
  });
1905
- };
1906
- try {
1907
- for (var _b = tslib_1.__values(Object.entries(json.linkedServices)), _c = _b.next(); !_c.done; _c = _b.next()) {
1908
- var _d = tslib_1.__read(_c.value, 2), serviceId = _d[0], linkedServicesKeys = _d[1];
1909
- _loop_3(serviceId, linkedServicesKeys);
1910
- }
1911
- }
1912
- catch (e_21_1) { e_21 = { error: e_21_1 }; }
1913
- finally {
1914
- try {
1915
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1916
- }
1917
- finally { if (e_21) throw e_21.error; }
1918
1633
  }
1919
1634
  }
1920
1635
  if (json.controllers) { // just save it for later if it exists {@see configureController}
1921
1636
  accessory.serializedControllers = {};
1922
- json.controllers.forEach(function (serializedController) {
1637
+ json.controllers.forEach(serializedController => {
1923
1638
  accessory.serializedControllers[serializedController.type] = Accessory.deserializeServiceMap(serializedController.services, servicesMap);
1924
1639
  });
1925
1640
  }
1926
1641
  accessory._sideloadServices(services);
1927
1642
  return accessory;
1928
- };
1929
- Accessory.cleanupAccessoryData = function (username) {
1643
+ }
1644
+ static cleanupAccessoryData(username) {
1930
1645
  IdentifierCache_1.IdentifierCache.remove(username);
1931
1646
  AccessoryInfo_1.AccessoryInfo.remove(username);
1932
1647
  ControllerStorage_1.ControllerStorage.remove(username);
1933
- };
1934
- Accessory.serializeServiceMap = function (serviceMap) {
1935
- var serialized = {};
1936
- Object.entries(serviceMap).forEach(function (_a) {
1937
- var _b = tslib_1.__read(_a, 2), name = _b[0], service = _b[1];
1648
+ }
1649
+ static serializeServiceMap(serviceMap) {
1650
+ const serialized = {};
1651
+ Object.entries(serviceMap).forEach(([name, service]) => {
1938
1652
  if (!service) {
1939
1653
  return;
1940
1654
  }
1941
1655
  serialized[name] = service.getServiceId();
1942
1656
  });
1943
1657
  return serialized;
1944
- };
1945
- Accessory.deserializeServiceMap = function (serializedServiceMap, servicesMap) {
1946
- var controllerServiceMap = {};
1947
- Object.entries(serializedServiceMap).forEach(function (_a) {
1948
- var _b = tslib_1.__read(_a, 2), name = _b[0], serviceId = _b[1];
1949
- var service = servicesMap[serviceId];
1658
+ }
1659
+ static deserializeServiceMap(serializedServiceMap, servicesMap) {
1660
+ const controllerServiceMap = {};
1661
+ Object.entries(serializedServiceMap).forEach(([name, serviceId]) => {
1662
+ const service = servicesMap[serviceId];
1950
1663
  if (service) {
1951
1664
  controllerServiceMap[name] = service;
1952
1665
  }
1953
1666
  });
1954
1667
  return controllerServiceMap;
1955
- };
1956
- Accessory.parseBindOption = function (info) {
1957
- var e_22, _a;
1958
- var advertiserAddress = undefined;
1959
- var disableIpv6 = undefined;
1960
- var serverAddress = undefined;
1668
+ }
1669
+ static parseBindOption(info) {
1670
+ let advertiserAddress = undefined;
1671
+ let disableIpv6 = undefined;
1672
+ let serverAddress = undefined;
1961
1673
  if (info.bind) {
1962
- var entries = new Set(Array.isArray(info.bind) ? info.bind : [info.bind]);
1674
+ const entries = new Set(Array.isArray(info.bind) ? info.bind : [info.bind]);
1963
1675
  if (entries.has("::")) {
1964
1676
  serverAddress = "::";
1965
1677
  entries.delete("::");
@@ -1977,8 +1689,8 @@ var Accessory = /** @class */ (function (_super) {
1977
1689
  }
1978
1690
  else if (entries.size === 1) {
1979
1691
  advertiserAddress = Array.from(entries);
1980
- var entry = entries.values().next().value; // grab the first one
1981
- var version = net_1.default.isIP(entry); // check if ip address was specified or an interface name
1692
+ const entry = entries.values().next().value; // grab the first one
1693
+ const version = net_1.default.isIP(entry); // check if ip address was specified or an interface name
1982
1694
  if (version) {
1983
1695
  serverAddress = version === 4 ? "0.0.0.0" : "::"; // we currently bind to unspecified addresses so config-ui always has a connection via loopback
1984
1696
  }
@@ -1988,24 +1700,14 @@ var Accessory = /** @class */ (function (_super) {
1988
1700
  }
1989
1701
  else if (entries.size > 1) {
1990
1702
  advertiserAddress = Array.from(entries);
1991
- var bindUnspecifiedIpv6 = false; // we bind on "::" if there are interface names, or we detect ipv6 addresses
1992
- try {
1993
- for (var entries_1 = tslib_1.__values(entries), entries_1_1 = entries_1.next(); !entries_1_1.done; entries_1_1 = entries_1.next()) {
1994
- var entry = entries_1_1.value;
1995
- var version = net_1.default.isIP(entry);
1996
- if (version === 0 || version === 6) {
1997
- bindUnspecifiedIpv6 = true;
1998
- break;
1999
- }
1703
+ let bindUnspecifiedIpv6 = false; // we bind on "::" if there are interface names, or we detect ipv6 addresses
1704
+ for (const entry of entries) {
1705
+ const version = net_1.default.isIP(entry);
1706
+ if (version === 0 || version === 6) {
1707
+ bindUnspecifiedIpv6 = true;
1708
+ break;
2000
1709
  }
2001
1710
  }
2002
- catch (e_22_1) { e_22 = { error: e_22_1 }; }
2003
- finally {
2004
- try {
2005
- if (entries_1_1 && !entries_1_1.done && (_a = entries_1.return)) _a.call(entries_1);
2006
- }
2007
- finally { if (e_22) throw e_22.error; }
2008
- }
2009
1711
  if (bindUnspecifiedIpv6) {
2010
1712
  serverAddress = "::";
2011
1713
  }
@@ -2020,17 +1722,7 @@ var Accessory = /** @class */ (function (_super) {
2020
1722
  serviceDisableIpv6: disableIpv6,
2021
1723
  serverAddress: serverAddress,
2022
1724
  };
2023
- };
2024
- /**
2025
- * @deprecated Please use the Categories const enum above.
2026
- */
2027
- // @ts-expect-error: forceConsistentCasingInFileNames compiler option
2028
- Accessory.Categories = Categories;
2029
- /// Timeout in milliseconds until a characteristic warning is issue
2030
- Accessory.TIMEOUT_WARNING = 3000;
2031
- /// Timeout in milliseconds after `TIMEOUT_WARNING` until the operation on the characteristic is considered timed out.
2032
- Accessory.TIMEOUT_AFTER_WARNING = 6000;
2033
- return Accessory;
2034
- }(events_1.EventEmitter));
1725
+ }
1726
+ }
2035
1727
  exports.Accessory = Accessory;
2036
1728
  //# sourceMappingURL=Accessory.js.map