matterbridge 3.3.7 → 3.3.8-dev-20251114-9b65e59

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 (308) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README-SERVICE-OPT.md +4 -4
  3. package/README.md +4 -0
  4. package/dist/broadcastServer.js +1 -93
  5. package/dist/broadcastServerTypes.js +0 -24
  6. package/dist/cli.js +1 -97
  7. package/dist/cliEmitter.js +0 -37
  8. package/dist/cliHistory.js +0 -38
  9. package/dist/clusters/export.js +0 -2
  10. package/dist/defaultConfigSchema.js +0 -24
  11. package/dist/deviceManager.js +1 -105
  12. package/dist/devices/airConditioner.js +1 -58
  13. package/dist/devices/batteryStorage.js +2 -49
  14. package/dist/devices/cooktop.js +1 -56
  15. package/dist/devices/dishwasher.js +1 -58
  16. package/dist/devices/evse.js +11 -75
  17. package/dist/devices/export.js +0 -5
  18. package/dist/devices/extractorHood.js +1 -43
  19. package/dist/devices/heatPump.js +3 -51
  20. package/dist/devices/laundryDryer.js +4 -63
  21. package/dist/devices/laundryWasher.js +5 -71
  22. package/dist/devices/microwaveOven.js +6 -89
  23. package/dist/devices/oven.js +1 -86
  24. package/dist/devices/refrigerator.js +2 -104
  25. package/dist/devices/roboticVacuumCleaner.js +10 -101
  26. package/dist/devices/solarPower.js +1 -39
  27. package/dist/devices/speaker.js +1 -85
  28. package/dist/devices/temperatureControl.js +3 -24
  29. package/dist/devices/waterHeater.js +3 -83
  30. package/dist/dgram/coap.js +13 -126
  31. package/dist/dgram/dgram.js +2 -114
  32. package/dist/dgram/mb_coap.js +3 -41
  33. package/dist/dgram/mb_mdns.js +15 -80
  34. package/dist/dgram/mdns.js +137 -299
  35. package/dist/dgram/multicast.js +1 -62
  36. package/dist/dgram/unicast.js +0 -54
  37. package/dist/frontend.js +40 -452
  38. package/dist/frontendTypes.js +0 -45
  39. package/dist/helpers.js +0 -53
  40. package/dist/index.js +1 -25
  41. package/dist/jestutils/export.js +1 -0
  42. package/dist/{utils → jestutils}/jestHelpers.js +167 -175
  43. package/dist/logger/export.js +0 -1
  44. package/dist/matter/behaviors.js +0 -2
  45. package/dist/matter/clusters.js +0 -2
  46. package/dist/matter/devices.js +0 -2
  47. package/dist/matter/endpoints.js +0 -2
  48. package/dist/matter/export.js +0 -3
  49. package/dist/matter/types.js +0 -3
  50. package/dist/matterbridge.js +50 -838
  51. package/dist/matterbridgeAccessoryPlatform.js +0 -37
  52. package/dist/matterbridgeBehaviors.js +5 -68
  53. package/dist/matterbridgeDeviceTypes.js +27 -653
  54. package/dist/matterbridgeDynamicPlatform.js +0 -37
  55. package/dist/matterbridgeEndpoint.js +73 -1429
  56. package/dist/matterbridgeEndpointHelpers.js +42 -475
  57. package/dist/matterbridgeEndpointTypes.js +3 -0
  58. package/dist/matterbridgePlatform.js +18 -341
  59. package/dist/matterbridgeTypes.js +0 -26
  60. package/dist/pluginManager.js +5 -340
  61. package/dist/shelly.js +7 -168
  62. package/dist/storage/export.js +0 -1
  63. package/dist/update.js +0 -69
  64. package/dist/utils/colorUtils.js +2 -97
  65. package/dist/utils/commandLine.js +0 -60
  66. package/dist/utils/copyDirectory.js +1 -38
  67. package/dist/utils/createDirectory.js +0 -33
  68. package/dist/utils/createZip.js +2 -47
  69. package/dist/utils/deepCopy.js +0 -39
  70. package/dist/utils/deepEqual.js +1 -72
  71. package/dist/utils/error.js +2 -43
  72. package/dist/utils/export.js +0 -1
  73. package/dist/utils/format.js +0 -49
  74. package/dist/utils/hex.js +0 -124
  75. package/dist/utils/inspector.js +1 -69
  76. package/dist/utils/isvalid.js +0 -101
  77. package/dist/utils/network.js +5 -96
  78. package/dist/utils/spawn.js +0 -71
  79. package/dist/utils/tracker.js +1 -64
  80. package/dist/utils/wait.js +8 -60
  81. package/npm-shrinkwrap.json +8 -8
  82. package/package.json +5 -2
  83. package/scripts/fetch-chip.mjs +100 -0
  84. package/dist/broadcastServer.d.ts +0 -115
  85. package/dist/broadcastServer.d.ts.map +0 -1
  86. package/dist/broadcastServer.js.map +0 -1
  87. package/dist/broadcastServerTypes.d.ts +0 -806
  88. package/dist/broadcastServerTypes.d.ts.map +0 -1
  89. package/dist/broadcastServerTypes.js.map +0 -1
  90. package/dist/cli.d.ts +0 -30
  91. package/dist/cli.d.ts.map +0 -1
  92. package/dist/cli.js.map +0 -1
  93. package/dist/cliEmitter.d.ts +0 -50
  94. package/dist/cliEmitter.d.ts.map +0 -1
  95. package/dist/cliEmitter.js.map +0 -1
  96. package/dist/cliHistory.d.ts +0 -48
  97. package/dist/cliHistory.d.ts.map +0 -1
  98. package/dist/cliHistory.js.map +0 -1
  99. package/dist/clusters/export.d.ts +0 -2
  100. package/dist/clusters/export.d.ts.map +0 -1
  101. package/dist/clusters/export.js.map +0 -1
  102. package/dist/defaultConfigSchema.d.ts +0 -28
  103. package/dist/defaultConfigSchema.d.ts.map +0 -1
  104. package/dist/defaultConfigSchema.js.map +0 -1
  105. package/dist/deviceManager.d.ts +0 -128
  106. package/dist/deviceManager.d.ts.map +0 -1
  107. package/dist/deviceManager.js.map +0 -1
  108. package/dist/devices/airConditioner.d.ts +0 -98
  109. package/dist/devices/airConditioner.d.ts.map +0 -1
  110. package/dist/devices/airConditioner.js.map +0 -1
  111. package/dist/devices/batteryStorage.d.ts +0 -48
  112. package/dist/devices/batteryStorage.d.ts.map +0 -1
  113. package/dist/devices/batteryStorage.js.map +0 -1
  114. package/dist/devices/cooktop.d.ts +0 -60
  115. package/dist/devices/cooktop.d.ts.map +0 -1
  116. package/dist/devices/cooktop.js.map +0 -1
  117. package/dist/devices/dishwasher.d.ts +0 -71
  118. package/dist/devices/dishwasher.d.ts.map +0 -1
  119. package/dist/devices/dishwasher.js.map +0 -1
  120. package/dist/devices/evse.d.ts +0 -76
  121. package/dist/devices/evse.d.ts.map +0 -1
  122. package/dist/devices/evse.js.map +0 -1
  123. package/dist/devices/export.d.ts +0 -17
  124. package/dist/devices/export.d.ts.map +0 -1
  125. package/dist/devices/export.js.map +0 -1
  126. package/dist/devices/extractorHood.d.ts +0 -46
  127. package/dist/devices/extractorHood.d.ts.map +0 -1
  128. package/dist/devices/extractorHood.js.map +0 -1
  129. package/dist/devices/heatPump.d.ts +0 -47
  130. package/dist/devices/heatPump.d.ts.map +0 -1
  131. package/dist/devices/heatPump.js.map +0 -1
  132. package/dist/devices/laundryDryer.d.ts +0 -67
  133. package/dist/devices/laundryDryer.d.ts.map +0 -1
  134. package/dist/devices/laundryDryer.js.map +0 -1
  135. package/dist/devices/laundryWasher.d.ts +0 -81
  136. package/dist/devices/laundryWasher.d.ts.map +0 -1
  137. package/dist/devices/laundryWasher.js.map +0 -1
  138. package/dist/devices/microwaveOven.d.ts +0 -168
  139. package/dist/devices/microwaveOven.d.ts.map +0 -1
  140. package/dist/devices/microwaveOven.js.map +0 -1
  141. package/dist/devices/oven.d.ts +0 -105
  142. package/dist/devices/oven.d.ts.map +0 -1
  143. package/dist/devices/oven.js.map +0 -1
  144. package/dist/devices/refrigerator.d.ts +0 -118
  145. package/dist/devices/refrigerator.d.ts.map +0 -1
  146. package/dist/devices/refrigerator.js.map +0 -1
  147. package/dist/devices/roboticVacuumCleaner.d.ts +0 -112
  148. package/dist/devices/roboticVacuumCleaner.d.ts.map +0 -1
  149. package/dist/devices/roboticVacuumCleaner.js.map +0 -1
  150. package/dist/devices/solarPower.d.ts +0 -40
  151. package/dist/devices/solarPower.d.ts.map +0 -1
  152. package/dist/devices/solarPower.js.map +0 -1
  153. package/dist/devices/speaker.d.ts +0 -87
  154. package/dist/devices/speaker.d.ts.map +0 -1
  155. package/dist/devices/speaker.js.map +0 -1
  156. package/dist/devices/temperatureControl.d.ts +0 -166
  157. package/dist/devices/temperatureControl.d.ts.map +0 -1
  158. package/dist/devices/temperatureControl.js.map +0 -1
  159. package/dist/devices/waterHeater.d.ts +0 -111
  160. package/dist/devices/waterHeater.d.ts.map +0 -1
  161. package/dist/devices/waterHeater.js.map +0 -1
  162. package/dist/dgram/coap.d.ts +0 -205
  163. package/dist/dgram/coap.d.ts.map +0 -1
  164. package/dist/dgram/coap.js.map +0 -1
  165. package/dist/dgram/dgram.d.ts +0 -141
  166. package/dist/dgram/dgram.d.ts.map +0 -1
  167. package/dist/dgram/dgram.js.map +0 -1
  168. package/dist/dgram/mb_coap.d.ts +0 -24
  169. package/dist/dgram/mb_coap.d.ts.map +0 -1
  170. package/dist/dgram/mb_coap.js.map +0 -1
  171. package/dist/dgram/mb_mdns.d.ts +0 -24
  172. package/dist/dgram/mb_mdns.d.ts.map +0 -1
  173. package/dist/dgram/mb_mdns.js.map +0 -1
  174. package/dist/dgram/mdns.d.ts +0 -290
  175. package/dist/dgram/mdns.d.ts.map +0 -1
  176. package/dist/dgram/mdns.js.map +0 -1
  177. package/dist/dgram/multicast.d.ts +0 -67
  178. package/dist/dgram/multicast.d.ts.map +0 -1
  179. package/dist/dgram/multicast.js.map +0 -1
  180. package/dist/dgram/unicast.d.ts +0 -56
  181. package/dist/dgram/unicast.d.ts.map +0 -1
  182. package/dist/dgram/unicast.js.map +0 -1
  183. package/dist/frontend.d.ts +0 -238
  184. package/dist/frontend.d.ts.map +0 -1
  185. package/dist/frontend.js.map +0 -1
  186. package/dist/frontendTypes.d.ts +0 -529
  187. package/dist/frontendTypes.d.ts.map +0 -1
  188. package/dist/frontendTypes.js.map +0 -1
  189. package/dist/helpers.d.ts +0 -48
  190. package/dist/helpers.d.ts.map +0 -1
  191. package/dist/helpers.js.map +0 -1
  192. package/dist/index.d.ts +0 -33
  193. package/dist/index.d.ts.map +0 -1
  194. package/dist/index.js.map +0 -1
  195. package/dist/logger/export.d.ts +0 -2
  196. package/dist/logger/export.d.ts.map +0 -1
  197. package/dist/logger/export.js.map +0 -1
  198. package/dist/matter/behaviors.d.ts +0 -2
  199. package/dist/matter/behaviors.d.ts.map +0 -1
  200. package/dist/matter/behaviors.js.map +0 -1
  201. package/dist/matter/clusters.d.ts +0 -2
  202. package/dist/matter/clusters.d.ts.map +0 -1
  203. package/dist/matter/clusters.js.map +0 -1
  204. package/dist/matter/devices.d.ts +0 -2
  205. package/dist/matter/devices.d.ts.map +0 -1
  206. package/dist/matter/devices.js.map +0 -1
  207. package/dist/matter/endpoints.d.ts +0 -2
  208. package/dist/matter/endpoints.d.ts.map +0 -1
  209. package/dist/matter/endpoints.js.map +0 -1
  210. package/dist/matter/export.d.ts +0 -5
  211. package/dist/matter/export.d.ts.map +0 -1
  212. package/dist/matter/export.js.map +0 -1
  213. package/dist/matter/types.d.ts +0 -3
  214. package/dist/matter/types.d.ts.map +0 -1
  215. package/dist/matter/types.js.map +0 -1
  216. package/dist/matterbridge.d.ts +0 -478
  217. package/dist/matterbridge.d.ts.map +0 -1
  218. package/dist/matterbridge.js.map +0 -1
  219. package/dist/matterbridgeAccessoryPlatform.d.ts +0 -42
  220. package/dist/matterbridgeAccessoryPlatform.d.ts.map +0 -1
  221. package/dist/matterbridgeAccessoryPlatform.js.map +0 -1
  222. package/dist/matterbridgeBehaviors.d.ts +0 -2404
  223. package/dist/matterbridgeBehaviors.d.ts.map +0 -1
  224. package/dist/matterbridgeBehaviors.js.map +0 -1
  225. package/dist/matterbridgeDeviceTypes.d.ts +0 -770
  226. package/dist/matterbridgeDeviceTypes.d.ts.map +0 -1
  227. package/dist/matterbridgeDeviceTypes.js.map +0 -1
  228. package/dist/matterbridgeDynamicPlatform.d.ts +0 -42
  229. package/dist/matterbridgeDynamicPlatform.d.ts.map +0 -1
  230. package/dist/matterbridgeDynamicPlatform.js.map +0 -1
  231. package/dist/matterbridgeEndpoint.d.ts +0 -1556
  232. package/dist/matterbridgeEndpoint.d.ts.map +0 -1
  233. package/dist/matterbridgeEndpoint.js.map +0 -1
  234. package/dist/matterbridgeEndpointHelpers.d.ts +0 -758
  235. package/dist/matterbridgeEndpointHelpers.d.ts.map +0 -1
  236. package/dist/matterbridgeEndpointHelpers.js.map +0 -1
  237. package/dist/matterbridgePlatform.d.ts +0 -402
  238. package/dist/matterbridgePlatform.d.ts.map +0 -1
  239. package/dist/matterbridgePlatform.js.map +0 -1
  240. package/dist/matterbridgeTypes.d.ts +0 -239
  241. package/dist/matterbridgeTypes.d.ts.map +0 -1
  242. package/dist/matterbridgeTypes.js.map +0 -1
  243. package/dist/pluginManager.d.ts +0 -371
  244. package/dist/pluginManager.d.ts.map +0 -1
  245. package/dist/pluginManager.js.map +0 -1
  246. package/dist/shelly.d.ts +0 -174
  247. package/dist/shelly.d.ts.map +0 -1
  248. package/dist/shelly.js.map +0 -1
  249. package/dist/storage/export.d.ts +0 -2
  250. package/dist/storage/export.d.ts.map +0 -1
  251. package/dist/storage/export.js.map +0 -1
  252. package/dist/update.d.ts +0 -75
  253. package/dist/update.d.ts.map +0 -1
  254. package/dist/update.js.map +0 -1
  255. package/dist/utils/colorUtils.d.ts +0 -101
  256. package/dist/utils/colorUtils.d.ts.map +0 -1
  257. package/dist/utils/colorUtils.js.map +0 -1
  258. package/dist/utils/commandLine.d.ts +0 -66
  259. package/dist/utils/commandLine.d.ts.map +0 -1
  260. package/dist/utils/commandLine.js.map +0 -1
  261. package/dist/utils/copyDirectory.d.ts +0 -33
  262. package/dist/utils/copyDirectory.d.ts.map +0 -1
  263. package/dist/utils/copyDirectory.js.map +0 -1
  264. package/dist/utils/createDirectory.d.ts +0 -34
  265. package/dist/utils/createDirectory.d.ts.map +0 -1
  266. package/dist/utils/createDirectory.js.map +0 -1
  267. package/dist/utils/createZip.d.ts +0 -39
  268. package/dist/utils/createZip.d.ts.map +0 -1
  269. package/dist/utils/createZip.js.map +0 -1
  270. package/dist/utils/deepCopy.d.ts +0 -32
  271. package/dist/utils/deepCopy.d.ts.map +0 -1
  272. package/dist/utils/deepCopy.js.map +0 -1
  273. package/dist/utils/deepEqual.d.ts +0 -54
  274. package/dist/utils/deepEqual.d.ts.map +0 -1
  275. package/dist/utils/deepEqual.js.map +0 -1
  276. package/dist/utils/error.d.ts +0 -44
  277. package/dist/utils/error.d.ts.map +0 -1
  278. package/dist/utils/error.js.map +0 -1
  279. package/dist/utils/export.d.ts +0 -13
  280. package/dist/utils/export.d.ts.map +0 -1
  281. package/dist/utils/export.js.map +0 -1
  282. package/dist/utils/format.d.ts +0 -53
  283. package/dist/utils/format.d.ts.map +0 -1
  284. package/dist/utils/format.js.map +0 -1
  285. package/dist/utils/hex.d.ts +0 -89
  286. package/dist/utils/hex.d.ts.map +0 -1
  287. package/dist/utils/hex.js.map +0 -1
  288. package/dist/utils/inspector.d.ts +0 -87
  289. package/dist/utils/inspector.d.ts.map +0 -1
  290. package/dist/utils/inspector.js.map +0 -1
  291. package/dist/utils/isvalid.d.ts +0 -103
  292. package/dist/utils/isvalid.d.ts.map +0 -1
  293. package/dist/utils/isvalid.js.map +0 -1
  294. package/dist/utils/jestHelpers.d.ts +0 -139
  295. package/dist/utils/jestHelpers.d.ts.map +0 -1
  296. package/dist/utils/jestHelpers.js.map +0 -1
  297. package/dist/utils/network.d.ts +0 -101
  298. package/dist/utils/network.d.ts.map +0 -1
  299. package/dist/utils/network.js.map +0 -1
  300. package/dist/utils/spawn.d.ts +0 -35
  301. package/dist/utils/spawn.d.ts.map +0 -1
  302. package/dist/utils/spawn.js.map +0 -1
  303. package/dist/utils/tracker.d.ts +0 -108
  304. package/dist/utils/tracker.d.ts.map +0 -1
  305. package/dist/utils/tracker.js.map +0 -1
  306. package/dist/utils/wait.d.ts +0 -54
  307. package/dist/utils/wait.d.ts.map +0 -1
  308. package/dist/utils/wait.js.map +0 -1
@@ -1,73 +1,46 @@
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.5
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
- import { jest } from '@jest/globals';
27
4
  import { AnsiLogger } from 'node-ansi-logger';
28
- // @matter
29
- import '@matter/nodejs';
30
- import { LogFormat as MatterLogFormat, LogLevel as MatterLogLevel, Environment, Lifecycle } from '@matter/general';
31
- import { DeviceTypeId, VendorId } from '@matter/types';
32
- import { MdnsService } from '@matter/protocol';
33
- import { ServerNode, Endpoint, ServerNodeStore } from '@matter/node';
34
- import { AggregatorEndpoint } from '@matter/node/endpoints/aggregator';
35
- import { RootEndpoint } from '@matter/node/endpoints/root';
36
- // Imports from a plugin
37
- /*
38
- import { jest } from '@jest/globals';
39
- import { DeviceTypeId, Endpoint, Environment, MdnsService, ServerNode, ServerNodeStore, VendorId, LogFormat as MatterLogFormat, LogLevel as MatterLogLevel, Lifecycle } from 'matterbridge/matter';
40
- import { RootEndpoint, AggregatorEndpoint } from 'matterbridge/matter/endpoints';
41
- import { AnsiLogger } from 'matterbridge/logger';
42
- */
5
+ import { LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, Environment, Lifecycle } from '@matter/general';
6
+ import { Endpoint, ServerNode, ServerNodeStore } from '@matter/node';
7
+ import { DeviceTypeId, VendorId } from '@matter/types/datatype';
8
+ import { AggregatorEndpoint, RootEndpoint } from '@matter/node/endpoints';
9
+ import { MdnsService } from '@matter/main/protocol';
10
+ import { Matterbridge } from '../matterbridge.js';
11
+ import { MATTER_STORAGE_NAME } from '../matterbridgeTypes.js';
43
12
  export let loggerLogSpy;
13
+ export let loggerDebugSpy;
14
+ export let loggerInfoSpy;
15
+ export let loggerNoticeSpy;
16
+ export let loggerWarnSpy;
17
+ export let loggerErrorSpy;
18
+ export let loggerFatalSpy;
44
19
  export let consoleLogSpy;
45
20
  export let consoleDebugSpy;
46
21
  export let consoleInfoSpy;
47
22
  export let consoleWarnSpy;
48
23
  export let consoleErrorSpy;
49
- /**
50
- * Setup the Jest environment:
51
- * - it will remove any existing home directory
52
- * - setup the spies for logging
53
- *
54
- * @param {string} name The name of the test suite.
55
- * @param {boolean} debug If true, the logging is not mocked.
56
- *
57
- * ```typescript
58
- * import { consoleDebugSpy, consoleErrorSpy, consoleInfoSpy, consoleLogSpy, consoleWarnSpy, loggerLogSpy, setDebug, setupTest } from './jestHelpers.js';
59
- *
60
- * // Setup the test environment
61
- * setupTest(NAME, false);
62
- *
63
- * ```
64
- */
65
- export function setupTest(name, debug = false) {
24
+ export let addBridgedEndpointSpy;
25
+ export let removeBridgedEndpointSpy;
26
+ export let removeAllBridgedEndpointsSpy;
27
+ export let matterbridge;
28
+ export let environment;
29
+ export let server;
30
+ export let aggregator;
31
+ export let log;
32
+ export async function setupTest(name, debug = false) {
66
33
  expect(name).toBeDefined();
67
34
  expect(typeof name).toBe('string');
68
- expect(name.length).toBeGreaterThanOrEqual(4); // avoid accidental deletion of short paths like "/" or "C:\"
69
- // Cleanup any existing home directory
35
+ expect(name.length).toBeGreaterThanOrEqual(4);
70
36
  rmSync(path.join('jest', name), { recursive: true, force: true });
37
+ const { jest } = await import('@jest/globals');
38
+ loggerDebugSpy = jest.spyOn(AnsiLogger.prototype, 'debug');
39
+ loggerInfoSpy = jest.spyOn(AnsiLogger.prototype, 'info');
40
+ loggerNoticeSpy = jest.spyOn(AnsiLogger.prototype, 'notice');
41
+ loggerWarnSpy = jest.spyOn(AnsiLogger.prototype, 'warn');
42
+ loggerErrorSpy = jest.spyOn(AnsiLogger.prototype, 'error');
43
+ loggerFatalSpy = jest.spyOn(AnsiLogger.prototype, 'fatal');
71
44
  if (debug) {
72
45
  loggerLogSpy = jest.spyOn(AnsiLogger.prototype, 'log');
73
46
  consoleLogSpy = jest.spyOn(console, 'log');
@@ -84,13 +57,12 @@ export function setupTest(name, debug = false) {
84
57
  consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => { });
85
58
  consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
86
59
  }
60
+ addBridgedEndpointSpy = jest.spyOn(Matterbridge.prototype, 'addBridgedEndpoint');
61
+ removeBridgedEndpointSpy = jest.spyOn(Matterbridge.prototype, 'removeBridgedEndpoint');
62
+ removeAllBridgedEndpointsSpy = jest.spyOn(Matterbridge.prototype, 'removeAllBridgedEndpoints');
87
63
  }
88
- /**
89
- * Set or unset the debug mode.
90
- *
91
- * @param {boolean} debug If true, the logging is not mocked.
92
- */
93
- export function setDebug(debug) {
64
+ export async function setDebug(debug) {
65
+ const { jest } = await import('@jest/globals');
94
66
  if (debug) {
95
67
  loggerLogSpy.mockRestore();
96
68
  consoleLogSpy.mockRestore();
@@ -114,42 +86,133 @@ export function setDebug(debug) {
114
86
  consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
115
87
  }
116
88
  }
117
- /**
118
- * Create a matter Environment for testing:
119
- * - it will remove any existing home directory
120
- * - setup the matter environment with homeDir, debug logging and ANSI format
121
- *
122
- * @param {string} homeDir Home directory for the environment.
123
- * @returns {Environment} The default matter environment.
124
- */
125
- export function createTestEnvironment(homeDir) {
126
- expect(homeDir).toBeDefined();
127
- expect(typeof homeDir).toBe('string');
128
- expect(homeDir.length).toBeGreaterThanOrEqual(4); // avoid accidental deletion of short paths like "/" or "C:\"
129
- // Cleanup any existing home directory
130
- rmSync(homeDir, { recursive: true, force: true });
131
- // Setup the matter environment
132
- const environment = Environment.default;
89
+ export async function createMatterbridgeEnvironment(name) {
90
+ matterbridge = await Matterbridge.loadInstance(false);
91
+ expect(matterbridge).toBeDefined();
92
+ expect(matterbridge).toBeInstanceOf(Matterbridge);
93
+ matterbridge.matterbridgeVersion = '3.3.0';
94
+ matterbridge.bridgeMode = 'bridge';
95
+ matterbridge.rootDirectory = path.join('jest', name);
96
+ matterbridge.homeDirectory = path.join('jest', name);
97
+ matterbridge.matterbridgeDirectory = path.join('jest', name, '.matterbridge');
98
+ matterbridge.matterbridgePluginDirectory = path.join('jest', name, 'Matterbridge');
99
+ matterbridge.matterbridgeCertDirectory = path.join('jest', name, '.mattercert');
100
+ matterbridge.log.logLevel = "debug";
101
+ log = new AnsiLogger({ logName: 'Plugin platform', logTimestampFormat: 4, logLevel: "debug" });
102
+ matterbridge.environment = createTestEnvironment(name);
103
+ expect(matterbridge.environment).toBeDefined();
104
+ expect(matterbridge.environment).toBeInstanceOf(Environment);
105
+ return matterbridge;
106
+ }
107
+ export async function startMatterbridgeEnvironment(port = 5540) {
108
+ await matterbridge.startMatterStorage();
109
+ expect(matterbridge.matterStorageService).toBeDefined();
110
+ expect(matterbridge.matterStorageManager).toBeDefined();
111
+ expect(matterbridge.matterbridgeContext).toBeDefined();
112
+ server = await matterbridge.createServerNode(matterbridge.matterbridgeContext, port);
113
+ expect(server).toBeDefined();
114
+ expect(server).toBeDefined();
115
+ expect(server.lifecycle.isReady).toBeTruthy();
116
+ matterbridge.serverNode = server;
117
+ aggregator = await matterbridge.createAggregatorNode(matterbridge.matterbridgeContext);
118
+ expect(aggregator).toBeDefined();
119
+ matterbridge.aggregatorNode = aggregator;
120
+ expect(await server.add(aggregator)).toBeDefined();
121
+ expect(server.parts.has(aggregator.id)).toBeTruthy();
122
+ expect(server.parts.has(aggregator)).toBeTruthy();
123
+ expect(aggregator.lifecycle.isReady).toBeTruthy();
124
+ expect(server.lifecycle.isOnline).toBeFalsy();
125
+ await new Promise((resolve) => {
126
+ server.lifecycle.online.on(async () => {
127
+ resolve();
128
+ });
129
+ server.start();
130
+ });
131
+ expect(server.lifecycle.isReady).toBeTruthy();
132
+ expect(server.lifecycle.isOnline).toBeTruthy();
133
+ expect(server.lifecycle.isCommissioned).toBeFalsy();
134
+ expect(server.lifecycle.isPartsReady).toBeTruthy();
135
+ expect(server.lifecycle.hasId).toBeTruthy();
136
+ expect(server.lifecycle.hasNumber).toBeTruthy();
137
+ expect(aggregator.lifecycle.isReady).toBeTruthy();
138
+ expect(aggregator.lifecycle.isInstalled).toBeTruthy();
139
+ expect(aggregator.lifecycle.isPartsReady).toBeTruthy();
140
+ expect(aggregator.lifecycle.hasId).toBeTruthy();
141
+ expect(aggregator.lifecycle.hasNumber).toBeTruthy();
142
+ await flushAsync();
143
+ return [server, aggregator];
144
+ }
145
+ export function addMatterbridgePlatform(platform, name) {
146
+ if (name)
147
+ platform.config.name = name;
148
+ expect(platform).toBeDefined();
149
+ expect(platform.config.name).toBeDefined();
150
+ expect(platform.config.type).toBeDefined();
151
+ expect(platform.type).toBeDefined();
152
+ expect(platform.config.version).toBeDefined();
153
+ expect(platform.version).toBeDefined();
154
+ expect(platform.config.debug).toBeDefined();
155
+ expect(platform.config.unregisterOnShutdown).toBeDefined();
156
+ matterbridge.plugins._plugins.set(platform.config.name, {
157
+ name: platform.config.name,
158
+ path: './',
159
+ type: platform.type,
160
+ version: platform.version,
161
+ description: 'Plugin ' + platform.config.name,
162
+ author: 'Unknown',
163
+ enabled: true,
164
+ });
165
+ platform['name'] = platform.config.name;
166
+ }
167
+ export async function stopMatterbridgeEnvironment() {
168
+ expect(matterbridge).toBeDefined();
169
+ expect(server).toBeDefined();
170
+ expect(aggregator).toBeDefined();
171
+ await flushAllEndpointNumberPersistence(server);
172
+ await assertAllEndpointNumbersPersisted(server);
173
+ expect(server.lifecycle.isReady).toBeTruthy();
174
+ expect(server.lifecycle.isOnline).toBeTruthy();
175
+ await server.close();
176
+ expect(server.lifecycle.isReady).toBeTruthy();
177
+ expect(server.lifecycle.isOnline).toBeFalsy();
178
+ await matterbridge.stopMatterStorage();
179
+ expect(matterbridge.matterStorageService).not.toBeDefined();
180
+ expect(matterbridge.matterStorageManager).not.toBeDefined();
181
+ expect(matterbridge.matterbridgeContext).not.toBeDefined();
182
+ await flushAsync();
183
+ }
184
+ export async function destroyMatterbridgeEnvironment(cleanupPause = 10, destroyPause = 250) {
185
+ await destroyInstance(matterbridge, cleanupPause, destroyPause);
186
+ await closeMdnsInstance(matterbridge);
187
+ Matterbridge.instance = undefined;
188
+ }
189
+ export async function destroyInstance(matterbridge, cleanupPause = 10, destroyPause = 250) {
190
+ await matterbridge.cleanup('destroying instance...', false, cleanupPause);
191
+ if (destroyPause > 0)
192
+ await flushAsync(undefined, undefined, destroyPause);
193
+ }
194
+ export async function closeMdnsInstance(matterbridge) {
195
+ const mdns = matterbridge.environment.get(MdnsService);
196
+ if (mdns && mdns[Symbol.asyncDispose] && typeof mdns[Symbol.asyncDispose] === 'function')
197
+ await mdns[Symbol.asyncDispose]();
198
+ if (mdns && mdns.close && typeof mdns.close === 'function')
199
+ await mdns.close();
200
+ }
201
+ export function createTestEnvironment(name) {
202
+ expect(name).toBeDefined();
203
+ expect(typeof name).toBe('string');
204
+ expect(name.length).toBeGreaterThanOrEqual(4);
205
+ rmSync(path.join('jest', name), { recursive: true, force: true });
206
+ environment = Environment.default;
133
207
  environment.vars.set('log.level', MatterLogLevel.DEBUG);
134
208
  environment.vars.set('log.format', MatterLogFormat.ANSI);
135
- environment.vars.set('path.root', homeDir);
209
+ environment.vars.set('path.root', path.join('jest', name, '.matterbridge', MATTER_STORAGE_NAME));
136
210
  environment.vars.set('runtime.signals', false);
137
211
  environment.vars.set('runtime.exitcode', false);
212
+ new MdnsService(environment);
138
213
  return environment;
139
214
  }
140
- /**
141
- * Advance the Node.js event loop deterministically to allow chained asynchronous work (Promises scheduled in
142
- * microtasks and follow‑up macrotasks) to complete inside tests without adding arbitrary long timeouts.
143
- *
144
- * NOTE: This does not guarantee OS level network IO completion—only JavaScript task queue progression inside the
145
- * current process.
146
- *
147
- * @param {number} ticks Number of macrotask (setImmediate) turns to yield (default 3).
148
- * @param {number} microTurns Number of microtask drains (Promise.resolve chains) after macrotask yielding (default 10).
149
- * @param {number} pause Final timer delay in ms; set 0 to disable (default 100ms).
150
- * @returns {Promise<void>} Resolves after the requested event loop advancement has completed.
151
- */
152
- export async function flushAsync(ticks = 3, microTurns = 10, pause = 100) {
215
+ export async function flushAsync(ticks = 3, microTurns = 10, pause = 250) {
153
216
  for (let i = 0; i < ticks; i++)
154
217
  await new Promise((resolve) => setImmediate(resolve));
155
218
  for (let i = 0; i < microTurns; i++)
@@ -157,19 +220,6 @@ export async function flushAsync(ticks = 3, microTurns = 10, pause = 100) {
157
220
  if (pause)
158
221
  await new Promise((resolve) => setTimeout(resolve, pause));
159
222
  }
160
- /**
161
- * Flush (await) the lazy endpoint number persistence mechanism used by matter.js.
162
- *
163
- * Background:
164
- * assignNumber() batches persistence (store.saveNumber + updating __nextNumber__) via an internal promise (#numbersPersisted).
165
- * Calling endpointStores.close() waits for the current batch only. If new endpoints were added in the same macrotask
166
- * cycle additional micro/macro turns might be needed to ensure the batch started. We defensively yield macrotasks
167
- * (setImmediate) and then await close() multiple rounds.
168
- *
169
- * @param {ServerNode} targetServer The server whose endpoint numbering persistence should be flushed.
170
- * @param {number} rounds Number of macrotask + close cycles to run (2 is usually sufficient; 1 often works).
171
- * @returns {Promise<void>} Resolves when pending number persistence batches have completed.
172
- */
173
223
  export async function flushAllEndpointNumberPersistence(targetServer, rounds = 2) {
174
224
  const nodeStore = targetServer.env.get(ServerNodeStore);
175
225
  for (let i = 0; i < rounds; i++) {
@@ -177,12 +227,6 @@ export async function flushAllEndpointNumberPersistence(targetServer, rounds = 2
177
227
  await nodeStore.endpointStores.close();
178
228
  }
179
229
  }
180
- /**
181
- * Collect all endpoints in the server endpoint tree (root -> descendants).
182
- *
183
- * @param {Endpoint} root Root endpoint (typically the ServerNode root endpoint cast as Endpoint).
184
- * @returns {Endpoint[]} Flat array including the root and every descendant once.
185
- */
186
230
  function collectAllEndpoints(root) {
187
231
  const list = [];
188
232
  const walk = (ep) => {
@@ -196,26 +240,14 @@ function collectAllEndpoints(root) {
196
240
  walk(root);
197
241
  return list;
198
242
  }
199
- /**
200
- * Assert that every endpoint attached to the server has an assigned and (batch-)persisted endpoint number.
201
- *
202
- * This waits for any outstanding number persistence batch (endpointStores.close()), then traverses the endpoint
203
- * graph and asserts:
204
- * - Root endpoint: number is 0 (allowing undefined to coerce to 0 via nullish coalescing check).
205
- * - All other endpoints: number > 0.
206
- *
207
- * @param {ServerNode} targetServer The server whose endpoint numbers are verified.
208
- * @returns {Promise<void>} Resolves when assertions complete.
209
- */
210
243
  export async function assertAllEndpointNumbersPersisted(targetServer) {
211
244
  const nodeStore = targetServer.env.get(ServerNodeStore);
212
- // Ensure any pending persistence finished (flush any in-flight batch promise)
213
245
  await nodeStore.endpointStores.close();
214
246
  const all = collectAllEndpoints(targetServer);
215
247
  for (const ep of all) {
216
248
  const store = nodeStore.storeForEndpoint(ep);
217
249
  if (ep.maybeNumber === 0) {
218
- expect(store.number ?? 0).toBe(0); // root
250
+ expect(store.number ?? 0).toBe(0);
219
251
  }
220
252
  else {
221
253
  expect(store.number).toBeGreaterThan(0);
@@ -223,24 +255,16 @@ export async function assertAllEndpointNumbersPersisted(targetServer) {
223
255
  }
224
256
  return all.length;
225
257
  }
226
- /**
227
- * Start a matter server node for testing.
228
- *
229
- * @param {string} name Name of the server (used for logging and product description).
230
- * @param {number} port TCP port to listen on.
231
- * @returns {Promise<[ServerNode<ServerNode.RootEndpoint>, Endpoint<AggregatorEndpoint>]>} Resolves to an array containing the created ServerNode and its AggregatorNode.
232
- */
233
258
  export async function startServerNode(name, port) {
234
- // Create the server node
235
- const server = await ServerNode.create({
259
+ server = await ServerNode.create({
236
260
  id: name + 'ServerNode',
261
+ environment,
237
262
  productDescription: {
238
263
  name: name + 'ServerNode',
239
264
  deviceType: DeviceTypeId(RootEndpoint.deviceType),
240
265
  vendorId: VendorId(0xfff1),
241
266
  productId: 0x8000,
242
267
  },
243
- // Provide defaults for the BasicInformation cluster on the Root endpoint
244
268
  basicInformation: {
245
269
  vendorId: VendorId(0xfff1),
246
270
  vendorName: 'Matterbridge',
@@ -257,26 +281,21 @@ export async function startServerNode(name, port) {
257
281
  });
258
282
  expect(server).toBeDefined();
259
283
  expect(server.lifecycle.isReady).toBeTruthy();
260
- // Create the aggregator node
261
- const aggregator = new Endpoint(AggregatorEndpoint, {
284
+ aggregator = new Endpoint(AggregatorEndpoint, {
262
285
  id: name + 'AggregatorNode',
263
286
  });
264
287
  expect(aggregator).toBeDefined();
265
- // Add the aggregator to the server
266
288
  await server.add(aggregator);
267
289
  expect(server.parts.has(aggregator.id)).toBeTruthy();
268
290
  expect(server.parts.has(aggregator)).toBeTruthy();
269
291
  expect(aggregator.lifecycle.isReady).toBeTruthy();
270
- // Run the server
271
292
  expect(server.lifecycle.isOnline).toBeFalsy();
272
- // Wait for the server to be online
273
293
  await new Promise((resolve) => {
274
294
  server.lifecycle.online.on(async () => {
275
295
  resolve();
276
296
  });
277
297
  server.start();
278
298
  });
279
- // Check if the server is online
280
299
  expect(server.lifecycle.isReady).toBeTruthy();
281
300
  expect(server.lifecycle.isOnline).toBeTruthy();
282
301
  expect(server.lifecycle.isCommissioned).toBeFalsy();
@@ -288,41 +307,25 @@ export async function startServerNode(name, port) {
288
307
  expect(aggregator.lifecycle.isPartsReady).toBeTruthy();
289
308
  expect(aggregator.lifecycle.hasId).toBeTruthy();
290
309
  expect(aggregator.lifecycle.hasNumber).toBeTruthy();
291
- // Ensure the queue is empty and pause 100ms
292
310
  await flushAsync();
293
311
  return [server, aggregator];
294
312
  }
295
- /**
296
- * Stop a matter server node.
297
- *
298
- * @param {ServerNode<ServerNode.RootEndpoint>} server The server to stop.
299
- * @returns {Promise<void>} Resolves when the server has stopped.
300
- */
301
313
  export async function stopServerNode(server) {
302
- // Flush any pending endpoint number persistence
303
314
  await flushAllEndpointNumberPersistence(server);
304
- // Ensure all endpoint numbers are persisted
305
315
  await assertAllEndpointNumbersPersisted(server);
306
- // Stop the server
307
316
  expect(server).toBeDefined();
308
317
  expect(server.lifecycle.isReady).toBeTruthy();
309
318
  expect(server.lifecycle.isOnline).toBeTruthy();
310
319
  await server.close();
311
320
  expect(server.lifecycle.isReady).toBeTruthy();
312
321
  expect(server.lifecycle.isOnline).toBeFalsy();
313
- // stop the mDNS service
314
- await server.env.get(MdnsService)[Symbol.asyncDispose]();
315
- // Ensure the queue is empty and pause 100ms
322
+ const mdns = environment.get(MdnsService);
323
+ if (mdns && typeof mdns[Symbol.asyncDispose] === 'function')
324
+ await mdns[Symbol.asyncDispose]();
325
+ if (mdns && typeof mdns.close === 'function')
326
+ await mdns.close();
316
327
  await flushAsync();
317
328
  }
318
- /**
319
- * Add a device (endpoint) to a matter server node or an aggregator.
320
- *
321
- * @param {ServerNode<ServerNode.RootEndpoint> | Endpoint<AggregatorEndpoint>} owner The server or aggregator to add the device to.
322
- * @param {Endpoint} device The device to add.
323
- * @param {number} pause The pause time in milliseconds after addition (default 10ms).
324
- * @returns {Promise<void>} Resolves when the device has been added and is ready.
325
- */
326
329
  export async function addDevice(owner, device, pause = 10) {
327
330
  expect(owner).toBeDefined();
328
331
  expect(device).toBeDefined();
@@ -335,7 +338,6 @@ export async function addDevice(owner, device, pause = 10) {
335
338
  catch (error) {
336
339
  const errorMessage = error instanceof Error ? error.message : error;
337
340
  const errorInspect = inspect(error, { depth: 10 });
338
- // eslint-disable-next-line no-console
339
341
  console.error(`Error adding device ${device.maybeId}.${device.maybeNumber}: ${errorMessage}\nstack: ${errorInspect}`);
340
342
  return false;
341
343
  }
@@ -346,17 +348,9 @@ export async function addDevice(owner, device, pause = 10) {
346
348
  expect(device.lifecycle.hasId).toBeTruthy();
347
349
  expect(device.lifecycle.hasNumber).toBeTruthy();
348
350
  expect(device.construction.status).toBe(Lifecycle.Status.Active);
349
- await flushAsync(1, 1, pause);
351
+ await flushAsync(undefined, undefined, pause);
350
352
  return true;
351
353
  }
352
- /**
353
- * Delete a device (endpoint) from a matter server node or an aggregator.
354
- *
355
- * @param {ServerNode<ServerNode.RootEndpoint> | Endpoint<AggregatorEndpoint>} owner The server or aggregator to remove the device from.
356
- * @param {Endpoint} device The device to remove.
357
- * @param {number} pause The pause time in milliseconds after deletion (default 10ms).
358
- * @returns {Promise<void>} Resolves when the device has been removed and is no longer ready.
359
- */
360
354
  export async function deleteDevice(owner, device, pause = 10) {
361
355
  expect(owner).toBeDefined();
362
356
  expect(device).toBeDefined();
@@ -369,7 +363,6 @@ export async function deleteDevice(owner, device, pause = 10) {
369
363
  catch (error) {
370
364
  const errorMessage = error instanceof Error ? error.message : error;
371
365
  const errorInspect = inspect(error, { depth: 10 });
372
- // eslint-disable-next-line no-console
373
366
  console.error(`Error deleting device ${device.maybeId}.${device.maybeNumber}: ${errorMessage}\nstack: ${errorInspect}`);
374
367
  return false;
375
368
  }
@@ -380,7 +373,6 @@ export async function deleteDevice(owner, device, pause = 10) {
380
373
  expect(device.lifecycle.hasId).toBeTruthy();
381
374
  expect(device.lifecycle.hasNumber).toBeTruthy();
382
375
  expect(device.construction.status).toBe(Lifecycle.Status.Destroyed);
383
- await flushAsync(1, 1, pause);
376
+ await flushAsync(undefined, undefined, pause);
384
377
  return true;
385
378
  }
386
- //# sourceMappingURL=jestHelpers.js.map
@@ -1,2 +1 @@
1
1
  export * from 'node-ansi-logger';
2
- //# sourceMappingURL=export.js.map
@@ -1,3 +1 @@
1
- // @matter
2
1
  export * from '@matter/node/behaviors';
3
- //# sourceMappingURL=behaviors.js.map
@@ -1,3 +1 @@
1
- // @matter
2
1
  export * from '@matter/types/clusters';
3
- //# sourceMappingURL=clusters.js.map
@@ -1,3 +1 @@
1
- // @matter
2
1
  export * from '@matter/node/devices';
3
- //# sourceMappingURL=devices.js.map
@@ -1,3 +1 @@
1
- // @matter
2
1
  export { AggregatorEndpoint, ElectricalSensorEndpoint, PowerSourceEndpoint, BridgedNodeEndpoint, RootEndpoint, DeviceEnergyManagementEndpoint, OtaProviderEndpoint, OtaRequestorEndpoint } from '@matter/node/endpoints';
3
- //# sourceMappingURL=endpoints.js.map
@@ -1,7 +1,4 @@
1
- /* eslint-disable import/export */
2
- // @matter
3
1
  export * from '@matter/main';
4
2
  export { SemanticNamespace, ClosureTag, CompassDirectionTag, CompassLocationTag, DirectionTag, ElectricalMeasurementTag, LaundryTag, LevelTag, LocationTag, NumberTag, PositionTag, PowerSourceTag, RefrigeratorTag, RoomAirConditionerTag, SwitchesTag, } from '@matter/main';
5
3
  export { AttributeElement, ClusterElement, ClusterModel, CommandElement, EventElement, FieldElement } from '@matter/main/model';
6
4
  export { MdnsService, Val } from '@matter/main/protocol';
7
- //# sourceMappingURL=export.js.map
@@ -1,5 +1,2 @@
1
- /* eslint-disable import/export */
2
- // @matter
3
1
  export * from '@matter/types';
4
2
  export { ClusterRegistry } from '@matter/types';
5
- //# sourceMappingURL=types.js.map