@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/node-red-contrib-runeya.tar +0 -0
- package/package.json +1 -1
- package/www.js +1113 -1074
- package/www.js.map +1 -1
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
|
|
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 (!
|
|
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
|
|
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(
|
|
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
|
|
164
|
-
var
|
|
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
|
-
//
|
|
205
|
-
var
|
|
206
|
-
"
|
|
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
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
//
|
|
265
|
-
var
|
|
266
|
-
"
|
|
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
|
|
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 {
|
|
274
|
-
var
|
|
275
|
-
var
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
constructor() {
|
|
280
|
-
|
|
281
|
-
this.
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
this.
|
|
285
|
-
|
|
286
|
-
|
|
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
|
|
297
|
-
|
|
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
|
-
|
|
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
|
|
305
|
-
return
|
|
384
|
+
async remove() {
|
|
385
|
+
return dbLeafTree.write(`DELETE from ${dbLeafTree.table} where id = '${this.id}'`);
|
|
306
386
|
}
|
|
307
|
-
async
|
|
308
|
-
|
|
309
|
-
|
|
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
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
359
|
-
var
|
|
360
|
-
"
|
|
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
|
|
363
|
-
var
|
|
364
|
-
var
|
|
365
|
-
var
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
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
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
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
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
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
|
-
//
|
|
475
|
-
var
|
|
476
|
-
"
|
|
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
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
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
|
-
//
|
|
648
|
-
var
|
|
649
|
-
"
|
|
562
|
+
// helpers/exec.js
|
|
563
|
+
var require_exec = __commonJS({
|
|
564
|
+
"helpers/exec.js"(exports2, module2) {
|
|
650
565
|
"use strict";
|
|
651
|
-
var
|
|
652
|
-
|
|
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 {
|
|
569
|
+
* @param {string} cmd
|
|
570
|
+
* @param {import('child_process').ExecOptions} options
|
|
571
|
+
* @returns {Promise<string>}
|
|
659
572
|
*/
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
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
|
|
1008
|
-
var
|
|
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 (
|
|
1015
|
-
const parentPath =
|
|
1016
|
-
if (parentPath ===
|
|
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 (!
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
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
|
|
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 =
|
|
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
|
|
2276
|
-
var { existsSync
|
|
2277
|
-
var { rm
|
|
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 =
|
|
2286
|
-
if (!
|
|
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 =
|
|
2309
|
-
const localNodeModuleTarPath =
|
|
2310
|
-
const packageJSONPath =
|
|
2311
|
-
if (
|
|
2312
|
-
await
|
|
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 (
|
|
1965
|
+
if (existsSync(modulePath)) {
|
|
2316
1966
|
console.log(moduleName, "found, delete it before start nodered");
|
|
2317
|
-
await
|
|
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
|
|
1972
|
+
await rm(pathfs.resolve(userDir, file));
|
|
2323
1973
|
}
|
|
2324
1974
|
});
|
|
2325
1975
|
let buffer;
|
|
2326
|
-
if (
|
|
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(
|
|
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 (
|
|
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 =
|
|
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(
|
|
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
|
|
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 (!
|
|
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
|
|
2411
|
+
var { existsSync, readFileSync } = require("fs");
|
|
2762
2412
|
var kill = require("tree-kill");
|
|
2763
2413
|
var axios = require("axios").default;
|
|
2764
|
-
var
|
|
2414
|
+
var pathfs = require("path");
|
|
2765
2415
|
var net = require("net");
|
|
2766
2416
|
var { sockets: sockets2 } = require_src();
|
|
2767
|
-
var { mkdir
|
|
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 =
|
|
2900
|
-
if (
|
|
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 (!
|
|
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 =
|
|
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 =
|
|
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("~") ?
|
|
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 =
|
|
3359
|
-
if (internal) 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 =
|
|
3364
|
-
if (!
|
|
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 =
|
|
3387
|
-
const dockerContextPath =
|
|
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 =
|
|
3471
|
-
const dockerIgnoreFilePath =
|
|
3472
|
-
const dockerContextPath =
|
|
3473
|
-
if (!
|
|
3474
|
-
if (!
|
|
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
|
|
3543
|
-
var path = require("path");
|
|
3544
|
-
var file = {
|
|
3545
|
-
version: "0.0.0"
|
|
3546
|
-
};
|
|
3547
|
-
if (
|
|
3548
|
-
file.version = JSON.parse(readFileSync(path.resolve(__dirname, "./package.json"), { encoding: "utf-8" })).version;
|
|
3549
|
-
} else if (
|
|
3550
|
-
file.version = JSON.parse(readFileSync(path.resolve(__dirname, "../package.json"), { encoding: "utf-8" })).version;
|
|
3551
|
-
} else if (
|
|
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
|
|
3565
|
-
var homedir = require("os").homedir();
|
|
3566
|
-
var {
|
|
3567
|
-
existsSync
|
|
3568
|
-
mkdirSync,
|
|
3569
|
-
writeFileSync,
|
|
3570
|
-
readFileSync
|
|
3571
|
-
} = require("fs");
|
|
3572
|
-
var confDir =
|
|
3573
|
-
function getSave(file, initialData, options = {}) {
|
|
3574
|
-
if (!
|
|
3575
|
-
const dataConfPath =
|
|
3576
|
-
if (!
|
|
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
|
-
//
|
|
3593
|
-
var
|
|
3594
|
-
"
|
|
3822
|
+
// helpers/createDefaultFiles.js
|
|
3823
|
+
var require_createDefaultFiles = __commonJS({
|
|
3824
|
+
"helpers/createDefaultFiles.js"(exports2, module2) {
|
|
3595
3825
|
"use strict";
|
|
3596
|
-
var
|
|
3597
|
-
var
|
|
3598
|
-
var
|
|
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
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
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
|
-
|
|
3755
|
-
const
|
|
3756
|
-
if (
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
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
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
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
|
|
3838
|
-
var { writeFile, mkdir
|
|
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 (!
|
|
3941
|
+
if (!existsSync(rootPath)) await mkdir(rootPath, { recursive: true });
|
|
3884
3942
|
const runeyaPath = path.resolve(rootPath, ".runeya");
|
|
3885
|
-
if (!
|
|
3943
|
+
if (!existsSync(runeyaPath)) await mkdir(runeyaPath, { recursive: true });
|
|
3886
3944
|
const pluginsPath = path.resolve(runeyaPath, "plugins");
|
|
3887
|
-
if (!
|
|
3945
|
+
if (!existsSync(pluginsPath)) await mkdir(pluginsPath, { recursive: true });
|
|
3888
3946
|
const packageTmpPath = path.resolve(tmpdir(), `runeya-plugin-${Date.now()}`);
|
|
3889
|
-
if (!
|
|
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 (
|
|
3903
|
-
await
|
|
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 &&
|
|
3995
|
-
await
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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
|
|
4406
|
+
var pathfs = require("path");
|
|
4349
4407
|
var os = require("os");
|
|
4350
4408
|
var {
|
|
4351
|
-
existsSync
|
|
4409
|
+
existsSync,
|
|
4352
4410
|
mkdirSync,
|
|
4353
4411
|
writeFileSync,
|
|
4354
4412
|
readFileSync
|
|
4355
4413
|
} = require("fs");
|
|
4356
|
-
var persistencePath =
|
|
4357
|
-
if (!
|
|
4358
|
-
var confsPath =
|
|
4359
|
-
if (!
|
|
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
|
|
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:
|
|
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 =
|
|
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 (
|
|
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(
|
|
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
|
|
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" ?
|
|
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
|
|
5022
|
-
var
|
|
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
|
-
|
|
5029
|
-
|
|
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);
|