@camstack/addon-provider-reolink 1.2.13 → 1.2.15
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.js +451 -76
- package/dist/addon.mjs +451 -76
- package/package.json +3 -2
package/dist/addon.js
CHANGED
|
@@ -26,7 +26,7 @@ let fs_promises = require("fs/promises");
|
|
|
26
26
|
fs_promises = require_chunk.__toESM(fs_promises, 1);
|
|
27
27
|
let node_os = require("node:os");
|
|
28
28
|
node_os = require_chunk.__toESM(node_os);
|
|
29
|
-
//#region ../types/dist/event-category-
|
|
29
|
+
//#region ../types/dist/event-category-Bz24uP1U.mjs
|
|
30
30
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
31
31
|
EventCategory["SystemBoot"] = "system.boot";
|
|
32
32
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -297,6 +297,19 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
297
297
|
*/
|
|
298
298
|
EventCategory["DeviceStateChanged"] = "device.state-changed";
|
|
299
299
|
/**
|
|
300
|
+
* Frame occupancy for a camera CHANGED — a tracked object was gained or
|
|
301
|
+
* lost. Carries `{ deviceId, totalObjects, byClass, zones }`.
|
|
302
|
+
*
|
|
303
|
+
* Emitted only on a change, so a steady scene is silent. It exists so a
|
|
304
|
+
* client can stop polling `zoneAnalytics.getCurrentSnapshot`: that was the
|
|
305
|
+
* one live badge with no push signal at all, and it cost a request every
|
|
306
|
+
* four seconds per visible camera.
|
|
307
|
+
*
|
|
308
|
+
* Like every event it is telemetry and may be dropped ([D8]) — a consumer
|
|
309
|
+
* keeps a slow reconcile rather than trusting it alone.
|
|
310
|
+
*/
|
|
311
|
+
EventCategory["ZoneAnalyticsOccupancyChanged"] = "zone-analytics.occupancy-changed";
|
|
312
|
+
/**
|
|
300
313
|
* Cap event fired by every device that registers the `battery`
|
|
301
314
|
* capability. Mirrors the cap definition's `onStatusChanged`. Carries
|
|
302
315
|
* `{ deviceId, status: BatteryStatus }`. Subscribers (alert center,
|
|
@@ -7413,35 +7426,22 @@ function findTimezone(id) {
|
|
|
7413
7426
|
*/
|
|
7414
7427
|
var RecordingWeekdaySchema = number().int().min(0).max(6);
|
|
7415
7428
|
var HHMM = /^([01]\d|2[0-3]):[0-5]\d$/;
|
|
7416
|
-
var RecordingScheduleSchema = discriminatedUnion("kind", [object({ kind: literal("always") }), object({
|
|
7417
|
-
kind: literal("timeOfDay"),
|
|
7418
|
-
start: string().regex(HHMM),
|
|
7419
|
-
end: string().regex(HHMM),
|
|
7420
|
-
/** Restrict to these weekdays; omit = every day. */
|
|
7421
|
-
days: array(RecordingWeekdaySchema).optional()
|
|
7422
|
-
})]);
|
|
7423
|
-
var RecordingModeSchema = _enum([
|
|
7424
|
-
"continuous",
|
|
7425
|
-
"onMotion",
|
|
7426
|
-
"onAudioThreshold"
|
|
7427
|
-
]);
|
|
7428
7429
|
/**
|
|
7429
|
-
*
|
|
7430
|
-
*
|
|
7431
|
-
* - `off` —
|
|
7432
|
-
* - `events` —
|
|
7433
|
-
*
|
|
7434
|
-
* - `continuous` — record 24/7 within the schedule.
|
|
7430
|
+
* DERIVED per-camera storage summary — the single field cheap consumers read
|
|
7431
|
+
* (the viewer's status dot, the camera list) instead of walking `bands`:
|
|
7432
|
+
* - `off` — no band covers the camera (or it is disabled).
|
|
7433
|
+
* - `events` — every band records around triggers only.
|
|
7434
|
+
* - `continuous` — at least one band records continuously.
|
|
7435
7435
|
*
|
|
7436
|
-
*
|
|
7437
|
-
*
|
|
7436
|
+
* NEVER authored: the recorder stamps it from the authoritative `bands` on
|
|
7437
|
+
* every save (`activeModeForConfig`). Writing it has no effect.
|
|
7438
7438
|
*/
|
|
7439
7439
|
var RecordingStorageModeSchema = _enum([
|
|
7440
7440
|
"off",
|
|
7441
7441
|
"events",
|
|
7442
7442
|
"continuous"
|
|
7443
7443
|
]);
|
|
7444
|
-
/** Which detectors trigger an `events`-mode
|
|
7444
|
+
/** Which detectors trigger an `events`-mode band. */
|
|
7445
7445
|
var RecordingTriggersSchema = object({
|
|
7446
7446
|
motion: boolean().optional(),
|
|
7447
7447
|
audioThresholdDbfs: number().optional()
|
|
@@ -7477,18 +7477,6 @@ var RecordingBandSchema = object({
|
|
|
7477
7477
|
preBufferSec: number().min(0).optional(),
|
|
7478
7478
|
postBufferSec: number().min(0).optional()
|
|
7479
7479
|
});
|
|
7480
|
-
var RecordingRuleSchema = object({
|
|
7481
|
-
schedule: RecordingScheduleSchema,
|
|
7482
|
-
mode: RecordingModeSchema,
|
|
7483
|
-
/** Seconds of footage to retain BEFORE a trigger (applied at keep/discard). */
|
|
7484
|
-
preBufferSec: number().min(0).default(0),
|
|
7485
|
-
/** Keep recording until this many seconds after the last trigger. */
|
|
7486
|
-
postBufferSec: number().min(0).default(0),
|
|
7487
|
-
/** Each new trigger restarts the post-buffer window. */
|
|
7488
|
-
resetTimeoutOnNewEvent: boolean().default(true),
|
|
7489
|
-
/** onAudioThreshold only — dBFS level that counts as a trigger. */
|
|
7490
|
-
thresholdDbfs: number().optional()
|
|
7491
|
-
});
|
|
7492
7480
|
/**
|
|
7493
7481
|
* Per-device retention overrides. Every field is optional; an unset or `0`
|
|
7494
7482
|
* value inherits the node-wide recorder default. Only footage-lifetime limits
|
|
@@ -7522,40 +7510,28 @@ var ScrubThumbnailPresetSchema = _enum([
|
|
|
7522
7510
|
/**
|
|
7523
7511
|
* The full per-camera recording intent — the wire shape of a RecordingTarget.
|
|
7524
7512
|
*
|
|
7525
|
-
* `
|
|
7526
|
-
*
|
|
7527
|
-
*
|
|
7528
|
-
*
|
|
7513
|
+
* `bands` is the ONLY authored recording intent: what to record, when, and on
|
|
7514
|
+
* which trigger. `mode` is a derived summary the recorder stamps on save; every
|
|
7515
|
+
* other field is a storage knob (profiles, segment length, retention, scrub).
|
|
7516
|
+
*
|
|
7517
|
+
* STRICT on purpose: the legacy authoring surface (`schedule`/`schedules`/
|
|
7518
|
+
* `triggers`/`preBufferSec`/`postBufferSec`/`rules`) was retired 2026-07-30.
|
|
7519
|
+
* A stale caller must fail loudly — silently stripping its legacy intent would
|
|
7520
|
+
* persist a band-less config, i.e. silently stop recording the camera.
|
|
7529
7521
|
*/
|
|
7530
7522
|
var RecordingConfigSchema = object({
|
|
7531
7523
|
enabled: boolean(),
|
|
7532
|
-
/**
|
|
7533
|
-
*
|
|
7524
|
+
/** DERIVED summary of `bands`, stamped by the recorder on every save.
|
|
7525
|
+
* Authoring it has no effect — see {@link RecordingStorageModeSchema}. */
|
|
7534
7526
|
mode: RecordingStorageModeSchema.optional(),
|
|
7535
7527
|
profiles: array(CamProfileSchema).optional(),
|
|
7536
7528
|
segmentSeconds: number().int().positive().optional(),
|
|
7537
|
-
/** Shared recording time-bands for `events` & `continuous` — record only when
|
|
7538
|
-
* the wall-clock falls inside one of these windows. Omit or empty = always.
|
|
7539
|
-
* `continuous` compiles to one rule per band; `events` to band × trigger. */
|
|
7540
|
-
schedules: array(RecordingScheduleSchema).optional(),
|
|
7541
|
-
/** Legacy single-band predecessor of `schedules`. Read-compat only — it is
|
|
7542
|
-
* normalized into `schedules` on read and never written going forward. (Not
|
|
7543
|
-
* tagged `@deprecated`: the normalization paths must read it cast-free.) */
|
|
7544
|
-
schedule: RecordingScheduleSchema.optional(),
|
|
7545
|
-
/** `events`-mode only — which detectors trigger a recording. */
|
|
7546
|
-
triggers: RecordingTriggersSchema.optional(),
|
|
7547
|
-
/** `events`-mode only — seconds retained before / after a trigger. */
|
|
7548
|
-
preBufferSec: number().min(0).optional(),
|
|
7549
|
-
postBufferSec: number().min(0).optional(),
|
|
7550
|
-
/** DEPRECATED authoring input; retained for migration/transition. */
|
|
7551
|
-
rules: array(RecordingRuleSchema).optional(),
|
|
7552
7529
|
/**
|
|
7553
|
-
* AUTHORITATIVE mode-per-band recording model
|
|
7554
|
-
*
|
|
7555
|
-
*
|
|
7556
|
-
* derived into bands once via `migrateConfigToBands`.
|
|
7530
|
+
* AUTHORITATIVE mode-per-band recording model — the single source of truth
|
|
7531
|
+
* the recorder's band engine consumes. An empty array = record nothing;
|
|
7532
|
+
* "off" is the absence of a covering band, never a band value.
|
|
7557
7533
|
*/
|
|
7558
|
-
bands: array(RecordingBandSchema).
|
|
7534
|
+
bands: array(RecordingBandSchema).default([]),
|
|
7559
7535
|
retention: RecordingRetentionSchema.optional(),
|
|
7560
7536
|
/**
|
|
7561
7537
|
* Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
|
|
@@ -7563,8 +7539,15 @@ var RecordingConfigSchema = object({
|
|
|
7563
7539
|
* windows only — existing sheets are immutable, and each window's index
|
|
7564
7540
|
* carries its own tile dims so mixed-preset history renders correctly.
|
|
7565
7541
|
*/
|
|
7566
|
-
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7567
|
-
|
|
7542
|
+
scrubThumbnails: ScrubThumbnailPresetSchema.optional(),
|
|
7543
|
+
/**
|
|
7544
|
+
* OPT-IN thumbnail-strip generation for this camera: every keyframe of the
|
|
7545
|
+
* low recording saved as a JPEG (the fast-drag scrub depth), a derived
|
|
7546
|
+
* cache that eviction reclaims with the footage. Absent/false = no strips
|
|
7547
|
+
* are written and scrub reads exact keyframes at every velocity.
|
|
7548
|
+
*/
|
|
7549
|
+
stripsEnabled: boolean().optional()
|
|
7550
|
+
}).strict();
|
|
7568
7551
|
/**
|
|
7569
7552
|
* Ops-log — the durable, append-only operations audit shared by the
|
|
7570
7553
|
* recordings and events management surfaces.
|
|
@@ -7583,7 +7566,8 @@ var OpsLogOpSchema = _enum([
|
|
|
7583
7566
|
"prune",
|
|
7584
7567
|
"manual-delete",
|
|
7585
7568
|
"rescan",
|
|
7586
|
-
"retention-run"
|
|
7569
|
+
"retention-run",
|
|
7570
|
+
"relocate"
|
|
7587
7571
|
]);
|
|
7588
7572
|
/** Why the operation ran. */
|
|
7589
7573
|
var OpsLogReasonSchema = _enum([
|
|
@@ -7622,6 +7606,55 @@ var OpsLogQueryInputSchema = object({
|
|
|
7622
7606
|
limit: number().int().min(1).max(1e3).optional()
|
|
7623
7607
|
});
|
|
7624
7608
|
/**
|
|
7609
|
+
* Entity-relocation job state (storage entity-routing spec, Phase 4).
|
|
7610
|
+
*
|
|
7611
|
+
* One shape shared by the recorder's `relocateFootage` (segments + strips) and
|
|
7612
|
+
* pipeline-analytics' `relocateMedia` (event media blobs) so the admin Data
|
|
7613
|
+
* page renders both movers with one component. Jobs are in-RAM (a restart
|
|
7614
|
+
* forgets them — re-running is safe by construction: copy-if-absent, delete
|
|
7615
|
+
* after verify) and each completed/failed run also lands one durable ops-log
|
|
7616
|
+
* row on the owning addon's surface.
|
|
7617
|
+
*/
|
|
7618
|
+
var RelocateJobStateSchema = _enum([
|
|
7619
|
+
"running",
|
|
7620
|
+
"done",
|
|
7621
|
+
"failed",
|
|
7622
|
+
"cancelled"
|
|
7623
|
+
]);
|
|
7624
|
+
var RelocateJobSchema = object({
|
|
7625
|
+
jobId: string(),
|
|
7626
|
+
state: RelocateJobStateSchema,
|
|
7627
|
+
/** Source location — for media relocation this is informational ('*': rows
|
|
7628
|
+
* move from wherever they are to the target). */
|
|
7629
|
+
fromLocationId: string(),
|
|
7630
|
+
toLocationId: string(),
|
|
7631
|
+
/** Scoped device, or null = every device. */
|
|
7632
|
+
deviceId: number().nullable(),
|
|
7633
|
+
/** What the job moves (owner-addon specific: segments/strips or media). */
|
|
7634
|
+
entities: array(string()),
|
|
7635
|
+
filesMoved: number().int(),
|
|
7636
|
+
bytesMoved: number().int(),
|
|
7637
|
+
/** Total files discovered up front; null while (or when) unknown. */
|
|
7638
|
+
filesTotal: number().int().nullable(),
|
|
7639
|
+
startedAt: number(),
|
|
7640
|
+
finishedAt: number().nullable(),
|
|
7641
|
+
error: string().nullable()
|
|
7642
|
+
});
|
|
7643
|
+
var RelocateFootageInputSchema = object({
|
|
7644
|
+
deviceId: number().optional(),
|
|
7645
|
+
fromLocationId: string(),
|
|
7646
|
+
toLocationId: string(),
|
|
7647
|
+
entities: array(_enum(["segments", "strips"])).optional(),
|
|
7648
|
+
/** Copy throttle in MB/s (default 40) — the drain is a background chore,
|
|
7649
|
+
* never allowed to starve live writers. */
|
|
7650
|
+
throttleMbps: number().min(1).max(1e3).optional()
|
|
7651
|
+
});
|
|
7652
|
+
var RelocateMediaInputSchema = object({
|
|
7653
|
+
deviceId: number().optional(),
|
|
7654
|
+
toLocationId: string(),
|
|
7655
|
+
throttleMbps: number().min(1).max(1e3).optional()
|
|
7656
|
+
});
|
|
7657
|
+
/**
|
|
7625
7658
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7626
7659
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7627
7660
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -7671,6 +7704,13 @@ var StorageLocationSchema = object({
|
|
|
7671
7704
|
nodeId: string().optional(),
|
|
7672
7705
|
isDefault: boolean().default(false),
|
|
7673
7706
|
isSystem: boolean().default(false),
|
|
7707
|
+
/** COMPUTED at read time by the orchestrator (statfs of the backing volume
|
|
7708
|
+
* for node-local locations it can reach) — never persisted, absent when the
|
|
7709
|
+
* volume is remote/unreachable. The single capacity truth every UI reads. */
|
|
7710
|
+
capacity: object({
|
|
7711
|
+
totalBytes: number(),
|
|
7712
|
+
availableBytes: number()
|
|
7713
|
+
}).nullable().optional(),
|
|
7674
7714
|
createdAt: number(),
|
|
7675
7715
|
updatedAt: number()
|
|
7676
7716
|
});
|
|
@@ -8438,7 +8478,8 @@ var NcTaxonomyEntrySchema = object({
|
|
|
8438
8478
|
/** Macro/category parent for grouping ('car' → 'vehicle'); null for a top. */
|
|
8439
8479
|
parentKind: string().nullable()
|
|
8440
8480
|
});
|
|
8441
|
-
|
|
8481
|
+
/** The complete NC picker taxonomy — three grouped buckets. */
|
|
8482
|
+
var NcTaxonomySchema = object({
|
|
8442
8483
|
videoClasses: array(NcTaxonomyEntrySchema),
|
|
8443
8484
|
audioKinds: array(NcTaxonomyEntrySchema),
|
|
8444
8485
|
labels: array(NcTaxonomyEntrySchema)
|
|
@@ -9380,6 +9421,7 @@ function createRuntimeStateBridge(params) {
|
|
|
9380
9421
|
getStatus
|
|
9381
9422
|
};
|
|
9382
9423
|
}
|
|
9424
|
+
new Set(["devices", "classes"]);
|
|
9383
9425
|
/**
|
|
9384
9426
|
* Shared geometry vocabulary for on-frame shape caps — privacy-mask,
|
|
9385
9427
|
* motion-zones, and the detection zones/lines editor all speak this one
|
|
@@ -9538,6 +9580,29 @@ var NcOccupancyConditionSchema = object({
|
|
|
9538
9580
|
count: number().int().min(0).default(1),
|
|
9539
9581
|
sustainSeconds: number().int().min(0).max(3600).default(15)
|
|
9540
9582
|
});
|
|
9583
|
+
/**
|
|
9584
|
+
* Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
|
|
9585
|
+
*
|
|
9586
|
+
* The values are not symmetric, and deliberately so — the absent value has to
|
|
9587
|
+
* mean exactly what every rule authored before this condition existed already
|
|
9588
|
+
* does:
|
|
9589
|
+
* - `enter` — entries and every NON-crossing record (movement state,
|
|
9590
|
+
* package, sensor). Exits are rejected. **This is the absent behaviour**:
|
|
9591
|
+
* an operator who never asked for exits must not start receiving them.
|
|
9592
|
+
* - `exit` — ONLY an exit crossing. A record that is not a crossing at all
|
|
9593
|
+
* fails closed, because "the car left the drive" is a question about a
|
|
9594
|
+
* boundary, not about a detection.
|
|
9595
|
+
* - `any` — no direction filter; entries, exits and non-crossings alike.
|
|
9596
|
+
*
|
|
9597
|
+
* A rule asking for a direction should normally also scope `zones`, which the
|
|
9598
|
+
* engine evaluates against the crossed zone as well as the current membership
|
|
9599
|
+
* (an exit's membership no longer contains the zone it just left).
|
|
9600
|
+
*/
|
|
9601
|
+
var NcCrossingSchema = _enum([
|
|
9602
|
+
"enter",
|
|
9603
|
+
"exit",
|
|
9604
|
+
"any"
|
|
9605
|
+
]);
|
|
9541
9606
|
/** Admin-zone membership condition (zone IDs as stamped by the ZoneEngine). */
|
|
9542
9607
|
var NcZoneConditionSchema = object({
|
|
9543
9608
|
ids: array(string().min(1)).min(1),
|
|
@@ -9562,6 +9627,13 @@ var NcConditionsSchema = object({
|
|
|
9562
9627
|
/** Veto zones — any hit fails the rule. */
|
|
9563
9628
|
zonesExclude: array(string().min(1)).optional(),
|
|
9564
9629
|
/**
|
|
9630
|
+
* Zone-crossing direction. IMMEDIATE only — a crossing is a per-event fact
|
|
9631
|
+
* and a closed track carries none, so a `track-end` rule asking for one
|
|
9632
|
+
* fails closed (use `zones`, which tests `zonesVisited`). ABSENT = `enter`,
|
|
9633
|
+
* which is exactly today's behaviour. See {@link NcCrossingSchema}.
|
|
9634
|
+
*/
|
|
9635
|
+
crossing: NcCrossingSchema.optional(),
|
|
9636
|
+
/**
|
|
9565
9637
|
* Exact (case-insensitive) match on the record's collapsed `label`
|
|
9566
9638
|
* (identity name / plate text / subclass).
|
|
9567
9639
|
*/
|
|
@@ -9696,17 +9768,85 @@ var NcRuleTargetSchema = object({
|
|
|
9696
9768
|
* - `keyFrame` — the clean scene frame (no subject box).
|
|
9697
9769
|
* - `none` — no attachment.
|
|
9698
9770
|
*/
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
9771
|
+
/**
|
|
9772
|
+
* WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
|
|
9773
|
+
* conflate it with the selection strategy and betray the request: asking for
|
|
9774
|
+
* the clean scene frame on an object-event owner used to start at
|
|
9775
|
+
* `fullFrameBoxed`, i.e. the annotated frame (2026-07-30).
|
|
9776
|
+
* - `cropped` — the subject, tight. What "who is at the door" wants.
|
|
9777
|
+
* - `full` — the clean scene, no annotation. What "what is going on" wants.
|
|
9778
|
+
* - `boxed` — the scene WITH the detection boxes drawn, for verifying what
|
|
9779
|
+
* the pipeline actually saw.
|
|
9780
|
+
*/
|
|
9781
|
+
var NcMediaFrameSchema = _enum([
|
|
9782
|
+
"cropped",
|
|
9783
|
+
"full",
|
|
9784
|
+
"boxed"
|
|
9785
|
+
]);
|
|
9786
|
+
var NcMediaPolicySchema = object({
|
|
9787
|
+
attach: _enum([
|
|
9788
|
+
"best",
|
|
9789
|
+
"best-matching",
|
|
9790
|
+
"keyFrame",
|
|
9791
|
+
"none"
|
|
9792
|
+
]).default("best"),
|
|
9793
|
+
/** What the still shows. Absent = `cropped` (the historical `best` shape). */
|
|
9794
|
+
frame: NcMediaFrameSchema.optional(),
|
|
9795
|
+
/** Crop the attached still to the rule's condition-zone bbox (padded) —
|
|
9796
|
+
* "show me the ZONE", not the whole scene or the subject crop. */
|
|
9797
|
+
zoneCrop: boolean().optional(),
|
|
9798
|
+
/**
|
|
9799
|
+
* Also attach a short GIF cut from the stream broker's clip ring around the
|
|
9800
|
+
* event — NOT from the recording, so the camera does not have to be
|
|
9801
|
+
* recording, and the window sits AROUND the moment instead of a segment
|
|
9802
|
+
* behind it. Fail-closed: a window the ring does not cover contributes no
|
|
9803
|
+
* gif, never a failed notification.
|
|
9804
|
+
*/
|
|
9805
|
+
gif: boolean().optional(),
|
|
9806
|
+
/**
|
|
9807
|
+
* Also attach a short MP4 CLIP of the same cut. Same source and the same
|
|
9808
|
+
* fail-closed rule as `gif`. Prefer it where the backend takes video
|
|
9809
|
+
* (telegram, discord, zentik, webhook); backends that do not are handled by
|
|
9810
|
+
* the degrade engine, which drops the video and keeps the still.
|
|
9811
|
+
*/
|
|
9812
|
+
clip: boolean().optional(),
|
|
9813
|
+
/** Seconds of footage BEFORE / AFTER the event instant. Defaults 3 / 7. */
|
|
9814
|
+
clipPreRollSec: number().int().min(0).max(30).optional(),
|
|
9815
|
+
clipPostRollSec: number().int().min(0).max(30).optional(),
|
|
9816
|
+
/**
|
|
9817
|
+
* Which stream profile the footage is cut from. Absent = the CHEAPEST
|
|
9818
|
+
* assigned profile: a notification is watched on a phone, so the 4K
|
|
9819
|
+
* rendition would burn CPU to produce a file the client downscales anyway.
|
|
9820
|
+
* A profile that is not assigned falls back to the cheapest, and the render
|
|
9821
|
+
* reports which one actually ran.
|
|
9822
|
+
*/
|
|
9823
|
+
profile: CamProfileSchema.optional()
|
|
9824
|
+
});
|
|
9825
|
+
/**
|
|
9826
|
+
* Cooldown GRANULARITY over the subject's class — how much a fired
|
|
9827
|
+
* notification suppresses.
|
|
9828
|
+
* - `shared` (default, and the absent value) — one window for the whole
|
|
9829
|
+
* rule/scope: a cat silences the next dog for `cooldownSec`.
|
|
9830
|
+
* - `per-class` — an independent window per detected class, so cat→dog fires
|
|
9831
|
+
* at once and cat→cat still waits.
|
|
9832
|
+
*
|
|
9833
|
+
* AUDIO subjects are ALWAYS per-class regardless of this setting: a scream
|
|
9834
|
+
* must not be swallowed by a bark's window (the precedent this generalizes —
|
|
9835
|
+
* see `cooldownKey` in the rule engine).
|
|
9836
|
+
*/
|
|
9837
|
+
var NcThrottleGranularitySchema = _enum(["shared", "per-class"]);
|
|
9705
9838
|
/** Throttle — cooldown survives restarts (rebuilt from the outbox on boot). */
|
|
9706
9839
|
var NcThrottleSchema = object({
|
|
9707
9840
|
cooldownSec: number().int().min(0).max(86400).default(60),
|
|
9708
9841
|
/** `rule` = one shared cooldown; `rule-device` = per-camera cooldown. */
|
|
9709
|
-
scope: _enum(["rule", "rule-device"]).default("rule-device")
|
|
9842
|
+
scope: _enum(["rule", "rule-device"]).default("rule-device"),
|
|
9843
|
+
/**
|
|
9844
|
+
* Class granularity of the cooldown key. Optional rather than defaulted:
|
|
9845
|
+
* a Zod default does NOT run on the addon→addon cap path, so a persisted
|
|
9846
|
+
* rule authored before this field simply carries none — and the engine
|
|
9847
|
+
* reads absent as `shared`, the pre-existing behaviour.
|
|
9848
|
+
*/
|
|
9849
|
+
granularity: NcThrottleGranularitySchema.optional()
|
|
9710
9850
|
});
|
|
9711
9851
|
/** Client-supplied rule fields (server stamps id/createdBy/createdAt/updatedAt). */
|
|
9712
9852
|
var NcRuleInputSchema = object({
|
|
@@ -9715,7 +9855,19 @@ var NcRuleInputSchema = object({
|
|
|
9715
9855
|
delivery: NcDeliverySchema,
|
|
9716
9856
|
conditions: NcConditionsSchema.default({}),
|
|
9717
9857
|
schedule: NcScheduleSchema.optional(),
|
|
9718
|
-
|
|
9858
|
+
/** May be empty when `targetUsers` addresses at least one user — the
|
|
9859
|
+
* "at least one addressee" invariant is enforced by the provider, because
|
|
9860
|
+
* a cross-field refine here would break `NcRulePatchSchema.partial()`. */
|
|
9861
|
+
targets: array(NcRuleTargetSchema),
|
|
9862
|
+
/**
|
|
9863
|
+
* USERS this rule addresses in addition to `targets` (Phase 4). At fire
|
|
9864
|
+
* time each user fans out to the personal targets they own
|
|
9865
|
+
* (`config.ownerUserId`), filtered by that user's `allowedDevices` for the
|
|
9866
|
+
* firing camera — a user is never notified about a device they cannot open.
|
|
9867
|
+
* Per-user opt-outs (`disabledTargetIds`) still apply to the fanned-out
|
|
9868
|
+
* targets.
|
|
9869
|
+
*/
|
|
9870
|
+
targetUsers: array(string()).optional(),
|
|
9719
9871
|
media: NcMediaPolicySchema.default({ attach: "best" }),
|
|
9720
9872
|
throttle: NcThrottleSchema.default({
|
|
9721
9873
|
cooldownSec: 60,
|
|
@@ -9802,6 +9954,7 @@ var NcConditionDescriptorSchema = object({
|
|
|
9802
9954
|
"schedule",
|
|
9803
9955
|
"plateMatcher",
|
|
9804
9956
|
"packagePhase",
|
|
9957
|
+
"crossingSelect",
|
|
9805
9958
|
"polygonDraw",
|
|
9806
9959
|
"occupancy"
|
|
9807
9960
|
]),
|
|
@@ -9928,7 +10081,10 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
|
|
|
9928
10081
|
}), object({ results: array(NcTestResultSchema) }), {
|
|
9929
10082
|
kind: "mutation",
|
|
9930
10083
|
auth: "admin"
|
|
9931
|
-
}), method(object({}), object({
|
|
10084
|
+
}), method(object({}), object({
|
|
10085
|
+
catalog: array(NcConditionDescriptorSchema),
|
|
10086
|
+
taxonomy: NcTaxonomySchema.optional()
|
|
10087
|
+
})), method(object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), object({ entries: array(NcHistoryEntrySchema) }), { auth: "admin" });
|
|
9932
10088
|
/**
|
|
9933
10089
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
9934
10090
|
*
|
|
@@ -10937,6 +11093,28 @@ method(object({
|
|
|
10937
11093
|
}), object({ success: literal(true) }), {
|
|
10938
11094
|
kind: "mutation",
|
|
10939
11095
|
auth: "admin"
|
|
11096
|
+
}), method(object({
|
|
11097
|
+
deviceId: number(),
|
|
11098
|
+
/** Absent = the LOWEST assigned profile — a notification attachment is
|
|
11099
|
+
* watched on a phone, and the cheap rendition is the right default. */
|
|
11100
|
+
profile: CamProfileSchema.optional(),
|
|
11101
|
+
aroundMs: number(),
|
|
11102
|
+
preRollSec: number().min(0).max(20).default(3),
|
|
11103
|
+
postRollSec: number().min(0).max(20).default(5),
|
|
11104
|
+
format: _enum(["gif", "mp4"]).default("gif"),
|
|
11105
|
+
maxWidth: number().int().min(120).max(1920).default(480),
|
|
11106
|
+
/** GIF only — MP4 keeps the source cadence. */
|
|
11107
|
+
fps: number().int().min(1).max(15).default(5)
|
|
11108
|
+
}), object({
|
|
11109
|
+
base64: string(),
|
|
11110
|
+
mime: string(),
|
|
11111
|
+
bytes: number().int(),
|
|
11112
|
+
/** The profile actually rendered (what the default resolved to). */
|
|
11113
|
+
profile: CamProfileSchema,
|
|
11114
|
+
durationMs: number()
|
|
11115
|
+
}), {
|
|
11116
|
+
kind: "mutation",
|
|
11117
|
+
auth: "admin"
|
|
10940
11118
|
}), method(_void(), array(CameraStreamSchema).readonly()), method(_void(), array(ProfileSlotSchema).readonly()), method(object({ brokerId: string() }), BrokerStatsSchema), method(object({ brokerId: string() }), object({
|
|
10941
11119
|
probed: boolean(),
|
|
10942
11120
|
summary: string()
|
|
@@ -19011,7 +19189,10 @@ method(object({
|
|
|
19011
19189
|
}), method(object({
|
|
19012
19190
|
deviceId: number(),
|
|
19013
19191
|
caps: array(string()).readonly().optional()
|
|
19014
|
-
}), record(string(), unknown().nullable()))
|
|
19192
|
+
}), record(string(), unknown().nullable())), method(object({
|
|
19193
|
+
deviceIds: array(number()).readonly(),
|
|
19194
|
+
caps: array(string()).readonly().optional()
|
|
19195
|
+
}), record(string(), record(string(), unknown().nullable())));
|
|
19015
19196
|
method(object({ deviceId: number() }), record(string(), record(string(), unknown()))), method(object({
|
|
19016
19197
|
deviceId: number(),
|
|
19017
19198
|
capName: string()
|
|
@@ -19942,6 +20123,36 @@ var TargetKindSchema = object({
|
|
|
19942
20123
|
icon: string(),
|
|
19943
20124
|
/** Stamped by each provider so the concat-fanned catalog stays routable. */
|
|
19944
20125
|
addonId: string(),
|
|
20126
|
+
/**
|
|
20127
|
+
* URL of the kind's bundled BRAND icon, served by the providing addon over
|
|
20128
|
+
* its own `addon-routes` surface (`/addon/<addonId>/icons/<kind>`). Absent
|
|
20129
|
+
* when the addon bundles no icon for that kind — the client then falls back
|
|
20130
|
+
* to a neutral glyph rather than rendering the raw `icon` NAME as text.
|
|
20131
|
+
*
|
|
20132
|
+
* Root-relative on purpose: it resolves against whatever origin serves a web
|
|
20133
|
+
* client, and a native client joins it onto its own hub base.
|
|
20134
|
+
*
|
|
20135
|
+
* DECLARED here deliberately. It used to travel as an undeclared passthrough
|
|
20136
|
+
* field that survived only because the runtime cap-router forwards provider
|
|
20137
|
+
* output verbatim — so every consumer had to re-declare it by hand to stop
|
|
20138
|
+
* its own Zod parse from stripping it, and the whole arrangement would have
|
|
20139
|
+
* broken silently the moment output validation was tightened anywhere.
|
|
20140
|
+
*/
|
|
20141
|
+
iconUrl: string().optional(),
|
|
20142
|
+
/**
|
|
20143
|
+
* Media type of {@link iconUrl} (`image/svg+xml`, `image/png`, …).
|
|
20144
|
+
*
|
|
20145
|
+
* The server knows this and therefore says it, because the client cannot
|
|
20146
|
+
* safely guess: a React-Native client renders SVG and raster through two
|
|
20147
|
+
* DIFFERENT components (`react-native-svg` vs `expo-image` — expo-image does
|
|
20148
|
+
* not decode SVG on iOS/Android), so without this it silently fell back to a
|
|
20149
|
+
* placeholder glyph for every vector icon while the web build looked fine.
|
|
20150
|
+
*
|
|
20151
|
+
* Absent when {@link iconUrl} is absent, or for a legacy provider that has
|
|
20152
|
+
* not been updated — a client that cannot determine the type should prefer
|
|
20153
|
+
* its raster path, which is the safe default for an unknown image.
|
|
20154
|
+
*/
|
|
20155
|
+
iconMediaType: string().optional(),
|
|
19945
20156
|
configSchema: ConfigSchemaPassthrough,
|
|
19946
20157
|
supportsDiscovery: boolean(),
|
|
19947
20158
|
caps: TargetKindCapsSchema
|
|
@@ -20389,6 +20600,29 @@ var MotionEventSchema = object({
|
|
|
20389
20600
|
* Absent on legacy rows ⇒ treat as `pipeline`.
|
|
20390
20601
|
*/
|
|
20391
20602
|
var DetectionSourceSchema = _enum(["pipeline", "onboard"]);
|
|
20603
|
+
/**
|
|
20604
|
+
* The confirmed zone crossing that produced an object event. Present ONLY on
|
|
20605
|
+
* an event emitted BY a crossing (`zone.enter` / `zone.exit`); a movement-state
|
|
20606
|
+
* event (`object.entering` / `leaving` / `stationary` / `loitering`) and an
|
|
20607
|
+
* appearance event carry none, so a rule asking for a direction fails closed
|
|
20608
|
+
* on them.
|
|
20609
|
+
*
|
|
20610
|
+
* Exactly ONE crossing per event: the emitter turns each confirmed crossing
|
|
20611
|
+
* into its own event, so a frame in which a track enters A while leaving B
|
|
20612
|
+
* produces two events with two directions — never one ambiguous row.
|
|
20613
|
+
*
|
|
20614
|
+
* `zoneId` is load-bearing for an EXIT: the event's `zones` list is the
|
|
20615
|
+
* membership the box has NOW, and by definition it no longer contains the zone
|
|
20616
|
+
* that was just left. Without the id here, a zone-scoped rule could never match
|
|
20617
|
+
* the exit it asked for.
|
|
20618
|
+
*/
|
|
20619
|
+
var ZoneCrossingSchema = object({
|
|
20620
|
+
direction: _enum(["enter", "exit"]),
|
|
20621
|
+
/** Admin zone id crossed. */
|
|
20622
|
+
zoneId: string(),
|
|
20623
|
+
/** Zone display name at crossing time (falls back to the id). */
|
|
20624
|
+
zoneName: string().optional()
|
|
20625
|
+
});
|
|
20392
20626
|
var ObjectEventSchema = object({
|
|
20393
20627
|
...BaseEventFields,
|
|
20394
20628
|
kind: literal("object"),
|
|
@@ -20415,6 +20649,12 @@ var ObjectEventSchema = object({
|
|
|
20415
20649
|
zones: array(string()).readonly().optional(),
|
|
20416
20650
|
/** Omitted in slim projection. */
|
|
20417
20651
|
state: TrackStateSchema.optional(),
|
|
20652
|
+
/**
|
|
20653
|
+
* The zone crossing this event IS, when it is one. Absent on every other
|
|
20654
|
+
* event kind (movement state, appearance, package) — see
|
|
20655
|
+
* {@link ZoneCrossingSchema}. Omitted in slim projection.
|
|
20656
|
+
*/
|
|
20657
|
+
zoneCrossing: ZoneCrossingSchema.optional(),
|
|
20418
20658
|
/** Detection-frame dimensions in pixels — let consumers normalize the
|
|
20419
20659
|
* pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
|
|
20420
20660
|
frameWidth: number().optional(),
|
|
@@ -20673,6 +20913,15 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
20673
20913
|
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
20674
20914
|
kind: "mutation",
|
|
20675
20915
|
auth: "admin"
|
|
20916
|
+
}), method(RelocateMediaInputSchema, object({ jobId: string() }), {
|
|
20917
|
+
kind: "mutation",
|
|
20918
|
+
auth: "admin"
|
|
20919
|
+
}), method(object({}), array(RelocateJobSchema).readonly(), {
|
|
20920
|
+
kind: "query",
|
|
20921
|
+
auth: "admin"
|
|
20922
|
+
}), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
|
|
20923
|
+
kind: "mutation",
|
|
20924
|
+
auth: "admin"
|
|
20676
20925
|
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
20677
20926
|
kind: "query",
|
|
20678
20927
|
auth: "admin"
|
|
@@ -23254,6 +23503,17 @@ var GetConnectionEndpointsResultSchema = object({ endpoints: array(object({
|
|
|
23254
23503
|
*/
|
|
23255
23504
|
priority: number()
|
|
23256
23505
|
})).readonly() });
|
|
23506
|
+
/**
|
|
23507
|
+
* The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
|
|
23508
|
+
* AUTO (resolved from the candidate ranking at send time); `resolved` reports
|
|
23509
|
+
* what AUTO currently picks, so the UI can show the effective value either way.
|
|
23510
|
+
*/
|
|
23511
|
+
var NotificationEndpointSchema = object({
|
|
23512
|
+
/** The operator's explicit choice, or null for AUTO. */
|
|
23513
|
+
baseUrl: string().nullable(),
|
|
23514
|
+
/** What the ranking currently resolves to (null when nothing is reachable). */
|
|
23515
|
+
resolved: string().nullable()
|
|
23516
|
+
});
|
|
23257
23517
|
var AllowedAddressesSchema = object({
|
|
23258
23518
|
/**
|
|
23259
23519
|
* Allowlist of interface addresses operators have explicitly opted
|
|
@@ -23276,7 +23536,7 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
23276
23536
|
* to avoid mixed-content blocks in the browser. The public
|
|
23277
23537
|
* tunnel always emits `https://` regardless. */
|
|
23278
23538
|
scheme: _enum(["http", "https"]).optional()
|
|
23279
|
-
}), GetConnectionEndpointsResultSchema), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" });
|
|
23539
|
+
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" });
|
|
23280
23540
|
/**
|
|
23281
23541
|
* mesh-network — collection cap for mesh-VPN providers.
|
|
23282
23542
|
*
|
|
@@ -24142,7 +24402,12 @@ var RecordingDeviceUsageSchema = object({
|
|
|
24142
24402
|
var RecordingLocationUsageSchema = object({
|
|
24143
24403
|
/** StorageLocation id; null for the legacy/degraded single-root fallback. */
|
|
24144
24404
|
locationId: string().nullable(),
|
|
24145
|
-
/**
|
|
24405
|
+
/** Every location id sharing this row's PHYSICAL volume (aliases). One row
|
|
24406
|
+
* is emitted per physical disk (2026-07-29): two locations on one root
|
|
24407
|
+
* previously rendered as two identical "disks" with a nonsensical used
|
|
24408
|
+
* split — hydrate attribution across aliases is arbitrary by nature. */
|
|
24409
|
+
locationIds: array(string()).optional(),
|
|
24410
|
+
/** Bytes of recordings stored on this PHYSICAL volume (all aliases). */
|
|
24146
24411
|
usedBytes: number(),
|
|
24147
24412
|
/** Free bytes on the location's volume; null when capacity is unknown (remote). */
|
|
24148
24413
|
availableBytes: number().nullable(),
|
|
@@ -24254,6 +24519,44 @@ method(object({
|
|
|
24254
24519
|
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
24255
24520
|
kind: "query",
|
|
24256
24521
|
auth: "admin"
|
|
24522
|
+
}), method(object({
|
|
24523
|
+
deviceId: number(),
|
|
24524
|
+
aroundMs: number(),
|
|
24525
|
+
preRollSec: number().min(0).max(30).default(2),
|
|
24526
|
+
postRollSec: number().min(0).max(30).default(5),
|
|
24527
|
+
maxWidth: number().int().min(120).max(1280).default(480),
|
|
24528
|
+
fps: number().int().min(1).max(15).default(5)
|
|
24529
|
+
}), object({
|
|
24530
|
+
gifBase64: string(),
|
|
24531
|
+
fromMs: number(),
|
|
24532
|
+
toMs: number()
|
|
24533
|
+
}), {
|
|
24534
|
+
kind: "mutation",
|
|
24535
|
+
auth: "admin"
|
|
24536
|
+
}), method(object({
|
|
24537
|
+
deviceId: number(),
|
|
24538
|
+
aroundMs: number(),
|
|
24539
|
+
preRollSec: number().min(0).max(30).default(3),
|
|
24540
|
+
postRollSec: number().min(0).max(30).default(7),
|
|
24541
|
+
maxWidth: number().int().min(160).max(1920).default(640)
|
|
24542
|
+
}), object({
|
|
24543
|
+
clipBase64: string(),
|
|
24544
|
+
mime: string(),
|
|
24545
|
+
fromMs: number(),
|
|
24546
|
+
toMs: number(),
|
|
24547
|
+
bytes: number().int()
|
|
24548
|
+
}), {
|
|
24549
|
+
kind: "mutation",
|
|
24550
|
+
auth: "admin"
|
|
24551
|
+
}), method(RelocateFootageInputSchema, object({ jobId: string() }), {
|
|
24552
|
+
kind: "mutation",
|
|
24553
|
+
auth: "admin"
|
|
24554
|
+
}), method(object({}), array(RelocateJobSchema).readonly(), {
|
|
24555
|
+
kind: "query",
|
|
24556
|
+
auth: "admin"
|
|
24557
|
+
}), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
|
|
24558
|
+
kind: "mutation",
|
|
24559
|
+
auth: "admin"
|
|
24257
24560
|
});
|
|
24258
24561
|
/**
|
|
24259
24562
|
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
@@ -26056,6 +26359,12 @@ Object.freeze({
|
|
|
26056
26359
|
addonId: null,
|
|
26057
26360
|
access: "view"
|
|
26058
26361
|
},
|
|
26362
|
+
"deviceManager.getDeviceStatusAggregateBatch": {
|
|
26363
|
+
capName: "device-manager",
|
|
26364
|
+
capScope: "system",
|
|
26365
|
+
addonId: null,
|
|
26366
|
+
access: "view"
|
|
26367
|
+
},
|
|
26059
26368
|
"deviceManager.getLinkedDevices": {
|
|
26060
26369
|
capName: "device-manager",
|
|
26061
26370
|
capScope: "system",
|
|
@@ -26950,6 +27259,12 @@ Object.freeze({
|
|
|
26950
27259
|
addonId: null,
|
|
26951
27260
|
access: "view"
|
|
26952
27261
|
},
|
|
27262
|
+
"localNetwork.getNotificationEndpoint": {
|
|
27263
|
+
capName: "local-network",
|
|
27264
|
+
capScope: "system",
|
|
27265
|
+
addonId: null,
|
|
27266
|
+
access: "view"
|
|
27267
|
+
},
|
|
26953
27268
|
"localNetwork.getPreferred": {
|
|
26954
27269
|
capName: "local-network",
|
|
26955
27270
|
capScope: "system",
|
|
@@ -26974,6 +27289,12 @@ Object.freeze({
|
|
|
26974
27289
|
addonId: null,
|
|
26975
27290
|
access: "create"
|
|
26976
27291
|
},
|
|
27292
|
+
"localNetwork.setNotificationEndpoint": {
|
|
27293
|
+
capName: "local-network",
|
|
27294
|
+
capScope: "system",
|
|
27295
|
+
addonId: null,
|
|
27296
|
+
access: "create"
|
|
27297
|
+
},
|
|
26977
27298
|
"lockControl.lock": {
|
|
26978
27299
|
capName: "lock-control",
|
|
26979
27300
|
capScope: "device",
|
|
@@ -27616,6 +27937,12 @@ Object.freeze({
|
|
|
27616
27937
|
addonId: null,
|
|
27617
27938
|
access: "create"
|
|
27618
27939
|
},
|
|
27940
|
+
"pipelineAnalytics.cancelMediaRelocate": {
|
|
27941
|
+
capName: "pipeline-analytics",
|
|
27942
|
+
capScope: "device",
|
|
27943
|
+
addonId: null,
|
|
27944
|
+
access: "create"
|
|
27945
|
+
},
|
|
27619
27946
|
"pipelineAnalytics.clearTracks": {
|
|
27620
27947
|
capName: "pipeline-analytics",
|
|
27621
27948
|
capScope: "device",
|
|
@@ -27670,6 +27997,12 @@ Object.freeze({
|
|
|
27670
27997
|
addonId: null,
|
|
27671
27998
|
access: "view"
|
|
27672
27999
|
},
|
|
28000
|
+
"pipelineAnalytics.getMediaRelocateStatus": {
|
|
28001
|
+
capName: "pipeline-analytics",
|
|
28002
|
+
capScope: "device",
|
|
28003
|
+
addonId: null,
|
|
28004
|
+
access: "view"
|
|
28005
|
+
},
|
|
27673
28006
|
"pipelineAnalytics.getMotionEvents": {
|
|
27674
28007
|
capName: "pipeline-analytics",
|
|
27675
28008
|
capScope: "device",
|
|
@@ -27742,6 +28075,12 @@ Object.freeze({
|
|
|
27742
28075
|
addonId: null,
|
|
27743
28076
|
access: "create"
|
|
27744
28077
|
},
|
|
28078
|
+
"pipelineAnalytics.relocateMedia": {
|
|
28079
|
+
capName: "pipeline-analytics",
|
|
28080
|
+
capScope: "device",
|
|
28081
|
+
addonId: null,
|
|
28082
|
+
access: "create"
|
|
28083
|
+
},
|
|
27745
28084
|
"pipelineAnalytics.searchObjectEvents": {
|
|
27746
28085
|
capName: "pipeline-analytics",
|
|
27747
28086
|
capScope: "device",
|
|
@@ -28504,6 +28843,12 @@ Object.freeze({
|
|
|
28504
28843
|
addonId: null,
|
|
28505
28844
|
access: "create"
|
|
28506
28845
|
},
|
|
28846
|
+
"recording.cancelRelocate": {
|
|
28847
|
+
capName: "recording",
|
|
28848
|
+
capScope: "system",
|
|
28849
|
+
addonId: null,
|
|
28850
|
+
access: "create"
|
|
28851
|
+
},
|
|
28507
28852
|
"recording.deleteFootprint": {
|
|
28508
28853
|
capName: "recording",
|
|
28509
28854
|
capScope: "system",
|
|
@@ -28534,6 +28879,12 @@ Object.freeze({
|
|
|
28534
28879
|
addonId: null,
|
|
28535
28880
|
access: "view"
|
|
28536
28881
|
},
|
|
28882
|
+
"recording.getRelocateStatus": {
|
|
28883
|
+
capName: "recording",
|
|
28884
|
+
capScope: "system",
|
|
28885
|
+
addonId: null,
|
|
28886
|
+
access: "view"
|
|
28887
|
+
},
|
|
28537
28888
|
"recording.getStorageUsage": {
|
|
28538
28889
|
capName: "recording",
|
|
28539
28890
|
capScope: "system",
|
|
@@ -28564,6 +28915,24 @@ Object.freeze({
|
|
|
28564
28915
|
addonId: null,
|
|
28565
28916
|
access: "view"
|
|
28566
28917
|
},
|
|
28918
|
+
"recording.relocateFootage": {
|
|
28919
|
+
capName: "recording",
|
|
28920
|
+
capScope: "system",
|
|
28921
|
+
addonId: null,
|
|
28922
|
+
access: "create"
|
|
28923
|
+
},
|
|
28924
|
+
"recording.renderClip": {
|
|
28925
|
+
capName: "recording",
|
|
28926
|
+
capScope: "system",
|
|
28927
|
+
addonId: null,
|
|
28928
|
+
access: "create"
|
|
28929
|
+
},
|
|
28930
|
+
"recording.renderGif": {
|
|
28931
|
+
capName: "recording",
|
|
28932
|
+
capScope: "system",
|
|
28933
|
+
addonId: null,
|
|
28934
|
+
access: "create"
|
|
28935
|
+
},
|
|
28567
28936
|
"recording.rescanStorage": {
|
|
28568
28937
|
capName: "recording",
|
|
28569
28938
|
capScope: "system",
|
|
@@ -29158,6 +29527,12 @@ Object.freeze({
|
|
|
29158
29527
|
addonId: null,
|
|
29159
29528
|
access: "create"
|
|
29160
29529
|
},
|
|
29530
|
+
"streamBroker.renderPreBufferClip": {
|
|
29531
|
+
capName: "stream-broker",
|
|
29532
|
+
capScope: "system",
|
|
29533
|
+
addonId: null,
|
|
29534
|
+
access: "create"
|
|
29535
|
+
},
|
|
29161
29536
|
"streamBroker.restartProfile": {
|
|
29162
29537
|
capName: "stream-broker",
|
|
29163
29538
|
capScope: "system",
|