@camstack/types 1.2.304 → 1.2.305
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/capabilities/device-admin-link-url.d.ts +2 -2
- package/dist/capabilities/device-admin-link.cap.d.ts +1 -1
- package/dist/capabilities/index.d.ts +8 -7
- package/dist/capabilities/local-network.cap.d.ts +18 -8
- package/dist/capabilities/notification-rules.cap.d.ts +34 -2
- package/dist/capabilities/pipeline-runner.cap.d.ts +54 -0
- package/dist/capabilities/viewer-link-url.d.ts +104 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +272 -34
- package/dist/index.mjs +262 -35
- package/dist/interfaces/event-bus.d.ts +23 -0
- package/dist/interfaces/pipeline-runner-capability.d.ts +6 -0
- package/dist/notification/alarm-settings.d.ts +25 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12460,7 +12460,7 @@ var detectionPipelineCapability = {
|
|
|
12460
12460
|
* This matters here more than anywhere else in the repo, because every provider
|
|
12461
12461
|
* that knows a device's host knows its PASSWORD too: `{ host, port, username,
|
|
12462
12462
|
* password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
|
|
12463
|
-
* and `http://admin:hunter2@192.168.
|
|
12463
|
+
* and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
|
|
12464
12464
|
* camera's own page will ask for its own login. That is correct, and pre-
|
|
12465
12465
|
* filling it is the operator's business, not ours.
|
|
12466
12466
|
*
|
|
@@ -20504,8 +20504,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
20504
20504
|
disabledTargetIds: zod.z.array(zod.z.string()).default([])
|
|
20505
20505
|
});
|
|
20506
20506
|
/**
|
|
20507
|
-
* The state-summary SECTIONS (D647 / D698): the D637 kind groups that
|
|
20508
|
-
* still-true state. `
|
|
20507
|
+
* The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
|
|
20508
|
+
* report a still-true state. `addons` is the crash-looped addons only and
|
|
20509
|
+
* `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
|
|
20509
20510
|
* job is not an open state, and the alarm stays instant.
|
|
20510
20511
|
*/
|
|
20511
20512
|
var NcStateSummarySectionIdSchema = zod.z.enum([
|
|
@@ -20517,6 +20518,7 @@ var NcStateSummarySectionIdSchema = zod.z.enum([
|
|
|
20517
20518
|
"detection-blind",
|
|
20518
20519
|
"nodes",
|
|
20519
20520
|
"addons",
|
|
20521
|
+
"addon-updates",
|
|
20520
20522
|
"updates"
|
|
20521
20523
|
]);
|
|
20522
20524
|
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
@@ -21555,7 +21557,19 @@ var NcAlarmModeDelaysSchema = zod.z.object({
|
|
|
21555
21557
|
* When this mode may be armed. Absent / null = always allowed (same as a
|
|
21556
21558
|
* rule with no `schedule`). Evaluated with {@link isScheduleActive}.
|
|
21557
21559
|
*/
|
|
21558
|
-
schedule: NcScheduleSchema.optional()
|
|
21560
|
+
schedule: NcScheduleSchema.optional(),
|
|
21561
|
+
/**
|
|
21562
|
+
* D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
|
|
21563
|
+
* intrusion naming the locations)? Absent = false — the entry-delay notification is the
|
|
21564
|
+
* only one, and the matches ride the triggered notification's mosaic (D705).
|
|
21565
|
+
*/
|
|
21566
|
+
notifyDuringEntryDelay: zod.z.boolean().optional(),
|
|
21567
|
+
/**
|
|
21568
|
+
* D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
|
|
21569
|
+
* Absent = false (logged, not sent). Even when true it is not sent when that same sensor
|
|
21570
|
+
* is the one that starts the entry delay — the entry-delay notification already names it.
|
|
21571
|
+
*/
|
|
21572
|
+
notifySensorRewatched: zod.z.boolean().optional()
|
|
21559
21573
|
});
|
|
21560
21574
|
var NcAlarmModeDelaysListSchema = zod.z.array(NcAlarmModeDelaysSchema).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
21561
21575
|
/**
|
|
@@ -21570,7 +21584,11 @@ var NcAlarmModeDelaysEditSchema = zod.z.object({
|
|
|
21570
21584
|
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
|
|
21571
21585
|
postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
|
|
21572
21586
|
/** Set a schedule, or `null` to clear (mode always allowed again). */
|
|
21573
|
-
schedule: NcScheduleSchema.nullable().optional()
|
|
21587
|
+
schedule: NcScheduleSchema.nullable().optional(),
|
|
21588
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
21589
|
+
notifyDuringEntryDelay: zod.z.boolean().nullable().optional(),
|
|
21590
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
21591
|
+
notifySensorRewatched: zod.z.boolean().nullable().optional()
|
|
21574
21592
|
});
|
|
21575
21593
|
var NcAlarmModeDelaysEditListSchema = zod.z.array(NcAlarmModeDelaysEditSchema).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
21576
21594
|
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
@@ -26801,6 +26819,22 @@ var MotionSourceEnum = zod.z.enum([
|
|
|
26801
26819
|
"device-activity"
|
|
26802
26820
|
]);
|
|
26803
26821
|
/**
|
|
26822
|
+
* What opened an on-motion detection SESSION: the motion source that passed the
|
|
26823
|
+
* camera's `motionSources` gate, and what raised it (the camera itself, or a
|
|
26824
|
+
* sensor the operator attached — D672). `sensorName` is the attached sensor's
|
|
26825
|
+
* device name as the orchestrator's camera-sensors resolution last read it;
|
|
26826
|
+
* absent when unknown or when the camera itself triggered.
|
|
26827
|
+
*
|
|
26828
|
+
* Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
|
|
26829
|
+
* can say what started the session (D672 rule 11, amended 2026-10-06). The
|
|
26830
|
+
* runner never decides anything on it.
|
|
26831
|
+
*/
|
|
26832
|
+
var SessionTriggerSchema = zod.z.object({
|
|
26833
|
+
source: MotionSourceEnum,
|
|
26834
|
+
triggeredBy: MotionTriggeredBySchema,
|
|
26835
|
+
sensorName: zod.z.string().optional()
|
|
26836
|
+
});
|
|
26837
|
+
/**
|
|
26804
26838
|
* List of motion sources active on a camera. Empty array is valid:
|
|
26805
26839
|
* "no source" — happens for battery cams without firmware motion when
|
|
26806
26840
|
* the operator hasn't opted into the SW analyzer (would hold the
|
|
@@ -27057,6 +27091,14 @@ var RunnerCameraConfigSchema = zod.z.object({
|
|
|
27057
27091
|
*/
|
|
27058
27092
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
27059
27093
|
/**
|
|
27094
|
+
* What opened this attach, on a SESSION attach only (see
|
|
27095
|
+
* {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
|
|
27096
|
+
* standing attach, an occupancy burst, a re-dispatch with no motion event
|
|
27097
|
+
* behind it, and every attach from an orchestrator older than the field — the
|
|
27098
|
+
* runner then names no source on the phase event.
|
|
27099
|
+
*/
|
|
27100
|
+
sessionTrigger: SessionTriggerSchema.optional(),
|
|
27101
|
+
/**
|
|
27060
27102
|
* WHICH root detector runs for this camera. The detection counterpart of
|
|
27061
27103
|
* {@link motionSources}, same shape and same discipline: a per-camera list
|
|
27062
27104
|
* of sources the system understands, vendor-agnostic, owned here.
|
|
@@ -32212,6 +32254,122 @@ var CLIP_PLAYBACK_OPTIONS = {
|
|
|
32212
32254
|
}
|
|
32213
32255
|
};
|
|
32214
32256
|
//#endregion
|
|
32257
|
+
//#region src/capabilities/viewer-link-url.ts
|
|
32258
|
+
/** The central link domain the viewer app claims (Universal Links / App Links). */
|
|
32259
|
+
var CAMSTACK_APP_LINK_ORIGIN = "https://camstack.zentik.app";
|
|
32260
|
+
/** Where the hub serves the viewer SPA. */
|
|
32261
|
+
var HUB_VIEWER_MOUNT = "/viewer/camstack";
|
|
32262
|
+
/** True when `baseUrl` names the CamStack app link rather than a hub address. */
|
|
32263
|
+
function isAppLinkBase(baseUrl) {
|
|
32264
|
+
if (baseUrl === null || baseUrl === void 0 || baseUrl === "") return false;
|
|
32265
|
+
try {
|
|
32266
|
+
return new URL(baseUrl).origin === CAMSTACK_APP_LINK_ORIGIN;
|
|
32267
|
+
} catch {
|
|
32268
|
+
return false;
|
|
32269
|
+
}
|
|
32270
|
+
}
|
|
32271
|
+
/**
|
|
32272
|
+
* The base a viewer link is built on, from the flagged notification address:
|
|
32273
|
+
* the effective address is the explicit choice, else AUTO's `resolved`. The
|
|
32274
|
+
* one reading of that answer — the NC's tap and the Network page's preview
|
|
32275
|
+
* both go through it.
|
|
32276
|
+
*/
|
|
32277
|
+
function viewerLinkBaseOf(endpoint) {
|
|
32278
|
+
const flagged = endpoint.baseUrl ?? endpoint.resolved;
|
|
32279
|
+
return isAppLinkBase(flagged) ? {
|
|
32280
|
+
form: "app",
|
|
32281
|
+
hubBaseUrl: endpoint.appLinkHub ?? null
|
|
32282
|
+
} : {
|
|
32283
|
+
form: "hub",
|
|
32284
|
+
hubBaseUrl: flagged
|
|
32285
|
+
};
|
|
32286
|
+
}
|
|
32287
|
+
/**
|
|
32288
|
+
* Reduce a base URL to the bare origin the central page accepts as `hub=`,
|
|
32289
|
+
* or `null` when it cannot be one: not http(s), carries credentials, or does
|
|
32290
|
+
* not parse. A path/query/fragment is dropped — the central page mounts the
|
|
32291
|
+
* viewer under the origin itself.
|
|
32292
|
+
*/
|
|
32293
|
+
function toAppLinkHubOrigin(baseUrl) {
|
|
32294
|
+
let parsed;
|
|
32295
|
+
try {
|
|
32296
|
+
parsed = new URL(baseUrl);
|
|
32297
|
+
} catch {
|
|
32298
|
+
return null;
|
|
32299
|
+
}
|
|
32300
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return null;
|
|
32301
|
+
if (parsed.username !== "" || parsed.password !== "") return null;
|
|
32302
|
+
if (parsed.hostname === "") return null;
|
|
32303
|
+
return parsed.origin;
|
|
32304
|
+
}
|
|
32305
|
+
/**
|
|
32306
|
+
* The hub address an app link carries as `hub=`, chosen from the hub's OWN
|
|
32307
|
+
* advertised palette so it always agrees with what the Network page lists:
|
|
32308
|
+
* the public tunnel first, then the mesh (Tailscale MagicDNS) — HTTPS only,
|
|
32309
|
+
* because the app and the hosted viewer reach it from off the LAN. `null`
|
|
32310
|
+
* when the hub advertises neither.
|
|
32311
|
+
*/
|
|
32312
|
+
function pickAppLinkHub(endpoints) {
|
|
32313
|
+
const rank = (e) => {
|
|
32314
|
+
if (e.kind !== "public" || !e.baseUrl.startsWith("https://")) return null;
|
|
32315
|
+
if (e.interfaceKind === "public") return 0;
|
|
32316
|
+
if (e.interfaceKind === "vpn") return 1;
|
|
32317
|
+
return null;
|
|
32318
|
+
};
|
|
32319
|
+
return endpoints.flatMap((e) => {
|
|
32320
|
+
const r = rank(e);
|
|
32321
|
+
const origin = toAppLinkHubOrigin(e.baseUrl);
|
|
32322
|
+
return r === null || origin === null ? [] : [{
|
|
32323
|
+
r,
|
|
32324
|
+
p: e.priority,
|
|
32325
|
+
origin
|
|
32326
|
+
}];
|
|
32327
|
+
}).toSorted((a, b) => a.r - b.r || a.p - b.p)[0]?.origin ?? null;
|
|
32328
|
+
}
|
|
32329
|
+
/** The viewer route for a destination, or null when it names nothing. */
|
|
32330
|
+
function viewerRoute(destination) {
|
|
32331
|
+
switch (destination.kind) {
|
|
32332
|
+
case "camera": {
|
|
32333
|
+
if (!Number.isInteger(destination.deviceId) || destination.deviceId <= 0) return null;
|
|
32334
|
+
const at = destination.atMs;
|
|
32335
|
+
return {
|
|
32336
|
+
path: `/camera/${String(destination.deviceId)}`,
|
|
32337
|
+
query: at !== void 0 && Number.isFinite(at) ? [["at", String(Math.trunc(at))]] : []
|
|
32338
|
+
};
|
|
32339
|
+
}
|
|
32340
|
+
case "events": return {
|
|
32341
|
+
path: "/events",
|
|
32342
|
+
query: []
|
|
32343
|
+
};
|
|
32344
|
+
case "notifications": return {
|
|
32345
|
+
path: "/notifications",
|
|
32346
|
+
query: []
|
|
32347
|
+
};
|
|
32348
|
+
}
|
|
32349
|
+
}
|
|
32350
|
+
function encodeQuery(query) {
|
|
32351
|
+
if (query.length === 0) return "";
|
|
32352
|
+
return `?${query.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join("&")}`;
|
|
32353
|
+
}
|
|
32354
|
+
/**
|
|
32355
|
+
* The link for a viewer destination, or `null` when none can be minted: an
|
|
32356
|
+
* unknown destination, or the `hub` form with no reachable base (a dead link
|
|
32357
|
+
* is worse than none).
|
|
32358
|
+
*/
|
|
32359
|
+
function buildViewerLink(input) {
|
|
32360
|
+
const route = viewerRoute(input.destination);
|
|
32361
|
+
if (route === null) return null;
|
|
32362
|
+
const raw = input.base.hubBaseUrl;
|
|
32363
|
+
const base = raw === null ? "" : raw.replace(/\/+$/, "");
|
|
32364
|
+
if (input.base.form === "app") {
|
|
32365
|
+
const origin = base === "" ? null : toAppLinkHubOrigin(base);
|
|
32366
|
+
const query = origin === null ? route.query : [...route.query, ["hub", origin]];
|
|
32367
|
+
return `${CAMSTACK_APP_LINK_ORIGIN}${route.path}${encodeQuery(query)}`;
|
|
32368
|
+
}
|
|
32369
|
+
if (base === "" || isAppLinkBase(base)) return null;
|
|
32370
|
+
return `${base}${HUB_VIEWER_MOUNT}${route.path}${encodeQuery(route.query)}`;
|
|
32371
|
+
}
|
|
32372
|
+
//#endregion
|
|
32215
32373
|
//#region src/capabilities/webrtc-session.cap.ts
|
|
32216
32374
|
/**
|
|
32217
32375
|
* Optional client-side hints sent at session creation to help the provider
|
|
@@ -37085,7 +37243,7 @@ var LocalInterfaceSchema = zod.z.object({
|
|
|
37085
37243
|
name: zod.z.string(),
|
|
37086
37244
|
family: zod.z.enum(["IPv4", "IPv6"]),
|
|
37087
37245
|
address: zod.z.string(),
|
|
37088
|
-
/** CIDR shorthand (e.g. `192.168.
|
|
37246
|
+
/** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
|
|
37089
37247
|
cidr: zod.z.string(),
|
|
37090
37248
|
/** OS netmask. Stable across calls so the SDK can hash on it. */
|
|
37091
37249
|
netmask: zod.z.string(),
|
|
@@ -37139,7 +37297,8 @@ var ConnectionEndpointSchema = zod.z.object({
|
|
|
37139
37297
|
"lan-ipv4",
|
|
37140
37298
|
"lan-ipv6",
|
|
37141
37299
|
"public",
|
|
37142
|
-
"loopback"
|
|
37300
|
+
"loopback",
|
|
37301
|
+
"app-link"
|
|
37143
37302
|
]),
|
|
37144
37303
|
/**
|
|
37145
37304
|
* Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
|
|
@@ -37208,15 +37367,27 @@ var GetConnectionEndpointsResultSchema = zod.z.object({
|
|
|
37208
37367
|
localPort: AdvertisedLocalPortSchema
|
|
37209
37368
|
});
|
|
37210
37369
|
/**
|
|
37211
|
-
* The
|
|
37212
|
-
*
|
|
37213
|
-
*
|
|
37370
|
+
* The address flagged for notification links. `baseUrl: null` = AUTO, which
|
|
37371
|
+
* since D709 is the CamStack app link; `resolved` reports the effective value,
|
|
37372
|
+
* so the UI can show it either way.
|
|
37214
37373
|
*/
|
|
37215
37374
|
var NotificationEndpointSchema = zod.z.object({
|
|
37216
37375
|
/** The operator's explicit choice, or null for AUTO. */
|
|
37217
37376
|
baseUrl: zod.z.string().nullable(),
|
|
37218
|
-
/**
|
|
37219
|
-
|
|
37377
|
+
/**
|
|
37378
|
+
* The effective flagged address: the explicit choice, else (AUTO) the
|
|
37379
|
+
* CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
|
|
37380
|
+
* answered the public tunnel / mesh here, or null.
|
|
37381
|
+
*/
|
|
37382
|
+
resolved: zod.z.string().nullable(),
|
|
37383
|
+
/**
|
|
37384
|
+
* The hub origin an app link carries as `hub=` (D709): the hub's best
|
|
37385
|
+
* public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
|
|
37386
|
+
* picked from this cap's own palette by `pickAppLinkHub`. `null` when the
|
|
37387
|
+
* hub advertises neither; the app link is then minted without `hub=`.
|
|
37388
|
+
* Absent on a pre-D709 hub.
|
|
37389
|
+
*/
|
|
37390
|
+
appLinkHub: zod.z.string().nullable()
|
|
37220
37391
|
});
|
|
37221
37392
|
/**
|
|
37222
37393
|
* The URLs the SDK / viewer should race for API access. `baseUrls` empty =
|
|
@@ -37284,7 +37455,7 @@ var localNetworkCapability = {
|
|
|
37284
37455
|
* every client a second authority on a socket only the hub binds. A viewer
|
|
37285
37456
|
* configured with a port-less public URL (`https://camstack.example.top`)
|
|
37286
37457
|
* infers 443 from the scheme, asks with 443, and was handed
|
|
37287
|
-
* `https://192.168.
|
|
37458
|
+
* `https://192.168.10.9:443` for a hub listening on 4443. That candidate
|
|
37288
37459
|
* cannot ever answer, and losing its race reads in the log exactly like
|
|
37289
37460
|
* "the LAN was tried and it was slower" — so an operator sitting on his own
|
|
37290
37461
|
* WiFi stayed on the public tunnel for weeks, with the LAN candidate born
|
|
@@ -37317,13 +37488,21 @@ var localNetworkCapability = {
|
|
|
37317
37488
|
* Pass `'https'` when the caller is itself loaded over HTTPS
|
|
37318
37489
|
* to avoid mixed-content blocks in the browser. The public
|
|
37319
37490
|
* tunnel always emits `https://` regardless. */
|
|
37320
|
-
scheme: zod.z.enum(["http", "https"]).optional()
|
|
37491
|
+
scheme: zod.z.enum(["http", "https"]).optional(),
|
|
37492
|
+
/** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
|
|
37493
|
+
* an address notification links can be flagged with, not a hub
|
|
37494
|
+
* route. Default `false`: racers and rankers never see it. */
|
|
37495
|
+
includeAppLink: zod.z.boolean().optional()
|
|
37321
37496
|
}), GetConnectionEndpointsResultSchema),
|
|
37322
37497
|
/**
|
|
37323
|
-
* The
|
|
37324
|
-
*
|
|
37325
|
-
*
|
|
37326
|
-
*
|
|
37498
|
+
* The address notification links are flagged with. `baseUrl: null` means
|
|
37499
|
+
* AUTO, which is the CamStack app link (D709): viewer taps go through
|
|
37500
|
+
* `https://camstack.zentik.app/…?hub=<appLinkHub>` and open the app. Any
|
|
37501
|
+
* hub address the palette lists can be flagged instead; then viewer taps,
|
|
37502
|
+
* attachment links and action buttons all use it. Signed media and
|
|
37503
|
+
* buttons never use the app link — with it flagged (or AUTO) they keep
|
|
37504
|
+
* the ranked hub ladder (a configured origin, a connected tunnel, then
|
|
37505
|
+
* the LAN), never loopback.
|
|
37327
37506
|
*
|
|
37328
37507
|
* Why an explicit marker: the automatic ranking cannot know which of
|
|
37329
37508
|
* several reachable addresses the RECIPIENT can actually open. A link is
|
|
@@ -37743,7 +37922,7 @@ var MeshPeerSchema = zod.z.object({
|
|
|
37743
37922
|
tags: zod.z.array(zod.z.string()).readonly(),
|
|
37744
37923
|
/** True when the peer advertises itself as an exit-node candidate. */
|
|
37745
37924
|
exitNodeOption: zod.z.boolean(),
|
|
37746
|
-
/** Subnet routes the peer advertises (e.g. `["192.168.
|
|
37925
|
+
/** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
|
|
37747
37926
|
advertisedRoutes: zod.z.array(zod.z.string()).readonly(),
|
|
37748
37927
|
/** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
|
|
37749
37928
|
userLogin: zod.z.string().nullable(),
|
|
@@ -66902,12 +67081,14 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
66902
67081
|
{
|
|
66903
67082
|
id: "addons",
|
|
66904
67083
|
family: "system",
|
|
66905
|
-
label: "Addons",
|
|
66906
|
-
kinds: [
|
|
66907
|
-
|
|
66908
|
-
|
|
66909
|
-
|
|
66910
|
-
|
|
67084
|
+
label: "Addons stopped",
|
|
67085
|
+
kinds: ["addon-crash-loop"]
|
|
67086
|
+
},
|
|
67087
|
+
{
|
|
67088
|
+
id: "addon-updates",
|
|
67089
|
+
family: "system",
|
|
67090
|
+
label: "Addon updates",
|
|
67091
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
66911
67092
|
},
|
|
66912
67093
|
{
|
|
66913
67094
|
id: "updates",
|
|
@@ -67754,6 +67935,26 @@ var NC_ALARM_DELAY_FIELDS = [
|
|
|
67754
67935
|
"triggeredDurationSec"
|
|
67755
67936
|
];
|
|
67756
67937
|
/**
|
|
67938
|
+
* The STOCK after-trigger duration a panel seeds and every mode inherits unless it sets its
|
|
67939
|
+
* own (D706: 30 s, was 10 s under D701). Only the seed: a persisted value is never rewritten.
|
|
67940
|
+
* The panel's defaults, its one-shot migration and the admin UI's "pick a timed action" fill
|
|
67941
|
+
* all read this one constant.
|
|
67942
|
+
*/
|
|
67943
|
+
var NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC = 30;
|
|
67944
|
+
var NC_ALARM_NOTIFY_FIELDS = ["notifyDuringEntryDelay", "notifySensorRewatched"];
|
|
67945
|
+
/**
|
|
67946
|
+
* The switches `mode` runs on. There is no global value: absent is OFF (operator decision
|
|
67947
|
+
* 2026-10-06 — the entry-delay notification is the only one by default, and "watched again"
|
|
67948
|
+
* is not sent). An answer from an older hub carries no switch and reads as off.
|
|
67949
|
+
*/
|
|
67950
|
+
function resolveModeNotifyPolicy(settings, mode) {
|
|
67951
|
+
const entry = (settings.modeDelays ?? []).find((e) => e.mode === mode);
|
|
67952
|
+
return {
|
|
67953
|
+
notifyDuringEntryDelay: entry?.notifyDuringEntryDelay === true,
|
|
67954
|
+
notifySensorRewatched: entry?.notifySensorRewatched === true
|
|
67955
|
+
};
|
|
67956
|
+
}
|
|
67957
|
+
/**
|
|
67757
67958
|
* Derive the post-triggered action from a stored blob that may predate the field:
|
|
67758
67959
|
* a positive duration meant re-arm; zero/absent meant stay triggered.
|
|
67759
67960
|
*/
|
|
@@ -67802,6 +68003,10 @@ function editedAction(current, edit) {
|
|
|
67802
68003
|
if (edit === void 0) return current;
|
|
67803
68004
|
return edit === null ? void 0 : edit;
|
|
67804
68005
|
}
|
|
68006
|
+
function editedFlag(current, edit) {
|
|
68007
|
+
if (edit === void 0) return current;
|
|
68008
|
+
return edit === null ? void 0 : edit;
|
|
68009
|
+
}
|
|
67805
68010
|
function editedSchedule(current, edit) {
|
|
67806
68011
|
if (edit === void 0) return current;
|
|
67807
68012
|
return edit === null ? void 0 : edit;
|
|
@@ -67836,15 +68041,19 @@ function applyModeDelaysEdits(current, edits) {
|
|
|
67836
68041
|
const triggered = edited(base.triggeredDurationSec, edit.triggeredDurationSec);
|
|
67837
68042
|
const action = editedAction(base.postTriggeredAction, edit.postTriggeredAction);
|
|
67838
68043
|
const schedule = editedSchedule(base.schedule, edit.schedule);
|
|
68044
|
+
const duringEntry = editedFlag(base.notifyDuringEntryDelay, edit.notifyDuringEntryDelay);
|
|
68045
|
+
const rewatched = editedFlag(base.notifySensorRewatched, edit.notifySensorRewatched);
|
|
67839
68046
|
if (exit !== void 0) next.exitDelaySec = exit;
|
|
67840
68047
|
if (entry !== void 0) next.entryDelaySec = entry;
|
|
67841
68048
|
if (triggered !== void 0) next.triggeredDurationSec = triggered;
|
|
67842
68049
|
if (action !== void 0) next.postTriggeredAction = action;
|
|
67843
68050
|
if (schedule !== void 0) next.schedule = schedule;
|
|
68051
|
+
if (duringEntry !== void 0) next.notifyDuringEntryDelay = duringEntry;
|
|
68052
|
+
if (rewatched !== void 0) next.notifySensorRewatched = rewatched;
|
|
67844
68053
|
if (at >= 0) out[at] = next;
|
|
67845
68054
|
else out.push(next);
|
|
67846
68055
|
}
|
|
67847
|
-
return out.filter((e) => e.exitDelaySec !== void 0 || e.entryDelaySec !== void 0 || e.triggeredDurationSec !== void 0 || e.postTriggeredAction !== void 0 || e.schedule !== void 0);
|
|
68056
|
+
return out.filter((e) => e.exitDelaySec !== void 0 || e.entryDelaySec !== void 0 || e.triggeredDurationSec !== void 0 || e.postTriggeredAction !== void 0 || e.schedule !== void 0 || e.notifyDuringEntryDelay !== void 0 || e.notifySensorRewatched !== void 0);
|
|
67848
68057
|
}
|
|
67849
68058
|
/**
|
|
67850
68059
|
* Put ONE device on, or take it off, ONE mode's device-id list. A no-op answers
|
|
@@ -67989,6 +68198,12 @@ function alarmPatchLanded(patch, returned) {
|
|
|
67989
68198
|
const got = entry?.postTriggeredAction;
|
|
67990
68199
|
if (edit.postTriggeredAction === null ? got !== void 0 : got !== edit.postTriggeredAction) return false;
|
|
67991
68200
|
}
|
|
68201
|
+
for (const field of NC_ALARM_NOTIFY_FIELDS) {
|
|
68202
|
+
const want = edit[field];
|
|
68203
|
+
if (want === void 0) continue;
|
|
68204
|
+
const got = entry?.[field];
|
|
68205
|
+
if (want === null ? got !== void 0 : got !== want) return false;
|
|
68206
|
+
}
|
|
67992
68207
|
if (edit.schedule !== void 0) {
|
|
67993
68208
|
const got = entry?.schedule;
|
|
67994
68209
|
if (edit.schedule === null ? got !== void 0 : !sameSchedule(got, edit.schedule)) return false;
|
|
@@ -68385,13 +68600,15 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
68385
68600
|
},
|
|
68386
68601
|
{
|
|
68387
68602
|
name: "summaryAddons",
|
|
68388
|
-
label: "Summary: addons",
|
|
68389
|
-
example: "
|
|
68390
|
-
kinds: [
|
|
68391
|
-
|
|
68392
|
-
|
|
68393
|
-
|
|
68394
|
-
|
|
68603
|
+
label: "Summary: addons stopped",
|
|
68604
|
+
example: "hub — recorder stopped after repeated crashes",
|
|
68605
|
+
kinds: ["addon-crash-loop"]
|
|
68606
|
+
},
|
|
68607
|
+
{
|
|
68608
|
+
name: "summaryAddonUpdates",
|
|
68609
|
+
label: "Summary: addon updates",
|
|
68610
|
+
example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
|
|
68611
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
68395
68612
|
},
|
|
68396
68613
|
{
|
|
68397
68614
|
name: "summaryUpdates",
|
|
@@ -68732,6 +68949,16 @@ var NC_TEMPLATE_VARS = [
|
|
|
68732
68949
|
kinds: ["system"],
|
|
68733
68950
|
systemEventKinds: [...DEVICE_EVENTS]
|
|
68734
68951
|
},
|
|
68952
|
+
{
|
|
68953
|
+
name: "locations",
|
|
68954
|
+
label: "Intrusion locations",
|
|
68955
|
+
example: "Ingresso, Corridoio, Salone",
|
|
68956
|
+
group: "system",
|
|
68957
|
+
families: ["rule"],
|
|
68958
|
+
fields: [...RULE_TEXT],
|
|
68959
|
+
kinds: ["system"],
|
|
68960
|
+
systemEventKinds: [...COMBINED_ALARM]
|
|
68961
|
+
},
|
|
68735
68962
|
{
|
|
68736
68963
|
name: "deviceId",
|
|
68737
68964
|
label: "Device id",
|
|
@@ -69448,7 +69675,7 @@ function sendTimesForEditor(schedule) {
|
|
|
69448
69675
|
approximated: times.length > 0
|
|
69449
69676
|
};
|
|
69450
69677
|
}
|
|
69451
|
-
var SUMMARY_CONTENT_VAR = /\{\{\s*summary(?:Text|Devices|Streams|Battery|Consumables|Tanks|Detection|Nodes|Addons|Updates)\s*\}\}/;
|
|
69678
|
+
var SUMMARY_CONTENT_VAR = /\{\{\s*summary(?:Text|Devices|Streams|Battery|Consumables|Tanks|Detection|Nodes|Addons|AddonUpdates|Updates)\s*\}\}/;
|
|
69452
69679
|
/**
|
|
69453
69680
|
* Does a custom BODY carry the summary's content (`{{summaryText}}` or a
|
|
69454
69681
|
* section variable)? A body that does not would send a summary with nothing
|
|
@@ -72662,6 +72889,7 @@ exports.CAMERA_SENSORS_SETTINGS_KEY = CAMERA_SENSORS_SETTINGS_KEY;
|
|
|
72662
72889
|
exports.CAMERA_SWITCH_CATALOG = CAMERA_SWITCH_CATALOG;
|
|
72663
72890
|
exports.CAMERA_SWITCH_ORDER = CAMERA_SWITCH_ORDER;
|
|
72664
72891
|
exports.CAMERA_TRIGGER = CAMERA_TRIGGER;
|
|
72892
|
+
exports.CAMSTACK_APP_LINK_ORIGIN = CAMSTACK_APP_LINK_ORIGIN;
|
|
72665
72893
|
exports.CAM_PROFILE_ORDER = require_sleep.CAM_PROFILE_ORDER;
|
|
72666
72894
|
exports.CAPABILITY_NAMES = CAPABILITY_NAMES;
|
|
72667
72895
|
exports.CAPABILITY_ROUTER_KEYS = CAPABILITY_ROUTER_KEYS;
|
|
@@ -73098,6 +73326,7 @@ exports.HAP_KEYFRAME_INTERVAL_SEC = HAP_KEYFRAME_INTERVAL_SEC;
|
|
|
73098
73326
|
exports.HF_BASE_URL = HF_BASE_URL;
|
|
73099
73327
|
exports.HF_REPO = HF_REPO;
|
|
73100
73328
|
exports.HOURS_PER_DAY = HOURS_PER_DAY;
|
|
73329
|
+
exports.HUB_VIEWER_MOUNT = HUB_VIEWER_MOUNT;
|
|
73101
73330
|
exports.HWACCEL_OPTIONS = HWACCEL_OPTIONS;
|
|
73102
73331
|
exports.HealthStatusSchema = HealthStatusSchema;
|
|
73103
73332
|
exports.HfModelResolutionSchema = HfModelResolutionSchema;
|
|
@@ -73315,9 +73544,11 @@ exports.NAVIGATION_LIGHT_LEVEL_MIN = NAVIGATION_LIGHT_LEVEL_MIN;
|
|
|
73315
73544
|
exports.NC_ALARM_CONTROLLABLE_CAPS = NC_ALARM_CONTROLLABLE_CAPS;
|
|
73316
73545
|
exports.NC_ALARM_DEFAULT_PROFILE_ID = NC_ALARM_DEFAULT_PROFILE_ID;
|
|
73317
73546
|
exports.NC_ALARM_DEFAULT_PROFILE_NAME = NC_ALARM_DEFAULT_PROFILE_NAME;
|
|
73547
|
+
exports.NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC = NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC;
|
|
73318
73548
|
exports.NC_ALARM_DELAY_FIELDS = NC_ALARM_DELAY_FIELDS;
|
|
73319
73549
|
exports.NC_ALARM_DELAY_MAX_SEC = NC_ALARM_DELAY_MAX_SEC;
|
|
73320
73550
|
exports.NC_ALARM_NONBLOCKING_MAX = NC_ALARM_NONBLOCKING_MAX;
|
|
73551
|
+
exports.NC_ALARM_NOTIFY_FIELDS = NC_ALARM_NOTIFY_FIELDS;
|
|
73321
73552
|
exports.NC_ALARM_OPENING_EVENT_KINDS = NC_ALARM_OPENING_EVENT_KINDS;
|
|
73322
73553
|
exports.NC_ALARM_SENSORS_MAX = NC_ALARM_SENSORS_MAX;
|
|
73323
73554
|
exports.NC_ALARM_SYSTEM_DEFAULT_DELAYS = NC_ALARM_SYSTEM_DEFAULT_DELAYS;
|
|
@@ -73793,6 +74024,7 @@ exports.ServerUpdateActionResultSchema = ServerUpdateActionResultSchema;
|
|
|
73793
74024
|
exports.ServerUpdateCheckResultSchema = ServerUpdateCheckResultSchema;
|
|
73794
74025
|
exports.ServerUpdateOutcomeSchema = ServerUpdateOutcomeSchema;
|
|
73795
74026
|
exports.ServerUpdateStateSchema = ServerUpdateStateSchema;
|
|
74027
|
+
exports.SessionTriggerSchema = SessionTriggerSchema;
|
|
73796
74028
|
exports.SetCameraSensorsInputSchema = SetCameraSensorsInputSchema;
|
|
73797
74029
|
exports.SetLoggingSettingsInputSchema = SetLoggingSettingsInputSchema;
|
|
73798
74030
|
exports.SetSiteLocationInputSchema = SetSiteLocationInputSchema;
|
|
@@ -74076,6 +74308,7 @@ exports.buildNcTaxonomy = buildNcTaxonomy;
|
|
|
74076
74308
|
exports.buildRoleScopes = buildRoleScopes;
|
|
74077
74309
|
exports.buildStreamParamsConfigSchema = buildStreamParamsConfigSchema;
|
|
74078
74310
|
exports.buildVideoArgs = require_composition.buildVideoArgs;
|
|
74311
|
+
exports.buildViewerLink = buildViewerLink;
|
|
74079
74312
|
exports.builtCapabilityBlockers = builtCapabilityBlockers;
|
|
74080
74313
|
exports.buttonCapability = buttonCapability;
|
|
74081
74314
|
exports.calendarSourceCapability = calendarSourceCapability;
|
|
@@ -74305,6 +74538,7 @@ exports.invertPresetFeature = invertPresetFeature;
|
|
|
74305
74538
|
exports.invocationFromEncodeProfile = require_composition.invocationFromEncodeProfile;
|
|
74306
74539
|
exports.isAgentOnlyPlacement = isAgentOnlyPlacement;
|
|
74307
74540
|
exports.isAlarmControllableCap = isAlarmControllableCap;
|
|
74541
|
+
exports.isAppLinkBase = isAppLinkBase;
|
|
74308
74542
|
exports.isArrayOutputSchema = isArrayOutputSchema;
|
|
74309
74543
|
exports.isAudioChunkFormat = require_sleep.isAudioChunkFormat;
|
|
74310
74544
|
exports.isAudioClassName = isAudioClassName;
|
|
@@ -74451,6 +74685,7 @@ exports.parseStreamParamsFormPatch = parseStreamParamsFormPatch;
|
|
|
74451
74685
|
exports.patchAudio = patchAudio;
|
|
74452
74686
|
exports.petFeederCapability = petFeederCapability;
|
|
74453
74687
|
exports.pickAccessoryControl = pickAccessoryControl;
|
|
74688
|
+
exports.pickAppLinkHub = pickAppLinkHub;
|
|
74454
74689
|
exports.pickClusterStepModels = pickClusterStepModels;
|
|
74455
74690
|
exports.pickClusterStepSettings = pickClusterStepSettings;
|
|
74456
74691
|
exports.pickDetailCropConvention = pickDetailCropConvention;
|
|
@@ -74530,6 +74765,7 @@ exports.resolveLocationIcon = resolveLocationIcon;
|
|
|
74530
74765
|
exports.resolveLocationMode = resolveLocationMode;
|
|
74531
74766
|
exports.resolveMethodAuth = resolveMethodAuth;
|
|
74532
74767
|
exports.resolveModeDelays = resolveModeDelays;
|
|
74768
|
+
exports.resolveModeNotifyPolicy = resolveModeNotifyPolicy;
|
|
74533
74769
|
exports.resolveMutate = resolveMutate;
|
|
74534
74770
|
exports.resolvePoolMemoryPolicy = resolvePoolMemoryPolicy;
|
|
74535
74771
|
exports.resolveRecordingProfiles = resolveRecordingProfiles;
|
|
@@ -74638,6 +74874,7 @@ exports.templateVarsFor = templateVarsFor;
|
|
|
74638
74874
|
exports.terminalSessionCapability = terminalSessionCapability;
|
|
74639
74875
|
exports.textToHtml = textToHtml;
|
|
74640
74876
|
exports.timeOfDayToMinutes = timeOfDayToMinutes;
|
|
74877
|
+
exports.toAppLinkHubOrigin = toAppLinkHubOrigin;
|
|
74641
74878
|
exports.toDeviceSummary = toDeviceSummary;
|
|
74642
74879
|
exports.toExpressionValue = require_composition.toExpressionValue;
|
|
74643
74880
|
exports.toNodeId = require_sleep.toNodeId;
|
|
@@ -74665,6 +74902,7 @@ exports.vectorIndexDimConflictError = vectorIndexDimConflictError;
|
|
|
74665
74902
|
exports.vectorStoreCapability = vectorStoreCapability;
|
|
74666
74903
|
exports.vibrationCapability = vibrationCapability;
|
|
74667
74904
|
exports.videoclipsCapability = videoclipsCapability;
|
|
74905
|
+
exports.viewerLinkBaseOf = viewerLinkBaseOf;
|
|
74668
74906
|
exports.viewerUiCapability = require_sleep.viewerUiCapability;
|
|
74669
74907
|
exports.waterHeaterCapability = waterHeaterCapability;
|
|
74670
74908
|
exports.weatherCapability = weatherCapability;
|