@camstack/types 1.2.122 → 1.2.124
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.js +1 -1
- package/dist/addon.mjs +1 -1
- package/dist/capabilities/intercom.cap.d.ts +27 -0
- package/dist/capabilities/pipeline-analytics.cap.d.ts +25 -0
- package/dist/capabilities/storage-migration.cap.d.ts +47 -0
- package/dist/capabilities/storage.cap.d.ts +15 -0
- package/dist/generated/addon-api.d.ts +7 -0
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/index.js +209 -20
- package/dist/index.mjs +205 -21
- package/dist/interfaces/relocate.d.ts +189 -6
- package/dist/{sleep-DUxF5DdC.js → sleep-CJrvRDlD.js} +1 -0
- package/dist/{sleep-C9C8EoK8.mjs → sleep-L5-bG_a_.mjs} +1 -0
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_event_category = require("./event-category-BaEgqJNv.js");
|
|
3
|
-
const require_sleep = require("./sleep-
|
|
3
|
+
const require_sleep = require("./sleep-CJrvRDlD.js");
|
|
4
4
|
const require_err_msg = require("./err-msg-COpsHMw2.js");
|
|
5
5
|
//#region src/generated/cap-input-defaults.ts
|
|
6
6
|
/**
|
package/dist/addon.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as EventCategory } from "./event-category-BZL-fdNj.mjs";
|
|
2
|
-
import { B as ReadinessRegistry, E as adminUiCapability, L as nodePin, R as readNodePin, St as emitReadiness, T as DeviceType, V as ReadinessTimeoutError, W as scopeKey, _t as DisposerChain, a as asJsonObject, b as deviceOpsCapability, d as BOOT_RECOVERY_BACKOFF_MS, f as DEVICE_SCOPED_CAPS, gt as DATAPLANE_SECRET_HEADER, h as createEventBusSliceSource, j as expandCapMethods, m as createDeviceProxy, p as isDeviceScopedCap, s as asString, t as sleep, u as parseJsonUnknown, vt as BaseAddon, x as viewerUiCapability, yt as normalizeAddonInitResult } from "./sleep-
|
|
2
|
+
import { B as ReadinessRegistry, E as adminUiCapability, L as nodePin, R as readNodePin, St as emitReadiness, T as DeviceType, V as ReadinessTimeoutError, W as scopeKey, _t as DisposerChain, a as asJsonObject, b as deviceOpsCapability, d as BOOT_RECOVERY_BACKOFF_MS, f as DEVICE_SCOPED_CAPS, gt as DATAPLANE_SECRET_HEADER, h as createEventBusSliceSource, j as expandCapMethods, m as createDeviceProxy, p as isDeviceScopedCap, s as asString, t as sleep, u as parseJsonUnknown, vt as BaseAddon, x as viewerUiCapability, yt as normalizeAddonInitResult } from "./sleep-L5-bG_a_.mjs";
|
|
3
3
|
import { t as errMsg } from "./err-msg-IQTHeDzc.mjs";
|
|
4
4
|
//#region src/generated/cap-input-defaults.ts
|
|
5
5
|
/**
|
|
@@ -69,6 +69,33 @@ export declare const intercomCapability: {
|
|
|
69
69
|
readonly deviceNative: true;
|
|
70
70
|
readonly mode: "singleton";
|
|
71
71
|
readonly deviceTypes: readonly [DeviceType.Camera];
|
|
72
|
+
/**
|
|
73
|
+
* **Auth tier: `protected` on every method — deliberate, and load-bearing.**
|
|
74
|
+
*
|
|
75
|
+
* Talking through a camera is an OPERATE action, not a CONFIGURE one. This
|
|
76
|
+
* cap has no configuration surface at all: all six methods open, feed and
|
|
77
|
+
* close one live audio session against one `deviceId`. That is the same
|
|
78
|
+
* authority as `ptz.move` or `snapshot.getSnapshot`, both `protected` — and
|
|
79
|
+
* the opposite of `ptz.savePreset` / `snapshot.invalidateCache`, which are
|
|
80
|
+
* `admin` because they change what the device IS.
|
|
81
|
+
*
|
|
82
|
+
* `protected` does not mean ungated: `protectedProcedure` runs the
|
|
83
|
+
* `METHOD_ACCESS_MAP` scope check, and every method here is `scope: 'device'`
|
|
84
|
+
* with `access: 'create'` and a `deviceId` in its input. So a caller needs a
|
|
85
|
+
* grant that covers THAT camera at `create` — a `camera-viewer` (`view`
|
|
86
|
+
* only) still cannot talk, and a grant on camera 5 cannot talk through
|
|
87
|
+
* camera 7.
|
|
88
|
+
*
|
|
89
|
+
* Every method was `auth: 'admin'` from the initial commit, which made the
|
|
90
|
+
* cap unreachable by every non-admin principal — `adminProcedure` throws
|
|
91
|
+
* `FORBIDDEN: Admin required` BEFORE the scope check runs, so the scope
|
|
92
|
+
* machinery generated for this cap (`METHOD_ACCESS_MAP`,
|
|
93
|
+
* `DEVICE_SCOPED_CAPS`, `METHOD_DEVICE_SELECTORS`) was complete and dead. The
|
|
94
|
+
* `camera-operator` scope preset has promised "PTZ control, intercom,
|
|
95
|
+
* snapshots" since that same commit; the promise could not be kept. Recorded
|
|
96
|
+
* as D289; `scripts/check-scope-preset-promises.ts` now fails the build if a
|
|
97
|
+
* preset promises a cap no row of that preset can reach.
|
|
98
|
+
*/
|
|
72
99
|
readonly methods: {
|
|
73
100
|
/**
|
|
74
101
|
* Open a server-side WebRTC audio-only session. Returns an SDP
|
|
@@ -2394,6 +2394,11 @@ export declare const pipelineAnalyticsCapability: {
|
|
|
2394
2394
|
readonly startStorageMigrationMove: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
2395
2395
|
toLocationId: z.ZodString;
|
|
2396
2396
|
throttleMbps: z.ZodOptional<z.ZodNumber>;
|
|
2397
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
2398
|
+
move: "move";
|
|
2399
|
+
seal: "seal";
|
|
2400
|
+
gallery: "gallery";
|
|
2401
|
+
}>>;
|
|
2397
2402
|
leaseId: z.ZodString;
|
|
2398
2403
|
}, z.core.$strip>, z.ZodObject<{
|
|
2399
2404
|
jobId: z.ZodString;
|
|
@@ -2436,9 +2441,29 @@ export declare const pipelineAnalyticsCapability: {
|
|
|
2436
2441
|
readonly relocateMedia: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
2437
2442
|
toLocationId: z.ZodString;
|
|
2438
2443
|
throttleMbps: z.ZodOptional<z.ZodNumber>;
|
|
2444
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
2445
|
+
move: "move";
|
|
2446
|
+
seal: "seal";
|
|
2447
|
+
gallery: "gallery";
|
|
2448
|
+
}>>;
|
|
2439
2449
|
}, z.core.$strip>, z.ZodObject<{
|
|
2440
2450
|
jobId: z.ZodString;
|
|
2441
2451
|
}, z.core.$strip>, "mutation">;
|
|
2452
|
+
/**
|
|
2453
|
+
* How many media / retrain rows still carry NO `locationId`.
|
|
2454
|
+
*
|
|
2455
|
+
* A NULL row means "wherever `eventMedia` points NOW", so the instant a
|
|
2456
|
+
* repoint moves that pointer every such row reads from the new disk while
|
|
2457
|
+
* its bytes are on the old one — the archive goes dark until a drain
|
|
2458
|
+
* happens to stamp it. This count is what the migration planner's
|
|
2459
|
+
* non-blocking gate reads; `relocateMedia({ mode: 'seal' })` is what drives
|
|
2460
|
+
* it to zero.
|
|
2461
|
+
*/
|
|
2462
|
+
readonly countUnstampedEventMedia: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
|
|
2463
|
+
media: z.ZodNumber;
|
|
2464
|
+
retrainFrames: z.ZodNumber;
|
|
2465
|
+
total: z.ZodNumber;
|
|
2466
|
+
}, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
|
|
2442
2467
|
/** Every relocate job this addon knows about, newest first (in RAM: the
|
|
2443
2468
|
* move is resumable, so a lost list costs nothing but the display). */
|
|
2444
2469
|
readonly listRelocateMediaJobs: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{}, z.core.$strip>, z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
@@ -15,31 +15,68 @@ export declare const storageMigrationCapability: {
|
|
|
15
15
|
recordings: z.ZodOptional<z.ZodString>;
|
|
16
16
|
recordingsLow: z.ZodOptional<z.ZodString>;
|
|
17
17
|
eventMedia: z.ZodOptional<z.ZodString>;
|
|
18
|
+
backups: z.ZodOptional<z.ZodString>;
|
|
19
|
+
galleryMedia: z.ZodOptional<z.ZodString>;
|
|
18
20
|
}, z.core.$strip>;
|
|
19
21
|
throttleMbps: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
23
|
+
blocking: "blocking";
|
|
24
|
+
nonBlocking: "nonBlocking";
|
|
25
|
+
}>>;
|
|
20
26
|
}, z.core.$strip>, z.ZodObject<{
|
|
21
27
|
destinations: z.ZodObject<{
|
|
22
28
|
recordings: z.ZodOptional<z.ZodString>;
|
|
23
29
|
recordingsLow: z.ZodOptional<z.ZodString>;
|
|
24
30
|
eventMedia: z.ZodOptional<z.ZodString>;
|
|
31
|
+
backups: z.ZodOptional<z.ZodString>;
|
|
32
|
+
galleryMedia: z.ZodOptional<z.ZodString>;
|
|
25
33
|
}, z.core.$strip>;
|
|
34
|
+
mode: z.ZodEnum<{
|
|
35
|
+
blocking: "blocking";
|
|
36
|
+
nonBlocking: "nonBlocking";
|
|
37
|
+
}>;
|
|
26
38
|
moves: z.ZodArray<z.ZodObject<{
|
|
27
39
|
storageClass: z.ZodEnum<{
|
|
28
40
|
recordings: "recordings";
|
|
29
41
|
recordingsLow: "recordingsLow";
|
|
30
42
|
eventMedia: "eventMedia";
|
|
43
|
+
backups: "backups";
|
|
44
|
+
galleryMedia: "galleryMedia";
|
|
31
45
|
}>;
|
|
32
46
|
fromLocationId: z.ZodString;
|
|
33
47
|
toLocationId: z.ZodString;
|
|
34
48
|
}, z.core.$strip>>;
|
|
49
|
+
findings: z.ZodArray<z.ZodObject<{
|
|
50
|
+
code: z.ZodEnum<{
|
|
51
|
+
sharesDeviceWithSource: "sharesDeviceWithSource";
|
|
52
|
+
deviceIdentityUnknown: "deviceIdentityUnknown";
|
|
53
|
+
unstampedEventMediaRows: "unstampedEventMediaRows";
|
|
54
|
+
blockingOnly: "blockingOnly";
|
|
55
|
+
noMover: "noMover";
|
|
56
|
+
}>;
|
|
57
|
+
storageClass: z.ZodEnum<{
|
|
58
|
+
recordings: "recordings";
|
|
59
|
+
recordingsLow: "recordingsLow";
|
|
60
|
+
eventMedia: "eventMedia";
|
|
61
|
+
backups: "backups";
|
|
62
|
+
galleryMedia: "galleryMedia";
|
|
63
|
+
}>;
|
|
64
|
+
message: z.ZodString;
|
|
65
|
+
}, z.core.$strip>>;
|
|
35
66
|
}, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
|
|
36
67
|
readonly start: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
37
68
|
destinations: z.ZodObject<{
|
|
38
69
|
recordings: z.ZodOptional<z.ZodString>;
|
|
39
70
|
recordingsLow: z.ZodOptional<z.ZodString>;
|
|
40
71
|
eventMedia: z.ZodOptional<z.ZodString>;
|
|
72
|
+
backups: z.ZodOptional<z.ZodString>;
|
|
73
|
+
galleryMedia: z.ZodOptional<z.ZodString>;
|
|
41
74
|
}, z.core.$strip>;
|
|
42
75
|
throttleMbps: z.ZodOptional<z.ZodNumber>;
|
|
76
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
77
|
+
blocking: "blocking";
|
|
78
|
+
nonBlocking: "nonBlocking";
|
|
79
|
+
}>>;
|
|
43
80
|
}, z.core.$strip>, z.ZodObject<{
|
|
44
81
|
jobId: z.ZodString;
|
|
45
82
|
}, z.core.$strip>, "mutation">;
|
|
@@ -54,15 +91,23 @@ export declare const storageMigrationCapability: {
|
|
|
54
91
|
done: "done";
|
|
55
92
|
cancelled: "cancelled";
|
|
56
93
|
planning: "planning";
|
|
94
|
+
sealing: "sealing";
|
|
57
95
|
pausing: "pausing";
|
|
96
|
+
draining: "draining";
|
|
58
97
|
repointing: "repointing";
|
|
59
98
|
refreshing: "refreshing";
|
|
60
99
|
resuming: "resuming";
|
|
61
100
|
}>;
|
|
101
|
+
mode: z.ZodEnum<{
|
|
102
|
+
blocking: "blocking";
|
|
103
|
+
nonBlocking: "nonBlocking";
|
|
104
|
+
}>;
|
|
62
105
|
destinations: z.ZodObject<{
|
|
63
106
|
recordings: z.ZodOptional<z.ZodString>;
|
|
64
107
|
recordingsLow: z.ZodOptional<z.ZodString>;
|
|
65
108
|
eventMedia: z.ZodOptional<z.ZodString>;
|
|
109
|
+
backups: z.ZodOptional<z.ZodString>;
|
|
110
|
+
galleryMedia: z.ZodOptional<z.ZodString>;
|
|
66
111
|
}, z.core.$strip>;
|
|
67
112
|
throttleMbps: z.ZodNumber;
|
|
68
113
|
moves: z.ZodArray<z.ZodObject<{
|
|
@@ -70,6 +115,8 @@ export declare const storageMigrationCapability: {
|
|
|
70
115
|
recordings: "recordings";
|
|
71
116
|
recordingsLow: "recordingsLow";
|
|
72
117
|
eventMedia: "eventMedia";
|
|
118
|
+
backups: "backups";
|
|
119
|
+
galleryMedia: "galleryMedia";
|
|
73
120
|
}>;
|
|
74
121
|
fromLocationId: z.ZodString;
|
|
75
122
|
toLocationId: z.ZodString;
|
|
@@ -169,8 +169,23 @@ export declare const storageCapability: {
|
|
|
169
169
|
createdAt: z.ZodNumber;
|
|
170
170
|
updatedAt: z.ZodNumber;
|
|
171
171
|
}, z.core.$strip>, "mutation">;
|
|
172
|
+
/**
|
|
173
|
+
* Remove a location record. REFUSES a location that still holds data —
|
|
174
|
+
* deleting a drained location whose durable rows still name it is how this
|
|
175
|
+
* hub acquired 2 131 ghost `recordings:high` segments, and playback does
|
|
176
|
+
* not stat, so the operator sees a silent black window rather than an
|
|
177
|
+
* error.
|
|
178
|
+
*
|
|
179
|
+
* `force` exists because the occupancy check is BEST-EFFORT and refuses on
|
|
180
|
+
* "unknown" as well as on "occupied" (a read that fails must not authorise
|
|
181
|
+
* a destruction — D49). A location on a removed disk, on another node, or
|
|
182
|
+
* behind a remote provider answers "unknown" forever, and a refusal an
|
|
183
|
+
* operator cannot override is its own failure mode. `force: true` is
|
|
184
|
+
* logged, loudly, with what the check saw.
|
|
185
|
+
*/
|
|
172
186
|
readonly deleteLocation: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
173
187
|
id: z.ZodString;
|
|
188
|
+
force: z.ZodOptional<z.ZodBoolean>;
|
|
174
189
|
}, z.core.$strip>, z.ZodVoid, "mutation">;
|
|
175
190
|
readonly testLocation: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
176
191
|
id: z.ZodString;
|
|
@@ -5121,6 +5121,13 @@ export type AppRouter = TrpcCoreRouter<{
|
|
|
5121
5121
|
output: z.infer<typeof pipelineAnalyticsCapability.methods.relocateMedia.output>;
|
|
5122
5122
|
meta: object;
|
|
5123
5123
|
}>;
|
|
5124
|
+
countUnstampedEventMedia: TRPCQueryProcedure<{
|
|
5125
|
+
input: {
|
|
5126
|
+
[x: string]: unknown;
|
|
5127
|
+
} & z.input<typeof pipelineAnalyticsCapability.methods.countUnstampedEventMedia.input>;
|
|
5128
|
+
output: z.infer<typeof pipelineAnalyticsCapability.methods.countUnstampedEventMedia.output>;
|
|
5129
|
+
meta: object;
|
|
5130
|
+
}>;
|
|
5124
5131
|
listRelocateMediaJobs: TRPCQueryProcedure<{
|
|
5125
5132
|
input: {
|
|
5126
5133
|
[x: string]: unknown;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* scope+access check inside `protectedProcedure` (see
|
|
7
7
|
* `server/backend/src/api/trpc/trpc.middleware.ts`).
|
|
8
8
|
*
|
|
9
|
-
* Coverage:
|
|
9
|
+
* Coverage: 979 method paths across 126 capabilities.
|
|
10
10
|
*/
|
|
11
11
|
import type { CapabilityMethodAccess } from '../capabilities/capability-definition.js';
|
|
12
12
|
export interface MethodAccessRecord {
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_event_category = require("./event-category-BaEgqJNv.js");
|
|
3
|
-
const require_sleep = require("./sleep-
|
|
3
|
+
const require_sleep = require("./sleep-CJrvRDlD.js");
|
|
4
4
|
const require_canonical_hash = require("./canonical-hash-DNV8S5ET.js");
|
|
5
5
|
const require_enums = require("./enums.js");
|
|
6
6
|
const require_err_msg = require("./err-msg-COpsHMw2.js");
|
|
@@ -2225,18 +2225,61 @@ var RelocateFootageInputSchema = zod.z.object({
|
|
|
2225
2225
|
* `RecordingConfig.enabled` or camera wrapper bindings. */
|
|
2226
2226
|
var StorageMigrationLeaseInputSchema = zod.z.object({ leaseId: zod.z.string().min(1) });
|
|
2227
2227
|
var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: zod.z.string().min(1) });
|
|
2228
|
+
/**
|
|
2229
|
+
* What a `relocateMedia` pass DOES. One engine, three passes — never a second
|
|
2230
|
+
* mover (the engine already walks both collections with a timestamp cursor and
|
|
2231
|
+
* already has a stamp-without-copy path).
|
|
2232
|
+
*
|
|
2233
|
+
* - `move` — the default and the historical behaviour: event-media and
|
|
2234
|
+
* retrain blobs move to `toLocationId` and their rows are
|
|
2235
|
+
* stamped. The enrolled gallery is skipped (D197).
|
|
2236
|
+
* - `seal` — ROWS ONLY, no bytes. Every row whose `locationId` is NULL is
|
|
2237
|
+
* stamped with `toLocationId`. `toLocationId` here is the id the
|
|
2238
|
+
* bytes ALREADY sit on — today's `eventMedia` default — because
|
|
2239
|
+
* a NULL row means "wherever `eventMedia` points *now*", and the
|
|
2240
|
+
* instant a repoint moves that pointer the row reads from the
|
|
2241
|
+
* new disk while its bytes are on the old one.
|
|
2242
|
+
* - `gallery` — the inverse selection of `move`: ONLY the retention-exempt
|
|
2243
|
+
* (enrolled-gallery) rows, which `move` deliberately skips.
|
|
2244
|
+
* `galleryMedia` is `cardinality: 'single'`, so this pass can
|
|
2245
|
+
* never run beside a live second location: it is stop-the-world
|
|
2246
|
+
* by construction, which is acceptable only because the gallery
|
|
2247
|
+
* is a few KB per enrolled sample.
|
|
2248
|
+
*/
|
|
2249
|
+
var MediaRelocateModeSchema = zod.z.enum([
|
|
2250
|
+
"move",
|
|
2251
|
+
"seal",
|
|
2252
|
+
"gallery"
|
|
2253
|
+
]);
|
|
2228
2254
|
var RelocateMediaInputSchema = zod.z.object({
|
|
2229
2255
|
toLocationId: zod.z.string(),
|
|
2230
|
-
throttleMbps: zod.z.number().min(1).max(1e3).optional()
|
|
2256
|
+
throttleMbps: zod.z.number().min(1).max(1e3).optional(),
|
|
2257
|
+
/** Omitted = `move`, the pre-existing behaviour. */
|
|
2258
|
+
mode: MediaRelocateModeSchema.optional()
|
|
2259
|
+
});
|
|
2260
|
+
/** How many rows still carry NO `locationId` — the population a repoint would
|
|
2261
|
+
* silently re-aim at a disk that does not hold their bytes. Zero is the only
|
|
2262
|
+
* value that permits a non-blocking `eventMedia` cutover. */
|
|
2263
|
+
var UnstampedEventMediaCountSchema = zod.z.object({
|
|
2264
|
+
media: zod.z.number().int().nonnegative(),
|
|
2265
|
+
retrainFrames: zod.z.number().int().nonnegative(),
|
|
2266
|
+
total: zod.z.number().int().nonnegative()
|
|
2231
2267
|
});
|
|
2232
2268
|
var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: zod.z.string().min(1) });
|
|
2233
|
-
/** The independently selectable logical storage classes
|
|
2234
|
-
*
|
|
2235
|
-
*
|
|
2269
|
+
/** The independently selectable logical storage classes — every class
|
|
2270
|
+
* `storage.listLocationDeclarations` reports, so an operator never meets a
|
|
2271
|
+
* Zod enum error where they should meet an explanation.
|
|
2272
|
+
*
|
|
2273
|
+
* `recordings` encompasses the high and mid segment profiles; `recordingsLow`
|
|
2274
|
+
* is low segments; `eventMedia` is post-analysis blobs; `galleryMedia` is the
|
|
2275
|
+
* enrolled gallery; `backups` is the system backup archive. The last two have
|
|
2276
|
+
* their own rules — see {@link StorageMigrationFindingCodeSchema}. */
|
|
2236
2277
|
var StorageMigrationClassSchema = zod.z.enum([
|
|
2237
2278
|
"recordings",
|
|
2238
2279
|
"recordingsLow",
|
|
2239
|
-
"eventMedia"
|
|
2280
|
+
"eventMedia",
|
|
2281
|
+
"backups",
|
|
2282
|
+
"galleryMedia"
|
|
2240
2283
|
]);
|
|
2241
2284
|
/** A destination is always an existing, fully-qualified location id. The
|
|
2242
2285
|
* migration API intentionally never changes a source location's `basePath`:
|
|
@@ -2244,20 +2287,56 @@ var StorageMigrationClassSchema = zod.z.enum([
|
|
|
2244
2287
|
var StorageMigrationDestinationsSchema = zod.z.object({
|
|
2245
2288
|
recordings: zod.z.string().min(1).optional(),
|
|
2246
2289
|
recordingsLow: zod.z.string().min(1).optional(),
|
|
2247
|
-
eventMedia: zod.z.string().min(1).optional()
|
|
2290
|
+
eventMedia: zod.z.string().min(1).optional(),
|
|
2291
|
+
backups: zod.z.string().min(1).optional(),
|
|
2292
|
+
galleryMedia: zod.z.string().min(1).optional()
|
|
2248
2293
|
}).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
|
|
2294
|
+
/**
|
|
2295
|
+
* How a migration sequences the cutover against the byte move.
|
|
2296
|
+
*
|
|
2297
|
+
* - `blocking` — the historical order: pause, move every byte, repoint,
|
|
2298
|
+
* resume. Recording is stopped for the whole move. Right
|
|
2299
|
+
* for a small or a cold class, and the only legal mode for
|
|
2300
|
+
* a `cardinality: 'single'` class.
|
|
2301
|
+
* - `nonBlocking` — repoint FIRST, drain behind: seal, pause, repoint,
|
|
2302
|
+
* refresh, resume, then move the past with everything
|
|
2303
|
+
* running. The pause is three bounded instants (a detach +
|
|
2304
|
+
* attach round, a write-gate drain, a lease) instead of one
|
|
2305
|
+
* bounded by bytes. 1.09 TB at 7–14 MB/s is thirty hours of
|
|
2306
|
+
* stopped recording under `blocking`; the same move is
|
|
2307
|
+
* seconds of stopped recording under `nonBlocking`.
|
|
2308
|
+
*
|
|
2309
|
+
* The mode is on the JOB, not only on the input, because `status` is where an
|
|
2310
|
+
* operator finds out which one is running.
|
|
2311
|
+
*/
|
|
2312
|
+
var StorageMigrationModeSchema = zod.z.enum(["blocking", "nonBlocking"]);
|
|
2249
2313
|
/** Shared input for planning and starting an orchestrated storage migration. */
|
|
2250
2314
|
var StorageMigrationInputSchema = zod.z.object({
|
|
2251
2315
|
destinations: StorageMigrationDestinationsSchema,
|
|
2252
|
-
throttleMbps: zod.z.number().min(1).max(1e3).optional()
|
|
2316
|
+
throttleMbps: zod.z.number().min(1).max(1e3).optional(),
|
|
2317
|
+
/** Omitted = `blocking`, which stays the default. */
|
|
2318
|
+
mode: StorageMigrationModeSchema.optional()
|
|
2253
2319
|
});
|
|
2254
|
-
/**
|
|
2255
|
-
*
|
|
2256
|
-
*
|
|
2320
|
+
/**
|
|
2321
|
+
* The durable coordinator state machine.
|
|
2322
|
+
*
|
|
2323
|
+
* `blocking`:
|
|
2324
|
+
* planning → pausing → moving → verifying → repointing → refreshing → resuming → done
|
|
2325
|
+
*
|
|
2326
|
+
* `nonBlocking`:
|
|
2327
|
+
* planning → sealing → pausing → repointing → refreshing → resuming → draining → verifying → done
|
|
2328
|
+
*
|
|
2329
|
+
* Same phases, different order plus two new ones — not a second mover.
|
|
2330
|
+
* `sealing` closes the `eventMedia` NULL-row hole BEFORE anything is paused;
|
|
2331
|
+
* `draining` runs the same movers UNLEASED, after every writer is back up.
|
|
2332
|
+
* `repointing` is still the only phase that changes a default location.
|
|
2333
|
+
*/
|
|
2257
2334
|
var StorageMigrationPhaseSchema = zod.z.enum([
|
|
2258
2335
|
"planning",
|
|
2336
|
+
"sealing",
|
|
2259
2337
|
"pausing",
|
|
2260
2338
|
"moving",
|
|
2339
|
+
"draining",
|
|
2261
2340
|
"verifying",
|
|
2262
2341
|
"repointing",
|
|
2263
2342
|
"refreshing",
|
|
@@ -2282,6 +2361,9 @@ var StorageMigrationMoveSchema = zod.z.object({
|
|
|
2282
2361
|
var StorageMigrationJobSchema = zod.z.object({
|
|
2283
2362
|
jobId: zod.z.string(),
|
|
2284
2363
|
phase: StorageMigrationPhaseSchema,
|
|
2364
|
+
/** Which order this job is running. `status` is the only place an operator
|
|
2365
|
+
* can tell a seconds-long cutover from a thirty-hour one. */
|
|
2366
|
+
mode: StorageMigrationModeSchema,
|
|
2285
2367
|
destinations: StorageMigrationDestinationsSchema,
|
|
2286
2368
|
throttleMbps: zod.z.number(),
|
|
2287
2369
|
moves: zod.z.array(StorageMigrationMoveSchema),
|
|
@@ -2294,13 +2376,54 @@ var StorageMigrationJobSchema = zod.z.object({
|
|
|
2294
2376
|
finishedAt: zod.z.number().nullable(),
|
|
2295
2377
|
error: zod.z.string().nullable()
|
|
2296
2378
|
});
|
|
2379
|
+
/**
|
|
2380
|
+
* What the planner NOTICED but did not refuse.
|
|
2381
|
+
*
|
|
2382
|
+
* A refusal throws — the operator cannot miss it. A finding is the other half:
|
|
2383
|
+
* something true about this plan that changes what the operator should expect,
|
|
2384
|
+
* surfaced where they read it rather than in a document they will not open.
|
|
2385
|
+
*
|
|
2386
|
+
* - `sharesDeviceWithSource` — the destination realpath's to the same place as
|
|
2387
|
+
* the source. The move will be a row re-stamp, not a byte move, and it buys
|
|
2388
|
+
* no redundancy. NOTE: this is PATH identity, not `st_dev` — two distinct
|
|
2389
|
+
* directories on one filesystem are NOT detected. See
|
|
2390
|
+
* `deviceIdentityUnknown`.
|
|
2391
|
+
* - `deviceIdentityUnknown` — a location carries a `nodeId` other than this
|
|
2392
|
+
* one (or has no `basePath`), so its realpath cannot be taken here and the
|
|
2393
|
+
* same-device question was not answered at all. Stated rather than assumed
|
|
2394
|
+
* clear: a check that silently never fires is worse than no check.
|
|
2395
|
+
* - `unstampedEventMediaRows` — how many `eventMedia`/retrain rows still carry
|
|
2396
|
+
* no `locationId`. Non-zero refuses a `nonBlocking` cutover.
|
|
2397
|
+
* - `blockingOnly` — this class is `cardinality: 'single'`, so it can never
|
|
2398
|
+
* span two locations and can only ever be moved stop-the-world.
|
|
2399
|
+
* - `noMover` — the class is selectable and planned, but no addon owns a mover
|
|
2400
|
+
* for it. The migration cannot move its bytes.
|
|
2401
|
+
*/
|
|
2402
|
+
var StorageMigrationFindingCodeSchema = zod.z.enum([
|
|
2403
|
+
"sharesDeviceWithSource",
|
|
2404
|
+
"deviceIdentityUnknown",
|
|
2405
|
+
"unstampedEventMediaRows",
|
|
2406
|
+
"blockingOnly",
|
|
2407
|
+
"noMover"
|
|
2408
|
+
]);
|
|
2409
|
+
var StorageMigrationFindingSchema = zod.z.object({
|
|
2410
|
+
code: StorageMigrationFindingCodeSchema,
|
|
2411
|
+
storageClass: StorageMigrationClassSchema,
|
|
2412
|
+
/** Human-readable, already carrying the ids and counts. */
|
|
2413
|
+
message: zod.z.string()
|
|
2414
|
+
});
|
|
2297
2415
|
var StorageMigrationPlanSchema = zod.z.object({
|
|
2298
2416
|
destinations: StorageMigrationDestinationsSchema,
|
|
2417
|
+
/** The mode this plan was built for. A plan is only valid for its mode: the
|
|
2418
|
+
* `eventMedia` seal gate and the single-cardinality refusal both depend on
|
|
2419
|
+
* it. */
|
|
2420
|
+
mode: StorageMigrationModeSchema,
|
|
2299
2421
|
moves: zod.z.array(zod.z.object({
|
|
2300
2422
|
storageClass: StorageMigrationClassSchema,
|
|
2301
2423
|
fromLocationId: zod.z.string(),
|
|
2302
2424
|
toLocationId: zod.z.string()
|
|
2303
|
-
}))
|
|
2425
|
+
})),
|
|
2426
|
+
findings: zod.z.array(StorageMigrationFindingSchema)
|
|
2304
2427
|
});
|
|
2305
2428
|
//#endregion
|
|
2306
2429
|
//#region src/interfaces/server-analysis.ts
|
|
@@ -18630,6 +18753,17 @@ var pipelineAnalyticsCapability = {
|
|
|
18630
18753
|
kind: "mutation",
|
|
18631
18754
|
auth: "admin"
|
|
18632
18755
|
}),
|
|
18756
|
+
/**
|
|
18757
|
+
* How many media / retrain rows still carry NO `locationId`.
|
|
18758
|
+
*
|
|
18759
|
+
* A NULL row means "wherever `eventMedia` points NOW", so the instant a
|
|
18760
|
+
* repoint moves that pointer every such row reads from the new disk while
|
|
18761
|
+
* its bytes are on the old one — the archive goes dark until a drain
|
|
18762
|
+
* happens to stamp it. This count is what the migration planner's
|
|
18763
|
+
* non-blocking gate reads; `relocateMedia({ mode: 'seal' })` is what drives
|
|
18764
|
+
* it to zero.
|
|
18765
|
+
*/
|
|
18766
|
+
countUnstampedEventMedia: require_sleep.method(zod.z.object({}), UnstampedEventMediaCountSchema, { auth: "admin" }),
|
|
18633
18767
|
/** Every relocate job this addon knows about, newest first (in RAM: the
|
|
18634
18768
|
* move is resumable, so a lost list costs nothing but the display). */
|
|
18635
18769
|
listRelocateMediaJobs: require_sleep.method(zod.z.object({}), zod.z.array(RelocateJobSchema).readonly(), {
|
|
@@ -21702,7 +21836,24 @@ var storageCapability = {
|
|
|
21702
21836
|
kind: "mutation",
|
|
21703
21837
|
auth: "admin"
|
|
21704
21838
|
}),
|
|
21705
|
-
|
|
21839
|
+
/**
|
|
21840
|
+
* Remove a location record. REFUSES a location that still holds data —
|
|
21841
|
+
* deleting a drained location whose durable rows still name it is how this
|
|
21842
|
+
* hub acquired 2 131 ghost `recordings:high` segments, and playback does
|
|
21843
|
+
* not stat, so the operator sees a silent black window rather than an
|
|
21844
|
+
* error.
|
|
21845
|
+
*
|
|
21846
|
+
* `force` exists because the occupancy check is BEST-EFFORT and refuses on
|
|
21847
|
+
* "unknown" as well as on "occupied" (a read that fails must not authorise
|
|
21848
|
+
* a destruction — D49). A location on a removed disk, on another node, or
|
|
21849
|
+
* behind a remote provider answers "unknown" forever, and a refusal an
|
|
21850
|
+
* operator cannot override is its own failure mode. `force: true` is
|
|
21851
|
+
* logged, loudly, with what the check saw.
|
|
21852
|
+
*/
|
|
21853
|
+
deleteLocation: require_sleep.method(zod.z.object({
|
|
21854
|
+
id: zod.z.string(),
|
|
21855
|
+
force: zod.z.boolean().optional()
|
|
21856
|
+
}), zod.z.void(), {
|
|
21706
21857
|
kind: "mutation",
|
|
21707
21858
|
auth: "admin"
|
|
21708
21859
|
}),
|
|
@@ -26657,6 +26808,33 @@ var intercomCapability = {
|
|
|
26657
26808
|
deviceNative: true,
|
|
26658
26809
|
mode: "singleton",
|
|
26659
26810
|
deviceTypes: [require_sleep.DeviceType.Camera],
|
|
26811
|
+
/**
|
|
26812
|
+
* **Auth tier: `protected` on every method — deliberate, and load-bearing.**
|
|
26813
|
+
*
|
|
26814
|
+
* Talking through a camera is an OPERATE action, not a CONFIGURE one. This
|
|
26815
|
+
* cap has no configuration surface at all: all six methods open, feed and
|
|
26816
|
+
* close one live audio session against one `deviceId`. That is the same
|
|
26817
|
+
* authority as `ptz.move` or `snapshot.getSnapshot`, both `protected` — and
|
|
26818
|
+
* the opposite of `ptz.savePreset` / `snapshot.invalidateCache`, which are
|
|
26819
|
+
* `admin` because they change what the device IS.
|
|
26820
|
+
*
|
|
26821
|
+
* `protected` does not mean ungated: `protectedProcedure` runs the
|
|
26822
|
+
* `METHOD_ACCESS_MAP` scope check, and every method here is `scope: 'device'`
|
|
26823
|
+
* with `access: 'create'` and a `deviceId` in its input. So a caller needs a
|
|
26824
|
+
* grant that covers THAT camera at `create` — a `camera-viewer` (`view`
|
|
26825
|
+
* only) still cannot talk, and a grant on camera 5 cannot talk through
|
|
26826
|
+
* camera 7.
|
|
26827
|
+
*
|
|
26828
|
+
* Every method was `auth: 'admin'` from the initial commit, which made the
|
|
26829
|
+
* cap unreachable by every non-admin principal — `adminProcedure` throws
|
|
26830
|
+
* `FORBIDDEN: Admin required` BEFORE the scope check runs, so the scope
|
|
26831
|
+
* machinery generated for this cap (`METHOD_ACCESS_MAP`,
|
|
26832
|
+
* `DEVICE_SCOPED_CAPS`, `METHOD_DEVICE_SELECTORS`) was complete and dead. The
|
|
26833
|
+
* `camera-operator` scope preset has promised "PTZ control, intercom,
|
|
26834
|
+
* snapshots" since that same commit; the promise could not be kept. Recorded
|
|
26835
|
+
* as D289; `scripts/check-scope-preset-promises.ts` now fails the build if a
|
|
26836
|
+
* preset promises a cap no row of that preset can reach.
|
|
26837
|
+
*/
|
|
26660
26838
|
methods: {
|
|
26661
26839
|
/**
|
|
26662
26840
|
* Open a server-side WebRTC audio-only session. Returns an SDP
|
|
@@ -26669,7 +26847,7 @@ var intercomCapability = {
|
|
|
26669
26847
|
sdpOffer: zod.z.string()
|
|
26670
26848
|
}), {
|
|
26671
26849
|
kind: "mutation",
|
|
26672
|
-
auth: "
|
|
26850
|
+
auth: "protected"
|
|
26673
26851
|
}),
|
|
26674
26852
|
handleAnswer: require_sleep.method(zod.z.object({
|
|
26675
26853
|
deviceId: zod.z.number(),
|
|
@@ -26677,7 +26855,7 @@ var intercomCapability = {
|
|
|
26677
26855
|
sdpAnswer: zod.z.string()
|
|
26678
26856
|
}), zod.z.void(), {
|
|
26679
26857
|
kind: "mutation",
|
|
26680
|
-
auth: "
|
|
26858
|
+
auth: "protected"
|
|
26681
26859
|
}),
|
|
26682
26860
|
/** Close explicitly. Server also auto-closes on 30s idle. */
|
|
26683
26861
|
stopSession: require_sleep.method(zod.z.object({
|
|
@@ -26685,7 +26863,7 @@ var intercomCapability = {
|
|
|
26685
26863
|
sessionId: zod.z.string()
|
|
26686
26864
|
}), zod.z.void(), {
|
|
26687
26865
|
kind: "mutation",
|
|
26688
|
-
auth: "
|
|
26866
|
+
auth: "protected"
|
|
26689
26867
|
}),
|
|
26690
26868
|
/**
|
|
26691
26869
|
* Open a raw-PCM talk session (no WebRTC SDP plumbing). Used by
|
|
@@ -26698,7 +26876,7 @@ var intercomCapability = {
|
|
|
26698
26876
|
*/
|
|
26699
26877
|
startTalkSession: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), zod.z.object({ sessionId: zod.z.string() }), {
|
|
26700
26878
|
kind: "mutation",
|
|
26701
|
-
auth: "
|
|
26879
|
+
auth: "protected"
|
|
26702
26880
|
}),
|
|
26703
26881
|
/**
|
|
26704
26882
|
* Push one chunk of talk-back audio onto the active talk session.
|
|
@@ -26733,12 +26911,12 @@ var intercomCapability = {
|
|
|
26733
26911
|
sequenceNumber: zod.z.number().int()
|
|
26734
26912
|
}), zod.z.object({ accepted: zod.z.boolean() }), {
|
|
26735
26913
|
kind: "mutation",
|
|
26736
|
-
auth: "
|
|
26914
|
+
auth: "protected"
|
|
26737
26915
|
}),
|
|
26738
26916
|
/** Close the raw-PCM talk session. Idempotent. */
|
|
26739
26917
|
endTalkSession: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), zod.z.void(), {
|
|
26740
26918
|
kind: "mutation",
|
|
26741
|
-
auth: "
|
|
26919
|
+
auth: "protected"
|
|
26742
26920
|
})
|
|
26743
26921
|
},
|
|
26744
26922
|
events: { onStatusChanged: { data: zod.z.object({
|
|
@@ -40712,6 +40890,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
40712
40890
|
addonId: null,
|
|
40713
40891
|
access: "create"
|
|
40714
40892
|
},
|
|
40893
|
+
"pipelineAnalytics.countUnstampedEventMedia": {
|
|
40894
|
+
capName: "pipeline-analytics",
|
|
40895
|
+
capScope: "device",
|
|
40896
|
+
addonId: null,
|
|
40897
|
+
access: "view"
|
|
40898
|
+
},
|
|
40715
40899
|
"pipelineAnalytics.deleteDeviceEvents": {
|
|
40716
40900
|
capName: "pipeline-analytics",
|
|
40717
40901
|
capScope: "device",
|
|
@@ -45954,7 +46138,7 @@ var SCOPE_PRESETS = [
|
|
|
45954
46138
|
{
|
|
45955
46139
|
id: "camera-operator",
|
|
45956
46140
|
label: "Camera operator",
|
|
45957
|
-
description: "Everything `camera-viewer` does plus PTZ
|
|
46141
|
+
description: "Everything `camera-viewer` does plus live control of every granted camera — PTZ movement, intercom talk-back and on-demand snapshots. Cannot delete devices, and grants nothing on system-scope caps (recording control, users, addons).",
|
|
45958
46142
|
rows: [{
|
|
45959
46143
|
type: "category",
|
|
45960
46144
|
target: "device",
|
|
@@ -51077,6 +51261,7 @@ exports.MediaFileSchema = MediaFileSchema;
|
|
|
51077
51261
|
exports.MediaPlayerRepeatSchema = MediaPlayerRepeatSchema;
|
|
51078
51262
|
exports.MediaPlayerStateSchema = MediaPlayerStateSchema;
|
|
51079
51263
|
exports.MediaPlayerStatusSchema = MediaPlayerStatusSchema;
|
|
51264
|
+
exports.MediaRelocateModeSchema = MediaRelocateModeSchema;
|
|
51080
51265
|
exports.MeshPeerSchema = MeshPeerSchema;
|
|
51081
51266
|
exports.MeshStatusSchema = MeshStatusSchema;
|
|
51082
51267
|
exports.MethodAccessSchema = MethodAccessSchema;
|
|
@@ -51454,11 +51639,14 @@ exports.StorageLocationSchema = StorageLocationSchema;
|
|
|
51454
51639
|
exports.StorageLocationTypeSchema = StorageLocationTypeSchema;
|
|
51455
51640
|
exports.StorageMigrationClassSchema = StorageMigrationClassSchema;
|
|
51456
51641
|
exports.StorageMigrationDestinationsSchema = StorageMigrationDestinationsSchema;
|
|
51642
|
+
exports.StorageMigrationFindingCodeSchema = StorageMigrationFindingCodeSchema;
|
|
51643
|
+
exports.StorageMigrationFindingSchema = StorageMigrationFindingSchema;
|
|
51457
51644
|
exports.StorageMigrationFootageMoveInputSchema = StorageMigrationFootageMoveInputSchema;
|
|
51458
51645
|
exports.StorageMigrationInputSchema = StorageMigrationInputSchema;
|
|
51459
51646
|
exports.StorageMigrationJobSchema = StorageMigrationJobSchema;
|
|
51460
51647
|
exports.StorageMigrationLeaseInputSchema = StorageMigrationLeaseInputSchema;
|
|
51461
51648
|
exports.StorageMigrationMediaMoveInputSchema = StorageMigrationMediaMoveInputSchema;
|
|
51649
|
+
exports.StorageMigrationModeSchema = StorageMigrationModeSchema;
|
|
51462
51650
|
exports.StorageMigrationMoveSchema = StorageMigrationMoveSchema;
|
|
51463
51651
|
exports.StorageMigrationParticipantSchema = StorageMigrationParticipantSchema;
|
|
51464
51652
|
exports.StorageMigrationPhaseSchema = StorageMigrationPhaseSchema;
|
|
@@ -51534,6 +51722,7 @@ exports.UNATTRIBUTED_BUCKET_KEY = UNATTRIBUTED_BUCKET_KEY;
|
|
|
51534
51722
|
exports.UNIT_TABLE = UNIT_TABLE;
|
|
51535
51723
|
exports.UnifiedBrokerInfoSchema = BrokerInfoSchema$1;
|
|
51536
51724
|
exports.UnitConversionError = UnitConversionError;
|
|
51725
|
+
exports.UnstampedEventMediaCountSchema = UnstampedEventMediaCountSchema;
|
|
51537
51726
|
exports.UpdateIntegrationInputSchema = UpdateIntegrationInputSchema;
|
|
51538
51727
|
exports.UpdateStatusSchema = UpdateStatusSchema;
|
|
51539
51728
|
exports.UpdateUserInputSchema = UpdateUserInputSchema;
|