dsh-home-hosted 0.7.3 → 0.7.4
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/lib/index.js +67 -7
- package/lib/index.js.map +3 -3
- package/lib/types/home-hosted/config-file.d.ts +23 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -2484,6 +2484,9 @@ function migrationRefusal(home) {
|
|
|
2484
2484
|
var ConfigLayoutError = class extends Error {
|
|
2485
2485
|
name = "ConfigLayoutError";
|
|
2486
2486
|
};
|
|
2487
|
+
var ConfigPatchError = class extends Error {
|
|
2488
|
+
name = "ConfigPatchError";
|
|
2489
|
+
};
|
|
2487
2490
|
function readConfig(home, workspace = DEFAULT_WORKSPACE) {
|
|
2488
2491
|
const refusal = migrationRefusal(home);
|
|
2489
2492
|
if (refusal !== null)
|
|
@@ -2494,8 +2497,15 @@ function readConfig(home, workspace = DEFAULT_WORKSPACE) {
|
|
|
2494
2497
|
const exists = fs8.existsSync(file);
|
|
2495
2498
|
return { raw: null, exists, error: exists ? "the workspace config file could not be parsed" : null };
|
|
2496
2499
|
}
|
|
2500
|
+
if (!isRecordValue(raw))
|
|
2501
|
+
return { raw: null, exists: true, error: "the workspace config file does not contain a JSON object" };
|
|
2497
2502
|
if (!Array.isArray(raw.servers) && raw.servers !== void 0)
|
|
2498
2503
|
return { raw: null, exists: true, error: "the workspace config file has a servers field that is not an array" };
|
|
2504
|
+
if (Array.isArray(raw.servers)) {
|
|
2505
|
+
const index = raw.servers.findIndex((entry) => !isRecordValue(entry));
|
|
2506
|
+
if (index >= 0)
|
|
2507
|
+
return { raw: null, exists: true, error: `the workspace config file has an entry at servers[${index}] that is not an object` };
|
|
2508
|
+
}
|
|
2499
2509
|
return { raw, exists: true, error: null };
|
|
2500
2510
|
}
|
|
2501
2511
|
function writeConfig(home, raw, writtenBy = "dsh-home-hosted", workspace = DEFAULT_WORKSPACE) {
|
|
@@ -2515,7 +2525,9 @@ function readGlobalSettings(home) {
|
|
|
2515
2525
|
const exists = fs8.existsSync(file);
|
|
2516
2526
|
return { raw: null, exists, error: exists ? "the panel settings file could not be parsed" : null };
|
|
2517
2527
|
}
|
|
2518
|
-
if (
|
|
2528
|
+
if (!isRecordValue(raw))
|
|
2529
|
+
return { raw: null, exists: true, error: "the panel settings file does not contain a JSON object" };
|
|
2530
|
+
if (raw.control !== void 0 && !isRecordValue(raw.control))
|
|
2519
2531
|
return { raw: null, exists: true, error: "the panel settings file has a control field that is not an object" };
|
|
2520
2532
|
return { raw, exists: true, error: null };
|
|
2521
2533
|
}
|
|
@@ -2529,7 +2541,7 @@ function setControl(home, patch, writtenBy = "dsh-home-hosted") {
|
|
|
2529
2541
|
const read = readGlobalSettings(home);
|
|
2530
2542
|
if (read.error !== null)
|
|
2531
2543
|
throw new ConfigLayoutError(read.error);
|
|
2532
|
-
writeGlobalSettings(home,
|
|
2544
|
+
writeGlobalSettings(home, patchControl(read.raw ?? {}, patch), writtenBy);
|
|
2533
2545
|
}
|
|
2534
2546
|
function refuseUnmigrated(home) {
|
|
2535
2547
|
const refusal = migrationRefusal(home);
|
|
@@ -2548,17 +2560,61 @@ function upsertEntry(raw, entry) {
|
|
|
2548
2560
|
servers.push(entry);
|
|
2549
2561
|
return { ...raw, servers };
|
|
2550
2562
|
}
|
|
2563
|
+
var SERVER_MERGE_KEYS = /* @__PURE__ */ new Set(["restart", "health", "stop"]);
|
|
2564
|
+
var CONTROL_MERGE_KEYS = /* @__PURE__ */ new Set(["auth", "tls"]);
|
|
2565
|
+
function isRecordValue(value) {
|
|
2566
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2567
|
+
}
|
|
2568
|
+
function mergeGroup(target, patch) {
|
|
2569
|
+
const merged = { ...target };
|
|
2570
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
2571
|
+
if (value === void 0)
|
|
2572
|
+
continue;
|
|
2573
|
+
if (value === null) {
|
|
2574
|
+
delete merged[key];
|
|
2575
|
+
continue;
|
|
2576
|
+
}
|
|
2577
|
+
if (isRecordValue(value) && isRecordValue(merged[key])) {
|
|
2578
|
+
merged[key] = mergeGroup(merged[key], value);
|
|
2579
|
+
continue;
|
|
2580
|
+
}
|
|
2581
|
+
merged[key] = value;
|
|
2582
|
+
}
|
|
2583
|
+
return merged;
|
|
2584
|
+
}
|
|
2551
2585
|
function patchEntry(raw, id, patch) {
|
|
2586
|
+
for (const key of SERVER_MERGE_KEYS) {
|
|
2587
|
+
if (patch[key] === null)
|
|
2588
|
+
throw new ConfigPatchError(`${key} must be an object (was null): the panel refuses to boot a config that carries it`);
|
|
2589
|
+
}
|
|
2552
2590
|
const servers = (raw.servers ?? []).map((entry) => {
|
|
2553
2591
|
if (entry.id !== id)
|
|
2554
2592
|
return entry;
|
|
2555
|
-
const merged = { ...entry
|
|
2556
|
-
|
|
2557
|
-
|
|
2593
|
+
const merged = { ...entry };
|
|
2594
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
2595
|
+
if (value === void 0)
|
|
2596
|
+
continue;
|
|
2597
|
+
if (SERVER_MERGE_KEYS.has(key) && isRecordValue(value) && isRecordValue(merged[key]))
|
|
2598
|
+
merged[key] = mergeGroup(merged[key], value);
|
|
2599
|
+
else
|
|
2600
|
+
merged[key] = value;
|
|
2601
|
+
}
|
|
2558
2602
|
return merged;
|
|
2559
2603
|
});
|
|
2560
2604
|
return { ...raw, servers };
|
|
2561
2605
|
}
|
|
2606
|
+
function patchControl(raw, patch) {
|
|
2607
|
+
const control = { ...raw.control ?? {} };
|
|
2608
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
2609
|
+
if (value === void 0)
|
|
2610
|
+
continue;
|
|
2611
|
+
if (CONTROL_MERGE_KEYS.has(key) && isRecordValue(value) && isRecordValue(control[key]))
|
|
2612
|
+
control[key] = mergeGroup(control[key], value);
|
|
2613
|
+
else
|
|
2614
|
+
control[key] = value;
|
|
2615
|
+
}
|
|
2616
|
+
return { ...raw, control };
|
|
2617
|
+
}
|
|
2562
2618
|
function removeEntry(raw, id) {
|
|
2563
2619
|
return { ...raw, servers: (raw.servers ?? []).filter((entry) => entry.id !== id) };
|
|
2564
2620
|
}
|
|
@@ -4455,7 +4511,7 @@ var HomeHostedError = class extends Error {
|
|
|
4455
4511
|
this.name = "HomeHostedError";
|
|
4456
4512
|
}
|
|
4457
4513
|
};
|
|
4458
|
-
function
|
|
4514
|
+
function isRecordValue2(value) {
|
|
4459
4515
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4460
4516
|
}
|
|
4461
4517
|
function foreignView(entry, workspace) {
|
|
@@ -4954,7 +5010,7 @@ var HomeHostedService = class extends Service {
|
|
|
4954
5010
|
const raw = readJson(this.snapshotsFile);
|
|
4955
5011
|
if (raw === null)
|
|
4956
5012
|
return {};
|
|
4957
|
-
if (raw.version === 2 &&
|
|
5013
|
+
if (raw.version === 2 && isRecordValue2(raw.entries))
|
|
4958
5014
|
return raw.workspace === this.managedWorkspace() ? raw.entries : {};
|
|
4959
5015
|
return this.managedWorkspace() === DEFAULT_WORKSPACE ? raw : {};
|
|
4960
5016
|
}
|
|
@@ -5843,6 +5899,10 @@ var HomeHostedService = class extends Service {
|
|
|
5843
5899
|
const target = await this.targetHome(input.home);
|
|
5844
5900
|
const id = String(input.id);
|
|
5845
5901
|
const patch = input.patch ?? {};
|
|
5902
|
+
for (const key of ["restart", "health", "stop"]) {
|
|
5903
|
+
if (patch[key] === null)
|
|
5904
|
+
throw new HomeHostedError(`${key} must be an object (was null)`, "INVALID_PATCH");
|
|
5905
|
+
}
|
|
5846
5906
|
const workspace = this.callWorkspace(input, target.home, target.foreign);
|
|
5847
5907
|
if (!target.foreign)
|
|
5848
5908
|
return await (await this.requireClient()).updateServer(id, patch, workspace);
|