@camstack/addon-pipeline 1.2.603 → 1.2.604

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 (33) hide show
  1. package/dist/audio-analyzer/index.js +3 -3
  2. package/dist/audio-analyzer/index.mjs +3 -3
  3. package/dist/{custom-model-catalog-Dv09Pvq_.mjs → custom-model-catalog-BWxCwQ1L.mjs} +2 -2
  4. package/dist/{custom-model-catalog-BAnOZBOf.js → custom-model-catalog-BmQ6g825.js} +2 -2
  5. package/dist/detection-pipeline/index.js +4 -4
  6. package/dist/detection-pipeline/index.mjs +4 -4
  7. package/dist/{dist-CsCflIM1.mjs → dist-BZ34hSbo.mjs} +229 -196
  8. package/dist/{dist-DvXRw_dM.js → dist-DGzDqaBO.js} +229 -196
  9. package/dist/{model-catalogs-B95QZeYt.js → model-catalogs-BZ7wE3tk.js} +1 -1
  10. package/dist/{model-catalogs-aTwF92Re.mjs → model-catalogs-EjFqjUfh.mjs} +1 -1
  11. package/dist/motion-wasm/index.js +1 -1
  12. package/dist/motion-wasm/index.mjs +1 -1
  13. package/dist/{node-DAp5MmRJ.mjs → node-CJPdIMAm.mjs} +1 -1
  14. package/dist/{node-DxAtLKEn.js → node-CVbPzQN2.js} +1 -1
  15. package/dist/pipeline-runner/index.js +3 -3
  16. package/dist/pipeline-runner/index.mjs +3 -3
  17. package/dist/{process-memory-1_2L6U3Q.mjs → process-memory-BPqkGyDA.mjs} +1 -1
  18. package/dist/{process-memory-CmWDOMmE.js → process-memory-C8-aiceH.js} +1 -1
  19. package/dist/recorder/index.js +2 -2
  20. package/dist/recorder/index.mjs +2 -2
  21. package/dist/{segment-demux-js-DQo9qSHm.mjs → segment-demux-js-CxA4wyuM.mjs} +1 -1
  22. package/dist/{segment-demux-js-HagdockZ.js → segment-demux-js-z3asNjJ8.js} +1 -1
  23. package/dist/stream-broker/_stub.js +1 -1
  24. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DoBB8xYv.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-D28YdqZf.mjs} +3 -3
  25. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DdrO8p3-.mjs +26 -0
  26. package/dist/stream-broker/demux-worker-child.js +1 -1
  27. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  28. package/dist/stream-broker/{hostInit-DaZYQhX4.mjs → hostInit-CT3_w1iD.mjs} +3 -3
  29. package/dist/stream-broker/index.js +3 -3
  30. package/dist/stream-broker/index.mjs +3 -3
  31. package/dist/stream-broker/remoteEntry.js +1 -1
  32. package/package.json +1 -1
  33. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DkA9R3eo.mjs +0 -26
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-DvXRw_dM.js");
7
- const require_model_catalogs = require("../model-catalogs-B95QZeYt.js");
8
- const require_process_memory = require("../process-memory-CmWDOMmE.js");
6
+ const require_dist = require("../dist-DGzDqaBO.js");
7
+ const require_model_catalogs = require("../model-catalogs-BZ7wE3tk.js");
8
+ const require_process_memory = require("../process-memory-C8-aiceH.js");
9
9
  let node_fs = require("node:fs");
10
10
  node_fs = require_chunk.__toESM(node_fs);
11
11
  let node_path = require("node:path");
@@ -1,7 +1,7 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { $ as audioAnalyzerCapability, F as PoolMemoryWatchdog, Gn as hydrateSchema, Lt as mapAudioLabelToMacro, Nn as BaseAddon, Q as audioAnalysisCapability, Rn as audioChunkBytesPerSample, Un as expandAudioChunkToF32le, Zn as nodePin, cn as resolvePoolMemoryPolicy, h as DEFAULT_AUDIO_ANALYZER_CONFIG, jn as errMsg, mr as EventCategory, r as AUDIO_BACKEND_CHOICES } from "../dist-CsCflIM1.mjs";
3
- import { n as AUDIO_CLASSIFIER_MODELS } from "../model-catalogs-aTwF92Re.mjs";
4
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-1_2L6U3Q.mjs";
2
+ import { $ as audioAnalyzerCapability, F as PoolMemoryWatchdog, Gn as hydrateSchema, Lt as mapAudioLabelToMacro, Nn as BaseAddon, Q as audioAnalysisCapability, Rn as audioChunkBytesPerSample, Un as expandAudioChunkToF32le, Zn as nodePin, cn as resolvePoolMemoryPolicy, h as DEFAULT_AUDIO_ANALYZER_CONFIG, jn as errMsg, mr as EventCategory, r as AUDIO_BACKEND_CHOICES } from "../dist-BZ34hSbo.mjs";
3
+ import { n as AUDIO_CLASSIFIER_MODELS } from "../model-catalogs-EjFqjUfh.mjs";
4
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-BPqkGyDA.mjs";
5
5
  import * as fs from "node:fs";
6
6
  import * as path$1 from "node:path";
7
7
  import { ensureModel } from "@camstack/system/addon-utils";
@@ -1,5 +1,5 @@
1
- import { b as DEVICE_BACKEND_TO_FORMAT, et as audioKindId, f as COCO_80_LABELS, i as AUDIO_MACRO_LABELS, jt as inferModelProvider, k as LABEL_SUPPLY_VOCABULARIES, mn as stepModelRunsOnFormat, p as COCO_TO_MACRO } from "./dist-CsCflIM1.mjs";
2
- import { a as FACE_DETECTION_MODELS, c as OBJECT_DETECTION_MODELS, d as PLATE_OCR_MODELS, f as SEGMENTATION_REFINER_MODELS, i as CLIP_EMBEDDING_MODELS, l as PACKAGE_DETECTION_MODELS, n as AUDIO_CLASSIFIER_MODELS, o as FACE_EMBEDDING_MODELS, p as VEHICLE_CLASSIFIER_MODELS, r as BIRD_CLASSIFIER_MODELS, s as INSTANCE_SEGMENTATION_MODELS, t as ANIMAL_CLASSIFIER_MODELS, u as PLATE_DETECTION_MODELS } from "./model-catalogs-aTwF92Re.mjs";
1
+ import { b as DEVICE_BACKEND_TO_FORMAT, et as audioKindId, f as COCO_80_LABELS, i as AUDIO_MACRO_LABELS, jt as inferModelProvider, k as LABEL_SUPPLY_VOCABULARIES, mn as stepModelRunsOnFormat, p as COCO_TO_MACRO } from "./dist-BZ34hSbo.mjs";
2
+ import { a as FACE_DETECTION_MODELS, c as OBJECT_DETECTION_MODELS, d as PLATE_OCR_MODELS, f as SEGMENTATION_REFINER_MODELS, i as CLIP_EMBEDDING_MODELS, l as PACKAGE_DETECTION_MODELS, n as AUDIO_CLASSIFIER_MODELS, o as FACE_EMBEDDING_MODELS, p as VEHICLE_CLASSIFIER_MODELS, r as BIRD_CLASSIFIER_MODELS, s as INSTANCE_SEGMENTATION_MODELS, t as ANIMAL_CLASSIFIER_MODELS, u as PLATE_DETECTION_MODELS } from "./model-catalogs-EjFqjUfh.mjs";
3
3
  import { t as isWorkerReply } from "./worker-protocol-D_NzPcnh.mjs";
4
4
  import { randomUUID } from "node:crypto";
5
5
  //#region src/detection-pipeline/registry/effective-confidence.ts
@@ -1,5 +1,5 @@
1
- const require_dist = require("./dist-DvXRw_dM.js");
2
- const require_model_catalogs = require("./model-catalogs-B95QZeYt.js");
1
+ const require_dist = require("./dist-DGzDqaBO.js");
2
+ const require_model_catalogs = require("./model-catalogs-BZ7wE3tk.js");
3
3
  const require_worker_protocol = require("./worker-protocol-C-G8qmye.js");
4
4
  let node_crypto = require("node:crypto");
5
5
  //#region src/detection-pipeline/registry/effective-confidence.ts
@@ -3,11 +3,11 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-DvXRw_dM.js");
7
- const require_node = require("../node-DxAtLKEn.js");
8
- const require_custom_model_catalog = require("../custom-model-catalog-BAnOZBOf.js");
6
+ const require_dist = require("../dist-DGzDqaBO.js");
7
+ const require_node = require("../node-CVbPzQN2.js");
8
+ const require_custom_model_catalog = require("../custom-model-catalog-BmQ6g825.js");
9
9
  const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
10
- const require_process_memory = require("../process-memory-CmWDOMmE.js");
10
+ const require_process_memory = require("../process-memory-C8-aiceH.js");
11
11
  let node_os = require("node:os");
12
12
  node_os = require_chunk.__toESM(node_os);
13
13
  let node_fs = require("node:fs");
@@ -1,9 +1,9 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { F as PoolMemoryWatchdog, Ft as loadContributionCapability, Gn as hydrateSchema, Gt as overlayClusterStepSettings, Nn as BaseAddon, Nt as linkedLabelStepId, O as LABEL_SUPPLY_MACRO, St as evaluateZoneRules, Ut as modelBindingKey, Wn as hfModelUrl, X as applyModelBoundSettings, Xt as pipelineExecutorCapability, Zn as nodePin, _t as detectionPipelineCapability, cn as resolvePoolMemoryPolicy, ct as containingParentIndex, d as CLUSTER_MODEL_SCOPED_STEPS, dn as rootSuppliesOf, er as sleep, fn as runtimeDevices$1, fr as string, ft as defaultDeviceFor$1, g as DEFAULT_CLUSTER_STEP_SETTINGS, jn as errMsg$1, lr as object, mn as stepModelRunsOnFormat, mr as EventCategory, n as APPLE_SA_TO_MACRO, pr as union, q as YAMNET_TO_MACRO, qt as pickClusterStepSettings, rn as resolveClusterStepModelId, rr as array, st as collectModelBoundKeys, xt as enumerateInferenceDevices, yn as supportedRuntimes$1, zn as createEvent } from "../dist-CsCflIM1.mjs";
3
- import { c as readProcessCost } from "../node-DAp5MmRJ.mjs";
4
- import { C as resolveModelDefaultConfidence, S as landmarkPrecisionVerdict, _ as ALL_STEPS, b as getStepDefinition, f as localFrameRegistry, g as ALL_PIPELINE_STEPS, l as resolveDefaultDetectionModel, n as mergeCustomModels, o as deviceKeyOf, r as buildSubtreeCanRun, s as resolveDeviceEngine, t as CustomModelCatalog, u as macroGateVerdict, v as getDefaultModelForFormat, x as resolveModelForFormat, y as getStep } from "../custom-model-catalog-Dv09Pvq_.mjs";
2
+ import { F as PoolMemoryWatchdog, Ft as loadContributionCapability, Gn as hydrateSchema, Gt as overlayClusterStepSettings, Nn as BaseAddon, Nt as linkedLabelStepId, O as LABEL_SUPPLY_MACRO, St as evaluateZoneRules, Ut as modelBindingKey, Wn as hfModelUrl, X as applyModelBoundSettings, Xt as pipelineExecutorCapability, Zn as nodePin, _t as detectionPipelineCapability, cn as resolvePoolMemoryPolicy, ct as containingParentIndex, d as CLUSTER_MODEL_SCOPED_STEPS, dn as rootSuppliesOf, er as sleep, fn as runtimeDevices$1, fr as string, ft as defaultDeviceFor$1, g as DEFAULT_CLUSTER_STEP_SETTINGS, jn as errMsg$1, lr as object, mn as stepModelRunsOnFormat, mr as EventCategory, n as APPLE_SA_TO_MACRO, pr as union, q as YAMNET_TO_MACRO, qt as pickClusterStepSettings, rn as resolveClusterStepModelId, rr as array, st as collectModelBoundKeys, xt as enumerateInferenceDevices, yn as supportedRuntimes$1, zn as createEvent } from "../dist-BZ34hSbo.mjs";
3
+ import { c as readProcessCost } from "../node-CJPdIMAm.mjs";
4
+ import { C as resolveModelDefaultConfidence, S as landmarkPrecisionVerdict, _ as ALL_STEPS, b as getStepDefinition, f as localFrameRegistry, g as ALL_PIPELINE_STEPS, l as resolveDefaultDetectionModel, n as mergeCustomModels, o as deviceKeyOf, r as buildSubtreeCanRun, s as resolveDeviceEngine, t as CustomModelCatalog, u as macroGateVerdict, v as getDefaultModelForFormat, x as resolveModelForFormat, y as getStep } from "../custom-model-catalog-BWxCwQ1L.mjs";
5
5
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
6
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-1_2L6U3Q.mjs";
6
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-BPqkGyDA.mjs";
7
7
  import * as os$1 from "node:os";
8
8
  import * as fs from "node:fs";
9
9
  import * as path$1 from "node:path";
@@ -7977,6 +7977,12 @@ function normalizeAddonInitResult(result) {
7977
7977
  if (Array.isArray(result)) return { providers: result };
7978
7978
  return result;
7979
7979
  }
7980
+ /**
7981
+ * The share-view scope kinds a `csv_*` share token can carry. The hub mints
7982
+ * and validates them (`share-token.service.ts` builds its enum from this
7983
+ * list); a data plane names the kinds it ACCEPTS in `share`.
7984
+ */
7985
+ var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7980
7986
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
7981
7987
  var PeerBytesTicketSchema = object({
7982
7988
  /** `http://127.0.0.1:<port>/<token>`. One `GET` takes it. */
@@ -15278,6 +15284,229 @@ var ConvertResultSchema = object({
15278
15284
  files: array(string()).readonly()
15279
15285
  })).readonly()
15280
15286
  });
15287
+ /**
15288
+ * Zod schemas for persisted record types.
15289
+ *
15290
+ * These schemas serve as the single source of truth for types that are
15291
+ * stored in the settings-store backend and retrieved via tRPC. They
15292
+ * replace the manual TypeScript interfaces with schema-derived types,
15293
+ * enabling runtime validation when reading from the backend.
15294
+ *
15295
+ * Convention: each schema is named `<Type>Schema`, the inferred TS type
15296
+ * keeps the original name for backward compatibility.
15297
+ */
15298
+ /**
15299
+ * Auth model (v2 — 2026-05-12 caps-only):
15300
+ *
15301
+ * Two principals:
15302
+ * - `isAdmin: true` — full bypass. Admin scope set is ignored.
15303
+ * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
15304
+ *
15305
+ * No role enum. There used to be `viewer / agent / scoped` and earlier
15306
+ * `super_admin` — collapsed onto the single boolean because every
15307
+ * non-admin caller is governed by the same scope-check rules; the
15308
+ * distinction was only ever used to route role-specific procedures
15309
+ * which we no longer have. CLI / webhook integrations are `cst_*` tokens
15310
+ * with `isAdmin: false` + an explicit scope list.
15311
+ */
15312
+ /** Per-method access flavour. Materialised on every cap method via codegen. */
15313
+ var MethodAccessSchema = _enum([
15314
+ "view",
15315
+ "create",
15316
+ "delete"
15317
+ ]);
15318
+ /**
15319
+ * A single scope grant. Three forms — checked in matcher with OR
15320
+ * semantics; the first match decides whether the call passes:
15321
+ *
15322
+ * - `category` — broadest. `target: 'device' | 'system'` selects every
15323
+ * cap with the matching `scope` declaration. New caps inherit grants
15324
+ * automatically — adding a device cap to the codebase makes it
15325
+ * reachable to every user with `category:device [...]` without a
15326
+ * re-grant. Use this for "family viewer" / "operator" tiers.
15327
+ *
15328
+ * - `addon` — every cap that ships inside a given addon id. Niche;
15329
+ * useful when an integration needs to interact with one specific
15330
+ * addon's surface regardless of how many caps it exports.
15331
+ *
15332
+ * - `capability` — the most precise form. Single cap name. Use for
15333
+ * integration tokens where you want to grant `addons.installPackage`
15334
+ * and nothing else.
15335
+ *
15336
+ * `access` is REQUIRED with min 1 element. `admin` bypass is the
15337
+ * "give me everything" escape; there is no wildcard scope.
15338
+ */
15339
+ var AllowedProviderSchema = union([literal("*"), array(string())]);
15340
+ var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
15341
+ var CapScopeSchema = _enum(["device", "system"]);
15342
+ /**
15343
+ * DeviceSelector (scope model v3 — 2026-08-12).
15344
+ *
15345
+ * A `device` grant no longer carries a frozen list of deviceIds. It carries
15346
+ * a SELECTOR the matcher resolves against the live fleet, so the grant can be
15347
+ * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
15348
+ * AFTER the grant was minted — no re-grant, no re-login.
15349
+ *
15350
+ * - `all` — every device in the deployment. The broad viewer/operator
15351
+ * lever without a `category` grant (a `category` grant also covers device
15352
+ * caps that carry no deviceId; `all` is specifically the device set).
15353
+ * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
15354
+ * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
15355
+ * is NOT covered until the grant is edited.
15356
+ * - `types` — every device of a `DeviceType` (e.g. every `camera`).
15357
+ * DYNAMIC. A device that changes type, or a new device of the type,
15358
+ * re-resolves on the next request.
15359
+ * - `locations` — every device whose operator-assigned `location` label is
15360
+ * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
15361
+ * null/unset location matches NO `locations` selector.
15362
+ */
15363
+ var DeviceSelectorSchema = discriminatedUnion("kind", [
15364
+ object({ kind: literal("all") }),
15365
+ object({
15366
+ kind: literal("ids"),
15367
+ ids: array(number().int()).min(1)
15368
+ }),
15369
+ object({
15370
+ kind: literal("types"),
15371
+ types: array(_enum(DeviceType)).min(1)
15372
+ }),
15373
+ object({
15374
+ kind: literal("locations"),
15375
+ locations: array(string().min(1)).min(1)
15376
+ })
15377
+ ]);
15378
+ var DeviceTokenScopeSchema = object({
15379
+ type: literal("device"),
15380
+ /** The device SET this grant covers — resolved against the live fleet. */
15381
+ selector: DeviceSelectorSchema,
15382
+ access: array(MethodAccessSchema).min(1),
15383
+ /**
15384
+ * Whether a grant on a PARENT device transparently covers its accessory
15385
+ * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
15386
+ * Direction is parent → children ONLY.
15387
+ *
15388
+ * Absent → the matcher DERIVES it from the access flavour: `view`
15389
+ * inherits (a camera viewer sees the camera's accessories), `create` /
15390
+ * `delete` do NOT (actuating/removing a child is an explicit act the
15391
+ * operator must grant on the child, not inherit from the parent). Set it
15392
+ * explicitly to override that default per grant.
15393
+ */
15394
+ includeLinked: boolean().optional()
15395
+ });
15396
+ /**
15397
+ * v2 → v3 lazy migration. A pre-v3 `device` grant carried
15398
+ * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
15399
+ * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
15400
+ * EVERY parse path — stored records AND the JWT-carried scope arrays
15401
+ * normalised at the request boundary ({@link normalizeTokenScopes} in
15402
+ * `device-selector.ts`). Chosen over a one-time DB migration because a
15403
+ * migration cannot reach a JWT already in a client's hands; parse-time
15404
+ * migration covers both without a flag day. No cast — the raw object is read
15405
+ * through `Reflect.get` (its static type is `unknown`).
15406
+ */
15407
+ function migrateLegacyTokenScope(raw) {
15408
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
15409
+ if (Reflect.get(raw, "type") !== "device") return raw;
15410
+ if (Reflect.get(raw, "selector") !== void 0) return raw;
15411
+ const targets = Reflect.get(raw, "targets");
15412
+ if (!Array.isArray(targets)) return raw;
15413
+ return {
15414
+ type: "device",
15415
+ selector: {
15416
+ kind: "ids",
15417
+ ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
15418
+ },
15419
+ access: Reflect.get(raw, "access")
15420
+ };
15421
+ }
15422
+ var TokenScopeSchema = preprocess(migrateLegacyTokenScope, discriminatedUnion("type", [
15423
+ object({
15424
+ type: literal("category"),
15425
+ target: CapScopeSchema,
15426
+ access: array(MethodAccessSchema).min(1)
15427
+ }),
15428
+ object({
15429
+ type: literal("capability"),
15430
+ target: string(),
15431
+ access: array(MethodAccessSchema).min(1)
15432
+ }),
15433
+ object({
15434
+ type: literal("addon"),
15435
+ target: string(),
15436
+ access: array(MethodAccessSchema).min(1)
15437
+ }),
15438
+ DeviceTokenScopeSchema
15439
+ ]));
15440
+ object({
15441
+ id: string(),
15442
+ username: string(),
15443
+ passwordHash: string(),
15444
+ /**
15445
+ * Admin bypass. When true, the middleware skips the scope-access
15446
+ * check entirely. There is no other axis of privilege; the legacy
15447
+ * role enum collapsed onto this boolean in v2.
15448
+ */
15449
+ isAdmin: boolean().default(false),
15450
+ allowedProviders: AllowedProviderSchema,
15451
+ allowedDevices: AllowedDevicesSchema,
15452
+ /**
15453
+ * Scopes granted to this user. Admins bypass; their `scopes` is
15454
+ * ignored. Non-admins without scopes are locked out of every
15455
+ * protected call.
15456
+ */
15457
+ scopes: array(TokenScopeSchema).default([]),
15458
+ createdAt: number(),
15459
+ updatedAt: number()
15460
+ });
15461
+ object({
15462
+ id: string(),
15463
+ label: string(),
15464
+ isAdmin: boolean().default(false),
15465
+ allowedProviders: AllowedProviderSchema,
15466
+ allowedDevices: AllowedDevicesSchema,
15467
+ tokenHash: string(),
15468
+ tokenPrefix: string(),
15469
+ createdAt: number(),
15470
+ lastUsedAt: number().optional()
15471
+ });
15472
+ object({
15473
+ id: string(),
15474
+ userId: string(),
15475
+ name: string(),
15476
+ tokenHash: string(),
15477
+ tokenPrefix: string(),
15478
+ scopes: array(TokenScopeSchema),
15479
+ expiresAt: number().nullish(),
15480
+ lastUsedAt: number().nullish(),
15481
+ createdAt: number()
15482
+ });
15483
+ /** What a share-view grant lets its holder see. */
15484
+ var ShareViewGrantSchema = object({
15485
+ kind: _enum(SHARE_VIEW_KINDS),
15486
+ deviceIds: array(number().int().nonnegative()).min(1).max(64),
15487
+ /** Talk-back, opt-in at mint time; absent means off. */
15488
+ talk: boolean().optional()
15489
+ });
15490
+ var ShareViewScopeSchema = object({
15491
+ type: literal("share-view"),
15492
+ grant: ShareViewGrantSchema
15493
+ });
15494
+ var AddonRoutesScopeSchema = object({
15495
+ type: literal("addon-routes"),
15496
+ access: array(MethodAccessSchema).min(1)
15497
+ });
15498
+ var CredentialScopeSchema = union([
15499
+ literal("*"),
15500
+ ShareViewScopeSchema,
15501
+ AddonRoutesScopeSchema,
15502
+ TokenScopeSchema
15503
+ ]);
15504
+ object({
15505
+ kind: literal("credential"),
15506
+ sub: string().min(1),
15507
+ jti: string().min(16),
15508
+ scopes: array(CredentialScopeSchema).min(1)
15509
+ });
15281
15510
  _enum(["new-session", "step-up"]);
15282
15511
  /** The languages the hub's app landing pages are written in (D858). */
15283
15512
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -47332,202 +47561,6 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
47332
47561
  auth: "admin"
47333
47562
  }), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
47334
47563
  /**
47335
- * Zod schemas for persisted record types.
47336
- *
47337
- * These schemas serve as the single source of truth for types that are
47338
- * stored in the settings-store backend and retrieved via tRPC. They
47339
- * replace the manual TypeScript interfaces with schema-derived types,
47340
- * enabling runtime validation when reading from the backend.
47341
- *
47342
- * Convention: each schema is named `<Type>Schema`, the inferred TS type
47343
- * keeps the original name for backward compatibility.
47344
- */
47345
- /**
47346
- * Auth model (v2 — 2026-05-12 caps-only):
47347
- *
47348
- * Two principals:
47349
- * - `isAdmin: true` — full bypass. Admin scope set is ignored.
47350
- * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
47351
- *
47352
- * No role enum. There used to be `viewer / agent / scoped` and earlier
47353
- * `super_admin` — collapsed onto the single boolean because every
47354
- * non-admin caller is governed by the same scope-check rules; the
47355
- * distinction was only ever used to route role-specific procedures
47356
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
47357
- * with `isAdmin: false` + an explicit scope list.
47358
- */
47359
- /** Per-method access flavour. Materialised on every cap method via codegen. */
47360
- var MethodAccessSchema = _enum([
47361
- "view",
47362
- "create",
47363
- "delete"
47364
- ]);
47365
- /**
47366
- * A single scope grant. Three forms — checked in matcher with OR
47367
- * semantics; the first match decides whether the call passes:
47368
- *
47369
- * - `category` — broadest. `target: 'device' | 'system'` selects every
47370
- * cap with the matching `scope` declaration. New caps inherit grants
47371
- * automatically — adding a device cap to the codebase makes it
47372
- * reachable to every user with `category:device [...]` without a
47373
- * re-grant. Use this for "family viewer" / "operator" tiers.
47374
- *
47375
- * - `addon` — every cap that ships inside a given addon id. Niche;
47376
- * useful when an integration needs to interact with one specific
47377
- * addon's surface regardless of how many caps it exports.
47378
- *
47379
- * - `capability` — the most precise form. Single cap name. Use for
47380
- * integration tokens where you want to grant `addons.installPackage`
47381
- * and nothing else.
47382
- *
47383
- * `access` is REQUIRED with min 1 element. `admin` bypass is the
47384
- * "give me everything" escape; there is no wildcard scope.
47385
- */
47386
- var AllowedProviderSchema = union([literal("*"), array(string())]);
47387
- var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
47388
- var CapScopeSchema = _enum(["device", "system"]);
47389
- /**
47390
- * DeviceSelector (scope model v3 — 2026-08-12).
47391
- *
47392
- * A `device` grant no longer carries a frozen list of deviceIds. It carries
47393
- * a SELECTOR the matcher resolves against the live fleet, so the grant can be
47394
- * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
47395
- * AFTER the grant was minted — no re-grant, no re-login.
47396
- *
47397
- * - `all` — every device in the deployment. The broad viewer/operator
47398
- * lever without a `category` grant (a `category` grant also covers device
47399
- * caps that carry no deviceId; `all` is specifically the device set).
47400
- * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
47401
- * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
47402
- * is NOT covered until the grant is edited.
47403
- * - `types` — every device of a `DeviceType` (e.g. every `camera`).
47404
- * DYNAMIC. A device that changes type, or a new device of the type,
47405
- * re-resolves on the next request.
47406
- * - `locations` — every device whose operator-assigned `location` label is
47407
- * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
47408
- * null/unset location matches NO `locations` selector.
47409
- */
47410
- var DeviceSelectorSchema = discriminatedUnion("kind", [
47411
- object({ kind: literal("all") }),
47412
- object({
47413
- kind: literal("ids"),
47414
- ids: array(number().int()).min(1)
47415
- }),
47416
- object({
47417
- kind: literal("types"),
47418
- types: array(_enum(DeviceType)).min(1)
47419
- }),
47420
- object({
47421
- kind: literal("locations"),
47422
- locations: array(string().min(1)).min(1)
47423
- })
47424
- ]);
47425
- var DeviceTokenScopeSchema = object({
47426
- type: literal("device"),
47427
- /** The device SET this grant covers — resolved against the live fleet. */
47428
- selector: DeviceSelectorSchema,
47429
- access: array(MethodAccessSchema).min(1),
47430
- /**
47431
- * Whether a grant on a PARENT device transparently covers its accessory
47432
- * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
47433
- * Direction is parent → children ONLY.
47434
- *
47435
- * Absent → the matcher DERIVES it from the access flavour: `view`
47436
- * inherits (a camera viewer sees the camera's accessories), `create` /
47437
- * `delete` do NOT (actuating/removing a child is an explicit act the
47438
- * operator must grant on the child, not inherit from the parent). Set it
47439
- * explicitly to override that default per grant.
47440
- */
47441
- includeLinked: boolean().optional()
47442
- });
47443
- /**
47444
- * v2 → v3 lazy migration. A pre-v3 `device` grant carried
47445
- * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
47446
- * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
47447
- * EVERY parse path — stored records AND the JWT-carried scope arrays
47448
- * normalised at the request boundary ({@link normalizeTokenScopes} in
47449
- * `device-selector.ts`). Chosen over a one-time DB migration because a
47450
- * migration cannot reach a JWT already in a client's hands; parse-time
47451
- * migration covers both without a flag day. No cast — the raw object is read
47452
- * through `Reflect.get` (its static type is `unknown`).
47453
- */
47454
- function migrateLegacyTokenScope(raw) {
47455
- if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
47456
- if (Reflect.get(raw, "type") !== "device") return raw;
47457
- if (Reflect.get(raw, "selector") !== void 0) return raw;
47458
- const targets = Reflect.get(raw, "targets");
47459
- if (!Array.isArray(targets)) return raw;
47460
- return {
47461
- type: "device",
47462
- selector: {
47463
- kind: "ids",
47464
- ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
47465
- },
47466
- access: Reflect.get(raw, "access")
47467
- };
47468
- }
47469
- var TokenScopeSchema = preprocess(migrateLegacyTokenScope, discriminatedUnion("type", [
47470
- object({
47471
- type: literal("category"),
47472
- target: CapScopeSchema,
47473
- access: array(MethodAccessSchema).min(1)
47474
- }),
47475
- object({
47476
- type: literal("capability"),
47477
- target: string(),
47478
- access: array(MethodAccessSchema).min(1)
47479
- }),
47480
- object({
47481
- type: literal("addon"),
47482
- target: string(),
47483
- access: array(MethodAccessSchema).min(1)
47484
- }),
47485
- DeviceTokenScopeSchema
47486
- ]));
47487
- object({
47488
- id: string(),
47489
- username: string(),
47490
- passwordHash: string(),
47491
- /**
47492
- * Admin bypass. When true, the middleware skips the scope-access
47493
- * check entirely. There is no other axis of privilege; the legacy
47494
- * role enum collapsed onto this boolean in v2.
47495
- */
47496
- isAdmin: boolean().default(false),
47497
- allowedProviders: AllowedProviderSchema,
47498
- allowedDevices: AllowedDevicesSchema,
47499
- /**
47500
- * Scopes granted to this user. Admins bypass; their `scopes` is
47501
- * ignored. Non-admins without scopes are locked out of every
47502
- * protected call.
47503
- */
47504
- scopes: array(TokenScopeSchema).default([]),
47505
- createdAt: number(),
47506
- updatedAt: number()
47507
- });
47508
- object({
47509
- id: string(),
47510
- label: string(),
47511
- isAdmin: boolean().default(false),
47512
- allowedProviders: AllowedProviderSchema,
47513
- allowedDevices: AllowedDevicesSchema,
47514
- tokenHash: string(),
47515
- tokenPrefix: string(),
47516
- createdAt: number(),
47517
- lastUsedAt: number().optional()
47518
- });
47519
- object({
47520
- id: string(),
47521
- userId: string(),
47522
- name: string(),
47523
- tokenHash: string(),
47524
- tokenPrefix: string(),
47525
- scopes: array(TokenScopeSchema),
47526
- expiresAt: number().nullish(),
47527
- lastUsedAt: number().nullish(),
47528
- createdAt: number()
47529
- });
47530
- /**
47531
47564
  * `oauth-integration` — a collection cap by which an addon declares
47532
47565
  * itself a linkable OAuth client of the hub's core `/oauth2/*` server.
47533
47566
  * Each provider returns a static descriptor; the core enumerates them