@camstack/system 1.2.437 → 1.2.439
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 +64 -12
- package/dist/addon-runner.mjs +65 -13
- package/dist/{agent-https-BZIwS4xF.js → agent-https-DlpTMDqA.js} +252 -22
- package/dist/{agent-https-BPfHrI4c.mjs → agent-https-U0d4uvn2.mjs} +211 -23
- 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 +7 -1
- package/dist/builtins/alerts/alerts.addon.mjs +7 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
- package/dist/builtins/calendars/calendars.addon.js +1 -1
- package/dist/builtins/calendars/calendars.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +9 -1
- package/dist/builtins/camera-grid/index.mjs +9 -1
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +12 -5
- package/dist/builtins/console-logging/index.mjs +12 -5
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-manager/device-manager.addon.d.ts +5 -0
- package/dist/builtins/device-manager/device-manager.addon.js +717 -28
- package/dist/builtins/device-manager/device-manager.addon.mjs +717 -28
- package/dist/builtins/device-manager/device-meta-types.d.ts +4 -0
- package/dist/builtins/device-manager/device-provider-context.d.ts +9 -0
- package/dist/builtins/device-manager/device-removal-hooks.d.ts +103 -0
- package/dist/builtins/device-manager/device-row-store.d.ts +1 -0
- package/dist/builtins/device-manager/device-tombstone-store.d.ts +68 -0
- package/dist/builtins/device-manager/removal-cleanup.d.ts +50 -0
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +37 -4
- package/dist/builtins/keychain/index.mjs +37 -4
- package/dist/builtins/keychain/keychain-service.d.ts +14 -0
- package/dist/builtins/keychain/keychain-store.d.ts +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +12 -12
- package/dist/builtins/local-auth/local-auth.addon.mjs +12 -12
- package/dist/builtins/local-network/local-network.addon.js +16 -2
- package/dist/builtins/local-network/local-network.addon.mjs +16 -2
- package/dist/builtins/loki-logging/index.js +28 -5
- package/dist/builtins/loki-logging/index.mjs +28 -5
- package/dist/builtins/native-metrics/native-metrics.addon.js +11 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +11 -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 +11 -1
- package/dist/builtins/snapshot/index.mjs +11 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +4 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +4 -1
- package/dist/builtins/sqlite-storage/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +3 -3
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +3 -3
- 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-config/system-config.addon.js +22 -4
- package/dist/builtins/system-config/system-config.addon.mjs +22 -4
- package/dist/builtins/winston-logging/index.js +14 -5
- package/dist/builtins/winston-logging/index.mjs +14 -5
- package/dist/{composition-sources-BIT8IUKm.js → composition-sources-B4jC2FC7.js} +1 -1
- package/dist/{composition-sources-tpYR0f1x.mjs → composition-sources-BGOSCGWa.mjs} +1 -1
- package/dist/{constants-Bc6trhoW.mjs → constants-B92BjObl.mjs} +1 -1
- package/dist/{constants-CwRY32Nx.js → constants-BRsjQwi-.js} +1 -1
- package/dist/{device-ca-BhdBByGD.mjs → device-ca-46BUsWD1.mjs} +2 -2
- package/dist/{device-ca-DImD8IzR.js → device-ca-DHG9OW2m.js} +2 -2
- package/dist/{dist-CEAyXW3Q.js → dist-BOWdLjoK.js} +341 -13
- package/dist/{dist-m5JkT8UN.mjs → dist-yI6kF6r6.mjs} +306 -14
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/{hub-mdns-ciao-CBLvq2oj.js → hub-mdns-ciao-D7S5AJRU.js} +377 -69
- package/dist/{hub-mdns-ciao-DMlQTdPU.mjs → hub-mdns-ciao-DGwVc2uh.mjs} +344 -72
- package/dist/i18n/catalog-registry.d.ts +35 -0
- package/dist/i18n/index.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +698 -22
- package/dist/index.mjs +681 -24
- package/dist/kernel/gc-census.d.ts +18 -1
- package/dist/kernel/settings-view-types.d.ts +2 -0
- package/dist/kernel/transport/local-transport.d.ts +3 -0
- package/dist/kernel/transport/peer-answered-error.d.ts +5 -1
- package/dist/{lib-NNxHSOIE.js → lib-8oZrELLm.js} +1 -1
- package/dist/{lib-BeGzVQcd.mjs → lib-DK38ompL.mjs} +1 -1
- package/dist/{restore-archive-DNxAStrJ.mjs → restore-archive-CpdUO-uS.mjs} +1 -1
- package/dist/{restore-archive-C75srVbG.js → restore-archive-DiGiI6Jp.js} +1 -1
- package/dist/{retired-settings-keys-DNfV28R_.js → retired-settings-keys-CyQ7uvta.js} +1 -1
- package/dist/{retired-settings-keys-C5qP9QIf.mjs → retired-settings-keys-UsVtLOT0.mjs} +1 -1
- package/dist/tls/agent-https.d.ts +2 -2
- package/dist/tls/boot-tls.d.ts +6 -0
- package/dist/tls/cert-evaluation.d.ts +1 -1
- package/dist/tls/cert-issue.d.ts +5 -1
- package/dist/tls/cert-manager.d.ts +18 -0
- package/dist/tls/cert-name-constraints.d.ts +53 -0
- package/dist/tls/index.d.ts +5 -4
- package/dist/tls/tls-actions.d.ts +27 -7
- package/dist/tls/tls-status.d.ts +22 -0
- package/dist/tls/uploaded-cert.d.ts +36 -4
- package/dist/{wal-maintenance-Ch79gy9S.js → wal-maintenance-DEL_jeG0.js} +0 -0
- package/dist/{wal-maintenance-DvnVO5IK.mjs → wal-maintenance-xsvdT5Go.mjs} +0 -0
- package/dist/{x509.es-r7Ht1thA.js → x509.es-C4cOo48M.js} +36 -0
- package/dist/{x509.es-CDvj67p1.mjs → x509.es-DK__ETIe.mjs} +1 -1
- package/package.json +3 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_dist = require("./dist-
|
|
2
|
-
const require_x509_es = require("./x509.es-
|
|
1
|
+
const require_dist = require("./dist-BOWdLjoK.js");
|
|
2
|
+
const require_x509_es = require("./x509.es-C4cOo48M.js");
|
|
3
3
|
let node_crypto = require("node:crypto");
|
|
4
4
|
//#region src/auth/jwt-signing-key.ts
|
|
5
5
|
/**
|
|
@@ -718,7 +718,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
718
718
|
return EventCategory;
|
|
719
719
|
}({});
|
|
720
720
|
//#endregion
|
|
721
|
-
//#region ../types/dist/sleep-
|
|
721
|
+
//#region ../types/dist/sleep-DRqxtc0C.mjs
|
|
722
722
|
/**
|
|
723
723
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
724
724
|
* window to float samples (D455).
|
|
@@ -4421,6 +4421,35 @@ function collectZodSecretPaths(schema, prefix = "") {
|
|
|
4421
4421
|
return [...new Set(paths)];
|
|
4422
4422
|
}
|
|
4423
4423
|
/**
|
|
4424
|
+
* A user-facing error with a STABLE code (D863).
|
|
4425
|
+
*
|
|
4426
|
+
* `message` is always the English text, so every consumer that knows nothing
|
|
4427
|
+
* of codes (old clients, logs, the mesh) behaves exactly as before. The hub's
|
|
4428
|
+
* tRPC error formatter reads `code` + `params` and, when the request language
|
|
4429
|
+
* has a text for `server:<code>`, replaces the response `message`; the code
|
|
4430
|
+
* stays in the payload (`data.i18n`).
|
|
4431
|
+
*/
|
|
4432
|
+
/** Dotted lower-case code, e.g. `auth.invalid-credentials`. It is the key in the `server` catalog. */
|
|
4433
|
+
var ErrorCodeSchema = zod.z.string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/);
|
|
4434
|
+
zod.z.object({
|
|
4435
|
+
code: ErrorCodeSchema,
|
|
4436
|
+
params: zod.z.record(zod.z.string(), zod.z.union([zod.z.string(), zod.z.number()])).optional()
|
|
4437
|
+
});
|
|
4438
|
+
var CamstackError = class extends Error {
|
|
4439
|
+
i18nCode;
|
|
4440
|
+
i18nParams;
|
|
4441
|
+
constructor(code, params, englishMessage) {
|
|
4442
|
+
super(englishMessage);
|
|
4443
|
+
this.name = "CamstackError";
|
|
4444
|
+
this.i18nCode = code;
|
|
4445
|
+
this.i18nParams = params;
|
|
4446
|
+
}
|
|
4447
|
+
};
|
|
4448
|
+
/** `throw userError('device.not-found', { id }, 'Device 12 not found')` */
|
|
4449
|
+
function userError(code, params, englishFallback) {
|
|
4450
|
+
return new CamstackError(code, params, englishFallback);
|
|
4451
|
+
}
|
|
4452
|
+
/**
|
|
4424
4453
|
* Type-safe JSON parsing helpers.
|
|
4425
4454
|
*
|
|
4426
4455
|
* `JSON.parse` is typed as `any` in lib.es5.d.ts, which triggers
|
|
@@ -4486,7 +4515,7 @@ function sleep(ms) {
|
|
|
4486
4515
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
4487
4516
|
}
|
|
4488
4517
|
//#endregion
|
|
4489
|
-
//#region ../types/dist/err-msg-
|
|
4518
|
+
//#region ../types/dist/err-msg-DLerKiVO.mjs
|
|
4490
4519
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
4491
4520
|
DeviceType["Camera"] = "camera";
|
|
4492
4521
|
DeviceType["Hub"] = "hub";
|
|
@@ -4736,6 +4765,22 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
4736
4765
|
DeviceRole["Nightvision"] = "nightvision";
|
|
4737
4766
|
DeviceRole["PrivacyMask"] = "privacy-mask";
|
|
4738
4767
|
DeviceRole["Doorbell"] = "doorbell";
|
|
4768
|
+
/** Interior blind / shade / roller blind. HA `device_class: blind|shade`. */
|
|
4769
|
+
DeviceRole["CoverBlind"] = "cover-blind";
|
|
4770
|
+
/** Exterior roller shutter. HA `device_class: shutter`; Homematic BROLL. */
|
|
4771
|
+
DeviceRole["CoverShutter"] = "cover-shutter";
|
|
4772
|
+
/** Exterior awning. HA `device_class: awning`. */
|
|
4773
|
+
DeviceRole["CoverAwning"] = "cover-awning";
|
|
4774
|
+
/** Curtain / drape. HA `device_class: curtain`. */
|
|
4775
|
+
DeviceRole["CoverCurtain"] = "cover-curtain";
|
|
4776
|
+
/** Garage door. HA `device_class: garage`. A security actuator: exports gate it. */
|
|
4777
|
+
DeviceRole["CoverGarage"] = "cover-garage";
|
|
4778
|
+
/** Gate. HA `device_class: gate`. A security actuator: exports gate it. */
|
|
4779
|
+
DeviceRole["CoverGate"] = "cover-gate";
|
|
4780
|
+
/** Door. HA `device_class: door`. A security actuator: exports gate it. */
|
|
4781
|
+
DeviceRole["CoverDoor"] = "cover-door";
|
|
4782
|
+
/** Window. HA `device_class: window`. */
|
|
4783
|
+
DeviceRole["CoverWindow"] = "cover-window";
|
|
4739
4784
|
/** Virtual HA toggle (input_boolean.*) — distinguishable from a
|
|
4740
4785
|
* real Switch device for UI rendering / export adapters. */
|
|
4741
4786
|
DeviceRole["BinaryHelper"] = "binary-helper";
|
|
@@ -4816,7 +4861,7 @@ function errMsg(err) {
|
|
|
4816
4861
|
return String(err);
|
|
4817
4862
|
}
|
|
4818
4863
|
//#endregion
|
|
4819
|
-
//#region ../types/dist/composition-
|
|
4864
|
+
//#region ../types/dist/composition-EQ9Ok0Ee.mjs
|
|
4820
4865
|
var AUDIO_ENCODER_BY_CODEC = {
|
|
4821
4866
|
opus: "libopus",
|
|
4822
4867
|
aac: "aac",
|
|
@@ -9276,11 +9321,10 @@ var ClipModelMetaSchema = zod.z.object({
|
|
|
9276
9321
|
/**
|
|
9277
9322
|
* The `vector-store` index this model's vectors live in. ONE feature space
|
|
9278
9323
|
* per index: two models share an index only when their vectors are ranked
|
|
9279
|
-
* against each other, which for CLIP means never across families.
|
|
9280
|
-
*
|
|
9281
|
-
* `modelId`); any other model gets its own.
|
|
9324
|
+
* against each other, which for CLIP means never across families. Every
|
|
9325
|
+
* model gets its own.
|
|
9282
9326
|
*/
|
|
9283
|
-
vectorIndex: zod.z.string().regex(/^object-clip
|
|
9327
|
+
vectorIndex: zod.z.string().regex(/^object-clip-[a-z0-9][a-z0-9-]*$/),
|
|
9284
9328
|
/**
|
|
9285
9329
|
* The text encoder's tokenizer, a declared SIBLING file of its onnx. The name
|
|
9286
9330
|
* must be unique per tokenizer: every model's siblings land in ONE flat
|
|
@@ -9769,7 +9813,8 @@ function scopesAllowAddon(scopes, addonId, access) {
|
|
|
9769
9813
|
return scopes.some((s) => s.type === "addon" && s.target === addonId && s.access.includes(access));
|
|
9770
9814
|
}
|
|
9771
9815
|
zod.z.enum(["new-session", "step-up"]);
|
|
9772
|
-
|
|
9816
|
+
/** The languages the hub's app landing pages are written in (D858). */
|
|
9817
|
+
var AppPageLangSchema = zod.z.enum(["en", "it"]);
|
|
9773
9818
|
/** How a native app starts one login method (D858), as `auth.listLoginMethods` reports it. */
|
|
9774
9819
|
var AppLoginPathSchema = zod.z.discriminatedUnion("kind", [zod.z.object({ kind: zod.z.literal("native") }), zod.z.object({
|
|
9775
9820
|
kind: zod.z.literal("browser"),
|
|
@@ -10372,7 +10417,9 @@ var ConfigTabDeclarationSchema = zod.z.object({
|
|
|
10372
10417
|
var ConfigSectionWithValuesSchema = zod.z.object({
|
|
10373
10418
|
id: zod.z.string(),
|
|
10374
10419
|
title: zod.z.string(),
|
|
10420
|
+
titleKey: zod.z.string().optional(),
|
|
10375
10421
|
description: zod.z.string().optional(),
|
|
10422
|
+
descriptionKey: zod.z.string().optional(),
|
|
10376
10423
|
style: zod.z.enum(["card", "accordion"]).optional(),
|
|
10377
10424
|
defaultCollapsed: zod.z.boolean().optional(),
|
|
10378
10425
|
columns: zod.z.union([
|
|
@@ -16216,6 +16263,16 @@ var keychainCapability = {
|
|
|
16216
16263
|
kind: "mutation",
|
|
16217
16264
|
auth: "admin"
|
|
16218
16265
|
}),
|
|
16266
|
+
/**
|
|
16267
|
+
* Delete every value scoped `device/<deviceId>`, whatever its owner (D864).
|
|
16268
|
+
* Reserved to `device-manager`, on the device-removed path: a driver's
|
|
16269
|
+
* device-scoped secret is not anybody's once the device is gone. Answers the
|
|
16270
|
+
* refs removed (never values).
|
|
16271
|
+
*/
|
|
16272
|
+
deleteDeviceScope: method(zod.z.object({ deviceId: zod.z.number().int() }), zod.z.object({ refs: zod.z.array(zod.z.string()).readonly() }), {
|
|
16273
|
+
kind: "mutation",
|
|
16274
|
+
auth: "admin"
|
|
16275
|
+
}),
|
|
16219
16276
|
/** The caller's own refs, metadata only. */
|
|
16220
16277
|
listMeta: method(zod.z.object({}), zod.z.array(KeychainSecretMetaSchema).readonly(), { auth: "admin" }),
|
|
16221
16278
|
/** Whether values can be served — the save path refuses a write while locked. */
|
|
@@ -38220,6 +38277,42 @@ var DeviceRegisterPayloadSchema = zod.z.object({
|
|
|
38220
38277
|
* omits it and the keyword backstop applies. */
|
|
38221
38278
|
secretConfigPaths: zod.z.array(zod.z.string()).optional()
|
|
38222
38279
|
});
|
|
38280
|
+
/** One deleted device, kept by device-manager so an addon that missed the
|
|
38281
|
+
* deletion can still learn of it (D865). Written by the delete path ONLY. */
|
|
38282
|
+
var DeviceTombstoneSchema = zod.z.object({
|
|
38283
|
+
deviceId: zod.z.number().int().positive(),
|
|
38284
|
+
/** Epoch ms the device was deleted. */
|
|
38285
|
+
deletedAt: zod.z.number(),
|
|
38286
|
+
/** The addon that owned the device when it was deleted. */
|
|
38287
|
+
providerAddonId: zod.z.string()
|
|
38288
|
+
});
|
|
38289
|
+
/** How long a tombstone stays readable. Past it, a device that was deleted
|
|
38290
|
+
* and never cleaned is only reachable by the admin "clean data of deleted
|
|
38291
|
+
* devices" action. */
|
|
38292
|
+
var DEVICE_TOMBSTONE_RETENTION_MS = 2160 * 60 * 60 * 1e3;
|
|
38293
|
+
/** Data held for one device that device-manager no longer knows. */
|
|
38294
|
+
var OrphanDeviceDataSchema = zod.z.object({
|
|
38295
|
+
deviceId: zod.z.number().int().positive(),
|
|
38296
|
+
/** Rows/files per store (`<addonId>:<store>`). */
|
|
38297
|
+
stores: zod.z.record(zod.z.string(), zod.z.number().int().nonnegative())
|
|
38298
|
+
});
|
|
38299
|
+
var CleanupDeletedDevicesResultSchema = zod.z.object({
|
|
38300
|
+
/**
|
|
38301
|
+
* `skipped` — the absence check could not be trusted (a device-list read
|
|
38302
|
+
* failed or the two reads disagreed); nothing was listed or deleted.
|
|
38303
|
+
* `dry-run` — `devices` is what a confirmed run would delete.
|
|
38304
|
+
* `cleaned` — `devices` is what was deleted.
|
|
38305
|
+
*/
|
|
38306
|
+
status: zod.z.enum([
|
|
38307
|
+
"skipped",
|
|
38308
|
+
"dry-run",
|
|
38309
|
+
"cleaned"
|
|
38310
|
+
]),
|
|
38311
|
+
reason: zod.z.string().nullable(),
|
|
38312
|
+
devices: zod.z.array(OrphanDeviceDataSchema),
|
|
38313
|
+
/** Implementers that could not be asked (their stores are not in `devices`). */
|
|
38314
|
+
unreachable: zod.z.array(zod.z.string())
|
|
38315
|
+
});
|
|
38223
38316
|
var DeviceRemovePayloadSchema = zod.z.object({ deviceId: zod.z.number() });
|
|
38224
38317
|
var DevicePersistConfigPayloadSchema = zod.z.object({
|
|
38225
38318
|
deviceId: zod.z.number(),
|
|
@@ -38816,6 +38909,27 @@ var deviceManagerCapability = {
|
|
|
38816
38909
|
kind: "mutation",
|
|
38817
38910
|
auth: "admin"
|
|
38818
38911
|
}),
|
|
38912
|
+
/**
|
|
38913
|
+
* The tombstones of devices deleted at or after `sinceMs` (D865). The
|
|
38914
|
+
* reconcile feed of every `device-removal-hook` implementer: an addon that
|
|
38915
|
+
* was down when a device was deleted asks here at start and periodically.
|
|
38916
|
+
* A tombstone exists only for a DELETE — never for a device that is merely
|
|
38917
|
+
* unregistered, offline or whose provider is restarting. Tombstones older
|
|
38918
|
+
* than `DEVICE_TOMBSTONE_RETENTION_MS` are gone.
|
|
38919
|
+
*/
|
|
38920
|
+
listDeletedSince: method(zod.z.object({ sinceMs: zod.z.number() }), zod.z.array(DeviceTombstoneSchema).readonly(), { auth: "admin" }),
|
|
38921
|
+
/**
|
|
38922
|
+
* Admin-triggered clean-up of data that belongs to devices deleted BEFORE
|
|
38923
|
+
* tombstones existed (D865). Asks every `device-removal-hook` implementer
|
|
38924
|
+
* which device ids it holds data for, keeps those absent from the device
|
|
38925
|
+
* list — confirmed by TWO reads of the list, skipped if either fails — and
|
|
38926
|
+
* with `confirm: false` only reports the counts per store. `confirm: true`
|
|
38927
|
+
* deletes. Never runs on its own.
|
|
38928
|
+
*/
|
|
38929
|
+
cleanupDeletedDevicesData: method(zod.z.object({ confirm: zod.z.boolean() }), CleanupDeletedDevicesResultSchema, {
|
|
38930
|
+
kind: "mutation",
|
|
38931
|
+
auth: "admin"
|
|
38932
|
+
}),
|
|
38819
38933
|
/** Cascade-delete every top-level device whose `integrationId` matches.
|
|
38820
38934
|
* Children cascade automatically via the per-parent remove path.
|
|
38821
38935
|
* Idempotent: a device whose `integrationId` was never set never matches.
|
|
@@ -39731,6 +39845,85 @@ var embeddingEncoderCapability = {
|
|
|
39731
39845
|
}
|
|
39732
39846
|
};
|
|
39733
39847
|
/**
|
|
39848
|
+
* `device-removal-hook` — the reliable way an addon learns a device was DELETED,
|
|
39849
|
+
* so it can delete what it keeps for that device (D865).
|
|
39850
|
+
*
|
|
39851
|
+
* ## Why an event was not enough
|
|
39852
|
+
*
|
|
39853
|
+
* `DeviceUnregistered` is telemetry and may be dropped (D8, D11). An addon that
|
|
39854
|
+
* hung its per-device clean-up on it left durable garbage whenever the event was
|
|
39855
|
+
* lost, the addon was down, or it was restarting at that moment — footage,
|
|
39856
|
+
* analytics rows and settings of device 4483 outlived the device. Loss of this
|
|
39857
|
+
* signal corrupts durable state, so it travels by RPC with a recorded fact
|
|
39858
|
+
* behind it (D8: "if loss would corrupt durable state, use RPC plus a reconcile").
|
|
39859
|
+
*
|
|
39860
|
+
* ## The three pieces
|
|
39861
|
+
*
|
|
39862
|
+
* 1. device-manager records a TOMBSTONE per deleted device
|
|
39863
|
+
* (`deviceManager.listDeletedSince`). The tombstone is written by the delete
|
|
39864
|
+
* path only — a device that is unregistered, offline or whose provider is
|
|
39865
|
+
* restarting is NOT deleted and gets none.
|
|
39866
|
+
* 2. After a delete, device-manager calls `onDeviceRemoved` on EVERY provider of
|
|
39867
|
+
* this collection, one by one, with bounded retries, logged.
|
|
39868
|
+
* 3. An implementer that was down asks `deviceManager.listDeletedSince` at start
|
|
39869
|
+
* (and periodically) and runs its own `onDeviceRemoved` for each tombstone it
|
|
39870
|
+
* may have missed. Reconcile is driven by tombstones, never by "the device is
|
|
39871
|
+
* not in the current list": a failed or partial list read must not destroy data.
|
|
39872
|
+
*
|
|
39873
|
+
* ## Contract for an implementer
|
|
39874
|
+
*
|
|
39875
|
+
* - **Idempotent.** It is called again by a retry, by a reconcile and by the
|
|
39876
|
+
* admin cleanup of data that predates tombstones. A device with nothing left
|
|
39877
|
+
* answers zero counts.
|
|
39878
|
+
* - **One key per store** in `counts`, deleted rows/files per store, so the log
|
|
39879
|
+
* line and the admin dry run can say where the data was.
|
|
39880
|
+
* - **Training datasets are NOT device data** and are never deleted by a hook.
|
|
39881
|
+
* - **Per-device SETTINGS are not hooked.** Configuration lives in the standard
|
|
39882
|
+
* per-device store (`ctx.settings.*DeviceStore`), which device-manager clears
|
|
39883
|
+
* for every addon centrally at delete time. This hook is for device DATA
|
|
39884
|
+
* that is not settings: footage, event media, analytics rows, history.
|
|
39885
|
+
* - A provider that cannot tell is allowed to throw; the caller retries it.
|
|
39886
|
+
*
|
|
39887
|
+
* `listDeviceData` is the read side of the admin "Clean data of deleted devices"
|
|
39888
|
+
* action: which device ids this addon holds data for, and how much per store. It
|
|
39889
|
+
* never deletes. device-manager decides which of those ids are absent from the
|
|
39890
|
+
* fleet, from TWO consistent reads of the device list (D49).
|
|
39891
|
+
*/
|
|
39892
|
+
/** What a hook is told about the deletion. */
|
|
39893
|
+
var DeviceRemovedInputSchema = zod.z.object({
|
|
39894
|
+
deviceId: zod.z.number().int().positive(),
|
|
39895
|
+
/** Epoch ms the device was deleted (the tombstone's `deletedAt`). */
|
|
39896
|
+
deletedAt: zod.z.number(),
|
|
39897
|
+
/** The addon that owned the device, as device-manager last knew it. */
|
|
39898
|
+
providerAddonId: zod.z.string()
|
|
39899
|
+
});
|
|
39900
|
+
/** Rows/files/refs deleted, per store this implementer owns. */
|
|
39901
|
+
var DeviceRemovedResultSchema = zod.z.object({ counts: zod.z.record(zod.z.string(), zod.z.number().int().nonnegative()) });
|
|
39902
|
+
/** One (store, device) pair an implementer holds data for. */
|
|
39903
|
+
var DeviceDataEntrySchema = zod.z.object({
|
|
39904
|
+
store: zod.z.string(),
|
|
39905
|
+
deviceId: zod.z.number().int().positive(),
|
|
39906
|
+
/** Rows (or files) held for the device in the store. */
|
|
39907
|
+
count: zod.z.number().int().nonnegative()
|
|
39908
|
+
});
|
|
39909
|
+
var deviceRemovalHookCapability = {
|
|
39910
|
+
name: "device-removal-hook",
|
|
39911
|
+
scope: "system",
|
|
39912
|
+
mode: "collection",
|
|
39913
|
+
internal: true,
|
|
39914
|
+
methods: {
|
|
39915
|
+
/** Delete everything this addon keeps for the deleted device. Idempotent. */
|
|
39916
|
+
onDeviceRemoved: method(DeviceRemovedInputSchema, DeviceRemovedResultSchema, {
|
|
39917
|
+
kind: "mutation",
|
|
39918
|
+
auth: "admin"
|
|
39919
|
+
}),
|
|
39920
|
+
/** Which devices this addon holds data for, per store. Reads only. */
|
|
39921
|
+
listDeviceData: method(zod.z.void(), zod.z.array(DeviceDataEntrySchema).readonly(), { auth: "admin" })
|
|
39922
|
+
},
|
|
39923
|
+
/** In-process only — enumerated through `addons.listCapabilityProviders`. */
|
|
39924
|
+
mount: { kind: "skip" }
|
|
39925
|
+
};
|
|
39926
|
+
/**
|
|
39734
39927
|
* `failure-contribution` — the capability an addon reports its OWN losses
|
|
39735
39928
|
* through, per camera, with the denominator attached. It stores nothing.
|
|
39736
39929
|
*
|
|
@@ -61694,7 +61887,19 @@ var TlsStatusSchema = zod.z.object({
|
|
|
61694
61887
|
sans: zod.z.array(zod.z.string()),
|
|
61695
61888
|
caCertPem: zod.z.string().nullable(),
|
|
61696
61889
|
reissueError: zod.z.string().nullable(),
|
|
61697
|
-
restartRequired: zod.z.boolean()
|
|
61890
|
+
restartRequired: zod.z.boolean(),
|
|
61891
|
+
/** An uploaded certificate is served but no CA is kept for it and it is not publicly signed (D873). */
|
|
61892
|
+
caMissing: zod.z.boolean(),
|
|
61893
|
+
/** Does the hub's own generated CA carry a critical name constraint? `null` while it has none. */
|
|
61894
|
+
localCaConstrained: zod.z.boolean().nullable(),
|
|
61895
|
+
/** ISO time the generated CA was replaced by a constrained one; devices must re-download it. */
|
|
61896
|
+
caReplacedAt: zod.z.string().nullable(),
|
|
61897
|
+
/** The uploaded certificate kept on disk, selectable again after "Revert to generated". */
|
|
61898
|
+
storedUpload: zod.z.object({
|
|
61899
|
+
leafFingerprintSha256: zod.z.string(),
|
|
61900
|
+
validTo: zod.z.string(),
|
|
61901
|
+
hasCa: zod.z.boolean()
|
|
61902
|
+
}).nullable()
|
|
61698
61903
|
});
|
|
61699
61904
|
var localNetworkCapability = {
|
|
61700
61905
|
name: "local-network",
|
|
@@ -61888,7 +62093,10 @@ var localNetworkCapability = {
|
|
|
61888
62093
|
kind: "mutation",
|
|
61889
62094
|
auth: "admin"
|
|
61890
62095
|
}),
|
|
61891
|
-
/**
|
|
62096
|
+
/**
|
|
62097
|
+
* Replace the served material with operator-supplied PEMs. A certificate that does not lead
|
|
62098
|
+
* to a public CA must come with its CA certificate, validated and kept for Download CA (D873).
|
|
62099
|
+
*/
|
|
61892
62100
|
uploadCertificate: method(zod.z.object({
|
|
61893
62101
|
certPem: zod.z.string().min(1),
|
|
61894
62102
|
keyPem: zod.z.string().min(1),
|
|
@@ -61899,7 +62107,14 @@ var localNetworkCapability = {
|
|
|
61899
62107
|
}),
|
|
61900
62108
|
/** The local CA PEM, or empty when there is none to download. */
|
|
61901
62109
|
downloadCa: method(zod.z.void(), zod.z.object({ pem: zod.z.string() })),
|
|
61902
|
-
/**
|
|
62110
|
+
/**
|
|
62111
|
+
* Serve the kept upload again after "Revert to generated" (D873). Refused when none is kept.
|
|
62112
|
+
*/
|
|
62113
|
+
useStoredUploadedCertificate: method(zod.z.void(), TlsStatusSchema, {
|
|
62114
|
+
kind: "mutation",
|
|
62115
|
+
auth: "admin"
|
|
62116
|
+
}),
|
|
62117
|
+
/** Return to the generated local CA. The uploaded certificate stays stored (D873). */
|
|
61903
62118
|
revertToGeneratedCertificate: method(zod.z.void(), TlsStatusSchema, {
|
|
61904
62119
|
kind: "mutation",
|
|
61905
62120
|
auth: "admin"
|
|
@@ -68661,10 +68876,20 @@ var ServerNameInfoSchema = zod.z.object({
|
|
|
68661
68876
|
/** `true` when nobody named the hub: `name` is the machine hostname. */
|
|
68662
68877
|
isDefault: zod.z.boolean()
|
|
68663
68878
|
});
|
|
68664
|
-
/**
|
|
68879
|
+
/** What an unset name shows when the hostname says nothing about the hub. */
|
|
68880
|
+
var SERVER_NAME_FALLBACK = "CamStack";
|
|
68881
|
+
/** A container id: Docker's default hostname (12 hex chars, or the full 64). */
|
|
68882
|
+
var CONTAINER_ID_PATTERN = /^(?:[0-9a-f]{12}|[0-9a-f]{64})$/;
|
|
68883
|
+
/**
|
|
68884
|
+
* The hostname without its domain (`nas.lan.example` becomes `nas`). A hostname
|
|
68885
|
+
* that names nothing (empty, `localhost`, a container id) yields
|
|
68886
|
+
* {@link SERVER_NAME_FALLBACK}.
|
|
68887
|
+
*/
|
|
68665
68888
|
function shortHostname(hostname) {
|
|
68666
68889
|
const first = hostname.trim().split(".")[0] ?? "";
|
|
68667
|
-
|
|
68890
|
+
if (first.length === 0 || first.toLowerCase() === "localhost") return SERVER_NAME_FALLBACK;
|
|
68891
|
+
if (CONTAINER_ID_PATTERN.test(first)) return SERVER_NAME_FALLBACK;
|
|
68892
|
+
return first;
|
|
68668
68893
|
}
|
|
68669
68894
|
/**
|
|
68670
68895
|
* system — system-scoped singleton capability exposing hub-level
|
|
@@ -74790,6 +75015,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
74790
75015
|
addonId: null,
|
|
74791
75016
|
access: "create"
|
|
74792
75017
|
},
|
|
75018
|
+
"deviceManager.cleanupDeletedDevicesData": {
|
|
75019
|
+
capName: "device-manager",
|
|
75020
|
+
capScope: "system",
|
|
75021
|
+
addonId: null,
|
|
75022
|
+
access: "create"
|
|
75023
|
+
},
|
|
74793
75024
|
"deviceManager.createDevice": {
|
|
74794
75025
|
capName: "device-manager",
|
|
74795
75026
|
capScope: "system",
|
|
@@ -74970,6 +75201,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
74970
75201
|
addonId: null,
|
|
74971
75202
|
access: "view"
|
|
74972
75203
|
},
|
|
75204
|
+
"deviceManager.listDeletedSince": {
|
|
75205
|
+
capName: "device-manager",
|
|
75206
|
+
capScope: "system",
|
|
75207
|
+
addonId: null,
|
|
75208
|
+
access: "view"
|
|
75209
|
+
},
|
|
74973
75210
|
"deviceManager.listDeviceIdsByCaps": {
|
|
74974
75211
|
capName: "device-manager",
|
|
74975
75212
|
capScope: "system",
|
|
@@ -75378,6 +75615,18 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
75378
75615
|
addonId: null,
|
|
75379
75616
|
access: "create"
|
|
75380
75617
|
},
|
|
75618
|
+
"deviceRemovalHook.listDeviceData": {
|
|
75619
|
+
capName: "device-removal-hook",
|
|
75620
|
+
capScope: "system",
|
|
75621
|
+
addonId: null,
|
|
75622
|
+
access: "view"
|
|
75623
|
+
},
|
|
75624
|
+
"deviceRemovalHook.onDeviceRemoved": {
|
|
75625
|
+
capName: "device-removal-hook",
|
|
75626
|
+
capScope: "system",
|
|
75627
|
+
addonId: null,
|
|
75628
|
+
access: "create"
|
|
75629
|
+
},
|
|
75381
75630
|
"deviceState.claimFields": {
|
|
75382
75631
|
capName: "device-state",
|
|
75383
75632
|
capScope: "system",
|
|
@@ -75810,6 +76059,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
75810
76059
|
addonId: null,
|
|
75811
76060
|
access: "delete"
|
|
75812
76061
|
},
|
|
76062
|
+
"keychain.deleteDeviceScope": {
|
|
76063
|
+
capName: "keychain",
|
|
76064
|
+
capScope: "system",
|
|
76065
|
+
addonId: null,
|
|
76066
|
+
access: "delete"
|
|
76067
|
+
},
|
|
75813
76068
|
"keychain.getState": {
|
|
75814
76069
|
capName: "keychain",
|
|
75815
76070
|
capScope: "system",
|
|
@@ -76248,6 +76503,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
76248
76503
|
addonId: null,
|
|
76249
76504
|
access: "create"
|
|
76250
76505
|
},
|
|
76506
|
+
"localNetwork.useStoredUploadedCertificate": {
|
|
76507
|
+
capName: "local-network",
|
|
76508
|
+
capScope: "system",
|
|
76509
|
+
addonId: null,
|
|
76510
|
+
access: "create"
|
|
76511
|
+
},
|
|
76251
76512
|
"lockControl.getStatus": {
|
|
76252
76513
|
capName: "lock-control",
|
|
76253
76514
|
capScope: "device",
|
|
@@ -81192,6 +81453,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
|
|
|
81192
81453
|
deviceManagerCapability,
|
|
81193
81454
|
deviceOpsCapability,
|
|
81194
81455
|
deviceProviderCapability,
|
|
81456
|
+
deviceRemovalHookCapability,
|
|
81195
81457
|
deviceStateCapability,
|
|
81196
81458
|
deviceStatusCapability,
|
|
81197
81459
|
doorbellCapability,
|
|
@@ -82085,6 +82347,11 @@ Object.freeze({
|
|
|
82085
82347
|
form: "single",
|
|
82086
82348
|
optional: false
|
|
82087
82349
|
}],
|
|
82350
|
+
"deviceRemovalHook.onDeviceRemoved": [{
|
|
82351
|
+
name: "deviceId",
|
|
82352
|
+
form: "single",
|
|
82353
|
+
optional: false
|
|
82354
|
+
}],
|
|
82088
82355
|
"deviceState.claimFields": [{
|
|
82089
82356
|
name: "deviceId",
|
|
82090
82357
|
form: "single",
|
|
@@ -82274,6 +82541,11 @@ Object.freeze({
|
|
|
82274
82541
|
form: "single",
|
|
82275
82542
|
optional: false
|
|
82276
82543
|
}],
|
|
82544
|
+
"keychain.deleteDeviceScope": [{
|
|
82545
|
+
name: "deviceId",
|
|
82546
|
+
form: "single",
|
|
82547
|
+
optional: false
|
|
82548
|
+
}],
|
|
82277
82549
|
"lawnMowerControl.dock": [{
|
|
82278
82550
|
name: "deviceId",
|
|
82279
82551
|
form: "single",
|
|
@@ -84922,6 +85194,26 @@ new Set([
|
|
|
84922
85194
|
"audio-tools",
|
|
84923
85195
|
"audio-silence"
|
|
84924
85196
|
]);
|
|
85197
|
+
var CATALOG_LANGS = AppPageLangSchema.options;
|
|
85198
|
+
/** One catalog file: flat key to text. A file of any other shape is rejected whole. */
|
|
85199
|
+
var CatalogFileSchema = zod.z.record(zod.z.string().min(1), zod.z.string());
|
|
85200
|
+
/** Fills `{name}` placeholders; an unknown placeholder is left as written. */
|
|
85201
|
+
function interpolate(template, params) {
|
|
85202
|
+
if (params === void 0) return template;
|
|
85203
|
+
return template.replace(/\{(\w+)\}/g, (whole, name) => {
|
|
85204
|
+
const value = params[name];
|
|
85205
|
+
return value === void 0 ? whole : String(value);
|
|
85206
|
+
});
|
|
85207
|
+
}
|
|
85208
|
+
/** Splits `"ns:key"`; `null` when the reference has no namespace. */
|
|
85209
|
+
function splitTranslationRef(ref) {
|
|
85210
|
+
const at = ref.indexOf(":");
|
|
85211
|
+
if (at <= 0 || at === ref.length - 1) return null;
|
|
85212
|
+
return {
|
|
85213
|
+
ns: ref.slice(0, at),
|
|
85214
|
+
key: ref.slice(at + 1)
|
|
85215
|
+
};
|
|
85216
|
+
}
|
|
84925
85217
|
/**
|
|
84926
85218
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
84927
85219
|
*
|
|
@@ -85679,6 +85971,12 @@ Object.defineProperty(exports, "CAP_NAMES_WITH_STATUS", {
|
|
|
85679
85971
|
return CAP_NAMES_WITH_STATUS;
|
|
85680
85972
|
}
|
|
85681
85973
|
});
|
|
85974
|
+
Object.defineProperty(exports, "CATALOG_LANGS", {
|
|
85975
|
+
enumerable: true,
|
|
85976
|
+
get: function() {
|
|
85977
|
+
return CATALOG_LANGS;
|
|
85978
|
+
}
|
|
85979
|
+
});
|
|
85682
85980
|
Object.defineProperty(exports, "COMPOSED_ITEM_FIXED_FIELDS", {
|
|
85683
85981
|
enumerable: true,
|
|
85684
85982
|
get: function() {
|
|
@@ -85715,6 +86013,12 @@ Object.defineProperty(exports, "CalendarPreferencesSchema", {
|
|
|
85715
86013
|
return CalendarPreferencesSchema;
|
|
85716
86014
|
}
|
|
85717
86015
|
});
|
|
86016
|
+
Object.defineProperty(exports, "CatalogFileSchema", {
|
|
86017
|
+
enumerable: true,
|
|
86018
|
+
get: function() {
|
|
86019
|
+
return CatalogFileSchema;
|
|
86020
|
+
}
|
|
86021
|
+
});
|
|
85718
86022
|
Object.defineProperty(exports, "CoreBlockSchema", {
|
|
85719
86023
|
enumerable: true,
|
|
85720
86024
|
get: function() {
|
|
@@ -85799,6 +86103,12 @@ Object.defineProperty(exports, "DEVICE_STATUS_METHOD", {
|
|
|
85799
86103
|
return DEVICE_STATUS_METHOD;
|
|
85800
86104
|
}
|
|
85801
86105
|
});
|
|
86106
|
+
Object.defineProperty(exports, "DEVICE_TOMBSTONE_RETENTION_MS", {
|
|
86107
|
+
enumerable: true,
|
|
86108
|
+
get: function() {
|
|
86109
|
+
return DEVICE_TOMBSTONE_RETENTION_MS;
|
|
86110
|
+
}
|
|
86111
|
+
});
|
|
85802
86112
|
Object.defineProperty(exports, "DeclaredDevices", {
|
|
85803
86113
|
enumerable: true,
|
|
85804
86114
|
get: function() {
|
|
@@ -86465,6 +86775,12 @@ Object.defineProperty(exports, "hydrateSchema", {
|
|
|
86465
86775
|
return hydrateSchema;
|
|
86466
86776
|
}
|
|
86467
86777
|
});
|
|
86778
|
+
Object.defineProperty(exports, "interpolate", {
|
|
86779
|
+
enumerable: true,
|
|
86780
|
+
get: function() {
|
|
86781
|
+
return interpolate;
|
|
86782
|
+
}
|
|
86783
|
+
});
|
|
86468
86784
|
Object.defineProperty(exports, "isAppLinkBase", {
|
|
86469
86785
|
enumerable: true,
|
|
86470
86786
|
get: function() {
|
|
@@ -86879,6 +87195,12 @@ Object.defineProperty(exports, "snapshotCapability", {
|
|
|
86879
87195
|
return snapshotCapability;
|
|
86880
87196
|
}
|
|
86881
87197
|
});
|
|
87198
|
+
Object.defineProperty(exports, "splitTranslationRef", {
|
|
87199
|
+
enumerable: true,
|
|
87200
|
+
get: function() {
|
|
87201
|
+
return splitTranslationRef;
|
|
87202
|
+
}
|
|
87203
|
+
});
|
|
86882
87204
|
Object.defineProperty(exports, "storageCapability", {
|
|
86883
87205
|
enumerable: true,
|
|
86884
87206
|
get: function() {
|
|
@@ -86945,6 +87267,12 @@ Object.defineProperty(exports, "transformSecretWrite", {
|
|
|
86945
87267
|
return transformSecretWrite;
|
|
86946
87268
|
}
|
|
86947
87269
|
});
|
|
87270
|
+
Object.defineProperty(exports, "userError", {
|
|
87271
|
+
enumerable: true,
|
|
87272
|
+
get: function() {
|
|
87273
|
+
return userError;
|
|
87274
|
+
}
|
|
87275
|
+
});
|
|
86948
87276
|
Object.defineProperty(exports, "userManagementCapability", {
|
|
86949
87277
|
enumerable: true,
|
|
86950
87278
|
get: function() {
|