@matterbridge/core 3.6.1-dev-20260311-8b3e31c → 3.6.1-dev-20260313-a699c0e
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/dist/frontend.js +19 -19
- package/dist/matterbridge.js +5 -11
- package/dist/matterbridgeBehaviors.d.ts +0 -1
- package/dist/matterbridgeBehaviors.js +0 -11
- package/dist/pluginManager.d.ts +15 -0
- package/dist/pluginManager.js +46 -152
- package/package.json +6 -6
- package/dist/spawn.d.ts +0 -1
- package/dist/spawn.js +0 -96
package/dist/frontend.js
CHANGED
|
@@ -727,6 +727,7 @@ export class Frontend extends EventEmitter {
|
|
|
727
727
|
});
|
|
728
728
|
});
|
|
729
729
|
this.expressApp.post('/api/uploadpackage', upload.single('file'), async (req, res) => {
|
|
730
|
+
this.log.debug('The frontend sent /api/uploadpackage');
|
|
730
731
|
if (!this.validateReq(req, res))
|
|
731
732
|
return;
|
|
732
733
|
const { filename } = req.body;
|
|
@@ -736,35 +737,34 @@ export class Frontend extends EventEmitter {
|
|
|
736
737
|
res.status(400).send('Invalid request: file and filename are required');
|
|
737
738
|
return;
|
|
738
739
|
}
|
|
739
|
-
this.wssSendSnackbarMessage(`Installing package ${filename}
|
|
740
|
+
this.wssSendSnackbarMessage(`Installing package ${filename}...`, 0);
|
|
740
741
|
const filePath = path.join(this.matterbridge.matterbridgeDirectory, 'uploads', filename);
|
|
741
742
|
try {
|
|
742
743
|
const fs = await import('node:fs');
|
|
743
744
|
await fs.promises.rename(file.path, filePath);
|
|
744
745
|
this.log.info(`File ${plg}${filename}${nf} uploaded successfully`);
|
|
745
746
|
if (filename.endsWith('.tgz')) {
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
else {
|
|
762
|
-
res.send(`File ${filename} uploaded successfully`);
|
|
747
|
+
this.server.request({
|
|
748
|
+
type: 'manager_run',
|
|
749
|
+
src: 'frontend',
|
|
750
|
+
dst: 'manager',
|
|
751
|
+
params: {
|
|
752
|
+
name: 'SpawnCommand',
|
|
753
|
+
workerData: {
|
|
754
|
+
threadName: 'SpawnCommand',
|
|
755
|
+
command: 'npm',
|
|
756
|
+
args: ['install', '-g', filePath, '--omit=dev', '--verbose'],
|
|
757
|
+
packageCommand: 'install',
|
|
758
|
+
packageName: filename,
|
|
759
|
+
},
|
|
760
|
+
},
|
|
761
|
+
});
|
|
763
762
|
}
|
|
763
|
+
res.send(`File ${filename} uploaded successfully`);
|
|
764
764
|
}
|
|
765
765
|
catch (err) {
|
|
766
766
|
this.log.error(`Error uploading or installing plugin package file ${plg}${filename}${er}:`, err);
|
|
767
|
-
this.wssSendCloseSnackbarMessage(`Installing package ${filename}
|
|
767
|
+
this.wssSendCloseSnackbarMessage(`Installing package ${filename}...`);
|
|
768
768
|
this.wssSendSnackbarMessage(`Error uploading or installing plugin package ${filename}`, 10, 'error');
|
|
769
769
|
res.status(500).send(`Error uploading or installing plugin package ${filename}`);
|
|
770
770
|
}
|
package/dist/matterbridge.js
CHANGED
|
@@ -16,7 +16,7 @@ import { DeviceTypeId, VendorId } from '@matter/types/datatype';
|
|
|
16
16
|
import { BroadcastServer } from '@matterbridge/thread/server';
|
|
17
17
|
import { dev, MATTER_LOGGER_FILE, MATTER_STORAGE_NAME, MATTERBRIDGE_LOGGER_FILE, NODE_STORAGE_DIR, plg, typ } from '@matterbridge/types';
|
|
18
18
|
import { wait } from '@matterbridge/utils';
|
|
19
|
-
import { getIntParameter, getParameter, hasParameter } from '@matterbridge/utils/cli';
|
|
19
|
+
import { getIntParameter, getParameter, hasAnyParameter, hasParameter } from '@matterbridge/utils/cli';
|
|
20
20
|
import { copyDirectory } from '@matterbridge/utils/copy-dir';
|
|
21
21
|
import { createDirectory } from '@matterbridge/utils/create-dir';
|
|
22
22
|
import { formatBytes, formatPercent, formatUptime } from '@matterbridge/utils/format';
|
|
@@ -566,17 +566,11 @@ export class Matterbridge extends EventEmitter {
|
|
|
566
566
|
this.devices.logLevel = this.log.logLevel;
|
|
567
567
|
for (const plugin of this.plugins) {
|
|
568
568
|
this.log.debug(`Parsing plugin ${plg}${plugin.name}${db} from path ${CYAN}${plugin.path}${db} with version ${CYAN}${plugin.version}${db} and type ${CYAN}${plugin.type}${db}.`);
|
|
569
|
-
if (!fs.existsSync(plugin.path) &&
|
|
570
|
-
!hasParameter('add') &&
|
|
571
|
-
!hasParameter('remove') &&
|
|
572
|
-
!hasParameter('enable') &&
|
|
573
|
-
!hasParameter('disable') &&
|
|
574
|
-
!hasParameter('reset') &&
|
|
575
|
-
!hasParameter('factoryreset') &&
|
|
576
|
-
!hasParameter('systemcheck')) {
|
|
569
|
+
if (!fs.existsSync(plugin.path) && !hasAnyParameter('add', 'remove', 'enable', 'disable', 'reset', 'factoryreset', 'systemcheck')) {
|
|
577
570
|
this.log.info(`Error parsing plugin ${plg}${plugin.name}${nf}. Trying to reinstall it from npm...`);
|
|
578
|
-
const {
|
|
579
|
-
|
|
571
|
+
const { execSync } = await import('node:child_process');
|
|
572
|
+
const sudo = hasParameter('sudo') || (process.platform !== 'win32' && !hasParameter('docker') && !hasParameter('nosudo') && !process.env.PATH?.includes('/.nvm/versions/node/'));
|
|
573
|
+
if (execSync(`${sudo ? 'sudo ' : ''}npm install -g ${plugin.name}${plugin.version.includes('-dev-') ? '@dev' : ''} --omit=dev`)) {
|
|
580
574
|
this.log.info(`Plugin ${plg}${plugin.name}${nf} reinstalled.`);
|
|
581
575
|
plugin.error = false;
|
|
582
576
|
}
|
|
@@ -1615,7 +1615,6 @@ declare const MatterbridgeThermostatServer_base: import("@matter/node").ClusterB
|
|
|
1615
1615
|
}];
|
|
1616
1616
|
}>, readonly [Thermostat.Feature.Cooling, Thermostat.Feature.Heating, Thermostat.Feature.AutoMode]>, typeof ThermostatServer, import("@matter/node/behaviors/thermostat").ThermostatInterface>;
|
|
1617
1617
|
export declare class MatterbridgeThermostatServer extends MatterbridgeThermostatServer_base {
|
|
1618
|
-
initialize(): Promise<void>;
|
|
1619
1618
|
setpointRaiseLower(request: Thermostat.SetpointRaiseLowerRequest): MaybePromise;
|
|
1620
1619
|
}
|
|
1621
1620
|
declare const MatterbridgePresetThermostatServer_base: import("@matter/node").ClusterBehavior.Type<import("@matter/types").ClusterComposer.WithFeatures<import("@matter/types").ClusterType.Of<{
|
|
@@ -321,17 +321,6 @@ export class MatterbridgeFanControlServer extends FanControlServer.with(FanContr
|
|
|
321
321
|
}
|
|
322
322
|
}
|
|
323
323
|
export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermostat.Feature.Cooling, Thermostat.Feature.Heating, Thermostat.Feature.AutoMode) {
|
|
324
|
-
async initialize() {
|
|
325
|
-
await super.initialize();
|
|
326
|
-
this.endpoint.construction.onSuccess(async () => {
|
|
327
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
328
|
-
device.log.debug(`Removing atomic commands (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
329
|
-
await this.endpoint.setStateOf(ThermostatServer, {
|
|
330
|
-
acceptedCommandList: [0],
|
|
331
|
-
generatedCommandList: [],
|
|
332
|
-
});
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
324
|
setpointRaiseLower(request) {
|
|
336
325
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
337
326
|
device.log.info(`Setting setpoint by ${request.amount} in mode ${request.mode} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
package/dist/pluginManager.d.ts
CHANGED
|
@@ -29,6 +29,16 @@ interface PluginManagerEvents {
|
|
|
29
29
|
configured: [name: string];
|
|
30
30
|
shutdown: [name: string];
|
|
31
31
|
}
|
|
32
|
+
type PackageJsonDependencies = Record<string, string> | string[];
|
|
33
|
+
type PackageJsonLike = Record<string, unknown> & {
|
|
34
|
+
name?: string;
|
|
35
|
+
dependencies?: PackageJsonDependencies;
|
|
36
|
+
devDependencies?: PackageJsonDependencies;
|
|
37
|
+
peerDependencies?: PackageJsonDependencies;
|
|
38
|
+
optionalDependencies?: PackageJsonDependencies;
|
|
39
|
+
bundledDependencies?: PackageJsonDependencies;
|
|
40
|
+
bundleDependencies?: PackageJsonDependencies;
|
|
41
|
+
};
|
|
32
42
|
export declare class PluginManager extends EventEmitter<PluginManagerEvents> {
|
|
33
43
|
private readonly matterbridge;
|
|
34
44
|
private readonly _plugins;
|
|
@@ -36,8 +46,13 @@ export declare class PluginManager extends EventEmitter<PluginManagerEvents> {
|
|
|
36
46
|
private readonly server;
|
|
37
47
|
private readonly debug;
|
|
38
48
|
private readonly verbose;
|
|
49
|
+
private readonly dependencyTypes;
|
|
39
50
|
constructor(matterbridge: Matterbridge);
|
|
40
51
|
destroy(): void;
|
|
52
|
+
private getDependencyNames;
|
|
53
|
+
private findInvalidDependencies;
|
|
54
|
+
private logInvalidDependencies;
|
|
55
|
+
checkDependencies(packageJson: PackageJsonLike): boolean;
|
|
41
56
|
private msgHandler;
|
|
42
57
|
get length(): number;
|
|
43
58
|
get size(): number;
|
package/dist/pluginManager.js
CHANGED
|
@@ -16,6 +16,7 @@ export class PluginManager extends EventEmitter {
|
|
|
16
16
|
server;
|
|
17
17
|
debug = hasParameter('debug') || hasParameter('verbose');
|
|
18
18
|
verbose = hasParameter('verbose');
|
|
19
|
+
dependencyTypes = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies', 'bundledDependencies', 'bundleDependencies'];
|
|
19
20
|
constructor(matterbridge) {
|
|
20
21
|
super();
|
|
21
22
|
this.matterbridge = matterbridge;
|
|
@@ -29,6 +30,43 @@ export class PluginManager extends EventEmitter {
|
|
|
29
30
|
this.server.off('broadcast_message', this.msgHandler.bind(this));
|
|
30
31
|
this.server.close();
|
|
31
32
|
}
|
|
33
|
+
getDependencyNames(dependencies) {
|
|
34
|
+
if (!dependencies)
|
|
35
|
+
return [];
|
|
36
|
+
return Array.isArray(dependencies) ? dependencies : Object.keys(dependencies);
|
|
37
|
+
}
|
|
38
|
+
findInvalidDependencies(packageJson) {
|
|
39
|
+
for (const dependencyType of this.dependencyTypes) {
|
|
40
|
+
const packages = this.getDependencyNames(packageJson[dependencyType]);
|
|
41
|
+
const matterbridgePackages = packages.filter((pkg) => pkg.startsWith('matterbridge'));
|
|
42
|
+
if (matterbridgePackages.length > 0) {
|
|
43
|
+
return { dependencyType, packages: matterbridgePackages, isMatterbridgePackage: true };
|
|
44
|
+
}
|
|
45
|
+
const scopedPackages = packages.filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matterbridge') || pkg.startsWith('@matter'));
|
|
46
|
+
if (scopedPackages.length > 0) {
|
|
47
|
+
return { dependencyType, packages: scopedPackages, isMatterbridgePackage: false };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
logInvalidDependencies(packageJson, invalidDependencies, pluginName) {
|
|
53
|
+
if (invalidDependencies.isMatterbridgePackage) {
|
|
54
|
+
this.log.error(`Found matterbridge package in the plugin${pluginName ? ` ${plg}${pluginName}${er}` : ''} ${invalidDependencies.dependencyType}.`);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
this.log.error(`Found invalid packages "${invalidDependencies.packages.join(', ')}" in plugin${pluginName ? ` ${plg}${pluginName}${er}` : ''} ${invalidDependencies.dependencyType}.`);
|
|
58
|
+
}
|
|
59
|
+
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
60
|
+
this.server.request({
|
|
61
|
+
type: 'frontend_snackbarmessage',
|
|
62
|
+
src: 'plugins',
|
|
63
|
+
dst: 'frontend',
|
|
64
|
+
params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' },
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
checkDependencies(packageJson) {
|
|
68
|
+
return this.findInvalidDependencies(packageJson) === null;
|
|
69
|
+
}
|
|
32
70
|
async msgHandler(msg) {
|
|
33
71
|
if (this.server.isWorkerRequest(msg)) {
|
|
34
72
|
if (this.verbose)
|
|
@@ -237,6 +275,8 @@ export class PluginManager extends EventEmitter {
|
|
|
237
275
|
switch (msg.type) {
|
|
238
276
|
case 'manager_spawn_response':
|
|
239
277
|
if (msg.result && msg.result.packageCommand === 'install') {
|
|
278
|
+
if (msg.result.packageName.endsWith('.tgz'))
|
|
279
|
+
return;
|
|
240
280
|
if (msg.result.success) {
|
|
241
281
|
const packageName = msg.result.packageName.replace(/@.*$/, '');
|
|
242
282
|
if (packageName !== 'matterbridge') {
|
|
@@ -435,82 +475,9 @@ export class PluginManager extends EventEmitter {
|
|
|
435
475
|
this.log.error(`Plugin at ${packageJsonPath} has no main entrypoint in package.json`);
|
|
436
476
|
return null;
|
|
437
477
|
}
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
const projectChipDependencies = checkForProjectChipPackages(packageJson.dependencies || {});
|
|
442
|
-
if (projectChipDependencies.length > 0) {
|
|
443
|
-
this.log.error(`Found @project-chip packages "${projectChipDependencies.join(', ')}" in plugin dependencies.`);
|
|
444
|
-
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
445
|
-
this.server.request({
|
|
446
|
-
type: 'frontend_snackbarmessage',
|
|
447
|
-
src: 'plugins',
|
|
448
|
-
dst: 'frontend',
|
|
449
|
-
params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' },
|
|
450
|
-
});
|
|
451
|
-
return null;
|
|
452
|
-
}
|
|
453
|
-
const projectChipDevDependencies = checkForProjectChipPackages(packageJson.devDependencies || {});
|
|
454
|
-
if (projectChipDevDependencies.length > 0) {
|
|
455
|
-
this.log.error(`Found @project-chip packages "${projectChipDevDependencies.join(', ')}" in plugin devDependencies.`);
|
|
456
|
-
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
457
|
-
this.server.request({
|
|
458
|
-
type: 'frontend_snackbarmessage',
|
|
459
|
-
src: 'plugins',
|
|
460
|
-
dst: 'frontend',
|
|
461
|
-
params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' },
|
|
462
|
-
});
|
|
463
|
-
return null;
|
|
464
|
-
}
|
|
465
|
-
const projectChipPeerDependencies = checkForProjectChipPackages(packageJson.peerDependencies || {});
|
|
466
|
-
if (projectChipPeerDependencies.length > 0) {
|
|
467
|
-
this.log.error(`Found @project-chip packages "${projectChipPeerDependencies.join(', ')}" in plugin peerDependencies.`);
|
|
468
|
-
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
469
|
-
this.server.request({
|
|
470
|
-
type: 'frontend_snackbarmessage',
|
|
471
|
-
src: 'plugins',
|
|
472
|
-
dst: 'frontend',
|
|
473
|
-
params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' },
|
|
474
|
-
});
|
|
475
|
-
return null;
|
|
476
|
-
}
|
|
477
|
-
const checkForMatterbridgePackage = (dependencies) => {
|
|
478
|
-
return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
|
|
479
|
-
};
|
|
480
|
-
const matterbridgeDependencies = checkForMatterbridgePackage(packageJson.dependencies || {});
|
|
481
|
-
if (matterbridgeDependencies.length > 0) {
|
|
482
|
-
this.log.error(`Found matterbridge package in the plugin dependencies.`);
|
|
483
|
-
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
484
|
-
this.server.request({
|
|
485
|
-
type: 'frontend_snackbarmessage',
|
|
486
|
-
src: 'plugins',
|
|
487
|
-
dst: 'frontend',
|
|
488
|
-
params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' },
|
|
489
|
-
});
|
|
490
|
-
return null;
|
|
491
|
-
}
|
|
492
|
-
const matterbridgeDevDependencies = checkForMatterbridgePackage(packageJson.devDependencies || {});
|
|
493
|
-
if (matterbridgeDevDependencies.length > 0) {
|
|
494
|
-
this.log.error(`Found matterbridge package in the plugin devDependencies.`);
|
|
495
|
-
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
496
|
-
this.server.request({
|
|
497
|
-
type: 'frontend_snackbarmessage',
|
|
498
|
-
src: 'plugins',
|
|
499
|
-
dst: 'frontend',
|
|
500
|
-
params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' },
|
|
501
|
-
});
|
|
502
|
-
return null;
|
|
503
|
-
}
|
|
504
|
-
const matterbridgePeerDependencies = checkForMatterbridgePackage(packageJson.peerDependencies || {});
|
|
505
|
-
if (matterbridgePeerDependencies.length > 0) {
|
|
506
|
-
this.log.error(`Found matterbridge package in the plugin peerDependencies.`);
|
|
507
|
-
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
508
|
-
this.server.request({
|
|
509
|
-
type: 'frontend_snackbarmessage',
|
|
510
|
-
src: 'plugins',
|
|
511
|
-
dst: 'frontend',
|
|
512
|
-
params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' },
|
|
513
|
-
});
|
|
478
|
+
const invalidDependencies = this.findInvalidDependencies(packageJson);
|
|
479
|
+
if (invalidDependencies) {
|
|
480
|
+
this.logInvalidDependencies(packageJson, invalidDependencies);
|
|
514
481
|
return null;
|
|
515
482
|
}
|
|
516
483
|
this.log.debug(`Resolved plugin path ${plg}${nameOrPath}${db}: ${packageJsonPath}`);
|
|
@@ -667,82 +634,9 @@ export class PluginManager extends EventEmitter {
|
|
|
667
634
|
plugin.funding = this.getFunding(packageJson);
|
|
668
635
|
if (!plugin.type)
|
|
669
636
|
this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no type`);
|
|
670
|
-
const
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
const projectChipDependencies = checkForProjectChipPackages(packageJson.dependencies || {});
|
|
674
|
-
if (projectChipDependencies.length > 0) {
|
|
675
|
-
this.log.error(`Found @project-chip packages "${projectChipDependencies.join(', ')}" in plugin ${plg}${plugin.name}${er} dependencies.`);
|
|
676
|
-
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
677
|
-
this.server.request({
|
|
678
|
-
type: 'frontend_snackbarmessage',
|
|
679
|
-
src: 'plugins',
|
|
680
|
-
dst: 'frontend',
|
|
681
|
-
params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' },
|
|
682
|
-
});
|
|
683
|
-
return null;
|
|
684
|
-
}
|
|
685
|
-
const projectChipDevDependencies = checkForProjectChipPackages(packageJson.devDependencies || {});
|
|
686
|
-
if (projectChipDevDependencies.length > 0) {
|
|
687
|
-
this.log.error(`Found @project-chip packages "${projectChipDevDependencies.join(', ')}" in plugin ${plg}${plugin.name}${er} devDependencies.`);
|
|
688
|
-
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
689
|
-
this.server.request({
|
|
690
|
-
type: 'frontend_snackbarmessage',
|
|
691
|
-
src: 'plugins',
|
|
692
|
-
dst: 'frontend',
|
|
693
|
-
params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' },
|
|
694
|
-
});
|
|
695
|
-
return null;
|
|
696
|
-
}
|
|
697
|
-
const projectChipPeerDependencies = checkForProjectChipPackages(packageJson.peerDependencies || {});
|
|
698
|
-
if (projectChipPeerDependencies.length > 0) {
|
|
699
|
-
this.log.error(`Found @project-chip packages "${projectChipPeerDependencies.join(', ')}" in plugin ${plg}${plugin.name}${er} peerDependencies.`);
|
|
700
|
-
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
701
|
-
this.server.request({
|
|
702
|
-
type: 'frontend_snackbarmessage',
|
|
703
|
-
src: 'plugins',
|
|
704
|
-
dst: 'frontend',
|
|
705
|
-
params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' },
|
|
706
|
-
});
|
|
707
|
-
return null;
|
|
708
|
-
}
|
|
709
|
-
const checkForMatterbridgePackage = (dependencies) => {
|
|
710
|
-
return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
|
|
711
|
-
};
|
|
712
|
-
const matterbridgeDependencies = checkForMatterbridgePackage(packageJson.dependencies || {});
|
|
713
|
-
if (matterbridgeDependencies.length > 0) {
|
|
714
|
-
this.log.error(`Found matterbridge package in the plugin ${plg}${plugin.name}${er} dependencies.`);
|
|
715
|
-
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
716
|
-
this.server.request({
|
|
717
|
-
type: 'frontend_snackbarmessage',
|
|
718
|
-
src: 'plugins',
|
|
719
|
-
dst: 'frontend',
|
|
720
|
-
params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' },
|
|
721
|
-
});
|
|
722
|
-
return null;
|
|
723
|
-
}
|
|
724
|
-
const matterbridgeDevDependencies = checkForMatterbridgePackage(packageJson.devDependencies || {});
|
|
725
|
-
if (matterbridgeDevDependencies.length > 0) {
|
|
726
|
-
this.log.error(`Found matterbridge package in the plugin ${plg}${plugin.name}${er} devDependencies.`);
|
|
727
|
-
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
728
|
-
this.server.request({
|
|
729
|
-
type: 'frontend_snackbarmessage',
|
|
730
|
-
src: 'plugins',
|
|
731
|
-
dst: 'frontend',
|
|
732
|
-
params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' },
|
|
733
|
-
});
|
|
734
|
-
return null;
|
|
735
|
-
}
|
|
736
|
-
const matterbridgePeerDependencies = checkForMatterbridgePackage(packageJson.peerDependencies || {});
|
|
737
|
-
if (matterbridgePeerDependencies.length > 0) {
|
|
738
|
-
this.log.error(`Found matterbridge package in the plugin ${plg}${plugin.name}${er} peerDependencies.`);
|
|
739
|
-
this.log.error(`Please open an issue on the plugin repository to remove them.`);
|
|
740
|
-
this.server.request({
|
|
741
|
-
type: 'frontend_snackbarmessage',
|
|
742
|
-
src: 'plugins',
|
|
743
|
-
dst: 'frontend',
|
|
744
|
-
params: { message: `Found not allowed package in plugin ${packageJson.name} package.json`, timeout: 30, severity: 'error' },
|
|
745
|
-
});
|
|
637
|
+
const invalidDependencies = this.findInvalidDependencies(packageJson);
|
|
638
|
+
if (invalidDependencies) {
|
|
639
|
+
this.logInvalidDependencies(packageJson, invalidDependencies, plugin.name);
|
|
746
640
|
return null;
|
|
747
641
|
}
|
|
748
642
|
return packageJson;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/core",
|
|
3
|
-
"version": "3.6.1-dev-
|
|
3
|
+
"version": "3.6.1-dev-20260313-a699c0e",
|
|
4
4
|
"description": "Matterbridge core library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -121,11 +121,11 @@
|
|
|
121
121
|
"CHANGELOG.md"
|
|
122
122
|
],
|
|
123
123
|
"dependencies": {
|
|
124
|
-
"@matter/main": "0.17.0-alpha.0-
|
|
125
|
-
"@matterbridge/dgram": "3.6.1-dev-
|
|
126
|
-
"@matterbridge/thread": "3.6.1-dev-
|
|
127
|
-
"@matterbridge/types": "3.6.1-dev-
|
|
128
|
-
"@matterbridge/utils": "3.6.1-dev-
|
|
124
|
+
"@matter/main": "0.17.0-alpha.0-20260311-3dbb8a732",
|
|
125
|
+
"@matterbridge/dgram": "3.6.1-dev-20260313-a699c0e",
|
|
126
|
+
"@matterbridge/thread": "3.6.1-dev-20260313-a699c0e",
|
|
127
|
+
"@matterbridge/types": "3.6.1-dev-20260313-a699c0e",
|
|
128
|
+
"@matterbridge/utils": "3.6.1-dev-20260313-a699c0e",
|
|
129
129
|
"archiver": "7.0.1",
|
|
130
130
|
"express": "5.2.1",
|
|
131
131
|
"glob": "13.0.6",
|
package/dist/spawn.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function spawnCommand(command: string, args: string[], packageCommand?: 'install' | 'uninstall', packageName?: string): Promise<boolean>;
|
package/dist/spawn.js
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { BroadcastServer } from '@matterbridge/thread/server';
|
|
2
|
-
import { hasParameter } from '@matterbridge/utils/cli';
|
|
3
|
-
import { AnsiLogger } from 'node-ansi-logger';
|
|
4
|
-
export async function spawnCommand(command, args, packageCommand, packageName) {
|
|
5
|
-
const { spawn } = await import('node:child_process');
|
|
6
|
-
const debug = hasParameter('debug') || hasParameter('verbose') || hasParameter('debug-spawn') || hasParameter('verbose-spawn');
|
|
7
|
-
const verbose = hasParameter('verbose') || hasParameter('verbose-spawn');
|
|
8
|
-
const log = new AnsiLogger({ logName: 'Spawn', logTimestampFormat: 4, logLevel: debug ? "debug" : "info" });
|
|
9
|
-
const server = new BroadcastServer('spawn', log);
|
|
10
|
-
const sendLog = (name, message) => {
|
|
11
|
-
try {
|
|
12
|
-
server.request({ type: 'frontend_logmessage', src: 'spawn', dst: 'frontend', params: { level: 'spawn', time: log.now(), name, message } });
|
|
13
|
-
}
|
|
14
|
-
catch (err) {
|
|
15
|
-
log.debug(`Failed to send log message to frontend: ${err instanceof Error ? err.message : String(err)}`);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
if (verbose)
|
|
19
|
-
log.debug(`Spawning command: ${command} with ${args.join(' ')} ${packageCommand} ${packageName}`);
|
|
20
|
-
const cmdLine = command + ' ' + args.join(' ');
|
|
21
|
-
if (process.platform === 'win32' && command === 'npm') {
|
|
22
|
-
const argstring = 'npm ' + args.join(' ');
|
|
23
|
-
args.splice(0, args.length, '/c', argstring);
|
|
24
|
-
command = 'cmd.exe';
|
|
25
|
-
}
|
|
26
|
-
if (hasParameter('sudo') ||
|
|
27
|
-
(process.platform !== 'win32' && command === 'npm' && !hasParameter('docker') && !hasParameter('nosudo') && !process.env.PATH?.includes('/.nvm/versions/node/'))) {
|
|
28
|
-
args.unshift(command);
|
|
29
|
-
command = 'sudo';
|
|
30
|
-
}
|
|
31
|
-
log.debug(`Spawn command ${command} with ${args.join(' ')}`);
|
|
32
|
-
const success = await new Promise((resolve) => {
|
|
33
|
-
if (packageCommand === 'install')
|
|
34
|
-
sendLog('Matterbridge:spawn-init', `Installing ${packageName}`);
|
|
35
|
-
else if (packageCommand === 'uninstall')
|
|
36
|
-
sendLog('Matterbridge:spawn-init', `Uninstalling ${packageName}`);
|
|
37
|
-
const childProcess = spawn(command, args, {
|
|
38
|
-
stdio: ['inherit', 'pipe', 'pipe'],
|
|
39
|
-
});
|
|
40
|
-
childProcess.on('error', (err) => {
|
|
41
|
-
log.error(`Failed to start child process "${cmdLine}": ${err.message}`);
|
|
42
|
-
sendLog('Matterbridge:spawn-exit-error', 'Spawn process error');
|
|
43
|
-
resolve(false);
|
|
44
|
-
});
|
|
45
|
-
childProcess.on('close', (code, signal) => {
|
|
46
|
-
if (code === 0) {
|
|
47
|
-
log.debug(`Child process "${cmdLine}" closed with code ${code} and signal ${signal}`);
|
|
48
|
-
sendLog('Matterbridge:spawn-exit-success', 'Child process closed');
|
|
49
|
-
resolve(true);
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
log.error(`Child process "${cmdLine}" closed with code ${code} and signal ${signal}`);
|
|
53
|
-
sendLog('Matterbridge:spawn-exit-error', 'Child process closed');
|
|
54
|
-
resolve(false);
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
childProcess.on('exit', (code, signal) => {
|
|
58
|
-
if (code === 0) {
|
|
59
|
-
log.debug(`Child process "${cmdLine}" exited with code ${code} and signal ${signal}`);
|
|
60
|
-
sendLog('Matterbridge:spawn-exit-success', 'Child process exited');
|
|
61
|
-
resolve(true);
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
log.error(`Child process "${cmdLine}" exited with code ${code} and signal ${signal}`);
|
|
65
|
-
sendLog('Matterbridge:spawn-exit-error', 'Child process exited');
|
|
66
|
-
resolve(false);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
childProcess.on('disconnect', () => {
|
|
70
|
-
log.debug(`Child process "${cmdLine}" has been disconnected from the parent`);
|
|
71
|
-
resolve(true);
|
|
72
|
-
});
|
|
73
|
-
if (childProcess.stdout) {
|
|
74
|
-
childProcess.stdout.on('data', (data) => {
|
|
75
|
-
const message = data.toString().trim();
|
|
76
|
-
const lines = message.split('\n');
|
|
77
|
-
for (const line of lines) {
|
|
78
|
-
log.debug(`Spawn output (stdout): ${line}`);
|
|
79
|
-
sendLog('Matterbridge:spawn', line);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
if (childProcess.stderr) {
|
|
84
|
-
childProcess.stderr.on('data', (data) => {
|
|
85
|
-
const message = data.toString().trim();
|
|
86
|
-
const lines = message.split('\n');
|
|
87
|
-
for (const line of lines) {
|
|
88
|
-
log.debug(`Spawn verbose (stderr): ${line}`);
|
|
89
|
-
sendLog('Matterbridge:spawn', line);
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
server.close();
|
|
95
|
-
return success;
|
|
96
|
-
}
|