matterbridge 3.5.2 → 3.5.3-dev-20260202-e19e9b6
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 +30 -1
- package/README-DOCKER.md +2 -2
- package/README.md +14 -9
- package/dist/broadcastServer.d.ts +0 -115
- package/dist/broadcastServer.js +0 -117
- package/dist/broadcastServerTypes.d.ts +0 -43
- package/dist/broadcastServerTypes.js +0 -24
- package/dist/checkUpdates.d.ts +0 -75
- package/dist/checkUpdates.js +1 -91
- package/dist/cli.d.ts +0 -24
- package/dist/cli.js +1 -97
- package/dist/cliEmitter.d.ts +0 -36
- package/dist/cliEmitter.js +0 -37
- package/dist/cliHistory.d.ts +0 -42
- package/dist/cliHistory.js +0 -38
- 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 +1 -114
- package/dist/devices/airConditioner.d.ts +0 -75
- package/dist/devices/airConditioner.js +0 -57
- package/dist/devices/basicVideoPlayer.d.ts +0 -58
- package/dist/devices/basicVideoPlayer.js +1 -56
- package/dist/devices/batteryStorage.d.ts +0 -43
- package/dist/devices/batteryStorage.js +1 -48
- package/dist/devices/castingVideoPlayer.d.ts +0 -63
- package/dist/devices/castingVideoPlayer.js +2 -65
- 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/dgram/export.d.ts +0 -1
- package/dist/dgram/export.js +0 -1
- package/dist/frontend.d.ts +0 -187
- package/dist/frontend.js +37 -498
- package/dist/frontendTypes.d.ts +0 -57
- package/dist/frontendTypes.js +0 -45
- package/dist/helpers.d.ts +0 -43
- package/dist/helpers.js +0 -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 +15 -371
- 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 +8 -359
- package/dist/matterbridge.d.ts +0 -373
- package/dist/matterbridge.js +46 -854
- package/dist/matterbridgeAccessoryPlatform.d.ts +0 -42
- package/dist/matterbridgeAccessoryPlatform.js +0 -50
- package/dist/matterbridgeBehaviors.d.ts +0 -24
- package/dist/matterbridgeBehaviors.js +5 -65
- package/dist/matterbridgeDeviceTypes.d.ts +0 -649
- package/dist/matterbridgeDeviceTypes.js +6 -673
- package/dist/matterbridgeDynamicPlatform.d.ts +0 -42
- package/dist/matterbridgeDynamicPlatform.js +0 -50
- package/dist/matterbridgeEndpoint.d.ts +0 -1369
- package/dist/matterbridgeEndpoint.js +54 -1507
- package/dist/matterbridgeEndpointHelpers.d.ts +0 -425
- package/dist/matterbridgeEndpointHelpers.js +20 -482
- package/dist/matterbridgeEndpointTypes.d.ts +0 -70
- package/dist/matterbridgeEndpointTypes.js +0 -25
- package/dist/matterbridgePlatform.d.ts +0 -434
- package/dist/matterbridgePlatform.js +1 -472
- package/dist/matterbridgePlatformTypes.d.ts +0 -29
- package/dist/matterbridgePlatformTypes.js +0 -24
- package/dist/matterbridgeTypes.d.ts +0 -46
- package/dist/matterbridgeTypes.js +0 -26
- package/dist/mb_coap.d.ts +0 -23
- package/dist/mb_coap.js +3 -41
- package/dist/mb_health.d.ts +0 -67
- package/dist/mb_health.js +0 -70
- package/dist/mb_mdns.d.ts +0 -23
- package/dist/mb_mdns.js +36 -94
- package/dist/pluginManager.d.ts +0 -305
- package/dist/pluginManager.js +5 -342
- package/dist/shelly.d.ts +0 -157
- package/dist/shelly.js +7 -178
- package/dist/spawn.d.ts +0 -32
- package/dist/spawn.js +1 -71
- package/dist/storage/export.d.ts +0 -1
- package/dist/storage/export.js +0 -1
- package/dist/utils/export.d.ts +0 -1
- package/dist/utils/export.js +0 -1
- package/dist/worker.d.ts +0 -61
- package/dist/worker.js +4 -65
- package/dist/workerCheckUpdates.d.ts +0 -24
- package/dist/workerCheckUpdates.js +5 -36
- package/dist/workerGlobalPrefix.d.ts +0 -24
- package/dist/workerGlobalPrefix.js +5 -36
- package/dist/workerTypes.d.ts +0 -25
- package/dist/workerTypes.js +0 -24
- package/frontend/build/assets/index.js +4 -4
- package/frontend/build/assets/vendor_emotion.js +1 -1
- package/frontend/build/assets/vendor_lodash.js +1 -1
- package/frontend/build/assets/vendor_mdi.js +1 -1
- package/frontend/build/assets/vendor_mui.js +22 -22
- package/frontend/build/assets/vendor_node_modules.js +20 -20
- package/frontend/build/assets/vendor_notistack.js +2 -2
- package/frontend/build/assets/vendor_qrcode.js +1 -1
- package/frontend/build/assets/vendor_rjsf.js +8 -8
- package/frontend/build/index.html +1 -1
- package/frontend/package.json +48 -47
- package/npm-shrinkwrap.json +77 -47
- package/package.json +7 -7
- 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/checkUpdates.d.ts.map +0 -1
- package/dist/checkUpdates.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/basicVideoPlayer.d.ts.map +0 -1
- package/dist/devices/basicVideoPlayer.js.map +0 -1
- package/dist/devices/batteryStorage.d.ts.map +0 -1
- package/dist/devices/batteryStorage.js.map +0 -1
- package/dist/devices/castingVideoPlayer.d.ts.map +0 -1
- package/dist/devices/castingVideoPlayer.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/export.d.ts.map +0 -1
- package/dist/dgram/export.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/matterbridgePlatformTypes.d.ts.map +0 -1
- package/dist/matterbridgePlatformTypes.js.map +0 -1
- package/dist/matterbridgeTypes.d.ts.map +0 -1
- package/dist/matterbridgeTypes.js.map +0 -1
- package/dist/mb_coap.d.ts.map +0 -1
- package/dist/mb_coap.js.map +0 -1
- package/dist/mb_health.d.ts.map +0 -1
- package/dist/mb_health.js.map +0 -1
- package/dist/mb_mdns.d.ts.map +0 -1
- package/dist/mb_mdns.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/spawn.d.ts.map +0 -1
- package/dist/spawn.js.map +0 -1
- package/dist/storage/export.d.ts.map +0 -1
- package/dist/storage/export.js.map +0 -1
- package/dist/utils/export.d.ts.map +0 -1
- package/dist/utils/export.js.map +0 -1
- package/dist/worker.d.ts.map +0 -1
- package/dist/worker.js.map +0 -1
- package/dist/workerCheckUpdates.d.ts.map +0 -1
- package/dist/workerCheckUpdates.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/pluginManager.js
CHANGED
|
@@ -1,40 +1,11 @@
|
|
|
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';
|
|
28
|
-
// @matterbridge
|
|
29
3
|
import { hasParameter, inspectError, logError } from '@matterbridge/utils';
|
|
30
4
|
import { assertMatterbridgePlatform } from './matterbridgePlatform.js';
|
|
31
5
|
import { plg, typ } from './matterbridgeTypes.js';
|
|
32
6
|
import { BroadcastServer } from './broadcastServer.js';
|
|
33
7
|
import { isMatterbridgeAccessoryPlatform } from './matterbridgeAccessoryPlatform.js';
|
|
34
8
|
import { isMatterbridgeDynamicPlatform } from './matterbridgeDynamicPlatform.js';
|
|
35
|
-
/**
|
|
36
|
-
* Manages Matterbridge plugins.
|
|
37
|
-
*/
|
|
38
9
|
export class PluginManager extends EventEmitter {
|
|
39
10
|
matterbridge;
|
|
40
11
|
_plugins = new Map();
|
|
@@ -42,15 +13,10 @@ export class PluginManager extends EventEmitter {
|
|
|
42
13
|
server;
|
|
43
14
|
debug = hasParameter('debug') || hasParameter('verbose');
|
|
44
15
|
verbose = hasParameter('verbose');
|
|
45
|
-
/**
|
|
46
|
-
* Creates an instance of PluginManager.
|
|
47
|
-
*
|
|
48
|
-
* @param {Matterbridge} matterbridge - The Matterbridge instance.
|
|
49
|
-
*/
|
|
50
16
|
constructor(matterbridge) {
|
|
51
17
|
super();
|
|
52
18
|
this.matterbridge = matterbridge;
|
|
53
|
-
this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4
|
|
19
|
+
this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
|
|
54
20
|
this.log.debug('Matterbridge plugin manager starting...');
|
|
55
21
|
this.server = new BroadcastServer('plugins', this.log);
|
|
56
22
|
this.server.on('broadcast_message', this.msgHandler.bind(this));
|
|
@@ -223,7 +189,7 @@ export class PluginManager extends EventEmitter {
|
|
|
223
189
|
{
|
|
224
190
|
const plugin = this.get(msg.params.name);
|
|
225
191
|
if (plugin) {
|
|
226
|
-
this.saveConfigFromJson(plugin, msg.params.config, msg.params.restartRequired);
|
|
192
|
+
this.saveConfigFromJson(plugin, msg.params.config, msg.params.restartRequired);
|
|
227
193
|
this.server.respond({ ...msg, result: { success: true } });
|
|
228
194
|
}
|
|
229
195
|
else {
|
|
@@ -261,62 +227,25 @@ export class PluginManager extends EventEmitter {
|
|
|
261
227
|
}
|
|
262
228
|
}
|
|
263
229
|
}
|
|
264
|
-
/**
|
|
265
|
-
* Gets the number of plugins.
|
|
266
|
-
*
|
|
267
|
-
* @returns {number} The number of plugins.
|
|
268
|
-
*/
|
|
269
230
|
get length() {
|
|
270
231
|
return this._plugins.size;
|
|
271
232
|
}
|
|
272
|
-
/**
|
|
273
|
-
* Gets the number of plugins.
|
|
274
|
-
*
|
|
275
|
-
* @returns {number} The number of plugins.
|
|
276
|
-
*/
|
|
277
233
|
get size() {
|
|
278
234
|
return this._plugins.size;
|
|
279
235
|
}
|
|
280
|
-
/**
|
|
281
|
-
* Checks if a plugin with the specified name exists.
|
|
282
|
-
*
|
|
283
|
-
* @param {string} name - The name of the plugin.
|
|
284
|
-
* @returns {boolean} True if the plugin exists, false otherwise.
|
|
285
|
-
*/
|
|
286
236
|
has(name) {
|
|
287
237
|
return this._plugins.has(name);
|
|
288
238
|
}
|
|
289
|
-
/**
|
|
290
|
-
* Gets a plugin by its name.
|
|
291
|
-
*
|
|
292
|
-
* @param {string} name - The name of the plugin.
|
|
293
|
-
* @returns {Plugin | undefined} The plugin, or undefined if not found.
|
|
294
|
-
*/
|
|
295
239
|
get(name) {
|
|
296
240
|
return this._plugins.get(name);
|
|
297
241
|
}
|
|
298
|
-
/**
|
|
299
|
-
* Adds a plugin to the manager.
|
|
300
|
-
*
|
|
301
|
-
* @param {Plugin} plugin - The plugin to add.
|
|
302
|
-
* @returns {Plugin} The added plugin.
|
|
303
|
-
*/
|
|
304
242
|
set(plugin) {
|
|
305
243
|
this._plugins.set(plugin.name, plugin);
|
|
306
244
|
return plugin;
|
|
307
245
|
}
|
|
308
|
-
/**
|
|
309
|
-
* Clears all plugins from the manager.
|
|
310
|
-
*/
|
|
311
246
|
clear() {
|
|
312
247
|
this._plugins.clear();
|
|
313
248
|
}
|
|
314
|
-
/**
|
|
315
|
-
* Converts a plugin or API plugin to a storage plugin.
|
|
316
|
-
*
|
|
317
|
-
* @param {Plugin | ApiPlugin} plugin - The plugin or API plugin to convert.
|
|
318
|
-
* @returns {StoragePlugin} The converted storage plugin.
|
|
319
|
-
*/
|
|
320
249
|
toStoragePlugin(plugin) {
|
|
321
250
|
return {
|
|
322
251
|
name: plugin.name,
|
|
@@ -328,12 +257,6 @@ export class PluginManager extends EventEmitter {
|
|
|
328
257
|
enabled: plugin.enabled,
|
|
329
258
|
};
|
|
330
259
|
}
|
|
331
|
-
/**
|
|
332
|
-
* Converts a plugin to an API plugin.
|
|
333
|
-
*
|
|
334
|
-
* @param {Plugin} plugin - The plugin to convert.
|
|
335
|
-
* @returns {ApiPlugin} The converted API plugin.
|
|
336
|
-
*/
|
|
337
260
|
toApiPlugin(plugin) {
|
|
338
261
|
return {
|
|
339
262
|
name: plugin.name,
|
|
@@ -363,19 +286,9 @@ export class PluginManager extends EventEmitter {
|
|
|
363
286
|
matter: plugin.serverNode ? this.matterbridge.getServerNodeData(plugin.serverNode) : undefined,
|
|
364
287
|
};
|
|
365
288
|
}
|
|
366
|
-
/**
|
|
367
|
-
* Gets an array of all plugins.
|
|
368
|
-
*
|
|
369
|
-
* @returns {Plugin[]} An array of all plugins.
|
|
370
|
-
*/
|
|
371
289
|
array() {
|
|
372
290
|
return Array.from(this._plugins.values());
|
|
373
291
|
}
|
|
374
|
-
/**
|
|
375
|
-
* Gets a StoragePlugin array of all plugins suitable for serialization.
|
|
376
|
-
*
|
|
377
|
-
* @returns {StoragePlugin[]} An array of all plugins.
|
|
378
|
-
*/
|
|
379
292
|
storagePluginArray() {
|
|
380
293
|
const storagePlugins = [];
|
|
381
294
|
for (const plugin of this._plugins.values()) {
|
|
@@ -383,11 +296,6 @@ export class PluginManager extends EventEmitter {
|
|
|
383
296
|
}
|
|
384
297
|
return storagePlugins;
|
|
385
298
|
}
|
|
386
|
-
/**
|
|
387
|
-
* Gets an ApiPlugin array of all plugins suitable for serialization.
|
|
388
|
-
*
|
|
389
|
-
* @returns {ApiPlugin[]} An array of all plugins.
|
|
390
|
-
*/
|
|
391
299
|
apiPluginArray() {
|
|
392
300
|
const apiPlugins = [];
|
|
393
301
|
for (const plugin of this._plugins.values()) {
|
|
@@ -395,20 +303,9 @@ export class PluginManager extends EventEmitter {
|
|
|
395
303
|
}
|
|
396
304
|
return apiPlugins;
|
|
397
305
|
}
|
|
398
|
-
/**
|
|
399
|
-
* Gets an iterator for the plugins.
|
|
400
|
-
*
|
|
401
|
-
* @returns {IterableIterator<Plugin>} An iterator for the plugins.
|
|
402
|
-
*/
|
|
403
306
|
[Symbol.iterator]() {
|
|
404
307
|
return this._plugins.values();
|
|
405
308
|
}
|
|
406
|
-
/**
|
|
407
|
-
* Executes a provided function once for each plugin.
|
|
408
|
-
*
|
|
409
|
-
* @param {Function} callback - The function to execute for each plugin.
|
|
410
|
-
* @returns {Promise<void>}
|
|
411
|
-
*/
|
|
412
309
|
async forEach(callback) {
|
|
413
310
|
if (this.size === 0)
|
|
414
311
|
return;
|
|
@@ -422,40 +319,23 @@ export class PluginManager extends EventEmitter {
|
|
|
422
319
|
});
|
|
423
320
|
await Promise.all(tasks);
|
|
424
321
|
}
|
|
425
|
-
/**
|
|
426
|
-
* Sets the log level for the plugin manager.
|
|
427
|
-
*
|
|
428
|
-
* @param {LogLevel} logLevel - The log level to set.
|
|
429
|
-
*/
|
|
430
322
|
set logLevel(logLevel) {
|
|
431
323
|
this.log.logLevel = logLevel;
|
|
432
324
|
}
|
|
433
|
-
/**
|
|
434
|
-
* Loads registered plugins from storage.
|
|
435
|
-
*
|
|
436
|
-
* @returns {Promise<StoragePlugin[]>} A promise that resolves to an array of registered plugins.
|
|
437
|
-
*/
|
|
438
325
|
async loadFromStorage() {
|
|
439
326
|
if (!this.matterbridge.nodeContext) {
|
|
440
327
|
throw new Error('loadFromStorage: node context is not available.');
|
|
441
328
|
}
|
|
442
|
-
// Load the array from storage and convert it to a map
|
|
443
329
|
const pluginsArray = await this.matterbridge.nodeContext.get('plugins', []);
|
|
444
330
|
for (const plugin of pluginsArray)
|
|
445
331
|
this._plugins.set(plugin.name, plugin);
|
|
446
332
|
this.log.debug(`Loaded ${BLUE}${pluginsArray.length}${db} plugins from storage`);
|
|
447
333
|
return pluginsArray;
|
|
448
334
|
}
|
|
449
|
-
/**
|
|
450
|
-
* Saves registered plugins to storage.
|
|
451
|
-
*
|
|
452
|
-
* @returns {Promise<number>} A promise that resolves to the number of registered plugins.
|
|
453
|
-
*/
|
|
454
335
|
async saveToStorage() {
|
|
455
336
|
if (!this.matterbridge.nodeContext) {
|
|
456
337
|
throw new Error('loadFromStorage: node context is not available.');
|
|
457
338
|
}
|
|
458
|
-
// Convert the map to an array
|
|
459
339
|
const plugins = [];
|
|
460
340
|
for (const plugin of this.array()) {
|
|
461
341
|
plugins.push({
|
|
@@ -472,22 +352,13 @@ export class PluginManager extends EventEmitter {
|
|
|
472
352
|
this.log.debug(`Saved ${BLUE}${plugins.length}${db} plugins to storage`);
|
|
473
353
|
return plugins.length;
|
|
474
354
|
}
|
|
475
|
-
/**
|
|
476
|
-
* Resolves the name of a plugin by loading and parsing its package.json file.
|
|
477
|
-
* It will first try to resolve the path as is, then in the global modules directory, and finally in the matterbridge plugin directory.
|
|
478
|
-
*
|
|
479
|
-
* @param {string} nameOrPath - The name of the plugin or the path to the plugin's package.json file.
|
|
480
|
-
* @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.
|
|
481
|
-
*/
|
|
482
355
|
async resolve(nameOrPath) {
|
|
483
356
|
const { default: path } = await import('node:path');
|
|
484
357
|
const { promises } = await import('node:fs');
|
|
485
358
|
if (!nameOrPath.endsWith('package.json'))
|
|
486
359
|
nameOrPath = path.join(nameOrPath, 'package.json');
|
|
487
|
-
// Resolve the package.json of the plugin
|
|
488
360
|
let packageJsonPath = path.resolve(nameOrPath);
|
|
489
361
|
this.log.debug(`Resolving plugin path ${plg}${packageJsonPath}${db}`);
|
|
490
|
-
// Check if the package.json file exists at the specified path or next try in the global modules directory
|
|
491
362
|
try {
|
|
492
363
|
await promises.access(packageJsonPath);
|
|
493
364
|
}
|
|
@@ -496,7 +367,6 @@ export class PluginManager extends EventEmitter {
|
|
|
496
367
|
packageJsonPath = path.join(this.matterbridge.globalModulesDirectory, nameOrPath);
|
|
497
368
|
this.log.debug(`Trying at ${plg}${packageJsonPath}${db}`);
|
|
498
369
|
}
|
|
499
|
-
// Check if the package.json file exists at the global modules directory or next try in the matterbridge plugin directory
|
|
500
370
|
try {
|
|
501
371
|
await promises.access(packageJsonPath);
|
|
502
372
|
}
|
|
@@ -506,9 +376,7 @@ export class PluginManager extends EventEmitter {
|
|
|
506
376
|
this.log.debug(`Trying at ${plg}${packageJsonPath}${db}`);
|
|
507
377
|
}
|
|
508
378
|
try {
|
|
509
|
-
// Load the package.json of the plugin or fails if even not found in the matterbridge plugin directory
|
|
510
379
|
const packageJson = JSON.parse(await promises.readFile(packageJsonPath, 'utf8'));
|
|
511
|
-
// Check for main issues
|
|
512
380
|
if (!packageJson.name) {
|
|
513
381
|
this.log.error(`Package.json name not found at ${packageJsonPath}`);
|
|
514
382
|
return null;
|
|
@@ -521,7 +389,6 @@ export class PluginManager extends EventEmitter {
|
|
|
521
389
|
this.log.error(`Plugin at ${packageJsonPath} has no main entrypoint in package.json`);
|
|
522
390
|
return null;
|
|
523
391
|
}
|
|
524
|
-
// Check for @project-chip and @matter packages in dependencies and devDependencies
|
|
525
392
|
const checkForProjectChipPackages = (dependencies) => {
|
|
526
393
|
return Object.keys(dependencies).filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matter'));
|
|
527
394
|
};
|
|
@@ -546,7 +413,6 @@ export class PluginManager extends EventEmitter {
|
|
|
546
413
|
this.server.request({ type: 'frontend_snackbarmessage', src: 'plugins', dst: 'frontend', params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' } });
|
|
547
414
|
return null;
|
|
548
415
|
}
|
|
549
|
-
// Check for matterbridge package in dependencies and devDependencies
|
|
550
416
|
const checkForMatterbridgePackage = (dependencies) => {
|
|
551
417
|
return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
|
|
552
418
|
};
|
|
@@ -580,19 +446,13 @@ export class PluginManager extends EventEmitter {
|
|
|
580
446
|
return null;
|
|
581
447
|
}
|
|
582
448
|
}
|
|
583
|
-
/**
|
|
584
|
-
* Installs a package globally using npm.
|
|
585
|
-
*
|
|
586
|
-
* @param {string} packageName - The name of the package to install.
|
|
587
|
-
* @returns {Promise<boolean>} A promise that resolves to true if the installation was successful, false otherwise.
|
|
588
|
-
*/
|
|
589
449
|
async install(packageName) {
|
|
590
450
|
this.log.debug(`Installing plugin ${plg}${packageName}${db}...`);
|
|
591
451
|
const { spawnCommand } = await import('./spawn.js');
|
|
592
452
|
if (await spawnCommand('npm', ['install', '-g', packageName, '--omit=dev', '--verbose'], 'install', packageName)) {
|
|
593
453
|
this.matterbridge.restartRequired = true;
|
|
594
454
|
this.matterbridge.fixedRestartRequired = true;
|
|
595
|
-
packageName = packageName.replace(/@.*$/, '');
|
|
455
|
+
packageName = packageName.replace(/@.*$/, '');
|
|
596
456
|
if (packageName !== 'matterbridge') {
|
|
597
457
|
if (!this.has(packageName))
|
|
598
458
|
await this.add(packageName);
|
|
@@ -613,12 +473,6 @@ export class PluginManager extends EventEmitter {
|
|
|
613
473
|
return false;
|
|
614
474
|
}
|
|
615
475
|
}
|
|
616
|
-
/**
|
|
617
|
-
* Uninstalls a package globally using npm.
|
|
618
|
-
*
|
|
619
|
-
* @param {string} packageName - The name of the package to uninstall.
|
|
620
|
-
* @returns {Promise<boolean>} A promise that resolves to true if the uninstallation was successful, false otherwise.
|
|
621
|
-
*/
|
|
622
476
|
async uninstall(packageName) {
|
|
623
477
|
this.log.debug(`Uninstalling plugin ${plg}${packageName}${db}...`);
|
|
624
478
|
const { spawnCommand } = await import('./spawn.js');
|
|
@@ -640,12 +494,6 @@ export class PluginManager extends EventEmitter {
|
|
|
640
494
|
return false;
|
|
641
495
|
}
|
|
642
496
|
}
|
|
643
|
-
/**
|
|
644
|
-
* Get the author of a plugin from its package.json.
|
|
645
|
-
*
|
|
646
|
-
* @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
|
|
647
|
-
* @returns {string} The author of the plugin, or 'Unknown author' if not found.
|
|
648
|
-
*/
|
|
649
497
|
getAuthor(packageJson) {
|
|
650
498
|
if (packageJson.author && typeof packageJson.author === 'string')
|
|
651
499
|
return packageJson.author;
|
|
@@ -653,12 +501,6 @@ export class PluginManager extends EventEmitter {
|
|
|
653
501
|
return packageJson.author.name;
|
|
654
502
|
return 'Unknown author';
|
|
655
503
|
}
|
|
656
|
-
/**
|
|
657
|
-
* Get the homepage of a plugin from its package.json.
|
|
658
|
-
*
|
|
659
|
-
* @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
|
|
660
|
-
* @returns {string | undefined} The homepage of the plugin, or undefined if not found.
|
|
661
|
-
*/
|
|
662
504
|
getHomepage(packageJson) {
|
|
663
505
|
if (packageJson.homepage && typeof packageJson.homepage === 'string' && packageJson.homepage.includes('http')) {
|
|
664
506
|
return packageJson.homepage.replace('git+', '').replace('.git', '');
|
|
@@ -667,14 +509,7 @@ export class PluginManager extends EventEmitter {
|
|
|
667
509
|
return packageJson.repository.url.replace('git+', '').replace('.git', '');
|
|
668
510
|
}
|
|
669
511
|
}
|
|
670
|
-
/**
|
|
671
|
-
* Get the help URL of a plugin from its package.json.
|
|
672
|
-
*
|
|
673
|
-
* @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
|
|
674
|
-
* @returns {string | undefined} The URL to the help page or to the README file, or undefined if not found.
|
|
675
|
-
*/
|
|
676
512
|
getHelp(packageJson) {
|
|
677
|
-
// If there's a help field that looks like a URL, return it.
|
|
678
513
|
if (packageJson.help && typeof packageJson.help === 'string' && packageJson.help.startsWith('http')) {
|
|
679
514
|
return packageJson.help;
|
|
680
515
|
}
|
|
@@ -685,14 +520,7 @@ export class PluginManager extends EventEmitter {
|
|
|
685
520
|
return packageJson.homepage.replace('git+', '').replace('.git', '');
|
|
686
521
|
}
|
|
687
522
|
}
|
|
688
|
-
/**
|
|
689
|
-
* Get the changelog URL of a plugin from its package.json.
|
|
690
|
-
*
|
|
691
|
-
* @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
|
|
692
|
-
* @returns {string | undefined} The URL to the CHANGELOG file, or undefined if not found.
|
|
693
|
-
*/
|
|
694
523
|
getChangelog(packageJson) {
|
|
695
|
-
// If there's a changelog field that looks like a URL, return it.
|
|
696
524
|
if (packageJson.changelog && typeof packageJson.changelog === 'string' && packageJson.changelog.startsWith('http')) {
|
|
697
525
|
return packageJson.changelog;
|
|
698
526
|
}
|
|
@@ -703,13 +531,6 @@ export class PluginManager extends EventEmitter {
|
|
|
703
531
|
return packageJson.homepage.replace('git+', '').replace('.git', '');
|
|
704
532
|
}
|
|
705
533
|
}
|
|
706
|
-
/**
|
|
707
|
-
* Get the first funding URL(s) of a plugin from its package.json.
|
|
708
|
-
*
|
|
709
|
-
* @param {Record<string, any>} packageJson - The package.json object of the plugin.
|
|
710
|
-
* @returns {string | undefined} The first funding URLs, or undefined if not found.
|
|
711
|
-
*/
|
|
712
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
713
534
|
getFunding(packageJson) {
|
|
714
535
|
const funding = packageJson.funding;
|
|
715
536
|
if (!funding)
|
|
@@ -718,27 +539,16 @@ export class PluginManager extends EventEmitter {
|
|
|
718
539
|
return;
|
|
719
540
|
if (typeof funding === 'string' && funding.startsWith('http'))
|
|
720
541
|
return funding;
|
|
721
|
-
// Normalize funding into an array.
|
|
722
542
|
const fundingEntries = Array.isArray(funding) ? funding : [funding];
|
|
723
543
|
for (const entry of fundingEntries) {
|
|
724
544
|
if (entry && typeof entry === 'string' && entry.startsWith('http')) {
|
|
725
|
-
// If the funding entry is a string, assume it is a URL.
|
|
726
545
|
return entry;
|
|
727
546
|
}
|
|
728
547
|
else if (entry && typeof entry === 'object' && typeof entry.url === 'string' && entry.url.startsWith('http')) {
|
|
729
|
-
// If it's an object with a 'url' property, use that.
|
|
730
548
|
return entry.url;
|
|
731
549
|
}
|
|
732
550
|
}
|
|
733
551
|
}
|
|
734
|
-
/**
|
|
735
|
-
* Parses the plugin package.json and returns it.
|
|
736
|
-
* It will also log warnings and errors for missing or invalid fields.
|
|
737
|
-
* It will return null if critical errors are found.
|
|
738
|
-
*
|
|
739
|
-
* @param {Plugin | PluginName} plugin - The plugin to load the package from.
|
|
740
|
-
* @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.
|
|
741
|
-
*/
|
|
742
552
|
async parse(plugin) {
|
|
743
553
|
const { promises } = await import('node:fs');
|
|
744
554
|
if (typeof plugin === 'string') {
|
|
@@ -776,7 +586,6 @@ export class PluginManager extends EventEmitter {
|
|
|
776
586
|
plugin.funding = this.getFunding(packageJson);
|
|
777
587
|
if (!plugin.type)
|
|
778
588
|
this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no type`);
|
|
779
|
-
// Check for @project-chip and @matter packages in dependencies and devDependencies
|
|
780
589
|
const checkForProjectChipPackages = (dependencies) => {
|
|
781
590
|
return Object.keys(dependencies).filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matter'));
|
|
782
591
|
};
|
|
@@ -801,7 +610,6 @@ export class PluginManager extends EventEmitter {
|
|
|
801
610
|
this.server.request({ type: 'frontend_snackbarmessage', src: 'plugins', dst: 'frontend', params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' } });
|
|
802
611
|
return null;
|
|
803
612
|
}
|
|
804
|
-
// Check for matterbridge package in dependencies and devDependencies
|
|
805
613
|
const checkForMatterbridgePackage = (dependencies) => {
|
|
806
614
|
return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
|
|
807
615
|
};
|
|
@@ -835,16 +643,6 @@ export class PluginManager extends EventEmitter {
|
|
|
835
643
|
return null;
|
|
836
644
|
}
|
|
837
645
|
}
|
|
838
|
-
/**
|
|
839
|
-
* Enables a plugin by its name or path.
|
|
840
|
-
*
|
|
841
|
-
* This method enables a plugin by setting its `enabled` property to `true` and saving the updated
|
|
842
|
-
* plugin information to storage. It first checks if the plugin is already registered in the `_plugins` map.
|
|
843
|
-
* If not, it attempts to resolve the plugin's `package.json` file to retrieve its name and enable it.
|
|
844
|
-
*
|
|
845
|
-
* @param {string} nameOrPath - The name or path of the plugin to enable.
|
|
846
|
-
* @returns {Promise<Plugin | null>} A promise that resolves to the enabled plugin object, or null if the plugin could not be enabled.
|
|
847
|
-
*/
|
|
848
646
|
async enable(nameOrPath) {
|
|
849
647
|
const { promises } = await import('node:fs');
|
|
850
648
|
if (!nameOrPath)
|
|
@@ -880,16 +678,6 @@ export class PluginManager extends EventEmitter {
|
|
|
880
678
|
return null;
|
|
881
679
|
}
|
|
882
680
|
}
|
|
883
|
-
/**
|
|
884
|
-
* Disables a plugin by its name or path.
|
|
885
|
-
*
|
|
886
|
-
* This method disables a plugin by setting its `enabled` property to `false` and saving the updated
|
|
887
|
-
* plugin information to storage. It first checks if the plugin is already registered in the `_plugins` map.
|
|
888
|
-
* If not, it attempts to resolve the plugin's `package.json` file to retrieve its name and disable it.
|
|
889
|
-
*
|
|
890
|
-
* @param {string} nameOrPath - The name or path of the plugin to enable.
|
|
891
|
-
* @returns {Promise<Plugin | null>} A promise that resolves to the disabled plugin object, or null if the plugin could not be disabled.
|
|
892
|
-
*/
|
|
893
681
|
async disable(nameOrPath) {
|
|
894
682
|
const { promises } = await import('node:fs');
|
|
895
683
|
if (!nameOrPath)
|
|
@@ -925,16 +713,6 @@ export class PluginManager extends EventEmitter {
|
|
|
925
713
|
return null;
|
|
926
714
|
}
|
|
927
715
|
}
|
|
928
|
-
/**
|
|
929
|
-
* Removes a plugin by its name or path.
|
|
930
|
-
*
|
|
931
|
-
* This method removes a plugin from the `_plugins` map and saves the updated plugin information to storage.
|
|
932
|
-
* It first checks if the plugin is already registered in the `_plugins` map. If not, it attempts to resolve
|
|
933
|
-
* the plugin's `package.json` file to retrieve its name and remove it.
|
|
934
|
-
*
|
|
935
|
-
* @param {string} nameOrPath - The name or path of the plugin to remove.
|
|
936
|
-
* @returns {Promise<Plugin | null>} A promise that resolves to the removed plugin object, or null if the plugin could not be removed.
|
|
937
|
-
*/
|
|
938
716
|
async remove(nameOrPath) {
|
|
939
717
|
const { promises } = await import('node:fs');
|
|
940
718
|
if (!nameOrPath)
|
|
@@ -970,17 +748,6 @@ export class PluginManager extends EventEmitter {
|
|
|
970
748
|
return null;
|
|
971
749
|
}
|
|
972
750
|
}
|
|
973
|
-
/**
|
|
974
|
-
* Adds a plugin by its name or path.
|
|
975
|
-
*
|
|
976
|
-
* This method adds a plugin to the plugins map and saves the updated plugin information to storage.
|
|
977
|
-
* It first resolves the plugin's `package.json` file to retrieve its details. If the plugin is already
|
|
978
|
-
* registered, it logs an info message and returns null. Otherwise, it registers the plugin, enables it,
|
|
979
|
-
* and saves the updated plugin information to storage.
|
|
980
|
-
*
|
|
981
|
-
* @param {string} nameOrPath - The name or path of the plugin to add.
|
|
982
|
-
* @returns {Promise<Plugin | null>} A promise that resolves to the added plugin object, or null if the plugin could not be added.
|
|
983
|
-
*/
|
|
984
751
|
async add(nameOrPath) {
|
|
985
752
|
const { promises } = await import('node:fs');
|
|
986
753
|
if (!nameOrPath)
|
|
@@ -1020,15 +787,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1020
787
|
return null;
|
|
1021
788
|
}
|
|
1022
789
|
}
|
|
1023
|
-
/**
|
|
1024
|
-
* Loads a plugin and returns the corresponding MatterbridgePlatform instance.
|
|
1025
|
-
*
|
|
1026
|
-
* @param {Plugin | PluginName} plugin - The plugin to load.
|
|
1027
|
-
* @param {boolean} start - Optional flag indicating whether to start the plugin after loading. Default is false.
|
|
1028
|
-
* @param {string} message - Optional message to pass to the plugin when starting.
|
|
1029
|
-
* @param {boolean} configure - Optional flag indicating whether to configure the plugin after loading. Default is false.
|
|
1030
|
-
* @returns {Promise<MatterbridgePlatform | undefined>} A Promise that resolves to the loaded MatterbridgePlatform instance or undefined.
|
|
1031
|
-
*/
|
|
1032
790
|
async load(plugin, start = false, message = '', configure = false) {
|
|
1033
791
|
const { promises } = await import('node:fs');
|
|
1034
792
|
const { default: path } = await import('node:path');
|
|
@@ -1050,20 +808,15 @@ export class PluginManager extends EventEmitter {
|
|
|
1050
808
|
}
|
|
1051
809
|
this.log.info(`Loading plugin ${plg}${plugin.name}${nf} type ${typ}${plugin.type}${nf}`);
|
|
1052
810
|
try {
|
|
1053
|
-
// Load the package.json of the plugin
|
|
1054
811
|
const packageJson = JSON.parse(await promises.readFile(plugin.path, 'utf8'));
|
|
1055
|
-
// Resolve the main module path relative to package.json
|
|
1056
812
|
const pluginEntry = path.resolve(path.dirname(plugin.path), packageJson.main);
|
|
1057
|
-
// Dynamically import the plugin
|
|
1058
813
|
const { pathToFileURL } = await import('node:url');
|
|
1059
814
|
const pluginUrl = pathToFileURL(pluginEntry);
|
|
1060
815
|
this.log.debug(`Importing plugin ${plg}${plugin.name}${db} from ${pluginUrl.href}`);
|
|
1061
816
|
const pluginInstance = (await import(pluginUrl.href));
|
|
1062
817
|
this.log.debug(`Imported plugin ${plg}${plugin.name}${db} from ${pluginUrl.href}`);
|
|
1063
|
-
// Call the default export function of the plugin, passing this MatterBridge instance, the log and the config
|
|
1064
818
|
if (pluginInstance.default) {
|
|
1065
819
|
const config = await this.loadConfig(plugin);
|
|
1066
|
-
// 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.
|
|
1067
820
|
plugin.name = packageJson.name;
|
|
1068
821
|
plugin.description = packageJson.description ?? 'No description';
|
|
1069
822
|
plugin.version = packageJson.version;
|
|
@@ -1072,7 +825,7 @@ export class PluginManager extends EventEmitter {
|
|
|
1072
825
|
plugin.schemaJson = await this.loadSchema(plugin);
|
|
1073
826
|
config.name = packageJson.name;
|
|
1074
827
|
config.version = packageJson.version;
|
|
1075
|
-
const log = new AnsiLogger({ logName: plugin.description, logTimestampFormat: 4
|
|
828
|
+
const log = new AnsiLogger({ logName: plugin.description, logTimestampFormat: 4, logLevel: config.debug ? "debug" : this.matterbridge.logLevel });
|
|
1076
829
|
const platform = pluginInstance.default(this.matterbridge.getPlatformMatterbridge(), log, config);
|
|
1077
830
|
assertMatterbridgePlatform(platform, `Plugin ${plugin.name} does not export a valid MatterbridgePlatform`);
|
|
1078
831
|
if (!isMatterbridgeAccessoryPlatform(platform) && !isMatterbridgeDynamicPlatform(platform))
|
|
@@ -1082,7 +835,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1082
835
|
platform.config = config;
|
|
1083
836
|
platform.version = packageJson.version;
|
|
1084
837
|
platform.isLoaded = true;
|
|
1085
|
-
// @ts-expect-error - setMatterNode is intentionally private
|
|
1086
838
|
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));
|
|
1087
839
|
plugin.name = packageJson.name;
|
|
1088
840
|
plugin.description = packageJson.description ?? 'No description';
|
|
@@ -1096,7 +848,7 @@ export class PluginManager extends EventEmitter {
|
|
|
1096
848
|
plugin.platform = platform;
|
|
1097
849
|
plugin.loaded = true;
|
|
1098
850
|
plugin.registeredDevices = 0;
|
|
1099
|
-
await this.saveToStorage();
|
|
851
|
+
await this.saveToStorage();
|
|
1100
852
|
this.log.notice(`Loaded plugin ${plg}${plugin.name}${nt} type ${typ}${platform.type}${nt} (entrypoint ${UNDERLINE}${pluginEntry}${UNDERLINEOFF})`);
|
|
1101
853
|
this.emit('loaded', plugin.name);
|
|
1102
854
|
if (start)
|
|
@@ -1116,14 +868,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1116
868
|
}
|
|
1117
869
|
return undefined;
|
|
1118
870
|
}
|
|
1119
|
-
/**
|
|
1120
|
-
* Starts a plugin.
|
|
1121
|
-
*
|
|
1122
|
-
* @param {Plugin | PluginName} plugin - The plugin to start.
|
|
1123
|
-
* @param {string} [message] - Optional message to pass to the plugin's onStart method.
|
|
1124
|
-
* @param {boolean} [configure] - Indicates whether to configure the plugin after starting (default false).
|
|
1125
|
-
* @returns {Promise<Plugin | undefined>} A promise that resolves when the plugin is started successfully, or rejects with an error if starting the plugin fails.
|
|
1126
|
-
*/
|
|
1127
871
|
async start(plugin, message, configure = false) {
|
|
1128
872
|
if (typeof plugin === 'string') {
|
|
1129
873
|
const p = this._plugins.get(plugin);
|
|
@@ -1163,12 +907,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1163
907
|
}
|
|
1164
908
|
return undefined;
|
|
1165
909
|
}
|
|
1166
|
-
/**
|
|
1167
|
-
* Configures a plugin.
|
|
1168
|
-
*
|
|
1169
|
-
* @param {Plugin | PluginName} plugin - The plugin to configure.
|
|
1170
|
-
* @returns {Promise<Plugin | undefined>} A promise that resolves when the plugin is configured successfully, or rejects with an error if configuration fails.
|
|
1171
|
-
*/
|
|
1172
910
|
async configure(plugin) {
|
|
1173
911
|
if (typeof plugin === 'string') {
|
|
1174
912
|
const p = this._plugins.get(plugin);
|
|
@@ -1209,18 +947,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1209
947
|
}
|
|
1210
948
|
return undefined;
|
|
1211
949
|
}
|
|
1212
|
-
/**
|
|
1213
|
-
* Shuts down a plugin.
|
|
1214
|
-
*
|
|
1215
|
-
* This method shuts down a plugin by calling its `onShutdown` method and resetting its state.
|
|
1216
|
-
* It logs the shutdown process and optionally removes all devices associated with the plugin.
|
|
1217
|
-
*
|
|
1218
|
-
* @param {Plugin | PluginName} plugin - The plugin to shut down.
|
|
1219
|
-
* @param {string} [reason] - The reason for shutting down the plugin.
|
|
1220
|
-
* @param {boolean} [removeAllDevices] - Whether to remove all devices associated with the plugin.
|
|
1221
|
-
* @param {boolean} [force] - Whether to force the shutdown even if the plugin is not loaded or started.
|
|
1222
|
-
* @returns {Promise<Plugin | undefined>} A promise that resolves to the shut down plugin object, or undefined if the shutdown failed.
|
|
1223
|
-
*/
|
|
1224
950
|
async shutdown(plugin, reason, removeAllDevices = false, force = false) {
|
|
1225
951
|
if (typeof plugin === 'string') {
|
|
1226
952
|
const p = this._plugins.get(plugin);
|
|
@@ -1277,15 +1003,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1277
1003
|
}
|
|
1278
1004
|
return undefined;
|
|
1279
1005
|
}
|
|
1280
|
-
/**
|
|
1281
|
-
* Loads the configuration for a plugin.
|
|
1282
|
-
* If the configuration file exists, it reads the file and returns the parsed JSON data.
|
|
1283
|
-
* If the configuration file does not exist, it creates a new file with default configuration and returns it.
|
|
1284
|
-
* If any error occurs during file access or creation, it logs an error and return un empty config.
|
|
1285
|
-
*
|
|
1286
|
-
* @param {Plugin} plugin - The plugin for which to load the configuration.
|
|
1287
|
-
* @returns {Promise<PlatformConfig>} A promise that resolves to the loaded or created configuration.
|
|
1288
|
-
*/
|
|
1289
1006
|
async loadConfig(plugin) {
|
|
1290
1007
|
const { default: path } = await import('node:path');
|
|
1291
1008
|
const { promises } = await import('node:fs');
|
|
@@ -1296,8 +1013,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1296
1013
|
const data = await promises.readFile(configFile, 'utf8');
|
|
1297
1014
|
const config = JSON.parse(data);
|
|
1298
1015
|
this.log.debug(`Loaded config file ${configFile} for plugin ${plg}${plugin.name}${db}.`);
|
|
1299
|
-
// this.log.debug(`Loaded config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
|
|
1300
|
-
// The first time a plugin is added to the system, the config file is created with the plugin name and type "AnyPlatform".
|
|
1301
1016
|
config.name = plugin.name;
|
|
1302
1017
|
config.type = plugin.type;
|
|
1303
1018
|
if (config.debug === undefined)
|
|
@@ -1324,7 +1039,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1324
1039
|
try {
|
|
1325
1040
|
await promises.writeFile(configFile, JSON.stringify(config, null, 2), 'utf8');
|
|
1326
1041
|
this.log.debug(`Created config file ${configFile} for plugin ${plg}${plugin.name}${db}.`);
|
|
1327
|
-
// this.log.debug(`Created config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
|
|
1328
1042
|
return config;
|
|
1329
1043
|
}
|
|
1330
1044
|
catch (err) {
|
|
@@ -1338,19 +1052,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1338
1052
|
}
|
|
1339
1053
|
}
|
|
1340
1054
|
}
|
|
1341
|
-
/**
|
|
1342
|
-
* Saves the configuration of a plugin to a file.
|
|
1343
|
-
*
|
|
1344
|
-
* This method saves the configuration of the specified plugin to a JSON file in the matterbridge directory.
|
|
1345
|
-
* If the plugin's configuration is not found, it logs an error and rejects the promise. If the configuration
|
|
1346
|
-
* is successfully saved, it logs a debug message. If an error occurs during the file write operation, it logs
|
|
1347
|
-
* the error and rejects the promise.
|
|
1348
|
-
*
|
|
1349
|
-
* @param {Plugin} plugin - The plugin whose configuration is to be saved.
|
|
1350
|
-
* @param {boolean} [restartRequired] - Indicates whether a restart is required after saving the configuration.
|
|
1351
|
-
* @returns {Promise<void>} A promise that resolves when the configuration is successfully saved, or rejects if an error occurs.
|
|
1352
|
-
* @throws {Error} If the plugin's configuration is not found.
|
|
1353
|
-
*/
|
|
1354
1055
|
async saveConfigFromPlugin(plugin, restartRequired = false) {
|
|
1355
1056
|
const { default: path } = await import('node:path');
|
|
1356
1057
|
const { promises } = await import('node:fs');
|
|
@@ -1365,7 +1066,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1365
1066
|
if (restartRequired)
|
|
1366
1067
|
plugin.restartRequired = true;
|
|
1367
1068
|
this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}`);
|
|
1368
|
-
// this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, plugin.platform.config);
|
|
1369
1069
|
return Promise.resolve();
|
|
1370
1070
|
}
|
|
1371
1071
|
catch (err) {
|
|
@@ -1373,20 +1073,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1373
1073
|
return Promise.reject(err);
|
|
1374
1074
|
}
|
|
1375
1075
|
}
|
|
1376
|
-
/**
|
|
1377
|
-
* Saves the configuration of a plugin from a JSON object to a file.
|
|
1378
|
-
*
|
|
1379
|
-
* This method saves the provided configuration of the specified plugin to a JSON file in the matterbridge directory.
|
|
1380
|
-
* It first checks if the configuration data is valid by ensuring it contains the correct name and type, and matches
|
|
1381
|
-
* the plugin's name. If the configuration data is invalid, it logs an error and returns. If the configuration is
|
|
1382
|
-
* successfully saved, it updates the plugin's `configJson` property and logs a debug message. If an error occurs
|
|
1383
|
-
* during the file write operation, it logs the error and returns.
|
|
1384
|
-
*
|
|
1385
|
-
* @param {Plugin} plugin - The plugin whose configuration is to be saved.
|
|
1386
|
-
* @param {PlatformConfig} config - The configuration data to be saved.
|
|
1387
|
-
* @param {boolean} [restartRequired] - Indicates whether a restart is required after saving the configuration.
|
|
1388
|
-
* @returns {Promise<void>} A promise that resolves when the configuration is successfully saved, or returns if an error occurs.
|
|
1389
|
-
*/
|
|
1390
1076
|
async saveConfigFromJson(plugin, config, restartRequired = false) {
|
|
1391
1077
|
const { default: path } = await import('node:path');
|
|
1392
1078
|
const { promises } = await import('node:fs');
|
|
@@ -1405,23 +1091,12 @@ export class PluginManager extends EventEmitter {
|
|
|
1405
1091
|
plugin.platform.onConfigChanged(config).catch((err) => this.log.error(`Error calling onConfigChanged for plugin ${plg}${plugin.name}${er}: ${err}`));
|
|
1406
1092
|
}
|
|
1407
1093
|
this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}`);
|
|
1408
|
-
// this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
|
|
1409
1094
|
}
|
|
1410
1095
|
catch (err) {
|
|
1411
1096
|
logError(this.log, `Error saving config file ${configFile} for plugin ${plg}${plugin.name}${er}`, err);
|
|
1412
1097
|
return;
|
|
1413
1098
|
}
|
|
1414
1099
|
}
|
|
1415
|
-
/**
|
|
1416
|
-
* Loads the schema for a plugin.
|
|
1417
|
-
*
|
|
1418
|
-
* This method attempts to load the schema file for the specified plugin. If the schema file is found,
|
|
1419
|
-
* it reads and parses the file, updates the schema's title and description, and logs the process.
|
|
1420
|
-
* If the schema file is not found, it logs the event and loads a default schema for the plugin.
|
|
1421
|
-
*
|
|
1422
|
-
* @param {Plugin} plugin - The plugin whose schema is to be loaded.
|
|
1423
|
-
* @returns {Promise<PlatformSchema>} A promise that resolves to the loaded schema object, or the default schema if the schema file is not found.
|
|
1424
|
-
*/
|
|
1425
1100
|
async loadSchema(plugin) {
|
|
1426
1101
|
const { promises } = await import('node:fs');
|
|
1427
1102
|
const schemaFile = plugin.path.replace('package.json', `${plugin.name}.schema.json`);
|
|
@@ -1432,7 +1107,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1432
1107
|
schema.title = plugin.description;
|
|
1433
1108
|
schema.description = plugin.name + ' v. ' + plugin.version + ' by ' + plugin.author;
|
|
1434
1109
|
this.log.debug(`Loaded schema file ${schemaFile} for plugin ${plg}${plugin.name}${db}.`);
|
|
1435
|
-
// this.log.debug(`Loaded schema file ${schemaFile} for plugin ${plg}${plugin.name}${db}.\nSchema:${rs}\n`, schema);
|
|
1436
1110
|
return schema;
|
|
1437
1111
|
}
|
|
1438
1112
|
catch (_err) {
|
|
@@ -1440,16 +1114,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1440
1114
|
return this.getDefaultSchema(plugin);
|
|
1441
1115
|
}
|
|
1442
1116
|
}
|
|
1443
|
-
/**
|
|
1444
|
-
* Returns the default schema for a plugin.
|
|
1445
|
-
*
|
|
1446
|
-
* This method generates a default schema object for the specified plugin. The schema includes
|
|
1447
|
-
* metadata such as the plugin's title, description, version, and author. It also defines the
|
|
1448
|
-
* properties of the schema, including the plugin's name, type, debug flag, and unregisterOnShutdown flag.
|
|
1449
|
-
*
|
|
1450
|
-
* @param {Plugin} plugin - The plugin for which the default schema is to be generated.
|
|
1451
|
-
* @returns {PlatformSchema} The default schema object for the plugin.
|
|
1452
|
-
*/
|
|
1453
1117
|
getDefaultSchema(plugin) {
|
|
1454
1118
|
return {
|
|
1455
1119
|
title: plugin.description,
|
|
@@ -1480,4 +1144,3 @@ export class PluginManager extends EventEmitter {
|
|
|
1480
1144
|
};
|
|
1481
1145
|
}
|
|
1482
1146
|
}
|
|
1483
|
-
//# sourceMappingURL=pluginManager.js.map
|