@camstack/core 0.1.37 → 0.1.39

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.
Files changed (82) hide show
  1. package/dist/auth/auth-manager.d.ts +12 -1
  2. package/dist/auth/auth-manager.d.ts.map +1 -1
  3. package/dist/auth/scope-matcher.d.ts +8 -0
  4. package/dist/auth/scope-matcher.d.ts.map +1 -0
  5. package/dist/auth/totp-manager.d.ts +0 -1
  6. package/dist/auth/totp-manager.d.ts.map +1 -1
  7. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.d.ts +15 -0
  8. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.d.ts.map +1 -1
  9. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +27 -6
  10. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js.map +1 -1
  11. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +27 -6
  12. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs.map +1 -1
  13. package/dist/builtins/device-manager/device-config-contribution.d.ts +33 -0
  14. package/dist/builtins/device-manager/device-config-contribution.d.ts.map +1 -0
  15. package/dist/builtins/device-manager/device-manager.addon.d.ts +52 -17
  16. package/dist/builtins/device-manager/device-manager.addon.d.ts.map +1 -1
  17. package/dist/builtins/device-manager/device-manager.addon.js +285 -161
  18. package/dist/builtins/device-manager/device-manager.addon.js.map +1 -1
  19. package/dist/builtins/device-manager/device-manager.addon.mjs +286 -162
  20. package/dist/builtins/device-manager/device-manager.addon.mjs.map +1 -1
  21. package/dist/builtins/local-auth/auth-schema.d.ts +1 -0
  22. package/dist/builtins/local-auth/auth-schema.d.ts.map +1 -1
  23. package/dist/builtins/local-auth/local-auth.addon.d.ts +1 -0
  24. package/dist/builtins/local-auth/local-auth.addon.d.ts.map +1 -1
  25. package/dist/builtins/local-auth/local-auth.addon.js +354 -3
  26. package/dist/builtins/local-auth/local-auth.addon.js.map +1 -1
  27. package/dist/builtins/local-auth/local-auth.addon.mjs +355 -3
  28. package/dist/builtins/local-auth/local-auth.addon.mjs.map +1 -1
  29. package/dist/builtins/local-auth/oauth-grants.d.ts +46 -0
  30. package/dist/builtins/local-auth/oauth-grants.d.ts.map +1 -0
  31. package/dist/builtins/local-auth/oauth-session-manager.d.ts +51 -0
  32. package/dist/builtins/local-auth/oauth-session-manager.d.ts.map +1 -0
  33. package/dist/builtins/remote-access-orchestrator/enabled-providers-reconcile.d.ts +97 -0
  34. package/dist/builtins/remote-access-orchestrator/enabled-providers-reconcile.d.ts.map +1 -0
  35. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.d.ts +24 -1
  36. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.d.ts.map +1 -1
  37. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +136 -56
  38. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js.map +1 -1
  39. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +137 -57
  40. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs.map +1 -1
  41. package/dist/builtins/snapshot/index.js +1 -3
  42. package/dist/builtins/snapshot/index.js.map +1 -1
  43. package/dist/builtins/snapshot/index.mjs +1 -3
  44. package/dist/builtins/snapshot/index.mjs.map +1 -1
  45. package/dist/builtins/snapshot/snapshot.addon.d.ts.map +1 -1
  46. package/dist/index.d.ts +1 -0
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +428 -234
  49. package/dist/index.js.map +1 -1
  50. package/dist/index.mjs +428 -235
  51. package/dist/index.mjs.map +1 -1
  52. package/package.json +19 -37
  53. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.d.ts +0 -8
  54. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.d.ts.map +0 -1
  55. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.js +0 -75
  56. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.js.map +0 -1
  57. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.mjs +0 -69
  58. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.mjs.map +0 -1
  59. package/dist/builtins/auth-orchestrator/index.d.ts +0 -2
  60. package/dist/builtins/auth-orchestrator/index.d.ts.map +0 -1
  61. package/dist/builtins/auth-orchestrator/index.js +0 -7
  62. package/dist/builtins/auth-orchestrator/index.mjs +0 -2
  63. package/dist/builtins/mesh-orchestrator/index.d.ts +0 -2
  64. package/dist/builtins/mesh-orchestrator/index.d.ts.map +0 -1
  65. package/dist/builtins/mesh-orchestrator/index.js +0 -7
  66. package/dist/builtins/mesh-orchestrator/index.mjs +0 -2
  67. package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.d.ts +0 -9
  68. package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.d.ts.map +0 -1
  69. package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.js +0 -113
  70. package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.js.map +0 -1
  71. package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.mjs +0 -107
  72. package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.mjs.map +0 -1
  73. package/dist/builtins/turn-orchestrator/index.d.ts +0 -2
  74. package/dist/builtins/turn-orchestrator/index.d.ts.map +0 -1
  75. package/dist/builtins/turn-orchestrator/index.js +0 -7
  76. package/dist/builtins/turn-orchestrator/index.mjs +0 -2
  77. package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.d.ts +0 -34
  78. package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.d.ts.map +0 -1
  79. package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.js +0 -126
  80. package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.js.map +0 -1
  81. package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.mjs +0 -120
  82. package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.mjs.map +0 -1
package/dist/index.js CHANGED
@@ -37,7 +37,7 @@ let node_vm = require("node:vm");
37
37
  node_vm = require_chunk.__toESM(node_vm);
38
38
  let node_os = require("node:os");
39
39
  node_os = require_chunk.__toESM(node_os);
40
- //#region ../types/dist/index-Ce7RZWP4.mjs
40
+ //#region ../types/dist/index-CgPd35k5.mjs
41
41
  var MODEL_FORMATS = [
42
42
  "onnx",
43
43
  "coreml",
@@ -112,6 +112,12 @@ Object.fromEntries([
112
112
  icon: "video",
113
113
  order: 35
114
114
  },
115
+ {
116
+ id: "ptz",
117
+ label: "PTZ",
118
+ icon: "move",
119
+ order: 40
120
+ },
115
121
  {
116
122
  id: "pipeline",
117
123
  label: "Detection Pipeline",
@@ -238,7 +244,19 @@ var DecoderSessionConfigSchema = zod.z.object({
238
244
  * on every line so `grep tag=broker:5/high` filters one camera
239
245
  * profile cleanly.
240
246
  */
241
- tag: zod.z.string().optional()
247
+ tag: zod.z.string().optional(),
248
+ /**
249
+ * Where the session delivers decoded frames (Phase 5 / D9):
250
+ *
251
+ * - `'callback'` (default) — the legacy pixel path: decoded frames are
252
+ * buffered as `DecodedFrame`s and drained via `pullFrames`.
253
+ * - `'shm'` — the shared-memory frame plane: decoded frames are written
254
+ * into an OS shared-memory ring and drained as zero-pixel
255
+ * `FrameHandle`s via `pullHandles`. A session is one mode or the
256
+ * other — `pullFrames` returns nothing for an `'shm'` session and
257
+ * `pullHandles` returns nothing for a `'callback'` session.
258
+ */
259
+ frameSink: zod.z.enum(["callback", "shm"]).default("callback")
242
260
  });
243
261
  function errMsg$2(err) {
244
262
  if (err instanceof Error) return err.message;
@@ -898,6 +916,63 @@ var DecodedFrameSchema = zod.z.object({
898
916
  ]),
899
917
  timestamp: zod.z.number()
900
918
  });
919
+ var FrameHandleSchema = zod.z.object({
920
+ shmId: zod.z.string(),
921
+ slot: zod.z.number().int().nonnegative(),
922
+ seq: zod.z.number().int().nonnegative(),
923
+ width: zod.z.number().int().positive(),
924
+ height: zod.z.number().int().positive(),
925
+ format: zod.z.enum([
926
+ "jpeg",
927
+ "rgb",
928
+ "bgr",
929
+ "yuv420",
930
+ "gray"
931
+ ]),
932
+ pts: zod.z.number(),
933
+ byteLength: zod.z.number().int().nonnegative(),
934
+ nodeId: zod.z.string(),
935
+ slotCount: zod.z.number().int().positive()
936
+ });
937
+ var FrameHandleFormatSchema = zod.z.enum([
938
+ "rgb",
939
+ "bgr",
940
+ "yuv420",
941
+ "gray"
942
+ ]);
943
+ var SubscribeFramesInputSchema = zod.z.object({
944
+ brokerId: zod.z.string(),
945
+ format: FrameHandleFormatSchema,
946
+ /**
947
+ * Optional reader-side cadence hint in frames per second. The broker does
948
+ * NOT throttle — latest-wins ring reads drop frames implicitly for a slow
949
+ * consumer. The value is echoed back in `SubscribeFramesResult.maxFps` so
950
+ * the consumer can pace its own `pullFrameHandles` polling.
951
+ */
952
+ maxFps: zod.z.number().positive().optional(),
953
+ /** Short caller-identity tag (`motion`, `detection`, …) for diagnostics. */
954
+ tag: zod.z.string().optional()
955
+ });
956
+ var SubscribeFramesResultSchema = zod.z.object({
957
+ /** Opaque id the consumer passes to `pullFrameHandles` / `unsubscribeFrames`. */
958
+ subscriptionId: zod.z.string(),
959
+ /** Reader-side cadence hint (frames/s) — echoes `SubscribeFramesInput.maxFps`. */
960
+ maxFps: zod.z.number().nonnegative()
961
+ });
962
+ var DecodedAudioChunkSchema = zod.z.object({
963
+ data: zod.z.instanceof(Uint8Array),
964
+ sampleRate: zod.z.number().int().positive(),
965
+ channels: zod.z.number().int().positive(),
966
+ timestamp: zod.z.number()
967
+ });
968
+ var SubscribeAudioChunksInputSchema = zod.z.object({
969
+ brokerId: zod.z.string(),
970
+ /** Short caller-identity tag (`audio-analyzer`, …) for `listClients`. */
971
+ tag: zod.z.string().optional()
972
+ });
973
+ var SubscribeAudioChunksResultSchema = zod.z.object({
974
+ /** Opaque id passed to `pullAudioChunks` / `unsubscribeAudioChunks`. */
975
+ subscriptionId: zod.z.string() });
901
976
  var BrokerStatusSchema$1 = zod.z.enum([
902
977
  "idle",
903
978
  "connecting",
@@ -1100,7 +1175,13 @@ method(zod.z.object({
1100
1175
  }), {
1101
1176
  kind: "mutation",
1102
1177
  auth: "admin"
1103
- }), method(zod.z.object({ brokerId: zod.z.string() }), zod.z.custom()), method(zod.z.object({
1178
+ }), method(SubscribeAudioChunksInputSchema, SubscribeAudioChunksResultSchema, { kind: "mutation" }), method(zod.z.object({
1179
+ subscriptionId: zod.z.string(),
1180
+ maxCount: zod.z.number().int().positive().default(8)
1181
+ }), zod.z.array(DecodedAudioChunkSchema).readonly()), method(zod.z.object({ subscriptionId: zod.z.string() }), zod.z.object({ released: zod.z.boolean() }), { kind: "mutation" }), method(SubscribeFramesInputSchema, SubscribeFramesResultSchema, { kind: "mutation" }), method(zod.z.object({
1182
+ subscriptionId: zod.z.string(),
1183
+ maxCount: zod.z.number().int().positive().default(4)
1184
+ }), zod.z.array(FrameHandleSchema).readonly()), method(zod.z.object({ subscriptionId: zod.z.string() }), zod.z.object({ released: zod.z.boolean() }), { kind: "mutation" }), method(zod.z.object({
1104
1185
  brokerId: zod.z.string(),
1105
1186
  seconds: zod.z.number().min(0).max(30)
1106
1187
  }), zod.z.void(), {
@@ -1793,6 +1874,34 @@ DeviceType.Light, DeviceType.Siren, DeviceType.Switch, method(zod.z.object({
1793
1874
  enabled: zod.z.boolean(),
1794
1875
  lastChangedAt: zod.z.number()
1795
1876
  });
1877
+ zod.z.object({
1878
+ enabled: zod.z.boolean(),
1879
+ sensitivity: zod.z.number(),
1880
+ /** Row-major active-cell grid. Length = gridWidth*gridHeight (see getOptions). */
1881
+ cells: zod.z.array(zod.z.boolean()),
1882
+ lastFetchedAt: zod.z.number()
1883
+ });
1884
+ var MotionZoneOptionsSchema = zod.z.object({
1885
+ gridWidth: zod.z.number(),
1886
+ gridHeight: zod.z.number(),
1887
+ sensitivity: zod.z.object({
1888
+ min: zod.z.number(),
1889
+ max: zod.z.number(),
1890
+ step: zod.z.number()
1891
+ })
1892
+ });
1893
+ var MotionZonePatchSchema = zod.z.object({
1894
+ enabled: zod.z.boolean().optional(),
1895
+ sensitivity: zod.z.number().optional(),
1896
+ cells: zod.z.array(zod.z.boolean()).optional()
1897
+ });
1898
+ DeviceType.Camera, method(zod.z.object({ deviceId: zod.z.number() }), MotionZoneOptionsSchema), method(zod.z.object({
1899
+ deviceId: zod.z.number(),
1900
+ patch: MotionZonePatchSchema
1901
+ }), zod.z.void(), {
1902
+ kind: "mutation",
1903
+ auth: "admin"
1904
+ });
1796
1905
  var AutotrackTargetTypeSchema = zod.z.string().describe("Vendor target string (people/vehicle/pet); empty = camera default");
1797
1906
  var PtzAutotrackSettingsSchema = zod.z.object({
1798
1907
  targetType: AutotrackTargetTypeSchema,
@@ -1835,6 +1944,85 @@ DeviceType.Camera, method(zod.z.object({ deviceId: zod.z.number() }), PtzAutotra
1835
1944
  deviceId: zod.z.number(),
1836
1945
  status: PtzAutotrackStatusSchema
1837
1946
  });
1947
+ var StreamProfileSchema = zod.z.enum([
1948
+ "main",
1949
+ "sub",
1950
+ "ext"
1951
+ ]);
1952
+ var StreamProfileConfigSchema = zod.z.object({
1953
+ width: zod.z.number(),
1954
+ height: zod.z.number(),
1955
+ codec: zod.z.enum(["h264", "h265"]),
1956
+ framerate: zod.z.number(),
1957
+ bitrate: zod.z.number(),
1958
+ bitrateMode: zod.z.enum(["vbr", "cbr"]).optional(),
1959
+ encoderProfile: zod.z.enum([
1960
+ "high",
1961
+ "main",
1962
+ "baseline"
1963
+ ]).optional(),
1964
+ gop: zod.z.number().optional(),
1965
+ audio: zod.z.boolean().optional()
1966
+ });
1967
+ zod.z.object({
1968
+ /** Per-profile current config. A profile absent = the camera doesn't have it. */
1969
+ main: StreamProfileConfigSchema.optional(),
1970
+ sub: StreamProfileConfigSchema.optional(),
1971
+ ext: StreamProfileConfigSchema.optional(),
1972
+ lastFetchedAt: zod.z.number()
1973
+ });
1974
+ var StreamProfileOptionsSchema = zod.z.object({
1975
+ resolutions: zod.z.array(zod.z.object({
1976
+ width: zod.z.number(),
1977
+ height: zod.z.number()
1978
+ })),
1979
+ codecs: zod.z.array(zod.z.enum(["h264", "h265"])),
1980
+ framerates: zod.z.array(zod.z.number()),
1981
+ /** Allowed bitrate values (kbps). Empty if the camera takes a free range. */
1982
+ bitrates: zod.z.array(zod.z.number()),
1983
+ /** Optional [min,max] kbps when the camera accepts a continuous range. */
1984
+ bitrateRange: zod.z.tuple([zod.z.number(), zod.z.number()]).optional(),
1985
+ supportsBitrateMode: zod.z.boolean(),
1986
+ supportsEncoderProfile: zod.z.boolean(),
1987
+ supportsGop: zod.z.boolean(),
1988
+ /** Allowed GOP / keyframe-interval range, in seconds — drives the
1989
+ * I-frame-interval selector. Absent when the camera advertises GOP
1990
+ * support but no concrete range (callers then fall back to a free
1991
+ * numeric input). `{ min, max, step }` per the getOptions convention. */
1992
+ gop: zod.z.object({
1993
+ min: zod.z.number(),
1994
+ max: zod.z.number(),
1995
+ step: zod.z.number()
1996
+ }).optional()
1997
+ });
1998
+ var StreamParamsOptionsSchema = zod.z.object({
1999
+ main: StreamProfileOptionsSchema.optional(),
2000
+ sub: StreamProfileOptionsSchema.optional(),
2001
+ ext: StreamProfileOptionsSchema.optional()
2002
+ });
2003
+ var StreamProfilePatchSchema = zod.z.object({
2004
+ width: zod.z.number().optional(),
2005
+ height: zod.z.number().optional(),
2006
+ codec: zod.z.enum(["h264", "h265"]).optional(),
2007
+ framerate: zod.z.number().optional(),
2008
+ bitrate: zod.z.number().optional(),
2009
+ bitrateMode: zod.z.enum(["vbr", "cbr"]).optional(),
2010
+ encoderProfile: zod.z.enum([
2011
+ "high",
2012
+ "main",
2013
+ "baseline"
2014
+ ]).optional(),
2015
+ gop: zod.z.number().optional(),
2016
+ audio: zod.z.boolean().optional()
2017
+ });
2018
+ DeviceType.Camera, method(zod.z.object({ deviceId: zod.z.number() }), StreamParamsOptionsSchema), method(zod.z.object({
2019
+ deviceId: zod.z.number(),
2020
+ profile: StreamProfileSchema,
2021
+ patch: StreamProfilePatchSchema
2022
+ }), zod.z.void(), {
2023
+ kind: "mutation",
2024
+ auth: "admin"
2025
+ }), method(zod.z.object({ deviceId: zod.z.number() }), zod.z.unknown().nullable());
1838
2026
  zod.z.object({
1839
2027
  on: zod.z.boolean(),
1840
2028
  /** Ms epoch of the last state change. Useful for UI "X minutes ago". */
@@ -2474,6 +2662,85 @@ method(LogEntrySchema, zod.z.void(), { kind: "mutation" }), method(zod.z.object(
2474
2662
  var StaticDirOutputSchema = zod.z.object({ staticDir: zod.z.string() });
2475
2663
  var VersionOutputSchema = zod.z.object({ version: zod.z.string() });
2476
2664
  method(zod.z.void(), StaticDirOutputSchema), method(zod.z.void(), VersionOutputSchema);
2665
+ var MethodAccessSchema = zod.z.enum([
2666
+ "view",
2667
+ "create",
2668
+ "delete"
2669
+ ]);
2670
+ var AllowedProviderSchema = zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]);
2671
+ var AllowedDevicesSchema = zod.z.record(zod.z.string(), zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]));
2672
+ var CapScopeSchema = zod.z.enum(["device", "system"]);
2673
+ var TokenScopeSchema = zod.z.discriminatedUnion("type", [
2674
+ zod.z.object({
2675
+ type: zod.z.literal("category"),
2676
+ target: CapScopeSchema,
2677
+ access: zod.z.array(MethodAccessSchema).min(1)
2678
+ }),
2679
+ zod.z.object({
2680
+ type: zod.z.literal("capability"),
2681
+ target: zod.z.string(),
2682
+ access: zod.z.array(MethodAccessSchema).min(1)
2683
+ }),
2684
+ zod.z.object({
2685
+ type: zod.z.literal("addon"),
2686
+ target: zod.z.string(),
2687
+ access: zod.z.array(MethodAccessSchema).min(1)
2688
+ }),
2689
+ zod.z.object({
2690
+ type: zod.z.literal("device"),
2691
+ /**
2692
+ * One or more deviceIds (serialised as strings for wire-format
2693
+ * consistency with the rest of the union). Matcher accepts if
2694
+ * `input.deviceId` ∈ `targets`. Array shape avoids the row-explosion
2695
+ * of one scope-per-device when granting access to a set of cameras.
2696
+ */
2697
+ targets: zod.z.array(zod.z.string()).min(1),
2698
+ access: zod.z.array(MethodAccessSchema).min(1)
2699
+ })
2700
+ ]);
2701
+ zod.z.object({
2702
+ id: zod.z.string(),
2703
+ username: zod.z.string(),
2704
+ passwordHash: zod.z.string(),
2705
+ /**
2706
+ * Admin bypass. When true, the middleware skips the scope-access
2707
+ * check entirely. There is no other axis of privilege; the legacy
2708
+ * role enum collapsed onto this boolean in v2.
2709
+ */
2710
+ isAdmin: zod.z.boolean().default(false),
2711
+ allowedProviders: AllowedProviderSchema,
2712
+ allowedDevices: AllowedDevicesSchema,
2713
+ /**
2714
+ * Scopes granted to this user. Admins bypass; their `scopes` is
2715
+ * ignored. Non-admins without scopes are locked out of every
2716
+ * protected call.
2717
+ */
2718
+ scopes: zod.z.array(TokenScopeSchema).default([]),
2719
+ createdAt: zod.z.number(),
2720
+ updatedAt: zod.z.number()
2721
+ });
2722
+ zod.z.object({
2723
+ id: zod.z.string(),
2724
+ label: zod.z.string(),
2725
+ isAdmin: zod.z.boolean().default(false),
2726
+ allowedProviders: AllowedProviderSchema,
2727
+ allowedDevices: AllowedDevicesSchema,
2728
+ tokenHash: zod.z.string(),
2729
+ tokenPrefix: zod.z.string(),
2730
+ createdAt: zod.z.number(),
2731
+ lastUsedAt: zod.z.number().optional()
2732
+ });
2733
+ zod.z.object({
2734
+ id: zod.z.string(),
2735
+ userId: zod.z.string(),
2736
+ name: zod.z.string(),
2737
+ tokenHash: zod.z.string(),
2738
+ tokenPrefix: zod.z.string(),
2739
+ scopes: zod.z.array(TokenScopeSchema),
2740
+ expiresAt: zod.z.number().nullish(),
2741
+ lastUsedAt: zod.z.number().nullish(),
2742
+ createdAt: zod.z.number()
2743
+ });
2477
2744
  var SsoBridgeClaimsSchema = zod.z.object({
2478
2745
  userId: zod.z.string(),
2479
2746
  username: zod.z.string(),
@@ -2489,12 +2756,36 @@ var SsoBridgeClaimsSchema = zod.z.object({
2489
2756
  * JWT WITHOUT verifying the signature — the hub re-verifies on every
2490
2757
  * inbound call so trust still rests with the signing hub.
2491
2758
  */
2492
- hubUrl: zod.z.string().optional()
2759
+ hubUrl: zod.z.string().optional(),
2760
+ /** Permission scopes baked into the token. Set by the OAuth
2761
+ * account-linking grant; absent on ordinary SSO-login tokens. */
2762
+ scopes: zod.z.array(TokenScopeSchema).optional(),
2763
+ /** OAuth authorization-code binding — set only on `oauth-code` tokens. */
2764
+ redirectUri: zod.z.string().optional(),
2765
+ integrationId: zod.z.string().optional(),
2766
+ /** JWT ID — unique per issued code; consumed-set enforces single-use. */
2767
+ jti: zod.z.string().optional(),
2768
+ /** OAuth session registry id — set on `oauth-access`/`oauth-refresh`
2769
+ * tokens so the verify path can check the session is not revoked. */
2770
+ sessionId: zod.z.string().optional()
2493
2771
  });
2494
2772
  method(zod.z.object({
2495
2773
  claims: SsoBridgeClaimsSchema,
2496
2774
  ttlSec: zod.z.number().int().positive().optional()
2497
2775
  }), zod.z.object({ token: zod.z.string() })), method(zod.z.object({ token: zod.z.string() }), SsoBridgeClaimsSchema.nullable());
2776
+ var OauthIntegrationDescriptorSchema = zod.z.object({
2777
+ /** Stable id used as the `integration=` query param, e.g. 'export-alexa'. */
2778
+ integrationId: zod.z.string(),
2779
+ /** Human label rendered on the consent page. */
2780
+ displayName: zod.z.string(),
2781
+ /** Scopes baked into every token issued for this integration. */
2782
+ requestedScopes: zod.z.array(TokenScopeSchema),
2783
+ /** Allowed redirect_uri prefixes. /api/oauth2/authorize rejects any
2784
+ * redirect_uri that does not start with one of these. Required —
2785
+ * an empty list means the integration can never complete linking. */
2786
+ allowedRedirectPrefixes: zod.z.array(zod.z.string()).min(1)
2787
+ });
2788
+ method(zod.z.void(), OauthIntegrationDescriptorSchema);
2498
2789
  var PasskeySummarySchema = zod.z.object({
2499
2790
  credentialId: zod.z.string(),
2500
2791
  label: zod.z.string(),
@@ -2740,22 +3031,29 @@ var WidgetSizeEnum = zod.z.enum([
2740
3031
  "lg",
2741
3032
  "xl"
2742
3033
  ]);
3034
+ var WidgetRemoteSchema = zod.z.object({
3035
+ remoteName: zod.z.string(),
3036
+ exposedModule: zod.z.string(),
3037
+ componentKey: zod.z.string().optional()
3038
+ });
2743
3039
  var WidgetMetadataSchema = zod.z.object({
2744
- /** Stable id within the addon kebab-case. */
2745
- stableId: zod.z.string(),
3040
+ /** Primary host tab `'dashboard'`, `'device-tab'`, or a device-detail tab id. */
3041
+ tab: zod.z.string(),
3042
+ /** Optional sub-tab within `tab`. */
3043
+ subTab: zod.z.string().optional(),
2746
3044
  /** Operator-facing label. */
2747
3045
  label: zod.z.string(),
3046
+ /** Ordering within `(tab, subTab)`, ascending. */
3047
+ order: zod.z.number().optional(),
3048
+ /** Always `'remote'` — a widget is a Module Federation remote. */
3049
+ kind: zod.z.literal("remote"),
3050
+ /** MF remote descriptor. */
3051
+ remote: WidgetRemoteSchema,
3052
+ /** Stable id within the addon — kebab-case. Equals `remote.componentKey`. */
3053
+ stableId: zod.z.string(),
2748
3054
  description: zod.z.string().optional(),
2749
3055
  icon: zod.z.string().optional(),
2750
3056
  /**
2751
- * Module Federation remote name — must match the `name` field on the
2752
- * widget addon's `federation()` plugin config. Used by the host's
2753
- * `<WidgetRegistryProvider>` to call `loadRemote('<remoteName>/widgets')`.
2754
- * Conventionally `addon_<addonid>_widgets` (snake_case; MF names
2755
- * cannot contain hyphens).
2756
- */
2757
- remoteName: zod.z.string(),
2758
- /**
2759
3057
  * Bundle filename inside the addon's `dist/` dir served at
2760
3058
  * `/api/addon-widgets/<addonId>/<bundle>`. With Module Federation
2761
3059
  * this is always `'remoteEntry.js'` — the value is kept on the
@@ -2763,9 +3061,9 @@ var WidgetMetadataSchema = zod.z.object({
2763
3061
  * cache-buster URL without a separate filesystem stat.
2764
3062
  */
2765
3063
  bundle: zod.z.string(),
2766
- /** Where the widget makes sense to render. */
3064
+ /** Every host the widget supports. The picker filters on this set. */
2767
3065
  hosts: zod.z.array(WidgetHostEnum).readonly(),
2768
- /** Required props the host must supply. Validated at <WidgetSlot> mount. */
3066
+ /** Required props the host must supply. Validated at `<WidgetSlot>` mount. */
2769
3067
  requires: zod.z.object({
2770
3068
  deviceContext: zod.z.boolean().default(false),
2771
3069
  integrationContext: zod.z.boolean().default(false)
@@ -2829,6 +3127,16 @@ var InvokeReplyEnvelopeSchema = zod.z.object({
2829
3127
  contentType: zod.z.string().optional()
2830
3128
  });
2831
3129
  method(zod.z.void(), zod.z.array(AddonHttpRouteSchema)), method(InvokeRequestSchema, InvokeReplyEnvelopeSchema, { kind: "mutation" });
3130
+ var ShmRingStatsSchema = zod.z.object({
3131
+ sessionId: zod.z.string(),
3132
+ slotCount: zod.z.number().int(),
3133
+ slotByteLength: zod.z.number().int(),
3134
+ segmentBytes: zod.z.number().int(),
3135
+ budgetMb: zod.z.number().int(),
3136
+ framesWritten: zod.z.number().int(),
3137
+ getFrameHits: zod.z.number().int(),
3138
+ getFrameMisses: zod.z.number().int()
3139
+ });
2832
3140
  method(zod.z.object({ codec: zod.z.string() }), zod.z.boolean()), method(zod.z.void(), zod.z.object({
2833
3141
  id: zod.z.string(),
2834
3142
  name: zod.z.string(),
@@ -2847,6 +3155,9 @@ method(zod.z.object({ codec: zod.z.string() }), zod.z.boolean()), method(zod.z.v
2847
3155
  sessionId: zod.z.string(),
2848
3156
  maxCount: zod.z.number().default(1)
2849
3157
  }), zod.z.array(DecodedFrameSchema)), method(zod.z.object({
3158
+ sessionId: zod.z.string(),
3159
+ maxCount: zod.z.number().default(1)
3160
+ }), zod.z.array(FrameHandleSchema)), method(zod.z.object({ handle: FrameHandleSchema }), DecodedFrameSchema.nullable()), method(zod.z.object({ sessionId: zod.z.string() }), ShmRingStatsSchema.nullable()), method(zod.z.object({
2850
3161
  sessionId: zod.z.string(),
2851
3162
  config: DecoderSessionConfigSchema.partial()
2852
3163
  }), zod.z.void()), method(zod.z.object({ sessionId: zod.z.string() }), DecoderStatsSchema), method(zod.z.void(), zod.z.array(zod.z.object({
@@ -3591,42 +3902,6 @@ method(zod.z.object({
3591
3902
  username: zod.z.string(),
3592
3903
  password: zod.z.string()
3593
3904
  }), AuthResultSchema.nullable(), { kind: "mutation" }), method(zod.z.object({ state: zod.z.string() }), zod.z.string()), method(zod.z.record(zod.z.string(), zod.z.string()), AuthResultSchema, { kind: "mutation" }), method(zod.z.object({ token: zod.z.string() }), AuthResultSchema.nullable());
3594
- var AuthProviderInfoSchema = zod.z.object({
3595
- /** Stable id matching the addon id (used for `getLoginUrl({addonId,…})`). */
3596
- addonId: zod.z.string(),
3597
- /**
3598
- * Per-instance id when one addon registers multiple "logical"
3599
- * providers (e.g. OIDC with Google + Microsoft + custom). The login
3600
- * URL becomes `/addon/${addonId}/${instanceId}/start` — handler reads
3601
- * `:instanceId` from the route. Empty/unset means the addon is a
3602
- * single-instance provider; the URL is `/addon/${addonId}/start`.
3603
- */
3604
- instanceId: zod.z.string().optional(),
3605
- /** Display label shown on the login button + admin row. */
3606
- displayName: zod.z.string(),
3607
- /** Optional iconography hint (lucide-react icon name OR emoji). */
3608
- icon: zod.z.string().optional(),
3609
- /** When true, the provider exposes a redirect-based login flow
3610
- * (`getLoginUrl` returns a URL the browser navigates to). */
3611
- hasRedirectFlow: zod.z.boolean(),
3612
- /** When true, the provider exposes a credential-form login flow
3613
- * (`validateCredentials` accepts username + password). */
3614
- hasCredentialFlow: zod.z.boolean(),
3615
- /** Provider kind, drives admin-UI hint dispatch (oidc / saml / totp / …). */
3616
- kind: zod.z.string().optional(),
3617
- /** Operator-facing status string (e.g. "Connected to https://login.acme.com"). */
3618
- status: zod.z.string().optional(),
3619
- /** When false, the provider is registered but disabled by config; the
3620
- * UI surfaces it as inactive without enumerating it for login. */
3621
- enabled: zod.z.boolean()
3622
- });
3623
- method(zod.z.void(), zod.z.array(AuthProviderInfoSchema).readonly()), method(zod.z.object({
3624
- addonId: zod.z.string(),
3625
- enabled: zod.z.boolean()
3626
- }), zod.z.object({ success: zod.z.literal(true) }), {
3627
- kind: "mutation",
3628
- auth: "admin"
3629
- });
3630
3905
  var NetworkEndpointSchema = zod.z.object({
3631
3906
  url: zod.z.string(),
3632
3907
  hostname: zod.z.string(),
@@ -3652,33 +3927,6 @@ var NetworkEndpointEntrySchema = NetworkEndpointSchema.extend({
3652
3927
  sourcePort: zod.z.number().optional()
3653
3928
  });
3654
3929
  method(zod.z.void(), NetworkEndpointSchema, { kind: "mutation" }), method(zod.z.void(), zod.z.void(), { kind: "mutation" }), method(zod.z.void(), NetworkEndpointSchema.nullable()), method(zod.z.void(), NetworkAccessStatusSchema), method(zod.z.void(), zod.z.array(NetworkEndpointEntrySchema).readonly());
3655
- var RemoteAccessEndpointSchema = zod.z.object({
3656
- url: zod.z.string(),
3657
- hostname: zod.z.string(),
3658
- port: zod.z.number(),
3659
- protocol: zod.z.enum(["http", "https"])
3660
- });
3661
- var RemoteAccessProviderInfoSchema = zod.z.object({
3662
- /** Stable id matching the addon id. */
3663
- addonId: zod.z.string(),
3664
- /** Display label shown on the admin row — sourced from the addon manifest. */
3665
- displayName: zod.z.string(),
3666
- /** When false, the provider is registered but disabled. */
3667
- enabled: zod.z.boolean(),
3668
- /** True when the underlying tunnel/connection is up. */
3669
- connected: zod.z.boolean(),
3670
- /** Public-facing endpoint, when connected. Null otherwise. */
3671
- endpoint: RemoteAccessEndpointSchema.nullable(),
3672
- /** Last error message (when connected=false), if available. */
3673
- error: zod.z.string().optional()
3674
- });
3675
- method(zod.z.void(), zod.z.array(RemoteAccessProviderInfoSchema).readonly()), method(zod.z.object({ addonId: zod.z.string() }), RemoteAccessEndpointSchema, {
3676
- kind: "mutation",
3677
- auth: "admin"
3678
- }), method(zod.z.object({ addonId: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), {
3679
- kind: "mutation",
3680
- auth: "admin"
3681
- });
3682
3930
  var TurnServerSchema = zod.z.object({
3683
3931
  /** Single URL or list of URLs (e.g. "turn:turn.example.com:3478?transport=udp"). */
3684
3932
  urls: zod.z.union([zod.z.string(), zod.z.array(zod.z.string())]),
@@ -3686,33 +3934,6 @@ var TurnServerSchema = zod.z.object({
3686
3934
  credential: zod.z.string().optional()
3687
3935
  });
3688
3936
  method(zod.z.void(), zod.z.array(TurnServerSchema).readonly());
3689
- var TurnProviderInfoSchema = zod.z.object({
3690
- /** Stable id matching the addon id. */
3691
- addonId: zod.z.string(),
3692
- /** Display label shown on the admin row — sourced from the addon manifest. */
3693
- displayName: zod.z.string(),
3694
- /** When false, the provider is registered but disabled. */
3695
- enabled: zod.z.boolean(),
3696
- /** Number of servers this provider is currently exposing. */
3697
- serverCount: zod.z.number(),
3698
- /**
3699
- * Flat list of every TURN/STUN URL this provider currently exposes.
3700
- * One row per URL (multi-URL ICE server entries are flattened). The
3701
- * admin UI shows this in a compact per-provider list so operators
3702
- * can verify what's actually being negotiated without having to dig
3703
- * into the combined `getAllServers` output.
3704
- */
3705
- urls: zod.z.array(zod.z.string()).readonly(),
3706
- /** Last fetch error (when serverCount=0 due to API failure), if any. */
3707
- error: zod.z.string().optional()
3708
- });
3709
- method(zod.z.void(), zod.z.array(TurnProviderInfoSchema).readonly()), method(zod.z.void(), zod.z.array(TurnServerSchema).readonly()), method(zod.z.object({
3710
- addonId: zod.z.string(),
3711
- enabled: zod.z.boolean()
3712
- }), zod.z.object({ success: zod.z.literal(true) }), {
3713
- kind: "mutation",
3714
- auth: "admin"
3715
- });
3716
3937
  var SnapshotImageSchema = zod.z.object({
3717
3938
  base64: zod.z.string(),
3718
3939
  contentType: zod.z.string()
@@ -4315,10 +4536,38 @@ var PtzMoveCommandSchema = zod.z.object({
4315
4536
  zoom: zod.z.number().optional(),
4316
4537
  speed: zod.z.number().optional()
4317
4538
  });
4539
+ PtzPositionSchema.extend({ autofocus: zod.z.boolean() });
4540
+ var PtzOptionsSchema = zod.z.object({
4541
+ hasPan: zod.z.boolean(),
4542
+ hasTilt: zod.z.boolean(),
4543
+ hasZoom: zod.z.boolean(),
4544
+ supportsPresets: zod.z.boolean(),
4545
+ /** Max number of named presets the camera supports, when known. */
4546
+ maxPresets: zod.z.number().optional(),
4547
+ /** Whether the camera exposes a controllable autofocus toggle
4548
+ * (boolean `hasX` per the getOptions availability convention). */
4549
+ hasAutofocus: zod.z.boolean()
4550
+ });
4318
4551
  DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: zod.z.number() }), zod.z.void(), { kind: "mutation" }), method(PtzMoveCommandSchema.extend({ deviceId: zod.z.number() }), zod.z.void(), { kind: "mutation" }), method(zod.z.object({ deviceId: zod.z.number() }), zod.z.void(), { kind: "mutation" }), method(zod.z.object({ deviceId: zod.z.number() }), zod.z.array(PtzPresetSchema)), method(zod.z.object({
4319
4552
  deviceId: zod.z.number(),
4320
4553
  presetId: zod.z.string()
4321
- }), zod.z.void(), { kind: "mutation" }), method(zod.z.object({ deviceId: zod.z.number() }), zod.z.void(), { kind: "mutation" }), method(zod.z.object({ deviceId: zod.z.number() }), PtzPositionSchema);
4554
+ }), zod.z.void(), { kind: "mutation" }), method(zod.z.object({
4555
+ deviceId: zod.z.number(),
4556
+ presetId: zod.z.string(),
4557
+ name: zod.z.string()
4558
+ }), zod.z.void(), {
4559
+ kind: "mutation",
4560
+ auth: "admin"
4561
+ }), method(zod.z.object({
4562
+ deviceId: zod.z.number(),
4563
+ presetId: zod.z.string()
4564
+ }), zod.z.void(), {
4565
+ kind: "mutation",
4566
+ auth: "admin"
4567
+ }), method(zod.z.object({ deviceId: zod.z.number() }), PtzOptionsSchema), method(zod.z.object({ deviceId: zod.z.number() }), zod.z.void(), { kind: "mutation" }), method(zod.z.object({ deviceId: zod.z.number() }), PtzPositionSchema), method(zod.z.object({
4568
+ deviceId: zod.z.number(),
4569
+ enabled: zod.z.boolean()
4570
+ }), zod.z.void(), { kind: "mutation" });
4322
4571
  var EventItemSchema = zod.z.object({
4323
4572
  id: zod.z.string(),
4324
4573
  type: zod.z.string(),
@@ -4809,7 +5058,7 @@ method(zod.z.void(), ListResultSchema), method(zod.z.void(), PreferredSchema), m
4809
5058
  * tunnel always emits `https://` regardless. */
4810
5059
  scheme: zod.z.enum(["http", "https"]).optional()
4811
5060
  }), GetConnectionEndpointsResultSchema), method(zod.z.void(), AllowedAddressesSchema), method(AllowedAddressesSchema, zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.void(), AllowedAddressesSchema, { kind: "mutation" });
4812
- var MeshEndpointSchema$1 = zod.z.object({
5061
+ var MeshEndpointSchema = zod.z.object({
4813
5062
  /** Stable identifier within the provider (e.g. `mesh-ipv4`, `magicdns`, `funnel`). */
4814
5063
  id: zod.z.string(),
4815
5064
  /** Operator-facing label (e.g. "Mesh IPv4", "MagicDNS"). */
@@ -4886,7 +5135,7 @@ var MeshStatusSchema = zod.z.object({
4886
5135
  /** Number of peers visible to this host (excluding self). */
4887
5136
  peerCount: zod.z.number(),
4888
5137
  /** Every endpoint this provider exposes for the current host. */
4889
- endpoints: zod.z.array(MeshEndpointSchema$1).readonly(),
5138
+ endpoints: zod.z.array(MeshEndpointSchema).readonly(),
4890
5139
  /** Last error from the daemon, when not joined. */
4891
5140
  error: zod.z.string().optional(),
4892
5141
  /**
@@ -4961,130 +5210,6 @@ authKey: zod.z.string().optional() }), zod.z.object({
4961
5210
  /** Human-readable error when `ok: false`. */
4962
5211
  error: zod.z.string().optional()
4963
5212
  }), { kind: "mutation" });
4964
- var MeshEndpointSchema = zod.z.object({
4965
- id: zod.z.string(),
4966
- label: zod.z.string(),
4967
- scope: zod.z.enum(["mesh", "public"]),
4968
- url: zod.z.string(),
4969
- hostname: zod.z.string(),
4970
- port: zod.z.number(),
4971
- protocol: zod.z.enum(["http", "https"])
4972
- });
4973
- var MeshProviderInfoSchema = zod.z.object({
4974
- /** Stable id matching the addon id. */
4975
- addonId: zod.z.string(),
4976
- /** Display label shown on the admin row — sourced from the addon manifest. */
4977
- displayName: zod.z.string(),
4978
- /** True when the host is joined to this provider's mesh. */
4979
- joined: zod.z.boolean(),
4980
- /** Local mesh IP (empty when not joined). */
4981
- meshIp: zod.z.string(),
4982
- /** MagicDNS / mesh hostname (empty when not configured). */
4983
- magicDnsHostname: zod.z.string(),
4984
- /** Peer count (excluding self). */
4985
- peerCount: zod.z.number(),
4986
- /** Active endpoints (mesh IP + MagicDNS + optional public Funnel). */
4987
- endpoints: zod.z.array(MeshEndpointSchema).readonly(),
4988
- /** Last error reported by the provider. */
4989
- error: zod.z.string().optional(),
4990
- /** Tenant / tailnet / network display name. Empty pre-join. */
4991
- tenantName: zod.z.string(),
4992
- /** Mesh DNS suffix (e.g. tailXXXX.ts.net). Empty when not configured. */
4993
- magicDnsSuffix: zod.z.string(),
4994
- /** Authenticated user / account login. Null for token-only providers. */
4995
- userLogin: zod.z.string().nullable(),
4996
- /** Provider control-plane URL. */
4997
- controlPlaneUrl: zod.z.string(),
4998
- /** Machine-key expiry (epoch ms). Null when keys don't rotate. */
4999
- keyExpiry: zod.z.number().nullable()
5000
- });
5001
- method(zod.z.void(), zod.z.array(MeshProviderInfoSchema).readonly()), method(zod.z.object({
5002
- addonId: zod.z.string(),
5003
- authKey: zod.z.string().min(8),
5004
- hostname: zod.z.string().optional()
5005
- }), zod.z.object({ joined: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.object({ addonId: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.object({
5006
- addonId: zod.z.string(),
5007
- hostname: zod.z.string().optional()
5008
- }), zod.z.object({ loginUrl: zod.z.string() }), { kind: "mutation" }), method(zod.z.object({ addonId: zod.z.string() }), zod.z.object({ loggedOut: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.object({ addonId: zod.z.string() }), zod.z.object({ peers: zod.z.array(MeshPeerSchema).readonly() }));
5009
- var MethodAccessSchema = zod.z.enum([
5010
- "view",
5011
- "create",
5012
- "delete"
5013
- ]);
5014
- var AllowedProviderSchema = zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]);
5015
- var AllowedDevicesSchema = zod.z.record(zod.z.string(), zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]));
5016
- var CapScopeSchema = zod.z.enum(["device", "system"]);
5017
- var TokenScopeSchema = zod.z.discriminatedUnion("type", [
5018
- zod.z.object({
5019
- type: zod.z.literal("category"),
5020
- target: CapScopeSchema,
5021
- access: zod.z.array(MethodAccessSchema).min(1)
5022
- }),
5023
- zod.z.object({
5024
- type: zod.z.literal("capability"),
5025
- target: zod.z.string(),
5026
- access: zod.z.array(MethodAccessSchema).min(1)
5027
- }),
5028
- zod.z.object({
5029
- type: zod.z.literal("addon"),
5030
- target: zod.z.string(),
5031
- access: zod.z.array(MethodAccessSchema).min(1)
5032
- }),
5033
- zod.z.object({
5034
- type: zod.z.literal("device"),
5035
- /**
5036
- * One or more deviceIds (serialised as strings for wire-format
5037
- * consistency with the rest of the union). Matcher accepts if
5038
- * `input.deviceId` ∈ `targets`. Array shape avoids the row-explosion
5039
- * of one scope-per-device when granting access to a set of cameras.
5040
- */
5041
- targets: zod.z.array(zod.z.string()).min(1),
5042
- access: zod.z.array(MethodAccessSchema).min(1)
5043
- })
5044
- ]);
5045
- zod.z.object({
5046
- id: zod.z.string(),
5047
- username: zod.z.string(),
5048
- passwordHash: zod.z.string(),
5049
- /**
5050
- * Admin bypass. When true, the middleware skips the scope-access
5051
- * check entirely. There is no other axis of privilege; the legacy
5052
- * role enum collapsed onto this boolean in v2.
5053
- */
5054
- isAdmin: zod.z.boolean().default(false),
5055
- allowedProviders: AllowedProviderSchema,
5056
- allowedDevices: AllowedDevicesSchema,
5057
- /**
5058
- * Scopes granted to this user. Admins bypass; their `scopes` is
5059
- * ignored. Non-admins without scopes are locked out of every
5060
- * protected call.
5061
- */
5062
- scopes: zod.z.array(TokenScopeSchema).default([]),
5063
- createdAt: zod.z.number(),
5064
- updatedAt: zod.z.number()
5065
- });
5066
- zod.z.object({
5067
- id: zod.z.string(),
5068
- label: zod.z.string(),
5069
- isAdmin: zod.z.boolean().default(false),
5070
- allowedProviders: AllowedProviderSchema,
5071
- allowedDevices: AllowedDevicesSchema,
5072
- tokenHash: zod.z.string(),
5073
- tokenPrefix: zod.z.string(),
5074
- createdAt: zod.z.number(),
5075
- lastUsedAt: zod.z.number().optional()
5076
- });
5077
- zod.z.object({
5078
- id: zod.z.string(),
5079
- userId: zod.z.string(),
5080
- name: zod.z.string(),
5081
- tokenHash: zod.z.string(),
5082
- tokenPrefix: zod.z.string(),
5083
- scopes: zod.z.array(TokenScopeSchema),
5084
- expiresAt: zod.z.number().nullish(),
5085
- lastUsedAt: zod.z.number().nullish(),
5086
- createdAt: zod.z.number()
5087
- });
5088
5213
  var UserSummarySchema = zod.z.object({
5089
5214
  id: zod.z.string(),
5090
5215
  username: zod.z.string(),
@@ -5157,6 +5282,16 @@ var CreateScopedTokenResultSchema = zod.z.object({
5157
5282
  token: zod.z.string(),
5158
5283
  record: ScopedTokenSummarySchema
5159
5284
  });
5285
+ var OauthSessionSummarySchema = zod.z.object({
5286
+ id: zod.z.string(),
5287
+ userId: zod.z.string(),
5288
+ username: zod.z.string(),
5289
+ integrationId: zod.z.string(),
5290
+ scopes: zod.z.array(TokenScopeSchema),
5291
+ createdAt: zod.z.number(),
5292
+ lastUsedAt: zod.z.number(),
5293
+ revokedAt: zod.z.number().nullable()
5294
+ });
5160
5295
  var TotpSetupResultSchema = zod.z.object({
5161
5296
  secret: zod.z.string(),
5162
5297
  otpauthUrl: zod.z.string()
@@ -5239,6 +5374,41 @@ method(zod.z.void(), zod.z.array(UserSummarySchema), { auth: "admin" }), method(
5239
5374
  }), zod.z.object({ valid: zod.z.boolean() }), {
5240
5375
  kind: "mutation",
5241
5376
  access: "view"
5377
+ }), method(zod.z.object({
5378
+ integrationId: zod.z.string(),
5379
+ userId: zod.z.string(),
5380
+ username: zod.z.string(),
5381
+ scopes: zod.z.array(TokenScopeSchema),
5382
+ redirectUri: zod.z.string(),
5383
+ hubUrl: zod.z.string()
5384
+ }), zod.z.object({ code: zod.z.string() }), {
5385
+ kind: "mutation",
5386
+ access: "create"
5387
+ }), method(zod.z.object({
5388
+ code: zod.z.string(),
5389
+ redirectUri: zod.z.string()
5390
+ }), zod.z.object({
5391
+ accessToken: zod.z.string(),
5392
+ refreshToken: zod.z.string(),
5393
+ expiresIn: zod.z.number()
5394
+ }).nullable(), {
5395
+ kind: "mutation",
5396
+ access: "view"
5397
+ }), method(zod.z.object({ refreshToken: zod.z.string() }), zod.z.object({
5398
+ accessToken: zod.z.string(),
5399
+ refreshToken: zod.z.string(),
5400
+ expiresIn: zod.z.number()
5401
+ }).nullable(), {
5402
+ kind: "mutation",
5403
+ access: "view"
5404
+ }), method(zod.z.object({ token: zod.z.string() }), zod.z.object({
5405
+ userId: zod.z.string(),
5406
+ username: zod.z.string(),
5407
+ scopes: zod.z.array(TokenScopeSchema)
5408
+ }).nullable(), { access: "view" }), method(zod.z.void(), zod.z.array(OauthSessionSummarySchema), { auth: "admin" }), method(zod.z.object({ id: zod.z.string() }), zod.z.object({ success: zod.z.boolean() }), {
5409
+ kind: "mutation",
5410
+ auth: "admin",
5411
+ access: "delete"
5242
5412
  });
5243
5413
  var FeatureManifestSchema = zod.z.object({
5244
5414
  streaming: zod.z.boolean(),
@@ -5407,7 +5577,13 @@ method(zod.z.void(), zod.z.array(TopologyNodeSchema).readonly(), { auth: "admin"
5407
5577
  }), RenameNodeResultSchema, {
5408
5578
  kind: "mutation",
5409
5579
  auth: "admin"
5410
- }), method(zod.z.void(), zod.z.record(zod.z.string(), ClusterAddonStatusEntrySchema), { auth: "admin" }), method(zod.z.object({ nodeId: zod.z.string() }), zod.z.array(NodeAddonEntrySchema).readonly(), { auth: "admin" }), method(zod.z.object({
5580
+ }), method(zod.z.void(), zod.z.record(zod.z.string(), ClusterAddonStatusEntrySchema), { auth: "admin" }), method(zod.z.object({ windowSeconds: zod.z.number().int().positive().max(300).default(60) }), zod.z.array(zod.z.object({
5581
+ callerAddonId: zod.z.string(),
5582
+ providerAddonId: zod.z.string(),
5583
+ capName: zod.z.string(),
5584
+ callsPerMin: zod.z.number(),
5585
+ lastCallAtMs: zod.z.number()
5586
+ })).readonly(), { auth: "admin" }), method(zod.z.object({ nodeId: zod.z.string() }), zod.z.array(NodeAddonEntrySchema).readonly(), { auth: "admin" }), method(zod.z.object({
5411
5587
  nodeId: zod.z.string(),
5412
5588
  level: zod.z.string()
5413
5589
  }), SuccessSchema, {
@@ -5695,6 +5871,13 @@ method(zod.z.void(), zod.z.array(AddonListItemSchema).readonly()), method(zod.z.
5695
5871
  mode: zod.z.enum(["singleton", "collection"]),
5696
5872
  isActive: zod.z.boolean()
5697
5873
  })).readonly()), method(zod.z.object({
5874
+ capName: zod.z.string().min(1),
5875
+ addonId: zod.z.string().min(1),
5876
+ enabled: zod.z.boolean()
5877
+ }), zod.z.object({ success: zod.z.literal(true) }), {
5878
+ kind: "mutation",
5879
+ auth: "admin"
5880
+ }), method(zod.z.object({
5698
5881
  packageName: zod.z.string().min(1),
5699
5882
  version: zod.z.string().optional()
5700
5883
  }), UpdateFrameworkPackageResultSchema, {
@@ -7638,6 +7821,16 @@ var StorageManager = class {
7638
7821
  }
7639
7822
  };
7640
7823
  //#endregion
7824
+ //#region src/auth/scope-matcher.ts
7825
+ /**
7826
+ * True if the scope set grants `access` on device-scoped capabilities.
7827
+ * A `category:device` grant covers every device cap (the broad grant).
7828
+ * Mirrors the OR-semantics of the existing token scope matcher.
7829
+ */
7830
+ function scopesAllowDeviceCap(scopes, access) {
7831
+ return scopes.some((s) => s.type === "category" && s.target === "device" && s.access.includes(access));
7832
+ }
7833
+ //#endregion
7641
7834
  //#region src/notification/notification-service.ts
7642
7835
  /**
7643
7836
  * Central notification service that routes notifications to configured outputs.
@@ -8463,5 +8656,6 @@ exports.installPythonPackages = installPythonPackages;
8463
8656
  exports.installPythonRequirements = installPythonRequirements;
8464
8657
  exports.isModelDownloaded = isModelDownloaded;
8465
8658
  exports.loadTlsCert = loadTlsCert;
8659
+ exports.scopesAllowDeviceCap = scopesAllowDeviceCap;
8466
8660
 
8467
8661
  //# sourceMappingURL=index.js.map