@matterbridge/core 3.5.3 → 3.5.4-dev-20260211-520e349
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/README.md +1 -1
- 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/export.d.ts +0 -23
- package/dist/export.js +0 -28
- package/dist/frontend.d.ts +0 -187
- package/dist/frontend.js +62 -581
- package/dist/helpers.d.ts +0 -43
- package/dist/helpers.js +0 -86
- package/dist/jestutils/export.d.ts +0 -1
- package/dist/jestutils/export.js +0 -1
- package/dist/jestutils/jestHelpers.d.ts +0 -259
- package/dist/jestutils/jestHelpers.js +15 -396
- 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 -356
- package/dist/matterbridge.d.ts +0 -389
- package/dist/matterbridge.js +48 -878
- 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 +56 -1514
- package/dist/matterbridgeEndpointHelpers.d.ts +0 -425
- package/dist/matterbridgeEndpointHelpers.js +20 -483
- 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 -473
- package/dist/pluginManager.d.ts +0 -307
- package/dist/pluginManager.js +6 -346
- package/dist/spawn.d.ts +0 -32
- package/dist/spawn.js +1 -71
- package/dist/utils/export.d.ts +0 -1
- package/dist/utils/export.js +0 -1
- package/package.json +27 -6
- 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/crypto/attestationDecoder.d.ts +0 -180
- package/dist/crypto/attestationDecoder.d.ts.map +0 -1
- package/dist/crypto/attestationDecoder.js +0 -176
- package/dist/crypto/attestationDecoder.js.map +0 -1
- package/dist/crypto/declarationDecoder.d.ts +0 -72
- package/dist/crypto/declarationDecoder.d.ts.map +0 -1
- package/dist/crypto/declarationDecoder.js +0 -241
- package/dist/crypto/declarationDecoder.js.map +0 -1
- package/dist/crypto/extract/342/200/220cert/342/200/220extensions.d.ts +0 -9
- package/dist/crypto/extract/342/200/220cert/342/200/220extensions.d.ts.map +0 -1
- package/dist/crypto/extract/342/200/220cert/342/200/220extensions.js +0 -120
- package/dist/crypto/extract/342/200/220cert/342/200/220extensions.js.map +0 -1
- package/dist/crypto/read-extensions.d.ts +0 -2
- package/dist/crypto/read-extensions.d.ts.map +0 -1
- package/dist/crypto/read-extensions.js +0 -81
- package/dist/crypto/read-extensions.js.map +0 -1
- package/dist/crypto/testData.d.ts +0 -31
- package/dist/crypto/testData.d.ts.map +0 -1
- package/dist/crypto/testData.js +0 -131
- package/dist/crypto/testData.js.map +0 -1
- package/dist/crypto/walk-der.d.ts +0 -2
- package/dist/crypto/walk-der.d.ts.map +0 -1
- package/dist/crypto/walk-der.js +0 -165
- package/dist/crypto/walk-der.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/export.d.ts.map +0 -1
- package/dist/export.js.map +0 -1
- package/dist/frontend.d.ts.map +0 -1
- package/dist/frontend.js.map +0 -1
- package/dist/helpers.d.ts.map +0 -1
- package/dist/helpers.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/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/mb_coap.d.ts +0 -24
- package/dist/mb_coap.d.ts.map +0 -1
- package/dist/mb_coap.js +0 -89
- package/dist/mb_coap.js.map +0 -1
- package/dist/mb_health.d.ts +0 -77
- package/dist/mb_health.d.ts.map +0 -1
- package/dist/mb_health.js +0 -147
- package/dist/mb_health.js.map +0 -1
- package/dist/mb_mdns.d.ts +0 -24
- package/dist/mb_mdns.d.ts.map +0 -1
- package/dist/mb_mdns.js +0 -285
- 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/spawn.d.ts.map +0 -1
- package/dist/spawn.js.map +0 -1
- package/dist/utils/export.d.ts.map +0 -1
- package/dist/utils/export.js.map +0 -1
- package/dist/workers/brand.d.ts +0 -25
- package/dist/workers/brand.d.ts.map +0 -1
- package/dist/workers/brand.extend.d.ts +0 -10
- package/dist/workers/brand.extend.d.ts.map +0 -1
- package/dist/workers/brand.extend.js +0 -15
- package/dist/workers/brand.extend.js.map +0 -1
- package/dist/workers/brand.invalid.d.ts +0 -9
- package/dist/workers/brand.invalid.d.ts.map +0 -1
- package/dist/workers/brand.invalid.js +0 -19
- package/dist/workers/brand.invalid.js.map +0 -1
- package/dist/workers/brand.js +0 -67
- package/dist/workers/brand.js.map +0 -1
- package/dist/workers/clusterTypes.d.ts +0 -47
- package/dist/workers/clusterTypes.d.ts.map +0 -1
- package/dist/workers/clusterTypes.js +0 -57
- package/dist/workers/clusterTypes.js.map +0 -1
- package/dist/workers/frontendWorker.d.ts +0 -2
- package/dist/workers/frontendWorker.d.ts.map +0 -1
- package/dist/workers/frontendWorker.js +0 -90
- package/dist/workers/frontendWorker.js.map +0 -1
- package/dist/workers/helloWorld.d.ts +0 -2
- package/dist/workers/helloWorld.d.ts.map +0 -1
- package/dist/workers/helloWorld.js +0 -135
- package/dist/workers/helloWorld.js.map +0 -1
- package/dist/workers/matterWorker.d.ts +0 -2
- package/dist/workers/matterWorker.d.ts.map +0 -1
- package/dist/workers/matterWorker.js +0 -104
- package/dist/workers/matterWorker.js.map +0 -1
- package/dist/workers/matterbridgeWorker.d.ts +0 -2
- package/dist/workers/matterbridgeWorker.d.ts.map +0 -1
- package/dist/workers/matterbridgeWorker.js +0 -75
- package/dist/workers/matterbridgeWorker.js.map +0 -1
- package/dist/workers/messageLab.d.ts +0 -134
- package/dist/workers/messageLab.d.ts.map +0 -1
- package/dist/workers/messageLab.js +0 -129
- package/dist/workers/messageLab.js.map +0 -1
- package/dist/workers/testWorker.d.ts +0 -2
- package/dist/workers/testWorker.d.ts.map +0 -1
- package/dist/workers/testWorker.js +0 -45
- package/dist/workers/testWorker.js.map +0 -1
- package/dist/workers/usage.d.ts +0 -19
- package/dist/workers/usage.d.ts.map +0 -1
- package/dist/workers/usage.js +0 -140
- package/dist/workers/usage.js.map +0 -1
- package/dist/workers/workerManager.d.ts +0 -115
- package/dist/workers/workerManager.d.ts.map +0 -1
- package/dist/workers/workerManager.js +0 -464
- package/dist/workers/workerManager.js.map +0 -1
- package/dist/workers/workerServer.d.ts +0 -126
- package/dist/workers/workerServer.d.ts.map +0 -1
- package/dist/workers/workerServer.js +0 -340
- package/dist/workers/workerServer.js.map +0 -1
- package/dist/workers/workerTypes.d.ts +0 -23
- package/dist/workers/workerTypes.d.ts.map +0 -1
- package/dist/workers/workerTypes.js +0 -3
- package/dist/workers/workerTypes.js.map +0 -1
package/dist/pluginManager.js
CHANGED
|
@@ -1,42 +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
|
-
/* eslint-disable jsdoc/reject-function-type */
|
|
25
|
-
/* eslint-disable jsdoc/reject-any-type */
|
|
26
|
-
// Node.js import
|
|
27
1
|
import EventEmitter from 'node:events';
|
|
28
|
-
// AnsiLogger
|
|
29
2
|
import { AnsiLogger, UNDERLINE, UNDERLINEOFF, BLUE, db, er, nf, nt, rs, wr, debugStringify, CYAN } from 'node-ansi-logger';
|
|
30
|
-
// @matterbridge
|
|
31
3
|
import { BroadcastServer } from '@matterbridge/thread';
|
|
32
4
|
import { hasParameter, inspectError, logError } from '@matterbridge/utils';
|
|
33
5
|
import { plg, typ } from '@matterbridge/types';
|
|
34
6
|
import { assertMatterbridgePlatform } from './matterbridgePlatform.js';
|
|
35
7
|
import { isMatterbridgeAccessoryPlatform } from './matterbridgeAccessoryPlatform.js';
|
|
36
8
|
import { isMatterbridgeDynamicPlatform } from './matterbridgeDynamicPlatform.js';
|
|
37
|
-
/**
|
|
38
|
-
* Manages Matterbridge plugins.
|
|
39
|
-
*/
|
|
40
9
|
export class PluginManager extends EventEmitter {
|
|
41
10
|
matterbridge;
|
|
42
11
|
_plugins = new Map();
|
|
@@ -44,15 +13,10 @@ export class PluginManager extends EventEmitter {
|
|
|
44
13
|
server;
|
|
45
14
|
debug = hasParameter('debug') || hasParameter('verbose');
|
|
46
15
|
verbose = hasParameter('verbose');
|
|
47
|
-
/**
|
|
48
|
-
* Creates an instance of PluginManager.
|
|
49
|
-
*
|
|
50
|
-
* @param {Matterbridge} matterbridge - The Matterbridge instance.
|
|
51
|
-
*/
|
|
52
16
|
constructor(matterbridge) {
|
|
53
17
|
super();
|
|
54
18
|
this.matterbridge = matterbridge;
|
|
55
|
-
this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4
|
|
19
|
+
this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
|
|
56
20
|
this.log.debug('Matterbridge plugin manager starting...');
|
|
57
21
|
this.server = new BroadcastServer('plugins', this.log);
|
|
58
22
|
this.server.on('broadcast_message', this.msgHandler.bind(this));
|
|
@@ -225,7 +189,7 @@ export class PluginManager extends EventEmitter {
|
|
|
225
189
|
{
|
|
226
190
|
const plugin = this.get(msg.params.name);
|
|
227
191
|
if (plugin) {
|
|
228
|
-
this.saveConfigFromJson(plugin, msg.params.config, msg.params.restartRequired);
|
|
192
|
+
this.saveConfigFromJson(plugin, msg.params.config, msg.params.restartRequired);
|
|
229
193
|
this.server.respond({ ...msg, result: { success: true } });
|
|
230
194
|
}
|
|
231
195
|
else {
|
|
@@ -263,62 +227,25 @@ export class PluginManager extends EventEmitter {
|
|
|
263
227
|
}
|
|
264
228
|
}
|
|
265
229
|
}
|
|
266
|
-
/**
|
|
267
|
-
* Gets the number of plugins.
|
|
268
|
-
*
|
|
269
|
-
* @returns {number} The number of plugins.
|
|
270
|
-
*/
|
|
271
230
|
get length() {
|
|
272
231
|
return this._plugins.size;
|
|
273
232
|
}
|
|
274
|
-
/**
|
|
275
|
-
* Gets the number of plugins.
|
|
276
|
-
*
|
|
277
|
-
* @returns {number} The number of plugins.
|
|
278
|
-
*/
|
|
279
233
|
get size() {
|
|
280
234
|
return this._plugins.size;
|
|
281
235
|
}
|
|
282
|
-
/**
|
|
283
|
-
* Checks if a plugin with the specified name exists.
|
|
284
|
-
*
|
|
285
|
-
* @param {string} name - The name of the plugin.
|
|
286
|
-
* @returns {boolean} True if the plugin exists, false otherwise.
|
|
287
|
-
*/
|
|
288
236
|
has(name) {
|
|
289
237
|
return this._plugins.has(name);
|
|
290
238
|
}
|
|
291
|
-
/**
|
|
292
|
-
* Gets a plugin by its name.
|
|
293
|
-
*
|
|
294
|
-
* @param {string} name - The name of the plugin.
|
|
295
|
-
* @returns {Plugin | undefined} The plugin, or undefined if not found.
|
|
296
|
-
*/
|
|
297
239
|
get(name) {
|
|
298
240
|
return this._plugins.get(name);
|
|
299
241
|
}
|
|
300
|
-
/**
|
|
301
|
-
* Adds a plugin to the manager.
|
|
302
|
-
*
|
|
303
|
-
* @param {Plugin} plugin - The plugin to add.
|
|
304
|
-
* @returns {Plugin} The added plugin.
|
|
305
|
-
*/
|
|
306
242
|
set(plugin) {
|
|
307
243
|
this._plugins.set(plugin.name, plugin);
|
|
308
244
|
return plugin;
|
|
309
245
|
}
|
|
310
|
-
/**
|
|
311
|
-
* Clears all plugins from the manager.
|
|
312
|
-
*/
|
|
313
246
|
clear() {
|
|
314
247
|
this._plugins.clear();
|
|
315
248
|
}
|
|
316
|
-
/**
|
|
317
|
-
* Converts a plugin or API plugin to a storage plugin.
|
|
318
|
-
*
|
|
319
|
-
* @param {Plugin | ApiPlugin} plugin - The plugin or API plugin to convert.
|
|
320
|
-
* @returns {StoragePlugin} The converted storage plugin.
|
|
321
|
-
*/
|
|
322
249
|
toStoragePlugin(plugin) {
|
|
323
250
|
return {
|
|
324
251
|
name: plugin.name,
|
|
@@ -330,12 +257,6 @@ export class PluginManager extends EventEmitter {
|
|
|
330
257
|
enabled: plugin.enabled,
|
|
331
258
|
};
|
|
332
259
|
}
|
|
333
|
-
/**
|
|
334
|
-
* Converts a plugin to an API plugin.
|
|
335
|
-
*
|
|
336
|
-
* @param {Plugin} plugin - The plugin to convert.
|
|
337
|
-
* @returns {ApiPlugin} The converted API plugin.
|
|
338
|
-
*/
|
|
339
260
|
toApiPlugin(plugin) {
|
|
340
261
|
return {
|
|
341
262
|
name: plugin.name,
|
|
@@ -365,19 +286,9 @@ export class PluginManager extends EventEmitter {
|
|
|
365
286
|
matter: plugin.serverNode ? this.matterbridge.getServerNodeData(plugin.serverNode) : undefined,
|
|
366
287
|
};
|
|
367
288
|
}
|
|
368
|
-
/**
|
|
369
|
-
* Gets an array of all plugins.
|
|
370
|
-
*
|
|
371
|
-
* @returns {Plugin[]} An array of all plugins.
|
|
372
|
-
*/
|
|
373
289
|
array() {
|
|
374
290
|
return Array.from(this._plugins.values());
|
|
375
291
|
}
|
|
376
|
-
/**
|
|
377
|
-
* Gets a StoragePlugin array of all plugins suitable for serialization.
|
|
378
|
-
*
|
|
379
|
-
* @returns {StoragePlugin[]} An array of all plugins.
|
|
380
|
-
*/
|
|
381
292
|
storagePluginArray() {
|
|
382
293
|
const storagePlugins = [];
|
|
383
294
|
for (const plugin of this._plugins.values()) {
|
|
@@ -385,11 +296,6 @@ export class PluginManager extends EventEmitter {
|
|
|
385
296
|
}
|
|
386
297
|
return storagePlugins;
|
|
387
298
|
}
|
|
388
|
-
/**
|
|
389
|
-
* Gets an ApiPlugin array of all plugins suitable for serialization.
|
|
390
|
-
*
|
|
391
|
-
* @returns {ApiPlugin[]} An array of all plugins.
|
|
392
|
-
*/
|
|
393
299
|
apiPluginArray() {
|
|
394
300
|
const apiPlugins = [];
|
|
395
301
|
for (const plugin of this._plugins.values()) {
|
|
@@ -397,20 +303,9 @@ export class PluginManager extends EventEmitter {
|
|
|
397
303
|
}
|
|
398
304
|
return apiPlugins;
|
|
399
305
|
}
|
|
400
|
-
/**
|
|
401
|
-
* Gets an iterator for the plugins.
|
|
402
|
-
*
|
|
403
|
-
* @returns {IterableIterator<Plugin>} An iterator for the plugins.
|
|
404
|
-
*/
|
|
405
306
|
[Symbol.iterator]() {
|
|
406
307
|
return this._plugins.values();
|
|
407
308
|
}
|
|
408
|
-
/**
|
|
409
|
-
* Executes a provided function once for each plugin.
|
|
410
|
-
*
|
|
411
|
-
* @param {Function} callback - The function to execute for each plugin.
|
|
412
|
-
* @returns {Promise<void>}
|
|
413
|
-
*/
|
|
414
309
|
async forEach(callback) {
|
|
415
310
|
if (this.size === 0)
|
|
416
311
|
return;
|
|
@@ -424,40 +319,23 @@ export class PluginManager extends EventEmitter {
|
|
|
424
319
|
});
|
|
425
320
|
await Promise.all(tasks);
|
|
426
321
|
}
|
|
427
|
-
/**
|
|
428
|
-
* Sets the log level for the plugin manager.
|
|
429
|
-
*
|
|
430
|
-
* @param {LogLevel} logLevel - The log level to set.
|
|
431
|
-
*/
|
|
432
322
|
set logLevel(logLevel) {
|
|
433
323
|
this.log.logLevel = logLevel;
|
|
434
324
|
}
|
|
435
|
-
/**
|
|
436
|
-
* Loads registered plugins from storage.
|
|
437
|
-
*
|
|
438
|
-
* @returns {Promise<StoragePlugin[]>} A promise that resolves to an array of registered plugins.
|
|
439
|
-
*/
|
|
440
325
|
async loadFromStorage() {
|
|
441
326
|
if (!this.matterbridge.nodeContext) {
|
|
442
327
|
throw new Error('loadFromStorage: node context is not available.');
|
|
443
328
|
}
|
|
444
|
-
// Load the array from storage and convert it to a map
|
|
445
329
|
const pluginsArray = await this.matterbridge.nodeContext.get('plugins', []);
|
|
446
330
|
for (const plugin of pluginsArray)
|
|
447
331
|
this._plugins.set(plugin.name, plugin);
|
|
448
332
|
this.log.debug(`Loaded ${BLUE}${pluginsArray.length}${db} plugins from storage`);
|
|
449
333
|
return pluginsArray;
|
|
450
334
|
}
|
|
451
|
-
/**
|
|
452
|
-
* Saves registered plugins to storage.
|
|
453
|
-
*
|
|
454
|
-
* @returns {Promise<number>} A promise that resolves to the number of registered plugins.
|
|
455
|
-
*/
|
|
456
335
|
async saveToStorage() {
|
|
457
336
|
if (!this.matterbridge.nodeContext) {
|
|
458
337
|
throw new Error('loadFromStorage: node context is not available.');
|
|
459
338
|
}
|
|
460
|
-
// Convert the map to an array
|
|
461
339
|
const plugins = [];
|
|
462
340
|
for (const plugin of this.array()) {
|
|
463
341
|
plugins.push({
|
|
@@ -474,22 +352,13 @@ export class PluginManager extends EventEmitter {
|
|
|
474
352
|
this.log.debug(`Saved ${BLUE}${plugins.length}${db} plugins to storage`);
|
|
475
353
|
return plugins.length;
|
|
476
354
|
}
|
|
477
|
-
/**
|
|
478
|
-
* Resolves the name of a plugin by loading and parsing its package.json file.
|
|
479
|
-
* It will first try to resolve the path as is, then in the global modules directory, and finally in the matterbridge plugin directory.
|
|
480
|
-
*
|
|
481
|
-
* @param {string} nameOrPath - The name of the plugin or the path to the plugin's package.json file.
|
|
482
|
-
* @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.
|
|
483
|
-
*/
|
|
484
355
|
async resolve(nameOrPath) {
|
|
485
356
|
const { default: path } = await import('node:path');
|
|
486
357
|
const { promises } = await import('node:fs');
|
|
487
358
|
if (!nameOrPath.endsWith('package.json'))
|
|
488
359
|
nameOrPath = path.join(nameOrPath, 'package.json');
|
|
489
|
-
// Resolve the package.json of the plugin
|
|
490
360
|
let packageJsonPath = path.resolve(nameOrPath);
|
|
491
361
|
this.log.debug(`Resolving plugin path ${plg}${packageJsonPath}${db}`);
|
|
492
|
-
// Check if the package.json file exists at the specified path or next try in the global modules directory
|
|
493
362
|
try {
|
|
494
363
|
await promises.access(packageJsonPath);
|
|
495
364
|
}
|
|
@@ -498,7 +367,6 @@ export class PluginManager extends EventEmitter {
|
|
|
498
367
|
packageJsonPath = path.join(this.matterbridge.globalModulesDirectory, nameOrPath);
|
|
499
368
|
this.log.debug(`Trying at ${plg}${packageJsonPath}${db}`);
|
|
500
369
|
}
|
|
501
|
-
// Check if the package.json file exists at the global modules directory or next try in the matterbridge plugin directory
|
|
502
370
|
try {
|
|
503
371
|
await promises.access(packageJsonPath);
|
|
504
372
|
}
|
|
@@ -508,9 +376,7 @@ export class PluginManager extends EventEmitter {
|
|
|
508
376
|
this.log.debug(`Trying at ${plg}${packageJsonPath}${db}`);
|
|
509
377
|
}
|
|
510
378
|
try {
|
|
511
|
-
// Load the package.json of the plugin or fails if even not found in the matterbridge plugin directory
|
|
512
379
|
const packageJson = JSON.parse(await promises.readFile(packageJsonPath, 'utf8'));
|
|
513
|
-
// Check for main issues
|
|
514
380
|
if (!packageJson.name) {
|
|
515
381
|
this.log.error(`Package.json name not found at ${packageJsonPath}`);
|
|
516
382
|
return null;
|
|
@@ -523,7 +389,6 @@ export class PluginManager extends EventEmitter {
|
|
|
523
389
|
this.log.error(`Plugin at ${packageJsonPath} has no main entrypoint in package.json`);
|
|
524
390
|
return null;
|
|
525
391
|
}
|
|
526
|
-
// Check for @project-chip and @matter packages in dependencies and devDependencies
|
|
527
392
|
const checkForProjectChipPackages = (dependencies) => {
|
|
528
393
|
return Object.keys(dependencies).filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matter'));
|
|
529
394
|
};
|
|
@@ -563,7 +428,6 @@ export class PluginManager extends EventEmitter {
|
|
|
563
428
|
});
|
|
564
429
|
return null;
|
|
565
430
|
}
|
|
566
|
-
// Check for matterbridge package in dependencies and devDependencies
|
|
567
431
|
const checkForMatterbridgePackage = (dependencies) => {
|
|
568
432
|
return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
|
|
569
433
|
};
|
|
@@ -617,19 +481,13 @@ export class PluginManager extends EventEmitter {
|
|
|
617
481
|
return null;
|
|
618
482
|
}
|
|
619
483
|
}
|
|
620
|
-
/**
|
|
621
|
-
* Installs a package globally using npm.
|
|
622
|
-
*
|
|
623
|
-
* @param {string} packageName - The name of the package to install.
|
|
624
|
-
* @returns {Promise<boolean>} A promise that resolves to true if the installation was successful, false otherwise.
|
|
625
|
-
*/
|
|
626
484
|
async install(packageName) {
|
|
627
485
|
this.log.debug(`Installing plugin ${plg}${packageName}${db}...`);
|
|
628
486
|
const { spawnCommand } = await import('./spawn.js');
|
|
629
487
|
if (await spawnCommand('npm', ['install', '-g', packageName, '--omit=dev', '--verbose'], 'install', packageName)) {
|
|
630
488
|
this.matterbridge.restartRequired = true;
|
|
631
489
|
this.matterbridge.fixedRestartRequired = true;
|
|
632
|
-
packageName = packageName.replace(/@.*$/, '');
|
|
490
|
+
packageName = packageName.replace(/@.*$/, '');
|
|
633
491
|
if (packageName !== 'matterbridge') {
|
|
634
492
|
if (!this.has(packageName))
|
|
635
493
|
await this.add(packageName);
|
|
@@ -650,12 +508,6 @@ export class PluginManager extends EventEmitter {
|
|
|
650
508
|
return false;
|
|
651
509
|
}
|
|
652
510
|
}
|
|
653
|
-
/**
|
|
654
|
-
* Uninstalls a package globally using npm.
|
|
655
|
-
*
|
|
656
|
-
* @param {string} packageName - The name of the package to uninstall.
|
|
657
|
-
* @returns {Promise<boolean>} A promise that resolves to true if the uninstallation was successful, false otherwise.
|
|
658
|
-
*/
|
|
659
511
|
async uninstall(packageName) {
|
|
660
512
|
this.log.debug(`Uninstalling plugin ${plg}${packageName}${db}...`);
|
|
661
513
|
const { spawnCommand } = await import('./spawn.js');
|
|
@@ -677,12 +529,6 @@ export class PluginManager extends EventEmitter {
|
|
|
677
529
|
return false;
|
|
678
530
|
}
|
|
679
531
|
}
|
|
680
|
-
/**
|
|
681
|
-
* Get the author of a plugin from its package.json.
|
|
682
|
-
*
|
|
683
|
-
* @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
|
|
684
|
-
* @returns {string} The author of the plugin, or 'Unknown author' if not found.
|
|
685
|
-
*/
|
|
686
532
|
getAuthor(packageJson) {
|
|
687
533
|
if (packageJson.author && typeof packageJson.author === 'string')
|
|
688
534
|
return packageJson.author;
|
|
@@ -690,12 +536,6 @@ export class PluginManager extends EventEmitter {
|
|
|
690
536
|
return packageJson.author.name;
|
|
691
537
|
return 'Unknown author';
|
|
692
538
|
}
|
|
693
|
-
/**
|
|
694
|
-
* Get the homepage of a plugin from its package.json.
|
|
695
|
-
*
|
|
696
|
-
* @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
|
|
697
|
-
* @returns {string | undefined} The homepage of the plugin, or undefined if not found.
|
|
698
|
-
*/
|
|
699
539
|
getHomepage(packageJson) {
|
|
700
540
|
if (packageJson.homepage && typeof packageJson.homepage === 'string' && packageJson.homepage.includes('http')) {
|
|
701
541
|
return packageJson.homepage.replace('git+', '').replace('.git', '');
|
|
@@ -708,14 +548,7 @@ export class PluginManager extends EventEmitter {
|
|
|
708
548
|
return packageJson.repository.url.replace('git+', '').replace('.git', '');
|
|
709
549
|
}
|
|
710
550
|
}
|
|
711
|
-
/**
|
|
712
|
-
* Get the help URL of a plugin from its package.json.
|
|
713
|
-
*
|
|
714
|
-
* @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
|
|
715
|
-
* @returns {string | undefined} The URL to the help page or to the README file, or undefined if not found.
|
|
716
|
-
*/
|
|
717
551
|
getHelp(packageJson) {
|
|
718
|
-
// If there's a help field that looks like a URL, return it.
|
|
719
552
|
if (packageJson.help && typeof packageJson.help === 'string' && packageJson.help.startsWith('http')) {
|
|
720
553
|
return packageJson.help;
|
|
721
554
|
}
|
|
@@ -730,14 +563,7 @@ export class PluginManager extends EventEmitter {
|
|
|
730
563
|
return packageJson.homepage.replace('git+', '').replace('.git', '');
|
|
731
564
|
}
|
|
732
565
|
}
|
|
733
|
-
/**
|
|
734
|
-
* Get the changelog URL of a plugin from its package.json.
|
|
735
|
-
*
|
|
736
|
-
* @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
|
|
737
|
-
* @returns {string | undefined} The URL to the CHANGELOG file, or undefined if not found.
|
|
738
|
-
*/
|
|
739
566
|
getChangelog(packageJson) {
|
|
740
|
-
// If there's a changelog field that looks like a URL, return it.
|
|
741
567
|
if (packageJson.changelog && typeof packageJson.changelog === 'string' && packageJson.changelog.startsWith('http')) {
|
|
742
568
|
return packageJson.changelog;
|
|
743
569
|
}
|
|
@@ -752,13 +578,6 @@ export class PluginManager extends EventEmitter {
|
|
|
752
578
|
return packageJson.homepage.replace('git+', '').replace('.git', '');
|
|
753
579
|
}
|
|
754
580
|
}
|
|
755
|
-
/**
|
|
756
|
-
* Get the first funding URL(s) of a plugin from its package.json.
|
|
757
|
-
*
|
|
758
|
-
* @param {Record<string, any>} packageJson - The package.json object of the plugin.
|
|
759
|
-
* @returns {string | undefined} The first funding URLs, or undefined if not found.
|
|
760
|
-
*/
|
|
761
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
762
581
|
getFunding(packageJson) {
|
|
763
582
|
const funding = packageJson.funding;
|
|
764
583
|
if (!funding)
|
|
@@ -767,27 +586,16 @@ export class PluginManager extends EventEmitter {
|
|
|
767
586
|
return;
|
|
768
587
|
if (typeof funding === 'string' && funding.startsWith('http'))
|
|
769
588
|
return funding;
|
|
770
|
-
// Normalize funding into an array.
|
|
771
589
|
const fundingEntries = Array.isArray(funding) ? funding : [funding];
|
|
772
590
|
for (const entry of fundingEntries) {
|
|
773
591
|
if (entry && typeof entry === 'string' && entry.startsWith('http')) {
|
|
774
|
-
// If the funding entry is a string, assume it is a URL.
|
|
775
592
|
return entry;
|
|
776
593
|
}
|
|
777
594
|
else if (entry && typeof entry === 'object' && typeof entry.url === 'string' && entry.url.startsWith('http')) {
|
|
778
|
-
// If it's an object with a 'url' property, use that.
|
|
779
595
|
return entry.url;
|
|
780
596
|
}
|
|
781
597
|
}
|
|
782
598
|
}
|
|
783
|
-
/**
|
|
784
|
-
* Parses the plugin package.json and returns it.
|
|
785
|
-
* It will also log warnings and errors for missing or invalid fields.
|
|
786
|
-
* It will return null if critical errors are found.
|
|
787
|
-
*
|
|
788
|
-
* @param {Plugin | PluginName} plugin - The plugin to load the package from.
|
|
789
|
-
* @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.
|
|
790
|
-
*/
|
|
791
599
|
async parse(plugin) {
|
|
792
600
|
const { promises } = await import('node:fs');
|
|
793
601
|
if (typeof plugin === 'string') {
|
|
@@ -825,7 +633,6 @@ export class PluginManager extends EventEmitter {
|
|
|
825
633
|
plugin.funding = this.getFunding(packageJson);
|
|
826
634
|
if (!plugin.type)
|
|
827
635
|
this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no type`);
|
|
828
|
-
// Check for @project-chip and @matter packages in dependencies and devDependencies
|
|
829
636
|
const checkForProjectChipPackages = (dependencies) => {
|
|
830
637
|
return Object.keys(dependencies).filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matter'));
|
|
831
638
|
};
|
|
@@ -865,7 +672,6 @@ export class PluginManager extends EventEmitter {
|
|
|
865
672
|
});
|
|
866
673
|
return null;
|
|
867
674
|
}
|
|
868
|
-
// Check for matterbridge package in dependencies and devDependencies
|
|
869
675
|
const checkForMatterbridgePackage = (dependencies) => {
|
|
870
676
|
return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
|
|
871
677
|
};
|
|
@@ -919,16 +725,6 @@ export class PluginManager extends EventEmitter {
|
|
|
919
725
|
return null;
|
|
920
726
|
}
|
|
921
727
|
}
|
|
922
|
-
/**
|
|
923
|
-
* Enables a plugin by its name or path.
|
|
924
|
-
*
|
|
925
|
-
* This method enables a plugin by setting its `enabled` property to `true` and saving the updated
|
|
926
|
-
* plugin information to storage. It first checks if the plugin is already registered in the `_plugins` map.
|
|
927
|
-
* If not, it attempts to resolve the plugin's `package.json` file to retrieve its name and enable it.
|
|
928
|
-
*
|
|
929
|
-
* @param {string} nameOrPath - The name or path of the plugin to enable.
|
|
930
|
-
* @returns {Promise<Plugin | null>} A promise that resolves to the enabled plugin object, or null if the plugin could not be enabled.
|
|
931
|
-
*/
|
|
932
728
|
async enable(nameOrPath) {
|
|
933
729
|
const { promises } = await import('node:fs');
|
|
934
730
|
if (!nameOrPath)
|
|
@@ -964,16 +760,6 @@ export class PluginManager extends EventEmitter {
|
|
|
964
760
|
return null;
|
|
965
761
|
}
|
|
966
762
|
}
|
|
967
|
-
/**
|
|
968
|
-
* Disables a plugin by its name or path.
|
|
969
|
-
*
|
|
970
|
-
* This method disables a plugin by setting its `enabled` property to `false` and saving the updated
|
|
971
|
-
* plugin information to storage. It first checks if the plugin is already registered in the `_plugins` map.
|
|
972
|
-
* If not, it attempts to resolve the plugin's `package.json` file to retrieve its name and disable it.
|
|
973
|
-
*
|
|
974
|
-
* @param {string} nameOrPath - The name or path of the plugin to enable.
|
|
975
|
-
* @returns {Promise<Plugin | null>} A promise that resolves to the disabled plugin object, or null if the plugin could not be disabled.
|
|
976
|
-
*/
|
|
977
763
|
async disable(nameOrPath) {
|
|
978
764
|
const { promises } = await import('node:fs');
|
|
979
765
|
if (!nameOrPath)
|
|
@@ -1009,16 +795,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1009
795
|
return null;
|
|
1010
796
|
}
|
|
1011
797
|
}
|
|
1012
|
-
/**
|
|
1013
|
-
* Removes a plugin by its name or path.
|
|
1014
|
-
*
|
|
1015
|
-
* This method removes a plugin from the `_plugins` map and saves the updated plugin information to storage.
|
|
1016
|
-
* It first checks if the plugin is already registered in the `_plugins` map. If not, it attempts to resolve
|
|
1017
|
-
* the plugin's `package.json` file to retrieve its name and remove it.
|
|
1018
|
-
*
|
|
1019
|
-
* @param {string} nameOrPath - The name or path of the plugin to remove.
|
|
1020
|
-
* @returns {Promise<Plugin | null>} A promise that resolves to the removed plugin object, or null if the plugin could not be removed.
|
|
1021
|
-
*/
|
|
1022
798
|
async remove(nameOrPath) {
|
|
1023
799
|
const { promises } = await import('node:fs');
|
|
1024
800
|
if (!nameOrPath)
|
|
@@ -1054,17 +830,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1054
830
|
return null;
|
|
1055
831
|
}
|
|
1056
832
|
}
|
|
1057
|
-
/**
|
|
1058
|
-
* Adds a plugin by its name or path.
|
|
1059
|
-
*
|
|
1060
|
-
* This method adds a plugin to the plugins map and saves the updated plugin information to storage.
|
|
1061
|
-
* It first resolves the plugin's `package.json` file to retrieve its details. If the plugin is already
|
|
1062
|
-
* registered, it logs an info message and returns null. Otherwise, it registers the plugin, enables it,
|
|
1063
|
-
* and saves the updated plugin information to storage.
|
|
1064
|
-
*
|
|
1065
|
-
* @param {string} nameOrPath - The name or path of the plugin to add.
|
|
1066
|
-
* @returns {Promise<Plugin | null>} A promise that resolves to the added plugin object, or null if the plugin could not be added.
|
|
1067
|
-
*/
|
|
1068
833
|
async add(nameOrPath) {
|
|
1069
834
|
const { promises } = await import('node:fs');
|
|
1070
835
|
if (!nameOrPath)
|
|
@@ -1104,15 +869,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1104
869
|
return null;
|
|
1105
870
|
}
|
|
1106
871
|
}
|
|
1107
|
-
/**
|
|
1108
|
-
* Loads a plugin and returns the corresponding MatterbridgePlatform instance.
|
|
1109
|
-
*
|
|
1110
|
-
* @param {Plugin | PluginName} plugin - The plugin to load.
|
|
1111
|
-
* @param {boolean} start - Optional flag indicating whether to start the plugin after loading. Default is false.
|
|
1112
|
-
* @param {string} message - Optional message to pass to the plugin when starting.
|
|
1113
|
-
* @param {boolean} configure - Optional flag indicating whether to configure the plugin after loading. Default is false.
|
|
1114
|
-
* @returns {Promise<MatterbridgePlatform | undefined>} A Promise that resolves to the loaded MatterbridgePlatform instance or undefined.
|
|
1115
|
-
*/
|
|
1116
872
|
async load(plugin, start = false, message = '', configure = false) {
|
|
1117
873
|
const { promises } = await import('node:fs');
|
|
1118
874
|
const { default: path } = await import('node:path');
|
|
@@ -1134,20 +890,15 @@ export class PluginManager extends EventEmitter {
|
|
|
1134
890
|
}
|
|
1135
891
|
this.log.info(`Loading plugin ${plg}${plugin.name}${nf} type ${typ}${plugin.type}${nf}`);
|
|
1136
892
|
try {
|
|
1137
|
-
// Load the package.json of the plugin
|
|
1138
893
|
const packageJson = JSON.parse(await promises.readFile(plugin.path, 'utf8'));
|
|
1139
|
-
// Resolve the main module path relative to package.json
|
|
1140
894
|
const pluginEntry = path.resolve(path.dirname(plugin.path), packageJson.main);
|
|
1141
|
-
// Dynamically import the plugin
|
|
1142
895
|
const { pathToFileURL } = await import('node:url');
|
|
1143
896
|
const pluginUrl = pathToFileURL(pluginEntry);
|
|
1144
897
|
this.log.debug(`Importing plugin ${plg}${plugin.name}${db} from ${pluginUrl.href}`);
|
|
1145
898
|
const pluginInstance = (await import(pluginUrl.href));
|
|
1146
899
|
this.log.debug(`Imported plugin ${plg}${plugin.name}${db} from ${pluginUrl.href}`);
|
|
1147
|
-
// Call the default export function of the plugin, passing this MatterBridge instance, the log and the config
|
|
1148
900
|
if (pluginInstance.default) {
|
|
1149
901
|
const config = await this.loadConfig(plugin);
|
|
1150
|
-
// 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.
|
|
1151
902
|
plugin.name = packageJson.name;
|
|
1152
903
|
plugin.description = packageJson.description ?? 'No description';
|
|
1153
904
|
plugin.version = packageJson.version;
|
|
@@ -1158,13 +909,12 @@ export class PluginManager extends EventEmitter {
|
|
|
1158
909
|
config.version = packageJson.version;
|
|
1159
910
|
const log = new AnsiLogger({
|
|
1160
911
|
logName: plugin.description,
|
|
1161
|
-
logTimestampFormat: 4
|
|
1162
|
-
logLevel: config.debug ? "debug"
|
|
912
|
+
logTimestampFormat: 4,
|
|
913
|
+
logLevel: config.debug ? "debug" : this.matterbridge.logLevel,
|
|
1163
914
|
});
|
|
1164
915
|
const platform = pluginInstance.default(this.matterbridge.getPlatformMatterbridge(), log, config);
|
|
1165
916
|
assertMatterbridgePlatform(platform, `Plugin ${plugin.name} does not export a valid MatterbridgePlatform`);
|
|
1166
917
|
if (!isMatterbridgeAccessoryPlatform(platform) && !isMatterbridgeDynamicPlatform(platform)) {
|
|
1167
|
-
// @ts-expect-error - override the type guard to call the shutdown method even if the platform is not valid
|
|
1168
918
|
await platform.onShutdown?.();
|
|
1169
919
|
throw new Error(`Plugin ${plugin.name} does not export a valid MatterbridgeAccessoryPlatform or MatterbridgeDynamicPlatform`);
|
|
1170
920
|
}
|
|
@@ -1173,7 +923,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1173
923
|
platform.config = config;
|
|
1174
924
|
platform.version = packageJson.version;
|
|
1175
925
|
platform.isLoaded = true;
|
|
1176
|
-
// @ts-expect-error - setMatterNode is intentionally private
|
|
1177
926
|
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));
|
|
1178
927
|
plugin.name = packageJson.name;
|
|
1179
928
|
plugin.description = packageJson.description ?? 'No description';
|
|
@@ -1187,7 +936,7 @@ export class PluginManager extends EventEmitter {
|
|
|
1187
936
|
plugin.platform = platform;
|
|
1188
937
|
plugin.loaded = true;
|
|
1189
938
|
plugin.registeredDevices = 0;
|
|
1190
|
-
await this.saveToStorage();
|
|
939
|
+
await this.saveToStorage();
|
|
1191
940
|
this.log.notice(`Loaded plugin ${plg}${plugin.name}${nt} type ${typ}${platform.type}${nt} (entrypoint ${UNDERLINE}${pluginEntry}${UNDERLINEOFF})`);
|
|
1192
941
|
this.emit('loaded', plugin.name);
|
|
1193
942
|
if (start)
|
|
@@ -1207,14 +956,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1207
956
|
}
|
|
1208
957
|
return undefined;
|
|
1209
958
|
}
|
|
1210
|
-
/**
|
|
1211
|
-
* Starts a plugin.
|
|
1212
|
-
*
|
|
1213
|
-
* @param {Plugin | PluginName} plugin - The plugin to start.
|
|
1214
|
-
* @param {string} [message] - Optional message to pass to the plugin's onStart method.
|
|
1215
|
-
* @param {boolean} [configure] - Indicates whether to configure the plugin after starting (default false).
|
|
1216
|
-
* @returns {Promise<Plugin | undefined>} A promise that resolves when the plugin is started successfully, or rejects with an error if starting the plugin fails.
|
|
1217
|
-
*/
|
|
1218
959
|
async start(plugin, message, configure = false) {
|
|
1219
960
|
if (typeof plugin === 'string') {
|
|
1220
961
|
const p = this._plugins.get(plugin);
|
|
@@ -1254,12 +995,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1254
995
|
}
|
|
1255
996
|
return undefined;
|
|
1256
997
|
}
|
|
1257
|
-
/**
|
|
1258
|
-
* Configures a plugin.
|
|
1259
|
-
*
|
|
1260
|
-
* @param {Plugin | PluginName} plugin - The plugin to configure.
|
|
1261
|
-
* @returns {Promise<Plugin | undefined>} A promise that resolves when the plugin is configured successfully, or rejects with an error if configuration fails.
|
|
1262
|
-
*/
|
|
1263
998
|
async configure(plugin) {
|
|
1264
999
|
if (typeof plugin === 'string') {
|
|
1265
1000
|
const p = this._plugins.get(plugin);
|
|
@@ -1300,18 +1035,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1300
1035
|
}
|
|
1301
1036
|
return undefined;
|
|
1302
1037
|
}
|
|
1303
|
-
/**
|
|
1304
|
-
* Shuts down a plugin.
|
|
1305
|
-
*
|
|
1306
|
-
* This method shuts down a plugin by calling its `onShutdown` method and resetting its state.
|
|
1307
|
-
* It logs the shutdown process and optionally removes all devices associated with the plugin.
|
|
1308
|
-
*
|
|
1309
|
-
* @param {Plugin | PluginName} plugin - The plugin to shut down.
|
|
1310
|
-
* @param {string} [reason] - The reason for shutting down the plugin.
|
|
1311
|
-
* @param {boolean} [removeAllDevices] - Whether to remove all devices associated with the plugin.
|
|
1312
|
-
* @param {boolean} [force] - Whether to force the shutdown even if the plugin is not loaded or started.
|
|
1313
|
-
* @returns {Promise<Plugin | undefined>} A promise that resolves to the shut down plugin object, or undefined if the shutdown failed.
|
|
1314
|
-
*/
|
|
1315
1038
|
async shutdown(plugin, reason, removeAllDevices = false, force = false) {
|
|
1316
1039
|
if (typeof plugin === 'string') {
|
|
1317
1040
|
const p = this._plugins.get(plugin);
|
|
@@ -1368,15 +1091,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1368
1091
|
}
|
|
1369
1092
|
return undefined;
|
|
1370
1093
|
}
|
|
1371
|
-
/**
|
|
1372
|
-
* Loads the configuration for a plugin.
|
|
1373
|
-
* If the configuration file exists, it reads the file and returns the parsed JSON data.
|
|
1374
|
-
* If the configuration file does not exist, it creates a new file with default configuration and returns it.
|
|
1375
|
-
* If any error occurs during file access or creation, it logs an error and return un empty config.
|
|
1376
|
-
*
|
|
1377
|
-
* @param {Plugin} plugin - The plugin for which to load the configuration.
|
|
1378
|
-
* @returns {Promise<PlatformConfig>} A promise that resolves to the loaded or created configuration.
|
|
1379
|
-
*/
|
|
1380
1094
|
async loadConfig(plugin) {
|
|
1381
1095
|
const { default: path } = await import('node:path');
|
|
1382
1096
|
const { promises } = await import('node:fs');
|
|
@@ -1387,8 +1101,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1387
1101
|
const data = await promises.readFile(configFile, 'utf8');
|
|
1388
1102
|
const config = JSON.parse(data);
|
|
1389
1103
|
this.log.debug(`Loaded config file ${configFile} for plugin ${plg}${plugin.name}${db}.`);
|
|
1390
|
-
// this.log.debug(`Loaded config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
|
|
1391
|
-
// The first time a plugin is added to the system, the config file is created with the plugin name and type "AnyPlatform".
|
|
1392
1104
|
config.name = plugin.name;
|
|
1393
1105
|
config.type = plugin.type;
|
|
1394
1106
|
if (config.debug === undefined)
|
|
@@ -1415,7 +1127,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1415
1127
|
try {
|
|
1416
1128
|
await promises.writeFile(configFile, JSON.stringify(config, null, 2), 'utf8');
|
|
1417
1129
|
this.log.debug(`Created config file ${configFile} for plugin ${plg}${plugin.name}${db}.`);
|
|
1418
|
-
// this.log.debug(`Created config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
|
|
1419
1130
|
return config;
|
|
1420
1131
|
}
|
|
1421
1132
|
catch (err) {
|
|
@@ -1429,19 +1140,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1429
1140
|
}
|
|
1430
1141
|
}
|
|
1431
1142
|
}
|
|
1432
|
-
/**
|
|
1433
|
-
* Saves the configuration of a plugin to a file.
|
|
1434
|
-
*
|
|
1435
|
-
* This method saves the configuration of the specified plugin to a JSON file in the matterbridge directory.
|
|
1436
|
-
* If the plugin's configuration is not found, it logs an error and rejects the promise. If the configuration
|
|
1437
|
-
* is successfully saved, it logs a debug message. If an error occurs during the file write operation, it logs
|
|
1438
|
-
* the error and rejects the promise.
|
|
1439
|
-
*
|
|
1440
|
-
* @param {Plugin} plugin - The plugin whose configuration is to be saved.
|
|
1441
|
-
* @param {boolean} [restartRequired] - Indicates whether a restart is required after saving the configuration.
|
|
1442
|
-
* @returns {Promise<void>} A promise that resolves when the configuration is successfully saved, or rejects if an error occurs.
|
|
1443
|
-
* @throws {Error} If the plugin's configuration is not found.
|
|
1444
|
-
*/
|
|
1445
1143
|
async saveConfigFromPlugin(plugin, restartRequired = false) {
|
|
1446
1144
|
const { default: path } = await import('node:path');
|
|
1447
1145
|
const { promises } = await import('node:fs');
|
|
@@ -1456,7 +1154,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1456
1154
|
if (restartRequired)
|
|
1457
1155
|
plugin.restartRequired = true;
|
|
1458
1156
|
this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}`);
|
|
1459
|
-
// this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, plugin.platform.config);
|
|
1460
1157
|
return Promise.resolve();
|
|
1461
1158
|
}
|
|
1462
1159
|
catch (err) {
|
|
@@ -1464,20 +1161,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1464
1161
|
return Promise.reject(err);
|
|
1465
1162
|
}
|
|
1466
1163
|
}
|
|
1467
|
-
/**
|
|
1468
|
-
* Saves the configuration of a plugin from a JSON object to a file.
|
|
1469
|
-
*
|
|
1470
|
-
* This method saves the provided configuration of the specified plugin to a JSON file in the matterbridge directory.
|
|
1471
|
-
* It first checks if the configuration data is valid by ensuring it contains the correct name and type, and matches
|
|
1472
|
-
* the plugin's name. If the configuration data is invalid, it logs an error and returns. If the configuration is
|
|
1473
|
-
* successfully saved, it updates the plugin's `configJson` property and logs a debug message. If an error occurs
|
|
1474
|
-
* during the file write operation, it logs the error and returns.
|
|
1475
|
-
*
|
|
1476
|
-
* @param {Plugin} plugin - The plugin whose configuration is to be saved.
|
|
1477
|
-
* @param {PlatformConfig} config - The configuration data to be saved.
|
|
1478
|
-
* @param {boolean} [restartRequired] - Indicates whether a restart is required after saving the configuration.
|
|
1479
|
-
* @returns {Promise<void>} A promise that resolves when the configuration is successfully saved, or returns if an error occurs.
|
|
1480
|
-
*/
|
|
1481
1164
|
async saveConfigFromJson(plugin, config, restartRequired = false) {
|
|
1482
1165
|
const { default: path } = await import('node:path');
|
|
1483
1166
|
const { promises } = await import('node:fs');
|
|
@@ -1496,23 +1179,12 @@ export class PluginManager extends EventEmitter {
|
|
|
1496
1179
|
plugin.platform.onConfigChanged(config).catch((err) => this.log.error(`Error calling onConfigChanged for plugin ${plg}${plugin.name}${er}: ${err}`));
|
|
1497
1180
|
}
|
|
1498
1181
|
this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}`);
|
|
1499
|
-
// this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
|
|
1500
1182
|
}
|
|
1501
1183
|
catch (err) {
|
|
1502
1184
|
logError(this.log, `Error saving config file ${configFile} for plugin ${plg}${plugin.name}${er}`, err);
|
|
1503
1185
|
return;
|
|
1504
1186
|
}
|
|
1505
1187
|
}
|
|
1506
|
-
/**
|
|
1507
|
-
* Loads the schema for a plugin.
|
|
1508
|
-
*
|
|
1509
|
-
* This method attempts to load the schema file for the specified plugin. If the schema file is found,
|
|
1510
|
-
* it reads and parses the file, updates the schema's title and description, and logs the process.
|
|
1511
|
-
* If the schema file is not found, it logs the event and loads a default schema for the plugin.
|
|
1512
|
-
*
|
|
1513
|
-
* @param {Plugin} plugin - The plugin whose schema is to be loaded.
|
|
1514
|
-
* @returns {Promise<PlatformSchema>} A promise that resolves to the loaded schema object, or the default schema if the schema file is not found.
|
|
1515
|
-
*/
|
|
1516
1188
|
async loadSchema(plugin) {
|
|
1517
1189
|
const { promises } = await import('node:fs');
|
|
1518
1190
|
const schemaFile = plugin.path.replace('package.json', `${plugin.name}.schema.json`);
|
|
@@ -1523,7 +1195,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1523
1195
|
schema.title = plugin.description;
|
|
1524
1196
|
schema.description = plugin.name + ' v. ' + plugin.version + ' by ' + plugin.author;
|
|
1525
1197
|
this.log.debug(`Loaded schema file ${schemaFile} for plugin ${plg}${plugin.name}${db}.`);
|
|
1526
|
-
// this.log.debug(`Loaded schema file ${schemaFile} for plugin ${plg}${plugin.name}${db}.\nSchema:${rs}\n`, schema);
|
|
1527
1198
|
return schema;
|
|
1528
1199
|
}
|
|
1529
1200
|
catch (_err) {
|
|
@@ -1531,16 +1202,6 @@ export class PluginManager extends EventEmitter {
|
|
|
1531
1202
|
return this.getDefaultSchema(plugin);
|
|
1532
1203
|
}
|
|
1533
1204
|
}
|
|
1534
|
-
/**
|
|
1535
|
-
* Returns the default schema for a plugin.
|
|
1536
|
-
*
|
|
1537
|
-
* This method generates a default schema object for the specified plugin. The schema includes
|
|
1538
|
-
* metadata such as the plugin's title, description, version, and author. It also defines the
|
|
1539
|
-
* properties of the schema, including the plugin's name, type, debug flag, and unregisterOnShutdown flag.
|
|
1540
|
-
*
|
|
1541
|
-
* @param {Plugin} plugin - The plugin for which the default schema is to be generated.
|
|
1542
|
-
* @returns {PlatformSchema} The default schema object for the plugin.
|
|
1543
|
-
*/
|
|
1544
1205
|
getDefaultSchema(plugin) {
|
|
1545
1206
|
return {
|
|
1546
1207
|
title: plugin.description,
|
|
@@ -1571,4 +1232,3 @@ export class PluginManager extends EventEmitter {
|
|
|
1571
1232
|
};
|
|
1572
1233
|
}
|
|
1573
1234
|
}
|
|
1574
|
-
//# sourceMappingURL=pluginManager.js.map
|