matterbridge 2.0.0 → 2.1.0-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 +22 -1
- package/README.md +1 -1
- 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/frontend.js +57 -242
- package/dist/index.js +1 -30
- package/dist/logger/export.js +0 -1
- package/dist/matter/export.js +0 -7
- package/dist/matterbridge.js +77 -702
- package/dist/matterbridgeAccessoryPlatform.js +0 -33
- package/dist/matterbridgeBehaviors.js +33 -38
- package/dist/matterbridgeDeviceTypes.js +11 -112
- package/dist/matterbridgeDynamicPlatform.js +0 -33
- package/dist/matterbridgeEndpoint.js +970 -2524
- package/dist/matterbridgePlatform.js +3 -123
- package/dist/matterbridgeTypes.js +0 -28
- package/dist/pluginManager.js +3 -240
- package/dist/storage/export.js +0 -1
- package/dist/utils/colorUtils.js +2 -205
- package/dist/utils/export.js +0 -1
- package/dist/utils/utils.js +7 -251
- package/frontend/build/asset-manifest.json +3 -3
- package/frontend/build/index.html +1 -1
- package/frontend/build/static/js/{main.6df4ebe4.js → main.26dbf9b9.js} +3 -3
- package/frontend/build/static/js/{main.6df4ebe4.js.map → main.26dbf9b9.js.map} +1 -1
- package/npm-shrinkwrap.json +83 -68
- package/package.json +2 -4
- 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/frontend.d.ts +0 -98
- package/dist/frontend.d.ts.map +0 -1
- package/dist/frontend.js.map +0 -1
- package/dist/index.d.ts +0 -34
- 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 -10
- package/dist/matter/export.d.ts.map +0 -1
- package/dist/matter/export.js.map +0 -1
- package/dist/matterbridge.d.ts +0 -356
- 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 -963
- package/dist/matterbridgeBehaviors.d.ts.map +0 -1
- package/dist/matterbridgeBehaviors.js.map +0 -1
- package/dist/matterbridgeDeviceTypes.d.ts +0 -177
- 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/matterbridgeEndpoint.d.ts +0 -10254
- package/dist/matterbridgeEndpoint.d.ts.map +0 -1
- package/dist/matterbridgeEndpoint.js.map +0 -1
- package/dist/matterbridgeEndpointDefault.d.ts +0 -2
- package/dist/matterbridgeEndpointDefault.d.ts.map +0 -1
- package/dist/matterbridgeEndpointDefault.js +0 -159
- package/dist/matterbridgeEndpointDefault.js.map +0 -1
- package/dist/matterbridgePlatform.d.ts +0 -164
- package/dist/matterbridgePlatform.d.ts.map +0 -1
- package/dist/matterbridgePlatform.js.map +0 -1
- package/dist/matterbridgeTypes.d.ts +0 -167
- package/dist/matterbridgeTypes.d.ts.map +0 -1
- package/dist/matterbridgeTypes.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/frontend/build/static/js/{main.6df4ebe4.js.LICENSE.txt → main.26dbf9b9.js.LICENSE.txt} +0 -0
package/dist/pluginManager.js
CHANGED
|
@@ -1,28 +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
|
-
// NodeStorage and AnsiLogger modules
|
|
24
1
|
import { AnsiLogger, BLUE, db, er, nf, nt, rs, UNDERLINE, UNDERLINEOFF, wr } from './logger/export.js';
|
|
25
|
-
// Node.js modules
|
|
26
2
|
import path from 'path';
|
|
27
3
|
import { promises as fs } from 'fs';
|
|
28
4
|
import { pathToFileURL } from 'url';
|
|
@@ -36,9 +12,8 @@ export class PluginManager {
|
|
|
36
12
|
log;
|
|
37
13
|
constructor(matterbridge) {
|
|
38
14
|
this.matterbridge = matterbridge;
|
|
39
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
40
15
|
this.nodeContext = matterbridge.nodeContext;
|
|
41
|
-
this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4
|
|
16
|
+
this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4, logLevel: matterbridge.log.logLevel });
|
|
42
17
|
this.log.debug('Matterbridge plugin manager starting...');
|
|
43
18
|
}
|
|
44
19
|
get length() {
|
|
@@ -73,7 +48,6 @@ export class PluginManager {
|
|
|
73
48
|
}
|
|
74
49
|
catch (error) {
|
|
75
50
|
this.log.error(`Error processing forEach plugin ${plg}${plugin.name}${er}:`, error);
|
|
76
|
-
// throw error;
|
|
77
51
|
}
|
|
78
52
|
});
|
|
79
53
|
await Promise.all(tasks);
|
|
@@ -84,31 +58,13 @@ export class PluginManager {
|
|
|
84
58
|
set logLevel(logLevel) {
|
|
85
59
|
this.log.logLevel = logLevel;
|
|
86
60
|
}
|
|
87
|
-
/**
|
|
88
|
-
* Loads registered plugins from storage.
|
|
89
|
-
*
|
|
90
|
-
* This method retrieves an array of registered plugins from the storage and converts it
|
|
91
|
-
* into a map where the plugin names are the keys and the plugin objects are the values.
|
|
92
|
-
*
|
|
93
|
-
* @returns {Promise<RegisteredPlugin[]>} A promise that resolves to an array of registered plugins.
|
|
94
|
-
*/
|
|
95
61
|
async loadFromStorage() {
|
|
96
|
-
// Load the array from storage and convert it to a map
|
|
97
62
|
const pluginsArray = await this.nodeContext.get('plugins', []);
|
|
98
63
|
for (const plugin of pluginsArray)
|
|
99
64
|
this._plugins.set(plugin.name, plugin);
|
|
100
65
|
return pluginsArray;
|
|
101
66
|
}
|
|
102
|
-
/**
|
|
103
|
-
* Loads registered plugins from storage.
|
|
104
|
-
*
|
|
105
|
-
* This method retrieves an array of registered plugins from the storage and converts it
|
|
106
|
-
* into a map where the plugin names are the keys and the plugin objects are the values.
|
|
107
|
-
*
|
|
108
|
-
* @returns {Promise<RegisteredPlugin[]>} A promise that resolves to an array of registered plugins.
|
|
109
|
-
*/
|
|
110
67
|
async saveToStorage() {
|
|
111
|
-
// Convert the map to an array
|
|
112
68
|
const plugins = [];
|
|
113
69
|
const pluginArrayFromMap = Array.from(this._plugins.values());
|
|
114
70
|
for (const plugin of pluginArrayFromMap) {
|
|
@@ -128,18 +84,11 @@ export class PluginManager {
|
|
|
128
84
|
this.log.debug(`Saved ${BLUE}${plugins.length}${db} plugins to storage`);
|
|
129
85
|
return plugins.length;
|
|
130
86
|
}
|
|
131
|
-
/**
|
|
132
|
-
* Resolves the name of a plugin by loading and parsing its package.json file.
|
|
133
|
-
* @param pluginPath - The path to the plugin or the path to the plugin's package.json file.
|
|
134
|
-
* @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.
|
|
135
|
-
*/
|
|
136
87
|
async resolve(pluginPath) {
|
|
137
88
|
if (!pluginPath.endsWith('package.json'))
|
|
138
89
|
pluginPath = path.join(pluginPath, 'package.json');
|
|
139
|
-
// Resolve the package.json of the plugin
|
|
140
90
|
let packageJsonPath = path.resolve(pluginPath);
|
|
141
91
|
this.log.debug(`Resolving plugin path ${plg}${packageJsonPath}${db}`);
|
|
142
|
-
// Check if the package.json file exists
|
|
143
92
|
try {
|
|
144
93
|
await fs.access(packageJsonPath);
|
|
145
94
|
}
|
|
@@ -149,13 +98,11 @@ export class PluginManager {
|
|
|
149
98
|
this.log.debug(`Trying at ${plg}${packageJsonPath}${db}`);
|
|
150
99
|
}
|
|
151
100
|
try {
|
|
152
|
-
// Load the package.json of the plugin
|
|
153
101
|
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
|
|
154
102
|
if (!packageJson.name) {
|
|
155
103
|
this.log.error(`Package.json name not found at ${packageJsonPath}`);
|
|
156
104
|
return null;
|
|
157
105
|
}
|
|
158
|
-
// Check for main issues
|
|
159
106
|
if (!packageJson.type || packageJson.type !== 'module') {
|
|
160
107
|
this.log.error(`Plugin at ${packageJsonPath} is not a module`);
|
|
161
108
|
return null;
|
|
@@ -164,13 +111,6 @@ export class PluginManager {
|
|
|
164
111
|
this.log.error(`Plugin at ${packageJsonPath} has no main entrypoint in package.json`);
|
|
165
112
|
return null;
|
|
166
113
|
}
|
|
167
|
-
/*
|
|
168
|
-
if (!packageJson.types) {
|
|
169
|
-
this.log.error(`Plugin at ${packageJsonPath} has no types in package.json`);
|
|
170
|
-
return null;
|
|
171
|
-
}
|
|
172
|
-
*/
|
|
173
|
-
// Check for @project-chip packages in dependencies and devDependencies
|
|
174
114
|
const checkForProjectChipPackages = (dependencies) => {
|
|
175
115
|
return Object.keys(dependencies).filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matter'));
|
|
176
116
|
};
|
|
@@ -192,7 +132,6 @@ export class PluginManager {
|
|
|
192
132
|
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
193
133
|
return null;
|
|
194
134
|
}
|
|
195
|
-
// Check for matterbridge package in dependencies and devDependencies
|
|
196
135
|
const checkForMatterbridgePackage = (dependencies) => {
|
|
197
136
|
return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
|
|
198
137
|
};
|
|
@@ -222,11 +161,6 @@ export class PluginManager {
|
|
|
222
161
|
return null;
|
|
223
162
|
}
|
|
224
163
|
}
|
|
225
|
-
/**
|
|
226
|
-
* Loads and parse the plugin package.json and returns it.
|
|
227
|
-
* @param plugin - The plugin to load the package from.
|
|
228
|
-
* @returns A Promise that resolves to the package.json object or undefined if the package.json could not be loaded.
|
|
229
|
-
*/
|
|
230
164
|
async parse(plugin) {
|
|
231
165
|
this.log.debug(`Parsing package.json of plugin ${plg}${plugin.name}${db}`);
|
|
232
166
|
try {
|
|
@@ -243,7 +177,6 @@ export class PluginManager {
|
|
|
243
177
|
this.log.error(`Plugin ${plg}${plugin.name}${er} is not a module`);
|
|
244
178
|
if (!packageJson.main)
|
|
245
179
|
this.log.error(`Plugin ${plg}${plugin.name}${er} has no main entrypoint in package.json`);
|
|
246
|
-
// if (!packageJson.types) 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,19 +356,9 @@ 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}`);
|
|
482
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
483
362
|
return new Promise((resolve, reject) => {
|
|
484
363
|
exec(`npm install -g ${name} --omit=dev --force`, (error, stdout, stderr) => {
|
|
485
364
|
if (error) {
|
|
@@ -490,14 +369,11 @@ export class PluginManager {
|
|
|
490
369
|
else {
|
|
491
370
|
this.log.info(`Installed plugin ${plg}${name}${nf}`);
|
|
492
371
|
this.log.debug(`Installed plugin ${plg}${name}${db}: ${stdout}`);
|
|
493
|
-
// Get the installed version
|
|
494
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
495
372
|
exec(`npm list -g ${name} --depth=0`, (listError, listStdout, listStderr) => {
|
|
496
373
|
if (listError) {
|
|
497
374
|
this.log.error(`List error: ${listError}`);
|
|
498
375
|
resolve(undefined);
|
|
499
376
|
}
|
|
500
|
-
// Clean the output to get only the package name and version
|
|
501
377
|
const lines = listStdout.split('\n');
|
|
502
378
|
const versionLine = lines.find((line) => line.includes(`${name}@`));
|
|
503
379
|
if (versionLine) {
|
|
@@ -513,18 +389,8 @@ export class PluginManager {
|
|
|
513
389
|
});
|
|
514
390
|
});
|
|
515
391
|
}
|
|
516
|
-
/**
|
|
517
|
-
* Uninstalls a plugin by its name.
|
|
518
|
-
*
|
|
519
|
-
* This method uninstalls a globally installed plugin using npm. It logs the uninstallation process
|
|
520
|
-
* and returns the name of the uninstalled plugin if successful, or undefined if the uninstallation failed.
|
|
521
|
-
*
|
|
522
|
-
* @param {string} name - The name of the plugin to uninstall.
|
|
523
|
-
* @returns {Promise<string | undefined>} A promise that resolves to the name of the uninstalled plugin, or undefined if the uninstallation failed.
|
|
524
|
-
*/
|
|
525
392
|
async uninstall(name) {
|
|
526
393
|
this.log.info(`Uninstalling plugin ${plg}${name}${nf}`);
|
|
527
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
528
394
|
return new Promise((resolve, reject) => {
|
|
529
395
|
exec(`npm uninstall -g ${name} --force`, (error, stdout, stderr) => {
|
|
530
396
|
if (error) {
|
|
@@ -540,14 +406,6 @@ export class PluginManager {
|
|
|
540
406
|
});
|
|
541
407
|
});
|
|
542
408
|
}
|
|
543
|
-
/**
|
|
544
|
-
* Loads a plugin and returns the corresponding MatterbridgePlatform instance.
|
|
545
|
-
* @param plugin - The plugin to load.
|
|
546
|
-
* @param start - Optional flag indicating whether to start the plugin after loading. Default is false.
|
|
547
|
-
* @param message - Optional message to pass to the plugin when starting.
|
|
548
|
-
* @returns A Promise that resolves to the loaded MatterbridgePlatform instance.
|
|
549
|
-
* @throws An error if the plugin is not enabled, already loaded, or fails to load.
|
|
550
|
-
*/
|
|
551
409
|
async load(plugin, start = false, message = '', configure = false) {
|
|
552
410
|
if (!plugin.enabled) {
|
|
553
411
|
this.log.error(`Plugin ${plg}${plugin.name}${er} not enabled`);
|
|
@@ -559,19 +417,14 @@ export class PluginManager {
|
|
|
559
417
|
}
|
|
560
418
|
this.log.info(`Loading plugin ${plg}${plugin.name}${nf} type ${typ}${plugin.type}${nf}`);
|
|
561
419
|
try {
|
|
562
|
-
// Load the package.json of the plugin
|
|
563
420
|
const packageJson = JSON.parse(await fs.readFile(plugin.path, 'utf8'));
|
|
564
|
-
// Resolve the main module path relative to package.json
|
|
565
421
|
const pluginEntry = path.resolve(path.dirname(plugin.path), packageJson.main);
|
|
566
|
-
// Dynamically import the plugin
|
|
567
422
|
const pluginUrl = pathToFileURL(pluginEntry);
|
|
568
423
|
this.log.debug(`Importing plugin ${plg}${plugin.name}${db} from ${pluginUrl.href}`);
|
|
569
424
|
const pluginInstance = await import(pluginUrl.href);
|
|
570
425
|
this.log.debug(`Imported plugin ${plg}${plugin.name}${db} from ${pluginUrl.href}`);
|
|
571
|
-
// Call the default export function of the plugin, passing this MatterBridge instance, the log and the config
|
|
572
426
|
if (pluginInstance.default) {
|
|
573
427
|
const config = await this.loadConfig(plugin);
|
|
574
|
-
// 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.
|
|
575
428
|
plugin.name = packageJson.name;
|
|
576
429
|
plugin.description = packageJson.description ?? 'No description';
|
|
577
430
|
plugin.version = packageJson.version;
|
|
@@ -580,7 +433,7 @@ export class PluginManager {
|
|
|
580
433
|
plugin.schemaJson = await this.loadSchema(plugin);
|
|
581
434
|
config.name = plugin.name;
|
|
582
435
|
config.version = packageJson.version;
|
|
583
|
-
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 });
|
|
584
437
|
const platform = pluginInstance.default(this.matterbridge, log, config);
|
|
585
438
|
config.type = platform.type;
|
|
586
439
|
platform.name = packageJson.name;
|
|
@@ -597,7 +450,7 @@ export class PluginManager {
|
|
|
597
450
|
plugin.addedDevices = 0;
|
|
598
451
|
plugin.configJson = config;
|
|
599
452
|
plugin.schemaJson = await this.loadSchema(plugin);
|
|
600
|
-
await this.saveToStorage();
|
|
453
|
+
await this.saveToStorage();
|
|
601
454
|
this.log.notice(`Loaded plugin ${plg}${plugin.name}${nf} type ${typ}${platform.type}${db} (entrypoint ${UNDERLINE}${pluginEntry}${UNDERLINEOFF})`);
|
|
602
455
|
if (start)
|
|
603
456
|
await this.start(plugin, message, false);
|
|
@@ -616,14 +469,6 @@ export class PluginManager {
|
|
|
616
469
|
}
|
|
617
470
|
return undefined;
|
|
618
471
|
}
|
|
619
|
-
/**
|
|
620
|
-
* Starts a plugin.
|
|
621
|
-
*
|
|
622
|
-
* @param {RegisteredPlugin} plugin - The plugin to start.
|
|
623
|
-
* @param {string} [message] - Optional message to pass to the plugin's onStart method.
|
|
624
|
-
* @param {boolean} [configure] - Indicates whether to configure the plugin after starting (default false).
|
|
625
|
-
* @returns {Promise<RegisteredPlugin | undefined>} A promise that resolves when the plugin is started successfully, or rejects with an error if starting the plugin fails.
|
|
626
|
-
*/
|
|
627
472
|
async start(plugin, message, configure = false) {
|
|
628
473
|
if (!plugin.loaded) {
|
|
629
474
|
this.log.error(`Plugin ${plg}${plugin.name}${er} not loaded`);
|
|
@@ -653,12 +498,6 @@ export class PluginManager {
|
|
|
653
498
|
}
|
|
654
499
|
return undefined;
|
|
655
500
|
}
|
|
656
|
-
/**
|
|
657
|
-
* Configures a plugin.
|
|
658
|
-
*
|
|
659
|
-
* @param {RegisteredPlugin} plugin - The plugin to configure.
|
|
660
|
-
* @returns {Promise<void>} A promise that resolves when the plugin is configured successfully, or rejects with an error if configuration fails.
|
|
661
|
-
*/
|
|
662
501
|
async configure(plugin) {
|
|
663
502
|
if (!plugin.loaded) {
|
|
664
503
|
this.log.error(`Plugin ${plg}${plugin.name}${er} not loaded`);
|
|
@@ -681,7 +520,6 @@ export class PluginManager {
|
|
|
681
520
|
await plugin.platform.onConfigure();
|
|
682
521
|
this.log.notice(`Configured plugin ${plg}${plugin.name}${nt} type ${typ}${plugin.type}${nt}`);
|
|
683
522
|
plugin.configured = true;
|
|
684
|
-
// await this.saveConfigFromPlugin(plugin);
|
|
685
523
|
return plugin;
|
|
686
524
|
}
|
|
687
525
|
catch (err) {
|
|
@@ -690,18 +528,6 @@ export class PluginManager {
|
|
|
690
528
|
}
|
|
691
529
|
return undefined;
|
|
692
530
|
}
|
|
693
|
-
/**
|
|
694
|
-
* Shuts down a plugin.
|
|
695
|
-
*
|
|
696
|
-
* This method shuts down a plugin by calling its `onShutdown` method and resetting its state.
|
|
697
|
-
* It logs the shutdown process and optionally removes all devices associated with the plugin.
|
|
698
|
-
*
|
|
699
|
-
* @param {RegisteredPlugin} plugin - The plugin to shut down.
|
|
700
|
-
* @param {string} [reason] - The reason for shutting down the plugin.
|
|
701
|
-
* @param {boolean} [removeAllDevices=false] - Whether to remove all devices associated with the plugin.
|
|
702
|
-
* @param {boolean} [force=false] - Whether to force the shutdown even if the plugin is not loaded or started.
|
|
703
|
-
* @returns {Promise<RegisteredPlugin | undefined>} A promise that resolves to the shut down plugin object, or undefined if the shutdown failed.
|
|
704
|
-
*/
|
|
705
531
|
async shutdown(plugin, reason, removeAllDevices = false, force = false) {
|
|
706
532
|
this.log.debug(`Shutting down plugin ${plg}${plugin.name}${db}`);
|
|
707
533
|
if (!plugin.loaded) {
|
|
@@ -744,15 +570,6 @@ export class PluginManager {
|
|
|
744
570
|
}
|
|
745
571
|
return undefined;
|
|
746
572
|
}
|
|
747
|
-
/**
|
|
748
|
-
* Loads the configuration for a plugin.
|
|
749
|
-
* If the configuration file exists, it reads the file and returns the parsed JSON data.
|
|
750
|
-
* If the configuration file does not exist, it creates a new file with default configuration and returns it.
|
|
751
|
-
* If any error occurs during file access or creation, it logs an error and return un empty config.
|
|
752
|
-
*
|
|
753
|
-
* @param plugin - The plugin for which to load the configuration.
|
|
754
|
-
* @returns A promise that resolves to the loaded or created configuration.
|
|
755
|
-
*/
|
|
756
573
|
async loadConfig(plugin) {
|
|
757
574
|
const configFile = path.join(this.matterbridge.matterbridgeDirectory, `${plugin.name}.config.json`);
|
|
758
575
|
try {
|
|
@@ -760,8 +577,6 @@ export class PluginManager {
|
|
|
760
577
|
const data = await fs.readFile(configFile, 'utf8');
|
|
761
578
|
const config = JSON.parse(data);
|
|
762
579
|
this.log.debug(`Loaded config file ${configFile} for plugin ${plg}${plugin.name}${db}.`);
|
|
763
|
-
// this.log.debug(`Loaded config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
|
|
764
|
-
// The first time a plugin is added to the system, the config file is created with the plugin name and type "AnyPlatform".
|
|
765
580
|
config.name = plugin.name;
|
|
766
581
|
config.type = plugin.type;
|
|
767
582
|
if (config.debug === undefined)
|
|
@@ -786,7 +601,6 @@ export class PluginManager {
|
|
|
786
601
|
try {
|
|
787
602
|
await fs.writeFile(configFile, JSON.stringify(config, null, 2), 'utf8');
|
|
788
603
|
this.log.debug(`Created config file ${configFile} for plugin ${plg}${plugin.name}${db}.`);
|
|
789
|
-
// this.log.debug(`Created config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
|
|
790
604
|
return config;
|
|
791
605
|
}
|
|
792
606
|
catch (err) {
|
|
@@ -803,18 +617,6 @@ export class PluginManager {
|
|
|
803
617
|
return { name: plugin.name, type: plugin.type, debug: false, unregisterOnShutdown: false };
|
|
804
618
|
}
|
|
805
619
|
}
|
|
806
|
-
/**
|
|
807
|
-
* Saves the configuration of a plugin to a file.
|
|
808
|
-
*
|
|
809
|
-
* This method saves the configuration of the specified plugin to a JSON file in the matterbridge directory.
|
|
810
|
-
* If the plugin's configuration is not found, it logs an error and rejects the promise. If the configuration
|
|
811
|
-
* is successfully saved, it logs a debug message. If an error occurs during the file write operation, it logs
|
|
812
|
-
* the error and rejects the promise.
|
|
813
|
-
*
|
|
814
|
-
* @param {RegisteredPlugin} plugin - The plugin whose configuration is to be saved.
|
|
815
|
-
* @returns {Promise<void>} A promise that resolves when the configuration is successfully saved, or rejects if an error occurs.
|
|
816
|
-
* @throws {Error} If the plugin's configuration is not found.
|
|
817
|
-
*/
|
|
818
620
|
async saveConfigFromPlugin(plugin) {
|
|
819
621
|
if (!plugin.platform?.config) {
|
|
820
622
|
this.log.error(`Error saving config file for plugin ${plg}${plugin.name}${er}: config not found`);
|
|
@@ -824,7 +626,6 @@ export class PluginManager {
|
|
|
824
626
|
try {
|
|
825
627
|
await fs.writeFile(configFile, JSON.stringify(plugin.platform.config, null, 2), 'utf8');
|
|
826
628
|
this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}`);
|
|
827
|
-
// this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, plugin.platform.config);
|
|
828
629
|
return Promise.resolve();
|
|
829
630
|
}
|
|
830
631
|
catch (err) {
|
|
@@ -832,19 +633,6 @@ export class PluginManager {
|
|
|
832
633
|
return Promise.reject(err);
|
|
833
634
|
}
|
|
834
635
|
}
|
|
835
|
-
/**
|
|
836
|
-
* Saves the configuration of a plugin from a JSON object to a file.
|
|
837
|
-
*
|
|
838
|
-
* This method saves the provided configuration of the specified plugin to a JSON file in the matterbridge directory.
|
|
839
|
-
* It first checks if the configuration data is valid by ensuring it contains the correct name and type, and matches
|
|
840
|
-
* the plugin's name. If the configuration data is invalid, it logs an error and returns. If the configuration is
|
|
841
|
-
* successfully saved, it updates the plugin's `configJson` property and logs a debug message. If an error occurs
|
|
842
|
-
* during the file write operation, it logs the error and returns.
|
|
843
|
-
*
|
|
844
|
-
* @param {RegisteredPlugin} plugin - The plugin whose configuration is to be saved.
|
|
845
|
-
* @param {PlatformConfig} config - The configuration data to be saved.
|
|
846
|
-
* @returns {Promise<void>} A promise that resolves when the configuration is successfully saved, or returns if an error occurs.
|
|
847
|
-
*/
|
|
848
636
|
async saveConfigFromJson(plugin, config) {
|
|
849
637
|
if (!config.name || !config.type || config.name !== plugin.name) {
|
|
850
638
|
this.log.error(`Error saving config file for plugin ${plg}${plugin.name}${er}. Wrong config data content:${rs}\n`, config);
|
|
@@ -855,24 +643,12 @@ export class PluginManager {
|
|
|
855
643
|
await fs.writeFile(configFile, JSON.stringify(config, null, 2), 'utf8');
|
|
856
644
|
plugin.configJson = config;
|
|
857
645
|
this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}`);
|
|
858
|
-
// this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
|
|
859
646
|
}
|
|
860
647
|
catch (err) {
|
|
861
648
|
this.log.error(`Error saving config file ${configFile} for plugin ${plg}${plugin.name}${er}: ${err}`);
|
|
862
649
|
return;
|
|
863
650
|
}
|
|
864
651
|
}
|
|
865
|
-
/**
|
|
866
|
-
* Loads the schema for a plugin.
|
|
867
|
-
*
|
|
868
|
-
* This method attempts to load the schema file for the specified plugin. If the schema file is found,
|
|
869
|
-
* it reads and parses the file, updates the schema's title and description, and logs the process.
|
|
870
|
-
* It also attempts to delete any old schema file from the matterbridge directory. If the schema file
|
|
871
|
-
* is not found, it logs the event and loads a default schema for the plugin.
|
|
872
|
-
*
|
|
873
|
-
* @param {RegisteredPlugin} plugin - The plugin whose schema is to be loaded.
|
|
874
|
-
* @returns {Promise<PlatformSchema>} A promise that resolves to the loaded schema object, or the default schema if the schema file is not found.
|
|
875
|
-
*/
|
|
876
652
|
async loadSchema(plugin) {
|
|
877
653
|
const schemaFile = plugin.path.replace('package.json', `${plugin.name}.schema.json`);
|
|
878
654
|
try {
|
|
@@ -882,8 +658,6 @@ export class PluginManager {
|
|
|
882
658
|
schema.title = plugin.description;
|
|
883
659
|
schema.description = plugin.name + ' v. ' + plugin.version + ' by ' + plugin.author;
|
|
884
660
|
this.log.debug(`Loaded schema file ${schemaFile} for plugin ${plg}${plugin.name}${db}.`);
|
|
885
|
-
// this.log.debug(`Loaded schema file ${schemaFile} for plugin ${plg}${plugin.name}${db}.\nSchema:${rs}\n`, schema);
|
|
886
|
-
// Delete the schema file from old position
|
|
887
661
|
return schema;
|
|
888
662
|
}
|
|
889
663
|
catch (error) {
|
|
@@ -891,16 +665,6 @@ export class PluginManager {
|
|
|
891
665
|
return this.getDefaultSchema(plugin);
|
|
892
666
|
}
|
|
893
667
|
}
|
|
894
|
-
/**
|
|
895
|
-
* Returns the default schema for a plugin.
|
|
896
|
-
*
|
|
897
|
-
* This method generates a default schema object for the specified plugin. The schema includes
|
|
898
|
-
* metadata such as the plugin's title, description, version, and author. It also defines the
|
|
899
|
-
* properties of the schema, including the plugin's name, type, debug flag, and unregisterOnShutdown flag.
|
|
900
|
-
*
|
|
901
|
-
* @param {RegisteredPlugin} plugin - The plugin for which the default schema is to be generated.
|
|
902
|
-
* @returns {PlatformSchema} The default schema object for the plugin.
|
|
903
|
-
*/
|
|
904
668
|
getDefaultSchema(plugin) {
|
|
905
669
|
return {
|
|
906
670
|
title: plugin.description,
|
|
@@ -931,4 +695,3 @@ export class PluginManager {
|
|
|
931
695
|
};
|
|
932
696
|
}
|
|
933
697
|
}
|
|
934
|
-
//# sourceMappingURL=pluginManager.js.map
|
package/dist/storage/export.js
CHANGED