@camstack/addon-provider-bosch 0.1.38 → 0.1.39

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.
@@ -5981,7 +5981,7 @@ var ZodIssueCode = {
5981
5981
  var ZodFirstPartyTypeKind;
5982
5982
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5983
5983
  //#endregion
5984
- //#region ../types/dist/sleep-DEZaLbiu.mjs
5984
+ //#region ../types/dist/sleep-BX_MqzUe.mjs
5985
5985
  /**
5986
5986
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5987
5987
  * window to float samples (D455).
@@ -7610,6 +7610,28 @@ var SECRET_RETRY_MAX_MS = 5 * 6e4;
7610
7610
  /** Coalesces a burst of `keychain.changed` events into one re-resolve. */
7611
7611
  var SECRET_CHANGE_DEBOUNCE_MS = 250;
7612
7612
  /**
7613
+ * Pair a catalogue with the function that builds its ports FROM THE MIGRATION API. The one
7614
+ * place a catalogue is bound: a migration reaches nothing a ports binder cannot reach
7615
+ * through `api` (guard `check-migration-ports-surface`).
7616
+ */
7617
+ function migrationSet(catalogue, bindPorts) {
7618
+ return { bind: (api) => defineAddonMigrations(catalogue, bindPorts(api)) };
7619
+ }
7620
+ /** A mixed array is a mistake: the other kind would be dropped without a word. */
7621
+ function refuseMixed(form, kept, dropped) {
7622
+ if (dropped > 0) throw new Error(`runMigrations(${form}): ${dropped} of ${kept + dropped} entries are of the other kind and would be dropped; pass one kind per call`);
7623
+ }
7624
+ function catalogueOf(list) {
7625
+ const kept = list.filter((entry) => !("execute" in entry));
7626
+ refuseMixed("catalogue, (api) => ports", kept.length, list.length - kept.length);
7627
+ return kept;
7628
+ }
7629
+ function boundOf(list) {
7630
+ const kept = list.filter((entry) => "execute" in entry);
7631
+ refuseMixed("bound migrations", kept.length, list.length - kept.length);
7632
+ return kept;
7633
+ }
7634
+ /**
7613
7635
  * Base class for CamStack addons. Eliminates settings boilerplate:
7614
7636
  *
7615
7637
  * - Typed `config` property with automatic resolution from store + defaults
@@ -7776,23 +7798,21 @@ var BaseAddon = class {
7776
7798
  await this.loadScopedSchemas();
7777
7799
  return normalized;
7778
7800
  }
7801
+ async runMigrations(first, second, third) {
7802
+ if (typeof second === "function") return this.runMigrationSets([migrationSet(catalogueOf(first), second)], third);
7803
+ return this.runBound(boundOf(first), second);
7804
+ }
7779
7805
  /**
7780
- * Run this addon's migration catalogue (D987 M3) through the hub's `migrations`
7781
- * engine. Call it at the point of the boot where the data must already have the new
7782
- * shape — `onInitialize`, or `onRestoreDevices` for a migration that needs the
7783
- * restored devices — with the catalogue bound to the addon's ports
7784
- * (`defineAddonMigrations(ADDON_MIGRATIONS, ports)`).
7785
- *
7786
- * An engine that cannot be reached or refuses the catalogue is logged and runs
7787
- * nothing; the boot continues. A migration that FAILED (or was blocked by one)
7788
- * and declares `onFailure: 'block-owner'` makes this throw, so the addon does not
7789
- * serve data whose shape it cannot trust; `tolerate` migrations never do.
7790
- *
7791
- * ALWAYS pass the whole catalogue; a phase that must run only some of it passes
7792
- * `{ only: [ids] }` — never a filtered catalogue (the engine would judge the
7793
- * omitted applied ids "newer").
7806
+ * Several catalogues of ONE owner in one declaration (the engine replaces an owner's
7807
+ * catalogue on every declare, so two calls would each judge the other's ids "newer").
7808
+ * Build each entry with `migrationSet(catalogue, (api) => ports)`.
7794
7809
  */
7795
- async runMigrations(migrations, options) {
7810
+ async runMigrationSets(sets, options) {
7811
+ const api = this.ctx.migrationApi;
7812
+ if (api === void 0) throw new Error(`${this.ctx.id}: the migration API is not available on this context`);
7813
+ return this.runBound(sets.flatMap((set) => set.bind(api)), options);
7814
+ }
7815
+ async runBound(migrations, options) {
7796
7816
  const api = this.ctx.api.migrations;
7797
7817
  const report = await runAddonMigrations({
7798
7818
  declareOwner: (input) => api.declareOwner.mutate(input),
@@ -13532,26 +13552,16 @@ var RecordIntegrationInstances = class {
13532
13552
  ...this.hooks.description,
13533
13553
  mintsId: true
13534
13554
  };
13535
- /**
13536
- * The record an id names. A caller holding the `integrations` registry id (the Integrations
13537
- * page) reaches a kind whose body links to it through `integrationId`; an id that is itself a
13538
- * record id answers as it is. An id that names nothing comes back unchanged.
13539
- */
13540
- async resolveRecordId(id) {
13541
- if (await this.handle.get(id) !== null) return id;
13542
- const linked = (await this.handle.query({ limit: INSTANCES_LIST_MAX })).records.find((record) => record.data["integrationId"] === id);
13543
- return linked === void 0 ? id : linked.id;
13544
- }
13545
- instanceFormSchema = async ({ id }) => this.hooks.formSchema(id === null ? null : await this.resolveRecordId(id));
13555
+ instanceFormSchema = async ({ id }) => this.hooks.formSchema(id);
13546
13556
  listInstances = async () => {
13547
13557
  return (await this.handle.query({ limit: INSTANCES_LIST_MAX })).records.map((record) => this.viewOf(record));
13548
13558
  };
13549
13559
  getInstance = async ({ id }) => {
13550
- const record = await this.handle.get(await this.resolveRecordId(id));
13560
+ const record = await this.handle.get(id);
13551
13561
  return record === null ? null : this.viewOf(record);
13552
13562
  };
13553
13563
  /** Insert ONE row (`ifRev: 0`: an existing id is refused, never overwritten). */
13554
- createInstance = async ({ id, name, kind }) => {
13564
+ createInstance = async ({ id, name, kind, values }) => {
13555
13565
  const minted = id ?? this.hooks.mintId?.({
13556
13566
  name,
13557
13567
  ...kind !== void 0 ? { kind } : {}
@@ -13561,11 +13571,20 @@ var RecordIntegrationInstances = class {
13561
13571
  id: minted,
13562
13572
  data: this.hooks.initialBody(name, kind)
13563
13573
  }, { ifRev: 0 });
13574
+ const patch = this.patchOf(values ?? {});
13575
+ if (Object.keys(patch).length > 0) await this.handle.patch(minted, patch);
13564
13576
  await this.hooks.onChanged?.(minted, "created");
13565
13577
  return { id: minted };
13566
13578
  };
13567
- updateInstance = async ({ id: askedId, name, values }) => {
13568
- const id = await this.resolveRecordId(askedId);
13579
+ updateInstance = async ({ id, name, values }) => {
13580
+ const patch = this.patchOf(values);
13581
+ if (name !== void 0) patch[this.nameField] = name;
13582
+ await this.handle.patch(id, patch);
13583
+ await this.hooks.onChanged?.(id, "updated");
13584
+ return { ok: true };
13585
+ };
13586
+ /** The record patch a form `values` object means: secrets kept, cleared or replaced. */
13587
+ patchOf(values) {
13569
13588
  const patch = {};
13570
13589
  for (const [key, value] of Object.entries(values)) {
13571
13590
  if (value === void 0) continue;
@@ -13576,11 +13595,8 @@ var RecordIntegrationInstances = class {
13576
13595
  else if (isSecretClear(value)) patch[key] = null;
13577
13596
  else if (typeof value === "string" && value !== "" && value !== "__camstack_redacted__" && !isSecretFieldView(value)) patch[key] = value;
13578
13597
  }
13579
- if (name !== void 0) patch[this.nameField] = name;
13580
- await this.handle.patch(id, patch);
13581
- await this.hooks.onChanged?.(id, "updated");
13582
- return { ok: true };
13583
- };
13598
+ return patch;
13599
+ }
13584
13600
  /** The switch lives in the record body; the addon is told so it applies it (D996). */
13585
13601
  setInstanceEnabled = async ({ id, enabled }) => {
13586
13602
  if (this.registryOwnsEnabled) throw new Error(`instance "${id}": the integrations registry owns the on/off switch of this addon; set it with integrations.update`);
@@ -13600,10 +13616,7 @@ var RecordIntegrationInstances = class {
13600
13616
  status: "unsupported",
13601
13617
  error: "This integration declares no connection test"
13602
13618
  };
13603
- return this.hooks.test(input.id === null ? input : {
13604
- ...input,
13605
- id: await this.resolveRecordId(input.id)
13606
- });
13619
+ return this.hooks.test(input);
13607
13620
  };
13608
13621
  /** The flat provider object to hand to `registerProvider`. */
13609
13622
  toProvider() {
@@ -14828,25 +14841,6 @@ function integrationRowsPortsOverApi(deps) {
14828
14841
  }
14829
14842
  };
14830
14843
  }
14831
- function defaultIntegrationApiOver(api) {
14832
- return {
14833
- list: () => api.integrations.list.query(),
14834
- readLegacyIntegrationRows: (input) => api.migrations.readLegacyIntegrationRows.query(input),
14835
- clearLegacyIntegrationRows: (input) => api.migrations.clearLegacyIntegrationRows.mutate(input),
14836
- listDevices: (addonId) => api.deviceManager.listAll.query({
14837
- addonId,
14838
- projection: "slim"
14839
- }),
14840
- setDeviceIntegrationId: async (deviceId, integrationId) => {
14841
- await api.deviceManager.setIntegrationId.mutate({
14842
- deviceId,
14843
- integrationId
14844
- });
14845
- },
14846
- readDeviceHasConfig: async (deviceId) => Object.keys((await api.deviceManager.getDevice.query({ deviceId }))?.config ?? {}).length > 0,
14847
- readDeviceIntegrationId: async (deviceId) => (await api.deviceManager.getDevice.query({ deviceId }))?.integrationId ?? null
14848
- };
14849
- }
14850
14844
  /**
14851
14845
  * The trainer contract — what the hub hands the cloud trainer and what it
14852
14846
  * gets back (cloud training, D805+).
@@ -15935,6 +15929,39 @@ var UnstampedEventMediaCountSchema = object({
15935
15929
  /** Sum across both, or `null` when either lane could not be counted. */
15936
15930
  total: number().int().nonnegative().nullable()
15937
15931
  }).nullable();
15932
+ /**
15933
+ * Where the stored event media sits, per storage location: how many media rows
15934
+ * and how many bytes carry each location id, how many carry none (legacy,
15935
+ * resolved to the default `eventMedia` location), and how many name a location
15936
+ * that was not asked about (a deleted or never-listed one).
15937
+ *
15938
+ * One covering-index aggregate per asked location plus the NULL one, and one
15939
+ * unfiltered total that scans the covering index: O(rows), not a walk of the
15940
+ * rows themselves. `unlisted` is total minus the ASKED locations minus NULL, so
15941
+ * it is a deleted location only when every location id was asked.
15942
+ * `null` is "could not be measured", never zero.
15943
+ */
15944
+ var MediaLocationCensusInputSchema = object({ locationIds: array(string().min(1)).max(50).readonly() });
15945
+ var MediaLocationCensusSchema = object({
15946
+ locations: array(object({
15947
+ locationId: string(),
15948
+ rows: number().int().nonnegative(),
15949
+ bytes: number().nonnegative()
15950
+ })).readonly(),
15951
+ unstamped: object({
15952
+ rows: number().int().nonnegative(),
15953
+ bytes: number().nonnegative()
15954
+ }),
15955
+ /** Rows stamped with a location id that was not in the asked list. */
15956
+ unlisted: object({
15957
+ rows: number().int().nonnegative(),
15958
+ bytes: number().nonnegative()
15959
+ }),
15960
+ total: object({
15961
+ rows: number().int().nonnegative(),
15962
+ bytes: number().nonnegative()
15963
+ })
15964
+ });
15938
15965
  var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
15939
15966
  /** The independently selectable logical storage classes — every class
15940
15967
  * `storage.listLocationDeclarations` reports, so an operator never meets a
@@ -47050,52 +47077,7 @@ onBrightnessChanged: { data: object({
47050
47077
  minIntervalMs: 0
47051
47078
  } } }
47052
47079
  };
47053
- /**
47054
- * `broker` — unified pub/sub broker registry, system-scoped collection.
47055
- *
47056
- * The cap models any kind-tagged message broker the user wants to
47057
- * register and that other addons might consume. The first two kinds
47058
- * are MQTT (mosquitto / aedes embedded / cloud bridge) and
47059
- * Home Assistant (HA WebSocket — subscribe_entities + call_service).
47060
- * Future kinds (Zigbee2MQTT bridge, ZHA, KNX, Telegram, …) plug in
47061
- * the same surface.
47062
- *
47063
- * Why one cap, not one cap per kind:
47064
- * - The integrations page wants a single table of "every broker"
47065
- * across kinds; a unified cap drives it without join logic.
47066
- * - Generic admin operations (add / remove / test / status) are
47067
- * identical across kinds — duplicating them per cap was busywork.
47068
- * - The `network-access` cap precedent: same interface, many
47069
- * `providerKind: 'ingress'` implementations (Tailscale, ngrok, …).
47070
- *
47071
- * What stays kind-specific:
47072
- * - `getBrokerConfig` payload (kind decides whether it returns
47073
- * mqtt URL+creds, HA baseUrl+token, …) — typed as
47074
- * `Record<string, unknown>` at the wire; consumers narrow.
47075
- * - `publish` / `subscribe` / `getState` arguments (target / filter /
47076
- * key) — also typed as `Record<string, unknown>` so each kind can
47077
- * evolve its surface (MQTT topic+qos vs HA entity_id+domain)
47078
- * without rebreaking the cap signature.
47079
- * - `add` `settings` payload (different fields per kind, validated by
47080
- * the kind-specific provider).
47081
- *
47082
- * Bidirectionality:
47083
- * - `publish` is RPC — synchronous result (provider-defined).
47084
- * - `subscribe` returns a subscription handle; the actual message
47085
- * stream flows over the typed event-bus as `broker.message` events
47086
- * keyed by `(brokerId, subscriptionId)`. Consumers filter in their
47087
- * event handler. Subscriptions persist across reconnects — the
47088
- * provider re-subscribes upstream after a transport drop.
47089
- *
47090
- * Why event-bus push (not a subscription RPC stream):
47091
- * - Matches the rest of CamStack's D8 contract — events for telemetry,
47092
- * RPC for loss-is-a-bug. Broker messages are telemetry (a single
47093
- * drop is recoverable via `getState({key})`).
47094
- * - Frees `broker.subscribe` from holding a long-lived RPC channel.
47095
- * - Cross-process: events already route through `$event-bus`; no
47096
- * per-broker wire-shaping needed.
47097
- */
47098
- var BrokerStatusEnum = _enum([
47080
+ _enum([
47099
47081
  "connected",
47100
47082
  "disconnected",
47101
47083
  "connecting",
@@ -47103,141 +47085,12 @@ var BrokerStatusEnum = _enum([
47103
47085
  "unreachable",
47104
47086
  "error"
47105
47087
  ]);
47106
- var BrokerInfoSchema = object({
47107
- /** Stable broker id. Persisted; survives addon restarts. */
47108
- id: string(),
47109
- /** Addon id of the provider that OWNS this broker.
47110
- *
47111
- * The `broker` cap is a system-scoped collection: several addons
47112
- * register a `broker` provider, each owning a DISJOINT set of
47113
- * brokers (mqtt-broker owns `mqtt_*`, provider-homeassistant owns
47114
- * `ha_*`). A broker therefore belongs to exactly one addon — like a
47115
- * device belongs to one integration. The admin UI threads this id
47116
- * back as the `{ addonId }` system-collection selector on every
47117
- * id-keyed call (`get` / `getSettings` / `setSettings` / `remove` /
47118
- * `testConnection`), so the call routes to the OWNING provider
47119
- * instead of defaulting to the first-registered one. */
47120
- addonId: string(),
47121
- /** Human-readable name (operator-chosen at add-time). */
47122
- name: string(),
47123
- /** Provider-defined kind tag — `mqtt` / `home-assistant` / future. */
47124
- kind: string(),
47125
- status: BrokerStatusEnum,
47126
- /** Free-form provider-specific info (HA version, MQTT broker
47127
- * flavour, latency, mTLS active, …). */
47128
- info: record(string(), unknown()),
47129
- /** Ms epoch of the last connection probe / status update. */
47130
- lastCheckedAt: number().nullable(),
47131
- /** Last error message, when `status` indicates failure. */
47132
- error: string().nullable()
47133
- });
47134
47088
  var RegistryStatusSchema = object({
47135
47089
  brokerCount: number().int().nonnegative(),
47136
47090
  connectedCount: number().int().nonnegative()
47137
47091
  });
47138
- /**
47139
- * One entry per `broker` provider — which addon provides which broker
47140
- * kind(s). The unified create picker reads this to know, for each
47141
- * (addonId, kind) pair the operator can pick, where to route the
47142
- * follow-up `getSettingsSchema` / `testSettings` / `add` calls (via the
47143
- * `{ addonId }` selector). A provider only advertises a kind here when
47144
- * it implements `getSettingsSchema` for that kind (so the picker never
47145
- * offers a kind whose creation form can't be rendered).
47146
- */
47147
- var BrokerProviderInfoSchema = object({
47148
- /** Addon id of the `broker` provider this entry describes. */
47149
- addonId: string(),
47150
- /** Broker kinds this provider can create, with a display label. */
47151
- kinds: array(object({
47152
- kind: string(),
47153
- label: string(),
47154
- /**
47155
- * Relative hub path to start an interactive account link (OAuth popup).
47156
- * May include `{{brokerId}}`; admin-ui substitutes and appends `?popup=1`.
47157
- */
47158
- interactiveConnectPath: string().min(1).optional(),
47159
- /** Relative hub path to disconnect the linked account (same popup pattern). */
47160
- interactiveDisconnectPath: string().min(1).optional(),
47161
- /**
47162
- * The kind signs in through a server-held interactive session instead of
47163
- * (or before) typed credentials. `basePath` is a hub-relative route set
47164
- * served by the owning addon (`/addon/<id>/...`) speaking the sign-in
47165
- * contract: `POST {basePath}/start` (body: the form's settings) answers
47166
- * `{ sessionId, loginUrl }`; `GET {basePath}/status?sessionId=` answers
47167
- * `{ phase: 'starting' | 'awaiting-login' | 'captured' | 'error' |
47168
- * 'cancelled', loginUrl, error }`; `POST {basePath}/commit`
47169
- * (`{ sessionId, name, brokerId? }`) stores the credentials on a new or
47170
- * existing broker and answers `{ brokerId }`; `POST {basePath}/cancel`
47171
- * (`{ sessionId }`) drops the session. The dialog that edits a broker
47172
- * offers it as the default path; the fields the session fills are
47173
- * marked `filledBySignIn` in the kind's settings schema.
47174
- *
47175
- * `methods` lists the ways the session can sign in, recommended first:
47176
- * `'device-code'` adds `POST {basePath}/code/start` (body: the form's
47177
- * settings) answering `{ sessionId, userCode, verificationUrl,
47178
- * expiresAt }` — the operator types `userCode` at `verificationUrl` on
47179
- * any device, and the same `status` / `commit` / `cancel` routes follow
47180
- * (status then carries `method`, `userCode`, `verificationUrl`,
47181
- * `expiresAt` and the phases `'awaiting-code'` / `'expired'`);
47182
- * `'proxy'` is the `{basePath}/start` flow above. Absent means
47183
- * `['proxy']`.
47184
- */
47185
- signIn: object({
47186
- basePath: string().min(1),
47187
- methods: array(_enum(["device-code", "proxy"])).optional()
47188
- }).optional()
47189
- }))
47190
- });
47191
- var ListInputSchema = object({
47192
- /** Optional kind filter — `list({kind:'home-assistant'})` returns
47193
- * only HA brokers. Omit to list every broker. */
47194
- kind: string().optional() });
47195
47092
  var GetInputSchema = object({ id: string() });
47196
- var AddInputSchema = object({
47197
- kind: string().min(1),
47198
- name: string().min(1),
47199
- /**
47200
- * ADOPT an existing id instead of minting a new one.
47201
- *
47202
- * Written the day this cost an outage. A broker's id is not a detail: HA
47203
- * devices carry it inside their `stableId` (`ha:ha_004:dev:…`), so a broker
47204
- * lost from config and re-added as `ha_001` leaves every one of its devices
47205
- * bound to a broker that no longer exists. Re-entering the password under the
47206
- * ORIGINAL id turns a multi-step device migration back into re-entering a
47207
- * password.
47208
- *
47209
- * A provider MUST refuse an id that is already in use — adopting a live
47210
- * broker's id would silently take it over.
47211
- */
47212
- id: string().min(1).optional(),
47213
- /** Kind-specific settings (e.g. MQTT `{url,username,password}` or HA
47214
- * `{baseUrl,accessToken}`). Validated by the kind-specific provider
47215
- * branch on receipt — invalid shape rejects the add. */
47216
- settings: record(string(), unknown())
47217
- });
47218
- var AddResultSchema = object({ id: string() });
47219
- var RemoveInputSchema = object({ id: string() });
47220
- var TestConnectionResultSchema = discriminatedUnion("ok", [object({
47221
- ok: literal(true),
47222
- latencyMs: number().nonnegative()
47223
- }), object({
47224
- ok: literal(false),
47225
- error: string()
47226
- })]);
47227
47093
  var SettingsRecordSchema$1 = record(string(), unknown());
47228
- var SettingsSchemaInputSchema = object({ kind: string() });
47229
- var TestSettingsInputSchema = object({
47230
- kind: string(),
47231
- settings: SettingsRecordSchema$1
47232
- });
47233
- var TestSettingsResultSchema = discriminatedUnion("ok", [object({
47234
- ok: literal(true),
47235
- latencyMs: number().nonnegative().optional()
47236
- }).strict(), object({
47237
- ok: literal(false),
47238
- error: string()
47239
- })]);
47240
- var SettingsSchemaResultSchema = unknown().nullable();
47241
47094
  var PublishInputSchema = object({
47242
47095
  brokerId: string(),
47243
47096
  /** Kind-specific routing target.
@@ -47271,25 +47124,7 @@ var GetStateInputSchema = object({
47271
47124
  * HA: entity_id (returns the cached entity state). */
47272
47125
  key: string()
47273
47126
  });
47274
- method(ListInputSchema, array(BrokerInfoSchema)), method(GetInputSchema, BrokerInfoSchema.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
47275
- kind: "mutation",
47276
- auth: "admin"
47277
- }), method(RemoveInputSchema, _void(), {
47278
- kind: "mutation",
47279
- auth: "admin"
47280
- }), method(GetInputSchema, TestConnectionResultSchema, {
47281
- kind: "mutation",
47282
- auth: "admin"
47283
- }), method(GetInputSchema, SettingsRecordSchema$1.nullable(), { auth: "admin" }), method(object({
47284
- id: string(),
47285
- settings: SettingsRecordSchema$1
47286
- }), _void(), {
47287
- kind: "mutation",
47288
- auth: "admin"
47289
- }), method(GetInputSchema, SettingsRecordSchema$1.nullable(), { auth: "admin" }), method(SettingsSchemaInputSchema, SettingsSchemaResultSchema, { auth: "admin" }), method(TestSettingsInputSchema, TestSettingsResultSchema, {
47290
- kind: "mutation",
47291
- auth: "admin"
47292
- }), method(PublishInputSchema, unknown(), {
47127
+ method(GetInputSchema, SettingsRecordSchema$1.nullable(), { auth: "admin" }), method(PublishInputSchema, unknown(), {
47293
47128
  kind: "mutation",
47294
47129
  auth: "admin"
47295
47130
  }), method(SubscribeInputSchema, SubscribeResultSchema, {
@@ -52248,7 +52083,9 @@ var deviceProviderCapability = {
52248
52083
  * provider does not support manual creation. Lets the Add-Device dialog
52249
52084
  * pick the right type instead of assuming Camera.
52250
52085
  */
52251
- getManualCreationType: method(object({}), object({ deviceType: _enum(DeviceType).nullable() })),
52086
+ getManualCreationType: method(object({
52087
+ /** The integration asked about; a provider whose integrations differ answers per one. */
52088
+ integrationId: string().optional() }), object({ deviceType: _enum(DeviceType).nullable() })),
52252
52089
  adoptDiscoveredDevice: method(object({
52253
52090
  candidate: DiscoveryCandidateSchema,
52254
52091
  /** The integration the operator adopts into; a provider with several instances needs it. */
@@ -52264,7 +52101,11 @@ var deviceProviderCapability = {
52264
52101
  * devices of that type. The output is a `ConfigUISchema` — the
52265
52102
  * router type-asserts it at the boundary.
52266
52103
  */
52267
- getChildCreationSchema: method(object({ type: _enum(DeviceType) }), CreationSchemaOutputSchema),
52104
+ getChildCreationSchema: method(object({
52105
+ type: _enum(DeviceType),
52106
+ /** The integration asked about; a provider whose integrations differ answers per one. */
52107
+ integrationId: string().optional()
52108
+ }), CreationSchemaOutputSchema),
52268
52109
  createDevice: method(object({
52269
52110
  type: _enum(DeviceType),
52270
52111
  config: record(string(), unknown()),
@@ -52994,7 +52835,10 @@ method(object({
52994
52835
  auth: "admin"
52995
52836
  }), method(object({
52996
52837
  addonId: string(),
52997
- type: _enum(DeviceType)
52838
+ type: _enum(DeviceType),
52839
+ /** The integration the form is for; a provider whose integrations differ (a hub
52840
+ * integration takes no manual add) answers per integration. Absent = the addon's own. */
52841
+ integrationId: string().optional()
52998
52842
  }), unknown().nullable()), method(object({
52999
52843
  addonId: string(),
53000
52844
  type: _enum(DeviceType),
@@ -53078,7 +52922,11 @@ method(object({
53078
52922
  kind: "mutation",
53079
52923
  auth: "admin",
53080
52924
  timeoutMs: 12e4
53081
- }), method(object({ addonId: string() }), object({ deviceType: _enum(DeviceType).nullable() }), { auth: "admin" }), method(object({ addonId: string() }), unknown(), { auth: "admin" }), method(object({
52925
+ }), method(object({
52926
+ addonId: string(),
52927
+ /** The integration the Add-Device dialog is open on; absent = the addon's own. */
52928
+ integrationId: string().optional()
52929
+ }), object({ deviceType: _enum(DeviceType).nullable() }), { auth: "admin" }), method(object({ addonId: string() }), unknown(), { auth: "admin" }), method(object({
53082
52930
  deviceId: number(),
53083
52931
  key: string(),
53084
52932
  value: unknown()
@@ -56358,7 +56206,7 @@ var TestConnectionStatusEnum = _enum([
56358
56206
  "inconclusive",
56359
56207
  "unsupported"
56360
56208
  ]);
56361
- var TestConnectionResultSchema$1 = object({
56209
+ var TestConnectionResultSchema = object({
56362
56210
  /** True ONLY for `validated`. Never true for a test that did not run. */
56363
56211
  success: boolean(),
56364
56212
  error: string().optional(),
@@ -56403,7 +56251,7 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
56403
56251
  }), method(_void(), array(AvailableIntegrationTypeSchema), { auth: "admin" }), method(object({
56404
56252
  addonId: string(),
56405
56253
  settings: record(string(), unknown())
56406
- }), TestConnectionResultSchema$1, {
56254
+ }), TestConnectionResultSchema, {
56407
56255
  kind: "mutation",
56408
56256
  auth: "admin"
56409
56257
  });
@@ -56430,6 +56278,14 @@ var ConfigSchemaPassthrough$3 = custom();
56430
56278
  var IntegrationInstanceIdSchema = string().min(1);
56431
56279
  var IntegrationInstanceModeSchema = _enum(["single", "multiple"]);
56432
56280
  /**
56281
+ * What the addon's instances ARE for the Integrations page (planning#416). `devices`: each
56282
+ * instance is an integration that brings devices (the registry owns its on/off switch);
56283
+ * `services`: a connection configured from the addon's own function page, never listed on
56284
+ * Integrations.
56285
+ * It is the same vocabulary as the manifest's `integrationRole`, which stays as an override.
56286
+ */
56287
+ var IntegrationInstanceRoleSchema = _enum(["devices", "services"]);
56288
+ /**
56433
56289
  * One kind of instance a provider can create (an adapter, an account type). The sign-in and
56434
56290
  * connect fields follow the `broker` contract (`broker.cap.ts`): `signIn.basePath` is a
56435
56291
  * hub-relative route set speaking the sign-in contract, `connectPath` / `disconnectPath` open an
@@ -56440,6 +56296,22 @@ var IntegrationInstanceKindSchema = object({
56440
56296
  /** Stable id of the kind, sent back as `createInstance.kind`. */
56441
56297
  id: string().min(1),
56442
56298
  label: string().min(1),
56299
+ /**
56300
+ * The function capability this kind is configured for (`broker`, `smtp-provider`,
56301
+ * `device-provider`, ...). A page section is the kinds whose `functionCap` it names (D1013); a
56302
+ * provider with more than one section must name it on every kind.
56303
+ */
56304
+ functionCap: string().min(1),
56305
+ /**
56306
+ * For `functionCap: 'broker'`: the registry kind of the broker an instance of this kind is
56307
+ * (`matter`, `home-assistant`, ...). A caller that needs a broker of one kind (a link field)
56308
+ * finds the instances whose kind names it; absent takes the kind `id`.
56309
+ */
56310
+ brokerKind: string().min(1).optional(),
56311
+ /** What instances of this kind are for the Integrations page; absent takes the provider's `role`. */
56312
+ role: IntegrationInstanceRoleSchema.optional(),
56313
+ /** `testInstance` really probes the remote for this kind; absent takes the provider's `canTest`. */
56314
+ canTest: boolean().optional(),
56443
56315
  /** The kind signs in through a server-held interactive session. */
56444
56316
  signIn: object({
56445
56317
  basePath: string().min(1),
@@ -56452,11 +56324,7 @@ var IntegrationInstanceKindSchema = object({
56452
56324
  });
56453
56325
  var IntegrationInstanceDescriptionSchema = object({
56454
56326
  /** What the instances are for the Integrations page; see {@link IntegrationInstanceRoleSchema}. */
56455
- role: _enum([
56456
- "devices",
56457
- "services",
56458
- "both"
56459
- ]),
56327
+ role: IntegrationInstanceRoleSchema,
56460
56328
  /** How the devices of an instance are found; absent means `{ mode: 'none' }`. */
56461
56329
  discovery: object({
56462
56330
  mode: _enum([
@@ -56531,7 +56399,11 @@ var integrationInstancesCapability = {
56531
56399
  methods: {
56532
56400
  describe: method(_void(), IntegrationInstanceDescriptionSchema, { auth: "admin" }),
56533
56401
  /** The form; `id: null` is the create form. */
56534
- instanceFormSchema: method(object({ id: IntegrationInstanceIdSchema.nullable() }), ConfigSchemaPassthrough$3, { auth: "admin" }),
56402
+ instanceFormSchema: method(object({
56403
+ id: IntegrationInstanceIdSchema.nullable(),
56404
+ /** The kind of the create form (`id: null`) of a provider with several. */
56405
+ kind: string().min(1).optional()
56406
+ }), ConfigSchemaPassthrough$3, { auth: "admin" }),
56535
56407
  listInstances: method(_void(), array(IntegrationInstanceSchema).readonly(), { auth: "admin" }),
56536
56408
  getInstance: method(object({ id: IntegrationInstanceIdSchema }), IntegrationInstanceSchema.nullable(), { auth: "admin" }),
56537
56409
  /**
@@ -56541,7 +56413,9 @@ var integrationInstancesCapability = {
56541
56413
  createInstance: method(object({
56542
56414
  id: IntegrationInstanceIdSchema.optional(),
56543
56415
  name: string().min(1),
56544
- kind: string().min(1).optional()
56416
+ kind: string().min(1).optional(),
56417
+ /** Form values written with the record (a link picked in the create dialog). */
56418
+ values: record(string(), unknown()).optional()
56545
56419
  }), object({ id: string() }), {
56546
56420
  kind: "mutation",
56547
56421
  auth: "admin"
@@ -56568,8 +56442,10 @@ var integrationInstancesCapability = {
56568
56442
  }),
56569
56443
  testInstance: optionalMethod(object({
56570
56444
  id: IntegrationInstanceIdSchema.nullable(),
56571
- values: record(string(), unknown())
56572
- }), TestConnectionResultSchema$1, {
56445
+ values: record(string(), unknown()),
56446
+ /** The kind to test when `id` is null and the provider has several. */
56447
+ kind: string().min(1).optional()
56448
+ }), TestConnectionResultSchema, {
56573
56449
  kind: "mutation",
56574
56450
  auth: "admin"
56575
56451
  })
@@ -59326,6 +59202,380 @@ var SystemMetricsSchema = object({
59326
59202
  gpuMemoryPercent: number().optional()
59327
59203
  });
59328
59204
  method(_void(), SystemResourceSnapshotSchema), method(_void(), SystemResourceSnapshotSchema.nullable()), method(_void(), SystemMetricsSchema), method(object({ dirPath: string() }), DiskSpaceInfoSchema), method(_void(), MetricsGpuInfoSchema.nullable()), method(_void(), number().nullable()), method(object({ pids: array(number()) }), array(PidResourceStatsSchema)), method(_void(), array(AddonInstanceSchema).readonly()), method(object({ addonId: string() }), PidResourceStatsSchema.nullable()), method(_void(), array(NodeProcessSchema).readonly()), method(GetLoadSeriesInputSchema, NodeLoadSeriesSchema);
59205
+ /**
59206
+ * records - an addon's own facts and documents (D881): ledgers, audit rows,
59207
+ * config documents, mirrors. The third storage API next to `ctx.settings`
59208
+ * (operator intent, D870) and device-history (numbers over time, D850).
59209
+ *
59210
+ * Who the OWNER is: `callerAddonId`, stamped by the transport on a call that
59211
+ * crossed a process and stated by a hub in-process caller (`ctx.records` does
59212
+ * that with the addon id closed over). It is deliberately NOT in any input
59213
+ * schema, so a session can never supply it, and a call with no stamp is refused
59214
+ * `records/no-caller`. A kind is readable and writable only by its owner; other
59215
+ * addons go through the owner's capability.
59216
+ *
59217
+ * Every read is three-way: a row, `null`, or the call THROWS. A failed read is
59218
+ * never `[]`. Secret fields are never on the wire: a read shows the
59219
+ * redaction token, `secretRefs` hands the owner's `ctx.secrets` the refs it
59220
+ * resolves itself, and a write may carry only a keychain marker bound to the
59221
+ * row's own ref.
59222
+ *
59223
+ * Internal: addons reach it through `ctx.records`, never directly.
59224
+ */
59225
+ var RecordIdSchema = string().min(1).max(256);
59226
+ /** A JSON object body. Size is the engine's check (`maxDataBytes`), not a schema's. */
59227
+ var RecordBodySchema = record(string(), unknown());
59228
+ var RecordInputSchema = object({
59229
+ id: RecordIdSchema,
59230
+ /** The device this row belongs to (D865 removal, per-device reads). */
59231
+ deviceId: number().int().optional(),
59232
+ /** The domain clock, ms: observed / created / opened. */
59233
+ at: number().int().optional(),
59234
+ /** Producer-set expiry, ms. Refused on a kind whose retention is an engine TTL. */
59235
+ expiresAt: number().int().optional(),
59236
+ data: RecordBodySchema
59237
+ });
59238
+ var RecordViewSchema = object({
59239
+ id: string(),
59240
+ deviceId: number().int().nullable(),
59241
+ at: number().nullable(),
59242
+ expiresAt: number().nullable(),
59243
+ rev: number().int(),
59244
+ updatedAt: number(),
59245
+ data: RecordBodySchema
59246
+ });
59247
+ /** Declared index fields only. Anything else does not compile, by design. */
59248
+ var RecordWhereSchema = record(RecordFieldPathSchema, union([
59249
+ string(),
59250
+ number(),
59251
+ boolean(),
59252
+ object({ in: array(union([
59253
+ string(),
59254
+ number(),
59255
+ boolean()
59256
+ ])).min(1).max(RECORD_BATCH_MAX) }),
59257
+ object({
59258
+ gt: union([string(), number()]).optional(),
59259
+ gte: union([string(), number()]).optional(),
59260
+ lt: union([string(), number()]).optional(),
59261
+ lte: union([string(), number()]).optional()
59262
+ }).refine((r) => Object.keys(r).length > 0, { message: "name at least one bound" })
59263
+ ]));
59264
+ var KindShape = { kind: RecordKindNameSchema };
59265
+ var TimeWindowShape = {
59266
+ deviceId: number().int().optional(),
59267
+ atFrom: number().optional(),
59268
+ atTo: number().optional()
59269
+ };
59270
+ var RecordQueryInputSchema = object({
59271
+ ...KindShape,
59272
+ ...TimeWindowShape,
59273
+ where: RecordWhereSchema.optional(),
59274
+ /** Without `where`: `at` (default for a kind with a clock) or `id`. With `where` the order is the index's. */
59275
+ order: _enum(["at", "id"]).optional(),
59276
+ desc: boolean().optional(),
59277
+ limit: number().int().min(1).max(RECORD_QUERY_MAX).default(100),
59278
+ /** Opaque keyset cursor from a previous answer. There is no offset. */
59279
+ cursor: string().min(1).optional()
59280
+ });
59281
+ var RecordQueryResultSchema = object({
59282
+ records: array(RecordViewSchema),
59283
+ nextCursor: string().nullable()
59284
+ });
59285
+ var RecordKindStateSchema = _enum([
59286
+ "created",
59287
+ "unchanged",
59288
+ "updated"
59289
+ ]);
59290
+ var DeclareKindResultSchema = object({
59291
+ kindId: number().int(),
59292
+ state: RecordKindStateSchema,
59293
+ createdIndexes: array(string())
59294
+ });
59295
+ /** Keychain refs a write released (the old marker is gone from the row): the owner deletes the values. */
59296
+ var SecretRefsList = array(string());
59297
+ /**
59298
+ * One op of a `transact`: the single-row writes, each on a kind of the caller.
59299
+ * All ops of one call share ONE database file and ONE `transactFamily`.
59300
+ */
59301
+ var RecordTransactOpSchema = discriminatedUnion("op", [
59302
+ object({
59303
+ op: literal("put"),
59304
+ kind: RecordKindNameSchema,
59305
+ record: RecordInputSchema,
59306
+ ifRev: number().int().min(0).optional()
59307
+ }),
59308
+ object({
59309
+ op: literal("patch"),
59310
+ kind: RecordKindNameSchema,
59311
+ id: RecordIdSchema,
59312
+ data: RecordBodySchema,
59313
+ at: number().int().nullable().optional(),
59314
+ expiresAt: number().int().nullable().optional(),
59315
+ ifRev: number().int().min(1).optional()
59316
+ }),
59317
+ object({
59318
+ op: literal("delete"),
59319
+ kind: RecordKindNameSchema,
59320
+ id: RecordIdSchema
59321
+ })
59322
+ ]);
59323
+ var RecordSecretRefsSchema = record(string(), record(string(), string()));
59324
+ method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema) }), object({ kinds: record(string(), DeclareKindResultSchema) }), {
59325
+ kind: "mutation",
59326
+ auth: "admin"
59327
+ }), method(object({
59328
+ ...KindShape,
59329
+ id: RecordIdSchema
59330
+ }), RecordViewSchema.nullable(), { auth: "admin" }), method(object({
59331
+ ...KindShape,
59332
+ ids: array(RecordIdSchema).min(1).max(RECORD_BATCH_MAX)
59333
+ }), array(RecordViewSchema), { auth: "admin" }), method(object({
59334
+ ...KindShape,
59335
+ ids: array(RecordIdSchema).min(1).max(RECORD_BATCH_MAX)
59336
+ }), RecordSecretRefsSchema, { auth: "admin" }), method(object({
59337
+ ...KindShape,
59338
+ record: RecordInputSchema,
59339
+ /** Compare-and-set. `0` means "the row must not exist". */
59340
+ ifRev: number().int().min(0).optional()
59341
+ }), object({
59342
+ rev: number().int(),
59343
+ releasedRefs: SecretRefsList
59344
+ }), {
59345
+ kind: "mutation",
59346
+ auth: "admin"
59347
+ }), method(object({
59348
+ ...KindShape,
59349
+ records: array(RecordInputSchema).min(1).max(RECORD_BATCH_MAX)
59350
+ }), object({
59351
+ count: number().int(),
59352
+ releasedRefs: SecretRefsList
59353
+ }), {
59354
+ kind: "mutation",
59355
+ auth: "admin"
59356
+ }), method(object({
59357
+ ...KindShape,
59358
+ id: RecordIdSchema,
59359
+ data: RecordBodySchema,
59360
+ at: number().int().nullable().optional(),
59361
+ expiresAt: number().int().nullable().optional(),
59362
+ ifRev: number().int().min(1).optional()
59363
+ }), object({
59364
+ rev: number().int(),
59365
+ releasedRefs: SecretRefsList
59366
+ }), {
59367
+ kind: "mutation",
59368
+ auth: "admin"
59369
+ }), method(object({
59370
+ ...KindShape,
59371
+ id: RecordIdSchema
59372
+ }), object({
59373
+ deleted: boolean(),
59374
+ secretRefs: SecretRefsList
59375
+ }), {
59376
+ kind: "mutation",
59377
+ auth: "admin"
59378
+ }), method(object({
59379
+ ...KindShape,
59380
+ ids: array(RecordIdSchema).min(1).max(RECORD_BATCH_MAX)
59381
+ }), object({
59382
+ deleted: number().int(),
59383
+ secretRefs: SecretRefsList
59384
+ }), {
59385
+ kind: "mutation",
59386
+ auth: "admin"
59387
+ }), method(RecordQueryInputSchema, RecordQueryResultSchema, { auth: "admin" }), method(object({
59388
+ ...KindShape,
59389
+ ...TimeWindowShape,
59390
+ where: RecordWhereSchema.optional()
59391
+ }), object({ count: number().int() }), { auth: "admin" }), method(object({
59392
+ ...KindShape,
59393
+ deviceId: number().int().optional(),
59394
+ from: number(),
59395
+ to: number(),
59396
+ bucketMs: number().int().positive()
59397
+ }), object({ buckets: array(object({
59398
+ bucketStart: number(),
59399
+ count: number().int()
59400
+ })) }), { auth: "admin" }), method(object({
59401
+ ...KindShape,
59402
+ op: _enum([
59403
+ "sum",
59404
+ "min",
59405
+ "max",
59406
+ "count"
59407
+ ]),
59408
+ field: RecordFieldPathSchema.optional(),
59409
+ groupBy: RecordFieldPathSchema.optional(),
59410
+ where: RecordWhereSchema.optional()
59411
+ }), object({ rows: array(object({
59412
+ group: union([
59413
+ string(),
59414
+ number(),
59415
+ _null()
59416
+ ]),
59417
+ value: number().nullable()
59418
+ })) }), { auth: "admin" }), method(object({
59419
+ ...KindShape,
59420
+ deviceId: number().int().optional(),
59421
+ atBefore: number().optional(),
59422
+ where: RecordWhereSchema.optional()
59423
+ }), object({
59424
+ deleted: number().int(),
59425
+ secretRefs: SecretRefsList
59426
+ }), {
59427
+ kind: "mutation",
59428
+ auth: "admin"
59429
+ }), method(object({ ops: array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), object({
59430
+ results: array(object({
59431
+ rev: number().int().nullable(),
59432
+ deleted: boolean()
59433
+ })),
59434
+ releasedRefs: SecretRefsList,
59435
+ secretRefs: SecretRefsList
59436
+ }), {
59437
+ kind: "mutation",
59438
+ auth: "admin"
59439
+ }), method(object({
59440
+ deviceId: number().int(),
59441
+ kinds: array(RecordKindNameSchema).optional()
59442
+ }), object({
59443
+ deleted: record(string(), number().int()),
59444
+ secretRefs: SecretRefsList
59445
+ }), {
59446
+ kind: "mutation",
59447
+ auth: "admin"
59448
+ }), method(object(KindShape), object({ id: number().int() }), {
59449
+ kind: "mutation",
59450
+ auth: "admin"
59451
+ });
59452
+ /**
59453
+ * The wire shapes of the migration API, version 1 (planning#447).
59454
+ *
59455
+ * A migration is code that outlives the server it was written against: an addon at
59456
+ * version 1.4 that is brought to 1.9 in one jump still runs its 1.4 catalogue, against
59457
+ * the 1.9 kernel. The only thing that code may call is {@link MigrationApiV1}; this file
59458
+ * is the contract of every method of it, one Zod pair per method.
59459
+ *
59460
+ * APPEND-ONLY. A released method is never removed and never changes meaning: an input
59461
+ * field is never removed or made required, an enum never narrows, an output field is
59462
+ * never removed. A change that cannot be expressed that way is `migration-api.v2`, next
59463
+ * to this file. `scripts/check-migration-api-append-only.ts` holds the line against
59464
+ * `scripts/migration-api-contract.json`, and every `behaviours` id below must have an
59465
+ * `it('<id>'` in `migration-api.contract.spec.ts`.
59466
+ */
59467
+ var Rows = record(string(), unknown());
59468
+ var IntegrationId = object({ integrationId: string().min(1) });
59469
+ var RecordId = object({ id: string().min(1) });
59470
+ var RecordRowSchema = object({
59471
+ id: string(),
59472
+ deviceId: number().int().nullable(),
59473
+ at: number().nullable(),
59474
+ expiresAt: number().nullable(),
59475
+ rev: number().int(),
59476
+ updatedAt: number(),
59477
+ data: Rows
59478
+ });
59479
+ var RecordPutShape = {
59480
+ id: string().min(1),
59481
+ deviceId: number().int().optional(),
59482
+ at: number().int().optional(),
59483
+ expiresAt: number().int().optional(),
59484
+ data: Rows
59485
+ };
59486
+ var MigrationIntegrationSchema = object({
59487
+ id: string(),
59488
+ addonId: string(),
59489
+ name: string(),
59490
+ info: Rows,
59491
+ originStableId: string().optional()
59492
+ });
59493
+ var MigrationDeviceSchema = object({
59494
+ id: number().int(),
59495
+ integrationId: string().nullable().optional(),
59496
+ /** The owning device; null or absent for a root. */
59497
+ parentDeviceId: number().int().nullable().optional(),
59498
+ type: string().optional(),
59499
+ name: string().optional(),
59500
+ stableId: string().optional()
59501
+ });
59502
+ /** What the engine says about the migration API it serves: lets an addon notice an older server. */
59503
+ var MigrationApiInfoSchema = object({
59504
+ version: number().int(),
59505
+ methods: array(string())
59506
+ });
59507
+ object({
59508
+ message: string(),
59509
+ meta: Rows.optional(),
59510
+ /** Grouping tags of the line; a line about a device carries `{ deviceId }`. */
59511
+ tags: object({ deviceId: number().int().optional() }).optional()
59512
+ });
59513
+ object({
59514
+ owner: string().min(1),
59515
+ metas: array(MigrationMetaSchema)
59516
+ }), object({
59517
+ bootId: string(),
59518
+ snapshot: _enum([
59519
+ "none",
59520
+ "written",
59521
+ "refused"
59522
+ ]),
59523
+ steps: array(MigrationOwnerStepSchema),
59524
+ /** The migration API the engine serves; absent from a server that predates it. */
59525
+ migrationApi: MigrationApiInfoSchema.optional()
59526
+ }), object({ id: string().min(1) }), object({
59527
+ proceed: boolean(),
59528
+ state: union([literal("pending"), MigrationStatusSchema]),
59529
+ reason: string().nullable()
59530
+ }), object({
59531
+ id: string().min(1),
59532
+ result: MigrationOwnerResultSchema
59533
+ }), object({
59534
+ status: MigrationStatusSchema,
59535
+ error: string().nullable(),
59536
+ rowsChanged: number().int().nonnegative()
59537
+ }), object({
59538
+ rows: number().int().nonnegative(),
59539
+ secrets: number().int().nonnegative()
59540
+ }), IntegrationId.extend({ patch: Rows }), object({ written: boolean() }), IntegrationId.extend({ keys: array(string().min(1)) }), object({
59541
+ present: boolean(),
59542
+ removed: Rows
59543
+ }), RecordRowSchema.nullable(), RecordRowSchema.nullable(), object({
59544
+ ...RecordPutShape,
59545
+ ifRev: number().int().optional()
59546
+ }), object({ rev: number().int() }), object({ records: array(object(RecordPutShape)) }), object({ count: number().int().nonnegative() }), RecordId.extend({
59547
+ partial: Rows,
59548
+ ifRev: number().int().optional()
59549
+ }), object({ rev: number().int() }), object({ deleted: boolean() }), object({
59550
+ deviceId: number().int().optional(),
59551
+ atFrom: number().optional(),
59552
+ atTo: number().optional(),
59553
+ where: RecordWhereSchema.optional(),
59554
+ limit: number().int().min(1).optional(),
59555
+ cursor: string().min(1).optional(),
59556
+ resolveSecrets: boolean().optional()
59557
+ }), object({
59558
+ records: array(RecordRowSchema),
59559
+ nextCursor: string().nullable()
59560
+ }), object({
59561
+ deviceId: number().int().optional(),
59562
+ atBefore: number().optional(),
59563
+ where: RecordWhereSchema.optional()
59564
+ }), object({ count: number().int().nonnegative() }), object({}), object({ store: Rows }), object({ patch: Rows }), object({}), object({ keys: array(string().min(1)) }), object({ removed: array(string()) }), object({ refs: array(string()) }), object({ values: record(string(), string().nullable()) }), object({
59565
+ ref: string().min(1),
59566
+ value: string()
59567
+ }), object({}), object({ refs: array(string()) }), object({ deleted: number().int().nonnegative() }), object({}), object({ integrations: array(MigrationIntegrationSchema) }), object({ id: string().min(1) }), MigrationIntegrationSchema.nullable(), object({
59568
+ addonId: string().min(1),
59569
+ integrationId: string().min(1).optional()
59570
+ }), object({ devices: array(MigrationDeviceSchema) }), object({ deviceId: number().int() }), object({
59571
+ id: number().int(),
59572
+ integrationId: string().nullable(),
59573
+ /** Whether the device carries any stored config; its content is not offered. */
59574
+ hasConfig: boolean()
59575
+ }).nullable(), object({
59576
+ deviceId: number().int(),
59577
+ integrationId: string().min(1)
59578
+ }), object({}), object({}), object({ nodeId: string() }), object({}), object({});
59329
59579
  method(object({}), object({ entries: array(MigrationLedgerEntrySchema) }), { auth: "admin" }), method(object({ owner: string().optional() }), object({ pending: array(MigrationPendingEntrySchema) }), { auth: "admin" }), method(object({ id: string().min(1) }), MigrationDryRunResultSchema, { auth: "admin" }), method(object({
59330
59580
  id: string().min(1),
59331
59581
  error: string().min(1)
@@ -59355,7 +59605,9 @@ method(object({}), object({ entries: array(MigrationLedgerEntrySchema) }), { aut
59355
59605
  "written",
59356
59606
  "refused"
59357
59607
  ]),
59358
- steps: array(MigrationOwnerStepSchema)
59608
+ steps: array(MigrationOwnerStepSchema),
59609
+ /** The migration API this engine serves (additive: a server that predates it omits it). */
59610
+ migrationApi: MigrationApiInfoSchema.optional()
59359
59611
  }), {
59360
59612
  kind: "mutation",
59361
59613
  auth: "admin"
@@ -62022,7 +62274,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
62022
62274
  }), method(RelocateMediaInputSchema, object({ jobId: string() }), {
62023
62275
  kind: "mutation",
62024
62276
  auth: "admin"
62025
- }), method(object({}), UnstampedEventMediaCountSchema, { auth: "admin" }), method(RelocatableMediaCountInputSchema, RelocatableMediaCountSchema, {
62277
+ }), method(object({}), UnstampedEventMediaCountSchema, { auth: "admin" }), method(MediaLocationCensusInputSchema, MediaLocationCensusSchema, {
62278
+ kind: "query",
62279
+ auth: "admin"
62280
+ }), method(RelocatableMediaCountInputSchema, RelocatableMediaCountSchema, {
62026
62281
  kind: "query",
62027
62282
  auth: "admin"
62028
62283
  }), method(object({}), array(RelocateJobSchema).readonly(), {
@@ -64677,7 +64932,7 @@ var BrokerStatusSchema$1 = _enum([
64677
64932
  "unreachable",
64678
64933
  "tls-error"
64679
64934
  ]);
64680
- var BrokerInfoSchema$1 = object({
64935
+ var BrokerInfoSchema = object({
64681
64936
  id: string(),
64682
64937
  name: string(),
64683
64938
  url: string(),
@@ -64740,7 +64995,7 @@ var StatusSchema = object({
64740
64995
  brokerCount: number(),
64741
64996
  embeddedRunning: boolean()
64742
64997
  });
64743
- method(_void(), array(BrokerInfoSchema$1)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
64998
+ method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
64744
64999
  kind: "mutation",
64745
65000
  auth: "admin"
64746
65001
  }), method(IdInputSchema, _void(), {
@@ -71922,253 +72177,6 @@ DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, DeviceType.Gateway, met
71922
72177
  auth: "admin"
71923
72178
  });
71924
72179
  /**
71925
- * records - an addon's own facts and documents (D881): ledgers, audit rows,
71926
- * config documents, mirrors. The third storage API next to `ctx.settings`
71927
- * (operator intent, D870) and device-history (numbers over time, D850).
71928
- *
71929
- * Who the OWNER is: `callerAddonId`, stamped by the transport on a call that
71930
- * crossed a process and stated by a hub in-process caller (`ctx.records` does
71931
- * that with the addon id closed over). It is deliberately NOT in any input
71932
- * schema, so a session can never supply it, and a call with no stamp is refused
71933
- * `records/no-caller`. A kind is readable and writable only by its owner; other
71934
- * addons go through the owner's capability.
71935
- *
71936
- * Every read is three-way: a row, `null`, or the call THROWS. A failed read is
71937
- * never `[]`. Secret fields are never on the wire: a read shows the
71938
- * redaction token, `secretRefs` hands the owner's `ctx.secrets` the refs it
71939
- * resolves itself, and a write may carry only a keychain marker bound to the
71940
- * row's own ref.
71941
- *
71942
- * Internal: addons reach it through `ctx.records`, never directly.
71943
- */
71944
- var RecordIdSchema = string().min(1).max(256);
71945
- /** A JSON object body. Size is the engine's check (`maxDataBytes`), not a schema's. */
71946
- var RecordBodySchema = record(string(), unknown());
71947
- var RecordInputSchema = object({
71948
- id: RecordIdSchema,
71949
- /** The device this row belongs to (D865 removal, per-device reads). */
71950
- deviceId: number().int().optional(),
71951
- /** The domain clock, ms: observed / created / opened. */
71952
- at: number().int().optional(),
71953
- /** Producer-set expiry, ms. Refused on a kind whose retention is an engine TTL. */
71954
- expiresAt: number().int().optional(),
71955
- data: RecordBodySchema
71956
- });
71957
- var RecordViewSchema = object({
71958
- id: string(),
71959
- deviceId: number().int().nullable(),
71960
- at: number().nullable(),
71961
- expiresAt: number().nullable(),
71962
- rev: number().int(),
71963
- updatedAt: number(),
71964
- data: RecordBodySchema
71965
- });
71966
- /** Declared index fields only. Anything else does not compile, by design. */
71967
- var RecordWhereSchema = record(RecordFieldPathSchema, union([
71968
- string(),
71969
- number(),
71970
- boolean(),
71971
- object({ in: array(union([
71972
- string(),
71973
- number(),
71974
- boolean()
71975
- ])).min(1).max(RECORD_BATCH_MAX) }),
71976
- object({
71977
- gt: union([string(), number()]).optional(),
71978
- gte: union([string(), number()]).optional(),
71979
- lt: union([string(), number()]).optional(),
71980
- lte: union([string(), number()]).optional()
71981
- }).refine((r) => Object.keys(r).length > 0, { message: "name at least one bound" })
71982
- ]));
71983
- var KindShape = { kind: RecordKindNameSchema };
71984
- var TimeWindowShape = {
71985
- deviceId: number().int().optional(),
71986
- atFrom: number().optional(),
71987
- atTo: number().optional()
71988
- };
71989
- var RecordQueryInputSchema = object({
71990
- ...KindShape,
71991
- ...TimeWindowShape,
71992
- where: RecordWhereSchema.optional(),
71993
- /** Without `where`: `at` (default for a kind with a clock) or `id`. With `where` the order is the index's. */
71994
- order: _enum(["at", "id"]).optional(),
71995
- desc: boolean().optional(),
71996
- limit: number().int().min(1).max(RECORD_QUERY_MAX).default(100),
71997
- /** Opaque keyset cursor from a previous answer. There is no offset. */
71998
- cursor: string().min(1).optional()
71999
- });
72000
- var RecordQueryResultSchema = object({
72001
- records: array(RecordViewSchema),
72002
- nextCursor: string().nullable()
72003
- });
72004
- var RecordKindStateSchema = _enum([
72005
- "created",
72006
- "unchanged",
72007
- "updated"
72008
- ]);
72009
- var DeclareKindResultSchema = object({
72010
- kindId: number().int(),
72011
- state: RecordKindStateSchema,
72012
- createdIndexes: array(string())
72013
- });
72014
- /** Keychain refs a write released (the old marker is gone from the row): the owner deletes the values. */
72015
- var SecretRefsList = array(string());
72016
- /**
72017
- * One op of a `transact`: the single-row writes, each on a kind of the caller.
72018
- * All ops of one call share ONE database file and ONE `transactFamily`.
72019
- */
72020
- var RecordTransactOpSchema = discriminatedUnion("op", [
72021
- object({
72022
- op: literal("put"),
72023
- kind: RecordKindNameSchema,
72024
- record: RecordInputSchema,
72025
- ifRev: number().int().min(0).optional()
72026
- }),
72027
- object({
72028
- op: literal("patch"),
72029
- kind: RecordKindNameSchema,
72030
- id: RecordIdSchema,
72031
- data: RecordBodySchema,
72032
- at: number().int().nullable().optional(),
72033
- expiresAt: number().int().nullable().optional(),
72034
- ifRev: number().int().min(1).optional()
72035
- }),
72036
- object({
72037
- op: literal("delete"),
72038
- kind: RecordKindNameSchema,
72039
- id: RecordIdSchema
72040
- })
72041
- ]);
72042
- var RecordSecretRefsSchema = record(string(), record(string(), string()));
72043
- method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema) }), object({ kinds: record(string(), DeclareKindResultSchema) }), {
72044
- kind: "mutation",
72045
- auth: "admin"
72046
- }), method(object({
72047
- ...KindShape,
72048
- id: RecordIdSchema
72049
- }), RecordViewSchema.nullable(), { auth: "admin" }), method(object({
72050
- ...KindShape,
72051
- ids: array(RecordIdSchema).min(1).max(RECORD_BATCH_MAX)
72052
- }), array(RecordViewSchema), { auth: "admin" }), method(object({
72053
- ...KindShape,
72054
- ids: array(RecordIdSchema).min(1).max(RECORD_BATCH_MAX)
72055
- }), RecordSecretRefsSchema, { auth: "admin" }), method(object({
72056
- ...KindShape,
72057
- record: RecordInputSchema,
72058
- /** Compare-and-set. `0` means "the row must not exist". */
72059
- ifRev: number().int().min(0).optional()
72060
- }), object({
72061
- rev: number().int(),
72062
- releasedRefs: SecretRefsList
72063
- }), {
72064
- kind: "mutation",
72065
- auth: "admin"
72066
- }), method(object({
72067
- ...KindShape,
72068
- records: array(RecordInputSchema).min(1).max(RECORD_BATCH_MAX)
72069
- }), object({
72070
- count: number().int(),
72071
- releasedRefs: SecretRefsList
72072
- }), {
72073
- kind: "mutation",
72074
- auth: "admin"
72075
- }), method(object({
72076
- ...KindShape,
72077
- id: RecordIdSchema,
72078
- data: RecordBodySchema,
72079
- at: number().int().nullable().optional(),
72080
- expiresAt: number().int().nullable().optional(),
72081
- ifRev: number().int().min(1).optional()
72082
- }), object({
72083
- rev: number().int(),
72084
- releasedRefs: SecretRefsList
72085
- }), {
72086
- kind: "mutation",
72087
- auth: "admin"
72088
- }), method(object({
72089
- ...KindShape,
72090
- id: RecordIdSchema
72091
- }), object({
72092
- deleted: boolean(),
72093
- secretRefs: SecretRefsList
72094
- }), {
72095
- kind: "mutation",
72096
- auth: "admin"
72097
- }), method(object({
72098
- ...KindShape,
72099
- ids: array(RecordIdSchema).min(1).max(RECORD_BATCH_MAX)
72100
- }), object({
72101
- deleted: number().int(),
72102
- secretRefs: SecretRefsList
72103
- }), {
72104
- kind: "mutation",
72105
- auth: "admin"
72106
- }), method(RecordQueryInputSchema, RecordQueryResultSchema, { auth: "admin" }), method(object({
72107
- ...KindShape,
72108
- ...TimeWindowShape,
72109
- where: RecordWhereSchema.optional()
72110
- }), object({ count: number().int() }), { auth: "admin" }), method(object({
72111
- ...KindShape,
72112
- deviceId: number().int().optional(),
72113
- from: number(),
72114
- to: number(),
72115
- bucketMs: number().int().positive()
72116
- }), object({ buckets: array(object({
72117
- bucketStart: number(),
72118
- count: number().int()
72119
- })) }), { auth: "admin" }), method(object({
72120
- ...KindShape,
72121
- op: _enum([
72122
- "sum",
72123
- "min",
72124
- "max",
72125
- "count"
72126
- ]),
72127
- field: RecordFieldPathSchema.optional(),
72128
- groupBy: RecordFieldPathSchema.optional(),
72129
- where: RecordWhereSchema.optional()
72130
- }), object({ rows: array(object({
72131
- group: union([
72132
- string(),
72133
- number(),
72134
- _null()
72135
- ]),
72136
- value: number().nullable()
72137
- })) }), { auth: "admin" }), method(object({
72138
- ...KindShape,
72139
- deviceId: number().int().optional(),
72140
- atBefore: number().optional(),
72141
- where: RecordWhereSchema.optional()
72142
- }), object({
72143
- deleted: number().int(),
72144
- secretRefs: SecretRefsList
72145
- }), {
72146
- kind: "mutation",
72147
- auth: "admin"
72148
- }), method(object({ ops: array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), object({
72149
- results: array(object({
72150
- rev: number().int().nullable(),
72151
- deleted: boolean()
72152
- })),
72153
- releasedRefs: SecretRefsList,
72154
- secretRefs: SecretRefsList
72155
- }), {
72156
- kind: "mutation",
72157
- auth: "admin"
72158
- }), method(object({
72159
- deviceId: number().int(),
72160
- kinds: array(RecordKindNameSchema).optional()
72161
- }), object({
72162
- deleted: record(string(), number().int()),
72163
- secretRefs: SecretRefsList
72164
- }), {
72165
- kind: "mutation",
72166
- auth: "admin"
72167
- }), method(object(KindShape), object({ id: number().int() }), {
72168
- kind: "mutation",
72169
- auth: "admin"
72170
- });
72171
- /**
72172
72180
  * record-entries - the ONE admin surface for every list of user-created entries
72173
72181
  * (D881): notification targets, brokers, LLM profiles, anything an addon
72174
72182
  * declares as an ENTRY kind (`entry: { title }` in `defineRecordKinds`).
@@ -81935,7 +81943,7 @@ var BaseDeviceProvider = class extends BaseAddon {
81935
81943
  * `deviceClasses` map (first registered type). `null` when manual creation is
81936
81944
  * unsupported. Lets the Add-Device dialog pick the right type per provider.
81937
81945
  */
81938
- async getManualCreationType() {
81946
+ async getManualCreationType(_input) {
81939
81947
  if (!await this.supportsManualCreation()) return { deviceType: null };
81940
81948
  return { deviceType: Object.values(DeviceType).find((t) => this.deviceClasses[t] !== void 0) ?? null };
81941
81949
  }
@@ -81946,7 +81954,7 @@ var BaseDeviceProvider = class extends BaseAddon {
81946
81954
  return true;
81947
81955
  }
81948
81956
  async getChildCreationSchema(input) {
81949
- return this.onGetCreationSchema(input.type);
81957
+ return this.onGetCreationSchema(input.type, { integrationId: input.integrationId });
81950
81958
  }
81951
81959
  /**
81952
81960
  * Default kernel-orchestrated `createDevice` implementation. The
@@ -83367,20 +83375,6 @@ Object.freeze({
83367
83375
  access: "create",
83368
83376
  role: "viewer"
83369
83377
  },
83370
- "broker.add": {
83371
- capName: "broker",
83372
- capScope: "system",
83373
- addonId: null,
83374
- access: "create",
83375
- role: "admin"
83376
- },
83377
- "broker.get": {
83378
- capName: "broker",
83379
- capScope: "system",
83380
- addonId: null,
83381
- access: "view",
83382
- role: "admin"
83383
- },
83384
83378
  "broker.getBrokerConfig": {
83385
83379
  capName: "broker",
83386
83380
  capScope: "system",
@@ -83388,20 +83382,6 @@ Object.freeze({
83388
83382
  access: "view",
83389
83383
  role: "admin"
83390
83384
  },
83391
- "broker.getSettings": {
83392
- capName: "broker",
83393
- capScope: "system",
83394
- addonId: null,
83395
- access: "view",
83396
- role: "admin"
83397
- },
83398
- "broker.getSettingsSchema": {
83399
- capName: "broker",
83400
- capScope: "system",
83401
- addonId: null,
83402
- access: "view",
83403
- role: "admin"
83404
- },
83405
83385
  "broker.getState": {
83406
83386
  capName: "broker",
83407
83387
  capScope: "system",
@@ -83416,20 +83396,6 @@ Object.freeze({
83416
83396
  access: "view",
83417
83397
  role: "admin"
83418
83398
  },
83419
- "broker.list": {
83420
- capName: "broker",
83421
- capScope: "system",
83422
- addonId: null,
83423
- access: "view",
83424
- role: "admin"
83425
- },
83426
- "broker.listProviders": {
83427
- capName: "broker",
83428
- capScope: "system",
83429
- addonId: null,
83430
- access: "view",
83431
- role: "admin"
83432
- },
83433
83399
  "broker.publish": {
83434
83400
  capName: "broker",
83435
83401
  capScope: "system",
@@ -83437,20 +83403,6 @@ Object.freeze({
83437
83403
  access: "create",
83438
83404
  role: "admin"
83439
83405
  },
83440
- "broker.remove": {
83441
- capName: "broker",
83442
- capScope: "system",
83443
- addonId: null,
83444
- access: "delete",
83445
- role: "admin"
83446
- },
83447
- "broker.setSettings": {
83448
- capName: "broker",
83449
- capScope: "system",
83450
- addonId: null,
83451
- access: "create",
83452
- role: "admin"
83453
- },
83454
83406
  "broker.subscribe": {
83455
83407
  capName: "broker",
83456
83408
  capScope: "system",
@@ -83458,20 +83410,6 @@ Object.freeze({
83458
83410
  access: "create",
83459
83411
  role: "admin"
83460
83412
  },
83461
- "broker.testConnection": {
83462
- capName: "broker",
83463
- capScope: "system",
83464
- addonId: null,
83465
- access: "create",
83466
- role: "admin"
83467
- },
83468
- "broker.testSettings": {
83469
- capName: "broker",
83470
- capScope: "system",
83471
- addonId: null,
83472
- access: "create",
83473
- role: "admin"
83474
- },
83475
83413
  "broker.unsubscribe": {
83476
83414
  capName: "broker",
83477
83415
  capScope: "system",
@@ -88435,6 +88373,13 @@ Object.freeze({
88435
88373
  access: "view",
88436
88374
  role: "viewer"
88437
88375
  },
88376
+ "pipelineAnalytics.getMediaLocationCensus": {
88377
+ capName: "pipeline-analytics",
88378
+ capScope: "device",
88379
+ addonId: null,
88380
+ access: "view",
88381
+ role: "admin"
88382
+ },
88438
88383
  "pipelineAnalytics.getMediaReclaimStatus": {
88439
88384
  capName: "pipeline-analytics",
88440
88385
  capScope: "device",
@@ -98217,6 +98162,74 @@ object({
98217
98162
  delay: number().nonnegative().optional(),
98218
98163
  commands: record(string(), unknown())
98219
98164
  });
98165
+ entryBody({ brokerId: string() });
98166
+ function secretsOverMigrationApi(api) {
98167
+ return {
98168
+ resolve: async (refs) => {
98169
+ const { values } = await api.secrets.resolve({ refs: [...refs] });
98170
+ const out = {};
98171
+ for (const ref of refs) {
98172
+ const value = values[ref];
98173
+ out[ref] = value === null || value === void 0 ? { kind: "missing" } : {
98174
+ kind: "value",
98175
+ value,
98176
+ version: 0
98177
+ };
98178
+ }
98179
+ return out;
98180
+ },
98181
+ delete: async (refs) => (await api.secrets.delete({ refs: [...refs] })).deleted
98182
+ };
98183
+ }
98184
+ /** `ctx.records` as the migration API offers it: bind a kind, read and write by id. */
98185
+ function recordsOverMigrationApi(api) {
98186
+ return { kind: (definition) => {
98187
+ const handle = api.records.kind(definition);
98188
+ return {
98189
+ get: (id) => handle.get({ id }),
98190
+ getResolved: (id) => handle.getResolved({ id }),
98191
+ put: (input, opts) => handle.put({
98192
+ ...input,
98193
+ ...opts?.ifRev === void 0 ? {} : { ifRev: opts.ifRev }
98194
+ }),
98195
+ delete: (id) => handle.delete({ id })
98196
+ };
98197
+ } };
98198
+ }
98199
+ function integrationRowsApiOver(api) {
98200
+ return {
98201
+ list: async () => (await api.integrations.list({})).integrations,
98202
+ readLegacyIntegrationRows: (input) => api.legacyRows.read(input),
98203
+ clearLegacyIntegrationRows: (input) => api.legacyRows.clear(input)
98204
+ };
98205
+ }
98206
+ /**
98207
+ * One serial lane per migration API: a log line is delivered after the line before it, so the
98208
+ * order the steps wrote them in is the order the hub reads them in. A delivery that fails
98209
+ * is reported once through the same door; if that fails too nothing is left to tell, and the
98210
+ * line is dropped rather than thrown into a migration step or left as an unhandled rejection.
98211
+ */
98212
+ var lanes = /* @__PURE__ */ new WeakMap();
98213
+ function deliver(api, send) {
98214
+ const next = (lanes.get(api) ?? Promise.resolve()).then(send).then(() => void 0).catch(async (error) => {
98215
+ const reason = error instanceof Error ? error.message : String(error);
98216
+ await api.log.warn({ message: `a migration log line could not be delivered: ${reason}` }).catch(() => void 0);
98217
+ });
98218
+ lanes.set(api, next);
98219
+ return next;
98220
+ }
98221
+ function warnOver(api) {
98222
+ return (message) => deliver(api, () => api.log.warn({ message }));
98223
+ }
98224
+ /** What the rows-to-records move needs, over the migration API. */
98225
+ function rowsDepsOver(api) {
98226
+ return {
98227
+ api: integrationRowsApiOver(api),
98228
+ records: recordsOverMigrationApi(api),
98229
+ secrets: secretsOverMigrationApi(api),
98230
+ warn: warnOver(api)
98231
+ };
98232
+ }
98220
98233
  //#endregion
98221
98234
  //#region src/shared/bosch-instances.ts
98222
98235
  /**
@@ -98446,18 +98459,6 @@ Object.defineProperty(exports, "customAction", {
98446
98459
  return customAction;
98447
98460
  }
98448
98461
  });
98449
- Object.defineProperty(exports, "defaultIntegrationApiOver", {
98450
- enumerable: true,
98451
- get: function() {
98452
- return defaultIntegrationApiOver;
98453
- }
98454
- });
98455
- Object.defineProperty(exports, "defineAddonMigrations", {
98456
- enumerable: true,
98457
- get: function() {
98458
- return defineAddonMigrations;
98459
- }
98460
- });
98461
98462
  Object.defineProperty(exports, "defineCustomActions", {
98462
98463
  enumerable: true,
98463
98464
  get: function() {
@@ -98584,6 +98585,12 @@ Object.defineProperty(exports, "record", {
98584
98585
  return record;
98585
98586
  }
98586
98587
  });
98588
+ Object.defineProperty(exports, "rowsDepsOver", {
98589
+ enumerable: true,
98590
+ get: function() {
98591
+ return rowsDepsOver;
98592
+ }
98593
+ });
98587
98594
  Object.defineProperty(exports, "runningFromDishwasherOperation", {
98588
98595
  enumerable: true,
98589
98596
  get: function() {