@camstack/types 1.2.372 → 1.2.374

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 (41) hide show
  1. package/dist/addon.d.ts +2 -0
  2. package/dist/addon.js +6 -3
  3. package/dist/addon.mjs +5 -4
  4. package/dist/auth/app-flow.d.ts +12 -1
  5. package/dist/capabilities/addon-settings.cap.d.ts +10 -0
  6. package/dist/capabilities/core-blocks.cap.d.ts +2 -0
  7. package/dist/capabilities/device-manager.cap.d.ts +78 -0
  8. package/dist/capabilities/device-removal-hook.cap.d.ts +93 -0
  9. package/dist/capabilities/index.d.ts +6 -3
  10. package/dist/capabilities/keychain.cap.d.ts +11 -0
  11. package/dist/capabilities/sso-bridge.cap.d.ts +12 -0
  12. package/dist/capabilities/system.cap.d.ts +4 -0
  13. package/dist/client.js +3 -0
  14. package/dist/client.mjs +3 -0
  15. package/dist/{composition-DCYnv4I6.js → composition-DIp0uE_b.js} +1 -1
  16. package/dist/{composition-C-WpVYTX.mjs → composition-EQ9Ok0Ee.mjs} +1 -1
  17. package/dist/device/device-removal-reconcile.d.ts +49 -0
  18. package/dist/device/device-type.d.ts +16 -0
  19. package/dist/{err-msg-DX6i_MY4.mjs → err-msg-DLerKiVO.mjs} +16 -0
  20. package/dist/{err-msg-Dx2Kor0g.js → err-msg-Ls8Q6dHO.js} +16 -0
  21. package/dist/generated/addon-api.d.ts +60 -0
  22. package/dist/generated/capability-router-map.d.ts +5 -2
  23. package/dist/generated/collection-array-methods.d.ts +1 -1
  24. package/dist/generated/method-access-map.d.ts +1 -1
  25. package/dist/generated/method-device-selectors.d.ts +2 -2
  26. package/dist/generated/system-proxy.d.ts +1 -1
  27. package/dist/i18n/camstack-error.d.ts +31 -0
  28. package/dist/i18n/translation.d.ts +39 -0
  29. package/dist/index.d.ts +9 -1
  30. package/dist/index.js +535 -18
  31. package/dist/index.mjs +499 -19
  32. package/dist/interfaces/addon.d.ts +11 -0
  33. package/dist/interfaces/config-ui.d.ts +20 -0
  34. package/dist/keychain/secrets-access.d.ts +12 -0
  35. package/dist/node.js +2 -2
  36. package/dist/node.mjs +2 -2
  37. package/dist/pipeline/face-rescore-schedule.d.ts +35 -0
  38. package/dist/{sleep-DAX0-2v9.mjs → sleep-DRqxtc0C.mjs} +62 -1
  39. package/dist/{sleep-DnQ5WsMI.js → sleep-rqlHXgwb.js} +91 -0
  40. package/dist/system/server-name.d.ts +35 -0
  41. package/package.json +1 -1
@@ -564,6 +564,17 @@ export interface AddonContext<TConfig = Record<string, unknown>> {
564
564
  * it is absent.
565
565
  */
566
566
  readDeviceStoreBatch?(deviceIds: readonly number[]): Promise<ReadonlyMap<number, Record<string, unknown>>>;
567
+ /**
568
+ * The device ids this addon holds a per-device store for — ids only, no
569
+ * values. The read side of a fleet-wide pass over the standard per-device
570
+ * settings (D865): a caller that needs "every device with a config of
571
+ * mine" lists the ids, then reads them with `readDeviceStoreBatch`.
572
+ *
573
+ * OPTIONAL: only the door-backed view can answer it. A view that cannot
574
+ * must be absent, never an empty list — "none" and "cannot tell" are
575
+ * different answers.
576
+ */
577
+ listDeviceStoreIds?(): Promise<readonly number[]>;
567
578
  /**
568
579
  * Write a patch into the per-device store. Does NOT touch the
569
580
  * addon-level store. Keys preserved as in `writeAddonStore`.
@@ -52,7 +52,11 @@ export interface ConfigUISchema {
52
52
  export interface ConfigSection {
53
53
  readonly id: string;
54
54
  readonly title: string;
55
+ /** `"<namespace>:<key>"` of the translated `title` (D863); `title` stays the English text. */
56
+ readonly titleKey?: string;
55
57
  readonly description?: string;
58
+ /** `"<namespace>:<key>"` of the translated `description` (D863). */
59
+ readonly descriptionKey?: string;
56
60
  readonly style?: 'card' | 'accordion';
57
61
  readonly defaultCollapsed?: boolean;
58
62
  readonly columns?: 1 | 2 | 3 | 4;
@@ -123,7 +127,15 @@ export interface ConfigFieldModelApplicability {
123
127
  export interface ConfigFieldBase {
124
128
  readonly key: string;
125
129
  readonly label: string;
130
+ /**
131
+ * `"<namespace>:<key>"` of the translated `label` (D863). `label` stays the
132
+ * mandatory English text: the hub substitutes the catalog text when the
133
+ * request language has the key, and leaves `label` alone otherwise.
134
+ */
135
+ readonly labelKey?: string;
126
136
  readonly description?: string;
137
+ /** `"<namespace>:<key>"` of the translated `description` (D863). */
138
+ readonly descriptionKey?: string;
127
139
  readonly required?: boolean;
128
140
  readonly disabled?: boolean;
129
141
  readonly placeholder?: string;
@@ -638,6 +650,8 @@ export interface ConfigInfoField {
638
650
  type: 'info';
639
651
  key: string;
640
652
  label: string;
653
+ /** `"<namespace>:<key>"` of the translated `label` (D863). */
654
+ labelKey?: string;
641
655
  content: string;
642
656
  variant?: 'info' | 'warning' | 'success' | 'danger';
643
657
  /**
@@ -672,7 +686,9 @@ export interface ConfigObjectArrayField {
672
686
  type: 'object-array';
673
687
  key: string;
674
688
  label: string;
689
+ labelKey?: string;
675
690
  description?: string;
691
+ descriptionKey?: string;
676
692
  /**
677
693
  * Column definitions in render order. The `kind` hint controls cell
678
694
  * formatting:
@@ -686,6 +702,8 @@ export interface ConfigObjectArrayField {
686
702
  columns: ReadonlyArray<{
687
703
  readonly key: string;
688
704
  readonly label: string;
705
+ /** `"<namespace>:<key>"` of the translated `label` (D863). */
706
+ readonly labelKey?: string;
689
707
  readonly kind?: 'text' | 'monospace' | 'status' | 'duration' | 'timestamp';
690
708
  /** Optional fixed width hint (CSS values: '120px', '20%', etc). */
691
709
  readonly width?: string;
@@ -698,6 +716,8 @@ export interface ConfigObjectArrayField {
698
716
  export interface ConfigOption {
699
717
  value: string;
700
718
  label: string;
719
+ /** `"<namespace>:<key>"` of the translated `label` (D863). */
720
+ labelKey?: string;
701
721
  description?: string;
702
722
  icon?: string;
703
723
  /**
@@ -40,6 +40,12 @@ export interface KeychainTransport {
40
40
  readonly deleted: number;
41
41
  }>;
42
42
  getState(): Promise<KeychainState>;
43
+ /** The device-removed purge (D864) — the device manager's transport only. */
44
+ deleteDeviceScope?(input: {
45
+ readonly deviceId: number;
46
+ }): Promise<{
47
+ readonly refs: readonly string[];
48
+ }>;
43
49
  }
44
50
  export interface SecretsAccess {
45
51
  /** The owner every ref of this handle belongs to. */
@@ -65,6 +71,12 @@ export interface SecretsAccess {
65
71
  * forked addon has no way to state an identity the transport would accept.
66
72
  */
67
73
  readonly forOwner: ((owner: string) => SecretsAccess) | null;
74
+ /**
75
+ * The device manager only (D864): delete every value scoped `device/<id>`,
76
+ * whatever its owner, when the device is removed. The keychain refuses any
77
+ * other caller; absent where the transport has no such door.
78
+ */
79
+ readonly deleteDeviceScope?: (deviceId: number) => Promise<readonly string[]>;
68
80
  }
69
81
  export interface SecretsAccessOptions {
70
82
  readonly owner: string;
package/dist/node.js CHANGED
@@ -21,8 +21,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  enumerable: true
22
22
  }) : target, mod));
23
23
  //#endregion
24
- const require_composition = require("./composition-DCYnv4I6.js");
25
- const require_err_msg = require("./err-msg-Dx2Kor0g.js");
24
+ const require_composition = require("./composition-DIp0uE_b.js");
25
+ const require_err_msg = require("./err-msg-Ls8Q6dHO.js");
26
26
  let node_crypto = require("node:crypto");
27
27
  let node_fs = require("node:fs");
28
28
  node_fs = __toESM(node_fs);
package/dist/node.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { At as Fmp4BoxSplitter, Ct as FFMPEG_PATH_ENV, Dt as getFfmpegArtifact, Et as FFMPEG_RELEASE, Ot as getFfmpegDownloadUrl, P as compositionSourceKey, Pt as buildFfmpegArgs, Rt as isSoftwareDecode, Tt as ffmpegBinaryName, a as CUSTOMIZATION_BLOCK_NAME_PREFIX, kt as canonicalHash, wt as chooseFfmpegBinary } from "./composition-C-WpVYTX.mjs";
2
- import { t as errMsg } from "./err-msg-DX6i_MY4.mjs";
1
+ import { At as Fmp4BoxSplitter, Ct as FFMPEG_PATH_ENV, Dt as getFfmpegArtifact, Et as FFMPEG_RELEASE, Ot as getFfmpegDownloadUrl, P as compositionSourceKey, Pt as buildFfmpegArgs, Rt as isSoftwareDecode, Tt as ffmpegBinaryName, a as CUSTOMIZATION_BLOCK_NAME_PREFIX, kt as canonicalHash, wt as chooseFfmpegBinary } from "./composition-EQ9Ok0Ee.mjs";
2
+ import { t as errMsg } from "./err-msg-DLerKiVO.mjs";
3
3
  import { createHash, createHmac, randomUUID, timingSafeEqual } from "node:crypto";
4
4
  import * as fs from "node:fs";
5
5
  import { chmodSync, createWriteStream, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The cadence of the automatic whole-archive face rescore (D866).
3
+ *
4
+ * One cluster-wide knob in `pipeline-orchestrator`'s GLOBAL settings, read by
5
+ * `pipeline-analytics` over the hub-routed `addon-settings` cap on every tick.
6
+ * It lives here for the same reason the detail-crop convention does: the
7
+ * writer (orchestrator) and the reader (analytics) are different addons, they
8
+ * never import each other, and a key copied by hand is how a setting silently
9
+ * stops arriving.
10
+ */
11
+ export declare const FACE_RESCORE_SECTION_ID = "face-rescore";
12
+ export declare const FACE_RESCORE_INTERVAL_KEY = "faceRescoreIntervalMinutes";
13
+ /** Slider bounds. `0` is "disabled"; anything in 1..9 is raised to `min`. */
14
+ export declare const FACE_RESCORE_INTERVAL_FIELD: {
15
+ readonly min: 0;
16
+ readonly max: 1440;
17
+ readonly step: 5;
18
+ readonly default: 60;
19
+ };
20
+ /** The smallest period that actually runs; below it (but above 0) is clamped up. */
21
+ export declare const FACE_RESCORE_INTERVAL_MIN_RUNNING = 10;
22
+ /**
23
+ * Narrow a stored value to minutes. `0` ⇒ disabled; a positive value under
24
+ * {@link FACE_RESCORE_INTERVAL_MIN_RUNNING} is raised to it; junk or absent ⇒
25
+ * the default (an unreadable setting must not switch the job off nor storm it).
26
+ */
27
+ export declare function readFaceRescoreIntervalMinutes(value: unknown): number;
28
+ /** One hydrated section of an `addon-settings.getGlobalSettings` payload. */
29
+ export interface FaceRescoreSettingsView {
30
+ readonly sections: readonly {
31
+ readonly fields: readonly unknown[];
32
+ }[];
33
+ }
34
+ /** The interval out of a hydrated payload; a `null` view (mid-boot) is the default. */
35
+ export declare function pickFaceRescoreIntervalMinutes(view: FaceRescoreSettingsView | null): number;
@@ -2922,6 +2922,13 @@ function createSecretsAccess(opts) {
2922
2922
  return result.deleted;
2923
2923
  },
2924
2924
  state: () => opts.transport.getState(),
2925
+ ...opts.transport.deleteDeviceScope === void 0 ? {} : { deleteDeviceScope: async (deviceId) => {
2926
+ const purge = opts.transport.deleteDeviceScope;
2927
+ if (purge === void 0) return [];
2928
+ const { refs } = await purge.call(opts.transport, { deviceId });
2929
+ for (const ref of refs) drop(ref);
2930
+ return refs;
2931
+ } },
2925
2932
  onChange(handler) {
2926
2933
  handlers.add(handler);
2927
2934
  return () => {
@@ -5803,6 +5810,60 @@ function isDeviceScopedCap(capName) {
5803
5810
  return DEVICE_SCOPED_CAPS.has(capName);
5804
5811
  }
5805
5812
  //#endregion
5813
+ //#region src/i18n/camstack-error.ts
5814
+ /**
5815
+ * A user-facing error with a STABLE code (D863).
5816
+ *
5817
+ * `message` is always the English text, so every consumer that knows nothing
5818
+ * of codes (old clients, logs, the mesh) behaves exactly as before. The hub's
5819
+ * tRPC error formatter reads `code` + `params` and, when the request language
5820
+ * has a text for `server:<code>`, replaces the response `message`; the code
5821
+ * stays in the payload (`data.i18n`).
5822
+ */
5823
+ /** Dotted lower-case code, e.g. `auth.invalid-credentials`. It is the key in the `server` catalog. */
5824
+ var ErrorCodeSchema = z.string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/);
5825
+ /** What travels in the error payload next to the message. */
5826
+ var ErrorI18nPayloadSchema = z.object({
5827
+ code: ErrorCodeSchema,
5828
+ params: z.record(z.string(), z.union([z.string(), z.number()])).optional()
5829
+ });
5830
+ var CamstackError = class extends Error {
5831
+ i18nCode;
5832
+ i18nParams;
5833
+ constructor(code, params, englishMessage) {
5834
+ super(englishMessage);
5835
+ this.name = "CamstackError";
5836
+ this.i18nCode = code;
5837
+ this.i18nParams = params;
5838
+ }
5839
+ };
5840
+ /** `throw userError('device.not-found', { id }, 'Device 12 not found')` */
5841
+ function userError(code, params, englishFallback) {
5842
+ return new CamstackError(code, params, englishFallback);
5843
+ }
5844
+ /**
5845
+ * Finds a code on `err` or anywhere down its `.cause` chain. Duck-typed on
5846
+ * the field so it survives a module boundary (self-contained addons).
5847
+ */
5848
+ function readErrorI18n(err) {
5849
+ let current = err;
5850
+ for (let depth = 0; depth < 8; depth++) {
5851
+ if (typeof current !== "object" || current === null) return null;
5852
+ const code = Reflect.get(current, "i18nCode");
5853
+ if (typeof code === "string") {
5854
+ const parsed = ErrorI18nPayloadSchema.safeParse({
5855
+ code,
5856
+ params: Reflect.get(current, "i18nParams")
5857
+ });
5858
+ return parsed.success ? parsed.data : null;
5859
+ }
5860
+ const cause = Reflect.get(current, "cause");
5861
+ if (cause === current) return null;
5862
+ current = cause;
5863
+ }
5864
+ return null;
5865
+ }
5866
+ //#endregion
5806
5867
  //#region src/util/boot-recovery-backoff.ts
5807
5868
  /**
5808
5869
  * The ONE retry schedule for work that can fail simply because the node was
@@ -6034,4 +6095,4 @@ function sleepCancellable(ms, signal) {
6034
6095
  });
6035
6096
  }
6036
6097
  //#endregion
6037
- export { toNodeId as $, collectSecretMarkerRefs as $t, viewerUiCapability as A, collectKeychainStoredKeys as An, createSecretsAccess as At, HISTORY_DEFAULT_MIN_INTERVAL_MS as B, PEER_BYTES_STALL_MS as Bt, isZodSecret as C, isSecretClear as Cn, SubscribeAudioChunksResultSchema as Ct, RUNTIME_DEFAULTS as D, makeSecretMarker as Dn, selectAssignedProfileSlots as Dt, HF_REPO as E, isSecretMarkerLike as En, parseProfileBrokerId as Et, deviceCustomAction as F, AUDIO_CHUNK_FORMATS as Fn, registerKnownSecret as Ft, isDeviceConfigCap as G, DisposerChain as Gt, PROVIDER_PIN_FIELD as H, PeerBytesTicketSchema as Ht, adminUiCapability as I, audioChunkBytesPerSample as In, scrubKnownSecrets as It, resolveCapMount as J, mergeSecretStatePaths as Jt, method as K, BaseAddon as Kt, DEFAULT_RUNTIME_STATE_DURABILITY as L, expandAudioChunkToF32le as Ln, shortSecretRefHash as Lt, customAction as M, isKeychainStoredField as Mn, clearKnownSecrets as Mt, defineCustomActions as N, isSecretConfigField as Nn, forgetKnownSecret as Nt, RawStateResultSchema as O, toSecretFieldView as On, resolveSecretViewsIn as Ot, describeCustomActions as P, schemaDeclaresAnyField as Pn, knownSecretCount as Pt, readNodePin as Q, KeychainWriteRefusedError as Qt, DEVICE_SETTINGS_CONTRIBUTION_METHODS as R, isAudioChunkFormat as Rn, PEER_BYTES_CHUNK_BYTES as Rt, collectZodSecretPaths as S, classifySecretWrite as Sn, SubscribeAudioChunksInputSchema as St, HF_BASE_URL as T, isSecretMarker as Tn, makeSourceBrokerId as Tt, event as U, DATAPLANE_SECRET_HEADER as Ut, HISTORY_UNIT_LABELS as V, PEER_BYTES_TICKET_TTL_MS as Vt, expandCapMethods as W, SHARE_VIEW_KINDS as Wt, CAP_NODE_PIN_CONTEXT_KEY as X, secretTreeFromPaths as Xt, systemMethod as Y, parseSecretStatePath as Yt, nodePin as Z, secretTreeFromSchema as Zt, createEventBusSliceSource as _, collectHydratedFieldEntries as _n, ProfileRtspEntrySchema as _t, asJsonArray as a, formatSecretScope as an, scopeKey as at, createSliceHandle as b, resolveHydratedFieldValue as bn, StreamSourceEntrySchema$1 as bt, asString as c, normalizeSecretOwner as cn, BrokerStatsSchema as ct, parseJsonUnknown as d, createDurableState as dn, CamProfileSchema as dt, resolveSecretMarkers as en, MODEL_FORMATS as et, hfModelUrl as f, createEvent as fn, CamStreamKindSchema as ft, createDeviceProxy as g, WELL_KNOWN_TAB_MAP as gn, FrameHandleSchema as gt, isDeviceScopedCap as h, WELL_KNOWN_TABS as hn, DecodedAudioChunkSchema as ht, asBoolean as i, buildSecretRef as in, readinessKey as it, DEVICE_CHILDREN_BATCH_MAX as j, collectSecretConfigKeys as jn, MIN_SCRUBBED_LENGTH as jt, deviceOpsCapability as k, REDACTED_SECRET as kn, REVALIDATE_AFTER_MS as kt, parseJsonArray as l, parseSecretRef as ln, BrokerStatusSchema as lt, DEVICE_SCOPED_CAPS as m, isEvent as mn, CameraStreamSchema as mt, sleepCancellable as n, SECRET_REF_SCHEME as nn, ReadinessTimeoutError as nt, asJsonObject as o, globalSecretScope as on, AudioChunkFormatSchema as ot, BOOT_RECOVERY_BACKOFF_MS as p, emitReadiness as pn, CamStreamResolutionSchema as pt, optionalMethod as q, normalizeAddonInitResult as qt, maskUrlCredentials as r, arrayItemFieldPath as rn, emitDownForOwnedCaps as rt, asNumber as s, isSecretRef as sn, AudioStreamPickSchema as st, sleep as t, transformSecretWrite as tn, ReadinessRegistry as tt, parseJsonObject as u, normalizeNodeId as un, CAM_PROFILE_ORDER as ut, createLazyTrpcSource as v, collectHydratedFieldValues as vn, ProfileSlotSchema as vt, DEFAULT_TOKEN_EXPIRY as w, isSecretFieldView as wn, makeProfileBrokerId as wt, SECRET_META as x, SECRET_CLEAR as xn, StreamSourceSchema as xt, createMirrorSource as y, hydrateSchema as yn, ProfileSlotStatusSchema as yt, DEVICE_STATUS_METHOD as z, PEER_BYTES_MAX_OUTSTANDING as zt };
6098
+ export { resolveCapMount as $, mergeSecretStatePaths as $t, HF_BASE_URL as A, isSecretMarker as An, makeSourceBrokerId as At, deviceCustomAction as B, AUDIO_CHUNK_FORMATS as Bn, registerKnownSecret as Bt, createLazyTrpcSource as C, collectHydratedFieldValues as Cn, ProfileSlotSchema as Ct, collectZodSecretPaths as D, classifySecretWrite as Dn, SubscribeAudioChunksInputSchema as Dt, SECRET_META as E, SECRET_CLEAR as En, StreamSourceSchema as Et, viewerUiCapability as F, collectKeychainStoredKeys as Fn, createSecretsAccess as Ft, HISTORY_DEFAULT_MIN_INTERVAL_MS as G, PEER_BYTES_STALL_MS as Gt, DEFAULT_RUNTIME_STATE_DURABILITY as H, expandAudioChunkToF32le as Hn, shortSecretRefHash as Ht, DEVICE_CHILDREN_BATCH_MAX as I, collectSecretConfigKeys as In, MIN_SCRUBBED_LENGTH as It, event as J, DATAPLANE_SECRET_HEADER as Jt, HISTORY_UNIT_LABELS as K, PEER_BYTES_TICKET_TTL_MS as Kt, customAction as L, isKeychainStoredField as Ln, clearKnownSecrets as Lt, RUNTIME_DEFAULTS as M, makeSecretMarker as Mn, selectAssignedProfileSlots as Mt, RawStateResultSchema as N, toSecretFieldView as Nn, resolveSecretViewsIn as Nt, isZodSecret as O, isSecretClear as On, SubscribeAudioChunksResultSchema as Ot, deviceOpsCapability as P, REDACTED_SECRET as Pn, REVALIDATE_AFTER_MS as Pt, optionalMethod as Q, normalizeAddonInitResult as Qt, defineCustomActions as R, isSecretConfigField as Rn, forgetKnownSecret as Rt, createEventBusSliceSource as S, collectHydratedFieldEntries as Sn, ProfileRtspEntrySchema as St, createSliceHandle as T, resolveHydratedFieldValue as Tn, StreamSourceEntrySchema$1 as Tt, DEVICE_SETTINGS_CONTRIBUTION_METHODS as U, isAudioChunkFormat as Un, PEER_BYTES_CHUNK_BYTES as Ut, adminUiCapability as V, audioChunkBytesPerSample as Vn, scrubKnownSecrets as Vt, DEVICE_STATUS_METHOD as W, PEER_BYTES_MAX_OUTSTANDING as Wt, isDeviceConfigCap as X, DisposerChain as Xt, expandCapMethods as Y, SHARE_VIEW_KINDS as Yt, method as Z, BaseAddon as Zt, readErrorI18n as _, createEvent as _n, CamStreamKindSchema as _t, asJsonArray as a, resolveSecretMarkers as an, MODEL_FORMATS as at, isDeviceScopedCap as b, WELL_KNOWN_TABS as bn, DecodedAudioChunkSchema as bt, asString as c, arrayItemFieldPath as cn, emitDownForOwnedCaps as ct, parseJsonUnknown as d, globalSecretScope as dn, AudioChunkFormatSchema as dt, parseSecretStatePath as en, systemMethod as et, hfModelUrl as f, isSecretRef as fn, AudioStreamPickSchema as ft, ErrorI18nPayloadSchema as g, createDurableState as gn, CamProfileSchema as gt, ErrorCodeSchema as h, normalizeNodeId as hn, CAM_PROFILE_ORDER as ht, asBoolean as i, collectSecretMarkerRefs as in, toNodeId as it, HF_REPO as j, isSecretMarkerLike as jn, parseProfileBrokerId as jt, DEFAULT_TOKEN_EXPIRY as k, isSecretFieldView as kn, makeProfileBrokerId as kt, parseJsonArray as l, buildSecretRef as ln, readinessKey as lt, CamstackError as m, parseSecretRef as mn, BrokerStatusSchema as mt, sleepCancellable as n, secretTreeFromSchema as nn, nodePin as nt, asJsonObject as o, transformSecretWrite as on, ReadinessRegistry as ot, BOOT_RECOVERY_BACKOFF_MS as p, normalizeSecretOwner as pn, BrokerStatsSchema as pt, PROVIDER_PIN_FIELD as q, PeerBytesTicketSchema as qt, maskUrlCredentials as r, KeychainWriteRefusedError as rn, readNodePin as rt, asNumber as s, SECRET_REF_SCHEME as sn, ReadinessTimeoutError as st, sleep as t, secretTreeFromPaths as tn, CAP_NODE_PIN_CONTEXT_KEY as tt, parseJsonObject as u, formatSecretScope as un, scopeKey as ut, userError as v, emitReadiness as vn, CamStreamResolutionSchema as vt, createMirrorSource as w, hydrateSchema as wn, ProfileSlotStatusSchema as wt, createDeviceProxy as x, WELL_KNOWN_TAB_MAP as xn, FrameHandleSchema as xt, DEVICE_SCOPED_CAPS as y, isEvent as yn, CameraStreamSchema as yt, describeCustomActions as z, schemaDeclaresAnyField as zn, knownSecretCount as zt };
@@ -2922,6 +2922,13 @@ function createSecretsAccess(opts) {
2922
2922
  return result.deleted;
2923
2923
  },
2924
2924
  state: () => opts.transport.getState(),
2925
+ ...opts.transport.deleteDeviceScope === void 0 ? {} : { deleteDeviceScope: async (deviceId) => {
2926
+ const purge = opts.transport.deleteDeviceScope;
2927
+ if (purge === void 0) return [];
2928
+ const { refs } = await purge.call(opts.transport, { deviceId });
2929
+ for (const ref of refs) drop(ref);
2930
+ return refs;
2931
+ } },
2925
2932
  onChange(handler) {
2926
2933
  handlers.add(handler);
2927
2934
  return () => {
@@ -5803,6 +5810,60 @@ function isDeviceScopedCap(capName) {
5803
5810
  return DEVICE_SCOPED_CAPS.has(capName);
5804
5811
  }
5805
5812
  //#endregion
5813
+ //#region src/i18n/camstack-error.ts
5814
+ /**
5815
+ * A user-facing error with a STABLE code (D863).
5816
+ *
5817
+ * `message` is always the English text, so every consumer that knows nothing
5818
+ * of codes (old clients, logs, the mesh) behaves exactly as before. The hub's
5819
+ * tRPC error formatter reads `code` + `params` and, when the request language
5820
+ * has a text for `server:<code>`, replaces the response `message`; the code
5821
+ * stays in the payload (`data.i18n`).
5822
+ */
5823
+ /** Dotted lower-case code, e.g. `auth.invalid-credentials`. It is the key in the `server` catalog. */
5824
+ var ErrorCodeSchema = zod.z.string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/);
5825
+ /** What travels in the error payload next to the message. */
5826
+ var ErrorI18nPayloadSchema = zod.z.object({
5827
+ code: ErrorCodeSchema,
5828
+ params: zod.z.record(zod.z.string(), zod.z.union([zod.z.string(), zod.z.number()])).optional()
5829
+ });
5830
+ var CamstackError = class extends Error {
5831
+ i18nCode;
5832
+ i18nParams;
5833
+ constructor(code, params, englishMessage) {
5834
+ super(englishMessage);
5835
+ this.name = "CamstackError";
5836
+ this.i18nCode = code;
5837
+ this.i18nParams = params;
5838
+ }
5839
+ };
5840
+ /** `throw userError('device.not-found', { id }, 'Device 12 not found')` */
5841
+ function userError(code, params, englishFallback) {
5842
+ return new CamstackError(code, params, englishFallback);
5843
+ }
5844
+ /**
5845
+ * Finds a code on `err` or anywhere down its `.cause` chain. Duck-typed on
5846
+ * the field so it survives a module boundary (self-contained addons).
5847
+ */
5848
+ function readErrorI18n(err) {
5849
+ let current = err;
5850
+ for (let depth = 0; depth < 8; depth++) {
5851
+ if (typeof current !== "object" || current === null) return null;
5852
+ const code = Reflect.get(current, "i18nCode");
5853
+ if (typeof code === "string") {
5854
+ const parsed = ErrorI18nPayloadSchema.safeParse({
5855
+ code,
5856
+ params: Reflect.get(current, "i18nParams")
5857
+ });
5858
+ return parsed.success ? parsed.data : null;
5859
+ }
5860
+ const cause = Reflect.get(current, "cause");
5861
+ if (cause === current) return null;
5862
+ current = cause;
5863
+ }
5864
+ return null;
5865
+ }
5866
+ //#endregion
5806
5867
  //#region src/util/boot-recovery-backoff.ts
5807
5868
  /**
5808
5869
  * The ONE retry schedule for work that can fail simply because the node was
@@ -6112,6 +6173,12 @@ Object.defineProperty(exports, "CameraStreamSchema", {
6112
6173
  return CameraStreamSchema;
6113
6174
  }
6114
6175
  });
6176
+ Object.defineProperty(exports, "CamstackError", {
6177
+ enumerable: true,
6178
+ get: function() {
6179
+ return CamstackError;
6180
+ }
6181
+ });
6115
6182
  Object.defineProperty(exports, "DATAPLANE_SECRET_HEADER", {
6116
6183
  enumerable: true,
6117
6184
  get: function() {
@@ -6166,6 +6233,18 @@ Object.defineProperty(exports, "DisposerChain", {
6166
6233
  return DisposerChain;
6167
6234
  }
6168
6235
  });
6236
+ Object.defineProperty(exports, "ErrorCodeSchema", {
6237
+ enumerable: true,
6238
+ get: function() {
6239
+ return ErrorCodeSchema;
6240
+ }
6241
+ });
6242
+ Object.defineProperty(exports, "ErrorI18nPayloadSchema", {
6243
+ enumerable: true,
6244
+ get: function() {
6245
+ return ErrorI18nPayloadSchema;
6246
+ }
6247
+ });
6169
6248
  Object.defineProperty(exports, "FrameHandleSchema", {
6170
6249
  enumerable: true,
6171
6250
  get: function() {
@@ -6784,6 +6863,12 @@ Object.defineProperty(exports, "parseSecretStatePath", {
6784
6863
  return parseSecretStatePath;
6785
6864
  }
6786
6865
  });
6866
+ Object.defineProperty(exports, "readErrorI18n", {
6867
+ enumerable: true,
6868
+ get: function() {
6869
+ return readErrorI18n;
6870
+ }
6871
+ });
6787
6872
  Object.defineProperty(exports, "readNodePin", {
6788
6873
  enumerable: true,
6789
6874
  get: function() {
@@ -6904,6 +6989,12 @@ Object.defineProperty(exports, "transformSecretWrite", {
6904
6989
  return transformSecretWrite;
6905
6990
  }
6906
6991
  });
6992
+ Object.defineProperty(exports, "userError", {
6993
+ enumerable: true,
6994
+ get: function() {
6995
+ return userError;
6996
+ }
6997
+ });
6907
6998
  Object.defineProperty(exports, "viewerUiCapability", {
6908
6999
  enumerable: true,
6909
7000
  get: function() {
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * The hub's human name (D861): ONE `system-settings` row, `server.name`.
4
+ *
5
+ * Nothing writes it by itself. An unset name is not an error and not a stored
6
+ * default: every reader falls back to the machine hostname and says so with
7
+ * `isDefault: true`, so a consumer can tell a name somebody chose from one the
8
+ * hub made up.
9
+ */
10
+ /** The `system-settings` key of the stored name. */
11
+ export declare const SERVER_NAME_SETTING_KEY = "server.name";
12
+ /** The longest a name may be, after trimming. */
13
+ export declare const SERVER_NAME_MAX_LENGTH = 48;
14
+ /** A name an operator may save: trimmed, 1-48 characters, no control characters. */
15
+ export declare const ServerNameSchema: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
16
+ /** What every reader gets: the name to show, and whether the hub chose it itself. */
17
+ export declare const ServerNameInfoSchema: z.ZodObject<{
18
+ name: z.ZodString;
19
+ isDefault: z.ZodBoolean;
20
+ }, z.core.$strip>;
21
+ export type ServerNameInfo = z.infer<typeof ServerNameInfoSchema>;
22
+ /** What an unset name shows when the hostname says nothing about the hub. */
23
+ export declare const SERVER_NAME_FALLBACK = "CamStack";
24
+ /**
25
+ * The hostname without its domain (`nas.lan.example` becomes `nas`). A hostname
26
+ * that names nothing (empty, `localhost`, a container id) yields
27
+ * {@link SERVER_NAME_FALLBACK}.
28
+ */
29
+ export declare function shortHostname(hostname: string): string;
30
+ /**
31
+ * Resolve a stored value (whatever the row held, `undefined` when unset) and the
32
+ * machine hostname into what readers show. A stored value that does not
33
+ * validate is treated as unset: a damaged row must not title the hub.
34
+ */
35
+ export declare function resolveServerName(stored: unknown, hostname: string): ServerNameInfo;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.372",
3
+ "version": "1.2.374",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",