@matterbridge/core 3.5.3 → 3.5.4-edge-20260211-1ea4e31

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