matterbridge 1.6.5 → 1.6.6-dev.2
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 +11 -0
- package/dist/cli.js +0 -26
- package/dist/cluster/export.js +0 -2
- package/dist/defaultConfigSchema.js +0 -23
- package/dist/deviceManager.js +1 -26
- package/dist/index.js +0 -30
- package/dist/logger/export.js +0 -1
- package/dist/matter/export.js +0 -1
- package/dist/matterbridge.js +62 -702
- package/dist/matterbridgeAccessoryPlatform.js +0 -33
- package/dist/matterbridgeBehaviors.js +1 -29
- package/dist/matterbridgeDevice.js +39 -933
- package/dist/matterbridgeDeviceTypes.js +21 -41
- package/dist/matterbridgeDynamicPlatform.js +0 -33
- package/dist/matterbridgeEdge.js +0 -525
- package/dist/matterbridgeEndpoint.js +61 -1027
- package/dist/matterbridgePlatform.js +3 -74
- package/dist/matterbridgeTypes.js +0 -24
- package/dist/matterbridgeWebsocket.js +0 -45
- package/dist/pluginManager.js +3 -237
- package/dist/storage/export.js +0 -1
- package/dist/utils/colorUtils.js +2 -78
- package/dist/utils/export.js +0 -1
- package/dist/utils/utils.js +7 -252
- package/npm-shrinkwrap.json +12 -15
- package/package.json +2 -2
- package/dist/cli.d.ts +0 -25
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/cluster/export.d.ts +0 -2
- package/dist/cluster/export.d.ts.map +0 -1
- package/dist/cluster/export.js.map +0 -1
- package/dist/defaultConfigSchema.d.ts +0 -27
- package/dist/defaultConfigSchema.d.ts.map +0 -1
- package/dist/defaultConfigSchema.js.map +0 -1
- package/dist/deviceManager.d.ts +0 -46
- package/dist/deviceManager.d.ts.map +0 -1
- package/dist/deviceManager.js.map +0 -1
- package/dist/index.d.ts +0 -40
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/logger/export.d.ts +0 -2
- package/dist/logger/export.d.ts.map +0 -1
- package/dist/logger/export.js.map +0 -1
- package/dist/matter/export.d.ts +0 -5
- package/dist/matter/export.d.ts.map +0 -1
- package/dist/matter/export.js.map +0 -1
- package/dist/matterbridge.d.ts +0 -466
- package/dist/matterbridge.d.ts.map +0 -1
- package/dist/matterbridge.js.map +0 -1
- package/dist/matterbridgeAccessoryPlatform.d.ts +0 -39
- package/dist/matterbridgeAccessoryPlatform.d.ts.map +0 -1
- package/dist/matterbridgeAccessoryPlatform.js.map +0 -1
- package/dist/matterbridgeBehaviors.d.ts +0 -934
- package/dist/matterbridgeBehaviors.d.ts.map +0 -1
- package/dist/matterbridgeBehaviors.js.map +0 -1
- package/dist/matterbridgeDevice.d.ts +0 -6504
- package/dist/matterbridgeDevice.d.ts.map +0 -1
- package/dist/matterbridgeDevice.js.map +0 -1
- package/dist/matterbridgeDeviceTypes.d.ts +0 -65
- package/dist/matterbridgeDeviceTypes.d.ts.map +0 -1
- package/dist/matterbridgeDeviceTypes.js.map +0 -1
- package/dist/matterbridgeDynamicPlatform.d.ts +0 -39
- package/dist/matterbridgeDynamicPlatform.d.ts.map +0 -1
- package/dist/matterbridgeDynamicPlatform.js.map +0 -1
- package/dist/matterbridgeEdge.d.ts +0 -89
- package/dist/matterbridgeEdge.d.ts.map +0 -1
- package/dist/matterbridgeEdge.js.map +0 -1
- package/dist/matterbridgeEndpoint.d.ts +0 -8529
- package/dist/matterbridgeEndpoint.d.ts.map +0 -1
- package/dist/matterbridgeEndpoint.js.map +0 -1
- package/dist/matterbridgePlatform.d.ts +0 -96
- package/dist/matterbridgePlatform.d.ts.map +0 -1
- package/dist/matterbridgePlatform.js.map +0 -1
- package/dist/matterbridgeTypes.d.ts +0 -147
- package/dist/matterbridgeTypes.d.ts.map +0 -1
- package/dist/matterbridgeTypes.js.map +0 -1
- package/dist/matterbridgeWebsocket.d.ts +0 -49
- package/dist/matterbridgeWebsocket.d.ts.map +0 -1
- package/dist/matterbridgeWebsocket.js.map +0 -1
- package/dist/pluginManager.d.ts +0 -238
- package/dist/pluginManager.d.ts.map +0 -1
- package/dist/pluginManager.js.map +0 -1
- package/dist/storage/export.d.ts +0 -2
- package/dist/storage/export.d.ts.map +0 -1
- package/dist/storage/export.js.map +0 -1
- package/dist/utils/colorUtils.d.ts +0 -61
- package/dist/utils/colorUtils.d.ts.map +0 -1
- package/dist/utils/colorUtils.js.map +0 -1
- package/dist/utils/export.d.ts +0 -3
- package/dist/utils/export.d.ts.map +0 -1
- package/dist/utils/export.js.map +0 -1
- package/dist/utils/utils.d.ts +0 -221
- package/dist/utils/utils.d.ts.map +0 -1
- package/dist/utils/utils.js.map +0 -1
package/dist/pluginManager.js
CHANGED
|
@@ -1,29 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file contains the Plugins class.
|
|
3
|
-
*
|
|
4
|
-
* @file plugins.ts
|
|
5
|
-
* @author Luca Liguori
|
|
6
|
-
* @date 2024-07-14
|
|
7
|
-
* @version 1.1.0
|
|
8
|
-
*
|
|
9
|
-
* Copyright 2024, 2025, 2026 Luca Liguori.
|
|
10
|
-
*
|
|
11
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
|
-
* you may not use this file except in compliance with the License.
|
|
13
|
-
* You may obtain a copy of the License at
|
|
14
|
-
*
|
|
15
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
16
|
-
*
|
|
17
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
18
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
19
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20
|
-
* See the License for the specific language governing permissions and
|
|
21
|
-
* limitations under the License. *
|
|
22
|
-
*/
|
|
23
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
24
|
-
// NodeStorage and AnsiLogger modules
|
|
25
1
|
import { AnsiLogger, BLUE, db, er, nf, nt, rs, UNDERLINE, UNDERLINEOFF, wr } from 'node-ansi-logger';
|
|
26
|
-
// Node.js modules
|
|
27
2
|
import path from 'path';
|
|
28
3
|
import { promises as fs } from 'fs';
|
|
29
4
|
import { pathToFileURL } from 'url';
|
|
@@ -37,9 +12,8 @@ export class PluginManager {
|
|
|
37
12
|
log;
|
|
38
13
|
constructor(matterbridge) {
|
|
39
14
|
this.matterbridge = matterbridge;
|
|
40
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
15
|
this.nodeContext = matterbridge.nodeContext;
|
|
42
|
-
this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4
|
|
16
|
+
this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4, logLevel: matterbridge.log.logLevel });
|
|
43
17
|
this.log.debug('Matterbridge plugin manager starting...');
|
|
44
18
|
}
|
|
45
19
|
get length() {
|
|
@@ -74,7 +48,6 @@ export class PluginManager {
|
|
|
74
48
|
}
|
|
75
49
|
catch (error) {
|
|
76
50
|
this.log.error(`Error processing forEach plugin ${plg}${plugin.name}${er}:`, error);
|
|
77
|
-
// throw error;
|
|
78
51
|
}
|
|
79
52
|
});
|
|
80
53
|
await Promise.all(tasks);
|
|
@@ -85,31 +58,13 @@ export class PluginManager {
|
|
|
85
58
|
set logLevel(logLevel) {
|
|
86
59
|
this.log.logLevel = logLevel;
|
|
87
60
|
}
|
|
88
|
-
/**
|
|
89
|
-
* Loads registered plugins from storage.
|
|
90
|
-
*
|
|
91
|
-
* This method retrieves an array of registered plugins from the storage and converts it
|
|
92
|
-
* into a map where the plugin names are the keys and the plugin objects are the values.
|
|
93
|
-
*
|
|
94
|
-
* @returns {Promise<RegisteredPlugin[]>} A promise that resolves to an array of registered plugins.
|
|
95
|
-
*/
|
|
96
61
|
async loadFromStorage() {
|
|
97
|
-
// Load the array from storage and convert it to a map
|
|
98
62
|
const pluginsArray = await this.nodeContext.get('plugins', []);
|
|
99
63
|
for (const plugin of pluginsArray)
|
|
100
64
|
this._plugins.set(plugin.name, plugin);
|
|
101
65
|
return pluginsArray;
|
|
102
66
|
}
|
|
103
|
-
/**
|
|
104
|
-
* Loads registered plugins from storage.
|
|
105
|
-
*
|
|
106
|
-
* This method retrieves an array of registered plugins from the storage and converts it
|
|
107
|
-
* into a map where the plugin names are the keys and the plugin objects are the values.
|
|
108
|
-
*
|
|
109
|
-
* @returns {Promise<RegisteredPlugin[]>} A promise that resolves to an array of registered plugins.
|
|
110
|
-
*/
|
|
111
67
|
async saveToStorage() {
|
|
112
|
-
// Convert the map to an array
|
|
113
68
|
const plugins = [];
|
|
114
69
|
const pluginArrayFromMap = Array.from(this._plugins.values());
|
|
115
70
|
for (const plugin of pluginArrayFromMap) {
|
|
@@ -129,18 +84,11 @@ export class PluginManager {
|
|
|
129
84
|
this.log.debug(`Saved ${BLUE}${plugins.length}${db} plugins to storage`);
|
|
130
85
|
return plugins.length;
|
|
131
86
|
}
|
|
132
|
-
/**
|
|
133
|
-
* Resolves the name of a plugin by loading and parsing its package.json file.
|
|
134
|
-
* @param pluginPath - The path to the plugin or the path to the plugin's package.json file.
|
|
135
|
-
* @returns The path to the resolved package.json file, or null if the package.json file is not found or does not contain a name.
|
|
136
|
-
*/
|
|
137
87
|
async resolve(pluginPath) {
|
|
138
88
|
if (!pluginPath.endsWith('package.json'))
|
|
139
89
|
pluginPath = path.join(pluginPath, 'package.json');
|
|
140
|
-
// Resolve the package.json of the plugin
|
|
141
90
|
let packageJsonPath = path.resolve(pluginPath);
|
|
142
91
|
this.log.debug(`Resolving plugin path ${plg}${packageJsonPath}${db}`);
|
|
143
|
-
// Check if the package.json file exists
|
|
144
92
|
try {
|
|
145
93
|
await fs.access(packageJsonPath);
|
|
146
94
|
}
|
|
@@ -150,13 +98,11 @@ export class PluginManager {
|
|
|
150
98
|
this.log.debug(`Trying at ${plg}${packageJsonPath}${db}`);
|
|
151
99
|
}
|
|
152
100
|
try {
|
|
153
|
-
// Load the package.json of the plugin
|
|
154
101
|
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
|
|
155
102
|
if (!packageJson.name) {
|
|
156
103
|
this.log.error(`Package.json name not found at ${packageJsonPath}`);
|
|
157
104
|
return null;
|
|
158
105
|
}
|
|
159
|
-
// Check for main issues
|
|
160
106
|
if (!packageJson.type || packageJson.type !== 'module') {
|
|
161
107
|
this.log.error(`Plugin at ${packageJsonPath} is not a module`);
|
|
162
108
|
return null;
|
|
@@ -165,11 +111,6 @@ export class PluginManager {
|
|
|
165
111
|
this.log.error(`Plugin at ${packageJsonPath} has no main entrypoint in package.json`);
|
|
166
112
|
return null;
|
|
167
113
|
}
|
|
168
|
-
if (!packageJson.types) {
|
|
169
|
-
this.log.error(`Plugin at ${packageJsonPath} has no types in package.json`);
|
|
170
|
-
return null;
|
|
171
|
-
}
|
|
172
|
-
// Check for @project-chip packages in dependencies and devDependencies
|
|
173
114
|
const checkForProjectChipPackages = (dependencies) => {
|
|
174
115
|
return Object.keys(dependencies).filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matter'));
|
|
175
116
|
};
|
|
@@ -191,7 +132,6 @@ export class PluginManager {
|
|
|
191
132
|
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
192
133
|
return null;
|
|
193
134
|
}
|
|
194
|
-
// Check for matterbridge package in dependencies and devDependencies
|
|
195
135
|
const checkForMatterbridgePackage = (dependencies) => {
|
|
196
136
|
return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
|
|
197
137
|
};
|
|
@@ -221,11 +161,6 @@ export class PluginManager {
|
|
|
221
161
|
return null;
|
|
222
162
|
}
|
|
223
163
|
}
|
|
224
|
-
/**
|
|
225
|
-
* Loads and parse the plugin package.json and returns it.
|
|
226
|
-
* @param plugin - The plugin to load the package from.
|
|
227
|
-
* @returns A Promise that resolves to the package.json object or undefined if the package.json could not be loaded.
|
|
228
|
-
*/
|
|
229
164
|
async parse(plugin) {
|
|
230
165
|
this.log.debug(`Parsing package.json of plugin ${plg}${plugin.name}${db}`);
|
|
231
166
|
try {
|
|
@@ -242,8 +177,6 @@ export class PluginManager {
|
|
|
242
177
|
this.log.error(`Plugin ${plg}${plugin.name}${er} is not a module`);
|
|
243
178
|
if (!packageJson.main)
|
|
244
179
|
this.log.error(`Plugin ${plg}${plugin.name}${er} has no main entrypoint in package.json`);
|
|
245
|
-
if (!packageJson.types)
|
|
246
|
-
this.log.error(`Plugin ${plg}${plugin.name}${er} has no types in package.json`);
|
|
247
180
|
plugin.name = packageJson.name || 'Unknown name';
|
|
248
181
|
plugin.version = packageJson.version || '1.0.0';
|
|
249
182
|
plugin.description = packageJson.description || 'Unknown description';
|
|
@@ -252,7 +185,6 @@ export class PluginManager {
|
|
|
252
185
|
this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no path`);
|
|
253
186
|
if (!plugin.type)
|
|
254
187
|
this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no type`);
|
|
255
|
-
// Check for @project-chip packages in dependencies and devDependencies
|
|
256
188
|
const checkForProjectChipPackages = (dependencies) => {
|
|
257
189
|
return Object.keys(dependencies).filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matter'));
|
|
258
190
|
};
|
|
@@ -274,7 +206,6 @@ export class PluginManager {
|
|
|
274
206
|
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
275
207
|
return null;
|
|
276
208
|
}
|
|
277
|
-
// Check for matterbridge package in dependencies and devDependencies
|
|
278
209
|
const checkForMatterbridgePackage = (dependencies) => {
|
|
279
210
|
return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
|
|
280
211
|
};
|
|
@@ -296,7 +227,6 @@ export class PluginManager {
|
|
|
296
227
|
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
297
228
|
return null;
|
|
298
229
|
}
|
|
299
|
-
// await this.saveToStorage(); // No need to save the plugin to storage
|
|
300
230
|
return packageJson;
|
|
301
231
|
}
|
|
302
232
|
catch (err) {
|
|
@@ -305,16 +235,6 @@ export class PluginManager {
|
|
|
305
235
|
return null;
|
|
306
236
|
}
|
|
307
237
|
}
|
|
308
|
-
/**
|
|
309
|
-
* Enables a plugin by its name or path.
|
|
310
|
-
*
|
|
311
|
-
* This method enables a plugin by setting its `enabled` property to `true` and saving the updated
|
|
312
|
-
* plugin information to storage. It first checks if the plugin is already registered in the `_plugins` map.
|
|
313
|
-
* If not, it attempts to resolve the plugin's `package.json` file to retrieve its name and enable it.
|
|
314
|
-
*
|
|
315
|
-
* @param {string} nameOrPath - The name or path of the plugin to enable.
|
|
316
|
-
* @returns {Promise<RegisteredPlugin | null>} A promise that resolves to the enabled plugin object, or null if the plugin could not be enabled.
|
|
317
|
-
*/
|
|
318
238
|
async enable(nameOrPath) {
|
|
319
239
|
if (!nameOrPath || nameOrPath === '')
|
|
320
240
|
return null;
|
|
@@ -347,16 +267,6 @@ export class PluginManager {
|
|
|
347
267
|
return null;
|
|
348
268
|
}
|
|
349
269
|
}
|
|
350
|
-
/**
|
|
351
|
-
* Enables a plugin by its name or path.
|
|
352
|
-
*
|
|
353
|
-
* This method enables a plugin by setting its `enabled` property to `true` and saving the updated
|
|
354
|
-
* plugin information to storage. It first checks if the plugin is already registered in the `_plugins` map.
|
|
355
|
-
* If not, it attempts to resolve the plugin's `package.json` file to retrieve its name and enable it.
|
|
356
|
-
*
|
|
357
|
-
* @param {string} nameOrPath - The name or path of the plugin to enable.
|
|
358
|
-
* @returns {Promise<RegisteredPlugin | null>} A promise that resolves to the enabled plugin object, or null if the plugin could not be enabled.
|
|
359
|
-
*/
|
|
360
270
|
async disable(nameOrPath) {
|
|
361
271
|
if (!nameOrPath || nameOrPath === '')
|
|
362
272
|
return null;
|
|
@@ -389,16 +299,6 @@ export class PluginManager {
|
|
|
389
299
|
return null;
|
|
390
300
|
}
|
|
391
301
|
}
|
|
392
|
-
/**
|
|
393
|
-
* Removes a plugin by its name or path.
|
|
394
|
-
*
|
|
395
|
-
* This method removes a plugin from the `_plugins` map and saves the updated plugin information to storage.
|
|
396
|
-
* It first checks if the plugin is already registered in the `_plugins` map. If not, it attempts to resolve
|
|
397
|
-
* the plugin's `package.json` file to retrieve its name and remove it.
|
|
398
|
-
*
|
|
399
|
-
* @param {string} nameOrPath - The name or path of the plugin to remove.
|
|
400
|
-
* @returns {Promise<RegisteredPlugin | null>} A promise that resolves to the removed plugin object, or null if the plugin could not be removed.
|
|
401
|
-
*/
|
|
402
302
|
async remove(nameOrPath) {
|
|
403
303
|
if (!nameOrPath || nameOrPath === '')
|
|
404
304
|
return null;
|
|
@@ -431,17 +331,6 @@ export class PluginManager {
|
|
|
431
331
|
return null;
|
|
432
332
|
}
|
|
433
333
|
}
|
|
434
|
-
/**
|
|
435
|
-
* Adds a plugin by its name or path.
|
|
436
|
-
*
|
|
437
|
-
* This method adds a plugin to the `_plugins` map and saves the updated plugin information to storage.
|
|
438
|
-
* It first resolves the plugin's `package.json` file to retrieve its details. If the plugin is already
|
|
439
|
-
* registered, it logs an info message and returns null. Otherwise, it registers the plugin, enables it,
|
|
440
|
-
* and saves the updated plugin information to storage.
|
|
441
|
-
*
|
|
442
|
-
* @param {string} nameOrPath - The name or path of the plugin to add.
|
|
443
|
-
* @returns {Promise<RegisteredPlugin | null>} A promise that resolves to the added plugin object, or null if the plugin could not be added.
|
|
444
|
-
*/
|
|
445
334
|
async add(nameOrPath) {
|
|
446
335
|
if (!nameOrPath || nameOrPath === '')
|
|
447
336
|
return null;
|
|
@@ -467,15 +356,6 @@ export class PluginManager {
|
|
|
467
356
|
return null;
|
|
468
357
|
}
|
|
469
358
|
}
|
|
470
|
-
/**
|
|
471
|
-
* Installs a plugin by its name.
|
|
472
|
-
*
|
|
473
|
-
* This method first uninstalls any existing version of the plugin, then installs the plugin globally using npm.
|
|
474
|
-
* It logs the installation process and retrieves the installed version of the plugin.
|
|
475
|
-
*
|
|
476
|
-
* @param {string} name - The name of the plugin to install.
|
|
477
|
-
* @returns {Promise<string | undefined>} A promise that resolves to the installed version of the plugin, or undefined if the installation failed.
|
|
478
|
-
*/
|
|
479
359
|
async install(name) {
|
|
480
360
|
await this.uninstall(name);
|
|
481
361
|
this.log.info(`Installing plugin ${plg}${name}${nf}`);
|
|
@@ -489,13 +369,11 @@ export class PluginManager {
|
|
|
489
369
|
else {
|
|
490
370
|
this.log.info(`Installed plugin ${plg}${name}${nf}`);
|
|
491
371
|
this.log.debug(`Installed plugin ${plg}${name}${db}: ${stdout}`);
|
|
492
|
-
// Get the installed version
|
|
493
372
|
exec(`npm list -g ${name} --depth=0`, (listError, listStdout, listStderr) => {
|
|
494
373
|
if (listError) {
|
|
495
374
|
this.log.error(`List error: ${listError}`);
|
|
496
375
|
resolve(undefined);
|
|
497
376
|
}
|
|
498
|
-
// Clean the output to get only the package name and version
|
|
499
377
|
const lines = listStdout.split('\n');
|
|
500
378
|
const versionLine = lines.find((line) => line.includes(`${name}@`));
|
|
501
379
|
if (versionLine) {
|
|
@@ -511,15 +389,6 @@ export class PluginManager {
|
|
|
511
389
|
});
|
|
512
390
|
});
|
|
513
391
|
}
|
|
514
|
-
/**
|
|
515
|
-
* Uninstalls a plugin by its name.
|
|
516
|
-
*
|
|
517
|
-
* This method uninstalls a globally installed plugin using npm. It logs the uninstallation process
|
|
518
|
-
* and returns the name of the uninstalled plugin if successful, or undefined if the uninstallation failed.
|
|
519
|
-
*
|
|
520
|
-
* @param {string} name - The name of the plugin to uninstall.
|
|
521
|
-
* @returns {Promise<string | undefined>} A promise that resolves to the name of the uninstalled plugin, or undefined if the uninstallation failed.
|
|
522
|
-
*/
|
|
523
392
|
async uninstall(name) {
|
|
524
393
|
this.log.info(`Uninstalling plugin ${plg}${name}${nf}`);
|
|
525
394
|
return new Promise((resolve, reject) => {
|
|
@@ -537,14 +406,6 @@ export class PluginManager {
|
|
|
537
406
|
});
|
|
538
407
|
});
|
|
539
408
|
}
|
|
540
|
-
/**
|
|
541
|
-
* Loads a plugin and returns the corresponding MatterbridgePlatform instance.
|
|
542
|
-
* @param plugin - The plugin to load.
|
|
543
|
-
* @param start - Optional flag indicating whether to start the plugin after loading. Default is false.
|
|
544
|
-
* @param message - Optional message to pass to the plugin when starting.
|
|
545
|
-
* @returns A Promise that resolves to the loaded MatterbridgePlatform instance.
|
|
546
|
-
* @throws An error if the plugin is not enabled, already loaded, or fails to load.
|
|
547
|
-
*/
|
|
548
409
|
async load(plugin, start = false, message = '', configure = false) {
|
|
549
410
|
if (!plugin.enabled) {
|
|
550
411
|
this.log.error(`Plugin ${plg}${plugin.name}${er} not enabled`);
|
|
@@ -556,19 +417,14 @@ export class PluginManager {
|
|
|
556
417
|
}
|
|
557
418
|
this.log.info(`Loading plugin ${plg}${plugin.name}${nf} type ${typ}${plugin.type}${nf}`);
|
|
558
419
|
try {
|
|
559
|
-
// Load the package.json of the plugin
|
|
560
420
|
const packageJson = JSON.parse(await fs.readFile(plugin.path, 'utf8'));
|
|
561
|
-
// Resolve the main module path relative to package.json
|
|
562
421
|
const pluginEntry = path.resolve(path.dirname(plugin.path), packageJson.main);
|
|
563
|
-
// Dynamically import the plugin
|
|
564
422
|
const pluginUrl = pathToFileURL(pluginEntry);
|
|
565
423
|
this.log.debug(`Importing plugin ${plg}${plugin.name}${db} from ${pluginUrl.href}`);
|
|
566
424
|
const pluginInstance = await import(pluginUrl.href);
|
|
567
425
|
this.log.debug(`Imported plugin ${plg}${plugin.name}${db} from ${pluginUrl.href}`);
|
|
568
|
-
// Call the default export function of the plugin, passing this MatterBridge instance, the log and the config
|
|
569
426
|
if (pluginInstance.default) {
|
|
570
427
|
const config = await this.loadConfig(plugin);
|
|
571
|
-
// 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.
|
|
572
428
|
plugin.name = packageJson.name;
|
|
573
429
|
plugin.description = packageJson.description ?? 'No description';
|
|
574
430
|
plugin.version = packageJson.version;
|
|
@@ -577,7 +433,7 @@ export class PluginManager {
|
|
|
577
433
|
plugin.schemaJson = await this.loadSchema(plugin);
|
|
578
434
|
config.name = plugin.name;
|
|
579
435
|
config.version = packageJson.version;
|
|
580
|
-
const log = new AnsiLogger({ logName: plugin.description ?? 'No description', logTimestampFormat: 4
|
|
436
|
+
const log = new AnsiLogger({ logName: plugin.description ?? 'No description', logTimestampFormat: 4, logLevel: config.debug ? "debug" : this.matterbridge.log.logLevel });
|
|
581
437
|
const platform = pluginInstance.default(this.matterbridge, log, config);
|
|
582
438
|
config.type = platform.type;
|
|
583
439
|
platform.name = packageJson.name;
|
|
@@ -594,7 +450,7 @@ export class PluginManager {
|
|
|
594
450
|
plugin.addedDevices = 0;
|
|
595
451
|
plugin.configJson = config;
|
|
596
452
|
plugin.schemaJson = await this.loadSchema(plugin);
|
|
597
|
-
await this.saveToStorage();
|
|
453
|
+
await this.saveToStorage();
|
|
598
454
|
this.log.notice(`Loaded plugin ${plg}${plugin.name}${nf} type ${typ}${platform.type}${db} (entrypoint ${UNDERLINE}${pluginEntry}${UNDERLINEOFF})`);
|
|
599
455
|
if (start)
|
|
600
456
|
await this.start(plugin, message, false);
|
|
@@ -613,14 +469,6 @@ export class PluginManager {
|
|
|
613
469
|
}
|
|
614
470
|
return undefined;
|
|
615
471
|
}
|
|
616
|
-
/**
|
|
617
|
-
* Starts a plugin.
|
|
618
|
-
*
|
|
619
|
-
* @param {RegisteredPlugin} plugin - The plugin to start.
|
|
620
|
-
* @param {string} [message] - Optional message to pass to the plugin's onStart method.
|
|
621
|
-
* @param {boolean} [configure] - Indicates whether to configure the plugin after starting (default false).
|
|
622
|
-
* @returns {Promise<RegisteredPlugin | undefined>} A promise that resolves when the plugin is started successfully, or rejects with an error if starting the plugin fails.
|
|
623
|
-
*/
|
|
624
472
|
async start(plugin, message, configure = false) {
|
|
625
473
|
if (!plugin.loaded) {
|
|
626
474
|
this.log.error(`Plugin ${plg}${plugin.name}${er} not loaded`);
|
|
@@ -650,12 +498,6 @@ export class PluginManager {
|
|
|
650
498
|
}
|
|
651
499
|
return undefined;
|
|
652
500
|
}
|
|
653
|
-
/**
|
|
654
|
-
* Configures a plugin.
|
|
655
|
-
*
|
|
656
|
-
* @param {RegisteredPlugin} plugin - The plugin to configure.
|
|
657
|
-
* @returns {Promise<void>} A promise that resolves when the plugin is configured successfully, or rejects with an error if configuration fails.
|
|
658
|
-
*/
|
|
659
501
|
async configure(plugin) {
|
|
660
502
|
if (!plugin.loaded) {
|
|
661
503
|
this.log.error(`Plugin ${plg}${plugin.name}${er} not loaded`);
|
|
@@ -678,7 +520,6 @@ export class PluginManager {
|
|
|
678
520
|
await plugin.platform.onConfigure();
|
|
679
521
|
this.log.notice(`Configured plugin ${plg}${plugin.name}${nt} type ${typ}${plugin.type}${nt}`);
|
|
680
522
|
plugin.configured = true;
|
|
681
|
-
// await this.saveConfigFromPlugin(plugin);
|
|
682
523
|
return plugin;
|
|
683
524
|
}
|
|
684
525
|
catch (err) {
|
|
@@ -687,18 +528,6 @@ export class PluginManager {
|
|
|
687
528
|
}
|
|
688
529
|
return undefined;
|
|
689
530
|
}
|
|
690
|
-
/**
|
|
691
|
-
* Shuts down a plugin.
|
|
692
|
-
*
|
|
693
|
-
* This method shuts down a plugin by calling its `onShutdown` method and resetting its state.
|
|
694
|
-
* It logs the shutdown process and optionally removes all devices associated with the plugin.
|
|
695
|
-
*
|
|
696
|
-
* @param {RegisteredPlugin} plugin - The plugin to shut down.
|
|
697
|
-
* @param {string} [reason] - The reason for shutting down the plugin.
|
|
698
|
-
* @param {boolean} [removeAllDevices=false] - Whether to remove all devices associated with the plugin.
|
|
699
|
-
* @param {boolean} [force=false] - Whether to force the shutdown even if the plugin is not loaded or started.
|
|
700
|
-
* @returns {Promise<RegisteredPlugin | undefined>} A promise that resolves to the shut down plugin object, or undefined if the shutdown failed.
|
|
701
|
-
*/
|
|
702
531
|
async shutdown(plugin, reason, removeAllDevices = false, force = false) {
|
|
703
532
|
this.log.debug(`Shutting down plugin ${plg}${plugin.name}${db}`);
|
|
704
533
|
if (!plugin.loaded) {
|
|
@@ -742,15 +571,6 @@ export class PluginManager {
|
|
|
742
571
|
}
|
|
743
572
|
return undefined;
|
|
744
573
|
}
|
|
745
|
-
/**
|
|
746
|
-
* Loads the configuration for a plugin.
|
|
747
|
-
* If the configuration file exists, it reads the file and returns the parsed JSON data.
|
|
748
|
-
* If the configuration file does not exist, it creates a new file with default configuration and returns it.
|
|
749
|
-
* If any error occurs during file access or creation, it logs an error and return un empty config.
|
|
750
|
-
*
|
|
751
|
-
* @param plugin - The plugin for which to load the configuration.
|
|
752
|
-
* @returns A promise that resolves to the loaded or created configuration.
|
|
753
|
-
*/
|
|
754
574
|
async loadConfig(plugin) {
|
|
755
575
|
const configFile = path.join(this.matterbridge.matterbridgeDirectory, `${plugin.name}.config.json`);
|
|
756
576
|
try {
|
|
@@ -758,8 +578,6 @@ export class PluginManager {
|
|
|
758
578
|
const data = await fs.readFile(configFile, 'utf8');
|
|
759
579
|
const config = JSON.parse(data);
|
|
760
580
|
this.log.debug(`Loaded config file ${configFile} for plugin ${plg}${plugin.name}${db}.`);
|
|
761
|
-
// this.log.debug(`Loaded config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
|
|
762
|
-
// The first time a plugin is added to the system, the config file is created with the plugin name and type "AnyPlatform".
|
|
763
581
|
config.name = plugin.name;
|
|
764
582
|
config.type = plugin.type;
|
|
765
583
|
if (config.debug === undefined)
|
|
@@ -784,7 +602,6 @@ export class PluginManager {
|
|
|
784
602
|
try {
|
|
785
603
|
await fs.writeFile(configFile, JSON.stringify(config, null, 2), 'utf8');
|
|
786
604
|
this.log.debug(`Created config file ${configFile} for plugin ${plg}${plugin.name}${db}.`);
|
|
787
|
-
// this.log.debug(`Created config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
|
|
788
605
|
return config;
|
|
789
606
|
}
|
|
790
607
|
catch (err) {
|
|
@@ -801,18 +618,6 @@ export class PluginManager {
|
|
|
801
618
|
return { name: plugin.name, type: plugin.type, debug: false, unregisterOnShutdown: false };
|
|
802
619
|
}
|
|
803
620
|
}
|
|
804
|
-
/**
|
|
805
|
-
* Saves the configuration of a plugin to a file.
|
|
806
|
-
*
|
|
807
|
-
* This method saves the configuration of the specified plugin to a JSON file in the matterbridge directory.
|
|
808
|
-
* If the plugin's configuration is not found, it logs an error and rejects the promise. If the configuration
|
|
809
|
-
* is successfully saved, it logs a debug message. If an error occurs during the file write operation, it logs
|
|
810
|
-
* the error and rejects the promise.
|
|
811
|
-
*
|
|
812
|
-
* @param {RegisteredPlugin} plugin - The plugin whose configuration is to be saved.
|
|
813
|
-
* @returns {Promise<void>} A promise that resolves when the configuration is successfully saved, or rejects if an error occurs.
|
|
814
|
-
* @throws {Error} If the plugin's configuration is not found.
|
|
815
|
-
*/
|
|
816
621
|
async saveConfigFromPlugin(plugin) {
|
|
817
622
|
if (!plugin.platform?.config) {
|
|
818
623
|
this.log.error(`Error saving config file for plugin ${plg}${plugin.name}${er}: config not found`);
|
|
@@ -822,7 +627,6 @@ export class PluginManager {
|
|
|
822
627
|
try {
|
|
823
628
|
await fs.writeFile(configFile, JSON.stringify(plugin.platform.config, null, 2), 'utf8');
|
|
824
629
|
this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}`);
|
|
825
|
-
// this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, plugin.platform.config);
|
|
826
630
|
return Promise.resolve();
|
|
827
631
|
}
|
|
828
632
|
catch (err) {
|
|
@@ -830,19 +634,6 @@ export class PluginManager {
|
|
|
830
634
|
return Promise.reject(err);
|
|
831
635
|
}
|
|
832
636
|
}
|
|
833
|
-
/**
|
|
834
|
-
* Saves the configuration of a plugin from a JSON object to a file.
|
|
835
|
-
*
|
|
836
|
-
* This method saves the provided configuration of the specified plugin to a JSON file in the matterbridge directory.
|
|
837
|
-
* It first checks if the configuration data is valid by ensuring it contains the correct name and type, and matches
|
|
838
|
-
* the plugin's name. If the configuration data is invalid, it logs an error and returns. If the configuration is
|
|
839
|
-
* successfully saved, it updates the plugin's `configJson` property and logs a debug message. If an error occurs
|
|
840
|
-
* during the file write operation, it logs the error and returns.
|
|
841
|
-
*
|
|
842
|
-
* @param {RegisteredPlugin} plugin - The plugin whose configuration is to be saved.
|
|
843
|
-
* @param {PlatformConfig} config - The configuration data to be saved.
|
|
844
|
-
* @returns {Promise<void>} A promise that resolves when the configuration is successfully saved, or returns if an error occurs.
|
|
845
|
-
*/
|
|
846
637
|
async saveConfigFromJson(plugin, config) {
|
|
847
638
|
if (!config.name || !config.type || config.name !== plugin.name) {
|
|
848
639
|
this.log.error(`Error saving config file for plugin ${plg}${plugin.name}${er}. Wrong config data content:${rs}\n`, config);
|
|
@@ -853,24 +644,12 @@ export class PluginManager {
|
|
|
853
644
|
await fs.writeFile(configFile, JSON.stringify(config, null, 2), 'utf8');
|
|
854
645
|
plugin.configJson = config;
|
|
855
646
|
this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}`);
|
|
856
|
-
// this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
|
|
857
647
|
}
|
|
858
648
|
catch (err) {
|
|
859
649
|
this.log.error(`Error saving config file ${configFile} for plugin ${plg}${plugin.name}${er}: ${err}`);
|
|
860
650
|
return;
|
|
861
651
|
}
|
|
862
652
|
}
|
|
863
|
-
/**
|
|
864
|
-
* Loads the schema for a plugin.
|
|
865
|
-
*
|
|
866
|
-
* This method attempts to load the schema file for the specified plugin. If the schema file is found,
|
|
867
|
-
* it reads and parses the file, updates the schema's title and description, and logs the process.
|
|
868
|
-
* It also attempts to delete any old schema file from the matterbridge directory. If the schema file
|
|
869
|
-
* is not found, it logs the event and loads a default schema for the plugin.
|
|
870
|
-
*
|
|
871
|
-
* @param {RegisteredPlugin} plugin - The plugin whose schema is to be loaded.
|
|
872
|
-
* @returns {Promise<PlatformSchema>} A promise that resolves to the loaded schema object, or the default schema if the schema file is not found.
|
|
873
|
-
*/
|
|
874
653
|
async loadSchema(plugin) {
|
|
875
654
|
let schemaFile = plugin.path.replace('package.json', `${plugin.name}.schema.json`);
|
|
876
655
|
try {
|
|
@@ -880,8 +659,6 @@ export class PluginManager {
|
|
|
880
659
|
schema.title = plugin.description;
|
|
881
660
|
schema.description = plugin.name + ' v. ' + plugin.version + ' by ' + plugin.author;
|
|
882
661
|
this.log.debug(`Loaded schema file ${schemaFile} for plugin ${plg}${plugin.name}${db}.`);
|
|
883
|
-
// this.log.debug(`Loaded schema file ${schemaFile} for plugin ${plg}${plugin.name}${db}.\nSchema:${rs}\n`, schema);
|
|
884
|
-
// Delete the schema file from old position
|
|
885
662
|
schemaFile = path.join(this.matterbridge.matterbridgeDirectory, `${plugin.name}.schema.json`);
|
|
886
663
|
try {
|
|
887
664
|
await fs.unlink(schemaFile);
|
|
@@ -897,16 +674,6 @@ export class PluginManager {
|
|
|
897
674
|
return this.getDefaultSchema(plugin);
|
|
898
675
|
}
|
|
899
676
|
}
|
|
900
|
-
/**
|
|
901
|
-
* Returns the default schema for a plugin.
|
|
902
|
-
*
|
|
903
|
-
* This method generates a default schema object for the specified plugin. The schema includes
|
|
904
|
-
* metadata such as the plugin's title, description, version, and author. It also defines the
|
|
905
|
-
* properties of the schema, including the plugin's name, type, debug flag, and unregisterOnShutdown flag.
|
|
906
|
-
*
|
|
907
|
-
* @param {RegisteredPlugin} plugin - The plugin for which the default schema is to be generated.
|
|
908
|
-
* @returns {PlatformSchema} The default schema object for the plugin.
|
|
909
|
-
*/
|
|
910
677
|
getDefaultSchema(plugin) {
|
|
911
678
|
return {
|
|
912
679
|
title: plugin.description,
|
|
@@ -937,4 +704,3 @@ export class PluginManager {
|
|
|
937
704
|
};
|
|
938
705
|
}
|
|
939
706
|
}
|
|
940
|
-
//# sourceMappingURL=pluginManager.js.map
|
package/dist/storage/export.js
CHANGED