@runeya/runeya 1.33.24 → 1.33.26

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 +165 -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,41 @@ 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 });
3961
3951
  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
- });
3952
+ if (insert) {
3953
+ await dbConfig.alasql.insertOne({
3954
+ name: config.name,
3955
+ version: config.version,
3956
+ config,
3957
+ remotePath
3958
+ });
3959
+ }
3969
3960
  if (config.runeya.entries.backend) {
3970
3961
  try {
3962
+ pluginsState[config.name] = { step: "INSTALL_BACKEND_START" };
3971
3963
  const child = await spawn("npm i --omit=dev", { cwd: path.dirname(path.resolve(diskPath, config.runeya.entries.backend)), shell: true });
3972
3964
  const installPromise = new Promise((resolve, reject) => {
3973
3965
  const installLog = [];
@@ -3992,17 +3984,28 @@ var require_plugins2 = __commonJS({
3992
3984
  console.error(error);
3993
3985
  sockets2.emit("plugins:install:error", config.name, error);
3994
3986
  return null;
3987
+ } finally {
3988
+ pluginsState[config.name] = void 0;
3995
3989
  }
3996
3990
  }
3997
- await loadPlugin(config.name);
3991
+ if (shouldLoadPlugin) await loadPlugin(config.name);
3998
3992
  sockets2.emit("plugins:installed", {
3999
3993
  name: config.name,
4000
3994
  version: config.version,
4001
- diskPath,
4002
3995
  config,
4003
3996
  remotePath
4004
3997
  });
4005
3998
  }
3999
+ async function init() {
4000
+ const plugins3 = await getInstalledPlugins();
4001
+ await PromiseB2.map(plugins3, async (plugin) => {
4002
+ try {
4003
+ await loadPlugin(plugin.name);
4004
+ } catch (error) {
4005
+ console.error(error);
4006
+ }
4007
+ }, { concurrency: 10 });
4008
+ }
4006
4009
  async function getInstalledPlugins() {
4007
4010
  let installedPlugins = [];
4008
4011
  if (process.env.NODE_ENV === "HFBXdZMJxLyJoua28asEaxRixJ6LriR7FnRzX6pwA7pFjZ" && process.env.PLUGIN_ONLY_PRODUCTION !== "true") {
@@ -4015,7 +4018,6 @@ var require_plugins2 = __commonJS({
4015
4018
  installedPlugins.push({
4016
4019
  "name": config.name,
4017
4020
  "version": "development",
4018
- "diskPath": pluginPath,
4019
4021
  "config": {
4020
4022
  ...config,
4021
4023
  runeya: {
@@ -4033,7 +4035,12 @@ var require_plugins2 = __commonJS({
4033
4035
  });
4034
4036
  }));
4035
4037
  } else {
4036
- installedPlugins = await dbConfig.alasql.simpleSelect({});
4038
+ const privatePlugins = await dbConfig.alasql.simpleSelect({});
4039
+ const publicPlugins = await dbPublicPlugins.alasql.simpleSelect({});
4040
+ const map = /* @__PURE__ */ new Map();
4041
+ publicPlugins.forEach((plugin) => map.set(plugin.name, { ...plugin, availableForAll: true }));
4042
+ privatePlugins.forEach((plugin) => map.set(plugin.name, plugin));
4043
+ installedPlugins = [...map.values()];
4037
4044
  installedPlugins = installedPlugins.filter((plugin) => plugin.version !== "development");
4038
4045
  }
4039
4046
  const sortedPlugins = installedPlugins.sort((a, b) => a.name.localeCompare(b.name));
@@ -4046,18 +4053,41 @@ var require_plugins2 = __commonJS({
4046
4053
  }
4047
4054
  async function uninstall(name) {
4048
4055
  const [plugin] = await dbConfig.alasql.simpleSelect({ where: `name='${name}'` });
4049
- if (!plugin) {
4056
+ const [publicPlugin] = await dbPublicPlugins.alasql.simpleSelect({ where: `name='${name}'` });
4057
+ if (!plugin && !publicPlugin) {
4050
4058
  throw new HTTPError("Plugin not found", "404.plugin.not.found");
4051
4059
  }
4052
- if (plugin.diskPath && existsSync(plugin.diskPath)) {
4053
- await rm(plugin.diskPath, { recursive: true, force: true });
4060
+ const diskPath = path.resolve(args2.runeyaConfigPath, "plugins", name);
4061
+ if (diskPath && existsSync(diskPath)) {
4062
+ await rm(diskPath, { recursive: true, force: true });
4063
+ }
4064
+ if (plugin) {
4065
+ await dbConfig.alasql.delete(`name='${name}'`);
4066
+ } else {
4067
+ await dbPublicPlugins.alasql.delete(`name='${name}'`);
4054
4068
  }
4055
- await dbConfig.alasql.delete(`name='${name}'`);
4056
4069
  sockets2.emit("plugins:uninstalled", {
4057
4070
  name
4058
4071
  });
4059
4072
  return { success: true, message: "Plugin uninstalled successfully" };
4060
4073
  }
4074
+ async function changeAvailability(name, availableForAll) {
4075
+ let [plugin] = await dbConfig.alasql.simpleSelect({ where: `name='${name}'` });
4076
+ if (!plugin) {
4077
+ [plugin] = await dbPublicPlugins.alasql.simpleSelect({ where: `name='${name}'` });
4078
+ }
4079
+ if (!plugin) {
4080
+ throw new HTTPError("Plugin not found", "404.plugin.not.found");
4081
+ }
4082
+ if (availableForAll) {
4083
+ await dbPublicPlugins.alasql.insertOne(plugin);
4084
+ await dbConfig.alasql.delete(`name='${name}'`);
4085
+ } else {
4086
+ await dbPublicPlugins.alasql.delete(`name='${name}'`);
4087
+ await dbConfig.alasql.insertOne(plugin);
4088
+ }
4089
+ return { success: true, message: "Plugin availability changed successfully" };
4090
+ }
4061
4091
  async function registerRoutes(router) {
4062
4092
  routes.forEach((route) => router.use(route));
4063
4093
  router.get("/api/plugins/themes", async (req, res) => {
@@ -4082,16 +4112,21 @@ var require_plugins2 = __commonJS({
4082
4112
  const pluginDir = path.dirname(pluginPath);
4083
4113
  Object.keys(require.cache).forEach((cachedPath) => {
4084
4114
  if (cachedPath.startsWith(pluginDir)) {
4085
- console.log("Clearing cache for:", cachedPath);
4086
4115
  delete require.cache[cachedPath];
4087
4116
  }
4088
4117
  });
4089
4118
  }
4090
4119
  async function loadPlugin(pluginName) {
4120
+ pluginsState[pluginName] = { step: "LOAD_START" };
4091
4121
  try {
4092
4122
  const plugin = await getInstalledPlugin(pluginName);
4093
4123
  let backendPath;
4094
4124
  let themePath;
4125
+ const diskPath = path.join(args2.runeyaConfigPath, "plugins", pluginName);
4126
+ if (!existsSync(diskPath)) {
4127
+ console.error("Plugin not found on disk, reinstalling", pluginName, "...");
4128
+ return install(plugin.remotePath, true, false, false);
4129
+ }
4095
4130
  if (process.env.NODE_ENV === "HFBXdZMJxLyJoua28asEaxRixJ6LriR7FnRzX6pwA7pFjZ" && process.env.PLUGIN_ONLY_PRODUCTION !== "true" && pluginName.startsWith("@runeya/")) {
4096
4131
  const pluginPath = path.resolve(__dirname, `../../../plugins/${pluginName.replace("@runeya/plugins-", "")}`);
4097
4132
  const frontPath = path.resolve(pluginPath, "front");
@@ -4149,9 +4184,12 @@ var require_plugins2 = __commonJS({
4149
4184
  }
4150
4185
  }
4151
4186
  if (backendPath) {
4187
+ pluginsState[pluginName] = { step: "CLEAR_CACHE" };
4152
4188
  clearPluginCache(backendPath);
4153
4189
  try {
4190
+ pluginsState[pluginName] = { step: "REQUIRE_BACKEND" };
4154
4191
  const loadedPlugin = safeRequire(backendPath);
4192
+ pluginsState[pluginName] = { step: "LOAD_BACKEND_START" };
4155
4193
  loadedPlugins[pluginName] = await loadedPlugin(stack, {
4156
4194
  socket: {
4157
4195
  emit: (event, ...args3) => {
@@ -4167,7 +4205,6 @@ var require_plugins2 = __commonJS({
4167
4205
  });
4168
4206
  } catch (error) {
4169
4207
  console.error(`[${plugin.name}@${plugin.version}]`, error);
4170
- console.log(Object.getOwnPropertyNames(error));
4171
4208
  setTimeout(() => {
4172
4209
  sockets2.emit("plugins:loading:error", pluginName, { ...error, message: error?.message?.split("\n")?.[0] });
4173
4210
  }, 1e3);
@@ -4175,8 +4212,11 @@ var require_plugins2 = __commonJS({
4175
4212
  }
4176
4213
  }
4177
4214
  if (themePath) {
4215
+ pluginsState[pluginName] = { step: "CLEAR_CACHE" };
4178
4216
  clearPluginCache(themePath);
4217
+ pluginsState[pluginName] = { step: "REQUIRE_BACKEND" };
4179
4218
  const loadedTheme = require(themePath);
4219
+ pluginsState[pluginName] = { step: "LOAD_BACKEND_START" };
4180
4220
  themes[pluginName] = await loadedTheme(stack, {
4181
4221
  socket: {
4182
4222
  emit: (event, ...args3) => {
@@ -4194,6 +4234,8 @@ var require_plugins2 = __commonJS({
4194
4234
  return loadedPlugins[pluginName];
4195
4235
  } catch (error) {
4196
4236
  console.error(error?.message || error);
4237
+ } finally {
4238
+ pluginsState[pluginName] = void 0;
4197
4239
  }
4198
4240
  }
4199
4241
  function safeRequire(path2) {
@@ -4206,19 +4248,8 @@ var require_plugins2 = __commonJS({
4206
4248
  }
4207
4249
  async function frontFile(pluginName) {
4208
4250
  const plugin = await getInstalledPlugin(pluginName);
4209
- return await readFile(path.join(plugin.diskPath, plugin.config.runeya.entries.front.js), "utf8");
4251
+ return await readFile(path.join(args2.runeyaConfigPath, "plugins", pluginName, plugin.config.runeya.entries.front.js), "utf8");
4210
4252
  }
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
4253
  module2.exports = {
4223
4254
  install,
4224
4255
  frontFile,
@@ -4227,6 +4258,8 @@ var require_plugins2 = __commonJS({
4227
4258
  getInstalledPlugins,
4228
4259
  getInstalledPlugin,
4229
4260
  registerRoutes,
4261
+ changeAvailability,
4262
+ init,
4230
4263
  forService,
4231
4264
  ...allPlugins,
4232
4265
  routes
@@ -4234,6 +4267,35 @@ var require_plugins2 = __commonJS({
4234
4267
  }
4235
4268
  });
4236
4269
 
4270
+ // helpers/console.table.js
4271
+ var require_console_table = __commonJS({
4272
+ "helpers/console.table.js"(exports2, module2) {
4273
+ "use strict";
4274
+ var { Transform } = require("stream");
4275
+ var { Console } = require("console");
4276
+ function table(input) {
4277
+ const ts = new Transform({ transform(chunk, enc, cb) {
4278
+ cb(null, chunk);
4279
+ } });
4280
+ const logger = new Console({ stdout: ts });
4281
+ logger.table(input);
4282
+ const table2 = (ts.read() || "").toString();
4283
+ let result = "";
4284
+ for (const row of table2.split(/[\r\n]+/)) {
4285
+ let r = row.replace(/[^┬]*┬/, "\u250C");
4286
+ r = r.replace(/^├─*┼/, "\u251C");
4287
+ r = r.replace(/│[^│]*/, "");
4288
+ r = r.replace(/^└─*┴/, "\u2514");
4289
+ r = r.replace(/'/g, " ");
4290
+ result += `${r}
4291
+ `;
4292
+ }
4293
+ console.log(result);
4294
+ }
4295
+ module2.exports = table;
4296
+ }
4297
+ });
4298
+
4237
4299
  // routes/plugins.js
4238
4300
  var require_plugins3 = __commonJS({
4239
4301
  "routes/plugins.js"(exports2, module2) {
@@ -4243,52 +4305,57 @@ var require_plugins3 = __commonJS({
4243
4305
  var PromiseB2 = require("bluebird");
4244
4306
  var { findService } = require_stack();
4245
4307
  var Stack = require_stack();
4246
- var plugins = require_plugins2();
4308
+ var plugins2 = require_plugins2();
4247
4309
  var { readFile } = require("fs/promises");
4248
4310
  var path = require("path");
4249
4311
  var args2 = require_args();
4250
4312
  router.get("/", async (req, res) => {
4251
- res.send(await plugins.getInstalledPlugins());
4313
+ res.send(await plugins2.getInstalledPlugins());
4252
4314
  });
4253
4315
  router.get("/front/:name", async (req, res) => {
4254
- const plugin = await plugins.getInstalledPlugin(req.params.name);
4316
+ const plugin = await plugins2.getInstalledPlugin(req.params.name);
4255
4317
  res.send(plugin);
4256
4318
  });
4257
4319
  router.post("/install", async (req, res) => {
4258
4320
  const { url } = req.body;
4259
- const plugin = await plugins.install(url, req.query.force?.toString() === "true");
4321
+ const plugin = await plugins2.install(url, req.query.force?.toString() === "true");
4260
4322
  res.send(plugin);
4261
4323
  });
4324
+ router.post("/:plugin/change-availability", async (req, res) => {
4325
+ const { availableForAll } = req.body;
4326
+ const result = await plugins2.changeAvailability(req.params.plugin, availableForAll);
4327
+ res.send(result);
4328
+ });
4262
4329
  router.delete("/delete", async (req, res) => {
4263
4330
  const { name } = req.body;
4264
- const result = await plugins.uninstall(name);
4331
+ const result = await plugins2.uninstall(name);
4265
4332
  res.send(result);
4266
4333
  });
4267
4334
  router.get("/services/:service", async (req, res) => {
4268
4335
  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);
4336
+ const services = await PromiseB2.filter(plugins2.forService, async (plugin) => plugin.hidden ? !await plugin.hidden(service, Stack, "service") : true);
4270
4337
  services.sort((a, b) => (b?.order || Number.MAX_SAFE_INTEGER) - (a?.order || Number.MAX_SAFE_INTEGER));
4271
4338
  res.send(services);
4272
4339
  });
4273
4340
  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);
4341
+ const services = await PromiseB2.filter(plugins2.forService, async (plugin) => plugin.hidden ? !await plugin.hidden(null, Stack, "global") : true);
4275
4342
  res.send(services);
4276
4343
  });
4277
4344
  router.get("/:type", async (req, res) => {
4278
4345
  const services = await PromiseB2.filter(
4279
- plugins[req.params.type] || [],
4346
+ plugins2[req.params.type] || [],
4280
4347
  async (plugin) => plugin.hidden ? !await plugin.hidden(null, Stack, req.params.type) : true
4281
4348
  );
4282
4349
  services.sort((a, b) => (a.order || 1e3) - (b.order || 1e3));
4283
4350
  res.send(services);
4284
4351
  });
4285
4352
  router.get("/:plugin/js", async (req, res) => {
4286
- const file = await plugins.frontFile(req.params.plugin);
4353
+ const file = await plugins2.frontFile(req.params.plugin);
4287
4354
  res.setHeader("Content-Type", "application/javascript");
4288
4355
  res.send(file);
4289
4356
  });
4290
4357
  router.post("/:plugin/call/:method", async (req, res) => {
4291
- const result = await plugins.call(req.params.plugin, req.params.method, req.body?.args || []);
4358
+ const result = await plugins2.call(req.params.plugin, req.params.method, req.body?.args || []);
4292
4359
  if (typeof result === "function") {
4293
4360
  await result(req, res);
4294
4361
  } else {
@@ -4935,8 +5002,8 @@ var require_routes11 = __commonJS({
4935
5002
  "use strict";
4936
5003
  var { express } = require_src6();
4937
5004
  var router = express.Router();
4938
- var plugins = require_plugins2();
4939
- plugins.registerRoutes(router);
5005
+ var plugins2 = require_plugins2();
5006
+ plugins2.registerRoutes(router);
4940
5007
  router.use("/plugins", require_plugins3());
4941
5008
  router.use("/system", require_system());
4942
5009
  router.use("/stack", require_stack2());
@@ -5078,12 +5145,14 @@ var require_server = __commonJS({
5078
5145
  var { sockets } = require_src();
5079
5146
  var migrateStackMonitor = require_migrateStackMonitor();
5080
5147
  var createDefaultFiles = require_createDefaultFiles();
5148
+ var plugins = require_plugins2();
5081
5149
  process.title = "runeya";
5082
5150
  var args = require_args();
5083
5151
  require("dotenv").config();
5084
5152
  (async () => {
5085
5153
  await migrateStackMonitor();
5086
5154
  await createDefaultFiles();
5155
+ await plugins.init();
5087
5156
  if (args["pull-env"]) {
5088
5157
  await require_stack().selectConf();
5089
5158
  const service = require_stack().findService(args.s);