@runeya/runeya 1.33.24 → 1.33.25

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 (75) hide show
  1. package/node-red-contrib-runeya.tar +0 -0
  2. package/package.json +1 -1
  3. package/public/assets/App-Cuu3qapD.js +101 -0
  4. package/public/assets/{App-BGPtogo-.css → App-DZ8M5vya.css} +1 -1
  5. package/public/assets/{Bugs-BYVaGclE.js → Bugs-H-Otgxln.js} +1 -1
  6. package/public/assets/{Configs-CGdacJ7j.js → Configs-CS7LQ3j2.js} +1 -1
  7. package/public/assets/{CurrentEditor-CaZTvScp.js → CurrentEditor-DSg_c1cT.js} +1 -1
  8. package/public/assets/{DynamicComponent-u2mgF7SR.js → DynamicComponent-Cd8cbFTY.js} +1 -1
  9. package/public/assets/{Editor-BkDstUPD.js → Editor-BUC6Zjcy.js} +6 -6
  10. package/public/assets/{Git-Da_IiEci.js → Git-CWhmBLgo.js} +1 -1
  11. package/public/assets/{ImportCreate-MvJTSajS.js → ImportCreate-BMYQ7CRt.js} +1 -1
  12. package/public/assets/{Index-B63IO9GV.js → Index-CCt5RYhV.js} +1 -1
  13. package/public/assets/{Index-Dx1OujL3.js → Index-CKyiBy6h.js} +1 -1
  14. package/public/assets/{Index-BTX-OBp_.js → Index-CNTmcq3o.js} +1 -1
  15. package/public/assets/{Index-Cig3CHAr.js → Index-CvSNWhOl.js} +1 -1
  16. package/public/assets/{Index-tb_q4KJZ.js → Index-DXLLCB8w.js} +1 -1
  17. package/public/assets/{Index-CnwSqgC1.js → Index-_Myie1IE.js} +1 -1
  18. package/public/assets/{Init-CVpaullv.js → Init-ec91xg4K.js} +1 -1
  19. package/public/assets/{LeftLogo-mu8SETbq.js → LeftLogo-DdpN8uKw.js} +1 -1
  20. package/public/assets/{Logs-BhdfGaw5.css → Logs-C7U-WsYO.css} +1 -1
  21. package/public/assets/Logs-Dr0aVld6.js +74 -0
  22. package/public/assets/{Markdown-DA8Jvtc4.js → Markdown-CINu7VUT.js} +1 -1
  23. package/public/assets/{Modal-CFSt4VI3.js → Modal-CMVKUmmz.js} +1 -1
  24. package/public/assets/{Modals-DL7ezEul.js → Modals-UgnVGGTd.js} +1 -1
  25. package/public/assets/{NotUpToDate-Du0KDqto.js → NotUpToDate-Dv1x5laT.js} +1 -1
  26. package/public/assets/{Npm-D2i5dOQC.js → Npm-BQOhWPXB.js} +1 -1
  27. package/public/assets/{Overview-DRm-6OxF.js → Overview-CyhbZrp6.js} +1 -1
  28. package/public/assets/Overview-D94ypoub.css +1 -0
  29. package/public/assets/{Section-BIExc-vD.js → Section-DWZalQSy.js} +1 -1
  30. package/public/assets/{Settings-DUCkJDco.css → Settings-DvieCtW4.css} +1 -1
  31. package/public/assets/{Settings-sGatgaZA.js → Settings-gQ2r_ArG.js} +8 -8
  32. package/public/assets/{Spinner-BxlVMO5C.js → Spinner-BDdyfVPn.js} +1 -1
  33. package/public/assets/{StackChooser-C6QUL1ts.js → StackChooser-D4JG1V6p.js} +1 -1
  34. package/public/assets/{StackChooser-BbxiXmbz.js → StackChooser-Dy0nw-1k.js} +1 -1
  35. package/public/assets/{StackMultiple-VFMgpudb.js → StackMultiple-CXbZO3gp.js} +1 -1
  36. package/public/assets/{StackSingle-CNFNiJ6j.js → StackSingle-BrA92wNq.js} +1 -1
  37. package/public/assets/{Tabs-DOzRR3WD.js → Tabs-zx6MP1w5.js} +1 -1
  38. package/public/assets/{Theme-D5wc2JN5.js → Theme-CVJqEc74.js} +1 -1
  39. package/public/assets/{Toolbox-BctYsp_m.js → Toolbox-CeYvSlof.js} +1 -1
  40. package/public/assets/{cssMode-D6DX_pzi.js → cssMode-DRJB02N-.js} +1 -1
  41. package/public/assets/{currentEditor-CPSYuOXJ.js → currentEditor-Mutd140I.js} +1 -1
  42. package/public/assets/{freemarker2-QTuv0L1w.js → freemarker2-CUNqJsQJ.js} +1 -1
  43. package/public/assets/{fs-BKy6SF5M.js → fs-zCN6KWbV.js} +1 -1
  44. package/public/assets/{handlebars-DjsjeDRt.js → handlebars-DFPe5IUH.js} +1 -1
  45. package/public/assets/{html-CS11tPhf.js → html-iAZ8fYxX.js} +1 -1
  46. package/public/assets/{htmlMode-cW1qbNS1.js → htmlMode-CiLcIJ9M.js} +1 -1
  47. package/public/assets/{index-9SUUWz0Q.js → index-BYlmWHqo.js} +2 -2
  48. package/public/assets/{index-BVMisFgJ.js → index-BvK3ngOF.js} +4 -4
  49. package/public/assets/{index-L-hKesb9.js → index-BykKOUV5.js} +3 -3
  50. package/public/assets/{index-D2kTRQ0g.js → index-CED4m1pl.js} +2 -2
  51. package/public/assets/{index-B2Zn1t0F.js → index-CnHkskP1.js} +24 -24
  52. package/public/assets/{index-D6T2JqTJ.js → index-D6ITaiDq.js} +1 -1
  53. package/public/assets/{index-BAdR3mLX.js → index-D7eodgey.js} +10 -10
  54. package/public/assets/{index-DGs7mxSp.js → index-DlBh1BN-.js} +3 -3
  55. package/public/assets/{index-DljcUO2A.js → index-LXuPKlr_.js} +1 -1
  56. package/public/assets/{index-BIZVTENX.js → index-r5zB7DkH.js} +5 -5
  57. package/public/assets/{javascript-D8fzI4Kf.js → javascript-DRLQS2xP.js} +1 -1
  58. package/public/assets/{json-tree-view-vue3.es-YUK7eu-v.js → json-tree-view-vue3.es-BAcuRLYG.js} +1 -1
  59. package/public/assets/{jsonMode-Bk3_CK5T.js → jsonMode-BKVfjW9m.js} +1 -1
  60. package/public/assets/{liquid-3VzXePtH.js → liquid-CBIGo8D7.js} +1 -1
  61. package/public/assets/{mdx-DokQ4srC.js → mdx-D_MaKLKm.js} +1 -1
  62. package/public/assets/{python-DqM5cWUD.js → python-ROmifk5f.js} +1 -1
  63. package/public/assets/{razor-C6qvoKqe.js → razor-B2BrIgAg.js} +1 -1
  64. package/public/assets/{router-BvhIqmd_.js → router-BmEvmcw4.js} +3 -3
  65. package/public/assets/{system-D0myLYD8.js → system-CmOEECxV.js} +1 -1
  66. package/public/assets/{tsMode-_FuGn5T1.js → tsMode-ur-_baj-.js} +1 -1
  67. package/public/assets/{typescript-DUGr9yKr.js → typescript-BI5fccq7.js} +1 -1
  68. package/public/assets/{xml-EjEx9Mzb.js → xml-C8ZhN0MF.js} +1 -1
  69. package/public/assets/{yaml-DPx0oNUg.js → yaml-DEXuQlV0.js} +1 -1
  70. package/public/index.html +1 -1
  71. package/www.js +167 -96
  72. package/www.js.map +1 -1
  73. package/public/assets/App-Bd0xshf7.js +0 -101
  74. package/public/assets/Logs-DRBJWBGG.js +0 -74
  75. package/public/assets/Overview-DZIOmzKx.css +0 -1
package/www.js CHANGED
@@ -202,20 +202,20 @@ var require_conflictStorage = __commonJS({
202
202
  var require_reencrypt_nodered = __commonJS({
203
203
  "helpers/reencrypt-nodered.js"(exports2, module2) {
204
204
  "use strict";
205
- var crypto = require("crypto");
205
+ var crypto2 = require("crypto");
206
206
  var { readFile, writeFile } = require("fs/promises");
207
207
  var encryptionAlgorithm = "aes-256-ctr";
208
208
  module2.exports = async function decryptCreds(oldSecret, newScret, path) {
209
- const oldKey = crypto.createHash("sha256").update(oldSecret).digest();
210
- const newKey = crypto.createHash("sha256").update(newScret).digest();
209
+ const oldKey = crypto2.createHash("sha256").update(oldSecret).digest();
210
+ const newKey = crypto2.createHash("sha256").update(newScret).digest();
211
211
  const cipher = JSON.parse(await readFile(path, "utf-8"));
212
212
  let flows = cipher["$"];
213
213
  const vector = Buffer.from(flows.substring(0, 32), "hex");
214
214
  flows = flows.substring(32);
215
- const decipher = crypto.createDecipheriv(encryptionAlgorithm, oldKey, vector);
215
+ const decipher = crypto2.createDecipheriv(encryptionAlgorithm, oldKey, vector);
216
216
  const decrypted = decipher.update(flows, "base64", "utf8") + decipher.final("utf8");
217
- const newVector = crypto.randomBytes(16);
218
- const newCipher = crypto.createCipheriv(encryptionAlgorithm, newKey, newVector);
217
+ const newVector = crypto2.randomBytes(16);
218
+ const newCipher = crypto2.createCipheriv(encryptionAlgorithm, newKey, newVector);
219
219
  const encrypted = newCipher.update(decrypted, "utf8", "base64") + newCipher.final("base64");
220
220
  await writeFile(path, JSON.stringify({
221
221
  "$": newVector.toString("hex") + encrypted
@@ -509,8 +509,8 @@ var require_routes3 = __commonJS({
509
509
  group: "Service",
510
510
  url: `/stack-single/${service.label}`
511
511
  }));
512
- const { plugins } = runeya;
513
- const _plugins = (await PromiseB2.map(Object.keys(plugins), (key) => plugins[key]).map(async (plugin) => [
512
+ const { plugins: plugins2 } = runeya;
513
+ const _plugins = (await PromiseB2.map(Object.keys(plugins2), (key) => plugins2[key]).map(async (plugin) => [
514
514
  ...await plugin?.finder?.(search, runeya)?.catch?.(() => []) || [],
515
515
  ...searchString(plugin.name, search) ? [{
516
516
  title: plugin.displayName || plugin.name,
@@ -2055,7 +2055,7 @@ var require_backend13 = __commonJS({
2055
2055
  var require_plugins = __commonJS({
2056
2056
  "../../modules/plugins-loader/backend/plugins.js"(exports2, module2) {
2057
2057
  "use strict";
2058
- var plugins = {
2058
+ var plugins2 = {
2059
2059
  bugs: require_backend(),
2060
2060
  configuration: require_backend2(),
2061
2061
  documentation: require_backend3(),
@@ -2070,8 +2070,8 @@ var require_plugins = __commonJS({
2070
2070
  docker: require_backend12(),
2071
2071
  nodered: require_backend13()
2072
2072
  };
2073
- module2.exports = Object.keys(plugins).reduce((acc, key) => {
2074
- if (plugins[key].enabled) acc[key] = plugins[key];
2073
+ module2.exports = Object.keys(plugins2).reduce((acc, key) => {
2074
+ if (plugins2[key].enabled) acc[key] = plugins2[key];
2075
2075
  return acc;
2076
2076
  }, {});
2077
2077
  }
@@ -2339,7 +2339,10 @@ var require_Parser = __commonJS({
2339
2339
  var nativeParsers = {
2340
2340
  [require_debug().id]: require_debug(),
2341
2341
  [require_json().id]: require_json(),
2342
- [require_link().id]: require_link()
2342
+ [require_link().id]: require_link(),
2343
+ "stack-monitor-parser-debug": { ...require_debug(), id: "stack-monitor-parser-debug" },
2344
+ "stack-monitor-parser-jsons": { ...require_json(), id: "stack-monitor-parser-jsons" },
2345
+ "stack-monitor-parser-links": { ...require_link(), id: "stack-monitor-parser-links" }
2343
2346
  };
2344
2347
  var Parser = class _Parser {
2345
2348
  /**
@@ -3244,7 +3247,7 @@ var require_stack = __commonJS({
3244
3247
  "models/stack.js"(exports2, module2) {
3245
3248
  "use strict";
3246
3249
  var { sockets: sockets2 } = require_src();
3247
- var plugins = require_plugins();
3250
+ var plugins2 = require_plugins();
3248
3251
  var PromiseB2 = require("bluebird");
3249
3252
  var Service = require_Service();
3250
3253
  var ports = require_ports();
@@ -3279,7 +3282,7 @@ var require_stack = __commonJS({
3279
3282
  Stack.currentWatches = [];
3280
3283
  Stack.currentEnvironment = null;
3281
3284
  Stack.Socket = sockets2;
3282
- Stack.plugins = plugins;
3285
+ Stack.plugins = plugins2;
3283
3286
  Stack.version = require_version().version || "";
3284
3287
  Stack.url = `http://localhost:${ports.http}`;
3285
3288
  Stack.port = +ports.http;
@@ -3426,9 +3429,9 @@ var require_stack = __commonJS({
3426
3429
  };
3427
3430
  var pluginsToLoad = (
3428
3431
  /** @type {(keyof typeof plugins)[]} */
3429
- Object.keys(plugins).reduce(
3432
+ Object.keys(plugins2).reduce(
3430
3433
  (p, key) => {
3431
- const plugin = plugins[key];
3434
+ const plugin = plugins2[key];
3432
3435
  if (plugin.export) {
3433
3436
  p[key] = typeof plugin.export === "function" && !/^\s*class\s+/.test(plugin.export.toString()) ? plugin.export(
3434
3437
  /** @type {StackWithPlugins} */
@@ -3535,7 +3538,7 @@ var require_crypto = __commonJS({
3535
3538
  "helpers/crypto.js"(exports2, module2) {
3536
3539
  "use strict";
3537
3540
  var _sodium = require("libsodium-wrappers");
3538
- var crypto = require("crypto");
3541
+ var crypto2 = require("crypto");
3539
3542
  var { sockets: sockets2 } = require_src();
3540
3543
  var conflictStorage = require_conflictStorage();
3541
3544
  var path = require("path");
@@ -3555,7 +3558,7 @@ var require_crypto = __commonJS({
3555
3558
  }
3556
3559
  let nonce;
3557
3560
  if (additionnalNonce) {
3558
- const combinedHash = crypto.createHash("blake2b512").update(data + additionnalNonce).digest();
3561
+ const combinedHash = crypto2.createHash("blake2b512").update(data + additionnalNonce).digest();
3559
3562
  nonce = combinedHash.slice(0, sodium.crypto_secretbox_NONCEBYTES);
3560
3563
  } else {
3561
3564
  nonce = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES);
@@ -3854,40 +3857,11 @@ var require_createDefaultFiles = __commonJS({
3854
3857
  }
3855
3858
  });
3856
3859
 
3857
- // helpers/console.table.js
3858
- var require_console_table = __commonJS({
3859
- "helpers/console.table.js"(exports2, module2) {
3860
- "use strict";
3861
- var { Transform } = require("stream");
3862
- var { Console } = require("console");
3863
- function table(input) {
3864
- const ts = new Transform({ transform(chunk, enc, cb) {
3865
- cb(null, chunk);
3866
- } });
3867
- const logger = new Console({ stdout: ts });
3868
- logger.table(input);
3869
- const table2 = (ts.read() || "").toString();
3870
- let result = "";
3871
- for (const row of table2.split(/[\r\n]+/)) {
3872
- let r = row.replace(/[^┬]*┬/, "\u250C");
3873
- r = r.replace(/^├─*┼/, "\u251C");
3874
- r = r.replace(/│[^│]*/, "");
3875
- r = r.replace(/^└─*┴/, "\u2514");
3876
- r = r.replace(/'/g, " ");
3877
- result += `${r}
3878
- `;
3879
- }
3880
- console.log(result);
3881
- }
3882
- module2.exports = table;
3883
- }
3884
- });
3885
-
3886
3860
  // helpers/plugins.js
3887
3861
  var require_plugins2 = __commonJS({
3888
3862
  "helpers/plugins.js"(exports2, module2) {
3889
3863
  "use strict";
3890
- var plugins = require_plugins();
3864
+ var plugins2 = require_plugins();
3891
3865
  var Stack = require_stack();
3892
3866
  var { default: axios } = require("axios");
3893
3867
  var { tmpdir } = require("os");
@@ -3900,9 +3874,24 @@ var require_plugins2 = __commonJS({
3900
3874
  var args2 = require_args();
3901
3875
  var tar = require("tar");
3902
3876
  var dbConfig = dbs2.getDb("plugins", { encrypted: false, defaultData: [] });
3877
+ var dbPublicPlugins = dbs2.getDb("public-plugins", { encrypted: false, defaultData: [] });
3903
3878
  var { sockets: sockets2 } = require_src();
3904
3879
  var stack = require_stack();
3905
3880
  var debounce = require("debounce");
3881
+ var PromiseB2 = require("bluebird");
3882
+ var pluginsState = new Proxy({}, {
3883
+ get(target, prop) {
3884
+ return target[prop];
3885
+ },
3886
+ set(target, prop, value) {
3887
+ sockets2.emit("plugins:loading:progress", {
3888
+ ...value,
3889
+ plugin: prop
3890
+ });
3891
+ target[prop] = value;
3892
+ return true;
3893
+ }
3894
+ });
3906
3895
  var chokidar = null;
3907
3896
  if (process.env.NODE_ENV === "HFBXdZMJxLyJoua28asEaxRixJ6LriR7FnRzX6pwA7pFjZ") {
3908
3897
  chokidar = require("chokidar");
@@ -3912,7 +3901,7 @@ var require_plugins2 = __commonJS({
3912
3901
  var allPlugins = {};
3913
3902
  var loadedPlugins = {};
3914
3903
  var themes = {};
3915
- Object.keys(plugins).map((key) => plugins[
3904
+ Object.keys(plugins2).map((key) => plugins2[
3916
3905
  /** @type {keyof (typeof plugins)} */
3917
3906
  key
3918
3907
  ]).forEach((plugin) => {
@@ -3936,38 +3925,43 @@ var require_plugins2 = __commonJS({
3936
3925
  });
3937
3926
  return plugin;
3938
3927
  });
3939
- async function install(remotePath, force = false) {
3928
+ async function install(remotePath, force = false, insert = true, shouldLoadPlugin = true) {
3940
3929
  const rootPath = args2.rootPath;
3941
3930
  if (!existsSync(rootPath)) await mkdir(rootPath, { recursive: true });
3942
- const runeyaPath = path.resolve(rootPath, ".runeya");
3943
- if (!existsSync(runeyaPath)) await mkdir(runeyaPath, { recursive: true });
3944
- const pluginsPath = path.resolve(runeyaPath, "plugins");
3931
+ const pluginsPath = path.resolve(args2.runeyaConfigPath, "plugins");
3945
3932
  if (!existsSync(pluginsPath)) await mkdir(pluginsPath, { recursive: true });
3946
- const packageTmpPath = path.resolve(tmpdir(), `runeya-plugin-${Date.now()}`);
3933
+ const packageTmpPath = path.resolve(tmpdir(), `runeya-plugin-${crypto.randomUUID()}`);
3947
3934
  if (!existsSync(packageTmpPath)) await mkdir(packageTmpPath, { recursive: true });
3948
3935
  const packageTmpFilePath = `${packageTmpPath}.tar.gz`;
3949
3936
  const { data } = await axios.get(remotePath, { responseType: "arraybuffer" });
3950
3937
  await writeFile(packageTmpFilePath, data);
3951
3938
  await tar.extract({ file: packageTmpFilePath, cwd: packageTmpPath });
3952
3939
  const config = JSON.parse(await readFile(path.join(packageTmpPath, "package.json"), "utf8"));
3940
+ pluginsState[config.name] = { step: "INSTALL_START" };
3953
3941
  const plugin = await getInstalledPlugin(config.name, config.version);
3954
3942
  console.log("Installing", config.name + "@" + config.version);
3955
3943
  if (plugin && !force) {
3944
+ sockets2.emit("plugins:install:error", config.name, "Plugin already installed");
3945
+ pluginsState[config.name] = void 0;
3956
3946
  throw new HTTPError("Plugin already installed", "400.68746854743512");
3957
3947
  }
3958
- await dbConfig.alasql.delete(`name='${config.name}'`);
3948
+ if (insert) await dbConfig.alasql.delete(`name='${config.name}'`);
3959
3949
  const diskPath = path.resolve(pluginsPath, config.name);
3960
3950
  if (existsSync(diskPath)) await rm(diskPath, { recursive: true, force: true });
3951
+ console.log("Copying plugin to", diskPath, plugin.name);
3961
3952
  await cp(path.resolve(packageTmpPath), diskPath, { recursive: true });
3962
- await dbConfig.alasql.insertOne({
3963
- name: config.name,
3964
- version: config.version,
3965
- diskPath,
3966
- config,
3967
- remotePath
3968
- });
3953
+ console.log("Copying done", diskPath, plugin.name);
3954
+ if (insert) {
3955
+ await dbConfig.alasql.insertOne({
3956
+ name: config.name,
3957
+ version: config.version,
3958
+ config,
3959
+ remotePath
3960
+ });
3961
+ }
3969
3962
  if (config.runeya.entries.backend) {
3970
3963
  try {
3964
+ pluginsState[config.name] = { step: "INSTALL_BACKEND_START" };
3971
3965
  const child = await spawn("npm i --omit=dev", { cwd: path.dirname(path.resolve(diskPath, config.runeya.entries.backend)), shell: true });
3972
3966
  const installPromise = new Promise((resolve, reject) => {
3973
3967
  const installLog = [];
@@ -3992,17 +3986,28 @@ var require_plugins2 = __commonJS({
3992
3986
  console.error(error);
3993
3987
  sockets2.emit("plugins:install:error", config.name, error);
3994
3988
  return null;
3989
+ } finally {
3990
+ pluginsState[config.name] = void 0;
3995
3991
  }
3996
3992
  }
3997
- await loadPlugin(config.name);
3993
+ if (shouldLoadPlugin) await loadPlugin(config.name);
3998
3994
  sockets2.emit("plugins:installed", {
3999
3995
  name: config.name,
4000
3996
  version: config.version,
4001
- diskPath,
4002
3997
  config,
4003
3998
  remotePath
4004
3999
  });
4005
4000
  }
4001
+ async function init() {
4002
+ const plugins3 = await getInstalledPlugins();
4003
+ await PromiseB2.map(plugins3, async (plugin) => {
4004
+ try {
4005
+ await loadPlugin(plugin.name);
4006
+ } catch (error) {
4007
+ console.error(error);
4008
+ }
4009
+ }, { concurrency: 10 });
4010
+ }
4006
4011
  async function getInstalledPlugins() {
4007
4012
  let installedPlugins = [];
4008
4013
  if (process.env.NODE_ENV === "HFBXdZMJxLyJoua28asEaxRixJ6LriR7FnRzX6pwA7pFjZ" && process.env.PLUGIN_ONLY_PRODUCTION !== "true") {
@@ -4015,7 +4020,6 @@ var require_plugins2 = __commonJS({
4015
4020
  installedPlugins.push({
4016
4021
  "name": config.name,
4017
4022
  "version": "development",
4018
- "diskPath": pluginPath,
4019
4023
  "config": {
4020
4024
  ...config,
4021
4025
  runeya: {
@@ -4033,7 +4037,12 @@ var require_plugins2 = __commonJS({
4033
4037
  });
4034
4038
  }));
4035
4039
  } else {
4036
- installedPlugins = await dbConfig.alasql.simpleSelect({});
4040
+ const privatePlugins = await dbConfig.alasql.simpleSelect({});
4041
+ const publicPlugins = await dbPublicPlugins.alasql.simpleSelect({});
4042
+ const map = /* @__PURE__ */ new Map();
4043
+ publicPlugins.forEach((plugin) => map.set(plugin.name, { ...plugin, availableForAll: true }));
4044
+ privatePlugins.forEach((plugin) => map.set(plugin.name, plugin));
4045
+ installedPlugins = [...map.values()];
4037
4046
  installedPlugins = installedPlugins.filter((plugin) => plugin.version !== "development");
4038
4047
  }
4039
4048
  const sortedPlugins = installedPlugins.sort((a, b) => a.name.localeCompare(b.name));
@@ -4046,18 +4055,41 @@ var require_plugins2 = __commonJS({
4046
4055
  }
4047
4056
  async function uninstall(name) {
4048
4057
  const [plugin] = await dbConfig.alasql.simpleSelect({ where: `name='${name}'` });
4049
- if (!plugin) {
4058
+ const [publicPlugin] = await dbPublicPlugins.alasql.simpleSelect({ where: `name='${name}'` });
4059
+ if (!plugin && !publicPlugin) {
4050
4060
  throw new HTTPError("Plugin not found", "404.plugin.not.found");
4051
4061
  }
4052
- if (plugin.diskPath && existsSync(plugin.diskPath)) {
4053
- await rm(plugin.diskPath, { recursive: true, force: true });
4062
+ const diskPath = path.resolve(args2.runeyaConfigPath, "plugins", name);
4063
+ if (diskPath && existsSync(diskPath)) {
4064
+ await rm(diskPath, { recursive: true, force: true });
4065
+ }
4066
+ if (plugin) {
4067
+ await dbConfig.alasql.delete(`name='${name}'`);
4068
+ } else {
4069
+ await dbPublicPlugins.alasql.delete(`name='${name}'`);
4054
4070
  }
4055
- await dbConfig.alasql.delete(`name='${name}'`);
4056
4071
  sockets2.emit("plugins:uninstalled", {
4057
4072
  name
4058
4073
  });
4059
4074
  return { success: true, message: "Plugin uninstalled successfully" };
4060
4075
  }
4076
+ async function changeAvailability(name, availableForAll) {
4077
+ let [plugin] = await dbConfig.alasql.simpleSelect({ where: `name='${name}'` });
4078
+ if (!plugin) {
4079
+ [plugin] = await dbPublicPlugins.alasql.simpleSelect({ where: `name='${name}'` });
4080
+ }
4081
+ if (!plugin) {
4082
+ throw new HTTPError("Plugin not found", "404.plugin.not.found");
4083
+ }
4084
+ if (availableForAll) {
4085
+ await dbPublicPlugins.alasql.insertOne(plugin);
4086
+ await dbConfig.alasql.delete(`name='${name}'`);
4087
+ } else {
4088
+ await dbPublicPlugins.alasql.delete(`name='${name}'`);
4089
+ await dbConfig.alasql.insertOne(plugin);
4090
+ }
4091
+ return { success: true, message: "Plugin availability changed successfully" };
4092
+ }
4061
4093
  async function registerRoutes(router) {
4062
4094
  routes.forEach((route) => router.use(route));
4063
4095
  router.get("/api/plugins/themes", async (req, res) => {
@@ -4082,16 +4114,21 @@ var require_plugins2 = __commonJS({
4082
4114
  const pluginDir = path.dirname(pluginPath);
4083
4115
  Object.keys(require.cache).forEach((cachedPath) => {
4084
4116
  if (cachedPath.startsWith(pluginDir)) {
4085
- console.log("Clearing cache for:", cachedPath);
4086
4117
  delete require.cache[cachedPath];
4087
4118
  }
4088
4119
  });
4089
4120
  }
4090
4121
  async function loadPlugin(pluginName) {
4122
+ pluginsState[pluginName] = { step: "LOAD_START" };
4091
4123
  try {
4092
4124
  const plugin = await getInstalledPlugin(pluginName);
4093
4125
  let backendPath;
4094
4126
  let themePath;
4127
+ const diskPath = path.join(args2.runeyaConfigPath, "plugins", pluginName);
4128
+ if (!existsSync(diskPath)) {
4129
+ console.error("Plugin not found on disk, reinstalling", pluginName, "...");
4130
+ return install(plugin.remotePath, true, false, false);
4131
+ }
4095
4132
  if (process.env.NODE_ENV === "HFBXdZMJxLyJoua28asEaxRixJ6LriR7FnRzX6pwA7pFjZ" && process.env.PLUGIN_ONLY_PRODUCTION !== "true" && pluginName.startsWith("@runeya/")) {
4096
4133
  const pluginPath = path.resolve(__dirname, `../../../plugins/${pluginName.replace("@runeya/plugins-", "")}`);
4097
4134
  const frontPath = path.resolve(pluginPath, "front");
@@ -4149,9 +4186,12 @@ var require_plugins2 = __commonJS({
4149
4186
  }
4150
4187
  }
4151
4188
  if (backendPath) {
4189
+ pluginsState[pluginName] = { step: "CLEAR_CACHE" };
4152
4190
  clearPluginCache(backendPath);
4153
4191
  try {
4192
+ pluginsState[pluginName] = { step: "REQUIRE_BACKEND" };
4154
4193
  const loadedPlugin = safeRequire(backendPath);
4194
+ pluginsState[pluginName] = { step: "LOAD_BACKEND_START" };
4155
4195
  loadedPlugins[pluginName] = await loadedPlugin(stack, {
4156
4196
  socket: {
4157
4197
  emit: (event, ...args3) => {
@@ -4167,7 +4207,6 @@ var require_plugins2 = __commonJS({
4167
4207
  });
4168
4208
  } catch (error) {
4169
4209
  console.error(`[${plugin.name}@${plugin.version}]`, error);
4170
- console.log(Object.getOwnPropertyNames(error));
4171
4210
  setTimeout(() => {
4172
4211
  sockets2.emit("plugins:loading:error", pluginName, { ...error, message: error?.message?.split("\n")?.[0] });
4173
4212
  }, 1e3);
@@ -4175,8 +4214,11 @@ var require_plugins2 = __commonJS({
4175
4214
  }
4176
4215
  }
4177
4216
  if (themePath) {
4217
+ pluginsState[pluginName] = { step: "CLEAR_CACHE" };
4178
4218
  clearPluginCache(themePath);
4219
+ pluginsState[pluginName] = { step: "REQUIRE_BACKEND" };
4179
4220
  const loadedTheme = require(themePath);
4221
+ pluginsState[pluginName] = { step: "LOAD_BACKEND_START" };
4180
4222
  themes[pluginName] = await loadedTheme(stack, {
4181
4223
  socket: {
4182
4224
  emit: (event, ...args3) => {
@@ -4194,6 +4236,8 @@ var require_plugins2 = __commonJS({
4194
4236
  return loadedPlugins[pluginName];
4195
4237
  } catch (error) {
4196
4238
  console.error(error?.message || error);
4239
+ } finally {
4240
+ pluginsState[pluginName] = void 0;
4197
4241
  }
4198
4242
  }
4199
4243
  function safeRequire(path2) {
@@ -4206,19 +4250,8 @@ var require_plugins2 = __commonJS({
4206
4250
  }
4207
4251
  async function frontFile(pluginName) {
4208
4252
  const plugin = await getInstalledPlugin(pluginName);
4209
- return await readFile(path.join(plugin.diskPath, plugin.config.runeya.entries.front.js), "utf8");
4253
+ return await readFile(path.join(args2.runeyaConfigPath, "plugins", pluginName, plugin.config.runeya.entries.front.js), "utf8");
4210
4254
  }
4211
- (async () => {
4212
- const plugins2 = await getInstalledPlugins();
4213
- await Promise.all(plugins2.map(async (plugin) => {
4214
- try {
4215
- await loadPlugin(plugin.name);
4216
- console.log("loadedPlugin", plugin.name);
4217
- } catch (error) {
4218
- console.error(error);
4219
- }
4220
- }));
4221
- })();
4222
4255
  module2.exports = {
4223
4256
  install,
4224
4257
  frontFile,
@@ -4227,6 +4260,8 @@ var require_plugins2 = __commonJS({
4227
4260
  getInstalledPlugins,
4228
4261
  getInstalledPlugin,
4229
4262
  registerRoutes,
4263
+ changeAvailability,
4264
+ init,
4230
4265
  forService,
4231
4266
  ...allPlugins,
4232
4267
  routes
@@ -4234,6 +4269,35 @@ var require_plugins2 = __commonJS({
4234
4269
  }
4235
4270
  });
4236
4271
 
4272
+ // helpers/console.table.js
4273
+ var require_console_table = __commonJS({
4274
+ "helpers/console.table.js"(exports2, module2) {
4275
+ "use strict";
4276
+ var { Transform } = require("stream");
4277
+ var { Console } = require("console");
4278
+ function table(input) {
4279
+ const ts = new Transform({ transform(chunk, enc, cb) {
4280
+ cb(null, chunk);
4281
+ } });
4282
+ const logger = new Console({ stdout: ts });
4283
+ logger.table(input);
4284
+ const table2 = (ts.read() || "").toString();
4285
+ let result = "";
4286
+ for (const row of table2.split(/[\r\n]+/)) {
4287
+ let r = row.replace(/[^┬]*┬/, "\u250C");
4288
+ r = r.replace(/^├─*┼/, "\u251C");
4289
+ r = r.replace(/│[^│]*/, "");
4290
+ r = r.replace(/^└─*┴/, "\u2514");
4291
+ r = r.replace(/'/g, " ");
4292
+ result += `${r}
4293
+ `;
4294
+ }
4295
+ console.log(result);
4296
+ }
4297
+ module2.exports = table;
4298
+ }
4299
+ });
4300
+
4237
4301
  // routes/plugins.js
4238
4302
  var require_plugins3 = __commonJS({
4239
4303
  "routes/plugins.js"(exports2, module2) {
@@ -4243,52 +4307,57 @@ var require_plugins3 = __commonJS({
4243
4307
  var PromiseB2 = require("bluebird");
4244
4308
  var { findService } = require_stack();
4245
4309
  var Stack = require_stack();
4246
- var plugins = require_plugins2();
4310
+ var plugins2 = require_plugins2();
4247
4311
  var { readFile } = require("fs/promises");
4248
4312
  var path = require("path");
4249
4313
  var args2 = require_args();
4250
4314
  router.get("/", async (req, res) => {
4251
- res.send(await plugins.getInstalledPlugins());
4315
+ res.send(await plugins2.getInstalledPlugins());
4252
4316
  });
4253
4317
  router.get("/front/:name", async (req, res) => {
4254
- const plugin = await plugins.getInstalledPlugin(req.params.name);
4318
+ const plugin = await plugins2.getInstalledPlugin(req.params.name);
4255
4319
  res.send(plugin);
4256
4320
  });
4257
4321
  router.post("/install", async (req, res) => {
4258
4322
  const { url } = req.body;
4259
- const plugin = await plugins.install(url, req.query.force?.toString() === "true");
4323
+ const plugin = await plugins2.install(url, req.query.force?.toString() === "true");
4260
4324
  res.send(plugin);
4261
4325
  });
4326
+ router.post("/:plugin/change-availability", async (req, res) => {
4327
+ const { availableForAll } = req.body;
4328
+ const result = await plugins2.changeAvailability(req.params.plugin, availableForAll);
4329
+ res.send(result);
4330
+ });
4262
4331
  router.delete("/delete", async (req, res) => {
4263
4332
  const { name } = req.body;
4264
- const result = await plugins.uninstall(name);
4333
+ const result = await plugins2.uninstall(name);
4265
4334
  res.send(result);
4266
4335
  });
4267
4336
  router.get("/services/:service", async (req, res) => {
4268
4337
  const service = findService(req.params.service);
4269
- const services = await PromiseB2.filter(plugins.forService, async (plugin) => plugin.hidden ? !await plugin.hidden(service, Stack, "service") : true);
4338
+ const services = await PromiseB2.filter(plugins2.forService, async (plugin) => plugin.hidden ? !await plugin.hidden(service, Stack, "service") : true);
4270
4339
  services.sort((a, b) => (b?.order || Number.MAX_SAFE_INTEGER) - (a?.order || Number.MAX_SAFE_INTEGER));
4271
4340
  res.send(services);
4272
4341
  });
4273
4342
  router.get("/services", async (req, res) => {
4274
- const services = await PromiseB2.filter(plugins.forService, async (plugin) => plugin.hidden ? !await plugin.hidden(null, Stack, "global") : true);
4343
+ const services = await PromiseB2.filter(plugins2.forService, async (plugin) => plugin.hidden ? !await plugin.hidden(null, Stack, "global") : true);
4275
4344
  res.send(services);
4276
4345
  });
4277
4346
  router.get("/:type", async (req, res) => {
4278
4347
  const services = await PromiseB2.filter(
4279
- plugins[req.params.type] || [],
4348
+ plugins2[req.params.type] || [],
4280
4349
  async (plugin) => plugin.hidden ? !await plugin.hidden(null, Stack, req.params.type) : true
4281
4350
  );
4282
4351
  services.sort((a, b) => (a.order || 1e3) - (b.order || 1e3));
4283
4352
  res.send(services);
4284
4353
  });
4285
4354
  router.get("/:plugin/js", async (req, res) => {
4286
- const file = await plugins.frontFile(req.params.plugin);
4355
+ const file = await plugins2.frontFile(req.params.plugin);
4287
4356
  res.setHeader("Content-Type", "application/javascript");
4288
4357
  res.send(file);
4289
4358
  });
4290
4359
  router.post("/:plugin/call/:method", async (req, res) => {
4291
- const result = await plugins.call(req.params.plugin, req.params.method, req.body?.args || []);
4360
+ const result = await plugins2.call(req.params.plugin, req.params.method, req.body?.args || []);
4292
4361
  if (typeof result === "function") {
4293
4362
  await result(req, res);
4294
4363
  } else {
@@ -4935,8 +5004,8 @@ var require_routes11 = __commonJS({
4935
5004
  "use strict";
4936
5005
  var { express } = require_src6();
4937
5006
  var router = express.Router();
4938
- var plugins = require_plugins2();
4939
- plugins.registerRoutes(router);
5007
+ var plugins2 = require_plugins2();
5008
+ plugins2.registerRoutes(router);
4940
5009
  router.use("/plugins", require_plugins3());
4941
5010
  router.use("/system", require_system());
4942
5011
  router.use("/stack", require_stack2());
@@ -5078,12 +5147,14 @@ var require_server = __commonJS({
5078
5147
  var { sockets } = require_src();
5079
5148
  var migrateStackMonitor = require_migrateStackMonitor();
5080
5149
  var createDefaultFiles = require_createDefaultFiles();
5150
+ var plugins = require_plugins2();
5081
5151
  process.title = "runeya";
5082
5152
  var args = require_args();
5083
5153
  require("dotenv").config();
5084
5154
  (async () => {
5085
5155
  await migrateStackMonitor();
5086
5156
  await createDefaultFiles();
5157
+ await plugins.init();
5087
5158
  if (args["pull-env"]) {
5088
5159
  await require_stack().selectConf();
5089
5160
  const service = require_stack().findService(args.s);