matterbridge 3.4.0 → 3.4.1-dev-20251127-826b2bf

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