@camstack/system 1.1.38 → 1.1.40
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 +1 -1
- package/dist/addon-runner.mjs +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +48 -25
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +48 -25
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +1 -1
- package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-backup/system-backup.service.d.ts +20 -2
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-CU3lb_Ys.mjs → dist-C0d3UidT.mjs} +38 -0
- package/dist/{dist-fRVWwrkF.js → dist-D_ijwYtl.js} +38 -0
- package/dist/index.js +70 -5
- package/dist/index.mjs +70 -5
- package/dist/kernel/fs-utils.d.ts +28 -0
- package/dist/{manifest-python-deps-4QvOLiBn.mjs → manifest-python-deps-6u3YnO2u.mjs} +3 -2
- package/dist/{manifest-python-deps-B6ahe90k.js → manifest-python-deps-Cp9WdXiT.js} +3 -2
- package/package.json +1 -1
package/dist/addon-runner.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
2
|
-
const require_manifest_python_deps = require("./manifest-python-deps-
|
|
2
|
+
const require_manifest_python_deps = require("./manifest-python-deps-Cp9WdXiT.js");
|
|
3
3
|
const require_custom_action_registry = require("./custom-action-registry-vLYEFTtv.js");
|
|
4
4
|
let node_fs = require("node:fs");
|
|
5
5
|
node_fs = require_chunk.__toESM(node_fs);
|
package/dist/addon-runner.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as createUdsLoggerWithControl, I as LocalChildClient, i as createUdsAddonContext, it as setWorkerNativeCapsChangeListener, nt as getWorkerNativeCapSnapshot, ot as validateProviderRegistrations, t as installManifestPythonDeps, tt as getWorkerNativeCapProvider, vt as installManifestNativeDeps, yt as resolveAddonClass } from "./manifest-python-deps-
|
|
1
|
+
import { F as createUdsLoggerWithControl, I as LocalChildClient, i as createUdsAddonContext, it as setWorkerNativeCapsChangeListener, nt as getWorkerNativeCapSnapshot, ot as validateProviderRegistrations, t as installManifestPythonDeps, tt as getWorkerNativeCapProvider, vt as installManifestNativeDeps, yt as resolveAddonClass } from "./manifest-python-deps-6u3YnO2u.mjs";
|
|
2
2
|
import { t as CustomActionRegistry } from "./custom-action-registry-BEXwC-oo.mjs";
|
|
3
3
|
import { register } from "node:module";
|
|
4
4
|
import * as fs from "node:fs";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_fs = require("node:fs");
|
|
9
9
|
node_fs = require_chunk.__toESM(node_fs);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as errMsg, et as BaseAddon, f as addonPagesCapability, st as EventCategory } from "../../dist-
|
|
1
|
+
import { $ as errMsg, et as BaseAddon, f as addonPagesCapability, st as EventCategory } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_fs = require("node:fs");
|
|
9
9
|
node_fs = require_chunk.__toESM(node_fs);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as errMsg, et as BaseAddon, m as addonWidgetsCapability, st as EventCategory } from "../../dist-
|
|
1
|
+
import { $ as errMsg, et as BaseAddon, m as addonWidgetsCapability, st as EventCategory } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
//#region src/builtins/alerts/alerts.addon.ts
|
|
8
8
|
var CATEGORY_MAPPINGS = {
|
|
9
9
|
"addon.crashed": {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as errMsg, et as BaseAddon, h as alertsCapability, mt as createEvent, n as AlertSchema, st as EventCategory } from "../../dist-
|
|
1
|
+
import { $ as errMsg, et as BaseAddon, h as alertsCapability, mt as createEvent, n as AlertSchema, st as EventCategory } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
//#region src/builtins/alerts/alerts.addon.ts
|
|
3
3
|
var CATEGORY_MAPPINGS = {
|
|
4
4
|
"addon.crashed": {
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
let node_fs$1 = require_chunk.__toESM(node_fs, 1);
|
|
9
9
|
node_fs = require_chunk.__toESM(node_fs);
|
|
@@ -3021,6 +3021,7 @@ var DEFAULT_BACKUP_LOCATIONS = [
|
|
|
3021
3021
|
];
|
|
3022
3022
|
/** Path of the manifest file embedded inside every archive. */
|
|
3023
3023
|
var ARCHIVE_MANIFEST_NAME = ".camstack-backup-manifest.json";
|
|
3024
|
+
var DEFAULT_STAT_CACHE_TTL_MS = 6e4;
|
|
3024
3025
|
/**
|
|
3025
3026
|
* System-level archive primitives. Construct one per server boot;
|
|
3026
3027
|
* methods are pure I/O.
|
|
@@ -3028,33 +3029,55 @@ var ARCHIVE_MANIFEST_NAME = ".camstack-backup-manifest.json";
|
|
|
3028
3029
|
var SystemBackupService = class {
|
|
3029
3030
|
dataDir;
|
|
3030
3031
|
logger;
|
|
3031
|
-
|
|
3032
|
+
statCacheTtlMs;
|
|
3033
|
+
statCache = /* @__PURE__ */ new Map();
|
|
3034
|
+
constructor(dataDir, logger, opts) {
|
|
3032
3035
|
this.dataDir = dataDir;
|
|
3033
3036
|
this.logger = logger;
|
|
3037
|
+
this.statCacheTtlMs = opts?.statCacheTtlMs ?? DEFAULT_STAT_CACHE_TTL_MS;
|
|
3034
3038
|
}
|
|
3035
3039
|
/**
|
|
3036
3040
|
* Snapshot the current size + file count of each well-known
|
|
3037
3041
|
* location. Used by the admin UI to render an opt-in checklist
|
|
3038
3042
|
* before triggering a backup, and by `createArchive` to derive the
|
|
3039
3043
|
* embedded manifest.
|
|
3044
|
+
*
|
|
3045
|
+
* The walk is async (yields to the event loop per directory) and
|
|
3046
|
+
* per-location results are cached + single-flighted: the service
|
|
3047
|
+
* runs in-process in the hub, and a synchronous walk of the 70k+
|
|
3048
|
+
* file `addons` location blocked the event loop long enough to kill
|
|
3049
|
+
* WS keepalives cluster-wide.
|
|
3040
3050
|
*/
|
|
3041
3051
|
statLocations(locations = DEFAULT_BACKUP_LOCATIONS) {
|
|
3042
|
-
return locations.map((loc) =>
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
name: loc,
|
|
3053
|
-
sizeBytes: walked.reduce((acc, e) => acc + e.sizeBytes, 0),
|
|
3054
|
-
fileCount: walked.filter((e) => e.kind === "file").length,
|
|
3055
|
-
present: true
|
|
3056
|
-
};
|
|
3052
|
+
return Promise.all(locations.map((loc) => this.statLocationCached(loc)));
|
|
3053
|
+
}
|
|
3054
|
+
statLocationCached(loc) {
|
|
3055
|
+
const now = Date.now();
|
|
3056
|
+
const hit = this.statCache.get(loc);
|
|
3057
|
+
if (hit && now - hit.at < this.statCacheTtlMs) return hit.value;
|
|
3058
|
+
const value = this.statLocation(loc);
|
|
3059
|
+
this.statCache.set(loc, {
|
|
3060
|
+
at: now,
|
|
3061
|
+
value
|
|
3057
3062
|
});
|
|
3063
|
+
value.catch(() => this.statCache.delete(loc));
|
|
3064
|
+
return value;
|
|
3065
|
+
}
|
|
3066
|
+
async statLocation(loc) {
|
|
3067
|
+
const abs = node_path.isAbsolute(loc) ? loc : node_path.join(this.dataDir, loc);
|
|
3068
|
+
if (!node_fs.existsSync(abs)) return {
|
|
3069
|
+
name: loc,
|
|
3070
|
+
sizeBytes: 0,
|
|
3071
|
+
fileCount: 0,
|
|
3072
|
+
present: false
|
|
3073
|
+
};
|
|
3074
|
+
const walked = await walkAbs(abs, abs);
|
|
3075
|
+
return {
|
|
3076
|
+
name: loc,
|
|
3077
|
+
sizeBytes: walked.reduce((acc, e) => acc + e.sizeBytes, 0),
|
|
3078
|
+
fileCount: walked.filter((e) => e.kind === "file").length,
|
|
3079
|
+
present: true
|
|
3080
|
+
};
|
|
3058
3081
|
}
|
|
3059
3082
|
/**
|
|
3060
3083
|
* Create a tar.gz of the given locations. Uses the `tar` npm package
|
|
@@ -3082,8 +3105,8 @@ var SystemBackupService = class {
|
|
|
3082
3105
|
const entries = [];
|
|
3083
3106
|
for (const loc of present) {
|
|
3084
3107
|
const abs = node_path.join(this.dataDir, loc);
|
|
3085
|
-
const stat =
|
|
3086
|
-
if (stat.isDirectory()) for (const e of walkAbs(abs, this.dataDir)) entries.push(e);
|
|
3108
|
+
const stat = await node_fs_promises.stat(abs);
|
|
3109
|
+
if (stat.isDirectory()) for (const e of await walkAbs(abs, this.dataDir)) entries.push(e);
|
|
3087
3110
|
else entries.push(toArchiveEntry(abs, this.dataDir, stat));
|
|
3088
3111
|
}
|
|
3089
3112
|
const manifest = {
|
|
@@ -3258,15 +3281,15 @@ var SystemBackupService = class {
|
|
|
3258
3281
|
* path. Symlinks are dereferenced (matches the `follow: true` flag we
|
|
3259
3282
|
* pass to tar.create).
|
|
3260
3283
|
*/
|
|
3261
|
-
function walkAbs(absRoot, dataDir) {
|
|
3284
|
+
async function walkAbs(absRoot, dataDir) {
|
|
3262
3285
|
const out = [];
|
|
3263
|
-
walkRec(absRoot, dataDir, out);
|
|
3286
|
+
await walkRec(absRoot, dataDir, out);
|
|
3264
3287
|
return out;
|
|
3265
3288
|
}
|
|
3266
|
-
function walkRec(abs, dataDir, out) {
|
|
3289
|
+
async function walkRec(abs, dataDir, out) {
|
|
3267
3290
|
let stat;
|
|
3268
3291
|
try {
|
|
3269
|
-
stat =
|
|
3292
|
+
stat = await node_fs_promises.stat(abs);
|
|
3270
3293
|
} catch {
|
|
3271
3294
|
return;
|
|
3272
3295
|
}
|
|
@@ -3274,11 +3297,11 @@ function walkRec(abs, dataDir, out) {
|
|
|
3274
3297
|
if (stat.isDirectory()) {
|
|
3275
3298
|
let children;
|
|
3276
3299
|
try {
|
|
3277
|
-
children =
|
|
3300
|
+
children = await node_fs_promises.readdir(abs);
|
|
3278
3301
|
} catch {
|
|
3279
3302
|
return;
|
|
3280
3303
|
}
|
|
3281
|
-
for (const child of children) walkRec(node_path.join(abs, child), dataDir, out);
|
|
3304
|
+
for (const child of children) await walkRec(node_path.join(abs, child), dataDir, out);
|
|
3282
3305
|
}
|
|
3283
3306
|
}
|
|
3284
3307
|
function toArchiveEntry(abs, dataDir, stat) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { et as BaseAddon, st as EventCategory, v as backupCapability } from "../../dist-
|
|
1
|
+
import { et as BaseAddon, st as EventCategory, v as backupCapability } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import Kt from "node:fs";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3006,6 +3006,7 @@ var DEFAULT_BACKUP_LOCATIONS = [
|
|
|
3006
3006
|
];
|
|
3007
3007
|
/** Path of the manifest file embedded inside every archive. */
|
|
3008
3008
|
var ARCHIVE_MANIFEST_NAME = ".camstack-backup-manifest.json";
|
|
3009
|
+
var DEFAULT_STAT_CACHE_TTL_MS = 6e4;
|
|
3009
3010
|
/**
|
|
3010
3011
|
* System-level archive primitives. Construct one per server boot;
|
|
3011
3012
|
* methods are pure I/O.
|
|
@@ -3013,33 +3014,55 @@ var ARCHIVE_MANIFEST_NAME = ".camstack-backup-manifest.json";
|
|
|
3013
3014
|
var SystemBackupService = class {
|
|
3014
3015
|
dataDir;
|
|
3015
3016
|
logger;
|
|
3016
|
-
|
|
3017
|
+
statCacheTtlMs;
|
|
3018
|
+
statCache = /* @__PURE__ */ new Map();
|
|
3019
|
+
constructor(dataDir, logger, opts) {
|
|
3017
3020
|
this.dataDir = dataDir;
|
|
3018
3021
|
this.logger = logger;
|
|
3022
|
+
this.statCacheTtlMs = opts?.statCacheTtlMs ?? DEFAULT_STAT_CACHE_TTL_MS;
|
|
3019
3023
|
}
|
|
3020
3024
|
/**
|
|
3021
3025
|
* Snapshot the current size + file count of each well-known
|
|
3022
3026
|
* location. Used by the admin UI to render an opt-in checklist
|
|
3023
3027
|
* before triggering a backup, and by `createArchive` to derive the
|
|
3024
3028
|
* embedded manifest.
|
|
3029
|
+
*
|
|
3030
|
+
* The walk is async (yields to the event loop per directory) and
|
|
3031
|
+
* per-location results are cached + single-flighted: the service
|
|
3032
|
+
* runs in-process in the hub, and a synchronous walk of the 70k+
|
|
3033
|
+
* file `addons` location blocked the event loop long enough to kill
|
|
3034
|
+
* WS keepalives cluster-wide.
|
|
3025
3035
|
*/
|
|
3026
3036
|
statLocations(locations = DEFAULT_BACKUP_LOCATIONS) {
|
|
3027
|
-
return locations.map((loc) =>
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
name: loc,
|
|
3038
|
-
sizeBytes: walked.reduce((acc, e) => acc + e.sizeBytes, 0),
|
|
3039
|
-
fileCount: walked.filter((e) => e.kind === "file").length,
|
|
3040
|
-
present: true
|
|
3041
|
-
};
|
|
3037
|
+
return Promise.all(locations.map((loc) => this.statLocationCached(loc)));
|
|
3038
|
+
}
|
|
3039
|
+
statLocationCached(loc) {
|
|
3040
|
+
const now = Date.now();
|
|
3041
|
+
const hit = this.statCache.get(loc);
|
|
3042
|
+
if (hit && now - hit.at < this.statCacheTtlMs) return hit.value;
|
|
3043
|
+
const value = this.statLocation(loc);
|
|
3044
|
+
this.statCache.set(loc, {
|
|
3045
|
+
at: now,
|
|
3046
|
+
value
|
|
3042
3047
|
});
|
|
3048
|
+
value.catch(() => this.statCache.delete(loc));
|
|
3049
|
+
return value;
|
|
3050
|
+
}
|
|
3051
|
+
async statLocation(loc) {
|
|
3052
|
+
const abs = path$1.isAbsolute(loc) ? loc : path$1.join(this.dataDir, loc);
|
|
3053
|
+
if (!fs.existsSync(abs)) return {
|
|
3054
|
+
name: loc,
|
|
3055
|
+
sizeBytes: 0,
|
|
3056
|
+
fileCount: 0,
|
|
3057
|
+
present: false
|
|
3058
|
+
};
|
|
3059
|
+
const walked = await walkAbs(abs, abs);
|
|
3060
|
+
return {
|
|
3061
|
+
name: loc,
|
|
3062
|
+
sizeBytes: walked.reduce((acc, e) => acc + e.sizeBytes, 0),
|
|
3063
|
+
fileCount: walked.filter((e) => e.kind === "file").length,
|
|
3064
|
+
present: true
|
|
3065
|
+
};
|
|
3043
3066
|
}
|
|
3044
3067
|
/**
|
|
3045
3068
|
* Create a tar.gz of the given locations. Uses the `tar` npm package
|
|
@@ -3067,8 +3090,8 @@ var SystemBackupService = class {
|
|
|
3067
3090
|
const entries = [];
|
|
3068
3091
|
for (const loc of present) {
|
|
3069
3092
|
const abs = path$1.join(this.dataDir, loc);
|
|
3070
|
-
const stat =
|
|
3071
|
-
if (stat.isDirectory()) for (const e of walkAbs(abs, this.dataDir)) entries.push(e);
|
|
3093
|
+
const stat = await fsp.stat(abs);
|
|
3094
|
+
if (stat.isDirectory()) for (const e of await walkAbs(abs, this.dataDir)) entries.push(e);
|
|
3072
3095
|
else entries.push(toArchiveEntry(abs, this.dataDir, stat));
|
|
3073
3096
|
}
|
|
3074
3097
|
const manifest = {
|
|
@@ -3243,15 +3266,15 @@ var SystemBackupService = class {
|
|
|
3243
3266
|
* path. Symlinks are dereferenced (matches the `follow: true` flag we
|
|
3244
3267
|
* pass to tar.create).
|
|
3245
3268
|
*/
|
|
3246
|
-
function walkAbs(absRoot, dataDir) {
|
|
3269
|
+
async function walkAbs(absRoot, dataDir) {
|
|
3247
3270
|
const out = [];
|
|
3248
|
-
walkRec(absRoot, dataDir, out);
|
|
3271
|
+
await walkRec(absRoot, dataDir, out);
|
|
3249
3272
|
return out;
|
|
3250
3273
|
}
|
|
3251
|
-
function walkRec(abs, dataDir, out) {
|
|
3274
|
+
async function walkRec(abs, dataDir, out) {
|
|
3252
3275
|
let stat;
|
|
3253
3276
|
try {
|
|
3254
|
-
stat =
|
|
3277
|
+
stat = await fsp.stat(abs);
|
|
3255
3278
|
} catch {
|
|
3256
3279
|
return;
|
|
3257
3280
|
}
|
|
@@ -3259,11 +3282,11 @@ function walkRec(abs, dataDir, out) {
|
|
|
3259
3282
|
if (stat.isDirectory()) {
|
|
3260
3283
|
let children;
|
|
3261
3284
|
try {
|
|
3262
|
-
children =
|
|
3285
|
+
children = await fsp.readdir(abs);
|
|
3263
3286
|
} catch {
|
|
3264
3287
|
return;
|
|
3265
3288
|
}
|
|
3266
|
-
for (const child of children) walkRec(path$1.join(abs, child), dataDir, out);
|
|
3289
|
+
for (const child of children) await walkRec(path$1.join(abs, child), dataDir, out);
|
|
3267
3290
|
}
|
|
3268
3291
|
}
|
|
3269
3292
|
function toArchiveEntry(abs, dataDir, stat) {
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/console-logging/console-destination.ts
|
|
9
9
|
var LEVEL_RANK = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as logDestinationCapability, et as BaseAddon } from "../../dist-
|
|
1
|
+
import { P as logDestinationCapability, et as BaseAddon } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/console-logging/console-destination.ts
|
|
4
4
|
var LEVEL_RANK = {
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
let _camstack_types_node = require("@camstack/types/node");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as errMsg, C as enumerateItemArrayFields, D as getByPath, Q as validateExpressionSource, R as normalizeUnit, S as deviceStatusCapability, T as evaluateLinkExpression, Tt as sleep, W as setByPath, X as toExpressionValue, a as DeviceStatusSchema, at as DeviceRole, b as deviceManagerCapability, c as STREAM_PROFILE_META, et as BaseAddon, g as applyTransform, i as CAP_NAMES_WITH_STATUS, it as DeviceFeature, ot as DeviceType, st as EventCategory, t as ALL_CAPABILITY_DEFINITIONS, ut as WELL_KNOWN_TAB_MAP, w as enumerateSchemaFields, x as deviceStateCapability, y as buildStreamParamsConfigSchema, yt as isDeviceConfigCap, z as parseStreamParamsFormPatch } from "../../dist-
|
|
1
|
+
import { $ as errMsg, C as enumerateItemArrayFields, D as getByPath, Q as validateExpressionSource, R as normalizeUnit, S as deviceStatusCapability, T as evaluateLinkExpression, Tt as sleep, W as setByPath, X as toExpressionValue, a as DeviceStatusSchema, at as DeviceRole, b as deviceManagerCapability, c as STREAM_PROFILE_META, et as BaseAddon, g as applyTransform, i as CAP_NAMES_WITH_STATUS, it as DeviceFeature, ot as DeviceType, st as EventCategory, t as ALL_CAPABILITY_DEFINITIONS, ut as WELL_KNOWN_TAB_MAP, w as enumerateSchemaFields, x as deviceStateCapability, y as buildStreamParamsConfigSchema, yt as isDeviceConfigCap, z as parseStreamParamsFormPatch } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import { canonicalDeviceFingerprint } from "@camstack/types/node";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
9
9
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as logDestinationCapability, et as BaseAddon } from "../../dist-
|
|
1
|
+
import { P as logDestinationCapability, et as BaseAddon } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
4
4
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
9
9
|
let crypto$1 = require("crypto");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Z as userManagementCapability, _ as authProviderCapability, d as UserRecordSchema, et as BaseAddon, l as ScopedTokenSchema, r as ApiKeyRecordSchema } from "../../dist-
|
|
1
|
+
import { Z as userManagementCapability, _ as authProviderCapability, d as UserRecordSchema, et as BaseAddon, l as ScopedTokenSchema, r as ApiKeyRecordSchema } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import * as crypto$1 from "node:crypto";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
4
4
|
let node_os = require("node:os");
|
|
5
5
|
node_os = require_chunk.__toESM(node_os);
|
|
6
6
|
//#region src/builtins/local-network/local-network.addon.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as localNetworkCapability, et as BaseAddon, st as EventCategory } from "../../dist-
|
|
1
|
+
import { N as localNetworkCapability, et as BaseAddon, st as EventCategory } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
//#region src/builtins/local-network/local-network.addon.ts
|
|
4
4
|
/**
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
node_fs = require_chunk.__toESM(node_fs);
|
|
9
9
|
let node_child_process = require("node:child_process");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as metricsProviderCapability, et as BaseAddon, mt as createEvent, st as EventCategory } from "../../dist-
|
|
1
|
+
import { I as metricsProviderCapability, et as BaseAddon, mt as createEvent, st as EventCategory } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import { execFile, execFileSync } from "node:child_process";
|
|
4
4
|
import { promisify } from "node:util";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
node_fs = require_chunk.__toESM(node_fs);
|
|
9
9
|
let node_child_process = require("node:child_process");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as errMsg, B as platformProbeCapability, U as scoreRuntimes, et as BaseAddon, gt as emitReadiness, st as EventCategory } from "../../dist-
|
|
1
|
+
import { $ as errMsg, B as platformProbeCapability, U as scoreRuntimes, et as BaseAddon, gt as emitReadiness, st as EventCategory } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import { execFile } from "node:child_process";
|
|
4
4
|
import { promisify } from "node:util";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
//#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
|
|
8
8
|
/**
|
|
9
9
|
* Reconcile the durable `enabledProviders` set against authoritative
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { et as BaseAddon, st as EventCategory } from "../../dist-
|
|
1
|
+
import { et as BaseAddon, st as EventCategory } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
//#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
|
|
3
3
|
/**
|
|
4
4
|
* Reconcile the durable `enabledProviders` set against authoritative
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
let node_child_process = require("node:child_process");
|
|
8
8
|
//#region src/builtins/snapshot/snapshot.addon.ts
|
|
9
9
|
/** Default cache window for non-battery cams (seconds). 10s feels live. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as errMsg, K as snapshotCapability, L as nodePin, Y as streamQualityLabel, et as BaseAddon, it as DeviceFeature, ot as DeviceType } from "../../dist-
|
|
1
|
+
import { $ as errMsg, K as snapshotCapability, L as nodePin, Y as streamQualityLabel, et as BaseAddon, it as DeviceFeature, ot as DeviceType } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import { execFile } from "node:child_process";
|
|
3
3
|
//#region src/builtins/snapshot/snapshot.addon.ts
|
|
4
4
|
/** Default cache window for non-battery cams (seconds). 10s feels live. */
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
node_fs = require_chunk.__toESM(node_fs);
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as filesystemBrowseCapability, J as storageProviderCapability, et as BaseAddon } from "../../dist-
|
|
1
|
+
import { E as filesystemBrowseCapability, J as storageProviderCapability, et as BaseAddon } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path$1 from "node:path";
|
|
4
4
|
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let better_sqlite3 = require("better-sqlite3");
|
|
9
9
|
better_sqlite3 = require_chunk.__toESM(better_sqlite3);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as errMsg, G as settingsStoreCapability, dt as asJsonObject, et as BaseAddon, s as RUNTIME_DEFAULTS, xt as parseJsonUnknown } from "../../dist-
|
|
1
|
+
import { $ as errMsg, G as settingsStoreCapability, dt as asJsonObject, et as BaseAddon, s as RUNTIME_DEFAULTS, xt as parseJsonUnknown } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import Database from "better-sqlite3";
|
|
4
4
|
//#region src/builtins/sqlite-storage/sqlite-settings-backend.ts
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
let node_path = require("node:path");
|
|
8
8
|
node_path = require_chunk.__toESM(node_path);
|
|
9
9
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bt as parseJsonObject, et as BaseAddon, q as storageCapability, u as StorageLocationTypeSchema } from "../../dist-
|
|
1
|
+
import { bt as parseJsonObject, et as BaseAddon, q as storageCapability, u as StorageLocationTypeSchema } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import * as path$1 from "node:path";
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import { buildStorageLocationRegistry } from "@camstack/system";
|
|
@@ -64,6 +64,14 @@ export interface LocationStat {
|
|
|
64
64
|
/** False when the location doesn't exist under dataDir. */
|
|
65
65
|
readonly present: boolean;
|
|
66
66
|
}
|
|
67
|
+
export interface SystemBackupServiceOptions {
|
|
68
|
+
/**
|
|
69
|
+
* How long a `statLocations` walk result stays fresh. The `addons`
|
|
70
|
+
* location holds tens of thousands of files; without a cache every
|
|
71
|
+
* admin-UI visit re-walks it.
|
|
72
|
+
*/
|
|
73
|
+
readonly statCacheTtlMs?: number;
|
|
74
|
+
}
|
|
67
75
|
/**
|
|
68
76
|
* System-level archive primitives. Construct one per server boot;
|
|
69
77
|
* methods are pure I/O.
|
|
@@ -71,14 +79,24 @@ export interface LocationStat {
|
|
|
71
79
|
export declare class SystemBackupService {
|
|
72
80
|
private readonly dataDir;
|
|
73
81
|
private readonly logger;
|
|
74
|
-
|
|
82
|
+
private readonly statCacheTtlMs;
|
|
83
|
+
private readonly statCache;
|
|
84
|
+
constructor(dataDir: string, logger: IScopedLogger, opts?: SystemBackupServiceOptions);
|
|
75
85
|
/**
|
|
76
86
|
* Snapshot the current size + file count of each well-known
|
|
77
87
|
* location. Used by the admin UI to render an opt-in checklist
|
|
78
88
|
* before triggering a backup, and by `createArchive` to derive the
|
|
79
89
|
* embedded manifest.
|
|
90
|
+
*
|
|
91
|
+
* The walk is async (yields to the event loop per directory) and
|
|
92
|
+
* per-location results are cached + single-flighted: the service
|
|
93
|
+
* runs in-process in the hub, and a synchronous walk of the 70k+
|
|
94
|
+
* file `addons` location blocked the event loop long enough to kill
|
|
95
|
+
* WS keepalives cluster-wide.
|
|
80
96
|
*/
|
|
81
|
-
statLocations(locations?: readonly string[]): readonly LocationStat[]
|
|
97
|
+
statLocations(locations?: readonly string[]): Promise<readonly LocationStat[]>;
|
|
98
|
+
private statLocationCached;
|
|
99
|
+
private statLocation;
|
|
82
100
|
/**
|
|
83
101
|
* Create a tar.gz of the given locations. Uses the `tar` npm package
|
|
84
102
|
* (used by npm itself) instead of shelling out — gives us:
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
8
8
|
/**
|
|
9
9
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as errMsg, et as BaseAddon, vt as hydrateSchema } from "../../dist-
|
|
1
|
+
import { $ as errMsg, et as BaseAddon, vt as hydrateSchema } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
3
3
|
/**
|
|
4
4
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D_ijwYtl.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as logDestinationCapability, et as BaseAddon } from "../../dist-
|
|
1
|
+
import { P as logDestinationCapability, et as BaseAddon } from "../../dist-C0d3UidT.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
import * as path$1 from "node:path";
|
|
4
4
|
import path from "node:path";
|
|
@@ -16578,6 +16578,19 @@ getTurnServers: method(z.void(), z.array(TurnServerSchema).readonly()) }
|
|
|
16578
16578
|
* b. `finishAuthentication({userId, response})` → server verifies
|
|
16579
16579
|
* the assertion, bumps the credential counter, returns ok.
|
|
16580
16580
|
*
|
|
16581
|
+
* 2b. Usernameless (discoverable-credential) authentication — the
|
|
16582
|
+
* passkey IS the primary factor, no password leg:
|
|
16583
|
+
* a. `beginDiscoverableAuthentication({})` → assertion options with
|
|
16584
|
+
* EMPTY `allowCredentials` (the browser offers every resident
|
|
16585
|
+
* passkey it holds for this RP) + `userVerification: 'required'`
|
|
16586
|
+
* (the passkey replaces both factors, so UV is mandatory).
|
|
16587
|
+
* The challenge is stored server-side, NOT bound to any user.
|
|
16588
|
+
* b. `finishDiscoverableAuthentication({response})` → the provider
|
|
16589
|
+
* resolves the credential by the response's credential id,
|
|
16590
|
+
* verifies the assertion against the stored challenge + that
|
|
16591
|
+
* credential's public key/counter, and returns the OWNING
|
|
16592
|
+
* `userId` — the caller (core auth router) mints the session.
|
|
16593
|
+
*
|
|
16581
16594
|
* 3. Management:
|
|
16582
16595
|
* - `listPasskeys({userId})` — enumerate user's enrolled credentials.
|
|
16583
16596
|
* - `removePasskey({userId, credentialId})` — revoke one credential.
|
|
@@ -16634,6 +16647,19 @@ var userPasskeysCapability = {
|
|
|
16634
16647
|
kind: "mutation",
|
|
16635
16648
|
access: "view"
|
|
16636
16649
|
}),
|
|
16650
|
+
beginDiscoverableAuthentication: method(z.object({}), z.object({ optionsJSON: z.record(z.string(), z.unknown()) }), {
|
|
16651
|
+
kind: "mutation",
|
|
16652
|
+
access: "view"
|
|
16653
|
+
}),
|
|
16654
|
+
finishDiscoverableAuthentication: method(z.object({
|
|
16655
|
+
/** AuthenticationResponseJSON from the browser. */
|
|
16656
|
+
response: z.record(z.string(), z.unknown()) }), z.object({
|
|
16657
|
+
verified: z.boolean(),
|
|
16658
|
+
userId: z.string().nullable()
|
|
16659
|
+
}), {
|
|
16660
|
+
kind: "mutation",
|
|
16661
|
+
access: "view"
|
|
16662
|
+
}),
|
|
16637
16663
|
listPasskeys: method(z.object({ userId: z.string() }), z.array(PasskeySummarySchema), { auth: "admin" }),
|
|
16638
16664
|
removePasskey: method(z.object({
|
|
16639
16665
|
userId: z.string(),
|
|
@@ -24532,6 +24558,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
24532
24558
|
addonId: null,
|
|
24533
24559
|
access: "view"
|
|
24534
24560
|
},
|
|
24561
|
+
"userPasskeys.beginDiscoverableAuthentication": {
|
|
24562
|
+
capName: "user-passkeys",
|
|
24563
|
+
capScope: "system",
|
|
24564
|
+
addonId: null,
|
|
24565
|
+
access: "view"
|
|
24566
|
+
},
|
|
24535
24567
|
"userPasskeys.beginRegistration": {
|
|
24536
24568
|
capName: "user-passkeys",
|
|
24537
24569
|
capScope: "system",
|
|
@@ -24544,6 +24576,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
24544
24576
|
addonId: null,
|
|
24545
24577
|
access: "view"
|
|
24546
24578
|
},
|
|
24579
|
+
"userPasskeys.finishDiscoverableAuthentication": {
|
|
24580
|
+
capName: "user-passkeys",
|
|
24581
|
+
capScope: "system",
|
|
24582
|
+
addonId: null,
|
|
24583
|
+
access: "view"
|
|
24584
|
+
},
|
|
24547
24585
|
"userPasskeys.finishRegistration": {
|
|
24548
24586
|
capName: "user-passkeys",
|
|
24549
24587
|
capScope: "system",
|
|
@@ -16578,6 +16578,19 @@ getTurnServers: method(zod.z.void(), zod.z.array(TurnServerSchema).readonly()) }
|
|
|
16578
16578
|
* b. `finishAuthentication({userId, response})` → server verifies
|
|
16579
16579
|
* the assertion, bumps the credential counter, returns ok.
|
|
16580
16580
|
*
|
|
16581
|
+
* 2b. Usernameless (discoverable-credential) authentication — the
|
|
16582
|
+
* passkey IS the primary factor, no password leg:
|
|
16583
|
+
* a. `beginDiscoverableAuthentication({})` → assertion options with
|
|
16584
|
+
* EMPTY `allowCredentials` (the browser offers every resident
|
|
16585
|
+
* passkey it holds for this RP) + `userVerification: 'required'`
|
|
16586
|
+
* (the passkey replaces both factors, so UV is mandatory).
|
|
16587
|
+
* The challenge is stored server-side, NOT bound to any user.
|
|
16588
|
+
* b. `finishDiscoverableAuthentication({response})` → the provider
|
|
16589
|
+
* resolves the credential by the response's credential id,
|
|
16590
|
+
* verifies the assertion against the stored challenge + that
|
|
16591
|
+
* credential's public key/counter, and returns the OWNING
|
|
16592
|
+
* `userId` — the caller (core auth router) mints the session.
|
|
16593
|
+
*
|
|
16581
16594
|
* 3. Management:
|
|
16582
16595
|
* - `listPasskeys({userId})` — enumerate user's enrolled credentials.
|
|
16583
16596
|
* - `removePasskey({userId, credentialId})` — revoke one credential.
|
|
@@ -16634,6 +16647,19 @@ var userPasskeysCapability = {
|
|
|
16634
16647
|
kind: "mutation",
|
|
16635
16648
|
access: "view"
|
|
16636
16649
|
}),
|
|
16650
|
+
beginDiscoverableAuthentication: method(zod.z.object({}), zod.z.object({ optionsJSON: zod.z.record(zod.z.string(), zod.z.unknown()) }), {
|
|
16651
|
+
kind: "mutation",
|
|
16652
|
+
access: "view"
|
|
16653
|
+
}),
|
|
16654
|
+
finishDiscoverableAuthentication: method(zod.z.object({
|
|
16655
|
+
/** AuthenticationResponseJSON from the browser. */
|
|
16656
|
+
response: zod.z.record(zod.z.string(), zod.z.unknown()) }), zod.z.object({
|
|
16657
|
+
verified: zod.z.boolean(),
|
|
16658
|
+
userId: zod.z.string().nullable()
|
|
16659
|
+
}), {
|
|
16660
|
+
kind: "mutation",
|
|
16661
|
+
access: "view"
|
|
16662
|
+
}),
|
|
16637
16663
|
listPasskeys: method(zod.z.object({ userId: zod.z.string() }), zod.z.array(PasskeySummarySchema), { auth: "admin" }),
|
|
16638
16664
|
removePasskey: method(zod.z.object({
|
|
16639
16665
|
userId: zod.z.string(),
|
|
@@ -24532,6 +24558,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
24532
24558
|
addonId: null,
|
|
24533
24559
|
access: "view"
|
|
24534
24560
|
},
|
|
24561
|
+
"userPasskeys.beginDiscoverableAuthentication": {
|
|
24562
|
+
capName: "user-passkeys",
|
|
24563
|
+
capScope: "system",
|
|
24564
|
+
addonId: null,
|
|
24565
|
+
access: "view"
|
|
24566
|
+
},
|
|
24535
24567
|
"userPasskeys.beginRegistration": {
|
|
24536
24568
|
capName: "user-passkeys",
|
|
24537
24569
|
capScope: "system",
|
|
@@ -24544,6 +24576,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
24544
24576
|
addonId: null,
|
|
24545
24577
|
access: "view"
|
|
24546
24578
|
},
|
|
24579
|
+
"userPasskeys.finishDiscoverableAuthentication": {
|
|
24580
|
+
capName: "user-passkeys",
|
|
24581
|
+
capScope: "system",
|
|
24582
|
+
addonId: null,
|
|
24583
|
+
access: "view"
|
|
24584
|
+
},
|
|
24547
24585
|
"userPasskeys.finishRegistration": {
|
|
24548
24586
|
capName: "user-passkeys",
|
|
24549
24587
|
capScope: "system",
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("./dist-
|
|
3
|
+
const require_dist = require("./dist-D_ijwYtl.js");
|
|
4
4
|
const require_model_download_service = require("./model-download-service-D-Umz4-L.js");
|
|
5
5
|
const require_resource_monitor = require("./resource-monitor-DNNomR-i.js");
|
|
6
6
|
const require_builtins_sqlite_storage_filesystem_storage_addon = require("./builtins/sqlite-storage/filesystem-storage.addon.js");
|
|
@@ -21,7 +21,7 @@ const require_builtins_local_auth_local_auth_addon = require("./builtins/local-a
|
|
|
21
21
|
require("./builtins/local-auth/index.js");
|
|
22
22
|
const require_builtins_device_manager_device_manager_addon = require("./builtins/device-manager/device-manager.addon.js");
|
|
23
23
|
require("./builtins/device-manager/index.js");
|
|
24
|
-
const require_manifest_python_deps = require("./manifest-python-deps-
|
|
24
|
+
const require_manifest_python_deps = require("./manifest-python-deps-Cp9WdXiT.js");
|
|
25
25
|
const require_custom_action_registry = require("./custom-action-registry-vLYEFTtv.js");
|
|
26
26
|
let _camstack_types_node = require("@camstack/types/node");
|
|
27
27
|
let zod = require("zod");
|
|
@@ -2587,6 +2587,71 @@ async function copyDirRecursive(src, dest) {
|
|
|
2587
2587
|
});
|
|
2588
2588
|
}
|
|
2589
2589
|
/**
|
|
2590
|
+
* Runtime natives that must stay installable even when an addon forgets to
|
|
2591
|
+
* declare them: the mirror of the build preset's `COMMON_NATIVE_DEPS`
|
|
2592
|
+
* (tools/build/vite-lib.preset.ts — build tooling, not loadable at runtime).
|
|
2593
|
+
* These are the ONLY packages a self-contained dist genuinely `require()`s
|
|
2594
|
+
* from node_modules; everything else is already inlined by the bundle.
|
|
2595
|
+
*/
|
|
2596
|
+
var RUNTIME_NATIVE_KEEP = [
|
|
2597
|
+
"better-sqlite3",
|
|
2598
|
+
"node-av",
|
|
2599
|
+
"onnxruntime-node",
|
|
2600
|
+
"sharp",
|
|
2601
|
+
"ssh2",
|
|
2602
|
+
"werift",
|
|
2603
|
+
"systeminformation"
|
|
2604
|
+
];
|
|
2605
|
+
/** Read `camstack.runtimeDependencies` (extra non-native deps the dist
|
|
2606
|
+
* requires at runtime — versions come from the manifest's own dep maps). */
|
|
2607
|
+
function readRuntimeDependencies(pkg) {
|
|
2608
|
+
const camstack = pkg.camstack;
|
|
2609
|
+
if (camstack === null || typeof camstack !== "object" || Array.isArray(camstack)) return [];
|
|
2610
|
+
const raw = camstack.runtimeDependencies;
|
|
2611
|
+
if (!Array.isArray(raw)) return [];
|
|
2612
|
+
return raw.filter((entry) => typeof entry === "string");
|
|
2613
|
+
}
|
|
2614
|
+
/**
|
|
2615
|
+
* Strip every dependency an addon's self-contained dist has already bundled,
|
|
2616
|
+
* keeping ONLY what must resolve from node_modules at runtime:
|
|
2617
|
+
*
|
|
2618
|
+
* keep = RUNTIME_NATIVE_KEEP ∪ camstack.runtimeDependencies (minus @camstack/*)
|
|
2619
|
+
*
|
|
2620
|
+
* Addon dists are fully bundled (vite `externals: 'self-contained'`), yet the
|
|
2621
|
+
* blanket `npm install` of the manifest's dependencies re-installed the whole
|
|
2622
|
+
* tree the dist already contains — 98% of the deployed addons dir was
|
|
2623
|
+
* redundant node_modules (74k files / 1.34 GB on the live hub; it stalled the
|
|
2624
|
+
* backup walk and bloated every deploy). Kept PEER deps are folded into
|
|
2625
|
+
* `dependencies` so `--omit=peer` installs can't drop them (pipeline's
|
|
2626
|
+
* patched `werift`).
|
|
2627
|
+
*
|
|
2628
|
+
* Escape hatch: `CAMSTACK_INSTALL_FULL_DEPS=1` restores the legacy behaviour
|
|
2629
|
+
* (strip only @camstack/*) for debugging a suspected undeclared runtime dep.
|
|
2630
|
+
*
|
|
2631
|
+
* Returns a new object (immutable).
|
|
2632
|
+
*/
|
|
2633
|
+
function stripBundledDeps(pkg) {
|
|
2634
|
+
if (process.env.CAMSTACK_INSTALL_FULL_DEPS === "1") return stripCamstackDeps(pkg);
|
|
2635
|
+
const camstack = pkg.camstack;
|
|
2636
|
+
if (camstack !== null && typeof camstack === "object" && !Array.isArray(camstack) && camstack.system === true) return stripCamstackDeps(pkg);
|
|
2637
|
+
const keep = new Set([...RUNTIME_NATIVE_KEEP, ...readRuntimeDependencies(pkg)]);
|
|
2638
|
+
const kept = {};
|
|
2639
|
+
for (const depType of ["dependencies", "peerDependencies"]) {
|
|
2640
|
+
const rawDeps = pkg[depType];
|
|
2641
|
+
if (rawDeps === null || typeof rawDeps !== "object" || Array.isArray(rawDeps)) continue;
|
|
2642
|
+
for (const [name, version] of Object.entries(rawDeps)) {
|
|
2643
|
+
if (name.startsWith("@camstack/")) continue;
|
|
2644
|
+
if (!keep.has(name) || typeof version !== "string") continue;
|
|
2645
|
+
if (!(name in kept)) kept[name] = version;
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
const result = { ...pkg };
|
|
2649
|
+
result.dependencies = Object.keys(kept).length > 0 ? kept : void 0;
|
|
2650
|
+
result.peerDependencies = void 0;
|
|
2651
|
+
delete result.devDependencies;
|
|
2652
|
+
return result;
|
|
2653
|
+
}
|
|
2654
|
+
/**
|
|
2590
2655
|
* Strip @camstack/* dependencies and devDependencies from a package.json object.
|
|
2591
2656
|
* Used when installing addons into the addons directory — @camstack packages
|
|
2592
2657
|
* are provided by the host runtime, not installed per-addon.
|
|
@@ -3171,7 +3236,7 @@ var AddonInstaller = class AddonInstaller {
|
|
|
3171
3236
|
force: true
|
|
3172
3237
|
});
|
|
3173
3238
|
ensureDir(targetDir);
|
|
3174
|
-
await node_fs.promises.writeFile(node_path.join(targetDir, "package.json"), JSON.stringify(
|
|
3239
|
+
await node_fs.promises.writeFile(node_path.join(targetDir, "package.json"), JSON.stringify(stripBundledDeps(pkgData), null, 2));
|
|
3175
3240
|
await copyDirRecursive(distDir, node_path.join(targetDir, "dist"));
|
|
3176
3241
|
await copyExtraFileDirs(pkgData, sourceDir, targetDir);
|
|
3177
3242
|
await node_fs.promises.writeFile(node_path.join(targetDir, ".install-source"), "local");
|
|
@@ -3180,7 +3245,7 @@ var AddonInstaller = class AddonInstaller {
|
|
|
3180
3245
|
version: localPkgVersion,
|
|
3181
3246
|
source: "local"
|
|
3182
3247
|
});
|
|
3183
|
-
const strippedDeps =
|
|
3248
|
+
const strippedDeps = stripBundledDeps(pkgData);
|
|
3184
3249
|
if (strippedDeps["dependencies"] && typeof strippedDeps["dependencies"] === "object" && Object.keys(strippedDeps["dependencies"]).length > 0) try {
|
|
3185
3250
|
await execFileAsync("npm", [
|
|
3186
3251
|
"install",
|
|
@@ -3358,7 +3423,7 @@ var AddonInstaller = class AddonInstaller {
|
|
|
3358
3423
|
if (!pkgView) throw new Error(`Invalid package.json at ${pkgJsonPath}`);
|
|
3359
3424
|
if (!pkgView.camstackAddons) throw new Error(`Package ${pkgView.name} has no camstack.addons manifest`);
|
|
3360
3425
|
const targetDir = node_path.join(this.addonsDir, pkgView.name);
|
|
3361
|
-
const strippedManifest =
|
|
3426
|
+
const strippedManifest = stripBundledDeps(pkgView.raw);
|
|
3362
3427
|
await node_fs.promises.writeFile(pkgJsonPath, JSON.stringify(strippedManifest, null, 2));
|
|
3363
3428
|
const strippedRuntimeDeps = strippedManifest["dependencies"];
|
|
3364
3429
|
if (strippedRuntimeDeps != null && typeof strippedRuntimeDeps === "object" && Object.keys(strippedRuntimeDeps).length > 0) {
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as errMsg$1, A as isVoidInput, Ct as resolveCapMount, F as looseSchema, M as lifecycleJobSchema, O as isArrayOutputSchema, St as readinessKey, V as procedureAuthKey, _t as expandCapMethods, bt as parseJsonObject, ct as ReadinessRegistry, dt as asJsonObject$1, ft as asNumber, ht as emitDownForOwnedCaps, j as kebabToCamel, k as isObjectInput, lt as ReadinessTimeoutError, mt as createEvent, nt as DEVICE_SETTINGS_CONTRIBUTION_METHODS, o as METHOD_ACCESS_MAP, p as addonSettingsCapability, pt as asString$1, rt as DEVICE_STATUS_METHOD, s as RUNTIME_DEFAULTS, st as EventCategory$1, t as ALL_CAPABILITY_DEFINITIONS, tt as DATAPLANE_SECRET_HEADER$1, wt as scopeKey, xt as parseJsonUnknown$1 } from "./dist-
|
|
1
|
+
import { $ as errMsg$1, A as isVoidInput, Ct as resolveCapMount, F as looseSchema, M as lifecycleJobSchema, O as isArrayOutputSchema, St as readinessKey, V as procedureAuthKey, _t as expandCapMethods, bt as parseJsonObject, ct as ReadinessRegistry, dt as asJsonObject$1, ft as asNumber, ht as emitDownForOwnedCaps, j as kebabToCamel, k as isObjectInput, lt as ReadinessTimeoutError, mt as createEvent, nt as DEVICE_SETTINGS_CONTRIBUTION_METHODS, o as METHOD_ACCESS_MAP, p as addonSettingsCapability, pt as asString$1, rt as DEVICE_STATUS_METHOD, s as RUNTIME_DEFAULTS, st as EventCategory$1, t as ALL_CAPABILITY_DEFINITIONS, tt as DATAPLANE_SECRET_HEADER$1, wt as scopeKey, xt as parseJsonUnknown$1 } from "./dist-C0d3UidT.mjs";
|
|
2
2
|
import { a as downloadModel, c as getModelFilePath, d as contentTypeFor, f as createAuthenticatedFileServer, h as resolveFilePath, i as downloadFile, l as isModelDownloaded, m as parseTokenizedUrl, n as collectModelFiles, o as ensureModel, p as parseRangeHeader, r as deleteModelFromDisk, s as fetchJson, t as ModelDownloadService, u as createFileDataPlaneHandler } from "./model-download-service-C-IHWnXx.mjs";
|
|
3
3
|
import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-Le3l0qS2.mjs";
|
|
4
4
|
import { FilesystemStorageAddon, t as FilesystemStorageProvider } from "./builtins/sqlite-storage/filesystem-storage.addon.mjs";
|
|
@@ -19,7 +19,7 @@ import { LocalAuthAddon, a as require_ms, c as __esmMin, d as __toCommonJS, f as
|
|
|
19
19
|
import "./builtins/local-auth/index.mjs";
|
|
20
20
|
import { DeviceManagerAddon } from "./builtins/device-manager/device-manager.addon.mjs";
|
|
21
21
|
import "./builtins/device-manager/index.mjs";
|
|
22
|
-
import { $ as buildUdsNativeCapProxy, A as createParentUnownedCallHandler, B as AGENT_CAP_FWD_SERVICE, C as buildLinkChain, D as HUB_CAP_FWD_ACTION, E as localProviderLink, F as createUdsLoggerWithControl, G as createLocalTransport, H as CapRouteError, I as LocalChildClient, J as SocketChannel, K as UdsLocalTransportClient, L as LocalChildRegistry, M as createUdsEventBus, N as udsChildLogToWorkerEntry, O as HUB_CAP_FWD_SERVICE, P as createUdsLogger, Q as buildNativeCapProxy, R as UDS_NO_ROUTE_PREFIX, S as brokerTransportLink, T as ipcParentLink, U as classifyCapRoute, V as CapRouteResolver, W as callWithServiceDiscovery, X as FrameDecoder, Y as localEndpointPath, Z as encodeFrame, _ as resolveHwAccel, _t as CapabilityUnavailableError, a as getWorkerDeviceRegistry, at as createAddonService, b as getCapUsageRegistry, c as setHubConnected, ct as capActionName, d as getMoleculerEventStats, dt as capServiceName, et as createBrokerDeviceManagerApi, f as registerEventBusService, ft as parseCapAction, g as createKernelHwAccel, gt as CapabilityHandle, h as AddonDepsManager, ht as DeviceRegistry, i as createUdsAddonContext, j as createUdsEventBridge, k as createHubCapForwardService, l as EVENT_TOPIC_PREFIX, lt as capActionSuffix, m as subscribePassthrough, mt as serializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as validateProviderRegistrations, p as setNodeEventInterest, pt as deserializeTypedArrays, q as UdsLocalTransportServer, r as createAddonContext, rt as mountNativeCapService, s as getOrInitReadinessRegistryForClient, st as NATIVE_PROVIDER_SERVICE_INFIX, t as installManifestPythonDeps, u as getBrokerEventBus, ut as capBareAction, v as CapUsageRegistry, vt as installManifestNativeDeps, w as ipcChildLink, x as brokerCallForCap, y as __resetCapUsageRegistryForTests, yt as resolveAddonClass, z as AGENT_CAP_FWD_ACTION } from "./manifest-python-deps-
|
|
22
|
+
import { $ as buildUdsNativeCapProxy, A as createParentUnownedCallHandler, B as AGENT_CAP_FWD_SERVICE, C as buildLinkChain, D as HUB_CAP_FWD_ACTION, E as localProviderLink, F as createUdsLoggerWithControl, G as createLocalTransport, H as CapRouteError, I as LocalChildClient, J as SocketChannel, K as UdsLocalTransportClient, L as LocalChildRegistry, M as createUdsEventBus, N as udsChildLogToWorkerEntry, O as HUB_CAP_FWD_SERVICE, P as createUdsLogger, Q as buildNativeCapProxy, R as UDS_NO_ROUTE_PREFIX, S as brokerTransportLink, T as ipcParentLink, U as classifyCapRoute, V as CapRouteResolver, W as callWithServiceDiscovery, X as FrameDecoder, Y as localEndpointPath, Z as encodeFrame, _ as resolveHwAccel, _t as CapabilityUnavailableError, a as getWorkerDeviceRegistry, at as createAddonService, b as getCapUsageRegistry, c as setHubConnected, ct as capActionName, d as getMoleculerEventStats, dt as capServiceName, et as createBrokerDeviceManagerApi, f as registerEventBusService, ft as parseCapAction, g as createKernelHwAccel, gt as CapabilityHandle, h as AddonDepsManager, ht as DeviceRegistry, i as createUdsAddonContext, j as createUdsEventBridge, k as createHubCapForwardService, l as EVENT_TOPIC_PREFIX, lt as capActionSuffix, m as subscribePassthrough, mt as serializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as validateProviderRegistrations, p as setNodeEventInterest, pt as deserializeTypedArrays, q as UdsLocalTransportServer, r as createAddonContext, rt as mountNativeCapService, s as getOrInitReadinessRegistryForClient, st as NATIVE_PROVIDER_SERVICE_INFIX, t as installManifestPythonDeps, u as getBrokerEventBus, ut as capBareAction, v as CapUsageRegistry, vt as installManifestNativeDeps, w as ipcChildLink, x as brokerCallForCap, y as __resetCapUsageRegistryForTests, yt as resolveAddonClass, z as AGENT_CAP_FWD_ACTION } from "./manifest-python-deps-6u3YnO2u.mjs";
|
|
23
23
|
import { t as CustomActionRegistry } from "./custom-action-registry-BEXwC-oo.mjs";
|
|
24
24
|
import { PYTHON_VERSION, buildBinaryPath, downloadBinary, ensureBinary, ensureFfmpeg, ensurePython, findInPath, getFfmpegDownloadUrl, getPlatformInfo, getPythonDownloadUrl, installPythonPackages, installPythonRequirements } from "@camstack/types/node";
|
|
25
25
|
import { z } from "zod";
|
|
@@ -2579,6 +2579,71 @@ async function copyDirRecursive(src, dest) {
|
|
|
2579
2579
|
});
|
|
2580
2580
|
}
|
|
2581
2581
|
/**
|
|
2582
|
+
* Runtime natives that must stay installable even when an addon forgets to
|
|
2583
|
+
* declare them: the mirror of the build preset's `COMMON_NATIVE_DEPS`
|
|
2584
|
+
* (tools/build/vite-lib.preset.ts — build tooling, not loadable at runtime).
|
|
2585
|
+
* These are the ONLY packages a self-contained dist genuinely `require()`s
|
|
2586
|
+
* from node_modules; everything else is already inlined by the bundle.
|
|
2587
|
+
*/
|
|
2588
|
+
var RUNTIME_NATIVE_KEEP = [
|
|
2589
|
+
"better-sqlite3",
|
|
2590
|
+
"node-av",
|
|
2591
|
+
"onnxruntime-node",
|
|
2592
|
+
"sharp",
|
|
2593
|
+
"ssh2",
|
|
2594
|
+
"werift",
|
|
2595
|
+
"systeminformation"
|
|
2596
|
+
];
|
|
2597
|
+
/** Read `camstack.runtimeDependencies` (extra non-native deps the dist
|
|
2598
|
+
* requires at runtime — versions come from the manifest's own dep maps). */
|
|
2599
|
+
function readRuntimeDependencies(pkg) {
|
|
2600
|
+
const camstack = pkg.camstack;
|
|
2601
|
+
if (camstack === null || typeof camstack !== "object" || Array.isArray(camstack)) return [];
|
|
2602
|
+
const raw = camstack.runtimeDependencies;
|
|
2603
|
+
if (!Array.isArray(raw)) return [];
|
|
2604
|
+
return raw.filter((entry) => typeof entry === "string");
|
|
2605
|
+
}
|
|
2606
|
+
/**
|
|
2607
|
+
* Strip every dependency an addon's self-contained dist has already bundled,
|
|
2608
|
+
* keeping ONLY what must resolve from node_modules at runtime:
|
|
2609
|
+
*
|
|
2610
|
+
* keep = RUNTIME_NATIVE_KEEP ∪ camstack.runtimeDependencies (minus @camstack/*)
|
|
2611
|
+
*
|
|
2612
|
+
* Addon dists are fully bundled (vite `externals: 'self-contained'`), yet the
|
|
2613
|
+
* blanket `npm install` of the manifest's dependencies re-installed the whole
|
|
2614
|
+
* tree the dist already contains — 98% of the deployed addons dir was
|
|
2615
|
+
* redundant node_modules (74k files / 1.34 GB on the live hub; it stalled the
|
|
2616
|
+
* backup walk and bloated every deploy). Kept PEER deps are folded into
|
|
2617
|
+
* `dependencies` so `--omit=peer` installs can't drop them (pipeline's
|
|
2618
|
+
* patched `werift`).
|
|
2619
|
+
*
|
|
2620
|
+
* Escape hatch: `CAMSTACK_INSTALL_FULL_DEPS=1` restores the legacy behaviour
|
|
2621
|
+
* (strip only @camstack/*) for debugging a suspected undeclared runtime dep.
|
|
2622
|
+
*
|
|
2623
|
+
* Returns a new object (immutable).
|
|
2624
|
+
*/
|
|
2625
|
+
function stripBundledDeps(pkg) {
|
|
2626
|
+
if (process.env.CAMSTACK_INSTALL_FULL_DEPS === "1") return stripCamstackDeps(pkg);
|
|
2627
|
+
const camstack = pkg.camstack;
|
|
2628
|
+
if (camstack !== null && typeof camstack === "object" && !Array.isArray(camstack) && camstack.system === true) return stripCamstackDeps(pkg);
|
|
2629
|
+
const keep = new Set([...RUNTIME_NATIVE_KEEP, ...readRuntimeDependencies(pkg)]);
|
|
2630
|
+
const kept = {};
|
|
2631
|
+
for (const depType of ["dependencies", "peerDependencies"]) {
|
|
2632
|
+
const rawDeps = pkg[depType];
|
|
2633
|
+
if (rawDeps === null || typeof rawDeps !== "object" || Array.isArray(rawDeps)) continue;
|
|
2634
|
+
for (const [name, version] of Object.entries(rawDeps)) {
|
|
2635
|
+
if (name.startsWith("@camstack/")) continue;
|
|
2636
|
+
if (!keep.has(name) || typeof version !== "string") continue;
|
|
2637
|
+
if (!(name in kept)) kept[name] = version;
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
const result = { ...pkg };
|
|
2641
|
+
result.dependencies = Object.keys(kept).length > 0 ? kept : void 0;
|
|
2642
|
+
result.peerDependencies = void 0;
|
|
2643
|
+
delete result.devDependencies;
|
|
2644
|
+
return result;
|
|
2645
|
+
}
|
|
2646
|
+
/**
|
|
2582
2647
|
* Strip @camstack/* dependencies and devDependencies from a package.json object.
|
|
2583
2648
|
* Used when installing addons into the addons directory — @camstack packages
|
|
2584
2649
|
* are provided by the host runtime, not installed per-addon.
|
|
@@ -3163,7 +3228,7 @@ var AddonInstaller = class AddonInstaller {
|
|
|
3163
3228
|
force: true
|
|
3164
3229
|
});
|
|
3165
3230
|
ensureDir(targetDir);
|
|
3166
|
-
await fs$17.promises.writeFile(path$39.join(targetDir, "package.json"), JSON.stringify(
|
|
3231
|
+
await fs$17.promises.writeFile(path$39.join(targetDir, "package.json"), JSON.stringify(stripBundledDeps(pkgData), null, 2));
|
|
3167
3232
|
await copyDirRecursive(distDir, path$39.join(targetDir, "dist"));
|
|
3168
3233
|
await copyExtraFileDirs(pkgData, sourceDir, targetDir);
|
|
3169
3234
|
await fs$17.promises.writeFile(path$39.join(targetDir, ".install-source"), "local");
|
|
@@ -3172,7 +3237,7 @@ var AddonInstaller = class AddonInstaller {
|
|
|
3172
3237
|
version: localPkgVersion,
|
|
3173
3238
|
source: "local"
|
|
3174
3239
|
});
|
|
3175
|
-
const strippedDeps =
|
|
3240
|
+
const strippedDeps = stripBundledDeps(pkgData);
|
|
3176
3241
|
if (strippedDeps["dependencies"] && typeof strippedDeps["dependencies"] === "object" && Object.keys(strippedDeps["dependencies"]).length > 0) try {
|
|
3177
3242
|
await execFileAsync("npm", [
|
|
3178
3243
|
"install",
|
|
@@ -3350,7 +3415,7 @@ var AddonInstaller = class AddonInstaller {
|
|
|
3350
3415
|
if (!pkgView) throw new Error(`Invalid package.json at ${pkgJsonPath}`);
|
|
3351
3416
|
if (!pkgView.camstackAddons) throw new Error(`Package ${pkgView.name} has no camstack.addons manifest`);
|
|
3352
3417
|
const targetDir = path$39.join(this.addonsDir, pkgView.name);
|
|
3353
|
-
const strippedManifest =
|
|
3418
|
+
const strippedManifest = stripBundledDeps(pkgView.raw);
|
|
3354
3419
|
await fs$17.promises.writeFile(pkgJsonPath, JSON.stringify(strippedManifest, null, 2));
|
|
3355
3420
|
const strippedRuntimeDeps = strippedManifest["dependencies"];
|
|
3356
3421
|
if (strippedRuntimeDeps != null && typeof strippedRuntimeDeps === "object" && Object.keys(strippedRuntimeDeps).length > 0) {
|
|
@@ -14,6 +14,34 @@ export declare function ensureDir(dirPath: string): void;
|
|
|
14
14
|
* `fs.promises.cp` keeps the I/O off the event loop. (Node ≥18 stable.)
|
|
15
15
|
*/
|
|
16
16
|
export declare function copyDirRecursive(src: string, dest: string): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Runtime natives that must stay installable even when an addon forgets to
|
|
19
|
+
* declare them: the mirror of the build preset's `COMMON_NATIVE_DEPS`
|
|
20
|
+
* (tools/build/vite-lib.preset.ts — build tooling, not loadable at runtime).
|
|
21
|
+
* These are the ONLY packages a self-contained dist genuinely `require()`s
|
|
22
|
+
* from node_modules; everything else is already inlined by the bundle.
|
|
23
|
+
*/
|
|
24
|
+
export declare const RUNTIME_NATIVE_KEEP: readonly string[];
|
|
25
|
+
/**
|
|
26
|
+
* Strip every dependency an addon's self-contained dist has already bundled,
|
|
27
|
+
* keeping ONLY what must resolve from node_modules at runtime:
|
|
28
|
+
*
|
|
29
|
+
* keep = RUNTIME_NATIVE_KEEP ∪ camstack.runtimeDependencies (minus @camstack/*)
|
|
30
|
+
*
|
|
31
|
+
* Addon dists are fully bundled (vite `externals: 'self-contained'`), yet the
|
|
32
|
+
* blanket `npm install` of the manifest's dependencies re-installed the whole
|
|
33
|
+
* tree the dist already contains — 98% of the deployed addons dir was
|
|
34
|
+
* redundant node_modules (74k files / 1.34 GB on the live hub; it stalled the
|
|
35
|
+
* backup walk and bloated every deploy). Kept PEER deps are folded into
|
|
36
|
+
* `dependencies` so `--omit=peer` installs can't drop them (pipeline's
|
|
37
|
+
* patched `werift`).
|
|
38
|
+
*
|
|
39
|
+
* Escape hatch: `CAMSTACK_INSTALL_FULL_DEPS=1` restores the legacy behaviour
|
|
40
|
+
* (strip only @camstack/*) for debugging a suspected undeclared runtime dep.
|
|
41
|
+
*
|
|
42
|
+
* Returns a new object (immutable).
|
|
43
|
+
*/
|
|
44
|
+
export declare function stripBundledDeps(pkg: Record<string, unknown>): Record<string, unknown>;
|
|
17
45
|
/**
|
|
18
46
|
* Strip @camstack/* dependencies and devDependencies from a package.json object.
|
|
19
47
|
* Used when installing addons into the addons directory — @camstack packages
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { H as readNodePin } from "./dist-
|
|
1
|
+
import { H as readNodePin } from "./dist-C0d3UidT.mjs";
|
|
2
2
|
import { ensureBinary, ensureFfmpeg, ensurePython, installPythonPackages, installPythonRequirements } from "@camstack/types/node";
|
|
3
3
|
import { createServer } from "node:http";
|
|
4
4
|
import * as fs from "node:fs";
|
|
@@ -4527,7 +4527,8 @@ var LocalChildClient = class {
|
|
|
4527
4527
|
capName: msg.capName,
|
|
4528
4528
|
method: msg.method,
|
|
4529
4529
|
args: msg.args,
|
|
4530
|
-
...msg.deviceId !== void 0 ? { deviceId: msg.deviceId } : {}
|
|
4530
|
+
...msg.deviceId !== void 0 ? { deviceId: msg.deviceId } : {},
|
|
4531
|
+
...msg.addonId !== void 0 ? { addonId: msg.addonId } : {}
|
|
4531
4532
|
});
|
|
4532
4533
|
if (msg.kind === "addon-call") {
|
|
4533
4534
|
if (this.addonCallHandler === null) throw new Error(`LocalChildClient: addon-call for "${msg.addonId}" arrived but no onAddonCall handler is registered`);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
2
|
-
const require_dist = require("./dist-
|
|
2
|
+
const require_dist = require("./dist-D_ijwYtl.js");
|
|
3
3
|
let _camstack_types_node = require("@camstack/types/node");
|
|
4
4
|
let node_http = require("node:http");
|
|
5
5
|
let node_fs = require("node:fs");
|
|
@@ -4529,7 +4529,8 @@ var LocalChildClient = class {
|
|
|
4529
4529
|
capName: msg.capName,
|
|
4530
4530
|
method: msg.method,
|
|
4531
4531
|
args: msg.args,
|
|
4532
|
-
...msg.deviceId !== void 0 ? { deviceId: msg.deviceId } : {}
|
|
4532
|
+
...msg.deviceId !== void 0 ? { deviceId: msg.deviceId } : {},
|
|
4533
|
+
...msg.addonId !== void 0 ? { addonId: msg.addonId } : {}
|
|
4533
4534
|
});
|
|
4534
4535
|
if (msg.kind === "addon-call") {
|
|
4535
4536
|
if (this.addonCallHandler === null) throw new Error(`LocalChildClient: addon-call for "${msg.addonId}" arrived but no onAddonCall handler is registered`);
|