@camstack/addon-tailscale-ingress 0.1.5 → 0.1.6

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.
@@ -4621,7 +4621,7 @@ function _instanceof(cls, params = {}) {
4621
4621
  return inst;
4622
4622
  }
4623
4623
  //#endregion
4624
- //#region ../types/dist/index-CWhQOnm9.mjs
4624
+ //#region ../types/dist/index-CgPd35k5.mjs
4625
4625
  var MODEL_FORMATS = [
4626
4626
  "onnx",
4627
4627
  "coreml",
@@ -4696,6 +4696,12 @@ Object.fromEntries([
4696
4696
  icon: "video",
4697
4697
  order: 35
4698
4698
  },
4699
+ {
4700
+ id: "ptz",
4701
+ label: "PTZ",
4702
+ icon: "move",
4703
+ order: 40
4704
+ },
4699
4705
  {
4700
4706
  id: "pipeline",
4701
4707
  label: "Detection Pipeline",
@@ -4809,6 +4815,10 @@ function hydrateField(field, values) {
4809
4815
  };
4810
4816
  }
4811
4817
  const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
4818
+ if (field.type === "password") return {
4819
+ ...field,
4820
+ value: ""
4821
+ };
4812
4822
  const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
4813
4823
  return {
4814
4824
  ...field,
@@ -4887,7 +4897,19 @@ var DecoderSessionConfigSchema = object({
4887
4897
  * on every line so `grep tag=broker:5/high` filters one camera
4888
4898
  * profile cleanly.
4889
4899
  */
4890
- tag: string().optional()
4900
+ tag: string().optional(),
4901
+ /**
4902
+ * Where the session delivers decoded frames (Phase 5 / D9):
4903
+ *
4904
+ * - `'callback'` (default) — the legacy pixel path: decoded frames are
4905
+ * buffered as `DecodedFrame`s and drained via `pullFrames`.
4906
+ * - `'shm'` — the shared-memory frame plane: decoded frames are written
4907
+ * into an OS shared-memory ring and drained as zero-pixel
4908
+ * `FrameHandle`s via `pullHandles`. A session is one mode or the
4909
+ * other — `pullFrames` returns nothing for an `'shm'` session and
4910
+ * `pullHandles` returns nothing for a `'callback'` session.
4911
+ */
4912
+ frameSink: _enum(["callback", "shm"]).default("callback")
4891
4913
  });
4892
4914
  var YAMNET_TO_MACRO = {
4893
4915
  mapping: {
@@ -5540,6 +5562,63 @@ var DecodedFrameSchema = object({
5540
5562
  ]),
5541
5563
  timestamp: number()
5542
5564
  });
5565
+ var FrameHandleSchema = object({
5566
+ shmId: string(),
5567
+ slot: number().int().nonnegative(),
5568
+ seq: number().int().nonnegative(),
5569
+ width: number().int().positive(),
5570
+ height: number().int().positive(),
5571
+ format: _enum([
5572
+ "jpeg",
5573
+ "rgb",
5574
+ "bgr",
5575
+ "yuv420",
5576
+ "gray"
5577
+ ]),
5578
+ pts: number(),
5579
+ byteLength: number().int().nonnegative(),
5580
+ nodeId: string(),
5581
+ slotCount: number().int().positive()
5582
+ });
5583
+ var FrameHandleFormatSchema = _enum([
5584
+ "rgb",
5585
+ "bgr",
5586
+ "yuv420",
5587
+ "gray"
5588
+ ]);
5589
+ var SubscribeFramesInputSchema = object({
5590
+ brokerId: string(),
5591
+ format: FrameHandleFormatSchema,
5592
+ /**
5593
+ * Optional reader-side cadence hint in frames per second. The broker does
5594
+ * NOT throttle — latest-wins ring reads drop frames implicitly for a slow
5595
+ * consumer. The value is echoed back in `SubscribeFramesResult.maxFps` so
5596
+ * the consumer can pace its own `pullFrameHandles` polling.
5597
+ */
5598
+ maxFps: number().positive().optional(),
5599
+ /** Short caller-identity tag (`motion`, `detection`, …) for diagnostics. */
5600
+ tag: string().optional()
5601
+ });
5602
+ var SubscribeFramesResultSchema = object({
5603
+ /** Opaque id the consumer passes to `pullFrameHandles` / `unsubscribeFrames`. */
5604
+ subscriptionId: string(),
5605
+ /** Reader-side cadence hint (frames/s) — echoes `SubscribeFramesInput.maxFps`. */
5606
+ maxFps: number().nonnegative()
5607
+ });
5608
+ var DecodedAudioChunkSchema = object({
5609
+ data: _instanceof(Uint8Array),
5610
+ sampleRate: number().int().positive(),
5611
+ channels: number().int().positive(),
5612
+ timestamp: number()
5613
+ });
5614
+ var SubscribeAudioChunksInputSchema = object({
5615
+ brokerId: string(),
5616
+ /** Short caller-identity tag (`audio-analyzer`, …) for `listClients`. */
5617
+ tag: string().optional()
5618
+ });
5619
+ var SubscribeAudioChunksResultSchema = object({
5620
+ /** Opaque id passed to `pullAudioChunks` / `unsubscribeAudioChunks`. */
5621
+ subscriptionId: string() });
5543
5622
  var BrokerStatsSchema = object({
5544
5623
  status: _enum([
5545
5624
  "idle",
@@ -5741,7 +5820,13 @@ method(object({
5741
5820
  }), {
5742
5821
  kind: "mutation",
5743
5822
  auth: "admin"
5744
- }), method(object({ brokerId: string() }), custom()), method(object({
5823
+ }), method(SubscribeAudioChunksInputSchema, SubscribeAudioChunksResultSchema, { kind: "mutation" }), method(object({
5824
+ subscriptionId: string(),
5825
+ maxCount: number().int().positive().default(8)
5826
+ }), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(SubscribeFramesInputSchema, SubscribeFramesResultSchema, { kind: "mutation" }), method(object({
5827
+ subscriptionId: string(),
5828
+ maxCount: number().int().positive().default(4)
5829
+ }), array(FrameHandleSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
5745
5830
  brokerId: string(),
5746
5831
  seconds: number().min(0).max(30)
5747
5832
  }), _void(), {
@@ -6433,6 +6518,34 @@ DeviceType.Light, DeviceType.Siren, DeviceType.Switch, method(object({
6433
6518
  enabled: boolean(),
6434
6519
  lastChangedAt: number()
6435
6520
  });
6521
+ object({
6522
+ enabled: boolean(),
6523
+ sensitivity: number(),
6524
+ /** Row-major active-cell grid. Length = gridWidth*gridHeight (see getOptions). */
6525
+ cells: array(boolean()),
6526
+ lastFetchedAt: number()
6527
+ });
6528
+ var MotionZoneOptionsSchema = object({
6529
+ gridWidth: number(),
6530
+ gridHeight: number(),
6531
+ sensitivity: object({
6532
+ min: number(),
6533
+ max: number(),
6534
+ step: number()
6535
+ })
6536
+ });
6537
+ var MotionZonePatchSchema = object({
6538
+ enabled: boolean().optional(),
6539
+ sensitivity: number().optional(),
6540
+ cells: array(boolean()).optional()
6541
+ });
6542
+ DeviceType.Camera, method(object({ deviceId: number() }), MotionZoneOptionsSchema), method(object({
6543
+ deviceId: number(),
6544
+ patch: MotionZonePatchSchema
6545
+ }), _void(), {
6546
+ kind: "mutation",
6547
+ auth: "admin"
6548
+ });
6436
6549
  var PtzAutotrackSettingsSchema = object({
6437
6550
  targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
6438
6551
  stopDelaySeconds: number().int().min(0).max(300),
@@ -6474,6 +6587,85 @@ DeviceType.Camera, method(object({ deviceId: number() }), PtzAutotrackStatusSche
6474
6587
  deviceId: number(),
6475
6588
  status: PtzAutotrackStatusSchema
6476
6589
  });
6590
+ var StreamProfileSchema = _enum([
6591
+ "main",
6592
+ "sub",
6593
+ "ext"
6594
+ ]);
6595
+ var StreamProfileConfigSchema = object({
6596
+ width: number(),
6597
+ height: number(),
6598
+ codec: _enum(["h264", "h265"]),
6599
+ framerate: number(),
6600
+ bitrate: number(),
6601
+ bitrateMode: _enum(["vbr", "cbr"]).optional(),
6602
+ encoderProfile: _enum([
6603
+ "high",
6604
+ "main",
6605
+ "baseline"
6606
+ ]).optional(),
6607
+ gop: number().optional(),
6608
+ audio: boolean().optional()
6609
+ });
6610
+ object({
6611
+ /** Per-profile current config. A profile absent = the camera doesn't have it. */
6612
+ main: StreamProfileConfigSchema.optional(),
6613
+ sub: StreamProfileConfigSchema.optional(),
6614
+ ext: StreamProfileConfigSchema.optional(),
6615
+ lastFetchedAt: number()
6616
+ });
6617
+ var StreamProfileOptionsSchema = object({
6618
+ resolutions: array(object({
6619
+ width: number(),
6620
+ height: number()
6621
+ })),
6622
+ codecs: array(_enum(["h264", "h265"])),
6623
+ framerates: array(number()),
6624
+ /** Allowed bitrate values (kbps). Empty if the camera takes a free range. */
6625
+ bitrates: array(number()),
6626
+ /** Optional [min,max] kbps when the camera accepts a continuous range. */
6627
+ bitrateRange: tuple([number(), number()]).optional(),
6628
+ supportsBitrateMode: boolean(),
6629
+ supportsEncoderProfile: boolean(),
6630
+ supportsGop: boolean(),
6631
+ /** Allowed GOP / keyframe-interval range, in seconds — drives the
6632
+ * I-frame-interval selector. Absent when the camera advertises GOP
6633
+ * support but no concrete range (callers then fall back to a free
6634
+ * numeric input). `{ min, max, step }` per the getOptions convention. */
6635
+ gop: object({
6636
+ min: number(),
6637
+ max: number(),
6638
+ step: number()
6639
+ }).optional()
6640
+ });
6641
+ var StreamParamsOptionsSchema = object({
6642
+ main: StreamProfileOptionsSchema.optional(),
6643
+ sub: StreamProfileOptionsSchema.optional(),
6644
+ ext: StreamProfileOptionsSchema.optional()
6645
+ });
6646
+ var StreamProfilePatchSchema = object({
6647
+ width: number().optional(),
6648
+ height: number().optional(),
6649
+ codec: _enum(["h264", "h265"]).optional(),
6650
+ framerate: number().optional(),
6651
+ bitrate: number().optional(),
6652
+ bitrateMode: _enum(["vbr", "cbr"]).optional(),
6653
+ encoderProfile: _enum([
6654
+ "high",
6655
+ "main",
6656
+ "baseline"
6657
+ ]).optional(),
6658
+ gop: number().optional(),
6659
+ audio: boolean().optional()
6660
+ });
6661
+ DeviceType.Camera, method(object({ deviceId: number() }), StreamParamsOptionsSchema), method(object({
6662
+ deviceId: number(),
6663
+ profile: StreamProfileSchema,
6664
+ patch: StreamProfilePatchSchema
6665
+ }), _void(), {
6666
+ kind: "mutation",
6667
+ auth: "admin"
6668
+ }), method(object({ deviceId: number() }), unknown().nullable());
6477
6669
  object({
6478
6670
  on: boolean(),
6479
6671
  /** Ms epoch of the last state change. Useful for UI "X minutes ago". */
@@ -7113,6 +7305,85 @@ method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
7113
7305
  var StaticDirOutputSchema = object({ staticDir: string() });
7114
7306
  var VersionOutputSchema = object({ version: string() });
7115
7307
  method(_void(), StaticDirOutputSchema), method(_void(), VersionOutputSchema);
7308
+ var MethodAccessSchema = _enum([
7309
+ "view",
7310
+ "create",
7311
+ "delete"
7312
+ ]);
7313
+ var AllowedProviderSchema = union([literal("*"), array(string())]);
7314
+ var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
7315
+ var CapScopeSchema = _enum(["device", "system"]);
7316
+ var TokenScopeSchema = discriminatedUnion("type", [
7317
+ object({
7318
+ type: literal("category"),
7319
+ target: CapScopeSchema,
7320
+ access: array(MethodAccessSchema).min(1)
7321
+ }),
7322
+ object({
7323
+ type: literal("capability"),
7324
+ target: string(),
7325
+ access: array(MethodAccessSchema).min(1)
7326
+ }),
7327
+ object({
7328
+ type: literal("addon"),
7329
+ target: string(),
7330
+ access: array(MethodAccessSchema).min(1)
7331
+ }),
7332
+ object({
7333
+ type: literal("device"),
7334
+ /**
7335
+ * One or more deviceIds (serialised as strings for wire-format
7336
+ * consistency with the rest of the union). Matcher accepts if
7337
+ * `input.deviceId` ∈ `targets`. Array shape avoids the row-explosion
7338
+ * of one scope-per-device when granting access to a set of cameras.
7339
+ */
7340
+ targets: array(string()).min(1),
7341
+ access: array(MethodAccessSchema).min(1)
7342
+ })
7343
+ ]);
7344
+ object({
7345
+ id: string(),
7346
+ username: string(),
7347
+ passwordHash: string(),
7348
+ /**
7349
+ * Admin bypass. When true, the middleware skips the scope-access
7350
+ * check entirely. There is no other axis of privilege; the legacy
7351
+ * role enum collapsed onto this boolean in v2.
7352
+ */
7353
+ isAdmin: boolean().default(false),
7354
+ allowedProviders: AllowedProviderSchema,
7355
+ allowedDevices: AllowedDevicesSchema,
7356
+ /**
7357
+ * Scopes granted to this user. Admins bypass; their `scopes` is
7358
+ * ignored. Non-admins without scopes are locked out of every
7359
+ * protected call.
7360
+ */
7361
+ scopes: array(TokenScopeSchema).default([]),
7362
+ createdAt: number(),
7363
+ updatedAt: number()
7364
+ });
7365
+ object({
7366
+ id: string(),
7367
+ label: string(),
7368
+ isAdmin: boolean().default(false),
7369
+ allowedProviders: AllowedProviderSchema,
7370
+ allowedDevices: AllowedDevicesSchema,
7371
+ tokenHash: string(),
7372
+ tokenPrefix: string(),
7373
+ createdAt: number(),
7374
+ lastUsedAt: number().optional()
7375
+ });
7376
+ object({
7377
+ id: string(),
7378
+ userId: string(),
7379
+ name: string(),
7380
+ tokenHash: string(),
7381
+ tokenPrefix: string(),
7382
+ scopes: array(TokenScopeSchema),
7383
+ expiresAt: number().nullish(),
7384
+ lastUsedAt: number().nullish(),
7385
+ createdAt: number()
7386
+ });
7116
7387
  var SsoBridgeClaimsSchema = object({
7117
7388
  userId: string(),
7118
7389
  username: string(),
@@ -7128,12 +7399,36 @@ var SsoBridgeClaimsSchema = object({
7128
7399
  * JWT WITHOUT verifying the signature — the hub re-verifies on every
7129
7400
  * inbound call so trust still rests with the signing hub.
7130
7401
  */
7131
- hubUrl: string().optional()
7402
+ hubUrl: string().optional(),
7403
+ /** Permission scopes baked into the token. Set by the OAuth
7404
+ * account-linking grant; absent on ordinary SSO-login tokens. */
7405
+ scopes: array(TokenScopeSchema).optional(),
7406
+ /** OAuth authorization-code binding — set only on `oauth-code` tokens. */
7407
+ redirectUri: string().optional(),
7408
+ integrationId: string().optional(),
7409
+ /** JWT ID — unique per issued code; consumed-set enforces single-use. */
7410
+ jti: string().optional(),
7411
+ /** OAuth session registry id — set on `oauth-access`/`oauth-refresh`
7412
+ * tokens so the verify path can check the session is not revoked. */
7413
+ sessionId: string().optional()
7132
7414
  });
7133
7415
  method(object({
7134
7416
  claims: SsoBridgeClaimsSchema,
7135
7417
  ttlSec: number().int().positive().optional()
7136
7418
  }), object({ token: string() })), method(object({ token: string() }), SsoBridgeClaimsSchema.nullable());
7419
+ var OauthIntegrationDescriptorSchema = object({
7420
+ /** Stable id used as the `integration=` query param, e.g. 'export-alexa'. */
7421
+ integrationId: string(),
7422
+ /** Human label rendered on the consent page. */
7423
+ displayName: string(),
7424
+ /** Scopes baked into every token issued for this integration. */
7425
+ requestedScopes: array(TokenScopeSchema),
7426
+ /** Allowed redirect_uri prefixes. /api/oauth2/authorize rejects any
7427
+ * redirect_uri that does not start with one of these. Required —
7428
+ * an empty list means the integration can never complete linking. */
7429
+ allowedRedirectPrefixes: array(string()).min(1)
7430
+ });
7431
+ method(_void(), OauthIntegrationDescriptorSchema);
7137
7432
  var PasskeySummarySchema = object({
7138
7433
  credentialId: string(),
7139
7434
  label: string(),
@@ -7379,22 +7674,29 @@ var WidgetSizeEnum = _enum([
7379
7674
  "lg",
7380
7675
  "xl"
7381
7676
  ]);
7677
+ var WidgetRemoteSchema = object({
7678
+ remoteName: string(),
7679
+ exposedModule: string(),
7680
+ componentKey: string().optional()
7681
+ });
7382
7682
  var WidgetMetadataSchema = object({
7383
- /** Stable id within the addon kebab-case. */
7384
- stableId: string(),
7683
+ /** Primary host tab `'dashboard'`, `'device-tab'`, or a device-detail tab id. */
7684
+ tab: string(),
7685
+ /** Optional sub-tab within `tab`. */
7686
+ subTab: string().optional(),
7385
7687
  /** Operator-facing label. */
7386
7688
  label: string(),
7689
+ /** Ordering within `(tab, subTab)`, ascending. */
7690
+ order: number().optional(),
7691
+ /** Always `'remote'` — a widget is a Module Federation remote. */
7692
+ kind: literal("remote"),
7693
+ /** MF remote descriptor. */
7694
+ remote: WidgetRemoteSchema,
7695
+ /** Stable id within the addon — kebab-case. Equals `remote.componentKey`. */
7696
+ stableId: string(),
7387
7697
  description: string().optional(),
7388
7698
  icon: string().optional(),
7389
7699
  /**
7390
- * Module Federation remote name — must match the `name` field on the
7391
- * widget addon's `federation()` plugin config. Used by the host's
7392
- * `<WidgetRegistryProvider>` to call `loadRemote('<remoteName>/widgets')`.
7393
- * Conventionally `addon_<addonid>_widgets` (snake_case; MF names
7394
- * cannot contain hyphens).
7395
- */
7396
- remoteName: string(),
7397
- /**
7398
7700
  * Bundle filename inside the addon's `dist/` dir served at
7399
7701
  * `/api/addon-widgets/<addonId>/<bundle>`. With Module Federation
7400
7702
  * this is always `'remoteEntry.js'` — the value is kept on the
@@ -7402,9 +7704,9 @@ var WidgetMetadataSchema = object({
7402
7704
  * cache-buster URL without a separate filesystem stat.
7403
7705
  */
7404
7706
  bundle: string(),
7405
- /** Where the widget makes sense to render. */
7707
+ /** Every host the widget supports. The picker filters on this set. */
7406
7708
  hosts: array(WidgetHostEnum).readonly(),
7407
- /** Required props the host must supply. Validated at <WidgetSlot> mount. */
7709
+ /** Required props the host must supply. Validated at `<WidgetSlot>` mount. */
7408
7710
  requires: object({
7409
7711
  deviceContext: boolean().default(false),
7410
7712
  integrationContext: boolean().default(false)
@@ -7468,6 +7770,16 @@ var InvokeReplyEnvelopeSchema = object({
7468
7770
  contentType: string().optional()
7469
7771
  });
7470
7772
  method(_void(), array(AddonHttpRouteSchema)), method(InvokeRequestSchema, InvokeReplyEnvelopeSchema, { kind: "mutation" });
7773
+ var ShmRingStatsSchema = object({
7774
+ sessionId: string(),
7775
+ slotCount: number().int(),
7776
+ slotByteLength: number().int(),
7777
+ segmentBytes: number().int(),
7778
+ budgetMb: number().int(),
7779
+ framesWritten: number().int(),
7780
+ getFrameHits: number().int(),
7781
+ getFrameMisses: number().int()
7782
+ });
7471
7783
  method(object({ codec: string() }), boolean()), method(_void(), object({
7472
7784
  id: string(),
7473
7785
  name: string(),
@@ -7486,6 +7798,9 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
7486
7798
  sessionId: string(),
7487
7799
  maxCount: number().default(1)
7488
7800
  }), array(DecodedFrameSchema)), method(object({
7801
+ sessionId: string(),
7802
+ maxCount: number().default(1)
7803
+ }), array(FrameHandleSchema)), method(object({ handle: FrameHandleSchema }), DecodedFrameSchema.nullable()), method(object({ sessionId: string() }), ShmRingStatsSchema.nullable()), method(object({
7489
7804
  sessionId: string(),
7490
7805
  config: DecoderSessionConfigSchema.partial()
7491
7806
  }), _void()), method(object({ sessionId: string() }), DecoderStatsSchema), method(_void(), array(object({
@@ -8881,10 +9196,38 @@ var PtzMoveCommandSchema = object({
8881
9196
  zoom: number().optional(),
8882
9197
  speed: number().optional()
8883
9198
  });
9199
+ PtzPositionSchema.extend({ autofocus: boolean() });
9200
+ var PtzOptionsSchema = object({
9201
+ hasPan: boolean(),
9202
+ hasTilt: boolean(),
9203
+ hasZoom: boolean(),
9204
+ supportsPresets: boolean(),
9205
+ /** Max number of named presets the camera supports, when known. */
9206
+ maxPresets: number().optional(),
9207
+ /** Whether the camera exposes a controllable autofocus toggle
9208
+ * (boolean `hasX` per the getOptions availability convention). */
9209
+ hasAutofocus: boolean()
9210
+ });
8884
9211
  DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(PtzMoveCommandSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(PtzPresetSchema)), method(object({
8885
9212
  deviceId: number(),
8886
9213
  presetId: string()
8887
- }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), PtzPositionSchema);
9214
+ }), _void(), { kind: "mutation" }), method(object({
9215
+ deviceId: number(),
9216
+ presetId: string(),
9217
+ name: string()
9218
+ }), _void(), {
9219
+ kind: "mutation",
9220
+ auth: "admin"
9221
+ }), method(object({
9222
+ deviceId: number(),
9223
+ presetId: string()
9224
+ }), _void(), {
9225
+ kind: "mutation",
9226
+ auth: "admin"
9227
+ }), method(object({ deviceId: number() }), PtzOptionsSchema), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), PtzPositionSchema), method(object({
9228
+ deviceId: number(),
9229
+ enabled: boolean()
9230
+ }), _void(), { kind: "mutation" });
8888
9231
  var EventItemSchema = object({
8889
9232
  id: string(),
8890
9233
  type: string(),
@@ -9524,85 +9867,6 @@ authKey: string().optional() }), object({
9524
9867
  /** Human-readable error when `ok: false`. */
9525
9868
  error: string().optional()
9526
9869
  }), { kind: "mutation" });
9527
- var MethodAccessSchema = _enum([
9528
- "view",
9529
- "create",
9530
- "delete"
9531
- ]);
9532
- var AllowedProviderSchema = union([literal("*"), array(string())]);
9533
- var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
9534
- var CapScopeSchema = _enum(["device", "system"]);
9535
- var TokenScopeSchema = discriminatedUnion("type", [
9536
- object({
9537
- type: literal("category"),
9538
- target: CapScopeSchema,
9539
- access: array(MethodAccessSchema).min(1)
9540
- }),
9541
- object({
9542
- type: literal("capability"),
9543
- target: string(),
9544
- access: array(MethodAccessSchema).min(1)
9545
- }),
9546
- object({
9547
- type: literal("addon"),
9548
- target: string(),
9549
- access: array(MethodAccessSchema).min(1)
9550
- }),
9551
- object({
9552
- type: literal("device"),
9553
- /**
9554
- * One or more deviceIds (serialised as strings for wire-format
9555
- * consistency with the rest of the union). Matcher accepts if
9556
- * `input.deviceId` ∈ `targets`. Array shape avoids the row-explosion
9557
- * of one scope-per-device when granting access to a set of cameras.
9558
- */
9559
- targets: array(string()).min(1),
9560
- access: array(MethodAccessSchema).min(1)
9561
- })
9562
- ]);
9563
- object({
9564
- id: string(),
9565
- username: string(),
9566
- passwordHash: string(),
9567
- /**
9568
- * Admin bypass. When true, the middleware skips the scope-access
9569
- * check entirely. There is no other axis of privilege; the legacy
9570
- * role enum collapsed onto this boolean in v2.
9571
- */
9572
- isAdmin: boolean().default(false),
9573
- allowedProviders: AllowedProviderSchema,
9574
- allowedDevices: AllowedDevicesSchema,
9575
- /**
9576
- * Scopes granted to this user. Admins bypass; their `scopes` is
9577
- * ignored. Non-admins without scopes are locked out of every
9578
- * protected call.
9579
- */
9580
- scopes: array(TokenScopeSchema).default([]),
9581
- createdAt: number(),
9582
- updatedAt: number()
9583
- });
9584
- object({
9585
- id: string(),
9586
- label: string(),
9587
- isAdmin: boolean().default(false),
9588
- allowedProviders: AllowedProviderSchema,
9589
- allowedDevices: AllowedDevicesSchema,
9590
- tokenHash: string(),
9591
- tokenPrefix: string(),
9592
- createdAt: number(),
9593
- lastUsedAt: number().optional()
9594
- });
9595
- object({
9596
- id: string(),
9597
- userId: string(),
9598
- name: string(),
9599
- tokenHash: string(),
9600
- tokenPrefix: string(),
9601
- scopes: array(TokenScopeSchema),
9602
- expiresAt: number().nullish(),
9603
- lastUsedAt: number().nullish(),
9604
- createdAt: number()
9605
- });
9606
9870
  var UserSummarySchema = object({
9607
9871
  id: string(),
9608
9872
  username: string(),
@@ -9675,6 +9939,16 @@ var CreateScopedTokenResultSchema = object({
9675
9939
  token: string(),
9676
9940
  record: ScopedTokenSummarySchema
9677
9941
  });
9942
+ var OauthSessionSummarySchema = object({
9943
+ id: string(),
9944
+ userId: string(),
9945
+ username: string(),
9946
+ integrationId: string(),
9947
+ scopes: array(TokenScopeSchema),
9948
+ createdAt: number(),
9949
+ lastUsedAt: number(),
9950
+ revokedAt: number().nullable()
9951
+ });
9678
9952
  var TotpSetupResultSchema = object({
9679
9953
  secret: string(),
9680
9954
  otpauthUrl: string()
@@ -9757,6 +10031,41 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
9757
10031
  }), object({ valid: boolean() }), {
9758
10032
  kind: "mutation",
9759
10033
  access: "view"
10034
+ }), method(object({
10035
+ integrationId: string(),
10036
+ userId: string(),
10037
+ username: string(),
10038
+ scopes: array(TokenScopeSchema),
10039
+ redirectUri: string(),
10040
+ hubUrl: string()
10041
+ }), object({ code: string() }), {
10042
+ kind: "mutation",
10043
+ access: "create"
10044
+ }), method(object({
10045
+ code: string(),
10046
+ redirectUri: string()
10047
+ }), object({
10048
+ accessToken: string(),
10049
+ refreshToken: string(),
10050
+ expiresIn: number()
10051
+ }).nullable(), {
10052
+ kind: "mutation",
10053
+ access: "view"
10054
+ }), method(object({ refreshToken: string() }), object({
10055
+ accessToken: string(),
10056
+ refreshToken: string(),
10057
+ expiresIn: number()
10058
+ }).nullable(), {
10059
+ kind: "mutation",
10060
+ access: "view"
10061
+ }), method(object({ token: string() }), object({
10062
+ userId: string(),
10063
+ username: string(),
10064
+ scopes: array(TokenScopeSchema)
10065
+ }).nullable(), { access: "view" }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
10066
+ kind: "mutation",
10067
+ auth: "admin",
10068
+ access: "delete"
9760
10069
  });
9761
10070
  var FeatureManifestSchema = object({
9762
10071
  streaming: boolean(),
@@ -9925,7 +10234,13 @@ method(_void(), array(TopologyNodeSchema).readonly(), { auth: "admin" }), method
9925
10234
  }), RenameNodeResultSchema, {
9926
10235
  kind: "mutation",
9927
10236
  auth: "admin"
9928
- }), method(_void(), record(string(), ClusterAddonStatusEntrySchema), { auth: "admin" }), method(object({ nodeId: string() }), array(NodeAddonEntrySchema).readonly(), { auth: "admin" }), method(object({
10237
+ }), method(_void(), record(string(), ClusterAddonStatusEntrySchema), { auth: "admin" }), method(object({ windowSeconds: number().int().positive().max(300).default(60) }), array(object({
10238
+ callerAddonId: string(),
10239
+ providerAddonId: string(),
10240
+ capName: string(),
10241
+ callsPerMin: number(),
10242
+ lastCallAtMs: number()
10243
+ })).readonly(), { auth: "admin" }), method(object({ nodeId: string() }), array(NodeAddonEntrySchema).readonly(), { auth: "admin" }), method(object({
9929
10244
  nodeId: string(),
9930
10245
  level: string()
9931
10246
  }), SuccessSchema, {
@@ -11289,12 +11604,24 @@ Object.freeze({
11289
11604
  addonId: null,
11290
11605
  access: "delete"
11291
11606
  },
11607
+ "decoder.getFrame": {
11608
+ capName: "decoder",
11609
+ capScope: "system",
11610
+ addonId: null,
11611
+ access: "view"
11612
+ },
11292
11613
  "decoder.getInfo": {
11293
11614
  capName: "decoder",
11294
11615
  capScope: "system",
11295
11616
  addonId: null,
11296
11617
  access: "view"
11297
11618
  },
11619
+ "decoder.getShmStats": {
11620
+ capName: "decoder",
11621
+ capScope: "system",
11622
+ addonId: null,
11623
+ access: "view"
11624
+ },
11298
11625
  "decoder.getStats": {
11299
11626
  capName: "decoder",
11300
11627
  capScope: "system",
@@ -11319,6 +11646,12 @@ Object.freeze({
11319
11646
  addonId: null,
11320
11647
  access: "view"
11321
11648
  },
11649
+ "decoder.pullHandles": {
11650
+ capName: "decoder",
11651
+ capScope: "system",
11652
+ addonId: null,
11653
+ access: "view"
11654
+ },
11322
11655
  "decoder.pushPacket": {
11323
11656
  capName: "decoder",
11324
11657
  capScope: "system",
@@ -12105,6 +12438,18 @@ Object.freeze({
12105
12438
  addonId: null,
12106
12439
  access: "create"
12107
12440
  },
12441
+ "motionZones.getOptions": {
12442
+ capName: "motion-zones",
12443
+ capScope: "device",
12444
+ addonId: null,
12445
+ access: "view"
12446
+ },
12447
+ "motionZones.setZone": {
12448
+ capName: "motion-zones",
12449
+ capScope: "device",
12450
+ addonId: null,
12451
+ access: "create"
12452
+ },
12108
12453
  "mqttBroker.addBroker": {
12109
12454
  capName: "mqtt-broker",
12110
12455
  capScope: "system",
@@ -12219,6 +12564,12 @@ Object.freeze({
12219
12564
  addonId: null,
12220
12565
  access: "create"
12221
12566
  },
12567
+ "nodes.getCapUsageGraph": {
12568
+ capName: "nodes",
12569
+ capScope: "system",
12570
+ addonId: null,
12571
+ access: "view"
12572
+ },
12222
12573
  "nodes.getNodeAddons": {
12223
12574
  capName: "nodes",
12224
12575
  capScope: "system",
@@ -12285,6 +12636,12 @@ Object.freeze({
12285
12636
  addonId: null,
12286
12637
  access: "create"
12287
12638
  },
12639
+ "oauthIntegration.getDescriptor": {
12640
+ capName: "oauth-integration",
12641
+ capScope: "system",
12642
+ addonId: null,
12643
+ access: "view"
12644
+ },
12288
12645
  "osd.setOverlay": {
12289
12646
  capName: "osd",
12290
12647
  capScope: "device",
@@ -12843,6 +13200,18 @@ Object.freeze({
12843
13200
  addonId: null,
12844
13201
  access: "create"
12845
13202
  },
13203
+ "ptz.deletePreset": {
13204
+ capName: "ptz",
13205
+ capScope: "device",
13206
+ addonId: null,
13207
+ access: "delete"
13208
+ },
13209
+ "ptz.getOptions": {
13210
+ capName: "ptz",
13211
+ capScope: "device",
13212
+ addonId: null,
13213
+ access: "view"
13214
+ },
12846
13215
  "ptz.getPosition": {
12847
13216
  capName: "ptz",
12848
13217
  capScope: "device",
@@ -12873,6 +13242,18 @@ Object.freeze({
12873
13242
  addonId: null,
12874
13243
  access: "create"
12875
13244
  },
13245
+ "ptz.savePreset": {
13246
+ capName: "ptz",
13247
+ capScope: "device",
13248
+ addonId: null,
13249
+ access: "create"
13250
+ },
13251
+ "ptz.setAutofocus": {
13252
+ capName: "ptz",
13253
+ capScope: "device",
13254
+ addonId: null,
13255
+ access: "create"
13256
+ },
12876
13257
  "ptz.stop": {
12877
13258
  capName: "ptz",
12878
13259
  capScope: "device",
@@ -13395,12 +13776,6 @@ Object.freeze({
13395
13776
  addonId: null,
13396
13777
  access: "view"
13397
13778
  },
13398
- "streamBroker.getBroker": {
13399
- capName: "stream-broker",
13400
- capScope: "system",
13401
- addonId: null,
13402
- access: "view"
13403
- },
13404
13779
  "streamBroker.getBrokerStats": {
13405
13780
  capName: "stream-broker",
13406
13781
  capScope: "system",
@@ -13473,6 +13848,18 @@ Object.freeze({
13473
13848
  addonId: null,
13474
13849
  access: "create"
13475
13850
  },
13851
+ "streamBroker.pullAudioChunks": {
13852
+ capName: "stream-broker",
13853
+ capScope: "system",
13854
+ addonId: null,
13855
+ access: "view"
13856
+ },
13857
+ "streamBroker.pullFrameHandles": {
13858
+ capName: "stream-broker",
13859
+ capScope: "system",
13860
+ addonId: null,
13861
+ access: "view"
13862
+ },
13476
13863
  "streamBroker.regenerateRtspToken": {
13477
13864
  capName: "stream-broker",
13478
13865
  capScope: "system",
@@ -13509,12 +13896,36 @@ Object.freeze({
13509
13896
  addonId: null,
13510
13897
  access: "create"
13511
13898
  },
13899
+ "streamBroker.subscribeAudioChunks": {
13900
+ capName: "stream-broker",
13901
+ capScope: "system",
13902
+ addonId: null,
13903
+ access: "create"
13904
+ },
13905
+ "streamBroker.subscribeFrames": {
13906
+ capName: "stream-broker",
13907
+ capScope: "system",
13908
+ addonId: null,
13909
+ access: "create"
13910
+ },
13512
13911
  "streamBroker.unassignProfile": {
13513
13912
  capName: "stream-broker",
13514
13913
  capScope: "system",
13515
13914
  addonId: null,
13516
13915
  access: "create"
13517
13916
  },
13917
+ "streamBroker.unsubscribeAudioChunks": {
13918
+ capName: "stream-broker",
13919
+ capScope: "system",
13920
+ addonId: null,
13921
+ access: "create"
13922
+ },
13923
+ "streamBroker.unsubscribeFrames": {
13924
+ capName: "stream-broker",
13925
+ capScope: "system",
13926
+ addonId: null,
13927
+ access: "create"
13928
+ },
13518
13929
  "streamingEngine.getStreamUrl": {
13519
13930
  capName: "streaming-engine",
13520
13931
  capScope: "system",
@@ -13539,6 +13950,24 @@ Object.freeze({
13539
13950
  addonId: null,
13540
13951
  access: "delete"
13541
13952
  },
13953
+ "streamParams.getConfigSchema": {
13954
+ capName: "stream-params",
13955
+ capScope: "device",
13956
+ addonId: null,
13957
+ access: "view"
13958
+ },
13959
+ "streamParams.getOptions": {
13960
+ capName: "stream-params",
13961
+ capScope: "device",
13962
+ addonId: null,
13963
+ access: "view"
13964
+ },
13965
+ "streamParams.setProfile": {
13966
+ capName: "stream-params",
13967
+ capScope: "device",
13968
+ addonId: null,
13969
+ access: "create"
13970
+ },
13542
13971
  "switch.setState": {
13543
13972
  capName: "switch",
13544
13973
  capScope: "device",
@@ -13647,6 +14076,12 @@ Object.freeze({
13647
14076
  addonId: null,
13648
14077
  access: "view"
13649
14078
  },
14079
+ "userManagement.listOauthSessions": {
14080
+ capName: "user-management",
14081
+ capScope: "system",
14082
+ addonId: null,
14083
+ access: "view"
14084
+ },
13650
14085
  "userManagement.listScopedTokens": {
13651
14086
  capName: "user-management",
13652
14087
  capScope: "system",
@@ -13659,6 +14094,30 @@ Object.freeze({
13659
14094
  addonId: null,
13660
14095
  access: "view"
13661
14096
  },
14097
+ "userManagement.oauthExchangeCode": {
14098
+ capName: "user-management",
14099
+ capScope: "system",
14100
+ addonId: null,
14101
+ access: "view"
14102
+ },
14103
+ "userManagement.oauthIssueCode": {
14104
+ capName: "user-management",
14105
+ capScope: "system",
14106
+ addonId: null,
14107
+ access: "create"
14108
+ },
14109
+ "userManagement.oauthRefresh": {
14110
+ capName: "user-management",
14111
+ capScope: "system",
14112
+ addonId: null,
14113
+ access: "view"
14114
+ },
14115
+ "userManagement.oauthVerifyAccessToken": {
14116
+ capName: "user-management",
14117
+ capScope: "system",
14118
+ addonId: null,
14119
+ access: "view"
14120
+ },
13662
14121
  "userManagement.resetPassword": {
13663
14122
  capName: "user-management",
13664
14123
  capScope: "system",
@@ -13671,6 +14130,12 @@ Object.freeze({
13671
14130
  addonId: null,
13672
14131
  access: "delete"
13673
14132
  },
14133
+ "userManagement.revokeOauthSession": {
14134
+ capName: "user-management",
14135
+ capScope: "system",
14136
+ addonId: null,
14137
+ access: "delete"
14138
+ },
13674
14139
  "userManagement.revokeScopedToken": {
13675
14140
  capName: "user-management",
13676
14141
  capScope: "system",