matterbridge 3.4.3-dev-20251209-e6cb85f → 3.4.3

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 (324) hide show
  1. package/README.md +2 -3
  2. package/dist/broadcastServer.d.ts +144 -0
  3. package/dist/broadcastServer.d.ts.map +1 -0
  4. package/dist/broadcastServer.js +119 -0
  5. package/dist/broadcastServer.js.map +1 -0
  6. package/dist/broadcastServerTypes.d.ts +841 -0
  7. package/dist/broadcastServerTypes.d.ts.map +1 -0
  8. package/dist/broadcastServerTypes.js +24 -0
  9. package/dist/broadcastServerTypes.js.map +1 -0
  10. package/dist/cli.d.ts +30 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +97 -1
  13. package/dist/cli.js.map +1 -0
  14. package/dist/cliEmitter.d.ts +50 -0
  15. package/dist/cliEmitter.d.ts.map +1 -0
  16. package/dist/cliEmitter.js +37 -0
  17. package/dist/cliEmitter.js.map +1 -0
  18. package/dist/cliHistory.d.ts +48 -0
  19. package/dist/cliHistory.d.ts.map +1 -0
  20. package/dist/cliHistory.js +38 -0
  21. package/dist/cliHistory.js.map +1 -0
  22. package/dist/clusters/export.d.ts +2 -0
  23. package/dist/clusters/export.d.ts.map +1 -0
  24. package/dist/clusters/export.js +2 -0
  25. package/dist/clusters/export.js.map +1 -0
  26. package/dist/deviceManager.d.ts +135 -0
  27. package/dist/deviceManager.d.ts.map +1 -0
  28. package/dist/deviceManager.js +113 -1
  29. package/dist/deviceManager.js.map +1 -0
  30. package/dist/devices/airConditioner.d.ts +98 -0
  31. package/dist/devices/airConditioner.d.ts.map +1 -0
  32. package/dist/devices/airConditioner.js +57 -0
  33. package/dist/devices/airConditioner.js.map +1 -0
  34. package/dist/devices/batteryStorage.d.ts +48 -0
  35. package/dist/devices/batteryStorage.d.ts.map +1 -0
  36. package/dist/devices/batteryStorage.js +48 -1
  37. package/dist/devices/batteryStorage.js.map +1 -0
  38. package/dist/devices/cooktop.d.ts +61 -0
  39. package/dist/devices/cooktop.d.ts.map +1 -0
  40. package/dist/devices/cooktop.js +56 -0
  41. package/dist/devices/cooktop.js.map +1 -0
  42. package/dist/devices/dishwasher.d.ts +71 -0
  43. package/dist/devices/dishwasher.d.ts.map +1 -0
  44. package/dist/devices/dishwasher.js +57 -0
  45. package/dist/devices/dishwasher.js.map +1 -0
  46. package/dist/devices/evse.d.ts +76 -0
  47. package/dist/devices/evse.d.ts.map +1 -0
  48. package/dist/devices/evse.js +74 -10
  49. package/dist/devices/evse.js.map +1 -0
  50. package/dist/devices/export.d.ts +17 -0
  51. package/dist/devices/export.d.ts.map +1 -0
  52. package/dist/devices/export.js +5 -0
  53. package/dist/devices/export.js.map +1 -0
  54. package/dist/devices/extractorHood.d.ts +46 -0
  55. package/dist/devices/extractorHood.d.ts.map +1 -0
  56. package/dist/devices/extractorHood.js +43 -0
  57. package/dist/devices/extractorHood.js.map +1 -0
  58. package/dist/devices/heatPump.d.ts +47 -0
  59. package/dist/devices/heatPump.d.ts.map +1 -0
  60. package/dist/devices/heatPump.js +50 -2
  61. package/dist/devices/heatPump.js.map +1 -0
  62. package/dist/devices/laundryDryer.d.ts +67 -0
  63. package/dist/devices/laundryDryer.d.ts.map +1 -0
  64. package/dist/devices/laundryDryer.js +62 -3
  65. package/dist/devices/laundryDryer.js.map +1 -0
  66. package/dist/devices/laundryWasher.d.ts +81 -0
  67. package/dist/devices/laundryWasher.d.ts.map +1 -0
  68. package/dist/devices/laundryWasher.js +70 -4
  69. package/dist/devices/laundryWasher.js.map +1 -0
  70. package/dist/devices/microwaveOven.d.ts +168 -0
  71. package/dist/devices/microwaveOven.d.ts.map +1 -0
  72. package/dist/devices/microwaveOven.js +88 -5
  73. package/dist/devices/microwaveOven.js.map +1 -0
  74. package/dist/devices/oven.d.ts +105 -0
  75. package/dist/devices/oven.d.ts.map +1 -0
  76. package/dist/devices/oven.js +85 -0
  77. package/dist/devices/oven.js.map +1 -0
  78. package/dist/devices/refrigerator.d.ts +118 -0
  79. package/dist/devices/refrigerator.d.ts.map +1 -0
  80. package/dist/devices/refrigerator.js +102 -0
  81. package/dist/devices/refrigerator.js.map +1 -0
  82. package/dist/devices/roboticVacuumCleaner.d.ts +112 -0
  83. package/dist/devices/roboticVacuumCleaner.d.ts.map +1 -0
  84. package/dist/devices/roboticVacuumCleaner.js +100 -9
  85. package/dist/devices/roboticVacuumCleaner.js.map +1 -0
  86. package/dist/devices/solarPower.d.ts +40 -0
  87. package/dist/devices/solarPower.d.ts.map +1 -0
  88. package/dist/devices/solarPower.js +38 -0
  89. package/dist/devices/solarPower.js.map +1 -0
  90. package/dist/devices/speaker.d.ts +87 -0
  91. package/dist/devices/speaker.d.ts.map +1 -0
  92. package/dist/devices/speaker.js +84 -0
  93. package/dist/devices/speaker.js.map +1 -0
  94. package/dist/devices/temperatureControl.d.ts +166 -0
  95. package/dist/devices/temperatureControl.d.ts.map +1 -0
  96. package/dist/devices/temperatureControl.js +24 -3
  97. package/dist/devices/temperatureControl.js.map +1 -0
  98. package/dist/devices/waterHeater.d.ts +111 -0
  99. package/dist/devices/waterHeater.d.ts.map +1 -0
  100. package/dist/devices/waterHeater.js +82 -2
  101. package/dist/devices/waterHeater.js.map +1 -0
  102. package/dist/dgram/coap.d.ts +205 -0
  103. package/dist/dgram/coap.d.ts.map +1 -0
  104. package/dist/dgram/coap.js +126 -13
  105. package/dist/dgram/coap.js.map +1 -0
  106. package/dist/dgram/dgram.d.ts +141 -0
  107. package/dist/dgram/dgram.d.ts.map +1 -0
  108. package/dist/dgram/dgram.js +114 -2
  109. package/dist/dgram/dgram.js.map +1 -0
  110. package/dist/dgram/mb_coap.d.ts +24 -0
  111. package/dist/dgram/mb_coap.d.ts.map +1 -0
  112. package/dist/dgram/mb_coap.js +41 -3
  113. package/dist/dgram/mb_coap.js.map +1 -0
  114. package/dist/dgram/mb_mdns.d.ts +24 -0
  115. package/dist/dgram/mb_mdns.d.ts.map +1 -0
  116. package/dist/dgram/mb_mdns.js +80 -15
  117. package/dist/dgram/mb_mdns.js.map +1 -0
  118. package/dist/dgram/mdns.d.ts +290 -0
  119. package/dist/dgram/mdns.d.ts.map +1 -0
  120. package/dist/dgram/mdns.js +299 -137
  121. package/dist/dgram/mdns.js.map +1 -0
  122. package/dist/dgram/multicast.d.ts +67 -0
  123. package/dist/dgram/multicast.d.ts.map +1 -0
  124. package/dist/dgram/multicast.js +62 -1
  125. package/dist/dgram/multicast.js.map +1 -0
  126. package/dist/dgram/unicast.d.ts +56 -0
  127. package/dist/dgram/unicast.d.ts.map +1 -0
  128. package/dist/dgram/unicast.js +54 -0
  129. package/dist/dgram/unicast.js.map +1 -0
  130. package/dist/frontend.d.ts +238 -0
  131. package/dist/frontend.d.ts.map +1 -0
  132. package/dist/frontend.js +455 -35
  133. package/dist/frontend.js.map +1 -0
  134. package/dist/frontendTypes.d.ts +529 -0
  135. package/dist/frontendTypes.d.ts.map +1 -0
  136. package/dist/frontendTypes.js +45 -0
  137. package/dist/frontendTypes.js.map +1 -0
  138. package/dist/helpers.d.ts +48 -0
  139. package/dist/helpers.d.ts.map +1 -0
  140. package/dist/helpers.js +53 -0
  141. package/dist/helpers.js.map +1 -0
  142. package/dist/index.d.ts +34 -0
  143. package/dist/index.d.ts.map +1 -0
  144. package/dist/index.js +25 -0
  145. package/dist/index.js.map +1 -0
  146. package/dist/jestutils/export.d.ts +2 -0
  147. package/dist/jestutils/export.d.ts.map +1 -0
  148. package/dist/jestutils/export.js +1 -0
  149. package/dist/jestutils/export.js.map +1 -0
  150. package/dist/jestutils/jestHelpers.d.ts +345 -0
  151. package/dist/jestutils/jestHelpers.d.ts.map +1 -0
  152. package/dist/jestutils/jestHelpers.js +371 -14
  153. package/dist/jestutils/jestHelpers.js.map +1 -0
  154. package/dist/logger/export.d.ts +2 -0
  155. package/dist/logger/export.d.ts.map +1 -0
  156. package/dist/logger/export.js +1 -0
  157. package/dist/logger/export.js.map +1 -0
  158. package/dist/matter/behaviors.d.ts +2 -0
  159. package/dist/matter/behaviors.d.ts.map +1 -0
  160. package/dist/matter/behaviors.js +2 -0
  161. package/dist/matter/behaviors.js.map +1 -0
  162. package/dist/matter/clusters.d.ts +2 -0
  163. package/dist/matter/clusters.d.ts.map +1 -0
  164. package/dist/matter/clusters.js +2 -0
  165. package/dist/matter/clusters.js.map +1 -0
  166. package/dist/matter/devices.d.ts +2 -0
  167. package/dist/matter/devices.d.ts.map +1 -0
  168. package/dist/matter/devices.js +2 -0
  169. package/dist/matter/devices.js.map +1 -0
  170. package/dist/matter/endpoints.d.ts +2 -0
  171. package/dist/matter/endpoints.d.ts.map +1 -0
  172. package/dist/matter/endpoints.js +2 -0
  173. package/dist/matter/endpoints.js.map +1 -0
  174. package/dist/matter/export.d.ts +5 -0
  175. package/dist/matter/export.d.ts.map +1 -0
  176. package/dist/matter/export.js +3 -0
  177. package/dist/matter/export.js.map +1 -0
  178. package/dist/matter/types.d.ts +3 -0
  179. package/dist/matter/types.d.ts.map +1 -0
  180. package/dist/matter/types.js +3 -0
  181. package/dist/matter/types.js.map +1 -0
  182. package/dist/matterNode.d.ts +342 -0
  183. package/dist/matterNode.d.ts.map +1 -0
  184. package/dist/matterNode.js +369 -8
  185. package/dist/matterNode.js.map +1 -0
  186. package/dist/matterbridge.d.ts +492 -0
  187. package/dist/matterbridge.d.ts.map +1 -0
  188. package/dist/matterbridge.js +811 -46
  189. package/dist/matterbridge.js.map +1 -0
  190. package/dist/matterbridgeAccessoryPlatform.d.ts +41 -0
  191. package/dist/matterbridgeAccessoryPlatform.d.ts.map +1 -0
  192. package/dist/matterbridgeAccessoryPlatform.js +38 -0
  193. package/dist/matterbridgeAccessoryPlatform.js.map +1 -0
  194. package/dist/matterbridgeBehaviors.d.ts +2404 -0
  195. package/dist/matterbridgeBehaviors.d.ts.map +1 -0
  196. package/dist/matterbridgeBehaviors.js +68 -5
  197. package/dist/matterbridgeBehaviors.js.map +1 -0
  198. package/dist/matterbridgeDeviceTypes.d.ts +698 -0
  199. package/dist/matterbridgeDeviceTypes.d.ts.map +1 -0
  200. package/dist/matterbridgeDeviceTypes.js +635 -14
  201. package/dist/matterbridgeDeviceTypes.js.map +1 -0
  202. package/dist/matterbridgeDynamicPlatform.d.ts +41 -0
  203. package/dist/matterbridgeDynamicPlatform.d.ts.map +1 -0
  204. package/dist/matterbridgeDynamicPlatform.js +38 -0
  205. package/dist/matterbridgeDynamicPlatform.js.map +1 -0
  206. package/dist/matterbridgeEndpoint.d.ts +1507 -0
  207. package/dist/matterbridgeEndpoint.d.ts.map +1 -0
  208. package/dist/matterbridgeEndpoint.js +1444 -53
  209. package/dist/matterbridgeEndpoint.js.map +1 -0
  210. package/dist/matterbridgeEndpointHelpers.d.ts +787 -0
  211. package/dist/matterbridgeEndpointHelpers.d.ts.map +1 -0
  212. package/dist/matterbridgeEndpointHelpers.js +483 -20
  213. package/dist/matterbridgeEndpointHelpers.js.map +1 -0
  214. package/dist/matterbridgeEndpointTypes.d.ts +166 -0
  215. package/dist/matterbridgeEndpointTypes.d.ts.map +1 -0
  216. package/dist/matterbridgeEndpointTypes.js +25 -0
  217. package/dist/matterbridgeEndpointTypes.js.map +1 -0
  218. package/dist/matterbridgePlatform.d.ts +539 -0
  219. package/dist/matterbridgePlatform.d.ts.map +1 -0
  220. package/dist/matterbridgePlatform.js +451 -1
  221. package/dist/matterbridgePlatform.js.map +1 -0
  222. package/dist/matterbridgeTypes.d.ts +251 -0
  223. package/dist/matterbridgeTypes.d.ts.map +1 -0
  224. package/dist/matterbridgeTypes.js +26 -0
  225. package/dist/matterbridgeTypes.js.map +1 -0
  226. package/dist/pluginManager.d.ts +372 -0
  227. package/dist/pluginManager.d.ts.map +1 -0
  228. package/dist/pluginManager.js +341 -5
  229. package/dist/pluginManager.js.map +1 -0
  230. package/dist/shelly.d.ts +181 -0
  231. package/dist/shelly.d.ts.map +1 -0
  232. package/dist/shelly.js +178 -7
  233. package/dist/shelly.js.map +1 -0
  234. package/dist/storage/export.d.ts +2 -0
  235. package/dist/storage/export.d.ts.map +1 -0
  236. package/dist/storage/export.js +1 -0
  237. package/dist/storage/export.js.map +1 -0
  238. package/dist/update.d.ts +84 -0
  239. package/dist/update.d.ts.map +1 -0
  240. package/dist/update.js +93 -1
  241. package/dist/update.js.map +1 -0
  242. package/dist/utils/colorUtils.d.ts +101 -0
  243. package/dist/utils/colorUtils.d.ts.map +1 -0
  244. package/dist/utils/colorUtils.js +97 -2
  245. package/dist/utils/colorUtils.js.map +1 -0
  246. package/dist/utils/commandLine.d.ts +66 -0
  247. package/dist/utils/commandLine.d.ts.map +1 -0
  248. package/dist/utils/commandLine.js +60 -0
  249. package/dist/utils/commandLine.js.map +1 -0
  250. package/dist/utils/copyDirectory.d.ts +35 -0
  251. package/dist/utils/copyDirectory.d.ts.map +1 -0
  252. package/dist/utils/copyDirectory.js +37 -0
  253. package/dist/utils/copyDirectory.js.map +1 -0
  254. package/dist/utils/createDirectory.d.ts +34 -0
  255. package/dist/utils/createDirectory.d.ts.map +1 -0
  256. package/dist/utils/createDirectory.js +33 -0
  257. package/dist/utils/createDirectory.js.map +1 -0
  258. package/dist/utils/createZip.d.ts +39 -0
  259. package/dist/utils/createZip.d.ts.map +1 -0
  260. package/dist/utils/createZip.js +47 -2
  261. package/dist/utils/createZip.js.map +1 -0
  262. package/dist/utils/deepCopy.d.ts +32 -0
  263. package/dist/utils/deepCopy.d.ts.map +1 -0
  264. package/dist/utils/deepCopy.js +39 -0
  265. package/dist/utils/deepCopy.js.map +1 -0
  266. package/dist/utils/deepEqual.d.ts +54 -0
  267. package/dist/utils/deepEqual.d.ts.map +1 -0
  268. package/dist/utils/deepEqual.js +72 -1
  269. package/dist/utils/deepEqual.js.map +1 -0
  270. package/dist/utils/error.d.ts +45 -0
  271. package/dist/utils/error.d.ts.map +1 -0
  272. package/dist/utils/error.js +42 -0
  273. package/dist/utils/error.js.map +1 -0
  274. package/dist/utils/export.d.ts +13 -0
  275. package/dist/utils/export.d.ts.map +1 -0
  276. package/dist/utils/export.js +1 -0
  277. package/dist/utils/export.js.map +1 -0
  278. package/dist/utils/format.d.ts +53 -0
  279. package/dist/utils/format.d.ts.map +1 -0
  280. package/dist/utils/format.js +49 -0
  281. package/dist/utils/format.js.map +1 -0
  282. package/dist/utils/hex.d.ts +89 -0
  283. package/dist/utils/hex.d.ts.map +1 -0
  284. package/dist/utils/hex.js +124 -0
  285. package/dist/utils/hex.js.map +1 -0
  286. package/dist/utils/inspector.d.ts +87 -0
  287. package/dist/utils/inspector.d.ts.map +1 -0
  288. package/dist/utils/inspector.js +69 -1
  289. package/dist/utils/inspector.js.map +1 -0
  290. package/dist/utils/isvalid.d.ts +103 -0
  291. package/dist/utils/isvalid.d.ts.map +1 -0
  292. package/dist/utils/isvalid.js +101 -0
  293. package/dist/utils/isvalid.js.map +1 -0
  294. package/dist/utils/network.d.ts +111 -0
  295. package/dist/utils/network.d.ts.map +1 -0
  296. package/dist/utils/network.js +96 -5
  297. package/dist/utils/network.js.map +1 -0
  298. package/dist/utils/spawn.d.ts +33 -0
  299. package/dist/utils/spawn.d.ts.map +1 -0
  300. package/dist/utils/spawn.js +71 -1
  301. package/dist/utils/spawn.js.map +1 -0
  302. package/dist/utils/tracker.d.ts +108 -0
  303. package/dist/utils/tracker.d.ts.map +1 -0
  304. package/dist/utils/tracker.js +64 -1
  305. package/dist/utils/tracker.js.map +1 -0
  306. package/dist/utils/wait.d.ts +54 -0
  307. package/dist/utils/wait.d.ts.map +1 -0
  308. package/dist/utils/wait.js +60 -8
  309. package/dist/utils/wait.js.map +1 -0
  310. package/dist/workerGlobalPrefix.d.ts +25 -0
  311. package/dist/workerGlobalPrefix.d.ts.map +1 -0
  312. package/dist/workerGlobalPrefix.js +37 -5
  313. package/dist/workerGlobalPrefix.js.map +1 -0
  314. package/dist/workerTypes.d.ts +52 -0
  315. package/dist/workerTypes.d.ts.map +1 -0
  316. package/dist/workerTypes.js +24 -0
  317. package/dist/workerTypes.js.map +1 -0
  318. package/dist/workers.d.ts +69 -0
  319. package/dist/workers.d.ts.map +1 -0
  320. package/dist/workers.js +68 -4
  321. package/dist/workers.js.map +1 -0
  322. package/npm-shrinkwrap.json +2 -2
  323. package/package.json +2 -1
  324. package/scripts/data_model.mjs +2058 -0
@@ -1,9 +1,37 @@
1
+ /**
2
+ * This file contains the Plugins class.
3
+ *
4
+ * @file plugins.ts
5
+ * @author Luca Liguori
6
+ * @created 2024-07-14
7
+ * @version 1.3.5
8
+ * @license Apache-2.0
9
+ *
10
+ * Copyright 2024, 2025, 2026 Luca Liguori.
11
+ *
12
+ * Licensed under the Apache License, Version 2.0 (the "License");
13
+ * you may not use this file except in compliance with the License.
14
+ * You may obtain a copy of the License at
15
+ *
16
+ * http://www.apache.org/licenses/LICENSE-2.0
17
+ *
18
+ * Unless required by applicable law or agreed to in writing, software
19
+ * distributed under the License is distributed on an "AS IS" BASIS,
20
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
+ * See the License for the specific language governing permissions and
22
+ * limitations under the License.
23
+ */
24
+ // Node.js import
1
25
  import EventEmitter from 'node:events';
26
+ // AnsiLogger module
2
27
  import { AnsiLogger, UNDERLINE, UNDERLINEOFF, BLUE, db, er, nf, nt, rs, wr, debugStringify, CYAN } from 'node-ansi-logger';
3
28
  import { plg, typ } from './matterbridgeTypes.js';
4
29
  import { inspectError, logError } from './utils/error.js';
5
30
  import { hasParameter } from './utils/commandLine.js';
6
31
  import { BroadcastServer } from './broadcastServer.js';
32
+ /**
33
+ * Manages Matterbridge plugins.
34
+ */
7
35
  export class PluginManager extends EventEmitter {
8
36
  matterbridge;
9
37
  _plugins = new Map();
@@ -11,10 +39,15 @@ export class PluginManager extends EventEmitter {
11
39
  server;
12
40
  debug = hasParameter('debug') || hasParameter('verbose');
13
41
  verbose = hasParameter('verbose');
42
+ /**
43
+ * Creates an instance of PluginManager.
44
+ *
45
+ * @param {Matterbridge} matterbridge - The Matterbridge instance.
46
+ */
14
47
  constructor(matterbridge) {
15
48
  super();
16
49
  this.matterbridge = matterbridge;
17
- this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
50
+ this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: hasParameter('debug') ? "debug" /* LogLevel.DEBUG */ : "info" /* LogLevel.INFO */ });
18
51
  this.log.debug('Matterbridge plugin manager starting...');
19
52
  this.server = new BroadcastServer('plugins', this.log);
20
53
  this.server.on('broadcast_message', this.msgHandler.bind(this));
@@ -187,7 +220,7 @@ export class PluginManager extends EventEmitter {
187
220
  {
188
221
  const plugin = this.get(msg.params.name);
189
222
  if (plugin) {
190
- this.saveConfigFromJson(plugin, msg.params.config, msg.params.restartRequired);
223
+ this.saveConfigFromJson(plugin, msg.params.config, msg.params.restartRequired); // No await as it's not necessary to wait
191
224
  this.server.respond({ ...msg, result: { success: true } });
192
225
  }
193
226
  else {
@@ -225,25 +258,62 @@ export class PluginManager extends EventEmitter {
225
258
  }
226
259
  }
227
260
  }
261
+ /**
262
+ * Gets the number of plugins.
263
+ *
264
+ * @returns {number} The number of plugins.
265
+ */
228
266
  get length() {
229
267
  return this._plugins.size;
230
268
  }
269
+ /**
270
+ * Gets the number of plugins.
271
+ *
272
+ * @returns {number} The number of plugins.
273
+ */
231
274
  get size() {
232
275
  return this._plugins.size;
233
276
  }
277
+ /**
278
+ * Checks if a plugin with the specified name exists.
279
+ *
280
+ * @param {string} name - The name of the plugin.
281
+ * @returns {boolean} True if the plugin exists, false otherwise.
282
+ */
234
283
  has(name) {
235
284
  return this._plugins.has(name);
236
285
  }
286
+ /**
287
+ * Gets a plugin by its name.
288
+ *
289
+ * @param {string} name - The name of the plugin.
290
+ * @returns {Plugin | undefined} The plugin, or undefined if not found.
291
+ */
237
292
  get(name) {
238
293
  return this._plugins.get(name);
239
294
  }
295
+ /**
296
+ * Adds a plugin to the manager.
297
+ *
298
+ * @param {Plugin} plugin - The plugin to add.
299
+ * @returns {Plugin} The added plugin.
300
+ */
240
301
  set(plugin) {
241
302
  this._plugins.set(plugin.name, plugin);
242
303
  return plugin;
243
304
  }
305
+ /**
306
+ * Clears all plugins from the manager.
307
+ */
244
308
  clear() {
245
309
  this._plugins.clear();
246
310
  }
311
+ /**
312
+ * Converts a plugin or API plugin to a storage plugin.
313
+ *
314
+ * @param {Plugin | ApiPlugin} plugin - The plugin or API plugin to convert.
315
+ * @returns {StoragePlugin} The converted storage plugin.
316
+ */
247
317
  toStoragePlugin(plugin) {
248
318
  return {
249
319
  name: plugin.name,
@@ -255,6 +325,12 @@ export class PluginManager extends EventEmitter {
255
325
  enabled: plugin.enabled,
256
326
  };
257
327
  }
328
+ /**
329
+ * Converts a plugin to an API plugin.
330
+ *
331
+ * @param {Plugin} plugin - The plugin to convert.
332
+ * @returns {ApiPlugin} The converted API plugin.
333
+ */
258
334
  toApiPlugin(plugin) {
259
335
  return {
260
336
  name: plugin.name,
@@ -284,9 +360,19 @@ export class PluginManager extends EventEmitter {
284
360
  matter: plugin.serverNode ? this.matterbridge.getServerNodeData(plugin.serverNode) : undefined,
285
361
  };
286
362
  }
363
+ /**
364
+ * Gets an array of all plugins.
365
+ *
366
+ * @returns {Plugin[]} An array of all plugins.
367
+ */
287
368
  array() {
288
369
  return Array.from(this._plugins.values());
289
370
  }
371
+ /**
372
+ * Gets a StoragePlugin array of all plugins suitable for serialization.
373
+ *
374
+ * @returns {StoragePlugin[]} An array of all plugins.
375
+ */
290
376
  storagePluginArray() {
291
377
  const storagePlugins = [];
292
378
  for (const plugin of this._plugins.values()) {
@@ -294,6 +380,11 @@ export class PluginManager extends EventEmitter {
294
380
  }
295
381
  return storagePlugins;
296
382
  }
383
+ /**
384
+ * Gets an ApiPlugin array of all plugins suitable for serialization.
385
+ *
386
+ * @returns {ApiPlugin[]} An array of all plugins.
387
+ */
297
388
  apiPluginArray() {
298
389
  const apiPlugins = [];
299
390
  for (const plugin of this._plugins.values()) {
@@ -301,9 +392,20 @@ export class PluginManager extends EventEmitter {
301
392
  }
302
393
  return apiPlugins;
303
394
  }
395
+ /**
396
+ * Gets an iterator for the plugins.
397
+ *
398
+ * @returns {IterableIterator<Plugin>} An iterator for the plugins.
399
+ */
304
400
  [Symbol.iterator]() {
305
401
  return this._plugins.values();
306
402
  }
403
+ /**
404
+ * Executes a provided function once for each plugin.
405
+ *
406
+ * @param {Function} callback - The function to execute for each plugin.
407
+ * @returns {Promise<void>}
408
+ */
307
409
  async forEach(callback) {
308
410
  if (this.size === 0)
309
411
  return;
@@ -317,23 +419,40 @@ export class PluginManager extends EventEmitter {
317
419
  });
318
420
  await Promise.all(tasks);
319
421
  }
422
+ /**
423
+ * Sets the log level for the plugin manager.
424
+ *
425
+ * @param {LogLevel} logLevel - The log level to set.
426
+ */
320
427
  set logLevel(logLevel) {
321
428
  this.log.logLevel = logLevel;
322
429
  }
430
+ /**
431
+ * Loads registered plugins from storage.
432
+ *
433
+ * @returns {Promise<StoragePlugin[]>} A promise that resolves to an array of registered plugins.
434
+ */
323
435
  async loadFromStorage() {
324
436
  if (!this.matterbridge.nodeContext) {
325
437
  throw new Error('loadFromStorage: node context is not available.');
326
438
  }
439
+ // Load the array from storage and convert it to a map
327
440
  const pluginsArray = await this.matterbridge.nodeContext.get('plugins', []);
328
441
  for (const plugin of pluginsArray)
329
442
  this._plugins.set(plugin.name, plugin);
330
443
  this.log.debug(`Loaded ${BLUE}${pluginsArray.length}${db} plugins from storage`);
331
444
  return pluginsArray;
332
445
  }
446
+ /**
447
+ * Saves registered plugins to storage.
448
+ *
449
+ * @returns {Promise<number>} A promise that resolves to the number of registered plugins.
450
+ */
333
451
  async saveToStorage() {
334
452
  if (!this.matterbridge.nodeContext) {
335
453
  throw new Error('loadFromStorage: node context is not available.');
336
454
  }
455
+ // Convert the map to an array
337
456
  const plugins = [];
338
457
  for (const plugin of this.array()) {
339
458
  plugins.push({
@@ -350,13 +469,22 @@ export class PluginManager extends EventEmitter {
350
469
  this.log.debug(`Saved ${BLUE}${plugins.length}${db} plugins to storage`);
351
470
  return plugins.length;
352
471
  }
472
+ /**
473
+ * Resolves the name of a plugin by loading and parsing its package.json file.
474
+ * It will first try to resolve the path as is, then in the global modules directory, and finally in the matterbridge plugin directory.
475
+ *
476
+ * @param {string} nameOrPath - The name of the plugin or the path to the plugin's package.json file.
477
+ * @returns {Promise<string | null>} A promise that resolves to the path of the plugin's package.json file or null if it could not be resolved.
478
+ */
353
479
  async resolve(nameOrPath) {
354
480
  const { default: path } = await import('node:path');
355
481
  const { promises } = await import('node:fs');
356
482
  if (!nameOrPath.endsWith('package.json'))
357
483
  nameOrPath = path.join(nameOrPath, 'package.json');
484
+ // Resolve the package.json of the plugin
358
485
  let packageJsonPath = path.resolve(nameOrPath);
359
486
  this.log.debug(`Resolving plugin path ${plg}${packageJsonPath}${db}`);
487
+ // Check if the package.json file exists at the specified path or next try in the global modules directory
360
488
  try {
361
489
  await promises.access(packageJsonPath);
362
490
  }
@@ -365,6 +493,7 @@ export class PluginManager extends EventEmitter {
365
493
  packageJsonPath = path.join(this.matterbridge.globalModulesDirectory, nameOrPath);
366
494
  this.log.debug(`Trying at ${plg}${packageJsonPath}${db}`);
367
495
  }
496
+ // Check if the package.json file exists at the global modules directory or next try in the matterbridge plugin directory
368
497
  try {
369
498
  await promises.access(packageJsonPath);
370
499
  }
@@ -374,7 +503,9 @@ export class PluginManager extends EventEmitter {
374
503
  this.log.debug(`Trying at ${plg}${packageJsonPath}${db}`);
375
504
  }
376
505
  try {
506
+ // Load the package.json of the plugin or fails if even not found in the matterbridge plugin directory
377
507
  const packageJson = JSON.parse(await promises.readFile(packageJsonPath, 'utf8'));
508
+ // Check for main issues
378
509
  if (!packageJson.name) {
379
510
  this.log.error(`Package.json name not found at ${packageJsonPath}`);
380
511
  return null;
@@ -387,6 +518,7 @@ export class PluginManager extends EventEmitter {
387
518
  this.log.error(`Plugin at ${packageJsonPath} has no main entrypoint in package.json`);
388
519
  return null;
389
520
  }
521
+ // Check for @project-chip and @matter packages in dependencies and devDependencies
390
522
  const checkForProjectChipPackages = (dependencies) => {
391
523
  return Object.keys(dependencies).filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matter'));
392
524
  };
@@ -408,6 +540,7 @@ export class PluginManager extends EventEmitter {
408
540
  this.log.error(`Please open an issue on the plugin repository to remove them.`);
409
541
  return null;
410
542
  }
543
+ // Check for matterbridge package in dependencies and devDependencies
411
544
  const checkForMatterbridgePackage = (dependencies) => {
412
545
  return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
413
546
  };
@@ -437,13 +570,19 @@ export class PluginManager extends EventEmitter {
437
570
  return null;
438
571
  }
439
572
  }
573
+ /**
574
+ * Installs a package globally using npm.
575
+ *
576
+ * @param {string} packageName - The name of the package to install.
577
+ * @returns {Promise<boolean>} A promise that resolves to true if the installation was successful, false otherwise.
578
+ */
440
579
  async install(packageName) {
441
580
  this.log.debug(`Installing plugin ${plg}${packageName}${db}...`);
442
581
  const { spawnCommand } = await import('./utils/spawn.js');
443
582
  if (await spawnCommand('npm', ['install', '-g', packageName, '--omit=dev', '--verbose'], 'install', packageName)) {
444
583
  this.matterbridge.restartRequired = true;
445
584
  this.matterbridge.fixedRestartRequired = true;
446
- packageName = packageName.replace(/@.*$/, '');
585
+ packageName = packageName.replace(/@.*$/, ''); // Remove @version if present
447
586
  if (packageName !== 'matterbridge') {
448
587
  if (!this.has(packageName))
449
588
  await this.add(packageName);
@@ -464,6 +603,12 @@ export class PluginManager extends EventEmitter {
464
603
  return false;
465
604
  }
466
605
  }
606
+ /**
607
+ * Uninstalls a package globally using npm.
608
+ *
609
+ * @param {string} packageName - The name of the package to uninstall.
610
+ * @returns {Promise<boolean>} A promise that resolves to true if the uninstallation was successful, false otherwise.
611
+ */
467
612
  async uninstall(packageName) {
468
613
  this.log.debug(`Uninstalling plugin ${plg}${packageName}${db}...`);
469
614
  const { spawnCommand } = await import('./utils/spawn.js');
@@ -485,6 +630,12 @@ export class PluginManager extends EventEmitter {
485
630
  return false;
486
631
  }
487
632
  }
633
+ /**
634
+ * Get the author of a plugin from its package.json.
635
+ *
636
+ * @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
637
+ * @returns {string} The author of the plugin, or 'Unknown author' if not found.
638
+ */
488
639
  getAuthor(packageJson) {
489
640
  if (packageJson.author && typeof packageJson.author === 'string')
490
641
  return packageJson.author;
@@ -492,6 +643,12 @@ export class PluginManager extends EventEmitter {
492
643
  return packageJson.author.name;
493
644
  return 'Unknown author';
494
645
  }
646
+ /**
647
+ * Get the homepage of a plugin from its package.json.
648
+ *
649
+ * @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
650
+ * @returns {string | undefined} The homepage of the plugin, or undefined if not found.
651
+ */
495
652
  getHomepage(packageJson) {
496
653
  if (packageJson.homepage && typeof packageJson.homepage === 'string' && packageJson.homepage.includes('http')) {
497
654
  return packageJson.homepage.replace('git+', '').replace('.git', '');
@@ -500,7 +657,14 @@ export class PluginManager extends EventEmitter {
500
657
  return packageJson.repository.url.replace('git+', '').replace('.git', '');
501
658
  }
502
659
  }
660
+ /**
661
+ * Get the help URL of a plugin from its package.json.
662
+ *
663
+ * @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
664
+ * @returns {string | undefined} The URL to the help page or to the README file, or undefined if not found.
665
+ */
503
666
  getHelp(packageJson) {
667
+ // If there's a help field that looks like a URL, return it.
504
668
  if (packageJson.help && typeof packageJson.help === 'string' && packageJson.help.startsWith('http')) {
505
669
  return packageJson.help;
506
670
  }
@@ -511,7 +675,14 @@ export class PluginManager extends EventEmitter {
511
675
  return packageJson.homepage.replace('git+', '').replace('.git', '');
512
676
  }
513
677
  }
678
+ /**
679
+ * Get the changelog URL of a plugin from its package.json.
680
+ *
681
+ * @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
682
+ * @returns {string | undefined} The URL to the CHANGELOG file, or undefined if not found.
683
+ */
514
684
  getChangelog(packageJson) {
685
+ // If there's a changelog field that looks like a URL, return it.
515
686
  if (packageJson.changelog && typeof packageJson.changelog === 'string' && packageJson.changelog.startsWith('http')) {
516
687
  return packageJson.changelog;
517
688
  }
@@ -522,6 +693,13 @@ export class PluginManager extends EventEmitter {
522
693
  return packageJson.homepage.replace('git+', '').replace('.git', '');
523
694
  }
524
695
  }
696
+ /**
697
+ * Get the first funding URL(s) of a plugin from its package.json.
698
+ *
699
+ * @param {Record<string, any>} packageJson - The package.json object of the plugin.
700
+ * @returns {string | undefined} The first funding URLs, or undefined if not found.
701
+ */
702
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
525
703
  getFunding(packageJson) {
526
704
  const funding = packageJson.funding;
527
705
  if (!funding)
@@ -530,16 +708,27 @@ export class PluginManager extends EventEmitter {
530
708
  return;
531
709
  if (typeof funding === 'string' && funding.startsWith('http'))
532
710
  return funding;
711
+ // Normalize funding into an array.
533
712
  const fundingEntries = Array.isArray(funding) ? funding : [funding];
534
713
  for (const entry of fundingEntries) {
535
714
  if (entry && typeof entry === 'string' && entry.startsWith('http')) {
715
+ // If the funding entry is a string, assume it is a URL.
536
716
  return entry;
537
717
  }
538
718
  else if (entry && typeof entry === 'object' && typeof entry.url === 'string' && entry.url.startsWith('http')) {
719
+ // If it's an object with a 'url' property, use that.
539
720
  return entry.url;
540
721
  }
541
722
  }
542
723
  }
724
+ /**
725
+ * Parses the plugin package.json and returns it.
726
+ * It will also log warnings and errors for missing or invalid fields.
727
+ * It will return null if critical errors are found.
728
+ *
729
+ * @param {Plugin | PluginName} plugin - The plugin to load the package from.
730
+ * @returns {Promise<Record<string, string | number | object> | null>} A promise that resolves to the parsed package.json object or null if it could not be parsed.
731
+ */
543
732
  async parse(plugin) {
544
733
  const { promises } = await import('node:fs');
545
734
  if (typeof plugin === 'string') {
@@ -577,6 +766,7 @@ export class PluginManager extends EventEmitter {
577
766
  plugin.funding = this.getFunding(packageJson);
578
767
  if (!plugin.type)
579
768
  this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no type`);
769
+ // Check for @project-chip and @matter packages in dependencies and devDependencies
580
770
  const checkForProjectChipPackages = (dependencies) => {
581
771
  return Object.keys(dependencies).filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matter'));
582
772
  };
@@ -598,6 +788,7 @@ export class PluginManager extends EventEmitter {
598
788
  this.log.error(`Please open an issue on the plugin repository to remove them.`);
599
789
  return null;
600
790
  }
791
+ // Check for matterbridge package in dependencies and devDependencies
601
792
  const checkForMatterbridgePackage = (dependencies) => {
602
793
  return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
603
794
  };
@@ -627,6 +818,16 @@ export class PluginManager extends EventEmitter {
627
818
  return null;
628
819
  }
629
820
  }
821
+ /**
822
+ * Enables a plugin by its name or path.
823
+ *
824
+ * This method enables a plugin by setting its `enabled` property to `true` and saving the updated
825
+ * plugin information to storage. It first checks if the plugin is already registered in the `_plugins` map.
826
+ * If not, it attempts to resolve the plugin's `package.json` file to retrieve its name and enable it.
827
+ *
828
+ * @param {string} nameOrPath - The name or path of the plugin to enable.
829
+ * @returns {Promise<Plugin | null>} A promise that resolves to the enabled plugin object, or null if the plugin could not be enabled.
830
+ */
630
831
  async enable(nameOrPath) {
631
832
  const { promises } = await import('node:fs');
632
833
  if (!nameOrPath)
@@ -662,6 +863,16 @@ export class PluginManager extends EventEmitter {
662
863
  return null;
663
864
  }
664
865
  }
866
+ /**
867
+ * Disables a plugin by its name or path.
868
+ *
869
+ * This method disables a plugin by setting its `enabled` property to `false` and saving the updated
870
+ * plugin information to storage. It first checks if the plugin is already registered in the `_plugins` map.
871
+ * If not, it attempts to resolve the plugin's `package.json` file to retrieve its name and disable it.
872
+ *
873
+ * @param {string} nameOrPath - The name or path of the plugin to enable.
874
+ * @returns {Promise<Plugin | null>} A promise that resolves to the disabled plugin object, or null if the plugin could not be disabled.
875
+ */
665
876
  async disable(nameOrPath) {
666
877
  const { promises } = await import('node:fs');
667
878
  if (!nameOrPath)
@@ -697,6 +908,16 @@ export class PluginManager extends EventEmitter {
697
908
  return null;
698
909
  }
699
910
  }
911
+ /**
912
+ * Removes a plugin by its name or path.
913
+ *
914
+ * This method removes a plugin from the `_plugins` map and saves the updated plugin information to storage.
915
+ * It first checks if the plugin is already registered in the `_plugins` map. If not, it attempts to resolve
916
+ * the plugin's `package.json` file to retrieve its name and remove it.
917
+ *
918
+ * @param {string} nameOrPath - The name or path of the plugin to remove.
919
+ * @returns {Promise<Plugin | null>} A promise that resolves to the removed plugin object, or null if the plugin could not be removed.
920
+ */
700
921
  async remove(nameOrPath) {
701
922
  const { promises } = await import('node:fs');
702
923
  if (!nameOrPath)
@@ -732,6 +953,17 @@ export class PluginManager extends EventEmitter {
732
953
  return null;
733
954
  }
734
955
  }
956
+ /**
957
+ * Adds a plugin by its name or path.
958
+ *
959
+ * This method adds a plugin to the plugins map and saves the updated plugin information to storage.
960
+ * It first resolves the plugin's `package.json` file to retrieve its details. If the plugin is already
961
+ * registered, it logs an info message and returns null. Otherwise, it registers the plugin, enables it,
962
+ * and saves the updated plugin information to storage.
963
+ *
964
+ * @param {string} nameOrPath - The name or path of the plugin to add.
965
+ * @returns {Promise<Plugin | null>} A promise that resolves to the added plugin object, or null if the plugin could not be added.
966
+ */
735
967
  async add(nameOrPath) {
736
968
  const { promises } = await import('node:fs');
737
969
  if (!nameOrPath)
@@ -771,6 +1003,15 @@ export class PluginManager extends EventEmitter {
771
1003
  return null;
772
1004
  }
773
1005
  }
1006
+ /**
1007
+ * Loads a plugin and returns the corresponding MatterbridgePlatform instance.
1008
+ *
1009
+ * @param {Plugin | PluginName} plugin - The plugin to load.
1010
+ * @param {boolean} start - Optional flag indicating whether to start the plugin after loading. Default is false.
1011
+ * @param {string} message - Optional message to pass to the plugin when starting.
1012
+ * @param {boolean} configure - Optional flag indicating whether to configure the plugin after loading. Default is false.
1013
+ * @returns {Promise<MatterbridgePlatform | undefined>} A Promise that resolves to the loaded MatterbridgePlatform instance or undefined.
1014
+ */
774
1015
  async load(plugin, start = false, message = '', configure = false) {
775
1016
  const { promises } = await import('node:fs');
776
1017
  const { default: path } = await import('node:path');
@@ -792,15 +1033,20 @@ export class PluginManager extends EventEmitter {
792
1033
  }
793
1034
  this.log.info(`Loading plugin ${plg}${plugin.name}${nf} type ${typ}${plugin.type}${nf}`);
794
1035
  try {
1036
+ // Load the package.json of the plugin
795
1037
  const packageJson = JSON.parse(await promises.readFile(plugin.path, 'utf8'));
1038
+ // Resolve the main module path relative to package.json
796
1039
  const pluginEntry = path.resolve(path.dirname(plugin.path), packageJson.main);
1040
+ // Dynamically import the plugin
797
1041
  const { pathToFileURL } = await import('node:url');
798
1042
  const pluginUrl = pathToFileURL(pluginEntry);
799
1043
  this.log.debug(`Importing plugin ${plg}${plugin.name}${db} from ${pluginUrl.href}`);
800
1044
  const pluginInstance = (await import(pluginUrl.href));
801
1045
  this.log.debug(`Imported plugin ${plg}${plugin.name}${db} from ${pluginUrl.href}`);
1046
+ // Call the default export function of the plugin, passing this MatterBridge instance, the log and the config
802
1047
  if (pluginInstance.default) {
803
1048
  const config = await this.loadConfig(plugin);
1049
+ // Preset the plugin properties here in case the plugin throws an error during loading. In this case the user can change the config and restart the plugin.
804
1050
  plugin.name = packageJson.name;
805
1051
  plugin.description = packageJson.description ?? 'No description';
806
1052
  plugin.version = packageJson.version;
@@ -809,13 +1055,14 @@ export class PluginManager extends EventEmitter {
809
1055
  plugin.schemaJson = await this.loadSchema(plugin);
810
1056
  config.name = packageJson.name;
811
1057
  config.version = packageJson.version;
812
- const log = new AnsiLogger({ logName: plugin.description, logTimestampFormat: 4, logLevel: config.debug ? "debug" : this.matterbridge.logLevel });
1058
+ const log = new AnsiLogger({ logName: plugin.description, logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: config.debug ? "debug" /* LogLevel.DEBUG */ : this.matterbridge.logLevel });
813
1059
  const platform = pluginInstance.default(this.matterbridge, log, config);
814
1060
  config.type = platform.type;
815
1061
  platform.name = packageJson.name;
816
1062
  platform.config = config;
817
1063
  platform.version = packageJson.version;
818
1064
  platform.isLoaded = true;
1065
+ // @ts-expect-error - setMatterNode is intentionally private
819
1066
  platform.setMatterNode?.(this.matterbridge.addBridgedEndpoint.bind(this.matterbridge), this.matterbridge.removeBridgedEndpoint.bind(this.matterbridge), this.matterbridge.removeAllBridgedEndpoints.bind(this.matterbridge), this.matterbridge.addVirtualEndpoint.bind(this.matterbridge));
820
1067
  plugin.name = packageJson.name;
821
1068
  plugin.description = packageJson.description ?? 'No description';
@@ -829,7 +1076,7 @@ export class PluginManager extends EventEmitter {
829
1076
  plugin.platform = platform;
830
1077
  plugin.loaded = true;
831
1078
  plugin.registeredDevices = 0;
832
- await this.saveToStorage();
1079
+ await this.saveToStorage(); // Save the plugin to storage
833
1080
  this.log.notice(`Loaded plugin ${plg}${plugin.name}${nt} type ${typ}${platform.type}${nt} (entrypoint ${UNDERLINE}${pluginEntry}${UNDERLINEOFF})`);
834
1081
  this.emit('loaded', plugin.name);
835
1082
  if (start)
@@ -849,6 +1096,14 @@ export class PluginManager extends EventEmitter {
849
1096
  }
850
1097
  return undefined;
851
1098
  }
1099
+ /**
1100
+ * Starts a plugin.
1101
+ *
1102
+ * @param {Plugin | PluginName} plugin - The plugin to start.
1103
+ * @param {string} [message] - Optional message to pass to the plugin's onStart method.
1104
+ * @param {boolean} [configure] - Indicates whether to configure the plugin after starting (default false).
1105
+ * @returns {Promise<Plugin | undefined>} A promise that resolves when the plugin is started successfully, or rejects with an error if starting the plugin fails.
1106
+ */
852
1107
  async start(plugin, message, configure = false) {
853
1108
  if (typeof plugin === 'string') {
854
1109
  const p = this._plugins.get(plugin);
@@ -888,6 +1143,12 @@ export class PluginManager extends EventEmitter {
888
1143
  }
889
1144
  return undefined;
890
1145
  }
1146
+ /**
1147
+ * Configures a plugin.
1148
+ *
1149
+ * @param {Plugin | PluginName} plugin - The plugin to configure.
1150
+ * @returns {Promise<Plugin | undefined>} A promise that resolves when the plugin is configured successfully, or rejects with an error if configuration fails.
1151
+ */
891
1152
  async configure(plugin) {
892
1153
  if (typeof plugin === 'string') {
893
1154
  const p = this._plugins.get(plugin);
@@ -928,6 +1189,18 @@ export class PluginManager extends EventEmitter {
928
1189
  }
929
1190
  return undefined;
930
1191
  }
1192
+ /**
1193
+ * Shuts down a plugin.
1194
+ *
1195
+ * This method shuts down a plugin by calling its `onShutdown` method and resetting its state.
1196
+ * It logs the shutdown process and optionally removes all devices associated with the plugin.
1197
+ *
1198
+ * @param {Plugin | PluginName} plugin - The plugin to shut down.
1199
+ * @param {string} [reason] - The reason for shutting down the plugin.
1200
+ * @param {boolean} [removeAllDevices] - Whether to remove all devices associated with the plugin.
1201
+ * @param {boolean} [force] - Whether to force the shutdown even if the plugin is not loaded or started.
1202
+ * @returns {Promise<Plugin | undefined>} A promise that resolves to the shut down plugin object, or undefined if the shutdown failed.
1203
+ */
931
1204
  async shutdown(plugin, reason, removeAllDevices = false, force = false) {
932
1205
  if (typeof plugin === 'string') {
933
1206
  const p = this._plugins.get(plugin);
@@ -984,6 +1257,15 @@ export class PluginManager extends EventEmitter {
984
1257
  }
985
1258
  return undefined;
986
1259
  }
1260
+ /**
1261
+ * Loads the configuration for a plugin.
1262
+ * If the configuration file exists, it reads the file and returns the parsed JSON data.
1263
+ * If the configuration file does not exist, it creates a new file with default configuration and returns it.
1264
+ * If any error occurs during file access or creation, it logs an error and return un empty config.
1265
+ *
1266
+ * @param {Plugin} plugin - The plugin for which to load the configuration.
1267
+ * @returns {Promise<PlatformConfig>} A promise that resolves to the loaded or created configuration.
1268
+ */
987
1269
  async loadConfig(plugin) {
988
1270
  const { default: path } = await import('node:path');
989
1271
  const { promises } = await import('node:fs');
@@ -994,6 +1276,8 @@ export class PluginManager extends EventEmitter {
994
1276
  const data = await promises.readFile(configFile, 'utf8');
995
1277
  const config = JSON.parse(data);
996
1278
  this.log.debug(`Loaded config file ${configFile} for plugin ${plg}${plugin.name}${db}.`);
1279
+ // this.log.debug(`Loaded config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
1280
+ // The first time a plugin is added to the system, the config file is created with the plugin name and type "AnyPlatform".
997
1281
  config.name = plugin.name;
998
1282
  config.type = plugin.type;
999
1283
  if (config.debug === undefined)
@@ -1020,6 +1304,7 @@ export class PluginManager extends EventEmitter {
1020
1304
  try {
1021
1305
  await promises.writeFile(configFile, JSON.stringify(config, null, 2), 'utf8');
1022
1306
  this.log.debug(`Created config file ${configFile} for plugin ${plg}${plugin.name}${db}.`);
1307
+ // this.log.debug(`Created config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
1023
1308
  return config;
1024
1309
  }
1025
1310
  catch (err) {
@@ -1033,6 +1318,19 @@ export class PluginManager extends EventEmitter {
1033
1318
  }
1034
1319
  }
1035
1320
  }
1321
+ /**
1322
+ * Saves the configuration of a plugin to a file.
1323
+ *
1324
+ * This method saves the configuration of the specified plugin to a JSON file in the matterbridge directory.
1325
+ * If the plugin's configuration is not found, it logs an error and rejects the promise. If the configuration
1326
+ * is successfully saved, it logs a debug message. If an error occurs during the file write operation, it logs
1327
+ * the error and rejects the promise.
1328
+ *
1329
+ * @param {Plugin} plugin - The plugin whose configuration is to be saved.
1330
+ * @param {boolean} [restartRequired] - Indicates whether a restart is required after saving the configuration.
1331
+ * @returns {Promise<void>} A promise that resolves when the configuration is successfully saved, or rejects if an error occurs.
1332
+ * @throws {Error} If the plugin's configuration is not found.
1333
+ */
1036
1334
  async saveConfigFromPlugin(plugin, restartRequired = false) {
1037
1335
  const { default: path } = await import('node:path');
1038
1336
  const { promises } = await import('node:fs');
@@ -1047,6 +1345,7 @@ export class PluginManager extends EventEmitter {
1047
1345
  if (restartRequired)
1048
1346
  plugin.restartRequired = true;
1049
1347
  this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}`);
1348
+ // this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, plugin.platform.config);
1050
1349
  return Promise.resolve();
1051
1350
  }
1052
1351
  catch (err) {
@@ -1054,6 +1353,20 @@ export class PluginManager extends EventEmitter {
1054
1353
  return Promise.reject(err);
1055
1354
  }
1056
1355
  }
1356
+ /**
1357
+ * Saves the configuration of a plugin from a JSON object to a file.
1358
+ *
1359
+ * This method saves the provided configuration of the specified plugin to a JSON file in the matterbridge directory.
1360
+ * It first checks if the configuration data is valid by ensuring it contains the correct name and type, and matches
1361
+ * the plugin's name. If the configuration data is invalid, it logs an error and returns. If the configuration is
1362
+ * successfully saved, it updates the plugin's `configJson` property and logs a debug message. If an error occurs
1363
+ * during the file write operation, it logs the error and returns.
1364
+ *
1365
+ * @param {Plugin} plugin - The plugin whose configuration is to be saved.
1366
+ * @param {PlatformConfig} config - The configuration data to be saved.
1367
+ * @param {boolean} [restartRequired] - Indicates whether a restart is required after saving the configuration.
1368
+ * @returns {Promise<void>} A promise that resolves when the configuration is successfully saved, or returns if an error occurs.
1369
+ */
1057
1370
  async saveConfigFromJson(plugin, config, restartRequired = false) {
1058
1371
  const { default: path } = await import('node:path');
1059
1372
  const { promises } = await import('node:fs');
@@ -1072,12 +1385,23 @@ export class PluginManager extends EventEmitter {
1072
1385
  plugin.platform.onConfigChanged(config).catch((err) => this.log.error(`Error calling onConfigChanged for plugin ${plg}${plugin.name}${er}: ${err}`));
1073
1386
  }
1074
1387
  this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}`);
1388
+ // this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
1075
1389
  }
1076
1390
  catch (err) {
1077
1391
  logError(this.log, `Error saving config file ${configFile} for plugin ${plg}${plugin.name}${er}`, err);
1078
1392
  return;
1079
1393
  }
1080
1394
  }
1395
+ /**
1396
+ * Loads the schema for a plugin.
1397
+ *
1398
+ * This method attempts to load the schema file for the specified plugin. If the schema file is found,
1399
+ * it reads and parses the file, updates the schema's title and description, and logs the process.
1400
+ * If the schema file is not found, it logs the event and loads a default schema for the plugin.
1401
+ *
1402
+ * @param {Plugin} plugin - The plugin whose schema is to be loaded.
1403
+ * @returns {Promise<PlatformSchema>} A promise that resolves to the loaded schema object, or the default schema if the schema file is not found.
1404
+ */
1081
1405
  async loadSchema(plugin) {
1082
1406
  const { promises } = await import('node:fs');
1083
1407
  const schemaFile = plugin.path.replace('package.json', `${plugin.name}.schema.json`);
@@ -1088,6 +1412,7 @@ export class PluginManager extends EventEmitter {
1088
1412
  schema.title = plugin.description;
1089
1413
  schema.description = plugin.name + ' v. ' + plugin.version + ' by ' + plugin.author;
1090
1414
  this.log.debug(`Loaded schema file ${schemaFile} for plugin ${plg}${plugin.name}${db}.`);
1415
+ // this.log.debug(`Loaded schema file ${schemaFile} for plugin ${plg}${plugin.name}${db}.\nSchema:${rs}\n`, schema);
1091
1416
  return schema;
1092
1417
  }
1093
1418
  catch (_err) {
@@ -1095,6 +1420,16 @@ export class PluginManager extends EventEmitter {
1095
1420
  return this.getDefaultSchema(plugin);
1096
1421
  }
1097
1422
  }
1423
+ /**
1424
+ * Returns the default schema for a plugin.
1425
+ *
1426
+ * This method generates a default schema object for the specified plugin. The schema includes
1427
+ * metadata such as the plugin's title, description, version, and author. It also defines the
1428
+ * properties of the schema, including the plugin's name, type, debug flag, and unregisterOnShutdown flag.
1429
+ *
1430
+ * @param {Plugin} plugin - The plugin for which the default schema is to be generated.
1431
+ * @returns {PlatformSchema} The default schema object for the plugin.
1432
+ */
1098
1433
  getDefaultSchema(plugin) {
1099
1434
  return {
1100
1435
  title: plugin.description,
@@ -1125,3 +1460,4 @@ export class PluginManager extends EventEmitter {
1125
1460
  };
1126
1461
  }
1127
1462
  }
1463
+ //# sourceMappingURL=pluginManager.js.map