matterbridge 3.0.7 → 3.0.8-dev-20250622-f9e44a2

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.
Files changed (207) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/bin/matterbridge +2 -0
  3. package/dist/cli.js +5 -66
  4. package/dist/clusters/export.js +0 -2
  5. package/dist/defaultConfigSchema.js +0 -23
  6. package/dist/deviceManager.js +2 -95
  7. package/dist/devices/export.js +0 -2
  8. package/dist/evse.js +9 -65
  9. package/dist/frontend.js +47 -383
  10. package/dist/globalMatterbridge.js +0 -20
  11. package/dist/helpers.js +4 -52
  12. package/dist/index.js +2 -29
  13. package/dist/laundryWasher.js +7 -92
  14. package/dist/logger/export.js +0 -1
  15. package/dist/matter/behaviors.js +0 -2
  16. package/dist/matter/clusters.js +0 -2
  17. package/dist/matter/devices.js +0 -2
  18. package/dist/matter/endpoints.js +0 -2
  19. package/dist/matter/export.js +0 -2
  20. package/dist/matter/types.js +0 -2
  21. package/dist/matterbridge.js +53 -755
  22. package/dist/matterbridgeAccessoryPlatform.js +0 -34
  23. package/dist/matterbridgeBehaviors.js +1 -54
  24. package/dist/matterbridgeDeviceTypes.js +15 -578
  25. package/dist/matterbridgeDynamicPlatform.js +0 -34
  26. package/dist/matterbridgeEndpoint.js +45 -1000
  27. package/dist/matterbridgeEndpointHelpers.js +12 -206
  28. package/dist/matterbridgePlatform.js +13 -224
  29. package/dist/matterbridgeTypes.js +0 -24
  30. package/dist/pluginManager.js +4 -270
  31. package/dist/roboticVacuumCleaner.js +9 -84
  32. package/dist/shelly.js +9 -156
  33. package/dist/storage/export.js +0 -1
  34. package/dist/update.js +0 -53
  35. package/dist/utils/colorUtils.js +2 -205
  36. package/dist/utils/commandLine.js +0 -53
  37. package/dist/utils/copyDirectory.js +1 -37
  38. package/dist/utils/createDirectory.js +0 -31
  39. package/dist/utils/createZip.js +2 -42
  40. package/dist/utils/deepCopy.js +0 -38
  41. package/dist/utils/deepEqual.js +1 -71
  42. package/dist/utils/export.js +0 -1
  43. package/dist/utils/hex.js +0 -57
  44. package/dist/utils/isvalid.js +0 -100
  45. package/dist/utils/network.js +6 -77
  46. package/dist/utils/spawn.js +0 -16
  47. package/dist/utils/wait.js +10 -58
  48. package/dist/waterHeater.js +5 -65
  49. package/frontend/build/matterbridge 1250x1250.png +0 -0
  50. package/frontend/build/matterbridge 624x624.png +0 -0
  51. package/frontend/package-lock.json +19176 -0
  52. package/frontend/package.json +79 -0
  53. package/frontend/public/Shelly.svg +1 -0
  54. package/frontend/public/bmc-button.svg +22 -0
  55. package/frontend/public/discord.svg +5 -0
  56. package/frontend/public/favicon.ico +0 -0
  57. package/frontend/public/index.html +19 -0
  58. package/frontend/public/manifest.json +15 -0
  59. package/frontend/public/matter.png +0 -0
  60. package/frontend/public/matterbridge 1250x1250.png +0 -0
  61. package/frontend/public/matterbridge 32x32.png +0 -0
  62. package/frontend/public/matterbridge 624x624.png +0 -0
  63. package/frontend/public/matterbridge 64x64.png +0 -0
  64. package/frontend/public/matterbridge.svg +50 -0
  65. package/frontend/public/robots.txt +3 -0
  66. package/npm-shrinkwrap.json +27 -36
  67. package/package.json +2 -3
  68. package/dist/cli.d.ts +0 -29
  69. package/dist/cli.d.ts.map +0 -1
  70. package/dist/cli.js.map +0 -1
  71. package/dist/clusters/export.d.ts +0 -2
  72. package/dist/clusters/export.d.ts.map +0 -1
  73. package/dist/clusters/export.js.map +0 -1
  74. package/dist/defaultConfigSchema.d.ts +0 -27
  75. package/dist/defaultConfigSchema.d.ts.map +0 -1
  76. package/dist/defaultConfigSchema.js.map +0 -1
  77. package/dist/deviceManager.d.ts +0 -114
  78. package/dist/deviceManager.d.ts.map +0 -1
  79. package/dist/deviceManager.js.map +0 -1
  80. package/dist/devices/export.d.ts +0 -5
  81. package/dist/devices/export.d.ts.map +0 -1
  82. package/dist/devices/export.js.map +0 -1
  83. package/dist/evse.d.ts +0 -67
  84. package/dist/evse.d.ts.map +0 -1
  85. package/dist/evse.js.map +0 -1
  86. package/dist/frontend.d.ts +0 -256
  87. package/dist/frontend.d.ts.map +0 -1
  88. package/dist/frontend.js.map +0 -1
  89. package/dist/globalMatterbridge.d.ts +0 -32
  90. package/dist/globalMatterbridge.d.ts.map +0 -1
  91. package/dist/globalMatterbridge.js.map +0 -1
  92. package/dist/helpers.d.ts +0 -47
  93. package/dist/helpers.d.ts.map +0 -1
  94. package/dist/helpers.js.map +0 -1
  95. package/dist/index.d.ts +0 -37
  96. package/dist/index.d.ts.map +0 -1
  97. package/dist/index.js.map +0 -1
  98. package/dist/laundryWasher.d.ts +0 -243
  99. package/dist/laundryWasher.d.ts.map +0 -1
  100. package/dist/laundryWasher.js.map +0 -1
  101. package/dist/logger/export.d.ts +0 -2
  102. package/dist/logger/export.d.ts.map +0 -1
  103. package/dist/logger/export.js.map +0 -1
  104. package/dist/matter/behaviors.d.ts +0 -2
  105. package/dist/matter/behaviors.d.ts.map +0 -1
  106. package/dist/matter/behaviors.js.map +0 -1
  107. package/dist/matter/clusters.d.ts +0 -2
  108. package/dist/matter/clusters.d.ts.map +0 -1
  109. package/dist/matter/clusters.js.map +0 -1
  110. package/dist/matter/devices.d.ts +0 -2
  111. package/dist/matter/devices.d.ts.map +0 -1
  112. package/dist/matter/devices.js.map +0 -1
  113. package/dist/matter/endpoints.d.ts +0 -2
  114. package/dist/matter/endpoints.d.ts.map +0 -1
  115. package/dist/matter/endpoints.js.map +0 -1
  116. package/dist/matter/export.d.ts +0 -5
  117. package/dist/matter/export.d.ts.map +0 -1
  118. package/dist/matter/export.js.map +0 -1
  119. package/dist/matter/types.d.ts +0 -3
  120. package/dist/matter/types.d.ts.map +0 -1
  121. package/dist/matter/types.js.map +0 -1
  122. package/dist/matterbridge.d.ts +0 -445
  123. package/dist/matterbridge.d.ts.map +0 -1
  124. package/dist/matterbridge.js.map +0 -1
  125. package/dist/matterbridgeAccessoryPlatform.d.ts +0 -40
  126. package/dist/matterbridgeAccessoryPlatform.d.ts.map +0 -1
  127. package/dist/matterbridgeAccessoryPlatform.js.map +0 -1
  128. package/dist/matterbridgeBehaviors.d.ts +0 -1333
  129. package/dist/matterbridgeBehaviors.d.ts.map +0 -1
  130. package/dist/matterbridgeBehaviors.js.map +0 -1
  131. package/dist/matterbridgeDeviceTypes.d.ts +0 -644
  132. package/dist/matterbridgeDeviceTypes.d.ts.map +0 -1
  133. package/dist/matterbridgeDeviceTypes.js.map +0 -1
  134. package/dist/matterbridgeDynamicPlatform.d.ts +0 -40
  135. package/dist/matterbridgeDynamicPlatform.d.ts.map +0 -1
  136. package/dist/matterbridgeDynamicPlatform.js.map +0 -1
  137. package/dist/matterbridgeEndpoint.d.ts +0 -1145
  138. package/dist/matterbridgeEndpoint.d.ts.map +0 -1
  139. package/dist/matterbridgeEndpoint.js.map +0 -1
  140. package/dist/matterbridgeEndpointHelpers.d.ts +0 -3083
  141. package/dist/matterbridgeEndpointHelpers.d.ts.map +0 -1
  142. package/dist/matterbridgeEndpointHelpers.js.map +0 -1
  143. package/dist/matterbridgePlatform.d.ts +0 -290
  144. package/dist/matterbridgePlatform.d.ts.map +0 -1
  145. package/dist/matterbridgePlatform.js.map +0 -1
  146. package/dist/matterbridgeTypes.d.ts +0 -196
  147. package/dist/matterbridgeTypes.d.ts.map +0 -1
  148. package/dist/matterbridgeTypes.js.map +0 -1
  149. package/dist/pluginManager.d.ts +0 -273
  150. package/dist/pluginManager.d.ts.map +0 -1
  151. package/dist/pluginManager.js.map +0 -1
  152. package/dist/roboticVacuumCleaner.d.ts +0 -102
  153. package/dist/roboticVacuumCleaner.d.ts.map +0 -1
  154. package/dist/roboticVacuumCleaner.js.map +0 -1
  155. package/dist/shelly.d.ts +0 -161
  156. package/dist/shelly.d.ts.map +0 -1
  157. package/dist/shelly.js.map +0 -1
  158. package/dist/storage/export.d.ts +0 -2
  159. package/dist/storage/export.d.ts.map +0 -1
  160. package/dist/storage/export.js.map +0 -1
  161. package/dist/update.d.ts +0 -58
  162. package/dist/update.d.ts.map +0 -1
  163. package/dist/update.js.map +0 -1
  164. package/dist/utils/colorUtils.d.ts +0 -61
  165. package/dist/utils/colorUtils.d.ts.map +0 -1
  166. package/dist/utils/colorUtils.js.map +0 -1
  167. package/dist/utils/commandLine.d.ts +0 -58
  168. package/dist/utils/commandLine.d.ts.map +0 -1
  169. package/dist/utils/commandLine.js.map +0 -1
  170. package/dist/utils/copyDirectory.d.ts +0 -32
  171. package/dist/utils/copyDirectory.d.ts.map +0 -1
  172. package/dist/utils/copyDirectory.js.map +0 -1
  173. package/dist/utils/createDirectory.d.ts +0 -32
  174. package/dist/utils/createDirectory.d.ts.map +0 -1
  175. package/dist/utils/createDirectory.js.map +0 -1
  176. package/dist/utils/createZip.d.ts +0 -38
  177. package/dist/utils/createZip.d.ts.map +0 -1
  178. package/dist/utils/createZip.js.map +0 -1
  179. package/dist/utils/deepCopy.d.ts +0 -31
  180. package/dist/utils/deepCopy.d.ts.map +0 -1
  181. package/dist/utils/deepCopy.js.map +0 -1
  182. package/dist/utils/deepEqual.d.ts +0 -53
  183. package/dist/utils/deepEqual.d.ts.map +0 -1
  184. package/dist/utils/deepEqual.js.map +0 -1
  185. package/dist/utils/export.d.ts +0 -12
  186. package/dist/utils/export.d.ts.map +0 -1
  187. package/dist/utils/export.js.map +0 -1
  188. package/dist/utils/hex.d.ts +0 -48
  189. package/dist/utils/hex.d.ts.map +0 -1
  190. package/dist/utils/hex.js.map +0 -1
  191. package/dist/utils/isvalid.d.ts +0 -102
  192. package/dist/utils/isvalid.d.ts.map +0 -1
  193. package/dist/utils/isvalid.js.map +0 -1
  194. package/dist/utils/network.d.ts +0 -69
  195. package/dist/utils/network.d.ts.map +0 -1
  196. package/dist/utils/network.js.map +0 -1
  197. package/dist/utils/spawn.d.ts +0 -12
  198. package/dist/utils/spawn.d.ts.map +0 -1
  199. package/dist/utils/spawn.js.map +0 -1
  200. package/dist/utils/wait.d.ts +0 -52
  201. package/dist/utils/wait.d.ts.map +0 -1
  202. package/dist/utils/wait.js.map +0 -1
  203. package/dist/waterHeater.d.ts +0 -90
  204. package/dist/waterHeater.d.ts.map +0 -1
  205. package/dist/waterHeater.js.map +0 -1
  206. package/tsconfig.jest.json +0 -8
  207. package/tsconfig.production.json +0 -13
@@ -1,27 +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.2
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
- // AnsiLogger module
24
- import { AnsiLogger, UNDERLINE, UNDERLINEOFF, BLUE, db, er, nf, nt, rs, wr } from './logger/export.js';
1
+ import { AnsiLogger, UNDERLINE, UNDERLINEOFF, BLUE, db, er, nf, nt, rs, wr } from 'node-ansi-logger';
25
2
  import { plg, typ } from './matterbridgeTypes.js';
26
3
  export class PluginManager {
27
4
  _plugins = new Map();
@@ -30,9 +7,8 @@ export class PluginManager {
30
7
  log;
31
8
  constructor(matterbridge) {
32
9
  this.matterbridge = matterbridge;
33
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
10
  this.nodeContext = matterbridge.nodeContext;
35
- this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: matterbridge.log.logLevel });
11
+ this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4, logLevel: matterbridge.log.logLevel });
36
12
  this.log.debug('Matterbridge plugin manager starting...');
37
13
  }
38
14
  get length() {
@@ -69,7 +45,6 @@ export class PluginManager {
69
45
  }
70
46
  catch (err) {
71
47
  this.log.error(`Error processing forEach plugin ${plg}${plugin.name}${er}: ${err instanceof Error ? err.message + '\n' + err.stack : err}`);
72
- // throw error;
73
48
  }
74
49
  });
75
50
  await Promise.all(tasks);
@@ -77,31 +52,13 @@ export class PluginManager {
77
52
  set logLevel(logLevel) {
78
53
  this.log.logLevel = logLevel;
79
54
  }
80
- /**
81
- * Loads registered plugins from storage.
82
- *
83
- * This method retrieves an array of registered plugins from the storage and converts it
84
- * into a map where the plugin names are the keys and the plugin objects are the values.
85
- *
86
- * @returns {Promise<RegisteredPlugin[]>} A promise that resolves to an array of registered plugins.
87
- */
88
55
  async loadFromStorage() {
89
- // Load the array from storage and convert it to a map
90
56
  const pluginsArray = await this.nodeContext.get('plugins', []);
91
57
  for (const plugin of pluginsArray)
92
58
  this._plugins.set(plugin.name, plugin);
93
59
  return pluginsArray;
94
60
  }
95
- /**
96
- * Loads registered plugins from storage.
97
- *
98
- * This method retrieves an array of registered plugins from the storage and converts it
99
- * into a map where the plugin names are the keys and the plugin objects are the values.
100
- *
101
- * @returns {Promise<RegisteredPlugin[]>} A promise that resolves to an array of registered plugins.
102
- */
103
61
  async saveToStorage() {
104
- // Convert the map to an array
105
62
  const plugins = [];
106
63
  const pluginArrayFromMap = Array.from(this._plugins.values());
107
64
  for (const plugin of pluginArrayFromMap) {
@@ -121,20 +78,13 @@ export class PluginManager {
121
78
  this.log.debug(`Saved ${BLUE}${plugins.length}${db} plugins to storage`);
122
79
  return plugins.length;
123
80
  }
124
- /**
125
- * Resolves the name of a plugin by loading and parsing its package.json file.
126
- * @param {string} pluginPath - The path to the plugin or the path to the plugin's package.json file.
127
- * @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.
128
- */
129
81
  async resolve(pluginPath) {
130
82
  const { default: path } = await import('node:path');
131
83
  const { promises } = await import('node:fs');
132
84
  if (!pluginPath.endsWith('package.json'))
133
85
  pluginPath = path.join(pluginPath, 'package.json');
134
- // Resolve the package.json of the plugin
135
86
  let packageJsonPath = path.resolve(pluginPath);
136
87
  this.log.debug(`Resolving plugin path ${plg}${packageJsonPath}${db}`);
137
- // Check if the package.json file exists
138
88
  try {
139
89
  await promises.access(packageJsonPath);
140
90
  }
@@ -144,9 +94,7 @@ export class PluginManager {
144
94
  this.log.debug(`Trying at ${plg}${packageJsonPath}${db}`);
145
95
  }
146
96
  try {
147
- // Load the package.json of the plugin
148
97
  const packageJson = JSON.parse(await promises.readFile(packageJsonPath, 'utf8'));
149
- // Check for main issues
150
98
  if (!packageJson.name) {
151
99
  this.log.error(`Package.json name not found at ${packageJsonPath}`);
152
100
  return null;
@@ -159,7 +107,6 @@ export class PluginManager {
159
107
  this.log.error(`Plugin at ${packageJsonPath} has no main entrypoint in package.json`);
160
108
  return null;
161
109
  }
162
- // Check for @project-chip and @matter packages in dependencies and devDependencies
163
110
  const checkForProjectChipPackages = (dependencies) => {
164
111
  return Object.keys(dependencies).filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matter'));
165
112
  };
@@ -181,7 +128,6 @@ export class PluginManager {
181
128
  this.log.error(`Please open an issue on the plugin repository to remove them.`);
182
129
  return null;
183
130
  }
184
- // Check for matterbridge package in dependencies and devDependencies
185
131
  const checkForMatterbridgePackage = (dependencies) => {
186
132
  return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
187
133
  };
@@ -211,12 +157,6 @@ export class PluginManager {
211
157
  return null;
212
158
  }
213
159
  }
214
- /**
215
- * Get the author of a plugin from its package.json.
216
- *
217
- * @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
218
- * @returns {string} The author of the plugin, or 'Unknown author' if not found.
219
- */
220
160
  getAuthor(packageJson) {
221
161
  if (packageJson.author && typeof packageJson.author === 'string')
222
162
  return packageJson.author;
@@ -224,12 +164,6 @@ export class PluginManager {
224
164
  return packageJson.author.name;
225
165
  return 'Unknown author';
226
166
  }
227
- /**
228
- * Get the homepage of a plugin from its package.json.
229
- *
230
- * @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
231
- * @returns {string | undefined} The homepage of the plugin, or undefined if not found.
232
- */
233
167
  getHomepage(packageJson) {
234
168
  if (packageJson.homepage && typeof packageJson.homepage === 'string' && packageJson.homepage.includes('http')) {
235
169
  return packageJson.homepage.replace('git+', '').replace('.git', '');
@@ -238,14 +172,7 @@ export class PluginManager {
238
172
  return packageJson.repository.url.replace('git+', '').replace('.git', '');
239
173
  }
240
174
  }
241
- /**
242
- * Get the help URL of a plugin from its package.json.
243
- *
244
- * @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
245
- * @returns {string | undefined} The URL to the help page or to the README file, or undefined if not found.
246
- */
247
175
  getHelp(packageJson) {
248
- // If there's a help field that looks like a URL, return it.
249
176
  if (packageJson.help && typeof packageJson.help === 'string' && packageJson.help.startsWith('http')) {
250
177
  return packageJson.help;
251
178
  }
@@ -256,14 +183,7 @@ export class PluginManager {
256
183
  return packageJson.homepage.replace('git+', '').replace('.git', '');
257
184
  }
258
185
  }
259
- /**
260
- * Get the changelog URL of a plugin from its package.json.
261
- *
262
- * @param {Record<string, string | number | Record<string, string | number | object>>} packageJson - The package.json object of the plugin.
263
- * @returns {string | undefined} The URL to the CHANGELOG file, or undefined if not found.
264
- */
265
186
  getChangelog(packageJson) {
266
- // If there's a changelog field that looks like a URL, return it.
267
187
  if (packageJson.changelog && typeof packageJson.changelog === 'string' && packageJson.changelog.startsWith('http')) {
268
188
  return packageJson.changelog;
269
189
  }
@@ -274,13 +194,6 @@ export class PluginManager {
274
194
  return packageJson.homepage.replace('git+', '').replace('.git', '');
275
195
  }
276
196
  }
277
- /**
278
- * Get the first funding URL(s) of a plugin from its package.json.
279
- *
280
- * @param {Record<string, any>} packageJson - The package.json object of the plugin.
281
- * @returns {string | undefined} The first funding URLs, or undefined if not found.
282
- */
283
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
284
197
  getFunding(packageJson) {
285
198
  const funding = packageJson.funding;
286
199
  if (!funding)
@@ -289,24 +202,16 @@ export class PluginManager {
289
202
  return;
290
203
  if (typeof funding === 'string' && funding.startsWith('http'))
291
204
  return funding;
292
- // Normalize funding into an array.
293
205
  const fundingEntries = Array.isArray(funding) ? funding : [funding];
294
206
  for (const entry of fundingEntries) {
295
207
  if (entry && typeof entry === 'string' && entry.startsWith('http')) {
296
- // If the funding entry is a string, assume it is a URL.
297
208
  return entry;
298
209
  }
299
210
  else if (entry && typeof entry === 'object' && typeof entry.url === 'string' && entry.url.startsWith('http')) {
300
- // If it's an object with a 'url' property, use that.
301
211
  return entry.url;
302
212
  }
303
213
  }
304
214
  }
305
- /**
306
- * Loads and parse the plugin package.json and returns it.
307
- * @param {RegisteredPlugin} plugin - The plugin to load the package from.
308
- * @returns A Promise that resolves to the package.json object or null if the package.json could not be loaded.
309
- */
310
215
  async parse(plugin) {
311
216
  const { promises } = await import('node:fs');
312
217
  try {
@@ -338,7 +243,6 @@ export class PluginManager {
338
243
  this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no path`);
339
244
  if (!plugin.type)
340
245
  this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no type`);
341
- // Check for @project-chip and @matter packages in dependencies and devDependencies
342
246
  const checkForProjectChipPackages = (dependencies) => {
343
247
  return Object.keys(dependencies).filter((pkg) => pkg.startsWith('@project-chip') || pkg.startsWith('@matter'));
344
248
  };
@@ -360,7 +264,6 @@ export class PluginManager {
360
264
  this.log.error(`Please open an issue on the plugin repository to remove them.`);
361
265
  return null;
362
266
  }
363
- // Check for matterbridge package in dependencies and devDependencies
364
267
  const checkForMatterbridgePackage = (dependencies) => {
365
268
  return Object.keys(dependencies).filter((pkg) => pkg === 'matterbridge');
366
269
  };
@@ -390,16 +293,6 @@ export class PluginManager {
390
293
  return null;
391
294
  }
392
295
  }
393
- /**
394
- * Enables a plugin by its name or path.
395
- *
396
- * This method enables a plugin by setting its `enabled` property to `true` and saving the updated
397
- * plugin information to storage. It first checks if the plugin is already registered in the `_plugins` map.
398
- * If not, it attempts to resolve the plugin's `package.json` file to retrieve its name and enable it.
399
- *
400
- * @param {string} nameOrPath - The name or path of the plugin to enable.
401
- * @returns {Promise<RegisteredPlugin | null>} A promise that resolves to the enabled plugin object, or null if the plugin could not be enabled.
402
- */
403
296
  async enable(nameOrPath) {
404
297
  const { promises } = await import('node:fs');
405
298
  if (!nameOrPath || nameOrPath === '')
@@ -433,16 +326,6 @@ export class PluginManager {
433
326
  return null;
434
327
  }
435
328
  }
436
- /**
437
- * Enables a plugin by its name or path.
438
- *
439
- * This method enables a plugin by setting its `enabled` property to `true` and saving the updated
440
- * plugin information to storage. It first checks if the plugin is already registered in the `_plugins` map.
441
- * If not, it attempts to resolve the plugin's `package.json` file to retrieve its name and enable it.
442
- *
443
- * @param {string} nameOrPath - The name or path of the plugin to enable.
444
- * @returns {Promise<RegisteredPlugin | null>} A promise that resolves to the enabled plugin object, or null if the plugin could not be enabled.
445
- */
446
329
  async disable(nameOrPath) {
447
330
  const { promises } = await import('node:fs');
448
331
  if (!nameOrPath || nameOrPath === '')
@@ -476,16 +359,6 @@ export class PluginManager {
476
359
  return null;
477
360
  }
478
361
  }
479
- /**
480
- * Removes a plugin by its name or path.
481
- *
482
- * This method removes a plugin from the `_plugins` map and saves the updated plugin information to storage.
483
- * It first checks if the plugin is already registered in the `_plugins` map. If not, it attempts to resolve
484
- * the plugin's `package.json` file to retrieve its name and remove it.
485
- *
486
- * @param {string} nameOrPath - The name or path of the plugin to remove.
487
- * @returns {Promise<RegisteredPlugin | null>} A promise that resolves to the removed plugin object, or null if the plugin could not be removed.
488
- */
489
362
  async remove(nameOrPath) {
490
363
  const { promises } = await import('node:fs');
491
364
  if (!nameOrPath || nameOrPath === '')
@@ -519,17 +392,6 @@ export class PluginManager {
519
392
  return null;
520
393
  }
521
394
  }
522
- /**
523
- * Adds a plugin by its name or path.
524
- *
525
- * This method adds a plugin to the plugins map and saves the updated plugin information to storage.
526
- * It first resolves the plugin's `package.json` file to retrieve its details. If the plugin is already
527
- * registered, it logs an info message and returns null. Otherwise, it registers the plugin, enables it,
528
- * and saves the updated plugin information to storage.
529
- *
530
- * @param {string} nameOrPath - The name or path of the plugin to add.
531
- * @returns {Promise<RegisteredPlugin | null>} A promise that resolves to the added plugin object, or null if the plugin could not be added.
532
- */
533
395
  async add(nameOrPath) {
534
396
  const { promises } = await import('node:fs');
535
397
  if (!nameOrPath || nameOrPath === '')
@@ -564,15 +426,6 @@ export class PluginManager {
564
426
  return null;
565
427
  }
566
428
  }
567
- /**
568
- * Installs a plugin by its name.
569
- *
570
- * This method first uninstalls any existing version of the plugin, then installs the plugin globally using npm.
571
- * It logs the installation process and retrieves the installed version of the plugin.
572
- *
573
- * @param {string} name - The name of the plugin to install.
574
- * @returns {Promise<string | undefined>} A promise that resolves to the installed version of the plugin, or undefined if the installation failed.
575
- */
576
429
  async install(name) {
577
430
  const { exec } = await import('node:child_process');
578
431
  await this.uninstall(name);
@@ -587,14 +440,11 @@ export class PluginManager {
587
440
  else {
588
441
  this.log.info(`Installed plugin ${plg}${name}${nf}`);
589
442
  this.log.debug(`Installed plugin ${plg}${name}${db}: ${stdout}`);
590
- // Get the installed version
591
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
592
443
  exec(`npm list -g ${name} --depth=0`, (listError, listStdout, listStderr) => {
593
444
  if (listError) {
594
445
  this.log.error(`List error: ${listError}`);
595
446
  resolve(undefined);
596
447
  }
597
- // Clean the output to get only the package name and version
598
448
  const lines = listStdout.split('\n');
599
449
  const versionLine = lines.find((line) => line.includes(`${name}@`));
600
450
  if (versionLine) {
@@ -610,15 +460,6 @@ export class PluginManager {
610
460
  });
611
461
  });
612
462
  }
613
- /**
614
- * Uninstalls a plugin by its name.
615
- *
616
- * This method uninstalls a globally installed plugin using npm. It logs the uninstallation process
617
- * and returns the name of the uninstalled plugin if successful, or undefined if the uninstallation failed.
618
- *
619
- * @param {string} name - The name of the plugin to uninstall.
620
- * @returns {Promise<string | undefined>} A promise that resolves to the name of the uninstalled plugin, or undefined if the uninstallation failed.
621
- */
622
463
  async uninstall(name) {
623
464
  const { exec } = await import('node:child_process');
624
465
  this.log.info(`Uninstalling plugin ${plg}${name}${nf}`);
@@ -637,14 +478,6 @@ export class PluginManager {
637
478
  });
638
479
  });
639
480
  }
640
- /**
641
- * Loads a plugin and returns the corresponding MatterbridgePlatform instance.
642
- * @param {RegisteredPlugin} plugin - The plugin to load.
643
- * @param {boolean} start - Optional flag indicating whether to start the plugin after loading. Default is false.
644
- * @param {string} message - Optional message to pass to the plugin when starting.
645
- * @param {boolean} configure - Optional flag indicating whether to configure the plugin after loading. Default is false.
646
- * @returns {Promise<MatterbridgePlatform | undefined>} A Promise that resolves to the loaded MatterbridgePlatform instance or undefined.
647
- */
648
481
  async load(plugin, start = false, message = '', configure = false) {
649
482
  const { promises } = await import('node:fs');
650
483
  const { default: path } = await import('node:path');
@@ -658,20 +491,15 @@ export class PluginManager {
658
491
  }
659
492
  this.log.info(`Loading plugin ${plg}${plugin.name}${nf} type ${typ}${plugin.type}${nf}`);
660
493
  try {
661
- // Load the package.json of the plugin
662
494
  const packageJson = JSON.parse(await promises.readFile(plugin.path, 'utf8'));
663
- // Resolve the main module path relative to package.json
664
495
  const pluginEntry = path.resolve(path.dirname(plugin.path), packageJson.main);
665
- // Dynamically import the plugin
666
496
  const { pathToFileURL } = await import('node:url');
667
497
  const pluginUrl = pathToFileURL(pluginEntry);
668
498
  this.log.debug(`Importing plugin ${plg}${plugin.name}${db} from ${pluginUrl.href}`);
669
499
  const pluginInstance = await import(pluginUrl.href);
670
500
  this.log.debug(`Imported plugin ${plg}${plugin.name}${db} from ${pluginUrl.href}`);
671
- // Call the default export function of the plugin, passing this MatterBridge instance, the log and the config
672
501
  if (pluginInstance.default) {
673
502
  const config = await this.loadConfig(plugin);
674
- // 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.
675
503
  plugin.name = packageJson.name;
676
504
  plugin.description = packageJson.description ?? 'No description';
677
505
  plugin.version = packageJson.version;
@@ -680,7 +508,7 @@ export class PluginManager {
680
508
  plugin.schemaJson = await this.loadSchema(plugin);
681
509
  config.name = plugin.name;
682
510
  config.version = packageJson.version;
683
- const log = new AnsiLogger({ logName: plugin.description ?? 'No description', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: config.debug ? "debug" /* LogLevel.DEBUG */ : this.matterbridge.log.logLevel });
511
+ const log = new AnsiLogger({ logName: plugin.description ?? 'No description', logTimestampFormat: 4, logLevel: config.debug ? "debug" : this.matterbridge.log.logLevel });
684
512
  const platform = pluginInstance.default(this.matterbridge, log, config);
685
513
  config.type = platform.type;
686
514
  platform.name = packageJson.name;
@@ -699,7 +527,7 @@ export class PluginManager {
699
527
  plugin.loaded = true;
700
528
  plugin.registeredDevices = 0;
701
529
  plugin.addedDevices = 0;
702
- await this.saveToStorage(); // Save the plugin to storage
530
+ await this.saveToStorage();
703
531
  this.log.notice(`Loaded plugin ${plg}${plugin.name}${nt} type ${typ}${platform.type}${nt} (entrypoint ${UNDERLINE}${pluginEntry}${UNDERLINEOFF})`);
704
532
  if (start)
705
533
  await this.start(plugin, message, false);
@@ -718,14 +546,6 @@ export class PluginManager {
718
546
  }
719
547
  return undefined;
720
548
  }
721
- /**
722
- * Starts a plugin.
723
- *
724
- * @param {RegisteredPlugin} plugin - The plugin to start.
725
- * @param {string} [message] - Optional message to pass to the plugin's onStart method.
726
- * @param {boolean} [configure] - Indicates whether to configure the plugin after starting (default false).
727
- * @returns {Promise<RegisteredPlugin | undefined>} A promise that resolves when the plugin is started successfully, or rejects with an error if starting the plugin fails.
728
- */
729
549
  async start(plugin, message, configure = false) {
730
550
  if (!plugin.loaded) {
731
551
  this.log.error(`Plugin ${plg}${plugin.name}${er} not loaded`);
@@ -755,12 +575,6 @@ export class PluginManager {
755
575
  }
756
576
  return undefined;
757
577
  }
758
- /**
759
- * Configures a plugin.
760
- *
761
- * @param {RegisteredPlugin} plugin - The plugin to configure.
762
- * @returns {Promise<RegisteredPlugin | undefined>} A promise that resolves when the plugin is configured successfully, or rejects with an error if configuration fails.
763
- */
764
578
  async configure(plugin) {
765
579
  if (!plugin.loaded) {
766
580
  this.log.error(`Plugin ${plg}${plugin.name}${er} not loaded`);
@@ -791,18 +605,6 @@ export class PluginManager {
791
605
  }
792
606
  return undefined;
793
607
  }
794
- /**
795
- * Shuts down a plugin.
796
- *
797
- * This method shuts down a plugin by calling its `onShutdown` method and resetting its state.
798
- * It logs the shutdown process and optionally removes all devices associated with the plugin.
799
- *
800
- * @param {RegisteredPlugin} plugin - The plugin to shut down.
801
- * @param {string} [reason] - The reason for shutting down the plugin.
802
- * @param {boolean} [removeAllDevices=false] - Whether to remove all devices associated with the plugin.
803
- * @param {boolean} [force=false] - Whether to force the shutdown even if the plugin is not loaded or started.
804
- * @returns {Promise<RegisteredPlugin | undefined>} A promise that resolves to the shut down plugin object, or undefined if the shutdown failed.
805
- */
806
608
  async shutdown(plugin, reason, removeAllDevices = false, force = false) {
807
609
  this.log.debug(`Shutting down plugin ${plg}${plugin.name}${db}`);
808
610
  if (!plugin.loaded) {
@@ -845,15 +647,6 @@ export class PluginManager {
845
647
  }
846
648
  return undefined;
847
649
  }
848
- /**
849
- * Loads the configuration for a plugin.
850
- * If the configuration file exists, it reads the file and returns the parsed JSON data.
851
- * If the configuration file does not exist, it creates a new file with default configuration and returns it.
852
- * If any error occurs during file access or creation, it logs an error and return un empty config.
853
- *
854
- * @param {RegisteredPlugin} plugin - The plugin for which to load the configuration.
855
- * @returns {Promise<PlatformConfig>} A promise that resolves to the loaded or created configuration.
856
- */
857
650
  async loadConfig(plugin) {
858
651
  const { default: path } = await import('node:path');
859
652
  const { promises } = await import('node:fs');
@@ -864,8 +657,6 @@ export class PluginManager {
864
657
  const data = await promises.readFile(configFile, 'utf8');
865
658
  const config = JSON.parse(data);
866
659
  this.log.debug(`Loaded config file ${configFile} for plugin ${plg}${plugin.name}${db}.`);
867
- // this.log.debug(`Loaded config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
868
- // The first time a plugin is added to the system, the config file is created with the plugin name and type "AnyPlatform".
869
660
  config.name = plugin.name;
870
661
  config.type = plugin.type;
871
662
  if (config.debug === undefined)
@@ -889,7 +680,6 @@ export class PluginManager {
889
680
  try {
890
681
  await promises.writeFile(configFile, JSON.stringify(config, null, 2), 'utf8');
891
682
  this.log.debug(`Created config file ${configFile} for plugin ${plg}${plugin.name}${db}.`);
892
- // this.log.debug(`Created config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
893
683
  return config;
894
684
  }
895
685
  catch (err) {
@@ -903,19 +693,6 @@ export class PluginManager {
903
693
  }
904
694
  }
905
695
  }
906
- /**
907
- * Saves the configuration of a plugin to a file.
908
- *
909
- * This method saves the configuration of the specified plugin to a JSON file in the matterbridge directory.
910
- * If the plugin's configuration is not found, it logs an error and rejects the promise. If the configuration
911
- * is successfully saved, it logs a debug message. If an error occurs during the file write operation, it logs
912
- * the error and rejects the promise.
913
- *
914
- * @param {RegisteredPlugin} plugin - The plugin whose configuration is to be saved.
915
- * @param {boolean} [restartRequired=false] - Indicates whether a restart is required after saving the configuration.
916
- * @returns {Promise<void>} A promise that resolves when the configuration is successfully saved, or rejects if an error occurs.
917
- * @throws {Error} If the plugin's configuration is not found.
918
- */
919
696
  async saveConfigFromPlugin(plugin, restartRequired = false) {
920
697
  const { default: path } = await import('node:path');
921
698
  const { promises } = await import('node:fs');
@@ -930,7 +707,6 @@ export class PluginManager {
930
707
  if (restartRequired)
931
708
  plugin.restartRequired = true;
932
709
  this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}`);
933
- // this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, plugin.platform.config);
934
710
  return Promise.resolve();
935
711
  }
936
712
  catch (err) {
@@ -938,20 +714,6 @@ export class PluginManager {
938
714
  return Promise.reject(err);
939
715
  }
940
716
  }
941
- /**
942
- * Saves the configuration of a plugin from a JSON object to a file.
943
- *
944
- * This method saves the provided configuration of the specified plugin to a JSON file in the matterbridge directory.
945
- * It first checks if the configuration data is valid by ensuring it contains the correct name and type, and matches
946
- * the plugin's name. If the configuration data is invalid, it logs an error and returns. If the configuration is
947
- * successfully saved, it updates the plugin's `configJson` property and logs a debug message. If an error occurs
948
- * during the file write operation, it logs the error and returns.
949
- *
950
- * @param {RegisteredPlugin} plugin - The plugin whose configuration is to be saved.
951
- * @param {PlatformConfig} config - The configuration data to be saved.
952
- * @param {boolean} [restartRequired=false] - Indicates whether a restart is required after saving the configuration.
953
- * @returns {Promise<void>} A promise that resolves when the configuration is successfully saved, or returns if an error occurs.
954
- */
955
717
  async saveConfigFromJson(plugin, config, restartRequired = false) {
956
718
  const { default: path } = await import('node:path');
957
719
  const { promises } = await import('node:fs');
@@ -970,23 +732,12 @@ export class PluginManager {
970
732
  plugin.platform.onConfigChanged(config).catch((err) => this.log.error(`Error calling onConfigChanged for plugin ${plg}${plugin.name}${er}: ${err}`));
971
733
  }
972
734
  this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}`);
973
- // this.log.debug(`Saved config file ${configFile} for plugin ${plg}${plugin.name}${db}.\nConfig:${rs}\n`, config);
974
735
  }
975
736
  catch (err) {
976
737
  this.log.error(`Error saving config file ${configFile} for plugin ${plg}${plugin.name}${er}: ${err instanceof Error ? err.message + '\n' + err.stack : err}`);
977
738
  return;
978
739
  }
979
740
  }
980
- /**
981
- * Loads the schema for a plugin.
982
- *
983
- * This method attempts to load the schema file for the specified plugin. If the schema file is found,
984
- * it reads and parses the file, updates the schema's title and description, and logs the process.
985
- * If the schema file is not found, it logs the event and loads a default schema for the plugin.
986
- *
987
- * @param {RegisteredPlugin} plugin - The plugin whose schema is to be loaded.
988
- * @returns {Promise<PlatformSchema>} A promise that resolves to the loaded schema object, or the default schema if the schema file is not found.
989
- */
990
741
  async loadSchema(plugin) {
991
742
  const { promises } = await import('node:fs');
992
743
  const schemaFile = plugin.path.replace('package.json', `${plugin.name}.schema.json`);
@@ -997,29 +748,13 @@ export class PluginManager {
997
748
  schema.title = plugin.description;
998
749
  schema.description = plugin.name + ' v. ' + plugin.version + ' by ' + plugin.author;
999
750
  this.log.debug(`Loaded schema file ${schemaFile} for plugin ${plg}${plugin.name}${db}.`);
1000
- // this.log.debug(`Loaded schema file ${schemaFile} for plugin ${plg}${plugin.name}${db}.\nSchema:${rs}\n`, schema);
1001
751
  return schema;
1002
752
  }
1003
753
  catch (_err) {
1004
- // const nodeErr = err as NodeJS.ErrnoException;
1005
- // if (nodeErr.code === 'ENOENT') {
1006
754
  this.log.debug(`Schema file ${schemaFile} for plugin ${plg}${plugin.name}${db} not found. Loading default schema.`);
1007
- // } else {
1008
- // this.log.debug(`Schema file ${schemaFile} for plugin ${plg}${plugin.name}${db} not found. Loading default schema. Error: ${err instanceof Error ? err.message + '\n' + err.stack : err}`);
1009
- // }
1010
755
  return this.getDefaultSchema(plugin);
1011
756
  }
1012
757
  }
1013
- /**
1014
- * Returns the default schema for a plugin.
1015
- *
1016
- * This method generates a default schema object for the specified plugin. The schema includes
1017
- * metadata such as the plugin's title, description, version, and author. It also defines the
1018
- * properties of the schema, including the plugin's name, type, debug flag, and unregisterOnShutdown flag.
1019
- *
1020
- * @param {RegisteredPlugin} plugin - The plugin for which the default schema is to be generated.
1021
- * @returns {PlatformSchema} The default schema object for the plugin.
1022
- */
1023
758
  getDefaultSchema(plugin) {
1024
759
  return {
1025
760
  title: plugin.description,
@@ -1050,4 +785,3 @@ export class PluginManager {
1050
785
  };
1051
786
  }
1052
787
  }
1053
- //# sourceMappingURL=pluginManager.js.map