@camstack/addon-post-analysis 1.2.667 → 1.2.669
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/{clip-model-registry-DpzRS8q3.mjs → clip-model-registry-BPvijtCz.mjs} +353 -74
- package/dist/{clip-model-registry-D7cqhFK3.js → clip-model-registry-CbzBwacH.js} +353 -74
- package/dist/embedding-encoder/index.js +6 -2
- package/dist/embedding-encoder/index.mjs +6 -2
- package/dist/pipeline-analytics/_stub.js +2 -2
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DmTIEp0m.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-C4QK9e1e.mjs} +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-9HsFj_VL.mjs +26 -0
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-anSYIl3S.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-ODebWXu_.mjs → hostInit-CPLvPO3K.mjs} +9 -9
- package/dist/pipeline-analytics/index.js +12 -3
- package/dist/pipeline-analytics/index.mjs +12 -3
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DAAkZRnK.mjs +0 -26
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-znrgUrN1.mjs +0 -26
|
@@ -6069,7 +6069,7 @@ var ZodIssueCode = {
|
|
|
6069
6069
|
var ZodFirstPartyTypeKind;
|
|
6070
6070
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6071
6071
|
//#endregion
|
|
6072
|
-
//#region ../types/dist/sleep-
|
|
6072
|
+
//#region ../types/dist/sleep-DEZaLbiu.mjs
|
|
6073
6073
|
/**
|
|
6074
6074
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6075
6075
|
* window to float samples (D455).
|
|
@@ -6662,7 +6662,7 @@ var NOT_RUN = {
|
|
|
6662
6662
|
* throws: an unreachable or refusing engine is logged and reported `declared: false`,
|
|
6663
6663
|
* because the hub (and this addon's boot) must not hang on a migration.
|
|
6664
6664
|
*/
|
|
6665
|
-
async function runAddonMigrations(host, migrations, logger) {
|
|
6665
|
+
async function runAddonMigrations(host, migrations, logger, options = {}) {
|
|
6666
6666
|
const first = migrations[0];
|
|
6667
6667
|
if (first === void 0) return NOT_RUN;
|
|
6668
6668
|
const owner = first.meta.owner;
|
|
@@ -6691,7 +6691,9 @@ async function runAddonMigrations(host, migrations, logger) {
|
|
|
6691
6691
|
else if (status === "blocked") blocked.push(id);
|
|
6692
6692
|
else skipped.push(id);
|
|
6693
6693
|
};
|
|
6694
|
+
const selected = options.only === void 0 ? null : new Set(options.only);
|
|
6694
6695
|
for (const step of declaration.steps) {
|
|
6696
|
+
if (selected !== null && !selected.has(step.id)) continue;
|
|
6695
6697
|
const bound = byId.get(step.id);
|
|
6696
6698
|
if (bound === void 0 || step.action === "skip") {
|
|
6697
6699
|
skipped.push(step.id);
|
|
@@ -6869,6 +6871,12 @@ function projectStore(store, perNodeKeys, nodeId) {
|
|
|
6869
6871
|
}
|
|
6870
6872
|
return out;
|
|
6871
6873
|
}
|
|
6874
|
+
/** Every scope, in the order the guard and the docs list them. */
|
|
6875
|
+
var SCOPED_SETTINGS_SCOPES = [
|
|
6876
|
+
"cluster",
|
|
6877
|
+
"device-defaults",
|
|
6878
|
+
"node"
|
|
6879
|
+
];
|
|
6872
6880
|
var GLOBAL_SCOPE = { kind: "global" };
|
|
6873
6881
|
/** The scope every addon-wide (not per-node, not per-device) setting lives in. */
|
|
6874
6882
|
function globalSecretScope() {
|
|
@@ -7718,6 +7726,13 @@ var BaseAddon = class {
|
|
|
7718
7726
|
*/
|
|
7719
7727
|
secretStatePaths = [];
|
|
7720
7728
|
_addonSecretTree = null;
|
|
7729
|
+
/**
|
|
7730
|
+
* D986 M4: the scoped schemas this addon declared, resolved once per capability
|
|
7731
|
+
* (`loadScopedSchemas`) so the sync readers (`perNodeKeys`, the secret tree, the restart check)
|
|
7732
|
+
* see them. Empty until loaded: the readers then fall back to {@link globalSettingsSchema}.
|
|
7733
|
+
*/
|
|
7734
|
+
_scopedByCap = /* @__PURE__ */ new Map();
|
|
7735
|
+
_nodeKeysByCap = /* @__PURE__ */ new Map();
|
|
7721
7736
|
_deviceSecretTree = null;
|
|
7722
7737
|
/** Refs the last resolved config pointed at — a change to one re-resolves. */
|
|
7723
7738
|
_configSecretRefs = /* @__PURE__ */ new Set();
|
|
@@ -7787,6 +7802,7 @@ var BaseAddon = class {
|
|
|
7787
7802
|
this._ctx = context;
|
|
7788
7803
|
this._secretSettings = null;
|
|
7789
7804
|
}
|
|
7805
|
+
await this.loadScopedSchemas();
|
|
7790
7806
|
await this.resolveConfig();
|
|
7791
7807
|
if (secrets !== void 0) this._secretChangeUnsub = secrets.onChange((ref) => {
|
|
7792
7808
|
if (this._configSecretRefs.has(ref)) this.scheduleSecretReresolve(SECRET_CHANGE_DEBOUNCE_MS);
|
|
@@ -7796,6 +7812,7 @@ var BaseAddon = class {
|
|
|
7796
7812
|
const normalized = normalizeAddonInitResult(result);
|
|
7797
7813
|
const providers = normalized && "providers" in normalized && normalized.providers ? normalized.providers : [];
|
|
7798
7814
|
this._registeredCapNames = providers.map((p) => p.capability.name);
|
|
7815
|
+
await this.loadScopedSchemas();
|
|
7799
7816
|
return normalized;
|
|
7800
7817
|
}
|
|
7801
7818
|
/**
|
|
@@ -7809,14 +7826,18 @@ var BaseAddon = class {
|
|
|
7809
7826
|
* nothing; the boot continues. A migration that FAILED (or was blocked by one)
|
|
7810
7827
|
* and declares `onFailure: 'block-owner'` makes this throw, so the addon does not
|
|
7811
7828
|
* serve data whose shape it cannot trust; `tolerate` migrations never do.
|
|
7829
|
+
*
|
|
7830
|
+
* ALWAYS pass the whole catalogue; a phase that must run only some of it passes
|
|
7831
|
+
* `{ only: [ids] }` — never a filtered catalogue (the engine would judge the
|
|
7832
|
+
* omitted applied ids "newer").
|
|
7812
7833
|
*/
|
|
7813
|
-
async runMigrations(migrations) {
|
|
7834
|
+
async runMigrations(migrations, options) {
|
|
7814
7835
|
const api = this.ctx.api.migrations;
|
|
7815
7836
|
const report = await runAddonMigrations({
|
|
7816
7837
|
declareOwner: (input) => api.declareOwner.mutate(input),
|
|
7817
7838
|
startMigration: (input) => api.startMigration.mutate(input),
|
|
7818
7839
|
finishMigration: (input) => api.finishMigration.mutate(input)
|
|
7819
|
-
}, migrations, this.ctx.logger);
|
|
7840
|
+
}, migrations, this.ctx.logger, options);
|
|
7820
7841
|
if (report.blockOwner.length > 0) throw new AddonMigrationsBlockedError(report.blockOwner);
|
|
7821
7842
|
return report;
|
|
7822
7843
|
}
|
|
@@ -7880,6 +7901,16 @@ var BaseAddon = class {
|
|
|
7880
7901
|
schema(schema) {
|
|
7881
7902
|
return schema;
|
|
7882
7903
|
}
|
|
7904
|
+
/**
|
|
7905
|
+
* The capability names whose scoped settings schemas ({@link clusterSettingsSchema},
|
|
7906
|
+
* {@link nodeSettingsSchema}, {@link deviceDefaultsSchema}) this addon declares. Read BEFORE
|
|
7907
|
+
* `onInitialize`, when the providers it registers are not known yet: the first config resolve
|
|
7908
|
+
* must already know which keys are per node. Names the providers register at init are added
|
|
7909
|
+
* once known.
|
|
7910
|
+
*/
|
|
7911
|
+
scopedSettingsCapabilities() {
|
|
7912
|
+
return [];
|
|
7913
|
+
}
|
|
7883
7914
|
/** Override to provide global-level settings UI schema. */
|
|
7884
7915
|
globalSettingsSchema(_cap) {
|
|
7885
7916
|
return null;
|
|
@@ -7923,7 +7954,8 @@ var BaseAddon = class {
|
|
|
7923
7954
|
return [];
|
|
7924
7955
|
}
|
|
7925
7956
|
async getGlobalSettings(overlay, cap, nodeId) {
|
|
7926
|
-
|
|
7957
|
+
await this.loadScopedSchemas(cap);
|
|
7958
|
+
const schema = this.globalSettingsSchema(cap) ?? this.scopedFormSchema(cap);
|
|
7927
7959
|
if (!schema) return { sections: [] };
|
|
7928
7960
|
const projected = await this.readRawProjectedStore(nodeId, cap);
|
|
7929
7961
|
return hydrateSchema(schema, overlay ? await this.overlayKeepingMarkers(projected, overlay) : projected, { inlineSecretsAsViews: true });
|
|
@@ -7958,10 +7990,9 @@ var BaseAddon = class {
|
|
|
7958
7990
|
*
|
|
7959
7991
|
* Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
|
|
7960
7992
|
* needs its connection fields, the default integration the addon's own sections. It is the
|
|
7961
|
-
* SHAPE of the form only — the values live
|
|
7962
|
-
* unchanged (`integrations.setSettings` for an account integration).
|
|
7993
|
+
* SHAPE of the form only — the values live on the instance record.
|
|
7963
7994
|
*/
|
|
7964
|
-
async
|
|
7995
|
+
async integrationFormSchema(_instance) {
|
|
7965
7996
|
return null;
|
|
7966
7997
|
}
|
|
7967
7998
|
/**
|
|
@@ -8007,7 +8038,7 @@ var BaseAddon = class {
|
|
|
8007
8038
|
* per-instance schema when it declares one, else its global schema (what they always showed).
|
|
8008
8039
|
*/
|
|
8009
8040
|
async getIntegrationFormSchema(instance, nodeId) {
|
|
8010
|
-
const scoped = await this.
|
|
8041
|
+
const scoped = await this.integrationFormSchema(instance);
|
|
8011
8042
|
if (scoped === null) return this.getGlobalSettings(void 0, void 0, nodeId);
|
|
8012
8043
|
return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
|
|
8013
8044
|
}
|
|
@@ -8055,6 +8086,7 @@ var BaseAddon = class {
|
|
|
8055
8086
|
* resolved blob back is a no-op for every unchanged secret.
|
|
8056
8087
|
*/
|
|
8057
8088
|
async resolveGlobalStore(nodeId, cap) {
|
|
8089
|
+
await this.loadScopedSchemas(cap);
|
|
8058
8090
|
const raw = await this._ctx?.settings?.readAddonStore() ?? {};
|
|
8059
8091
|
return this.projectForNode(raw, nodeId, cap);
|
|
8060
8092
|
}
|
|
@@ -8065,6 +8097,7 @@ var BaseAddon = class {
|
|
|
8065
8097
|
}
|
|
8066
8098
|
/** The PROJECTED store with its markers — the form hydrate only (D798). */
|
|
8067
8099
|
async readRawProjectedStore(nodeId, cap) {
|
|
8100
|
+
await this.loadScopedSchemas(cap);
|
|
8068
8101
|
const raw = await this.rawSettings()?.readAddonStore() ?? {};
|
|
8069
8102
|
return this.projectForNode(raw, nodeId, cap);
|
|
8070
8103
|
}
|
|
@@ -8167,6 +8200,7 @@ var BaseAddon = class {
|
|
|
8167
8200
|
await this.applyGlobalPatch(patch, nodeId);
|
|
8168
8201
|
}
|
|
8169
8202
|
async applyGlobalPatch(barePatch, nodeId) {
|
|
8203
|
+
await this.loadScopedSchemas();
|
|
8170
8204
|
const keys = this.perNodeKeys();
|
|
8171
8205
|
const localNode = normalizeNodeId(this._ctx?.kernel?.localNodeId);
|
|
8172
8206
|
const target = normalizeNodeId(nodeId ?? this._ctx?.kernel?.localNodeId);
|
|
@@ -8180,7 +8214,8 @@ var BaseAddon = class {
|
|
|
8180
8214
|
await this.resolveConfig();
|
|
8181
8215
|
await this.onConfigChanged();
|
|
8182
8216
|
this.emitLifecycle(EventCategory.AddonUpdated, { level: "global" });
|
|
8183
|
-
|
|
8217
|
+
const legacy = this.globalSettingsSchema();
|
|
8218
|
+
this.maybeAutoRestart(Object.keys(barePatch), [...legacy === null ? [] : [legacy], ...this.loadedScopedSchemas().map((entry) => entry.schema)]);
|
|
8184
8219
|
}
|
|
8185
8220
|
/**
|
|
8186
8221
|
* The set of field keys the global settings schema declares `perNode: true`
|
|
@@ -8188,14 +8223,67 @@ var BaseAddon = class {
|
|
|
8188
8223
|
* declarations). Empty set ⇒ every per-node code path is bypassed and the
|
|
8189
8224
|
* settings API behaves exactly like the legacy node-agnostic one.
|
|
8190
8225
|
*/
|
|
8191
|
-
|
|
8226
|
+
/**
|
|
8227
|
+
* Load the scoped schemas of every capability this addon declares (the override and the
|
|
8228
|
+
* providers registered at init, plus `extraCap`) that is not loaded yet, then drop what was
|
|
8229
|
+
* derived from the previous set. Idempotent.
|
|
8230
|
+
*/
|
|
8231
|
+
async loadScopedSchemas(extraCap) {
|
|
8232
|
+
const caps = new Set([
|
|
8233
|
+
...this.scopedSettingsCapabilities(),
|
|
8234
|
+
...this._registeredCapNames,
|
|
8235
|
+
...extraCap === void 0 ? [] : [extraCap]
|
|
8236
|
+
]);
|
|
8237
|
+
let added = false;
|
|
8238
|
+
for (const cap of caps) {
|
|
8239
|
+
if (this._scopedByCap.has(cap)) continue;
|
|
8240
|
+
const loaded = [];
|
|
8241
|
+
for (const scope of SCOPED_SETTINGS_SCOPES) {
|
|
8242
|
+
const schema = await this.getScopedSettingsSchema(scope, cap);
|
|
8243
|
+
if (schema !== null) loaded.push({
|
|
8244
|
+
scope,
|
|
8245
|
+
schema
|
|
8246
|
+
});
|
|
8247
|
+
}
|
|
8248
|
+
this._scopedByCap.set(cap, loaded);
|
|
8249
|
+
added = true;
|
|
8250
|
+
}
|
|
8251
|
+
if (!added) return;
|
|
8252
|
+
this._nodeKeysByCap = /* @__PURE__ */ new Map();
|
|
8253
|
+
this._addonSecretTree = null;
|
|
8254
|
+
}
|
|
8255
|
+
/**
|
|
8256
|
+
* The form the settings API serves while an addon declares no {@link globalSettingsSchema}: the
|
|
8257
|
+
* sections of its scoped schemas, so dropping the old hook does not blank the form.
|
|
8258
|
+
*/
|
|
8259
|
+
scopedFormSchema(cap) {
|
|
8260
|
+
const byId = /* @__PURE__ */ new Map();
|
|
8261
|
+
for (const entry of this.loadedScopedSchemas(cap)) for (const section of entry.schema.sections) if (!byId.has(section.id)) byId.set(section.id, section);
|
|
8262
|
+
return byId.size === 0 ? null : { sections: [...byId.values()] };
|
|
8263
|
+
}
|
|
8264
|
+
/** Every loaded scoped schema of `cap`, or of every loaded capability. */
|
|
8265
|
+
loadedScopedSchemas(cap) {
|
|
8266
|
+
if (cap !== void 0) return this._scopedByCap.get(cap) ?? [];
|
|
8267
|
+
return [...this._scopedByCap.values()].flat();
|
|
8268
|
+
}
|
|
8269
|
+
/**
|
|
8270
|
+
* The field keys that are stored per node: every field of a {@link nodeSettingsSchema}, plus
|
|
8271
|
+
* the fields the legacy {@link globalSettingsSchema} still marks `perNode: true`. Derived once
|
|
8272
|
+
* per `cap` argument and memoized (schemas are static declarations). Empty set ⇒ every
|
|
8273
|
+
* per-node code path is bypassed and the settings API behaves like the node-agnostic one.
|
|
8274
|
+
* Call {@link loadScopedSchemas} first (the async seams do).
|
|
8275
|
+
*/
|
|
8192
8276
|
perNodeKeys(cap) {
|
|
8193
8277
|
const cacheKey = cap ?? "";
|
|
8194
|
-
const cached = this.
|
|
8278
|
+
const cached = this._nodeKeysByCap.get(cacheKey);
|
|
8195
8279
|
if (cached) return cached;
|
|
8196
|
-
const
|
|
8197
|
-
const keys = new Set(
|
|
8198
|
-
this.
|
|
8280
|
+
const legacy = this.globalSettingsSchema(cap);
|
|
8281
|
+
const keys = new Set(legacy ? legacy.sections.flatMap((section) => collectPerNodeFieldKeys(section.fields)) : []);
|
|
8282
|
+
for (const { scope, schema } of this.loadedScopedSchemas(cap)) {
|
|
8283
|
+
if (scope !== "node") continue;
|
|
8284
|
+
for (const section of schema.sections) for (const key of collectValueFieldKeys(section.fields)) keys.add(key);
|
|
8285
|
+
}
|
|
8286
|
+
this._nodeKeysByCap.set(cacheKey, keys);
|
|
8199
8287
|
return keys;
|
|
8200
8288
|
}
|
|
8201
8289
|
/**
|
|
@@ -8205,10 +8293,9 @@ var BaseAddon = class {
|
|
|
8205
8293
|
* time to return its response before the addon is torn down and
|
|
8206
8294
|
* re-initialised by `AddonRegistryService.restartAddon`.
|
|
8207
8295
|
*/
|
|
8208
|
-
maybeAutoRestart(patchKeys,
|
|
8209
|
-
if (!schema) return;
|
|
8296
|
+
maybeAutoRestart(patchKeys, schemas) {
|
|
8210
8297
|
const restartKeys = /* @__PURE__ */ new Set();
|
|
8211
|
-
for (const section of schema.sections) for (const field of section.fields) {
|
|
8298
|
+
for (const schema of schemas) for (const section of schema.sections) for (const field of section.fields) {
|
|
8212
8299
|
if (field.type === "separator" || field.type === "info") continue;
|
|
8213
8300
|
if (field.requiresRestart) restartKeys.add(field.key);
|
|
8214
8301
|
}
|
|
@@ -8404,12 +8491,14 @@ var BaseAddon = class {
|
|
|
8404
8491
|
* here, in the addon's own process, so the hub keeps no copy of it.
|
|
8405
8492
|
*/
|
|
8406
8493
|
async getDeclaredSettingsKeys() {
|
|
8494
|
+
await this.loadScopedSchemas();
|
|
8407
8495
|
return { keys: [...this.declaredKeySet()].toSorted() };
|
|
8408
8496
|
}
|
|
8409
8497
|
declaredKeySet() {
|
|
8410
8498
|
const keys = new Set(Object.keys(this.defaults));
|
|
8411
8499
|
const schema = this.globalSettingsSchema();
|
|
8412
8500
|
if (schema) for (const section of schema.sections) for (const key of collectFieldKeys(section.fields)) keys.add(key);
|
|
8501
|
+
for (const { schema: scoped } of this.loadedScopedSchemas()) for (const section of scoped.sections) for (const key of collectFieldKeys(section.fields)) keys.add(key);
|
|
8413
8502
|
for (const key of this._declaredStateKeys) keys.add(key);
|
|
8414
8503
|
for (const path of this.secretStatePaths) {
|
|
8415
8504
|
const root = path.split(/[.[]/, 1)[0];
|
|
@@ -8505,7 +8594,11 @@ var BaseAddon = class {
|
|
|
8505
8594
|
}
|
|
8506
8595
|
/** The addon store's secret tree: schema fields by TYPE, plus `secretStatePaths`. */
|
|
8507
8596
|
addonSecretTree() {
|
|
8508
|
-
this._addonSecretTree
|
|
8597
|
+
if (this._addonSecretTree === null) {
|
|
8598
|
+
const tree = new Map(secretTreeFromSchema(this.globalSettingsSchema()));
|
|
8599
|
+
for (const { schema } of this.loadedScopedSchemas()) for (const [key, node] of secretTreeFromSchema(schema)) tree.set(key, node);
|
|
8600
|
+
this._addonSecretTree = mergeSecretStatePaths(tree, this.secretStatePaths);
|
|
8601
|
+
}
|
|
8509
8602
|
return this._addonSecretTree;
|
|
8510
8603
|
}
|
|
8511
8604
|
deviceSecretTree() {
|
|
@@ -8755,6 +8848,23 @@ function dropPerNodeFields(fields) {
|
|
|
8755
8848
|
}
|
|
8756
8849
|
return kept;
|
|
8757
8850
|
}
|
|
8851
|
+
/** The keys of the value-holding fields, recursing into layout containers. */
|
|
8852
|
+
function collectValueFieldKeys(fields) {
|
|
8853
|
+
const collected = [];
|
|
8854
|
+
for (const field of fields) {
|
|
8855
|
+
if (field.type === "group") {
|
|
8856
|
+
collected.push(...collectValueFieldKeys(field.fields));
|
|
8857
|
+
continue;
|
|
8858
|
+
}
|
|
8859
|
+
if (field.type === "sub-tabs") {
|
|
8860
|
+
for (const tab of field.tabs) collected.push(...collectValueFieldKeys(tab.fields));
|
|
8861
|
+
continue;
|
|
8862
|
+
}
|
|
8863
|
+
if (field.type === "separator" || field.type === "info") continue;
|
|
8864
|
+
if ("key" in field && typeof field.key === "string") collected.push(field.key);
|
|
8865
|
+
}
|
|
8866
|
+
return collected;
|
|
8867
|
+
}
|
|
8758
8868
|
function collectFieldKeys(fields) {
|
|
8759
8869
|
const collected = [];
|
|
8760
8870
|
for (const field of fields) {
|
|
@@ -8847,6 +8957,10 @@ var RECORD_SETTINGS_MAX_ROWS = 5e4;
|
|
|
8847
8957
|
* (`collectZodSecretPaths`): dotted keys, `[]` for "each element of this array"
|
|
8848
8958
|
* (`auth.accessToken`, `headers[].value`).
|
|
8849
8959
|
*
|
|
8960
|
+
* `{}` after a key means "each value of this map" (`applianceSecrets{}`): the map's own key
|
|
8961
|
+
* names the value (`applianceSecrets{fridge}`), so no id key is declared and a body that drops a
|
|
8962
|
+
* key releases exactly that key's secret.
|
|
8963
|
+
*
|
|
8850
8964
|
* Array elements are matched by a DECLARED id key (`secretArrayKeys`:
|
|
8851
8965
|
* `{ headers: 'name' }`), never by index, so reordering a list keeps every
|
|
8852
8966
|
* keychain ref (the same rule as `arrayItemFieldPath`). The concrete path of a
|
|
@@ -8859,11 +8973,13 @@ function parseSecretPath(path) {
|
|
|
8859
8973
|
if (path.length === 0) throw new InvalidRecordError("an empty secret path");
|
|
8860
8974
|
return path.split(".").map((raw) => {
|
|
8861
8975
|
const each = raw.endsWith("[]");
|
|
8862
|
-
const
|
|
8976
|
+
const map = raw.endsWith("{}");
|
|
8977
|
+
const key = each || map ? raw.slice(0, -2) : raw;
|
|
8863
8978
|
if (key.length === 0) throw new InvalidRecordError(`secret path "${path}" has an empty segment`);
|
|
8864
8979
|
return {
|
|
8865
8980
|
key,
|
|
8866
|
-
each
|
|
8981
|
+
each,
|
|
8982
|
+
map
|
|
8867
8983
|
};
|
|
8868
8984
|
});
|
|
8869
8985
|
}
|
|
@@ -8950,7 +9066,8 @@ function isZodSecret(schema) {
|
|
|
8950
9066
|
}
|
|
8951
9067
|
/**
|
|
8952
9068
|
* Every declared secret path in a config schema: dotted keys, `[]` for "each
|
|
8953
|
-
* element of this array" (`connection.password`, `rows[].token`)
|
|
9069
|
+
* element of this array" (`connection.password`, `rows[].token`), `{}` for "each value of this
|
|
9070
|
+
* map" (`applianceSecrets{}`). A declared
|
|
8954
9071
|
* object or array is reported as one path and not descended into — everything
|
|
8955
9072
|
* under it is secret.
|
|
8956
9073
|
*/
|
|
@@ -8961,6 +9078,7 @@ function collectZodSecretPaths(schema, prefix = "") {
|
|
|
8961
9078
|
const def = defOf(layer);
|
|
8962
9079
|
if (def.type === "object" && def.shape) for (const [key, child] of Object.entries(def.shape)) paths.push(...collectZodSecretPaths(child, prefix ? `${prefix}.${key}` : key));
|
|
8963
9080
|
else if (def.type === "array" && def.element) paths.push(...collectZodSecretPaths(def.element, `${prefix}[]`));
|
|
9081
|
+
else if (def.type === "record" && def.valueType) paths.push(...collectZodSecretPaths(def.valueType, `${prefix}{}`));
|
|
8964
9082
|
else if (def.type === "union" && def.options) for (const option of def.options) paths.push(...collectZodSecretPaths(option, prefix));
|
|
8965
9083
|
else if (def.type === "intersection") {
|
|
8966
9084
|
if (def.left) paths.push(...collectZodSecretPaths(def.left, prefix));
|
|
@@ -9100,7 +9218,7 @@ function defineRecordKinds(specs) {
|
|
|
9100
9218
|
retention: spec.retention,
|
|
9101
9219
|
deviceRemoval: spec.deviceRemoval,
|
|
9102
9220
|
maxDataBytes: spec.maxDataBytes,
|
|
9103
|
-
secretPaths: [...secretPaths],
|
|
9221
|
+
secretPaths: [...new Set([...secretPaths, ...spec.retiredSecretPaths ?? []])],
|
|
9104
9222
|
secretArrayKeys: spec.secretArrayKeys === void 0 ? void 0 : { ...spec.secretArrayKeys },
|
|
9105
9223
|
transactFamily: spec.transactFamily,
|
|
9106
9224
|
entry: spec.entry === void 0 ? void 0 : {
|
|
@@ -12009,7 +12127,7 @@ function sleep(ms) {
|
|
|
12009
12127
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
12010
12128
|
}
|
|
12011
12129
|
//#endregion
|
|
12012
|
-
//#region ../types/dist/composition-
|
|
12130
|
+
//#region ../types/dist/composition-pOHbTzRB.mjs
|
|
12013
12131
|
/**
|
|
12014
12132
|
* Deterministic SHA-256 hash of an arbitrary serialisable value. The
|
|
12015
12133
|
* canonical form sorts object keys alphabetically at every depth so two
|
|
@@ -14678,7 +14796,13 @@ var MigrationLedgerEntrySchema = object({
|
|
|
14678
14796
|
* joined by the engine from the catalogues it knows this boot. Absent when no
|
|
14679
14797
|
* catalogue lists the id (a newer database).
|
|
14680
14798
|
*/
|
|
14681
|
-
meta: MigrationMetaSchema.optional()
|
|
14799
|
+
meta: MigrationMetaSchema.optional(),
|
|
14800
|
+
/**
|
|
14801
|
+
* Set when this is an applied row of an addon owner whose catalogue the answering
|
|
14802
|
+
* process has not loaded (the owner has not declared yet): the row is applied, the
|
|
14803
|
+
* process just cannot judge it. Never `skipped-newer` — that needs the owner loaded.
|
|
14804
|
+
*/
|
|
14805
|
+
ownerNotLoaded: boolean().optional()
|
|
14682
14806
|
});
|
|
14683
14807
|
/** A catalogued migration that is not applied, with where it stands. */
|
|
14684
14808
|
var MigrationPendingEntrySchema = object({
|
|
@@ -51210,6 +51334,9 @@ var RunningProposalEvidenceSchema = object({
|
|
|
51210
51334
|
runsFound: number().int().nonnegative(),
|
|
51211
51335
|
pausesFound: number().int().nonnegative(),
|
|
51212
51336
|
longestPauseMs: number().nonnegative(),
|
|
51337
|
+
/** Episodes shorter than ~90 s (an anti-crease pulse, a display waking): never a run, never a pause. */
|
|
51338
|
+
pulsesFound: number().int().nonnegative(),
|
|
51339
|
+
longestPulseMs: number().nonnegative(),
|
|
51213
51340
|
idleFloorW: number(),
|
|
51214
51341
|
noiseCeilingW: number(),
|
|
51215
51342
|
plateauW: number(),
|
|
@@ -52500,7 +52627,27 @@ method(object({
|
|
|
52500
52627
|
* exposes only the COMMON surface: link state, supported device
|
|
52501
52628
|
* kinds (so the UI can filter the device picker), and per-device
|
|
52502
52629
|
* expose/unexpose.
|
|
52503
|
-
|
|
52630
|
+
*
|
|
52631
|
+
* INSTANCES. One export addon can serve several independent targets (a
|
|
52632
|
+
* HomeKit bridge, a Home Assistant broker). `listInstances` names them.
|
|
52633
|
+
* `instanceId` on a READ is optional: absent = the whole addon (linked if any
|
|
52634
|
+
* enabled instance is, `exposedDeviceCount` = distinct devices, `setup` = the
|
|
52635
|
+
* default instance's); present = that instance; an id the provider does not
|
|
52636
|
+
* serve is refused with `ExportInstanceUnknownError` (`export-instance-unknown`),
|
|
52637
|
+
* never answered empty. `instanceId` on a WRITE is REQUIRED: a membership
|
|
52638
|
+
* change always names the target it changes. A single-instance provider
|
|
52639
|
+
* accepts an absent id on a read or its own id, and refuses any other.
|
|
52640
|
+
*/
|
|
52641
|
+
/** Which instance of an export addon a call addresses. Absent on a read = the whole addon. */
|
|
52642
|
+
var InstanceIdSchema$1 = string().min(1);
|
|
52643
|
+
var InstancePinSchema = object({ instanceId: InstanceIdSchema$1.optional() });
|
|
52644
|
+
/** One independent export target of an addon. */
|
|
52645
|
+
var ExportInstanceSchema = object({
|
|
52646
|
+
instanceId: InstanceIdSchema$1,
|
|
52647
|
+
name: string(),
|
|
52648
|
+
enabled: boolean(),
|
|
52649
|
+
kind: string().optional()
|
|
52650
|
+
});
|
|
52504
52651
|
var LinkStateSchema = _enum([
|
|
52505
52652
|
"unlinked",
|
|
52506
52653
|
"linked",
|
|
@@ -52551,10 +52698,14 @@ var ExposedDeviceSchema = object({
|
|
|
52551
52698
|
capabilities: array(string()).optional()
|
|
52552
52699
|
});
|
|
52553
52700
|
var ExposeInputSchema = object({
|
|
52701
|
+
instanceId: InstanceIdSchema$1,
|
|
52554
52702
|
deviceId: string(),
|
|
52555
52703
|
capabilities: array(string()).optional()
|
|
52556
52704
|
});
|
|
52557
|
-
var UnexposeInputSchema = object({
|
|
52705
|
+
var UnexposeInputSchema = object({
|
|
52706
|
+
instanceId: InstanceIdSchema$1,
|
|
52707
|
+
deviceId: string()
|
|
52708
|
+
});
|
|
52558
52709
|
/**
|
|
52559
52710
|
* What an exporter may expose besides devices (D968). An action and a
|
|
52560
52711
|
* notification target are LIST ENTRIES, never devices (D954): they enter an
|
|
@@ -52583,15 +52734,21 @@ var ExposedEntitySchema = object({
|
|
|
52583
52734
|
entity: ExportEntityRefSchema,
|
|
52584
52735
|
exposedAs: string().optional()
|
|
52585
52736
|
});
|
|
52586
|
-
var ExposeEntityInputSchema = object({
|
|
52587
|
-
|
|
52588
|
-
|
|
52737
|
+
var ExposeEntityInputSchema = object({
|
|
52738
|
+
instanceId: InstanceIdSchema$1,
|
|
52739
|
+
entity: ExportEntityRefSchema
|
|
52740
|
+
});
|
|
52741
|
+
var UnexposeEntityInputSchema = object({
|
|
52742
|
+
instanceId: InstanceIdSchema$1,
|
|
52743
|
+
entity: ExportEntityRefSchema
|
|
52744
|
+
});
|
|
52745
|
+
method(InstancePinSchema, DeviceExportStatusSchema), method(_void(), array(ExportInstanceSchema)), method(InstancePinSchema, array(DeviceKindSchema)), method(InstancePinSchema, array(ExposedDeviceSchema)), method(ExposeInputSchema, _void(), {
|
|
52589
52746
|
kind: "mutation",
|
|
52590
52747
|
auth: "admin"
|
|
52591
52748
|
}), method(UnexposeInputSchema, _void(), {
|
|
52592
52749
|
kind: "mutation",
|
|
52593
52750
|
auth: "admin"
|
|
52594
|
-
}), optionalMethod(_void(), array(ExportEntityKindSchema)), optionalMethod(
|
|
52751
|
+
}), optionalMethod(_void(), array(ExportEntityKindSchema)), optionalMethod(InstancePinSchema, array(ExposedEntitySchema)), optionalMethod(ExposeEntityInputSchema, _void(), {
|
|
52595
52752
|
kind: "mutation",
|
|
52596
52753
|
auth: "admin"
|
|
52597
52754
|
}), optionalMethod(UnexposeEntityInputSchema, _void(), {
|
|
@@ -57092,11 +57249,7 @@ var CreateIntegrationInputSchema = object({
|
|
|
57092
57249
|
info: record(string(), unknown()).optional(),
|
|
57093
57250
|
/** `stableId` of the discovery candidate the form was seeded from (D984). */
|
|
57094
57251
|
originStableId: string().optional(),
|
|
57095
|
-
settings: record(string(), unknown()).optional()
|
|
57096
|
-
/** Keys of `settings` the form's schema declares secret (by type) — kept in
|
|
57097
|
-
* the keychain, not the table (D787). */
|
|
57098
|
-
secretKeys: array(string()).optional(),
|
|
57099
|
-
skipRestart: boolean().optional()
|
|
57252
|
+
settings: record(string(), unknown()).optional()
|
|
57100
57253
|
});
|
|
57101
57254
|
var UpdateIntegrationInputSchema = object({
|
|
57102
57255
|
id: string(),
|
|
@@ -57117,16 +57270,6 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
|
|
|
57117
57270
|
}), method(object({ id: string() }), DeleteIntegrationResultSchema, {
|
|
57118
57271
|
kind: "mutation",
|
|
57119
57272
|
auth: "admin"
|
|
57120
|
-
}), method(object({ id: string() }), record(string(), unknown()), { auth: "admin" }), method(object({
|
|
57121
|
-
id: string(),
|
|
57122
|
-
settings: record(string(), unknown()),
|
|
57123
|
-
/** Keys the form's schema declares secret (by type) — keychain-stored (D787). */
|
|
57124
|
-
secretKeys: array(string()).optional(),
|
|
57125
|
-
/** The integration's own addon applies the change in-process and asks the hub not to respawn it. */
|
|
57126
|
-
skipRestart: boolean().optional()
|
|
57127
|
-
}), object({ success: boolean() }), {
|
|
57128
|
-
kind: "mutation",
|
|
57129
|
-
auth: "admin"
|
|
57130
57273
|
}), method(_void(), array(AvailableIntegrationTypeSchema), { auth: "admin" }), method(object({
|
|
57131
57274
|
addonId: string(),
|
|
57132
57275
|
settings: record(string(), unknown())
|
|
@@ -57155,13 +57298,65 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
|
|
|
57155
57298
|
*/
|
|
57156
57299
|
var ConfigSchemaPassthrough$3 = custom();
|
|
57157
57300
|
var IntegrationInstanceIdSchema = string().min(1);
|
|
57301
|
+
var IntegrationInstanceModeSchema = _enum(["single", "multiple"]);
|
|
57302
|
+
/**
|
|
57303
|
+
* One kind of instance a provider can create (an adapter, an account type). The sign-in and
|
|
57304
|
+
* connect fields follow the `broker` contract (`broker.cap.ts`): `signIn.basePath` is a
|
|
57305
|
+
* hub-relative route set speaking the sign-in contract, `connectPath` / `disconnectPath` open an
|
|
57306
|
+
* interactive account link (popup) and may carry `{{brokerId}}`, which the UI replaces with the
|
|
57307
|
+
* instance id.
|
|
57308
|
+
*/
|
|
57309
|
+
var IntegrationInstanceKindSchema = object({
|
|
57310
|
+
/** Stable id of the kind, sent back as `createInstance.kind`. */
|
|
57311
|
+
id: string().min(1),
|
|
57312
|
+
label: string().min(1),
|
|
57313
|
+
/** The kind signs in through a server-held interactive session. */
|
|
57314
|
+
signIn: object({
|
|
57315
|
+
basePath: string().min(1),
|
|
57316
|
+
methods: array(_enum(["device-code", "proxy"])).optional()
|
|
57317
|
+
}).optional(),
|
|
57318
|
+
/** Relative hub path to start an interactive account link of an instance of this kind. */
|
|
57319
|
+
connectPath: string().min(1).optional(),
|
|
57320
|
+
/** Relative hub path to disconnect that account. */
|
|
57321
|
+
disconnectPath: string().min(1).optional()
|
|
57322
|
+
});
|
|
57158
57323
|
var IntegrationInstanceDescriptionSchema = object({
|
|
57324
|
+
/** What the instances are for the Integrations page; see {@link IntegrationInstanceRoleSchema}. */
|
|
57325
|
+
role: _enum([
|
|
57326
|
+
"devices",
|
|
57327
|
+
"services",
|
|
57328
|
+
"both"
|
|
57329
|
+
]),
|
|
57330
|
+
/** How the devices of an instance are found; absent means `{ mode: 'none' }`. */
|
|
57331
|
+
discovery: object({
|
|
57332
|
+
mode: _enum([
|
|
57333
|
+
"none",
|
|
57334
|
+
"lan",
|
|
57335
|
+
"account"
|
|
57336
|
+
]),
|
|
57337
|
+
scopedToInstance: boolean()
|
|
57338
|
+
}).optional(),
|
|
57159
57339
|
/** `single`: at most one instance can exist (Loki). `multiple`: an account each. */
|
|
57160
|
-
instanceMode:
|
|
57340
|
+
instanceMode: IntegrationInstanceModeSchema,
|
|
57161
57341
|
/** What the instance is, for the UI (`destination`, `relay`, `account`). */
|
|
57162
57342
|
kind: string(),
|
|
57163
57343
|
/** True when `testInstance` really probes the remote. */
|
|
57164
|
-
canTest: boolean()
|
|
57344
|
+
canTest: boolean(),
|
|
57345
|
+
/**
|
|
57346
|
+
* The kinds an instance can be of. Absent or one entry: nothing to choose; more than one: the
|
|
57347
|
+
* Add flow asks which first and sends it as `createInstance.kind`.
|
|
57348
|
+
*/
|
|
57349
|
+
kinds: array(IntegrationInstanceKindSchema).optional(),
|
|
57350
|
+
/**
|
|
57351
|
+
* The provider accepts `createInstance.id` for an id that once existed (an adopted id, because
|
|
57352
|
+
* devices carry it). The UI then offers "restore under its old id" on Add. Absent means no.
|
|
57353
|
+
*/
|
|
57354
|
+
allowRestoreId: boolean().optional(),
|
|
57355
|
+
/**
|
|
57356
|
+
* `createInstance` without an `id` works: the provider mints it. Absent means the caller must
|
|
57357
|
+
* send an id (the UI then mints an opaque one).
|
|
57358
|
+
*/
|
|
57359
|
+
mintsId: boolean().optional()
|
|
57165
57360
|
});
|
|
57166
57361
|
var IntegrationInstanceStatusSchema = object({
|
|
57167
57362
|
state: _enum([
|
|
@@ -57170,7 +57365,9 @@ var IntegrationInstanceStatusSchema = object({
|
|
|
57170
57365
|
"error",
|
|
57171
57366
|
"unknown"
|
|
57172
57367
|
]),
|
|
57173
|
-
detail: string().optional()
|
|
57368
|
+
detail: string().optional(),
|
|
57369
|
+
/** A short human word for the state ("Signed in", "Token expired"); shown instead of `state`. */
|
|
57370
|
+
label: string().optional()
|
|
57174
57371
|
});
|
|
57175
57372
|
var IntegrationInstanceSchema = object({
|
|
57176
57373
|
id: IntegrationInstanceIdSchema,
|
|
@@ -57178,13 +57375,18 @@ var IntegrationInstanceSchema = object({
|
|
|
57178
57375
|
/** The addon's own rule (an URL is present, a client id is present...). */
|
|
57179
57376
|
configured: boolean(),
|
|
57180
57377
|
/**
|
|
57181
|
-
* The instance's own on/off switch (D996)
|
|
57182
|
-
*
|
|
57378
|
+
* The instance's own on/off switch (D996), derived from the record body (`enabled !== false`,
|
|
57379
|
+
* so a row written before the field existed is on). Absent when the `integrations` registry
|
|
57380
|
+
* owns the switch (`describe().role` is `devices`): read it from the registry row.
|
|
57183
57381
|
*/
|
|
57184
|
-
enabled: boolean(),
|
|
57382
|
+
enabled: boolean().optional(),
|
|
57383
|
+
/** The kind of this instance (one of `describe().kinds[].id`), when the provider has kinds. */
|
|
57384
|
+
kind: string().optional(),
|
|
57185
57385
|
/** Values for the instance form; a secret is a `SecretFieldView`, never text. */
|
|
57186
57386
|
formValues: record(string(), unknown()),
|
|
57187
|
-
status: IntegrationInstanceStatusSchema.optional()
|
|
57387
|
+
status: IntegrationInstanceStatusSchema.optional(),
|
|
57388
|
+
/** Epoch ms of the last probe of the remote that produced `status`; absent when never checked. */
|
|
57389
|
+
lastCheckedAt: number().optional()
|
|
57188
57390
|
});
|
|
57189
57391
|
var IntegrationInstancePatchSchema = object({
|
|
57190
57392
|
id: IntegrationInstanceIdSchema,
|
|
@@ -57193,8 +57395,9 @@ var IntegrationInstancePatchSchema = object({
|
|
|
57193
57395
|
values: record(string(), unknown())
|
|
57194
57396
|
});
|
|
57195
57397
|
method(_void(), IntegrationInstanceDescriptionSchema, { auth: "admin" }), method(object({ id: IntegrationInstanceIdSchema.nullable() }), ConfigSchemaPassthrough$3, { auth: "admin" }), method(_void(), array(IntegrationInstanceSchema).readonly(), { auth: "admin" }), method(object({ id: IntegrationInstanceIdSchema }), IntegrationInstanceSchema.nullable(), { auth: "admin" }), method(object({
|
|
57196
|
-
id: IntegrationInstanceIdSchema,
|
|
57197
|
-
name: string().min(1)
|
|
57398
|
+
id: IntegrationInstanceIdSchema.optional(),
|
|
57399
|
+
name: string().min(1),
|
|
57400
|
+
kind: string().min(1).optional()
|
|
57198
57401
|
}), object({ id: string() }), {
|
|
57199
57402
|
kind: "mutation",
|
|
57200
57403
|
auth: "admin"
|
|
@@ -59354,6 +59557,11 @@ var LogEntrySchema = object({
|
|
|
59354
59557
|
* flight, and not asking for the next slice ends the scan.
|
|
59355
59558
|
*/
|
|
59356
59559
|
var LogReadQuerySchema = object({
|
|
59560
|
+
/**
|
|
59561
|
+
* Which destination INSTANCE answers (a destination addon may hold several records). Absent ⇒
|
|
59562
|
+
* the provider's first readable one, so a caller written before instances existed is unchanged.
|
|
59563
|
+
*/
|
|
59564
|
+
instanceId: string().min(1).max(200).optional(),
|
|
59357
59565
|
/** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
|
|
59358
59566
|
requestId: string().min(1).max(64).optional(),
|
|
59359
59567
|
/** The device the line is about (`tags.deviceId`, numeric). */
|
|
@@ -59416,6 +59624,8 @@ var LogReadResultSchema = object({
|
|
|
59416
59624
|
/** True when `cancelRead` ended this slice early. */
|
|
59417
59625
|
cancelled: boolean().optional()
|
|
59418
59626
|
});
|
|
59627
|
+
/** Names one destination instance; absent ⇒ the provider's first readable one. */
|
|
59628
|
+
var LogInstanceSelectorSchema = object({ instanceId: string().min(1).max(200).optional() });
|
|
59419
59629
|
var LogReadCapabilitiesSchema = object({
|
|
59420
59630
|
/** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
|
|
59421
59631
|
readable: boolean(),
|
|
@@ -59434,7 +59644,7 @@ var LogReadCapabilitiesSchema = object({
|
|
|
59434
59644
|
/** How far back the store reaches, when the provider knows (days). */
|
|
59435
59645
|
retentionDays: number().nullable()
|
|
59436
59646
|
});
|
|
59437
|
-
method(LogEntrySchema, _void(), { kind: "mutation" }), optionalMethod(
|
|
59647
|
+
method(LogEntrySchema, _void(), { kind: "mutation" }), optionalMethod(LogInstanceSelectorSchema, LogReadCapabilitiesSchema, { auth: "admin" }), optionalMethod(LogReadQuerySchema, LogReadResultSchema, { auth: "admin" }), optionalMethod(object({ requestId: string().min(1).max(64) }), object({ cancelled: boolean() }), {
|
|
59438
59648
|
kind: "mutation",
|
|
59439
59649
|
auth: "admin"
|
|
59440
59650
|
});
|
|
@@ -60131,6 +60341,27 @@ method(object({}), object({ entries: array(MigrationLedgerEntrySchema) }), { aut
|
|
|
60131
60341
|
}), {
|
|
60132
60342
|
kind: "mutation",
|
|
60133
60343
|
auth: "admin"
|
|
60344
|
+
}), method(object({ integrationId: string().min(1) }), record(string(), unknown()), { auth: "admin" }), method(object({ integrationId: string().min(1) }), object({
|
|
60345
|
+
rows: number().int().nonnegative(),
|
|
60346
|
+
secrets: number().int().nonnegative()
|
|
60347
|
+
}), {
|
|
60348
|
+
kind: "mutation",
|
|
60349
|
+
auth: "admin"
|
|
60350
|
+
}), method(object({
|
|
60351
|
+
integrationId: string().min(1),
|
|
60352
|
+
patch: record(string(), unknown())
|
|
60353
|
+
}), object({ written: boolean() }), {
|
|
60354
|
+
kind: "mutation",
|
|
60355
|
+
auth: "admin"
|
|
60356
|
+
}), method(object({
|
|
60357
|
+
integrationId: string().min(1),
|
|
60358
|
+
keys: array(string().min(1))
|
|
60359
|
+
}), object({
|
|
60360
|
+
present: boolean(),
|
|
60361
|
+
removed: record(string(), unknown())
|
|
60362
|
+
}), {
|
|
60363
|
+
kind: "mutation",
|
|
60364
|
+
auth: "admin"
|
|
60134
60365
|
});
|
|
60135
60366
|
method(object({
|
|
60136
60367
|
sourceUrl: string(),
|
|
@@ -83276,6 +83507,25 @@ function buildEventKindDescriptor(kind, source) {
|
|
|
83276
83507
|
}
|
|
83277
83508
|
};
|
|
83278
83509
|
}
|
|
83510
|
+
/**
|
|
83511
|
+
* What a remote key is CALLED and what it LOOKS like, for every role (D963),
|
|
83512
|
+
* shared by the admin UI and the viewer. A role is data on the wire; each
|
|
83513
|
+
* client resolves its name from `label` (English and Italian side by side) and
|
|
83514
|
+
* its glyph from `icon`, a lucide id from the shared icon catalogue — the
|
|
83515
|
+
* server sends an id, a client maps it to its own icon set.
|
|
83516
|
+
*
|
|
83517
|
+
* `legend` is text printed on the key INSTEAD of a glyph (a digit has no
|
|
83518
|
+
* pictogram): a client that can draw text shows it, one that cannot falls back
|
|
83519
|
+
* to `icon`.
|
|
83520
|
+
*/
|
|
83521
|
+
function digit(n) {
|
|
83522
|
+
return {
|
|
83523
|
+
label: t(n, n),
|
|
83524
|
+
icon: "hash",
|
|
83525
|
+
legend: n
|
|
83526
|
+
};
|
|
83527
|
+
}
|
|
83528
|
+
digit("0"), digit("1"), digit("2"), digit("3"), digit("4"), digit("5"), digit("6"), digit("7"), digit("8"), digit("9");
|
|
83279
83529
|
DeviceFeature.MediaPlayerPower, DeviceFeature.MediaPlayerVolumeStep, DeviceFeature.MediaPlayerChannelStep, DeviceFeature.MediaPlayerMute, DeviceFeature.MediaPlayerStop, DeviceFeature.MediaPlayerNext, DeviceFeature.MediaPlayerPrevious;
|
|
83280
83530
|
var btn = (idSuffix, row, col, init) => ({
|
|
83281
83531
|
idSuffix,
|
|
@@ -83414,11 +83664,15 @@ discriminatedUnion("kind", [object({
|
|
|
83414
83664
|
* 1. idle floor F = time-weighted median; noise ceiling N = highest value seen
|
|
83415
83665
|
* near F. A device that is not near one level most of the time has no floor.
|
|
83416
83666
|
* 2. coarse activity = above max(2N, N + 5 W); consecutive stretches are episodes.
|
|
83417
|
-
* 3.
|
|
83418
|
-
*
|
|
83667
|
+
* 3. an episode shorter than `PULSE_MAX_MS` is a PULSE (an anti-crease tumble, a
|
|
83668
|
+
* display waking): it is neither a run nor a pause. Among the remaining
|
|
83669
|
+
* episodes, gaps over `PAUSE_MAX_MS` always separate runs; the rest split in
|
|
83670
|
+
* two by the largest log-scale jump (>= 3x): the short ones are pauses INSIDE
|
|
83671
|
+
* a run (a soak), the long ones separate runs. A stretch under `MIN_RUN_MS`
|
|
83672
|
+
* is no run.
|
|
83419
83673
|
* 4. T = geometric mean of N and the plateau's 10th percentile, snapped to a
|
|
83420
|
-
* grid a person would type; stop dwell covers the longest pause
|
|
83421
|
-
* covers the longest standby blip above T.
|
|
83674
|
+
* grid a person would type; stop dwell covers the longest pause and the
|
|
83675
|
+
* kind's floor; start dwell covers the longest pulse and standby blip above T.
|
|
83422
83676
|
* 5. the numbers are proved by REPLAY through the real `dwell` evaluation: each
|
|
83423
83677
|
* run must hold exactly one true interval and nothing may flap outside.
|
|
83424
83678
|
*/
|
|
@@ -83429,6 +83683,10 @@ var MINUTE_MS$1 = 60 * SECOND_MS;
|
|
|
83429
83683
|
30 * SECOND_MS;
|
|
83430
83684
|
60 * SECOND_MS;
|
|
83431
83685
|
20 * MINUTE_MS$1;
|
|
83686
|
+
90 * SECOND_MS;
|
|
83687
|
+
30 * MINUTE_MS$1;
|
|
83688
|
+
10 * MINUTE_MS$1;
|
|
83689
|
+
DeviceType.Dryer, 3 * MINUTE_MS$1, DeviceType.Dishwasher, 3 * MINUTE_MS$1, DeviceType.Washer, 10 * MINUTE_MS$1;
|
|
83432
83690
|
10 * SECOND_MS;
|
|
83433
83691
|
10 * SECOND_MS;
|
|
83434
83692
|
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverStoppable, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
@@ -86613,6 +86871,13 @@ Object.freeze({
|
|
|
86613
86871
|
access: "view",
|
|
86614
86872
|
role: "admin"
|
|
86615
86873
|
},
|
|
86874
|
+
"deviceExport.listInstances": {
|
|
86875
|
+
capName: "device-export",
|
|
86876
|
+
capScope: "system",
|
|
86877
|
+
addonId: null,
|
|
86878
|
+
access: "view",
|
|
86879
|
+
role: "admin"
|
|
86880
|
+
},
|
|
86616
86881
|
"deviceExport.listSupportedDeviceKinds": {
|
|
86617
86882
|
capName: "device-export",
|
|
86618
86883
|
capScope: "system",
|
|
@@ -88300,13 +88565,6 @@ Object.freeze({
|
|
|
88300
88565
|
access: "view",
|
|
88301
88566
|
role: "admin"
|
|
88302
88567
|
},
|
|
88303
|
-
"integrations.getSettings": {
|
|
88304
|
-
capName: "integrations",
|
|
88305
|
-
capScope: "system",
|
|
88306
|
-
addonId: null,
|
|
88307
|
-
access: "view",
|
|
88308
|
-
role: "admin"
|
|
88309
|
-
},
|
|
88310
88568
|
"integrations.list": {
|
|
88311
88569
|
capName: "integrations",
|
|
88312
88570
|
capScope: "system",
|
|
@@ -88314,13 +88572,6 @@ Object.freeze({
|
|
|
88314
88572
|
access: "view",
|
|
88315
88573
|
role: "admin"
|
|
88316
88574
|
},
|
|
88317
|
-
"integrations.setSettings": {
|
|
88318
|
-
capName: "integrations",
|
|
88319
|
-
capScope: "system",
|
|
88320
|
-
addonId: null,
|
|
88321
|
-
access: "create",
|
|
88322
|
-
role: "admin"
|
|
88323
|
-
},
|
|
88324
88575
|
"integrations.testConnection": {
|
|
88325
88576
|
capName: "integrations",
|
|
88326
88577
|
capScope: "system",
|
|
@@ -89315,6 +89566,13 @@ Object.freeze({
|
|
|
89315
89566
|
access: "view",
|
|
89316
89567
|
role: "admin"
|
|
89317
89568
|
},
|
|
89569
|
+
"migrations.clearLegacyIntegrationRows": {
|
|
89570
|
+
capName: "migrations",
|
|
89571
|
+
capScope: "system",
|
|
89572
|
+
addonId: null,
|
|
89573
|
+
access: "delete",
|
|
89574
|
+
role: "admin"
|
|
89575
|
+
},
|
|
89318
89576
|
"migrations.declareOwner": {
|
|
89319
89577
|
capName: "migrations",
|
|
89320
89578
|
capScope: "system",
|
|
@@ -89322,6 +89580,13 @@ Object.freeze({
|
|
|
89322
89580
|
access: "create",
|
|
89323
89581
|
role: "admin"
|
|
89324
89582
|
},
|
|
89583
|
+
"migrations.deleteLegacyIntegrationRowKeys": {
|
|
89584
|
+
capName: "migrations",
|
|
89585
|
+
capScope: "system",
|
|
89586
|
+
addonId: null,
|
|
89587
|
+
access: "delete",
|
|
89588
|
+
role: "admin"
|
|
89589
|
+
},
|
|
89325
89590
|
"migrations.dryRun": {
|
|
89326
89591
|
capName: "migrations",
|
|
89327
89592
|
capScope: "system",
|
|
@@ -89357,6 +89622,20 @@ Object.freeze({
|
|
|
89357
89622
|
access: "create",
|
|
89358
89623
|
role: "admin"
|
|
89359
89624
|
},
|
|
89625
|
+
"migrations.patchLegacyIntegrationRows": {
|
|
89626
|
+
capName: "migrations",
|
|
89627
|
+
capScope: "system",
|
|
89628
|
+
addonId: null,
|
|
89629
|
+
access: "create",
|
|
89630
|
+
role: "admin"
|
|
89631
|
+
},
|
|
89632
|
+
"migrations.readLegacyIntegrationRows": {
|
|
89633
|
+
capName: "migrations",
|
|
89634
|
+
capScope: "system",
|
|
89635
|
+
addonId: null,
|
|
89636
|
+
access: "view",
|
|
89637
|
+
role: "admin"
|
|
89638
|
+
},
|
|
89360
89639
|
"migrations.restorePreMigration": {
|
|
89361
89640
|
capName: "migrations",
|
|
89362
89641
|
capScope: "system",
|