@camstack/addon-provider-onvif 1.1.22 → 1.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/addon.js CHANGED
@@ -4631,7 +4631,7 @@ function _instanceof(cls, params = {}) {
4631
4631
  return inst;
4632
4632
  }
4633
4633
  //#endregion
4634
- //#region ../types/dist/sleep-DJaTV2D7.mjs
4634
+ //#region ../types/dist/sleep-BC9Yqte7.mjs
4635
4635
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4636
4636
  EventCategory["SystemBoot"] = "system.boot";
4637
4637
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -6735,6 +6735,18 @@ function method(input, output, options) {
6735
6735
  timeoutMs: options?.timeoutMs
6736
6736
  };
6737
6737
  }
6738
+ /**
6739
+ * A wrapper/system-only method: served exclusively by the cap's system-level
6740
+ * provider (`InferProvider`), and OPTIONAL on `InferNativeProvider` so per-device
6741
+ * driver natives don't stub out a wrapper concern (e.g. a cross-device cache
6742
+ * overview). The `systemOnly: true` literal is what `InferNativeProvider` keys on.
6743
+ */
6744
+ function systemMethod(input, output, options) {
6745
+ return {
6746
+ ...method(input, output, options),
6747
+ systemOnly: true
6748
+ };
6749
+ }
6738
6750
  var StaticDirOutputSchema$1 = object({ staticDir: string() });
6739
6751
  var VersionOutputSchema$1 = object({ version: string() });
6740
6752
  method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
@@ -10655,6 +10667,7 @@ var PipelineAddonSchemaSchema = object({
10655
10667
  defaultModelId: string(),
10656
10668
  defaultModelIdByFormat: record(string(), string()).optional(),
10657
10669
  enabledByDefault: boolean().optional(),
10670
+ backfillIntoExistingOverrides: boolean().optional(),
10658
10671
  defaultConfidence: number(),
10659
10672
  group: string().optional(),
10660
10673
  configSchema: array(ConfigFieldBridge).readonly().optional()
@@ -10961,6 +10974,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(ZoneSchema).read
10961
10974
  auth: "admin"
10962
10975
  }), object({ zones: array(ZoneSchema).readonly() });
10963
10976
  /**
10977
+ * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
10978
+ * decode worker resolves it against the RETAINED native frame's real pixel dims,
10979
+ * so the caller supplies only the detection-res bbox divided by the detection
10980
+ * dims — no native resolution to plumb.
10981
+ */
10982
+ var NativeCropBboxSchema = object({
10983
+ x: number(),
10984
+ y: number(),
10985
+ w: number(),
10986
+ h: number()
10987
+ });
10988
+ /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
10989
+ var NativeCropResultSchema = object({
10990
+ /** Packed rgb (24-bit) pixels of the crop. */
10991
+ bytes: _instanceof(Uint8Array),
10992
+ width: number().int().positive(),
10993
+ height: number().int().positive()
10994
+ });
10995
+ /**
10964
10996
  * Per-camera tunable ranges + defaults. Single source of truth used
10965
10997
  * by both the Zod data schema (validation + default fallback) and
10966
10998
  * the device settings UI (slider min/max/step). Touch one place and
@@ -11216,7 +11248,11 @@ var RunnerLocalMetricsSchema = object({
11216
11248
  avgInferenceTimeMs: number(),
11217
11249
  queueDepth: number()
11218
11250
  });
11219
- method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly());
11251
+ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
11252
+ handle: FrameHandleSchema,
11253
+ bbox: NativeCropBboxSchema,
11254
+ maxWidth: number().int().positive().optional()
11255
+ }), NativeCropResultSchema.nullable());
11220
11256
  object({
11221
11257
  detected: boolean(),
11222
11258
  /** Ms epoch of the last detected-true observation. Null if never detected. */
@@ -15548,7 +15584,17 @@ var TrackSchema = object({
15548
15584
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
15549
15585
  totalDistance: number(),
15550
15586
  state: TrackStateSchema,
15551
- active: boolean()
15587
+ active: boolean(),
15588
+ /** Deterministic key-event importance score in [0,1] (server-computed at
15589
+ * track expiry, recomputed on late label). Absent on legacy rows written
15590
+ * before scoring shipped — consumers degrade to absence / compute-on-read. */
15591
+ importance: number().optional(),
15592
+ /** Id of the track's highest-confidence ObjectEvent (its representative
15593
+ * "best" frame). Absent when the track produced no object events. */
15594
+ bestEventId: string().optional(),
15595
+ /** Tag of the importance sub-signal that dominated the score
15596
+ * (identity|dwell|proximity|class|confidence|travel|zone). */
15597
+ importanceReason: string().optional()
15552
15598
  });
15553
15599
  var BaseEventFields = {
15554
15600
  id: string(),
@@ -15613,8 +15659,18 @@ var ObjectEventSchema = object({
15613
15659
  frameHeight: number().optional(),
15614
15660
  /** MediaStore key for the crop attached to this event (if any). */
15615
15661
  mediaKey: string().optional(),
15662
+ /** Design B: MediaStore key of the track's native-resolution key frame (the
15663
+ * best-detection full frame). Resolve via the event-media data-plane
15664
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
15665
+ * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
15666
+ * sources — consumers fall back to `mediaKey` (the tight crop). */
15667
+ keyFrameMediaKey: string().optional(),
15616
15668
  /** Populated by B5 (recording playback URL for this event). */
15617
- mediaUrl: string().optional()
15669
+ mediaUrl: string().optional(),
15670
+ /** The parent track's key-event importance [0,1], propagated to every object
15671
+ * event of the track (so an event row can be sorted by importance without a
15672
+ * track join). Absent on legacy rows / before the track was scored. */
15673
+ importance: number().optional()
15618
15674
  });
15619
15675
  var AudioEventSchema = object({
15620
15676
  ...BaseEventFields,
@@ -15638,7 +15694,8 @@ var MediaFileKindEnum = _enum([
15638
15694
  "fullFrame",
15639
15695
  "fullFrameBoxed",
15640
15696
  "faceCrop",
15641
- "plateCrop"
15697
+ "plateCrop",
15698
+ "keyFrame"
15642
15699
  ]);
15643
15700
  var MediaFileSchema = object({
15644
15701
  key: string(),
@@ -15659,6 +15716,32 @@ var DeviceEventQueryInput = object({
15659
15716
  projection: _enum(["full", "slim"]).optional()
15660
15717
  });
15661
15718
  var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
15719
+ var KeyEventQueryInput = object({
15720
+ deviceId: number(),
15721
+ /** Window lower bound (track firstSeen ≥ since). */
15722
+ since: number(),
15723
+ /** Window upper bound (track firstSeen ≤ until). */
15724
+ until: number(),
15725
+ limit: number().int().min(1).max(200).default(50),
15726
+ /** Drop tracks scoring below this importance. */
15727
+ minImportance: number().min(0).max(1).optional(),
15728
+ /** Restrict to a single class (e.g. 'person'). */
15729
+ classFilter: string().optional()
15730
+ });
15731
+ var KeyEventSchema = object({
15732
+ /** The representative event id (the track's best ObjectEvent, else its trackId). */
15733
+ id: string(),
15734
+ trackId: string(),
15735
+ /** Track start time (firstSeen). */
15736
+ timestamp: number(),
15737
+ className: string(),
15738
+ label: string().optional(),
15739
+ importance: number(),
15740
+ /** Highest-confidence ObjectEvent id for the track (empty when none). */
15741
+ bestEventId: string(),
15742
+ /** Track lifetime in ms (lastSeen - firstSeen). */
15743
+ windowMs: number().optional()
15744
+ });
15662
15745
  var TrackedDetectionSchema = object({
15663
15746
  trackId: string(),
15664
15747
  className: string(),
@@ -15688,7 +15771,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
15688
15771
  }), array(TrackSchema).readonly()), method(object({ deviceId: number() }), _void(), {
15689
15772
  kind: "mutation",
15690
15773
  auth: "admin"
15691
- }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({
15774
+ }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
15692
15775
  deviceId: number(),
15693
15776
  since: number(),
15694
15777
  until: number(),
@@ -16492,7 +16575,20 @@ var snapshotCapability = {
16492
16575
  invalidateCache: method(object({ deviceId: number() }), _void(), {
16493
16576
  kind: "mutation",
16494
16577
  auth: "admin"
16495
- })
16578
+ }),
16579
+ /**
16580
+ * Cache-only batch overview — answers from the wrapper's in-memory cache in
16581
+ * O(n) and NEVER triggers a capture. Lets a grid skip requesting images for
16582
+ * devices that never produced a frame, and gives it an ETag per device for
16583
+ * conditional (304-able) image fetches. `lastCapturedAt`/`cacheAgeMs`/`etag`
16584
+ * are null for a device with no cached frame.
16585
+ */
16586
+ getSnapshotOverview: systemMethod(object({ deviceIds: array(number()).min(1).max(200) }), array(object({
16587
+ deviceId: number(),
16588
+ lastCapturedAt: number().nullable(),
16589
+ cacheAgeMs: number().nullable(),
16590
+ etag: string().nullable()
16591
+ })))
16496
16592
  },
16497
16593
  status: {
16498
16594
  schema: SnapshotStatusSchema,
@@ -16749,10 +16845,32 @@ method(_void(), array(TurnServerSchema).readonly());
16749
16845
  * b. `finishAuthentication({userId, response})` → server verifies
16750
16846
  * the assertion, bumps the credential counter, returns ok.
16751
16847
  *
16848
+ * 2b. Usernameless (discoverable-credential) authentication — the
16849
+ * passkey IS the primary factor, no password leg:
16850
+ * a. `beginDiscoverableAuthentication({})` → assertion options with
16851
+ * EMPTY `allowCredentials` (the browser offers every resident
16852
+ * passkey it holds for this RP) + `userVerification: 'required'`
16853
+ * (the passkey replaces both factors, so UV is mandatory).
16854
+ * The challenge is stored server-side, NOT bound to any user.
16855
+ * b. `finishDiscoverableAuthentication({response})` → the provider
16856
+ * resolves the credential by the response's credential id,
16857
+ * verifies the assertion against the stored challenge + that
16858
+ * credential's public key/counter, and returns the OWNING
16859
+ * `userId` — the caller (core auth router) mints the session.
16860
+ *
16752
16861
  * 3. Management:
16753
16862
  * - `listPasskeys({userId})` — enumerate user's enrolled credentials.
16754
16863
  * - `removePasskey({userId, credentialId})` — revoke one credential.
16755
16864
  *
16865
+ * 4. Second-factor preference (opt-in, default OFF):
16866
+ * Enrolling a passkey only enables passkey-FIRST sign-in. It is
16867
+ * demanded as a second factor after a password login ONLY when the
16868
+ * user explicitly opts in via `setSecondFactorPreference`.
16869
+ * - `getSecondFactorPreference({userId})` → `{ enabled }` (missing
16870
+ * row ⇒ `enabled: false`).
16871
+ * - `setSecondFactorPreference({userId, enabled})` — persisted by
16872
+ * the providing addon beside its credentials.
16873
+ *
16756
16874
  * Challenges are short-lived (5 min, in-memory). The cap is internal —
16757
16875
  * the admin-ui composes the begin/finish round-trip and never exposes
16758
16876
  * the cap to non-admins.
@@ -16795,6 +16913,17 @@ method(object({
16795
16913
  }), object({ verified: boolean() }), {
16796
16914
  kind: "mutation",
16797
16915
  access: "view"
16916
+ }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
16917
+ kind: "mutation",
16918
+ access: "view"
16919
+ }), method(object({
16920
+ /** AuthenticationResponseJSON from the browser. */
16921
+ response: record(string(), unknown()) }), object({
16922
+ verified: boolean(),
16923
+ userId: string().nullable()
16924
+ }), {
16925
+ kind: "mutation",
16926
+ access: "view"
16798
16927
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
16799
16928
  userId: string(),
16800
16929
  credentialId: string()
@@ -16802,6 +16931,13 @@ method(object({
16802
16931
  kind: "mutation",
16803
16932
  auth: "admin",
16804
16933
  access: "delete"
16934
+ }), method(object({ userId: string() }), object({ enabled: boolean() }), { auth: "admin" }), method(object({
16935
+ userId: string(),
16936
+ enabled: boolean()
16937
+ }), object({ success: literal(true) }), {
16938
+ kind: "mutation",
16939
+ auth: "admin",
16940
+ access: "create"
16805
16941
  });
16806
16942
  /**
16807
16943
  * `videoclips` — the unified, navigable-clip surface for a camera.
@@ -17603,7 +17739,17 @@ var FaceInfoSchema = object({
17603
17739
  recognizedIdentityId: string().optional(),
17604
17740
  identityName: string().optional(),
17605
17741
  assigned: boolean(),
17606
- base64: string().optional()
17742
+ base64: string().optional(),
17743
+ /** Design B: the face bbox (pixel space) on the key frame — lets a detail
17744
+ * view draw the box over the native `keyFrameMediaKey` frame. Absent on
17745
+ * legacy rows written before design B. */
17746
+ faceBbox: BoundingBoxSchema.optional(),
17747
+ /** Design B: MediaStore key of the track's native-resolution key frame.
17748
+ * Fetch the native JPEG via the event-media data-plane
17749
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
17750
+ * track produced no key frame (e.g. native/onboard source) — the UI falls
17751
+ * back to the inline `base64` face crop. */
17752
+ keyFrameMediaKey: string().optional()
17607
17753
  });
17608
17754
  var FaceFilterEnum = _enum([
17609
17755
  "unassigned",
@@ -21764,6 +21910,12 @@ Object.freeze({
21764
21910
  addonId: null,
21765
21911
  access: "view"
21766
21912
  },
21913
+ "pipelineAnalytics.getKeyEvents": {
21914
+ capName: "pipeline-analytics",
21915
+ capScope: "device",
21916
+ addonId: null,
21917
+ access: "view"
21918
+ },
21767
21919
  "pipelineAnalytics.getMotionEvents": {
21768
21920
  capName: "pipeline-analytics",
21769
21921
  capScope: "device",
@@ -22292,6 +22444,12 @@ Object.freeze({
22292
22444
  addonId: null,
22293
22445
  access: "view"
22294
22446
  },
22447
+ "pipelineRunner.getNativeCrop": {
22448
+ capName: "pipeline-runner",
22449
+ capScope: "system",
22450
+ addonId: null,
22451
+ access: "view"
22452
+ },
22295
22453
  "pipelineRunner.reportMotion": {
22296
22454
  capName: "pipeline-runner",
22297
22455
  capScope: "system",
@@ -22658,6 +22816,12 @@ Object.freeze({
22658
22816
  addonId: null,
22659
22817
  access: "view"
22660
22818
  },
22819
+ "snapshot.getSnapshotOverview": {
22820
+ capName: "snapshot",
22821
+ capScope: "device",
22822
+ addonId: null,
22823
+ access: "view"
22824
+ },
22661
22825
  "snapshot.invalidateCache": {
22662
22826
  capName: "snapshot",
22663
22827
  capScope: "device",
@@ -23336,6 +23500,12 @@ Object.freeze({
23336
23500
  addonId: null,
23337
23501
  access: "view"
23338
23502
  },
23503
+ "userPasskeys.beginDiscoverableAuthentication": {
23504
+ capName: "user-passkeys",
23505
+ capScope: "system",
23506
+ addonId: null,
23507
+ access: "view"
23508
+ },
23339
23509
  "userPasskeys.beginRegistration": {
23340
23510
  capName: "user-passkeys",
23341
23511
  capScope: "system",
@@ -23348,12 +23518,24 @@ Object.freeze({
23348
23518
  addonId: null,
23349
23519
  access: "view"
23350
23520
  },
23521
+ "userPasskeys.finishDiscoverableAuthentication": {
23522
+ capName: "user-passkeys",
23523
+ capScope: "system",
23524
+ addonId: null,
23525
+ access: "view"
23526
+ },
23351
23527
  "userPasskeys.finishRegistration": {
23352
23528
  capName: "user-passkeys",
23353
23529
  capScope: "system",
23354
23530
  addonId: null,
23355
23531
  access: "create"
23356
23532
  },
23533
+ "userPasskeys.getSecondFactorPreference": {
23534
+ capName: "user-passkeys",
23535
+ capScope: "system",
23536
+ addonId: null,
23537
+ access: "view"
23538
+ },
23357
23539
  "userPasskeys.listPasskeys": {
23358
23540
  capName: "user-passkeys",
23359
23541
  capScope: "system",
@@ -23366,6 +23548,12 @@ Object.freeze({
23366
23548
  addonId: null,
23367
23549
  access: "delete"
23368
23550
  },
23551
+ "userPasskeys.setSecondFactorPreference": {
23552
+ capName: "user-passkeys",
23553
+ capScope: "system",
23554
+ addonId: null,
23555
+ access: "create"
23556
+ },
23369
23557
  "vacuumControl.locate": {
23370
23558
  capName: "vacuum-control",
23371
23559
  capScope: "device",
package/dist/addon.mjs CHANGED
@@ -4632,7 +4632,7 @@ function _instanceof(cls, params = {}) {
4632
4632
  return inst;
4633
4633
  }
4634
4634
  //#endregion
4635
- //#region ../types/dist/sleep-DJaTV2D7.mjs
4635
+ //#region ../types/dist/sleep-BC9Yqte7.mjs
4636
4636
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4637
4637
  EventCategory["SystemBoot"] = "system.boot";
4638
4638
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -6736,6 +6736,18 @@ function method(input, output, options) {
6736
6736
  timeoutMs: options?.timeoutMs
6737
6737
  };
6738
6738
  }
6739
+ /**
6740
+ * A wrapper/system-only method: served exclusively by the cap's system-level
6741
+ * provider (`InferProvider`), and OPTIONAL on `InferNativeProvider` so per-device
6742
+ * driver natives don't stub out a wrapper concern (e.g. a cross-device cache
6743
+ * overview). The `systemOnly: true` literal is what `InferNativeProvider` keys on.
6744
+ */
6745
+ function systemMethod(input, output, options) {
6746
+ return {
6747
+ ...method(input, output, options),
6748
+ systemOnly: true
6749
+ };
6750
+ }
6739
6751
  var StaticDirOutputSchema$1 = object({ staticDir: string() });
6740
6752
  var VersionOutputSchema$1 = object({ version: string() });
6741
6753
  method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
@@ -10656,6 +10668,7 @@ var PipelineAddonSchemaSchema = object({
10656
10668
  defaultModelId: string(),
10657
10669
  defaultModelIdByFormat: record(string(), string()).optional(),
10658
10670
  enabledByDefault: boolean().optional(),
10671
+ backfillIntoExistingOverrides: boolean().optional(),
10659
10672
  defaultConfidence: number(),
10660
10673
  group: string().optional(),
10661
10674
  configSchema: array(ConfigFieldBridge).readonly().optional()
@@ -10962,6 +10975,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(ZoneSchema).read
10962
10975
  auth: "admin"
10963
10976
  }), object({ zones: array(ZoneSchema).readonly() });
10964
10977
  /**
10978
+ * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
10979
+ * decode worker resolves it against the RETAINED native frame's real pixel dims,
10980
+ * so the caller supplies only the detection-res bbox divided by the detection
10981
+ * dims — no native resolution to plumb.
10982
+ */
10983
+ var NativeCropBboxSchema = object({
10984
+ x: number(),
10985
+ y: number(),
10986
+ w: number(),
10987
+ h: number()
10988
+ });
10989
+ /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
10990
+ var NativeCropResultSchema = object({
10991
+ /** Packed rgb (24-bit) pixels of the crop. */
10992
+ bytes: _instanceof(Uint8Array),
10993
+ width: number().int().positive(),
10994
+ height: number().int().positive()
10995
+ });
10996
+ /**
10965
10997
  * Per-camera tunable ranges + defaults. Single source of truth used
10966
10998
  * by both the Zod data schema (validation + default fallback) and
10967
10999
  * the device settings UI (slider min/max/step). Touch one place and
@@ -11217,7 +11249,11 @@ var RunnerLocalMetricsSchema = object({
11217
11249
  avgInferenceTimeMs: number(),
11218
11250
  queueDepth: number()
11219
11251
  });
11220
- method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly());
11252
+ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
11253
+ handle: FrameHandleSchema,
11254
+ bbox: NativeCropBboxSchema,
11255
+ maxWidth: number().int().positive().optional()
11256
+ }), NativeCropResultSchema.nullable());
11221
11257
  object({
11222
11258
  detected: boolean(),
11223
11259
  /** Ms epoch of the last detected-true observation. Null if never detected. */
@@ -15549,7 +15585,17 @@ var TrackSchema = object({
15549
15585
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
15550
15586
  totalDistance: number(),
15551
15587
  state: TrackStateSchema,
15552
- active: boolean()
15588
+ active: boolean(),
15589
+ /** Deterministic key-event importance score in [0,1] (server-computed at
15590
+ * track expiry, recomputed on late label). Absent on legacy rows written
15591
+ * before scoring shipped — consumers degrade to absence / compute-on-read. */
15592
+ importance: number().optional(),
15593
+ /** Id of the track's highest-confidence ObjectEvent (its representative
15594
+ * "best" frame). Absent when the track produced no object events. */
15595
+ bestEventId: string().optional(),
15596
+ /** Tag of the importance sub-signal that dominated the score
15597
+ * (identity|dwell|proximity|class|confidence|travel|zone). */
15598
+ importanceReason: string().optional()
15553
15599
  });
15554
15600
  var BaseEventFields = {
15555
15601
  id: string(),
@@ -15614,8 +15660,18 @@ var ObjectEventSchema = object({
15614
15660
  frameHeight: number().optional(),
15615
15661
  /** MediaStore key for the crop attached to this event (if any). */
15616
15662
  mediaKey: string().optional(),
15663
+ /** Design B: MediaStore key of the track's native-resolution key frame (the
15664
+ * best-detection full frame). Resolve via the event-media data-plane
15665
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
15666
+ * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
15667
+ * sources — consumers fall back to `mediaKey` (the tight crop). */
15668
+ keyFrameMediaKey: string().optional(),
15617
15669
  /** Populated by B5 (recording playback URL for this event). */
15618
- mediaUrl: string().optional()
15670
+ mediaUrl: string().optional(),
15671
+ /** The parent track's key-event importance [0,1], propagated to every object
15672
+ * event of the track (so an event row can be sorted by importance without a
15673
+ * track join). Absent on legacy rows / before the track was scored. */
15674
+ importance: number().optional()
15619
15675
  });
15620
15676
  var AudioEventSchema = object({
15621
15677
  ...BaseEventFields,
@@ -15639,7 +15695,8 @@ var MediaFileKindEnum = _enum([
15639
15695
  "fullFrame",
15640
15696
  "fullFrameBoxed",
15641
15697
  "faceCrop",
15642
- "plateCrop"
15698
+ "plateCrop",
15699
+ "keyFrame"
15643
15700
  ]);
15644
15701
  var MediaFileSchema = object({
15645
15702
  key: string(),
@@ -15660,6 +15717,32 @@ var DeviceEventQueryInput = object({
15660
15717
  projection: _enum(["full", "slim"]).optional()
15661
15718
  });
15662
15719
  var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
15720
+ var KeyEventQueryInput = object({
15721
+ deviceId: number(),
15722
+ /** Window lower bound (track firstSeen ≥ since). */
15723
+ since: number(),
15724
+ /** Window upper bound (track firstSeen ≤ until). */
15725
+ until: number(),
15726
+ limit: number().int().min(1).max(200).default(50),
15727
+ /** Drop tracks scoring below this importance. */
15728
+ minImportance: number().min(0).max(1).optional(),
15729
+ /** Restrict to a single class (e.g. 'person'). */
15730
+ classFilter: string().optional()
15731
+ });
15732
+ var KeyEventSchema = object({
15733
+ /** The representative event id (the track's best ObjectEvent, else its trackId). */
15734
+ id: string(),
15735
+ trackId: string(),
15736
+ /** Track start time (firstSeen). */
15737
+ timestamp: number(),
15738
+ className: string(),
15739
+ label: string().optional(),
15740
+ importance: number(),
15741
+ /** Highest-confidence ObjectEvent id for the track (empty when none). */
15742
+ bestEventId: string(),
15743
+ /** Track lifetime in ms (lastSeen - firstSeen). */
15744
+ windowMs: number().optional()
15745
+ });
15663
15746
  var TrackedDetectionSchema = object({
15664
15747
  trackId: string(),
15665
15748
  className: string(),
@@ -15689,7 +15772,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
15689
15772
  }), array(TrackSchema).readonly()), method(object({ deviceId: number() }), _void(), {
15690
15773
  kind: "mutation",
15691
15774
  auth: "admin"
15692
- }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({
15775
+ }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
15693
15776
  deviceId: number(),
15694
15777
  since: number(),
15695
15778
  until: number(),
@@ -16493,7 +16576,20 @@ var snapshotCapability = {
16493
16576
  invalidateCache: method(object({ deviceId: number() }), _void(), {
16494
16577
  kind: "mutation",
16495
16578
  auth: "admin"
16496
- })
16579
+ }),
16580
+ /**
16581
+ * Cache-only batch overview — answers from the wrapper's in-memory cache in
16582
+ * O(n) and NEVER triggers a capture. Lets a grid skip requesting images for
16583
+ * devices that never produced a frame, and gives it an ETag per device for
16584
+ * conditional (304-able) image fetches. `lastCapturedAt`/`cacheAgeMs`/`etag`
16585
+ * are null for a device with no cached frame.
16586
+ */
16587
+ getSnapshotOverview: systemMethod(object({ deviceIds: array(number()).min(1).max(200) }), array(object({
16588
+ deviceId: number(),
16589
+ lastCapturedAt: number().nullable(),
16590
+ cacheAgeMs: number().nullable(),
16591
+ etag: string().nullable()
16592
+ })))
16497
16593
  },
16498
16594
  status: {
16499
16595
  schema: SnapshotStatusSchema,
@@ -16750,10 +16846,32 @@ method(_void(), array(TurnServerSchema).readonly());
16750
16846
  * b. `finishAuthentication({userId, response})` → server verifies
16751
16847
  * the assertion, bumps the credential counter, returns ok.
16752
16848
  *
16849
+ * 2b. Usernameless (discoverable-credential) authentication — the
16850
+ * passkey IS the primary factor, no password leg:
16851
+ * a. `beginDiscoverableAuthentication({})` → assertion options with
16852
+ * EMPTY `allowCredentials` (the browser offers every resident
16853
+ * passkey it holds for this RP) + `userVerification: 'required'`
16854
+ * (the passkey replaces both factors, so UV is mandatory).
16855
+ * The challenge is stored server-side, NOT bound to any user.
16856
+ * b. `finishDiscoverableAuthentication({response})` → the provider
16857
+ * resolves the credential by the response's credential id,
16858
+ * verifies the assertion against the stored challenge + that
16859
+ * credential's public key/counter, and returns the OWNING
16860
+ * `userId` — the caller (core auth router) mints the session.
16861
+ *
16753
16862
  * 3. Management:
16754
16863
  * - `listPasskeys({userId})` — enumerate user's enrolled credentials.
16755
16864
  * - `removePasskey({userId, credentialId})` — revoke one credential.
16756
16865
  *
16866
+ * 4. Second-factor preference (opt-in, default OFF):
16867
+ * Enrolling a passkey only enables passkey-FIRST sign-in. It is
16868
+ * demanded as a second factor after a password login ONLY when the
16869
+ * user explicitly opts in via `setSecondFactorPreference`.
16870
+ * - `getSecondFactorPreference({userId})` → `{ enabled }` (missing
16871
+ * row ⇒ `enabled: false`).
16872
+ * - `setSecondFactorPreference({userId, enabled})` — persisted by
16873
+ * the providing addon beside its credentials.
16874
+ *
16757
16875
  * Challenges are short-lived (5 min, in-memory). The cap is internal —
16758
16876
  * the admin-ui composes the begin/finish round-trip and never exposes
16759
16877
  * the cap to non-admins.
@@ -16796,6 +16914,17 @@ method(object({
16796
16914
  }), object({ verified: boolean() }), {
16797
16915
  kind: "mutation",
16798
16916
  access: "view"
16917
+ }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
16918
+ kind: "mutation",
16919
+ access: "view"
16920
+ }), method(object({
16921
+ /** AuthenticationResponseJSON from the browser. */
16922
+ response: record(string(), unknown()) }), object({
16923
+ verified: boolean(),
16924
+ userId: string().nullable()
16925
+ }), {
16926
+ kind: "mutation",
16927
+ access: "view"
16799
16928
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
16800
16929
  userId: string(),
16801
16930
  credentialId: string()
@@ -16803,6 +16932,13 @@ method(object({
16803
16932
  kind: "mutation",
16804
16933
  auth: "admin",
16805
16934
  access: "delete"
16935
+ }), method(object({ userId: string() }), object({ enabled: boolean() }), { auth: "admin" }), method(object({
16936
+ userId: string(),
16937
+ enabled: boolean()
16938
+ }), object({ success: literal(true) }), {
16939
+ kind: "mutation",
16940
+ auth: "admin",
16941
+ access: "create"
16806
16942
  });
16807
16943
  /**
16808
16944
  * `videoclips` — the unified, navigable-clip surface for a camera.
@@ -17604,7 +17740,17 @@ var FaceInfoSchema = object({
17604
17740
  recognizedIdentityId: string().optional(),
17605
17741
  identityName: string().optional(),
17606
17742
  assigned: boolean(),
17607
- base64: string().optional()
17743
+ base64: string().optional(),
17744
+ /** Design B: the face bbox (pixel space) on the key frame — lets a detail
17745
+ * view draw the box over the native `keyFrameMediaKey` frame. Absent on
17746
+ * legacy rows written before design B. */
17747
+ faceBbox: BoundingBoxSchema.optional(),
17748
+ /** Design B: MediaStore key of the track's native-resolution key frame.
17749
+ * Fetch the native JPEG via the event-media data-plane
17750
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
17751
+ * track produced no key frame (e.g. native/onboard source) — the UI falls
17752
+ * back to the inline `base64` face crop. */
17753
+ keyFrameMediaKey: string().optional()
17608
17754
  });
17609
17755
  var FaceFilterEnum = _enum([
17610
17756
  "unassigned",
@@ -21765,6 +21911,12 @@ Object.freeze({
21765
21911
  addonId: null,
21766
21912
  access: "view"
21767
21913
  },
21914
+ "pipelineAnalytics.getKeyEvents": {
21915
+ capName: "pipeline-analytics",
21916
+ capScope: "device",
21917
+ addonId: null,
21918
+ access: "view"
21919
+ },
21768
21920
  "pipelineAnalytics.getMotionEvents": {
21769
21921
  capName: "pipeline-analytics",
21770
21922
  capScope: "device",
@@ -22293,6 +22445,12 @@ Object.freeze({
22293
22445
  addonId: null,
22294
22446
  access: "view"
22295
22447
  },
22448
+ "pipelineRunner.getNativeCrop": {
22449
+ capName: "pipeline-runner",
22450
+ capScope: "system",
22451
+ addonId: null,
22452
+ access: "view"
22453
+ },
22296
22454
  "pipelineRunner.reportMotion": {
22297
22455
  capName: "pipeline-runner",
22298
22456
  capScope: "system",
@@ -22659,6 +22817,12 @@ Object.freeze({
22659
22817
  addonId: null,
22660
22818
  access: "view"
22661
22819
  },
22820
+ "snapshot.getSnapshotOverview": {
22821
+ capName: "snapshot",
22822
+ capScope: "device",
22823
+ addonId: null,
22824
+ access: "view"
22825
+ },
22662
22826
  "snapshot.invalidateCache": {
22663
22827
  capName: "snapshot",
22664
22828
  capScope: "device",
@@ -23337,6 +23501,12 @@ Object.freeze({
23337
23501
  addonId: null,
23338
23502
  access: "view"
23339
23503
  },
23504
+ "userPasskeys.beginDiscoverableAuthentication": {
23505
+ capName: "user-passkeys",
23506
+ capScope: "system",
23507
+ addonId: null,
23508
+ access: "view"
23509
+ },
23340
23510
  "userPasskeys.beginRegistration": {
23341
23511
  capName: "user-passkeys",
23342
23512
  capScope: "system",
@@ -23349,12 +23519,24 @@ Object.freeze({
23349
23519
  addonId: null,
23350
23520
  access: "view"
23351
23521
  },
23522
+ "userPasskeys.finishDiscoverableAuthentication": {
23523
+ capName: "user-passkeys",
23524
+ capScope: "system",
23525
+ addonId: null,
23526
+ access: "view"
23527
+ },
23352
23528
  "userPasskeys.finishRegistration": {
23353
23529
  capName: "user-passkeys",
23354
23530
  capScope: "system",
23355
23531
  addonId: null,
23356
23532
  access: "create"
23357
23533
  },
23534
+ "userPasskeys.getSecondFactorPreference": {
23535
+ capName: "user-passkeys",
23536
+ capScope: "system",
23537
+ addonId: null,
23538
+ access: "view"
23539
+ },
23358
23540
  "userPasskeys.listPasskeys": {
23359
23541
  capName: "user-passkeys",
23360
23542
  capScope: "system",
@@ -23367,6 +23549,12 @@ Object.freeze({
23367
23549
  addonId: null,
23368
23550
  access: "delete"
23369
23551
  },
23552
+ "userPasskeys.setSecondFactorPreference": {
23553
+ capName: "user-passkeys",
23554
+ capScope: "system",
23555
+ addonId: null,
23556
+ access: "create"
23557
+ },
23370
23558
  "vacuumControl.locate": {
23371
23559
  capName: "vacuum-control",
23372
23560
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-onvif",
3
- "version": "1.1.22",
3
+ "version": "1.1.23",
4
4
  "description": "ONVIF camera device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",