matterbridge 3.4.1 → 3.4.2-dev-20251202-c41a119

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 (326) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/broadcastServer.js +0 -112
  3. package/dist/broadcastServerTypes.js +0 -24
  4. package/dist/cli.js +1 -97
  5. package/dist/cliEmitter.js +0 -37
  6. package/dist/cliHistory.js +0 -38
  7. package/dist/clusters/export.js +0 -2
  8. package/dist/deviceManager.js +1 -113
  9. package/dist/devices/airConditioner.js +0 -57
  10. package/dist/devices/batteryStorage.js +1 -48
  11. package/dist/devices/cooktop.js +0 -56
  12. package/dist/devices/dishwasher.js +0 -57
  13. package/dist/devices/evse.js +10 -74
  14. package/dist/devices/export.js +0 -5
  15. package/dist/devices/extractorHood.js +0 -43
  16. package/dist/devices/heatPump.js +2 -50
  17. package/dist/devices/laundryDryer.js +3 -62
  18. package/dist/devices/laundryWasher.js +4 -70
  19. package/dist/devices/microwaveOven.js +5 -88
  20. package/dist/devices/oven.js +0 -85
  21. package/dist/devices/refrigerator.js +0 -102
  22. package/dist/devices/roboticVacuumCleaner.js +9 -100
  23. package/dist/devices/solarPower.js +0 -38
  24. package/dist/devices/speaker.js +0 -84
  25. package/dist/devices/temperatureControl.js +3 -24
  26. package/dist/devices/waterHeater.js +2 -82
  27. package/dist/dgram/coap.js +13 -126
  28. package/dist/dgram/dgram.js +2 -114
  29. package/dist/dgram/mb_coap.js +3 -41
  30. package/dist/dgram/mb_mdns.js +15 -80
  31. package/dist/dgram/mdns.js +137 -299
  32. package/dist/dgram/multicast.js +1 -62
  33. package/dist/dgram/unicast.js +0 -54
  34. package/dist/frontend.js +35 -455
  35. package/dist/frontendTypes.js +0 -45
  36. package/dist/helpers.js +0 -53
  37. package/dist/index.js +0 -25
  38. package/dist/jestutils/export.js +0 -1
  39. package/dist/jestutils/jestHelpers.js +13 -368
  40. package/dist/logger/export.js +0 -1
  41. package/dist/matter/behaviors.js +0 -2
  42. package/dist/matter/clusters.js +0 -2
  43. package/dist/matter/devices.js +0 -2
  44. package/dist/matter/endpoints.js +0 -2
  45. package/dist/matter/export.js +0 -3
  46. package/dist/matter/types.js +0 -3
  47. package/dist/matterNode.js +8 -369
  48. package/dist/matterbridge.js +46 -807
  49. package/dist/matterbridgeAccessoryPlatform.js +0 -38
  50. package/dist/matterbridgeBehaviors.js +5 -68
  51. package/dist/matterbridgeDeviceTypes.js +14 -635
  52. package/dist/matterbridgeDynamicPlatform.js +0 -38
  53. package/dist/matterbridgeEndpoint.js +53 -1444
  54. package/dist/matterbridgeEndpointHelpers.js +20 -483
  55. package/dist/matterbridgeEndpointTypes.js +0 -25
  56. package/dist/matterbridgePlatform.js +1 -450
  57. package/dist/matterbridgeTypes.js +0 -26
  58. package/dist/pluginManager.js +5 -341
  59. package/dist/shelly.js +7 -178
  60. package/dist/storage/export.js +0 -1
  61. package/dist/update.js +1 -93
  62. package/dist/utils/colorUtils.js +2 -97
  63. package/dist/utils/commandLine.js +0 -60
  64. package/dist/utils/copyDirectory.js +0 -37
  65. package/dist/utils/createDirectory.js +0 -33
  66. package/dist/utils/createZip.js +2 -47
  67. package/dist/utils/deepCopy.js +0 -39
  68. package/dist/utils/deepEqual.js +1 -72
  69. package/dist/utils/error.js +0 -42
  70. package/dist/utils/export.js +0 -1
  71. package/dist/utils/format.js +0 -49
  72. package/dist/utils/hex.js +0 -124
  73. package/dist/utils/inspector.js +1 -69
  74. package/dist/utils/isvalid.js +0 -101
  75. package/dist/utils/network.js +5 -96
  76. package/dist/utils/spawn.js +1 -71
  77. package/dist/utils/tracker.js +1 -64
  78. package/dist/utils/wait.js +8 -60
  79. package/dist/workerGlobalPrefix.js +5 -37
  80. package/dist/workerTypes.js +0 -24
  81. package/dist/workers.js +4 -68
  82. package/frontend/build/assets/index.js +4 -4
  83. package/frontend/build/assets/vendor_mui.js +1 -1
  84. package/frontend/package.json +1 -1
  85. package/npm-shrinkwrap.json +14 -10
  86. package/package.json +1 -2
  87. package/dist/broadcastServer.d.ts +0 -136
  88. package/dist/broadcastServer.d.ts.map +0 -1
  89. package/dist/broadcastServer.js.map +0 -1
  90. package/dist/broadcastServerTypes.d.ts +0 -841
  91. package/dist/broadcastServerTypes.d.ts.map +0 -1
  92. package/dist/broadcastServerTypes.js.map +0 -1
  93. package/dist/cli.d.ts +0 -30
  94. package/dist/cli.d.ts.map +0 -1
  95. package/dist/cli.js.map +0 -1
  96. package/dist/cliEmitter.d.ts +0 -50
  97. package/dist/cliEmitter.d.ts.map +0 -1
  98. package/dist/cliEmitter.js.map +0 -1
  99. package/dist/cliHistory.d.ts +0 -48
  100. package/dist/cliHistory.d.ts.map +0 -1
  101. package/dist/cliHistory.js.map +0 -1
  102. package/dist/clusters/export.d.ts +0 -2
  103. package/dist/clusters/export.d.ts.map +0 -1
  104. package/dist/clusters/export.js.map +0 -1
  105. package/dist/deviceManager.d.ts +0 -135
  106. package/dist/deviceManager.d.ts.map +0 -1
  107. package/dist/deviceManager.js.map +0 -1
  108. package/dist/devices/airConditioner.d.ts +0 -98
  109. package/dist/devices/airConditioner.d.ts.map +0 -1
  110. package/dist/devices/airConditioner.js.map +0 -1
  111. package/dist/devices/batteryStorage.d.ts +0 -48
  112. package/dist/devices/batteryStorage.d.ts.map +0 -1
  113. package/dist/devices/batteryStorage.js.map +0 -1
  114. package/dist/devices/cooktop.d.ts +0 -61
  115. package/dist/devices/cooktop.d.ts.map +0 -1
  116. package/dist/devices/cooktop.js.map +0 -1
  117. package/dist/devices/dishwasher.d.ts +0 -71
  118. package/dist/devices/dishwasher.d.ts.map +0 -1
  119. package/dist/devices/dishwasher.js.map +0 -1
  120. package/dist/devices/evse.d.ts +0 -76
  121. package/dist/devices/evse.d.ts.map +0 -1
  122. package/dist/devices/evse.js.map +0 -1
  123. package/dist/devices/export.d.ts +0 -17
  124. package/dist/devices/export.d.ts.map +0 -1
  125. package/dist/devices/export.js.map +0 -1
  126. package/dist/devices/extractorHood.d.ts +0 -46
  127. package/dist/devices/extractorHood.d.ts.map +0 -1
  128. package/dist/devices/extractorHood.js.map +0 -1
  129. package/dist/devices/heatPump.d.ts +0 -47
  130. package/dist/devices/heatPump.d.ts.map +0 -1
  131. package/dist/devices/heatPump.js.map +0 -1
  132. package/dist/devices/laundryDryer.d.ts +0 -67
  133. package/dist/devices/laundryDryer.d.ts.map +0 -1
  134. package/dist/devices/laundryDryer.js.map +0 -1
  135. package/dist/devices/laundryWasher.d.ts +0 -81
  136. package/dist/devices/laundryWasher.d.ts.map +0 -1
  137. package/dist/devices/laundryWasher.js.map +0 -1
  138. package/dist/devices/microwaveOven.d.ts +0 -168
  139. package/dist/devices/microwaveOven.d.ts.map +0 -1
  140. package/dist/devices/microwaveOven.js.map +0 -1
  141. package/dist/devices/oven.d.ts +0 -105
  142. package/dist/devices/oven.d.ts.map +0 -1
  143. package/dist/devices/oven.js.map +0 -1
  144. package/dist/devices/refrigerator.d.ts +0 -118
  145. package/dist/devices/refrigerator.d.ts.map +0 -1
  146. package/dist/devices/refrigerator.js.map +0 -1
  147. package/dist/devices/roboticVacuumCleaner.d.ts +0 -112
  148. package/dist/devices/roboticVacuumCleaner.d.ts.map +0 -1
  149. package/dist/devices/roboticVacuumCleaner.js.map +0 -1
  150. package/dist/devices/solarPower.d.ts +0 -40
  151. package/dist/devices/solarPower.d.ts.map +0 -1
  152. package/dist/devices/solarPower.js.map +0 -1
  153. package/dist/devices/speaker.d.ts +0 -87
  154. package/dist/devices/speaker.d.ts.map +0 -1
  155. package/dist/devices/speaker.js.map +0 -1
  156. package/dist/devices/temperatureControl.d.ts +0 -166
  157. package/dist/devices/temperatureControl.d.ts.map +0 -1
  158. package/dist/devices/temperatureControl.js.map +0 -1
  159. package/dist/devices/waterHeater.d.ts +0 -111
  160. package/dist/devices/waterHeater.d.ts.map +0 -1
  161. package/dist/devices/waterHeater.js.map +0 -1
  162. package/dist/dgram/coap.d.ts +0 -205
  163. package/dist/dgram/coap.d.ts.map +0 -1
  164. package/dist/dgram/coap.js.map +0 -1
  165. package/dist/dgram/dgram.d.ts +0 -141
  166. package/dist/dgram/dgram.d.ts.map +0 -1
  167. package/dist/dgram/dgram.js.map +0 -1
  168. package/dist/dgram/mb_coap.d.ts +0 -24
  169. package/dist/dgram/mb_coap.d.ts.map +0 -1
  170. package/dist/dgram/mb_coap.js.map +0 -1
  171. package/dist/dgram/mb_mdns.d.ts +0 -24
  172. package/dist/dgram/mb_mdns.d.ts.map +0 -1
  173. package/dist/dgram/mb_mdns.js.map +0 -1
  174. package/dist/dgram/mdns.d.ts +0 -290
  175. package/dist/dgram/mdns.d.ts.map +0 -1
  176. package/dist/dgram/mdns.js.map +0 -1
  177. package/dist/dgram/multicast.d.ts +0 -67
  178. package/dist/dgram/multicast.d.ts.map +0 -1
  179. package/dist/dgram/multicast.js.map +0 -1
  180. package/dist/dgram/unicast.d.ts +0 -56
  181. package/dist/dgram/unicast.d.ts.map +0 -1
  182. package/dist/dgram/unicast.js.map +0 -1
  183. package/dist/frontend.d.ts +0 -238
  184. package/dist/frontend.d.ts.map +0 -1
  185. package/dist/frontend.js.map +0 -1
  186. package/dist/frontendTypes.d.ts +0 -529
  187. package/dist/frontendTypes.d.ts.map +0 -1
  188. package/dist/frontendTypes.js.map +0 -1
  189. package/dist/helpers.d.ts +0 -48
  190. package/dist/helpers.d.ts.map +0 -1
  191. package/dist/helpers.js.map +0 -1
  192. package/dist/index.d.ts +0 -34
  193. package/dist/index.d.ts.map +0 -1
  194. package/dist/index.js.map +0 -1
  195. package/dist/jestutils/export.d.ts +0 -2
  196. package/dist/jestutils/export.d.ts.map +0 -1
  197. package/dist/jestutils/export.js.map +0 -1
  198. package/dist/jestutils/jestHelpers.d.ts +0 -340
  199. package/dist/jestutils/jestHelpers.d.ts.map +0 -1
  200. package/dist/jestutils/jestHelpers.js.map +0 -1
  201. package/dist/logger/export.d.ts +0 -2
  202. package/dist/logger/export.d.ts.map +0 -1
  203. package/dist/logger/export.js.map +0 -1
  204. package/dist/matter/behaviors.d.ts +0 -2
  205. package/dist/matter/behaviors.d.ts.map +0 -1
  206. package/dist/matter/behaviors.js.map +0 -1
  207. package/dist/matter/clusters.d.ts +0 -2
  208. package/dist/matter/clusters.d.ts.map +0 -1
  209. package/dist/matter/clusters.js.map +0 -1
  210. package/dist/matter/devices.d.ts +0 -2
  211. package/dist/matter/devices.d.ts.map +0 -1
  212. package/dist/matter/devices.js.map +0 -1
  213. package/dist/matter/endpoints.d.ts +0 -2
  214. package/dist/matter/endpoints.d.ts.map +0 -1
  215. package/dist/matter/endpoints.js.map +0 -1
  216. package/dist/matter/export.d.ts +0 -5
  217. package/dist/matter/export.d.ts.map +0 -1
  218. package/dist/matter/export.js.map +0 -1
  219. package/dist/matter/types.d.ts +0 -3
  220. package/dist/matter/types.d.ts.map +0 -1
  221. package/dist/matter/types.js.map +0 -1
  222. package/dist/matterNode.d.ts +0 -342
  223. package/dist/matterNode.d.ts.map +0 -1
  224. package/dist/matterNode.js.map +0 -1
  225. package/dist/matterbridge.d.ts +0 -493
  226. package/dist/matterbridge.d.ts.map +0 -1
  227. package/dist/matterbridge.js.map +0 -1
  228. package/dist/matterbridgeAccessoryPlatform.d.ts +0 -41
  229. package/dist/matterbridgeAccessoryPlatform.d.ts.map +0 -1
  230. package/dist/matterbridgeAccessoryPlatform.js.map +0 -1
  231. package/dist/matterbridgeBehaviors.d.ts +0 -2404
  232. package/dist/matterbridgeBehaviors.d.ts.map +0 -1
  233. package/dist/matterbridgeBehaviors.js.map +0 -1
  234. package/dist/matterbridgeDeviceTypes.d.ts +0 -698
  235. package/dist/matterbridgeDeviceTypes.d.ts.map +0 -1
  236. package/dist/matterbridgeDeviceTypes.js.map +0 -1
  237. package/dist/matterbridgeDynamicPlatform.d.ts +0 -41
  238. package/dist/matterbridgeDynamicPlatform.d.ts.map +0 -1
  239. package/dist/matterbridgeDynamicPlatform.js.map +0 -1
  240. package/dist/matterbridgeEndpoint.d.ts +0 -1507
  241. package/dist/matterbridgeEndpoint.d.ts.map +0 -1
  242. package/dist/matterbridgeEndpoint.js.map +0 -1
  243. package/dist/matterbridgeEndpointHelpers.d.ts +0 -787
  244. package/dist/matterbridgeEndpointHelpers.d.ts.map +0 -1
  245. package/dist/matterbridgeEndpointHelpers.js.map +0 -1
  246. package/dist/matterbridgeEndpointTypes.d.ts +0 -166
  247. package/dist/matterbridgeEndpointTypes.d.ts.map +0 -1
  248. package/dist/matterbridgeEndpointTypes.js.map +0 -1
  249. package/dist/matterbridgePlatform.d.ts +0 -537
  250. package/dist/matterbridgePlatform.d.ts.map +0 -1
  251. package/dist/matterbridgePlatform.js.map +0 -1
  252. package/dist/matterbridgeTypes.d.ts +0 -251
  253. package/dist/matterbridgeTypes.d.ts.map +0 -1
  254. package/dist/matterbridgeTypes.js.map +0 -1
  255. package/dist/pluginManager.d.ts +0 -372
  256. package/dist/pluginManager.d.ts.map +0 -1
  257. package/dist/pluginManager.js.map +0 -1
  258. package/dist/shelly.d.ts +0 -181
  259. package/dist/shelly.d.ts.map +0 -1
  260. package/dist/shelly.js.map +0 -1
  261. package/dist/storage/export.d.ts +0 -2
  262. package/dist/storage/export.d.ts.map +0 -1
  263. package/dist/storage/export.js.map +0 -1
  264. package/dist/update.d.ts +0 -84
  265. package/dist/update.d.ts.map +0 -1
  266. package/dist/update.js.map +0 -1
  267. package/dist/utils/colorUtils.d.ts +0 -101
  268. package/dist/utils/colorUtils.d.ts.map +0 -1
  269. package/dist/utils/colorUtils.js.map +0 -1
  270. package/dist/utils/commandLine.d.ts +0 -66
  271. package/dist/utils/commandLine.d.ts.map +0 -1
  272. package/dist/utils/commandLine.js.map +0 -1
  273. package/dist/utils/copyDirectory.d.ts +0 -35
  274. package/dist/utils/copyDirectory.d.ts.map +0 -1
  275. package/dist/utils/copyDirectory.js.map +0 -1
  276. package/dist/utils/createDirectory.d.ts +0 -34
  277. package/dist/utils/createDirectory.d.ts.map +0 -1
  278. package/dist/utils/createDirectory.js.map +0 -1
  279. package/dist/utils/createZip.d.ts +0 -39
  280. package/dist/utils/createZip.d.ts.map +0 -1
  281. package/dist/utils/createZip.js.map +0 -1
  282. package/dist/utils/deepCopy.d.ts +0 -32
  283. package/dist/utils/deepCopy.d.ts.map +0 -1
  284. package/dist/utils/deepCopy.js.map +0 -1
  285. package/dist/utils/deepEqual.d.ts +0 -54
  286. package/dist/utils/deepEqual.d.ts.map +0 -1
  287. package/dist/utils/deepEqual.js.map +0 -1
  288. package/dist/utils/error.d.ts +0 -45
  289. package/dist/utils/error.d.ts.map +0 -1
  290. package/dist/utils/error.js.map +0 -1
  291. package/dist/utils/export.d.ts +0 -13
  292. package/dist/utils/export.d.ts.map +0 -1
  293. package/dist/utils/export.js.map +0 -1
  294. package/dist/utils/format.d.ts +0 -53
  295. package/dist/utils/format.d.ts.map +0 -1
  296. package/dist/utils/format.js.map +0 -1
  297. package/dist/utils/hex.d.ts +0 -89
  298. package/dist/utils/hex.d.ts.map +0 -1
  299. package/dist/utils/hex.js.map +0 -1
  300. package/dist/utils/inspector.d.ts +0 -87
  301. package/dist/utils/inspector.d.ts.map +0 -1
  302. package/dist/utils/inspector.js.map +0 -1
  303. package/dist/utils/isvalid.d.ts +0 -103
  304. package/dist/utils/isvalid.d.ts.map +0 -1
  305. package/dist/utils/isvalid.js.map +0 -1
  306. package/dist/utils/network.d.ts +0 -111
  307. package/dist/utils/network.d.ts.map +0 -1
  308. package/dist/utils/network.js.map +0 -1
  309. package/dist/utils/spawn.d.ts +0 -33
  310. package/dist/utils/spawn.d.ts.map +0 -1
  311. package/dist/utils/spawn.js.map +0 -1
  312. package/dist/utils/tracker.d.ts +0 -108
  313. package/dist/utils/tracker.d.ts.map +0 -1
  314. package/dist/utils/tracker.js.map +0 -1
  315. package/dist/utils/wait.d.ts +0 -54
  316. package/dist/utils/wait.d.ts.map +0 -1
  317. package/dist/utils/wait.js.map +0 -1
  318. package/dist/workerGlobalPrefix.d.ts +0 -25
  319. package/dist/workerGlobalPrefix.d.ts.map +0 -1
  320. package/dist/workerGlobalPrefix.js.map +0 -1
  321. package/dist/workerTypes.d.ts +0 -52
  322. package/dist/workerTypes.d.ts.map +0 -1
  323. package/dist/workerTypes.js.map +0 -1
  324. package/dist/workers.d.ts +0 -69
  325. package/dist/workers.d.ts.map +0 -1
  326. package/dist/workers.js.map +0 -1
@@ -1,38 +1,13 @@
1
- /**
2
- * @description This file contains the Jest helpers.
3
- * @file src/helpers.test.ts
4
- * @author Luca Liguori
5
- * @created 2025-09-03
6
- * @version 1.0.14
7
- * @license Apache-2.0
8
- *
9
- * Copyright 2025, 2026, 2027 Luca Liguori.
10
- *
11
- * Licensed under the Apache License, Version 2.0 (the "License");
12
- * you may not use this file except in compliance with the License.
13
- * You may obtain a copy of the License at
14
- *
15
- * http://www.apache.org/licenses/LICENSE-2.0
16
- *
17
- * Unless required by applicable law or agreed to in writing, software
18
- * distributed under the License is distributed on an "AS IS" BASIS,
19
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
- * See the License for the specific language governing permissions and
21
- * limitations under the License.
22
- */
23
1
  import { rmSync } from 'node:fs';
24
2
  import { inspect } from 'node:util';
25
3
  import path from 'node:path';
26
- // Imports from node-ansi-logger
27
4
  import { AnsiLogger, er, rs, UNDERLINE, UNDERLINEOFF } from 'node-ansi-logger';
28
- // Imports from @matter
29
5
  import { LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, Environment, Lifecycle } from '@matter/general';
30
6
  import { Endpoint, ServerNode, ServerNodeStore } from '@matter/node';
31
7
  import { DeviceTypeId, VendorId } from '@matter/types/datatype';
32
8
  import { AggregatorEndpoint } from '@matter/node/endpoints';
33
9
  import { MdnsService } from '@matter/main/protocol';
34
10
  import { NodeStorageManager } from 'node-persist-manager';
35
- // Imports from Matterbridge
36
11
  import { Matterbridge } from '../matterbridge.js';
37
12
  import { MATTER_STORAGE_NAME, NODE_STORAGE_DIR } from '../matterbridgeTypes.js';
38
13
  import { bridge } from '../matterbridgeDeviceTypes.js';
@@ -41,7 +16,6 @@ import { Frontend } from '../frontend.js';
41
16
  import { BroadcastServer } from '../broadcastServer.js';
42
17
  export const originalProcessArgv = Object.freeze([...process.argv]);
43
18
  export const originalProcessEnv = Object.freeze({ ...process.env });
44
- // Spy on logger methods
45
19
  export let loggerLogSpy;
46
20
  export let loggerDebugSpy;
47
21
  export let loggerInfoSpy;
@@ -49,18 +23,15 @@ export let loggerNoticeSpy;
49
23
  export let loggerWarnSpy;
50
24
  export let loggerErrorSpy;
51
25
  export let loggerFatalSpy;
52
- // Spy on console methods
53
26
  export let consoleLogSpy;
54
27
  export let consoleDebugSpy;
55
28
  export let consoleInfoSpy;
56
29
  export let consoleWarnSpy;
57
30
  export let consoleErrorSpy;
58
- // Spy on Matterbridge methods
59
31
  export let addBridgedEndpointSpy;
60
32
  export let removeBridgedEndpointSpy;
61
33
  export let removeAllBridgedEndpointsSpy;
62
34
  export let addVirtualEndpointSpy;
63
- // Spy on PluginManager methods
64
35
  export let installPluginSpy;
65
36
  export let uninstallPluginSpy;
66
37
  export let addPluginSpy;
@@ -71,14 +42,12 @@ export let shutdownPluginSpy;
71
42
  export let removePluginSpy;
72
43
  export let enablePluginSpy;
73
44
  export let disablePluginSpy;
74
- // Spy on Frontend methods
75
45
  export let wssSendSnackbarMessageSpy;
76
46
  export let wssSendCloseSnackbarMessageSpy;
77
47
  export let wssSendUpdateRequiredSpy;
78
48
  export let wssSendRefreshRequiredSpy;
79
49
  export let wssSendRestartRequiredSpy;
80
50
  export let wssSendRestartNotRequiredSpy;
81
- // Spy on BroadcastServer methods
82
51
  export let broadcastServerIsWorkerRequestSpy;
83
52
  export let broadcastServerIsWorkerResponseSpy;
84
53
  export let broadcastServerBroadcastSpy;
@@ -96,29 +65,12 @@ export let environment;
96
65
  export let server;
97
66
  export let aggregator;
98
67
  export let log;
99
- /**
100
- * Setup the Jest environment:
101
- * - it will remove any existing home directory
102
- * - setup the spies for logging
103
- *
104
- * @param {string} name The name of the test suite.
105
- * @param {boolean} debug If true, the logging is not mocked.
106
- *
107
- * @example
108
- * ```typescript
109
- * import { consoleDebugSpy, consoleErrorSpy, consoleInfoSpy, consoleLogSpy, consoleWarnSpy, loggerLogSpy, setDebug, setupTest } from './jestutils/jestHelpers.js';
110
- *
111
- * // Setup the test environment
112
- * await setupTest(NAME, false);
113
- * ```
114
- */
115
68
  export async function setupTest(name, debug = false) {
116
69
  expect(name).toBeDefined();
117
70
  expect(typeof name).toBe('string');
118
71
  expect(name.length).toBeGreaterThanOrEqual(4);
119
72
  NAME = name;
120
73
  HOMEDIR = path.join('jest', name);
121
- // Cleanup any existing home directory
122
74
  rmSync(HOMEDIR, { recursive: true, force: true });
123
75
  const { jest } = await import('@jest/globals');
124
76
  loggerDebugSpy = jest.spyOn(AnsiLogger.prototype, 'debug');
@@ -169,26 +121,8 @@ export async function setupTest(name, debug = false) {
169
121
  broadcastServerRequestSpy = jest.spyOn(BroadcastServer.prototype, 'request');
170
122
  broadcastServerRespondSpy = jest.spyOn(BroadcastServer.prototype, 'respond');
171
123
  broadcastServerFetchSpy = jest.spyOn(BroadcastServer.prototype, 'fetch');
172
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
173
124
  broadcastMessageHandlerSpy = jest.spyOn(BroadcastServer.prototype, 'broadcastMessageHandler');
174
125
  }
175
- /**
176
- * Set or unset the debug mode.
177
- *
178
- * @param {boolean} debug If true, the logging is not mocked.
179
- * @returns {Promise<void>} A promise that resolves when the debug mode is set.
180
- *
181
- * @example
182
- * ```typescript
183
- * // Set the debug mode in test environment
184
- * await setDebug(true);
185
- * ```
186
- *
187
- * ```typescript
188
- * // Reset the debug mode in test environment
189
- * await setDebug(false);
190
- * ```
191
- */
192
126
  export async function setDebug(debug) {
193
127
  const { jest } = await import('@jest/globals');
194
128
  if (debug) {
@@ -214,41 +148,18 @@ export async function setDebug(debug) {
214
148
  consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
215
149
  }
216
150
  }
217
- /**
218
- * Create and start a fully initialized Matterbridge instance for testing.
219
- *
220
- * @param {('bridge' | 'childbridge' | 'controller' | '')} bridgeMode The bridge mode to start the Matterbridge instance in.
221
- * @param {number} frontendPort The frontend port number.
222
- * @param {number} matterPort The matter port number.
223
- * @param {number} passcode The passcode number.
224
- * @param {number} discriminator The discriminator number.
225
- * @param {number} pluginSize The expected number of plugins.
226
- * @param {number} devicesSize The expected number of devices.
227
- * @returns {Promise<Matterbridge>} The Matterbridge instance.
228
- *
229
- * @example
230
- * ```typescript
231
- * // Create and start a fully initialized Matterbridge instance for testing.
232
- * await startMatterbridge();
233
- * ```
234
- */
235
151
  export async function startMatterbridge(bridgeMode = 'bridge', frontendPort = 8283, matterPort = 5540, passcode = 20252026, discriminator = 3840, pluginSize = 0, devicesSize = 0) {
236
- // Set the environment variables
237
152
  process.env['MATTERBRIDGE_START_MATTER_INTERVAL_MS'] = '100';
238
153
  process.env['MATTERBRIDGE_PAUSE_MATTER_INTERVAL_MS'] = '100';
239
- // Setup the process arguments
240
154
  process.argv.length = 0;
241
155
  process.argv.push(...originalProcessArgv, '-novirtual', '-debug', '-verbose', '-logger', 'debug', '-matterlogger', 'debug', bridgeMode === '' ? '-test' : '-' + bridgeMode, '-homedir', HOMEDIR, '-frontend', frontendPort.toString(), '-port', matterPort.toString(), '-passcode', passcode.toString(), '-discriminator', discriminator.toString());
242
- // Load Matterbridge instance and initialize it
243
156
  matterbridge = await Matterbridge.loadInstance(true);
244
157
  expect(matterbridge).toBeDefined();
245
158
  expect(matterbridge.profile).toBeUndefined();
246
159
  expect(matterbridge.bridgeMode).toBe(bridgeMode);
247
- // Get the frontend, plugins and devices
248
160
  frontend = matterbridge.frontend;
249
161
  plugins = matterbridge.plugins;
250
162
  devices = matterbridge.devices;
251
- // @ts-expect-error - access to private member for testing
252
163
  expect(matterbridge.initialized).toBeTruthy();
253
164
  expect(matterbridge.log).toBeDefined();
254
165
  expect(matterbridge.rootDirectory).toBe(path.resolve('./'));
@@ -261,15 +172,10 @@ export async function startMatterbridge(bridgeMode = 'bridge', frontendPort = 82
261
172
  expect(devices).toBeDefined();
262
173
  expect(devices.size).toBe(devicesSize);
263
174
  expect(frontend).toBeDefined();
264
- // @ts-expect-error - access to private member for testing
265
175
  expect(frontend.listening).toBeTruthy();
266
- // @ts-expect-error - access to private member for testing
267
176
  expect(frontend.httpServer).toBeDefined();
268
- // @ts-expect-error - access to private member for testing
269
177
  expect(frontend.httpsServer).toBeUndefined();
270
- // @ts-expect-error - access to private member for testing
271
178
  expect(frontend.expressApp).toBeDefined();
272
- // @ts-expect-error - access to private member for testing
273
179
  expect(frontend.webSocketServer).toBeDefined();
274
180
  expect(matterbridge.nodeStorage).toBeDefined();
275
181
  expect(matterbridge.nodeContext).toBeDefined();
@@ -307,51 +213,25 @@ export async function startMatterbridge(bridgeMode = 'bridge', frontendPort = 82
307
213
  });
308
214
  });
309
215
  }
310
- expect(loggerLogSpy).toHaveBeenCalledWith("info" /* LogLevel.INFO */, `The frontend http server is listening on ${UNDERLINE}http://${matterbridge.systemInformation.ipv4Address}:${frontendPort}${UNDERLINEOFF}${rs}`);
216
+ expect(loggerLogSpy).toHaveBeenCalledWith("info", `The frontend http server is listening on ${UNDERLINE}http://${matterbridge.systemInformation.ipv4Address}:${frontendPort}${UNDERLINEOFF}${rs}`);
311
217
  if (bridgeMode === 'bridge') {
312
- expect(loggerLogSpy).toHaveBeenCalledWith("notice" /* LogLevel.NOTICE */, `Starting Matterbridge server node`);
313
- expect(loggerLogSpy).toHaveBeenCalledWith("notice" /* LogLevel.NOTICE */, `Server node for Matterbridge is online`);
314
- expect(loggerLogSpy).toHaveBeenCalledWith("debug" /* LogLevel.DEBUG */, `Starting start matter interval in bridge mode...`);
315
- expect(loggerLogSpy).toHaveBeenCalledWith("debug" /* LogLevel.DEBUG */, `Cleared startMatterInterval interval in bridge mode`);
316
- expect(loggerLogSpy).toHaveBeenCalledWith("notice" /* LogLevel.NOTICE */, `Matterbridge bridge started successfully`);
218
+ expect(loggerLogSpy).toHaveBeenCalledWith("notice", `Starting Matterbridge server node`);
219
+ expect(loggerLogSpy).toHaveBeenCalledWith("notice", `Server node for Matterbridge is online`);
220
+ expect(loggerLogSpy).toHaveBeenCalledWith("debug", `Starting start matter interval in bridge mode...`);
221
+ expect(loggerLogSpy).toHaveBeenCalledWith("debug", `Cleared startMatterInterval interval in bridge mode`);
222
+ expect(loggerLogSpy).toHaveBeenCalledWith("notice", `Matterbridge bridge started successfully`);
317
223
  }
318
224
  else if (bridgeMode === 'childbridge') {
319
- expect(loggerLogSpy).toHaveBeenCalledWith("debug" /* LogLevel.DEBUG */, `Starting start matter interval in childbridge mode...`);
320
- expect(loggerLogSpy).toHaveBeenCalledWith("debug" /* LogLevel.DEBUG */, `Cleared startMatterInterval interval in childbridge mode`);
321
- expect(loggerLogSpy).toHaveBeenCalledWith("notice" /* LogLevel.NOTICE */, `Matterbridge childbridge started successfully`);
225
+ expect(loggerLogSpy).toHaveBeenCalledWith("debug", `Starting start matter interval in childbridge mode...`);
226
+ expect(loggerLogSpy).toHaveBeenCalledWith("debug", `Cleared startMatterInterval interval in childbridge mode`);
227
+ expect(loggerLogSpy).toHaveBeenCalledWith("notice", `Matterbridge childbridge started successfully`);
322
228
  }
323
229
  return matterbridge;
324
230
  }
325
- /**
326
- * Stop the fully initialized Matterbridge instance.
327
- *
328
- * @param {cleanupPause} cleanupPause The pause duration before cleanup. Default is 10 ms.
329
- * @param {destroyPause} destroyPause The pause duration before destruction. Default is 250 ms.
330
- *
331
- * @example
332
- * ```typescript
333
- * // Stop the fully initialized Matterbridge instance.
334
- * await stopMatterbridge();
335
- * ```
336
- */
337
231
  export async function stopMatterbridge(cleanupPause = 10, destroyPause = 250) {
338
232
  await destroyMatterbridgeEnvironment(cleanupPause, destroyPause);
339
233
  }
340
- /**
341
- * Create a Matterbridge instance for testing without initializing it.
342
- *
343
- * @param {string} name - Name for the environment (jest/name).
344
- * @returns {Promise<Matterbridge>} The Matterbridge instance.
345
- *
346
- * @example
347
- * ```typescript
348
- * // Create Matterbridge environment
349
- * await createMatterbridgeEnvironment(NAME);
350
- * await startMatterbridgeEnvironment(MATTER_PORT);
351
- * ```
352
- */
353
234
  export async function createMatterbridgeEnvironment(name) {
354
- // Create a MatterbridgeEdge instance
355
235
  matterbridge = await Matterbridge.loadInstance(false);
356
236
  expect(matterbridge).toBeDefined();
357
237
  expect(matterbridge).toBeInstanceOf(Matterbridge);
@@ -362,52 +242,28 @@ export async function createMatterbridgeEnvironment(name) {
362
242
  matterbridge.matterbridgeDirectory = path.join('jest', name, '.matterbridge');
363
243
  matterbridge.matterbridgePluginDirectory = path.join('jest', name, 'Matterbridge');
364
244
  matterbridge.matterbridgeCertDirectory = path.join('jest', name, '.mattercert');
365
- matterbridge.log.logLevel = "debug" /* LogLevel.DEBUG */;
366
- log = new AnsiLogger({ logName: 'Plugin platform', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: "debug" /* LogLevel.DEBUG */ });
367
- // Get the frontend, plugins and devices
245
+ matterbridge.log.logLevel = "debug";
246
+ log = new AnsiLogger({ logName: 'Plugin platform', logTimestampFormat: 4, logLevel: "debug" });
368
247
  frontend = matterbridge.frontend;
369
248
  plugins = matterbridge.plugins;
370
249
  devices = matterbridge.devices;
371
- // Setup matter environment
372
- // @ts-expect-error - access to private member for testing
373
250
  matterbridge.environment = createTestEnvironment(name);
374
- // @ts-expect-error - access to private member for testing
375
251
  expect(matterbridge.environment).toBeDefined();
376
- // @ts-expect-error - access to private member for testing
377
252
  expect(matterbridge.environment).toBeInstanceOf(Environment);
378
253
  return matterbridge;
379
254
  }
380
- /**
381
- * Start the matterbridge environment.
382
- * Only node storage, matter storage and the server and aggregator nodes are started.
383
- *
384
- * @param {number} port The matter server port.
385
- * @returns {Promise<[ServerNode<ServerNode.RootEndpoint>, Endpoint<AggregatorEndpoint>]>} The started server and aggregator.
386
- *
387
- * @example
388
- * ```typescript
389
- * // Create Matterbridge environment
390
- * await createMatterbridgeEnvironment(NAME);
391
- * await startMatterbridgeEnvironment(MATTER_PORT);
392
- * ```
393
- */
394
255
  export async function startMatterbridgeEnvironment(port = 5540) {
395
- // Create the node storage
396
256
  matterbridge.nodeStorage = new NodeStorageManager({ dir: path.join(matterbridge.matterbridgeDirectory, NODE_STORAGE_DIR), writeQueue: false, expiredInterval: undefined, logging: false });
397
257
  matterbridge.nodeContext = await matterbridge.nodeStorage.createStorage('matterbridge');
398
- // Create the matter storage
399
- // @ts-expect-error - access to private member for testing
400
258
  await matterbridge.startMatterStorage();
401
259
  expect(matterbridge.matterStorageService).toBeDefined();
402
260
  expect(matterbridge.matterStorageManager).toBeDefined();
403
261
  expect(matterbridge.matterbridgeContext).toBeDefined();
404
- // @ts-expect-error - access to private member for testing
405
262
  server = await matterbridge.createServerNode(matterbridge.matterbridgeContext, port);
406
263
  expect(server).toBeDefined();
407
264
  expect(server).toBeDefined();
408
265
  expect(server.lifecycle.isReady).toBeTruthy();
409
266
  matterbridge.serverNode = server;
410
- // @ts-expect-error - access to private member for testing
411
267
  aggregator = await matterbridge.createAggregatorNode(matterbridge.matterbridgeContext);
412
268
  expect(aggregator).toBeDefined();
413
269
  matterbridge.aggregatorNode = aggregator;
@@ -415,7 +271,6 @@ export async function startMatterbridgeEnvironment(port = 5540) {
415
271
  expect(server.parts.has(aggregator.id)).toBeTruthy();
416
272
  expect(server.parts.has(aggregator)).toBeTruthy();
417
273
  expect(aggregator.lifecycle.isReady).toBeTruthy();
418
- // Wait for the server to be online
419
274
  expect(server.lifecycle.isOnline).toBeFalsy();
420
275
  await new Promise((resolve) => {
421
276
  server.lifecycle.online.on(async () => {
@@ -423,7 +278,6 @@ export async function startMatterbridgeEnvironment(port = 5540) {
423
278
  });
424
279
  server.start();
425
280
  });
426
- // Check if the server is online
427
281
  expect(server.lifecycle.isReady).toBeTruthy();
428
282
  expect(server.lifecycle.isOnline).toBeTruthy();
429
283
  expect(server.lifecycle.isCommissioned).toBeFalsy();
@@ -435,27 +289,11 @@ export async function startMatterbridgeEnvironment(port = 5540) {
435
289
  expect(aggregator.lifecycle.isPartsReady).toBeTruthy();
436
290
  expect(aggregator.lifecycle.hasId).toBeTruthy();
437
291
  expect(aggregator.lifecycle.hasNumber).toBeTruthy();
438
- // Ensure the queue is empty and pause
439
292
  await flushAsync();
440
293
  return [server, aggregator];
441
294
  }
442
- /**
443
- * Add a matterbridge platform for testing.
444
- *
445
- * @param {MatterbridgePlatform} platform The platform to add.
446
- * @param {string} [name] Optional name of the platform.
447
- *
448
- * @example
449
- * ```typescript
450
- * platform = new Platform(matterbridge, log, config);
451
- * // Add the platform to the Matterbridge environment
452
- * addMatterbridgePlatform(platform);
453
- * ```
454
- */
455
295
  export function addMatterbridgePlatform(platform, name) {
456
296
  expect(platform).toBeDefined();
457
- // Setup the platform MatterNode helpers
458
- // @ts-expect-error - setMatterNode is intentionally private
459
297
  platform.setMatterNode?.(matterbridge.addBridgedEndpoint.bind(matterbridge), matterbridge.removeBridgedEndpoint.bind(matterbridge), matterbridge.removeAllBridgedEndpoints.bind(matterbridge), matterbridge.addVirtualEndpoint.bind(matterbridge));
460
298
  if (name)
461
299
  platform.config.name = name;
@@ -466,7 +304,6 @@ export function addMatterbridgePlatform(platform, name) {
466
304
  expect(platform.version).toBeDefined();
467
305
  expect(platform.config.debug).toBeDefined();
468
306
  expect(platform.config.unregisterOnShutdown).toBeDefined();
469
- // @ts-expect-error accessing private member for testing
470
307
  matterbridge.plugins._plugins.set(platform.config.name, {
471
308
  name: platform.config.name,
472
309
  path: './',
@@ -478,150 +315,65 @@ export function addMatterbridgePlatform(platform, name) {
478
315
  });
479
316
  platform['name'] = platform.config.name;
480
317
  }
481
- /**
482
- * Stop the matterbridge environment
483
- *
484
- * @example
485
- * ```typescript
486
- * // Destroy Matterbridge environment
487
- * await stopMatterbridgeEnvironment();
488
- * await destroyMatterbridgeEnvironment();
489
- * ```
490
- */
491
318
  export async function stopMatterbridgeEnvironment() {
492
319
  expect(matterbridge).toBeDefined();
493
320
  expect(server).toBeDefined();
494
321
  expect(aggregator).toBeDefined();
495
- // Flush any pending endpoint number persistence
496
322
  await flushAllEndpointNumberPersistence(server);
497
- // Ensure all endpoint numbers are persisted
498
323
  await assertAllEndpointNumbersPersisted(server);
499
- // Close the server node
500
324
  expect(server.lifecycle.isReady).toBeTruthy();
501
325
  expect(server.lifecycle.isOnline).toBeTruthy();
502
326
  await server.close();
503
327
  expect(server.lifecycle.isReady).toBeTruthy();
504
328
  expect(server.lifecycle.isOnline).toBeFalsy();
505
- // Stop the matter storage
506
- // @ts-expect-error - access to private member for testing
507
329
  await matterbridge.stopMatterStorage();
508
330
  expect(matterbridge.matterStorageService).not.toBeDefined();
509
331
  expect(matterbridge.matterStorageManager).not.toBeDefined();
510
332
  expect(matterbridge.matterbridgeContext).not.toBeDefined();
511
- // Stop the node storage
512
333
  await matterbridge.nodeContext?.close();
513
334
  matterbridge.nodeContext = undefined;
514
335
  await matterbridge.nodeStorage?.close();
515
336
  matterbridge.nodeStorage = undefined;
516
- // Ensure the queue is empty and pause
517
337
  await flushAsync();
518
338
  }
519
- /**
520
- * Destroy the matterbridge environment
521
- *
522
- * @param {number} cleanupPause The timeout for the destroy operation (default 10ms).
523
- * @param {number} destroyPause The pause duration after cleanup before destroying the instance (default 250ms).
524
- *
525
- * @example
526
- * ```typescript
527
- * // Destroy Matterbridge environment
528
- * await stopMatterbridgeEnvironment();
529
- * await destroyMatterbridgeEnvironment();
530
- * ```
531
- */
532
339
  export async function destroyMatterbridgeEnvironment(cleanupPause = 10, destroyPause = 250) {
533
- // Destroy a matterbridge instance
534
340
  await destroyInstance(matterbridge, cleanupPause, destroyPause);
535
- // Close the mDNS service
536
341
  await closeMdnsInstance(matterbridge);
537
- // Reset the singleton instance
538
- // @ts-expect-error - accessing private member for testing
539
342
  Matterbridge.instance = undefined;
540
343
  }
541
- /**
542
- * Destroy a matterbridge instance
543
- *
544
- * @param {Matterbridge} matterbridge The matterbridge instance to destroy.
545
- * @param {number} cleanupPause The pause duration to wait for the cleanup to complete in milliseconds (default 10ms).
546
- * @param {number} destroyPause The pause duration to wait after cleanup before destroying the instance in milliseconds (default 250ms).
547
- */
548
344
  export async function destroyInstance(matterbridge, cleanupPause = 10, destroyPause = 250) {
549
- // Cleanup the Matterbridge instance
550
- // @ts-expect-error - accessing private member for testing
551
345
  await matterbridge.cleanup('destroying instance...', false, cleanupPause);
552
- // Pause before destroying the instance
553
346
  if (destroyPause > 0)
554
347
  await flushAsync(undefined, undefined, destroyPause);
555
348
  }
556
- /**
557
- * Close the mDNS instance in the matterbridge environment.
558
- *
559
- * @param {Matterbridge} matterbridge The matterbridge instance.
560
- * @returns {Promise<void>} A promise that resolves when the mDNS instance is closed.
561
- */
562
349
  export async function closeMdnsInstance(matterbridge) {
563
- // TODO: matter.js 0.16.0 - provide close method to close the mDNS service
564
- // @ts-expect-error - accessing private member for testing
565
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
566
350
  const mdns = matterbridge.environment.get(MdnsService);
567
351
  if (mdns && mdns[Symbol.asyncDispose] && typeof mdns[Symbol.asyncDispose] === 'function')
568
352
  await mdns[Symbol.asyncDispose]();
569
353
  if (mdns && mdns.close && typeof mdns.close === 'function')
570
354
  await mdns.close();
571
355
  }
572
- /**
573
- * Create a matter test environment for testing:
574
- * - it will remove any existing home directory
575
- * - setup the matter environment with name, debug logging and ANSI format
576
- * - setup the mDNS service in the environment
577
- *
578
- * @param {string} name - Name for the environment (jest/name).
579
- * @returns {Environment} - The default matter environment.
580
- */
581
356
  export function createTestEnvironment(name) {
582
357
  expect(name).toBeDefined();
583
358
  expect(typeof name).toBe('string');
584
- expect(name.length).toBeGreaterThanOrEqual(4); // avoid accidental deletion of short paths like "/" or "C:\"
585
- // Cleanup any existing home directory
359
+ expect(name.length).toBeGreaterThanOrEqual(4);
586
360
  rmSync(path.join('jest', name), { recursive: true, force: true });
587
- // Setup the matter environment
588
361
  environment = Environment.default;
589
362
  environment.vars.set('log.level', MatterLogLevel.DEBUG);
590
363
  environment.vars.set('log.format', MatterLogFormat.ANSI);
591
364
  environment.vars.set('path.root', path.join('jest', name, '.matterbridge', MATTER_STORAGE_NAME));
592
365
  environment.vars.set('runtime.signals', false);
593
366
  environment.vars.set('runtime.exitcode', false);
594
- // Setup the mDNS service in the environment
595
367
  new MdnsService(environment);
596
- // await environment.get(MdnsService)?.construction.ready;
597
368
  return environment;
598
369
  }
599
- /**
600
- * Destroy the matter test environment by closing the mDNS service.
601
- *
602
- * @returns {Promise<void>} A promise that resolves when the test environment is destroyed.
603
- */
604
370
  export async function destroyTestEnvironment() {
605
- // stop the mDNS service
606
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
607
371
  const mdns = environment.get(MdnsService);
608
372
  if (mdns && typeof mdns[Symbol.asyncDispose] === 'function')
609
373
  await mdns[Symbol.asyncDispose]();
610
374
  if (mdns && typeof mdns.close === 'function')
611
375
  await mdns.close();
612
376
  }
613
- /**
614
- * Advance the Node.js event loop deterministically to allow chained asynchronous work (Promises scheduled in
615
- * microtasks and follow‑up macrotasks) to complete inside tests without adding arbitrary long timeouts.
616
- *
617
- * NOTE: This does not guarantee OS level network IO completion—only JavaScript task queue progression inside the
618
- * current process.
619
- *
620
- * @param {number} ticks Number of macrotask (setImmediate) turns to yield (default 3).
621
- * @param {number} microTurns Number of microtask drains (Promise.resolve chains) after macrotask yielding (default 10).
622
- * @param {number} pause Final timer delay in ms; set 0 to disable (default 250ms).
623
- * @returns {Promise<void>} Resolves after the requested event loop advancement has completed.
624
- */
625
377
  export async function flushAsync(ticks = 3, microTurns = 10, pause = 250) {
626
378
  for (let i = 0; i < ticks; i++)
627
379
  await new Promise((resolve) => setImmediate(resolve));
@@ -630,33 +382,16 @@ export async function flushAsync(ticks = 3, microTurns = 10, pause = 250) {
630
382
  if (pause)
631
383
  await new Promise((resolve) => setTimeout(resolve, pause));
632
384
  }
633
- /**
634
- * Summarize live libuv handles/requests inside a process.
635
- *
636
- * @param {AnsiLogger} log - Logger to use for output
637
- *
638
- * @returns {number} - The total number of active handles and requests
639
- */
640
385
  export function logKeepAlives(log) {
641
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
642
386
  const handles = process._getActiveHandles?.() ?? [];
643
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
644
387
  const requests = process._getActiveRequests?.() ?? [];
645
- // istanbul ignore next
646
388
  const fmtHandle = (h, i) => {
647
389
  const ctor = h?.constructor?.name ?? 'Unknown';
648
- // Timer-like?
649
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
650
390
  const hasRef = typeof h?.hasRef === 'function' ? h.hasRef() : undefined;
651
- // MessagePort?
652
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
653
391
  const isPort = h?.constructor?.name?.includes('MessagePort');
654
- // Socket/Server?
655
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
656
392
  const fd = h?.fd ?? h?._handle?.fd;
657
393
  return { i, type: ctor, hasRef, isPort, fd };
658
394
  };
659
- // istanbul ignore next
660
395
  const fmtReq = (r, i) => {
661
396
  const ctor = r?.constructor?.name ?? 'Unknown';
662
397
  return { i, type: ctor };
@@ -665,7 +400,6 @@ export function logKeepAlives(log) {
665
400
  handles: handles.map(fmtHandle),
666
401
  requests: requests.map(fmtReq),
667
402
  };
668
- // istanbul ignore next if
669
403
  if (summary.handles.length === 0 && summary.requests.length === 0) {
670
404
  log?.debug('KeepAlive: no active handles or requests.');
671
405
  }
@@ -677,19 +411,6 @@ export function logKeepAlives(log) {
677
411
  }
678
412
  return summary.handles.length + summary.requests.length;
679
413
  }
680
- /**
681
- * Flush (await) the lazy endpoint number persistence mechanism used by matter.js.
682
- *
683
- * Background:
684
- * assignNumber() batches persistence (store.saveNumber + updating __nextNumber__) via an internal promise (#numbersPersisted).
685
- * Calling endpointStores.close() waits for the current batch only. If new endpoints were added in the same macrotask
686
- * cycle additional micro/macro turns might be needed to ensure the batch started. We defensively yield macrotasks
687
- * (setImmediate) and then await close() multiple rounds.
688
- *
689
- * @param {ServerNode} targetServer The server whose endpoint numbering persistence should be flushed.
690
- * @param {number} rounds Number of macrotask + close cycles to run (2 is usually sufficient; 1 often works).
691
- * @returns {Promise<void>} Resolves when pending number persistence batches have completed.
692
- */
693
414
  export async function flushAllEndpointNumberPersistence(targetServer, rounds = 2) {
694
415
  const nodeStore = targetServer.env.get(ServerNodeStore);
695
416
  for (let i = 0; i < rounds; i++) {
@@ -697,12 +418,6 @@ export async function flushAllEndpointNumberPersistence(targetServer, rounds = 2
697
418
  await nodeStore.endpointStores.close();
698
419
  }
699
420
  }
700
- /**
701
- * Collect all endpoints in the server endpoint tree (root -> descendants).
702
- *
703
- * @param {Endpoint} root Root endpoint (typically the ServerNode root endpoint cast as Endpoint).
704
- * @returns {Endpoint[]} Flat array including the root and every descendant once.
705
- */
706
421
  function collectAllEndpoints(root) {
707
422
  const list = [];
708
423
  const walk = (ep) => {
@@ -716,26 +431,14 @@ function collectAllEndpoints(root) {
716
431
  walk(root);
717
432
  return list;
718
433
  }
719
- /**
720
- * Assert that every endpoint attached to the server has an assigned and (batch-)persisted endpoint number.
721
- *
722
- * This waits for any outstanding number persistence batch (endpointStores.close()), then traverses the endpoint
723
- * graph and asserts:
724
- * - Root endpoint: number is 0 (allowing undefined to coerce to 0 via nullish coalescing check).
725
- * - All other endpoints: number > 0.
726
- *
727
- * @param {ServerNode} targetServer The server whose endpoint numbers are verified.
728
- * @returns {Promise<void>} Resolves when assertions complete.
729
- */
730
434
  export async function assertAllEndpointNumbersPersisted(targetServer) {
731
435
  const nodeStore = targetServer.env.get(ServerNodeStore);
732
- // Ensure any pending persistence finished (flush any in-flight batch promise)
733
436
  await nodeStore.endpointStores.close();
734
437
  const all = collectAllEndpoints(targetServer);
735
438
  for (const ep of all) {
736
439
  const store = nodeStore.storeForEndpoint(ep);
737
440
  if (ep.maybeNumber === 0) {
738
- expect(store.number ?? 0).toBe(0); // root
441
+ expect(store.number ?? 0).toBe(0);
739
442
  }
740
443
  else {
741
444
  expect(store.number).toBeGreaterThan(0);
@@ -743,42 +446,23 @@ export async function assertAllEndpointNumbersPersisted(targetServer) {
743
446
  }
744
447
  return all.length;
745
448
  }
746
- /**
747
- * Close the server node stores to flush any pending endpoint number persistence.
748
- *
749
- * @param {ServerNode} targetServer The server whose endpoint stores should be closed.
750
- * @returns {Promise<void>} Resolves when the stores have been closed.
751
- */
752
449
  export async function closeServerNodeStores(targetServer) {
753
- // Close endpoint stores to avoid number persistence issues
754
450
  if (!targetServer)
755
451
  targetServer = server;
756
452
  await targetServer?.env.get(ServerNodeStore)?.endpointStores.close();
757
453
  }
758
- /**
759
- * Start a matter server node for testing.
760
- *
761
- * @param {string} name Name of the server (used for logging and product description).
762
- * @param {number} port TCP port to listen on.
763
- * @param {DeviceTypeId} deviceType Device type identifier for the server node.
764
- * @returns {Promise<[ServerNode<ServerNode.RootEndpoint>, Endpoint<AggregatorEndpoint>]>} Resolves to an array containing the created ServerNode and its AggregatorNode.
765
- */
766
454
  export async function startServerNode(name, port, deviceType = bridge.code) {
767
455
  const { randomBytes } = await import('node:crypto');
768
456
  const random = randomBytes(8).toString('hex');
769
- // Create the server node
770
457
  server = await ServerNode.create({
771
458
  id: name + 'ServerNode',
772
- // Provide the environment
773
459
  environment,
774
- // Provide Node announcement settings
775
460
  productDescription: {
776
461
  name: name + 'ServerNode',
777
462
  deviceType: DeviceTypeId(deviceType),
778
463
  vendorId: VendorId(0xfff1),
779
464
  productId: 0x8000,
780
465
  },
781
- // Provide defaults for the BasicInformation cluster on the Root endpoint
782
466
  basicInformation: {
783
467
  vendorId: VendorId(0xfff1),
784
468
  vendorName: 'Matterbridge',
@@ -791,39 +475,32 @@ export async function startServerNode(name, port, deviceType = bridge.code) {
791
475
  serialNumber: 'SN' + random,
792
476
  uniqueId: 'UI' + random,
793
477
  },
794
- // Provide Network relevant configuration like the port
795
478
  network: {
796
479
  listeningAddressIpv4: undefined,
797
480
  listeningAddressIpv6: undefined,
798
481
  port,
799
482
  },
800
- // Provide the certificate for the device
801
483
  operationalCredentials: {
802
484
  certification: undefined,
803
485
  },
804
486
  });
805
487
  expect(server).toBeDefined();
806
488
  expect(server.lifecycle.isReady).toBeTruthy();
807
- // Create the aggregator node
808
489
  aggregator = new Endpoint(AggregatorEndpoint, {
809
490
  id: name + 'AggregatorNode',
810
491
  });
811
492
  expect(aggregator).toBeDefined();
812
- // Add the aggregator to the server
813
493
  await server.add(aggregator);
814
494
  expect(server.parts.has(aggregator.id)).toBeTruthy();
815
495
  expect(server.parts.has(aggregator)).toBeTruthy();
816
496
  expect(aggregator.lifecycle.isReady).toBeTruthy();
817
- // Run the server
818
497
  expect(server.lifecycle.isOnline).toBeFalsy();
819
- // Wait for the server to be online
820
498
  await new Promise((resolve) => {
821
499
  server.lifecycle.online.on(async () => {
822
500
  resolve();
823
501
  });
824
502
  server.start();
825
503
  });
826
- // Check if the server is online
827
504
  expect(server.lifecycle.isReady).toBeTruthy();
828
505
  expect(server.lifecycle.isOnline).toBeTruthy();
829
506
  expect(server.lifecycle.isCommissioned).toBeFalsy();
@@ -835,53 +512,31 @@ export async function startServerNode(name, port, deviceType = bridge.code) {
835
512
  expect(aggregator.lifecycle.isPartsReady).toBeTruthy();
836
513
  expect(aggregator.lifecycle.hasId).toBeTruthy();
837
514
  expect(aggregator.lifecycle.hasNumber).toBeTruthy();
838
- // Ensure the queue is empty and pause 250ms
839
515
  await flushAsync();
840
516
  return [server, aggregator];
841
517
  }
842
- /**
843
- * Stop a matter server node.
844
- *
845
- * @param {ServerNode<ServerNode.RootEndpoint>} server The server to stop.
846
- * @returns {Promise<void>} Resolves when the server has stopped.
847
- */
848
518
  export async function stopServerNode(server) {
849
- // Flush any pending endpoint number persistence
850
519
  await flushAllEndpointNumberPersistence(server);
851
- // Ensure all endpoint numbers are persisted
852
520
  await assertAllEndpointNumbersPersisted(server);
853
- // Stop the server
854
521
  expect(server).toBeDefined();
855
522
  expect(server.lifecycle.isReady).toBeTruthy();
856
523
  expect(server.lifecycle.isOnline).toBeTruthy();
857
524
  await server.close();
858
525
  expect(server.lifecycle.isReady).toBeTruthy();
859
526
  expect(server.lifecycle.isOnline).toBeFalsy();
860
- // stop the mDNS service
861
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
862
527
  const mdns = environment.get(MdnsService);
863
528
  if (mdns && typeof mdns[Symbol.asyncDispose] === 'function')
864
529
  await mdns[Symbol.asyncDispose]();
865
530
  if (mdns && typeof mdns.close === 'function')
866
531
  await mdns.close();
867
- // Ensure the queue is empty and pause 250ms
868
532
  await flushAsync();
869
533
  }
870
- /**
871
- * Add a device (endpoint) to a matter server node or an aggregator.
872
- *
873
- * @param {ServerNode<ServerNode.RootEndpoint> | Endpoint<AggregatorEndpoint>} owner The server or aggregator to add the device to.
874
- * @param {Endpoint} device The device to add.
875
- * @param {number} pause The pause time in milliseconds after addition (default 10ms).
876
- * @returns {Promise<void>} Resolves when the device has been added and is ready.
877
- */
878
534
  export async function addDevice(owner, device, pause = 10) {
879
535
  expect(owner).toBeDefined();
880
536
  expect(device).toBeDefined();
881
537
  expect(owner.lifecycle.isReady).toBeTruthy();
882
538
  expect(owner.construction.status).toBe(Lifecycle.Status.Active);
883
539
  expect(owner.lifecycle.isPartsReady).toBeTruthy();
884
- // istanbul ignore next
885
540
  try {
886
541
  await owner.add(device);
887
542
  }
@@ -901,21 +556,12 @@ export async function addDevice(owner, device, pause = 10) {
901
556
  await flushAsync(undefined, undefined, pause);
902
557
  return true;
903
558
  }
904
- /**
905
- * Delete a device (endpoint) from a matter server node or an aggregator.
906
- *
907
- * @param {ServerNode<ServerNode.RootEndpoint> | Endpoint<AggregatorEndpoint>} owner The server or aggregator to remove the device from.
908
- * @param {Endpoint} device The device to remove.
909
- * @param {number} pause The pause time in milliseconds after deletion (default 10ms).
910
- * @returns {Promise<void>} Resolves when the device has been removed and is no longer ready.
911
- */
912
559
  export async function deleteDevice(owner, device, pause = 10) {
913
560
  expect(owner).toBeDefined();
914
561
  expect(device).toBeDefined();
915
562
  expect(owner.lifecycle.isReady).toBeTruthy();
916
563
  expect(owner.construction.status).toBe(Lifecycle.Status.Active);
917
564
  expect(owner.lifecycle.isPartsReady).toBeTruthy();
918
- // istanbul ignore next
919
565
  try {
920
566
  await device.delete();
921
567
  }
@@ -935,4 +581,3 @@ export async function deleteDevice(owner, device, pause = 10) {
935
581
  await flushAsync(undefined, undefined, pause);
936
582
  return true;
937
583
  }
938
- //# sourceMappingURL=jestHelpers.js.map