@camstack/addon-provider-reolink 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
@@ -4655,7 +4655,7 @@ function _instanceof(cls, params = {}) {
4655
4655
  return inst;
4656
4656
  }
4657
4657
  //#endregion
4658
- //#region ../types/dist/sleep-DJaTV2D7.mjs
4658
+ //#region ../types/dist/sleep-BC9Yqte7.mjs
4659
4659
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4660
4660
  EventCategory["SystemBoot"] = "system.boot";
4661
4661
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -6759,6 +6759,18 @@ function method(input, output, options) {
6759
6759
  timeoutMs: options?.timeoutMs
6760
6760
  };
6761
6761
  }
6762
+ /**
6763
+ * A wrapper/system-only method: served exclusively by the cap's system-level
6764
+ * provider (`InferProvider`), and OPTIONAL on `InferNativeProvider` so per-device
6765
+ * driver natives don't stub out a wrapper concern (e.g. a cross-device cache
6766
+ * overview). The `systemOnly: true` literal is what `InferNativeProvider` keys on.
6767
+ */
6768
+ function systemMethod(input, output, options) {
6769
+ return {
6770
+ ...method(input, output, options),
6771
+ systemOnly: true
6772
+ };
6773
+ }
6762
6774
  /** Shorthand to define an event schema */
6763
6775
  function event(data) {
6764
6776
  return { data };
@@ -12000,6 +12012,7 @@ var PipelineAddonSchemaSchema = object({
12000
12012
  defaultModelId: string(),
12001
12013
  defaultModelIdByFormat: record(string(), string()).optional(),
12002
12014
  enabledByDefault: boolean().optional(),
12015
+ backfillIntoExistingOverrides: boolean().optional(),
12003
12016
  defaultConfidence: number(),
12004
12017
  group: string().optional(),
12005
12018
  configSchema: array(ConfigFieldBridge).readonly().optional()
@@ -12339,6 +12352,25 @@ var zonesCapability = {
12339
12352
  runtimeState: object({ zones: array(ZoneSchema).readonly() })
12340
12353
  };
12341
12354
  /**
12355
+ * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
12356
+ * decode worker resolves it against the RETAINED native frame's real pixel dims,
12357
+ * so the caller supplies only the detection-res bbox divided by the detection
12358
+ * dims — no native resolution to plumb.
12359
+ */
12360
+ var NativeCropBboxSchema = object({
12361
+ x: number(),
12362
+ y: number(),
12363
+ w: number(),
12364
+ h: number()
12365
+ });
12366
+ /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
12367
+ var NativeCropResultSchema = object({
12368
+ /** Packed rgb (24-bit) pixels of the crop. */
12369
+ bytes: _instanceof(Uint8Array),
12370
+ width: number().int().positive(),
12371
+ height: number().int().positive()
12372
+ });
12373
+ /**
12342
12374
  * Per-camera tunable ranges + defaults. Single source of truth used
12343
12375
  * by both the Zod data schema (validation + default fallback) and
12344
12376
  * the device settings UI (slider min/max/step). Touch one place and
@@ -12594,7 +12626,11 @@ var RunnerLocalMetricsSchema = object({
12594
12626
  avgInferenceTimeMs: number(),
12595
12627
  queueDepth: number()
12596
12628
  });
12597
- 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());
12629
+ 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({
12630
+ handle: FrameHandleSchema,
12631
+ bbox: NativeCropBboxSchema,
12632
+ maxWidth: number().int().positive().optional()
12633
+ }), NativeCropResultSchema.nullable());
12598
12634
  /**
12599
12635
  * Hardware / firmware motion sensor cap — binary detected state plus
12600
12636
  * a timestamp of the last observation. Distinct from
@@ -18281,7 +18317,17 @@ var TrackSchema = object({
18281
18317
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
18282
18318
  totalDistance: number(),
18283
18319
  state: TrackStateSchema,
18284
- active: boolean()
18320
+ active: boolean(),
18321
+ /** Deterministic key-event importance score in [0,1] (server-computed at
18322
+ * track expiry, recomputed on late label). Absent on legacy rows written
18323
+ * before scoring shipped — consumers degrade to absence / compute-on-read. */
18324
+ importance: number().optional(),
18325
+ /** Id of the track's highest-confidence ObjectEvent (its representative
18326
+ * "best" frame). Absent when the track produced no object events. */
18327
+ bestEventId: string().optional(),
18328
+ /** Tag of the importance sub-signal that dominated the score
18329
+ * (identity|dwell|proximity|class|confidence|travel|zone). */
18330
+ importanceReason: string().optional()
18285
18331
  });
18286
18332
  var BaseEventFields = {
18287
18333
  id: string(),
@@ -18346,8 +18392,18 @@ var ObjectEventSchema = object({
18346
18392
  frameHeight: number().optional(),
18347
18393
  /** MediaStore key for the crop attached to this event (if any). */
18348
18394
  mediaKey: string().optional(),
18395
+ /** Design B: MediaStore key of the track's native-resolution key frame (the
18396
+ * best-detection full frame). Resolve via the event-media data-plane
18397
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
18398
+ * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
18399
+ * sources — consumers fall back to `mediaKey` (the tight crop). */
18400
+ keyFrameMediaKey: string().optional(),
18349
18401
  /** Populated by B5 (recording playback URL for this event). */
18350
- mediaUrl: string().optional()
18402
+ mediaUrl: string().optional(),
18403
+ /** The parent track's key-event importance [0,1], propagated to every object
18404
+ * event of the track (so an event row can be sorted by importance without a
18405
+ * track join). Absent on legacy rows / before the track was scored. */
18406
+ importance: number().optional()
18351
18407
  });
18352
18408
  var AudioEventSchema = object({
18353
18409
  ...BaseEventFields,
@@ -18371,7 +18427,8 @@ var MediaFileKindEnum = _enum([
18371
18427
  "fullFrame",
18372
18428
  "fullFrameBoxed",
18373
18429
  "faceCrop",
18374
- "plateCrop"
18430
+ "plateCrop",
18431
+ "keyFrame"
18375
18432
  ]);
18376
18433
  var MediaFileSchema = object({
18377
18434
  key: string(),
@@ -18392,6 +18449,32 @@ var DeviceEventQueryInput = object({
18392
18449
  projection: _enum(["full", "slim"]).optional()
18393
18450
  });
18394
18451
  var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
18452
+ var KeyEventQueryInput = object({
18453
+ deviceId: number(),
18454
+ /** Window lower bound (track firstSeen ≥ since). */
18455
+ since: number(),
18456
+ /** Window upper bound (track firstSeen ≤ until). */
18457
+ until: number(),
18458
+ limit: number().int().min(1).max(200).default(50),
18459
+ /** Drop tracks scoring below this importance. */
18460
+ minImportance: number().min(0).max(1).optional(),
18461
+ /** Restrict to a single class (e.g. 'person'). */
18462
+ classFilter: string().optional()
18463
+ });
18464
+ var KeyEventSchema = object({
18465
+ /** The representative event id (the track's best ObjectEvent, else its trackId). */
18466
+ id: string(),
18467
+ trackId: string(),
18468
+ /** Track start time (firstSeen). */
18469
+ timestamp: number(),
18470
+ className: string(),
18471
+ label: string().optional(),
18472
+ importance: number(),
18473
+ /** Highest-confidence ObjectEvent id for the track (empty when none). */
18474
+ bestEventId: string(),
18475
+ /** Track lifetime in ms (lastSeen - firstSeen). */
18476
+ windowMs: number().optional()
18477
+ });
18395
18478
  var TrackedDetectionSchema = object({
18396
18479
  trackId: string(),
18397
18480
  className: string(),
@@ -18421,7 +18504,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
18421
18504
  }), array(TrackSchema).readonly()), method(object({ deviceId: number() }), _void(), {
18422
18505
  kind: "mutation",
18423
18506
  auth: "admin"
18424
- }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({
18507
+ }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
18425
18508
  deviceId: number(),
18426
18509
  since: number(),
18427
18510
  until: number(),
@@ -19225,7 +19308,20 @@ var snapshotCapability = {
19225
19308
  invalidateCache: method(object({ deviceId: number() }), _void(), {
19226
19309
  kind: "mutation",
19227
19310
  auth: "admin"
19228
- })
19311
+ }),
19312
+ /**
19313
+ * Cache-only batch overview — answers from the wrapper's in-memory cache in
19314
+ * O(n) and NEVER triggers a capture. Lets a grid skip requesting images for
19315
+ * devices that never produced a frame, and gives it an ETag per device for
19316
+ * conditional (304-able) image fetches. `lastCapturedAt`/`cacheAgeMs`/`etag`
19317
+ * are null for a device with no cached frame.
19318
+ */
19319
+ getSnapshotOverview: systemMethod(object({ deviceIds: array(number()).min(1).max(200) }), array(object({
19320
+ deviceId: number(),
19321
+ lastCapturedAt: number().nullable(),
19322
+ cacheAgeMs: number().nullable(),
19323
+ etag: string().nullable()
19324
+ })))
19229
19325
  },
19230
19326
  status: {
19231
19327
  schema: SnapshotStatusSchema,
@@ -19482,10 +19578,32 @@ method(_void(), array(TurnServerSchema).readonly());
19482
19578
  * b. `finishAuthentication({userId, response})` → server verifies
19483
19579
  * the assertion, bumps the credential counter, returns ok.
19484
19580
  *
19581
+ * 2b. Usernameless (discoverable-credential) authentication — the
19582
+ * passkey IS the primary factor, no password leg:
19583
+ * a. `beginDiscoverableAuthentication({})` → assertion options with
19584
+ * EMPTY `allowCredentials` (the browser offers every resident
19585
+ * passkey it holds for this RP) + `userVerification: 'required'`
19586
+ * (the passkey replaces both factors, so UV is mandatory).
19587
+ * The challenge is stored server-side, NOT bound to any user.
19588
+ * b. `finishDiscoverableAuthentication({response})` → the provider
19589
+ * resolves the credential by the response's credential id,
19590
+ * verifies the assertion against the stored challenge + that
19591
+ * credential's public key/counter, and returns the OWNING
19592
+ * `userId` — the caller (core auth router) mints the session.
19593
+ *
19485
19594
  * 3. Management:
19486
19595
  * - `listPasskeys({userId})` — enumerate user's enrolled credentials.
19487
19596
  * - `removePasskey({userId, credentialId})` — revoke one credential.
19488
19597
  *
19598
+ * 4. Second-factor preference (opt-in, default OFF):
19599
+ * Enrolling a passkey only enables passkey-FIRST sign-in. It is
19600
+ * demanded as a second factor after a password login ONLY when the
19601
+ * user explicitly opts in via `setSecondFactorPreference`.
19602
+ * - `getSecondFactorPreference({userId})` → `{ enabled }` (missing
19603
+ * row ⇒ `enabled: false`).
19604
+ * - `setSecondFactorPreference({userId, enabled})` — persisted by
19605
+ * the providing addon beside its credentials.
19606
+ *
19489
19607
  * Challenges are short-lived (5 min, in-memory). The cap is internal —
19490
19608
  * the admin-ui composes the begin/finish round-trip and never exposes
19491
19609
  * the cap to non-admins.
@@ -19528,6 +19646,17 @@ method(object({
19528
19646
  }), object({ verified: boolean() }), {
19529
19647
  kind: "mutation",
19530
19648
  access: "view"
19649
+ }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
19650
+ kind: "mutation",
19651
+ access: "view"
19652
+ }), method(object({
19653
+ /** AuthenticationResponseJSON from the browser. */
19654
+ response: record(string(), unknown()) }), object({
19655
+ verified: boolean(),
19656
+ userId: string().nullable()
19657
+ }), {
19658
+ kind: "mutation",
19659
+ access: "view"
19531
19660
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
19532
19661
  userId: string(),
19533
19662
  credentialId: string()
@@ -19535,6 +19664,13 @@ method(object({
19535
19664
  kind: "mutation",
19536
19665
  auth: "admin",
19537
19666
  access: "delete"
19667
+ }), method(object({ userId: string() }), object({ enabled: boolean() }), { auth: "admin" }), method(object({
19668
+ userId: string(),
19669
+ enabled: boolean()
19670
+ }), object({ success: literal(true) }), {
19671
+ kind: "mutation",
19672
+ auth: "admin",
19673
+ access: "create"
19538
19674
  });
19539
19675
  /**
19540
19676
  * `videoclips` — the unified, navigable-clip surface for a camera.
@@ -20336,7 +20472,17 @@ var FaceInfoSchema = object({
20336
20472
  recognizedIdentityId: string().optional(),
20337
20473
  identityName: string().optional(),
20338
20474
  assigned: boolean(),
20339
- base64: string().optional()
20475
+ base64: string().optional(),
20476
+ /** Design B: the face bbox (pixel space) on the key frame — lets a detail
20477
+ * view draw the box over the native `keyFrameMediaKey` frame. Absent on
20478
+ * legacy rows written before design B. */
20479
+ faceBbox: BoundingBoxSchema.optional(),
20480
+ /** Design B: MediaStore key of the track's native-resolution key frame.
20481
+ * Fetch the native JPEG via the event-media data-plane
20482
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
20483
+ * track produced no key frame (e.g. native/onboard source) — the UI falls
20484
+ * back to the inline `base64` face crop. */
20485
+ keyFrameMediaKey: string().optional()
20340
20486
  });
20341
20487
  var FaceFilterEnum = _enum([
20342
20488
  "unassigned",
@@ -24784,6 +24930,12 @@ Object.freeze({
24784
24930
  addonId: null,
24785
24931
  access: "view"
24786
24932
  },
24933
+ "pipelineAnalytics.getKeyEvents": {
24934
+ capName: "pipeline-analytics",
24935
+ capScope: "device",
24936
+ addonId: null,
24937
+ access: "view"
24938
+ },
24787
24939
  "pipelineAnalytics.getMotionEvents": {
24788
24940
  capName: "pipeline-analytics",
24789
24941
  capScope: "device",
@@ -25312,6 +25464,12 @@ Object.freeze({
25312
25464
  addonId: null,
25313
25465
  access: "view"
25314
25466
  },
25467
+ "pipelineRunner.getNativeCrop": {
25468
+ capName: "pipeline-runner",
25469
+ capScope: "system",
25470
+ addonId: null,
25471
+ access: "view"
25472
+ },
25315
25473
  "pipelineRunner.reportMotion": {
25316
25474
  capName: "pipeline-runner",
25317
25475
  capScope: "system",
@@ -25678,6 +25836,12 @@ Object.freeze({
25678
25836
  addonId: null,
25679
25837
  access: "view"
25680
25838
  },
25839
+ "snapshot.getSnapshotOverview": {
25840
+ capName: "snapshot",
25841
+ capScope: "device",
25842
+ addonId: null,
25843
+ access: "view"
25844
+ },
25681
25845
  "snapshot.invalidateCache": {
25682
25846
  capName: "snapshot",
25683
25847
  capScope: "device",
@@ -26356,6 +26520,12 @@ Object.freeze({
26356
26520
  addonId: null,
26357
26521
  access: "view"
26358
26522
  },
26523
+ "userPasskeys.beginDiscoverableAuthentication": {
26524
+ capName: "user-passkeys",
26525
+ capScope: "system",
26526
+ addonId: null,
26527
+ access: "view"
26528
+ },
26359
26529
  "userPasskeys.beginRegistration": {
26360
26530
  capName: "user-passkeys",
26361
26531
  capScope: "system",
@@ -26368,12 +26538,24 @@ Object.freeze({
26368
26538
  addonId: null,
26369
26539
  access: "view"
26370
26540
  },
26541
+ "userPasskeys.finishDiscoverableAuthentication": {
26542
+ capName: "user-passkeys",
26543
+ capScope: "system",
26544
+ addonId: null,
26545
+ access: "view"
26546
+ },
26371
26547
  "userPasskeys.finishRegistration": {
26372
26548
  capName: "user-passkeys",
26373
26549
  capScope: "system",
26374
26550
  addonId: null,
26375
26551
  access: "create"
26376
26552
  },
26553
+ "userPasskeys.getSecondFactorPreference": {
26554
+ capName: "user-passkeys",
26555
+ capScope: "system",
26556
+ addonId: null,
26557
+ access: "view"
26558
+ },
26377
26559
  "userPasskeys.listPasskeys": {
26378
26560
  capName: "user-passkeys",
26379
26561
  capScope: "system",
@@ -26386,6 +26568,12 @@ Object.freeze({
26386
26568
  addonId: null,
26387
26569
  access: "delete"
26388
26570
  },
26571
+ "userPasskeys.setSecondFactorPreference": {
26572
+ capName: "user-passkeys",
26573
+ capScope: "system",
26574
+ addonId: null,
26575
+ access: "create"
26576
+ },
26389
26577
  "vacuumControl.locate": {
26390
26578
  capName: "vacuum-control",
26391
26579
  capScope: "device",
package/dist/addon.mjs CHANGED
@@ -4650,7 +4650,7 @@ function _instanceof(cls, params = {}) {
4650
4650
  return inst;
4651
4651
  }
4652
4652
  //#endregion
4653
- //#region ../types/dist/sleep-DJaTV2D7.mjs
4653
+ //#region ../types/dist/sleep-BC9Yqte7.mjs
4654
4654
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4655
4655
  EventCategory["SystemBoot"] = "system.boot";
4656
4656
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -6754,6 +6754,18 @@ function method(input, output, options) {
6754
6754
  timeoutMs: options?.timeoutMs
6755
6755
  };
6756
6756
  }
6757
+ /**
6758
+ * A wrapper/system-only method: served exclusively by the cap's system-level
6759
+ * provider (`InferProvider`), and OPTIONAL on `InferNativeProvider` so per-device
6760
+ * driver natives don't stub out a wrapper concern (e.g. a cross-device cache
6761
+ * overview). The `systemOnly: true` literal is what `InferNativeProvider` keys on.
6762
+ */
6763
+ function systemMethod(input, output, options) {
6764
+ return {
6765
+ ...method(input, output, options),
6766
+ systemOnly: true
6767
+ };
6768
+ }
6757
6769
  /** Shorthand to define an event schema */
6758
6770
  function event(data) {
6759
6771
  return { data };
@@ -11995,6 +12007,7 @@ var PipelineAddonSchemaSchema = object({
11995
12007
  defaultModelId: string(),
11996
12008
  defaultModelIdByFormat: record(string(), string()).optional(),
11997
12009
  enabledByDefault: boolean().optional(),
12010
+ backfillIntoExistingOverrides: boolean().optional(),
11998
12011
  defaultConfidence: number(),
11999
12012
  group: string().optional(),
12000
12013
  configSchema: array(ConfigFieldBridge).readonly().optional()
@@ -12334,6 +12347,25 @@ var zonesCapability = {
12334
12347
  runtimeState: object({ zones: array(ZoneSchema).readonly() })
12335
12348
  };
12336
12349
  /**
12350
+ * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
12351
+ * decode worker resolves it against the RETAINED native frame's real pixel dims,
12352
+ * so the caller supplies only the detection-res bbox divided by the detection
12353
+ * dims — no native resolution to plumb.
12354
+ */
12355
+ var NativeCropBboxSchema = object({
12356
+ x: number(),
12357
+ y: number(),
12358
+ w: number(),
12359
+ h: number()
12360
+ });
12361
+ /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
12362
+ var NativeCropResultSchema = object({
12363
+ /** Packed rgb (24-bit) pixels of the crop. */
12364
+ bytes: _instanceof(Uint8Array),
12365
+ width: number().int().positive(),
12366
+ height: number().int().positive()
12367
+ });
12368
+ /**
12337
12369
  * Per-camera tunable ranges + defaults. Single source of truth used
12338
12370
  * by both the Zod data schema (validation + default fallback) and
12339
12371
  * the device settings UI (slider min/max/step). Touch one place and
@@ -12589,7 +12621,11 @@ var RunnerLocalMetricsSchema = object({
12589
12621
  avgInferenceTimeMs: number(),
12590
12622
  queueDepth: number()
12591
12623
  });
12592
- 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());
12624
+ 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({
12625
+ handle: FrameHandleSchema,
12626
+ bbox: NativeCropBboxSchema,
12627
+ maxWidth: number().int().positive().optional()
12628
+ }), NativeCropResultSchema.nullable());
12593
12629
  /**
12594
12630
  * Hardware / firmware motion sensor cap — binary detected state plus
12595
12631
  * a timestamp of the last observation. Distinct from
@@ -18276,7 +18312,17 @@ var TrackSchema = object({
18276
18312
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
18277
18313
  totalDistance: number(),
18278
18314
  state: TrackStateSchema,
18279
- active: boolean()
18315
+ active: boolean(),
18316
+ /** Deterministic key-event importance score in [0,1] (server-computed at
18317
+ * track expiry, recomputed on late label). Absent on legacy rows written
18318
+ * before scoring shipped — consumers degrade to absence / compute-on-read. */
18319
+ importance: number().optional(),
18320
+ /** Id of the track's highest-confidence ObjectEvent (its representative
18321
+ * "best" frame). Absent when the track produced no object events. */
18322
+ bestEventId: string().optional(),
18323
+ /** Tag of the importance sub-signal that dominated the score
18324
+ * (identity|dwell|proximity|class|confidence|travel|zone). */
18325
+ importanceReason: string().optional()
18280
18326
  });
18281
18327
  var BaseEventFields = {
18282
18328
  id: string(),
@@ -18341,8 +18387,18 @@ var ObjectEventSchema = object({
18341
18387
  frameHeight: number().optional(),
18342
18388
  /** MediaStore key for the crop attached to this event (if any). */
18343
18389
  mediaKey: string().optional(),
18390
+ /** Design B: MediaStore key of the track's native-resolution key frame (the
18391
+ * best-detection full frame). Resolve via the event-media data-plane
18392
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
18393
+ * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
18394
+ * sources — consumers fall back to `mediaKey` (the tight crop). */
18395
+ keyFrameMediaKey: string().optional(),
18344
18396
  /** Populated by B5 (recording playback URL for this event). */
18345
- mediaUrl: string().optional()
18397
+ mediaUrl: string().optional(),
18398
+ /** The parent track's key-event importance [0,1], propagated to every object
18399
+ * event of the track (so an event row can be sorted by importance without a
18400
+ * track join). Absent on legacy rows / before the track was scored. */
18401
+ importance: number().optional()
18346
18402
  });
18347
18403
  var AudioEventSchema = object({
18348
18404
  ...BaseEventFields,
@@ -18366,7 +18422,8 @@ var MediaFileKindEnum = _enum([
18366
18422
  "fullFrame",
18367
18423
  "fullFrameBoxed",
18368
18424
  "faceCrop",
18369
- "plateCrop"
18425
+ "plateCrop",
18426
+ "keyFrame"
18370
18427
  ]);
18371
18428
  var MediaFileSchema = object({
18372
18429
  key: string(),
@@ -18387,6 +18444,32 @@ var DeviceEventQueryInput = object({
18387
18444
  projection: _enum(["full", "slim"]).optional()
18388
18445
  });
18389
18446
  var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
18447
+ var KeyEventQueryInput = object({
18448
+ deviceId: number(),
18449
+ /** Window lower bound (track firstSeen ≥ since). */
18450
+ since: number(),
18451
+ /** Window upper bound (track firstSeen ≤ until). */
18452
+ until: number(),
18453
+ limit: number().int().min(1).max(200).default(50),
18454
+ /** Drop tracks scoring below this importance. */
18455
+ minImportance: number().min(0).max(1).optional(),
18456
+ /** Restrict to a single class (e.g. 'person'). */
18457
+ classFilter: string().optional()
18458
+ });
18459
+ var KeyEventSchema = object({
18460
+ /** The representative event id (the track's best ObjectEvent, else its trackId). */
18461
+ id: string(),
18462
+ trackId: string(),
18463
+ /** Track start time (firstSeen). */
18464
+ timestamp: number(),
18465
+ className: string(),
18466
+ label: string().optional(),
18467
+ importance: number(),
18468
+ /** Highest-confidence ObjectEvent id for the track (empty when none). */
18469
+ bestEventId: string(),
18470
+ /** Track lifetime in ms (lastSeen - firstSeen). */
18471
+ windowMs: number().optional()
18472
+ });
18390
18473
  var TrackedDetectionSchema = object({
18391
18474
  trackId: string(),
18392
18475
  className: string(),
@@ -18416,7 +18499,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
18416
18499
  }), array(TrackSchema).readonly()), method(object({ deviceId: number() }), _void(), {
18417
18500
  kind: "mutation",
18418
18501
  auth: "admin"
18419
- }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({
18502
+ }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
18420
18503
  deviceId: number(),
18421
18504
  since: number(),
18422
18505
  until: number(),
@@ -19220,7 +19303,20 @@ var snapshotCapability = {
19220
19303
  invalidateCache: method(object({ deviceId: number() }), _void(), {
19221
19304
  kind: "mutation",
19222
19305
  auth: "admin"
19223
- })
19306
+ }),
19307
+ /**
19308
+ * Cache-only batch overview — answers from the wrapper's in-memory cache in
19309
+ * O(n) and NEVER triggers a capture. Lets a grid skip requesting images for
19310
+ * devices that never produced a frame, and gives it an ETag per device for
19311
+ * conditional (304-able) image fetches. `lastCapturedAt`/`cacheAgeMs`/`etag`
19312
+ * are null for a device with no cached frame.
19313
+ */
19314
+ getSnapshotOverview: systemMethod(object({ deviceIds: array(number()).min(1).max(200) }), array(object({
19315
+ deviceId: number(),
19316
+ lastCapturedAt: number().nullable(),
19317
+ cacheAgeMs: number().nullable(),
19318
+ etag: string().nullable()
19319
+ })))
19224
19320
  },
19225
19321
  status: {
19226
19322
  schema: SnapshotStatusSchema,
@@ -19477,10 +19573,32 @@ method(_void(), array(TurnServerSchema).readonly());
19477
19573
  * b. `finishAuthentication({userId, response})` → server verifies
19478
19574
  * the assertion, bumps the credential counter, returns ok.
19479
19575
  *
19576
+ * 2b. Usernameless (discoverable-credential) authentication — the
19577
+ * passkey IS the primary factor, no password leg:
19578
+ * a. `beginDiscoverableAuthentication({})` → assertion options with
19579
+ * EMPTY `allowCredentials` (the browser offers every resident
19580
+ * passkey it holds for this RP) + `userVerification: 'required'`
19581
+ * (the passkey replaces both factors, so UV is mandatory).
19582
+ * The challenge is stored server-side, NOT bound to any user.
19583
+ * b. `finishDiscoverableAuthentication({response})` → the provider
19584
+ * resolves the credential by the response's credential id,
19585
+ * verifies the assertion against the stored challenge + that
19586
+ * credential's public key/counter, and returns the OWNING
19587
+ * `userId` — the caller (core auth router) mints the session.
19588
+ *
19480
19589
  * 3. Management:
19481
19590
  * - `listPasskeys({userId})` — enumerate user's enrolled credentials.
19482
19591
  * - `removePasskey({userId, credentialId})` — revoke one credential.
19483
19592
  *
19593
+ * 4. Second-factor preference (opt-in, default OFF):
19594
+ * Enrolling a passkey only enables passkey-FIRST sign-in. It is
19595
+ * demanded as a second factor after a password login ONLY when the
19596
+ * user explicitly opts in via `setSecondFactorPreference`.
19597
+ * - `getSecondFactorPreference({userId})` → `{ enabled }` (missing
19598
+ * row ⇒ `enabled: false`).
19599
+ * - `setSecondFactorPreference({userId, enabled})` — persisted by
19600
+ * the providing addon beside its credentials.
19601
+ *
19484
19602
  * Challenges are short-lived (5 min, in-memory). The cap is internal —
19485
19603
  * the admin-ui composes the begin/finish round-trip and never exposes
19486
19604
  * the cap to non-admins.
@@ -19523,6 +19641,17 @@ method(object({
19523
19641
  }), object({ verified: boolean() }), {
19524
19642
  kind: "mutation",
19525
19643
  access: "view"
19644
+ }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
19645
+ kind: "mutation",
19646
+ access: "view"
19647
+ }), method(object({
19648
+ /** AuthenticationResponseJSON from the browser. */
19649
+ response: record(string(), unknown()) }), object({
19650
+ verified: boolean(),
19651
+ userId: string().nullable()
19652
+ }), {
19653
+ kind: "mutation",
19654
+ access: "view"
19526
19655
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
19527
19656
  userId: string(),
19528
19657
  credentialId: string()
@@ -19530,6 +19659,13 @@ method(object({
19530
19659
  kind: "mutation",
19531
19660
  auth: "admin",
19532
19661
  access: "delete"
19662
+ }), method(object({ userId: string() }), object({ enabled: boolean() }), { auth: "admin" }), method(object({
19663
+ userId: string(),
19664
+ enabled: boolean()
19665
+ }), object({ success: literal(true) }), {
19666
+ kind: "mutation",
19667
+ auth: "admin",
19668
+ access: "create"
19533
19669
  });
19534
19670
  /**
19535
19671
  * `videoclips` — the unified, navigable-clip surface for a camera.
@@ -20331,7 +20467,17 @@ var FaceInfoSchema = object({
20331
20467
  recognizedIdentityId: string().optional(),
20332
20468
  identityName: string().optional(),
20333
20469
  assigned: boolean(),
20334
- base64: string().optional()
20470
+ base64: string().optional(),
20471
+ /** Design B: the face bbox (pixel space) on the key frame — lets a detail
20472
+ * view draw the box over the native `keyFrameMediaKey` frame. Absent on
20473
+ * legacy rows written before design B. */
20474
+ faceBbox: BoundingBoxSchema.optional(),
20475
+ /** Design B: MediaStore key of the track's native-resolution key frame.
20476
+ * Fetch the native JPEG via the event-media data-plane
20477
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
20478
+ * track produced no key frame (e.g. native/onboard source) — the UI falls
20479
+ * back to the inline `base64` face crop. */
20480
+ keyFrameMediaKey: string().optional()
20335
20481
  });
20336
20482
  var FaceFilterEnum = _enum([
20337
20483
  "unassigned",
@@ -24779,6 +24925,12 @@ Object.freeze({
24779
24925
  addonId: null,
24780
24926
  access: "view"
24781
24927
  },
24928
+ "pipelineAnalytics.getKeyEvents": {
24929
+ capName: "pipeline-analytics",
24930
+ capScope: "device",
24931
+ addonId: null,
24932
+ access: "view"
24933
+ },
24782
24934
  "pipelineAnalytics.getMotionEvents": {
24783
24935
  capName: "pipeline-analytics",
24784
24936
  capScope: "device",
@@ -25307,6 +25459,12 @@ Object.freeze({
25307
25459
  addonId: null,
25308
25460
  access: "view"
25309
25461
  },
25462
+ "pipelineRunner.getNativeCrop": {
25463
+ capName: "pipeline-runner",
25464
+ capScope: "system",
25465
+ addonId: null,
25466
+ access: "view"
25467
+ },
25310
25468
  "pipelineRunner.reportMotion": {
25311
25469
  capName: "pipeline-runner",
25312
25470
  capScope: "system",
@@ -25673,6 +25831,12 @@ Object.freeze({
25673
25831
  addonId: null,
25674
25832
  access: "view"
25675
25833
  },
25834
+ "snapshot.getSnapshotOverview": {
25835
+ capName: "snapshot",
25836
+ capScope: "device",
25837
+ addonId: null,
25838
+ access: "view"
25839
+ },
25676
25840
  "snapshot.invalidateCache": {
25677
25841
  capName: "snapshot",
25678
25842
  capScope: "device",
@@ -26351,6 +26515,12 @@ Object.freeze({
26351
26515
  addonId: null,
26352
26516
  access: "view"
26353
26517
  },
26518
+ "userPasskeys.beginDiscoverableAuthentication": {
26519
+ capName: "user-passkeys",
26520
+ capScope: "system",
26521
+ addonId: null,
26522
+ access: "view"
26523
+ },
26354
26524
  "userPasskeys.beginRegistration": {
26355
26525
  capName: "user-passkeys",
26356
26526
  capScope: "system",
@@ -26363,12 +26533,24 @@ Object.freeze({
26363
26533
  addonId: null,
26364
26534
  access: "view"
26365
26535
  },
26536
+ "userPasskeys.finishDiscoverableAuthentication": {
26537
+ capName: "user-passkeys",
26538
+ capScope: "system",
26539
+ addonId: null,
26540
+ access: "view"
26541
+ },
26366
26542
  "userPasskeys.finishRegistration": {
26367
26543
  capName: "user-passkeys",
26368
26544
  capScope: "system",
26369
26545
  addonId: null,
26370
26546
  access: "create"
26371
26547
  },
26548
+ "userPasskeys.getSecondFactorPreference": {
26549
+ capName: "user-passkeys",
26550
+ capScope: "system",
26551
+ addonId: null,
26552
+ access: "view"
26553
+ },
26372
26554
  "userPasskeys.listPasskeys": {
26373
26555
  capName: "user-passkeys",
26374
26556
  capScope: "system",
@@ -26381,6 +26563,12 @@ Object.freeze({
26381
26563
  addonId: null,
26382
26564
  access: "delete"
26383
26565
  },
26566
+ "userPasskeys.setSecondFactorPreference": {
26567
+ capName: "user-passkeys",
26568
+ capScope: "system",
26569
+ addonId: null,
26570
+ access: "create"
26571
+ },
26384
26572
  "vacuumControl.locate": {
26385
26573
  capName: "vacuum-control",
26386
26574
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-reolink",
3
- "version": "1.1.22",
3
+ "version": "1.1.23",
4
4
  "description": "Reolink camera device provider addon for CamStack — native Baichuan protocol",
5
5
  "keywords": [
6
6
  "camstack",