matterbridge 3.4.2 → 3.4.3-dev-20251207-3ce5a0e

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