@camstack/system 1.2.349 → 1.2.350
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 +2 -2
- 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.d.ts +8 -0
- package/dist/builtins/alerts/alerts.addon.js +146 -31
- package/dist/builtins/alerts/alerts.addon.mjs +146 -31
- package/dist/builtins/alerts/device-label.d.ts +8 -0
- 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 +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- 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 +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -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 +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/block-type-defs.d.ts +20 -5
- package/dist/builtins/core-blocks/core-blocks.addon.js +171 -26
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +171 -26
- package/dist/builtins/device-manager/device-bindings-store.d.ts +3 -1
- package/dist/builtins/device-manager/device-manager.addon.js +4 -56
- package/dist/builtins/device-manager/device-manager.addon.mjs +4 -56
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-checks.d.ts +7 -0
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +8 -4
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +8 -4
- 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/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.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 +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- 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 +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/{child-cap-dispatch-DiDBYNY4.js → child-cap-dispatch-CYgHiMdj.js} +1 -1
- package/dist/{child-cap-dispatch-Pkx_sEKR.mjs → child-cap-dispatch-zEt3rqy-.mjs} +1 -1
- package/dist/{composition-sources-w_NIID5d.js → composition-sources-DyxH-DLr.js} +1 -1
- package/dist/{composition-sources-DK-hFG7I.mjs → composition-sources-d7zXAC70.mjs} +1 -1
- package/dist/{dist-DvAczrLl.js → dist-DZKm2EOp.js} +94 -3
- package/dist/{dist-C6CPaa8G.mjs → dist-Di0aX2zy.mjs} +94 -3
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{retired-settings-keys-BQYjCJWI.js → retired-settings-keys-BEY9Wjf1.js} +1 -1
- package/dist/{retired-settings-keys-tmMQQ9OH.mjs → retired-settings-keys-jzB4iJpq.mjs} +1 -1
- package/package.json +1 -1
package/dist/addon-runner.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
2
|
-
const require_child_cap_dispatch = require("./child-cap-dispatch-
|
|
2
|
+
const require_child_cap_dispatch = require("./child-cap-dispatch-CYgHiMdj.js");
|
|
3
3
|
const require_custom_action_registry = require("./custom-action-registry-acBY3mHA.js");
|
|
4
4
|
let node_path = require("node:path");
|
|
5
5
|
node_path = require_chunk.__toESM(node_path);
|
|
6
|
+
let node_module = require("node:module");
|
|
6
7
|
let node_url = require("node:url");
|
|
7
8
|
let node_fs = require("node:fs");
|
|
8
9
|
node_fs = require_chunk.__toESM(node_fs);
|
|
9
|
-
let node_module = require("node:module");
|
|
10
10
|
let _camstack_types_addon = require("@camstack/types/addon");
|
|
11
11
|
//#region src/kernel/moleculer/child-addon-call-dispatch.ts
|
|
12
12
|
function isRecord$1(value) {
|
package/dist/addon-runner.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ft as installManifestNativeDeps, H as createUdsLoggerWithControl, It as resolveAddonClass, St as validateProviderRegistrations, Tn as emitHeapDiagnosticReport, U as LocalChildClient, _t as getWorkerNativeCapProvider, bt as setWorkerNativeCapsChangeListener, en as RUNNER_RSS_BUDGET_ENV, f as installManifestSystemDeps, g as createUdsAddonContext, i as killOwnRunnerGroupAfterParentLoss, n as createChildCapDispatch, p as installManifestPythonDeps, pn as startRunnerHeapWatch, u as startRunnerParentDeathWatchdog, vt as getWorkerNativeCapSnapshot } from "./child-cap-dispatch-
|
|
1
|
+
import { Ft as installManifestNativeDeps, H as createUdsLoggerWithControl, It as resolveAddonClass, St as validateProviderRegistrations, Tn as emitHeapDiagnosticReport, U as LocalChildClient, _t as getWorkerNativeCapProvider, bt as setWorkerNativeCapsChangeListener, en as RUNNER_RSS_BUDGET_ENV, f as installManifestSystemDeps, g as createUdsAddonContext, i as killOwnRunnerGroupAfterParentLoss, n as createChildCapDispatch, p as installManifestPythonDeps, pn as startRunnerHeapWatch, u as startRunnerParentDeathWatchdog, vt as getWorkerNativeCapSnapshot } from "./child-cap-dispatch-zEt3rqy-.mjs";
|
|
2
2
|
import { t as CustomActionRegistry } from "./custom-action-registry-B4Cf4O_X.mjs";
|
|
3
3
|
import { register } from "node:module";
|
|
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-DZKm2EOp.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { H as addonPagesCapability, Jn as errMsg, Yn as BaseAddon, br as EventCategory } from "../../dist-
|
|
1
|
+
import { H as addonPagesCapability, Jn as errMsg, Yn as BaseAddon, br as EventCategory } from "../../dist-Di0aX2zy.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
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-DZKm2EOp.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Jn as errMsg, W as addonWidgetsCapability, Yn as BaseAddon, br as EventCategory } from "../../dist-
|
|
1
|
+
import { Jn as errMsg, W as addonWidgetsCapability, Yn as BaseAddon, br as EventCategory } from "../../dist-Di0aX2zy.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -67,6 +67,14 @@ export declare class AlertCenterAddon extends BaseAddon<AlertCenterConfig> {
|
|
|
67
67
|
private handleLivenessFailed;
|
|
68
68
|
/** SystemLivenessRecovered — the invariant holds again; drop the alert. */
|
|
69
69
|
private handleLivenessRecovered;
|
|
70
|
+
/**
|
|
71
|
+
* Stream offline — ONLY `stale-timeout` is an outage. Suspend / destroy /
|
|
72
|
+
* idle dial are deliberate and must not ring the bell (same gate NC uses).
|
|
73
|
+
*/
|
|
74
|
+
private handleStreamOffline;
|
|
75
|
+
/** Stream online after an outage — drop the matching offline card. */
|
|
76
|
+
private handleStreamOnline;
|
|
77
|
+
private resolveDeviceName;
|
|
70
78
|
private buildMessage;
|
|
71
79
|
private emitAlert;
|
|
72
80
|
private updateAlert;
|
|
@@ -3,7 +3,27 @@ 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-DZKm2EOp.js");
|
|
7
|
+
//#region src/builtins/alerts/device-label.ts
|
|
8
|
+
/**
|
|
9
|
+
* Operator-facing device label for alert messages.
|
|
10
|
+
*
|
|
11
|
+
* Prefer a real name; fall back to `Camera <id>` only when nothing else is
|
|
12
|
+
* known. Never prefer the bare id when a name is present — "Camera 618"
|
|
13
|
+
* next to a named "Cucina" is how the Recording-stopped alerts used to read.
|
|
14
|
+
*/
|
|
15
|
+
function deviceLabelFromEventData(data) {
|
|
16
|
+
const name = stringNonEmpty(data["name"]) ?? stringNonEmpty(data["deviceName"]);
|
|
17
|
+
if (name !== void 0) return name;
|
|
18
|
+
const id = data["deviceId"];
|
|
19
|
+
if (typeof id === "number" && Number.isFinite(id)) return `Camera ${String(id)}`;
|
|
20
|
+
if (typeof id === "string" && id.length > 0) return `Camera ${id}`;
|
|
21
|
+
return "unknown device";
|
|
22
|
+
}
|
|
23
|
+
function stringNonEmpty(value) {
|
|
24
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
7
27
|
//#region src/builtins/alerts/prune-policy.ts
|
|
8
28
|
/**
|
|
9
29
|
* Ids older than `cutoffMs`, oldest first.
|
|
@@ -33,6 +53,10 @@ var CATEGORY_MAPPINGS = {
|
|
|
33
53
|
severity: "error",
|
|
34
54
|
titleTemplate: "Addon crashed"
|
|
35
55
|
},
|
|
56
|
+
"addon.runner-failed": {
|
|
57
|
+
severity: "error",
|
|
58
|
+
titleTemplate: "Addon crash loop"
|
|
59
|
+
},
|
|
36
60
|
"addon.error": {
|
|
37
61
|
severity: "error",
|
|
38
62
|
titleTemplate: "Addon error"
|
|
@@ -53,30 +77,26 @@ var CATEGORY_MAPPINGS = {
|
|
|
53
77
|
severity: "error",
|
|
54
78
|
titleTemplate: "Notification failed"
|
|
55
79
|
},
|
|
56
|
-
"agent.online": {
|
|
57
|
-
severity: "info",
|
|
58
|
-
titleTemplate: "Agent connected"
|
|
59
|
-
},
|
|
60
80
|
"agent.offline": {
|
|
61
81
|
severity: "warning",
|
|
62
82
|
titleTemplate: "Agent disconnected"
|
|
63
83
|
},
|
|
64
|
-
"system.boot": {
|
|
65
|
-
severity: "info",
|
|
66
|
-
titleTemplate: "System boot"
|
|
67
|
-
},
|
|
68
84
|
"system.restarting": {
|
|
69
85
|
severity: "warning",
|
|
70
86
|
titleTemplate: "System restarting"
|
|
71
87
|
},
|
|
88
|
+
"system.restart-completed": {
|
|
89
|
+
severity: "info",
|
|
90
|
+
titleTemplate: "Node updated"
|
|
91
|
+
},
|
|
92
|
+
"update.available": {
|
|
93
|
+
severity: "info",
|
|
94
|
+
titleTemplate: "Update available"
|
|
95
|
+
},
|
|
72
96
|
"system.tls-cert-changed": {
|
|
73
97
|
severity: "warning",
|
|
74
98
|
titleTemplate: "TLS certificate changed"
|
|
75
99
|
},
|
|
76
|
-
"device.registered": {
|
|
77
|
-
severity: "info",
|
|
78
|
-
titleTemplate: "Device registered"
|
|
79
|
-
},
|
|
80
100
|
"device.unregistered": {
|
|
81
101
|
severity: "warning",
|
|
82
102
|
titleTemplate: "Device unregistered"
|
|
@@ -101,13 +121,9 @@ var CATEGORY_MAPPINGS = {
|
|
|
101
121
|
severity: "error",
|
|
102
122
|
titleTemplate: "Node liveness"
|
|
103
123
|
},
|
|
104
|
-
"
|
|
105
|
-
severity: "
|
|
106
|
-
titleTemplate: "
|
|
107
|
-
},
|
|
108
|
-
"backup.completed": {
|
|
109
|
-
severity: "info",
|
|
110
|
-
titleTemplate: "Backup completed"
|
|
124
|
+
"stream.offline": {
|
|
125
|
+
severity: "warning",
|
|
126
|
+
titleTemplate: "Stream offline"
|
|
111
127
|
},
|
|
112
128
|
"backup.restored": {
|
|
113
129
|
severity: "info",
|
|
@@ -118,7 +134,17 @@ var CATEGORY_MAPPINGS = {
|
|
|
118
134
|
titleTemplate: "Model download"
|
|
119
135
|
}
|
|
120
136
|
};
|
|
121
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Subscribed for dismiss / merge side-effects only — never mint a card.
|
|
139
|
+
* Must stay in the subscribe set even though they are absent from
|
|
140
|
+
* {@link CATEGORY_MAPPINGS}.
|
|
141
|
+
*/
|
|
142
|
+
var SILENT_TRACKED_CATEGORIES = [
|
|
143
|
+
"addon.load-recovered",
|
|
144
|
+
"system.liveness-recovered",
|
|
145
|
+
"stream.online"
|
|
146
|
+
];
|
|
147
|
+
var TRACKED_CATEGORIES = [...Object.keys(CATEGORY_MAPPINGS), ...SILENT_TRACKED_CATEGORIES];
|
|
122
148
|
/**
|
|
123
149
|
* `[ALERT-CENTER-EVENTS]` — rate limiting. Events that fire thousands of
|
|
124
150
|
* times a minute (flaky cam reconnecting, chatty integration, …) would
|
|
@@ -305,12 +331,26 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
305
331
|
await this.handleLivenessRecovered(event);
|
|
306
332
|
return;
|
|
307
333
|
}
|
|
334
|
+
if (category === require_dist.EventCategory.StreamOffline) {
|
|
335
|
+
await this.handleStreamOffline(event);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
if (category === require_dist.EventCategory.StreamOnline) {
|
|
339
|
+
await this.handleStreamOnline(event);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
308
342
|
const mapping = CATEGORY_MAPPINGS[category];
|
|
309
343
|
if (!mapping) return;
|
|
344
|
+
if (category === "addon.updated") {
|
|
345
|
+
const toVersion = event.data["toVersion"];
|
|
346
|
+
if (typeof toVersion !== "string" || toVersion.length === 0) return;
|
|
347
|
+
}
|
|
310
348
|
if (this.shouldSuppressByRate(category, event)) return;
|
|
311
349
|
const message = this.buildMessage(category, event.data, event.source ? String(event.source.id) : void 0);
|
|
350
|
+
const addonIdForKey = (typeof event.data["addonId"] === "string" ? event.data["addonId"] : void 0) ?? (event.source ? String(event.source.id) : void 0);
|
|
351
|
+
const toVersionForKey = typeof event.data["toVersion"] === "string" ? event.data["toVersion"] : void 0;
|
|
312
352
|
const alert = {
|
|
313
|
-
id: crypto.randomUUID(),
|
|
353
|
+
id: category === "addon.updated" && addonIdForKey !== void 0 && toVersionForKey !== void 0 ? `addon-updated:${addonIdForKey}:${toVersionForKey}` : crypto.randomUUID(),
|
|
314
354
|
category,
|
|
315
355
|
severity: mapping.severity,
|
|
316
356
|
title: mapping.titleTemplate,
|
|
@@ -543,32 +583,107 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
543
583
|
} });
|
|
544
584
|
}
|
|
545
585
|
}
|
|
586
|
+
/**
|
|
587
|
+
* Stream offline — ONLY `stale-timeout` is an outage. Suspend / destroy /
|
|
588
|
+
* idle dial are deliberate and must not ring the bell (same gate NC uses).
|
|
589
|
+
*/
|
|
590
|
+
async handleStreamOffline(event) {
|
|
591
|
+
const reason = event.data["reason"];
|
|
592
|
+
if (reason !== "stale-timeout") return;
|
|
593
|
+
const deviceId = event.data["deviceId"];
|
|
594
|
+
const camStreamId = event.data["camStreamId"];
|
|
595
|
+
if (typeof deviceId !== "number" || typeof camStreamId !== "string") return;
|
|
596
|
+
const name = await this.resolveDeviceName(deviceId);
|
|
597
|
+
const label = name ?? `Camera ${String(deviceId)}`;
|
|
598
|
+
const alert = {
|
|
599
|
+
id: `stream-offline:${String(deviceId)}:${camStreamId}`,
|
|
600
|
+
category: require_dist.EventCategory.StreamOffline,
|
|
601
|
+
severity: "warning",
|
|
602
|
+
title: "Stream offline",
|
|
603
|
+
message: `${label} — ${camStreamId} stopped sending video (stale timeout).`,
|
|
604
|
+
status: "active",
|
|
605
|
+
read: false,
|
|
606
|
+
createdAt: Date.now(),
|
|
607
|
+
updatedAt: Date.now(),
|
|
608
|
+
source: {
|
|
609
|
+
type: "device",
|
|
610
|
+
id: String(deviceId)
|
|
611
|
+
},
|
|
612
|
+
metadata: {
|
|
613
|
+
deviceId,
|
|
614
|
+
camStreamId,
|
|
615
|
+
reason,
|
|
616
|
+
...name !== void 0 ? { name } : {}
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
await this.emitAlert(alert);
|
|
620
|
+
}
|
|
621
|
+
/** Stream online after an outage — drop the matching offline card. */
|
|
622
|
+
async handleStreamOnline(event) {
|
|
623
|
+
const deviceId = event.data["deviceId"];
|
|
624
|
+
const camStreamId = event.data["camStreamId"];
|
|
625
|
+
if (typeof deviceId !== "number" || typeof camStreamId !== "string") return;
|
|
626
|
+
const stableId = `stream-offline:${String(deviceId)}:${camStreamId}`;
|
|
627
|
+
try {
|
|
628
|
+
await this.dismiss(stableId);
|
|
629
|
+
} catch (err) {
|
|
630
|
+
this.ctx.logger?.debug("StreamOnline: dismiss failed (likely already dismissed)", { meta: {
|
|
631
|
+
stableId,
|
|
632
|
+
error: require_dist.errMsg(err)
|
|
633
|
+
} });
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
async resolveDeviceName(deviceId) {
|
|
637
|
+
try {
|
|
638
|
+
const device = await this.ctx.api.deviceManager.getDevice.query({ deviceId });
|
|
639
|
+
if (device !== null && typeof device.name === "string" && device.name.trim().length > 0) return device.name.trim();
|
|
640
|
+
} catch (err) {
|
|
641
|
+
this.ctx.logger?.debug("resolveDeviceName failed", {
|
|
642
|
+
tags: { deviceId },
|
|
643
|
+
meta: { error: require_dist.errMsg(err) }
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
}
|
|
546
647
|
buildMessage(category, data, sourceId) {
|
|
547
648
|
const addonId = data.addonId ?? sourceId;
|
|
548
|
-
const
|
|
649
|
+
const device = deviceLabelFromEventData(data);
|
|
549
650
|
const error = data.error;
|
|
550
651
|
const processId = data.processId;
|
|
551
652
|
switch (category) {
|
|
552
653
|
case "addon.crashed": return `Addon "${addonId ?? "unknown"}" crashed${error ? `: ${error}` : ""}`;
|
|
654
|
+
case "addon.runner-failed": {
|
|
655
|
+
const runnerId = typeof data.runnerId === "string" ? data.runnerId : "unknown";
|
|
656
|
+
const addonIds = Array.isArray(data.addonIds) ? data.addonIds.filter((x) => typeof x === "string").join(", ") : "";
|
|
657
|
+
return `Runner "${runnerId}" gave up${addonIds.length > 0 ? ` (addons: ${addonIds})` : ""}`;
|
|
658
|
+
}
|
|
553
659
|
case "addon.error": return `Addon "${addonId ?? "unknown"}" error${error ? `: ${error}` : ""}`;
|
|
554
660
|
case "addon.installed": return `Addon "${addonId ?? "unknown"}" installed`;
|
|
555
661
|
case "addon.updated": {
|
|
556
662
|
const from = data.fromVersion;
|
|
557
663
|
const to = data.toVersion;
|
|
558
|
-
return `Addon "${addonId ?? "unknown"}" updated${from && to ? ` from ${from} to ${to}` : ""}`;
|
|
664
|
+
return `Addon "${typeof data.packageName === "string" && data.packageName.length > 0 ? data.packageName : addonId ?? "unknown"}" updated${from && to ? ` from ${from} to ${to}` : to ? ` to ${to}` : ""}`;
|
|
559
665
|
}
|
|
560
666
|
case "addon.uninstalled": return `Addon "${addonId ?? "unknown"}" uninstalled`;
|
|
561
|
-
case "device.
|
|
562
|
-
case "device.unregistered": return `Device "${deviceId ?? "unknown"}" unregistered`;
|
|
563
|
-
case "agent.online": return `Agent "${data.agentId ?? data.nodeId ?? "unknown"}" connected`;
|
|
667
|
+
case "device.unregistered": return `Device "${device}" unregistered`;
|
|
564
668
|
case "agent.offline": return `Agent "${data.agentId ?? data.nodeId ?? "unknown"}" disconnected${data.reason ? `: ${String(data.reason)}` : ""}`;
|
|
565
|
-
case "backup.completed": return `Backup completed${data.targetId ? ` (${String(data.targetId)})` : ""}`;
|
|
566
669
|
case "backup.restored": return `Backup restored${data.source ? ` from ${String(data.source)}` : ""}`;
|
|
567
670
|
case "notification.failed": return `Notification failed${error ? `: ${error}` : ""}`;
|
|
568
671
|
case "system.restarting": return `System restarting${data.reason ? ` — ${String(data.reason)}` : ""}`;
|
|
569
|
-
case "
|
|
570
|
-
|
|
571
|
-
|
|
672
|
+
case "system.restart-completed": {
|
|
673
|
+
const pkg = typeof data.packageName === "string" ? data.packageName : void 0;
|
|
674
|
+
const to = typeof data.toVersion === "string" ? data.toVersion : void 0;
|
|
675
|
+
const kind = typeof data.kind === "string" ? data.kind : "restart";
|
|
676
|
+
if (pkg !== void 0 && to !== void 0) return `${pkg} is now ${to}`;
|
|
677
|
+
return `Node restart completed (${kind})`;
|
|
678
|
+
}
|
|
679
|
+
case "update.available": {
|
|
680
|
+
const pkg = typeof data.packageName === "string" ? data.packageName : "package";
|
|
681
|
+
const latest = typeof data.latestVersion === "string" ? data.latestVersion : "?";
|
|
682
|
+
const node = typeof data.nodeId === "string" ? data.nodeId : void 0;
|
|
683
|
+
return `${pkg} ${latest} available${node !== void 0 ? ` on ${node}` : ""}`;
|
|
684
|
+
}
|
|
685
|
+
case "recording.error": return `Recording error on "${device}"${error ? `: ${error}` : ""}`;
|
|
686
|
+
case "recording.storage.critical": return `Storage critical for "${device}"`;
|
|
572
687
|
case "system.tls-cert-changed": return data.caRotated === true ? `TLS certificate reissued (${String(data.reason)}) — the local CA also changed. Re-install ${String(data.caCertPath)} on any device that trusted the old one.` : `TLS certificate reissued (${String(data.reason)}) — the local CA is unchanged, previously trusted devices keep working.`;
|
|
573
688
|
case "process.crashed": return `Process "${processId ?? "unknown"}" crashed`;
|
|
574
689
|
default: return `Event: ${category}`;
|
|
@@ -1,4 +1,24 @@
|
|
|
1
|
-
import { G as alertsCapability, Jn as errMsg, Yn as BaseAddon, ar as createEvent, br as EventCategory, n as AlertSchema } from "../../dist-
|
|
1
|
+
import { G as alertsCapability, Jn as errMsg, Yn as BaseAddon, ar as createEvent, br as EventCategory, n as AlertSchema } from "../../dist-Di0aX2zy.mjs";
|
|
2
|
+
//#region src/builtins/alerts/device-label.ts
|
|
3
|
+
/**
|
|
4
|
+
* Operator-facing device label for alert messages.
|
|
5
|
+
*
|
|
6
|
+
* Prefer a real name; fall back to `Camera <id>` only when nothing else is
|
|
7
|
+
* known. Never prefer the bare id when a name is present — "Camera 618"
|
|
8
|
+
* next to a named "Cucina" is how the Recording-stopped alerts used to read.
|
|
9
|
+
*/
|
|
10
|
+
function deviceLabelFromEventData(data) {
|
|
11
|
+
const name = stringNonEmpty(data["name"]) ?? stringNonEmpty(data["deviceName"]);
|
|
12
|
+
if (name !== void 0) return name;
|
|
13
|
+
const id = data["deviceId"];
|
|
14
|
+
if (typeof id === "number" && Number.isFinite(id)) return `Camera ${String(id)}`;
|
|
15
|
+
if (typeof id === "string" && id.length > 0) return `Camera ${id}`;
|
|
16
|
+
return "unknown device";
|
|
17
|
+
}
|
|
18
|
+
function stringNonEmpty(value) {
|
|
19
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
2
22
|
//#region src/builtins/alerts/prune-policy.ts
|
|
3
23
|
/**
|
|
4
24
|
* Ids older than `cutoffMs`, oldest first.
|
|
@@ -28,6 +48,10 @@ var CATEGORY_MAPPINGS = {
|
|
|
28
48
|
severity: "error",
|
|
29
49
|
titleTemplate: "Addon crashed"
|
|
30
50
|
},
|
|
51
|
+
"addon.runner-failed": {
|
|
52
|
+
severity: "error",
|
|
53
|
+
titleTemplate: "Addon crash loop"
|
|
54
|
+
},
|
|
31
55
|
"addon.error": {
|
|
32
56
|
severity: "error",
|
|
33
57
|
titleTemplate: "Addon error"
|
|
@@ -48,30 +72,26 @@ var CATEGORY_MAPPINGS = {
|
|
|
48
72
|
severity: "error",
|
|
49
73
|
titleTemplate: "Notification failed"
|
|
50
74
|
},
|
|
51
|
-
"agent.online": {
|
|
52
|
-
severity: "info",
|
|
53
|
-
titleTemplate: "Agent connected"
|
|
54
|
-
},
|
|
55
75
|
"agent.offline": {
|
|
56
76
|
severity: "warning",
|
|
57
77
|
titleTemplate: "Agent disconnected"
|
|
58
78
|
},
|
|
59
|
-
"system.boot": {
|
|
60
|
-
severity: "info",
|
|
61
|
-
titleTemplate: "System boot"
|
|
62
|
-
},
|
|
63
79
|
"system.restarting": {
|
|
64
80
|
severity: "warning",
|
|
65
81
|
titleTemplate: "System restarting"
|
|
66
82
|
},
|
|
83
|
+
"system.restart-completed": {
|
|
84
|
+
severity: "info",
|
|
85
|
+
titleTemplate: "Node updated"
|
|
86
|
+
},
|
|
87
|
+
"update.available": {
|
|
88
|
+
severity: "info",
|
|
89
|
+
titleTemplate: "Update available"
|
|
90
|
+
},
|
|
67
91
|
"system.tls-cert-changed": {
|
|
68
92
|
severity: "warning",
|
|
69
93
|
titleTemplate: "TLS certificate changed"
|
|
70
94
|
},
|
|
71
|
-
"device.registered": {
|
|
72
|
-
severity: "info",
|
|
73
|
-
titleTemplate: "Device registered"
|
|
74
|
-
},
|
|
75
95
|
"device.unregistered": {
|
|
76
96
|
severity: "warning",
|
|
77
97
|
titleTemplate: "Device unregistered"
|
|
@@ -96,13 +116,9 @@ var CATEGORY_MAPPINGS = {
|
|
|
96
116
|
severity: "error",
|
|
97
117
|
titleTemplate: "Node liveness"
|
|
98
118
|
},
|
|
99
|
-
"
|
|
100
|
-
severity: "
|
|
101
|
-
titleTemplate: "
|
|
102
|
-
},
|
|
103
|
-
"backup.completed": {
|
|
104
|
-
severity: "info",
|
|
105
|
-
titleTemplate: "Backup completed"
|
|
119
|
+
"stream.offline": {
|
|
120
|
+
severity: "warning",
|
|
121
|
+
titleTemplate: "Stream offline"
|
|
106
122
|
},
|
|
107
123
|
"backup.restored": {
|
|
108
124
|
severity: "info",
|
|
@@ -113,7 +129,17 @@ var CATEGORY_MAPPINGS = {
|
|
|
113
129
|
titleTemplate: "Model download"
|
|
114
130
|
}
|
|
115
131
|
};
|
|
116
|
-
|
|
132
|
+
/**
|
|
133
|
+
* Subscribed for dismiss / merge side-effects only — never mint a card.
|
|
134
|
+
* Must stay in the subscribe set even though they are absent from
|
|
135
|
+
* {@link CATEGORY_MAPPINGS}.
|
|
136
|
+
*/
|
|
137
|
+
var SILENT_TRACKED_CATEGORIES = [
|
|
138
|
+
"addon.load-recovered",
|
|
139
|
+
"system.liveness-recovered",
|
|
140
|
+
"stream.online"
|
|
141
|
+
];
|
|
142
|
+
var TRACKED_CATEGORIES = [...Object.keys(CATEGORY_MAPPINGS), ...SILENT_TRACKED_CATEGORIES];
|
|
117
143
|
/**
|
|
118
144
|
* `[ALERT-CENTER-EVENTS]` — rate limiting. Events that fire thousands of
|
|
119
145
|
* times a minute (flaky cam reconnecting, chatty integration, …) would
|
|
@@ -300,12 +326,26 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
300
326
|
await this.handleLivenessRecovered(event);
|
|
301
327
|
return;
|
|
302
328
|
}
|
|
329
|
+
if (category === EventCategory.StreamOffline) {
|
|
330
|
+
await this.handleStreamOffline(event);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
if (category === EventCategory.StreamOnline) {
|
|
334
|
+
await this.handleStreamOnline(event);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
303
337
|
const mapping = CATEGORY_MAPPINGS[category];
|
|
304
338
|
if (!mapping) return;
|
|
339
|
+
if (category === "addon.updated") {
|
|
340
|
+
const toVersion = event.data["toVersion"];
|
|
341
|
+
if (typeof toVersion !== "string" || toVersion.length === 0) return;
|
|
342
|
+
}
|
|
305
343
|
if (this.shouldSuppressByRate(category, event)) return;
|
|
306
344
|
const message = this.buildMessage(category, event.data, event.source ? String(event.source.id) : void 0);
|
|
345
|
+
const addonIdForKey = (typeof event.data["addonId"] === "string" ? event.data["addonId"] : void 0) ?? (event.source ? String(event.source.id) : void 0);
|
|
346
|
+
const toVersionForKey = typeof event.data["toVersion"] === "string" ? event.data["toVersion"] : void 0;
|
|
307
347
|
const alert = {
|
|
308
|
-
id: crypto.randomUUID(),
|
|
348
|
+
id: category === "addon.updated" && addonIdForKey !== void 0 && toVersionForKey !== void 0 ? `addon-updated:${addonIdForKey}:${toVersionForKey}` : crypto.randomUUID(),
|
|
309
349
|
category,
|
|
310
350
|
severity: mapping.severity,
|
|
311
351
|
title: mapping.titleTemplate,
|
|
@@ -538,32 +578,107 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
538
578
|
} });
|
|
539
579
|
}
|
|
540
580
|
}
|
|
581
|
+
/**
|
|
582
|
+
* Stream offline — ONLY `stale-timeout` is an outage. Suspend / destroy /
|
|
583
|
+
* idle dial are deliberate and must not ring the bell (same gate NC uses).
|
|
584
|
+
*/
|
|
585
|
+
async handleStreamOffline(event) {
|
|
586
|
+
const reason = event.data["reason"];
|
|
587
|
+
if (reason !== "stale-timeout") return;
|
|
588
|
+
const deviceId = event.data["deviceId"];
|
|
589
|
+
const camStreamId = event.data["camStreamId"];
|
|
590
|
+
if (typeof deviceId !== "number" || typeof camStreamId !== "string") return;
|
|
591
|
+
const name = await this.resolveDeviceName(deviceId);
|
|
592
|
+
const label = name ?? `Camera ${String(deviceId)}`;
|
|
593
|
+
const alert = {
|
|
594
|
+
id: `stream-offline:${String(deviceId)}:${camStreamId}`,
|
|
595
|
+
category: EventCategory.StreamOffline,
|
|
596
|
+
severity: "warning",
|
|
597
|
+
title: "Stream offline",
|
|
598
|
+
message: `${label} — ${camStreamId} stopped sending video (stale timeout).`,
|
|
599
|
+
status: "active",
|
|
600
|
+
read: false,
|
|
601
|
+
createdAt: Date.now(),
|
|
602
|
+
updatedAt: Date.now(),
|
|
603
|
+
source: {
|
|
604
|
+
type: "device",
|
|
605
|
+
id: String(deviceId)
|
|
606
|
+
},
|
|
607
|
+
metadata: {
|
|
608
|
+
deviceId,
|
|
609
|
+
camStreamId,
|
|
610
|
+
reason,
|
|
611
|
+
...name !== void 0 ? { name } : {}
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
await this.emitAlert(alert);
|
|
615
|
+
}
|
|
616
|
+
/** Stream online after an outage — drop the matching offline card. */
|
|
617
|
+
async handleStreamOnline(event) {
|
|
618
|
+
const deviceId = event.data["deviceId"];
|
|
619
|
+
const camStreamId = event.data["camStreamId"];
|
|
620
|
+
if (typeof deviceId !== "number" || typeof camStreamId !== "string") return;
|
|
621
|
+
const stableId = `stream-offline:${String(deviceId)}:${camStreamId}`;
|
|
622
|
+
try {
|
|
623
|
+
await this.dismiss(stableId);
|
|
624
|
+
} catch (err) {
|
|
625
|
+
this.ctx.logger?.debug("StreamOnline: dismiss failed (likely already dismissed)", { meta: {
|
|
626
|
+
stableId,
|
|
627
|
+
error: errMsg(err)
|
|
628
|
+
} });
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
async resolveDeviceName(deviceId) {
|
|
632
|
+
try {
|
|
633
|
+
const device = await this.ctx.api.deviceManager.getDevice.query({ deviceId });
|
|
634
|
+
if (device !== null && typeof device.name === "string" && device.name.trim().length > 0) return device.name.trim();
|
|
635
|
+
} catch (err) {
|
|
636
|
+
this.ctx.logger?.debug("resolveDeviceName failed", {
|
|
637
|
+
tags: { deviceId },
|
|
638
|
+
meta: { error: errMsg(err) }
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
}
|
|
541
642
|
buildMessage(category, data, sourceId) {
|
|
542
643
|
const addonId = data.addonId ?? sourceId;
|
|
543
|
-
const
|
|
644
|
+
const device = deviceLabelFromEventData(data);
|
|
544
645
|
const error = data.error;
|
|
545
646
|
const processId = data.processId;
|
|
546
647
|
switch (category) {
|
|
547
648
|
case "addon.crashed": return `Addon "${addonId ?? "unknown"}" crashed${error ? `: ${error}` : ""}`;
|
|
649
|
+
case "addon.runner-failed": {
|
|
650
|
+
const runnerId = typeof data.runnerId === "string" ? data.runnerId : "unknown";
|
|
651
|
+
const addonIds = Array.isArray(data.addonIds) ? data.addonIds.filter((x) => typeof x === "string").join(", ") : "";
|
|
652
|
+
return `Runner "${runnerId}" gave up${addonIds.length > 0 ? ` (addons: ${addonIds})` : ""}`;
|
|
653
|
+
}
|
|
548
654
|
case "addon.error": return `Addon "${addonId ?? "unknown"}" error${error ? `: ${error}` : ""}`;
|
|
549
655
|
case "addon.installed": return `Addon "${addonId ?? "unknown"}" installed`;
|
|
550
656
|
case "addon.updated": {
|
|
551
657
|
const from = data.fromVersion;
|
|
552
658
|
const to = data.toVersion;
|
|
553
|
-
return `Addon "${addonId ?? "unknown"}" updated${from && to ? ` from ${from} to ${to}` : ""}`;
|
|
659
|
+
return `Addon "${typeof data.packageName === "string" && data.packageName.length > 0 ? data.packageName : addonId ?? "unknown"}" updated${from && to ? ` from ${from} to ${to}` : to ? ` to ${to}` : ""}`;
|
|
554
660
|
}
|
|
555
661
|
case "addon.uninstalled": return `Addon "${addonId ?? "unknown"}" uninstalled`;
|
|
556
|
-
case "device.
|
|
557
|
-
case "device.unregistered": return `Device "${deviceId ?? "unknown"}" unregistered`;
|
|
558
|
-
case "agent.online": return `Agent "${data.agentId ?? data.nodeId ?? "unknown"}" connected`;
|
|
662
|
+
case "device.unregistered": return `Device "${device}" unregistered`;
|
|
559
663
|
case "agent.offline": return `Agent "${data.agentId ?? data.nodeId ?? "unknown"}" disconnected${data.reason ? `: ${String(data.reason)}` : ""}`;
|
|
560
|
-
case "backup.completed": return `Backup completed${data.targetId ? ` (${String(data.targetId)})` : ""}`;
|
|
561
664
|
case "backup.restored": return `Backup restored${data.source ? ` from ${String(data.source)}` : ""}`;
|
|
562
665
|
case "notification.failed": return `Notification failed${error ? `: ${error}` : ""}`;
|
|
563
666
|
case "system.restarting": return `System restarting${data.reason ? ` — ${String(data.reason)}` : ""}`;
|
|
564
|
-
case "
|
|
565
|
-
|
|
566
|
-
|
|
667
|
+
case "system.restart-completed": {
|
|
668
|
+
const pkg = typeof data.packageName === "string" ? data.packageName : void 0;
|
|
669
|
+
const to = typeof data.toVersion === "string" ? data.toVersion : void 0;
|
|
670
|
+
const kind = typeof data.kind === "string" ? data.kind : "restart";
|
|
671
|
+
if (pkg !== void 0 && to !== void 0) return `${pkg} is now ${to}`;
|
|
672
|
+
return `Node restart completed (${kind})`;
|
|
673
|
+
}
|
|
674
|
+
case "update.available": {
|
|
675
|
+
const pkg = typeof data.packageName === "string" ? data.packageName : "package";
|
|
676
|
+
const latest = typeof data.latestVersion === "string" ? data.latestVersion : "?";
|
|
677
|
+
const node = typeof data.nodeId === "string" ? data.nodeId : void 0;
|
|
678
|
+
return `${pkg} ${latest} available${node !== void 0 ? ` on ${node}` : ""}`;
|
|
679
|
+
}
|
|
680
|
+
case "recording.error": return `Recording error on "${device}"${error ? `: ${error}` : ""}`;
|
|
681
|
+
case "recording.storage.critical": return `Storage critical for "${device}"`;
|
|
567
682
|
case "system.tls-cert-changed": return data.caRotated === true ? `TLS certificate reissued (${String(data.reason)}) — the local CA also changed. Re-install ${String(data.caCertPath)} on any device that trusted the old one.` : `TLS certificate reissued (${String(data.reason)}) — the local CA is unchanged, previously trusted devices keep working.`;
|
|
568
683
|
case "process.crashed": return `Process "${processId ?? "unknown"}" crashed`;
|
|
569
684
|
default: return `Event: ${category}`;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator-facing device label for alert messages.
|
|
3
|
+
*
|
|
4
|
+
* Prefer a real name; fall back to `Camera <id>` only when nothing else is
|
|
5
|
+
* known. Never prefer the bare id when a name is present — "Camera 618"
|
|
6
|
+
* next to a named "Cucina" is how the Recording-stopped alerts used to read.
|
|
7
|
+
*/
|
|
8
|
+
export declare function deviceLabelFromEventData(data: Readonly<Record<string, unknown>>): string;
|
|
@@ -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-DZKm2EOp.js");
|
|
7
7
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
8
8
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
9
9
|
deadZoneFraction: .5,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { J as bareAddonId, Jn as errMsg, Yn as BaseAddon, br as EventCategory, dr as isEvent, on as ptzAutotrackCapability, x as FIRST_LEVEL_MACRO_CLASSES } from "../../dist-
|
|
1
|
+
import { J as bareAddonId, Jn as errMsg, Yn as BaseAddon, br as EventCategory, dr as isEvent, on as ptzAutotrackCapability, x as FIRST_LEVEL_MACRO_CLASSES } from "../../dist-Di0aX2zy.mjs";
|
|
2
2
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
3
3
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
4
4
|
deadZoneFraction: .5,
|
|
@@ -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-DZKm2EOp.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let buffer = require("buffer");
|
|
9
9
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Cn as storageOccupancyCapability, Yn as BaseAddon, br as EventCategory, fr as nodePin, h as DATABASE_SNAPSHOT_SUFFIX, q as backupCapability, qt as mayWriteToLocation, yr as toNodeId } from "../../dist-
|
|
1
|
+
import { Cn as storageOccupancyCapability, Yn as BaseAddon, br as EventCategory, fr as nodePin, h as DATABASE_SNAPSHOT_SUFFIX, q as backupCapability, qt as mayWriteToLocation, yr as toNodeId } from "../../dist-Di0aX2zy.mjs";
|
|
2
2
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
3
|
import { Buffer as Buffer$1 } from "buffer";
|
|
4
4
|
import * as fsp from "node:fs/promises";
|
|
@@ -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-DZKm2EOp.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
//#region src/builtins/calendars/calendar-color.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Q as calendarsCapability, Yn as BaseAddon, f as CalendarPreferencesSchema } from "../../dist-
|
|
1
|
+
import { Q as calendarsCapability, Yn as BaseAddon, f as CalendarPreferencesSchema } from "../../dist-Di0aX2zy.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region src/builtins/calendars/calendar-color.ts
|