@camstack/addon-admin-ui 0.1.39 → 0.1.46
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/assets/{__mfe_internal__admin_ui_host__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.mjs-Cv6qLu_-.js → __mfe_internal__admin_ui_host__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.mjs-CRKSbdgN.js} +1 -1
- package/dist/assets/{__mfe_internal__admin_ui_host__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.mjs_commonjs-proxy-CChEG9e0.js → __mfe_internal__admin_ui_host__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.mjs_commonjs-proxy-BGPfTw3V.js} +1 -1
- package/dist/assets/{__mfe_internal__admin_ui_host__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.mjs-C1BmHlGM.js → __mfe_internal__admin_ui_host__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.mjs-jPpiOa0I.js} +1 -1
- package/dist/assets/{__mfe_internal__admin_ui_host__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.mjs_commonjs-proxy-Bxv_3KWz.js → __mfe_internal__admin_ui_host__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.mjs_commonjs-proxy-DYNYuSL7.js} +1 -1
- package/dist/assets/{__mfe_internal__admin_ui_host__loadShare__react__loadShare__.mjs-DC63qZbr.js → __mfe_internal__admin_ui_host__loadShare__react__loadShare__.mjs-ij0ODm-n.js} +1 -1
- package/dist/assets/{__mfe_internal__admin_ui_host__loadShare__react__loadShare__.mjs_commonjs-proxy-D2C49VyZ.js → __mfe_internal__admin_ui_host__loadShare__react__loadShare__.mjs_commonjs-proxy-C4Ko8zXp.js} +1 -1
- package/dist/assets/{__mfe_internal__admin_ui_host__loadShare__react_mf_2_dom__loadShare__.mjs-D3WbXy3O.js → __mfe_internal__admin_ui_host__loadShare__react_mf_2_dom__loadShare__.mjs-Cf5gSqc_.js} +1 -1
- package/dist/assets/{__mfe_internal__admin_ui_host__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-Csg6EbPB.js → __mfe_internal__admin_ui_host__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-CYaX3FDr.js} +1 -1
- package/dist/assets/{__mfe_internal__admin_ui_host__loadShare__react_mf_2_dom_mf_1_client__loadShare__.mjs-CUc0oFNo.js → __mfe_internal__admin_ui_host__loadShare__react_mf_2_dom_mf_1_client__loadShare__.mjs-rHwdrynu.js} +1 -1
- package/dist/assets/{__mfe_internal__admin_ui_host__loadShare__react_mf_2_dom_mf_1_client__loadShare__.mjs_commonjs-proxy-vh0hhA5d.js → __mfe_internal__admin_ui_host__loadShare__react_mf_2_dom_mf_1_client__loadShare__.mjs_commonjs-proxy-DRDS6j-Y.js} +1 -1
- package/dist/assets/{__mfe_internal__admin_ui_host__loadShare__react_mf_2_konva__loadShare__.mjs-CpGtTxci.js → __mfe_internal__admin_ui_host__loadShare__react_mf_2_konva__loadShare__.mjs-cUuqcEcL.js} +2 -2
- package/dist/assets/{__mfe_internal__admin_ui_host__loadShare__react_mf_2_konva__loadShare__.mjs_commonjs-proxy-RUDPE9aM.js → __mfe_internal__admin_ui_host__loadShare__react_mf_2_konva__loadShare__.mjs_commonjs-proxy-CzMP41OH.js} +1 -1
- package/dist/assets/{_virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-TUicghXo.js → _virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-DNAkeUTZ.js} +1 -1
- package/dist/assets/{devices-GLp7me2a.js → devices-DaqavVOg.js} +1 -1
- package/dist/assets/{hostInit-94fVe_XD.js → hostInit-ByQycOVJ.js} +1 -1
- package/dist/assets/index-B6kubsZI.js +151 -0
- package/dist/assets/index-BI1a6Whs.js +1 -0
- package/dist/assets/index-BVNg3Krt.js +1185 -0
- package/dist/assets/{index-TiJwCuZx.js → index-BbwPCEeT.js} +1 -1
- package/dist/assets/{index-D6khiudP.js → index-BpC2rqYA.js} +1 -1
- package/dist/assets/index-CukoHCyD.js +1 -0
- package/dist/assets/{index-JJ5NLHxC.js → index-Cyva9RmE.js} +1 -1
- package/dist/assets/index-DLnW8nGB.css +1 -0
- package/dist/assets/index-DNydUTOB.js +1 -0
- package/dist/assets/{index-CwF7Dxf8.js → index-DVLRgczW.js} +1 -1
- package/dist/assets/index-PXbclFuZ.js +87 -0
- package/dist/assets/index-QqQmcu5i.js +1 -0
- package/dist/assets/method-access-map-DjDdPRYC.js +1 -0
- package/dist/assets/{remoteEntry-JLETvOnh.js → remoteEntry-iRKuVHUX.js} +1 -1
- package/dist/assets/{schemas-BEt-CulV.js → schemas-BdJePqbR.js} +5 -5
- package/dist/assets/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-DM77_4pA.js → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-QVZxTxLo.js} +2 -2
- package/dist/index.html +152 -9
- package/dist/mf-entry-bootstrap-0.js +2 -2
- package/dist/server/addon.js +435 -52
- package/dist/server/addon.js.map +1 -1
- package/dist/sw.js +1 -1
- package/package.json +1 -1
- package/dist/assets/index-BM6aK9lG.js +0 -1150
- package/dist/assets/index-ByRJWRUP.js +0 -1
- package/dist/assets/index-COoei6lw.css +0 -1
- package/dist/assets/index-CtHpLu0L.js +0 -1
- package/dist/assets/index-DNY_otk4.js +0 -151
- package/dist/assets/index-DQFO9ZU6.js +0 -1
- package/dist/assets/index-WrAHDGEr.js +0 -87
- package/dist/assets/index-b0D9qthW.js +0 -1
- package/dist/assets/method-access-map-DLEhlu0x.js +0 -1
- package/dist/registerSW.js +0 -1
package/dist/server/addon.js
CHANGED
|
@@ -4780,6 +4780,16 @@ function record(keyType, valueType, params) {
|
|
|
4780
4780
|
...normalizeParams(params)
|
|
4781
4781
|
});
|
|
4782
4782
|
}
|
|
4783
|
+
function partialRecord(keyType, valueType, params) {
|
|
4784
|
+
const k = clone(keyType);
|
|
4785
|
+
k._zod.values = void 0;
|
|
4786
|
+
return new ZodRecord({
|
|
4787
|
+
type: "record",
|
|
4788
|
+
keyType: k,
|
|
4789
|
+
valueType,
|
|
4790
|
+
...normalizeParams(params)
|
|
4791
|
+
});
|
|
4792
|
+
}
|
|
4783
4793
|
const ZodEnum = /* @__PURE__ */ $constructor("ZodEnum", (inst, def) => {
|
|
4784
4794
|
$ZodEnum.init(inst, def);
|
|
4785
4795
|
ZodType.init(inst, def);
|
|
@@ -5056,6 +5066,37 @@ function _instanceof(cls, params = {}) {
|
|
|
5056
5066
|
};
|
|
5057
5067
|
return inst;
|
|
5058
5068
|
}
|
|
5069
|
+
const wiringProbeKindSchema = _enum(["singleton", "device", "widget"]);
|
|
5070
|
+
const wiringProbeResultSchema = object({
|
|
5071
|
+
capName: string(),
|
|
5072
|
+
kind: wiringProbeKindSchema,
|
|
5073
|
+
deviceId: number().optional(),
|
|
5074
|
+
reachable: boolean(),
|
|
5075
|
+
latencyMs: number(),
|
|
5076
|
+
error: string().optional()
|
|
5077
|
+
});
|
|
5078
|
+
const wiringAddonHealthSchema = object({
|
|
5079
|
+
addonId: string(),
|
|
5080
|
+
caps: array(wiringProbeResultSchema).readonly(),
|
|
5081
|
+
widgets: array(wiringProbeResultSchema).readonly()
|
|
5082
|
+
});
|
|
5083
|
+
const wiringNodeHealthSchema = object({
|
|
5084
|
+
nodeId: string(),
|
|
5085
|
+
addons: array(wiringAddonHealthSchema).readonly()
|
|
5086
|
+
});
|
|
5087
|
+
object({
|
|
5088
|
+
/** True only when every probed target is reachable. */
|
|
5089
|
+
ok: boolean(),
|
|
5090
|
+
/** True when at least one target is unreachable. */
|
|
5091
|
+
degraded: boolean(),
|
|
5092
|
+
checkedAt: string(),
|
|
5093
|
+
nodes: array(wiringNodeHealthSchema).readonly(),
|
|
5094
|
+
summary: object({
|
|
5095
|
+
total: number(),
|
|
5096
|
+
reachable: number(),
|
|
5097
|
+
unreachable: number()
|
|
5098
|
+
})
|
|
5099
|
+
});
|
|
5059
5100
|
const MODEL_FORMATS = ["onnx", "coreml", "openvino", "tflite", "pt"];
|
|
5060
5101
|
const WELL_KNOWN_TABS = [
|
|
5061
5102
|
{ id: "overview", label: "Overview", icon: "layout-dashboard", order: -10 },
|
|
@@ -6575,7 +6616,7 @@ const SpatialDetectionSchema = object({
|
|
|
6575
6616
|
bbox: BoundingBoxSchema
|
|
6576
6617
|
});
|
|
6577
6618
|
const AudioChunkInputSchema = object({
|
|
6578
|
-
data: _instanceof(
|
|
6619
|
+
data: _instanceof(Uint8Array),
|
|
6579
6620
|
sampleRate: number(),
|
|
6580
6621
|
channels: number(),
|
|
6581
6622
|
timestamp: number(),
|
|
@@ -7246,7 +7287,23 @@ const RunnerCameraConfigSchema = object({
|
|
|
7246
7287
|
* whenever its `zones` device-state slice changes, so the runner's
|
|
7247
7288
|
* copy stays in sync. Empty array → no zone filtering.
|
|
7248
7289
|
*/
|
|
7249
|
-
zones: array(ZoneSchema).readonly().default([])
|
|
7290
|
+
zones: array(ZoneSchema).readonly().default([]),
|
|
7291
|
+
/**
|
|
7292
|
+
* When true (default) and the camera's `motionSources` contains only
|
|
7293
|
+
* `'onboard'`, the runner dynamically opens the same WASM frame-diff
|
|
7294
|
+
* motion-frames subscription on each `MotionOnMotionChanged
|
|
7295
|
+
* source:'onboard'` event and tears it down after `motionCooldownMs`.
|
|
7296
|
+
* This causes `runMotionAnalysis` to emit `MotionZonesRaw` /
|
|
7297
|
+
* `MotionAnalysis` during active-motion windows without the
|
|
7298
|
+
* substream being held open continuously.
|
|
7299
|
+
*
|
|
7300
|
+
* Set to `false` to disable the dynamic analyzer for this camera
|
|
7301
|
+
* (e.g. very low-bandwidth links where the extra substream is
|
|
7302
|
+
* undesirable). Has no effect when `motionSources` already includes
|
|
7303
|
+
* `'analyzer'` — the analyzer runs continuously in that case and
|
|
7304
|
+
* this gate is bypassed.
|
|
7305
|
+
*/
|
|
7306
|
+
onboardMotionDrivesAnalyzer: boolean().default(true)
|
|
7250
7307
|
});
|
|
7251
7308
|
const RunnerLocalLoadSchema = object({
|
|
7252
7309
|
/** Moleculer node id of this runner instance. */
|
|
@@ -7383,22 +7440,68 @@ MotionTriggerStatusSchema.extend({
|
|
|
7383
7440
|
}) }
|
|
7384
7441
|
}
|
|
7385
7442
|
});
|
|
7443
|
+
const MaskPointSchema = object({
|
|
7444
|
+
x: number(),
|
|
7445
|
+
y: number()
|
|
7446
|
+
});
|
|
7447
|
+
const MaskRectShapeSchema = object({
|
|
7448
|
+
kind: literal("rect"),
|
|
7449
|
+
x: number(),
|
|
7450
|
+
y: number(),
|
|
7451
|
+
width: number(),
|
|
7452
|
+
height: number()
|
|
7453
|
+
});
|
|
7454
|
+
const MaskPolygonShapeSchema = object({
|
|
7455
|
+
kind: literal("polygon"),
|
|
7456
|
+
points: array(MaskPointSchema)
|
|
7457
|
+
});
|
|
7458
|
+
const MaskGridShapeSchema = object({
|
|
7459
|
+
kind: literal("grid"),
|
|
7460
|
+
gridWidth: number(),
|
|
7461
|
+
gridHeight: number(),
|
|
7462
|
+
cells: array(boolean())
|
|
7463
|
+
});
|
|
7464
|
+
const MaskLineShapeSchema = object({
|
|
7465
|
+
kind: literal("line"),
|
|
7466
|
+
points: array(MaskPointSchema)
|
|
7467
|
+
});
|
|
7468
|
+
discriminatedUnion("kind", [
|
|
7469
|
+
MaskRectShapeSchema,
|
|
7470
|
+
MaskPolygonShapeSchema,
|
|
7471
|
+
MaskGridShapeSchema,
|
|
7472
|
+
MaskLineShapeSchema
|
|
7473
|
+
]);
|
|
7474
|
+
const MaskShapeKindSchema = _enum(["rect", "polygon", "grid", "line"]);
|
|
7475
|
+
const MaskPolygonVerticesSchema = object({
|
|
7476
|
+
min: number(),
|
|
7477
|
+
max: number()
|
|
7478
|
+
});
|
|
7479
|
+
const MaskGridDimsSchema = object({
|
|
7480
|
+
width: number(),
|
|
7481
|
+
height: number()
|
|
7482
|
+
});
|
|
7483
|
+
const MotionZoneRegionSchema = object({
|
|
7484
|
+
id: number(),
|
|
7485
|
+
enabled: boolean(),
|
|
7486
|
+
shape: MaskGridShapeSchema
|
|
7487
|
+
});
|
|
7386
7488
|
object({
|
|
7387
7489
|
enabled: boolean(),
|
|
7388
7490
|
sensitivity: number(),
|
|
7389
|
-
/**
|
|
7390
|
-
|
|
7491
|
+
/** Grid region(s). Today exactly one `grid` shape. */
|
|
7492
|
+
regions: array(MotionZoneRegionSchema),
|
|
7391
7493
|
lastFetchedAt: number()
|
|
7392
7494
|
});
|
|
7393
7495
|
const MotionZoneOptionsSchema = object({
|
|
7394
|
-
|
|
7395
|
-
|
|
7496
|
+
maxRegions: number(),
|
|
7497
|
+
supportedShapes: array(MaskShapeKindSchema),
|
|
7498
|
+
grid: MaskGridDimsSchema,
|
|
7396
7499
|
sensitivity: object({ min: number(), max: number(), step: number() })
|
|
7397
7500
|
});
|
|
7398
7501
|
const MotionZonePatchSchema = object({
|
|
7399
7502
|
enabled: boolean().optional(),
|
|
7400
7503
|
sensitivity: number().optional(),
|
|
7401
|
-
|
|
7504
|
+
regions: array(MotionZoneRegionSchema).optional()
|
|
7402
7505
|
});
|
|
7403
7506
|
({
|
|
7404
7507
|
deviceTypes: [DeviceType.Camera],
|
|
@@ -7411,6 +7514,102 @@ const MotionZonePatchSchema = object({
|
|
|
7411
7514
|
)
|
|
7412
7515
|
}
|
|
7413
7516
|
});
|
|
7517
|
+
const NativeObjectClassEnum = _enum([
|
|
7518
|
+
"person",
|
|
7519
|
+
"vehicle",
|
|
7520
|
+
"animal",
|
|
7521
|
+
"face",
|
|
7522
|
+
"package",
|
|
7523
|
+
"other"
|
|
7524
|
+
]);
|
|
7525
|
+
const NativeDetectionSchema = object({
|
|
7526
|
+
class: NativeObjectClassEnum,
|
|
7527
|
+
timestamp: number(),
|
|
7528
|
+
/** Firmware-provided confidence [0..1]. Reolink pushes don't carry it → undefined. */
|
|
7529
|
+
confidence: number().min(0).max(1).optional()
|
|
7530
|
+
});
|
|
7531
|
+
const NativeObjectDetectionStatusSchema = object({
|
|
7532
|
+
/**
|
|
7533
|
+
* Last observed instance per class. Missing entries mean the class
|
|
7534
|
+
* is supported but nothing has been seen since the provider started.
|
|
7535
|
+
*
|
|
7536
|
+
* MUST be a partial record: providers seed an empty `{}` on cold-start
|
|
7537
|
+
* and write one class at a time as detections arrive. In Zod 4
|
|
7538
|
+
* `z.record(enum, …)` is EXHAUSTIVE (requires every enum key), so a
|
|
7539
|
+
* partial write throws "expected object, received undefined" for every
|
|
7540
|
+
* unseen class. `z.partialRecord` keeps the enum-key narrowing while
|
|
7541
|
+
* allowing the sparse shape the providers actually write.
|
|
7542
|
+
*/
|
|
7543
|
+
lastByClass: partialRecord(NativeObjectClassEnum, NativeDetectionSchema.nullable()),
|
|
7544
|
+
/** Classes the firmware is capable of detecting — enumerated at device register. */
|
|
7545
|
+
supportedClasses: array(NativeObjectClassEnum).readonly(),
|
|
7546
|
+
/**
|
|
7547
|
+
* Whether forwarding of onboard AI detections is enabled for this device.
|
|
7548
|
+
* Default true (on cold-start) — detections flow unconditionally before
|
|
7549
|
+
* the toggle is saved, so defaulting true preserves existing behaviour.
|
|
7550
|
+
*/
|
|
7551
|
+
enabled: boolean()
|
|
7552
|
+
});
|
|
7553
|
+
NativeObjectDetectionStatusSchema.extend({
|
|
7554
|
+
/** Required by createRuntimeStateBridge — epoch ms of last refresh. */
|
|
7555
|
+
lastFetchedAt: number()
|
|
7556
|
+
});
|
|
7557
|
+
({
|
|
7558
|
+
deviceTypes: [DeviceType.Camera],
|
|
7559
|
+
methods: {
|
|
7560
|
+
setEnabled: method(
|
|
7561
|
+
object({ deviceId: number(), enabled: boolean() }),
|
|
7562
|
+
_void(),
|
|
7563
|
+
{ kind: "mutation", auth: "admin" }
|
|
7564
|
+
)
|
|
7565
|
+
},
|
|
7566
|
+
events: {
|
|
7567
|
+
onDetected: { data: object({
|
|
7568
|
+
deviceId: number(),
|
|
7569
|
+
detection: NativeDetectionSchema
|
|
7570
|
+
}) }
|
|
7571
|
+
}
|
|
7572
|
+
});
|
|
7573
|
+
const PrivacyMaskShapeSchema = discriminatedUnion("kind", [
|
|
7574
|
+
MaskRectShapeSchema,
|
|
7575
|
+
MaskPolygonShapeSchema
|
|
7576
|
+
]);
|
|
7577
|
+
const PrivacyMaskRegionSchema = object({
|
|
7578
|
+
/** Slot id, 0-based. Stable across read/write. */
|
|
7579
|
+
id: number(),
|
|
7580
|
+
/** Whether this zone is active (blanked out by the camera). */
|
|
7581
|
+
enabled: boolean(),
|
|
7582
|
+
shape: PrivacyMaskShapeSchema
|
|
7583
|
+
});
|
|
7584
|
+
object({
|
|
7585
|
+
enabled: boolean(),
|
|
7586
|
+
/** Active zones (normalized 0..1). Length ≤ maxRegions. */
|
|
7587
|
+
regions: array(PrivacyMaskRegionSchema),
|
|
7588
|
+
lastFetchedAt: number()
|
|
7589
|
+
});
|
|
7590
|
+
const PrivacyMaskOptionsSchema = object({
|
|
7591
|
+
/** Maximum number of supported zones. */
|
|
7592
|
+
maxRegions: number(),
|
|
7593
|
+
/** Shape kinds this camera accepts — Reolink: ['rect']; Hikvision: ['rect','polygon']. */
|
|
7594
|
+
supportedShapes: array(MaskShapeKindSchema),
|
|
7595
|
+
/** Polygon vertex bounds when 'polygon' is supported (Hikvision: {min:4,max:4}). */
|
|
7596
|
+
polygonVertices: MaskPolygonVerticesSchema.optional()
|
|
7597
|
+
});
|
|
7598
|
+
const PrivacyMaskPatchSchema = object({
|
|
7599
|
+
enabled: boolean().optional(),
|
|
7600
|
+
regions: array(PrivacyMaskRegionSchema).optional()
|
|
7601
|
+
});
|
|
7602
|
+
({
|
|
7603
|
+
deviceTypes: [DeviceType.Camera],
|
|
7604
|
+
methods: {
|
|
7605
|
+
getOptions: method(object({ deviceId: number() }), PrivacyMaskOptionsSchema),
|
|
7606
|
+
setMask: method(
|
|
7607
|
+
object({ deviceId: number(), patch: PrivacyMaskPatchSchema }),
|
|
7608
|
+
_void(),
|
|
7609
|
+
{ kind: "mutation", auth: "admin" }
|
|
7610
|
+
)
|
|
7611
|
+
}
|
|
7612
|
+
});
|
|
7414
7613
|
const AutotrackTargetTypeSchema = string().describe("Vendor target string (people/vehicle/pet); empty = camera default");
|
|
7415
7614
|
const PtzAutotrackSettingsSchema = object({
|
|
7416
7615
|
targetType: AutotrackTargetTypeSchema,
|
|
@@ -7929,7 +8128,8 @@ const SettingsUpdateResultSchema = object({
|
|
|
7929
8128
|
object({
|
|
7930
8129
|
addonId: string(),
|
|
7931
8130
|
nodeId: string().optional(),
|
|
7932
|
-
overlay: record(string(), unknown()).optional()
|
|
8131
|
+
overlay: record(string(), unknown()).optional(),
|
|
8132
|
+
cap: string().optional()
|
|
7933
8133
|
}),
|
|
7934
8134
|
SettingsSchemaWithValuesSchema.nullable()
|
|
7935
8135
|
),
|
|
@@ -8664,7 +8864,14 @@ const OauthIntegrationDescriptorSchema = object({
|
|
|
8664
8864
|
/** Allowed redirect_uri prefixes. /api/oauth2/authorize rejects any
|
|
8665
8865
|
* redirect_uri that does not start with one of these. Required —
|
|
8666
8866
|
* an empty list means the integration can never complete linking. */
|
|
8667
|
-
allowedRedirectPrefixes: array(string()).min(1)
|
|
8867
|
+
allowedRedirectPrefixes: array(string()).min(1),
|
|
8868
|
+
/** Optional public origin (no trailing slash) that this integration's
|
|
8869
|
+
* issued codes/tokens should carry as the `hubUrl` claim — typically the
|
|
8870
|
+
* operator-selected external-access endpoint resolved by the addon. When
|
|
8871
|
+
* present, /api/oauth2/authorize bakes THIS into the code instead of the
|
|
8872
|
+
* hub-global `publicHubUrl()`, so a forked exporter addon (which can't set
|
|
8873
|
+
* the hub's env) drives the claim that its cloud Lambda routes back on. */
|
|
8874
|
+
hubUrl: string().optional()
|
|
8668
8875
|
});
|
|
8669
8876
|
({
|
|
8670
8877
|
methods: {
|
|
@@ -9278,7 +9485,20 @@ const WebrtcStreamChoiceSchema = object({
|
|
|
9278
9485
|
object({
|
|
9279
9486
|
deviceId: number().int().nonnegative(),
|
|
9280
9487
|
target: WebrtcStreamTargetSchema,
|
|
9281
|
-
hints: webrtcClientHintsSchema.optional()
|
|
9488
|
+
hints: webrtcClientHintsSchema.optional(),
|
|
9489
|
+
/**
|
|
9490
|
+
* SERVER-INJECTED — NOT a client hint. The hub layer that holds
|
|
9491
|
+
* the tRPC request context (and therefore the client IP) sets
|
|
9492
|
+
* this to `true` when the viewer's source IP is non-LAN
|
|
9493
|
+
* (4G/CGNAT/internet). The broker then forces TURN-relay-only
|
|
9494
|
+
* ICE for the session so a CGNAT client (which can only offer a
|
|
9495
|
+
* relay candidate) gets a clean relay↔relay media path instead
|
|
9496
|
+
* of werift nominating a dead host/hairpin-srflx pair. LAN
|
|
9497
|
+
* clients leave this absent/false and keep the low-latency
|
|
9498
|
+
* direct (host/srflx) path. Clients MUST NOT send this — the
|
|
9499
|
+
* server overwrites it from the request context.
|
|
9500
|
+
*/
|
|
9501
|
+
relayOnly: boolean().optional()
|
|
9282
9502
|
}),
|
|
9283
9503
|
object({ sessionId: string(), sdpOffer: string() }),
|
|
9284
9504
|
{ kind: "mutation" }
|
|
@@ -9301,7 +9521,22 @@ const WebrtcStreamChoiceSchema = object({
|
|
|
9301
9521
|
deviceId: number().int().nonnegative(),
|
|
9302
9522
|
target: WebrtcStreamTargetSchema.optional(),
|
|
9303
9523
|
sdpOffer: string(),
|
|
9304
|
-
sessionId: string().optional()
|
|
9524
|
+
sessionId: string().optional(),
|
|
9525
|
+
/**
|
|
9526
|
+
* Force TURN-relay-only ICE for this session. Two kinds of caller
|
|
9527
|
+
* set it:
|
|
9528
|
+
* - A cloud peer like Alexa's RTCSessionController (reachable
|
|
9529
|
+
* only via TURN, never our host/srflx behind NAT) passes
|
|
9530
|
+
* `true` from its own trusted addon context.
|
|
9531
|
+
* - The hub injects it for browser client-offer viewers from the
|
|
9532
|
+
* request's source IP (non-LAN ⇒ true), exactly as it does for
|
|
9533
|
+
* `createSession`.
|
|
9534
|
+
* A LAN/Tailscale browser doing client-offer passthrough leaves it
|
|
9535
|
+
* absent/false so a direct host pair carries full native quality.
|
|
9536
|
+
* Untrusted browser clients MUST NOT send it — the hub overwrites
|
|
9537
|
+
* it from the request context.
|
|
9538
|
+
*/
|
|
9539
|
+
relayOnly: boolean().optional()
|
|
9305
9540
|
}),
|
|
9306
9541
|
object({ sessionId: string(), sdpAnswer: string() }),
|
|
9307
9542
|
{ kind: "mutation" }
|
|
@@ -9315,6 +9550,46 @@ const WebrtcStreamChoiceSchema = object({
|
|
|
9315
9550
|
_void(),
|
|
9316
9551
|
{ kind: "mutation" }
|
|
9317
9552
|
),
|
|
9553
|
+
/**
|
|
9554
|
+
* Trickle ICE — add a remote (client) ICE candidate to a live session.
|
|
9555
|
+
* Lets the client send its SDP offer/answer IMMEDIATELY (before ICE
|
|
9556
|
+
* gathering finishes) and deliver candidates as they arrive, so the
|
|
9557
|
+
* connection establishes in ~0s instead of waiting for full gathering.
|
|
9558
|
+
* The dual of `getIceCandidates`. Mirrors Scrypted's signaling.
|
|
9559
|
+
*/
|
|
9560
|
+
addIceCandidate: method(
|
|
9561
|
+
object({
|
|
9562
|
+
deviceId: number().int().nonnegative(),
|
|
9563
|
+
sessionId: string(),
|
|
9564
|
+
candidate: string(),
|
|
9565
|
+
sdpMid: string().nullable().optional(),
|
|
9566
|
+
sdpMLineIndex: number().int().nullable().optional()
|
|
9567
|
+
}),
|
|
9568
|
+
_void(),
|
|
9569
|
+
{ kind: "mutation" }
|
|
9570
|
+
),
|
|
9571
|
+
/**
|
|
9572
|
+
* Trickle ICE — poll the server's gathered ICE candidates for a session.
|
|
9573
|
+
* The server answers immediately (no gathering wait) and the client polls
|
|
9574
|
+
* this to receive host/srflx/relay candidates as werift gathers them,
|
|
9575
|
+
* adding each to its PeerConnection. Returns all candidates gathered so
|
|
9576
|
+
* far; the client dedupes. `done` flips true once gathering completes.
|
|
9577
|
+
*/
|
|
9578
|
+
getIceCandidates: method(
|
|
9579
|
+
object({
|
|
9580
|
+
deviceId: number().int().nonnegative(),
|
|
9581
|
+
sessionId: string()
|
|
9582
|
+
}),
|
|
9583
|
+
object({
|
|
9584
|
+
candidates: array(object({
|
|
9585
|
+
candidate: string(),
|
|
9586
|
+
sdpMid: string().nullable(),
|
|
9587
|
+
sdpMLineIndex: number().int().nullable()
|
|
9588
|
+
})),
|
|
9589
|
+
done: boolean()
|
|
9590
|
+
}),
|
|
9591
|
+
{ kind: "query" }
|
|
9592
|
+
),
|
|
9318
9593
|
closeSession: method(
|
|
9319
9594
|
object({
|
|
9320
9595
|
deviceId: number().int().nonnegative(),
|
|
@@ -10986,6 +11261,9 @@ const UpdateConfigInput = object({
|
|
|
10986
11261
|
({
|
|
10987
11262
|
deviceTypes: [DeviceType.Camera]
|
|
10988
11263
|
});
|
|
11264
|
+
({
|
|
11265
|
+
deviceTypes: [DeviceType.Camera]
|
|
11266
|
+
});
|
|
10989
11267
|
const TrackStateSchema = _enum(["new", "entered", "left", "moving", "idle"]);
|
|
10990
11268
|
const EventKindSchema = _enum(["motion", "object", "audio"]);
|
|
10991
11269
|
const TrackPositionSchema = object({
|
|
@@ -11813,36 +12091,28 @@ const IntercomStatusSchema = object({
|
|
|
11813
12091
|
}) }
|
|
11814
12092
|
}
|
|
11815
12093
|
});
|
|
11816
|
-
const
|
|
11817
|
-
|
|
11818
|
-
|
|
11819
|
-
|
|
11820
|
-
|
|
11821
|
-
|
|
11822
|
-
|
|
11823
|
-
|
|
11824
|
-
|
|
11825
|
-
|
|
11826
|
-
|
|
11827
|
-
|
|
11828
|
-
|
|
11829
|
-
|
|
11830
|
-
object({
|
|
11831
|
-
/**
|
|
11832
|
-
* Last observed instance per class. Undefined entries mean the class
|
|
11833
|
-
* is supported but nothing has been seen since the provider started.
|
|
11834
|
-
*/
|
|
11835
|
-
lastByClass: record(NativeObjectClassEnum, NativeDetectionSchema.nullable()),
|
|
11836
|
-
/** Classes the firmware is capable of detecting — enumerated at device register. */
|
|
11837
|
-
supportedClasses: array(NativeObjectClassEnum).readonly()
|
|
12094
|
+
const CamStreamDescriptorSchema = object({
|
|
12095
|
+
camStreamId: string().min(1),
|
|
12096
|
+
kind: CamStreamKindSchema,
|
|
12097
|
+
url: string().optional(),
|
|
12098
|
+
codec: string().optional(),
|
|
12099
|
+
resolution: CamStreamResolutionSchema.optional(),
|
|
12100
|
+
fps: number().positive().optional(),
|
|
12101
|
+
label: string().optional(),
|
|
12102
|
+
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
12103
|
+
deviceFeatures: array(string()).optional(),
|
|
12104
|
+
/** Eligible for automatic profile assignment. Absent = `true`. */
|
|
12105
|
+
autoEligible: boolean().optional(),
|
|
12106
|
+
/** Transport-specific opaque metadata (e.g. rfc4571 SDP). */
|
|
12107
|
+
metadata: record(string(), unknown()).optional()
|
|
11838
12108
|
});
|
|
11839
12109
|
({
|
|
11840
12110
|
deviceTypes: [DeviceType.Camera],
|
|
11841
|
-
|
|
11842
|
-
|
|
11843
|
-
deviceId: number(),
|
|
11844
|
-
|
|
11845
|
-
|
|
12111
|
+
methods: {
|
|
12112
|
+
getCatalog: method(
|
|
12113
|
+
object({ deviceId: number().int().nonnegative() }),
|
|
12114
|
+
array(CamStreamDescriptorSchema).readonly()
|
|
12115
|
+
)
|
|
11846
12116
|
}
|
|
11847
12117
|
});
|
|
11848
12118
|
const ModelFormatSchema = _enum(MODEL_FORMATS);
|
|
@@ -12710,6 +12980,18 @@ const TopologyProcessSchema = object({
|
|
|
12710
12980
|
services: array(TopologyServiceSchema).readonly(),
|
|
12711
12981
|
groupId: string().optional()
|
|
12712
12982
|
});
|
|
12983
|
+
const TopologyCategoryAddonSchema = object({
|
|
12984
|
+
id: string(),
|
|
12985
|
+
status: string(),
|
|
12986
|
+
cpuPercent: number(),
|
|
12987
|
+
memoryRss: number()
|
|
12988
|
+
});
|
|
12989
|
+
const TopologyCategorySchema = object({
|
|
12990
|
+
category: string(),
|
|
12991
|
+
total: number(),
|
|
12992
|
+
healthy: number(),
|
|
12993
|
+
addons: array(TopologyCategoryAddonSchema).readonly()
|
|
12994
|
+
});
|
|
12713
12995
|
const TopologyNodeSchema = object({
|
|
12714
12996
|
id: string(),
|
|
12715
12997
|
name: string(),
|
|
@@ -12734,7 +13016,15 @@ const TopologyNodeSchema = object({
|
|
|
12734
13016
|
status: string()
|
|
12735
13017
|
})
|
|
12736
13018
|
).readonly(),
|
|
12737
|
-
processes: array(TopologyProcessSchema).readonly()
|
|
13019
|
+
processes: array(TopologyProcessSchema).readonly(),
|
|
13020
|
+
categories: array(TopologyCategorySchema).readonly()
|
|
13021
|
+
});
|
|
13022
|
+
const CapUsageEdgeSchema = object({
|
|
13023
|
+
callerAddonId: string(),
|
|
13024
|
+
providerAddonId: string(),
|
|
13025
|
+
capName: string(),
|
|
13026
|
+
callsPerMin: number(),
|
|
13027
|
+
lastCallAtMs: number()
|
|
12738
13028
|
});
|
|
12739
13029
|
const ClusterAddonNodeDeploymentSchema = object({
|
|
12740
13030
|
nodeId: string(),
|
|
@@ -12818,13 +13108,7 @@ const RenameNodeResultSchema = object({
|
|
|
12818
13108
|
object({
|
|
12819
13109
|
windowSeconds: number().int().positive().max(300).default(60)
|
|
12820
13110
|
}),
|
|
12821
|
-
array(
|
|
12822
|
-
callerAddonId: string(),
|
|
12823
|
-
providerAddonId: string(),
|
|
12824
|
-
capName: string(),
|
|
12825
|
-
callsPerMin: number(),
|
|
12826
|
-
lastCallAtMs: number()
|
|
12827
|
-
})).readonly(),
|
|
13111
|
+
array(CapUsageEdgeSchema).readonly(),
|
|
12828
13112
|
{ auth: "admin" }
|
|
12829
13113
|
),
|
|
12830
13114
|
/**
|
|
@@ -13036,7 +13320,8 @@ const PackageUpdateSchema = object({
|
|
|
13036
13320
|
currentVersion: string(),
|
|
13037
13321
|
latestVersion: string(),
|
|
13038
13322
|
category: _enum(["addon", "core"]),
|
|
13039
|
-
requiresRestart: boolean()
|
|
13323
|
+
requiresRestart: boolean(),
|
|
13324
|
+
isSystem: boolean()
|
|
13040
13325
|
});
|
|
13041
13326
|
const PackageVersionInfoSchema = object({
|
|
13042
13327
|
version: string(),
|
|
@@ -13069,6 +13354,42 @@ const UpdateFrameworkPackageResultSchema = object({
|
|
|
13069
13354
|
/** Ms-epoch the server scheduled its self-restart. */
|
|
13070
13355
|
restartingAt: number()
|
|
13071
13356
|
});
|
|
13357
|
+
const BulkUpdateItemStatusSchema = _enum([
|
|
13358
|
+
"queued",
|
|
13359
|
+
"updating",
|
|
13360
|
+
"done",
|
|
13361
|
+
"done-pending-restart",
|
|
13362
|
+
"failed"
|
|
13363
|
+
]);
|
|
13364
|
+
const BulkUpdateItemSchema = object({
|
|
13365
|
+
name: string(),
|
|
13366
|
+
isSystem: boolean(),
|
|
13367
|
+
fromVersion: string(),
|
|
13368
|
+
toVersion: string(),
|
|
13369
|
+
status: BulkUpdateItemStatusSchema,
|
|
13370
|
+
error: string().optional(),
|
|
13371
|
+
startedAtMs: number().optional(),
|
|
13372
|
+
completedAtMs: number().optional()
|
|
13373
|
+
});
|
|
13374
|
+
const BulkUpdatePhaseSchema = _enum([
|
|
13375
|
+
"regular",
|
|
13376
|
+
"system",
|
|
13377
|
+
"restarting",
|
|
13378
|
+
"finalizing"
|
|
13379
|
+
]);
|
|
13380
|
+
const BulkUpdateStateSchema = object({
|
|
13381
|
+
id: string(),
|
|
13382
|
+
nodeId: string(),
|
|
13383
|
+
startedAtMs: number(),
|
|
13384
|
+
completedAtMs: number().optional(),
|
|
13385
|
+
total: number(),
|
|
13386
|
+
completed: number(),
|
|
13387
|
+
failed: number(),
|
|
13388
|
+
current: string().nullable(),
|
|
13389
|
+
phase: BulkUpdatePhaseSchema,
|
|
13390
|
+
cancelled: boolean(),
|
|
13391
|
+
items: array(BulkUpdateItemSchema).readonly()
|
|
13392
|
+
});
|
|
13072
13393
|
const FrameworkPackageStatusSchema = object({
|
|
13073
13394
|
packageName: string(),
|
|
13074
13395
|
currentVersion: string(),
|
|
@@ -13206,7 +13527,7 @@ const CustomActionInputSchema = object({
|
|
|
13206
13527
|
getLastRestart: method(
|
|
13207
13528
|
_void(),
|
|
13208
13529
|
object({
|
|
13209
|
-
kind: _enum(["framework-update", "manual", "system"]),
|
|
13530
|
+
kind: _enum(["framework-update", "manual", "system", "framework-bulk-update"]),
|
|
13210
13531
|
packageName: string().optional(),
|
|
13211
13532
|
fromVersion: string().optional(),
|
|
13212
13533
|
toVersion: string().optional(),
|
|
@@ -13296,11 +13617,70 @@ const CustomActionInputSchema = object({
|
|
|
13296
13617
|
updateFrameworkPackage: method(
|
|
13297
13618
|
object({
|
|
13298
13619
|
packageName: string().min(1),
|
|
13299
|
-
version: string().optional()
|
|
13620
|
+
version: string().optional(),
|
|
13621
|
+
deferRestart: boolean().optional()
|
|
13300
13622
|
}),
|
|
13301
13623
|
UpdateFrameworkPackageResultSchema,
|
|
13302
13624
|
{ kind: "mutation", auth: "admin" }
|
|
13303
13625
|
),
|
|
13626
|
+
/**
|
|
13627
|
+
* Kicks off a server-side bulk update operation and returns the bulk
|
|
13628
|
+
* id immediately. The operation runs asynchronously; observe progress
|
|
13629
|
+
* via the `AddonsBulkUpdateProgress` event or `getBulkUpdateState`.
|
|
13630
|
+
* Items with `isSystem: true` use `deferRestart` — the hub restarts
|
|
13631
|
+
* ONCE at the end of the system phase, after all system packages are
|
|
13632
|
+
* installed.
|
|
13633
|
+
*
|
|
13634
|
+
* `items[].version` is REQUIRED — callers must pass the resolved
|
|
13635
|
+
* version from `listUpdates`. There is no `'latest'` default here
|
|
13636
|
+
* (unlike `updatePackage`) to guarantee deterministic bulk rolls.
|
|
13637
|
+
*/
|
|
13638
|
+
startBulkUpdate: method(
|
|
13639
|
+
object({
|
|
13640
|
+
nodeId: string(),
|
|
13641
|
+
items: array(object({
|
|
13642
|
+
name: string(),
|
|
13643
|
+
version: string(),
|
|
13644
|
+
isSystem: boolean()
|
|
13645
|
+
})).readonly()
|
|
13646
|
+
}),
|
|
13647
|
+
object({ id: string() }),
|
|
13648
|
+
{ kind: "mutation", auth: "admin" }
|
|
13649
|
+
),
|
|
13650
|
+
/**
|
|
13651
|
+
* Returns the current state of a bulk update by id.
|
|
13652
|
+
* Returns `null` if the id is unknown or has been auto-cleaned
|
|
13653
|
+
* (5 minutes after `completedAt` the record is evicted from memory).
|
|
13654
|
+
*/
|
|
13655
|
+
getBulkUpdateState: method(
|
|
13656
|
+
object({ id: string() }),
|
|
13657
|
+
BulkUpdateStateSchema.nullable(),
|
|
13658
|
+
{ auth: "admin" }
|
|
13659
|
+
),
|
|
13660
|
+
/**
|
|
13661
|
+
* Cancels an in-flight bulk update. The update loop exits after the
|
|
13662
|
+
* currently-processing item completes — cancellation is not
|
|
13663
|
+
* instantaneous. Has no effect once the `restarting` phase has been
|
|
13664
|
+
* entered (the hub is already shutting down at that point).
|
|
13665
|
+
* Returns `{ cancelled: false }` if the id is unknown, the operation
|
|
13666
|
+
* has already completed, or the `restarting` phase is active.
|
|
13667
|
+
*/
|
|
13668
|
+
cancelBulkUpdate: method(
|
|
13669
|
+
object({ id: string() }),
|
|
13670
|
+
object({ cancelled: boolean() }),
|
|
13671
|
+
{ kind: "mutation", auth: "admin" }
|
|
13672
|
+
),
|
|
13673
|
+
/**
|
|
13674
|
+
* Lists all currently active (non-completed) bulk updates.
|
|
13675
|
+
* If `nodeId` is provided, filters to only bulk updates targeting
|
|
13676
|
+
* that node. Useful for restoring an in-progress banner on a fresh
|
|
13677
|
+
* page load when the UI reconnects mid-operation.
|
|
13678
|
+
*/
|
|
13679
|
+
listActiveBulkUpdates: method(
|
|
13680
|
+
object({ nodeId: string().optional() }),
|
|
13681
|
+
array(BulkUpdateStateSchema).readonly(),
|
|
13682
|
+
{ auth: "admin" }
|
|
13683
|
+
),
|
|
13304
13684
|
getVersions: method(
|
|
13305
13685
|
object({ name: string() }),
|
|
13306
13686
|
array(PackageVersionInfoSchema).readonly()
|
|
@@ -13428,6 +13808,7 @@ var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
|
|
|
13428
13808
|
EventCategory2["StreamBrokerOnCamStreamDemand"] = "stream-broker.onCamStreamDemand";
|
|
13429
13809
|
EventCategory2["StreamBrokerOnCamStreamIdle"] = "stream-broker.onCamStreamIdle";
|
|
13430
13810
|
EventCategory2["StreamBrokerOnRequestStreamSourceRefresh"] = "stream-broker.onRequestStreamSourceRefresh";
|
|
13811
|
+
EventCategory2["StreamParamsChanged"] = "stream-params.changed";
|
|
13431
13812
|
EventCategory2["DeviceStateChanged"] = "device.state-changed";
|
|
13432
13813
|
EventCategory2["BatteryOnStatusChanged"] = "battery.onStatusChanged";
|
|
13433
13814
|
EventCategory2["DoorbellOnPressed"] = "doorbell.onPressed";
|
|
@@ -13475,6 +13856,7 @@ var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
|
|
|
13475
13856
|
EventCategory2["NetworkTunnelStarted"] = "network.tunnel.started";
|
|
13476
13857
|
EventCategory2["NetworkTunnelStopped"] = "network.tunnel.stopped";
|
|
13477
13858
|
EventCategory2["LocalNetworkChanged"] = "network.local.changed";
|
|
13859
|
+
EventCategory2["MeshNetworkChanged"] = "network.mesh.changed";
|
|
13478
13860
|
EventCategory2["BackupCompleted"] = "backup.completed";
|
|
13479
13861
|
EventCategory2["BackupRestored"] = "backup.restored";
|
|
13480
13862
|
EventCategory2["NotificationDispatched"] = "notification.dispatched";
|
|
@@ -13485,6 +13867,7 @@ var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
|
|
|
13485
13867
|
EventCategory2["DeviceAwake"] = "device.awake";
|
|
13486
13868
|
EventCategory2["DeviceSleeping"] = "device.sleeping";
|
|
13487
13869
|
EventCategory2["RetentionCleanup"] = "retention.cleanup";
|
|
13870
|
+
EventCategory2["AddonsBulkUpdateProgress"] = "addons.bulk-update-progress";
|
|
13488
13871
|
return EventCategory2;
|
|
13489
13872
|
})(EventCategory || {});
|
|
13490
13873
|
function createEvent(category, source, data) {
|
|
@@ -13634,7 +14017,7 @@ class BaseAddon {
|
|
|
13634
14017
|
}
|
|
13635
14018
|
// ── Settings schemas (override to provide UI) ─────────────────────────
|
|
13636
14019
|
/** Override to provide global-level settings UI schema. */
|
|
13637
|
-
globalSettingsSchema() {
|
|
14020
|
+
globalSettingsSchema(_cap) {
|
|
13638
14021
|
return null;
|
|
13639
14022
|
}
|
|
13640
14023
|
/** Override to provide device-level settings UI schema. */
|
|
@@ -13648,8 +14031,8 @@ class BaseAddon {
|
|
|
13648
14031
|
// blob and every addon used exactly one of them; the distinction was
|
|
13649
14032
|
// never semantically load-bearing. `global` won because it was the
|
|
13650
14033
|
// widely-used one and the name reads naturally (per-node addon config).
|
|
13651
|
-
async getGlobalSettings(overlay) {
|
|
13652
|
-
const schema = this.globalSettingsSchema();
|
|
14034
|
+
async getGlobalSettings(overlay, cap) {
|
|
14035
|
+
const schema = this.globalSettingsSchema(cap);
|
|
13653
14036
|
if (!schema) return { sections: [] };
|
|
13654
14037
|
const raw = await this._ctx?.settings?.readAddonStore() ?? {};
|
|
13655
14038
|
return hydrateSchema(schema, overlay ? { ...raw, ...overlay } : raw);
|