@camstack/types 1.2.379 → 1.2.381

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 (45) hide show
  1. package/dist/addon.d.ts +3 -0
  2. package/dist/addon.js +67 -2
  3. package/dist/addon.mjs +5 -3
  4. package/dist/capabilities/caller-stamp.d.ts +12 -0
  5. package/dist/capabilities/index.d.ts +7 -2
  6. package/dist/capabilities/record-entries.cap.d.ts +84 -0
  7. package/dist/capabilities/records.cap.d.ts +399 -0
  8. package/dist/capabilities/storage-admin.cap.d.ts +268 -0
  9. package/dist/client.js +57 -32
  10. package/dist/client.mjs +57 -32
  11. package/dist/device/device-context.d.ts +2 -0
  12. package/dist/ffmpeg/fmp4-fragment-child.d.ts +2 -2
  13. package/dist/ffmpeg/process.d.ts +21 -0
  14. package/dist/generated/addon-api.d.ts +191 -0
  15. package/dist/generated/cap-input-defaults.d.ts +1 -1
  16. package/dist/generated/capability-router-map.d.ts +8 -2
  17. package/dist/generated/method-access-map.d.ts +1 -1
  18. package/dist/generated/method-device-selectors.d.ts +2 -2
  19. package/dist/generated/system-proxy.d.ts +2 -0
  20. package/dist/helpers/addon-slice-handle.d.ts +4 -0
  21. package/dist/helpers/trpc-leaf.d.ts +17 -0
  22. package/dist/index.d.ts +3 -1
  23. package/dist/index.js +724 -32
  24. package/dist/index.mjs +646 -33
  25. package/dist/interfaces/addon-peer-bytes.d.ts +19 -2
  26. package/dist/interfaces/addon.d.ts +13 -0
  27. package/dist/interfaces/config-ui.d.ts +4 -0
  28. package/dist/interfaces/event-bus.d.ts +32 -3
  29. package/dist/interfaces/storage.d.ts +1 -1
  30. package/dist/node.d.ts +2 -2
  31. package/dist/node.js +4 -0
  32. package/dist/node.mjs +4 -1
  33. package/dist/records/constants.d.ts +23 -0
  34. package/dist/records/entry-kind.d.ts +31 -0
  35. package/dist/records/errors.d.ts +81 -0
  36. package/dist/records/in-memory-records.d.ts +21 -0
  37. package/dist/records/index.d.ts +9 -0
  38. package/dist/records/record-kind.d.ts +144 -0
  39. package/dist/records/records-access.d.ts +153 -0
  40. package/dist/records/secret-paths.d.ts +52 -0
  41. package/dist/records/settings-array-adopts-from.d.ts +12 -0
  42. package/dist/records/settings-brokers-adopts-from.d.ts +10 -0
  43. package/dist/{sleep-DQYi915G.js → sleep-D8yJVc4r.js} +1971 -290
  44. package/dist/{sleep-D-Q2_Mcd.mjs → sleep-bZIhUvjd.mjs} +1413 -128
  45. package/package.json +1 -1
@@ -162,7 +162,7 @@ function collectKeychainStoredKeys(schema) {
162
162
  return keys;
163
163
  }
164
164
  function walkKeychainField(field, out) {
165
- if (!isRecord$3(field)) return;
165
+ if (!isRecord$6(field)) return;
166
166
  const type = field["type"];
167
167
  const key = field["key"];
168
168
  const isSecret = type === "password" || field["secret"] === true;
@@ -187,21 +187,21 @@ function schemaDeclaresAnyField(schema) {
187
187
  for (const section of sectionsOf(schema)) if (fieldsOf(section).length > 0) return true;
188
188
  return false;
189
189
  }
190
- function isRecord$3(value) {
190
+ function isRecord$6(value) {
191
191
  return typeof value === "object" && value !== null && !Array.isArray(value);
192
192
  }
193
193
  function sectionsOf(schema) {
194
- if (!isRecord$3(schema)) return [];
194
+ if (!isRecord$6(schema)) return [];
195
195
  const sections = schema["sections"];
196
196
  return Array.isArray(sections) ? sections : [];
197
197
  }
198
198
  function fieldsOf(node) {
199
- if (!isRecord$3(node)) return [];
199
+ if (!isRecord$6(node)) return [];
200
200
  const fields = node["fields"];
201
201
  return Array.isArray(fields) ? fields : [];
202
202
  }
203
203
  function walkField(field, out) {
204
- if (!isRecord$3(field)) return;
204
+ if (!isRecord$6(field)) return;
205
205
  const type = field["type"];
206
206
  const key = field["key"];
207
207
  if ((type === "password" || field["secret"] === true) && typeof key === "string" && key.length > 0) out.add(key);
@@ -241,7 +241,7 @@ function walkField(field, out) {
241
241
  var SECRET_CLEAR = { $secretClear: true };
242
242
  /** The `'***'` token D634 redaction writes for non-admins. */
243
243
  var LEGACY_DEVICE_REDACTION = "***";
244
- function isRecord$2(value) {
244
+ function isRecord$5(value) {
245
245
  return typeof value === "object" && value !== null && !Array.isArray(value);
246
246
  }
247
247
  function makeSecretMarker(ref) {
@@ -252,19 +252,19 @@ function makeSecretMarker(ref) {
252
252
  }
253
253
  /** A stored marker: an object whose `$secret` is a non-empty string. */
254
254
  function isSecretMarker(value) {
255
- if (!isRecord$2(value)) return false;
255
+ if (!isRecord$5(value)) return false;
256
256
  const ref = value["$secret"];
257
257
  return typeof ref === "string" && ref.length > 0;
258
258
  }
259
259
  /** Anything carrying a `$secret` key — a stored marker or a UI view of one. */
260
260
  function isSecretMarkerLike(value) {
261
- return isRecord$2(value) && Object.prototype.hasOwnProperty.call(value, "$secret");
261
+ return isRecord$5(value) && Object.prototype.hasOwnProperty.call(value, "$secret");
262
262
  }
263
263
  function isSecretClear(value) {
264
- return isRecord$2(value) && value["$secretClear"] === true;
264
+ return isRecord$5(value) && value["$secretClear"] === true;
265
265
  }
266
266
  function isSecretFieldView(value) {
267
- return isRecord$2(value) && value["set"] === true && isSecretMarkerLike(value);
267
+ return isRecord$5(value) && value["set"] === true && isSecretMarkerLike(value);
268
268
  }
269
269
  /**
270
270
  * The UI view of a stored secret field value: a marker becomes "set", inline
@@ -677,6 +677,33 @@ function typeOf(field) {
677
677
  default: return "other";
678
678
  }
679
679
  }
680
+ /** Strip inline `value` from a hydrated field for schema-only round-trips. */
681
+ function dehydrateConfigField(field) {
682
+ if (field.type === "group") return {
683
+ ...field,
684
+ fields: field.fields.map(dehydrateConfigField)
685
+ };
686
+ if (field.type === "sub-tabs") return {
687
+ ...field,
688
+ tabs: field.tabs.map((tab) => ({
689
+ ...tab,
690
+ fields: tab.fields.map(dehydrateConfigField)
691
+ }))
692
+ };
693
+ if (isValuelessField(field)) return field;
694
+ const { value: _drop, ...rest } = field;
695
+ return rest;
696
+ }
697
+ /** Inverse of {@link hydrateSchema} — drops resolved values from every leaf field. */
698
+ function dehydrateSchema(schema) {
699
+ return {
700
+ ...schema.tabs ? { tabs: [...schema.tabs] } : {},
701
+ sections: schema.sections.map((section) => ({
702
+ ...section,
703
+ fields: section.fields.map(dehydrateConfigField)
704
+ }))
705
+ };
706
+ }
680
707
  //#endregion
681
708
  //#region src/interfaces/event-bus.ts
682
709
  /**
@@ -1018,7 +1045,7 @@ var KeychainWriteRefusedError = class extends Error {
1018
1045
  }
1019
1046
  };
1020
1047
  var KEEP = { kind: "keep" };
1021
- function isRecord$1(value) {
1048
+ function isRecord$4(value) {
1022
1049
  return typeof value === "object" && value !== null && !Array.isArray(value);
1023
1050
  }
1024
1051
  function defaultMintId() {
@@ -1031,7 +1058,7 @@ function collectSecretMarkerRefs(value, out = []) {
1031
1058
  return out;
1032
1059
  }
1033
1060
  if (Array.isArray(value)) for (const item of value) collectSecretMarkerRefs(item, out);
1034
- else if (isRecord$1(value)) for (const child of Object.values(value)) collectSecretMarkerRefs(child, out);
1061
+ else if (isRecord$4(value)) for (const child of Object.values(value)) collectSecretMarkerRefs(child, out);
1035
1062
  return out;
1036
1063
  }
1037
1064
  async function storedValueEquals(secrets, marker, candidate) {
@@ -1086,7 +1113,7 @@ function rowId(row, idKey) {
1086
1113
  return null;
1087
1114
  }
1088
1115
  async function writeArray(ctx, node, incoming, stored, fieldPath) {
1089
- const storedRows = Array.isArray(stored) ? stored.filter(isRecord$1) : [];
1116
+ const storedRows = Array.isArray(stored) ? stored.filter(isRecord$4) : [];
1090
1117
  if (!Array.isArray(incoming)) {
1091
1118
  ctx.deletes.push(...collectSecretMarkerRefs(storedRows));
1092
1119
  return {
@@ -1102,7 +1129,7 @@ async function writeArray(ctx, node, incoming, stored, fieldPath) {
1102
1129
  const kept = /* @__PURE__ */ new Set();
1103
1130
  const rows = [];
1104
1131
  for (const row of incoming) {
1105
- if (!isRecord$1(row)) {
1132
+ if (!isRecord$4(row)) {
1106
1133
  rows.push(row);
1107
1134
  continue;
1108
1135
  }
@@ -1127,7 +1154,7 @@ async function writeNode(ctx, node, incoming, stored, fieldPath) {
1127
1154
  case "leaf": return writeLeaf(ctx, incoming, stored, fieldPath);
1128
1155
  case "array": return writeArray(ctx, node, incoming, stored, fieldPath);
1129
1156
  case "object": {
1130
- if (!isRecord$1(incoming)) {
1157
+ if (!isRecord$4(incoming)) {
1131
1158
  if (incoming === void 0) return KEEP;
1132
1159
  ctx.deletes.push(...collectSecretMarkerRefs(stored));
1133
1160
  return {
@@ -1135,7 +1162,7 @@ async function writeNode(ctx, node, incoming, stored, fieldPath) {
1135
1162
  value: incoming
1136
1163
  };
1137
1164
  }
1138
- const storedObj = isRecord$1(stored) ? stored : {};
1165
+ const storedObj = isRecord$4(stored) ? stored : {};
1139
1166
  return {
1140
1167
  kind: "value",
1141
1168
  value: await writeMembers(ctx, node.children, incoming, storedObj, (m) => `${fieldPath}.${m}`)
@@ -1258,7 +1285,7 @@ async function resolveSecretMarkers(value, secrets, options = {}) {
1258
1285
  value: items
1259
1286
  };
1260
1287
  }
1261
- if (isRecord$1(v)) {
1288
+ if (isRecord$4(v)) {
1262
1289
  const out = {};
1263
1290
  for (const [k, child] of Object.entries(v)) {
1264
1291
  const s = substitute(child);
@@ -1292,7 +1319,7 @@ var SecretOverwriteRefusedError = class extends Error {
1292
1319
  this.name = "SecretOverwriteRefusedError";
1293
1320
  }
1294
1321
  };
1295
- function isRecord(value) {
1322
+ function isRecord$3(value) {
1296
1323
  return typeof value === "object" && value !== null && !Array.isArray(value);
1297
1324
  }
1298
1325
  function resolvedValue(pass, marker) {
@@ -1321,7 +1348,7 @@ function inArray(pass, incoming, stored) {
1321
1348
  return incoming.map((item, index) => {
1322
1349
  const twin = stored[index];
1323
1350
  if (isSecretMarker(twin)) return typeof item === "string" && item === resolvedValue(pass, twin) ? twin : item;
1324
- if (isRecord(item) && isRecord(twin)) return inArrayRow(pass, item, twin);
1351
+ if (isRecord$3(item) && isRecord$3(twin)) return inArrayRow(pass, item, twin);
1325
1352
  if (Array.isArray(item) && Array.isArray(twin)) return inArray(pass, item, twin);
1326
1353
  return item;
1327
1354
  });
@@ -1332,7 +1359,7 @@ function inArrayRow(pass, incoming, stored) {
1332
1359
  const twin = stored[key];
1333
1360
  if (isSecretMarker(twin)) {
1334
1361
  if (typeof value === "string" && value === resolvedValue(pass, twin)) out[key] = twin;
1335
- } else if (isRecord(value) && isRecord(twin)) out[key] = inArrayRow(pass, value, twin);
1362
+ } else if (isRecord$3(value) && isRecord$3(twin)) out[key] = inArrayRow(pass, value, twin);
1336
1363
  else if (Array.isArray(value) && Array.isArray(twin)) out[key] = inArray(pass, value, twin);
1337
1364
  }
1338
1365
  return out;
@@ -1340,7 +1367,7 @@ function inArrayRow(pass, incoming, stored) {
1340
1367
  async function walk(pass, incoming, stored) {
1341
1368
  if (isSecretMarker(stored)) return atMarker(pass, incoming, stored);
1342
1369
  if (Array.isArray(incoming) && Array.isArray(stored)) return inArray(pass, incoming, stored);
1343
- if (!isRecord(incoming) || !isRecord(stored)) return incoming;
1370
+ if (!isRecord$3(incoming) || !isRecord$3(stored)) return incoming;
1344
1371
  const out = { ...incoming };
1345
1372
  for (const [key, value] of Object.entries(incoming)) out[key] = await walk(pass, value, stored[key]);
1346
1373
  return out;
@@ -1371,7 +1398,7 @@ async function restoreUnchangedSecrets(input) {
1371
1398
  function isJsonEqual(a, b) {
1372
1399
  if (Object.is(a, b)) return true;
1373
1400
  if (Array.isArray(a)) return Array.isArray(b) && a.length === b.length && a.every((v, i) => isJsonEqual(v, b[i]));
1374
- if (isRecord(a) && isRecord(b)) {
1401
+ if (isRecord$3(a) && isRecord$3(b)) {
1375
1402
  const keys = Object.keys(a);
1376
1403
  if (keys.length !== Object.keys(b).length) return false;
1377
1404
  return keys.every((k) => Object.prototype.hasOwnProperty.call(b, k) && isJsonEqual(a[k], b[k]));
@@ -1395,7 +1422,7 @@ function markerKeysOf(blob, owner) {
1395
1422
  }
1396
1423
  function nodeFromStored(value, owner) {
1397
1424
  if (isSecretMarker(value)) return isSecretRefOwnedBy(value.$secret, owner) ? { kind: "leaf" } : null;
1398
- if (!isRecord(value)) return null;
1425
+ if (!isRecord$3(value)) return null;
1399
1426
  const children = /* @__PURE__ */ new Map();
1400
1427
  for (const [key, child] of Object.entries(value)) {
1401
1428
  const node = nodeFromStored(child, owner);
@@ -2202,7 +2229,7 @@ var BaseAddon = class {
2202
2229
  if (!ctx) return;
2203
2230
  const addonId = ctx.id;
2204
2231
  setImmediate(() => {
2205
- ctx.api.addons?.restartAddon?.mutate({ addonId }).then(() => {
2232
+ ctx.api.addons.restartAddon.mutate({ addonId }).then(() => {
2206
2233
  ctx.logger.info("addon auto-restart triggered by restart-required setting change", { meta: { changedFields: patchKeys.filter((k) => restartKeys.has(k)) } });
2207
2234
  }).catch((err) => {
2208
2235
  ctx.logger.error("addon auto-restart failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
@@ -3122,185 +3149,1476 @@ async function resolveSecretViewsIn(args, secrets) {
3122
3149
  return swap(args).value;
3123
3150
  }
3124
3151
  //#endregion
3125
- //#region src/capabilities/schemas/streaming-shared.ts
3126
- /** Shared Zod schemas used across streaming capabilities. */
3127
- var CamProfileSchema = zod.z.enum([
3128
- "high",
3129
- "mid",
3130
- "low"
3131
- ]);
3132
- /** Canonical ordering. Hard-coded; never sorted. */
3133
- var CAM_PROFILE_ORDER = [
3134
- "high",
3135
- "mid",
3136
- "low"
3152
+ //#region src/records/constants.ts
3153
+ /** Limits and names of `ctx.records` (D881). One authority; the engine and the facade read it. */
3154
+ /** The files a kind may live in. `history` is device-history's (D850), never records. */
3155
+ var RECORD_DATABASES = ["settings", "events"];
3156
+ /** The classes of a kind: the `@durable` vocabulary, one authority (replaces the annotation). */
3157
+ var RECORD_CLASSES = [
3158
+ "config",
3159
+ "ledger",
3160
+ "audit",
3161
+ "mirror",
3162
+ "ephemeral"
3137
3163
  ];
3164
+ var RECORD_DEFAULT_MAX_DATA_BYTES = 64 * 1024;
3165
+ var RECORD_MAX_DATA_BYTES = 1024 * 1024;
3166
+ var RECORD_ID_MAX_LENGTH = 256;
3167
+ var RECORD_BATCH_MAX = 1e3;
3168
+ var RECORD_BATCH_MAX_BYTES = 4 * 1024 * 1024;
3169
+ var RECORD_QUERY_MAX = 1e3;
3170
+ /** Rows one DELETE statement removes before the serving thread yields. */
3171
+ var RECORD_DELETE_BATCH = 5e3;
3172
+ /** A kind in the `settings` file may not bound itself above this (D447: high volume is `events`). */
3173
+ var RECORD_SETTINGS_MAX_ROWS = 5e4;
3174
+ var RECORD_MAX_INDEXES = 8;
3175
+ var RECORD_MAX_INDEX_FIELDS = 4;
3176
+ /** The engine's TTL sweep cadence. */
3177
+ var RECORD_SWEEP_INTERVAL_MS = 10 * 6e4;
3178
+ /** The `Column`-free proof prefix: a ref collection for a kind's secret fields. */
3179
+ var RECORD_SECRET_COLLECTION_PREFIX = "records:";
3180
+ //#endregion
3181
+ //#region src/records/errors.ts
3138
3182
  /**
3139
- * Which rung a per-camera consumer listens on: an explicit profile, or `auto`.
3183
+ * The named failures of `ctx.records` (D881).
3140
3184
  *
3141
- * `auto` is a REAL value, not an absent one — it means "resolve it by the rule
3142
- * that consumer owns". It lives beside `CamProfile` because a rung is the only
3143
- * operator-facing way to name a stream: a cam-stream id is broker-internal and
3144
- * moves when a slot is reassigned, so a stored id silently stops meaning what
3145
- * the operator picked. Today's one user is the audio analyser, whose rule is
3146
- * "the lowest AVAILABLE native rung" (D537).
3185
+ * A records call crosses a worker thread, a UDS channel and a tRPC router, and
3186
+ * an error class does not survive any of them - only its message does. So
3187
+ * every message STARTS with a stable code, `records/<code>: <detail>`, and
3188
+ * {@link recordsErrorFromMessage} rebuilds the typed class on the caller's side.
3189
+ * A failed read is never `[]` or `undefined`: it throws one of these.
3147
3190
  */
3148
- var AudioStreamPickSchema = zod.z.union([CamProfileSchema, zod.z.literal("auto")]);
3149
- var CamStreamKindSchema = zod.z.enum([
3150
- "pull-rtsp",
3151
- "pull-rtmp",
3152
- "pull-http",
3153
- "pull-flv",
3154
- "pull-rfc4571",
3155
- "push-annexb",
3156
- "derived"
3157
- ]);
3158
- var CamStreamResolutionSchema = zod.z.object({
3159
- width: zod.z.number().int().positive(),
3160
- height: zod.z.number().int().positive()
3161
- });
3162
- var CameraStreamSchema = zod.z.object({
3163
- /** Stable, provider-assigned id unique within the (deviceId) scope. */
3164
- camStreamId: zod.z.string().min(1),
3165
- deviceId: zod.z.number().int().nonnegative(),
3166
- kind: CamStreamKindSchema,
3167
- /** Required for pull-* kinds. Ignored for push-annexb. */
3168
- url: zod.z.string().optional(),
3169
- codec: zod.z.string().optional(),
3170
- resolution: CamStreamResolutionSchema.optional(),
3171
- fps: zod.z.number().positive().optional(),
3172
- /** Human label surfaced in the Admin UI "Camera Stream" dropdown. */
3173
- label: zod.z.string().optional(),
3174
- /**
3175
- * Device-level features the publisher advertised (e.g. `battery-operated`).
3176
- * The broker, snapshot orchestrator, and prebuffer manager all consult
3177
- * this list to derive policy — relaxed stall watchdog for battery
3178
- * cams, prebuffer off by default, longer snapshot rate-limit, etc.
3179
- *
3180
- * Single source of truth replacing per-stream flags like the
3181
- * historical `allowStall`: if the publisher knows the camera is
3182
- * battery-powered, every downstream service derives the right policy
3183
- * from this list.
3184
- */
3185
- deviceFeatures: zod.z.array(zod.z.string()).optional(),
3186
- /**
3187
- * Whether this stream participates in the broker's automatic profile
3188
- * assignment (`computeInitialAssignment`). Defaults to `true`. Publishers
3189
- * use `false` when they want a stream to be SELECTABLE in the UI but not
3190
- * picked by default — e.g. Reolink publishes its native Baichuan streams
3191
- * as `autoEligible: true` (the recommended path) and its RTSP / RTMP
3192
- * mirrors as `autoEligible: false` (still pickable per slot, just not
3193
- * the auto choice). Manual `assignProfile` calls remain valid for
3194
- * non-eligible streams.
3195
- */
3196
- autoEligible: zod.z.boolean().optional(),
3197
- /**
3198
- * The profile slot the PUBLISHER says this stream is: `low` for a stream
3199
- * whose only sensible role is the low-bandwidth one, `high` for a main
3200
- * stream. Consulted by the broker's automatic ranking
3201
- * (`rankInitialAssignment`) BEFORE the pixel-count heuristic, and only there:
3202
- * an operator's manual assignment still wins, and an absent hint is the
3203
- * pixel-ranked default every camera had before this field existed.
3204
- *
3205
- * Why it exists: a camera with ONE stream ranked to `mid` — the slot no
3206
- * storage class is written for on its own (`recordings` is high|mid,
3207
- * `recordingsLow` is low) and the one profile scrub does not read. The robot
3208
- * camera's single 720p relay is a `low` in every respect except the slot the
3209
- * heuristic put it in.
3210
- */
3211
- profileHint: CamProfileSchema.optional(),
3212
- /**
3213
- * Transport-specific opaque metadata. The broker passes it through to
3214
- * the source reader without inspecting it. Currently used by
3215
- * `pull-rfc4571` streams to carry the upstream SDP (so the reader can
3216
- * route RTP packets to the right depacketizer without an in-band
3217
- * DESCRIBE phase). Other kinds typically leave it undefined.
3218
- */
3219
- metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
3220
- });
3221
- var ProfileSlotStatusSchema = zod.z.enum([
3222
- "unassigned",
3223
- "idle",
3224
- "connecting",
3225
- "streaming",
3226
- "error"
3227
- ]);
3228
- var ProfileSlotSchema = zod.z.object({
3229
- deviceId: zod.z.number().int().nonnegative(),
3230
- profile: CamProfileSchema,
3231
- /** Broker id the rest of the system addresses: `${deviceId}/${profile}`. */
3232
- brokerId: zod.z.string(),
3233
- /** `null` when the profile is unassigned. */
3234
- sourceCamStreamId: zod.z.string().nullable(),
3235
- status: ProfileSlotStatusSchema,
3236
- resolution: CamStreamResolutionSchema.optional(),
3237
- codec: zod.z.string().optional(),
3238
- preBufferSec: zod.z.number().nonnegative().optional(),
3239
- errorMessage: zod.z.string().optional()
3240
- });
3241
- /** The canonical consumer-facing broker id for a device profile. */
3242
- function makeProfileBrokerId(deviceId, profile) {
3243
- return `${deviceId}/${profile}`;
3191
+ /** Every code a records failure carries. */
3192
+ var RECORDS_ERROR_CODES = [
3193
+ "rev-conflict",
3194
+ "too-large",
3195
+ "unindexed-filter",
3196
+ "filter-required",
3197
+ "unknown-kind",
3198
+ "not-found",
3199
+ "unique-violation",
3200
+ "plaintext-secret",
3201
+ "foreign-marker",
3202
+ "secret-unavailable",
3203
+ "invalid-record",
3204
+ "declaration-refused",
3205
+ "adoption-pending",
3206
+ "no-caller",
3207
+ "batch-too-large"
3208
+ ];
3209
+ var PREFIX = "records/";
3210
+ /** The base of every records failure. `detail` is the human part of the message. */
3211
+ var RecordsError = class extends Error {
3212
+ code;
3213
+ detail;
3214
+ constructor(code, detail) {
3215
+ super(`${PREFIX}${code}: ${detail}`);
3216
+ this.name = "RecordsError";
3217
+ this.code = code;
3218
+ this.detail = detail;
3219
+ }
3220
+ };
3221
+ /** A write guarded by `ifRev` found another revision (or an existing row for `ifRev: 0`). */
3222
+ var RevConflictError = class extends RecordsError {
3223
+ constructor(detail) {
3224
+ super("rev-conflict", detail);
3225
+ this.name = "RevConflictError";
3226
+ }
3227
+ };
3228
+ /** `data` exceeds the kind's `maxDataBytes`. Bytes are never record fields (D613). */
3229
+ var RecordTooLargeError = class extends RecordsError {
3230
+ constructor(detail) {
3231
+ super("too-large", detail);
3232
+ this.name = "RecordTooLargeError";
3233
+ }
3234
+ };
3235
+ /** A filter, order or aggregate names a field no declared index serves. */
3236
+ var UnindexedFilterError = class extends RecordsError {
3237
+ constructor(detail) {
3238
+ super("unindexed-filter", detail);
3239
+ this.name = "UnindexedFilterError";
3240
+ }
3241
+ };
3242
+ /** A bulk delete with no predicate at all. */
3243
+ var FilterRequiredError = class extends RecordsError {
3244
+ constructor(detail) {
3245
+ super("filter-required", detail);
3246
+ this.name = "FilterRequiredError";
3247
+ }
3248
+ };
3249
+ /** The caller declared no such kind (another addon's kind is indistinguishable from none). */
3250
+ var UnknownRecordKindError = class extends RecordsError {
3251
+ constructor(detail) {
3252
+ super("unknown-kind", detail);
3253
+ this.name = "UnknownRecordKindError";
3254
+ }
3255
+ };
3256
+ var RecordNotFoundError = class extends RecordsError {
3257
+ constructor(detail) {
3258
+ super("not-found", detail);
3259
+ this.name = "RecordNotFoundError";
3260
+ }
3261
+ };
3262
+ /** A unique index refused the write. */
3263
+ var RecordUniqueViolationError = class extends RecordsError {
3264
+ constructor(detail) {
3265
+ super("unique-violation", detail);
3266
+ this.name = "RecordUniqueViolationError";
3267
+ }
3268
+ };
3269
+ /** A secret field held a plain string where only a keychain marker may be stored. */
3270
+ var PlaintextSecretError = class extends RecordsError {
3271
+ constructor(detail) {
3272
+ super("plaintext-secret", detail);
3273
+ this.name = "PlaintextSecretError";
3274
+ }
3275
+ };
3276
+ /** A marker whose ref is not the row's own (the D878 rule). */
3277
+ var ForeignSecretMarkerError = class extends RecordsError {
3278
+ constructor(detail) {
3279
+ super("foreign-marker", detail);
3280
+ this.name = "ForeignSecretMarkerError";
3281
+ }
3282
+ };
3283
+ /** The keychain could not store or serve a value: explicit, never an empty string. */
3284
+ var RecordSecretUnavailableError = class extends RecordsError {
3285
+ constructor(detail) {
3286
+ super("secret-unavailable", detail);
3287
+ this.name = "RecordSecretUnavailableError";
3288
+ }
3289
+ };
3290
+ var InvalidRecordError = class extends RecordsError {
3291
+ constructor(detail) {
3292
+ super("invalid-record", detail);
3293
+ this.name = "InvalidRecordError";
3294
+ }
3295
+ };
3296
+ /** A kind declaration the engine refuses (non-additive change, bad shape, wrong file). */
3297
+ var DeclarationRefusedError = class extends RecordsError {
3298
+ constructor(detail) {
3299
+ super("declaration-refused", detail);
3300
+ this.name = "DeclarationRefusedError";
3301
+ }
3302
+ };
3303
+ /** A kind is empty while the legacy table it adopts from still holds rows. */
3304
+ var AdoptionPendingError = class extends RecordsError {
3305
+ constructor(detail) {
3306
+ super("adoption-pending", detail);
3307
+ this.name = "AdoptionPendingError";
3308
+ }
3309
+ };
3310
+ var NoCallerError = class extends RecordsError {
3311
+ constructor(detail) {
3312
+ super("no-caller", detail);
3313
+ this.name = "NoCallerError";
3314
+ }
3315
+ };
3316
+ var BatchTooLargeError = class extends RecordsError {
3317
+ constructor(detail) {
3318
+ super("batch-too-large", detail);
3319
+ this.name = "BatchTooLargeError";
3320
+ }
3321
+ };
3322
+ var FACTORIES = {
3323
+ "rev-conflict": (d) => new RevConflictError(d),
3324
+ "too-large": (d) => new RecordTooLargeError(d),
3325
+ "unindexed-filter": (d) => new UnindexedFilterError(d),
3326
+ "filter-required": (d) => new FilterRequiredError(d),
3327
+ "unknown-kind": (d) => new UnknownRecordKindError(d),
3328
+ "not-found": (d) => new RecordNotFoundError(d),
3329
+ "unique-violation": (d) => new RecordUniqueViolationError(d),
3330
+ "plaintext-secret": (d) => new PlaintextSecretError(d),
3331
+ "foreign-marker": (d) => new ForeignSecretMarkerError(d),
3332
+ "secret-unavailable": (d) => new RecordSecretUnavailableError(d),
3333
+ "invalid-record": (d) => new InvalidRecordError(d),
3334
+ "declaration-refused": (d) => new DeclarationRefusedError(d),
3335
+ "adoption-pending": (d) => new AdoptionPendingError(d),
3336
+ "no-caller": (d) => new NoCallerError(d),
3337
+ "batch-too-large": (d) => new BatchTooLargeError(d)
3338
+ };
3339
+ function isCode(value) {
3340
+ return RECORDS_ERROR_CODES.some((code) => code === value);
3244
3341
  }
3245
3342
  /**
3246
- * The broker id keying a physical SOURCE stream: `${deviceId}/${camStreamId}`.
3247
- * This is the broker's internal source key (`brokerIdFor` in the manager) — a
3248
- * `camStreamId` like `native:main` — as opposed to the public profile alias
3249
- * {@link makeProfileBrokerId}. Used to resolve a source's restream endpoint
3250
- * (e.g. routing a transcode's ffmpeg input through the broker so it rides the
3251
- * single source dial instead of opening a second camera connection).
3343
+ * Rebuild the typed error from a message that crossed a wire; `null` when the
3344
+ * message is not a records failure.
3252
3345
  */
3253
- function makeSourceBrokerId(deviceId, camStreamId) {
3254
- return `${deviceId}/${camStreamId}`;
3346
+ function recordsErrorFromMessage(message) {
3347
+ if (!message.startsWith(PREFIX)) return null;
3348
+ const colon = message.indexOf(": ");
3349
+ if (colon < 0) return null;
3350
+ const code = message.slice(8, colon);
3351
+ if (!isCode(code)) return null;
3352
+ return FACTORIES[code](message.slice(colon + 2));
3353
+ }
3354
+ /** The records failure inside any thrown value (a wrapped tRPC error included), or the value. */
3355
+ function asRecordsError(err) {
3356
+ if (err instanceof RecordsError) return err;
3357
+ if (err instanceof Error) {
3358
+ const typed = recordsErrorFromMessage(err.message);
3359
+ if (typed !== null) return typed;
3360
+ }
3361
+ return err;
3255
3362
  }
3363
+ //#endregion
3364
+ //#region src/device/zod-secret.ts
3256
3365
  /**
3257
- * Inverse of {@link makeProfileBrokerId}. Returns `null` when the string is
3258
- * not a canonical `${deviceId}/${profile}` id — e.g. a broker-internal
3259
- * cam-stream id (`5/native:main`), a derived/adaptive ref, or a malformed
3260
- * value. So a caller can safely distinguish "addresses a public profile"
3261
- * from "addresses something broker-internal".
3366
+ * Secret declaration on a Zod config schema (D783).
3367
+ *
3368
+ * A field is a secret because its schema SAYS so — `.meta({ secret: true })`,
3369
+ * spelled {@link SECRET_META} — never because its key looks like a credential.
3370
+ * It is the Zod twin of `secret: true` / `type: 'password'` on a config-UI
3371
+ * field (`isSecretConfigField`), and every consumer that treats secrets
3372
+ * specially reads it: the settings form (`zodEntriesToConfigUI`), the paths a
3373
+ * device advertises at `registerDevice` (`secretConfigPaths`, which the
3374
+ * non-admin redaction withholds at any depth), and the keychain later.
3375
+ *
3376
+ * Zod keeps `.meta()` in `z.globalRegistry`, which lives on `globalThis`, so a
3377
+ * declaration made by an addon's own copy of zod is visible here.
3262
3378
  */
3263
- function parseProfileBrokerId(brokerId) {
3264
- const slash = brokerId.indexOf("/");
3265
- if (slash <= 0) return null;
3266
- const idPart = brokerId.slice(0, slash);
3267
- const profilePart = brokerId.slice(slash + 1);
3268
- if (!/^\d+$/.test(idPart)) return null;
3269
- const parsed = CamProfileSchema.safeParse(profilePart);
3270
- if (!parsed.success) return null;
3271
- return {
3272
- deviceId: Number(idPart),
3273
- profile: parsed.data
3274
- };
3275
- }
3276
3379
  /**
3277
- * The profile slots worth consuming/recording: ASSIGNED only
3278
- * (`sourceCamStreamId != null`), DEDUPED by physical source so the same
3279
- * camera encoder is never subscribed/recorded twice, ordered high→mid→low.
3280
- * Optionally scoped to one `deviceId`. Pure; never mutates the input.
3380
+ * `{ secret: true }` — the one spelling of "this field holds a credential".
3281
3381
  *
3282
- * Recording `main` and `mid` when both point at the same `sourceCamStreamId`
3283
- * would dial the camera's internal stream twice for no benefit — this is the
3284
- * dedup that prevents that.
3382
+ * Addons write the LITERAL `.meta({ secret: true })` rather than importing
3383
+ * this constant: an addon running against an older `@camstack/types` would
3384
+ * otherwise call `.meta(undefined)`, which in zod v4 is the metadata GETTER
3385
+ * and returns no schema at all.
3285
3386
  */
3286
- function selectAssignedProfileSlots(slots, deviceId) {
3287
- const ordered = [...slots].filter((s) => deviceId === void 0 || s.deviceId === deviceId).toSorted((a, b) => CAM_PROFILE_ORDER.indexOf(a.profile) - CAM_PROFILE_ORDER.indexOf(b.profile));
3288
- const seenSources = /* @__PURE__ */ new Set();
3289
- const out = [];
3290
- for (const s of ordered) {
3291
- const src = s.sourceCamStreamId;
3292
- if (src === null) continue;
3293
- if (seenSources.has(src)) continue;
3294
- seenSources.add(src);
3295
- out.push(s);
3296
- }
3297
- return out;
3387
+ var SECRET_META = { secret: true };
3388
+ function defOf(schema) {
3389
+ const zodBag = Reflect.get(schema, "_zod");
3390
+ if (typeof zodBag !== "object" || zodBag === null) return {};
3391
+ const def = Reflect.get(zodBag, "def");
3392
+ if (typeof def !== "object" || def === null) return {};
3393
+ return def;
3298
3394
  }
3395
+ function declaredHere(schema) {
3396
+ return zod.z.globalRegistry.get(schema)?.secret === true;
3397
+ }
3398
+ /** Wrapper kinds whose `innerType` is the field itself. */
3399
+ var WRAPPERS = new Set([
3400
+ "optional",
3401
+ "nullable",
3402
+ "default",
3403
+ "prefault",
3404
+ "catch",
3405
+ "readonly",
3406
+ "nonoptional"
3407
+ ]);
3299
3408
  /**
3300
- * Zod schema for StreamSourceEntry — the canonical stream descriptor
3301
- * exposed by ICameraDevice.getStreamSources() and consumed by the broker.
3409
+ * The schema layers that make up ONE field: the schema itself and every
3410
+ * wrapper below it (optional / default / nullable / readonly / catch), plus
3411
+ * both sides of a pipe (`z.preprocess` puts the real schema on `out`,
3412
+ * `.transform` on `in`).
3302
3413
  */
3303
- var StreamSourceEntrySchema$1 = zod.z.object({
3414
+ function layersOf(schema) {
3415
+ const out = [];
3416
+ const queue = [schema];
3417
+ while (queue.length > 0) {
3418
+ const s = queue.shift();
3419
+ if (!s || out.includes(s)) continue;
3420
+ out.push(s);
3421
+ const def = defOf(s);
3422
+ if (def.type !== void 0 && WRAPPERS.has(def.type) && def.innerType) queue.push(def.innerType);
3423
+ if (def.type === "pipe") {
3424
+ if (def.in) queue.push(def.in);
3425
+ if (def.out) queue.push(def.out);
3426
+ }
3427
+ }
3428
+ return out;
3429
+ }
3430
+ /** True when any layer of this field declares `.meta({ secret: true })`. */
3431
+ function isZodSecret(schema) {
3432
+ return layersOf(schema).some(declaredHere);
3433
+ }
3434
+ /**
3435
+ * Every declared secret path in a config schema: dotted keys, `[]` for "each
3436
+ * element of this array" (`connection.password`, `rows[].token`). A declared
3437
+ * object or array is reported as one path and not descended into — everything
3438
+ * under it is secret.
3439
+ */
3440
+ function collectZodSecretPaths(schema, prefix = "") {
3441
+ if (isZodSecret(schema)) return prefix.length > 0 ? [prefix] : [];
3442
+ const paths = [];
3443
+ for (const layer of layersOf(schema)) {
3444
+ const def = defOf(layer);
3445
+ if (def.type === "object" && def.shape) for (const [key, child] of Object.entries(def.shape)) paths.push(...collectZodSecretPaths(child, prefix ? `${prefix}.${key}` : key));
3446
+ else if (def.type === "array" && def.element) paths.push(...collectZodSecretPaths(def.element, `${prefix}[]`));
3447
+ else if (def.type === "union" && def.options) for (const option of def.options) paths.push(...collectZodSecretPaths(option, prefix));
3448
+ else if (def.type === "intersection") {
3449
+ if (def.left) paths.push(...collectZodSecretPaths(def.left, prefix));
3450
+ if (def.right) paths.push(...collectZodSecretPaths(def.right, prefix));
3451
+ }
3452
+ }
3453
+ return [...new Set(paths)];
3454
+ }
3455
+ //#endregion
3456
+ //#region src/records/secret-paths.ts
3457
+ /**
3458
+ * Secret fields of a record, addressed the way a Zod schema declares them
3459
+ * (`collectZodSecretPaths`): dotted keys, `[]` for "each element of this array"
3460
+ * (`auth.accessToken`, `headers[].value`).
3461
+ *
3462
+ * Array elements are matched by a DECLARED id key (`secretArrayKeys`:
3463
+ * `{ headers: 'name' }`), never by index, so reordering a list keeps every
3464
+ * keychain ref (the same rule as `arrayItemFieldPath`). The concrete path of a
3465
+ * leaf names its element: `headers[X-Api].value`.
3466
+ *
3467
+ * Pure and browser-safe. Nothing here mutates: every transform returns a new value.
3468
+ */
3469
+ /** The array prefixes (declared form, e.g. `headers` or `a.headers`) of a path. */
3470
+ function parseSecretPath(path) {
3471
+ if (path.length === 0) throw new InvalidRecordError("an empty secret path");
3472
+ return path.split(".").map((raw) => {
3473
+ const each = raw.endsWith("[]");
3474
+ const key = each ? raw.slice(0, -2) : raw;
3475
+ if (key.length === 0) throw new InvalidRecordError(`secret path "${path}" has an empty segment`);
3476
+ return {
3477
+ key,
3478
+ each
3479
+ };
3480
+ });
3481
+ }
3482
+ /** The declared array prefixes of `path` that need an id key (`headers`, `a.rows`). */
3483
+ function secretArrayPrefixes(path) {
3484
+ const segments = parseSecretPath(path);
3485
+ const prefixes = [];
3486
+ const walked = [];
3487
+ for (const segment of segments) {
3488
+ walked.push(segment.key);
3489
+ if (segment.each) prefixes.push(walked.join("."));
3490
+ }
3491
+ return prefixes;
3492
+ }
3493
+ function isRecord$2(value) {
3494
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3495
+ }
3496
+ function elementId(element, idKey, declared, prefix) {
3497
+ const id = isRecord$2(element) ? element[idKey] : void 0;
3498
+ if (typeof id !== "string" || id.length === 0) throw new InvalidRecordError(`"${declared}": every element of "${prefix}" needs a non-empty string "${idKey}" to carry a secret`);
3499
+ return id;
3500
+ }
3501
+ /**
3502
+ * Visit every secret leaf PRESENT in `data` (an absent branch has nothing to
3503
+ * visit). `replace` returns the new leaf value, or {@link REMOVE_LEAF}; the
3504
+ * result is a new body, `data` is untouched.
3505
+ */
3506
+ var REMOVE_LEAF = Symbol("remove-leaf");
3507
+ function mapAt(node, segments, index, walkedKeys, concretePrefix, declared, arrayKeys, visit) {
3508
+ if (!isRecord$2(node)) return node;
3509
+ const segment = segments[index];
3510
+ if (segment === void 0) return node;
3511
+ if (!Object.prototype.hasOwnProperty.call(node, segment.key)) return node;
3512
+ const child = node[segment.key];
3513
+ const keys = [...walkedKeys, segment.key];
3514
+ const last = index === segments.length - 1;
3515
+ if (segment.each) {
3516
+ if (!Array.isArray(child)) return node;
3517
+ const prefix = keys.join(".");
3518
+ const idKey = arrayKeys[prefix];
3519
+ if (idKey === void 0) throw new InvalidRecordError(`"${declared}": no id key declared for the array "${prefix}"`);
3520
+ const mapped = child.map((element) => {
3521
+ const id = elementId(element, idKey, declared, prefix);
3522
+ const concrete = `${concretePrefix}${concretePrefix.length > 0 ? "." : ""}${segment.key}[${encodeURIComponent(id)}]`;
3523
+ return last ? element : mapAt(element, segments, index + 1, keys, concrete, declared, arrayKeys, visit);
3524
+ });
3525
+ return {
3526
+ ...node,
3527
+ [segment.key]: mapped
3528
+ };
3529
+ }
3530
+ const concrete = `${concretePrefix}${concretePrefix.length > 0 ? "." : ""}${segment.key}`;
3531
+ if (last) {
3532
+ const replacement = visit({
3533
+ declared,
3534
+ concrete,
3535
+ value: child
3536
+ });
3537
+ if (replacement === REMOVE_LEAF) return Object.fromEntries(Object.entries(node).filter(([key]) => key !== segment.key));
3538
+ return {
3539
+ ...node,
3540
+ [segment.key]: replacement
3541
+ };
3542
+ }
3543
+ return {
3544
+ ...node,
3545
+ [segment.key]: mapAt(child, segments, index + 1, keys, concrete, declared, arrayKeys, visit)
3546
+ };
3547
+ }
3548
+ /** Replace/remove every present secret leaf; returns a NEW body. */
3549
+ function mapSecretLeaves(data, paths, arrayKeys, visit) {
3550
+ let current = data;
3551
+ for (const declared of paths) current = mapAt(current, parseSecretPath(declared), 0, [], "", declared, arrayKeys, visit);
3552
+ return current;
3553
+ }
3554
+ /** Every present secret leaf, read-only. */
3555
+ function collectSecretLeaves(data, paths, arrayKeys) {
3556
+ const found = [];
3557
+ mapSecretLeaves(data, paths, arrayKeys, (leaf) => {
3558
+ found.push(leaf);
3559
+ return leaf.value;
3560
+ });
3561
+ return found;
3562
+ }
3563
+ /**
3564
+ * The keychain collection name a kind's secrets live under. Prefixed so a
3565
+ * record's refs never collide with the refs a legacy collection of the same name
3566
+ * already holds during an adoption.
3567
+ */
3568
+ function recordSecretCollection(kind) {
3569
+ return `${RECORD_SECRET_COLLECTION_PREFIX}${kind}`;
3570
+ }
3571
+ /** The ONE ref a row's secret field may carry: the engine and the facade both build it here. */
3572
+ function recordSecretRef(owner, kind, rowId, concretePath) {
3573
+ return buildSecretRef({
3574
+ owner,
3575
+ scope: {
3576
+ kind: "row",
3577
+ collection: recordSecretCollection(kind),
3578
+ rowId
3579
+ },
3580
+ fieldPath: concretePath
3581
+ });
3582
+ }
3583
+ /** A concrete path built from a flat array item, re-exported for adoption tooling. */
3584
+ var recordArrayItemPath = arrayItemFieldPath;
3585
+ //#endregion
3586
+ //#region src/records/record-kind.ts
3587
+ /**
3588
+ * Record kinds (D881): the declaration an addon makes of one kind of fact, the
3589
+ * Zod row schema that describes it, and the helper that turns the two into the
3590
+ * JSON the engine stores.
3591
+ *
3592
+ * A kind is declared ONCE, next to the code that owns it, and the engine's
3593
+ * reconciler creates its indexes - nothing creates DDL at runtime from a write.
3594
+ * Everything the generic machinery needs (secret fields, the entry descriptor)
3595
+ * is DERIVED from the Zod schema: `.meta({ secret: true })` marks a credential,
3596
+ * never a field name (D879).
3597
+ */
3598
+ /** A JSON field path: `trackId`, `auth.accessToken`. Charset-restricted: it is rendered into DDL. */
3599
+ var RecordFieldPathSchema = zod.z.string().regex(/^[A-Za-z_][A-Za-z0-9_]{0,63}(\.[A-Za-z_][A-Za-z0-9_]{0,63}){0,3}$/);
3600
+ var RecordIndexSchema = zod.z.object({
3601
+ name: zod.z.string().regex(/^[a-z][a-z0-9_]{0,31}$/),
3602
+ fields: zod.z.array(RecordFieldPathSchema).min(1).max(4),
3603
+ unique: zod.z.boolean().optional()
3604
+ }).strict();
3605
+ var RecordRetentionSchema = zod.z.union([
3606
+ zod.z.object({
3607
+ ttlMs: zod.z.number().int().positive(),
3608
+ from: zod.z.enum(["at", "write"])
3609
+ }).strict(),
3610
+ zod.z.object({
3611
+ maxRows: zod.z.number().int().positive().optional(),
3612
+ maxRowsPerDevice: zod.z.number().int().positive().optional()
3613
+ }).strict().refine((r) => r.maxRows !== void 0 || r.maxRowsPerDevice !== void 0, { message: "name maxRows, maxRowsPerDevice or both" }),
3614
+ zod.z.object({
3615
+ owner: zod.z.string().min(1),
3616
+ reason: zod.z.string().min(1)
3617
+ }).strict(),
3618
+ zod.z.object({ none: zod.z.string().min(1) }).strict()
3619
+ ]);
3620
+ /** The descriptor a generic entries UI reads (D881 "generic entries"). */
3621
+ var EntryDescriptorSchema = zod.z.object({
3622
+ title: zod.z.string().min(1),
3623
+ /** The record body field shown as the entry's name. */
3624
+ nameField: zod.z.string().min(1),
3625
+ /** JSON Schema of the entry body; `secret: true` marks a password field. */
3626
+ fields: zod.z.record(zod.z.string(), zod.z.unknown())
3627
+ }).strict();
3628
+ /** What crosses the wire and sits in the engine's catalog: JSON only, no Zod. */
3629
+ var RecordKindDeclarationSchema = zod.z.object({
3630
+ database: zod.z.enum(RECORD_DATABASES).default("settings"),
3631
+ class: zod.z.enum(RECORD_CLASSES),
3632
+ writeTrigger: zod.z.string().min(1),
3633
+ device: zod.z.enum([
3634
+ "required",
3635
+ "optional",
3636
+ "none"
3637
+ ]).default("none"),
3638
+ at: zod.z.enum(["required", "none"]).default("none"),
3639
+ indexes: zod.z.array(RecordIndexSchema).max(8).default([]),
3640
+ retention: RecordRetentionSchema,
3641
+ deviceRemoval: zod.z.enum(["delete", "none"]).default("none"),
3642
+ maxDataBytes: zod.z.number().int().positive().max(RECORD_MAX_DATA_BYTES).default(RECORD_DEFAULT_MAX_DATA_BYTES),
3643
+ /** Derived from the Zod schema; never written by hand. */
3644
+ secretPaths: zod.z.array(zod.z.string().min(1)).default([]),
3645
+ /** The id key of each array that carries a secret (`{ headers: 'name' }`). */
3646
+ secretArrayKeys: zod.z.record(zod.z.string(), zod.z.string()).default({}),
3647
+ /** The legacy table this kind adopts from; the boot guard reads it (D853: no migration code). */
3648
+ adoptsFrom: zod.z.string().min(1).optional(),
3649
+ /** Kinds that must agree through `transact` sit in one file under one family name. */
3650
+ transactFamily: zod.z.string().min(1).optional(),
3651
+ entry: EntryDescriptorSchema.optional()
3652
+ }).strict();
3653
+ /** The kind names: lower-case, dash separated, short enough for an index name. */
3654
+ var RecordKindNameSchema = zod.z.string().regex(/^[a-z][a-z0-9-]{0,47}$/);
3655
+ /** Cross-field rules a declaration must satisfy. Throws {@link DeclarationRefusedError}. */
3656
+ function assertValidDeclaration(name, decl) {
3657
+ const refuse = (why) => {
3658
+ throw new DeclarationRefusedError(`kind "${name}": ${why}`);
3659
+ };
3660
+ if (!RecordKindNameSchema.safeParse(name).success) refuse("the name must be lower-case-dashed");
3661
+ const seen = /* @__PURE__ */ new Set();
3662
+ for (const index of decl.indexes) {
3663
+ if (seen.has(index.name)) refuse(`index name "${index.name}" is declared twice`);
3664
+ seen.add(index.name);
3665
+ }
3666
+ const { retention } = decl;
3667
+ const hasSecrets = decl.secretPaths.length > 0;
3668
+ if ("ttlMs" in retention) {
3669
+ if (retention.from === "at" && decl.at !== "required") refuse("a ttl from \"at\" needs at: \"required\"");
3670
+ if (hasSecrets) refuse("a kind with secret fields cannot use engine TTL (its keychain values would be orphaned)");
3671
+ }
3672
+ if ("maxRows" in retention || "maxRowsPerDevice" in retention) {
3673
+ if (retention.maxRowsPerDevice !== void 0 && decl.device !== "required") refuse("maxRowsPerDevice needs device: \"required\"");
3674
+ if (decl.at !== "required") refuse("a row bound trims the oldest \"at\": it needs at: \"required\"");
3675
+ if (hasSecrets) refuse("a kind with secret fields cannot use an engine row bound");
3676
+ const bound = Math.max(retention.maxRows ?? 0, retention.maxRowsPerDevice ?? 0);
3677
+ if (decl.database === "settings" && bound > 5e4) refuse(`a row bound above ${RECORD_SETTINGS_MAX_ROWS} belongs in database: "events" (a big delete on the settings thread stalls every configuration read)`);
3678
+ }
3679
+ if (decl.deviceRemoval === "delete" && decl.device === "none") refuse("deviceRemoval: \"delete\" needs a device: \"required\" or \"optional\"");
3680
+ for (const path of decl.secretPaths) for (const prefix of secretArrayPrefixes(path)) if (decl.secretArrayKeys[prefix] === void 0) refuse(`secret path "${path}" crosses the array "${prefix}": declare its id key in secretArrayKeys`);
3681
+ }
3682
+ function bodyFieldsOf(schema) {
3683
+ return { ...zod.z.toJSONSchema(schema, {
3684
+ unrepresentable: "any",
3685
+ io: "input"
3686
+ }) };
3687
+ }
3688
+ function isRecordLike(value) {
3689
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3690
+ }
3691
+ /** Does every branch of the body schema carry `field`? (A discriminated union has several.) */
3692
+ function hasNameField(json, field) {
3693
+ const branches = json["oneOf"] ?? json["anyOf"];
3694
+ if (Array.isArray(branches)) return branches.length > 0 && branches.every((b) => isRecordLike(b) && hasNameField(b, field));
3695
+ const properties = json["properties"];
3696
+ return isRecordLike(properties) && Object.prototype.hasOwnProperty.call(properties, field);
3697
+ }
3698
+ /**
3699
+ * Declare the kinds of a package. The keys are the kind names. The result is
3700
+ * what `ctx.records.declare` sends to the engine and what `ctx.records.kind`
3701
+ * types its handle from.
3702
+ */
3703
+ function defineRecordKinds(specs) {
3704
+ const out = {};
3705
+ for (const [name, spec] of Object.entries(specs)) {
3706
+ const secretPaths = collectZodSecretPaths(spec.schema);
3707
+ const nameField = spec.entry?.nameField ?? "name";
3708
+ const fields = bodyFieldsOf(spec.schema);
3709
+ if (spec.entry !== void 0 && !hasNameField(fields, nameField)) throw new DeclarationRefusedError(`kind "${name}": an entry kind's schema needs a "${nameField}" field`);
3710
+ const parsed = RecordKindDeclarationSchema.parse({
3711
+ database: spec.database,
3712
+ class: spec.class,
3713
+ writeTrigger: spec.writeTrigger,
3714
+ device: spec.device,
3715
+ at: spec.at,
3716
+ indexes: spec.indexes === void 0 ? void 0 : [...spec.indexes],
3717
+ retention: spec.retention,
3718
+ deviceRemoval: spec.deviceRemoval,
3719
+ maxDataBytes: spec.maxDataBytes,
3720
+ secretPaths: [...secretPaths],
3721
+ secretArrayKeys: spec.secretArrayKeys === void 0 ? void 0 : { ...spec.secretArrayKeys },
3722
+ adoptsFrom: spec.adoptsFrom,
3723
+ transactFamily: spec.transactFamily,
3724
+ entry: spec.entry === void 0 ? void 0 : {
3725
+ title: spec.entry.title,
3726
+ nameField,
3727
+ fields
3728
+ }
3729
+ });
3730
+ assertValidDeclaration(name, parsed);
3731
+ out[name] = {
3732
+ name,
3733
+ schema: spec.schema,
3734
+ declaration: parsed
3735
+ };
3736
+ }
3737
+ return out;
3738
+ }
3739
+ /** The wire form of a package's kinds: name -> declaration. */
3740
+ function declarationsOf(kinds) {
3741
+ return Object.fromEntries(Object.entries(kinds).map(([name, kind]) => [name, kind.declaration]));
3742
+ }
3743
+ //#endregion
3744
+ //#region src/records/records-access.ts
3745
+ function isRecord$1(value) {
3746
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3747
+ }
3748
+ /** Run a transport call and give a wire failure its typed class back. */
3749
+ async function call(fn) {
3750
+ try {
3751
+ return await fn();
3752
+ } catch (err) {
3753
+ throw asRecordsError(err);
3754
+ }
3755
+ }
3756
+ function zodSummary(error) {
3757
+ return error.issues.slice(0, 5).map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`).join("; ");
3758
+ }
3759
+ function toRow(view, data) {
3760
+ return {
3761
+ id: view.id,
3762
+ deviceId: view.deviceId,
3763
+ at: view.at,
3764
+ expiresAt: view.expiresAt,
3765
+ rev: view.rev,
3766
+ updatedAt: view.updatedAt,
3767
+ data
3768
+ };
3769
+ }
3770
+ var KindHandle = class {
3771
+ def;
3772
+ o;
3773
+ name;
3774
+ decl;
3775
+ constructor(def, o) {
3776
+ this.def = def;
3777
+ this.o = o;
3778
+ this.name = def.name;
3779
+ this.decl = def.declaration;
3780
+ }
3781
+ get hasSecrets() {
3782
+ return this.decl.secretPaths.length > 0;
3783
+ }
3784
+ requireSecrets() {
3785
+ if (this.o.secrets === null) throw new RecordSecretUnavailableError(`kind "${this.name}" has secret fields and this process has no keychain door`);
3786
+ return this.o.secrets;
3787
+ }
3788
+ /** Read the body as the schema's type. The engine already redacted the secrets. */
3789
+ typed(view) {
3790
+ return toRow(view, view.data);
3791
+ }
3792
+ /**
3793
+ * Classify and store the secret leaves of a body about to be written. The
3794
+ * keychain is written FIRST (a failure throws before any row is touched), and
3795
+ * what each ref held before is remembered: when the row write is then refused
3796
+ * (a stale `ifRev`, too large, a unique index) `rollback` puts the previous
3797
+ * values back, so a refused write never destroys the secret that was stored.
3798
+ */
3799
+ async storeSecrets(id, body, mode) {
3800
+ if (!this.hasSecrets) return {
3801
+ body,
3802
+ rollback: async () => {}
3803
+ };
3804
+ const secrets = this.requireSecrets();
3805
+ const writes = [];
3806
+ const prepared = mapSecretLeaves(body, this.decl.secretPaths, this.decl.secretArrayKeys, (leaf) => {
3807
+ const intent = classifySecretWrite(leaf.value);
3808
+ if (intent.kind === "clear") return REMOVE_LEAF;
3809
+ if (intent.kind === "keep") {
3810
+ if (mode === "put") return REDACTED_SECRET;
3811
+ if (leaf.value === null) return null;
3812
+ return leaf.concrete.includes("[") ? REDACTED_SECRET : REMOVE_LEAF;
3813
+ }
3814
+ const ref = recordSecretRef(this.o.owner, this.name, id, leaf.concrete);
3815
+ writes.push({
3816
+ ref,
3817
+ value: intent.value
3818
+ });
3819
+ return makeSecretMarker(ref);
3820
+ });
3821
+ const done = [];
3822
+ const rollback = async () => {
3823
+ for (const { ref, previous } of done) try {
3824
+ if (previous === void 0) await secrets.delete([ref]);
3825
+ else await secrets.put(ref, previous);
3826
+ } catch (err) {
3827
+ this.o.logger?.warn("records: could not restore a keychain value after a refused write", { meta: {
3828
+ kind: this.name,
3829
+ error: err instanceof Error ? err.message : "unknown"
3830
+ } });
3831
+ }
3832
+ };
3833
+ for (const write of writes) try {
3834
+ const before = (await secrets.resolve([write.ref]))[write.ref];
3835
+ const previous = before?.kind === "value" ? before.value : void 0;
3836
+ await secrets.put(write.ref, write.value);
3837
+ done.push({
3838
+ ref: write.ref,
3839
+ previous
3840
+ });
3841
+ } catch (err) {
3842
+ await rollback();
3843
+ throw new RecordSecretUnavailableError(`cannot store a secret of ${this.name}/${id}: ${err instanceof Error ? err.message : "the keychain refused"}. Unlock the keychain (System -> Secrets) and save again`);
3844
+ }
3845
+ return {
3846
+ body: prepared,
3847
+ rollback
3848
+ };
3849
+ }
3850
+ async releaseRefs(refs) {
3851
+ if (refs.length === 0 || this.o.secrets === null) return;
3852
+ try {
3853
+ await this.o.secrets.delete(refs);
3854
+ } catch (err) {
3855
+ this.o.logger?.warn("records: could not remove released keychain values", { meta: {
3856
+ kind: this.name,
3857
+ count: refs.length,
3858
+ error: err instanceof Error ? err.message : "unknown"
3859
+ } });
3860
+ }
3861
+ }
3862
+ validate(data, id) {
3863
+ const shaped = this.hasSecrets ? mapSecretLeaves(data, this.decl.secretPaths, this.decl.secretArrayKeys, (leaf) => {
3864
+ const intent = classifySecretWrite(leaf.value);
3865
+ if (intent.kind === "clear") return REMOVE_LEAF;
3866
+ return intent.kind === "keep" ? REDACTED_SECRET : leaf.value;
3867
+ }) : data;
3868
+ const parsed = this.def.schema.safeParse(shaped);
3869
+ if (!parsed.success) throw new InvalidRecordError(`${this.name}/${id}: ${zodSummary(parsed.error)}`);
3870
+ if (!isRecord$1(parsed.data)) throw new InvalidRecordError(`${this.name}/${id}: the body must be an object`);
3871
+ return parsed.data;
3872
+ }
3873
+ async get(id) {
3874
+ const view = await call(() => this.o.transport.get({
3875
+ kind: this.name,
3876
+ id
3877
+ }));
3878
+ return view === null ? null : this.typed(view);
3879
+ }
3880
+ async getMany(ids) {
3881
+ if (ids.length === 0) return [];
3882
+ return (await call(() => this.o.transport.getMany({
3883
+ kind: this.name,
3884
+ ids: [...ids]
3885
+ }))).map((v) => this.typed(v));
3886
+ }
3887
+ async getResolved(id) {
3888
+ const row = await this.get(id);
3889
+ if (row === null) return null;
3890
+ return (await this.resolveRows([row]))[0] ?? row;
3891
+ }
3892
+ async resolveRows(rows) {
3893
+ if (!this.hasSecrets || rows.length === 0) return rows;
3894
+ const secrets = this.requireSecrets();
3895
+ const refsById = await call(() => this.o.transport.secretRefs({
3896
+ kind: this.name,
3897
+ ids: rows.map((r) => r.id)
3898
+ }));
3899
+ const refs = Object.values(refsById).flatMap((byPath) => Object.values(byPath));
3900
+ if (refs.length === 0) return rows;
3901
+ const answers = await secrets.resolve(refs);
3902
+ return rows.map((row) => {
3903
+ const byPath = refsById[row.id] ?? {};
3904
+ const resolved = mapSecretLeaves(row.data, this.decl.secretPaths, this.decl.secretArrayKeys, (leaf) => {
3905
+ const ref = byPath[leaf.concrete];
3906
+ if (ref === void 0) return leaf.value;
3907
+ const answer = answers[ref];
3908
+ if (answer?.kind === "value") return answer.value;
3909
+ const why = answer?.kind === "unavailable" ? answer.reason : answer?.kind ?? "no answer";
3910
+ throw new RecordSecretUnavailableError(`the secret "${leaf.concrete}" of ${this.name}/${row.id} cannot be served (${why})`);
3911
+ });
3912
+ return {
3913
+ ...row,
3914
+ data: resolved
3915
+ };
3916
+ });
3917
+ }
3918
+ async put(input, opts = {}) {
3919
+ const checked = this.validate(input.data, input.id);
3920
+ const { body, rollback } = await this.storeSecrets(input.id, checked, "put");
3921
+ const result = await call(() => this.o.transport.put({
3922
+ kind: this.name,
3923
+ record: {
3924
+ ...input,
3925
+ data: toBody(body)
3926
+ },
3927
+ ...opts.ifRev === void 0 ? {} : { ifRev: opts.ifRev }
3928
+ })).catch(async (err) => {
3929
+ await rollback();
3930
+ throw err;
3931
+ });
3932
+ await this.releaseRefs(result.releasedRefs);
3933
+ return { rev: result.rev };
3934
+ }
3935
+ async putMany(inputs) {
3936
+ if (inputs.length === 0) return { count: 0 };
3937
+ const prepared = [];
3938
+ const rollbacks = [];
3939
+ try {
3940
+ for (const input of inputs) {
3941
+ const checked = this.validate(input.data, input.id);
3942
+ const { body, rollback } = await this.storeSecrets(input.id, checked, "put");
3943
+ rollbacks.push(rollback);
3944
+ prepared.push({
3945
+ ...input,
3946
+ data: toBody(body)
3947
+ });
3948
+ }
3949
+ } catch (err) {
3950
+ for (const rollback of rollbacks) await rollback();
3951
+ throw err;
3952
+ }
3953
+ const result = await call(() => this.o.transport.putMany({
3954
+ kind: this.name,
3955
+ records: prepared
3956
+ })).catch(async (err) => {
3957
+ for (const rollback of rollbacks) await rollback();
3958
+ throw err;
3959
+ });
3960
+ await this.releaseRefs(result.releasedRefs);
3961
+ return { count: result.count };
3962
+ }
3963
+ async patch(id, partial, opts = {}) {
3964
+ const { body, rollback } = await this.storeSecrets(id, partial, "patch");
3965
+ const result = await call(() => this.o.transport.patch({
3966
+ kind: this.name,
3967
+ id,
3968
+ data: toBody(body),
3969
+ ...opts.at === void 0 ? {} : { at: opts.at },
3970
+ ...opts.expiresAt === void 0 ? {} : { expiresAt: opts.expiresAt },
3971
+ ...opts.ifRev === void 0 ? {} : { ifRev: opts.ifRev }
3972
+ })).catch(async (err) => {
3973
+ await rollback();
3974
+ throw err;
3975
+ });
3976
+ await this.releaseRefs(result.releasedRefs);
3977
+ return { rev: result.rev };
3978
+ }
3979
+ async delete(id) {
3980
+ const result = await call(() => this.o.transport.delete({
3981
+ kind: this.name,
3982
+ id
3983
+ }));
3984
+ await this.releaseRefs(result.secretRefs);
3985
+ return result.deleted;
3986
+ }
3987
+ async deleteMany(ids) {
3988
+ if (ids.length === 0) return 0;
3989
+ const result = await call(() => this.o.transport.deleteMany({
3990
+ kind: this.name,
3991
+ ids: [...ids]
3992
+ }));
3993
+ await this.releaseRefs(result.secretRefs);
3994
+ return result.deleted;
3995
+ }
3996
+ async query(q, opts = {}) {
3997
+ const result = await call(() => this.o.transport.query({
3998
+ ...q,
3999
+ kind: this.name,
4000
+ limit: q.limit ?? 100
4001
+ }));
4002
+ const rows = result.records.map((v) => this.typed(v));
4003
+ return {
4004
+ records: opts.resolveSecrets === true ? await this.resolveRows(rows) : rows,
4005
+ nextCursor: result.nextCursor
4006
+ };
4007
+ }
4008
+ async count(q) {
4009
+ return (await call(() => this.o.transport.count({
4010
+ ...q,
4011
+ kind: this.name
4012
+ }))).count;
4013
+ }
4014
+ async histogram(q) {
4015
+ return (await call(() => this.o.transport.histogram({
4016
+ ...q,
4017
+ kind: this.name
4018
+ }))).buckets;
4019
+ }
4020
+ async aggregate(q) {
4021
+ return (await call(() => this.o.transport.aggregate({
4022
+ ...q,
4023
+ kind: this.name
4024
+ }))).rows;
4025
+ }
4026
+ async deleteWhere(q) {
4027
+ const result = await call(() => this.o.transport.deleteWhere({
4028
+ ...q,
4029
+ kind: this.name
4030
+ }));
4031
+ await this.releaseRefs(result.secretRefs);
4032
+ return result.deleted;
4033
+ }
4034
+ async allocateId() {
4035
+ return (await call(() => this.o.transport.allocateId({ kind: this.name }))).id;
4036
+ }
4037
+ };
4038
+ function toBody(value) {
4039
+ if (!isRecord$1(value)) throw new InvalidRecordError("the record body must be an object");
4040
+ return value;
4041
+ }
4042
+ /** Build the owner's records handle. */
4043
+ function createRecordsAccess(options) {
4044
+ const handles = /* @__PURE__ */ new WeakMap();
4045
+ const delegates = /* @__PURE__ */ new Map();
4046
+ return {
4047
+ owner: options.owner,
4048
+ forOwner: options.transportForOwner === void 0 ? null : (other) => {
4049
+ const existing = delegates.get(other);
4050
+ if (existing !== void 0) return existing;
4051
+ const build = options.transportForOwner;
4052
+ if (build === void 0) throw new Error("forOwner: no delegate transport");
4053
+ const delegate = createRecordsAccess({
4054
+ owner: other,
4055
+ transport: build(other),
4056
+ secrets: options.secrets?.forOwner?.(other) ?? null,
4057
+ ...options.logger === void 0 ? {} : { logger: options.logger }
4058
+ });
4059
+ delegates.set(other, delegate);
4060
+ return delegate;
4061
+ },
4062
+ async declare(kinds) {
4063
+ const result = await call(() => options.transport.declareKinds({ kinds: { ...declarationsOf(kinds) } }));
4064
+ const pending = Object.entries(result.kinds).filter((entry) => entry[1].adoptionPending !== null);
4065
+ if (pending.length > 0) throw new AdoptionPendingError(`${pending.map(([name, r]) => r.adoptionPending === null ? name : `${name} (legacy table "${r.adoptionPending.legacyTable}" holds ${r.adoptionPending.legacyRows} rows)`).join(", ")}. Stop the addon and run scripts/hub/records-adopt.ts --copy --apply before starting this build`);
4066
+ return result.kinds;
4067
+ },
4068
+ kind(definition) {
4069
+ const existing = handles.get(definition);
4070
+ if (existing !== void 0) return existing;
4071
+ const handle = new KindHandle(definition, options);
4072
+ handles.set(definition, handle);
4073
+ return handle;
4074
+ },
4075
+ async deleteDevice(deviceId, opts = {}) {
4076
+ const result = await call(() => options.transport.deleteDevice({
4077
+ deviceId,
4078
+ ...opts.kinds === void 0 ? {} : { kinds: [...opts.kinds] }
4079
+ }));
4080
+ if (result.secretRefs.length > 0 && options.secrets !== null) try {
4081
+ await options.secrets.delete(result.secretRefs);
4082
+ } catch (err) {
4083
+ options.logger?.warn("records: could not remove released keychain values", { meta: {
4084
+ count: result.secretRefs.length,
4085
+ error: err instanceof Error ? err.message : "unknown"
4086
+ } });
4087
+ }
4088
+ return result.deleted;
4089
+ }
4090
+ };
4091
+ }
4092
+ //#endregion
4093
+ //#region src/records/entry-kind.ts
4094
+ /**
4095
+ * Entry kinds (D881): every list of user-created entries (notification
4096
+ * targets, brokers, LLM profiles) is ONE record kind with an id, a name and a
4097
+ * kind-specific body, and the admin UI lists/adds/edits/deletes all of them
4098
+ * through the `record-entries` capability with password fields derived from
4099
+ * the schema (`.meta({ secret: true })`).
4100
+ */
4101
+ /** The body of a plain entry: a name and the fields the kind adds. */
4102
+ function entryBody(shape) {
4103
+ return zod.z.object({
4104
+ name: zod.z.string().min(1),
4105
+ ...shape
4106
+ });
4107
+ }
4108
+ /**
4109
+ * Declare one entry kind. An entry is configuration: never trimmed by the
4110
+ * engine, never aged, belonging to no device.
4111
+ */
4112
+ function defineEntryKind(name, spec) {
4113
+ const defined = defineRecordKinds({ [name]: {
4114
+ schema: spec.schema,
4115
+ class: "config",
4116
+ writeTrigger: spec.writeTrigger ?? "an operator adds or edits an entry in the entries UI",
4117
+ retention: { none: "an entry goes only when the operator deletes it" },
4118
+ ...spec.database === void 0 ? {} : { database: spec.database },
4119
+ ...spec.indexes === void 0 ? {} : { indexes: spec.indexes },
4120
+ ...spec.secretArrayKeys === void 0 ? {} : { secretArrayKeys: spec.secretArrayKeys },
4121
+ ...spec.adoptsFrom === void 0 ? {} : { adoptsFrom: spec.adoptsFrom },
4122
+ entry: {
4123
+ title: spec.title,
4124
+ ...spec.nameField === void 0 ? {} : { nameField: spec.nameField }
4125
+ }
4126
+ } })[name];
4127
+ if (defined === void 0) throw new DeclarationRefusedError(`entry kind "${name}" was not built`);
4128
+ return defined;
4129
+ }
4130
+ //#endregion
4131
+ //#region src/records/settings-brokers-adopts-from.ts
4132
+ /**
4133
+ * Legacy source for broker entry adoption (B2): brokers live in addon-settings
4134
+ * as one row `<addonId>.brokers` whose value is an array until records-adopt
4135
+ * copies them into the entry kind.
4136
+ */
4137
+ var SETTINGS_BROKERS_ADOPTS_PREFIX = "@settings-brokers/";
4138
+ /** The `adoptsFrom` value for an addon's broker entry kind. */
4139
+ function settingsBrokersAdoptsFrom(addonId) {
4140
+ return `${SETTINGS_BROKERS_ADOPTS_PREFIX}${addonId}`;
4141
+ }
4142
+ /** When non-null, `from` names an addon-settings brokers blob, not a SQL table. */
4143
+ function parseSettingsBrokersAdoptsFrom(from) {
4144
+ if (!from.startsWith("@settings-brokers/")) return null;
4145
+ const addonId = from.slice(18);
4146
+ return addonId.length > 0 ? addonId : null;
4147
+ }
4148
+ //#endregion
4149
+ //#region src/records/settings-array-adopts-from.ts
4150
+ /**
4151
+ * Legacy source for entry adoption (B3): a list stored under addon-settings
4152
+ * `<addonId>.<key>` until records-adopt copies rows into the entry kind.
4153
+ */
4154
+ var SETTINGS_ARRAY_ADOPTS_PREFIX = "@settings-array/";
4155
+ /** The `adoptsFrom` value for an addon-settings array field. */
4156
+ function settingsArrayAdoptsFrom(addonId, settingsKey) {
4157
+ return `${SETTINGS_ARRAY_ADOPTS_PREFIX}${addonId}/${settingsKey}`;
4158
+ }
4159
+ /** When non-null, `from` names an addon-settings array blob, not a SQL table. */
4160
+ function parseSettingsArrayAdoptsFrom(from) {
4161
+ if (!from.startsWith("@settings-array/")) return null;
4162
+ const rest = from.slice(16);
4163
+ const slash = rest.indexOf("/");
4164
+ if (slash <= 0 || slash >= rest.length - 1) return null;
4165
+ const addonId = rest.slice(0, slash);
4166
+ const settingsKey = rest.slice(slash + 1);
4167
+ if (addonId.length === 0 || settingsKey.length === 0) return null;
4168
+ return {
4169
+ addonId,
4170
+ settingsKey
4171
+ };
4172
+ }
4173
+ //#endregion
4174
+ //#region src/records/in-memory-records.ts
4175
+ /**
4176
+ * In-memory `RecordsAccess` for specs. Kinds are declared by the caller.
4177
+ * Lives in `@camstack/types` so a spec does not import another package's source.
4178
+ */
4179
+ function isRecord(value) {
4180
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4181
+ }
4182
+ function markersOf(decl, body) {
4183
+ const out = /* @__PURE__ */ new Map();
4184
+ mapSecretLeaves(body, decl.secretPaths, decl.secretArrayKeys, (leaf) => {
4185
+ if (isSecretMarker(leaf.value)) out.set(leaf.concrete, leaf.value.$secret);
4186
+ return leaf.value;
4187
+ });
4188
+ return out;
4189
+ }
4190
+ function makeSpecKeychain(owner) {
4191
+ const values = /* @__PURE__ */ new Map();
4192
+ return { access: {
4193
+ owner,
4194
+ ref: (scope, fieldPath) => buildSecretRef({
4195
+ owner,
4196
+ scope,
4197
+ fieldPath
4198
+ }),
4199
+ resolve: async (refs) => {
4200
+ const out = {};
4201
+ for (const ref of refs) {
4202
+ const value = values.get(ref);
4203
+ out[ref] = value === void 0 ? { kind: "missing" } : {
4204
+ kind: "value",
4205
+ value,
4206
+ version: 1
4207
+ };
4208
+ }
4209
+ return out;
4210
+ },
4211
+ put: async (ref, value) => {
4212
+ values.set(ref, value);
4213
+ return 1;
4214
+ },
4215
+ delete: async (refs) => {
4216
+ let deleted = 0;
4217
+ for (const ref of refs) if (values.delete(ref)) deleted += 1;
4218
+ return deleted;
4219
+ },
4220
+ state: async () => ({ state: "ready" }),
4221
+ onChange: () => () => void 0,
4222
+ forOwner: null
4223
+ } };
4224
+ }
4225
+ function makeInMemoryRecords(owner = "spec") {
4226
+ const decls = /* @__PURE__ */ new Map();
4227
+ const tables = /* @__PURE__ */ new Map();
4228
+ let clock = 1;
4229
+ let writesFail = false;
4230
+ let readsFail = false;
4231
+ const table = (kind) => {
4232
+ let t = tables.get(kind);
4233
+ if (t === void 0) {
4234
+ t = /* @__PURE__ */ new Map();
4235
+ tables.set(kind, t);
4236
+ }
4237
+ return t;
4238
+ };
4239
+ const declOf = (kind) => {
4240
+ const decl = decls.get(kind);
4241
+ if (decl === void 0) throw new Error(`kind "${kind}" is not declared`);
4242
+ return decl;
4243
+ };
4244
+ const redact = (decl, body) => {
4245
+ if (decl.secretPaths.length === 0) return body;
4246
+ const out = mapSecretLeaves(body, decl.secretPaths, decl.secretArrayKeys, (leaf) => leaf.value === null ? null : REDACTED_SECRET);
4247
+ return isRecord(out) ? out : body;
4248
+ };
4249
+ const view = (kind, row) => ({
4250
+ id: row.id,
4251
+ deviceId: null,
4252
+ at: row.at,
4253
+ expiresAt: null,
4254
+ rev: row.rev,
4255
+ updatedAt: row.updatedAt,
4256
+ data: redact(declOf(kind), row.data)
4257
+ });
4258
+ const enforce = (kind, id, body, stored) => {
4259
+ const decl = declOf(kind);
4260
+ if (decl.secretPaths.length === 0) return {
4261
+ body,
4262
+ released: []
4263
+ };
4264
+ const before = stored === null ? /* @__PURE__ */ new Map() : markersOf(decl, stored);
4265
+ const next = mapSecretLeaves(body, decl.secretPaths, decl.secretArrayKeys, (leaf) => {
4266
+ const expected = recordSecretRef(owner, kind, id, leaf.concrete);
4267
+ if (isSecretMarker(leaf.value)) {
4268
+ if (leaf.value.$secret !== expected) throw new Error("foreign secret marker");
4269
+ return leaf.value;
4270
+ }
4271
+ if (leaf.value === "__camstack_redacted__") {
4272
+ const keep = before.get(leaf.concrete);
4273
+ return keep === void 0 ? REMOVE_LEAF : {
4274
+ $secret: keep,
4275
+ v: 1
4276
+ };
4277
+ }
4278
+ if (leaf.value === null || leaf.value === void 0) return REMOVE_LEAF;
4279
+ throw new Error(`${kind}/${id}: a secret field takes a keychain marker, never a value`);
4280
+ });
4281
+ if (!isRecord(next)) throw new Error("the body must be an object");
4282
+ const after = markersOf(decl, next);
4283
+ return {
4284
+ body: next,
4285
+ released: [...before.entries()].filter(([p, ref]) => after.get(p) !== ref).map(([, r]) => r)
4286
+ };
4287
+ };
4288
+ const write = (kind, input) => {
4289
+ if (writesFail) throw new Error("records engine unreachable");
4290
+ if (declOf(kind).at === "required" && input.at === void 0) throw new Error(`${kind}/${input.id}: the kind needs "at" on every write`);
4291
+ const prev = table(kind).get(input.id);
4292
+ const { body, released } = enforce(kind, input.id, input.data, prev?.data ?? null);
4293
+ const rev = (prev?.rev ?? 0) + 1;
4294
+ clock += 1;
4295
+ table(kind).set(input.id, {
4296
+ id: input.id,
4297
+ at: input.at ?? null,
4298
+ rev,
4299
+ updatedAt: clock,
4300
+ data: body
4301
+ });
4302
+ return {
4303
+ rev,
4304
+ released
4305
+ };
4306
+ };
4307
+ const unimplemented = (op) => {
4308
+ throw new Error(`the fake records transport does not implement ${op}`);
4309
+ };
4310
+ return {
4311
+ records: createRecordsAccess({
4312
+ owner,
4313
+ transport: {
4314
+ declareKinds: async ({ kinds }) => {
4315
+ const out = {};
4316
+ let n = 0;
4317
+ for (const [name, decl] of Object.entries(kinds)) {
4318
+ decls.set(name, decl);
4319
+ n += 1;
4320
+ out[name] = {
4321
+ kindId: n,
4322
+ state: "created",
4323
+ createdIndexes: decl.indexes.map((i) => i.name),
4324
+ adoptionPending: null
4325
+ };
4326
+ }
4327
+ return { kinds: out };
4328
+ },
4329
+ get: async ({ kind, id }) => {
4330
+ if (readsFail) throw new Error("records engine unreachable");
4331
+ const row = table(kind).get(id);
4332
+ return row === void 0 ? null : view(kind, row);
4333
+ },
4334
+ getMany: async ({ kind, ids }) => ids.flatMap((id) => {
4335
+ const row = table(kind).get(id);
4336
+ return row === void 0 ? [] : [view(kind, row)];
4337
+ }),
4338
+ secretRefs: async ({ kind, ids }) => {
4339
+ const decl = declOf(kind);
4340
+ const out = {};
4341
+ for (const id of ids) {
4342
+ const row = table(kind).get(id);
4343
+ if (row !== void 0) out[id] = Object.fromEntries(markersOf(decl, row.data));
4344
+ }
4345
+ return out;
4346
+ },
4347
+ put: async ({ kind, record, ifRev }) => {
4348
+ if (ifRev !== void 0 && (table(kind).get(record.id)?.rev ?? 0) !== ifRev) throw new Error("stale ifRev");
4349
+ const { rev, released } = write(kind, record);
4350
+ return {
4351
+ rev,
4352
+ releasedRefs: released
4353
+ };
4354
+ },
4355
+ putMany: async ({ kind, records }) => {
4356
+ const released = [];
4357
+ for (const record of records) released.push(...write(kind, record).released);
4358
+ return {
4359
+ count: records.length,
4360
+ releasedRefs: released
4361
+ };
4362
+ },
4363
+ patch: async () => unimplemented("patch"),
4364
+ delete: async ({ kind, id }) => {
4365
+ if (writesFail) throw new Error("records engine unreachable");
4366
+ const row = table(kind).get(id);
4367
+ if (row === void 0) return {
4368
+ deleted: false,
4369
+ secretRefs: []
4370
+ };
4371
+ table(kind).delete(id);
4372
+ return {
4373
+ deleted: true,
4374
+ secretRefs: [...markersOf(declOf(kind), row.data).values()]
4375
+ };
4376
+ },
4377
+ deleteMany: async ({ kind, ids }) => {
4378
+ let deleted = 0;
4379
+ const refs = [];
4380
+ for (const id of ids) {
4381
+ const row = table(kind).get(id);
4382
+ if (row === void 0) continue;
4383
+ table(kind).delete(id);
4384
+ deleted += 1;
4385
+ refs.push(...markersOf(declOf(kind), row.data).values());
4386
+ }
4387
+ return {
4388
+ deleted,
4389
+ secretRefs: refs
4390
+ };
4391
+ },
4392
+ query: async (q) => {
4393
+ if (readsFail) throw new Error("records engine unreachable");
4394
+ const decl = declOf(q.kind);
4395
+ const asked = Object.keys(q.where ?? {});
4396
+ if (asked.length > 0) {
4397
+ if (!decl.indexes.some((index) => {
4398
+ const leading = new Set(index.fields.slice(0, asked.length));
4399
+ return asked.length <= index.fields.length && asked.every((f) => leading.has(f));
4400
+ })) throw new Error(`${q.kind}: no declared index serves [${asked.join(", ")}]`);
4401
+ }
4402
+ let rows = [...table(q.kind).values()];
4403
+ for (const [field, wanted] of Object.entries(q.where ?? {})) rows = rows.filter((r) => r.data[field] === wanted);
4404
+ const byAt = q.order === "at" || q.order === void 0 && decl.at === "required";
4405
+ rows.sort((a, b) => byAt ? (a.at ?? 0) - (b.at ?? 0) : a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
4406
+ if (q.desc === true) rows.reverse();
4407
+ const start = q.cursor === void 0 ? 0 : Number(q.cursor);
4408
+ const page = rows.slice(start, start + q.limit);
4409
+ const more = start + q.limit < rows.length;
4410
+ return {
4411
+ records: page.map((r) => view(q.kind, r)),
4412
+ nextCursor: more ? String(start + q.limit) : null
4413
+ };
4414
+ },
4415
+ count: async ({ kind }) => ({ count: table(kind).size }),
4416
+ histogram: async () => unimplemented("histogram"),
4417
+ aggregate: async () => unimplemented("aggregate"),
4418
+ deleteWhere: async () => unimplemented("deleteWhere"),
4419
+ deleteDevice: async () => unimplemented("deleteDevice"),
4420
+ allocateId: async () => unimplemented("allocateId")
4421
+ },
4422
+ secrets: makeSpecKeychain(owner).access
4423
+ }),
4424
+ tables,
4425
+ failWrites: (on) => {
4426
+ writesFail = on;
4427
+ },
4428
+ failReads: (on) => {
4429
+ readsFail = on;
4430
+ },
4431
+ seed: (kind, row) => {
4432
+ table(kind).set(row.id, {
4433
+ id: row.id,
4434
+ at: row.at ?? null,
4435
+ rev: 1,
4436
+ updatedAt: 1,
4437
+ data: row.data
4438
+ });
4439
+ }
4440
+ };
4441
+ }
4442
+ //#endregion
4443
+ //#region src/capabilities/schemas/streaming-shared.ts
4444
+ /** Shared Zod schemas used across streaming capabilities. */
4445
+ var CamProfileSchema = zod.z.enum([
4446
+ "high",
4447
+ "mid",
4448
+ "low"
4449
+ ]);
4450
+ /** Canonical ordering. Hard-coded; never sorted. */
4451
+ var CAM_PROFILE_ORDER = [
4452
+ "high",
4453
+ "mid",
4454
+ "low"
4455
+ ];
4456
+ /**
4457
+ * Which rung a per-camera consumer listens on: an explicit profile, or `auto`.
4458
+ *
4459
+ * `auto` is a REAL value, not an absent one — it means "resolve it by the rule
4460
+ * that consumer owns". It lives beside `CamProfile` because a rung is the only
4461
+ * operator-facing way to name a stream: a cam-stream id is broker-internal and
4462
+ * moves when a slot is reassigned, so a stored id silently stops meaning what
4463
+ * the operator picked. Today's one user is the audio analyser, whose rule is
4464
+ * "the lowest AVAILABLE native rung" (D537).
4465
+ */
4466
+ var AudioStreamPickSchema = zod.z.union([CamProfileSchema, zod.z.literal("auto")]);
4467
+ var CamStreamKindSchema = zod.z.enum([
4468
+ "pull-rtsp",
4469
+ "pull-rtmp",
4470
+ "pull-http",
4471
+ "pull-flv",
4472
+ "pull-rfc4571",
4473
+ "push-annexb",
4474
+ "derived"
4475
+ ]);
4476
+ var CamStreamResolutionSchema = zod.z.object({
4477
+ width: zod.z.number().int().positive(),
4478
+ height: zod.z.number().int().positive()
4479
+ });
4480
+ var CameraStreamSchema = zod.z.object({
4481
+ /** Stable, provider-assigned id unique within the (deviceId) scope. */
4482
+ camStreamId: zod.z.string().min(1),
4483
+ deviceId: zod.z.number().int().nonnegative(),
4484
+ kind: CamStreamKindSchema,
4485
+ /** Required for pull-* kinds. Ignored for push-annexb. */
4486
+ url: zod.z.string().optional(),
4487
+ codec: zod.z.string().optional(),
4488
+ resolution: CamStreamResolutionSchema.optional(),
4489
+ fps: zod.z.number().positive().optional(),
4490
+ /** Human label surfaced in the Admin UI "Camera Stream" dropdown. */
4491
+ label: zod.z.string().optional(),
4492
+ /**
4493
+ * Device-level features the publisher advertised (e.g. `battery-operated`).
4494
+ * The broker, snapshot orchestrator, and prebuffer manager all consult
4495
+ * this list to derive policy — relaxed stall watchdog for battery
4496
+ * cams, prebuffer off by default, longer snapshot rate-limit, etc.
4497
+ *
4498
+ * Single source of truth replacing per-stream flags like the
4499
+ * historical `allowStall`: if the publisher knows the camera is
4500
+ * battery-powered, every downstream service derives the right policy
4501
+ * from this list.
4502
+ */
4503
+ deviceFeatures: zod.z.array(zod.z.string()).optional(),
4504
+ /**
4505
+ * Whether this stream participates in the broker's automatic profile
4506
+ * assignment (`computeInitialAssignment`). Defaults to `true`. Publishers
4507
+ * use `false` when they want a stream to be SELECTABLE in the UI but not
4508
+ * picked by default — e.g. Reolink publishes its native Baichuan streams
4509
+ * as `autoEligible: true` (the recommended path) and its RTSP / RTMP
4510
+ * mirrors as `autoEligible: false` (still pickable per slot, just not
4511
+ * the auto choice). Manual `assignProfile` calls remain valid for
4512
+ * non-eligible streams.
4513
+ */
4514
+ autoEligible: zod.z.boolean().optional(),
4515
+ /**
4516
+ * The profile slot the PUBLISHER says this stream is: `low` for a stream
4517
+ * whose only sensible role is the low-bandwidth one, `high` for a main
4518
+ * stream. Consulted by the broker's automatic ranking
4519
+ * (`rankInitialAssignment`) BEFORE the pixel-count heuristic, and only there:
4520
+ * an operator's manual assignment still wins, and an absent hint is the
4521
+ * pixel-ranked default every camera had before this field existed.
4522
+ *
4523
+ * Why it exists: a camera with ONE stream ranked to `mid` — the slot no
4524
+ * storage class is written for on its own (`recordings` is high|mid,
4525
+ * `recordingsLow` is low) and the one profile scrub does not read. The robot
4526
+ * camera's single 720p relay is a `low` in every respect except the slot the
4527
+ * heuristic put it in.
4528
+ */
4529
+ profileHint: CamProfileSchema.optional(),
4530
+ /**
4531
+ * Transport-specific opaque metadata. The broker passes it through to
4532
+ * the source reader without inspecting it. Currently used by
4533
+ * `pull-rfc4571` streams to carry the upstream SDP (so the reader can
4534
+ * route RTP packets to the right depacketizer without an in-band
4535
+ * DESCRIBE phase). Other kinds typically leave it undefined.
4536
+ */
4537
+ metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
4538
+ });
4539
+ var ProfileSlotStatusSchema = zod.z.enum([
4540
+ "unassigned",
4541
+ "idle",
4542
+ "connecting",
4543
+ "streaming",
4544
+ "error"
4545
+ ]);
4546
+ var ProfileSlotSchema = zod.z.object({
4547
+ deviceId: zod.z.number().int().nonnegative(),
4548
+ profile: CamProfileSchema,
4549
+ /** Broker id the rest of the system addresses: `${deviceId}/${profile}`. */
4550
+ brokerId: zod.z.string(),
4551
+ /** `null` when the profile is unassigned. */
4552
+ sourceCamStreamId: zod.z.string().nullable(),
4553
+ status: ProfileSlotStatusSchema,
4554
+ resolution: CamStreamResolutionSchema.optional(),
4555
+ codec: zod.z.string().optional(),
4556
+ preBufferSec: zod.z.number().nonnegative().optional(),
4557
+ errorMessage: zod.z.string().optional()
4558
+ });
4559
+ /** The canonical consumer-facing broker id for a device profile. */
4560
+ function makeProfileBrokerId(deviceId, profile) {
4561
+ return `${deviceId}/${profile}`;
4562
+ }
4563
+ /**
4564
+ * The broker id keying a physical SOURCE stream: `${deviceId}/${camStreamId}`.
4565
+ * This is the broker's internal source key (`brokerIdFor` in the manager) — a
4566
+ * `camStreamId` like `native:main` — as opposed to the public profile alias
4567
+ * {@link makeProfileBrokerId}. Used to resolve a source's restream endpoint
4568
+ * (e.g. routing a transcode's ffmpeg input through the broker so it rides the
4569
+ * single source dial instead of opening a second camera connection).
4570
+ */
4571
+ function makeSourceBrokerId(deviceId, camStreamId) {
4572
+ return `${deviceId}/${camStreamId}`;
4573
+ }
4574
+ /**
4575
+ * Inverse of {@link makeProfileBrokerId}. Returns `null` when the string is
4576
+ * not a canonical `${deviceId}/${profile}` id — e.g. a broker-internal
4577
+ * cam-stream id (`5/native:main`), a derived/adaptive ref, or a malformed
4578
+ * value. So a caller can safely distinguish "addresses a public profile"
4579
+ * from "addresses something broker-internal".
4580
+ */
4581
+ function parseProfileBrokerId(brokerId) {
4582
+ const slash = brokerId.indexOf("/");
4583
+ if (slash <= 0) return null;
4584
+ const idPart = brokerId.slice(0, slash);
4585
+ const profilePart = brokerId.slice(slash + 1);
4586
+ if (!/^\d+$/.test(idPart)) return null;
4587
+ const parsed = CamProfileSchema.safeParse(profilePart);
4588
+ if (!parsed.success) return null;
4589
+ return {
4590
+ deviceId: Number(idPart),
4591
+ profile: parsed.data
4592
+ };
4593
+ }
4594
+ /**
4595
+ * The profile slots worth consuming/recording: ASSIGNED only
4596
+ * (`sourceCamStreamId != null`), DEDUPED by physical source so the same
4597
+ * camera encoder is never subscribed/recorded twice, ordered high→mid→low.
4598
+ * Optionally scoped to one `deviceId`. Pure; never mutates the input.
4599
+ *
4600
+ * Recording `main` and `mid` when both point at the same `sourceCamStreamId`
4601
+ * would dial the camera's internal stream twice for no benefit — this is the
4602
+ * dedup that prevents that.
4603
+ */
4604
+ function selectAssignedProfileSlots(slots, deviceId) {
4605
+ const ordered = [...slots].filter((s) => deviceId === void 0 || s.deviceId === deviceId).toSorted((a, b) => CAM_PROFILE_ORDER.indexOf(a.profile) - CAM_PROFILE_ORDER.indexOf(b.profile));
4606
+ const seenSources = /* @__PURE__ */ new Set();
4607
+ const out = [];
4608
+ for (const s of ordered) {
4609
+ const src = s.sourceCamStreamId;
4610
+ if (src === null) continue;
4611
+ if (seenSources.has(src)) continue;
4612
+ seenSources.add(src);
4613
+ out.push(s);
4614
+ }
4615
+ return out;
4616
+ }
4617
+ /**
4618
+ * Zod schema for StreamSourceEntry — the canonical stream descriptor
4619
+ * exposed by ICameraDevice.getStreamSources() and consumed by the broker.
4620
+ */
4621
+ var StreamSourceEntrySchema$1 = zod.z.object({
3304
4622
  id: zod.z.string(),
3305
4623
  label: zod.z.string(),
3306
4624
  protocol: zod.z.enum([
@@ -4281,6 +5599,30 @@ function describeCustomActions(catalog) {
4281
5599
  return out;
4282
5600
  }
4283
5601
  //#endregion
5602
+ //#region src/capabilities/caller-stamp.ts
5603
+ /**
5604
+ * Every cap whose provider reads a `callerAddonId` in its input (the keychain's
5605
+ * owner check, device-history's `not-owner`, records' owner).
5606
+ *
5607
+ * The stamp is set ONLY by the transport (`stampCallerAddonId`, or stated by a
5608
+ * hub in-process caller). The generated HTTP/tRPC mount parses input with
5609
+ * `.loose()`, so without this a session could add the key itself and act as
5610
+ * another addon. The mount strips it for these caps.
5611
+ */
5612
+ var CALLER_STAMPED_CAPABILITIES = [
5613
+ "keychain",
5614
+ "device-history",
5615
+ "records",
5616
+ "integrations",
5617
+ "device-manager"
5618
+ ];
5619
+ /** A copy of `input` without the caller stamp. Anything that is not a plain object passes through. */
5620
+ function withoutCallerStamp(input) {
5621
+ if (input === null || typeof input !== "object" || Array.isArray(input)) return input;
5622
+ if (!Object.prototype.hasOwnProperty.call(input, "callerAddonId")) return input;
5623
+ return Object.fromEntries(Object.entries(input).filter(([key]) => key !== "callerAddonId"));
5624
+ }
5625
+ //#endregion
4284
5626
  //#region src/device/children-batch-max.ts
4285
5627
  /**
4286
5628
  * Most parents one `getChildrenBatch` may name.
@@ -4537,94 +5879,6 @@ var RUNTIME_DEFAULTS = {
4537
5879
  "auth.tokenExpiry": "30d"
4538
5880
  };
4539
5881
  //#endregion
4540
- //#region src/device/zod-secret.ts
4541
- /**
4542
- * Secret declaration on a Zod config schema (D783).
4543
- *
4544
- * A field is a secret because its schema SAYS so — `.meta({ secret: true })`,
4545
- * spelled {@link SECRET_META} — never because its key looks like a credential.
4546
- * It is the Zod twin of `secret: true` / `type: 'password'` on a config-UI
4547
- * field (`isSecretConfigField`), and every consumer that treats secrets
4548
- * specially reads it: the settings form (`zodEntriesToConfigUI`), the paths a
4549
- * device advertises at `registerDevice` (`secretConfigPaths`, which the
4550
- * non-admin redaction withholds at any depth), and the keychain later.
4551
- *
4552
- * Zod keeps `.meta()` in `z.globalRegistry`, which lives on `globalThis`, so a
4553
- * declaration made by an addon's own copy of zod is visible here.
4554
- */
4555
- /**
4556
- * `{ secret: true }` — the one spelling of "this field holds a credential".
4557
- *
4558
- * Addons write the LITERAL `.meta({ secret: true })` rather than importing
4559
- * this constant: an addon running against an older `@camstack/types` would
4560
- * otherwise call `.meta(undefined)`, which in zod v4 is the metadata GETTER
4561
- * and returns no schema at all.
4562
- */
4563
- var SECRET_META = { secret: true };
4564
- function defOf(schema) {
4565
- return schema._zod?.def ?? {};
4566
- }
4567
- function declaredHere(schema) {
4568
- return zod.z.globalRegistry.get(schema)?.secret === true;
4569
- }
4570
- /** Wrapper kinds whose `innerType` is the field itself. */
4571
- var WRAPPERS = new Set([
4572
- "optional",
4573
- "nullable",
4574
- "default",
4575
- "prefault",
4576
- "catch",
4577
- "readonly",
4578
- "nonoptional"
4579
- ]);
4580
- /**
4581
- * The schema layers that make up ONE field: the schema itself and every
4582
- * wrapper below it (optional / default / nullable / readonly / catch), plus
4583
- * both sides of a pipe (`z.preprocess` puts the real schema on `out`,
4584
- * `.transform` on `in`).
4585
- */
4586
- function layersOf(schema) {
4587
- const out = [];
4588
- const queue = [schema];
4589
- while (queue.length > 0) {
4590
- const s = queue.shift();
4591
- if (!s || out.includes(s)) continue;
4592
- out.push(s);
4593
- const def = defOf(s);
4594
- if (def.type !== void 0 && WRAPPERS.has(def.type) && def.innerType) queue.push(def.innerType);
4595
- if (def.type === "pipe") {
4596
- if (def.in) queue.push(def.in);
4597
- if (def.out) queue.push(def.out);
4598
- }
4599
- }
4600
- return out;
4601
- }
4602
- /** True when any layer of this field declares `.meta({ secret: true })`. */
4603
- function isZodSecret(schema) {
4604
- return layersOf(schema).some(declaredHere);
4605
- }
4606
- /**
4607
- * Every declared secret path in a config schema: dotted keys, `[]` for "each
4608
- * element of this array" (`connection.password`, `rows[].token`). A declared
4609
- * object or array is reported as one path and not descended into — everything
4610
- * under it is secret.
4611
- */
4612
- function collectZodSecretPaths(schema, prefix = "") {
4613
- if (isZodSecret(schema)) return prefix.length > 0 ? [prefix] : [];
4614
- const paths = [];
4615
- for (const layer of layersOf(schema)) {
4616
- const def = defOf(layer);
4617
- if (def.type === "object" && def.shape) for (const [key, child] of Object.entries(def.shape)) paths.push(...collectZodSecretPaths(child, prefix ? `${prefix}.${key}` : key));
4618
- else if (def.type === "array" && def.element) paths.push(...collectZodSecretPaths(def.element, `${prefix}[]`));
4619
- else if (def.type === "union" && def.options) for (const option of def.options) paths.push(...collectZodSecretPaths(option, prefix));
4620
- else if (def.type === "intersection") {
4621
- if (def.left) paths.push(...collectZodSecretPaths(def.left, prefix));
4622
- if (def.right) paths.push(...collectZodSecretPaths(def.right, prefix));
4623
- }
4624
- }
4625
- return [...new Set(paths)];
4626
- }
4627
- //#endregion
4628
5882
  //#region src/device/device-state-handle.ts
4629
5883
  var DEVICE_STATE_EVENT_CATEGORY = "device.state-changed";
4630
5884
  /**
@@ -4871,6 +6125,50 @@ function isSource(x) {
4871
6125
  return typeof x.read === "function" && typeof x.watch === "function";
4872
6126
  }
4873
6127
  //#endregion
6128
+ //#region src/helpers/addon-slice-handle.ts
6129
+ /** Structural bridge: every `AddonApi` client carries `deviceState` (+ optional `live`). */
6130
+ function addonSliceHandleApi(api) {
6131
+ return api;
6132
+ }
6133
+ //#endregion
6134
+ //#region src/helpers/trpc-leaf.ts
6135
+ function isTrpcProcedureLeaf(value) {
6136
+ if (typeof value !== "object" || value === null) return false;
6137
+ const record = value;
6138
+ return (typeof record.query === "function" || typeof record.mutate === "function" || typeof record.subscribe === "function") && !Array.isArray(value);
6139
+ }
6140
+ function readCapRecord(api, capProp) {
6141
+ const cap = Reflect.get(api, capProp);
6142
+ if (typeof cap !== "object" || cap === null || Array.isArray(cap)) return void 0;
6143
+ return cap;
6144
+ }
6145
+ function readTrpcLeaf(api, capProp, method) {
6146
+ const capRecord = readCapRecord(api, capProp);
6147
+ if (!capRecord) throw new Error(`tRPC client has no router '${capProp}'`);
6148
+ const leaf = capRecord[method];
6149
+ if (!isTrpcProcedureLeaf(leaf)) throw new Error(`tRPC client has no '${capProp}.${method}'`);
6150
+ return leaf;
6151
+ }
6152
+ /**
6153
+ * Invoke `api.<capProp>.<method>.{query|mutate|subscribe}(input)`.
6154
+ * `Result` is the generated proxy method's return. The leaf itself is only
6155
+ * `unknown` (the client is a structural bag), so the assertion is the one
6156
+ * boundary between that bag and the typed proxy.
6157
+ */
6158
+ function invokeTrpcLeaf(api, capProp, method, kind, input, push) {
6159
+ const fn = readTrpcLeaf(api, capProp, method);
6160
+ if (kind === "mutation") {
6161
+ if (typeof fn.mutate !== "function") throw new Error(`tRPC '${capProp}.${method}' has no mutate()`);
6162
+ return fn.mutate(input);
6163
+ }
6164
+ if (kind === "subscription") {
6165
+ if (typeof fn.subscribe !== "function") throw new Error(`tRPC '${capProp}.${method}' has no subscribe()`);
6166
+ return fn.subscribe(input, push);
6167
+ }
6168
+ if (typeof fn.query !== "function") throw new Error(`tRPC '${capProp}.${method}' has no query()`);
6169
+ return fn.query(input);
6170
+ }
6171
+ //#endregion
4874
6172
  //#region src/generated/device-proxy.ts
4875
6173
  /**
4876
6174
  * Build a DeviceProxy that pre-binds deviceId + nodeId on every method call
@@ -4888,8 +6186,7 @@ function isSource(x) {
4888
6186
  * field on the returned object.
4889
6187
  */
4890
6188
  function createDeviceProxy(api, binding, opts) {
4891
- const typedApi = api;
4892
- const stateSource = opts?.stateSource ?? createLazyTrpcSource(api);
6189
+ const stateSource = opts?.stateSource ?? createLazyTrpcSource(addonSliceHandleApi(api));
4893
6190
  /** Merge `{deviceId, nodeId?}` into the caller-supplied input. */
4894
6191
  function mergeInput(input, nodeId) {
4895
6192
  const base = typeof input === "object" && input !== null ? input : {};
@@ -4902,20 +6199,8 @@ function createDeviceProxy(api, binding, opts) {
4902
6199
  deviceId: binding.deviceId
4903
6200
  };
4904
6201
  }
4905
- /**
4906
- * Invoke `api.<capProp>.<method>.{query|mutate|subscribe}(merged)`.
4907
- * Returns `any` so the caller-side per-method declaration assigns
4908
- * cleanly into the strongly-typed `InferDeviceProxyCap<...>` shape on
4909
- * the `DeviceProxy` interface — the proxy's contract is enforced by
4910
- * the interface, not the dispatch helper.
4911
- */
4912
6202
  function callLeaf(capProp, method, kind, merged, push) {
4913
- const leaf = typedApi[capProp]?.[method];
4914
- if (!leaf) throw new Error(`DeviceProxy: api has no '${capProp}.${method}'`);
4915
- const fn = leaf;
4916
- if (kind === "mutation") return fn.mutate(merged);
4917
- if (kind === "subscription") return fn.subscribe(merged, push);
4918
- return fn.query(merged);
6203
+ return invokeTrpcLeaf(api, capProp, method, kind, merged, push);
4919
6204
  }
4920
6205
  /**
4921
6206
  * Device-scoped cap dispatch. Looks up the binding entry for `capName`
@@ -6193,6 +7478,12 @@ Object.defineProperty(exports, "AUDIO_CHUNK_FORMATS", {
6193
7478
  return AUDIO_CHUNK_FORMATS;
6194
7479
  }
6195
7480
  });
7481
+ Object.defineProperty(exports, "AdoptionPendingError", {
7482
+ enumerable: true,
7483
+ get: function() {
7484
+ return AdoptionPendingError;
7485
+ }
7486
+ });
6196
7487
  Object.defineProperty(exports, "AudioChunkFormatSchema", {
6197
7488
  enumerable: true,
6198
7489
  get: function() {
@@ -6217,6 +7508,12 @@ Object.defineProperty(exports, "BaseAddon", {
6217
7508
  return BaseAddon;
6218
7509
  }
6219
7510
  });
7511
+ Object.defineProperty(exports, "BatchTooLargeError", {
7512
+ enumerable: true,
7513
+ get: function() {
7514
+ return BatchTooLargeError;
7515
+ }
7516
+ });
6220
7517
  Object.defineProperty(exports, "BrokerStatsSchema", {
6221
7518
  enumerable: true,
6222
7519
  get: function() {
@@ -6229,6 +7526,12 @@ Object.defineProperty(exports, "BrokerStatusSchema", {
6229
7526
  return BrokerStatusSchema;
6230
7527
  }
6231
7528
  });
7529
+ Object.defineProperty(exports, "CALLER_STAMPED_CAPABILITIES", {
7530
+ enumerable: true,
7531
+ get: function() {
7532
+ return CALLER_STAMPED_CAPABILITIES;
7533
+ }
7534
+ });
6232
7535
  Object.defineProperty(exports, "CAM_PROFILE_ORDER", {
6233
7536
  enumerable: true,
6234
7537
  get: function() {
@@ -6313,6 +7616,12 @@ Object.defineProperty(exports, "DEVICE_STATUS_METHOD", {
6313
7616
  return DEVICE_STATUS_METHOD;
6314
7617
  }
6315
7618
  });
7619
+ Object.defineProperty(exports, "DeclarationRefusedError", {
7620
+ enumerable: true,
7621
+ get: function() {
7622
+ return DeclarationRefusedError;
7623
+ }
7624
+ });
6316
7625
  Object.defineProperty(exports, "DecodedAudioChunkSchema", {
6317
7626
  enumerable: true,
6318
7627
  get: function() {
@@ -6325,6 +7634,12 @@ Object.defineProperty(exports, "DisposerChain", {
6325
7634
  return DisposerChain;
6326
7635
  }
6327
7636
  });
7637
+ Object.defineProperty(exports, "EntryDescriptorSchema", {
7638
+ enumerable: true,
7639
+ get: function() {
7640
+ return EntryDescriptorSchema;
7641
+ }
7642
+ });
6328
7643
  Object.defineProperty(exports, "ErrorCodeSchema", {
6329
7644
  enumerable: true,
6330
7645
  get: function() {
@@ -6337,6 +7652,18 @@ Object.defineProperty(exports, "ErrorI18nPayloadSchema", {
6337
7652
  return ErrorI18nPayloadSchema;
6338
7653
  }
6339
7654
  });
7655
+ Object.defineProperty(exports, "FilterRequiredError", {
7656
+ enumerable: true,
7657
+ get: function() {
7658
+ return FilterRequiredError;
7659
+ }
7660
+ });
7661
+ Object.defineProperty(exports, "ForeignSecretMarkerError", {
7662
+ enumerable: true,
7663
+ get: function() {
7664
+ return ForeignSecretMarkerError;
7665
+ }
7666
+ });
6340
7667
  Object.defineProperty(exports, "FrameHandleSchema", {
6341
7668
  enumerable: true,
6342
7669
  get: function() {
@@ -6367,6 +7694,12 @@ Object.defineProperty(exports, "HISTORY_UNIT_LABELS", {
6367
7694
  return HISTORY_UNIT_LABELS;
6368
7695
  }
6369
7696
  });
7697
+ Object.defineProperty(exports, "InvalidRecordError", {
7698
+ enumerable: true,
7699
+ get: function() {
7700
+ return InvalidRecordError;
7701
+ }
7702
+ });
6370
7703
  Object.defineProperty(exports, "KeychainWriteRefusedError", {
6371
7704
  enumerable: true,
6372
7705
  get: function() {
@@ -6385,6 +7718,12 @@ Object.defineProperty(exports, "MODEL_FORMATS", {
6385
7718
  return MODEL_FORMATS;
6386
7719
  }
6387
7720
  });
7721
+ Object.defineProperty(exports, "NoCallerError", {
7722
+ enumerable: true,
7723
+ get: function() {
7724
+ return NoCallerError;
7725
+ }
7726
+ });
6388
7727
  Object.defineProperty(exports, "PEER_BYTES_CHUNK_BYTES", {
6389
7728
  enumerable: true,
6390
7729
  get: function() {
@@ -6421,6 +7760,12 @@ Object.defineProperty(exports, "PeerBytesTicketSchema", {
6421
7760
  return PeerBytesTicketSchema;
6422
7761
  }
6423
7762
  });
7763
+ Object.defineProperty(exports, "PlaintextSecretError", {
7764
+ enumerable: true,
7765
+ get: function() {
7766
+ return PlaintextSecretError;
7767
+ }
7768
+ });
6424
7769
  Object.defineProperty(exports, "ProfileRtspEntrySchema", {
6425
7770
  enumerable: true,
6426
7771
  get: function() {
@@ -6439,12 +7784,108 @@ Object.defineProperty(exports, "ProfileSlotStatusSchema", {
6439
7784
  return ProfileSlotStatusSchema;
6440
7785
  }
6441
7786
  });
7787
+ Object.defineProperty(exports, "RECORDS_ERROR_CODES", {
7788
+ enumerable: true,
7789
+ get: function() {
7790
+ return RECORDS_ERROR_CODES;
7791
+ }
7792
+ });
7793
+ Object.defineProperty(exports, "RECORD_BATCH_MAX", {
7794
+ enumerable: true,
7795
+ get: function() {
7796
+ return RECORD_BATCH_MAX;
7797
+ }
7798
+ });
7799
+ Object.defineProperty(exports, "RECORD_BATCH_MAX_BYTES", {
7800
+ enumerable: true,
7801
+ get: function() {
7802
+ return RECORD_BATCH_MAX_BYTES;
7803
+ }
7804
+ });
7805
+ Object.defineProperty(exports, "RECORD_CLASSES", {
7806
+ enumerable: true,
7807
+ get: function() {
7808
+ return RECORD_CLASSES;
7809
+ }
7810
+ });
7811
+ Object.defineProperty(exports, "RECORD_DATABASES", {
7812
+ enumerable: true,
7813
+ get: function() {
7814
+ return RECORD_DATABASES;
7815
+ }
7816
+ });
7817
+ Object.defineProperty(exports, "RECORD_DEFAULT_MAX_DATA_BYTES", {
7818
+ enumerable: true,
7819
+ get: function() {
7820
+ return RECORD_DEFAULT_MAX_DATA_BYTES;
7821
+ }
7822
+ });
7823
+ Object.defineProperty(exports, "RECORD_DELETE_BATCH", {
7824
+ enumerable: true,
7825
+ get: function() {
7826
+ return RECORD_DELETE_BATCH;
7827
+ }
7828
+ });
7829
+ Object.defineProperty(exports, "RECORD_ID_MAX_LENGTH", {
7830
+ enumerable: true,
7831
+ get: function() {
7832
+ return RECORD_ID_MAX_LENGTH;
7833
+ }
7834
+ });
7835
+ Object.defineProperty(exports, "RECORD_MAX_DATA_BYTES", {
7836
+ enumerable: true,
7837
+ get: function() {
7838
+ return RECORD_MAX_DATA_BYTES;
7839
+ }
7840
+ });
7841
+ Object.defineProperty(exports, "RECORD_MAX_INDEXES", {
7842
+ enumerable: true,
7843
+ get: function() {
7844
+ return RECORD_MAX_INDEXES;
7845
+ }
7846
+ });
7847
+ Object.defineProperty(exports, "RECORD_MAX_INDEX_FIELDS", {
7848
+ enumerable: true,
7849
+ get: function() {
7850
+ return RECORD_MAX_INDEX_FIELDS;
7851
+ }
7852
+ });
7853
+ Object.defineProperty(exports, "RECORD_QUERY_MAX", {
7854
+ enumerable: true,
7855
+ get: function() {
7856
+ return RECORD_QUERY_MAX;
7857
+ }
7858
+ });
7859
+ Object.defineProperty(exports, "RECORD_SECRET_COLLECTION_PREFIX", {
7860
+ enumerable: true,
7861
+ get: function() {
7862
+ return RECORD_SECRET_COLLECTION_PREFIX;
7863
+ }
7864
+ });
7865
+ Object.defineProperty(exports, "RECORD_SETTINGS_MAX_ROWS", {
7866
+ enumerable: true,
7867
+ get: function() {
7868
+ return RECORD_SETTINGS_MAX_ROWS;
7869
+ }
7870
+ });
7871
+ Object.defineProperty(exports, "RECORD_SWEEP_INTERVAL_MS", {
7872
+ enumerable: true,
7873
+ get: function() {
7874
+ return RECORD_SWEEP_INTERVAL_MS;
7875
+ }
7876
+ });
6442
7877
  Object.defineProperty(exports, "REDACTED_SECRET", {
6443
7878
  enumerable: true,
6444
7879
  get: function() {
6445
7880
  return REDACTED_SECRET;
6446
7881
  }
6447
7882
  });
7883
+ Object.defineProperty(exports, "REMOVE_LEAF", {
7884
+ enumerable: true,
7885
+ get: function() {
7886
+ return REMOVE_LEAF;
7887
+ }
7888
+ });
6448
7889
  Object.defineProperty(exports, "REVALIDATE_AFTER_MS", {
6449
7890
  enumerable: true,
6450
7891
  get: function() {
@@ -6475,6 +7916,72 @@ Object.defineProperty(exports, "ReadinessTimeoutError", {
6475
7916
  return ReadinessTimeoutError;
6476
7917
  }
6477
7918
  });
7919
+ Object.defineProperty(exports, "RecordFieldPathSchema", {
7920
+ enumerable: true,
7921
+ get: function() {
7922
+ return RecordFieldPathSchema;
7923
+ }
7924
+ });
7925
+ Object.defineProperty(exports, "RecordIndexSchema", {
7926
+ enumerable: true,
7927
+ get: function() {
7928
+ return RecordIndexSchema;
7929
+ }
7930
+ });
7931
+ Object.defineProperty(exports, "RecordKindDeclarationSchema", {
7932
+ enumerable: true,
7933
+ get: function() {
7934
+ return RecordKindDeclarationSchema;
7935
+ }
7936
+ });
7937
+ Object.defineProperty(exports, "RecordKindNameSchema", {
7938
+ enumerable: true,
7939
+ get: function() {
7940
+ return RecordKindNameSchema;
7941
+ }
7942
+ });
7943
+ Object.defineProperty(exports, "RecordNotFoundError", {
7944
+ enumerable: true,
7945
+ get: function() {
7946
+ return RecordNotFoundError;
7947
+ }
7948
+ });
7949
+ Object.defineProperty(exports, "RecordRetentionSchema", {
7950
+ enumerable: true,
7951
+ get: function() {
7952
+ return RecordRetentionSchema;
7953
+ }
7954
+ });
7955
+ Object.defineProperty(exports, "RecordSecretUnavailableError", {
7956
+ enumerable: true,
7957
+ get: function() {
7958
+ return RecordSecretUnavailableError;
7959
+ }
7960
+ });
7961
+ Object.defineProperty(exports, "RecordTooLargeError", {
7962
+ enumerable: true,
7963
+ get: function() {
7964
+ return RecordTooLargeError;
7965
+ }
7966
+ });
7967
+ Object.defineProperty(exports, "RecordUniqueViolationError", {
7968
+ enumerable: true,
7969
+ get: function() {
7970
+ return RecordUniqueViolationError;
7971
+ }
7972
+ });
7973
+ Object.defineProperty(exports, "RecordsError", {
7974
+ enumerable: true,
7975
+ get: function() {
7976
+ return RecordsError;
7977
+ }
7978
+ });
7979
+ Object.defineProperty(exports, "RevConflictError", {
7980
+ enumerable: true,
7981
+ get: function() {
7982
+ return RevConflictError;
7983
+ }
7984
+ });
6478
7985
  Object.defineProperty(exports, "SECRET_CLEAR", {
6479
7986
  enumerable: true,
6480
7987
  get: function() {
@@ -6493,6 +8000,18 @@ Object.defineProperty(exports, "SECRET_REF_SCHEME", {
6493
8000
  return SECRET_REF_SCHEME;
6494
8001
  }
6495
8002
  });
8003
+ Object.defineProperty(exports, "SETTINGS_ARRAY_ADOPTS_PREFIX", {
8004
+ enumerable: true,
8005
+ get: function() {
8006
+ return SETTINGS_ARRAY_ADOPTS_PREFIX;
8007
+ }
8008
+ });
8009
+ Object.defineProperty(exports, "SETTINGS_BROKERS_ADOPTS_PREFIX", {
8010
+ enumerable: true,
8011
+ get: function() {
8012
+ return SETTINGS_BROKERS_ADOPTS_PREFIX;
8013
+ }
8014
+ });
6496
8015
  Object.defineProperty(exports, "SHARE_VIEW_KINDS", {
6497
8016
  enumerable: true,
6498
8017
  get: function() {
@@ -6523,6 +8042,18 @@ Object.defineProperty(exports, "SubscribeAudioChunksResultSchema", {
6523
8042
  return SubscribeAudioChunksResultSchema;
6524
8043
  }
6525
8044
  });
8045
+ Object.defineProperty(exports, "UnindexedFilterError", {
8046
+ enumerable: true,
8047
+ get: function() {
8048
+ return UnindexedFilterError;
8049
+ }
8050
+ });
8051
+ Object.defineProperty(exports, "UnknownRecordKindError", {
8052
+ enumerable: true,
8053
+ get: function() {
8054
+ return UnknownRecordKindError;
8055
+ }
8056
+ });
6526
8057
  Object.defineProperty(exports, "WELL_KNOWN_TABS", {
6527
8058
  enumerable: true,
6528
8059
  get: function() {
@@ -6535,6 +8066,12 @@ Object.defineProperty(exports, "WELL_KNOWN_TAB_MAP", {
6535
8066
  return WELL_KNOWN_TAB_MAP;
6536
8067
  }
6537
8068
  });
8069
+ Object.defineProperty(exports, "addonSliceHandleApi", {
8070
+ enumerable: true,
8071
+ get: function() {
8072
+ return addonSliceHandleApi;
8073
+ }
8074
+ });
6538
8075
  Object.defineProperty(exports, "adminUiCapability", {
6539
8076
  enumerable: true,
6540
8077
  get: function() {
@@ -6571,12 +8108,24 @@ Object.defineProperty(exports, "asNumber", {
6571
8108
  return asNumber;
6572
8109
  }
6573
8110
  });
8111
+ Object.defineProperty(exports, "asRecordsError", {
8112
+ enumerable: true,
8113
+ get: function() {
8114
+ return asRecordsError;
8115
+ }
8116
+ });
6574
8117
  Object.defineProperty(exports, "asString", {
6575
8118
  enumerable: true,
6576
8119
  get: function() {
6577
8120
  return asString;
6578
8121
  }
6579
8122
  });
8123
+ Object.defineProperty(exports, "assertValidDeclaration", {
8124
+ enumerable: true,
8125
+ get: function() {
8126
+ return assertValidDeclaration;
8127
+ }
8128
+ });
6580
8129
  Object.defineProperty(exports, "audioChunkBytesPerSample", {
6581
8130
  enumerable: true,
6582
8131
  get: function() {
@@ -6631,6 +8180,12 @@ Object.defineProperty(exports, "collectSecretConfigKeys", {
6631
8180
  return collectSecretConfigKeys;
6632
8181
  }
6633
8182
  });
8183
+ Object.defineProperty(exports, "collectSecretLeaves", {
8184
+ enumerable: true,
8185
+ get: function() {
8186
+ return collectSecretLeaves;
8187
+ }
8188
+ });
6634
8189
  Object.defineProperty(exports, "collectSecretMarkerRefs", {
6635
8190
  enumerable: true,
6636
8191
  get: function() {
@@ -6679,6 +8234,12 @@ Object.defineProperty(exports, "createMirrorSource", {
6679
8234
  return createMirrorSource;
6680
8235
  }
6681
8236
  });
8237
+ Object.defineProperty(exports, "createRecordsAccess", {
8238
+ enumerable: true,
8239
+ get: function() {
8240
+ return createRecordsAccess;
8241
+ }
8242
+ });
6682
8243
  Object.defineProperty(exports, "createSecretsAccess", {
6683
8244
  enumerable: true,
6684
8245
  get: function() {
@@ -6697,12 +8258,42 @@ Object.defineProperty(exports, "customAction", {
6697
8258
  return customAction;
6698
8259
  }
6699
8260
  });
8261
+ Object.defineProperty(exports, "declarationsOf", {
8262
+ enumerable: true,
8263
+ get: function() {
8264
+ return declarationsOf;
8265
+ }
8266
+ });
6700
8267
  Object.defineProperty(exports, "defineCustomActions", {
6701
8268
  enumerable: true,
6702
8269
  get: function() {
6703
8270
  return defineCustomActions;
6704
8271
  }
6705
8272
  });
8273
+ Object.defineProperty(exports, "defineEntryKind", {
8274
+ enumerable: true,
8275
+ get: function() {
8276
+ return defineEntryKind;
8277
+ }
8278
+ });
8279
+ Object.defineProperty(exports, "defineRecordKinds", {
8280
+ enumerable: true,
8281
+ get: function() {
8282
+ return defineRecordKinds;
8283
+ }
8284
+ });
8285
+ Object.defineProperty(exports, "dehydrateConfigField", {
8286
+ enumerable: true,
8287
+ get: function() {
8288
+ return dehydrateConfigField;
8289
+ }
8290
+ });
8291
+ Object.defineProperty(exports, "dehydrateSchema", {
8292
+ enumerable: true,
8293
+ get: function() {
8294
+ return dehydrateSchema;
8295
+ }
8296
+ });
6706
8297
  Object.defineProperty(exports, "describeCustomActions", {
6707
8298
  enumerable: true,
6708
8299
  get: function() {
@@ -6733,6 +8324,12 @@ Object.defineProperty(exports, "emitReadiness", {
6733
8324
  return emitReadiness;
6734
8325
  }
6735
8326
  });
8327
+ Object.defineProperty(exports, "entryBody", {
8328
+ enumerable: true,
8329
+ get: function() {
8330
+ return entryBody;
8331
+ }
8332
+ });
6736
8333
  Object.defineProperty(exports, "event", {
6737
8334
  enumerable: true,
6738
8335
  get: function() {
@@ -6781,6 +8378,12 @@ Object.defineProperty(exports, "hydrateSchema", {
6781
8378
  return hydrateSchema;
6782
8379
  }
6783
8380
  });
8381
+ Object.defineProperty(exports, "invokeTrpcLeaf", {
8382
+ enumerable: true,
8383
+ get: function() {
8384
+ return invokeTrpcLeaf;
8385
+ }
8386
+ });
6784
8387
  Object.defineProperty(exports, "isAudioChunkFormat", {
6785
8388
  enumerable: true,
6786
8389
  get: function() {
@@ -6865,6 +8468,12 @@ Object.defineProperty(exports, "knownSecretCount", {
6865
8468
  return knownSecretCount;
6866
8469
  }
6867
8470
  });
8471
+ Object.defineProperty(exports, "makeInMemoryRecords", {
8472
+ enumerable: true,
8473
+ get: function() {
8474
+ return makeInMemoryRecords;
8475
+ }
8476
+ });
6868
8477
  Object.defineProperty(exports, "makeProfileBrokerId", {
6869
8478
  enumerable: true,
6870
8479
  get: function() {
@@ -6883,6 +8492,12 @@ Object.defineProperty(exports, "makeSourceBrokerId", {
6883
8492
  return makeSourceBrokerId;
6884
8493
  }
6885
8494
  });
8495
+ Object.defineProperty(exports, "mapSecretLeaves", {
8496
+ enumerable: true,
8497
+ get: function() {
8498
+ return mapSecretLeaves;
8499
+ }
8500
+ });
6886
8501
  Object.defineProperty(exports, "maskUrlCredentials", {
6887
8502
  enumerable: true,
6888
8503
  get: function() {
@@ -6955,6 +8570,12 @@ Object.defineProperty(exports, "parseProfileBrokerId", {
6955
8570
  return parseProfileBrokerId;
6956
8571
  }
6957
8572
  });
8573
+ Object.defineProperty(exports, "parseSecretPath", {
8574
+ enumerable: true,
8575
+ get: function() {
8576
+ return parseSecretPath;
8577
+ }
8578
+ });
6958
8579
  Object.defineProperty(exports, "parseSecretRef", {
6959
8580
  enumerable: true,
6960
8581
  get: function() {
@@ -6967,6 +8588,18 @@ Object.defineProperty(exports, "parseSecretStatePath", {
6967
8588
  return parseSecretStatePath;
6968
8589
  }
6969
8590
  });
8591
+ Object.defineProperty(exports, "parseSettingsArrayAdoptsFrom", {
8592
+ enumerable: true,
8593
+ get: function() {
8594
+ return parseSettingsArrayAdoptsFrom;
8595
+ }
8596
+ });
8597
+ Object.defineProperty(exports, "parseSettingsBrokersAdoptsFrom", {
8598
+ enumerable: true,
8599
+ get: function() {
8600
+ return parseSettingsBrokersAdoptsFrom;
8601
+ }
8602
+ });
6970
8603
  Object.defineProperty(exports, "readErrorI18n", {
6971
8604
  enumerable: true,
6972
8605
  get: function() {
@@ -6985,6 +8618,30 @@ Object.defineProperty(exports, "readinessKey", {
6985
8618
  return readinessKey;
6986
8619
  }
6987
8620
  });
8621
+ Object.defineProperty(exports, "recordArrayItemPath", {
8622
+ enumerable: true,
8623
+ get: function() {
8624
+ return recordArrayItemPath;
8625
+ }
8626
+ });
8627
+ Object.defineProperty(exports, "recordSecretCollection", {
8628
+ enumerable: true,
8629
+ get: function() {
8630
+ return recordSecretCollection;
8631
+ }
8632
+ });
8633
+ Object.defineProperty(exports, "recordSecretRef", {
8634
+ enumerable: true,
8635
+ get: function() {
8636
+ return recordSecretRef;
8637
+ }
8638
+ });
8639
+ Object.defineProperty(exports, "recordsErrorFromMessage", {
8640
+ enumerable: true,
8641
+ get: function() {
8642
+ return recordsErrorFromMessage;
8643
+ }
8644
+ });
6988
8645
  Object.defineProperty(exports, "registerKnownSecret", {
6989
8646
  enumerable: true,
6990
8647
  get: function() {
@@ -7033,6 +8690,12 @@ Object.defineProperty(exports, "scrubKnownSecrets", {
7033
8690
  return scrubKnownSecrets;
7034
8691
  }
7035
8692
  });
8693
+ Object.defineProperty(exports, "secretArrayPrefixes", {
8694
+ enumerable: true,
8695
+ get: function() {
8696
+ return secretArrayPrefixes;
8697
+ }
8698
+ });
7036
8699
  Object.defineProperty(exports, "secretTreeFromPaths", {
7037
8700
  enumerable: true,
7038
8701
  get: function() {
@@ -7051,6 +8714,18 @@ Object.defineProperty(exports, "selectAssignedProfileSlots", {
7051
8714
  return selectAssignedProfileSlots;
7052
8715
  }
7053
8716
  });
8717
+ Object.defineProperty(exports, "settingsArrayAdoptsFrom", {
8718
+ enumerable: true,
8719
+ get: function() {
8720
+ return settingsArrayAdoptsFrom;
8721
+ }
8722
+ });
8723
+ Object.defineProperty(exports, "settingsBrokersAdoptsFrom", {
8724
+ enumerable: true,
8725
+ get: function() {
8726
+ return settingsBrokersAdoptsFrom;
8727
+ }
8728
+ });
7054
8729
  Object.defineProperty(exports, "shortSecretRefHash", {
7055
8730
  enumerable: true,
7056
8731
  get: function() {
@@ -7105,3 +8780,9 @@ Object.defineProperty(exports, "viewerUiCapability", {
7105
8780
  return viewerUiCapability;
7106
8781
  }
7107
8782
  });
8783
+ Object.defineProperty(exports, "withoutCallerStamp", {
8784
+ enumerable: true,
8785
+ get: function() {
8786
+ return withoutCallerStamp;
8787
+ }
8788
+ });