camstack 1.2.10 → 1.2.12
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.
|
@@ -14522,7 +14522,7 @@ function date4(params) {
|
|
|
14522
14522
|
// ../../node_modules/zod/v4/classic/external.js
|
|
14523
14523
|
config(en_default());
|
|
14524
14524
|
|
|
14525
|
-
// ../types/dist/sleep-
|
|
14525
|
+
// ../types/dist/sleep-B_Uaqbai.mjs
|
|
14526
14526
|
var WELL_KNOWN_TABS = [
|
|
14527
14527
|
{
|
|
14528
14528
|
id: "overview",
|
|
@@ -15504,18 +15504,6 @@ var ConvertResultSchema = external_exports.object({
|
|
|
15504
15504
|
});
|
|
15505
15505
|
var RecordingWeekdaySchema = external_exports.number().int().min(0).max(6);
|
|
15506
15506
|
var HHMM = /^([01]\d|2[0-3]):[0-5]\d$/;
|
|
15507
|
-
var RecordingScheduleSchema = external_exports.discriminatedUnion("kind", [external_exports.object({ kind: external_exports.literal("always") }), external_exports.object({
|
|
15508
|
-
kind: external_exports.literal("timeOfDay"),
|
|
15509
|
-
start: external_exports.string().regex(HHMM),
|
|
15510
|
-
end: external_exports.string().regex(HHMM),
|
|
15511
|
-
/** Restrict to these weekdays; omit = every day. */
|
|
15512
|
-
days: external_exports.array(RecordingWeekdaySchema).optional()
|
|
15513
|
-
})]);
|
|
15514
|
-
var RecordingModeSchema = external_exports.enum([
|
|
15515
|
-
"continuous",
|
|
15516
|
-
"onMotion",
|
|
15517
|
-
"onAudioThreshold"
|
|
15518
|
-
]);
|
|
15519
15507
|
var RecordingStorageModeSchema = external_exports.enum([
|
|
15520
15508
|
"off",
|
|
15521
15509
|
"events",
|
|
@@ -15536,18 +15524,6 @@ var RecordingBandSchema = external_exports.object({
|
|
|
15536
15524
|
preBufferSec: external_exports.number().min(0).optional(),
|
|
15537
15525
|
postBufferSec: external_exports.number().min(0).optional()
|
|
15538
15526
|
});
|
|
15539
|
-
var RecordingRuleSchema = external_exports.object({
|
|
15540
|
-
schedule: RecordingScheduleSchema,
|
|
15541
|
-
mode: RecordingModeSchema,
|
|
15542
|
-
/** Seconds of footage to retain BEFORE a trigger (applied at keep/discard). */
|
|
15543
|
-
preBufferSec: external_exports.number().min(0).default(0),
|
|
15544
|
-
/** Keep recording until this many seconds after the last trigger. */
|
|
15545
|
-
postBufferSec: external_exports.number().min(0).default(0),
|
|
15546
|
-
/** Each new trigger restarts the post-buffer window. */
|
|
15547
|
-
resetTimeoutOnNewEvent: external_exports.boolean().default(true),
|
|
15548
|
-
/** onAudioThreshold only — dBFS level that counts as a trigger. */
|
|
15549
|
-
thresholdDbfs: external_exports.number().optional()
|
|
15550
|
-
});
|
|
15551
15527
|
var RecordingRetentionSchema = external_exports.object({
|
|
15552
15528
|
maxAgeDays: external_exports.number().min(0).optional(),
|
|
15553
15529
|
maxSizeGb: external_exports.number().min(0).optional()
|
|
@@ -15561,33 +15537,17 @@ var ScrubThumbnailPresetSchema = external_exports.enum([
|
|
|
15561
15537
|
]);
|
|
15562
15538
|
var RecordingConfigSchema = external_exports.object({
|
|
15563
15539
|
enabled: external_exports.boolean(),
|
|
15564
|
-
/**
|
|
15565
|
-
*
|
|
15540
|
+
/** DERIVED summary of `bands`, stamped by the recorder on every save.
|
|
15541
|
+
* Authoring it has no effect — see {@link RecordingStorageModeSchema}. */
|
|
15566
15542
|
mode: RecordingStorageModeSchema.optional(),
|
|
15567
15543
|
profiles: external_exports.array(CamProfileSchema).optional(),
|
|
15568
15544
|
segmentSeconds: external_exports.number().int().positive().optional(),
|
|
15569
|
-
/** Shared recording time-bands for `events` & `continuous` — record only when
|
|
15570
|
-
* the wall-clock falls inside one of these windows. Omit or empty = always.
|
|
15571
|
-
* `continuous` compiles to one rule per band; `events` to band × trigger. */
|
|
15572
|
-
schedules: external_exports.array(RecordingScheduleSchema).optional(),
|
|
15573
|
-
/** Legacy single-band predecessor of `schedules`. Read-compat only — it is
|
|
15574
|
-
* normalized into `schedules` on read and never written going forward. (Not
|
|
15575
|
-
* tagged `@deprecated`: the normalization paths must read it cast-free.) */
|
|
15576
|
-
schedule: RecordingScheduleSchema.optional(),
|
|
15577
|
-
/** `events`-mode only — which detectors trigger a recording. */
|
|
15578
|
-
triggers: RecordingTriggersSchema.optional(),
|
|
15579
|
-
/** `events`-mode only — seconds retained before / after a trigger. */
|
|
15580
|
-
preBufferSec: external_exports.number().min(0).optional(),
|
|
15581
|
-
postBufferSec: external_exports.number().min(0).optional(),
|
|
15582
|
-
/** DEPRECATED authoring input; retained for migration/transition. */
|
|
15583
|
-
rules: external_exports.array(RecordingRuleSchema).optional(),
|
|
15584
15545
|
/**
|
|
15585
|
-
* AUTHORITATIVE mode-per-band recording model
|
|
15586
|
-
*
|
|
15587
|
-
*
|
|
15588
|
-
* derived into bands once via `migrateConfigToBands`.
|
|
15546
|
+
* AUTHORITATIVE mode-per-band recording model — the single source of truth
|
|
15547
|
+
* the recorder's band engine consumes. An empty array = record nothing;
|
|
15548
|
+
* "off" is the absence of a covering band, never a band value.
|
|
15589
15549
|
*/
|
|
15590
|
-
bands: external_exports.array(RecordingBandSchema).
|
|
15550
|
+
bands: external_exports.array(RecordingBandSchema).default([]),
|
|
15591
15551
|
retention: RecordingRetentionSchema.optional(),
|
|
15592
15552
|
/**
|
|
15593
15553
|
* Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
|
|
@@ -15595,14 +15555,22 @@ var RecordingConfigSchema = external_exports.object({
|
|
|
15595
15555
|
* windows only — existing sheets are immutable, and each window's index
|
|
15596
15556
|
* carries its own tile dims so mixed-preset history renders correctly.
|
|
15597
15557
|
*/
|
|
15598
|
-
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
15599
|
-
|
|
15558
|
+
scrubThumbnails: ScrubThumbnailPresetSchema.optional(),
|
|
15559
|
+
/**
|
|
15560
|
+
* OPT-IN thumbnail-strip generation for this camera: every keyframe of the
|
|
15561
|
+
* low recording saved as a JPEG (the fast-drag scrub depth), a derived
|
|
15562
|
+
* cache that eviction reclaims with the footage. Absent/false = no strips
|
|
15563
|
+
* are written and scrub reads exact keyframes at every velocity.
|
|
15564
|
+
*/
|
|
15565
|
+
stripsEnabled: external_exports.boolean().optional()
|
|
15566
|
+
}).strict();
|
|
15600
15567
|
var OpsLogDomainSchema = external_exports.enum(["recording", "events"]);
|
|
15601
15568
|
var OpsLogOpSchema = external_exports.enum([
|
|
15602
15569
|
"prune",
|
|
15603
15570
|
"manual-delete",
|
|
15604
15571
|
"rescan",
|
|
15605
|
-
"retention-run"
|
|
15572
|
+
"retention-run",
|
|
15573
|
+
"relocate"
|
|
15606
15574
|
]);
|
|
15607
15575
|
var OpsLogReasonSchema = external_exports.enum([
|
|
15608
15576
|
"retention",
|
|
@@ -15637,6 +15605,45 @@ var OpsLogQueryInputSchema = external_exports.object({
|
|
|
15637
15605
|
/** Max rows returned, newest-first. */
|
|
15638
15606
|
limit: external_exports.number().int().min(1).max(1e3).optional()
|
|
15639
15607
|
});
|
|
15608
|
+
var RelocateJobStateSchema = external_exports.enum([
|
|
15609
|
+
"running",
|
|
15610
|
+
"done",
|
|
15611
|
+
"failed",
|
|
15612
|
+
"cancelled"
|
|
15613
|
+
]);
|
|
15614
|
+
var RelocateJobSchema = external_exports.object({
|
|
15615
|
+
jobId: external_exports.string(),
|
|
15616
|
+
state: RelocateJobStateSchema,
|
|
15617
|
+
/** Source location — for media relocation this is informational ('*': rows
|
|
15618
|
+
* move from wherever they are to the target). */
|
|
15619
|
+
fromLocationId: external_exports.string(),
|
|
15620
|
+
toLocationId: external_exports.string(),
|
|
15621
|
+
/** Scoped device, or null = every device. */
|
|
15622
|
+
deviceId: external_exports.number().nullable(),
|
|
15623
|
+
/** What the job moves (owner-addon specific: segments/strips or media). */
|
|
15624
|
+
entities: external_exports.array(external_exports.string()),
|
|
15625
|
+
filesMoved: external_exports.number().int(),
|
|
15626
|
+
bytesMoved: external_exports.number().int(),
|
|
15627
|
+
/** Total files discovered up front; null while (or when) unknown. */
|
|
15628
|
+
filesTotal: external_exports.number().int().nullable(),
|
|
15629
|
+
startedAt: external_exports.number(),
|
|
15630
|
+
finishedAt: external_exports.number().nullable(),
|
|
15631
|
+
error: external_exports.string().nullable()
|
|
15632
|
+
});
|
|
15633
|
+
var RelocateFootageInputSchema = external_exports.object({
|
|
15634
|
+
deviceId: external_exports.number().optional(),
|
|
15635
|
+
fromLocationId: external_exports.string(),
|
|
15636
|
+
toLocationId: external_exports.string(),
|
|
15637
|
+
entities: external_exports.array(external_exports.enum(["segments", "strips"])).optional(),
|
|
15638
|
+
/** Copy throttle in MB/s (default 40) — the drain is a background chore,
|
|
15639
|
+
* never allowed to starve live writers. */
|
|
15640
|
+
throttleMbps: external_exports.number().min(1).max(1e3).optional()
|
|
15641
|
+
});
|
|
15642
|
+
var RelocateMediaInputSchema = external_exports.object({
|
|
15643
|
+
deviceId: external_exports.number().optional(),
|
|
15644
|
+
toLocationId: external_exports.string(),
|
|
15645
|
+
throttleMbps: external_exports.number().min(1).max(1e3).optional()
|
|
15646
|
+
});
|
|
15640
15647
|
var StorageLocationTypeSchema = external_exports.string().regex(/^[a-z][a-zA-Z0-9-]*$/);
|
|
15641
15648
|
var StorageLocationSchema = external_exports.object({
|
|
15642
15649
|
id: external_exports.string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
|
|
@@ -15654,6 +15661,13 @@ var StorageLocationSchema = external_exports.object({
|
|
|
15654
15661
|
nodeId: external_exports.string().optional(),
|
|
15655
15662
|
isDefault: external_exports.boolean().default(false),
|
|
15656
15663
|
isSystem: external_exports.boolean().default(false),
|
|
15664
|
+
/** COMPUTED at read time by the orchestrator (statfs of the backing volume
|
|
15665
|
+
* for node-local locations it can reach) — never persisted, absent when the
|
|
15666
|
+
* volume is remote/unreachable. The single capacity truth every UI reads. */
|
|
15667
|
+
capacity: external_exports.object({
|
|
15668
|
+
totalBytes: external_exports.number(),
|
|
15669
|
+
availableBytes: external_exports.number()
|
|
15670
|
+
}).nullable().optional(),
|
|
15657
15671
|
createdAt: external_exports.number(),
|
|
15658
15672
|
updatedAt: external_exports.number()
|
|
15659
15673
|
});
|
|
@@ -15687,16 +15701,23 @@ var StorageLocationDeclarationSchema = external_exports.object({
|
|
|
15687
15701
|
* Which node root the seeded `<id>:default` instance is placed under on a
|
|
15688
15702
|
* FRESH install:
|
|
15689
15703
|
* - `'data'` (default) — the node's data dir (`CAMSTACK_DATA` / boot dir),
|
|
15690
|
-
* the appData volume. Right for small/durable data (
|
|
15704
|
+
* the appData volume. Right for small/durable data (logs, models).
|
|
15691
15705
|
* - `'media'` — the dedicated media volume (`CAMSTACK_MEDIA_ROOT`) when that
|
|
15692
15706
|
* env is set, else falls back to the data root. Right for bulky, hot media
|
|
15693
15707
|
* (recordings, event media) that should stay off the appData disk.
|
|
15708
|
+
* - `'backup'` — the dedicated backup volume (`CAMSTACK_BACKUP_ROOT`, default
|
|
15709
|
+
* `/backups` in the image) so archives live on their own mount rather than
|
|
15710
|
+
* filling the appData disk. Falls back to the data root when unset.
|
|
15694
15711
|
*
|
|
15695
15712
|
* Only affects the seeded default's `basePath`; operators can repoint any
|
|
15696
15713
|
* location afterwards, and a `defaultsTo` slot inherits its parent's root
|
|
15697
15714
|
* regardless of this field. Absent (the common case) is treated as `'data'`.
|
|
15698
15715
|
*/
|
|
15699
|
-
defaultRoot: external_exports.enum([
|
|
15716
|
+
defaultRoot: external_exports.enum([
|
|
15717
|
+
"data",
|
|
15718
|
+
"media",
|
|
15719
|
+
"backup"
|
|
15720
|
+
]).optional()
|
|
15700
15721
|
});
|
|
15701
15722
|
var DecoderStatsSchema = external_exports.object({
|
|
15702
15723
|
inputFps: external_exports.number(),
|
|
@@ -16914,6 +16935,8 @@ var BATTERY_DEVICE_PROFILE = {
|
|
|
16914
16935
|
"streamBroker.preBufferEnabled": false
|
|
16915
16936
|
}
|
|
16916
16937
|
};
|
|
16938
|
+
var NC_BASE_CONDITION_KEYS = ["devices", "classes"];
|
|
16939
|
+
var BASE_CONDITION_SET = new Set(NC_BASE_CONDITION_KEYS);
|
|
16917
16940
|
var MaskPointSchema = external_exports.object({
|
|
16918
16941
|
x: external_exports.number(),
|
|
16919
16942
|
y: external_exports.number()
|
|
@@ -16997,6 +17020,11 @@ var NcOccupancyConditionSchema = external_exports.object({
|
|
|
16997
17020
|
count: external_exports.number().int().min(0).default(1),
|
|
16998
17021
|
sustainSeconds: external_exports.number().int().min(0).max(3600).default(15)
|
|
16999
17022
|
});
|
|
17023
|
+
var NcCrossingSchema = external_exports.enum([
|
|
17024
|
+
"enter",
|
|
17025
|
+
"exit",
|
|
17026
|
+
"any"
|
|
17027
|
+
]);
|
|
17000
17028
|
var NcZoneConditionSchema = external_exports.object({
|
|
17001
17029
|
ids: external_exports.array(external_exports.string().min(1)).min(1),
|
|
17002
17030
|
/** Quantifier over `ids` — at least one / every one visited. */
|
|
@@ -17016,6 +17044,13 @@ var NcConditionsSchema = external_exports.object({
|
|
|
17016
17044
|
/** Veto zones — any hit fails the rule. */
|
|
17017
17045
|
zonesExclude: external_exports.array(external_exports.string().min(1)).optional(),
|
|
17018
17046
|
/**
|
|
17047
|
+
* Zone-crossing direction. IMMEDIATE only — a crossing is a per-event fact
|
|
17048
|
+
* and a closed track carries none, so a `track-end` rule asking for one
|
|
17049
|
+
* fails closed (use `zones`, which tests `zonesVisited`). ABSENT = `enter`,
|
|
17050
|
+
* which is exactly today's behaviour. See {@link NcCrossingSchema}.
|
|
17051
|
+
*/
|
|
17052
|
+
crossing: NcCrossingSchema.optional(),
|
|
17053
|
+
/**
|
|
17019
17054
|
* Exact (case-insensitive) match on the record's collapsed `label`
|
|
17020
17055
|
* (identity name / plate text / subclass).
|
|
17021
17056
|
*/
|
|
@@ -17136,16 +17171,62 @@ var NcRuleTargetSchema = external_exports.object({
|
|
|
17136
17171
|
*/
|
|
17137
17172
|
params: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
17138
17173
|
});
|
|
17139
|
-
var
|
|
17140
|
-
"
|
|
17141
|
-
"
|
|
17142
|
-
"
|
|
17143
|
-
|
|
17144
|
-
|
|
17174
|
+
var NcMediaFrameSchema = external_exports.enum([
|
|
17175
|
+
"cropped",
|
|
17176
|
+
"full",
|
|
17177
|
+
"boxed"
|
|
17178
|
+
]);
|
|
17179
|
+
var NcMediaPolicySchema = external_exports.object({
|
|
17180
|
+
attach: external_exports.enum([
|
|
17181
|
+
"best",
|
|
17182
|
+
"best-matching",
|
|
17183
|
+
"keyFrame",
|
|
17184
|
+
"none"
|
|
17185
|
+
]).default("best"),
|
|
17186
|
+
/** What the still shows. Absent = `cropped` (the historical `best` shape). */
|
|
17187
|
+
frame: NcMediaFrameSchema.optional(),
|
|
17188
|
+
/** Crop the attached still to the rule's condition-zone bbox (padded) —
|
|
17189
|
+
* "show me the ZONE", not the whole scene or the subject crop. */
|
|
17190
|
+
zoneCrop: external_exports.boolean().optional(),
|
|
17191
|
+
/**
|
|
17192
|
+
* Also attach a short GIF cut from the stream broker's clip ring around the
|
|
17193
|
+
* event — NOT from the recording, so the camera does not have to be
|
|
17194
|
+
* recording, and the window sits AROUND the moment instead of a segment
|
|
17195
|
+
* behind it. Fail-closed: a window the ring does not cover contributes no
|
|
17196
|
+
* gif, never a failed notification.
|
|
17197
|
+
*/
|
|
17198
|
+
gif: external_exports.boolean().optional(),
|
|
17199
|
+
/**
|
|
17200
|
+
* Also attach a short MP4 CLIP of the same cut. Same source and the same
|
|
17201
|
+
* fail-closed rule as `gif`. Prefer it where the backend takes video
|
|
17202
|
+
* (telegram, discord, zentik, webhook); backends that do not are handled by
|
|
17203
|
+
* the degrade engine, which drops the video and keeps the still.
|
|
17204
|
+
*/
|
|
17205
|
+
clip: external_exports.boolean().optional(),
|
|
17206
|
+
/** Seconds of footage BEFORE / AFTER the event instant. Defaults 3 / 7. */
|
|
17207
|
+
clipPreRollSec: external_exports.number().int().min(0).max(30).optional(),
|
|
17208
|
+
clipPostRollSec: external_exports.number().int().min(0).max(30).optional(),
|
|
17209
|
+
/**
|
|
17210
|
+
* Which stream profile the footage is cut from. Absent = the CHEAPEST
|
|
17211
|
+
* assigned profile: a notification is watched on a phone, so the 4K
|
|
17212
|
+
* rendition would burn CPU to produce a file the client downscales anyway.
|
|
17213
|
+
* A profile that is not assigned falls back to the cheapest, and the render
|
|
17214
|
+
* reports which one actually ran.
|
|
17215
|
+
*/
|
|
17216
|
+
profile: CamProfileSchema.optional()
|
|
17217
|
+
});
|
|
17218
|
+
var NcThrottleGranularitySchema = external_exports.enum(["shared", "per-class"]);
|
|
17145
17219
|
var NcThrottleSchema = external_exports.object({
|
|
17146
17220
|
cooldownSec: external_exports.number().int().min(0).max(86400).default(60),
|
|
17147
17221
|
/** `rule` = one shared cooldown; `rule-device` = per-camera cooldown. */
|
|
17148
|
-
scope: external_exports.enum(["rule", "rule-device"]).default("rule-device")
|
|
17222
|
+
scope: external_exports.enum(["rule", "rule-device"]).default("rule-device"),
|
|
17223
|
+
/**
|
|
17224
|
+
* Class granularity of the cooldown key. Optional rather than defaulted:
|
|
17225
|
+
* a Zod default does NOT run on the addon→addon cap path, so a persisted
|
|
17226
|
+
* rule authored before this field simply carries none — and the engine
|
|
17227
|
+
* reads absent as `shared`, the pre-existing behaviour.
|
|
17228
|
+
*/
|
|
17229
|
+
granularity: NcThrottleGranularitySchema.optional()
|
|
17149
17230
|
});
|
|
17150
17231
|
var NcRuleInputSchema = external_exports.object({
|
|
17151
17232
|
name: external_exports.string().min(1).max(200),
|
|
@@ -17153,7 +17234,19 @@ var NcRuleInputSchema = external_exports.object({
|
|
|
17153
17234
|
delivery: NcDeliverySchema,
|
|
17154
17235
|
conditions: NcConditionsSchema.default({}),
|
|
17155
17236
|
schedule: NcScheduleSchema.optional(),
|
|
17156
|
-
|
|
17237
|
+
/** May be empty when `targetUsers` addresses at least one user — the
|
|
17238
|
+
* "at least one addressee" invariant is enforced by the provider, because
|
|
17239
|
+
* a cross-field refine here would break `NcRulePatchSchema.partial()`. */
|
|
17240
|
+
targets: external_exports.array(NcRuleTargetSchema),
|
|
17241
|
+
/**
|
|
17242
|
+
* USERS this rule addresses in addition to `targets` (Phase 4). At fire
|
|
17243
|
+
* time each user fans out to the personal targets they own
|
|
17244
|
+
* (`config.ownerUserId`), filtered by that user's `allowedDevices` for the
|
|
17245
|
+
* firing camera — a user is never notified about a device they cannot open.
|
|
17246
|
+
* Per-user opt-outs (`disabledTargetIds`) still apply to the fanned-out
|
|
17247
|
+
* targets.
|
|
17248
|
+
*/
|
|
17249
|
+
targetUsers: external_exports.array(external_exports.string()).optional(),
|
|
17157
17250
|
media: NcMediaPolicySchema.default({ attach: "best" }),
|
|
17158
17251
|
throttle: NcThrottleSchema.default({
|
|
17159
17252
|
cooldownSec: 60,
|
|
@@ -17230,6 +17323,7 @@ var NcConditionDescriptorSchema = external_exports.object({
|
|
|
17230
17323
|
"schedule",
|
|
17231
17324
|
"plateMatcher",
|
|
17232
17325
|
"packagePhase",
|
|
17326
|
+
"crossingSelect",
|
|
17233
17327
|
"polygonDraw",
|
|
17234
17328
|
"occupancy"
|
|
17235
17329
|
]),
|
|
@@ -17342,7 +17436,20 @@ var notificationRulesCapability = {
|
|
|
17342
17436
|
kind: "mutation",
|
|
17343
17437
|
auth: "admin"
|
|
17344
17438
|
}),
|
|
17345
|
-
|
|
17439
|
+
/**
|
|
17440
|
+
* The machine-readable condition surface a rule editor renders from, plus
|
|
17441
|
+
* the picker VOCABULARY those conditions draw on.
|
|
17442
|
+
*
|
|
17443
|
+
* `taxonomy` is optional so an older provider that only returns `catalog`
|
|
17444
|
+
* still validates; a client that receives none keeps free-text inputs.
|
|
17445
|
+
* It was previously served ONLY on the `nc.getConditionCatalog` bridge
|
|
17446
|
+
* action, which is why the viewer had grouped pickers and the admin UI —
|
|
17447
|
+
* which reaches this cap — was stuck typing `person` from memory.
|
|
17448
|
+
*/
|
|
17449
|
+
getConditionCatalog: method(external_exports.object({}), external_exports.object({
|
|
17450
|
+
catalog: external_exports.array(NcConditionDescriptorSchema),
|
|
17451
|
+
taxonomy: NcTaxonomySchema.optional()
|
|
17452
|
+
})),
|
|
17346
17453
|
/**
|
|
17347
17454
|
* Queryable delivery history — a read-only view over the durable outbox
|
|
17348
17455
|
* (fired rule, subject summary, target, status, timestamps, error on a
|
|
@@ -18212,6 +18319,48 @@ var streamBrokerCapability = {
|
|
|
18212
18319
|
kind: "mutation",
|
|
18213
18320
|
auth: "admin"
|
|
18214
18321
|
}),
|
|
18322
|
+
/**
|
|
18323
|
+
* Render a short GIF or MP4 from the broker's PRE-BUFFER around an instant.
|
|
18324
|
+
*
|
|
18325
|
+
* The pre-buffer is the only source that already holds the seconds BEFORE
|
|
18326
|
+
* an event (it is what it exists for — "when an addon needs the last N
|
|
18327
|
+
* seconds of video for clip creation"). Cutting from recorded segments
|
|
18328
|
+
* cannot: only finalized segments are addressable and the one covering the
|
|
18329
|
+
* moment is still being written, so a segment-sourced clip is either
|
|
18330
|
+
* delayed or shows the approach instead of the event (operator,
|
|
18331
|
+
* 2026-07-30). It also means a camera does not have to be RECORDING to
|
|
18332
|
+
* produce a notification clip.
|
|
18333
|
+
*
|
|
18334
|
+
* Returns muxed BYTES, never packets: the frame plane never crosses a
|
|
18335
|
+
* process boundary at frame rate (D9/D18) — this is one compressed,
|
|
18336
|
+
* on-demand payload per notification.
|
|
18337
|
+
*
|
|
18338
|
+
* Waits up to `postRollSec` for the tail to accumulate, so the window is
|
|
18339
|
+
* CENTRED on `aroundMs`.
|
|
18340
|
+
*/
|
|
18341
|
+
renderPreBufferClip: method(external_exports.object({
|
|
18342
|
+
deviceId: external_exports.number(),
|
|
18343
|
+
/** Absent = the LOWEST assigned profile — a notification attachment is
|
|
18344
|
+
* watched on a phone, and the cheap rendition is the right default. */
|
|
18345
|
+
profile: CamProfileSchema.optional(),
|
|
18346
|
+
aroundMs: external_exports.number(),
|
|
18347
|
+
preRollSec: external_exports.number().min(0).max(20).default(3),
|
|
18348
|
+
postRollSec: external_exports.number().min(0).max(20).default(5),
|
|
18349
|
+
format: external_exports.enum(["gif", "mp4"]).default("gif"),
|
|
18350
|
+
maxWidth: external_exports.number().int().min(120).max(1920).default(480),
|
|
18351
|
+
/** GIF only — MP4 keeps the source cadence. */
|
|
18352
|
+
fps: external_exports.number().int().min(1).max(15).default(5)
|
|
18353
|
+
}), external_exports.object({
|
|
18354
|
+
base64: external_exports.string(),
|
|
18355
|
+
mime: external_exports.string(),
|
|
18356
|
+
bytes: external_exports.number().int(),
|
|
18357
|
+
/** The profile actually rendered (what the default resolved to). */
|
|
18358
|
+
profile: CamProfileSchema,
|
|
18359
|
+
durationMs: external_exports.number()
|
|
18360
|
+
}), {
|
|
18361
|
+
kind: "mutation",
|
|
18362
|
+
auth: "admin"
|
|
18363
|
+
}),
|
|
18215
18364
|
listAllCameraStreams: method(external_exports.void(), external_exports.array(CameraStreamSchema).readonly()),
|
|
18216
18365
|
listAllProfileSlots: method(external_exports.void(), external_exports.array(ProfileSlotSchema).readonly()),
|
|
18217
18366
|
getBrokerStats: method(external_exports.object({ brokerId: external_exports.string() }), BrokerStatsSchema),
|
|
@@ -23868,6 +24017,26 @@ var LocationStatSchema = external_exports.object({
|
|
|
23868
24017
|
fileCount: external_exports.number(),
|
|
23869
24018
|
present: external_exports.boolean()
|
|
23870
24019
|
});
|
|
24020
|
+
var BackupScheduleSchema = external_exports.object({
|
|
24021
|
+
/** Stable id. Generated by the orchestrator on first upsert if absent. */
|
|
24022
|
+
id: external_exports.string(),
|
|
24023
|
+
/** Operator-facing display name. */
|
|
24024
|
+
label: external_exports.string(),
|
|
24025
|
+
/** 5-field POSIX cron. Empty = disabled cadence (kept for editing). */
|
|
24026
|
+
cron: external_exports.string(),
|
|
24027
|
+
/** Master on/off toggle for the whole schedule. */
|
|
24028
|
+
enabled: external_exports.boolean(),
|
|
24029
|
+
/** `backups`-location ids this schedule writes to (fan-out set). */
|
|
24030
|
+
locationIds: external_exports.array(external_exports.string()).readonly(),
|
|
24031
|
+
/** Archives kept per targeted location for this schedule. */
|
|
24032
|
+
retentionCount: external_exports.number().int().min(1).max(1e3),
|
|
24033
|
+
/** Optional subset of source locations to include; omitted = all. */
|
|
24034
|
+
dataSources: external_exports.array(external_exports.string()).readonly().optional(),
|
|
24035
|
+
/** ms-epoch of last successful run. */
|
|
24036
|
+
lastRunAt: external_exports.number().optional(),
|
|
24037
|
+
/** ms-epoch of next computed firing (read-only, filled on list). */
|
|
24038
|
+
nextRunAt: external_exports.number().optional()
|
|
24039
|
+
});
|
|
23871
24040
|
var backupCapability = {
|
|
23872
24041
|
name: "backup",
|
|
23873
24042
|
scope: "system",
|
|
@@ -23889,7 +24058,14 @@ var backupCapability = {
|
|
|
23889
24058
|
/** Subset of registered `backup-destination` addon ids to write to. */
|
|
23890
24059
|
destinations: external_exports.array(external_exports.string()).optional(),
|
|
23891
24060
|
locations: external_exports.array(external_exports.string()).optional(),
|
|
23892
|
-
label: external_exports.string().optional()
|
|
24061
|
+
label: external_exports.string().optional(),
|
|
24062
|
+
/**
|
|
24063
|
+
* Per-run retention override applied to every targeted
|
|
24064
|
+
* destination. Used by schedule-driven runs (per-entry
|
|
24065
|
+
* retention). Omitted = each destination's own policy
|
|
24066
|
+
* retention (manual runs).
|
|
24067
|
+
*/
|
|
24068
|
+
retentionCount: external_exports.number().int().min(1).max(1e3).optional()
|
|
23893
24069
|
}).optional(), external_exports.array(BackupEntrySchema).readonly(), {
|
|
23894
24070
|
kind: "mutation",
|
|
23895
24071
|
auth: "admin"
|
|
@@ -23976,7 +24152,36 @@ var backupCapability = {
|
|
|
23976
24152
|
ok: external_exports.boolean(),
|
|
23977
24153
|
error: external_exports.string().optional(),
|
|
23978
24154
|
nextRuns: external_exports.array(external_exports.number()).readonly()
|
|
23979
|
-
}))
|
|
24155
|
+
})),
|
|
24156
|
+
/**
|
|
24157
|
+
* List every backup schedule (the N:M entries), each with its
|
|
24158
|
+
* computed `nextRunAt`. Powers the Schedules section of the
|
|
24159
|
+
* admin-UI Backups page.
|
|
24160
|
+
*/
|
|
24161
|
+
listSchedules: method(external_exports.void(), external_exports.array(BackupScheduleSchema).readonly(), { auth: "admin" }),
|
|
24162
|
+
/**
|
|
24163
|
+
* Create or replace a schedule. An empty / absent `id` mints a new
|
|
24164
|
+
* one; a present `id` replaces in place. `cron` is validated
|
|
24165
|
+
* server-side; `locationIds` must reference existing `backups`
|
|
24166
|
+
* locations (unknown ids are dropped with a warning).
|
|
24167
|
+
*/
|
|
24168
|
+
upsertSchedule: method(external_exports.object({
|
|
24169
|
+
id: external_exports.string().optional(),
|
|
24170
|
+
label: external_exports.string(),
|
|
24171
|
+
cron: external_exports.string(),
|
|
24172
|
+
enabled: external_exports.boolean(),
|
|
24173
|
+
locationIds: external_exports.array(external_exports.string()).readonly(),
|
|
24174
|
+
retentionCount: external_exports.number().int().min(1).max(1e3),
|
|
24175
|
+
dataSources: external_exports.array(external_exports.string()).readonly().optional()
|
|
24176
|
+
}), BackupScheduleSchema, {
|
|
24177
|
+
kind: "mutation",
|
|
24178
|
+
auth: "admin"
|
|
24179
|
+
}),
|
|
24180
|
+
/** Delete a schedule by id. Does not touch the target locations. */
|
|
24181
|
+
deleteSchedule: method(external_exports.object({ id: external_exports.string() }), external_exports.void(), {
|
|
24182
|
+
kind: "mutation",
|
|
24183
|
+
auth: "admin"
|
|
24184
|
+
})
|
|
23980
24185
|
}
|
|
23981
24186
|
};
|
|
23982
24187
|
var BrokerStatusEnum = external_exports.enum([
|
|
@@ -25367,7 +25572,29 @@ var deviceManagerCapability = {
|
|
|
25367
25572
|
getDeviceStatusAggregate: method(external_exports.object({
|
|
25368
25573
|
deviceId: external_exports.number(),
|
|
25369
25574
|
caps: external_exports.array(external_exports.string()).readonly().optional()
|
|
25370
|
-
}), external_exports.record(external_exports.string(), external_exports.unknown().nullable()))
|
|
25575
|
+
}), external_exports.record(external_exports.string(), external_exports.unknown().nullable())),
|
|
25576
|
+
/**
|
|
25577
|
+
* The same aggregate, for a LIST of devices in one round-trip.
|
|
25578
|
+
*
|
|
25579
|
+
* The viewer's camera list is the caller this exists for. Each card asked
|
|
25580
|
+
* for its own badges — battery here, recording mode there — so a ten-camera
|
|
25581
|
+
* install issued N separate procedures per reconcile, each its own message
|
|
25582
|
+
* on the one WebSocket that also carries the WebRTC signalling (the client
|
|
25583
|
+
* has no `httpBatchLink`, so there is no transport-level batching to lean
|
|
25584
|
+
* on: collapsing has to happen at the procedure level, which is here).
|
|
25585
|
+
*
|
|
25586
|
+
* Keyed by device id as a STRING — a JSON object cannot key by number, and
|
|
25587
|
+
* pretending otherwise is how a record survives the wire only in tests.
|
|
25588
|
+
* The per-device value is exactly what `getDeviceStatusAggregate` returns,
|
|
25589
|
+
* so a caller can move between the two without reshaping anything.
|
|
25590
|
+
*
|
|
25591
|
+
* `caps` matters more here than in the single call: a client that needs two
|
|
25592
|
+
* caps should not pay for every status-carrying cap × every device.
|
|
25593
|
+
*/
|
|
25594
|
+
getDeviceStatusAggregateBatch: method(external_exports.object({
|
|
25595
|
+
deviceIds: external_exports.array(external_exports.number()).readonly(),
|
|
25596
|
+
caps: external_exports.array(external_exports.string()).readonly().optional()
|
|
25597
|
+
}), external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.unknown().nullable())))
|
|
25371
25598
|
}
|
|
25372
25599
|
};
|
|
25373
25600
|
var deviceStateCapability = {
|
|
@@ -26357,6 +26584,36 @@ var TargetKindSchema = external_exports.object({
|
|
|
26357
26584
|
icon: external_exports.string(),
|
|
26358
26585
|
/** Stamped by each provider so the concat-fanned catalog stays routable. */
|
|
26359
26586
|
addonId: external_exports.string(),
|
|
26587
|
+
/**
|
|
26588
|
+
* URL of the kind's bundled BRAND icon, served by the providing addon over
|
|
26589
|
+
* its own `addon-routes` surface (`/addon/<addonId>/icons/<kind>`). Absent
|
|
26590
|
+
* when the addon bundles no icon for that kind — the client then falls back
|
|
26591
|
+
* to a neutral glyph rather than rendering the raw `icon` NAME as text.
|
|
26592
|
+
*
|
|
26593
|
+
* Root-relative on purpose: it resolves against whatever origin serves a web
|
|
26594
|
+
* client, and a native client joins it onto its own hub base.
|
|
26595
|
+
*
|
|
26596
|
+
* DECLARED here deliberately. It used to travel as an undeclared passthrough
|
|
26597
|
+
* field that survived only because the runtime cap-router forwards provider
|
|
26598
|
+
* output verbatim — so every consumer had to re-declare it by hand to stop
|
|
26599
|
+
* its own Zod parse from stripping it, and the whole arrangement would have
|
|
26600
|
+
* broken silently the moment output validation was tightened anywhere.
|
|
26601
|
+
*/
|
|
26602
|
+
iconUrl: external_exports.string().optional(),
|
|
26603
|
+
/**
|
|
26604
|
+
* Media type of {@link iconUrl} (`image/svg+xml`, `image/png`, …).
|
|
26605
|
+
*
|
|
26606
|
+
* The server knows this and therefore says it, because the client cannot
|
|
26607
|
+
* safely guess: a React-Native client renders SVG and raster through two
|
|
26608
|
+
* DIFFERENT components (`react-native-svg` vs `expo-image` — expo-image does
|
|
26609
|
+
* not decode SVG on iOS/Android), so without this it silently fell back to a
|
|
26610
|
+
* placeholder glyph for every vector icon while the web build looked fine.
|
|
26611
|
+
*
|
|
26612
|
+
* Absent when {@link iconUrl} is absent, or for a legacy provider that has
|
|
26613
|
+
* not been updated — a client that cannot determine the type should prefer
|
|
26614
|
+
* its raster path, which is the safe default for an unknown image.
|
|
26615
|
+
*/
|
|
26616
|
+
iconMediaType: external_exports.string().optional(),
|
|
26360
26617
|
configSchema: ConfigSchemaPassthrough,
|
|
26361
26618
|
supportsDiscovery: external_exports.boolean(),
|
|
26362
26619
|
caps: TargetKindCapsSchema
|
|
@@ -26691,6 +26948,14 @@ var MotionEventSchema = external_exports.object({
|
|
|
26691
26948
|
mediaUrl: external_exports.string().optional()
|
|
26692
26949
|
});
|
|
26693
26950
|
var DetectionSourceSchema = external_exports.enum(["pipeline", "onboard"]);
|
|
26951
|
+
var ZoneCrossingDirectionSchema = external_exports.enum(["enter", "exit"]);
|
|
26952
|
+
var ZoneCrossingSchema = external_exports.object({
|
|
26953
|
+
direction: ZoneCrossingDirectionSchema,
|
|
26954
|
+
/** Admin zone id crossed. */
|
|
26955
|
+
zoneId: external_exports.string(),
|
|
26956
|
+
/** Zone display name at crossing time (falls back to the id). */
|
|
26957
|
+
zoneName: external_exports.string().optional()
|
|
26958
|
+
});
|
|
26694
26959
|
var ObjectEventSchema = external_exports.object({
|
|
26695
26960
|
...BaseEventFields,
|
|
26696
26961
|
kind: external_exports.literal("object"),
|
|
@@ -26717,6 +26982,12 @@ var ObjectEventSchema = external_exports.object({
|
|
|
26717
26982
|
zones: external_exports.array(external_exports.string()).readonly().optional(),
|
|
26718
26983
|
/** Omitted in slim projection. */
|
|
26719
26984
|
state: TrackStateSchema.optional(),
|
|
26985
|
+
/**
|
|
26986
|
+
* The zone crossing this event IS, when it is one. Absent on every other
|
|
26987
|
+
* event kind (movement state, appearance, package) — see
|
|
26988
|
+
* {@link ZoneCrossingSchema}. Omitted in slim projection.
|
|
26989
|
+
*/
|
|
26990
|
+
zoneCrossing: ZoneCrossingSchema.optional(),
|
|
26720
26991
|
/** Detection-frame dimensions in pixels — let consumers normalize the
|
|
26721
26992
|
* pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
|
|
26722
26993
|
frameWidth: external_exports.number().optional(),
|
|
@@ -27093,6 +27364,23 @@ var pipelineAnalyticsCapability = {
|
|
|
27093
27364
|
}),
|
|
27094
27365
|
/** The events ops-log rows (newest-first), optionally scoped to one camera.
|
|
27095
27366
|
* Backed by a declared pipeline-analytics SQLite collection. */
|
|
27367
|
+
/**
|
|
27368
|
+
* Move event-media blobs onto `toLocationId` (entity-routing spec Phase
|
|
27369
|
+
* 4): per-row copy → stamp row.locationId → delete old blob. Rows already
|
|
27370
|
+
* at the target are skipped, so a re-run resumes. Single-flight.
|
|
27371
|
+
*/
|
|
27372
|
+
relocateMedia: method(RelocateMediaInputSchema, external_exports.object({ jobId: external_exports.string() }), {
|
|
27373
|
+
kind: "mutation",
|
|
27374
|
+
auth: "admin"
|
|
27375
|
+
}),
|
|
27376
|
+
getMediaRelocateStatus: method(external_exports.object({}), external_exports.array(RelocateJobSchema).readonly(), {
|
|
27377
|
+
kind: "query",
|
|
27378
|
+
auth: "admin"
|
|
27379
|
+
}),
|
|
27380
|
+
cancelMediaRelocate: method(external_exports.object({ jobId: external_exports.string() }), external_exports.object({ cancelled: external_exports.boolean() }), {
|
|
27381
|
+
kind: "mutation",
|
|
27382
|
+
auth: "admin"
|
|
27383
|
+
}),
|
|
27096
27384
|
listOpsLog: method(OpsLogQueryInputSchema, external_exports.array(OpsLogEntrySchema).readonly(), {
|
|
27097
27385
|
kind: "query",
|
|
27098
27386
|
auth: "admin"
|
|
@@ -30079,6 +30367,12 @@ var ConnectionEndpointSchema = external_exports.object({
|
|
|
30079
30367
|
priority: external_exports.number()
|
|
30080
30368
|
});
|
|
30081
30369
|
var GetConnectionEndpointsResultSchema = external_exports.object({ endpoints: external_exports.array(ConnectionEndpointSchema).readonly() });
|
|
30370
|
+
var NotificationEndpointSchema = external_exports.object({
|
|
30371
|
+
/** The operator's explicit choice, or null for AUTO. */
|
|
30372
|
+
baseUrl: external_exports.string().nullable(),
|
|
30373
|
+
/** What the ranking currently resolves to (null when nothing is reachable). */
|
|
30374
|
+
resolved: external_exports.string().nullable()
|
|
30375
|
+
});
|
|
30082
30376
|
var AllowedAddressesSchema = external_exports.object({
|
|
30083
30377
|
/**
|
|
30084
30378
|
* Allowlist of interface addresses operators have explicitly opted
|
|
@@ -30131,6 +30425,26 @@ var localNetworkCapability = {
|
|
|
30131
30425
|
scheme: external_exports.enum(["http", "https"]).optional()
|
|
30132
30426
|
}), GetConnectionEndpointsResultSchema),
|
|
30133
30427
|
/**
|
|
30428
|
+
* The endpoint OUTBOUND artifacts must be addressed by — notification
|
|
30429
|
+
* attachment links and deep links. `baseUrl: null` means AUTO: the first
|
|
30430
|
+
* public candidate (a configured origin, then a connected tunnel, then the
|
|
30431
|
+
* LAN), never loopback.
|
|
30432
|
+
*
|
|
30433
|
+
* Why an explicit marker: the automatic ranking cannot know which of
|
|
30434
|
+
* several reachable addresses the RECIPIENT can actually open. A link is
|
|
30435
|
+
* consumed on someone's phone, off the LAN, possibly hours later — and a
|
|
30436
|
+
* link nobody can open is worse than no link, because the notification
|
|
30437
|
+
* arrives advertising media that 404s.
|
|
30438
|
+
*/
|
|
30439
|
+
getNotificationEndpoint: method(external_exports.void(), NotificationEndpointSchema),
|
|
30440
|
+
/**
|
|
30441
|
+
* Mark which endpoint notification artifacts use. `baseUrl: null` restores
|
|
30442
|
+
* AUTO. The value is stored verbatim (not an index into the candidate
|
|
30443
|
+
* list): interfaces come and go, and an index would silently re-point at a
|
|
30444
|
+
* different address after a reboot.
|
|
30445
|
+
*/
|
|
30446
|
+
setNotificationEndpoint: method(external_exports.object({ baseUrl: external_exports.string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }),
|
|
30447
|
+
/**
|
|
30134
30448
|
* Read the operator's allowlist. Empty = "auto" (no filter). Used
|
|
30135
30449
|
* by the admin UI's address selector to seed its checkbox state.
|
|
30136
30450
|
*/
|
|
@@ -31109,7 +31423,12 @@ var RecordingDeviceUsageSchema = external_exports.object({
|
|
|
31109
31423
|
var RecordingLocationUsageSchema = external_exports.object({
|
|
31110
31424
|
/** StorageLocation id; null for the legacy/degraded single-root fallback. */
|
|
31111
31425
|
locationId: external_exports.string().nullable(),
|
|
31112
|
-
/**
|
|
31426
|
+
/** Every location id sharing this row's PHYSICAL volume (aliases). One row
|
|
31427
|
+
* is emitted per physical disk (2026-07-29): two locations on one root
|
|
31428
|
+
* previously rendered as two identical "disks" with a nonsensical used
|
|
31429
|
+
* split — hydrate attribution across aliases is arbitrary by nature. */
|
|
31430
|
+
locationIds: external_exports.array(external_exports.string()).optional(),
|
|
31431
|
+
/** Bytes of recordings stored on this PHYSICAL volume (all aliases). */
|
|
31113
31432
|
usedBytes: external_exports.number(),
|
|
31114
31433
|
/** Free bytes on the location's volume; null when capacity is unknown (remote). */
|
|
31115
31434
|
availableBytes: external_exports.number().nullable(),
|
|
@@ -31251,6 +31570,77 @@ var recordingCapability = {
|
|
|
31251
31570
|
listOpsLog: method(OpsLogQueryInputSchema, external_exports.array(OpsLogEntrySchema).readonly(), {
|
|
31252
31571
|
kind: "query",
|
|
31253
31572
|
auth: "admin"
|
|
31573
|
+
}),
|
|
31574
|
+
/**
|
|
31575
|
+
* Move footage (segments and/or strips) from one recordings location to
|
|
31576
|
+
* another — the drain workflow's mover (entity-routing spec Phase 4).
|
|
31577
|
+
* Throttled copy → size-verify → delete source → index refresh; resumable
|
|
31578
|
+
* by construction (copy-if-absent). Single-flight: one job at a time.
|
|
31579
|
+
*/
|
|
31580
|
+
/**
|
|
31581
|
+
* Render a short GIF from recorded footage around `aroundMs` (low profile,
|
|
31582
|
+
* palette-free ffmpeg gif). Synchronous — the window is a few seconds of
|
|
31583
|
+
* `low`, rendering in ~1-2s. Built for notification attachments: the
|
|
31584
|
+
* caller gets bytes, nothing persists. Fails when no footage covers the
|
|
31585
|
+
* window (camera not recording → caller skips the attachment).
|
|
31586
|
+
*/
|
|
31587
|
+
renderGif: method(external_exports.object({
|
|
31588
|
+
deviceId: external_exports.number(),
|
|
31589
|
+
aroundMs: external_exports.number(),
|
|
31590
|
+
preRollSec: external_exports.number().min(0).max(30).default(2),
|
|
31591
|
+
postRollSec: external_exports.number().min(0).max(30).default(5),
|
|
31592
|
+
maxWidth: external_exports.number().int().min(120).max(1280).default(480),
|
|
31593
|
+
fps: external_exports.number().int().min(1).max(15).default(5)
|
|
31594
|
+
}), external_exports.object({
|
|
31595
|
+
gifBase64: external_exports.string(),
|
|
31596
|
+
fromMs: external_exports.number(),
|
|
31597
|
+
toMs: external_exports.number()
|
|
31598
|
+
}), {
|
|
31599
|
+
kind: "mutation",
|
|
31600
|
+
auth: "admin"
|
|
31601
|
+
}),
|
|
31602
|
+
/**
|
|
31603
|
+
* Render a short MP4 clip from recorded footage around `aroundMs` — the
|
|
31604
|
+
* "send a clip, not a gif" notification attachment. Same window, source
|
|
31605
|
+
* and fail-closed contract as {@link renderGif}: no footage covering the
|
|
31606
|
+
* window ⇒ it throws and the caller ships no attachment. Re-encoded (never
|
|
31607
|
+
* stream-copied) so a concat across segments with different encoder
|
|
31608
|
+
* parameters still plays. Silent by contract.
|
|
31609
|
+
*
|
|
31610
|
+
* The returned window is SEGMENT-GRANULAR: the source playlist is built
|
|
31611
|
+
* from whole segments, so the clip starts at or before `fromMs` and ends
|
|
31612
|
+
* at or after `toMs` — overshoot bounded by one segment per side (an 8 s
|
|
31613
|
+
* ask over 4 s segments measured 12 s). `fromMs`/`toMs` report the window
|
|
31614
|
+
* ASKED for, not the encoded duration.
|
|
31615
|
+
*/
|
|
31616
|
+
renderClip: method(external_exports.object({
|
|
31617
|
+
deviceId: external_exports.number(),
|
|
31618
|
+
aroundMs: external_exports.number(),
|
|
31619
|
+
preRollSec: external_exports.number().min(0).max(30).default(3),
|
|
31620
|
+
postRollSec: external_exports.number().min(0).max(30).default(7),
|
|
31621
|
+
maxWidth: external_exports.number().int().min(160).max(1920).default(640)
|
|
31622
|
+
}), external_exports.object({
|
|
31623
|
+
clipBase64: external_exports.string(),
|
|
31624
|
+
mime: external_exports.string(),
|
|
31625
|
+
fromMs: external_exports.number(),
|
|
31626
|
+
toMs: external_exports.number(),
|
|
31627
|
+
bytes: external_exports.number().int()
|
|
31628
|
+
}), {
|
|
31629
|
+
kind: "mutation",
|
|
31630
|
+
auth: "admin"
|
|
31631
|
+
}),
|
|
31632
|
+
relocateFootage: method(RelocateFootageInputSchema, external_exports.object({ jobId: external_exports.string() }), {
|
|
31633
|
+
kind: "mutation",
|
|
31634
|
+
auth: "admin"
|
|
31635
|
+
}),
|
|
31636
|
+
/** Every known relocate job (in-RAM, newest-first). */
|
|
31637
|
+
getRelocateStatus: method(external_exports.object({}), external_exports.array(RelocateJobSchema).readonly(), {
|
|
31638
|
+
kind: "query",
|
|
31639
|
+
auth: "admin"
|
|
31640
|
+
}),
|
|
31641
|
+
cancelRelocate: method(external_exports.object({ jobId: external_exports.string() }), external_exports.object({ cancelled: external_exports.boolean() }), {
|
|
31642
|
+
kind: "mutation",
|
|
31643
|
+
auth: "admin"
|
|
31254
31644
|
})
|
|
31255
31645
|
}
|
|
31256
31646
|
};
|
|
@@ -32181,6 +32571,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
32181
32571
|
addonId: null,
|
|
32182
32572
|
access: "delete"
|
|
32183
32573
|
},
|
|
32574
|
+
"backup.deleteSchedule": {
|
|
32575
|
+
capName: "backup",
|
|
32576
|
+
capScope: "system",
|
|
32577
|
+
addonId: null,
|
|
32578
|
+
access: "delete"
|
|
32579
|
+
},
|
|
32184
32580
|
"backup.getEntries": {
|
|
32185
32581
|
capName: "backup",
|
|
32186
32582
|
capScope: "system",
|
|
@@ -32211,6 +32607,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
32211
32607
|
addonId: null,
|
|
32212
32608
|
access: "view"
|
|
32213
32609
|
},
|
|
32610
|
+
"backup.listSchedules": {
|
|
32611
|
+
capName: "backup",
|
|
32612
|
+
capScope: "system",
|
|
32613
|
+
addonId: null,
|
|
32614
|
+
access: "view"
|
|
32615
|
+
},
|
|
32214
32616
|
"backup.previewSchedule": {
|
|
32215
32617
|
capName: "backup",
|
|
32216
32618
|
capScope: "system",
|
|
@@ -32235,6 +32637,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
32235
32637
|
addonId: null,
|
|
32236
32638
|
access: "create"
|
|
32237
32639
|
},
|
|
32640
|
+
"backup.upsertSchedule": {
|
|
32641
|
+
capName: "backup",
|
|
32642
|
+
capScope: "system",
|
|
32643
|
+
addonId: null,
|
|
32644
|
+
access: "create"
|
|
32645
|
+
},
|
|
32238
32646
|
"battery.wakeForStream": {
|
|
32239
32647
|
capName: "battery",
|
|
32240
32648
|
capScope: "device",
|
|
@@ -32841,6 +33249,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
32841
33249
|
addonId: null,
|
|
32842
33250
|
access: "view"
|
|
32843
33251
|
},
|
|
33252
|
+
"deviceManager.getDeviceStatusAggregateBatch": {
|
|
33253
|
+
capName: "device-manager",
|
|
33254
|
+
capScope: "system",
|
|
33255
|
+
addonId: null,
|
|
33256
|
+
access: "view"
|
|
33257
|
+
},
|
|
32844
33258
|
"deviceManager.getLinkedDevices": {
|
|
32845
33259
|
capName: "device-manager",
|
|
32846
33260
|
capScope: "system",
|
|
@@ -33735,6 +34149,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
33735
34149
|
addonId: null,
|
|
33736
34150
|
access: "view"
|
|
33737
34151
|
},
|
|
34152
|
+
"localNetwork.getNotificationEndpoint": {
|
|
34153
|
+
capName: "local-network",
|
|
34154
|
+
capScope: "system",
|
|
34155
|
+
addonId: null,
|
|
34156
|
+
access: "view"
|
|
34157
|
+
},
|
|
33738
34158
|
"localNetwork.getPreferred": {
|
|
33739
34159
|
capName: "local-network",
|
|
33740
34160
|
capScope: "system",
|
|
@@ -33759,6 +34179,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
33759
34179
|
addonId: null,
|
|
33760
34180
|
access: "create"
|
|
33761
34181
|
},
|
|
34182
|
+
"localNetwork.setNotificationEndpoint": {
|
|
34183
|
+
capName: "local-network",
|
|
34184
|
+
capScope: "system",
|
|
34185
|
+
addonId: null,
|
|
34186
|
+
access: "create"
|
|
34187
|
+
},
|
|
33762
34188
|
"lockControl.lock": {
|
|
33763
34189
|
capName: "lock-control",
|
|
33764
34190
|
capScope: "device",
|
|
@@ -34401,6 +34827,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
34401
34827
|
addonId: null,
|
|
34402
34828
|
access: "create"
|
|
34403
34829
|
},
|
|
34830
|
+
"pipelineAnalytics.cancelMediaRelocate": {
|
|
34831
|
+
capName: "pipeline-analytics",
|
|
34832
|
+
capScope: "device",
|
|
34833
|
+
addonId: null,
|
|
34834
|
+
access: "create"
|
|
34835
|
+
},
|
|
34404
34836
|
"pipelineAnalytics.clearTracks": {
|
|
34405
34837
|
capName: "pipeline-analytics",
|
|
34406
34838
|
capScope: "device",
|
|
@@ -34455,6 +34887,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
34455
34887
|
addonId: null,
|
|
34456
34888
|
access: "view"
|
|
34457
34889
|
},
|
|
34890
|
+
"pipelineAnalytics.getMediaRelocateStatus": {
|
|
34891
|
+
capName: "pipeline-analytics",
|
|
34892
|
+
capScope: "device",
|
|
34893
|
+
addonId: null,
|
|
34894
|
+
access: "view"
|
|
34895
|
+
},
|
|
34458
34896
|
"pipelineAnalytics.getMotionEvents": {
|
|
34459
34897
|
capName: "pipeline-analytics",
|
|
34460
34898
|
capScope: "device",
|
|
@@ -34527,6 +34965,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
34527
34965
|
addonId: null,
|
|
34528
34966
|
access: "create"
|
|
34529
34967
|
},
|
|
34968
|
+
"pipelineAnalytics.relocateMedia": {
|
|
34969
|
+
capName: "pipeline-analytics",
|
|
34970
|
+
capScope: "device",
|
|
34971
|
+
addonId: null,
|
|
34972
|
+
access: "create"
|
|
34973
|
+
},
|
|
34530
34974
|
"pipelineAnalytics.searchObjectEvents": {
|
|
34531
34975
|
capName: "pipeline-analytics",
|
|
34532
34976
|
capScope: "device",
|
|
@@ -35289,6 +35733,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
35289
35733
|
addonId: null,
|
|
35290
35734
|
access: "create"
|
|
35291
35735
|
},
|
|
35736
|
+
"recording.cancelRelocate": {
|
|
35737
|
+
capName: "recording",
|
|
35738
|
+
capScope: "system",
|
|
35739
|
+
addonId: null,
|
|
35740
|
+
access: "create"
|
|
35741
|
+
},
|
|
35292
35742
|
"recording.deleteFootprint": {
|
|
35293
35743
|
capName: "recording",
|
|
35294
35744
|
capScope: "system",
|
|
@@ -35319,6 +35769,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
35319
35769
|
addonId: null,
|
|
35320
35770
|
access: "view"
|
|
35321
35771
|
},
|
|
35772
|
+
"recording.getRelocateStatus": {
|
|
35773
|
+
capName: "recording",
|
|
35774
|
+
capScope: "system",
|
|
35775
|
+
addonId: null,
|
|
35776
|
+
access: "view"
|
|
35777
|
+
},
|
|
35322
35778
|
"recording.getStorageUsage": {
|
|
35323
35779
|
capName: "recording",
|
|
35324
35780
|
capScope: "system",
|
|
@@ -35349,6 +35805,24 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
35349
35805
|
addonId: null,
|
|
35350
35806
|
access: "view"
|
|
35351
35807
|
},
|
|
35808
|
+
"recording.relocateFootage": {
|
|
35809
|
+
capName: "recording",
|
|
35810
|
+
capScope: "system",
|
|
35811
|
+
addonId: null,
|
|
35812
|
+
access: "create"
|
|
35813
|
+
},
|
|
35814
|
+
"recording.renderClip": {
|
|
35815
|
+
capName: "recording",
|
|
35816
|
+
capScope: "system",
|
|
35817
|
+
addonId: null,
|
|
35818
|
+
access: "create"
|
|
35819
|
+
},
|
|
35820
|
+
"recording.renderGif": {
|
|
35821
|
+
capName: "recording",
|
|
35822
|
+
capScope: "system",
|
|
35823
|
+
addonId: null,
|
|
35824
|
+
access: "create"
|
|
35825
|
+
},
|
|
35352
35826
|
"recording.rescanStorage": {
|
|
35353
35827
|
capName: "recording",
|
|
35354
35828
|
capScope: "system",
|
|
@@ -35943,6 +36417,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
35943
36417
|
addonId: null,
|
|
35944
36418
|
access: "create"
|
|
35945
36419
|
},
|
|
36420
|
+
"streamBroker.renderPreBufferClip": {
|
|
36421
|
+
capName: "stream-broker",
|
|
36422
|
+
capScope: "system",
|
|
36423
|
+
addonId: null,
|
|
36424
|
+
access: "create"
|
|
36425
|
+
},
|
|
35946
36426
|
"streamBroker.restartProfile": {
|
|
35947
36427
|
capName: "stream-broker",
|
|
35948
36428
|
capScope: "system",
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runDiscover
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7EQOMKUT.js";
|
|
5
5
|
import "./chunk-K3NQKI34.js";
|
|
6
6
|
|
|
7
7
|
// src/cli.ts
|
|
@@ -1079,7 +1079,7 @@ function isUnknown(_value) {
|
|
|
1079
1079
|
return true;
|
|
1080
1080
|
}
|
|
1081
1081
|
async function resolveServerInteractive(presetNamespace) {
|
|
1082
|
-
const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-
|
|
1082
|
+
const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-JDVFZ6NG.js");
|
|
1083
1083
|
if (presetNamespace) {
|
|
1084
1084
|
const spinner4 = clack.spinner();
|
|
1085
1085
|
spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
|