@camstack/types 1.2.15 → 1.2.17
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.d.ts +1 -0
- package/dist/addon.js +265 -1
- package/dist/addon.mjs +264 -2
- package/dist/capabilities/addons.cap.d.ts +7 -7
- package/dist/capabilities/backup.cap.d.ts +73 -1
- package/dist/capabilities/broker.cap.d.ts +8 -8
- package/dist/capabilities/camera-streams.cap.d.ts +5 -5
- package/dist/capabilities/climate-control.cap.d.ts +8 -8
- package/dist/capabilities/day-night.cap.d.ts +8 -8
- package/dist/capabilities/decoder.cap.d.ts +2 -2
- package/dist/capabilities/device-manager.cap.d.ts +2 -2
- package/dist/capabilities/face-gallery.cap.d.ts +1 -1
- package/dist/capabilities/image-settings.cap.d.ts +16 -16
- package/dist/capabilities/index.d.ts +1 -1
- package/dist/capabilities/intercom.cap.d.ts +6 -6
- package/dist/capabilities/lawn-mower-control.cap.d.ts +4 -4
- package/dist/capabilities/llm-runtime.cap.d.ts +3 -3
- package/dist/capabilities/llm.cap.d.ts +4 -4
- package/dist/capabilities/local-network.cap.d.ts +38 -0
- package/dist/capabilities/media-player.cap.d.ts +9 -9
- package/dist/capabilities/metrics-provider.cap.d.ts +2 -2
- package/dist/capabilities/mqtt-broker.cap.d.ts +3 -3
- package/dist/capabilities/notification-output.cap.d.ts +4 -0
- package/dist/capabilities/notification-rules.cap.d.ts +236 -18
- package/dist/capabilities/pipeline-analytics.cap.d.ts +64 -27
- package/dist/capabilities/pipeline-executor.cap.d.ts +2 -2
- package/dist/capabilities/pipeline-orchestrator.cap.d.ts +15 -15
- package/dist/capabilities/pipeline-runner.cap.d.ts +2 -2
- package/dist/capabilities/recording-export.cap.d.ts +7 -7
- package/dist/capabilities/recording.cap.d.ts +102 -129
- package/dist/capabilities/schemas/orchestrator-metrics.d.ts +2 -2
- package/dist/capabilities/schemas/streaming-shared.d.ts +4 -4
- package/dist/capabilities/storage-provider.cap.d.ts +44 -0
- package/dist/capabilities/storage.cap.d.ts +17 -0
- package/dist/capabilities/stream-broker.cap.d.ts +58 -12
- package/dist/capabilities/webrtc-session.cap.d.ts +6 -6
- package/dist/generated/addon-api.d.ts +5365 -30879
- package/dist/generated/cap-input-defaults.d.ts +29 -0
- package/dist/generated/device-proxy.d.ts +2 -2
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/system-proxy.d.ts +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +693 -139
- package/dist/index.mjs +684 -136
- package/dist/interfaces/addon.d.ts +9 -0
- package/dist/interfaces/ops-log.d.ts +2 -0
- package/dist/interfaces/recording-config.d.ts +33 -91
- package/dist/interfaces/relocate.d.ts +55 -0
- package/dist/interfaces/storage-location-declaration.d.ts +1 -0
- package/dist/interfaces/storage-location.d.ts +4 -0
- package/dist/interfaces/stream-broker.d.ts +1 -1
- package/dist/lifecycle/job.d.ts +6 -6
- package/dist/node.js +1 -0
- package/dist/node.mjs +1 -0
- package/dist/notification/condition-taxonomy.d.ts +61 -0
- package/dist/notification/format-transcode.d.ts +12 -1
- package/dist/{sleep-C3ceNSsf.mjs → sleep-Ct4Is70g.mjs} +6 -0
- package/dist/{sleep-DRg9F6JJ.js → sleep-yfPaamGa.js} +6 -0
- package/package.json +1 -1
- package/dist/interfaces/recording-config-migrate.d.ts +0 -12
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_sleep = require("./sleep-
|
|
2
|
+
const require_sleep = require("./sleep-yfPaamGa.js");
|
|
3
3
|
const require_event_category = require("./event-category-Cdyife4p.js");
|
|
4
4
|
const require_enums = require("./enums.js");
|
|
5
5
|
const require_err_msg = require("./err-msg-COpsHMw2.js");
|
|
@@ -792,35 +792,22 @@ var EVENT_PAD_MS = {
|
|
|
792
792
|
*/
|
|
793
793
|
var RecordingWeekdaySchema = zod.z.number().int().min(0).max(6);
|
|
794
794
|
var HHMM = /^([01]\d|2[0-3]):[0-5]\d$/;
|
|
795
|
-
var RecordingScheduleSchema = zod.z.discriminatedUnion("kind", [zod.z.object({ kind: zod.z.literal("always") }), zod.z.object({
|
|
796
|
-
kind: zod.z.literal("timeOfDay"),
|
|
797
|
-
start: zod.z.string().regex(HHMM),
|
|
798
|
-
end: zod.z.string().regex(HHMM),
|
|
799
|
-
/** Restrict to these weekdays; omit = every day. */
|
|
800
|
-
days: zod.z.array(RecordingWeekdaySchema).optional()
|
|
801
|
-
})]);
|
|
802
|
-
var RecordingModeSchema = zod.z.enum([
|
|
803
|
-
"continuous",
|
|
804
|
-
"onMotion",
|
|
805
|
-
"onAudioThreshold"
|
|
806
|
-
]);
|
|
807
795
|
/**
|
|
808
|
-
*
|
|
809
|
-
*
|
|
810
|
-
* - `off` —
|
|
811
|
-
* - `events` —
|
|
812
|
-
*
|
|
813
|
-
* - `continuous` — record 24/7 within the schedule.
|
|
796
|
+
* DERIVED per-camera storage summary — the single field cheap consumers read
|
|
797
|
+
* (the viewer's status dot, the camera list) instead of walking `bands`:
|
|
798
|
+
* - `off` — no band covers the camera (or it is disabled).
|
|
799
|
+
* - `events` — every band records around triggers only.
|
|
800
|
+
* - `continuous` — at least one band records continuously.
|
|
814
801
|
*
|
|
815
|
-
*
|
|
816
|
-
*
|
|
802
|
+
* NEVER authored: the recorder stamps it from the authoritative `bands` on
|
|
803
|
+
* every save (`activeModeForConfig`). Writing it has no effect.
|
|
817
804
|
*/
|
|
818
805
|
var RecordingStorageModeSchema = zod.z.enum([
|
|
819
806
|
"off",
|
|
820
807
|
"events",
|
|
821
808
|
"continuous"
|
|
822
809
|
]);
|
|
823
|
-
/** Which detectors trigger an `events`-mode
|
|
810
|
+
/** Which detectors trigger an `events`-mode band. */
|
|
824
811
|
var RecordingTriggersSchema = zod.z.object({
|
|
825
812
|
motion: zod.z.boolean().optional(),
|
|
826
813
|
audioThresholdDbfs: zod.z.number().optional()
|
|
@@ -856,18 +843,6 @@ var RecordingBandSchema = zod.z.object({
|
|
|
856
843
|
preBufferSec: zod.z.number().min(0).optional(),
|
|
857
844
|
postBufferSec: zod.z.number().min(0).optional()
|
|
858
845
|
});
|
|
859
|
-
var RecordingRuleSchema = zod.z.object({
|
|
860
|
-
schedule: RecordingScheduleSchema,
|
|
861
|
-
mode: RecordingModeSchema,
|
|
862
|
-
/** Seconds of footage to retain BEFORE a trigger (applied at keep/discard). */
|
|
863
|
-
preBufferSec: zod.z.number().min(0).default(0),
|
|
864
|
-
/** Keep recording until this many seconds after the last trigger. */
|
|
865
|
-
postBufferSec: zod.z.number().min(0).default(0),
|
|
866
|
-
/** Each new trigger restarts the post-buffer window. */
|
|
867
|
-
resetTimeoutOnNewEvent: zod.z.boolean().default(true),
|
|
868
|
-
/** onAudioThreshold only — dBFS level that counts as a trigger. */
|
|
869
|
-
thresholdDbfs: zod.z.number().optional()
|
|
870
|
-
});
|
|
871
846
|
/**
|
|
872
847
|
* Per-device retention overrides. Every field is optional; an unset or `0`
|
|
873
848
|
* value inherits the node-wide recorder default. Only footage-lifetime limits
|
|
@@ -960,40 +935,28 @@ function resolveScrubThumbnailGeometry(preset) {
|
|
|
960
935
|
/**
|
|
961
936
|
* The full per-camera recording intent — the wire shape of a RecordingTarget.
|
|
962
937
|
*
|
|
963
|
-
* `
|
|
964
|
-
*
|
|
965
|
-
*
|
|
966
|
-
*
|
|
938
|
+
* `bands` is the ONLY authored recording intent: what to record, when, and on
|
|
939
|
+
* which trigger. `mode` is a derived summary the recorder stamps on save; every
|
|
940
|
+
* other field is a storage knob (profiles, segment length, retention, scrub).
|
|
941
|
+
*
|
|
942
|
+
* STRICT on purpose: the legacy authoring surface (`schedule`/`schedules`/
|
|
943
|
+
* `triggers`/`preBufferSec`/`postBufferSec`/`rules`) was retired 2026-07-30.
|
|
944
|
+
* A stale caller must fail loudly — silently stripping its legacy intent would
|
|
945
|
+
* persist a band-less config, i.e. silently stop recording the camera.
|
|
967
946
|
*/
|
|
968
947
|
var RecordingConfigSchema = zod.z.object({
|
|
969
948
|
enabled: zod.z.boolean(),
|
|
970
|
-
/**
|
|
971
|
-
*
|
|
949
|
+
/** DERIVED summary of `bands`, stamped by the recorder on every save.
|
|
950
|
+
* Authoring it has no effect — see {@link RecordingStorageModeSchema}. */
|
|
972
951
|
mode: RecordingStorageModeSchema.optional(),
|
|
973
952
|
profiles: zod.z.array(require_sleep.CamProfileSchema).optional(),
|
|
974
953
|
segmentSeconds: zod.z.number().int().positive().optional(),
|
|
975
|
-
/** Shared recording time-bands for `events` & `continuous` — record only when
|
|
976
|
-
* the wall-clock falls inside one of these windows. Omit or empty = always.
|
|
977
|
-
* `continuous` compiles to one rule per band; `events` to band × trigger. */
|
|
978
|
-
schedules: zod.z.array(RecordingScheduleSchema).optional(),
|
|
979
|
-
/** Legacy single-band predecessor of `schedules`. Read-compat only — it is
|
|
980
|
-
* normalized into `schedules` on read and never written going forward. (Not
|
|
981
|
-
* tagged `@deprecated`: the normalization paths must read it cast-free.) */
|
|
982
|
-
schedule: RecordingScheduleSchema.optional(),
|
|
983
|
-
/** `events`-mode only — which detectors trigger a recording. */
|
|
984
|
-
triggers: RecordingTriggersSchema.optional(),
|
|
985
|
-
/** `events`-mode only — seconds retained before / after a trigger. */
|
|
986
|
-
preBufferSec: zod.z.number().min(0).optional(),
|
|
987
|
-
postBufferSec: zod.z.number().min(0).optional(),
|
|
988
|
-
/** DEPRECATED authoring input; retained for migration/transition. */
|
|
989
|
-
rules: zod.z.array(RecordingRuleSchema).optional(),
|
|
990
954
|
/**
|
|
991
|
-
* AUTHORITATIVE mode-per-band recording model
|
|
992
|
-
*
|
|
993
|
-
*
|
|
994
|
-
* derived into bands once via `migrateConfigToBands`.
|
|
955
|
+
* AUTHORITATIVE mode-per-band recording model — the single source of truth
|
|
956
|
+
* the recorder's band engine consumes. An empty array = record nothing;
|
|
957
|
+
* "off" is the absence of a covering band, never a band value.
|
|
995
958
|
*/
|
|
996
|
-
bands: zod.z.array(RecordingBandSchema).
|
|
959
|
+
bands: zod.z.array(RecordingBandSchema).default([]),
|
|
997
960
|
retention: RecordingRetentionSchema.optional(),
|
|
998
961
|
/**
|
|
999
962
|
* Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
|
|
@@ -1001,62 +964,30 @@ var RecordingConfigSchema = zod.z.object({
|
|
|
1001
964
|
* windows only — existing sheets are immutable, and each window's index
|
|
1002
965
|
* carries its own tile dims so mixed-preset history renders correctly.
|
|
1003
966
|
*/
|
|
1004
|
-
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
*
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
*
|
|
1021
|
-
*
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
function
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
if (mode === "continuous") return {
|
|
1029
|
-
days,
|
|
1030
|
-
start,
|
|
1031
|
-
end,
|
|
1032
|
-
mode
|
|
1033
|
-
};
|
|
1034
|
-
return {
|
|
1035
|
-
days,
|
|
1036
|
-
start,
|
|
1037
|
-
end,
|
|
1038
|
-
mode,
|
|
1039
|
-
...config.triggers ? { triggers: config.triggers } : {},
|
|
1040
|
-
...config.preBufferSec !== void 0 ? { preBufferSec: config.preBufferSec } : {},
|
|
1041
|
-
...config.postBufferSec !== void 0 ? { postBufferSec: config.postBufferSec } : {}
|
|
1042
|
-
};
|
|
1043
|
-
}
|
|
1044
|
-
/**
|
|
1045
|
-
* One-way migration from the legacy recording-config shape to the authoritative
|
|
1046
|
-
* mode-per-band model. Pure (no clock access).
|
|
1047
|
-
*
|
|
1048
|
-
* - If `config.bands` is present, it is authoritative and returned as-is.
|
|
1049
|
-
* - Otherwise the result is derived from the legacy fields: a disabled config or
|
|
1050
|
-
* `mode: 'off'` yields no bands; every legacy schedule maps to one band whose
|
|
1051
|
-
* mode is `continuous` when `config.mode === 'continuous'`, else `events`
|
|
1052
|
-
* (carrying `triggers`/`preBufferSec`/`postBufferSec`).
|
|
1053
|
-
*/
|
|
1054
|
-
function migrateConfigToBands(config) {
|
|
1055
|
-
if (config.bands) return config.bands;
|
|
1056
|
-
if (!config.enabled || config.mode === "off") return [];
|
|
1057
|
-
const schedules = config.schedules ?? (config.schedule ? [config.schedule] : [{ kind: "always" }]);
|
|
1058
|
-
const bandMode = config.mode === "continuous" ? "continuous" : "events";
|
|
1059
|
-
return schedules.map((schedule) => bandFromSchedule(schedule, bandMode, config));
|
|
967
|
+
scrubThumbnails: ScrubThumbnailPresetSchema.optional(),
|
|
968
|
+
/**
|
|
969
|
+
* OPT-IN thumbnail-strip generation for this camera: every keyframe of the
|
|
970
|
+
* low recording saved as a JPEG (the fast-drag scrub depth), a derived
|
|
971
|
+
* cache that eviction reclaims with the footage. Absent/false = no strips
|
|
972
|
+
* are written and scrub reads exact keyframes at every velocity.
|
|
973
|
+
*/
|
|
974
|
+
stripsEnabled: zod.z.boolean().optional()
|
|
975
|
+
}).strict();
|
|
976
|
+
/**
|
|
977
|
+
* Derive the {@link RecordingStorageModeSchema} summary from the authoritative
|
|
978
|
+
* bands: `continuous` when any band records continuously, `events` when a band
|
|
979
|
+
* exists at all, else `off`. Pure.
|
|
980
|
+
*
|
|
981
|
+
* THE one definition: the recorder stamps `config.mode` with it on save and
|
|
982
|
+
* reports it as the cap's `activeMode`, and the settings UI reads it back to
|
|
983
|
+
* decide which authoring tab a config opens in. Two copies would drift, and the
|
|
984
|
+
* symptom (a status dot disagreeing with what is being recorded) is exactly the
|
|
985
|
+
* bug this field was added to fix.
|
|
986
|
+
*/
|
|
987
|
+
function deriveRecordingMode(config) {
|
|
988
|
+
if (!config.enabled || config.bands.length === 0) return "off";
|
|
989
|
+
if (config.bands.some((band) => band.mode === "continuous")) return "continuous";
|
|
990
|
+
return "events";
|
|
1060
991
|
}
|
|
1061
992
|
//#endregion
|
|
1062
993
|
//#region src/interfaces/ops-log.ts
|
|
@@ -1078,7 +1009,8 @@ var OpsLogOpSchema = zod.z.enum([
|
|
|
1078
1009
|
"prune",
|
|
1079
1010
|
"manual-delete",
|
|
1080
1011
|
"rescan",
|
|
1081
|
-
"retention-run"
|
|
1012
|
+
"retention-run",
|
|
1013
|
+
"relocate"
|
|
1082
1014
|
]);
|
|
1083
1015
|
/** Why the operation ran. */
|
|
1084
1016
|
var OpsLogReasonSchema = zod.z.enum([
|
|
@@ -1124,6 +1056,57 @@ var OPS_LOG_RING_DEFAULT_MAX = 500;
|
|
|
1124
1056
|
/** Default page size for a `listOpsLog` query when the caller omits `limit`. */
|
|
1125
1057
|
var OPS_LOG_DEFAULT_LIMIT = 200;
|
|
1126
1058
|
//#endregion
|
|
1059
|
+
//#region src/interfaces/relocate.ts
|
|
1060
|
+
/**
|
|
1061
|
+
* Entity-relocation job state (storage entity-routing spec, Phase 4).
|
|
1062
|
+
*
|
|
1063
|
+
* One shape shared by the recorder's `relocateFootage` (segments + strips) and
|
|
1064
|
+
* pipeline-analytics' `relocateMedia` (event media blobs) so the admin Data
|
|
1065
|
+
* page renders both movers with one component. Jobs are in-RAM (a restart
|
|
1066
|
+
* forgets them — re-running is safe by construction: copy-if-absent, delete
|
|
1067
|
+
* after verify) and each completed/failed run also lands one durable ops-log
|
|
1068
|
+
* row on the owning addon's surface.
|
|
1069
|
+
*/
|
|
1070
|
+
var RelocateJobStateSchema = zod.z.enum([
|
|
1071
|
+
"running",
|
|
1072
|
+
"done",
|
|
1073
|
+
"failed",
|
|
1074
|
+
"cancelled"
|
|
1075
|
+
]);
|
|
1076
|
+
var RelocateJobSchema = zod.z.object({
|
|
1077
|
+
jobId: zod.z.string(),
|
|
1078
|
+
state: RelocateJobStateSchema,
|
|
1079
|
+
/** Source location — for media relocation this is informational ('*': rows
|
|
1080
|
+
* move from wherever they are to the target). */
|
|
1081
|
+
fromLocationId: zod.z.string(),
|
|
1082
|
+
toLocationId: zod.z.string(),
|
|
1083
|
+
/** Scoped device, or null = every device. */
|
|
1084
|
+
deviceId: zod.z.number().nullable(),
|
|
1085
|
+
/** What the job moves (owner-addon specific: segments/strips or media). */
|
|
1086
|
+
entities: zod.z.array(zod.z.string()),
|
|
1087
|
+
filesMoved: zod.z.number().int(),
|
|
1088
|
+
bytesMoved: zod.z.number().int(),
|
|
1089
|
+
/** Total files discovered up front; null while (or when) unknown. */
|
|
1090
|
+
filesTotal: zod.z.number().int().nullable(),
|
|
1091
|
+
startedAt: zod.z.number(),
|
|
1092
|
+
finishedAt: zod.z.number().nullable(),
|
|
1093
|
+
error: zod.z.string().nullable()
|
|
1094
|
+
});
|
|
1095
|
+
var RelocateFootageInputSchema = zod.z.object({
|
|
1096
|
+
deviceId: zod.z.number().optional(),
|
|
1097
|
+
fromLocationId: zod.z.string(),
|
|
1098
|
+
toLocationId: zod.z.string(),
|
|
1099
|
+
entities: zod.z.array(zod.z.enum(["segments", "strips"])).optional(),
|
|
1100
|
+
/** Copy throttle in MB/s (default 40) — the drain is a background chore,
|
|
1101
|
+
* never allowed to starve live writers. */
|
|
1102
|
+
throttleMbps: zod.z.number().min(1).max(1e3).optional()
|
|
1103
|
+
});
|
|
1104
|
+
var RelocateMediaInputSchema = zod.z.object({
|
|
1105
|
+
deviceId: zod.z.number().optional(),
|
|
1106
|
+
toLocationId: zod.z.string(),
|
|
1107
|
+
throttleMbps: zod.z.number().min(1).max(1e3).optional()
|
|
1108
|
+
});
|
|
1109
|
+
//#endregion
|
|
1127
1110
|
//#region src/interfaces/logging.ts
|
|
1128
1111
|
/**
|
|
1129
1112
|
* Severity ordering. Declared once here because it had already been re-declared
|
|
@@ -1197,6 +1180,13 @@ var StorageLocationSchema = zod.z.object({
|
|
|
1197
1180
|
nodeId: zod.z.string().optional(),
|
|
1198
1181
|
isDefault: zod.z.boolean().default(false),
|
|
1199
1182
|
isSystem: zod.z.boolean().default(false),
|
|
1183
|
+
/** COMPUTED at read time by the orchestrator (statfs of the backing volume
|
|
1184
|
+
* for node-local locations it can reach) — never persisted, absent when the
|
|
1185
|
+
* volume is remote/unreachable. The single capacity truth every UI reads. */
|
|
1186
|
+
capacity: zod.z.object({
|
|
1187
|
+
totalBytes: zod.z.number(),
|
|
1188
|
+
availableBytes: zod.z.number()
|
|
1189
|
+
}).nullable().optional(),
|
|
1200
1190
|
createdAt: zod.z.number(),
|
|
1201
1191
|
updatedAt: zod.z.number()
|
|
1202
1192
|
});
|
|
@@ -1260,16 +1250,23 @@ var StorageLocationDeclarationSchema = zod.z.object({
|
|
|
1260
1250
|
* Which node root the seeded `<id>:default` instance is placed under on a
|
|
1261
1251
|
* FRESH install:
|
|
1262
1252
|
* - `'data'` (default) — the node's data dir (`CAMSTACK_DATA` / boot dir),
|
|
1263
|
-
* the appData volume. Right for small/durable data (
|
|
1253
|
+
* the appData volume. Right for small/durable data (logs, models).
|
|
1264
1254
|
* - `'media'` — the dedicated media volume (`CAMSTACK_MEDIA_ROOT`) when that
|
|
1265
1255
|
* env is set, else falls back to the data root. Right for bulky, hot media
|
|
1266
1256
|
* (recordings, event media) that should stay off the appData disk.
|
|
1257
|
+
* - `'backup'` — the dedicated backup volume (`CAMSTACK_BACKUP_ROOT`, default
|
|
1258
|
+
* `/backups` in the image) so archives live on their own mount rather than
|
|
1259
|
+
* filling the appData disk. Falls back to the data root when unset.
|
|
1267
1260
|
*
|
|
1268
1261
|
* Only affects the seeded default's `basePath`; operators can repoint any
|
|
1269
1262
|
* location afterwards, and a `defaultsTo` slot inherits its parent's root
|
|
1270
1263
|
* regardless of this field. Absent (the common case) is treated as `'data'`.
|
|
1271
1264
|
*/
|
|
1272
|
-
defaultRoot: zod.z.enum([
|
|
1265
|
+
defaultRoot: zod.z.enum([
|
|
1266
|
+
"data",
|
|
1267
|
+
"media",
|
|
1268
|
+
"backup"
|
|
1269
|
+
]).optional()
|
|
1273
1270
|
});
|
|
1274
1271
|
//#endregion
|
|
1275
1272
|
//#region src/interfaces/device-capabilities/camera.ts
|
|
@@ -4337,9 +4334,20 @@ var DEGRADE_ORDER = {
|
|
|
4337
4334
|
"markdown"
|
|
4338
4335
|
]
|
|
4339
4336
|
};
|
|
4340
|
-
/**
|
|
4337
|
+
/**
|
|
4338
|
+
* Pick the best target format the kind supports for a given source format.
|
|
4339
|
+
*
|
|
4340
|
+
* TOLERANT of a source outside the union. `NotificationSchema.format` carries
|
|
4341
|
+
* `.default('text')`, but that default only runs where the schema is PARSED —
|
|
4342
|
+
* the tRPC router. A cap call arriving from another addon (`ctx.api`) skips
|
|
4343
|
+
* that parse, so `format` reaches here `undefined`, and the bare
|
|
4344
|
+
* `DEGRADE_ORDER[source]` threw `is not iterable`. That broke the one promise
|
|
4345
|
+
* the degrade path makes ("never throws — degradation is reported, never
|
|
4346
|
+
* surfaced as an error") and dead-lettered every Notification-Center delivery
|
|
4347
|
+
* for a day (2026-07-30). An unknown source degrades like `text`.
|
|
4348
|
+
*/
|
|
4341
4349
|
function resolveFormat(source, supported) {
|
|
4342
|
-
for (const candidate of DEGRADE_ORDER[source]) if (supported.includes(candidate)) return candidate;
|
|
4350
|
+
for (const candidate of DEGRADE_ORDER[source] ?? DEGRADE_ORDER.text) if (supported.includes(candidate)) return candidate;
|
|
4343
4351
|
return supported[0] ?? "text";
|
|
4344
4352
|
}
|
|
4345
4353
|
/** Transcode a body between formats. */
|
|
@@ -4386,7 +4394,7 @@ function resolveLevel(levels, n) {
|
|
|
4386
4394
|
})[0]);
|
|
4387
4395
|
}
|
|
4388
4396
|
function splitBody(body, maxLen) {
|
|
4389
|
-
if (maxLen <= 0 || body.length <= maxLen) return [body];
|
|
4397
|
+
if (!Number.isFinite(maxLen) || maxLen <= 0 || body.length <= maxLen) return [body];
|
|
4390
4398
|
const parts = [];
|
|
4391
4399
|
for (let i = 0; i < body.length; i += maxLen) parts.push(body.slice(i, i + maxLen));
|
|
4392
4400
|
return parts;
|
|
@@ -4470,6 +4478,114 @@ function prepareNotification(caps, n) {
|
|
|
4470
4478
|
};
|
|
4471
4479
|
}
|
|
4472
4480
|
//#endregion
|
|
4481
|
+
//#region src/notification/condition-taxonomy.ts
|
|
4482
|
+
/** Condition ids that render the class picker (video macros/subs + audio). */
|
|
4483
|
+
var CLASS_CONDITION_IDS = new Set(["classes", "classesExclude"]);
|
|
4484
|
+
/** Condition ids that render the sensor/control label picker. */
|
|
4485
|
+
var LABEL_CONDITION_IDS = new Set(["sensorKinds"]);
|
|
4486
|
+
function toOption(entry) {
|
|
4487
|
+
return {
|
|
4488
|
+
value: entry.kind,
|
|
4489
|
+
label: entry.label
|
|
4490
|
+
};
|
|
4491
|
+
}
|
|
4492
|
+
/**
|
|
4493
|
+
* Group detection entries by their macro. A macro entry (`parentKind === null`)
|
|
4494
|
+
* opens its own group and is itself the first option in it; subs fall under
|
|
4495
|
+
* their `parentKind`. First-appearance order is preserved, which is why
|
|
4496
|
+
* `buildNcTaxonomy` emits macros before their subs.
|
|
4497
|
+
*/
|
|
4498
|
+
function groupVideoClasses(videoClasses) {
|
|
4499
|
+
const order = [];
|
|
4500
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
4501
|
+
const ensure = (key, fallbackLabel) => {
|
|
4502
|
+
const existing = byKey.get(key);
|
|
4503
|
+
if (existing !== void 0) return existing;
|
|
4504
|
+
const created = {
|
|
4505
|
+
fallbackLabel,
|
|
4506
|
+
options: []
|
|
4507
|
+
};
|
|
4508
|
+
byKey.set(key, created);
|
|
4509
|
+
order.push(key);
|
|
4510
|
+
return created;
|
|
4511
|
+
};
|
|
4512
|
+
for (const entry of videoClasses) {
|
|
4513
|
+
const key = entry.parentKind ?? entry.kind;
|
|
4514
|
+
const group = ensure(key, entry.parentKind === null ? entry.label : key);
|
|
4515
|
+
group.options.push(toOption(entry));
|
|
4516
|
+
if (entry.parentKind === null) group.fallbackLabel = entry.label;
|
|
4517
|
+
}
|
|
4518
|
+
return order.flatMap((key) => {
|
|
4519
|
+
const group = byKey.get(key);
|
|
4520
|
+
return group === void 0 ? [] : [{
|
|
4521
|
+
key,
|
|
4522
|
+
fallbackLabel: group.fallbackLabel,
|
|
4523
|
+
options: group.options
|
|
4524
|
+
}];
|
|
4525
|
+
});
|
|
4526
|
+
}
|
|
4527
|
+
/** Group sensor/control labels by their category parent (`sensor` | `control`). */
|
|
4528
|
+
function groupLabels(labels) {
|
|
4529
|
+
const order = [];
|
|
4530
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
4531
|
+
for (const entry of labels) {
|
|
4532
|
+
const key = entry.parentKind ?? "other";
|
|
4533
|
+
const existing = byKey.get(key);
|
|
4534
|
+
if (existing === void 0) {
|
|
4535
|
+
byKey.set(key, [toOption(entry)]);
|
|
4536
|
+
order.push(key);
|
|
4537
|
+
} else existing.push(toOption(entry));
|
|
4538
|
+
}
|
|
4539
|
+
return order.flatMap((key) => {
|
|
4540
|
+
const options = byKey.get(key);
|
|
4541
|
+
return options === void 0 ? [] : [{
|
|
4542
|
+
key,
|
|
4543
|
+
fallbackLabel: key,
|
|
4544
|
+
options
|
|
4545
|
+
}];
|
|
4546
|
+
});
|
|
4547
|
+
}
|
|
4548
|
+
/**
|
|
4549
|
+
* Build the grouped picker model for a condition id, or `null` when the
|
|
4550
|
+
* condition has no fixed vocabulary (→ free-text tag input).
|
|
4551
|
+
*/
|
|
4552
|
+
function pickerForCondition(conditionId, taxonomy) {
|
|
4553
|
+
if (!taxonomy) return null;
|
|
4554
|
+
if (CLASS_CONDITION_IDS.has(conditionId)) {
|
|
4555
|
+
const groups = groupVideoClasses(taxonomy.videoClasses);
|
|
4556
|
+
if (taxonomy.audioKinds.length > 0) groups.push({
|
|
4557
|
+
key: "audio",
|
|
4558
|
+
fallbackLabel: "Audio",
|
|
4559
|
+
options: taxonomy.audioKinds.map(toOption)
|
|
4560
|
+
});
|
|
4561
|
+
return groups.length > 0 ? { groups } : null;
|
|
4562
|
+
}
|
|
4563
|
+
if (LABEL_CONDITION_IDS.has(conditionId)) {
|
|
4564
|
+
const groups = groupLabels(taxonomy.labels);
|
|
4565
|
+
return groups.length > 0 ? { groups } : null;
|
|
4566
|
+
}
|
|
4567
|
+
return null;
|
|
4568
|
+
}
|
|
4569
|
+
/** All option values across a picker's groups (for custom-value detection). */
|
|
4570
|
+
function knownValues(picker) {
|
|
4571
|
+
const set = /* @__PURE__ */ new Set();
|
|
4572
|
+
for (const group of picker.groups) for (const option of group.options) set.add(option.value);
|
|
4573
|
+
return set;
|
|
4574
|
+
}
|
|
4575
|
+
/**
|
|
4576
|
+
* The condition ids shown in the ALWAYS-VISIBLE area of a rule editor. Every
|
|
4577
|
+
* other catalog descriptor is advanced and lives behind an expander.
|
|
4578
|
+
*
|
|
4579
|
+
* Shared for the same reason as the picker model: two surfaces disagreeing
|
|
4580
|
+
* about what counts as "basic" is a worse outcome than either choice.
|
|
4581
|
+
*/
|
|
4582
|
+
var NC_BASE_CONDITION_KEYS = ["devices", "classes"];
|
|
4583
|
+
var BASE_CONDITION_SET = new Set(NC_BASE_CONDITION_KEYS);
|
|
4584
|
+
/** True when a condition key belongs to the BASE surface. */
|
|
4585
|
+
function isBaseConditionKey(key) {
|
|
4586
|
+
return BASE_CONDITION_SET.has(key);
|
|
4587
|
+
}
|
|
4588
|
+
//#endregion
|
|
4473
4589
|
//#region src/capabilities/mask-shape.ts
|
|
4474
4590
|
/**
|
|
4475
4591
|
* Shared geometry vocabulary for on-frame shape caps — privacy-mask,
|
|
@@ -4800,12 +4916,60 @@ var NcRuleTargetSchema = zod.z.object({
|
|
|
4800
4916
|
* - `keyFrame` — the clean scene frame (no subject box).
|
|
4801
4917
|
* - `none` — no attachment.
|
|
4802
4918
|
*/
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4919
|
+
/**
|
|
4920
|
+
* WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
|
|
4921
|
+
* conflate it with the selection strategy and betray the request: asking for
|
|
4922
|
+
* the clean scene frame on an object-event owner used to start at
|
|
4923
|
+
* `fullFrameBoxed`, i.e. the annotated frame (2026-07-30).
|
|
4924
|
+
* - `cropped` — the subject, tight. What "who is at the door" wants.
|
|
4925
|
+
* - `full` — the clean scene, no annotation. What "what is going on" wants.
|
|
4926
|
+
* - `boxed` — the scene WITH the detection boxes drawn, for verifying what
|
|
4927
|
+
* the pipeline actually saw.
|
|
4928
|
+
*/
|
|
4929
|
+
var NcMediaFrameSchema = zod.z.enum([
|
|
4930
|
+
"cropped",
|
|
4931
|
+
"full",
|
|
4932
|
+
"boxed"
|
|
4933
|
+
]);
|
|
4934
|
+
var NcMediaPolicySchema = zod.z.object({
|
|
4935
|
+
attach: zod.z.enum([
|
|
4936
|
+
"best",
|
|
4937
|
+
"best-matching",
|
|
4938
|
+
"keyFrame",
|
|
4939
|
+
"none"
|
|
4940
|
+
]).default("best"),
|
|
4941
|
+
/** What the still shows. Absent = `cropped` (the historical `best` shape). */
|
|
4942
|
+
frame: NcMediaFrameSchema.optional(),
|
|
4943
|
+
/** Crop the attached still to the rule's condition-zone bbox (padded) —
|
|
4944
|
+
* "show me the ZONE", not the whole scene or the subject crop. */
|
|
4945
|
+
zoneCrop: zod.z.boolean().optional(),
|
|
4946
|
+
/**
|
|
4947
|
+
* Also attach a short GIF cut from the stream broker's clip ring around the
|
|
4948
|
+
* event — NOT from the recording, so the camera does not have to be
|
|
4949
|
+
* recording, and the window sits AROUND the moment instead of a segment
|
|
4950
|
+
* behind it. Fail-closed: a window the ring does not cover contributes no
|
|
4951
|
+
* gif, never a failed notification.
|
|
4952
|
+
*/
|
|
4953
|
+
gif: zod.z.boolean().optional(),
|
|
4954
|
+
/**
|
|
4955
|
+
* Also attach a short MP4 CLIP of the same cut. Same source and the same
|
|
4956
|
+
* fail-closed rule as `gif`. Prefer it where the backend takes video
|
|
4957
|
+
* (telegram, discord, zentik, webhook); backends that do not are handled by
|
|
4958
|
+
* the degrade engine, which drops the video and keeps the still.
|
|
4959
|
+
*/
|
|
4960
|
+
clip: zod.z.boolean().optional(),
|
|
4961
|
+
/** Seconds of footage BEFORE / AFTER the event instant. Defaults 3 / 7. */
|
|
4962
|
+
clipPreRollSec: zod.z.number().int().min(0).max(30).optional(),
|
|
4963
|
+
clipPostRollSec: zod.z.number().int().min(0).max(30).optional(),
|
|
4964
|
+
/**
|
|
4965
|
+
* Which stream profile the footage is cut from. Absent = the CHEAPEST
|
|
4966
|
+
* assigned profile: a notification is watched on a phone, so the 4K
|
|
4967
|
+
* rendition would burn CPU to produce a file the client downscales anyway.
|
|
4968
|
+
* A profile that is not assigned falls back to the cheapest, and the render
|
|
4969
|
+
* reports which one actually ran.
|
|
4970
|
+
*/
|
|
4971
|
+
profile: require_sleep.CamProfileSchema.optional()
|
|
4972
|
+
});
|
|
4809
4973
|
/** Throttle — cooldown survives restarts (rebuilt from the outbox on boot). */
|
|
4810
4974
|
var NcThrottleSchema = zod.z.object({
|
|
4811
4975
|
cooldownSec: zod.z.number().int().min(0).max(86400).default(60),
|
|
@@ -4819,7 +4983,19 @@ var NcRuleInputSchema = zod.z.object({
|
|
|
4819
4983
|
delivery: NcDeliverySchema,
|
|
4820
4984
|
conditions: NcConditionsSchema.default({}),
|
|
4821
4985
|
schedule: NcScheduleSchema.optional(),
|
|
4822
|
-
|
|
4986
|
+
/** May be empty when `targetUsers` addresses at least one user — the
|
|
4987
|
+
* "at least one addressee" invariant is enforced by the provider, because
|
|
4988
|
+
* a cross-field refine here would break `NcRulePatchSchema.partial()`. */
|
|
4989
|
+
targets: zod.z.array(NcRuleTargetSchema),
|
|
4990
|
+
/**
|
|
4991
|
+
* USERS this rule addresses in addition to `targets` (Phase 4). At fire
|
|
4992
|
+
* time each user fans out to the personal targets they own
|
|
4993
|
+
* (`config.ownerUserId`), filtered by that user's `allowedDevices` for the
|
|
4994
|
+
* firing camera — a user is never notified about a device they cannot open.
|
|
4995
|
+
* Per-user opt-outs (`disabledTargetIds`) still apply to the fanned-out
|
|
4996
|
+
* targets.
|
|
4997
|
+
*/
|
|
4998
|
+
targetUsers: zod.z.array(zod.z.string()).optional(),
|
|
4823
4999
|
media: NcMediaPolicySchema.default({ attach: "best" }),
|
|
4824
5000
|
throttle: NcThrottleSchema.default({
|
|
4825
5001
|
cooldownSec: 60,
|
|
@@ -5294,7 +5470,20 @@ var notificationRulesCapability = {
|
|
|
5294
5470
|
kind: "mutation",
|
|
5295
5471
|
auth: "admin"
|
|
5296
5472
|
}),
|
|
5297
|
-
|
|
5473
|
+
/**
|
|
5474
|
+
* The machine-readable condition surface a rule editor renders from, plus
|
|
5475
|
+
* the picker VOCABULARY those conditions draw on.
|
|
5476
|
+
*
|
|
5477
|
+
* `taxonomy` is optional so an older provider that only returns `catalog`
|
|
5478
|
+
* still validates; a client that receives none keeps free-text inputs.
|
|
5479
|
+
* It was previously served ONLY on the `nc.getConditionCatalog` bridge
|
|
5480
|
+
* action, which is why the viewer had grouped pickers and the admin UI —
|
|
5481
|
+
* which reaches this cap — was stuck typing `person` from memory.
|
|
5482
|
+
*/
|
|
5483
|
+
getConditionCatalog: require_sleep.method(zod.z.object({}), zod.z.object({
|
|
5484
|
+
catalog: zod.z.array(NcConditionDescriptorSchema),
|
|
5485
|
+
taxonomy: NcTaxonomySchema.optional()
|
|
5486
|
+
})),
|
|
5298
5487
|
/**
|
|
5299
5488
|
* Queryable delivery history — a read-only view over the durable outbox
|
|
5300
5489
|
* (fired rule, subject summary, target, status, timestamps, error on a
|
|
@@ -6383,6 +6572,48 @@ var streamBrokerCapability = {
|
|
|
6383
6572
|
kind: "mutation",
|
|
6384
6573
|
auth: "admin"
|
|
6385
6574
|
}),
|
|
6575
|
+
/**
|
|
6576
|
+
* Render a short GIF or MP4 from the broker's PRE-BUFFER around an instant.
|
|
6577
|
+
*
|
|
6578
|
+
* The pre-buffer is the only source that already holds the seconds BEFORE
|
|
6579
|
+
* an event (it is what it exists for — "when an addon needs the last N
|
|
6580
|
+
* seconds of video for clip creation"). Cutting from recorded segments
|
|
6581
|
+
* cannot: only finalized segments are addressable and the one covering the
|
|
6582
|
+
* moment is still being written, so a segment-sourced clip is either
|
|
6583
|
+
* delayed or shows the approach instead of the event (operator,
|
|
6584
|
+
* 2026-07-30). It also means a camera does not have to be RECORDING to
|
|
6585
|
+
* produce a notification clip.
|
|
6586
|
+
*
|
|
6587
|
+
* Returns muxed BYTES, never packets: the frame plane never crosses a
|
|
6588
|
+
* process boundary at frame rate (D9/D18) — this is one compressed,
|
|
6589
|
+
* on-demand payload per notification.
|
|
6590
|
+
*
|
|
6591
|
+
* Waits up to `postRollSec` for the tail to accumulate, so the window is
|
|
6592
|
+
* CENTRED on `aroundMs`.
|
|
6593
|
+
*/
|
|
6594
|
+
renderPreBufferClip: require_sleep.method(zod.z.object({
|
|
6595
|
+
deviceId: zod.z.number(),
|
|
6596
|
+
/** Absent = the LOWEST assigned profile — a notification attachment is
|
|
6597
|
+
* watched on a phone, and the cheap rendition is the right default. */
|
|
6598
|
+
profile: require_sleep.CamProfileSchema.optional(),
|
|
6599
|
+
aroundMs: zod.z.number(),
|
|
6600
|
+
preRollSec: zod.z.number().min(0).max(20).default(3),
|
|
6601
|
+
postRollSec: zod.z.number().min(0).max(20).default(5),
|
|
6602
|
+
format: zod.z.enum(["gif", "mp4"]).default("gif"),
|
|
6603
|
+
maxWidth: zod.z.number().int().min(120).max(1920).default(480),
|
|
6604
|
+
/** GIF only — MP4 keeps the source cadence. */
|
|
6605
|
+
fps: zod.z.number().int().min(1).max(15).default(5)
|
|
6606
|
+
}), zod.z.object({
|
|
6607
|
+
base64: zod.z.string(),
|
|
6608
|
+
mime: zod.z.string(),
|
|
6609
|
+
bytes: zod.z.number().int(),
|
|
6610
|
+
/** The profile actually rendered (what the default resolved to). */
|
|
6611
|
+
profile: require_sleep.CamProfileSchema,
|
|
6612
|
+
durationMs: zod.z.number()
|
|
6613
|
+
}), {
|
|
6614
|
+
kind: "mutation",
|
|
6615
|
+
auth: "admin"
|
|
6616
|
+
}),
|
|
6386
6617
|
listAllCameraStreams: require_sleep.method(zod.z.void(), zod.z.array(require_sleep.CameraStreamSchema).readonly()),
|
|
6387
6618
|
listAllProfileSlots: require_sleep.method(zod.z.void(), zod.z.array(require_sleep.ProfileSlotSchema).readonly()),
|
|
6388
6619
|
getBrokerStats: require_sleep.method(zod.z.object({ brokerId: zod.z.string() }), require_sleep.BrokerStatsSchema),
|
|
@@ -14269,7 +14500,10 @@ function createSystemProxy(api) {
|
|
|
14269
14500
|
delete: (input) => dispatch("backup", "delete", "mutation", input),
|
|
14270
14501
|
listArchives: (input) => dispatch("backup", "listArchives", "query", input),
|
|
14271
14502
|
upsertDestinationPolicy: (input) => dispatch("backup", "upsertDestinationPolicy", "mutation", input),
|
|
14272
|
-
previewSchedule: (input) => dispatch("backup", "previewSchedule", "query", input)
|
|
14503
|
+
previewSchedule: (input) => dispatch("backup", "previewSchedule", "query", input),
|
|
14504
|
+
listSchedules: (input) => dispatch("backup", "listSchedules", "query", input),
|
|
14505
|
+
upsertSchedule: (input) => dispatch("backup", "upsertSchedule", "mutation", input),
|
|
14506
|
+
deleteSchedule: (input) => dispatch("backup", "deleteSchedule", "mutation", input)
|
|
14273
14507
|
},
|
|
14274
14508
|
broker: {
|
|
14275
14509
|
list: (input) => dispatch("broker", "list", "query", input),
|
|
@@ -14423,6 +14657,8 @@ function createSystemProxy(api) {
|
|
|
14423
14657
|
list: (input) => dispatch("localNetwork", "list", "query", input),
|
|
14424
14658
|
getPreferred: (input) => dispatch("localNetwork", "getPreferred", "query", input),
|
|
14425
14659
|
getConnectionEndpoints: (input) => dispatch("localNetwork", "getConnectionEndpoints", "query", input),
|
|
14660
|
+
getNotificationEndpoint: (input) => dispatch("localNetwork", "getNotificationEndpoint", "query", input),
|
|
14661
|
+
setNotificationEndpoint: (input) => dispatch("localNetwork", "setNotificationEndpoint", "mutation", input),
|
|
14426
14662
|
getAllowedAddresses: (input) => dispatch("localNetwork", "getAllowedAddresses", "query", input),
|
|
14427
14663
|
setAllowedAddresses: (input) => dispatch("localNetwork", "setAllowedAddresses", "mutation", input),
|
|
14428
14664
|
resetAllowlistToBestMatch: (input) => dispatch("localNetwork", "resetAllowlistToBestMatch", "mutation", input)
|
|
@@ -14593,7 +14829,10 @@ function createSystemProxy(api) {
|
|
|
14593
14829
|
},
|
|
14594
14830
|
recording: {
|
|
14595
14831
|
getStorageUsage: (input) => dispatch("recording", "getStorageUsage", "query", input),
|
|
14596
|
-
listOpsLog: (input) => dispatch("recording", "listOpsLog", "query", input)
|
|
14832
|
+
listOpsLog: (input) => dispatch("recording", "listOpsLog", "query", input),
|
|
14833
|
+
relocateFootage: (input) => dispatch("recording", "relocateFootage", "mutation", input),
|
|
14834
|
+
getRelocateStatus: (input) => dispatch("recording", "getRelocateStatus", "query", input),
|
|
14835
|
+
cancelRelocate: (input) => dispatch("recording", "cancelRelocate", "mutation", input)
|
|
14597
14836
|
},
|
|
14598
14837
|
recordingExport: {
|
|
14599
14838
|
getExport: (input) => dispatch("recordingExport", "getExport", "query", input),
|
|
@@ -16301,6 +16540,41 @@ var LocationStatSchema = zod.z.object({
|
|
|
16301
16540
|
present: zod.z.boolean()
|
|
16302
16541
|
});
|
|
16303
16542
|
/**
|
|
16543
|
+
* A backup schedule — the N:M "entry" that binds one cron cadence to a
|
|
16544
|
+
* SET of destination locations. Supersedes the per-location cron on
|
|
16545
|
+
* `BackupDestinationPolicy`: an operator creates a schedule, picks the
|
|
16546
|
+
* `backups` locations it should write to, and the orchestrator fans a
|
|
16547
|
+
* single archive out to all of them when the cron fires.
|
|
16548
|
+
*
|
|
16549
|
+
* `retentionCount` is per-schedule (D-decision 2026-07-28): every
|
|
16550
|
+
* location targeted by this schedule keeps this many archives from
|
|
16551
|
+
* this schedule's runs.
|
|
16552
|
+
*
|
|
16553
|
+
* `dataSources` optionally narrows which top-level state locations
|
|
16554
|
+
* (db, addons, tls, …) are archived; omitted = the orchestrator's
|
|
16555
|
+
* default full set.
|
|
16556
|
+
*/
|
|
16557
|
+
var BackupScheduleSchema = zod.z.object({
|
|
16558
|
+
/** Stable id. Generated by the orchestrator on first upsert if absent. */
|
|
16559
|
+
id: zod.z.string(),
|
|
16560
|
+
/** Operator-facing display name. */
|
|
16561
|
+
label: zod.z.string(),
|
|
16562
|
+
/** 5-field POSIX cron. Empty = disabled cadence (kept for editing). */
|
|
16563
|
+
cron: zod.z.string(),
|
|
16564
|
+
/** Master on/off toggle for the whole schedule. */
|
|
16565
|
+
enabled: zod.z.boolean(),
|
|
16566
|
+
/** `backups`-location ids this schedule writes to (fan-out set). */
|
|
16567
|
+
locationIds: zod.z.array(zod.z.string()).readonly(),
|
|
16568
|
+
/** Archives kept per targeted location for this schedule. */
|
|
16569
|
+
retentionCount: zod.z.number().int().min(1).max(1e3),
|
|
16570
|
+
/** Optional subset of source locations to include; omitted = all. */
|
|
16571
|
+
dataSources: zod.z.array(zod.z.string()).readonly().optional(),
|
|
16572
|
+
/** ms-epoch of last successful run. */
|
|
16573
|
+
lastRunAt: zod.z.number().optional(),
|
|
16574
|
+
/** ms-epoch of next computed firing (read-only, filled on list). */
|
|
16575
|
+
nextRunAt: zod.z.number().optional()
|
|
16576
|
+
});
|
|
16577
|
+
/**
|
|
16304
16578
|
* backup — singleton capability for backup management.
|
|
16305
16579
|
*
|
|
16306
16580
|
* Implemented by `local-backup` addon. Future providers (S3, rsync)
|
|
@@ -16327,7 +16601,14 @@ var backupCapability = {
|
|
|
16327
16601
|
/** Subset of registered `backup-destination` addon ids to write to. */
|
|
16328
16602
|
destinations: zod.z.array(zod.z.string()).optional(),
|
|
16329
16603
|
locations: zod.z.array(zod.z.string()).optional(),
|
|
16330
|
-
label: zod.z.string().optional()
|
|
16604
|
+
label: zod.z.string().optional(),
|
|
16605
|
+
/**
|
|
16606
|
+
* Per-run retention override applied to every targeted
|
|
16607
|
+
* destination. Used by schedule-driven runs (per-entry
|
|
16608
|
+
* retention). Omitted = each destination's own policy
|
|
16609
|
+
* retention (manual runs).
|
|
16610
|
+
*/
|
|
16611
|
+
retentionCount: zod.z.number().int().min(1).max(1e3).optional()
|
|
16331
16612
|
}).optional(), zod.z.array(BackupEntrySchema).readonly(), {
|
|
16332
16613
|
kind: "mutation",
|
|
16333
16614
|
auth: "admin"
|
|
@@ -16414,7 +16695,36 @@ var backupCapability = {
|
|
|
16414
16695
|
ok: zod.z.boolean(),
|
|
16415
16696
|
error: zod.z.string().optional(),
|
|
16416
16697
|
nextRuns: zod.z.array(zod.z.number()).readonly()
|
|
16417
|
-
}))
|
|
16698
|
+
})),
|
|
16699
|
+
/**
|
|
16700
|
+
* List every backup schedule (the N:M entries), each with its
|
|
16701
|
+
* computed `nextRunAt`. Powers the Schedules section of the
|
|
16702
|
+
* admin-UI Backups page.
|
|
16703
|
+
*/
|
|
16704
|
+
listSchedules: require_sleep.method(zod.z.void(), zod.z.array(BackupScheduleSchema).readonly(), { auth: "admin" }),
|
|
16705
|
+
/**
|
|
16706
|
+
* Create or replace a schedule. An empty / absent `id` mints a new
|
|
16707
|
+
* one; a present `id` replaces in place. `cron` is validated
|
|
16708
|
+
* server-side; `locationIds` must reference existing `backups`
|
|
16709
|
+
* locations (unknown ids are dropped with a warning).
|
|
16710
|
+
*/
|
|
16711
|
+
upsertSchedule: require_sleep.method(zod.z.object({
|
|
16712
|
+
id: zod.z.string().optional(),
|
|
16713
|
+
label: zod.z.string(),
|
|
16714
|
+
cron: zod.z.string(),
|
|
16715
|
+
enabled: zod.z.boolean(),
|
|
16716
|
+
locationIds: zod.z.array(zod.z.string()).readonly(),
|
|
16717
|
+
retentionCount: zod.z.number().int().min(1).max(1e3),
|
|
16718
|
+
dataSources: zod.z.array(zod.z.string()).readonly().optional()
|
|
16719
|
+
}), BackupScheduleSchema, {
|
|
16720
|
+
kind: "mutation",
|
|
16721
|
+
auth: "admin"
|
|
16722
|
+
}),
|
|
16723
|
+
/** Delete a schedule by id. Does not touch the target locations. */
|
|
16724
|
+
deleteSchedule: require_sleep.method(zod.z.object({ id: zod.z.string() }), zod.z.void(), {
|
|
16725
|
+
kind: "mutation",
|
|
16726
|
+
auth: "admin"
|
|
16727
|
+
})
|
|
16418
16728
|
}
|
|
16419
16729
|
};
|
|
16420
16730
|
//#endregion
|
|
@@ -19564,6 +19874,36 @@ var TargetKindSchema = zod.z.object({
|
|
|
19564
19874
|
icon: zod.z.string(),
|
|
19565
19875
|
/** Stamped by each provider so the concat-fanned catalog stays routable. */
|
|
19566
19876
|
addonId: zod.z.string(),
|
|
19877
|
+
/**
|
|
19878
|
+
* URL of the kind's bundled BRAND icon, served by the providing addon over
|
|
19879
|
+
* its own `addon-routes` surface (`/addon/<addonId>/icons/<kind>`). Absent
|
|
19880
|
+
* when the addon bundles no icon for that kind — the client then falls back
|
|
19881
|
+
* to a neutral glyph rather than rendering the raw `icon` NAME as text.
|
|
19882
|
+
*
|
|
19883
|
+
* Root-relative on purpose: it resolves against whatever origin serves a web
|
|
19884
|
+
* client, and a native client joins it onto its own hub base.
|
|
19885
|
+
*
|
|
19886
|
+
* DECLARED here deliberately. It used to travel as an undeclared passthrough
|
|
19887
|
+
* field that survived only because the runtime cap-router forwards provider
|
|
19888
|
+
* output verbatim — so every consumer had to re-declare it by hand to stop
|
|
19889
|
+
* its own Zod parse from stripping it, and the whole arrangement would have
|
|
19890
|
+
* broken silently the moment output validation was tightened anywhere.
|
|
19891
|
+
*/
|
|
19892
|
+
iconUrl: zod.z.string().optional(),
|
|
19893
|
+
/**
|
|
19894
|
+
* Media type of {@link iconUrl} (`image/svg+xml`, `image/png`, …).
|
|
19895
|
+
*
|
|
19896
|
+
* The server knows this and therefore says it, because the client cannot
|
|
19897
|
+
* safely guess: a React-Native client renders SVG and raster through two
|
|
19898
|
+
* DIFFERENT components (`react-native-svg` vs `expo-image` — expo-image does
|
|
19899
|
+
* not decode SVG on iOS/Android), so without this it silently fell back to a
|
|
19900
|
+
* placeholder glyph for every vector icon while the web build looked fine.
|
|
19901
|
+
*
|
|
19902
|
+
* Absent when {@link iconUrl} is absent, or for a legacy provider that has
|
|
19903
|
+
* not been updated — a client that cannot determine the type should prefer
|
|
19904
|
+
* its raster path, which is the safe default for an unknown image.
|
|
19905
|
+
*/
|
|
19906
|
+
iconMediaType: zod.z.string().optional(),
|
|
19567
19907
|
configSchema: ConfigSchemaPassthrough,
|
|
19568
19908
|
supportsDiscovery: zod.z.boolean(),
|
|
19569
19909
|
caps: TargetKindCapsSchema
|
|
@@ -20442,6 +20782,23 @@ var pipelineAnalyticsCapability = {
|
|
|
20442
20782
|
}),
|
|
20443
20783
|
/** The events ops-log rows (newest-first), optionally scoped to one camera.
|
|
20444
20784
|
* Backed by a declared pipeline-analytics SQLite collection. */
|
|
20785
|
+
/**
|
|
20786
|
+
* Move event-media blobs onto `toLocationId` (entity-routing spec Phase
|
|
20787
|
+
* 4): per-row copy → stamp row.locationId → delete old blob. Rows already
|
|
20788
|
+
* at the target are skipped, so a re-run resumes. Single-flight.
|
|
20789
|
+
*/
|
|
20790
|
+
relocateMedia: require_sleep.method(RelocateMediaInputSchema, zod.z.object({ jobId: zod.z.string() }), {
|
|
20791
|
+
kind: "mutation",
|
|
20792
|
+
auth: "admin"
|
|
20793
|
+
}),
|
|
20794
|
+
getMediaRelocateStatus: require_sleep.method(zod.z.object({}), zod.z.array(RelocateJobSchema).readonly(), {
|
|
20795
|
+
kind: "query",
|
|
20796
|
+
auth: "admin"
|
|
20797
|
+
}),
|
|
20798
|
+
cancelMediaRelocate: require_sleep.method(zod.z.object({ jobId: zod.z.string() }), zod.z.object({ cancelled: zod.z.boolean() }), {
|
|
20799
|
+
kind: "mutation",
|
|
20800
|
+
auth: "admin"
|
|
20801
|
+
}),
|
|
20445
20802
|
listOpsLog: require_sleep.method(OpsLogQueryInputSchema, zod.z.array(OpsLogEntrySchema).readonly(), {
|
|
20446
20803
|
kind: "query",
|
|
20447
20804
|
auth: "admin"
|
|
@@ -24079,6 +24436,17 @@ var ConnectionEndpointSchema = zod.z.object({
|
|
|
24079
24436
|
priority: zod.z.number()
|
|
24080
24437
|
});
|
|
24081
24438
|
var GetConnectionEndpointsResultSchema = zod.z.object({ endpoints: zod.z.array(ConnectionEndpointSchema).readonly() });
|
|
24439
|
+
/**
|
|
24440
|
+
* The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
|
|
24441
|
+
* AUTO (resolved from the candidate ranking at send time); `resolved` reports
|
|
24442
|
+
* what AUTO currently picks, so the UI can show the effective value either way.
|
|
24443
|
+
*/
|
|
24444
|
+
var NotificationEndpointSchema = zod.z.object({
|
|
24445
|
+
/** The operator's explicit choice, or null for AUTO. */
|
|
24446
|
+
baseUrl: zod.z.string().nullable(),
|
|
24447
|
+
/** What the ranking currently resolves to (null when nothing is reachable). */
|
|
24448
|
+
resolved: zod.z.string().nullable()
|
|
24449
|
+
});
|
|
24082
24450
|
var AllowedAddressesSchema = zod.z.object({
|
|
24083
24451
|
/**
|
|
24084
24452
|
* Allowlist of interface addresses operators have explicitly opted
|
|
@@ -24130,6 +24498,26 @@ var localNetworkCapability = {
|
|
|
24130
24498
|
scheme: zod.z.enum(["http", "https"]).optional()
|
|
24131
24499
|
}), GetConnectionEndpointsResultSchema),
|
|
24132
24500
|
/**
|
|
24501
|
+
* The endpoint OUTBOUND artifacts must be addressed by — notification
|
|
24502
|
+
* attachment links and deep links. `baseUrl: null` means AUTO: the first
|
|
24503
|
+
* public candidate (a configured origin, then a connected tunnel, then the
|
|
24504
|
+
* LAN), never loopback.
|
|
24505
|
+
*
|
|
24506
|
+
* Why an explicit marker: the automatic ranking cannot know which of
|
|
24507
|
+
* several reachable addresses the RECIPIENT can actually open. A link is
|
|
24508
|
+
* consumed on someone's phone, off the LAN, possibly hours later — and a
|
|
24509
|
+
* link nobody can open is worse than no link, because the notification
|
|
24510
|
+
* arrives advertising media that 404s.
|
|
24511
|
+
*/
|
|
24512
|
+
getNotificationEndpoint: require_sleep.method(zod.z.void(), NotificationEndpointSchema),
|
|
24513
|
+
/**
|
|
24514
|
+
* Mark which endpoint notification artifacts use. `baseUrl: null` restores
|
|
24515
|
+
* AUTO. The value is stored verbatim (not an index into the candidate
|
|
24516
|
+
* list): interfaces come and go, and an index would silently re-point at a
|
|
24517
|
+
* different address after a reboot.
|
|
24518
|
+
*/
|
|
24519
|
+
setNotificationEndpoint: require_sleep.method(zod.z.object({ baseUrl: zod.z.string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }),
|
|
24520
|
+
/**
|
|
24133
24521
|
* Read the operator's allowlist. Empty = "auto" (no filter). Used
|
|
24134
24522
|
* by the admin UI's address selector to seed its checkbox state.
|
|
24135
24523
|
*/
|
|
@@ -25241,7 +25629,12 @@ var RecordingDeviceUsageSchema = zod.z.object({
|
|
|
25241
25629
|
var RecordingLocationUsageSchema = zod.z.object({
|
|
25242
25630
|
/** StorageLocation id; null for the legacy/degraded single-root fallback. */
|
|
25243
25631
|
locationId: zod.z.string().nullable(),
|
|
25244
|
-
/**
|
|
25632
|
+
/** Every location id sharing this row's PHYSICAL volume (aliases). One row
|
|
25633
|
+
* is emitted per physical disk (2026-07-29): two locations on one root
|
|
25634
|
+
* previously rendered as two identical "disks" with a nonsensical used
|
|
25635
|
+
* split — hydrate attribution across aliases is arbitrary by nature. */
|
|
25636
|
+
locationIds: zod.z.array(zod.z.string()).optional(),
|
|
25637
|
+
/** Bytes of recordings stored on this PHYSICAL volume (all aliases). */
|
|
25245
25638
|
usedBytes: zod.z.number(),
|
|
25246
25639
|
/** Free bytes on the location's volume; null when capacity is unknown (remote). */
|
|
25247
25640
|
availableBytes: zod.z.number().nullable(),
|
|
@@ -25397,6 +25790,77 @@ var recordingCapability = {
|
|
|
25397
25790
|
listOpsLog: require_sleep.method(OpsLogQueryInputSchema, zod.z.array(OpsLogEntrySchema).readonly(), {
|
|
25398
25791
|
kind: "query",
|
|
25399
25792
|
auth: "admin"
|
|
25793
|
+
}),
|
|
25794
|
+
/**
|
|
25795
|
+
* Move footage (segments and/or strips) from one recordings location to
|
|
25796
|
+
* another — the drain workflow's mover (entity-routing spec Phase 4).
|
|
25797
|
+
* Throttled copy → size-verify → delete source → index refresh; resumable
|
|
25798
|
+
* by construction (copy-if-absent). Single-flight: one job at a time.
|
|
25799
|
+
*/
|
|
25800
|
+
/**
|
|
25801
|
+
* Render a short GIF from recorded footage around `aroundMs` (low profile,
|
|
25802
|
+
* palette-free ffmpeg gif). Synchronous — the window is a few seconds of
|
|
25803
|
+
* `low`, rendering in ~1-2s. Built for notification attachments: the
|
|
25804
|
+
* caller gets bytes, nothing persists. Fails when no footage covers the
|
|
25805
|
+
* window (camera not recording → caller skips the attachment).
|
|
25806
|
+
*/
|
|
25807
|
+
renderGif: require_sleep.method(zod.z.object({
|
|
25808
|
+
deviceId: zod.z.number(),
|
|
25809
|
+
aroundMs: zod.z.number(),
|
|
25810
|
+
preRollSec: zod.z.number().min(0).max(30).default(2),
|
|
25811
|
+
postRollSec: zod.z.number().min(0).max(30).default(5),
|
|
25812
|
+
maxWidth: zod.z.number().int().min(120).max(1280).default(480),
|
|
25813
|
+
fps: zod.z.number().int().min(1).max(15).default(5)
|
|
25814
|
+
}), zod.z.object({
|
|
25815
|
+
gifBase64: zod.z.string(),
|
|
25816
|
+
fromMs: zod.z.number(),
|
|
25817
|
+
toMs: zod.z.number()
|
|
25818
|
+
}), {
|
|
25819
|
+
kind: "mutation",
|
|
25820
|
+
auth: "admin"
|
|
25821
|
+
}),
|
|
25822
|
+
/**
|
|
25823
|
+
* Render a short MP4 clip from recorded footage around `aroundMs` — the
|
|
25824
|
+
* "send a clip, not a gif" notification attachment. Same window, source
|
|
25825
|
+
* and fail-closed contract as {@link renderGif}: no footage covering the
|
|
25826
|
+
* window ⇒ it throws and the caller ships no attachment. Re-encoded (never
|
|
25827
|
+
* stream-copied) so a concat across segments with different encoder
|
|
25828
|
+
* parameters still plays. Silent by contract.
|
|
25829
|
+
*
|
|
25830
|
+
* The returned window is SEGMENT-GRANULAR: the source playlist is built
|
|
25831
|
+
* from whole segments, so the clip starts at or before `fromMs` and ends
|
|
25832
|
+
* at or after `toMs` — overshoot bounded by one segment per side (an 8 s
|
|
25833
|
+
* ask over 4 s segments measured 12 s). `fromMs`/`toMs` report the window
|
|
25834
|
+
* ASKED for, not the encoded duration.
|
|
25835
|
+
*/
|
|
25836
|
+
renderClip: require_sleep.method(zod.z.object({
|
|
25837
|
+
deviceId: zod.z.number(),
|
|
25838
|
+
aroundMs: zod.z.number(),
|
|
25839
|
+
preRollSec: zod.z.number().min(0).max(30).default(3),
|
|
25840
|
+
postRollSec: zod.z.number().min(0).max(30).default(7),
|
|
25841
|
+
maxWidth: zod.z.number().int().min(160).max(1920).default(640)
|
|
25842
|
+
}), zod.z.object({
|
|
25843
|
+
clipBase64: zod.z.string(),
|
|
25844
|
+
mime: zod.z.string(),
|
|
25845
|
+
fromMs: zod.z.number(),
|
|
25846
|
+
toMs: zod.z.number(),
|
|
25847
|
+
bytes: zod.z.number().int()
|
|
25848
|
+
}), {
|
|
25849
|
+
kind: "mutation",
|
|
25850
|
+
auth: "admin"
|
|
25851
|
+
}),
|
|
25852
|
+
relocateFootage: require_sleep.method(RelocateFootageInputSchema, zod.z.object({ jobId: zod.z.string() }), {
|
|
25853
|
+
kind: "mutation",
|
|
25854
|
+
auth: "admin"
|
|
25855
|
+
}),
|
|
25856
|
+
/** Every known relocate job (in-RAM, newest-first). */
|
|
25857
|
+
getRelocateStatus: require_sleep.method(zod.z.object({}), zod.z.array(RelocateJobSchema).readonly(), {
|
|
25858
|
+
kind: "query",
|
|
25859
|
+
auth: "admin"
|
|
25860
|
+
}),
|
|
25861
|
+
cancelRelocate: require_sleep.method(zod.z.object({ jobId: zod.z.string() }), zod.z.object({ cancelled: zod.z.boolean() }), {
|
|
25862
|
+
kind: "mutation",
|
|
25863
|
+
auth: "admin"
|
|
25400
25864
|
})
|
|
25401
25865
|
}
|
|
25402
25866
|
};
|
|
@@ -27657,6 +28121,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
27657
28121
|
addonId: null,
|
|
27658
28122
|
access: "delete"
|
|
27659
28123
|
},
|
|
28124
|
+
"backup.deleteSchedule": {
|
|
28125
|
+
capName: "backup",
|
|
28126
|
+
capScope: "system",
|
|
28127
|
+
addonId: null,
|
|
28128
|
+
access: "delete"
|
|
28129
|
+
},
|
|
27660
28130
|
"backup.getEntries": {
|
|
27661
28131
|
capName: "backup",
|
|
27662
28132
|
capScope: "system",
|
|
@@ -27687,6 +28157,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
27687
28157
|
addonId: null,
|
|
27688
28158
|
access: "view"
|
|
27689
28159
|
},
|
|
28160
|
+
"backup.listSchedules": {
|
|
28161
|
+
capName: "backup",
|
|
28162
|
+
capScope: "system",
|
|
28163
|
+
addonId: null,
|
|
28164
|
+
access: "view"
|
|
28165
|
+
},
|
|
27690
28166
|
"backup.previewSchedule": {
|
|
27691
28167
|
capName: "backup",
|
|
27692
28168
|
capScope: "system",
|
|
@@ -27711,6 +28187,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
27711
28187
|
addonId: null,
|
|
27712
28188
|
access: "create"
|
|
27713
28189
|
},
|
|
28190
|
+
"backup.upsertSchedule": {
|
|
28191
|
+
capName: "backup",
|
|
28192
|
+
capScope: "system",
|
|
28193
|
+
addonId: null,
|
|
28194
|
+
access: "create"
|
|
28195
|
+
},
|
|
27714
28196
|
"battery.wakeForStream": {
|
|
27715
28197
|
capName: "battery",
|
|
27716
28198
|
capScope: "device",
|
|
@@ -29211,6 +29693,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
29211
29693
|
addonId: null,
|
|
29212
29694
|
access: "view"
|
|
29213
29695
|
},
|
|
29696
|
+
"localNetwork.getNotificationEndpoint": {
|
|
29697
|
+
capName: "local-network",
|
|
29698
|
+
capScope: "system",
|
|
29699
|
+
addonId: null,
|
|
29700
|
+
access: "view"
|
|
29701
|
+
},
|
|
29214
29702
|
"localNetwork.getPreferred": {
|
|
29215
29703
|
capName: "local-network",
|
|
29216
29704
|
capScope: "system",
|
|
@@ -29235,6 +29723,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
29235
29723
|
addonId: null,
|
|
29236
29724
|
access: "create"
|
|
29237
29725
|
},
|
|
29726
|
+
"localNetwork.setNotificationEndpoint": {
|
|
29727
|
+
capName: "local-network",
|
|
29728
|
+
capScope: "system",
|
|
29729
|
+
addonId: null,
|
|
29730
|
+
access: "create"
|
|
29731
|
+
},
|
|
29238
29732
|
"lockControl.lock": {
|
|
29239
29733
|
capName: "lock-control",
|
|
29240
29734
|
capScope: "device",
|
|
@@ -29877,6 +30371,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
29877
30371
|
addonId: null,
|
|
29878
30372
|
access: "create"
|
|
29879
30373
|
},
|
|
30374
|
+
"pipelineAnalytics.cancelMediaRelocate": {
|
|
30375
|
+
capName: "pipeline-analytics",
|
|
30376
|
+
capScope: "device",
|
|
30377
|
+
addonId: null,
|
|
30378
|
+
access: "create"
|
|
30379
|
+
},
|
|
29880
30380
|
"pipelineAnalytics.clearTracks": {
|
|
29881
30381
|
capName: "pipeline-analytics",
|
|
29882
30382
|
capScope: "device",
|
|
@@ -29931,6 +30431,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
29931
30431
|
addonId: null,
|
|
29932
30432
|
access: "view"
|
|
29933
30433
|
},
|
|
30434
|
+
"pipelineAnalytics.getMediaRelocateStatus": {
|
|
30435
|
+
capName: "pipeline-analytics",
|
|
30436
|
+
capScope: "device",
|
|
30437
|
+
addonId: null,
|
|
30438
|
+
access: "view"
|
|
30439
|
+
},
|
|
29934
30440
|
"pipelineAnalytics.getMotionEvents": {
|
|
29935
30441
|
capName: "pipeline-analytics",
|
|
29936
30442
|
capScope: "device",
|
|
@@ -30003,6 +30509,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
30003
30509
|
addonId: null,
|
|
30004
30510
|
access: "create"
|
|
30005
30511
|
},
|
|
30512
|
+
"pipelineAnalytics.relocateMedia": {
|
|
30513
|
+
capName: "pipeline-analytics",
|
|
30514
|
+
capScope: "device",
|
|
30515
|
+
addonId: null,
|
|
30516
|
+
access: "create"
|
|
30517
|
+
},
|
|
30006
30518
|
"pipelineAnalytics.searchObjectEvents": {
|
|
30007
30519
|
capName: "pipeline-analytics",
|
|
30008
30520
|
capScope: "device",
|
|
@@ -30765,6 +31277,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
30765
31277
|
addonId: null,
|
|
30766
31278
|
access: "create"
|
|
30767
31279
|
},
|
|
31280
|
+
"recording.cancelRelocate": {
|
|
31281
|
+
capName: "recording",
|
|
31282
|
+
capScope: "system",
|
|
31283
|
+
addonId: null,
|
|
31284
|
+
access: "create"
|
|
31285
|
+
},
|
|
30768
31286
|
"recording.deleteFootprint": {
|
|
30769
31287
|
capName: "recording",
|
|
30770
31288
|
capScope: "system",
|
|
@@ -30795,6 +31313,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
30795
31313
|
addonId: null,
|
|
30796
31314
|
access: "view"
|
|
30797
31315
|
},
|
|
31316
|
+
"recording.getRelocateStatus": {
|
|
31317
|
+
capName: "recording",
|
|
31318
|
+
capScope: "system",
|
|
31319
|
+
addonId: null,
|
|
31320
|
+
access: "view"
|
|
31321
|
+
},
|
|
30798
31322
|
"recording.getStorageUsage": {
|
|
30799
31323
|
capName: "recording",
|
|
30800
31324
|
capScope: "system",
|
|
@@ -30825,6 +31349,24 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
30825
31349
|
addonId: null,
|
|
30826
31350
|
access: "view"
|
|
30827
31351
|
},
|
|
31352
|
+
"recording.relocateFootage": {
|
|
31353
|
+
capName: "recording",
|
|
31354
|
+
capScope: "system",
|
|
31355
|
+
addonId: null,
|
|
31356
|
+
access: "create"
|
|
31357
|
+
},
|
|
31358
|
+
"recording.renderClip": {
|
|
31359
|
+
capName: "recording",
|
|
31360
|
+
capScope: "system",
|
|
31361
|
+
addonId: null,
|
|
31362
|
+
access: "create"
|
|
31363
|
+
},
|
|
31364
|
+
"recording.renderGif": {
|
|
31365
|
+
capName: "recording",
|
|
31366
|
+
capScope: "system",
|
|
31367
|
+
addonId: null,
|
|
31368
|
+
access: "create"
|
|
31369
|
+
},
|
|
30828
31370
|
"recording.rescanStorage": {
|
|
30829
31371
|
capName: "recording",
|
|
30830
31372
|
capScope: "system",
|
|
@@ -31419,6 +31961,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
31419
31961
|
addonId: null,
|
|
31420
31962
|
access: "create"
|
|
31421
31963
|
},
|
|
31964
|
+
"streamBroker.renderPreBufferClip": {
|
|
31965
|
+
capName: "stream-broker",
|
|
31966
|
+
capScope: "system",
|
|
31967
|
+
addonId: null,
|
|
31968
|
+
access: "create"
|
|
31969
|
+
},
|
|
31422
31970
|
"streamBroker.restartProfile": {
|
|
31423
31971
|
capName: "stream-broker",
|
|
31424
31972
|
capScope: "system",
|
|
@@ -33226,6 +33774,7 @@ exports.MotionZonePatchSchema = MotionZonePatchSchema;
|
|
|
33226
33774
|
exports.MotionZoneRegionSchema = MotionZoneRegionSchema;
|
|
33227
33775
|
exports.MotionZoneStatusSchema = MotionZoneStatusSchema;
|
|
33228
33776
|
exports.MqttBrokerStatusSchema = StatusSchema;
|
|
33777
|
+
exports.NC_BASE_CONDITION_KEYS = NC_BASE_CONDITION_KEYS;
|
|
33229
33778
|
exports.NC_CONDITION_CATALOG = NC_CONDITION_CATALOG;
|
|
33230
33779
|
exports.NC_HISTORY_LIMIT_DEFAULT = NC_HISTORY_LIMIT_DEFAULT;
|
|
33231
33780
|
exports.NC_HISTORY_LIMIT_MAX = NC_HISTORY_LIMIT_MAX;
|
|
@@ -33246,6 +33795,7 @@ exports.NcHistoryFilterSchema = NcHistoryFilterSchema;
|
|
|
33246
33795
|
exports.NcHistoryRecordKindSchema = NcHistoryRecordKindSchema;
|
|
33247
33796
|
exports.NcHistoryStatusSchema = NcHistoryStatusSchema;
|
|
33248
33797
|
exports.NcHistorySubjectSchema = NcHistorySubjectSchema;
|
|
33798
|
+
exports.NcMediaFrameSchema = NcMediaFrameSchema;
|
|
33249
33799
|
exports.NcMediaPolicySchema = NcMediaPolicySchema;
|
|
33250
33800
|
exports.NcOccupancyConditionSchema = NcOccupancyConditionSchema;
|
|
33251
33801
|
exports.NcPlateMatcherSchema = NcPlateMatcherSchema;
|
|
@@ -33352,17 +33902,18 @@ exports.RecordingDaysSchema = RecordingDaysSchema;
|
|
|
33352
33902
|
exports.RecordingDeviceUsageSchema = RecordingDeviceUsageSchema;
|
|
33353
33903
|
exports.RecordingLocationUsageSchema = RecordingLocationUsageSchema;
|
|
33354
33904
|
exports.RecordingManifestSchema = RecordingManifestSchema;
|
|
33355
|
-
exports.RecordingModeSchema = RecordingModeSchema;
|
|
33356
33905
|
exports.RecordingRangeSchema = RecordingRangeSchema;
|
|
33357
33906
|
exports.RecordingRetentionSchema = RecordingRetentionSchema;
|
|
33358
|
-
exports.RecordingRuleSchema = RecordingRuleSchema;
|
|
33359
|
-
exports.RecordingScheduleSchema = RecordingScheduleSchema;
|
|
33360
33907
|
exports.RecordingStatusSchema = RecordingStatusSchema;
|
|
33361
33908
|
exports.RecordingStorageModeSchema = RecordingStorageModeSchema;
|
|
33362
33909
|
exports.RecordingStorageUsageSchema = RecordingStorageUsageSchema;
|
|
33363
33910
|
exports.RecordingTriggersSchema = RecordingTriggersSchema;
|
|
33364
33911
|
exports.RecordingWeekdaySchema = RecordingWeekdaySchema;
|
|
33365
33912
|
exports.RedirectLoginMethodSchema = RedirectLoginMethodSchema;
|
|
33913
|
+
exports.RelocateFootageInputSchema = RelocateFootageInputSchema;
|
|
33914
|
+
exports.RelocateJobSchema = RelocateJobSchema;
|
|
33915
|
+
exports.RelocateJobStateSchema = RelocateJobStateSchema;
|
|
33916
|
+
exports.RelocateMediaInputSchema = RelocateMediaInputSchema;
|
|
33366
33917
|
exports.RenderedAsSchema = RenderedAsSchema;
|
|
33367
33918
|
exports.ReportMotionInputSchema = ReportMotionInputSchema;
|
|
33368
33919
|
exports.RingBuffer = RingBuffer;
|
|
@@ -33594,6 +34145,7 @@ exports.dayNightCapability = dayNightCapability;
|
|
|
33594
34145
|
exports.decoderCapability = decoderCapability;
|
|
33595
34146
|
exports.defaultDeviceFor = defaultDeviceFor;
|
|
33596
34147
|
exports.defineCustomActions = defineCustomActions;
|
|
34148
|
+
exports.deriveRecordingMode = deriveRecordingMode;
|
|
33597
34149
|
exports.describeModelVariant = describeModelVariant;
|
|
33598
34150
|
exports.detectionPipelineCapability = detectionPipelineCapability;
|
|
33599
34151
|
exports.deviceAdoptionCapability = deviceAdoptionCapability;
|
|
@@ -33651,6 +34203,7 @@ exports.integrationsCapability = integrationsCapability;
|
|
|
33651
34203
|
exports.intercomCapability = intercomCapability;
|
|
33652
34204
|
exports.isAgentOnlyPlacement = isAgentOnlyPlacement;
|
|
33653
34205
|
exports.isArrayOutputSchema = isArrayOutputSchema;
|
|
34206
|
+
exports.isBaseConditionKey = isBaseConditionKey;
|
|
33654
34207
|
exports.isCollectionArrayMethod = isCollectionArrayMethod;
|
|
33655
34208
|
exports.isDeployableToAgent = isDeployableToAgent;
|
|
33656
34209
|
exports.isDeviceConfigCap = require_sleep.isDeviceConfigCap;
|
|
@@ -33660,6 +34213,7 @@ exports.isObjectInput = isObjectInput;
|
|
|
33660
34213
|
exports.isVoidInput = isVoidInput;
|
|
33661
34214
|
exports.jobKindSchema = jobKindSchema;
|
|
33662
34215
|
exports.kebabToCamel = kebabToCamel;
|
|
34216
|
+
exports.knownValues = knownValues;
|
|
33663
34217
|
exports.lawnMowerControlCapability = lawnMowerControlCapability;
|
|
33664
34218
|
exports.lifecycleJobSchema = lifecycleJobSchema;
|
|
33665
34219
|
exports.lifecycleJobScopeSchema = lifecycleJobScopeSchema;
|
|
@@ -33685,7 +34239,6 @@ exports.mergeSourceInfo = mergeSourceInfo;
|
|
|
33685
34239
|
exports.meshNetworkCapability = meshNetworkCapability;
|
|
33686
34240
|
exports.method = require_sleep.method;
|
|
33687
34241
|
exports.metricsProviderCapability = metricsProviderCapability;
|
|
33688
|
-
exports.migrateConfigToBands = migrateConfigToBands;
|
|
33689
34242
|
exports.modelConvertCapability = modelConvertCapability;
|
|
33690
34243
|
exports.modelDistributorCapability = modelDistributorCapability;
|
|
33691
34244
|
exports.modelFormatForRuntime = modelFormatForRuntime;
|
|
@@ -33718,6 +34271,7 @@ exports.parseStreamParamsFormPatch = parseStreamParamsFormPatch;
|
|
|
33718
34271
|
exports.petFeederCapability = petFeederCapability;
|
|
33719
34272
|
exports.pickAccessoryControl = pickAccessoryControl;
|
|
33720
34273
|
exports.pickPreferredRtspEntry = pickPreferredRtspEntry;
|
|
34274
|
+
exports.pickerForCondition = pickerForCondition;
|
|
33721
34275
|
exports.pipelineAnalyticsCapability = pipelineAnalyticsCapability;
|
|
33722
34276
|
exports.pipelineExecutorCapability = pipelineExecutorCapability;
|
|
33723
34277
|
exports.pipelineOrchestratorCapability = pipelineOrchestratorCapability;
|