matterbridge 3.5.0 → 3.5.1-dev-20260122-6461be3
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.
- package/CHANGELOG.md +18 -0
- package/README-DOCKER.md +4 -2
- package/README.md +4 -1
- package/bin/mb_coap.js +1 -1
- package/bin/mb_mdns.js +1 -1
- package/dist/broadcastServer.d.ts +0 -115
- package/dist/broadcastServer.js +1 -119
- package/dist/broadcastServerTypes.d.ts +0 -43
- package/dist/broadcastServerTypes.js +0 -24
- package/dist/cli.d.ts +1 -26
- package/dist/cli.js +2 -102
- package/dist/cliEmitter.d.ts +0 -36
- package/dist/cliEmitter.js +0 -37
- package/dist/cliHistory.d.ts +0 -42
- package/dist/cliHistory.js +1 -39
- package/dist/clusters/export.d.ts +0 -1
- package/dist/clusters/export.js +0 -2
- package/dist/deviceManager.d.ts +0 -108
- package/dist/deviceManager.js +2 -114
- package/dist/devices/airConditioner.d.ts +0 -75
- package/dist/devices/airConditioner.js +0 -57
- package/dist/devices/batteryStorage.d.ts +0 -43
- package/dist/devices/batteryStorage.js +1 -48
- package/dist/devices/cooktop.d.ts +0 -55
- package/dist/devices/cooktop.js +0 -56
- package/dist/devices/dishwasher.d.ts +0 -55
- package/dist/devices/dishwasher.js +0 -57
- package/dist/devices/evse.d.ts +0 -57
- package/dist/devices/evse.js +10 -74
- package/dist/devices/export.d.ts +0 -1
- package/dist/devices/export.js +0 -5
- package/dist/devices/extractorHood.d.ts +0 -41
- package/dist/devices/extractorHood.js +0 -43
- package/dist/devices/heatPump.d.ts +0 -43
- package/dist/devices/heatPump.js +2 -50
- package/dist/devices/laundryDryer.d.ts +0 -58
- package/dist/devices/laundryDryer.js +3 -62
- package/dist/devices/laundryWasher.d.ts +0 -64
- package/dist/devices/laundryWasher.js +4 -70
- package/dist/devices/microwaveOven.d.ts +1 -77
- package/dist/devices/microwaveOven.js +5 -88
- package/dist/devices/oven.d.ts +0 -82
- package/dist/devices/oven.js +0 -85
- package/dist/devices/refrigerator.d.ts +0 -100
- package/dist/devices/refrigerator.js +0 -102
- package/dist/devices/roboticVacuumCleaner.d.ts +0 -83
- package/dist/devices/roboticVacuumCleaner.js +9 -100
- package/dist/devices/solarPower.d.ts +0 -36
- package/dist/devices/solarPower.js +0 -38
- package/dist/devices/speaker.d.ts +0 -79
- package/dist/devices/speaker.js +0 -84
- package/dist/devices/temperatureControl.d.ts +0 -21
- package/dist/devices/temperatureControl.js +3 -24
- package/dist/devices/waterHeater.d.ts +0 -74
- package/dist/devices/waterHeater.js +2 -82
- package/dist/frontend.d.ts +4 -187
- package/dist/frontend.js +89 -505
- package/dist/frontendTypes.d.ts +0 -57
- package/dist/frontendTypes.js +0 -45
- package/dist/helpers.d.ts +0 -43
- package/dist/helpers.js +1 -54
- package/dist/index.d.ts +0 -23
- package/dist/index.js +0 -25
- package/dist/jestutils/export.d.ts +0 -1
- package/dist/jestutils/export.js +0 -1
- package/dist/jestutils/jestHelpers.d.ts +0 -255
- package/dist/jestutils/jestHelpers.js +16 -379
- package/dist/logger/export.d.ts +0 -1
- package/dist/logger/export.js +0 -1
- package/dist/matter/behaviors.d.ts +0 -1
- package/dist/matter/behaviors.js +0 -2
- package/dist/matter/clusters.d.ts +0 -1
- package/dist/matter/clusters.js +0 -2
- package/dist/matter/devices.d.ts +0 -1
- package/dist/matter/devices.js +0 -2
- package/dist/matter/endpoints.d.ts +0 -1
- package/dist/matter/endpoints.js +0 -2
- package/dist/matter/export.d.ts +0 -1
- package/dist/matter/export.js +0 -2
- package/dist/matter/types.d.ts +0 -1
- package/dist/matter/types.js +0 -2
- package/dist/matterNode.d.ts +0 -258
- package/dist/matterNode.js +9 -364
- package/dist/matterbridge.d.ts +0 -362
- package/dist/matterbridge.js +75 -864
- package/dist/matterbridgeAccessoryPlatform.d.ts +0 -36
- package/dist/matterbridgeAccessoryPlatform.js +0 -38
- package/dist/matterbridgeBehaviors.d.ts +0 -24
- package/dist/matterbridgeBehaviors.js +5 -68
- package/dist/matterbridgeDeviceTypes.d.ts +0 -649
- package/dist/matterbridgeDeviceTypes.js +6 -673
- package/dist/matterbridgeDynamicPlatform.d.ts +0 -36
- package/dist/matterbridgeDynamicPlatform.js +0 -38
- package/dist/matterbridgeEndpoint.d.ts +2 -1332
- package/dist/matterbridgeEndpoint.js +94 -1459
- package/dist/matterbridgeEndpointHelpers.d.ts +0 -425
- package/dist/matterbridgeEndpointHelpers.js +22 -487
- package/dist/matterbridgeEndpointTypes.d.ts +0 -70
- package/dist/matterbridgeEndpointTypes.js +0 -25
- package/dist/matterbridgePlatform.d.ts +0 -425
- package/dist/matterbridgePlatform.js +2 -453
- package/dist/matterbridgeTypes.d.ts +0 -46
- package/dist/matterbridgeTypes.js +0 -26
- package/dist/mb_coap.d.ts +1 -0
- package/dist/{dgram/mb_coap.js → mb_coap.js} +3 -41
- package/dist/mb_mdns.d.ts +1 -0
- package/dist/{dgram/mb_mdns.js → mb_mdns.js} +47 -81
- package/dist/pluginManager.d.ts +0 -305
- package/dist/pluginManager.js +8 -345
- package/dist/shelly.d.ts +0 -157
- package/dist/shelly.js +7 -178
- package/dist/spawn.d.ts +1 -0
- package/dist/{utils/spawn.js → spawn.js} +3 -73
- package/dist/storage/export.d.ts +0 -1
- package/dist/storage/export.js +0 -1
- package/dist/update.d.ts +0 -75
- package/dist/update.js +7 -100
- package/dist/utils/export.d.ts +1 -13
- package/dist/utils/export.js +1 -13
- package/dist/workerGlobalPrefix.d.ts +0 -24
- package/dist/workerGlobalPrefix.js +6 -40
- package/dist/workerTypes.d.ts +0 -25
- package/dist/workerTypes.js +0 -24
- package/dist/workers.d.ts +0 -61
- package/dist/workers.js +4 -68
- package/npm-shrinkwrap.json +80 -50
- package/package.json +8 -8
- package/dist/broadcastServer.d.ts.map +0 -1
- package/dist/broadcastServer.js.map +0 -1
- package/dist/broadcastServerTypes.d.ts.map +0 -1
- package/dist/broadcastServerTypes.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/cliEmitter.d.ts.map +0 -1
- package/dist/cliEmitter.js.map +0 -1
- package/dist/cliHistory.d.ts.map +0 -1
- package/dist/cliHistory.js.map +0 -1
- package/dist/clusters/export.d.ts.map +0 -1
- package/dist/clusters/export.js.map +0 -1
- package/dist/deviceManager.d.ts.map +0 -1
- package/dist/deviceManager.js.map +0 -1
- package/dist/devices/airConditioner.d.ts.map +0 -1
- package/dist/devices/airConditioner.js.map +0 -1
- package/dist/devices/batteryStorage.d.ts.map +0 -1
- package/dist/devices/batteryStorage.js.map +0 -1
- package/dist/devices/cooktop.d.ts.map +0 -1
- package/dist/devices/cooktop.js.map +0 -1
- package/dist/devices/dishwasher.d.ts.map +0 -1
- package/dist/devices/dishwasher.js.map +0 -1
- package/dist/devices/evse.d.ts.map +0 -1
- package/dist/devices/evse.js.map +0 -1
- package/dist/devices/export.d.ts.map +0 -1
- package/dist/devices/export.js.map +0 -1
- package/dist/devices/extractorHood.d.ts.map +0 -1
- package/dist/devices/extractorHood.js.map +0 -1
- package/dist/devices/heatPump.d.ts.map +0 -1
- package/dist/devices/heatPump.js.map +0 -1
- package/dist/devices/laundryDryer.d.ts.map +0 -1
- package/dist/devices/laundryDryer.js.map +0 -1
- package/dist/devices/laundryWasher.d.ts.map +0 -1
- package/dist/devices/laundryWasher.js.map +0 -1
- package/dist/devices/microwaveOven.d.ts.map +0 -1
- package/dist/devices/microwaveOven.js.map +0 -1
- package/dist/devices/oven.d.ts.map +0 -1
- package/dist/devices/oven.js.map +0 -1
- package/dist/devices/refrigerator.d.ts.map +0 -1
- package/dist/devices/refrigerator.js.map +0 -1
- package/dist/devices/roboticVacuumCleaner.d.ts.map +0 -1
- package/dist/devices/roboticVacuumCleaner.js.map +0 -1
- package/dist/devices/solarPower.d.ts.map +0 -1
- package/dist/devices/solarPower.js.map +0 -1
- package/dist/devices/speaker.d.ts.map +0 -1
- package/dist/devices/speaker.js.map +0 -1
- package/dist/devices/temperatureControl.d.ts.map +0 -1
- package/dist/devices/temperatureControl.js.map +0 -1
- package/dist/devices/waterHeater.d.ts.map +0 -1
- package/dist/devices/waterHeater.js.map +0 -1
- package/dist/dgram/coap.d.ts +0 -205
- package/dist/dgram/coap.d.ts.map +0 -1
- package/dist/dgram/coap.js +0 -365
- package/dist/dgram/coap.js.map +0 -1
- package/dist/dgram/dgram.d.ts +0 -144
- package/dist/dgram/dgram.d.ts.map +0 -1
- package/dist/dgram/dgram.js +0 -363
- package/dist/dgram/dgram.js.map +0 -1
- package/dist/dgram/mb_coap.d.ts +0 -24
- package/dist/dgram/mb_coap.d.ts.map +0 -1
- package/dist/dgram/mb_coap.js.map +0 -1
- package/dist/dgram/mb_mdns.d.ts +0 -24
- package/dist/dgram/mb_mdns.d.ts.map +0 -1
- package/dist/dgram/mb_mdns.js.map +0 -1
- package/dist/dgram/mdns.d.ts +0 -371
- package/dist/dgram/mdns.d.ts.map +0 -1
- package/dist/dgram/mdns.js +0 -934
- package/dist/dgram/mdns.js.map +0 -1
- package/dist/dgram/multicast.d.ts +0 -67
- package/dist/dgram/multicast.d.ts.map +0 -1
- package/dist/dgram/multicast.js +0 -179
- package/dist/dgram/multicast.js.map +0 -1
- package/dist/dgram/unicast.d.ts +0 -64
- package/dist/dgram/unicast.d.ts.map +0 -1
- package/dist/dgram/unicast.js +0 -100
- package/dist/dgram/unicast.js.map +0 -1
- package/dist/frontend.d.ts.map +0 -1
- package/dist/frontend.js.map +0 -1
- package/dist/frontendTypes.d.ts.map +0 -1
- package/dist/frontendTypes.js.map +0 -1
- package/dist/helpers.d.ts.map +0 -1
- package/dist/helpers.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/jestutils/export.d.ts.map +0 -1
- package/dist/jestutils/export.js.map +0 -1
- package/dist/jestutils/jestHelpers.d.ts.map +0 -1
- package/dist/jestutils/jestHelpers.js.map +0 -1
- package/dist/logger/export.d.ts.map +0 -1
- package/dist/logger/export.js.map +0 -1
- package/dist/matter/behaviors.d.ts.map +0 -1
- package/dist/matter/behaviors.js.map +0 -1
- package/dist/matter/clusters.d.ts.map +0 -1
- package/dist/matter/clusters.js.map +0 -1
- package/dist/matter/devices.d.ts.map +0 -1
- package/dist/matter/devices.js.map +0 -1
- package/dist/matter/endpoints.d.ts.map +0 -1
- package/dist/matter/endpoints.js.map +0 -1
- package/dist/matter/export.d.ts.map +0 -1
- package/dist/matter/export.js.map +0 -1
- package/dist/matter/types.d.ts.map +0 -1
- package/dist/matter/types.js.map +0 -1
- package/dist/matterNode.d.ts.map +0 -1
- package/dist/matterNode.js.map +0 -1
- package/dist/matterbridge.d.ts.map +0 -1
- package/dist/matterbridge.js.map +0 -1
- package/dist/matterbridgeAccessoryPlatform.d.ts.map +0 -1
- package/dist/matterbridgeAccessoryPlatform.js.map +0 -1
- package/dist/matterbridgeBehaviors.d.ts.map +0 -1
- package/dist/matterbridgeBehaviors.js.map +0 -1
- package/dist/matterbridgeDeviceTypes.d.ts.map +0 -1
- package/dist/matterbridgeDeviceTypes.js.map +0 -1
- package/dist/matterbridgeDynamicPlatform.d.ts.map +0 -1
- package/dist/matterbridgeDynamicPlatform.js.map +0 -1
- package/dist/matterbridgeEndpoint.d.ts.map +0 -1
- package/dist/matterbridgeEndpoint.js.map +0 -1
- package/dist/matterbridgeEndpointHelpers.d.ts.map +0 -1
- package/dist/matterbridgeEndpointHelpers.js.map +0 -1
- package/dist/matterbridgeEndpointTypes.d.ts.map +0 -1
- package/dist/matterbridgeEndpointTypes.js.map +0 -1
- package/dist/matterbridgePlatform.d.ts.map +0 -1
- package/dist/matterbridgePlatform.js.map +0 -1
- package/dist/matterbridgeTypes.d.ts.map +0 -1
- package/dist/matterbridgeTypes.js.map +0 -1
- package/dist/pluginManager.d.ts.map +0 -1
- package/dist/pluginManager.js.map +0 -1
- package/dist/shelly.d.ts.map +0 -1
- package/dist/shelly.js.map +0 -1
- package/dist/storage/export.d.ts.map +0 -1
- package/dist/storage/export.js.map +0 -1
- package/dist/update.d.ts.map +0 -1
- package/dist/update.js.map +0 -1
- package/dist/utils/colorUtils.d.ts +0 -101
- package/dist/utils/colorUtils.d.ts.map +0 -1
- package/dist/utils/colorUtils.js +0 -282
- package/dist/utils/colorUtils.js.map +0 -1
- package/dist/utils/commandLine.d.ts +0 -66
- package/dist/utils/commandLine.d.ts.map +0 -1
- package/dist/utils/commandLine.js +0 -123
- package/dist/utils/commandLine.js.map +0 -1
- package/dist/utils/copyDirectory.d.ts +0 -35
- package/dist/utils/copyDirectory.d.ts.map +0 -1
- package/dist/utils/copyDirectory.js +0 -76
- package/dist/utils/copyDirectory.js.map +0 -1
- package/dist/utils/createDirectory.d.ts +0 -34
- package/dist/utils/createDirectory.d.ts.map +0 -1
- package/dist/utils/createDirectory.js +0 -54
- package/dist/utils/createDirectory.js.map +0 -1
- package/dist/utils/createZip.d.ts +0 -39
- package/dist/utils/createZip.d.ts.map +0 -1
- package/dist/utils/createZip.js +0 -114
- package/dist/utils/createZip.js.map +0 -1
- package/dist/utils/deepCopy.d.ts +0 -32
- package/dist/utils/deepCopy.d.ts.map +0 -1
- package/dist/utils/deepCopy.js +0 -79
- package/dist/utils/deepCopy.js.map +0 -1
- package/dist/utils/deepEqual.d.ts +0 -54
- package/dist/utils/deepEqual.d.ts.map +0 -1
- package/dist/utils/deepEqual.js +0 -129
- package/dist/utils/deepEqual.js.map +0 -1
- package/dist/utils/error.d.ts +0 -45
- package/dist/utils/error.d.ts.map +0 -1
- package/dist/utils/error.js +0 -54
- package/dist/utils/error.js.map +0 -1
- package/dist/utils/export.d.ts.map +0 -1
- package/dist/utils/export.js.map +0 -1
- package/dist/utils/format.d.ts +0 -53
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/format.js +0 -78
- package/dist/utils/format.js.map +0 -1
- package/dist/utils/hex.d.ts +0 -89
- package/dist/utils/hex.d.ts.map +0 -1
- package/dist/utils/hex.js +0 -242
- package/dist/utils/hex.js.map +0 -1
- package/dist/utils/inspector.d.ts +0 -87
- package/dist/utils/inspector.d.ts.map +0 -1
- package/dist/utils/inspector.js +0 -268
- package/dist/utils/inspector.js.map +0 -1
- package/dist/utils/isValid.d.ts +0 -103
- package/dist/utils/isValid.d.ts.map +0 -1
- package/dist/utils/isValid.js +0 -162
- package/dist/utils/isValid.js.map +0 -1
- package/dist/utils/network.d.ts +0 -141
- package/dist/utils/network.d.ts.map +0 -1
- package/dist/utils/network.js +0 -314
- package/dist/utils/network.js.map +0 -1
- package/dist/utils/spawn.d.ts +0 -33
- package/dist/utils/spawn.d.ts.map +0 -1
- package/dist/utils/spawn.js.map +0 -1
- package/dist/utils/tracker.d.ts +0 -108
- package/dist/utils/tracker.d.ts.map +0 -1
- package/dist/utils/tracker.js +0 -264
- package/dist/utils/tracker.js.map +0 -1
- package/dist/utils/wait.d.ts +0 -54
- package/dist/utils/wait.d.ts.map +0 -1
- package/dist/utils/wait.js +0 -125
- package/dist/utils/wait.js.map +0 -1
- package/dist/workerGlobalPrefix.d.ts.map +0 -1
- package/dist/workerGlobalPrefix.js.map +0 -1
- package/dist/workerTypes.d.ts.map +0 -1
- package/dist/workerTypes.js.map +0 -1
- package/dist/workers.d.ts.map +0 -1
- package/dist/workers.js.map +0 -1
package/dist/pluginManager.js
CHANGED
|
@@ -1,37 +1,8 @@
|
|
|
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
|
|
25
1
|
import EventEmitter from 'node:events';
|
|
26
|
-
// AnsiLogger module
|
|
27
2
|
import { AnsiLogger, UNDERLINE, UNDERLINEOFF, BLUE, db, er, nf, nt, rs, wr, debugStringify, CYAN } from 'node-ansi-logger';
|
|
3
|
+
import { hasParameter, inspectError, logError } from '@matterbridge/utils';
|
|
28
4
|
import { plg, typ } from './matterbridgeTypes.js';
|
|
29
|
-
import { inspectError, logError } from './utils/error.js';
|
|
30
|
-
import { hasParameter } from './utils/commandLine.js';
|
|
31
5
|
import { BroadcastServer } from './broadcastServer.js';
|
|
32
|
-
/**
|
|
33
|
-
* Manages Matterbridge plugins.
|
|
34
|
-
*/
|
|
35
6
|
export class PluginManager extends EventEmitter {
|
|
36
7
|
matterbridge;
|
|
37
8
|
_plugins = new Map();
|
|
@@ -39,15 +10,10 @@ export class PluginManager extends EventEmitter {
|
|
|
39
10
|
server;
|
|
40
11
|
debug = hasParameter('debug') || hasParameter('verbose');
|
|
41
12
|
verbose = hasParameter('verbose');
|
|
42
|
-
/**
|
|
43
|
-
* Creates an instance of PluginManager.
|
|
44
|
-
*
|
|
45
|
-
* @param {Matterbridge} matterbridge - The Matterbridge instance.
|
|
46
|
-
*/
|
|
47
13
|
constructor(matterbridge) {
|
|
48
14
|
super();
|
|
49
15
|
this.matterbridge = matterbridge;
|
|
50
|
-
this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4
|
|
16
|
+
this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
|
|
51
17
|
this.log.debug('Matterbridge plugin manager starting...');
|
|
52
18
|
this.server = new BroadcastServer('plugins', this.log);
|
|
53
19
|
this.server.on('broadcast_message', this.msgHandler.bind(this));
|
|
@@ -220,7 +186,7 @@ export class PluginManager extends EventEmitter {
|
|
|
220
186
|
{
|
|
221
187
|
const plugin = this.get(msg.params.name);
|
|
222
188
|
if (plugin) {
|
|
223
|
-
this.saveConfigFromJson(plugin, msg.params.config, msg.params.restartRequired);
|
|
189
|
+
this.saveConfigFromJson(plugin, msg.params.config, msg.params.restartRequired);
|
|
224
190
|
this.server.respond({ ...msg, result: { success: true } });
|
|
225
191
|
}
|
|
226
192
|
else {
|
|
@@ -258,62 +224,25 @@ export class PluginManager extends EventEmitter {
|
|
|
258
224
|
}
|
|
259
225
|
}
|
|
260
226
|
}
|
|
261
|
-
/**
|
|
262
|
-
* Gets the number of plugins.
|
|
263
|
-
*
|
|
264
|
-
* @returns {number} The number of plugins.
|
|
265
|
-
*/
|
|
266
227
|
get length() {
|
|
267
228
|
return this._plugins.size;
|
|
268
229
|
}
|
|
269
|
-
/**
|
|
270
|
-
* Gets the number of plugins.
|
|
271
|
-
*
|
|
272
|
-
* @returns {number} The number of plugins.
|
|
273
|
-
*/
|
|
274
230
|
get size() {
|
|
275
231
|
return this._plugins.size;
|
|
276
232
|
}
|
|
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
|
-
*/
|
|
283
233
|
has(name) {
|
|
284
234
|
return this._plugins.has(name);
|
|
285
235
|
}
|
|
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
|
-
*/
|
|
292
236
|
get(name) {
|
|
293
237
|
return this._plugins.get(name);
|
|
294
238
|
}
|
|
295
|
-
/**
|
|
296
|
-
* Adds a plugin to the manager.
|
|
297
|
-
*
|
|
298
|
-
* @param {Plugin} plugin - The plugin to add.
|
|
299
|
-
* @returns {Plugin} The added plugin.
|
|
300
|
-
*/
|
|
301
239
|
set(plugin) {
|
|
302
240
|
this._plugins.set(plugin.name, plugin);
|
|
303
241
|
return plugin;
|
|
304
242
|
}
|
|
305
|
-
/**
|
|
306
|
-
* Clears all plugins from the manager.
|
|
307
|
-
*/
|
|
308
243
|
clear() {
|
|
309
244
|
this._plugins.clear();
|
|
310
245
|
}
|
|
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
|
-
*/
|
|
317
246
|
toStoragePlugin(plugin) {
|
|
318
247
|
return {
|
|
319
248
|
name: plugin.name,
|
|
@@ -325,12 +254,6 @@ export class PluginManager extends EventEmitter {
|
|
|
325
254
|
enabled: plugin.enabled,
|
|
326
255
|
};
|
|
327
256
|
}
|
|
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
|
-
*/
|
|
334
257
|
toApiPlugin(plugin) {
|
|
335
258
|
return {
|
|
336
259
|
name: plugin.name,
|
|
@@ -360,19 +283,9 @@ export class PluginManager extends EventEmitter {
|
|
|
360
283
|
matter: plugin.serverNode ? this.matterbridge.getServerNodeData(plugin.serverNode) : undefined,
|
|
361
284
|
};
|
|
362
285
|
}
|
|
363
|
-
/**
|
|
364
|
-
* Gets an array of all plugins.
|
|
365
|
-
*
|
|
366
|
-
* @returns {Plugin[]} An array of all plugins.
|
|
367
|
-
*/
|
|
368
286
|
array() {
|
|
369
287
|
return Array.from(this._plugins.values());
|
|
370
288
|
}
|
|
371
|
-
/**
|
|
372
|
-
* Gets a StoragePlugin array of all plugins suitable for serialization.
|
|
373
|
-
*
|
|
374
|
-
* @returns {StoragePlugin[]} An array of all plugins.
|
|
375
|
-
*/
|
|
376
289
|
storagePluginArray() {
|
|
377
290
|
const storagePlugins = [];
|
|
378
291
|
for (const plugin of this._plugins.values()) {
|
|
@@ -380,11 +293,6 @@ export class PluginManager extends EventEmitter {
|
|
|
380
293
|
}
|
|
381
294
|
return storagePlugins;
|
|
382
295
|
}
|
|
383
|
-
/**
|
|
384
|
-
* Gets an ApiPlugin array of all plugins suitable for serialization.
|
|
385
|
-
*
|
|
386
|
-
* @returns {ApiPlugin[]} An array of all plugins.
|
|
387
|
-
*/
|
|
388
296
|
apiPluginArray() {
|
|
389
297
|
const apiPlugins = [];
|
|
390
298
|
for (const plugin of this._plugins.values()) {
|
|
@@ -392,20 +300,9 @@ export class PluginManager extends EventEmitter {
|
|
|
392
300
|
}
|
|
393
301
|
return apiPlugins;
|
|
394
302
|
}
|
|
395
|
-
/**
|
|
396
|
-
* Gets an iterator for the plugins.
|
|
397
|
-
*
|
|
398
|
-
* @returns {IterableIterator<Plugin>} An iterator for the plugins.
|
|
399
|
-
*/
|
|
400
303
|
[Symbol.iterator]() {
|
|
401
304
|
return this._plugins.values();
|
|
402
305
|
}
|
|
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
|
-
*/
|
|
409
306
|
async forEach(callback) {
|
|
410
307
|
if (this.size === 0)
|
|
411
308
|
return;
|
|
@@ -419,40 +316,23 @@ export class PluginManager extends EventEmitter {
|
|
|
419
316
|
});
|
|
420
317
|
await Promise.all(tasks);
|
|
421
318
|
}
|
|
422
|
-
/**
|
|
423
|
-
* Sets the log level for the plugin manager.
|
|
424
|
-
*
|
|
425
|
-
* @param {LogLevel} logLevel - The log level to set.
|
|
426
|
-
*/
|
|
427
319
|
set logLevel(logLevel) {
|
|
428
320
|
this.log.logLevel = logLevel;
|
|
429
321
|
}
|
|
430
|
-
/**
|
|
431
|
-
* Loads registered plugins from storage.
|
|
432
|
-
*
|
|
433
|
-
* @returns {Promise<StoragePlugin[]>} A promise that resolves to an array of registered plugins.
|
|
434
|
-
*/
|
|
435
322
|
async loadFromStorage() {
|
|
436
323
|
if (!this.matterbridge.nodeContext) {
|
|
437
324
|
throw new Error('loadFromStorage: node context is not available.');
|
|
438
325
|
}
|
|
439
|
-
// Load the array from storage and convert it to a map
|
|
440
326
|
const pluginsArray = await this.matterbridge.nodeContext.get('plugins', []);
|
|
441
327
|
for (const plugin of pluginsArray)
|
|
442
328
|
this._plugins.set(plugin.name, plugin);
|
|
443
329
|
this.log.debug(`Loaded ${BLUE}${pluginsArray.length}${db} plugins from storage`);
|
|
444
330
|
return pluginsArray;
|
|
445
331
|
}
|
|
446
|
-
/**
|
|
447
|
-
* Saves registered plugins to storage.
|
|
448
|
-
*
|
|
449
|
-
* @returns {Promise<number>} A promise that resolves to the number of registered plugins.
|
|
450
|
-
*/
|
|
451
332
|
async saveToStorage() {
|
|
452
333
|
if (!this.matterbridge.nodeContext) {
|
|
453
334
|
throw new Error('loadFromStorage: node context is not available.');
|
|
454
335
|
}
|
|
455
|
-
// Convert the map to an array
|
|
456
336
|
const plugins = [];
|
|
457
337
|
for (const plugin of this.array()) {
|
|
458
338
|
plugins.push({
|
|
@@ -469,22 +349,13 @@ export class PluginManager extends EventEmitter {
|
|
|
469
349
|
this.log.debug(`Saved ${BLUE}${plugins.length}${db} plugins to storage`);
|
|
470
350
|
return plugins.length;
|
|
471
351
|
}
|
|
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
|
-
*/
|
|
479
352
|
async resolve(nameOrPath) {
|
|
480
353
|
const { default: path } = await import('node:path');
|
|
481
354
|
const { promises } = await import('node:fs');
|
|
482
355
|
if (!nameOrPath.endsWith('package.json'))
|
|
483
356
|
nameOrPath = path.join(nameOrPath, 'package.json');
|
|
484
|
-
// Resolve the package.json of the plugin
|
|
485
357
|
let packageJsonPath = path.resolve(nameOrPath);
|
|
486
358
|
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
|
|
488
359
|
try {
|
|
489
360
|
await promises.access(packageJsonPath);
|
|
490
361
|
}
|
|
@@ -493,7 +364,6 @@ export class PluginManager extends EventEmitter {
|
|
|
493
364
|
packageJsonPath = path.join(this.matterbridge.globalModulesDirectory, nameOrPath);
|
|
494
365
|
this.log.debug(`Trying at ${plg}${packageJsonPath}${db}`);
|
|
495
366
|
}
|
|
496
|
-
// Check if the package.json file exists at the global modules directory or next try in the matterbridge plugin directory
|
|
497
367
|
try {
|
|
498
368
|
await promises.access(packageJsonPath);
|
|
499
369
|
}
|
|
@@ -503,9 +373,7 @@ export class PluginManager extends EventEmitter {
|
|
|
503
373
|
this.log.debug(`Trying at ${plg}${packageJsonPath}${db}`);
|
|
504
374
|
}
|
|
505
375
|
try {
|
|
506
|
-
// Load the package.json of the plugin or fails if even not found in the matterbridge plugin directory
|
|
507
376
|
const packageJson = JSON.parse(await promises.readFile(packageJsonPath, 'utf8'));
|
|
508
|
-
// Check for main issues
|
|
509
377
|
if (!packageJson.name) {
|
|
510
378
|
this.log.error(`Package.json name not found at ${packageJsonPath}`);
|
|
511
379
|
return null;
|
|
@@ -518,7 +386,6 @@ export class PluginManager extends EventEmitter {
|
|
|
518
386
|
this.log.error(`Plugin at ${packageJsonPath} has no main entrypoint in package.json`);
|
|
519
387
|
return null;
|
|
520
388
|
}
|
|
521
|
-
// Check for @project-chip and @matter packages in dependencies and devDependencies
|
|
522
389
|
const checkForProjectChipPackages = (dependencies) => {
|
|
523
390
|
return Object.keys(dependencies).filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matter'));
|
|
524
391
|
};
|
|
@@ -540,7 +407,6 @@ export class PluginManager extends EventEmitter {
|
|
|
540
407
|
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
541
408
|
return null;
|
|
542
409
|
}
|
|
543
|
-
// Check for matterbridge package in dependencies and devDependencies
|
|
544
410
|
const checkForMatterbridgePackage = (dependencies) => {
|
|
545
411
|
return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
|
|
546
412
|
};
|
|
@@ -570,19 +436,13 @@ export class PluginManager extends EventEmitter {
|
|
|
570
436
|
return null;
|
|
571
437
|
}
|
|
572
438
|
}
|
|
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
|
-
*/
|
|
579
439
|
async install(packageName) {
|
|
580
440
|
this.log.debug(`Installing plugin ${plg}${packageName}${db}...`);
|
|
581
|
-
const { spawnCommand } = await import('./
|
|
441
|
+
const { spawnCommand } = await import('./spawn.js');
|
|
582
442
|
if (await spawnCommand('npm', ['install', '-g', packageName, '--omit=dev', '--verbose'], 'install', packageName)) {
|
|
583
443
|
this.matterbridge.restartRequired = true;
|
|
584
444
|
this.matterbridge.fixedRestartRequired = true;
|
|
585
|
-
packageName = packageName.replace(/@.*$/, '');
|
|
445
|
+
packageName = packageName.replace(/@.*$/, '');
|
|
586
446
|
if (packageName !== 'matterbridge') {
|
|
587
447
|
if (!this.has(packageName))
|
|
588
448
|
await this.add(packageName);
|
|
@@ -603,15 +463,9 @@ export class PluginManager extends EventEmitter {
|
|
|
603
463
|
return false;
|
|
604
464
|
}
|
|
605
465
|
}
|
|
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
|
-
*/
|
|
612
466
|
async uninstall(packageName) {
|
|
613
467
|
this.log.debug(`Uninstalling plugin ${plg}${packageName}${db}...`);
|
|
614
|
-
const { spawnCommand } = await import('./
|
|
468
|
+
const { spawnCommand } = await import('./spawn.js');
|
|
615
469
|
packageName = packageName.replace(/@.*$/, '');
|
|
616
470
|
if (packageName === 'matterbridge')
|
|
617
471
|
return false;
|
|
@@ -630,12 +484,6 @@ export class PluginManager extends EventEmitter {
|
|
|
630
484
|
return false;
|
|
631
485
|
}
|
|
632
486
|
}
|
|
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
|
-
*/
|
|
639
487
|
getAuthor(packageJson) {
|
|
640
488
|
if (packageJson.author && typeof packageJson.author === 'string')
|
|
641
489
|
return packageJson.author;
|
|
@@ -643,12 +491,6 @@ export class PluginManager extends EventEmitter {
|
|
|
643
491
|
return packageJson.author.name;
|
|
644
492
|
return 'Unknown author';
|
|
645
493
|
}
|
|
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
|
-
*/
|
|
652
494
|
getHomepage(packageJson) {
|
|
653
495
|
if (packageJson.homepage && typeof packageJson.homepage === 'string' && packageJson.homepage.includes('http')) {
|
|
654
496
|
return packageJson.homepage.replace('git+', '').replace('.git', '');
|
|
@@ -657,14 +499,7 @@ export class PluginManager extends EventEmitter {
|
|
|
657
499
|
return packageJson.repository.url.replace('git+', '').replace('.git', '');
|
|
658
500
|
}
|
|
659
501
|
}
|
|
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
|
-
*/
|
|
666
502
|
getHelp(packageJson) {
|
|
667
|
-
// If there's a help field that looks like a URL, return it.
|
|
668
503
|
if (packageJson.help && typeof packageJson.help === 'string' && packageJson.help.startsWith('http')) {
|
|
669
504
|
return packageJson.help;
|
|
670
505
|
}
|
|
@@ -675,14 +510,7 @@ export class PluginManager extends EventEmitter {
|
|
|
675
510
|
return packageJson.homepage.replace('git+', '').replace('.git', '');
|
|
676
511
|
}
|
|
677
512
|
}
|
|
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
|
-
*/
|
|
684
513
|
getChangelog(packageJson) {
|
|
685
|
-
// If there's a changelog field that looks like a URL, return it.
|
|
686
514
|
if (packageJson.changelog && typeof packageJson.changelog === 'string' && packageJson.changelog.startsWith('http')) {
|
|
687
515
|
return packageJson.changelog;
|
|
688
516
|
}
|
|
@@ -693,13 +521,6 @@ export class PluginManager extends EventEmitter {
|
|
|
693
521
|
return packageJson.homepage.replace('git+', '').replace('.git', '');
|
|
694
522
|
}
|
|
695
523
|
}
|
|
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
|
|
703
524
|
getFunding(packageJson) {
|
|
704
525
|
const funding = packageJson.funding;
|
|
705
526
|
if (!funding)
|
|
@@ -708,27 +529,16 @@ export class PluginManager extends EventEmitter {
|
|
|
708
529
|
return;
|
|
709
530
|
if (typeof funding === 'string' && funding.startsWith('http'))
|
|
710
531
|
return funding;
|
|
711
|
-
// Normalize funding into an array.
|
|
712
532
|
const fundingEntries = Array.isArray(funding) ? funding : [funding];
|
|
713
533
|
for (const entry of fundingEntries) {
|
|
714
534
|
if (entry && typeof entry === 'string' && entry.startsWith('http')) {
|
|
715
|
-
// If the funding entry is a string, assume it is a URL.
|
|
716
535
|
return entry;
|
|
717
536
|
}
|
|
718
537
|
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.
|
|
720
538
|
return entry.url;
|
|
721
539
|
}
|
|
722
540
|
}
|
|
723
541
|
}
|
|
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
|
-
*/
|
|
732
542
|
async parse(plugin) {
|
|
733
543
|
const { promises } = await import('node:fs');
|
|
734
544
|
if (typeof plugin === 'string') {
|
|
@@ -766,7 +576,6 @@ export class PluginManager extends EventEmitter {
|
|
|
766
576
|
plugin.funding = this.getFunding(packageJson);
|
|
767
577
|
if (!plugin.type)
|
|
768
578
|
this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no type`);
|
|
769
|
-
// Check for @project-chip and @matter packages in dependencies and devDependencies
|
|
770
579
|
const checkForProjectChipPackages = (dependencies) => {
|
|
771
580
|
return Object.keys(dependencies).filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matter'));
|
|
772
581
|
};
|
|
@@ -788,7 +597,6 @@ export class PluginManager extends EventEmitter {
|
|
|
788
597
|
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
789
598
|
return null;
|
|
790
599
|
}
|
|
791
|
-
// Check for matterbridge package in dependencies and devDependencies
|
|
792
600
|
const checkForMatterbridgePackage = (dependencies) => {
|
|
793
601
|
return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
|
|
794
602
|
};
|
|
@@ -818,16 +626,6 @@ export class PluginManager extends EventEmitter {
|
|
|
818
626
|
return null;
|
|
819
627
|
}
|
|
820
628
|
}
|
|
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
|
-
*/
|
|
831
629
|
async enable(nameOrPath) {
|
|
832
630
|
const { promises } = await import('node:fs');
|
|
833
631
|
if (!nameOrPath)
|
|
@@ -863,16 +661,6 @@ export class PluginManager extends EventEmitter {
|
|
|
863
661
|
return null;
|
|
864
662
|
}
|
|
865
663
|
}
|
|
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
|
-
*/
|
|
876
664
|
async disable(nameOrPath) {
|
|
877
665
|
const { promises } = await import('node:fs');
|
|
878
666
|
if (!nameOrPath)
|
|
@@ -908,16 +696,6 @@ export class PluginManager extends EventEmitter {
|
|
|
908
696
|
return null;
|
|
909
697
|
}
|
|
910
698
|
}
|
|
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
|
-
*/
|
|
921
699
|
async remove(nameOrPath) {
|
|
922
700
|
const { promises } = await import('node:fs');
|
|
923
701
|
if (!nameOrPath)
|
|
@@ -953,17 +731,6 @@ export class PluginManager extends EventEmitter {
|
|
|
953
731
|
return null;
|
|
954
732
|
}
|
|
955
733
|
}
|
|
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
|
-
*/
|
|
967
734
|
async add(nameOrPath) {
|
|
968
735
|
const { promises } = await import('node:fs');
|
|
969
736
|
if (!nameOrPath)
|
|
@@ -1003,15 +770,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1003
770
|
return null;
|
|
1004
771
|
}
|
|
1005
772
|
}
|
|
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
|
-
*/
|
|
1015
773
|
async load(plugin, start = false, message = '', configure = false) {
|
|
1016
774
|
const { promises } = await import('node:fs');
|
|
1017
775
|
const { default: path } = await import('node:path');
|
|
@@ -1033,20 +791,15 @@ export class PluginManager extends EventEmitter {
|
|
|
1033
791
|
}
|
|
1034
792
|
this.log.info(`Loading plugin ${plg}${plugin.name}${nf} type ${typ}${plugin.type}${nf}`);
|
|
1035
793
|
try {
|
|
1036
|
-
// Load the package.json of the plugin
|
|
1037
794
|
const packageJson = JSON.parse(await promises.readFile(plugin.path, 'utf8'));
|
|
1038
|
-
// Resolve the main module path relative to package.json
|
|
1039
795
|
const pluginEntry = path.resolve(path.dirname(plugin.path), packageJson.main);
|
|
1040
|
-
// Dynamically import the plugin
|
|
1041
796
|
const { pathToFileURL } = await import('node:url');
|
|
1042
797
|
const pluginUrl = pathToFileURL(pluginEntry);
|
|
1043
798
|
this.log.debug(`Importing plugin ${plg}${plugin.name}${db} from ${pluginUrl.href}`);
|
|
1044
799
|
const pluginInstance = (await import(pluginUrl.href));
|
|
1045
800
|
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
|
|
1047
801
|
if (pluginInstance.default) {
|
|
1048
802
|
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.
|
|
1050
803
|
plugin.name = packageJson.name;
|
|
1051
804
|
plugin.description = packageJson.description ?? 'No description';
|
|
1052
805
|
plugin.version = packageJson.version;
|
|
@@ -1055,14 +808,13 @@ export class PluginManager extends EventEmitter {
|
|
|
1055
808
|
plugin.schemaJson = await this.loadSchema(plugin);
|
|
1056
809
|
config.name = packageJson.name;
|
|
1057
810
|
config.version = packageJson.version;
|
|
1058
|
-
const log = new AnsiLogger({ logName: plugin.description, logTimestampFormat: 4
|
|
811
|
+
const log = new AnsiLogger({ logName: plugin.description, logTimestampFormat: 4, logLevel: config.debug ? "debug" : this.matterbridge.logLevel });
|
|
1059
812
|
const platform = pluginInstance.default(this.matterbridge, log, config);
|
|
1060
813
|
config.type = platform.type;
|
|
1061
814
|
platform.name = packageJson.name;
|
|
1062
815
|
platform.config = config;
|
|
1063
816
|
platform.version = packageJson.version;
|
|
1064
817
|
platform.isLoaded = true;
|
|
1065
|
-
// @ts-expect-error - setMatterNode is intentionally private
|
|
1066
818
|
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));
|
|
1067
819
|
plugin.name = packageJson.name;
|
|
1068
820
|
plugin.description = packageJson.description ?? 'No description';
|
|
@@ -1076,7 +828,7 @@ export class PluginManager extends EventEmitter {
|
|
|
1076
828
|
plugin.platform = platform;
|
|
1077
829
|
plugin.loaded = true;
|
|
1078
830
|
plugin.registeredDevices = 0;
|
|
1079
|
-
await this.saveToStorage();
|
|
831
|
+
await this.saveToStorage();
|
|
1080
832
|
this.log.notice(`Loaded plugin ${plg}${plugin.name}${nt} type ${typ}${platform.type}${nt} (entrypoint ${UNDERLINE}${pluginEntry}${UNDERLINEOFF})`);
|
|
1081
833
|
this.emit('loaded', plugin.name);
|
|
1082
834
|
if (start)
|
|
@@ -1096,14 +848,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1096
848
|
}
|
|
1097
849
|
return undefined;
|
|
1098
850
|
}
|
|
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
|
-
*/
|
|
1107
851
|
async start(plugin, message, configure = false) {
|
|
1108
852
|
if (typeof plugin === 'string') {
|
|
1109
853
|
const p = this._plugins.get(plugin);
|
|
@@ -1143,12 +887,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1143
887
|
}
|
|
1144
888
|
return undefined;
|
|
1145
889
|
}
|
|
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
|
-
*/
|
|
1152
890
|
async configure(plugin) {
|
|
1153
891
|
if (typeof plugin === 'string') {
|
|
1154
892
|
const p = this._plugins.get(plugin);
|
|
@@ -1189,18 +927,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1189
927
|
}
|
|
1190
928
|
return undefined;
|
|
1191
929
|
}
|
|
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
|
-
*/
|
|
1204
930
|
async shutdown(plugin, reason, removeAllDevices = false, force = false) {
|
|
1205
931
|
if (typeof plugin === 'string') {
|
|
1206
932
|
const p = this._plugins.get(plugin);
|
|
@@ -1257,15 +983,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1257
983
|
}
|
|
1258
984
|
return undefined;
|
|
1259
985
|
}
|
|
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
|
-
*/
|
|
1269
986
|
async loadConfig(plugin) {
|
|
1270
987
|
const { default: path } = await import('node:path');
|
|
1271
988
|
const { promises } = await import('node:fs');
|
|
@@ -1276,8 +993,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1276
993
|
const data = await promises.readFile(configFile, 'utf8');
|
|
1277
994
|
const config = JSON.parse(data);
|
|
1278
995
|
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".
|
|
1281
996
|
config.name = plugin.name;
|
|
1282
997
|
config.type = plugin.type;
|
|
1283
998
|
if (config.debug === undefined)
|
|
@@ -1304,7 +1019,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1304
1019
|
try {
|
|
1305
1020
|
await promises.writeFile(configFile, JSON.stringify(config, null, 2), 'utf8');
|
|
1306
1021
|
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);
|
|
1308
1022
|
return config;
|
|
1309
1023
|
}
|
|
1310
1024
|
catch (err) {
|
|
@@ -1318,19 +1032,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1318
1032
|
}
|
|
1319
1033
|
}
|
|
1320
1034
|
}
|
|
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
|
-
*/
|
|
1334
1035
|
async saveConfigFromPlugin(plugin, restartRequired = false) {
|
|
1335
1036
|
const { default: path } = await import('node:path');
|
|
1336
1037
|
const { promises } = await import('node:fs');
|
|
@@ -1345,7 +1046,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1345
1046
|
if (restartRequired)
|
|
1346
1047
|
plugin.restartRequired = true;
|
|
1347
1048
|
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);
|
|
1349
1049
|
return Promise.resolve();
|
|
1350
1050
|
}
|
|
1351
1051
|
catch (err) {
|
|
@@ -1353,20 +1053,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1353
1053
|
return Promise.reject(err);
|
|
1354
1054
|
}
|
|
1355
1055
|
}
|
|
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
|
-
*/
|
|
1370
1056
|
async saveConfigFromJson(plugin, config, restartRequired = false) {
|
|
1371
1057
|
const { default: path } = await import('node:path');
|
|
1372
1058
|
const { promises } = await import('node:fs');
|
|
@@ -1385,23 +1071,12 @@ export class PluginManager extends EventEmitter {
|
|
|
1385
1071
|
plugin.platform.onConfigChanged(config).catch((err) => this.log.error(`Error calling onConfigChanged for plugin ${plg}${plugin.name}${er}: ${err}`));
|
|
1386
1072
|
}
|
|
1387
1073
|
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);
|
|
1389
1074
|
}
|
|
1390
1075
|
catch (err) {
|
|
1391
1076
|
logError(this.log, `Error saving config file ${configFile} for plugin ${plg}${plugin.name}${er}`, err);
|
|
1392
1077
|
return;
|
|
1393
1078
|
}
|
|
1394
1079
|
}
|
|
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
|
-
*/
|
|
1405
1080
|
async loadSchema(plugin) {
|
|
1406
1081
|
const { promises } = await import('node:fs');
|
|
1407
1082
|
const schemaFile = plugin.path.replace('package.json', `${plugin.name}.schema.json`);
|
|
@@ -1412,7 +1087,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1412
1087
|
schema.title = plugin.description;
|
|
1413
1088
|
schema.description = plugin.name + ' v. ' + plugin.version + ' by ' + plugin.author;
|
|
1414
1089
|
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);
|
|
1416
1090
|
return schema;
|
|
1417
1091
|
}
|
|
1418
1092
|
catch (_err) {
|
|
@@ -1420,16 +1094,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1420
1094
|
return this.getDefaultSchema(plugin);
|
|
1421
1095
|
}
|
|
1422
1096
|
}
|
|
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
|
-
*/
|
|
1433
1097
|
getDefaultSchema(plugin) {
|
|
1434
1098
|
return {
|
|
1435
1099
|
title: plugin.description,
|
|
@@ -1460,4 +1124,3 @@ export class PluginManager extends EventEmitter {
|
|
|
1460
1124
|
};
|
|
1461
1125
|
}
|
|
1462
1126
|
}
|
|
1463
|
-
//# sourceMappingURL=pluginManager.js.map
|