@riddix/hamh 2.1.0-alpha.455 → 2.1.0-alpha.456

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.
@@ -146556,6 +146556,13 @@ var init_lock_credential = __esm({
146556
146556
  }
146557
146557
  });
146558
146558
 
146559
+ // ../common/dist/mapping-profile.js
146560
+ var init_mapping_profile = __esm({
146561
+ "../common/dist/mapping-profile.js"() {
146562
+ "use strict";
146563
+ }
146564
+ });
146565
+
146559
146566
  // ../common/dist/schemas/bridge-config-schema.js
146560
146567
  var homeAssistantMatcherSchema, homeAssistantFilterSchema, featureFlagSchema, bridgeConfigSchema;
146561
146568
  var init_bridge_config_schema = __esm({
@@ -147034,6 +147041,7 @@ var init_dist = __esm({
147034
147041
  init_home_assistant_entity_state();
147035
147042
  init_home_assistant_filter();
147036
147043
  init_lock_credential();
147044
+ init_mapping_profile();
147037
147045
  init_schemas();
147038
147046
  init_utils();
147039
147047
  init_websocket_message();
@@ -147455,7 +147463,7 @@ import * as ws from "ws";
147455
147463
 
147456
147464
  // src/api/web-api.ts
147457
147465
  init_service();
147458
- import express14 from "express";
147466
+ import express15 from "express";
147459
147467
  import basicAuth from "express-basic-auth";
147460
147468
  import AccessControl5 from "express-ip-access-control";
147461
147469
  import nocache from "nocache";
@@ -148529,6 +148537,7 @@ function healthApi(bridgeService, haClient, version, startTime) {
148529
148537
  status: data.status,
148530
148538
  statusReason: data.statusReason,
148531
148539
  port: data.port,
148540
+ priority: data.priority ?? 100,
148532
148541
  deviceCount: data.deviceCount,
148533
148542
  fabricCount: fabrics.length,
148534
148543
  fabrics: fabrics.map((f) => ({
@@ -148893,10 +148902,165 @@ function lockCredentialApi(lockCredentialStorage) {
148893
148902
  return router;
148894
148903
  }
148895
148904
 
148905
+ // src/api/mapping-profile-api.ts
148906
+ import express10 from "express";
148907
+ function configToProfileEntry(config10) {
148908
+ const domain = config10.entityId.split(".")[0];
148909
+ return {
148910
+ domain,
148911
+ entityIdPattern: config10.entityId,
148912
+ matterDeviceType: config10.matterDeviceType,
148913
+ customName: config10.customName,
148914
+ disabled: config10.disabled,
148915
+ filterLifeEntity: config10.filterLifeEntity,
148916
+ cleaningModeEntity: config10.cleaningModeEntity,
148917
+ humidityEntity: config10.humidityEntity,
148918
+ pressureEntity: config10.pressureEntity,
148919
+ batteryEntity: config10.batteryEntity,
148920
+ roomEntities: config10.roomEntities,
148921
+ disableLockPin: config10.disableLockPin,
148922
+ powerEntity: config10.powerEntity,
148923
+ energyEntity: config10.energyEntity,
148924
+ suctionLevelEntity: config10.suctionLevelEntity,
148925
+ mopIntensityEntity: config10.mopIntensityEntity,
148926
+ customServiceAreas: config10.customServiceAreas,
148927
+ customFanSpeedTags: config10.customFanSpeedTags
148928
+ };
148929
+ }
148930
+ function mappingProfileApi(mappingStorage) {
148931
+ const router = express10.Router();
148932
+ router.get("/export/:bridgeId", (req, res) => {
148933
+ const { bridgeId } = req.params;
148934
+ const profileName = req.query.name || "Unnamed Profile";
148935
+ const mappings = mappingStorage.getMappingsForBridge(bridgeId);
148936
+ if (mappings.length === 0) {
148937
+ res.status(404).json({ error: "No mappings found for this bridge" });
148938
+ return;
148939
+ }
148940
+ const entries = mappings.map(configToProfileEntry);
148941
+ const domains = [...new Set(entries.map((e) => e.domain))];
148942
+ const profile = {
148943
+ version: 1,
148944
+ name: profileName,
148945
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
148946
+ domains,
148947
+ entryCount: entries.length,
148948
+ entries
148949
+ };
148950
+ res.json(profile);
148951
+ });
148952
+ router.post("/import/preview/:bridgeId", (req, res) => {
148953
+ const { bridgeId } = req.params;
148954
+ const { profile, availableEntityIds } = req.body;
148955
+ if (!profile?.entries || !Array.isArray(profile.entries)) {
148956
+ res.status(400).json({ error: "Invalid mapping profile format" });
148957
+ return;
148958
+ }
148959
+ if (!availableEntityIds || !Array.isArray(availableEntityIds)) {
148960
+ res.status(400).json({ error: "Missing availableEntityIds" });
148961
+ return;
148962
+ }
148963
+ const existingMappings = mappingStorage.getMappingsForBridge(bridgeId);
148964
+ const existingMap = new Map(existingMappings.map((m) => [m.entityId, m]));
148965
+ const matches = [];
148966
+ const unmatchedEntries = [];
148967
+ for (const entry of profile.entries) {
148968
+ let matched = false;
148969
+ if (entry.entityIdPattern && availableEntityIds.includes(entry.entityIdPattern)) {
148970
+ matches.push({
148971
+ entry,
148972
+ matchedEntityId: entry.entityIdPattern,
148973
+ matchType: "exact",
148974
+ existingMapping: existingMap.get(entry.entityIdPattern)
148975
+ });
148976
+ matched = true;
148977
+ }
148978
+ if (!matched) {
148979
+ const domainEntities = availableEntityIds.filter(
148980
+ (id) => id.split(".")[0] === entry.domain
148981
+ );
148982
+ if (domainEntities.length === 1) {
148983
+ matches.push({
148984
+ entry,
148985
+ matchedEntityId: domainEntities[0],
148986
+ matchType: "domain",
148987
+ existingMapping: existingMap.get(domainEntities[0])
148988
+ });
148989
+ matched = true;
148990
+ }
148991
+ }
148992
+ if (!matched) {
148993
+ unmatchedEntries.push(entry);
148994
+ }
148995
+ }
148996
+ const preview = {
148997
+ profileName: profile.name,
148998
+ totalEntries: profile.entries.length,
148999
+ matches,
149000
+ unmatchedEntries
149001
+ };
149002
+ res.json(preview);
149003
+ });
149004
+ router.post("/import/apply/:bridgeId", async (req, res) => {
149005
+ const { bridgeId } = req.params;
149006
+ const { profile, selectedEntityIds } = req.body;
149007
+ if (!profile?.entries || !selectedEntityIds) {
149008
+ res.status(400).json({ error: "Missing profile or selectedEntityIds" });
149009
+ return;
149010
+ }
149011
+ const selectedSet = new Set(selectedEntityIds);
149012
+ let applied = 0;
149013
+ let skipped = 0;
149014
+ const errors = [];
149015
+ for (const entry of profile.entries) {
149016
+ const targetEntityId = entry.entityIdPattern;
149017
+ if (!targetEntityId || !selectedSet.has(targetEntityId)) {
149018
+ skipped++;
149019
+ continue;
149020
+ }
149021
+ try {
149022
+ await mappingStorage.setMapping({
149023
+ bridgeId,
149024
+ entityId: targetEntityId,
149025
+ matterDeviceType: entry.matterDeviceType,
149026
+ customName: entry.customName,
149027
+ disabled: entry.disabled,
149028
+ filterLifeEntity: entry.filterLifeEntity,
149029
+ cleaningModeEntity: entry.cleaningModeEntity,
149030
+ humidityEntity: entry.humidityEntity,
149031
+ pressureEntity: entry.pressureEntity,
149032
+ batteryEntity: entry.batteryEntity,
149033
+ roomEntities: entry.roomEntities,
149034
+ disableLockPin: entry.disableLockPin,
149035
+ powerEntity: entry.powerEntity,
149036
+ energyEntity: entry.energyEntity,
149037
+ suctionLevelEntity: entry.suctionLevelEntity,
149038
+ mopIntensityEntity: entry.mopIntensityEntity,
149039
+ customServiceAreas: entry.customServiceAreas,
149040
+ customFanSpeedTags: entry.customFanSpeedTags
149041
+ });
149042
+ applied++;
149043
+ } catch (e) {
149044
+ errors.push({
149045
+ entityId: targetEntityId,
149046
+ error: e instanceof Error ? e.message : "Unknown error"
149047
+ });
149048
+ }
149049
+ }
149050
+ const result = {
149051
+ applied,
149052
+ skipped,
149053
+ errors
149054
+ };
149055
+ res.json(result);
149056
+ });
149057
+ return router;
149058
+ }
149059
+
148896
149060
  // src/api/matter-api.ts
148897
149061
  init_dist();
148898
149062
  import { Ajv } from "ajv";
148899
- import express10 from "express";
149063
+ import express11 from "express";
148900
149064
 
148901
149065
  // src/services/bridges/matcher/matches-entity-filter.ts
148902
149066
  function testMatchers(matchers, device, entity, mode = "any", entityState, labels) {
@@ -149042,7 +149206,7 @@ function endpointToJson(endpoint, parentId) {
149042
149206
  // src/api/matter-api.ts
149043
149207
  var ajv = new Ajv();
149044
149208
  function matterApi(bridgeService, haRegistry) {
149045
- const router = express10.Router();
149209
+ const router = express11.Router();
149046
149210
  router.get("/", (_, res) => {
149047
149211
  res.status(200).json({});
149048
149212
  });
@@ -149483,9 +149647,9 @@ function matterApi(bridgeService, haRegistry) {
149483
149647
  }
149484
149648
 
149485
149649
  // src/api/metrics-api.ts
149486
- import express11 from "express";
149650
+ import express12 from "express";
149487
149651
  function metricsApi(bridgeService, haClient, haRegistry, startTime) {
149488
- const router = express11.Router();
149652
+ const router = express12.Router();
149489
149653
  router.get("/", (_, res) => {
149490
149654
  const memoryUsage = process.memoryUsage();
149491
149655
  const bridges = bridgeService.bridges;
@@ -149729,7 +149893,7 @@ import { exec } from "node:child_process";
149729
149893
  import os2 from "node:os";
149730
149894
  import { promisify } from "node:util";
149731
149895
  import v8 from "node:v8";
149732
- import express12 from "express";
149896
+ import express13 from "express";
149733
149897
  var execAsync = promisify(exec);
149734
149898
  var logger141 = Logger.get("SystemApi");
149735
149899
  function detectEnvironment2() {
@@ -149749,7 +149913,7 @@ function detectEnvironment2() {
149749
149913
  return "Standalone";
149750
149914
  }
149751
149915
  function systemApi(version) {
149752
- const router = express12.Router();
149916
+ const router = express13.Router();
149753
149917
  router.get("/update-check", async (_req, res) => {
149754
149918
  try {
149755
149919
  const response = await fetch(
@@ -149939,14 +150103,14 @@ async function getUnixStorageInfo(path9) {
149939
150103
  // src/api/web-ui.ts
149940
150104
  import fs4 from "node:fs";
149941
150105
  import path5 from "node:path";
149942
- import express13 from "express";
150106
+ import express14 from "express";
149943
150107
  function webUi(dist) {
149944
- const router = express13.Router();
150108
+ const router = express14.Router();
149945
150109
  if (dist) {
149946
150110
  const index = replaceBase(dist);
149947
150111
  router.get("/", index);
149948
150112
  router.get("/index.html", index);
149949
- router.use(express13.static(dist));
150113
+ router.use(express14.static(dist));
149950
150114
  router.get(/.*/, index);
149951
150115
  }
149952
150116
  return router;
@@ -150126,8 +150290,8 @@ var WebApi = class extends Service {
150126
150290
  return this.wsApi;
150127
150291
  }
150128
150292
  async initialize() {
150129
- const api = express14.Router();
150130
- api.use(express14.json()).use(nocache()).use("/matter", matterApi(this.bridgeService, this.haRegistry)).use(
150293
+ const api = express15.Router();
150294
+ api.use(express15.json()).use(nocache()).use("/matter", matterApi(this.bridgeService, this.haRegistry)).use(
150131
150295
  "/health",
150132
150296
  healthApi(
150133
150297
  this.bridgeService,
@@ -150138,7 +150302,7 @@ var WebApi = class extends Service {
150138
150302
  ).use("/bridges", bridgeExportApi(this.bridgeStorage)).use("/bridge-icons", bridgeIconApi(this.props.storageLocation)).use(
150139
150303
  "/device-images",
150140
150304
  deviceImageApi(this.props.storageLocation, this.haRegistry)
150141
- ).use("/entity-mappings", entityMappingApi(this.mappingStorage)).use("/lock-credentials", lockCredentialApi(this.lockCredentialStorage)).use("/settings", settingsApi(this.settingsStorage, this.props.auth)).use(
150305
+ ).use("/entity-mappings", entityMappingApi(this.mappingStorage)).use("/mapping-profiles", mappingProfileApi(this.mappingStorage)).use("/lock-credentials", lockCredentialApi(this.lockCredentialStorage)).use("/settings", settingsApi(this.settingsStorage, this.props.auth)).use(
150142
150306
  "/backup",
150143
150307
  backupApi(
150144
150308
  this.bridgeStorage,
@@ -150187,9 +150351,9 @@ var WebApi = class extends Service {
150187
150351
  })
150188
150352
  );
150189
150353
  }
150190
- const appRouter = express14.Router();
150354
+ const appRouter = express15.Router();
150191
150355
  appRouter.use(...middlewares).use("/api", api).use(webUi(this.props.webUiDist));
150192
- this.app = express14();
150356
+ this.app = express15();
150193
150357
  const basePath = this.props.basePath;
150194
150358
  if (basePath !== "/") {
150195
150359
  this.log.info(`Base path configured: ${basePath}`);