@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.
- package/dist/addon.d.ts +2 -0
- package/dist/addon.js +6 -3
- package/dist/addon.mjs +5 -4
- package/dist/auth/app-flow.d.ts +12 -1
- package/dist/capabilities/addon-settings.cap.d.ts +10 -0
- package/dist/capabilities/core-blocks.cap.d.ts +2 -0
- package/dist/capabilities/device-manager.cap.d.ts +78 -0
- package/dist/capabilities/device-removal-hook.cap.d.ts +93 -0
- package/dist/capabilities/index.d.ts +6 -3
- package/dist/capabilities/keychain.cap.d.ts +11 -0
- package/dist/capabilities/sso-bridge.cap.d.ts +12 -0
- package/dist/capabilities/system.cap.d.ts +4 -0
- package/dist/client.js +3 -0
- package/dist/client.mjs +3 -0
- package/dist/{composition-DCYnv4I6.js → composition-DIp0uE_b.js} +1 -1
- package/dist/{composition-C-WpVYTX.mjs → composition-EQ9Ok0Ee.mjs} +1 -1
- package/dist/device/device-removal-reconcile.d.ts +49 -0
- package/dist/device/device-type.d.ts +16 -0
- package/dist/{err-msg-DX6i_MY4.mjs → err-msg-DLerKiVO.mjs} +16 -0
- package/dist/{err-msg-Dx2Kor0g.js → err-msg-Ls8Q6dHO.js} +16 -0
- package/dist/generated/addon-api.d.ts +60 -0
- package/dist/generated/capability-router-map.d.ts +5 -2
- package/dist/generated/collection-array-methods.d.ts +1 -1
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/method-device-selectors.d.ts +2 -2
- package/dist/generated/system-proxy.d.ts +1 -1
- package/dist/i18n/camstack-error.d.ts +31 -0
- package/dist/i18n/translation.d.ts +39 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.js +535 -18
- package/dist/index.mjs +499 -19
- package/dist/interfaces/addon.d.ts +11 -0
- package/dist/interfaces/config-ui.d.ts +20 -0
- package/dist/keychain/secrets-access.d.ts +12 -0
- package/dist/node.js +2 -2
- package/dist/node.mjs +2 -2
- package/dist/pipeline/face-rescore-schedule.d.ts +35 -0
- package/dist/{sleep-DAX0-2v9.mjs → sleep-DRqxtc0C.mjs} +62 -1
- package/dist/{sleep-DnQ5WsMI.js → sleep-rqlHXgwb.js} +91 -0
- package/dist/system/server-name.d.ts +35 -0
- 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-
|
|
25
|
-
const require_err_msg = require("./err-msg-
|
|
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-
|
|
2
|
-
import { t as errMsg } from "./err-msg-
|
|
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 {
|
|
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;
|