@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
|
@@ -6038,7 +6038,7 @@ var ZodIssueCode = {
|
|
|
6038
6038
|
var ZodFirstPartyTypeKind;
|
|
6039
6039
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6040
6040
|
//#endregion
|
|
6041
|
-
//#region ../types/dist/sleep-
|
|
6041
|
+
//#region ../types/dist/sleep-DEZaLbiu.mjs
|
|
6042
6042
|
/**
|
|
6043
6043
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6044
6044
|
* window to float samples (D455).
|
|
@@ -6631,7 +6631,7 @@ var NOT_RUN = {
|
|
|
6631
6631
|
* throws: an unreachable or refusing engine is logged and reported `declared: false`,
|
|
6632
6632
|
* because the hub (and this addon's boot) must not hang on a migration.
|
|
6633
6633
|
*/
|
|
6634
|
-
async function runAddonMigrations(host, migrations, logger) {
|
|
6634
|
+
async function runAddonMigrations(host, migrations, logger, options = {}) {
|
|
6635
6635
|
const first = migrations[0];
|
|
6636
6636
|
if (first === void 0) return NOT_RUN;
|
|
6637
6637
|
const owner = first.meta.owner;
|
|
@@ -6660,7 +6660,9 @@ async function runAddonMigrations(host, migrations, logger) {
|
|
|
6660
6660
|
else if (status === "blocked") blocked.push(id);
|
|
6661
6661
|
else skipped.push(id);
|
|
6662
6662
|
};
|
|
6663
|
+
const selected = options.only === void 0 ? null : new Set(options.only);
|
|
6663
6664
|
for (const step of declaration.steps) {
|
|
6665
|
+
if (selected !== null && !selected.has(step.id)) continue;
|
|
6664
6666
|
const bound = byId.get(step.id);
|
|
6665
6667
|
if (bound === void 0 || step.action === "skip") {
|
|
6666
6668
|
skipped.push(step.id);
|
|
@@ -6838,6 +6840,12 @@ function projectStore(store, perNodeKeys, nodeId) {
|
|
|
6838
6840
|
}
|
|
6839
6841
|
return out;
|
|
6840
6842
|
}
|
|
6843
|
+
/** Every scope, in the order the guard and the docs list them. */
|
|
6844
|
+
var SCOPED_SETTINGS_SCOPES = [
|
|
6845
|
+
"cluster",
|
|
6846
|
+
"device-defaults",
|
|
6847
|
+
"node"
|
|
6848
|
+
];
|
|
6841
6849
|
var GLOBAL_SCOPE = { kind: "global" };
|
|
6842
6850
|
/** The scope every addon-wide (not per-node, not per-device) setting lives in. */
|
|
6843
6851
|
function globalSecretScope() {
|
|
@@ -7687,6 +7695,13 @@ var BaseAddon = class {
|
|
|
7687
7695
|
*/
|
|
7688
7696
|
secretStatePaths = [];
|
|
7689
7697
|
_addonSecretTree = null;
|
|
7698
|
+
/**
|
|
7699
|
+
* D986 M4: the scoped schemas this addon declared, resolved once per capability
|
|
7700
|
+
* (`loadScopedSchemas`) so the sync readers (`perNodeKeys`, the secret tree, the restart check)
|
|
7701
|
+
* see them. Empty until loaded: the readers then fall back to {@link globalSettingsSchema}.
|
|
7702
|
+
*/
|
|
7703
|
+
_scopedByCap = /* @__PURE__ */ new Map();
|
|
7704
|
+
_nodeKeysByCap = /* @__PURE__ */ new Map();
|
|
7690
7705
|
_deviceSecretTree = null;
|
|
7691
7706
|
/** Refs the last resolved config pointed at — a change to one re-resolves. */
|
|
7692
7707
|
_configSecretRefs = /* @__PURE__ */ new Set();
|
|
@@ -7756,6 +7771,7 @@ var BaseAddon = class {
|
|
|
7756
7771
|
this._ctx = context;
|
|
7757
7772
|
this._secretSettings = null;
|
|
7758
7773
|
}
|
|
7774
|
+
await this.loadScopedSchemas();
|
|
7759
7775
|
await this.resolveConfig();
|
|
7760
7776
|
if (secrets !== void 0) this._secretChangeUnsub = secrets.onChange((ref) => {
|
|
7761
7777
|
if (this._configSecretRefs.has(ref)) this.scheduleSecretReresolve(SECRET_CHANGE_DEBOUNCE_MS);
|
|
@@ -7765,6 +7781,7 @@ var BaseAddon = class {
|
|
|
7765
7781
|
const normalized = normalizeAddonInitResult(result);
|
|
7766
7782
|
const providers = normalized && "providers" in normalized && normalized.providers ? normalized.providers : [];
|
|
7767
7783
|
this._registeredCapNames = providers.map((p) => p.capability.name);
|
|
7784
|
+
await this.loadScopedSchemas();
|
|
7768
7785
|
return normalized;
|
|
7769
7786
|
}
|
|
7770
7787
|
/**
|
|
@@ -7778,14 +7795,18 @@ var BaseAddon = class {
|
|
|
7778
7795
|
* nothing; the boot continues. A migration that FAILED (or was blocked by one)
|
|
7779
7796
|
* and declares `onFailure: 'block-owner'` makes this throw, so the addon does not
|
|
7780
7797
|
* serve data whose shape it cannot trust; `tolerate` migrations never do.
|
|
7798
|
+
*
|
|
7799
|
+
* ALWAYS pass the whole catalogue; a phase that must run only some of it passes
|
|
7800
|
+
* `{ only: [ids] }` — never a filtered catalogue (the engine would judge the
|
|
7801
|
+
* omitted applied ids "newer").
|
|
7781
7802
|
*/
|
|
7782
|
-
async runMigrations(migrations) {
|
|
7803
|
+
async runMigrations(migrations, options) {
|
|
7783
7804
|
const api = this.ctx.api.migrations;
|
|
7784
7805
|
const report = await runAddonMigrations({
|
|
7785
7806
|
declareOwner: (input) => api.declareOwner.mutate(input),
|
|
7786
7807
|
startMigration: (input) => api.startMigration.mutate(input),
|
|
7787
7808
|
finishMigration: (input) => api.finishMigration.mutate(input)
|
|
7788
|
-
}, migrations, this.ctx.logger);
|
|
7809
|
+
}, migrations, this.ctx.logger, options);
|
|
7789
7810
|
if (report.blockOwner.length > 0) throw new AddonMigrationsBlockedError(report.blockOwner);
|
|
7790
7811
|
return report;
|
|
7791
7812
|
}
|
|
@@ -7849,6 +7870,16 @@ var BaseAddon = class {
|
|
|
7849
7870
|
schema(schema) {
|
|
7850
7871
|
return schema;
|
|
7851
7872
|
}
|
|
7873
|
+
/**
|
|
7874
|
+
* The capability names whose scoped settings schemas ({@link clusterSettingsSchema},
|
|
7875
|
+
* {@link nodeSettingsSchema}, {@link deviceDefaultsSchema}) this addon declares. Read BEFORE
|
|
7876
|
+
* `onInitialize`, when the providers it registers are not known yet: the first config resolve
|
|
7877
|
+
* must already know which keys are per node. Names the providers register at init are added
|
|
7878
|
+
* once known.
|
|
7879
|
+
*/
|
|
7880
|
+
scopedSettingsCapabilities() {
|
|
7881
|
+
return [];
|
|
7882
|
+
}
|
|
7852
7883
|
/** Override to provide global-level settings UI schema. */
|
|
7853
7884
|
globalSettingsSchema(_cap) {
|
|
7854
7885
|
return null;
|
|
@@ -7892,7 +7923,8 @@ var BaseAddon = class {
|
|
|
7892
7923
|
return [];
|
|
7893
7924
|
}
|
|
7894
7925
|
async getGlobalSettings(overlay, cap, nodeId) {
|
|
7895
|
-
|
|
7926
|
+
await this.loadScopedSchemas(cap);
|
|
7927
|
+
const schema = this.globalSettingsSchema(cap) ?? this.scopedFormSchema(cap);
|
|
7896
7928
|
if (!schema) return { sections: [] };
|
|
7897
7929
|
const projected = await this.readRawProjectedStore(nodeId, cap);
|
|
7898
7930
|
return hydrateSchema(schema, overlay ? await this.overlayKeepingMarkers(projected, overlay) : projected, { inlineSecretsAsViews: true });
|
|
@@ -7927,10 +7959,9 @@ var BaseAddon = class {
|
|
|
7927
7959
|
*
|
|
7928
7960
|
* Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
|
|
7929
7961
|
* needs its connection fields, the default integration the addon's own sections. It is the
|
|
7930
|
-
* SHAPE of the form only — the values live
|
|
7931
|
-
* unchanged (`integrations.setSettings` for an account integration).
|
|
7962
|
+
* SHAPE of the form only — the values live on the instance record.
|
|
7932
7963
|
*/
|
|
7933
|
-
async
|
|
7964
|
+
async integrationFormSchema(_instance) {
|
|
7934
7965
|
return null;
|
|
7935
7966
|
}
|
|
7936
7967
|
/**
|
|
@@ -7976,7 +8007,7 @@ var BaseAddon = class {
|
|
|
7976
8007
|
* per-instance schema when it declares one, else its global schema (what they always showed).
|
|
7977
8008
|
*/
|
|
7978
8009
|
async getIntegrationFormSchema(instance, nodeId) {
|
|
7979
|
-
const scoped = await this.
|
|
8010
|
+
const scoped = await this.integrationFormSchema(instance);
|
|
7980
8011
|
if (scoped === null) return this.getGlobalSettings(void 0, void 0, nodeId);
|
|
7981
8012
|
return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
|
|
7982
8013
|
}
|
|
@@ -8024,6 +8055,7 @@ var BaseAddon = class {
|
|
|
8024
8055
|
* resolved blob back is a no-op for every unchanged secret.
|
|
8025
8056
|
*/
|
|
8026
8057
|
async resolveGlobalStore(nodeId, cap) {
|
|
8058
|
+
await this.loadScopedSchemas(cap);
|
|
8027
8059
|
const raw = await this._ctx?.settings?.readAddonStore() ?? {};
|
|
8028
8060
|
return this.projectForNode(raw, nodeId, cap);
|
|
8029
8061
|
}
|
|
@@ -8034,6 +8066,7 @@ var BaseAddon = class {
|
|
|
8034
8066
|
}
|
|
8035
8067
|
/** The PROJECTED store with its markers — the form hydrate only (D798). */
|
|
8036
8068
|
async readRawProjectedStore(nodeId, cap) {
|
|
8069
|
+
await this.loadScopedSchemas(cap);
|
|
8037
8070
|
const raw = await this.rawSettings()?.readAddonStore() ?? {};
|
|
8038
8071
|
return this.projectForNode(raw, nodeId, cap);
|
|
8039
8072
|
}
|
|
@@ -8136,6 +8169,7 @@ var BaseAddon = class {
|
|
|
8136
8169
|
await this.applyGlobalPatch(patch, nodeId);
|
|
8137
8170
|
}
|
|
8138
8171
|
async applyGlobalPatch(barePatch, nodeId) {
|
|
8172
|
+
await this.loadScopedSchemas();
|
|
8139
8173
|
const keys = this.perNodeKeys();
|
|
8140
8174
|
const localNode = normalizeNodeId(this._ctx?.kernel?.localNodeId);
|
|
8141
8175
|
const target = normalizeNodeId(nodeId ?? this._ctx?.kernel?.localNodeId);
|
|
@@ -8149,7 +8183,8 @@ var BaseAddon = class {
|
|
|
8149
8183
|
await this.resolveConfig();
|
|
8150
8184
|
await this.onConfigChanged();
|
|
8151
8185
|
this.emitLifecycle(EventCategory.AddonUpdated, { level: "global" });
|
|
8152
|
-
|
|
8186
|
+
const legacy = this.globalSettingsSchema();
|
|
8187
|
+
this.maybeAutoRestart(Object.keys(barePatch), [...legacy === null ? [] : [legacy], ...this.loadedScopedSchemas().map((entry) => entry.schema)]);
|
|
8153
8188
|
}
|
|
8154
8189
|
/**
|
|
8155
8190
|
* The set of field keys the global settings schema declares `perNode: true`
|
|
@@ -8157,14 +8192,67 @@ var BaseAddon = class {
|
|
|
8157
8192
|
* declarations). Empty set ⇒ every per-node code path is bypassed and the
|
|
8158
8193
|
* settings API behaves exactly like the legacy node-agnostic one.
|
|
8159
8194
|
*/
|
|
8160
|
-
|
|
8195
|
+
/**
|
|
8196
|
+
* Load the scoped schemas of every capability this addon declares (the override and the
|
|
8197
|
+
* providers registered at init, plus `extraCap`) that is not loaded yet, then drop what was
|
|
8198
|
+
* derived from the previous set. Idempotent.
|
|
8199
|
+
*/
|
|
8200
|
+
async loadScopedSchemas(extraCap) {
|
|
8201
|
+
const caps = new Set([
|
|
8202
|
+
...this.scopedSettingsCapabilities(),
|
|
8203
|
+
...this._registeredCapNames,
|
|
8204
|
+
...extraCap === void 0 ? [] : [extraCap]
|
|
8205
|
+
]);
|
|
8206
|
+
let added = false;
|
|
8207
|
+
for (const cap of caps) {
|
|
8208
|
+
if (this._scopedByCap.has(cap)) continue;
|
|
8209
|
+
const loaded = [];
|
|
8210
|
+
for (const scope of SCOPED_SETTINGS_SCOPES) {
|
|
8211
|
+
const schema = await this.getScopedSettingsSchema(scope, cap);
|
|
8212
|
+
if (schema !== null) loaded.push({
|
|
8213
|
+
scope,
|
|
8214
|
+
schema
|
|
8215
|
+
});
|
|
8216
|
+
}
|
|
8217
|
+
this._scopedByCap.set(cap, loaded);
|
|
8218
|
+
added = true;
|
|
8219
|
+
}
|
|
8220
|
+
if (!added) return;
|
|
8221
|
+
this._nodeKeysByCap = /* @__PURE__ */ new Map();
|
|
8222
|
+
this._addonSecretTree = null;
|
|
8223
|
+
}
|
|
8224
|
+
/**
|
|
8225
|
+
* The form the settings API serves while an addon declares no {@link globalSettingsSchema}: the
|
|
8226
|
+
* sections of its scoped schemas, so dropping the old hook does not blank the form.
|
|
8227
|
+
*/
|
|
8228
|
+
scopedFormSchema(cap) {
|
|
8229
|
+
const byId = /* @__PURE__ */ new Map();
|
|
8230
|
+
for (const entry of this.loadedScopedSchemas(cap)) for (const section of entry.schema.sections) if (!byId.has(section.id)) byId.set(section.id, section);
|
|
8231
|
+
return byId.size === 0 ? null : { sections: [...byId.values()] };
|
|
8232
|
+
}
|
|
8233
|
+
/** Every loaded scoped schema of `cap`, or of every loaded capability. */
|
|
8234
|
+
loadedScopedSchemas(cap) {
|
|
8235
|
+
if (cap !== void 0) return this._scopedByCap.get(cap) ?? [];
|
|
8236
|
+
return [...this._scopedByCap.values()].flat();
|
|
8237
|
+
}
|
|
8238
|
+
/**
|
|
8239
|
+
* The field keys that are stored per node: every field of a {@link nodeSettingsSchema}, plus
|
|
8240
|
+
* the fields the legacy {@link globalSettingsSchema} still marks `perNode: true`. Derived once
|
|
8241
|
+
* per `cap` argument and memoized (schemas are static declarations). Empty set ⇒ every
|
|
8242
|
+
* per-node code path is bypassed and the settings API behaves like the node-agnostic one.
|
|
8243
|
+
* Call {@link loadScopedSchemas} first (the async seams do).
|
|
8244
|
+
*/
|
|
8161
8245
|
perNodeKeys(cap) {
|
|
8162
8246
|
const cacheKey = cap ?? "";
|
|
8163
|
-
const cached = this.
|
|
8247
|
+
const cached = this._nodeKeysByCap.get(cacheKey);
|
|
8164
8248
|
if (cached) return cached;
|
|
8165
|
-
const
|
|
8166
|
-
const keys = new Set(
|
|
8167
|
-
this.
|
|
8249
|
+
const legacy = this.globalSettingsSchema(cap);
|
|
8250
|
+
const keys = new Set(legacy ? legacy.sections.flatMap((section) => collectPerNodeFieldKeys(section.fields)) : []);
|
|
8251
|
+
for (const { scope, schema } of this.loadedScopedSchemas(cap)) {
|
|
8252
|
+
if (scope !== "node") continue;
|
|
8253
|
+
for (const section of schema.sections) for (const key of collectValueFieldKeys(section.fields)) keys.add(key);
|
|
8254
|
+
}
|
|
8255
|
+
this._nodeKeysByCap.set(cacheKey, keys);
|
|
8168
8256
|
return keys;
|
|
8169
8257
|
}
|
|
8170
8258
|
/**
|
|
@@ -8174,10 +8262,9 @@ var BaseAddon = class {
|
|
|
8174
8262
|
* time to return its response before the addon is torn down and
|
|
8175
8263
|
* re-initialised by `AddonRegistryService.restartAddon`.
|
|
8176
8264
|
*/
|
|
8177
|
-
maybeAutoRestart(patchKeys,
|
|
8178
|
-
if (!schema) return;
|
|
8265
|
+
maybeAutoRestart(patchKeys, schemas) {
|
|
8179
8266
|
const restartKeys = /* @__PURE__ */ new Set();
|
|
8180
|
-
for (const section of schema.sections) for (const field of section.fields) {
|
|
8267
|
+
for (const schema of schemas) for (const section of schema.sections) for (const field of section.fields) {
|
|
8181
8268
|
if (field.type === "separator" || field.type === "info") continue;
|
|
8182
8269
|
if (field.requiresRestart) restartKeys.add(field.key);
|
|
8183
8270
|
}
|
|
@@ -8373,12 +8460,14 @@ var BaseAddon = class {
|
|
|
8373
8460
|
* here, in the addon's own process, so the hub keeps no copy of it.
|
|
8374
8461
|
*/
|
|
8375
8462
|
async getDeclaredSettingsKeys() {
|
|
8463
|
+
await this.loadScopedSchemas();
|
|
8376
8464
|
return { keys: [...this.declaredKeySet()].toSorted() };
|
|
8377
8465
|
}
|
|
8378
8466
|
declaredKeySet() {
|
|
8379
8467
|
const keys = new Set(Object.keys(this.defaults));
|
|
8380
8468
|
const schema = this.globalSettingsSchema();
|
|
8381
8469
|
if (schema) for (const section of schema.sections) for (const key of collectFieldKeys(section.fields)) keys.add(key);
|
|
8470
|
+
for (const { schema: scoped } of this.loadedScopedSchemas()) for (const section of scoped.sections) for (const key of collectFieldKeys(section.fields)) keys.add(key);
|
|
8382
8471
|
for (const key of this._declaredStateKeys) keys.add(key);
|
|
8383
8472
|
for (const path of this.secretStatePaths) {
|
|
8384
8473
|
const root = path.split(/[.[]/, 1)[0];
|
|
@@ -8474,7 +8563,11 @@ var BaseAddon = class {
|
|
|
8474
8563
|
}
|
|
8475
8564
|
/** The addon store's secret tree: schema fields by TYPE, plus `secretStatePaths`. */
|
|
8476
8565
|
addonSecretTree() {
|
|
8477
|
-
this._addonSecretTree
|
|
8566
|
+
if (this._addonSecretTree === null) {
|
|
8567
|
+
const tree = new Map(secretTreeFromSchema(this.globalSettingsSchema()));
|
|
8568
|
+
for (const { schema } of this.loadedScopedSchemas()) for (const [key, node] of secretTreeFromSchema(schema)) tree.set(key, node);
|
|
8569
|
+
this._addonSecretTree = mergeSecretStatePaths(tree, this.secretStatePaths);
|
|
8570
|
+
}
|
|
8478
8571
|
return this._addonSecretTree;
|
|
8479
8572
|
}
|
|
8480
8573
|
deviceSecretTree() {
|
|
@@ -8724,6 +8817,23 @@ function dropPerNodeFields(fields) {
|
|
|
8724
8817
|
}
|
|
8725
8818
|
return kept;
|
|
8726
8819
|
}
|
|
8820
|
+
/** The keys of the value-holding fields, recursing into layout containers. */
|
|
8821
|
+
function collectValueFieldKeys(fields) {
|
|
8822
|
+
const collected = [];
|
|
8823
|
+
for (const field of fields) {
|
|
8824
|
+
if (field.type === "group") {
|
|
8825
|
+
collected.push(...collectValueFieldKeys(field.fields));
|
|
8826
|
+
continue;
|
|
8827
|
+
}
|
|
8828
|
+
if (field.type === "sub-tabs") {
|
|
8829
|
+
for (const tab of field.tabs) collected.push(...collectValueFieldKeys(tab.fields));
|
|
8830
|
+
continue;
|
|
8831
|
+
}
|
|
8832
|
+
if (field.type === "separator" || field.type === "info") continue;
|
|
8833
|
+
if ("key" in field && typeof field.key === "string") collected.push(field.key);
|
|
8834
|
+
}
|
|
8835
|
+
return collected;
|
|
8836
|
+
}
|
|
8727
8837
|
function collectFieldKeys(fields) {
|
|
8728
8838
|
const collected = [];
|
|
8729
8839
|
for (const field of fields) {
|
|
@@ -8816,6 +8926,10 @@ var RECORD_SETTINGS_MAX_ROWS = 5e4;
|
|
|
8816
8926
|
* (`collectZodSecretPaths`): dotted keys, `[]` for "each element of this array"
|
|
8817
8927
|
* (`auth.accessToken`, `headers[].value`).
|
|
8818
8928
|
*
|
|
8929
|
+
* `{}` after a key means "each value of this map" (`applianceSecrets{}`): the map's own key
|
|
8930
|
+
* names the value (`applianceSecrets{fridge}`), so no id key is declared and a body that drops a
|
|
8931
|
+
* key releases exactly that key's secret.
|
|
8932
|
+
*
|
|
8819
8933
|
* Array elements are matched by a DECLARED id key (`secretArrayKeys`:
|
|
8820
8934
|
* `{ headers: 'name' }`), never by index, so reordering a list keeps every
|
|
8821
8935
|
* keychain ref (the same rule as `arrayItemFieldPath`). The concrete path of a
|
|
@@ -8828,11 +8942,13 @@ function parseSecretPath(path) {
|
|
|
8828
8942
|
if (path.length === 0) throw new InvalidRecordError("an empty secret path");
|
|
8829
8943
|
return path.split(".").map((raw) => {
|
|
8830
8944
|
const each = raw.endsWith("[]");
|
|
8831
|
-
const
|
|
8945
|
+
const map = raw.endsWith("{}");
|
|
8946
|
+
const key = each || map ? raw.slice(0, -2) : raw;
|
|
8832
8947
|
if (key.length === 0) throw new InvalidRecordError(`secret path "${path}" has an empty segment`);
|
|
8833
8948
|
return {
|
|
8834
8949
|
key,
|
|
8835
|
-
each
|
|
8950
|
+
each,
|
|
8951
|
+
map
|
|
8836
8952
|
};
|
|
8837
8953
|
});
|
|
8838
8954
|
}
|
|
@@ -8919,7 +9035,8 @@ function isZodSecret(schema) {
|
|
|
8919
9035
|
}
|
|
8920
9036
|
/**
|
|
8921
9037
|
* Every declared secret path in a config schema: dotted keys, `[]` for "each
|
|
8922
|
-
* element of this array" (`connection.password`, `rows[].token`)
|
|
9038
|
+
* element of this array" (`connection.password`, `rows[].token`), `{}` for "each value of this
|
|
9039
|
+
* map" (`applianceSecrets{}`). A declared
|
|
8923
9040
|
* object or array is reported as one path and not descended into — everything
|
|
8924
9041
|
* under it is secret.
|
|
8925
9042
|
*/
|
|
@@ -8930,6 +9047,7 @@ function collectZodSecretPaths(schema, prefix = "") {
|
|
|
8930
9047
|
const def = defOf(layer);
|
|
8931
9048
|
if (def.type === "object" && def.shape) for (const [key, child] of Object.entries(def.shape)) paths.push(...collectZodSecretPaths(child, prefix ? `${prefix}.${key}` : key));
|
|
8932
9049
|
else if (def.type === "array" && def.element) paths.push(...collectZodSecretPaths(def.element, `${prefix}[]`));
|
|
9050
|
+
else if (def.type === "record" && def.valueType) paths.push(...collectZodSecretPaths(def.valueType, `${prefix}{}`));
|
|
8933
9051
|
else if (def.type === "union" && def.options) for (const option of def.options) paths.push(...collectZodSecretPaths(option, prefix));
|
|
8934
9052
|
else if (def.type === "intersection") {
|
|
8935
9053
|
if (def.left) paths.push(...collectZodSecretPaths(def.left, prefix));
|
|
@@ -9069,7 +9187,7 @@ function defineRecordKinds(specs) {
|
|
|
9069
9187
|
retention: spec.retention,
|
|
9070
9188
|
deviceRemoval: spec.deviceRemoval,
|
|
9071
9189
|
maxDataBytes: spec.maxDataBytes,
|
|
9072
|
-
secretPaths: [...secretPaths],
|
|
9190
|
+
secretPaths: [...new Set([...secretPaths, ...spec.retiredSecretPaths ?? []])],
|
|
9073
9191
|
secretArrayKeys: spec.secretArrayKeys === void 0 ? void 0 : { ...spec.secretArrayKeys },
|
|
9074
9192
|
transactFamily: spec.transactFamily,
|
|
9075
9193
|
entry: spec.entry === void 0 ? void 0 : {
|
|
@@ -11978,7 +12096,7 @@ function sleep(ms) {
|
|
|
11978
12096
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
11979
12097
|
}
|
|
11980
12098
|
//#endregion
|
|
11981
|
-
//#region ../types/dist/composition-
|
|
12099
|
+
//#region ../types/dist/composition-pOHbTzRB.mjs
|
|
11982
12100
|
/**
|
|
11983
12101
|
* Deterministic SHA-256 hash of an arbitrary serialisable value. The
|
|
11984
12102
|
* canonical form sorts object keys alphabetically at every depth so two
|
|
@@ -14647,7 +14765,13 @@ var MigrationLedgerEntrySchema = object({
|
|
|
14647
14765
|
* joined by the engine from the catalogues it knows this boot. Absent when no
|
|
14648
14766
|
* catalogue lists the id (a newer database).
|
|
14649
14767
|
*/
|
|
14650
|
-
meta: MigrationMetaSchema.optional()
|
|
14768
|
+
meta: MigrationMetaSchema.optional(),
|
|
14769
|
+
/**
|
|
14770
|
+
* Set when this is an applied row of an addon owner whose catalogue the answering
|
|
14771
|
+
* process has not loaded (the owner has not declared yet): the row is applied, the
|
|
14772
|
+
* process just cannot judge it. Never `skipped-newer` — that needs the owner loaded.
|
|
14773
|
+
*/
|
|
14774
|
+
ownerNotLoaded: boolean().optional()
|
|
14651
14775
|
});
|
|
14652
14776
|
/** A catalogued migration that is not applied, with where it stands. */
|
|
14653
14777
|
var MigrationPendingEntrySchema = object({
|
|
@@ -51179,6 +51303,9 @@ var RunningProposalEvidenceSchema = object({
|
|
|
51179
51303
|
runsFound: number().int().nonnegative(),
|
|
51180
51304
|
pausesFound: number().int().nonnegative(),
|
|
51181
51305
|
longestPauseMs: number().nonnegative(),
|
|
51306
|
+
/** Episodes shorter than ~90 s (an anti-crease pulse, a display waking): never a run, never a pause. */
|
|
51307
|
+
pulsesFound: number().int().nonnegative(),
|
|
51308
|
+
longestPulseMs: number().nonnegative(),
|
|
51182
51309
|
idleFloorW: number(),
|
|
51183
51310
|
noiseCeilingW: number(),
|
|
51184
51311
|
plateauW: number(),
|
|
@@ -52469,7 +52596,27 @@ method(object({
|
|
|
52469
52596
|
* exposes only the COMMON surface: link state, supported device
|
|
52470
52597
|
* kinds (so the UI can filter the device picker), and per-device
|
|
52471
52598
|
* expose/unexpose.
|
|
52472
|
-
|
|
52599
|
+
*
|
|
52600
|
+
* INSTANCES. One export addon can serve several independent targets (a
|
|
52601
|
+
* HomeKit bridge, a Home Assistant broker). `listInstances` names them.
|
|
52602
|
+
* `instanceId` on a READ is optional: absent = the whole addon (linked if any
|
|
52603
|
+
* enabled instance is, `exposedDeviceCount` = distinct devices, `setup` = the
|
|
52604
|
+
* default instance's); present = that instance; an id the provider does not
|
|
52605
|
+
* serve is refused with `ExportInstanceUnknownError` (`export-instance-unknown`),
|
|
52606
|
+
* never answered empty. `instanceId` on a WRITE is REQUIRED: a membership
|
|
52607
|
+
* change always names the target it changes. A single-instance provider
|
|
52608
|
+
* accepts an absent id on a read or its own id, and refuses any other.
|
|
52609
|
+
*/
|
|
52610
|
+
/** Which instance of an export addon a call addresses. Absent on a read = the whole addon. */
|
|
52611
|
+
var InstanceIdSchema$1 = string().min(1);
|
|
52612
|
+
var InstancePinSchema = object({ instanceId: InstanceIdSchema$1.optional() });
|
|
52613
|
+
/** One independent export target of an addon. */
|
|
52614
|
+
var ExportInstanceSchema = object({
|
|
52615
|
+
instanceId: InstanceIdSchema$1,
|
|
52616
|
+
name: string(),
|
|
52617
|
+
enabled: boolean(),
|
|
52618
|
+
kind: string().optional()
|
|
52619
|
+
});
|
|
52473
52620
|
var LinkStateSchema = _enum([
|
|
52474
52621
|
"unlinked",
|
|
52475
52622
|
"linked",
|
|
@@ -52520,10 +52667,14 @@ var ExposedDeviceSchema = object({
|
|
|
52520
52667
|
capabilities: array(string()).optional()
|
|
52521
52668
|
});
|
|
52522
52669
|
var ExposeInputSchema = object({
|
|
52670
|
+
instanceId: InstanceIdSchema$1,
|
|
52523
52671
|
deviceId: string(),
|
|
52524
52672
|
capabilities: array(string()).optional()
|
|
52525
52673
|
});
|
|
52526
|
-
var UnexposeInputSchema = object({
|
|
52674
|
+
var UnexposeInputSchema = object({
|
|
52675
|
+
instanceId: InstanceIdSchema$1,
|
|
52676
|
+
deviceId: string()
|
|
52677
|
+
});
|
|
52527
52678
|
/**
|
|
52528
52679
|
* What an exporter may expose besides devices (D968). An action and a
|
|
52529
52680
|
* notification target are LIST ENTRIES, never devices (D954): they enter an
|
|
@@ -52552,15 +52703,21 @@ var ExposedEntitySchema = object({
|
|
|
52552
52703
|
entity: ExportEntityRefSchema,
|
|
52553
52704
|
exposedAs: string().optional()
|
|
52554
52705
|
});
|
|
52555
|
-
var ExposeEntityInputSchema = object({
|
|
52556
|
-
|
|
52557
|
-
|
|
52706
|
+
var ExposeEntityInputSchema = object({
|
|
52707
|
+
instanceId: InstanceIdSchema$1,
|
|
52708
|
+
entity: ExportEntityRefSchema
|
|
52709
|
+
});
|
|
52710
|
+
var UnexposeEntityInputSchema = object({
|
|
52711
|
+
instanceId: InstanceIdSchema$1,
|
|
52712
|
+
entity: ExportEntityRefSchema
|
|
52713
|
+
});
|
|
52714
|
+
method(InstancePinSchema, DeviceExportStatusSchema), method(_void(), array(ExportInstanceSchema)), method(InstancePinSchema, array(DeviceKindSchema)), method(InstancePinSchema, array(ExposedDeviceSchema)), method(ExposeInputSchema, _void(), {
|
|
52558
52715
|
kind: "mutation",
|
|
52559
52716
|
auth: "admin"
|
|
52560
52717
|
}), method(UnexposeInputSchema, _void(), {
|
|
52561
52718
|
kind: "mutation",
|
|
52562
52719
|
auth: "admin"
|
|
52563
|
-
}), optionalMethod(_void(), array(ExportEntityKindSchema)), optionalMethod(
|
|
52720
|
+
}), optionalMethod(_void(), array(ExportEntityKindSchema)), optionalMethod(InstancePinSchema, array(ExposedEntitySchema)), optionalMethod(ExposeEntityInputSchema, _void(), {
|
|
52564
52721
|
kind: "mutation",
|
|
52565
52722
|
auth: "admin"
|
|
52566
52723
|
}), optionalMethod(UnexposeEntityInputSchema, _void(), {
|
|
@@ -57061,11 +57218,7 @@ var CreateIntegrationInputSchema = object({
|
|
|
57061
57218
|
info: record(string(), unknown()).optional(),
|
|
57062
57219
|
/** `stableId` of the discovery candidate the form was seeded from (D984). */
|
|
57063
57220
|
originStableId: string().optional(),
|
|
57064
|
-
settings: record(string(), unknown()).optional()
|
|
57065
|
-
/** Keys of `settings` the form's schema declares secret (by type) — kept in
|
|
57066
|
-
* the keychain, not the table (D787). */
|
|
57067
|
-
secretKeys: array(string()).optional(),
|
|
57068
|
-
skipRestart: boolean().optional()
|
|
57221
|
+
settings: record(string(), unknown()).optional()
|
|
57069
57222
|
});
|
|
57070
57223
|
var UpdateIntegrationInputSchema = object({
|
|
57071
57224
|
id: string(),
|
|
@@ -57086,16 +57239,6 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
|
|
|
57086
57239
|
}), method(object({ id: string() }), DeleteIntegrationResultSchema, {
|
|
57087
57240
|
kind: "mutation",
|
|
57088
57241
|
auth: "admin"
|
|
57089
|
-
}), method(object({ id: string() }), record(string(), unknown()), { auth: "admin" }), method(object({
|
|
57090
|
-
id: string(),
|
|
57091
|
-
settings: record(string(), unknown()),
|
|
57092
|
-
/** Keys the form's schema declares secret (by type) — keychain-stored (D787). */
|
|
57093
|
-
secretKeys: array(string()).optional(),
|
|
57094
|
-
/** The integration's own addon applies the change in-process and asks the hub not to respawn it. */
|
|
57095
|
-
skipRestart: boolean().optional()
|
|
57096
|
-
}), object({ success: boolean() }), {
|
|
57097
|
-
kind: "mutation",
|
|
57098
|
-
auth: "admin"
|
|
57099
57242
|
}), method(_void(), array(AvailableIntegrationTypeSchema), { auth: "admin" }), method(object({
|
|
57100
57243
|
addonId: string(),
|
|
57101
57244
|
settings: record(string(), unknown())
|
|
@@ -57124,13 +57267,65 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
|
|
|
57124
57267
|
*/
|
|
57125
57268
|
var ConfigSchemaPassthrough$3 = custom();
|
|
57126
57269
|
var IntegrationInstanceIdSchema = string().min(1);
|
|
57270
|
+
var IntegrationInstanceModeSchema = _enum(["single", "multiple"]);
|
|
57271
|
+
/**
|
|
57272
|
+
* One kind of instance a provider can create (an adapter, an account type). The sign-in and
|
|
57273
|
+
* connect fields follow the `broker` contract (`broker.cap.ts`): `signIn.basePath` is a
|
|
57274
|
+
* hub-relative route set speaking the sign-in contract, `connectPath` / `disconnectPath` open an
|
|
57275
|
+
* interactive account link (popup) and may carry `{{brokerId}}`, which the UI replaces with the
|
|
57276
|
+
* instance id.
|
|
57277
|
+
*/
|
|
57278
|
+
var IntegrationInstanceKindSchema = object({
|
|
57279
|
+
/** Stable id of the kind, sent back as `createInstance.kind`. */
|
|
57280
|
+
id: string().min(1),
|
|
57281
|
+
label: string().min(1),
|
|
57282
|
+
/** The kind signs in through a server-held interactive session. */
|
|
57283
|
+
signIn: object({
|
|
57284
|
+
basePath: string().min(1),
|
|
57285
|
+
methods: array(_enum(["device-code", "proxy"])).optional()
|
|
57286
|
+
}).optional(),
|
|
57287
|
+
/** Relative hub path to start an interactive account link of an instance of this kind. */
|
|
57288
|
+
connectPath: string().min(1).optional(),
|
|
57289
|
+
/** Relative hub path to disconnect that account. */
|
|
57290
|
+
disconnectPath: string().min(1).optional()
|
|
57291
|
+
});
|
|
57127
57292
|
var IntegrationInstanceDescriptionSchema = object({
|
|
57293
|
+
/** What the instances are for the Integrations page; see {@link IntegrationInstanceRoleSchema}. */
|
|
57294
|
+
role: _enum([
|
|
57295
|
+
"devices",
|
|
57296
|
+
"services",
|
|
57297
|
+
"both"
|
|
57298
|
+
]),
|
|
57299
|
+
/** How the devices of an instance are found; absent means `{ mode: 'none' }`. */
|
|
57300
|
+
discovery: object({
|
|
57301
|
+
mode: _enum([
|
|
57302
|
+
"none",
|
|
57303
|
+
"lan",
|
|
57304
|
+
"account"
|
|
57305
|
+
]),
|
|
57306
|
+
scopedToInstance: boolean()
|
|
57307
|
+
}).optional(),
|
|
57128
57308
|
/** `single`: at most one instance can exist (Loki). `multiple`: an account each. */
|
|
57129
|
-
instanceMode:
|
|
57309
|
+
instanceMode: IntegrationInstanceModeSchema,
|
|
57130
57310
|
/** What the instance is, for the UI (`destination`, `relay`, `account`). */
|
|
57131
57311
|
kind: string(),
|
|
57132
57312
|
/** True when `testInstance` really probes the remote. */
|
|
57133
|
-
canTest: boolean()
|
|
57313
|
+
canTest: boolean(),
|
|
57314
|
+
/**
|
|
57315
|
+
* The kinds an instance can be of. Absent or one entry: nothing to choose; more than one: the
|
|
57316
|
+
* Add flow asks which first and sends it as `createInstance.kind`.
|
|
57317
|
+
*/
|
|
57318
|
+
kinds: array(IntegrationInstanceKindSchema).optional(),
|
|
57319
|
+
/**
|
|
57320
|
+
* The provider accepts `createInstance.id` for an id that once existed (an adopted id, because
|
|
57321
|
+
* devices carry it). The UI then offers "restore under its old id" on Add. Absent means no.
|
|
57322
|
+
*/
|
|
57323
|
+
allowRestoreId: boolean().optional(),
|
|
57324
|
+
/**
|
|
57325
|
+
* `createInstance` without an `id` works: the provider mints it. Absent means the caller must
|
|
57326
|
+
* send an id (the UI then mints an opaque one).
|
|
57327
|
+
*/
|
|
57328
|
+
mintsId: boolean().optional()
|
|
57134
57329
|
});
|
|
57135
57330
|
var IntegrationInstanceStatusSchema = object({
|
|
57136
57331
|
state: _enum([
|
|
@@ -57139,7 +57334,9 @@ var IntegrationInstanceStatusSchema = object({
|
|
|
57139
57334
|
"error",
|
|
57140
57335
|
"unknown"
|
|
57141
57336
|
]),
|
|
57142
|
-
detail: string().optional()
|
|
57337
|
+
detail: string().optional(),
|
|
57338
|
+
/** A short human word for the state ("Signed in", "Token expired"); shown instead of `state`. */
|
|
57339
|
+
label: string().optional()
|
|
57143
57340
|
});
|
|
57144
57341
|
var IntegrationInstanceSchema = object({
|
|
57145
57342
|
id: IntegrationInstanceIdSchema,
|
|
@@ -57147,13 +57344,18 @@ var IntegrationInstanceSchema = object({
|
|
|
57147
57344
|
/** The addon's own rule (an URL is present, a client id is present...). */
|
|
57148
57345
|
configured: boolean(),
|
|
57149
57346
|
/**
|
|
57150
|
-
* The instance's own on/off switch (D996)
|
|
57151
|
-
*
|
|
57347
|
+
* The instance's own on/off switch (D996), derived from the record body (`enabled !== false`,
|
|
57348
|
+
* so a row written before the field existed is on). Absent when the `integrations` registry
|
|
57349
|
+
* owns the switch (`describe().role` is `devices`): read it from the registry row.
|
|
57152
57350
|
*/
|
|
57153
|
-
enabled: boolean(),
|
|
57351
|
+
enabled: boolean().optional(),
|
|
57352
|
+
/** The kind of this instance (one of `describe().kinds[].id`), when the provider has kinds. */
|
|
57353
|
+
kind: string().optional(),
|
|
57154
57354
|
/** Values for the instance form; a secret is a `SecretFieldView`, never text. */
|
|
57155
57355
|
formValues: record(string(), unknown()),
|
|
57156
|
-
status: IntegrationInstanceStatusSchema.optional()
|
|
57356
|
+
status: IntegrationInstanceStatusSchema.optional(),
|
|
57357
|
+
/** Epoch ms of the last probe of the remote that produced `status`; absent when never checked. */
|
|
57358
|
+
lastCheckedAt: number().optional()
|
|
57157
57359
|
});
|
|
57158
57360
|
var IntegrationInstancePatchSchema = object({
|
|
57159
57361
|
id: IntegrationInstanceIdSchema,
|
|
@@ -57162,8 +57364,9 @@ var IntegrationInstancePatchSchema = object({
|
|
|
57162
57364
|
values: record(string(), unknown())
|
|
57163
57365
|
});
|
|
57164
57366
|
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({
|
|
57165
|
-
id: IntegrationInstanceIdSchema,
|
|
57166
|
-
name: string().min(1)
|
|
57367
|
+
id: IntegrationInstanceIdSchema.optional(),
|
|
57368
|
+
name: string().min(1),
|
|
57369
|
+
kind: string().min(1).optional()
|
|
57167
57370
|
}), object({ id: string() }), {
|
|
57168
57371
|
kind: "mutation",
|
|
57169
57372
|
auth: "admin"
|
|
@@ -59323,6 +59526,11 @@ var LogEntrySchema = object({
|
|
|
59323
59526
|
* flight, and not asking for the next slice ends the scan.
|
|
59324
59527
|
*/
|
|
59325
59528
|
var LogReadQuerySchema = object({
|
|
59529
|
+
/**
|
|
59530
|
+
* Which destination INSTANCE answers (a destination addon may hold several records). Absent ⇒
|
|
59531
|
+
* the provider's first readable one, so a caller written before instances existed is unchanged.
|
|
59532
|
+
*/
|
|
59533
|
+
instanceId: string().min(1).max(200).optional(),
|
|
59326
59534
|
/** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
|
|
59327
59535
|
requestId: string().min(1).max(64).optional(),
|
|
59328
59536
|
/** The device the line is about (`tags.deviceId`, numeric). */
|
|
@@ -59385,6 +59593,8 @@ var LogReadResultSchema = object({
|
|
|
59385
59593
|
/** True when `cancelRead` ended this slice early. */
|
|
59386
59594
|
cancelled: boolean().optional()
|
|
59387
59595
|
});
|
|
59596
|
+
/** Names one destination instance; absent ⇒ the provider's first readable one. */
|
|
59597
|
+
var LogInstanceSelectorSchema = object({ instanceId: string().min(1).max(200).optional() });
|
|
59388
59598
|
var LogReadCapabilitiesSchema = object({
|
|
59389
59599
|
/** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
|
|
59390
59600
|
readable: boolean(),
|
|
@@ -59403,7 +59613,7 @@ var LogReadCapabilitiesSchema = object({
|
|
|
59403
59613
|
/** How far back the store reaches, when the provider knows (days). */
|
|
59404
59614
|
retentionDays: number().nullable()
|
|
59405
59615
|
});
|
|
59406
|
-
method(LogEntrySchema, _void(), { kind: "mutation" }), optionalMethod(
|
|
59616
|
+
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() }), {
|
|
59407
59617
|
kind: "mutation",
|
|
59408
59618
|
auth: "admin"
|
|
59409
59619
|
});
|
|
@@ -60100,6 +60310,27 @@ method(object({}), object({ entries: array(MigrationLedgerEntrySchema) }), { aut
|
|
|
60100
60310
|
}), {
|
|
60101
60311
|
kind: "mutation",
|
|
60102
60312
|
auth: "admin"
|
|
60313
|
+
}), method(object({ integrationId: string().min(1) }), record(string(), unknown()), { auth: "admin" }), method(object({ integrationId: string().min(1) }), object({
|
|
60314
|
+
rows: number().int().nonnegative(),
|
|
60315
|
+
secrets: number().int().nonnegative()
|
|
60316
|
+
}), {
|
|
60317
|
+
kind: "mutation",
|
|
60318
|
+
auth: "admin"
|
|
60319
|
+
}), method(object({
|
|
60320
|
+
integrationId: string().min(1),
|
|
60321
|
+
patch: record(string(), unknown())
|
|
60322
|
+
}), object({ written: boolean() }), {
|
|
60323
|
+
kind: "mutation",
|
|
60324
|
+
auth: "admin"
|
|
60325
|
+
}), method(object({
|
|
60326
|
+
integrationId: string().min(1),
|
|
60327
|
+
keys: array(string().min(1))
|
|
60328
|
+
}), object({
|
|
60329
|
+
present: boolean(),
|
|
60330
|
+
removed: record(string(), unknown())
|
|
60331
|
+
}), {
|
|
60332
|
+
kind: "mutation",
|
|
60333
|
+
auth: "admin"
|
|
60103
60334
|
});
|
|
60104
60335
|
method(object({
|
|
60105
60336
|
sourceUrl: string(),
|
|
@@ -83245,6 +83476,25 @@ function buildEventKindDescriptor(kind, source) {
|
|
|
83245
83476
|
}
|
|
83246
83477
|
};
|
|
83247
83478
|
}
|
|
83479
|
+
/**
|
|
83480
|
+
* What a remote key is CALLED and what it LOOKS like, for every role (D963),
|
|
83481
|
+
* shared by the admin UI and the viewer. A role is data on the wire; each
|
|
83482
|
+
* client resolves its name from `label` (English and Italian side by side) and
|
|
83483
|
+
* its glyph from `icon`, a lucide id from the shared icon catalogue — the
|
|
83484
|
+
* server sends an id, a client maps it to its own icon set.
|
|
83485
|
+
*
|
|
83486
|
+
* `legend` is text printed on the key INSTEAD of a glyph (a digit has no
|
|
83487
|
+
* pictogram): a client that can draw text shows it, one that cannot falls back
|
|
83488
|
+
* to `icon`.
|
|
83489
|
+
*/
|
|
83490
|
+
function digit(n) {
|
|
83491
|
+
return {
|
|
83492
|
+
label: t(n, n),
|
|
83493
|
+
icon: "hash",
|
|
83494
|
+
legend: n
|
|
83495
|
+
};
|
|
83496
|
+
}
|
|
83497
|
+
digit("0"), digit("1"), digit("2"), digit("3"), digit("4"), digit("5"), digit("6"), digit("7"), digit("8"), digit("9");
|
|
83248
83498
|
DeviceFeature.MediaPlayerPower, DeviceFeature.MediaPlayerVolumeStep, DeviceFeature.MediaPlayerChannelStep, DeviceFeature.MediaPlayerMute, DeviceFeature.MediaPlayerStop, DeviceFeature.MediaPlayerNext, DeviceFeature.MediaPlayerPrevious;
|
|
83249
83499
|
var btn = (idSuffix, row, col, init) => ({
|
|
83250
83500
|
idSuffix,
|
|
@@ -83383,11 +83633,15 @@ discriminatedUnion("kind", [object({
|
|
|
83383
83633
|
* 1. idle floor F = time-weighted median; noise ceiling N = highest value seen
|
|
83384
83634
|
* near F. A device that is not near one level most of the time has no floor.
|
|
83385
83635
|
* 2. coarse activity = above max(2N, N + 5 W); consecutive stretches are episodes.
|
|
83386
|
-
* 3.
|
|
83387
|
-
*
|
|
83636
|
+
* 3. an episode shorter than `PULSE_MAX_MS` is a PULSE (an anti-crease tumble, a
|
|
83637
|
+
* display waking): it is neither a run nor a pause. Among the remaining
|
|
83638
|
+
* episodes, gaps over `PAUSE_MAX_MS` always separate runs; the rest split in
|
|
83639
|
+
* two by the largest log-scale jump (>= 3x): the short ones are pauses INSIDE
|
|
83640
|
+
* a run (a soak), the long ones separate runs. A stretch under `MIN_RUN_MS`
|
|
83641
|
+
* is no run.
|
|
83388
83642
|
* 4. T = geometric mean of N and the plateau's 10th percentile, snapped to a
|
|
83389
|
-
* grid a person would type; stop dwell covers the longest pause
|
|
83390
|
-
* covers the longest standby blip above T.
|
|
83643
|
+
* grid a person would type; stop dwell covers the longest pause and the
|
|
83644
|
+
* kind's floor; start dwell covers the longest pulse and standby blip above T.
|
|
83391
83645
|
* 5. the numbers are proved by REPLAY through the real `dwell` evaluation: each
|
|
83392
83646
|
* run must hold exactly one true interval and nothing may flap outside.
|
|
83393
83647
|
*/
|
|
@@ -83398,6 +83652,10 @@ var MINUTE_MS$1 = 60 * SECOND_MS;
|
|
|
83398
83652
|
30 * SECOND_MS;
|
|
83399
83653
|
60 * SECOND_MS;
|
|
83400
83654
|
20 * MINUTE_MS$1;
|
|
83655
|
+
90 * SECOND_MS;
|
|
83656
|
+
30 * MINUTE_MS$1;
|
|
83657
|
+
10 * MINUTE_MS$1;
|
|
83658
|
+
DeviceType.Dryer, 3 * MINUTE_MS$1, DeviceType.Dishwasher, 3 * MINUTE_MS$1, DeviceType.Washer, 10 * MINUTE_MS$1;
|
|
83401
83659
|
10 * SECOND_MS;
|
|
83402
83660
|
10 * SECOND_MS;
|
|
83403
83661
|
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverStoppable, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
@@ -86582,6 +86840,13 @@ Object.freeze({
|
|
|
86582
86840
|
access: "view",
|
|
86583
86841
|
role: "admin"
|
|
86584
86842
|
},
|
|
86843
|
+
"deviceExport.listInstances": {
|
|
86844
|
+
capName: "device-export",
|
|
86845
|
+
capScope: "system",
|
|
86846
|
+
addonId: null,
|
|
86847
|
+
access: "view",
|
|
86848
|
+
role: "admin"
|
|
86849
|
+
},
|
|
86585
86850
|
"deviceExport.listSupportedDeviceKinds": {
|
|
86586
86851
|
capName: "device-export",
|
|
86587
86852
|
capScope: "system",
|
|
@@ -88269,13 +88534,6 @@ Object.freeze({
|
|
|
88269
88534
|
access: "view",
|
|
88270
88535
|
role: "admin"
|
|
88271
88536
|
},
|
|
88272
|
-
"integrations.getSettings": {
|
|
88273
|
-
capName: "integrations",
|
|
88274
|
-
capScope: "system",
|
|
88275
|
-
addonId: null,
|
|
88276
|
-
access: "view",
|
|
88277
|
-
role: "admin"
|
|
88278
|
-
},
|
|
88279
88537
|
"integrations.list": {
|
|
88280
88538
|
capName: "integrations",
|
|
88281
88539
|
capScope: "system",
|
|
@@ -88283,13 +88541,6 @@ Object.freeze({
|
|
|
88283
88541
|
access: "view",
|
|
88284
88542
|
role: "admin"
|
|
88285
88543
|
},
|
|
88286
|
-
"integrations.setSettings": {
|
|
88287
|
-
capName: "integrations",
|
|
88288
|
-
capScope: "system",
|
|
88289
|
-
addonId: null,
|
|
88290
|
-
access: "create",
|
|
88291
|
-
role: "admin"
|
|
88292
|
-
},
|
|
88293
88544
|
"integrations.testConnection": {
|
|
88294
88545
|
capName: "integrations",
|
|
88295
88546
|
capScope: "system",
|
|
@@ -89284,6 +89535,13 @@ Object.freeze({
|
|
|
89284
89535
|
access: "view",
|
|
89285
89536
|
role: "admin"
|
|
89286
89537
|
},
|
|
89538
|
+
"migrations.clearLegacyIntegrationRows": {
|
|
89539
|
+
capName: "migrations",
|
|
89540
|
+
capScope: "system",
|
|
89541
|
+
addonId: null,
|
|
89542
|
+
access: "delete",
|
|
89543
|
+
role: "admin"
|
|
89544
|
+
},
|
|
89287
89545
|
"migrations.declareOwner": {
|
|
89288
89546
|
capName: "migrations",
|
|
89289
89547
|
capScope: "system",
|
|
@@ -89291,6 +89549,13 @@ Object.freeze({
|
|
|
89291
89549
|
access: "create",
|
|
89292
89550
|
role: "admin"
|
|
89293
89551
|
},
|
|
89552
|
+
"migrations.deleteLegacyIntegrationRowKeys": {
|
|
89553
|
+
capName: "migrations",
|
|
89554
|
+
capScope: "system",
|
|
89555
|
+
addonId: null,
|
|
89556
|
+
access: "delete",
|
|
89557
|
+
role: "admin"
|
|
89558
|
+
},
|
|
89294
89559
|
"migrations.dryRun": {
|
|
89295
89560
|
capName: "migrations",
|
|
89296
89561
|
capScope: "system",
|
|
@@ -89326,6 +89591,20 @@ Object.freeze({
|
|
|
89326
89591
|
access: "create",
|
|
89327
89592
|
role: "admin"
|
|
89328
89593
|
},
|
|
89594
|
+
"migrations.patchLegacyIntegrationRows": {
|
|
89595
|
+
capName: "migrations",
|
|
89596
|
+
capScope: "system",
|
|
89597
|
+
addonId: null,
|
|
89598
|
+
access: "create",
|
|
89599
|
+
role: "admin"
|
|
89600
|
+
},
|
|
89601
|
+
"migrations.readLegacyIntegrationRows": {
|
|
89602
|
+
capName: "migrations",
|
|
89603
|
+
capScope: "system",
|
|
89604
|
+
addonId: null,
|
|
89605
|
+
access: "view",
|
|
89606
|
+
role: "admin"
|
|
89607
|
+
},
|
|
89329
89608
|
"migrations.restorePreMigration": {
|
|
89330
89609
|
capName: "migrations",
|
|
89331
89610
|
capScope: "system",
|