@runeya/runeya 1.33.22 → 1.33.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/www.js CHANGED
@@ -102,7 +102,7 @@ var require_args = __commonJS({
102
102
  var path = require("path");
103
103
  var yargs = require("yargs/yargs");
104
104
  var { hideBin } = require("yargs/helpers");
105
- var { existsSync: existsSync2 } = require("fs");
105
+ var { existsSync } = require("fs");
106
106
  var yarg = yargs(hideBin(process.argv)).usage("Usage: <path-to-your-stack> [options]").alias("pe", "pull-env").describe("pe", "Pull env from a service (need --environment and --service)").default("pe", false).alias("e", "environment").describe("e", "Choose your environment").default("e", void 0).alias("s", "service").describe("s", "Service").default("s", void 0).alias("ss", "services").describe("ss", "Services").default("ss", []).boolean(["pe"]).string(["e", "s"]).array(["ss"]).help("h").alias("h", "help").parse();
107
107
  var rootPath = path.resolve(yarg["_"]?.[0] || ".");
108
108
  var args2 = Object.assign({
@@ -111,7 +111,7 @@ var require_args = __commonJS({
111
111
  runeyaConfigPath: path.resolve(rootPath, ".runeya"),
112
112
  runeyaGlobalConfigPath: path.resolve(require("os").homedir(), ".runeya-global")
113
113
  }, yarg);
114
- if (!existsSync2(args2.rootPath)) {
114
+ if (!existsSync(args2.rootPath)) {
115
115
  console.error("Error: Runeya was launched with an invalid root path that does not exist. Please check your launch command. \nPath: ", args2.rootPath);
116
116
  process.exit(1);
117
117
  }
@@ -131,19 +131,112 @@ var require_args = __commonJS({
131
131
  }
132
132
  });
133
133
 
134
+ // helpers/migrateStackMonitor.js
135
+ var require_migrateStackMonitor = __commonJS({
136
+ "helpers/migrateStackMonitor.js"(exports2, module2) {
137
+ "use strict";
138
+ var pathfs = require("path");
139
+ var { existsSync } = require("fs");
140
+ var { cp } = require("fs/promises");
141
+ var args2 = require_args();
142
+ module2.exports = async function migrateStackMonitor2() {
143
+ const localLegacyPath = pathfs.resolve(args2.runeyaConfigPath, "../.stackmonitor");
144
+ const localNewPath = args2.runeyaConfigPath;
145
+ if (existsSync(localLegacyPath) && !existsSync(localNewPath)) {
146
+ console.log("Legacy path found, copy to new path");
147
+ await cp(localLegacyPath, localNewPath, { recursive: true, force: true });
148
+ }
149
+ const globalLegacyPath = pathfs.resolve(args2.runeyaGlobalConfigPath, "../.stackmonitor");
150
+ const globalNewPath = args2.runeyaGlobalConfigPath;
151
+ if (existsSync(globalLegacyPath) && !existsSync(globalNewPath)) {
152
+ console.log("Legacy path found, copy to new path");
153
+ await cp(globalLegacyPath, globalNewPath, { recursive: true, force: true });
154
+ }
155
+ if (existsSync(localLegacyPath) && !existsSync(pathfs.resolve(args2.runeyaConfigPath, "dbs/overrides"))) {
156
+ console.log("Legacy path found, copy to new path");
157
+ await cp(pathfs.resolve(localLegacyPath, "dbs/overrides"), pathfs.resolve(args2.runeyaConfigPath, "dbs/overrides"), { recursive: true, force: true });
158
+ }
159
+ if (existsSync(localLegacyPath) && !existsSync(pathfs.resolve(args2.runeyaConfigPath, "dbs/encryption-key.json"))) {
160
+ console.log("Legacy path found, copy to new path");
161
+ await cp(pathfs.resolve(localLegacyPath, "dbs/encryption-key.json"), pathfs.resolve(args2.runeyaConfigPath, "dbs/encryption-key.json"), { recursive: true, force: true });
162
+ }
163
+ };
164
+ }
165
+ });
166
+
167
+ // helpers/conflictStorage.js
168
+ var require_conflictStorage = __commonJS({
169
+ "helpers/conflictStorage.js"(exports2, module2) {
170
+ "use strict";
171
+ var pendingConflicts = [];
172
+ function storeConflict(conflict) {
173
+ const conflictId = Date.now().toString();
174
+ pendingConflicts.push({
175
+ id: conflictId,
176
+ timestamp: Date.now(),
177
+ ...conflict
178
+ });
179
+ if (pendingConflicts.length > 20) {
180
+ pendingConflicts.shift();
181
+ }
182
+ return conflictId;
183
+ }
184
+ function getPendingConflicts() {
185
+ return pendingConflicts;
186
+ }
187
+ function removeConflict(conflictId) {
188
+ const index = pendingConflicts.findIndex((c) => c.id === conflictId);
189
+ if (index !== -1) {
190
+ pendingConflicts.splice(index, 1);
191
+ }
192
+ }
193
+ module2.exports = {
194
+ storeConflict,
195
+ getPendingConflicts,
196
+ removeConflict
197
+ };
198
+ }
199
+ });
200
+
201
+ // helpers/reencrypt-nodered.js
202
+ var require_reencrypt_nodered = __commonJS({
203
+ "helpers/reencrypt-nodered.js"(exports2, module2) {
204
+ "use strict";
205
+ var crypto = require("crypto");
206
+ var { readFile, writeFile } = require("fs/promises");
207
+ var encryptionAlgorithm = "aes-256-ctr";
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();
211
+ const cipher = JSON.parse(await readFile(path, "utf-8"));
212
+ let flows = cipher["$"];
213
+ const vector = Buffer.from(flows.substring(0, 32), "hex");
214
+ flows = flows.substring(32);
215
+ const decipher = crypto.createDecipheriv(encryptionAlgorithm, oldKey, vector);
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);
219
+ const encrypted = newCipher.update(decrypted, "utf8", "base64") + newCipher.final("base64");
220
+ await writeFile(path, JSON.stringify({
221
+ "$": newVector.toString("hex") + encrypted
222
+ }, null, 2), "utf-8");
223
+ };
224
+ }
225
+ });
226
+
134
227
  // ../../modules/bugs/backend/routes.js
135
228
  var require_routes = __commonJS({
136
229
  "../../modules/bugs/backend/routes.js"(exports2, module2) {
137
230
  "use strict";
138
231
  var express = require("express");
139
232
  var router = express.Router();
140
- var pathfs2 = require("path");
233
+ var pathfs = require("path");
141
234
  var { fork } = require("child_process");
142
235
  module2.exports = (runeya) => {
143
236
  router.get("/bugs/:service", async (req, res) => {
144
237
  const service = runeya.findService(req.params.service);
145
238
  if (!service) return res.status(404).send("SERVICE_NOT_FOUND");
146
- const ts = fork(pathfs2.resolve(__dirname, "checkJsFork"));
239
+ const ts = fork(pathfs.resolve(__dirname, "checkJsFork"));
147
240
  ts.on("message", (results) => {
148
241
  res.json(results);
149
242
  ts.kill("SIGKILL");
@@ -160,8 +253,8 @@ var require_routes = __commonJS({
160
253
  var require_backend = __commonJS({
161
254
  "../../modules/bugs/backend/index.js"(exports2, module2) {
162
255
  "use strict";
163
- var { existsSync: existsSync2 } = require("fs");
164
- var pathfs2 = require("path");
256
+ var { existsSync } = require("fs");
257
+ var pathfs = require("path");
165
258
  var plugin = {
166
259
  enabled: true,
167
260
  name: "Bugs",
@@ -201,756 +294,313 @@ var require_backend2 = __commonJS({
201
294
  }
202
295
  });
203
296
 
204
- // helpers/conflictStorage.js
205
- var require_conflictStorage = __commonJS({
206
- "helpers/conflictStorage.js"(exports2, module2) {
297
+ // ../../modules/documentation/backend/Documentation.js
298
+ var require_Documentation = __commonJS({
299
+ "../../modules/documentation/backend/Documentation.js"(exports2, module2) {
207
300
  "use strict";
208
- var pendingConflicts = [];
209
- function storeConflict(conflict) {
210
- const conflictId = Date.now().toString();
211
- pendingConflicts.push({
212
- id: conflictId,
213
- timestamp: Date.now(),
214
- ...conflict
215
- });
216
- if (pendingConflicts.length > 20) {
217
- pendingConflicts.shift();
301
+ var PromiseB2 = require("bluebird");
302
+ var { randomUUID: randomUUID2 } = require("crypto");
303
+ var dbs2 = require_dbs();
304
+ var db = dbs2.getDb(`documentations`);
305
+ var dbDocumentationTree = dbs2.getDb(`documentations-tree`, { encrypted: true, defaultData: [] }).alasql;
306
+ var Documentation = class {
307
+ /**
308
+ * @param {import('@runeya/common-typings').NonFunctionProperties<Documentation>} documentation
309
+ */
310
+ constructor(documentation) {
311
+ this.id = documentation.id || "";
312
+ this.text = documentation.text || "";
218
313
  }
219
- return conflictId;
220
- }
221
- function getPendingConflicts() {
222
- return pendingConflicts;
223
- }
224
- function removeConflict(conflictId) {
225
- const index = pendingConflicts.findIndex((c) => c.id === conflictId);
226
- if (index !== -1) {
227
- pendingConflicts.splice(index, 1);
314
+ static async load(id) {
315
+ }
316
+ static async all() {
317
+ return db.alasql.select("Select * from ?");
318
+ }
319
+ static async find(envId) {
320
+ const documentations = await this.all();
321
+ return documentations.find((env) => env.id === envId);
322
+ }
323
+ async save() {
324
+ const obj = this.toStorage();
325
+ await dbs2.getDb(`documentations/${this.id}`).write(obj);
326
+ return this;
327
+ }
328
+ async update(env) {
329
+ this.transform = env.transform;
330
+ this.label = env.label;
331
+ await dbs2.getDb(`documentations/${this.id}`).write(this.toStorage());
332
+ }
333
+ async delete() {
334
+ await dbs2.getDb(`documentations/${this.id}`).delete();
335
+ }
336
+ toStorage() {
337
+ return {
338
+ id: this.id,
339
+ label: this.label,
340
+ transform: this.transform
341
+ };
228
342
  }
229
- }
230
- module2.exports = {
231
- storeConflict,
232
- getPendingConflicts,
233
- removeConflict
234
- };
235
- }
236
- });
237
-
238
- // helpers/reencrypt-nodered.js
239
- var require_reencrypt_nodered = __commonJS({
240
- "helpers/reencrypt-nodered.js"(exports2, module2) {
241
- "use strict";
242
- var crypto = require("crypto");
243
- var { readFile, writeFile } = require("fs/promises");
244
- var encryptionAlgorithm = "aes-256-ctr";
245
- module2.exports = async function decryptCreds(oldSecret, newScret, path) {
246
- const oldKey = crypto.createHash("sha256").update(oldSecret).digest();
247
- const newKey = crypto.createHash("sha256").update(newScret).digest();
248
- const cipher = JSON.parse(await readFile(path, "utf-8"));
249
- let flows = cipher["$"];
250
- const vector = Buffer.from(flows.substring(0, 32), "hex");
251
- flows = flows.substring(32);
252
- const decipher = crypto.createDecipheriv(encryptionAlgorithm, oldKey, vector);
253
- const decrypted = decipher.update(flows, "base64", "utf8") + decipher.final("utf8");
254
- const newVector = crypto.randomBytes(16);
255
- const newCipher = crypto.createCipheriv(encryptionAlgorithm, newKey, newVector);
256
- const encrypted = newCipher.update(decrypted, "utf8", "base64") + newCipher.final("base64");
257
- await writeFile(path, JSON.stringify({
258
- "$": newVector.toString("hex") + encrypted
259
- }, null, 2), "utf-8");
260
343
  };
344
+ module2.exports = Documentation;
261
345
  }
262
346
  });
263
347
 
264
- // models/EncryptionKey.js
265
- var require_EncryptionKey = __commonJS({
266
- "models/EncryptionKey.js"(exports2, module2) {
348
+ // ../../modules/documentation/backend/Leaf.js
349
+ var require_Leaf = __commonJS({
350
+ "../../modules/documentation/backend/Leaf.js"(exports2, module2) {
267
351
  "use strict";
268
- var { existsSync: existsSync2 } = require("fs");
269
- var path = require("path");
270
- var { writeFile, readFile, appendFile } = require("fs/promises");
352
+ var PromiseB2 = require("bluebird");
271
353
  var { randomUUID: randomUUID2 } = require("crypto");
272
354
  var dbs2 = require_dbs();
273
- var { generateKey, encrypt, decrypt } = require_crypto();
274
- var reencryptNodered = require_reencrypt_nodered();
275
- var pathfs2 = require("path");
276
- var args2 = require_args();
277
- var _EncryptionKey_instances, getDb_fn;
278
- var EncryptionKey = class {
279
- constructor() {
280
- __privateAdd(this, _EncryptionKey_instances);
281
- this.encryptionKey = "";
282
- }
283
- async init() {
284
- this.encryptionKey = (await __privateMethod(this, _EncryptionKey_instances, getDb_fn).call(this).read()).encryptionKey;
285
- const dirname = path.dirname(await dbs2.getDb("encryption-key", { encrypted: false }).getPath());
286
- const gitignorePath = path.resolve(dirname, ".gitignore");
287
- if (!existsSync2(gitignorePath)) {
288
- writeFile(gitignorePath, "encryption-key.json");
289
- } else {
290
- const gitignoreFile = (await readFile(gitignorePath, "utf-8")).split("\n");
291
- const gitignoreHasKey = (key) => gitignoreFile.some((line) => line.trim() === key);
292
- if (!gitignoreHasKey("encryption-key.json")) await appendFile(gitignorePath, "\nencryption-key.json");
293
- if (!gitignoreHasKey("overrides")) await appendFile(gitignorePath, "\noverrides");
294
- }
355
+ var { v4 } = require("uuid");
356
+ var dbLeafTree = dbs2.getDb(`leafs-leafs`, { encrypted: true, defaultData: [] }).alasql;
357
+ var Leaf = class _Leaf {
358
+ /**
359
+ * @param {import('@runeya/common-typings').NonFunctionProperties<Leaf>} leaf
360
+ */
361
+ constructor(leaf) {
362
+ this.id = leaf.id || v4();
363
+ this.docId = leaf.docId || "";
364
+ this.serviceId = leaf.serviceId || "";
365
+ this.label = leaf.label || "";
366
+ this.position = leaf.position || -1;
367
+ this.text = leaf.text || "";
368
+ this.parentId = leaf.parentId || "";
295
369
  }
296
- async update() {
297
- return __privateMethod(this, _EncryptionKey_instances, getDb_fn).call(this).write(this.toStorage());
370
+ static async getTree(serviceLabel) {
371
+ const leafs = await dbLeafTree.read(`Select * from ${dbLeafTree.table} ${serviceLabel ? `where serviceId = '${serviceLabel}'` : `where serviceId=''`}`);
372
+ return leafs;
298
373
  }
299
374
  toStorage() {
300
375
  return {
301
- encryptionKey: this.encryptionKey
376
+ docId: this.docId,
377
+ position: this.position,
378
+ serviceId: this.serviceId,
379
+ label: this.label,
380
+ text: this.text,
381
+ parentId: this.parentId
302
382
  };
303
383
  }
304
- async generateKey() {
305
- return generateKey();
384
+ async remove() {
385
+ return dbLeafTree.write(`DELETE from ${dbLeafTree.table} where id = '${this.id}'`);
306
386
  }
307
- async testKey(encryptionKey) {
308
- try {
309
- const variable = randomUUID2();
310
- const result = await encrypt(variable, { encryptionKey });
311
- const decrypted = await decrypt(result, { encryptionKey });
312
- if (decrypted === variable) return true;
313
- return false;
314
- } catch (error) {
315
- console.error(error);
316
- return false;
317
- }
387
+ static async find({ id }) {
388
+ const [leaf] = await dbLeafTree.read(`Select * from ${dbLeafTree.table} where id='${id}'`);
389
+ return leaf ? new _Leaf(leaf) : null;
318
390
  }
319
- async saveKey(key, { noReload } = { noReload: false }) {
320
- if (!await this.testKey(key)) throw new Error("Key not valid");
321
- try {
322
- const envSample = (await dbs2.getDbs("envs"))[0];
323
- if (envSample) await dbs2.getDb(`envs/${envSample}`).read();
324
- if (this.encryptionKey) {
325
- await reencryptNodered(this.encryptionKey, key, pathfs2.resolve(require_stack().getRootPath(), "nodered/flow_cred.json"));
326
- await dbs2.reencrypt(this.encryptionKey, key);
327
- }
328
- ;
329
- } catch (error) {
330
- console.error(error);
331
- }
332
- const shouldRestart = this.encryptionKey !== key;
333
- this.encryptionKey = key;
334
- await this.update();
335
- if (!noReload) {
336
- await require_stack().selectConf();
337
- }
338
- if (shouldRestart) {
339
- console.log("Restart...");
340
- require("child_process").spawn(process.argv[0], process.argv.slice(1), {
341
- cwd: args2.initialCwd,
342
- detached: true,
343
- stdio: "inherit"
344
- }).unref();
345
- process.exit(0);
346
- }
347
- return key;
391
+ async save() {
392
+ const leafExists = await _Leaf.find({ id: this.id });
393
+ const storage = this.toStorage();
394
+ const set = dbLeafTree.buildUpdateQuery(storage);
395
+ await leafExists ? dbLeafTree.write(`update ${dbLeafTree.table} set ${set} where id='${this.id}'`) : dbLeafTree.write(`insert into ${dbLeafTree.table} (id, docId, position, serviceId, label, text, parentId) values ('${this.id}', '${this.docId}', ${this.position}, '${this.serviceId}', '${this.label.replace(/'/g, "''")}', '${this.text.replace(/'/g, "''")}', '${this.parentId}')`);
396
+ return this;
348
397
  }
349
398
  };
350
- _EncryptionKey_instances = new WeakSet();
351
- getDb_fn = function() {
352
- return dbs2.getDb("encryption-key", { encrypted: false });
353
- };
354
- module2.exports = new EncryptionKey();
399
+ module2.exports = Leaf;
355
400
  }
356
401
  });
357
402
 
358
- // helpers/crypto.js
359
- var require_crypto = __commonJS({
360
- "helpers/crypto.js"(exports2, module2) {
403
+ // ../../modules/documentation/backend/routes.js
404
+ var require_routes2 = __commonJS({
405
+ "../../modules/documentation/backend/routes.js"(exports2, module2) {
361
406
  "use strict";
362
- var _sodium = require("libsodium-wrappers");
363
- var crypto = require("crypto");
364
- var { sockets: sockets2 } = require_src();
365
- var conflictStorage = require_conflictStorage();
366
- var path = require("path");
367
- module2.exports.generateKey = async () => {
368
- await _sodium.ready;
369
- const sodium = _sodium;
370
- const key = sodium.crypto_aead_aegis256_keygen();
371
- return sodium.to_base64(key);
372
- };
373
- module2.exports.encrypt = async (data, { additionnalNonce = "", encryptionKey = "" } = {}) => {
374
- await _sodium.ready;
375
- const sodium = _sodium;
376
- if (!encryptionKey) encryptionKey = require_EncryptionKey().encryptionKey;
377
- const key = sodium.from_base64(encryptionKey);
378
- if (!key || key.length !== sodium.crypto_secretbox_KEYBYTES) {
379
- throw new Error("Invalid encryption key length");
380
- }
381
- let nonce;
382
- if (additionnalNonce) {
383
- const combinedHash = crypto.createHash("blake2b512").update(data + additionnalNonce).digest();
384
- nonce = combinedHash.slice(0, sodium.crypto_secretbox_NONCEBYTES);
385
- } else {
386
- nonce = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES);
387
- }
388
- const dataStr = typeof data === "string" ? data : String(data);
389
- const dataArray = new TextEncoder().encode(dataStr);
390
- const ciphertext = sodium.crypto_secretbox_easy(dataArray, nonce, key);
391
- return Buffer.concat([
392
- Buffer.from(nonce.buffer, nonce.byteOffset, nonce.byteLength),
393
- Buffer.from(ciphertext.buffer, ciphertext.byteOffset, ciphertext.byteLength)
394
- ]).toString("base64");
395
- };
396
- module2.exports.decryptFile = async (encryptedData, options = {}, filePath) => {
397
- if (typeof encryptedData === "string" && (encryptedData.includes("<<<<<<< HEAD") || encryptedData.includes("=======") || encryptedData.includes(">>>>>>>"))) {
398
- return await handleGitConflict(encryptedData, options, filePath);
399
- }
400
- return await module2.exports.decrypt(encryptedData, options);
407
+ var express = require("express");
408
+ var Leaf = require_Leaf();
409
+ var PromiseB2 = require("bluebird");
410
+ var router = express.Router();
411
+ module2.exports = (runeya) => {
412
+ const { findService } = runeya;
413
+ router.get("/documentation/tree", async (req, res) => {
414
+ const service = findService(req.query.serviceId?.toString() || "");
415
+ const result = await Leaf.getTree(service?.label);
416
+ return res.send(result);
417
+ });
418
+ router.post("/documentation/tree/sort", async (req, res) => {
419
+ const leafs = await PromiseB2.mapSeries(req.body, async (_leaf, index) => {
420
+ const leaf = await Leaf.find({ id: _leaf.id });
421
+ if (!leaf) return;
422
+ leaf.position = index;
423
+ await leaf.save();
424
+ return leaf;
425
+ });
426
+ return res.send(leafs);
427
+ });
428
+ router.post("/documentation/tree", async (req, res) => {
429
+ const result = await new Leaf({
430
+ ...req.body
431
+ }).save();
432
+ return res.send(result);
433
+ });
434
+ router.post("/documentation/tree/:key", async (req, res) => {
435
+ const result = await new Leaf({
436
+ ...req.body,
437
+ id: req.params.key
438
+ }).save();
439
+ return res.send(result);
440
+ });
441
+ router.delete("/documentation/tree/:key", async (req, res) => {
442
+ const result = await Leaf.find({
443
+ id: req.params.key
444
+ });
445
+ if (result) return res.send(await result.remove());
446
+ return res.send();
447
+ });
448
+ return router;
401
449
  };
402
- module2.exports.decrypt = async (encryptedData, { additionnalNonce = "", encryptionKey = "" } = {}) => {
403
- if (typeof encryptedData === "string" && (encryptedData.includes("<<<<<<< HEAD") || encryptedData.includes("=======") || encryptedData.includes(">>>>>>>"))) {
404
- return await handleGitConflict(encryptedData, { additionnalNonce, encryptionKey });
405
- }
406
- await _sodium.ready;
407
- const sodium = _sodium;
408
- if (!encryptionKey) encryptionKey = require_EncryptionKey().encryptionKey;
409
- const key = sodium.from_base64(encryptionKey);
410
- if (!key || key.length !== sodium.crypto_secretbox_KEYBYTES) {
411
- throw new Error("Invalid decryption key length");
412
- }
413
- const encryptedBuffer = Buffer.from(encryptedData, "base64");
414
- const nonce = encryptedBuffer.slice(0, sodium.crypto_secretbox_NONCEBYTES);
415
- const ciphertext = encryptedBuffer.slice(sodium.crypto_secretbox_NONCEBYTES);
416
- let decrypted;
417
- try {
418
- const ciphertextArray = new Uint8Array(ciphertext);
419
- const nonceArray = new Uint8Array(nonce);
420
- decrypted = sodium.crypto_secretbox_open_easy(ciphertextArray, nonceArray, key);
421
- } catch (error) {
422
- throw new Error("Decryption failed");
423
- }
424
- if (!decrypted) {
425
- throw new Error("Decryption failed");
450
+ }
451
+ });
452
+
453
+ // ../../modules/documentation/backend/index.js
454
+ var require_backend3 = __commonJS({
455
+ "../../modules/documentation/backend/index.js"(exports2, module2) {
456
+ "use strict";
457
+ var { readFile } = require("fs/promises");
458
+ var PromiseB2 = require("bluebird");
459
+ var pathfs = require("path");
460
+ var Documentation = require_Documentation();
461
+ var plugin = {
462
+ enabled: true,
463
+ name: "Documentation",
464
+ displayName: "Documentation",
465
+ description: "Read documentation for a given service",
466
+ icon: "fas fa-book",
467
+ // export: Documentation,
468
+ placements: ["service"],
469
+ order: 6,
470
+ routes: require_routes2(),
471
+ finder: async (search, runeya) => {
426
472
  }
427
- return Buffer.from(decrypted).toString("utf-8");
428
473
  };
429
- async function handleGitConflict(conflictedData, options, filePath) {
430
- const headMatch = conflictedData.match(/<<<<<<< HEAD\r?\n([\s\S]*?)\r?\n=======\r?\n([\s\S]*?)\r?\n>>>>>>>.*/);
431
- if (!headMatch) {
432
- throw new Error("Git conflict detected but could not be properly parsed");
433
- }
434
- try {
435
- const ourVersion = headMatch[1];
436
- const theirVersion = headMatch[2];
437
- let ourDecrypted = "";
438
- let theirDecrypted = "";
439
- try {
440
- ourDecrypted = await module2.exports.decrypt(ourVersion, options);
441
- } catch (err) {
442
- const errorMessage = err instanceof Error ? err.message : String(err);
443
- ourDecrypted = `[ERROR DECRYPTING OUR VERSION: ${errorMessage}]`;
444
- }
445
- try {
446
- theirDecrypted = await module2.exports.decrypt(theirVersion, options);
447
- } catch (err) {
448
- const errorMessage = err instanceof Error ? err.message : String(err);
449
- theirDecrypted = `[ERROR DECRYPTING THEIR VERSION: ${errorMessage}]`;
474
+ module2.exports = plugin;
475
+ }
476
+ });
477
+
478
+ // ../../modules/finder/backend/routes.js
479
+ var require_routes3 = __commonJS({
480
+ "../../modules/finder/backend/routes.js"(exports2, module2) {
481
+ "use strict";
482
+ var express = require("express");
483
+ var router = express.Router();
484
+ var PromiseB2 = require("bluebird");
485
+ function pluginToUrl(plugin) {
486
+ for (let i = 0; i < plugin.placements.length; i += 1) {
487
+ const placement = plugin.placements[i];
488
+ if (typeof placement !== "string") {
489
+ if (placement.position === "toolbox") {
490
+ return `/toolbox${placement.goTo?.path || placement.goTo}`;
491
+ }
492
+ if (placement.position === "sidebar") {
493
+ return `${placement.goTo?.path || placement.goTo}`;
494
+ }
450
495
  }
451
- const conflictData = {
452
- original: conflictedData,
453
- ourVersion: ourDecrypted,
454
- theirVersion: theirDecrypted,
455
- filePath: filePath || null,
456
- filename: filePath ? path.basename(filePath) : null
457
- };
458
- const conflictId = conflictStorage.storeConflict(conflictData);
459
- conflictData.id = conflictId;
460
- sockets2.emit("crypto:conflict", conflictData);
461
- return `${JSON.stringify({
462
- ourVersion: ourDecrypted,
463
- theirVersion: theirDecrypted
464
- })}`;
465
- } catch (error) {
466
- const errorMessage = error instanceof Error ? error.message : String(error);
467
- console.error("Error handling git conflict:", errorMessage);
468
- throw new Error(`Git conflict detected, but failed to process: ${errorMessage}`);
469
496
  }
497
+ return "";
470
498
  }
499
+ var routes = (runeya) => {
500
+ const {
501
+ getServices,
502
+ helpers: { searchString }
503
+ } = runeya;
504
+ router.get("/finder/search", async (req, res) => {
505
+ const search = req.query.q?.toString()?.toUpperCase() || "";
506
+ const services = getServices().filter((service) => searchString(service?.label, search)).map((service) => ({
507
+ title: service.label,
508
+ description: service.description,
509
+ group: "Service",
510
+ url: `/stack-single/${service.label}`
511
+ }));
512
+ const { plugins } = runeya;
513
+ const _plugins = (await PromiseB2.map(Object.keys(plugins), (key) => plugins[key]).map(async (plugin) => [
514
+ ...await plugin?.finder?.(search, runeya)?.catch?.(() => []) || [],
515
+ ...searchString(plugin.name, search) ? [{
516
+ title: plugin.displayName || plugin.name,
517
+ description: plugin.description,
518
+ group: "Plugin",
519
+ icon: plugin.icon,
520
+ url: pluginToUrl(plugin) || ""
521
+ }] : []
522
+ ])).flat().filter((a) => a?.url);
523
+ const result = [
524
+ ...services,
525
+ ..._plugins
526
+ ].filter((a) => a);
527
+ res.send(result);
528
+ });
529
+ return router;
530
+ };
531
+ module2.exports = routes;
471
532
  }
472
533
  });
473
534
 
474
- // helpers/dbs.js
475
- var require_dbs = __commonJS({
476
- "helpers/dbs.js"(exports2, module2) {
535
+ // ../../modules/finder/backend/index.js
536
+ var require_backend4 = __commonJS({
537
+ "../../modules/finder/backend/index.js"(exports2, module2) {
477
538
  "use strict";
478
- var {
479
- existsSync: existsSync2,
480
- mkdirSync,
481
- writeFileSync,
482
- readFileSync,
483
- unlinkSync
484
- } = require("fs");
485
- var pathfs2 = require("path");
486
- var {
487
- readdir,
488
- mkdir: mkdir2,
489
- writeFile,
490
- readFile,
491
- unlink
492
- } = require("fs/promises");
493
- var { fdir } = require("fdir");
494
- var PromiseB2 = require("bluebird");
495
- var { sockets: sockets2 } = require_src();
496
- var args2 = require_args();
497
- var { encrypt, decrypt, decryptFile } = require_crypto();
498
- var alasql = require("alasql");
499
- module2.exports = new class {
500
- constructor() {
501
- __publicField(this, "cache", {});
502
- }
503
- getRootPath() {
504
- const rootPath = pathfs2.resolve(args2.rootPath, ".runeya/dbs");
505
- if (!existsSync2(rootPath)) mkdirSync(rootPath, { recursive: true });
506
- return rootPath;
507
- }
508
- async getDbs(namespace = "") {
509
- const pathToDbs = pathfs2.resolve(this.getRootPath(), namespace);
510
- if (!existsSync2(pathToDbs)) await mkdir2(pathToDbs, { recursive: true });
511
- return (await readdir(pathToDbs)).map((id) => id.replace(pathfs2.extname(id), "").replace(".encrypted", ""));
512
- }
513
- async reencrypt(oldKey, newKey) {
514
- const api = new fdir().withFullPaths().filter((path) => path.endsWith("encrypted.json")).crawl(this.getRootPath());
515
- await PromiseB2.map(api.withPromise(), async (file) => {
516
- const fileEncrypted = await readFile(file, "utf-8");
517
- const additionnalNonce = file.split(".runeya").pop();
518
- const fileDecrypted = await decrypt(fileEncrypted, { additionnalNonce, encryptionKey: oldKey });
519
- const fileReEncrypted = await encrypt(fileDecrypted, { additionnalNonce, encryptionKey: newKey });
520
- await writeFile(file, fileReEncrypted, "utf-8");
521
- });
522
- }
523
- getDb(id, { encrypted, defaultData } = { encrypted: true, defaultData: {} }) {
524
- const getPath = async () => {
525
- const persistencePath = pathfs2.resolve(`${this.getRootPath()}/${id}${encrypted ? ".encrypted" : ""}.json`);
526
- if (!existsSync2(pathfs2.dirname(persistencePath))) await mkdirSync(pathfs2.dirname(persistencePath), { recursive: true });
527
- if (!existsSync2(persistencePath)) {
528
- let defaultDB = JSON.stringify(defaultData || [], null, 2);
529
- if (encrypted) defaultDB = await encrypt(defaultDB, { additionnalNonce: persistencePath.split(".runeya").pop() });
530
- await writeFile(persistencePath, defaultDB, "utf-8");
531
- this.cache[id] = defaultDB;
532
- }
533
- return persistencePath;
534
- };
535
- const table = id.replace(/[^a-z0-9]|\s+|\r?\n|\r/gmi, "_");
536
- const read = async () => {
537
- if (this.cache[id]) return this.cache[id];
538
- const path = await getPath();
539
- const additionnalNonce = path.split(".runeya").pop();
540
- let db = readFileSync(path, "utf-8");
541
- if (encrypted) {
542
- try {
543
- if (typeof db === "string" && (db.includes("<<<<<<< HEAD") || db.includes("=======") || db.includes(">>>>>>>"))) {
544
- db = await decryptFile(db, { additionnalNonce }, path);
545
- } else {
546
- db = await decrypt(db, { additionnalNonce }).catch((err) => {
547
- console.error(path, err);
548
- sockets2.emit("system:wrongKey");
549
- throw err;
550
- });
551
- }
552
- } catch (err) {
553
- console.error(path, err);
554
- sockets2.emit("system:wrongKey");
555
- throw err;
556
- }
557
- }
558
- this.cache[id] = JSON.parse(db);
559
- if (!alasql.tables[table]) {
560
- await alasql(`CREATE TABLE ${table}`);
561
- }
562
- alasql.tables[table].data = this.cache[id];
563
- return this.cache[id];
564
- };
565
- const write = async (data) => {
566
- let db = JSON.stringify(data, null, 2);
567
- const path = await getPath();
568
- const additionnalNonce = path.split(".runeya").pop();
569
- if (encrypted) db = await encrypt(db, { additionnalNonce });
570
- writeFileSync(path, db, "utf-8");
571
- this.cache[id] = data;
572
- if (alasql.tables[table]) {
573
- alasql.tables[table].data = data;
574
- }
575
- };
576
- const escapeQuote = (data) => {
577
- if (typeof data === "string") {
578
- return data.replace(/'/g, "''");
579
- }
580
- return data;
581
- };
582
- const setValue = (item) => {
583
- if (item == null) {
584
- return "NULL";
585
- }
586
- if (item instanceof Date && item.toISOString) {
587
- return `'${item.toISOString()}'`;
588
- }
589
- if (typeof item === "string") {
590
- return `'${escapeQuote(item)}'`;
591
- }
592
- return `${item}`;
593
- };
594
- return {
595
- getPath,
596
- alasql: {
597
- table,
598
- buildUpdateQuery(data) {
599
- const set = [];
600
- Object.keys(data).forEach((key) => {
601
- set.push(`${key} = ${setValue(data[key])}`);
602
- });
603
- return set.join(", ");
604
- },
605
- read: async (sql) => {
606
- await read();
607
- return alasql.promise(sql);
608
- },
609
- /**
610
- *
611
- * @param {{where?: string, orderBy?: string, limit?: number, offset?: number}} param0
612
- * @returns {Promise<any[]>}
613
- */
614
- simpleSelect: async ({ where, orderBy, limit, offset }) => {
615
- await read();
616
- return alasql.promise(`SELECT * FROM ${table} ${where ? `WHERE ${where}` : ""} ${orderBy ? `ORDER BY ${orderBy}` : ""} ${limit ? `LIMIT ${limit}` : ""} ${offset ? `OFFSET ${offset}` : ""}`);
617
- },
618
- /** @param {string} where */
619
- delete: async (where) => {
620
- await read();
621
- await alasql.promise(`DELETE FROM ${table} WHERE ${where}`);
622
- await write(await alasql(`select * from ${table}`));
623
- },
624
- insertOne: async (data) => {
625
- await read();
626
- await alasql.promise(`INSERT INTO ${table} VALUES ${JSON.stringify(data)}`);
627
- await write(await alasql(`select * from ${table}`));
628
- },
629
- write: async (sql, value) => {
630
- await read();
631
- await alasql.promise(sql, value);
632
- await write(await alasql(`select * from ${table}`));
633
- }
634
- },
635
- write,
636
- read,
637
- delete: async () => {
638
- delete this.cache[id];
639
- return unlink(await getPath());
640
- }
641
- };
642
- }
643
- }();
539
+ var commandExists = require("command-exists");
540
+ var plugin = {
541
+ enabled: true,
542
+ name: "Finder",
543
+ displayName: "Finder",
544
+ description: "Find all you want inside this app",
545
+ icon: "fab fa-git-alt",
546
+ export: null,
547
+ order: -1,
548
+ placements: ["global", {
549
+ position: "sidebar",
550
+ label: "Finder",
551
+ icon: "fas fa-search",
552
+ goTo: { path: "/Finder" },
553
+ active: "Finder"
554
+ }],
555
+ hidden: () => commandExists("git").then(() => false).catch(() => true),
556
+ routes: require_routes3()
557
+ };
558
+ module2.exports = plugin;
644
559
  }
645
560
  });
646
561
 
647
- // ../../modules/documentation/backend/Documentation.js
648
- var require_Documentation = __commonJS({
649
- "../../modules/documentation/backend/Documentation.js"(exports2, module2) {
562
+ // helpers/exec.js
563
+ var require_exec = __commonJS({
564
+ "helpers/exec.js"(exports2, module2) {
650
565
  "use strict";
651
- var PromiseB2 = require("bluebird");
652
- var { randomUUID: randomUUID2 } = require("crypto");
653
- var dbs2 = require_dbs();
654
- var db = dbs2.getDb(`documentations`);
655
- var dbDocumentationTree = dbs2.getDb(`documentations-tree`, { encrypted: true, defaultData: [] }).alasql;
656
- var Documentation = class {
566
+ var { exec } = require("child_process");
567
+ module2.exports = {
657
568
  /**
658
- * @param {import('@runeya/common-typings').NonFunctionProperties<Documentation>} documentation
569
+ * @param {string} cmd
570
+ * @param {import('child_process').ExecOptions} options
571
+ * @returns {Promise<string>}
659
572
  */
660
- constructor(documentation) {
661
- this.id = documentation.id || "";
662
- this.text = documentation.text || "";
663
- }
664
- static async load(id) {
665
- }
666
- static async all() {
667
- return db.alasql.select("Select * from ?");
668
- }
669
- static async find(envId) {
670
- const documentations = await this.all();
671
- return documentations.find((env) => env.id === envId);
672
- }
673
- async save() {
674
- const obj = this.toStorage();
675
- await dbs2.getDb(`documentations/${this.id}`).write(obj);
676
- return this;
677
- }
678
- async update(env) {
679
- this.transform = env.transform;
680
- this.label = env.label;
681
- await dbs2.getDb(`documentations/${this.id}`).write(this.toStorage());
682
- }
683
- async delete() {
684
- await dbs2.getDb(`documentations/${this.id}`).delete();
685
- }
686
- toStorage() {
687
- return {
688
- id: this.id,
689
- label: this.label,
690
- transform: this.transform
691
- };
692
- }
693
- };
694
- module2.exports = Documentation;
695
- }
696
- });
697
-
698
- // ../../modules/documentation/backend/Leaf.js
699
- var require_Leaf = __commonJS({
700
- "../../modules/documentation/backend/Leaf.js"(exports2, module2) {
701
- "use strict";
702
- var PromiseB2 = require("bluebird");
703
- var { randomUUID: randomUUID2 } = require("crypto");
704
- var dbs2 = require_dbs();
705
- var { v4 } = require("uuid");
706
- var dbLeafTree = dbs2.getDb(`leafs-leafs`, { encrypted: true, defaultData: [] }).alasql;
707
- var Leaf = class _Leaf {
708
- /**
709
- * @param {import('@runeya/common-typings').NonFunctionProperties<Leaf>} leaf
710
- */
711
- constructor(leaf) {
712
- this.id = leaf.id || v4();
713
- this.docId = leaf.docId || "";
714
- this.serviceId = leaf.serviceId || "";
715
- this.label = leaf.label || "";
716
- this.position = leaf.position || -1;
717
- this.text = leaf.text || "";
718
- this.parentId = leaf.parentId || "";
719
- }
720
- static async getTree(serviceLabel) {
721
- const leafs = await dbLeafTree.read(`Select * from ${dbLeafTree.table} ${serviceLabel ? `where serviceId = '${serviceLabel}'` : `where serviceId=''`}`);
722
- return leafs;
723
- }
724
- toStorage() {
725
- return {
726
- docId: this.docId,
727
- position: this.position,
728
- serviceId: this.serviceId,
729
- label: this.label,
730
- text: this.text,
731
- parentId: this.parentId
732
- };
733
- }
734
- async remove() {
735
- return dbLeafTree.write(`DELETE from ${dbLeafTree.table} where id = '${this.id}'`);
736
- }
737
- static async find({ id }) {
738
- const [leaf] = await dbLeafTree.read(`Select * from ${dbLeafTree.table} where id='${id}'`);
739
- return leaf ? new _Leaf(leaf) : null;
740
- }
741
- async save() {
742
- const leafExists = await _Leaf.find({ id: this.id });
743
- const storage = this.toStorage();
744
- const set = dbLeafTree.buildUpdateQuery(storage);
745
- await leafExists ? dbLeafTree.write(`update ${dbLeafTree.table} set ${set} where id='${this.id}'`) : dbLeafTree.write(`insert into ${dbLeafTree.table} (id, docId, position, serviceId, label, text, parentId) values ('${this.id}', '${this.docId}', ${this.position}, '${this.serviceId}', '${this.label.replace(/'/g, "''")}', '${this.text.replace(/'/g, "''")}', '${this.parentId}')`);
746
- return this;
747
- }
748
- };
749
- module2.exports = Leaf;
750
- }
751
- });
752
-
753
- // ../../modules/documentation/backend/routes.js
754
- var require_routes2 = __commonJS({
755
- "../../modules/documentation/backend/routes.js"(exports2, module2) {
756
- "use strict";
757
- var express = require("express");
758
- var Leaf = require_Leaf();
759
- var PromiseB2 = require("bluebird");
760
- var router = express.Router();
761
- module2.exports = (runeya) => {
762
- const { findService } = runeya;
763
- router.get("/documentation/tree", async (req, res) => {
764
- const service = findService(req.query.serviceId?.toString() || "");
765
- const result = await Leaf.getTree(service?.label);
766
- return res.send(result);
767
- });
768
- router.post("/documentation/tree/sort", async (req, res) => {
769
- const leafs = await PromiseB2.mapSeries(req.body, async (_leaf, index) => {
770
- const leaf = await Leaf.find({ id: _leaf.id });
771
- if (!leaf) return;
772
- leaf.position = index;
773
- await leaf.save();
774
- return leaf;
775
- });
776
- return res.send(leafs);
777
- });
778
- router.post("/documentation/tree", async (req, res) => {
779
- const result = await new Leaf({
780
- ...req.body
781
- }).save();
782
- return res.send(result);
783
- });
784
- router.post("/documentation/tree/:key", async (req, res) => {
785
- const result = await new Leaf({
786
- ...req.body,
787
- id: req.params.key
788
- }).save();
789
- return res.send(result);
790
- });
791
- router.delete("/documentation/tree/:key", async (req, res) => {
792
- const result = await Leaf.find({
793
- id: req.params.key
794
- });
795
- if (result) return res.send(await result.remove());
796
- return res.send();
797
- });
798
- return router;
799
- };
800
- }
801
- });
802
-
803
- // ../../modules/documentation/backend/index.js
804
- var require_backend3 = __commonJS({
805
- "../../modules/documentation/backend/index.js"(exports2, module2) {
806
- "use strict";
807
- var { readFile } = require("fs/promises");
808
- var PromiseB2 = require("bluebird");
809
- var pathfs2 = require("path");
810
- var Documentation = require_Documentation();
811
- var plugin = {
812
- enabled: true,
813
- name: "Documentation",
814
- displayName: "Documentation",
815
- description: "Read documentation for a given service",
816
- icon: "fas fa-book",
817
- // export: Documentation,
818
- placements: ["service"],
819
- order: 6,
820
- routes: require_routes2(),
821
- finder: async (search, runeya) => {
822
- }
823
- };
824
- module2.exports = plugin;
825
- }
826
- });
827
-
828
- // ../../modules/finder/backend/routes.js
829
- var require_routes3 = __commonJS({
830
- "../../modules/finder/backend/routes.js"(exports2, module2) {
831
- "use strict";
832
- var express = require("express");
833
- var router = express.Router();
834
- var PromiseB2 = require("bluebird");
835
- function pluginToUrl(plugin) {
836
- for (let i = 0; i < plugin.placements.length; i += 1) {
837
- const placement = plugin.placements[i];
838
- if (typeof placement !== "string") {
839
- if (placement.position === "toolbox") {
840
- return `/toolbox${placement.goTo?.path || placement.goTo}`;
841
- }
842
- if (placement.position === "sidebar") {
843
- return `${placement.goTo?.path || placement.goTo}`;
844
- }
845
- }
846
- }
847
- return "";
848
- }
849
- var routes = (runeya) => {
850
- const {
851
- getServices,
852
- helpers: { searchString }
853
- } = runeya;
854
- router.get("/finder/search", async (req, res) => {
855
- const search = req.query.q?.toString()?.toUpperCase() || "";
856
- const services = getServices().filter((service) => searchString(service?.label, search)).map((service) => ({
857
- title: service.label,
858
- description: service.description,
859
- group: "Service",
860
- url: `/stack-single/${service.label}`
861
- }));
862
- const { plugins } = runeya;
863
- const _plugins = (await PromiseB2.map(Object.keys(plugins), (key) => plugins[key]).map(async (plugin) => [
864
- ...await plugin?.finder?.(search, runeya)?.catch?.(() => []) || [],
865
- ...searchString(plugin.name, search) ? [{
866
- title: plugin.displayName || plugin.name,
867
- description: plugin.description,
868
- group: "Plugin",
869
- icon: plugin.icon,
870
- url: pluginToUrl(plugin) || ""
871
- }] : []
872
- ])).flat().filter((a) => a?.url);
873
- const result = [
874
- ...services,
875
- ..._plugins
876
- ].filter((a) => a);
877
- res.send(result);
878
- });
879
- return router;
880
- };
881
- module2.exports = routes;
882
- }
883
- });
884
-
885
- // ../../modules/finder/backend/index.js
886
- var require_backend4 = __commonJS({
887
- "../../modules/finder/backend/index.js"(exports2, module2) {
888
- "use strict";
889
- var commandExists = require("command-exists");
890
- var plugin = {
891
- enabled: true,
892
- name: "Finder",
893
- displayName: "Finder",
894
- description: "Find all you want inside this app",
895
- icon: "fab fa-git-alt",
896
- export: null,
897
- order: -1,
898
- placements: ["global", {
899
- position: "sidebar",
900
- label: "Finder",
901
- icon: "fas fa-search",
902
- goTo: { path: "/Finder" },
903
- active: "Finder"
904
- }],
905
- hidden: () => commandExists("git").then(() => false).catch(() => true),
906
- routes: require_routes3()
907
- };
908
- module2.exports = plugin;
909
- }
910
- });
911
-
912
- // helpers/exec.js
913
- var require_exec = __commonJS({
914
- "helpers/exec.js"(exports2, module2) {
915
- "use strict";
916
- var { exec } = require("child_process");
917
- module2.exports = {
918
- /**
919
- * @param {string} cmd
920
- * @param {import('child_process').ExecOptions} options
921
- * @returns {Promise<string>}
922
- */
923
- execAsync(cmd, options) {
924
- return new Promise((res, rej) => {
925
- exec(cmd, options, (err, stdout, stderr) => {
926
- if (err) return rej(stderr || err);
927
- return res(stdout);
928
- });
929
- });
930
- },
931
- /**
932
- * @param {string} cmd
933
- * @param {import('child_process').ExecOptions} options
934
- * @returns {Promise<string>}
935
- */
936
- execAsyncWithoutErr(cmd, options) {
937
- return new Promise((res) => {
938
- exec(cmd, options, (err, stdout) => {
939
- res(stdout);
940
- });
941
- });
942
- },
943
- /**
944
- * @param {string} cmd
945
- * @param {import('child_process').ExecOptions} options
946
- * @returns {Promise<string>}
947
- */
948
- execAsyncGetError(cmd, options) {
949
- return new Promise((res) => {
950
- exec(cmd, options, (err, stdout, stderr) => {
951
- res(stderr);
952
- });
953
- });
573
+ execAsync(cmd, options) {
574
+ return new Promise((res, rej) => {
575
+ exec(cmd, options, (err, stdout, stderr) => {
576
+ if (err) return rej(stderr || err);
577
+ return res(stdout);
578
+ });
579
+ });
580
+ },
581
+ /**
582
+ * @param {string} cmd
583
+ * @param {import('child_process').ExecOptions} options
584
+ * @returns {Promise<string>}
585
+ */
586
+ execAsyncWithoutErr(cmd, options) {
587
+ return new Promise((res) => {
588
+ exec(cmd, options, (err, stdout) => {
589
+ res(stdout);
590
+ });
591
+ });
592
+ },
593
+ /**
594
+ * @param {string} cmd
595
+ * @param {import('child_process').ExecOptions} options
596
+ * @returns {Promise<string>}
597
+ */
598
+ execAsyncGetError(cmd, options) {
599
+ return new Promise((res) => {
600
+ exec(cmd, options, (err, stdout, stderr) => {
601
+ res(stderr);
602
+ });
603
+ });
954
604
  }
955
605
  };
956
606
  }
@@ -1004,16 +654,16 @@ var require_src2 = __commonJS({
1004
654
  var require_Git = __commonJS({
1005
655
  "../../modules/git/backend/Git.js"(exports2, module2) {
1006
656
  "use strict";
1007
- var { existsSync: existsSync2 } = require("fs");
1008
- var pathfs2 = require("path");
657
+ var { existsSync } = require("fs");
658
+ var pathfs = require("path");
1009
659
  var { execAsync, execAsyncWithoutErr } = require_exec();
1010
660
  var HTTPError = require_src2();
1011
661
  var Git = (runeya) => {
1012
662
  const { findService } = runeya;
1013
663
  const searchGit = (path) => {
1014
- if (existsSync2(pathfs2.resolve(path, ".git"))) return path;
1015
- const parentPath = pathfs2.resolve(path, "..");
1016
- if (parentPath === pathfs2.resolve("/")) return null;
664
+ if (existsSync(pathfs.resolve(path, ".git"))) return path;
665
+ const parentPath = pathfs.resolve(path, "..");
666
+ if (parentPath === pathfs.resolve("/")) return null;
1017
667
  return searchGit(parentPath);
1018
668
  };
1019
669
  const getGitRootPath = (service) => searchGit(service.getRootPath());
@@ -1022,7 +672,7 @@ var require_Git = __commonJS({
1022
672
  if (!service.git) throw new Error(`Git Error - ${service?.label}: Git option not set`);
1023
673
  const path = getGitRootPath(service);
1024
674
  if (!path) return false;
1025
- if (!existsSync2(path)) return false;
675
+ if (!existsSync(path)) return false;
1026
676
  return true;
1027
677
  }
1028
678
  return {
@@ -1650,11 +1300,11 @@ var require_stringTransformer_helper = __commonJS({
1650
1300
  var require_Npm = __commonJS({
1651
1301
  "../../modules/npm/backend/Npm.js"(exports2, module2) {
1652
1302
  "use strict";
1653
- var pathfs2 = require("path");
1303
+ var pathfs = require("path");
1654
1304
  var { execAsync } = require_exec();
1655
1305
  var { readFile } = require("fs/promises");
1656
1306
  var { replaceEnvs } = require_stringTransformer_helper();
1657
- var { existsSync: existsSync2 } = require("fs");
1307
+ var { existsSync } = require("fs");
1658
1308
  var Npm = class {
1659
1309
  /** @param {import('@runeya/servers-server/models/Service')} service */
1660
1310
  constructor(service) {
@@ -1662,7 +1312,7 @@ var require_Npm = __commonJS({
1662
1312
  }
1663
1313
  async isNpm(path) {
1664
1314
  if (path) {
1665
- return existsSync2(pathfs2.resolve(path?.toString(), "package.json"));
1315
+ return existsSync(pathfs.resolve(path?.toString(), "package.json"));
1666
1316
  }
1667
1317
  return null;
1668
1318
  }
@@ -1674,13 +1324,13 @@ var require_Npm = __commonJS({
1674
1324
  }
1675
1325
  async packageJSON(path) {
1676
1326
  if (path) {
1677
- return JSON.parse(await readFile(pathfs2.resolve(path?.toString(), "package.json"), "utf-8"));
1327
+ return JSON.parse(await readFile(pathfs.resolve(path?.toString(), "package.json"), "utf-8"));
1678
1328
  }
1679
1329
  return {};
1680
1330
  }
1681
1331
  async packageLock(path) {
1682
1332
  if (path) {
1683
- return JSON.parse(await readFile(pathfs2.resolve(path?.toString(), "package-lock.json"), "utf-8")).catch((err) => {
1333
+ return JSON.parse(await readFile(pathfs.resolve(path?.toString(), "package-lock.json"), "utf-8")).catch((err) => {
1684
1334
  console.error(err);
1685
1335
  return {};
1686
1336
  });
@@ -2109,7 +1759,7 @@ var require_src6 = __commonJS({
2109
1759
  require("express-async-errors");
2110
1760
  var express = require("express");
2111
1761
  var cors = require("cors");
2112
- var pathfs2 = require("path");
1762
+ var pathfs = require("path");
2113
1763
  var fs = require("fs");
2114
1764
  var healthCheck = require_src3();
2115
1765
  var helmet = require("helmet").default;
@@ -2179,7 +1829,7 @@ var require_src6 = __commonJS({
2179
1829
  authApi = (app) => {
2180
1830
  }
2181
1831
  }) {
2182
- const pkgJSONPath = pathfs2.resolve(baseUrl, "package.json");
1832
+ const pkgJSONPath = pathfs.resolve(baseUrl, "package.json");
2183
1833
  const isPkgJSONExists = fs.existsSync(pkgJSONPath);
2184
1834
  const pkgJSON = isPkgJSONExists ? require(pkgJSONPath) : { name: "unknown", version: "unknown" };
2185
1835
  const appVersion = pkgJSON.version;
@@ -2272,9 +1922,9 @@ var require_routes10 = __commonJS({
2272
1922
  var RED = require("node-red");
2273
1923
  var compressing = require("compressing");
2274
1924
  var router = express.Router();
2275
- var pathfs2 = require("path");
2276
- var { existsSync: existsSync2 } = require("fs");
2277
- var { rm: rm2, readFile, writeFile, mkdir: mkdir2, readdir } = require("fs/promises");
1925
+ var pathfs = require("path");
1926
+ var { existsSync } = require("fs");
1927
+ var { rm, readFile, writeFile, mkdir, readdir } = require("fs/promises");
2278
1928
  var ports = require_ports();
2279
1929
  var { execAsync } = require_exec();
2280
1930
  var EncryptionKey = require_EncryptionKey();
@@ -2282,8 +1932,8 @@ var require_routes10 = __commonJS({
2282
1932
  var { v4 } = require("uuid");
2283
1933
  module2.exports = (Stack) => {
2284
1934
  getServer().then(async (server) => {
2285
- const userDir = pathfs2.resolve(Stack.getRootPath(), "nodered");
2286
- if (!existsSync2(userDir)) await mkdir2(userDir, { recursive: true });
1935
+ const userDir = pathfs.resolve(Stack.getRootPath(), "nodered");
1936
+ if (!existsSync(userDir)) await mkdir(userDir, { recursive: true });
2287
1937
  const settings = {
2288
1938
  httpAdminRoot: "/red",
2289
1939
  httpNodeRoot: "/node-red",
@@ -2305,25 +1955,25 @@ var require_routes10 = __commonJS({
2305
1955
  router.use(settings.httpNodeRoot, RED.httpNode);
2306
1956
  const moduleName = "node-red-contrib-runeya";
2307
1957
  const moduleNameLegacy = "node-red-contrib-stack-monitor";
2308
- const modulePath = pathfs2.resolve(userDir, "node_modules", moduleName);
2309
- const localNodeModuleTarPath = pathfs2.resolve(__dirname, `${moduleName}.tar`);
2310
- const packageJSONPath = pathfs2.resolve(userDir, "package.json");
2311
- if (existsSync2(pathfs2.resolve(userDir, "node_modules", moduleNameLegacy))) {
2312
- await rm2(pathfs2.resolve(userDir, "node_modules", moduleNameLegacy), { recursive: true, force: true });
1958
+ const modulePath = pathfs.resolve(userDir, "node_modules", moduleName);
1959
+ const localNodeModuleTarPath = pathfs.resolve(__dirname, `${moduleName}.tar`);
1960
+ const packageJSONPath = pathfs.resolve(userDir, "package.json");
1961
+ if (existsSync(pathfs.resolve(userDir, "node_modules", moduleNameLegacy))) {
1962
+ await rm(pathfs.resolve(userDir, "node_modules", moduleNameLegacy), { recursive: true, force: true });
2313
1963
  await execAsync("npm uninstall node-red-contrib-stack-monitor", { cwd: userDir });
2314
1964
  }
2315
- if (existsSync2(modulePath)) {
1965
+ if (existsSync(modulePath)) {
2316
1966
  console.log(moduleName, "found, delete it before start nodered");
2317
- await rm2(modulePath, { recursive: true, force: true });
1967
+ await rm(modulePath, { recursive: true, force: true });
2318
1968
  await execAsync("npm uninstall node-red-contrib-runeya", { cwd: userDir });
2319
1969
  }
2320
1970
  await PromiseB2.map(await readdir(userDir), async (file) => {
2321
1971
  if (file.startsWith(`node-red-contrib-runeya-`) && file.endsWith(".tgz")) {
2322
- await rm2(pathfs2.resolve(userDir, file));
1972
+ await rm(pathfs.resolve(userDir, file));
2323
1973
  }
2324
1974
  });
2325
1975
  let buffer;
2326
- if (existsSync2(localNodeModuleTarPath)) {
1976
+ if (existsSync(localNodeModuleTarPath)) {
2327
1977
  console.log(`Read ${moduleName} from local tar`);
2328
1978
  buffer = await readFile(localNodeModuleTarPath);
2329
1979
  } else {
@@ -2338,7 +1988,7 @@ var require_routes10 = __commonJS({
2338
1988
  var stream2buffer = stream2buffer2;
2339
1989
  console.log(`Build ${moduleName} from dir`);
2340
1990
  const stream = new compressing.tar.Stream();
2341
- stream.addEntry(pathfs2.resolve(__dirname, "./nodes"), { ignoreBase: true, relativePath: "package" });
1991
+ stream.addEntry(pathfs.resolve(__dirname, "./nodes"), { ignoreBase: true, relativePath: "package" });
2342
1992
  buffer = await stream2buffer2(stream);
2343
1993
  }
2344
1994
  let packageJSON = {
@@ -2348,16 +1998,16 @@ var require_routes10 = __commonJS({
2348
1998
  "private": true,
2349
1999
  "dependencies": {}
2350
2000
  };
2351
- if (existsSync2(packageJSONPath)) {
2001
+ if (existsSync(packageJSONPath)) {
2352
2002
  Object.assign(packageJSON, JSON.parse(await readFile(packageJSONPath, "utf-8")));
2353
2003
  }
2354
2004
  const tgzFileName = `${moduleName}.tgz`;
2355
2005
  packageJSON.dependencies[moduleName] = `file:${tgzFileName}`;
2356
- const pathToTgz = pathfs2.resolve(userDir, `${tgzFileName}`);
2006
+ const pathToTgz = pathfs.resolve(userDir, `${tgzFileName}`);
2357
2007
  await writeFile(pathToTgz, buffer);
2358
2008
  await writeFile(packageJSONPath, JSON.stringify(packageJSON, null, 2), "utf-8");
2359
2009
  await execAsync("npm i", { cwd: userDir });
2360
- await writeFile(pathfs2.resolve(userDir, ".gitignore"), `*
2010
+ await writeFile(pathfs.resolve(userDir, ".gitignore"), `*
2361
2011
  !flow.json
2362
2012
  !flow_cred.json
2363
2013
  !package.json
@@ -2513,7 +2163,7 @@ var require_Environment = __commonJS({
2513
2163
  var PromiseB2 = require("bluebird");
2514
2164
  var { cloneDeep, merge, over } = require("lodash");
2515
2165
  var dbs2 = require_dbs();
2516
- var { existsSync: existsSync2 } = require("fs");
2166
+ var { existsSync } = require("fs");
2517
2167
  var Environment = class _Environment {
2518
2168
  /**
2519
2169
  * @param {import('@runeya/common-typings').NonFunctionProperties<Environment>} environment
@@ -2530,7 +2180,7 @@ var require_Environment = __commonJS({
2530
2180
  static async load(label, Stack) {
2531
2181
  const environmentDB = await dbs2.getDb(`envs/${label}`).read();
2532
2182
  const overridesDB = dbs2.getDb(`overrides/${label}-environment`);
2533
- if (!existsSync2(await overridesDB.getPath())) await new _Environment(environmentDB).save();
2183
+ if (!existsSync(await overridesDB.getPath())) await new _Environment(environmentDB).save();
2534
2184
  const overrides = await dbs2.getDb(`overrides/${label}-environment`).read();
2535
2185
  merge(environmentDB?.envs || {}, overrides?.envs || {});
2536
2186
  return new _Environment(environmentDB, Stack);
@@ -2758,13 +2408,13 @@ var require_Service = __commonJS({
2758
2408
  var PromiseB2 = require("bluebird");
2759
2409
  var dayjs = require("dayjs");
2760
2410
  var { v4 } = require("uuid");
2761
- var { existsSync: existsSync2, readFileSync } = require("fs");
2411
+ var { existsSync, readFileSync } = require("fs");
2762
2412
  var kill = require("tree-kill");
2763
2413
  var axios = require("axios").default;
2764
- var pathfs2 = require("path");
2414
+ var pathfs = require("path");
2765
2415
  var net = require("net");
2766
2416
  var { sockets: sockets2 } = require_src();
2767
- var { mkdir: mkdir2, writeFile } = require("fs/promises");
2417
+ var { mkdir, writeFile } = require("fs/promises");
2768
2418
  var { cloneDeep, over } = require("lodash");
2769
2419
  var CreateInterface = require_readline();
2770
2420
  var { stripAnsi, ansiconvert, unescapeAnsi } = require_ansiconvert();
@@ -2896,8 +2546,8 @@ var require_Service = __commonJS({
2896
2546
  return new Service(await dbs2.getDb(`services/${label}`).read(), Stack);
2897
2547
  };
2898
2548
  Service.prototype.loadCustomEnv = function(path2) {
2899
- const dotEnvPath = pathfs2.resolve(path2, ".env");
2900
- if (existsSync2(dotEnvPath) && readFileSync(dotEnvPath, { encoding: "utf-8" }).trim()) {
2549
+ const dotEnvPath = pathfs.resolve(path2, ".env");
2550
+ if (existsSync(dotEnvPath) && readFileSync(dotEnvPath, { encoding: "utf-8" }).trim()) {
2901
2551
  console.log(`! A .env will override your ${this.label} service !`);
2902
2552
  return require("dotenv").parse(readFileSync(dotEnvPath, "utf-8"));
2903
2553
  }
@@ -3051,7 +2701,7 @@ var require_Service = __commonJS({
3051
2701
  this.crashed = false;
3052
2702
  this.exited = false;
3053
2703
  let { cmd, args: args2, options } = this.container.enabled ? await this.parseIncomingCommandDocker(command) : await this.parseIncomingCommand(command);
3054
- if (!existsSync2(options.cwd)) {
2704
+ if (!existsSync(options.cwd)) {
3055
2705
  this.crashed = true;
3056
2706
  this.exited = true;
3057
2707
  const launchMessage2 = {
@@ -3315,7 +2965,7 @@ var require_Service = __commonJS({
3315
2965
  "sh",
3316
2966
  `-c '${spawnCmd} ${spawnArgs.join(" ")}'`
3317
2967
  ];
3318
- const cwd = pathfs2.resolve(replaceEnvs(spawnOptions.cwd || this.getRootPath() || "."));
2968
+ const cwd = pathfs.resolve(replaceEnvs(spawnOptions.cwd || this.getRootPath() || "."));
3319
2969
  const options = {
3320
2970
  cwd,
3321
2971
  shell: isWindows ? process.env.ComSpec : "/bin/sh"
@@ -3332,7 +2982,7 @@ var require_Service = __commonJS({
3332
2982
  cmd = currentAlias?.cmd || cmd;
3333
2983
  args2 = [...currentAlias?.args || [], ...args2];
3334
2984
  }
3335
- const cwd = pathfs2.resolve(replaceEnvs(spawnOptions.cwd || this.getRootPath() || "."));
2985
+ const cwd = pathfs.resolve(replaceEnvs(spawnOptions.cwd || this.getRootPath() || "."));
3336
2986
  const options = {
3337
2987
  ...spawnOptions,
3338
2988
  cwd,
@@ -3349,19 +2999,19 @@ var require_Service = __commonJS({
3349
2999
  return { cmd, args: args2, options };
3350
3000
  };
3351
3001
  function replaceHome(str) {
3352
- return str.startsWith("~") ? pathfs2.resolve(os.homedir(), str.replace("~/", "")) : pathfs2.resolve(str);
3002
+ return str.startsWith("~") ? pathfs.resolve(os.homedir(), str.replace("~/", "")) : pathfs.resolve(str);
3353
3003
  }
3354
3004
  Service.prototype.getDockerVolumesArgs = async function() {
3355
3005
  const internalVolumeRootPath = replaceHome(this.container.sharedVolume);
3356
3006
  const volumesCmd = this.container.volumes.map((v) => {
3357
3007
  let [external, internal] = v.split(":");
3358
- if (external) external = pathfs2.resolve(replaceHome(replaceEnvs(external)));
3359
- if (internal) internal = pathfs2.resolve(replaceHome(replaceEnvs(internal)));
3008
+ if (external) external = pathfs.resolve(replaceHome(replaceEnvs(external)));
3009
+ if (internal) internal = pathfs.resolve(replaceHome(replaceEnvs(internal)));
3360
3010
  return ["-v", `"${external}:${internal || external}"`];
3361
3011
  });
3362
3012
  volumesCmd.push(...await PromiseB2.map(this.container.ignoreVolumes, async (ignoredVolume) => {
3363
- const volumePath = pathfs2.join(internalVolumeRootPath, `ignored-volume-${humanStringToKey(this.label)}`, ignoredVolume);
3364
- if (!existsSync2(volumePath)) await mkdir2(volumePath, { recursive: true });
3013
+ const volumePath = pathfs.join(internalVolumeRootPath, `ignored-volume-${humanStringToKey(this.label)}`, ignoredVolume);
3014
+ if (!existsSync(volumePath)) await mkdir(volumePath, { recursive: true });
3365
3015
  return ["-v", `"${volumePath}:${ignoredVolume}"`];
3366
3016
  }).filter((f) => !!f?.length));
3367
3017
  return volumesCmd.flat(1);
@@ -3383,8 +3033,8 @@ var require_Service = __commonJS({
3383
3033
  };
3384
3034
  Service.prototype.launchDockerBuild = async function({ isMainProcess }) {
3385
3035
  const internalVolumeRootPath = replaceHome(this.container.sharedVolume);
3386
- const dockerFilePath = pathfs2.resolve(internalVolumeRootPath, `Dockerfile.${this.container.name}`);
3387
- const dockerContextPath = pathfs2.resolve(internalVolumeRootPath, ".empty-context");
3036
+ const dockerFilePath = pathfs.resolve(internalVolumeRootPath, `Dockerfile.${this.container.name}`);
3037
+ const dockerContextPath = pathfs.resolve(internalVolumeRootPath, ".empty-context");
3388
3038
  const command = {
3389
3039
  spwanCmd: "docker",
3390
3040
  spawnArgs: ["build", "-f", dockerFilePath, "-t", this.container?.name || "", dockerContextPath],
@@ -3467,11 +3117,11 @@ var require_Service = __commonJS({
3467
3117
  isMainProcess
3468
3118
  }) {
3469
3119
  const internalVolumeRootPath = replaceHome(this.container.sharedVolume);
3470
- const dockerFilePath = pathfs2.resolve(internalVolumeRootPath, `Dockerfile.${this.container.name}`);
3471
- const dockerIgnoreFilePath = pathfs2.resolve(internalVolumeRootPath, ".dockerignore");
3472
- const dockerContextPath = pathfs2.resolve(internalVolumeRootPath, ".empty-context");
3473
- if (!existsSync2(internalVolumeRootPath)) await mkdir2(internalVolumeRootPath, { recursive: true });
3474
- if (!existsSync2(dockerContextPath)) await mkdir2(dockerContextPath, { recursive: true });
3120
+ const dockerFilePath = pathfs.resolve(internalVolumeRootPath, `Dockerfile.${this.container.name}`);
3121
+ const dockerIgnoreFilePath = pathfs.resolve(internalVolumeRootPath, ".dockerignore");
3122
+ const dockerContextPath = pathfs.resolve(internalVolumeRootPath, ".empty-context");
3123
+ if (!existsSync(internalVolumeRootPath)) await mkdir(internalVolumeRootPath, { recursive: true });
3124
+ if (!existsSync(dockerContextPath)) await mkdir(dockerContextPath, { recursive: true });
3475
3125
  await writeFile(dockerFilePath, `${this.container.build || ""}`);
3476
3126
  await writeFile(dockerIgnoreFilePath, "Dockerfile.*".trim(), "utf-8");
3477
3127
  await this.launchDockerBuild({ isMainProcess });
@@ -3531,268 +3181,676 @@ var require_exportedHelpers = __commonJS({
3531
3181
  searchString(str, search) {
3532
3182
  return str?.toUpperCase()?.includes(search);
3533
3183
  }
3534
- };
3535
- }
3536
- });
3537
-
3538
- // helpers/version.js
3539
- var require_version = __commonJS({
3540
- "helpers/version.js"(exports2, module2) {
3541
- "use strict";
3542
- var { existsSync: existsSync2, readFileSync } = require("fs");
3543
- var path = require("path");
3544
- var file = {
3545
- version: "0.0.0"
3546
- };
3547
- if (existsSync2(path.resolve(__dirname, "./package.json"))) {
3548
- file.version = JSON.parse(readFileSync(path.resolve(__dirname, "./package.json"), { encoding: "utf-8" })).version;
3549
- } else if (existsSync2(path.resolve(__dirname, "../package.json"))) {
3550
- file.version = JSON.parse(readFileSync(path.resolve(__dirname, "../package.json"), { encoding: "utf-8" })).version;
3551
- } else if (existsSync2(path.resolve(__dirname, "../../../lerna.json"))) {
3552
- file.version = JSON.parse(readFileSync(path.resolve(__dirname, "../../../lerna.json"), { encoding: "utf-8" })).version;
3553
- }
3554
- module2.exports = {
3555
- version: file.version
3556
- };
3557
- }
3558
- });
3559
-
3560
- // models/saves.js
3561
- var require_saves = __commonJS({
3562
- "models/saves.js"(exports2, module2) {
3563
- "use strict";
3564
- var pathfs2 = require("path");
3565
- var homedir = require("os").homedir();
3566
- var {
3567
- existsSync: existsSync2,
3568
- mkdirSync,
3569
- writeFileSync,
3570
- readFileSync
3571
- } = require("fs");
3572
- var confDir = pathfs2.resolve(homedir, ".runeya");
3573
- function getSave(file, initialData, options = {}) {
3574
- if (!existsSync2(confDir)) mkdirSync(confDir);
3575
- const dataConfPath = pathfs2.resolve(confDir, file);
3576
- if (!existsSync2(dataConfPath)) writeFileSync(dataConfPath, JSON.stringify(initialData), "utf-8");
3577
- const data = JSON.parse(readFileSync(dataConfPath, "utf-8"));
3578
- options?.afterGet?.(data);
3579
- return {
3580
- /** @type {T} */
3581
- data,
3582
- save() {
3583
- options?.beforeSave?.(data);
3584
- writeFileSync(dataConfPath, JSON.stringify(data), "utf-8");
3585
- }
3586
- };
3587
- }
3588
- module2.exports = getSave;
3184
+ };
3185
+ }
3186
+ });
3187
+
3188
+ // helpers/version.js
3189
+ var require_version = __commonJS({
3190
+ "helpers/version.js"(exports2, module2) {
3191
+ "use strict";
3192
+ var { existsSync, readFileSync } = require("fs");
3193
+ var path = require("path");
3194
+ var file = {
3195
+ version: "0.0.0"
3196
+ };
3197
+ if (existsSync(path.resolve(__dirname, "./package.json"))) {
3198
+ file.version = JSON.parse(readFileSync(path.resolve(__dirname, "./package.json"), { encoding: "utf-8" })).version;
3199
+ } else if (existsSync(path.resolve(__dirname, "../package.json"))) {
3200
+ file.version = JSON.parse(readFileSync(path.resolve(__dirname, "../package.json"), { encoding: "utf-8" })).version;
3201
+ } else if (existsSync(path.resolve(__dirname, "../../../lerna.json"))) {
3202
+ file.version = JSON.parse(readFileSync(path.resolve(__dirname, "../../../lerna.json"), { encoding: "utf-8" })).version;
3203
+ }
3204
+ module2.exports = {
3205
+ version: file.version
3206
+ };
3207
+ }
3208
+ });
3209
+
3210
+ // models/saves.js
3211
+ var require_saves = __commonJS({
3212
+ "models/saves.js"(exports2, module2) {
3213
+ "use strict";
3214
+ var pathfs = require("path");
3215
+ var homedir = require("os").homedir();
3216
+ var {
3217
+ existsSync,
3218
+ mkdirSync,
3219
+ writeFileSync,
3220
+ readFileSync
3221
+ } = require("fs");
3222
+ var confDir = pathfs.resolve(homedir, ".runeya");
3223
+ function getSave(file, initialData, options = {}) {
3224
+ if (!existsSync(confDir)) mkdirSync(confDir);
3225
+ const dataConfPath = pathfs.resolve(confDir, file);
3226
+ if (!existsSync(dataConfPath)) writeFileSync(dataConfPath, JSON.stringify(initialData), "utf-8");
3227
+ const data = JSON.parse(readFileSync(dataConfPath, "utf-8"));
3228
+ options?.afterGet?.(data);
3229
+ return {
3230
+ /** @type {T} */
3231
+ data,
3232
+ save() {
3233
+ options?.beforeSave?.(data);
3234
+ writeFileSync(dataConfPath, JSON.stringify(data), "utf-8");
3235
+ }
3236
+ };
3237
+ }
3238
+ module2.exports = getSave;
3239
+ }
3240
+ });
3241
+
3242
+ // models/stack.js
3243
+ var require_stack = __commonJS({
3244
+ "models/stack.js"(exports2, module2) {
3245
+ "use strict";
3246
+ var { sockets: sockets2 } = require_src();
3247
+ var plugins = require_plugins();
3248
+ var PromiseB2 = require("bluebird");
3249
+ var Service = require_Service();
3250
+ var ports = require_ports();
3251
+ var dbs2 = require_dbs();
3252
+ var EnvironmentModel = require_Environment();
3253
+ var EncryptionKey = require_EncryptionKey();
3254
+ var CustomObservable = require_CustomObservable();
3255
+ var args2 = require_args();
3256
+ var { existsSync, mkdirSync } = require("fs");
3257
+ var { rename, cp, rmdir, rm } = require("fs/promises");
3258
+ var pathfs = require("path");
3259
+ var { default: axios } = require("axios");
3260
+ function Stack(stack) {
3261
+ this.onServerLauch = new CustomObservable();
3262
+ return (async () => {
3263
+ this.watchFiles = stack.watchFiles || [];
3264
+ this.logParsers = stack.logParsers || [];
3265
+ this.monorepo = stack.monorepo || false;
3266
+ this.themes = stack.themes || {};
3267
+ this.environments = stack.environments ? stack.environments.map((env) => new EnvironmentModel(env)) : [];
3268
+ this.documentation = stack.documentation;
3269
+ this.services = await PromiseB2.map(stack.services || [], (service) => new Service(
3270
+ service,
3271
+ /** @type {StackWithPlugins} */
3272
+ Stack
3273
+ ));
3274
+ this.helpers = require_exportedHelpers();
3275
+ return this;
3276
+ })();
3277
+ }
3278
+ Stack.currentStack = null;
3279
+ Stack.currentWatches = [];
3280
+ Stack.currentEnvironment = null;
3281
+ Stack.Socket = sockets2;
3282
+ Stack.plugins = plugins;
3283
+ Stack.version = require_version().version || "";
3284
+ Stack.url = `http://localhost:${ports.http}`;
3285
+ Stack.port = +ports.http;
3286
+ Stack.parsers = {
3287
+ links: require_link(),
3288
+ jsons: require_json(),
3289
+ debug: require_debug()
3290
+ };
3291
+ Stack.helpers = require_exportedHelpers();
3292
+ Stack.getSave = require_saves();
3293
+ Stack.prototype.enable = async function(servicesLabelSelected) {
3294
+ const services = this.getServices();
3295
+ await PromiseB2.map(servicesLabelSelected, (serviceConf) => {
3296
+ const service = services.find((service2) => serviceConf.label === service2.label);
3297
+ if (!service) return null;
3298
+ const hasChanged = serviceConf.enabled !== service.enabled;
3299
+ if (hasChanged) {
3300
+ if (serviceConf.enabled) {
3301
+ service.enable();
3302
+ return service.launch();
3303
+ }
3304
+ service.disable();
3305
+ return service.kill();
3306
+ }
3307
+ return null;
3308
+ });
3309
+ };
3310
+ Stack.restart = async function() {
3311
+ await PromiseB2.map(this.getEnabledServices(), (service) => service.restart());
3312
+ };
3313
+ Stack.kill = async function() {
3314
+ await PromiseB2.map(this.getEnabledServices(), (service) => service.kill());
3315
+ };
3316
+ Stack.getCurrentEnvironment = function() {
3317
+ return Stack.currentEnvironment;
3318
+ };
3319
+ Stack.prototype.toStorage = function() {
3320
+ return {
3321
+ watchFiles: this.watchFiles,
3322
+ themes: this.themes,
3323
+ services: this.services.map((s) => s.toStorage())
3324
+ };
3325
+ };
3326
+ Stack.getRootPath = () => {
3327
+ const rootPath = pathfs.resolve(args2.rootPath, ".runeya");
3328
+ return rootPath;
3329
+ };
3330
+ Stack.parse = async function() {
3331
+ const dbsRootPath = await dbs2.getDbs("services");
3332
+ let services = [];
3333
+ let environments = [];
3334
+ try {
3335
+ services = await PromiseB2.map(dbsRootPath, (id) => Service.load(id, Stack));
3336
+ environments = await EnvironmentModel.all();
3337
+ } catch (error) {
3338
+ console.error(error);
3339
+ this.Socket.emit("system:wrongKey");
3340
+ }
3341
+ return new Stack({
3342
+ environments,
3343
+ services
3344
+ });
3345
+ };
3346
+ Stack.prototype.launch = async function() {
3347
+ await PromiseB2.map(this.getServices(), (microservice) => {
3348
+ if (microservice.enabled) {
3349
+ return microservice.launch();
3350
+ }
3351
+ return microservice.kill();
3352
+ });
3353
+ };
3354
+ Stack.getStack = function() {
3355
+ return Stack.currentStack;
3356
+ };
3357
+ Stack.getServices = function() {
3358
+ return Stack.currentStack?.services || [];
3359
+ };
3360
+ Stack.deleteService = async function(label) {
3361
+ if (!Stack.currentStack) return;
3362
+ const service = this.findService(label);
3363
+ Stack.currentStack.services = Stack.currentStack.services.filter((a) => a.label !== label);
3364
+ await service.delete();
3365
+ };
3366
+ Stack.prototype.getServices = function() {
3367
+ return Stack.getServices();
3368
+ };
3369
+ Stack.getAxios = function() {
3370
+ return axios.create({ baseURL: this.url });
3371
+ };
3372
+ Stack.getEnabledServices = function() {
3373
+ return Stack.getServices().filter((s) => s.enabled);
3374
+ };
3375
+ Stack.prototype.getEnabledServices = function() {
3376
+ return Stack.getEnabledServices();
3377
+ };
3378
+ Stack.prototype.exportInApi = function() {
3379
+ const res = { ...this };
3380
+ res.services = res.services?.map((s) => s.exportInApi());
3381
+ return res;
3382
+ };
3383
+ Stack.findService = function(serviceLabel) {
3384
+ return Stack.getServices().filter((s) => s.label === serviceLabel)[0];
3385
+ };
3386
+ Stack.prototype.findService = function(serviceLabel) {
3387
+ return Stack.findService(serviceLabel);
3388
+ };
3389
+ Stack.selectConf = async function() {
3390
+ await EncryptionKey.init();
3391
+ if (!EncryptionKey.encryptionKey) {
3392
+ await EncryptionKey.saveKey(await EncryptionKey.generateKey());
3393
+ }
3394
+ Stack.currentStack = await this.parse();
3395
+ Stack.currentEnvironment = args2.e || process.env.RUNEYA_DEFAULT_ENVIRONMENT ? Stack.currentStack.environments.find((env) => env.label === args2.e?.toString() || env.label === process.env.RUNEYA_DEFAULT_ENVIRONMENT) || null : Stack.currentStack.environments.find((env) => env.default) || null;
3396
+ if (process.env.RUNEYA_SERVICES) {
3397
+ process.env.RUNEYA_SERVICES.split(",").forEach((serviceLabel) => {
3398
+ const service = Stack.findService(serviceLabel);
3399
+ if (service) service.enable();
3400
+ });
3401
+ }
3402
+ return sockets2.emit("stack:selectConf");
3403
+ };
3404
+ Stack.prototype.changeEnvironment = async function(envLabel) {
3405
+ const environment = await EnvironmentModel.find(envLabel);
3406
+ if (environment) {
3407
+ Stack.currentEnvironment = environment;
3408
+ Stack.getServices().forEach((service) => {
3409
+ if (!service.envs[envLabel]) {
3410
+ service.envs[envLabel] = {};
3411
+ }
3412
+ });
3413
+ const enabledServices = Stack.getEnabledServices();
3414
+ await Stack.kill();
3415
+ enabledServices.forEach((s) => {
3416
+ s.enabled = true;
3417
+ s.store = [];
3418
+ });
3419
+ await Stack.getStack()?.launch();
3420
+ } else {
3421
+ throw new Error("Environment not found");
3422
+ }
3423
+ };
3424
+ Stack.stopWatchers = function() {
3425
+ Stack.currentWatches.forEach((currentWatch) => currentWatch.close());
3426
+ };
3427
+ var pluginsToLoad = (
3428
+ /** @type {(keyof typeof plugins)[]} */
3429
+ Object.keys(plugins).reduce(
3430
+ (p, key) => {
3431
+ const plugin = plugins[key];
3432
+ if (plugin.export) {
3433
+ p[key] = typeof plugin.export === "function" && !/^\s*class\s+/.test(plugin.export.toString()) ? plugin.export(
3434
+ /** @type {StackWithPlugins} */
3435
+ Stack
3436
+ ) : plugin.export;
3437
+ }
3438
+ return p;
3439
+ },
3440
+ /** @type {OmitNever<typeof plugins>} */
3441
+ {}
3442
+ )
3443
+ );
3444
+ module2.exports = /** @type {StackWithPlugins} */
3445
+ Object.assign(Stack, pluginsToLoad);
3446
+ }
3447
+ });
3448
+
3449
+ // models/EncryptionKey.js
3450
+ var require_EncryptionKey = __commonJS({
3451
+ "models/EncryptionKey.js"(exports2, module2) {
3452
+ "use strict";
3453
+ var { existsSync } = require("fs");
3454
+ var path = require("path");
3455
+ var { writeFile, readFile, appendFile } = require("fs/promises");
3456
+ var { randomUUID: randomUUID2 } = require("crypto");
3457
+ var dbs2 = require_dbs();
3458
+ var { generateKey, encrypt, decrypt } = require_crypto();
3459
+ var reencryptNodered = require_reencrypt_nodered();
3460
+ var pathfs = require("path");
3461
+ var args2 = require_args();
3462
+ var _EncryptionKey_instances, getDb_fn;
3463
+ var EncryptionKey = class {
3464
+ constructor() {
3465
+ __privateAdd(this, _EncryptionKey_instances);
3466
+ this.encryptionKey = "";
3467
+ }
3468
+ async init() {
3469
+ this.encryptionKey = (await __privateMethod(this, _EncryptionKey_instances, getDb_fn).call(this).read()).encryptionKey;
3470
+ }
3471
+ async update() {
3472
+ return __privateMethod(this, _EncryptionKey_instances, getDb_fn).call(this).write(this.toStorage());
3473
+ }
3474
+ toStorage() {
3475
+ return {
3476
+ encryptionKey: this.encryptionKey
3477
+ };
3478
+ }
3479
+ async generateKey() {
3480
+ return generateKey();
3481
+ }
3482
+ async testKey(encryptionKey) {
3483
+ try {
3484
+ const variable = randomUUID2();
3485
+ const result = await encrypt(variable, { encryptionKey });
3486
+ const decrypted = await decrypt(result, { encryptionKey });
3487
+ if (decrypted === variable) return true;
3488
+ return false;
3489
+ } catch (error) {
3490
+ console.error(error);
3491
+ return false;
3492
+ }
3493
+ }
3494
+ async saveKey(key, { noReload } = { noReload: false }) {
3495
+ if (!await this.testKey(key)) throw new Error("Key not valid");
3496
+ try {
3497
+ const envSample = (await dbs2.getDbs("envs"))[0];
3498
+ if (envSample) await dbs2.getDb(`envs/${envSample}`).read();
3499
+ if (this.encryptionKey) {
3500
+ await reencryptNodered(this.encryptionKey, key, pathfs.resolve(require_stack().getRootPath(), "nodered/flow_cred.json"));
3501
+ await dbs2.reencrypt(this.encryptionKey, key);
3502
+ }
3503
+ ;
3504
+ } catch (error) {
3505
+ console.error(error);
3506
+ }
3507
+ const shouldRestart = this.encryptionKey !== key;
3508
+ this.encryptionKey = key;
3509
+ await this.update();
3510
+ if (!noReload) {
3511
+ await require_stack().selectConf();
3512
+ }
3513
+ if (shouldRestart) {
3514
+ console.log("Restart...");
3515
+ require("child_process").spawn(process.argv[0], process.argv.slice(1), {
3516
+ cwd: args2.initialCwd,
3517
+ detached: true,
3518
+ stdio: "inherit"
3519
+ }).unref();
3520
+ process.exit(0);
3521
+ }
3522
+ return key;
3523
+ }
3524
+ };
3525
+ _EncryptionKey_instances = new WeakSet();
3526
+ getDb_fn = function() {
3527
+ return dbs2.getDb("encryption-key", { encrypted: false });
3528
+ };
3529
+ module2.exports = new EncryptionKey();
3530
+ }
3531
+ });
3532
+
3533
+ // helpers/crypto.js
3534
+ var require_crypto = __commonJS({
3535
+ "helpers/crypto.js"(exports2, module2) {
3536
+ "use strict";
3537
+ var _sodium = require("libsodium-wrappers");
3538
+ var crypto = require("crypto");
3539
+ var { sockets: sockets2 } = require_src();
3540
+ var conflictStorage = require_conflictStorage();
3541
+ var path = require("path");
3542
+ module2.exports.generateKey = async () => {
3543
+ await _sodium.ready;
3544
+ const sodium = _sodium;
3545
+ const key = sodium.crypto_aead_aegis256_keygen();
3546
+ return sodium.to_base64(key);
3547
+ };
3548
+ module2.exports.encrypt = async (data, { additionnalNonce = "", encryptionKey = "" } = {}) => {
3549
+ await _sodium.ready;
3550
+ const sodium = _sodium;
3551
+ if (!encryptionKey) encryptionKey = require_EncryptionKey().encryptionKey;
3552
+ const key = sodium.from_base64(encryptionKey);
3553
+ if (!key || key.length !== sodium.crypto_secretbox_KEYBYTES) {
3554
+ throw new Error("Invalid encryption key length");
3555
+ }
3556
+ let nonce;
3557
+ if (additionnalNonce) {
3558
+ const combinedHash = crypto.createHash("blake2b512").update(data + additionnalNonce).digest();
3559
+ nonce = combinedHash.slice(0, sodium.crypto_secretbox_NONCEBYTES);
3560
+ } else {
3561
+ nonce = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES);
3562
+ }
3563
+ const dataStr = typeof data === "string" ? data : String(data);
3564
+ const dataArray = new TextEncoder().encode(dataStr);
3565
+ const ciphertext = sodium.crypto_secretbox_easy(dataArray, nonce, key);
3566
+ return Buffer.concat([
3567
+ Buffer.from(nonce.buffer, nonce.byteOffset, nonce.byteLength),
3568
+ Buffer.from(ciphertext.buffer, ciphertext.byteOffset, ciphertext.byteLength)
3569
+ ]).toString("base64");
3570
+ };
3571
+ module2.exports.decryptFile = async (encryptedData, options = {}, filePath) => {
3572
+ if (typeof encryptedData === "string" && (encryptedData.includes("<<<<<<< HEAD") || encryptedData.includes("=======") || encryptedData.includes(">>>>>>>"))) {
3573
+ return await handleGitConflict(encryptedData, options, filePath);
3574
+ }
3575
+ return await module2.exports.decrypt(encryptedData, options);
3576
+ };
3577
+ module2.exports.decrypt = async (encryptedData, { additionnalNonce = "", encryptionKey = "" } = {}) => {
3578
+ if (typeof encryptedData === "string" && (encryptedData.includes("<<<<<<< HEAD") || encryptedData.includes("=======") || encryptedData.includes(">>>>>>>"))) {
3579
+ return await handleGitConflict(encryptedData, { additionnalNonce, encryptionKey });
3580
+ }
3581
+ await _sodium.ready;
3582
+ const sodium = _sodium;
3583
+ if (!encryptionKey) encryptionKey = require_EncryptionKey().encryptionKey;
3584
+ const key = sodium.from_base64(encryptionKey);
3585
+ if (!key || key.length !== sodium.crypto_secretbox_KEYBYTES) {
3586
+ throw new Error("Invalid decryption key length");
3587
+ }
3588
+ const encryptedBuffer = Buffer.from(encryptedData, "base64");
3589
+ const nonce = encryptedBuffer.slice(0, sodium.crypto_secretbox_NONCEBYTES);
3590
+ const ciphertext = encryptedBuffer.slice(sodium.crypto_secretbox_NONCEBYTES);
3591
+ let decrypted;
3592
+ try {
3593
+ const ciphertextArray = new Uint8Array(ciphertext);
3594
+ const nonceArray = new Uint8Array(nonce);
3595
+ decrypted = sodium.crypto_secretbox_open_easy(ciphertextArray, nonceArray, key);
3596
+ } catch (error) {
3597
+ throw new Error("Decryption failed");
3598
+ }
3599
+ if (!decrypted) {
3600
+ throw new Error("Decryption failed");
3601
+ }
3602
+ return Buffer.from(decrypted).toString("utf-8");
3603
+ };
3604
+ async function handleGitConflict(conflictedData, options, filePath) {
3605
+ const headMatch = conflictedData.match(/<<<<<<< HEAD\r?\n([\s\S]*?)\r?\n=======\r?\n([\s\S]*?)\r?\n>>>>>>>.*/);
3606
+ if (!headMatch) {
3607
+ throw new Error("Git conflict detected but could not be properly parsed");
3608
+ }
3609
+ try {
3610
+ const ourVersion = headMatch[1];
3611
+ const theirVersion = headMatch[2];
3612
+ let ourDecrypted = "";
3613
+ let theirDecrypted = "";
3614
+ try {
3615
+ ourDecrypted = await module2.exports.decrypt(ourVersion, options);
3616
+ } catch (err) {
3617
+ const errorMessage = err instanceof Error ? err.message : String(err);
3618
+ ourDecrypted = `[ERROR DECRYPTING OUR VERSION: ${errorMessage}]`;
3619
+ }
3620
+ try {
3621
+ theirDecrypted = await module2.exports.decrypt(theirVersion, options);
3622
+ } catch (err) {
3623
+ const errorMessage = err instanceof Error ? err.message : String(err);
3624
+ theirDecrypted = `[ERROR DECRYPTING THEIR VERSION: ${errorMessage}]`;
3625
+ }
3626
+ const conflictData = {
3627
+ original: conflictedData,
3628
+ ourVersion: ourDecrypted,
3629
+ theirVersion: theirDecrypted,
3630
+ filePath: filePath || null,
3631
+ filename: filePath ? path.basename(filePath) : null
3632
+ };
3633
+ const conflictId = conflictStorage.storeConflict(conflictData);
3634
+ conflictData.id = conflictId;
3635
+ sockets2.emit("crypto:conflict", conflictData);
3636
+ return `${JSON.stringify({
3637
+ ourVersion: ourDecrypted,
3638
+ theirVersion: theirDecrypted
3639
+ })}`;
3640
+ } catch (error) {
3641
+ const errorMessage = error instanceof Error ? error.message : String(error);
3642
+ console.error("Error handling git conflict:", errorMessage);
3643
+ throw new Error(`Git conflict detected, but failed to process: ${errorMessage}`);
3644
+ }
3645
+ }
3646
+ }
3647
+ });
3648
+
3649
+ // helpers/dbs.js
3650
+ var require_dbs = __commonJS({
3651
+ "helpers/dbs.js"(exports2, module2) {
3652
+ "use strict";
3653
+ var {
3654
+ existsSync,
3655
+ mkdirSync,
3656
+ writeFileSync,
3657
+ readFileSync,
3658
+ unlinkSync
3659
+ } = require("fs");
3660
+ var pathfs = require("path");
3661
+ var {
3662
+ readdir,
3663
+ mkdir,
3664
+ writeFile,
3665
+ readFile,
3666
+ unlink
3667
+ } = require("fs/promises");
3668
+ var { fdir } = require("fdir");
3669
+ var PromiseB2 = require("bluebird");
3670
+ var { sockets: sockets2 } = require_src();
3671
+ var args2 = require_args();
3672
+ var { encrypt, decrypt, decryptFile } = require_crypto();
3673
+ var alasql = require("alasql");
3674
+ module2.exports = new class {
3675
+ constructor() {
3676
+ __publicField(this, "cache", {});
3677
+ }
3678
+ getRootPath() {
3679
+ const rootPath = pathfs.resolve(args2.rootPath, ".runeya/dbs");
3680
+ if (!existsSync(rootPath)) mkdirSync(rootPath, { recursive: true });
3681
+ return rootPath;
3682
+ }
3683
+ async getDbs(namespace = "") {
3684
+ const pathToDbs = pathfs.resolve(this.getRootPath(), namespace);
3685
+ if (!existsSync(pathToDbs)) await mkdir(pathToDbs, { recursive: true });
3686
+ return (await readdir(pathToDbs)).map((id) => id.replace(pathfs.extname(id), "").replace(".encrypted", ""));
3687
+ }
3688
+ async reencrypt(oldKey, newKey) {
3689
+ const api = new fdir().withFullPaths().filter((path) => path.endsWith("encrypted.json")).crawl(this.getRootPath());
3690
+ await PromiseB2.map(api.withPromise(), async (file) => {
3691
+ const fileEncrypted = await readFile(file, "utf-8");
3692
+ const additionnalNonce = file.split(".runeya").pop();
3693
+ const fileDecrypted = await decrypt(fileEncrypted, { additionnalNonce, encryptionKey: oldKey });
3694
+ const fileReEncrypted = await encrypt(fileDecrypted, { additionnalNonce, encryptionKey: newKey });
3695
+ await writeFile(file, fileReEncrypted, "utf-8");
3696
+ });
3697
+ }
3698
+ getDb(id, { encrypted, defaultData } = { encrypted: true, defaultData: {} }) {
3699
+ const getPath = async () => {
3700
+ const persistencePath = pathfs.resolve(`${this.getRootPath()}/${id}${encrypted ? ".encrypted" : ""}.json`);
3701
+ if (!existsSync(pathfs.dirname(persistencePath))) await mkdirSync(pathfs.dirname(persistencePath), { recursive: true });
3702
+ if (!existsSync(persistencePath)) {
3703
+ let defaultDB = JSON.stringify(defaultData || [], null, 2);
3704
+ if (encrypted) defaultDB = await encrypt(defaultDB, { additionnalNonce: persistencePath.split(".runeya").pop() });
3705
+ await writeFile(persistencePath, defaultDB, "utf-8");
3706
+ this.cache[id] = defaultDB;
3707
+ }
3708
+ return persistencePath;
3709
+ };
3710
+ const table = id.replace(/[^a-z0-9]|\s+|\r?\n|\r/gmi, "_");
3711
+ const read = async () => {
3712
+ if (this.cache[id]) return this.cache[id];
3713
+ const path = await getPath();
3714
+ const additionnalNonce = path.split(".runeya").pop();
3715
+ let db = readFileSync(path, "utf-8");
3716
+ if (encrypted) {
3717
+ try {
3718
+ if (typeof db === "string" && (db.includes("<<<<<<< HEAD") || db.includes("=======") || db.includes(">>>>>>>"))) {
3719
+ db = await decryptFile(db, { additionnalNonce }, path);
3720
+ } else {
3721
+ db = await decrypt(db, { additionnalNonce }).catch((err) => {
3722
+ console.error(path, err);
3723
+ sockets2.emit("system:wrongKey");
3724
+ throw err;
3725
+ });
3726
+ }
3727
+ } catch (err) {
3728
+ console.error(path, err);
3729
+ sockets2.emit("system:wrongKey");
3730
+ throw err;
3731
+ }
3732
+ }
3733
+ this.cache[id] = JSON.parse(db);
3734
+ if (!alasql.tables[table]) {
3735
+ await alasql(`CREATE TABLE ${table}`);
3736
+ }
3737
+ alasql.tables[table].data = this.cache[id];
3738
+ return this.cache[id];
3739
+ };
3740
+ const write = async (data) => {
3741
+ let db = JSON.stringify(data, null, 2);
3742
+ const path = await getPath();
3743
+ const additionnalNonce = path.split(".runeya").pop();
3744
+ if (encrypted) db = await encrypt(db, { additionnalNonce });
3745
+ writeFileSync(path, db, "utf-8");
3746
+ this.cache[id] = data;
3747
+ if (alasql.tables[table]) {
3748
+ alasql.tables[table].data = data;
3749
+ }
3750
+ };
3751
+ const escapeQuote = (data) => {
3752
+ if (typeof data === "string") {
3753
+ return data.replace(/'/g, "''");
3754
+ }
3755
+ return data;
3756
+ };
3757
+ const setValue = (item) => {
3758
+ if (item == null) {
3759
+ return "NULL";
3760
+ }
3761
+ if (item instanceof Date && item.toISOString) {
3762
+ return `'${item.toISOString()}'`;
3763
+ }
3764
+ if (typeof item === "string") {
3765
+ return `'${escapeQuote(item)}'`;
3766
+ }
3767
+ return `${item}`;
3768
+ };
3769
+ return {
3770
+ getPath,
3771
+ alasql: {
3772
+ table,
3773
+ buildUpdateQuery(data) {
3774
+ const set = [];
3775
+ Object.keys(data).forEach((key) => {
3776
+ set.push(`${key} = ${setValue(data[key])}`);
3777
+ });
3778
+ return set.join(", ");
3779
+ },
3780
+ read: async (sql) => {
3781
+ await read();
3782
+ return alasql.promise(sql);
3783
+ },
3784
+ /**
3785
+ *
3786
+ * @param {{where?: string, orderBy?: string, limit?: number, offset?: number}} param0
3787
+ * @returns {Promise<any[]>}
3788
+ */
3789
+ simpleSelect: async ({ where, orderBy, limit, offset }) => {
3790
+ await read();
3791
+ return alasql.promise(`SELECT * FROM ${table} ${where ? `WHERE ${where}` : ""} ${orderBy ? `ORDER BY ${orderBy}` : ""} ${limit ? `LIMIT ${limit}` : ""} ${offset ? `OFFSET ${offset}` : ""}`);
3792
+ },
3793
+ /** @param {string} where */
3794
+ delete: async (where) => {
3795
+ await read();
3796
+ await alasql.promise(`DELETE FROM ${table} WHERE ${where}`);
3797
+ await write(await alasql(`select * from ${table}`));
3798
+ },
3799
+ insertOne: async (data) => {
3800
+ await read();
3801
+ await alasql.promise(`INSERT INTO ${table} VALUES ${JSON.stringify(data)}`);
3802
+ await write(await alasql(`select * from ${table}`));
3803
+ },
3804
+ write: async (sql, value) => {
3805
+ await read();
3806
+ await alasql.promise(sql, value);
3807
+ await write(await alasql(`select * from ${table}`));
3808
+ }
3809
+ },
3810
+ write,
3811
+ read,
3812
+ delete: async () => {
3813
+ delete this.cache[id];
3814
+ return unlink(await getPath());
3815
+ }
3816
+ };
3817
+ }
3818
+ }();
3589
3819
  }
3590
3820
  });
3591
3821
 
3592
- // models/stack.js
3593
- var require_stack = __commonJS({
3594
- "models/stack.js"(exports2, module2) {
3822
+ // helpers/createDefaultFiles.js
3823
+ var require_createDefaultFiles = __commonJS({
3824
+ "helpers/createDefaultFiles.js"(exports2, module2) {
3595
3825
  "use strict";
3596
- var { sockets: sockets2 } = require_src();
3597
- var plugins = require_plugins();
3598
- var PromiseB2 = require("bluebird");
3599
- var Service = require_Service();
3600
- var ports = require_ports();
3601
- var dbs2 = require_dbs();
3602
- var EnvironmentModel = require_Environment();
3603
- var EncryptionKey = require_EncryptionKey();
3604
- var CustomObservable = require_CustomObservable();
3826
+ var pathfs = require("path");
3827
+ var { existsSync } = require("fs");
3828
+ var { writeFile, readFile, appendFile } = require("fs/promises");
3605
3829
  var args2 = require_args();
3606
- var { existsSync: existsSync2, mkdirSync } = require("fs");
3607
- var { rename, cp: cp2, rmdir, rm: rm2 } = require("fs/promises");
3608
- var pathfs2 = require("path");
3609
- var { default: axios } = require("axios");
3610
- function Stack(stack) {
3611
- this.onServerLauch = new CustomObservable();
3612
- return (async () => {
3613
- this.watchFiles = stack.watchFiles || [];
3614
- this.logParsers = stack.logParsers || [];
3615
- this.monorepo = stack.monorepo || false;
3616
- this.themes = stack.themes || {};
3617
- this.environments = stack.environments ? stack.environments.map((env) => new EnvironmentModel(env)) : [];
3618
- this.documentation = stack.documentation;
3619
- this.services = await PromiseB2.map(stack.services || [], (service) => new Service(
3620
- service,
3621
- /** @type {StackWithPlugins} */
3622
- Stack
3623
- ));
3624
- this.helpers = require_exportedHelpers();
3625
- return this;
3626
- })();
3627
- }
3628
- Stack.currentStack = null;
3629
- Stack.currentWatches = [];
3630
- Stack.currentEnvironment = null;
3631
- Stack.Socket = sockets2;
3632
- Stack.plugins = plugins;
3633
- Stack.version = require_version().version || "";
3634
- Stack.url = `http://localhost:${ports.http}`;
3635
- Stack.port = +ports.http;
3636
- Stack.parsers = {
3637
- links: require_link(),
3638
- jsons: require_json(),
3639
- debug: require_debug()
3640
- };
3641
- Stack.helpers = require_exportedHelpers();
3642
- Stack.getSave = require_saves();
3643
- Stack.prototype.enable = async function(servicesLabelSelected) {
3644
- const services = this.getServices();
3645
- await PromiseB2.map(servicesLabelSelected, (serviceConf) => {
3646
- const service = services.find((service2) => serviceConf.label === service2.label);
3647
- if (!service) return null;
3648
- const hasChanged = serviceConf.enabled !== service.enabled;
3649
- if (hasChanged) {
3650
- if (serviceConf.enabled) {
3651
- service.enable();
3652
- return service.launch();
3653
- }
3654
- service.disable();
3655
- return service.kill();
3656
- }
3657
- return null;
3658
- });
3659
- };
3660
- Stack.restart = async function() {
3661
- await PromiseB2.map(this.getEnabledServices(), (service) => service.restart());
3662
- };
3663
- Stack.kill = async function() {
3664
- await PromiseB2.map(this.getEnabledServices(), (service) => service.kill());
3665
- };
3666
- Stack.getCurrentEnvironment = function() {
3667
- return Stack.currentEnvironment;
3668
- };
3669
- Stack.prototype.toStorage = function() {
3670
- return {
3671
- watchFiles: this.watchFiles,
3672
- themes: this.themes,
3673
- services: this.services.map((s) => s.toStorage())
3674
- };
3675
- };
3676
- Stack.getRootPath = () => {
3677
- const rootPath = pathfs2.resolve(args2.rootPath, ".runeya");
3678
- return rootPath;
3679
- };
3680
- Stack.parse = async function() {
3681
- const dbsRootPath = await dbs2.getDbs("services");
3682
- let services = [];
3683
- let environments = [];
3684
- try {
3685
- services = await PromiseB2.map(dbsRootPath, (id) => Service.load(id, Stack));
3686
- environments = await EnvironmentModel.all();
3687
- } catch (error) {
3688
- console.error(error);
3689
- this.Socket.emit("system:wrongKey");
3690
- }
3691
- return new Stack({
3692
- environments,
3693
- services
3694
- });
3695
- };
3696
- Stack.prototype.launch = async function() {
3697
- await PromiseB2.map(this.getServices(), (microservice) => {
3698
- if (microservice.enabled) {
3699
- return microservice.launch();
3700
- }
3701
- return microservice.kill();
3702
- });
3703
- };
3704
- Stack.getStack = function() {
3705
- return Stack.currentStack;
3706
- };
3707
- Stack.getServices = function() {
3708
- return Stack.currentStack?.services || [];
3709
- };
3710
- Stack.deleteService = async function(label) {
3711
- if (!Stack.currentStack) return;
3712
- const service = this.findService(label);
3713
- Stack.currentStack.services = Stack.currentStack.services.filter((a) => a.label !== label);
3714
- await service.delete();
3715
- };
3716
- Stack.prototype.getServices = function() {
3717
- return Stack.getServices();
3718
- };
3719
- Stack.getAxios = function() {
3720
- return axios.create({ baseURL: this.url });
3721
- };
3722
- Stack.getEnabledServices = function() {
3723
- return Stack.getServices().filter((s) => s.enabled);
3724
- };
3725
- Stack.prototype.getEnabledServices = function() {
3726
- return Stack.getEnabledServices();
3727
- };
3728
- Stack.prototype.exportInApi = function() {
3729
- const res = { ...this };
3730
- res.services = res.services?.map((s) => s.exportInApi());
3731
- return res;
3732
- };
3733
- Stack.findService = function(serviceLabel) {
3734
- return Stack.getServices().filter((s) => s.label === serviceLabel)[0];
3735
- };
3736
- Stack.prototype.findService = function(serviceLabel) {
3737
- return Stack.findService(serviceLabel);
3738
- };
3739
- Stack.selectConf = async function() {
3740
- await EncryptionKey.init();
3741
- if (!EncryptionKey.encryptionKey) {
3742
- await EncryptionKey.saveKey(await EncryptionKey.generateKey());
3743
- }
3744
- Stack.currentStack = await this.parse();
3745
- Stack.currentEnvironment = args2.e || process.env.RUNEYA_DEFAULT_ENVIRONMENT ? Stack.currentStack.environments.find((env) => env.label === args2.e?.toString() || env.label === process.env.RUNEYA_DEFAULT_ENVIRONMENT) || null : Stack.currentStack.environments.find((env) => env.default) || null;
3746
- if (process.env.RUNEYA_SERVICES) {
3747
- process.env.RUNEYA_SERVICES.split(",").forEach((serviceLabel) => {
3748
- const service = Stack.findService(serviceLabel);
3749
- if (service) service.enable();
3750
- });
3751
- }
3752
- return sockets2.emit("stack:selectConf");
3830
+ var dbs2 = require_dbs();
3831
+ module2.exports = async function createDefaultFiles2() {
3832
+ await createGitignore();
3833
+ await createPluginsGitignore();
3753
3834
  };
3754
- Stack.prototype.changeEnvironment = async function(envLabel) {
3755
- const environment = await EnvironmentModel.find(envLabel);
3756
- if (environment) {
3757
- Stack.currentEnvironment = environment;
3758
- Stack.getServices().forEach((service) => {
3759
- if (!service.envs[envLabel]) {
3760
- service.envs[envLabel] = {};
3761
- }
3762
- });
3763
- const enabledServices = Stack.getEnabledServices();
3764
- await Stack.kill();
3765
- enabledServices.forEach((s) => {
3766
- s.enabled = true;
3767
- s.store = [];
3768
- });
3769
- await Stack.getStack()?.launch();
3770
- } else {
3771
- throw new Error("Environment not found");
3835
+ async function createPluginsGitignore() {
3836
+ const gitignorePath = pathfs.resolve(args2.runeyaConfigPath, ".gitignore");
3837
+ if (!existsSync(gitignorePath)) await writeFile(gitignorePath, "");
3838
+ const gitignoreFile = (await readFile(gitignorePath, "utf-8")).split("\n");
3839
+ const gitignoreHasKey = (key) => gitignoreFile.some((line) => line.trim() === key);
3840
+ if (!gitignoreHasKey("plugins.json")) await appendFile(gitignorePath, "\nplugins.json");
3841
+ if (!gitignoreHasKey("plugins")) await appendFile(gitignorePath, "\nplugins");
3842
+ }
3843
+ async function createGitignore() {
3844
+ const dirname = pathfs.dirname(await dbs2.getDb("encryption-key", { encrypted: false, defaultData: {} }).getPath());
3845
+ const gitignorePath = pathfs.resolve(dirname, ".gitignore");
3846
+ if (!existsSync(gitignorePath)) {
3847
+ await writeFile(gitignorePath, "encryption-key.json");
3772
3848
  }
3773
- };
3774
- Stack.stopWatchers = function() {
3775
- Stack.currentWatches.forEach((currentWatch) => currentWatch.close());
3776
- };
3777
- var pluginsToLoad = (
3778
- /** @type {(keyof typeof plugins)[]} */
3779
- Object.keys(plugins).reduce(
3780
- (p, key) => {
3781
- const plugin = plugins[key];
3782
- if (plugin.export) {
3783
- p[key] = typeof plugin.export === "function" && !/^\s*class\s+/.test(plugin.export.toString()) ? plugin.export(
3784
- /** @type {StackWithPlugins} */
3785
- Stack
3786
- ) : plugin.export;
3787
- }
3788
- return p;
3789
- },
3790
- /** @type {OmitNever<typeof plugins>} */
3791
- {}
3792
- )
3793
- );
3794
- module2.exports = /** @type {StackWithPlugins} */
3795
- Object.assign(Stack, pluginsToLoad);
3849
+ const gitignoreFile = (await readFile(gitignorePath, "utf-8")).split("\n");
3850
+ const gitignoreHasKey = (key) => gitignoreFile.some((line) => line.trim() === key);
3851
+ if (!gitignoreHasKey("encryption-key.json")) await appendFile(gitignorePath, "\nencryption-key.json");
3852
+ if (!gitignoreHasKey("overrides")) await appendFile(gitignorePath, "\noverrides");
3853
+ }
3796
3854
  }
3797
3855
  });
3798
3856
 
@@ -3834,8 +3892,8 @@ var require_plugins2 = __commonJS({
3834
3892
  var { default: axios } = require("axios");
3835
3893
  var { tmpdir } = require("os");
3836
3894
  var path = require("path");
3837
- var { existsSync: existsSync2 } = require("fs");
3838
- var { writeFile, mkdir: mkdir2, readFile, cp: cp2, rm: rm2, readdir } = require("fs/promises");
3895
+ var { existsSync } = require("fs");
3896
+ var { writeFile, mkdir, readFile, cp, rm, readdir, appendFile } = require("fs/promises");
3839
3897
  var { spawn } = require("child_process");
3840
3898
  var dbs2 = require_dbs();
3841
3899
  var HTTPError = require_src2();
@@ -3880,13 +3938,13 @@ var require_plugins2 = __commonJS({
3880
3938
  });
3881
3939
  async function install(remotePath, force = false) {
3882
3940
  const rootPath = args2.rootPath;
3883
- if (!existsSync2(rootPath)) await mkdir2(rootPath, { recursive: true });
3941
+ if (!existsSync(rootPath)) await mkdir(rootPath, { recursive: true });
3884
3942
  const runeyaPath = path.resolve(rootPath, ".runeya");
3885
- if (!existsSync2(runeyaPath)) await mkdir2(runeyaPath, { recursive: true });
3943
+ if (!existsSync(runeyaPath)) await mkdir(runeyaPath, { recursive: true });
3886
3944
  const pluginsPath = path.resolve(runeyaPath, "plugins");
3887
- if (!existsSync2(pluginsPath)) await mkdir2(pluginsPath, { recursive: true });
3945
+ if (!existsSync(pluginsPath)) await mkdir(pluginsPath, { recursive: true });
3888
3946
  const packageTmpPath = path.resolve(tmpdir(), `runeya-plugin-${Date.now()}`);
3889
- if (!existsSync2(packageTmpPath)) await mkdir2(packageTmpPath, { recursive: true });
3947
+ if (!existsSync(packageTmpPath)) await mkdir(packageTmpPath, { recursive: true });
3890
3948
  const packageTmpFilePath = `${packageTmpPath}.tar.gz`;
3891
3949
  const { data } = await axios.get(remotePath, { responseType: "arraybuffer" });
3892
3950
  await writeFile(packageTmpFilePath, data);
@@ -3899,8 +3957,8 @@ var require_plugins2 = __commonJS({
3899
3957
  }
3900
3958
  await dbConfig.alasql.delete(`name='${config.name}'`);
3901
3959
  const diskPath = path.resolve(pluginsPath, config.name);
3902
- if (existsSync2(diskPath)) await rm2(diskPath, { recursive: true, force: true });
3903
- await cp2(path.resolve(packageTmpPath), diskPath, { recursive: true });
3960
+ if (existsSync(diskPath)) await rm(diskPath, { recursive: true, force: true });
3961
+ await cp(path.resolve(packageTmpPath), diskPath, { recursive: true });
3904
3962
  await dbConfig.alasql.insertOne({
3905
3963
  name: config.name,
3906
3964
  version: config.version,
@@ -3991,8 +4049,8 @@ var require_plugins2 = __commonJS({
3991
4049
  if (!plugin) {
3992
4050
  throw new HTTPError("Plugin not found", "404.plugin.not.found");
3993
4051
  }
3994
- if (plugin.diskPath && existsSync2(plugin.diskPath)) {
3995
- await rm2(plugin.diskPath, { recursive: true, force: true });
4052
+ if (plugin.diskPath && existsSync(plugin.diskPath)) {
4053
+ await rm(plugin.diskPath, { recursive: true, force: true });
3996
4054
  }
3997
4055
  await dbConfig.alasql.delete(`name='${name}'`);
3998
4056
  sockets2.emit("plugins:uninstalled", {
@@ -4041,7 +4099,7 @@ var require_plugins2 = __commonJS({
4041
4099
  backendPath = path.resolve(pluginPath, "backend/index.js");
4042
4100
  themePath = path.resolve(pluginPath, "theme/index.js");
4043
4101
  let frontWatcher;
4044
- if (existsSync2(frontPath) && existsSync2(frontPathDist) && existsSync2(backendPath)) {
4102
+ if (existsSync(frontPath) && existsSync(frontPathDist) && existsSync(backendPath)) {
4045
4103
  const debouncedFrontWatcher = debounce(async () => {
4046
4104
  sockets2.emit("plugins:front:building", pluginName);
4047
4105
  console.log("Front changed", pluginName);
@@ -4049,7 +4107,7 @@ var require_plugins2 = __commonJS({
4049
4107
  frontWatcher = chokidar.watch(frontPath, { ignored: frontPathDist, ignoreInitial: true }).on("all", debouncedFrontWatcher);
4050
4108
  }
4051
4109
  let frontDistWatcher;
4052
- if (existsSync2(frontPathDist)) {
4110
+ if (existsSync(frontPathDist)) {
4053
4111
  const debouncedFrontDistWatcher = debounce(async (a, b, c) => {
4054
4112
  sockets2.emit("plugins:front:changed", pluginName);
4055
4113
  console.log("Front dist changed", pluginName);
@@ -4057,7 +4115,7 @@ var require_plugins2 = __commonJS({
4057
4115
  frontDistWatcher = chokidar.watch(frontPathDist, { ignoreInitial: true }).on("all", debouncedFrontDistWatcher);
4058
4116
  }
4059
4117
  let backendWatcher;
4060
- if (existsSync2(backendPath)) {
4118
+ if (existsSync(backendPath)) {
4061
4119
  const debouncedBackendWatcher = debounce(async () => {
4062
4120
  await frontWatcher.close();
4063
4121
  await frontDistWatcher.close();
@@ -4070,7 +4128,7 @@ var require_plugins2 = __commonJS({
4070
4128
  backendPath = null;
4071
4129
  }
4072
4130
  let themeWatcher;
4073
- if (existsSync2(themePath)) {
4131
+ if (existsSync(themePath)) {
4074
4132
  const debouncedThemeWatcher = debounce(async () => {
4075
4133
  if (frontWatcher) await frontWatcher.close();
4076
4134
  if (frontDistWatcher) await frontDistWatcher.close();
@@ -4345,18 +4403,18 @@ var require_system = __commonJS({
4345
4403
  var require_myConfs = __commonJS({
4346
4404
  "models/myConfs.js"(exports2, module2) {
4347
4405
  "use strict";
4348
- var pathfs2 = require("path");
4406
+ var pathfs = require("path");
4349
4407
  var os = require("os");
4350
4408
  var {
4351
- existsSync: existsSync2,
4409
+ existsSync,
4352
4410
  mkdirSync,
4353
4411
  writeFileSync,
4354
4412
  readFileSync
4355
4413
  } = require("fs");
4356
- var persistencePath = pathfs2.resolve(os.homedir(), ".runeya");
4357
- if (!existsSync2(persistencePath)) mkdirSync(persistencePath, { recursive: true });
4358
- var confsPath = pathfs2.resolve(persistencePath, "confs");
4359
- if (!existsSync2(confsPath)) writeFileSync(confsPath, JSON.stringify([]), "utf-8");
4414
+ var persistencePath = pathfs.resolve(os.homedir(), ".runeya");
4415
+ if (!existsSync(persistencePath)) mkdirSync(persistencePath, { recursive: true });
4416
+ var confsPath = pathfs.resolve(persistencePath, "confs");
4417
+ if (!existsSync(confsPath)) writeFileSync(confsPath, JSON.stringify([]), "utf-8");
4360
4418
  var store = JSON.parse(readFileSync(confsPath, "utf-8"));
4361
4419
  module2.exports = {
4362
4420
  /** @type {string[]} */
@@ -4568,7 +4626,7 @@ var require_fs = __commonJS({
4568
4626
  "use strict";
4569
4627
  var { express } = require_src6();
4570
4628
  var router = express.Router();
4571
- var pathfs2 = require("path");
4629
+ var pathfs = require("path");
4572
4630
  var PromiseB2 = require("bluebird");
4573
4631
  var os = require("os");
4574
4632
  var { sort } = require("fast-sort");
@@ -4580,7 +4638,7 @@ var require_fs = __commonJS({
4580
4638
  const path = req.query.path?.toString() || __dirname;
4581
4639
  const dir = await readdir(path);
4582
4640
  const parentDirectory = {
4583
- absolutePath: pathfs2.resolve(path, ".."),
4641
+ absolutePath: pathfs.resolve(path, ".."),
4584
4642
  name: "..",
4585
4643
  isDirectory: true
4586
4644
  };
@@ -4588,7 +4646,7 @@ var require_fs = __commonJS({
4588
4646
  await PromiseB2.map(dir, async (entry) => {
4589
4647
  try {
4590
4648
  if (entry.charAt(0) === ".") return null;
4591
- const absolutePath = pathfs2.resolve(path, entry);
4649
+ const absolutePath = pathfs.resolve(path, entry);
4592
4650
  const entryStat = await stat(absolutePath);
4593
4651
  const entryInfos = {
4594
4652
  absolutePath,
@@ -4599,7 +4657,7 @@ var require_fs = __commonJS({
4599
4657
  };
4600
4658
  if (entryInfos.isDirectory) {
4601
4659
  entryInfos.npmInfos = await getNpmInfos(entryInfos.absolutePath);
4602
- } else if (pathfs2.extname(absolutePath) === ".js") {
4660
+ } else if (pathfs.extname(absolutePath) === ".js") {
4603
4661
  try {
4604
4662
  const stack = require(absolutePath);
4605
4663
  if (Array.isArray(stack) && stack.length && stack[0].label && stack[0].spawnCmd) {
@@ -4622,7 +4680,7 @@ var require_fs = __commonJS({
4622
4680
  async function getNpmInfos(path) {
4623
4681
  const dir = await readdir(path);
4624
4682
  if (dir.includes("package.json")) {
4625
- const packageJSON = JSON.parse(await readFile(pathfs2.resolve(path, "package.json"), "utf-8"));
4683
+ const packageJSON = JSON.parse(await readFile(pathfs.resolve(path, "package.json"), "utf-8"));
4626
4684
  return {
4627
4685
  path,
4628
4686
  packageJSON,
@@ -4950,7 +5008,7 @@ var require_server = __commonJS({
4950
5008
  "bin/server.js"(exports2, module2) {
4951
5009
  "use strict";
4952
5010
  var { launch } = require_src6();
4953
- var pathfs2 = require("path");
5011
+ var pathfs = require("path");
4954
5012
  var ports = require_ports();
4955
5013
  var table = require_console_table();
4956
5014
  var args2 = require_args();
@@ -4963,7 +5021,7 @@ var require_server = __commonJS({
4963
5021
  apiPrefix: "/",
4964
5022
  bodyLimit: "100mb",
4965
5023
  noGreetings: true,
4966
- staticController: process.env.NODE_ENV !== "HFBXdZMJxLyJoua28asEaxRixJ6LriR7FnRzX6pwA7pFjZ" ? pathfs2.resolve(__dirname, "public") : void 0,
5024
+ staticController: process.env.NODE_ENV !== "HFBXdZMJxLyJoua28asEaxRixJ6LriR7FnRzX6pwA7pFjZ" ? pathfs.resolve(__dirname, "public") : void 0,
4967
5025
  helmetConf: process.env.NODE_ENV !== "HFBXdZMJxLyJoua28asEaxRixJ6LriR7FnRzX6pwA7pFjZ" ? {
4968
5026
  crossOriginEmbedderPolicy: false,
4969
5027
  crossOriginResourcePolicy: false,
@@ -5018,33 +5076,14 @@ var require_server = __commonJS({
5018
5076
 
5019
5077
  // bin/www
5020
5078
  var { sockets } = require_src();
5021
- var pathfs = require("path");
5022
- var { mkdir, rm, cp } = require("fs/promises");
5023
- var { existsSync } = require("fs");
5079
+ var migrateStackMonitor = require_migrateStackMonitor();
5080
+ var createDefaultFiles = require_createDefaultFiles();
5024
5081
  process.title = "runeya";
5025
5082
  var args = require_args();
5026
5083
  require("dotenv").config();
5027
5084
  (async () => {
5028
- const localLegacyPath = pathfs.resolve(args.runeyaConfigPath, "../.stackmonitor");
5029
- const localNewPath = args.runeyaConfigPath;
5030
- if (existsSync(localLegacyPath) && !existsSync(localNewPath)) {
5031
- console.log("Legacy path found, copy to new path");
5032
- await cp(localLegacyPath, localNewPath, { recursive: true, force: true });
5033
- }
5034
- const globalLegacyPath = pathfs.resolve(args.runeyaGlobalConfigPath, "../.stackmonitor");
5035
- const globalNewPath = args.runeyaGlobalConfigPath;
5036
- if (existsSync(globalLegacyPath) && !existsSync(globalNewPath)) {
5037
- console.log("Legacy path found, copy to new path");
5038
- await cp(globalLegacyPath, globalNewPath, { recursive: true, force: true });
5039
- }
5040
- if (existsSync(localLegacyPath) && !existsSync(pathfs.resolve(args.runeyaConfigPath, "dbs/overrides"))) {
5041
- console.log("Legacy path found, copy to new path");
5042
- await cp(pathfs.resolve(localLegacyPath, "dbs/overrides"), pathfs.resolve(args.runeyaConfigPath, "dbs/overrides"), { recursive: true, force: true });
5043
- }
5044
- if (existsSync(localLegacyPath) && !existsSync(pathfs.resolve(args.runeyaConfigPath, "dbs/encryption-key.json"))) {
5045
- console.log("Legacy path found, copy to new path");
5046
- await cp(pathfs.resolve(localLegacyPath, "dbs/encryption-key.json"), pathfs.resolve(args.runeyaConfigPath, "dbs/encryption-key.json"), { recursive: true, force: true });
5047
- }
5085
+ await migrateStackMonitor();
5086
+ await createDefaultFiles();
5048
5087
  if (args["pull-env"]) {
5049
5088
  await require_stack().selectConf();
5050
5089
  const service = require_stack().findService(args.s);