@camstack/system 1.0.7 → 1.0.8
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/dist/addon-runner.js +3 -3
- package/dist/addon-runner.mjs +3 -3
- package/dist/builtins/device-manager/device-manager.addon.js +8 -8
- package/dist/builtins/device-manager/device-manager.addon.mjs +8 -8
- package/dist/builtins/platform-probe/index.js +27 -139
- package/dist/builtins/platform-probe/index.mjs +28 -140
- package/dist/builtins/platform-probe/platform-scorer.d.ts +17 -10
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +2 -2
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +2 -2
- package/dist/index.js +82 -74
- package/dist/index.mjs +83 -75
- package/dist/kernel/config-manager.d.ts +4 -4
- package/dist/kernel/fs-utils.d.ts +16 -6
- package/dist/kernel/index.d.ts +1 -1
- package/dist/kernel/transport/child-cap-protocol.d.ts +10 -0
- package/dist/{manifest-python-deps-eBDj5HEY.js → manifest-python-deps-BWURo7dc.js} +34 -17
- package/dist/{manifest-python-deps-CoJXeb9u.mjs → manifest-python-deps-BcrTzHH_.mjs} +54 -37
- package/package.json +1 -1
|
@@ -154,7 +154,7 @@ var StorageOrchestratorService = class {
|
|
|
154
154
|
const resolver = this.nodeLocalResolver;
|
|
155
155
|
if (!resolver) return;
|
|
156
156
|
let stamped = 0;
|
|
157
|
-
for (const [id, loc] of
|
|
157
|
+
for (const [id, loc] of Array.from(this.locations)) {
|
|
158
158
|
if (loc.nodeId) continue;
|
|
159
159
|
if (resolver(loc.providerId) !== true) continue;
|
|
160
160
|
const updated = {
|
|
@@ -294,7 +294,7 @@ var StorageOrchestratorService = class {
|
|
|
294
294
|
this.logger.warn("storage-orchestrator: skipping prune — no location declarations loaded (fail-safe)");
|
|
295
295
|
return;
|
|
296
296
|
}
|
|
297
|
-
for (const [id, loc] of
|
|
297
|
+
for (const [id, loc] of Array.from(this.locations)) {
|
|
298
298
|
if (this.registry.cardinalityOf(loc.type) !== null) continue;
|
|
299
299
|
if (loc.isSystem) {
|
|
300
300
|
this.locations.delete(id);
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ const require_builtins_local_auth_local_auth_addon = require("./builtins/local-a
|
|
|
20
20
|
require("./builtins/local-auth/index.js");
|
|
21
21
|
const require_builtins_device_manager_device_manager_addon = require("./builtins/device-manager/device-manager.addon.js");
|
|
22
22
|
require("./builtins/device-manager/index.js");
|
|
23
|
-
const require_manifest_python_deps = require("./manifest-python-deps-
|
|
23
|
+
const require_manifest_python_deps = require("./manifest-python-deps-BWURo7dc.js");
|
|
24
24
|
const require_custom_action_registry = require("./custom-action-registry-vLYEFTtv.js");
|
|
25
25
|
const require_graceful_fs$1 = require("./graceful-fs-lg19SZNz.js");
|
|
26
26
|
let _camstack_types_node = require("@camstack/types/node");
|
|
@@ -183,7 +183,7 @@ function proxyToUpstream(opts) {
|
|
|
183
183
|
}
|
|
184
184
|
//#endregion
|
|
185
185
|
//#region src/python/python-env-manager.ts
|
|
186
|
-
var execFileAsync$
|
|
186
|
+
var execFileAsync$3 = (0, node_util.promisify)(node_child_process.execFile);
|
|
187
187
|
var PythonEnvManager = class {
|
|
188
188
|
venvPath;
|
|
189
189
|
cachedProbe = null;
|
|
@@ -193,12 +193,12 @@ var PythonEnvManager = class {
|
|
|
193
193
|
async probe() {
|
|
194
194
|
if (this.cachedProbe) return this.cachedProbe;
|
|
195
195
|
for (const cmd of ["python3", "python"]) try {
|
|
196
|
-
const { stdout } = await execFileAsync$
|
|
196
|
+
const { stdout } = await execFileAsync$3(cmd, ["--version"]);
|
|
197
197
|
const version = stdout.trim().replace("Python ", "");
|
|
198
198
|
const major = parseInt(version.split(".")[0] ?? "0", 10);
|
|
199
199
|
const minor = parseInt(version.split(".")[1] ?? "0", 10);
|
|
200
200
|
if (major < 3 || major === 3 && minor < 10) continue;
|
|
201
|
-
const { stdout: pathOut } = await execFileAsync$
|
|
201
|
+
const { stdout: pathOut } = await execFileAsync$3(cmd, ["-c", "import sys; print(sys.executable)"]);
|
|
202
202
|
this.cachedProbe = {
|
|
203
203
|
available: true,
|
|
204
204
|
version,
|
|
@@ -214,13 +214,13 @@ var PythonEnvManager = class {
|
|
|
214
214
|
async ensure(options) {
|
|
215
215
|
const probe = await this.probe();
|
|
216
216
|
if (!probe.available || !probe.path) throw new Error("Python 3.10+ is required but not found on this system");
|
|
217
|
-
if (!node_fs.existsSync(node_path.join(this.venvPath, "bin", "python"))) await execFileAsync$
|
|
217
|
+
if (!node_fs.existsSync(node_path.join(this.venvPath, "bin", "python"))) await execFileAsync$3(probe.path, [
|
|
218
218
|
"-m",
|
|
219
219
|
"venv",
|
|
220
220
|
this.venvPath
|
|
221
221
|
]);
|
|
222
222
|
const venvPython = node_path.join(this.venvPath, "bin", "python");
|
|
223
|
-
if (options.packages.length > 0) await execFileAsync$
|
|
223
|
+
if (options.packages.length > 0) await execFileAsync$3(venvPython, [
|
|
224
224
|
"-m",
|
|
225
225
|
"pip",
|
|
226
226
|
"install",
|
|
@@ -1419,12 +1419,11 @@ var StorageManager = class {
|
|
|
1419
1419
|
return namespace ? this.createNamespacedLocation(location, namespace) : location;
|
|
1420
1420
|
}
|
|
1421
1421
|
createLegacyShim() {
|
|
1422
|
-
const self = this;
|
|
1423
1422
|
return {
|
|
1424
1423
|
async initialize() {},
|
|
1425
1424
|
async shutdown() {},
|
|
1426
|
-
getLocation(name) {
|
|
1427
|
-
return
|
|
1425
|
+
getLocation: (name) => {
|
|
1426
|
+
return this.getLocation(name);
|
|
1428
1427
|
}
|
|
1429
1428
|
};
|
|
1430
1429
|
}
|
|
@@ -1700,7 +1699,7 @@ function matchPath(pattern, path) {
|
|
|
1700
1699
|
}
|
|
1701
1700
|
//#endregion
|
|
1702
1701
|
//#region src/tls/cert-manager.ts
|
|
1703
|
-
var execFileAsync$
|
|
1702
|
+
var execFileAsync$2 = (0, node_util.promisify)(node_child_process.execFile);
|
|
1704
1703
|
/**
|
|
1705
1704
|
* Ensure a self-signed TLS certificate exists in the given directory.
|
|
1706
1705
|
* Generates one if missing. Returns paths to cert and key files.
|
|
@@ -1737,7 +1736,7 @@ async function ensureTlsCert(dataDir, options) {
|
|
|
1737
1736
|
for (const dns of sanDns) sanParts.push(`DNS:${dns}`);
|
|
1738
1737
|
for (const ip of sanIps) sanParts.push(`IP:${ip}`);
|
|
1739
1738
|
const sanString = sanParts.join(",");
|
|
1740
|
-
await execFileAsync$
|
|
1739
|
+
await execFileAsync$2("openssl", [
|
|
1741
1740
|
"req",
|
|
1742
1741
|
"-x509",
|
|
1743
1742
|
"-newkey",
|
|
@@ -2570,6 +2569,7 @@ var AddonEngineManager = class {
|
|
|
2570
2569
|
};
|
|
2571
2570
|
//#endregion
|
|
2572
2571
|
//#region src/kernel/fs-utils.ts
|
|
2572
|
+
var execFileAsync$1 = (0, node_util.promisify)(node_child_process.execFile);
|
|
2573
2573
|
/**
|
|
2574
2574
|
* Ensure a directory exists (recursive).
|
|
2575
2575
|
* Single source of truth — replaces scattered mkdirSync calls.
|
|
@@ -2578,18 +2578,20 @@ function ensureDir(dirPath) {
|
|
|
2578
2578
|
node_fs.mkdirSync(dirPath, { recursive: true });
|
|
2579
2579
|
}
|
|
2580
2580
|
/**
|
|
2581
|
-
* Copy a directory recursively.
|
|
2582
|
-
*
|
|
2581
|
+
* Copy a directory recursively — ASYNC so it never blocks the event loop.
|
|
2582
|
+
*
|
|
2583
|
+
* The hub installs addons into `/data/addons`, which on Unraid is a slow
|
|
2584
|
+
* shfs/FUSE mount. The former synchronous `fs.copyFileSync`-per-file loop
|
|
2585
|
+
* blocked the Node event loop for the whole copy of a large bundle (e.g.
|
|
2586
|
+
* `addon-pipeline`), which froze the hub's HTTP listener mid-`camstack deploy`
|
|
2587
|
+
* (accept backlog piling up, existing connections stuck in CLOSE_WAIT). Using
|
|
2588
|
+
* `fs.promises.cp` keeps the I/O off the event loop. (Node ≥18 stable.)
|
|
2583
2589
|
*/
|
|
2584
|
-
function copyDirRecursive(src, dest) {
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
const destPath = node_path.join(dest, entry.name);
|
|
2590
|
-
if (entry.isDirectory()) copyDirRecursive(srcPath, destPath);
|
|
2591
|
-
else node_fs.copyFileSync(srcPath, destPath);
|
|
2592
|
-
}
|
|
2590
|
+
async function copyDirRecursive(src, dest) {
|
|
2591
|
+
await node_fs.promises.cp(src, dest, {
|
|
2592
|
+
recursive: true,
|
|
2593
|
+
force: true
|
|
2594
|
+
});
|
|
2593
2595
|
}
|
|
2594
2596
|
/**
|
|
2595
2597
|
* Strip @camstack/* dependencies and devDependencies from a package.json object.
|
|
@@ -2619,7 +2621,7 @@ function stripCamstackDeps(pkg) {
|
|
|
2619
2621
|
* Copies directories (not individual files) from source to destination.
|
|
2620
2622
|
* Skips "dist" (already handled) and glob patterns.
|
|
2621
2623
|
*/
|
|
2622
|
-
function copyExtraFileDirs(pkgJson, sourceDir, destDir) {
|
|
2624
|
+
async function copyExtraFileDirs(pkgJson, sourceDir, destDir) {
|
|
2623
2625
|
const rawFiles = pkgJson.files;
|
|
2624
2626
|
if (!Array.isArray(rawFiles)) return;
|
|
2625
2627
|
for (const fileEntry of rawFiles) {
|
|
@@ -2628,11 +2630,11 @@ function copyExtraFileDirs(pkgJson, sourceDir, destDir) {
|
|
|
2628
2630
|
const srcPath = node_path.join(sourceDir, fileEntry);
|
|
2629
2631
|
if (!node_fs.existsSync(srcPath)) continue;
|
|
2630
2632
|
const destPath = node_path.join(destDir, fileEntry);
|
|
2631
|
-
const stat = node_fs.
|
|
2632
|
-
if (stat.isDirectory()) copyDirRecursive(srcPath, destPath);
|
|
2633
|
+
const stat = await node_fs.promises.stat(srcPath);
|
|
2634
|
+
if (stat.isDirectory()) await copyDirRecursive(srcPath, destPath);
|
|
2633
2635
|
else if (stat.isFile()) {
|
|
2634
2636
|
ensureDir(node_path.dirname(destPath));
|
|
2635
|
-
node_fs.
|
|
2637
|
+
await node_fs.promises.copyFile(srcPath, destPath);
|
|
2636
2638
|
}
|
|
2637
2639
|
}
|
|
2638
2640
|
}
|
|
@@ -2677,12 +2679,16 @@ function ensureLibraryBuilt(packageName, packagesDir) {
|
|
|
2677
2679
|
/**
|
|
2678
2680
|
* Install a single npm package into a target directory (package.json + dist/).
|
|
2679
2681
|
* No validation on camstack.addons -- works for any @camstack/* package.
|
|
2680
|
-
*
|
|
2682
|
+
*
|
|
2683
|
+
* ASYNC: uses `execFile`/`fs.promises` throughout so a package install on a
|
|
2684
|
+
* live node never blocks the event loop (the `npm pack` + tar extract + copy to
|
|
2685
|
+
* the slow shfs/FUSE `/data` would otherwise freeze the HTTP listener). See
|
|
2686
|
+
* `copyDirRecursive` for the wedge this prevents.
|
|
2681
2687
|
*/
|
|
2682
|
-
function
|
|
2683
|
-
const tmpDir = node_fs.
|
|
2688
|
+
async function installPackageFromNpm(packageName, targetDir) {
|
|
2689
|
+
const tmpDir = await node_fs.promises.mkdtemp(node_path.join(node_os.tmpdir(), "camstack-install-"));
|
|
2684
2690
|
try {
|
|
2685
|
-
const
|
|
2691
|
+
const { stdout } = await execFileAsync$1("npm", [
|
|
2686
2692
|
"pack",
|
|
2687
2693
|
packageName,
|
|
2688
2694
|
"--pack-destination",
|
|
@@ -2690,12 +2696,13 @@ function installPackageFromNpmSync(packageName, targetDir) {
|
|
|
2690
2696
|
], {
|
|
2691
2697
|
timeout: 12e4,
|
|
2692
2698
|
encoding: "utf-8"
|
|
2693
|
-
})
|
|
2699
|
+
});
|
|
2700
|
+
const tgzFilename = stdout.trim().split("\n").pop()?.trim();
|
|
2694
2701
|
if (!tgzFilename) throw new Error("npm pack produced no output");
|
|
2695
2702
|
const tgzPath = node_path.join(tmpDir, tgzFilename);
|
|
2696
2703
|
const extractDir = node_path.join(tmpDir, "extracted");
|
|
2697
2704
|
ensureDir(extractDir);
|
|
2698
|
-
|
|
2705
|
+
await execFileAsync$1("tar", [
|
|
2699
2706
|
"-xzf",
|
|
2700
2707
|
tgzPath,
|
|
2701
2708
|
"-C",
|
|
@@ -2703,20 +2710,20 @@ function installPackageFromNpmSync(packageName, targetDir) {
|
|
|
2703
2710
|
], { timeout: 3e4 });
|
|
2704
2711
|
const packageSubDir = node_path.join(extractDir, "package");
|
|
2705
2712
|
const srcPkgJsonDir = node_fs.existsSync(node_path.join(packageSubDir, "package.json")) ? packageSubDir : extractDir;
|
|
2706
|
-
node_fs.
|
|
2713
|
+
await node_fs.promises.rm(targetDir, {
|
|
2707
2714
|
recursive: true,
|
|
2708
2715
|
force: true
|
|
2709
2716
|
});
|
|
2710
2717
|
ensureDir(targetDir);
|
|
2711
|
-
node_fs.
|
|
2718
|
+
await node_fs.promises.copyFile(node_path.join(srcPkgJsonDir, "package.json"), node_path.join(targetDir, "package.json"));
|
|
2712
2719
|
const distSrc = node_path.join(srcPkgJsonDir, "dist");
|
|
2713
|
-
if (node_fs.existsSync(distSrc)) copyDirRecursive(distSrc, node_path.join(targetDir, "dist"));
|
|
2720
|
+
if (node_fs.existsSync(distSrc)) await copyDirRecursive(distSrc, node_path.join(targetDir, "dist"));
|
|
2714
2721
|
try {
|
|
2715
|
-
const npmPkg = (0, _camstack_types.asJsonObject)((0, _camstack_types.parseJsonUnknown)(node_fs.
|
|
2716
|
-
if (npmPkg) copyExtraFileDirs(npmPkg, srcPkgJsonDir, targetDir);
|
|
2722
|
+
const npmPkg = (0, _camstack_types.asJsonObject)((0, _camstack_types.parseJsonUnknown)(await node_fs.promises.readFile(node_path.join(srcPkgJsonDir, "package.json"), "utf-8")));
|
|
2723
|
+
if (npmPkg) await copyExtraFileDirs(npmPkg, srcPkgJsonDir, targetDir);
|
|
2717
2724
|
} catch {}
|
|
2718
2725
|
} finally {
|
|
2719
|
-
node_fs.
|
|
2726
|
+
await node_fs.promises.rm(tmpDir, {
|
|
2720
2727
|
recursive: true,
|
|
2721
2728
|
force: true
|
|
2722
2729
|
});
|
|
@@ -3166,15 +3173,15 @@ var AddonInstaller = class AddonInstaller {
|
|
|
3166
3173
|
await this.ensureBuilt(packageName, sourceDir, pkgData);
|
|
3167
3174
|
const distDir = node_path.join(sourceDir, "dist");
|
|
3168
3175
|
if (!node_fs.existsSync(distDir)) throw new Error(`${packageName} has no dist/ after build`);
|
|
3169
|
-
node_fs.
|
|
3176
|
+
await node_fs.promises.rm(targetDir, {
|
|
3170
3177
|
recursive: true,
|
|
3171
3178
|
force: true
|
|
3172
3179
|
});
|
|
3173
3180
|
ensureDir(targetDir);
|
|
3174
|
-
node_fs.
|
|
3175
|
-
copyDirRecursive(distDir, node_path.join(targetDir, "dist"));
|
|
3176
|
-
copyExtraFileDirs(pkgData, sourceDir, targetDir);
|
|
3177
|
-
node_fs.
|
|
3181
|
+
await node_fs.promises.writeFile(node_path.join(targetDir, "package.json"), JSON.stringify(stripCamstackDeps(pkgData), null, 2));
|
|
3182
|
+
await copyDirRecursive(distDir, node_path.join(targetDir, "dist"));
|
|
3183
|
+
await copyExtraFileDirs(pkgData, sourceDir, targetDir);
|
|
3184
|
+
await node_fs.promises.writeFile(node_path.join(targetDir, ".install-source"), "local");
|
|
3178
3185
|
const localPkgVersion = (0, _camstack_types.asString)(pkgData.version, "0.0.0");
|
|
3179
3186
|
this.manifest.upsert(packageName, {
|
|
3180
3187
|
version: localPkgVersion,
|
|
@@ -3294,17 +3301,17 @@ var AddonInstaller = class AddonInstaller {
|
|
|
3294
3301
|
if (!pkgView) throw new Error(`Invalid package.json at ${pkgJsonPath}`);
|
|
3295
3302
|
if (!pkgView.camstackAddons) throw new Error(`Package ${pkgView.name} has no camstack.addons manifest`);
|
|
3296
3303
|
const targetDir = node_path.join(this.addonsDir, pkgView.name);
|
|
3297
|
-
node_fs.
|
|
3304
|
+
await node_fs.promises.rm(targetDir, {
|
|
3298
3305
|
recursive: true,
|
|
3299
3306
|
force: true
|
|
3300
3307
|
});
|
|
3301
3308
|
ensureDir(targetDir);
|
|
3302
3309
|
const sourceDir = node_path.dirname(pkgJsonPath);
|
|
3303
3310
|
const strippedManifest = stripCamstackDeps(pkgView.raw);
|
|
3304
|
-
node_fs.
|
|
3311
|
+
await node_fs.promises.writeFile(node_path.join(targetDir, "package.json"), JSON.stringify(strippedManifest, null, 2));
|
|
3305
3312
|
const sourceDist = node_path.join(sourceDir, "dist");
|
|
3306
|
-
if (node_fs.existsSync(sourceDist)) copyDirRecursive(sourceDist, node_path.join(targetDir, "dist"));
|
|
3307
|
-
copyExtraFileDirs(pkgView.raw, sourceDir, targetDir);
|
|
3313
|
+
if (node_fs.existsSync(sourceDist)) await copyDirRecursive(sourceDist, node_path.join(targetDir, "dist"));
|
|
3314
|
+
await copyExtraFileDirs(pkgView.raw, sourceDir, targetDir);
|
|
3308
3315
|
const strippedRuntimeDeps = strippedManifest["dependencies"];
|
|
3309
3316
|
if (strippedRuntimeDeps != null && typeof strippedRuntimeDeps === "object" && Object.keys(strippedRuntimeDeps).length > 0) {
|
|
3310
3317
|
this.logger.info(`${pkgView.name} — installing runtime dependencies`, { meta: { targetDir } });
|
|
@@ -3328,7 +3335,7 @@ var AddonInstaller = class AddonInstaller {
|
|
|
3328
3335
|
try {
|
|
3329
3336
|
await require_manifest_python_deps.installManifestNativeDeps(targetDir, pkgView.raw, this.logger, this.registry);
|
|
3330
3337
|
} catch (nativeErr) {
|
|
3331
|
-
node_fs.
|
|
3338
|
+
await node_fs.promises.rm(targetDir, {
|
|
3332
3339
|
recursive: true,
|
|
3333
3340
|
force: true
|
|
3334
3341
|
});
|
|
@@ -3343,7 +3350,7 @@ var AddonInstaller = class AddonInstaller {
|
|
|
3343
3350
|
version: pkgView.version
|
|
3344
3351
|
};
|
|
3345
3352
|
} finally {
|
|
3346
|
-
node_fs.
|
|
3353
|
+
await node_fs.promises.rm(tmpDir, {
|
|
3347
3354
|
recursive: true,
|
|
3348
3355
|
force: true
|
|
3349
3356
|
});
|
|
@@ -4111,7 +4118,7 @@ var CapabilityRegistry = class CapabilityRegistry {
|
|
|
4111
4118
|
const bare = this.bareAddonId(addonId);
|
|
4112
4119
|
const nodeMap = this.singletonNodeOverrides.get(capabilityName);
|
|
4113
4120
|
if (nodeMap) {
|
|
4114
|
-
for (const [nodeId, ov] of
|
|
4121
|
+
for (const [nodeId, ov] of Array.from(nodeMap)) if (ov === bare) nodeMap.delete(nodeId);
|
|
4115
4122
|
if (nodeMap.size === 0) this.singletonNodeOverrides.delete(capabilityName);
|
|
4116
4123
|
}
|
|
4117
4124
|
this.logger.info("Provider unregistered from capability", {
|
|
@@ -7388,20 +7395,20 @@ var ConfigManager = class ConfigManager {
|
|
|
7388
7395
|
setSettingsStore(store) {
|
|
7389
7396
|
this.settingsStore = store;
|
|
7390
7397
|
}
|
|
7391
|
-
get(
|
|
7392
|
-
return this.resolveConfigValue(
|
|
7398
|
+
get(configPath) {
|
|
7399
|
+
return this.resolveConfigValue(configPath);
|
|
7393
7400
|
}
|
|
7394
|
-
resolveConfigValue(
|
|
7395
|
-
const bootstrapValue = this.getFromBootstrap(
|
|
7401
|
+
resolveConfigValue(configPath) {
|
|
7402
|
+
const bootstrapValue = this.getFromBootstrap(configPath);
|
|
7396
7403
|
if (bootstrapValue !== void 0) return bootstrapValue;
|
|
7397
7404
|
if (this.settingsStore !== null) {
|
|
7398
|
-
const storeValue = this.settingsStore.getSystem(
|
|
7405
|
+
const storeValue = this.settingsStore.getSystem(configPath);
|
|
7399
7406
|
if (storeValue !== void 0) return storeValue;
|
|
7400
|
-
const nested = this.getNestedFromSystemSettings(
|
|
7407
|
+
const nested = this.getNestedFromSystemSettings(configPath);
|
|
7401
7408
|
if (nested !== null) return nested;
|
|
7402
7409
|
}
|
|
7403
|
-
if (
|
|
7404
|
-
return this.getFromRuntimeDefaults(
|
|
7410
|
+
if (configPath in _camstack_types.RUNTIME_DEFAULTS) return _camstack_types.RUNTIME_DEFAULTS[configPath];
|
|
7411
|
+
return this.getFromRuntimeDefaults(configPath) ?? void 0;
|
|
7405
7412
|
}
|
|
7406
7413
|
/**
|
|
7407
7414
|
* Write a value to the settings-store.
|
|
@@ -7617,8 +7624,8 @@ var ConfigManager = class ConfigManager {
|
|
|
7617
7624
|
};
|
|
7618
7625
|
this.saveRuntimeState();
|
|
7619
7626
|
}
|
|
7620
|
-
getBootstrap(
|
|
7621
|
-
return this.getFromBootstrap(
|
|
7627
|
+
getBootstrap(configPath) {
|
|
7628
|
+
return this.getFromBootstrap(configPath);
|
|
7622
7629
|
}
|
|
7623
7630
|
/** Features accessor -- reads from settings-store when available, falls back to RUNTIME_DEFAULTS */
|
|
7624
7631
|
get features() {
|
|
@@ -7708,8 +7715,8 @@ var ConfigManager = class ConfigManager {
|
|
|
7708
7715
|
* Deep-set a value in a nested plain object using a dot-notation path.
|
|
7709
7716
|
* Returns a new object (immutable).
|
|
7710
7717
|
*/
|
|
7711
|
-
setNested(obj,
|
|
7712
|
-
const [head, ...rest] =
|
|
7718
|
+
setNested(obj, configPath, value) {
|
|
7719
|
+
const [head, ...rest] = configPath.split(".");
|
|
7713
7720
|
if (!head) return obj;
|
|
7714
7721
|
if (rest.length === 0) return {
|
|
7715
7722
|
...obj,
|
|
@@ -7749,8 +7756,8 @@ var ConfigManager = class ConfigManager {
|
|
|
7749
7756
|
warnDefaultCredentials() {
|
|
7750
7757
|
if (this.bootstrapConfig.auth.adminPassword === "changeme") console.warn("[ConfigManager] Warning: Using default admin password \"changeme\". Set auth.adminPassword in your config.yaml or the CAMSTACK_ADMIN_PASS env var.");
|
|
7751
7758
|
}
|
|
7752
|
-
getFromBootstrap(
|
|
7753
|
-
const keys =
|
|
7759
|
+
getFromBootstrap(configPath) {
|
|
7760
|
+
const keys = configPath.split(".");
|
|
7754
7761
|
let current = this.bootstrapConfig;
|
|
7755
7762
|
for (const key of keys) {
|
|
7756
7763
|
if (!isRecord(current)) return void 0;
|
|
@@ -7758,8 +7765,8 @@ var ConfigManager = class ConfigManager {
|
|
|
7758
7765
|
}
|
|
7759
7766
|
return current;
|
|
7760
7767
|
}
|
|
7761
|
-
getFromRuntimeDefaults(
|
|
7762
|
-
const prefix =
|
|
7768
|
+
getFromRuntimeDefaults(configPath) {
|
|
7769
|
+
const prefix = configPath + ".";
|
|
7763
7770
|
const result = {};
|
|
7764
7771
|
let found = false;
|
|
7765
7772
|
for (const [key, value] of Object.entries(_camstack_types.RUNTIME_DEFAULTS)) if (key.startsWith(prefix)) {
|
|
@@ -7774,10 +7781,10 @@ var ConfigManager = class ConfigManager {
|
|
|
7774
7781
|
* e.g. path='features' matches keys 'features.streaming', 'features.notifications', etc.
|
|
7775
7782
|
* Returns an object keyed by the sub-key, or undefined if nothing is found.
|
|
7776
7783
|
*/
|
|
7777
|
-
getNestedFromSystemSettings(
|
|
7784
|
+
getNestedFromSystemSettings(configPath) {
|
|
7778
7785
|
if (this.settingsStore === null) return null;
|
|
7779
7786
|
const all = this.settingsStore.getAllSystem();
|
|
7780
|
-
const prefix =
|
|
7787
|
+
const prefix = configPath + ".";
|
|
7781
7788
|
const result = {};
|
|
7782
7789
|
let found = false;
|
|
7783
7790
|
for (const [key, value] of Object.entries(all)) if (key.startsWith(prefix)) {
|
|
@@ -90938,7 +90945,7 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
|
|
|
90938
90945
|
respawned.restartCount = prevRestartCount + 1;
|
|
90939
90946
|
});
|
|
90940
90947
|
restarted.push(name);
|
|
90941
|
-
} catch
|
|
90948
|
+
} catch {
|
|
90942
90949
|
failed.push(name);
|
|
90943
90950
|
}
|
|
90944
90951
|
return {
|
|
@@ -91333,8 +91340,8 @@ var LifecycleJobEngine = class {
|
|
|
91333
91340
|
} finally {
|
|
91334
91341
|
clearTimeout(timer);
|
|
91335
91342
|
}
|
|
91336
|
-
if (packages.length === 0) throw new Error("stageFramework returned no packages");
|
|
91337
91343
|
const [firstPackage] = packages;
|
|
91344
|
+
if (!firstPackage) throw new Error("stageFramework returned no packages");
|
|
91338
91345
|
this.advance(job.jobId, task, "staged", { stagedPath: firstPackage.stagedPath });
|
|
91339
91346
|
requestFrameworkSwap({
|
|
91340
91347
|
jobId: job.jobId,
|
|
@@ -91357,14 +91364,15 @@ var LifecycleJobEngine = class {
|
|
|
91357
91364
|
*/
|
|
91358
91365
|
async fetchAddonsBounded(job, addonTasks) {
|
|
91359
91366
|
const limit = Math.max(1, this.deps.fetchConcurrency ?? DEFAULT_FETCH_CONCURRENCY);
|
|
91360
|
-
const outcomes =
|
|
91367
|
+
const outcomes = Array.from({ length: addonTasks.length });
|
|
91361
91368
|
let nextIndex = 0;
|
|
91362
91369
|
const worker = async () => {
|
|
91363
91370
|
for (;;) {
|
|
91364
91371
|
const index = nextIndex;
|
|
91365
91372
|
nextIndex += 1;
|
|
91366
|
-
|
|
91367
|
-
|
|
91373
|
+
const addonTask = addonTasks[index];
|
|
91374
|
+
if (addonTask === void 0) return;
|
|
91375
|
+
outcomes[index] = await this.fetchAddonTask(job, addonTask);
|
|
91368
91376
|
}
|
|
91369
91377
|
};
|
|
91370
91378
|
const workerCount = Math.min(limit, addonTasks.length);
|
|
@@ -91732,7 +91740,7 @@ exports.getWorkerDeviceRegistry = require_manifest_python_deps.getWorkerDeviceRe
|
|
|
91732
91740
|
exports.hashClusterSecret = hashClusterSecret;
|
|
91733
91741
|
exports.installManifestNativeDeps = require_manifest_python_deps.installManifestNativeDeps;
|
|
91734
91742
|
exports.installManifestPythonDeps = require_manifest_python_deps.installManifestPythonDeps;
|
|
91735
|
-
exports.
|
|
91743
|
+
exports.installPackageFromNpm = installPackageFromNpm;
|
|
91736
91744
|
Object.defineProperty(exports, "installPythonPackages", {
|
|
91737
91745
|
enumerable: true,
|
|
91738
91746
|
get: function() {
|