@digital-alchemy/hass 25.10.27-beta.0 → 25.10.27-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/dev/mappings.d.mts +28 -0
  2. package/dist/hass.module.d.mts +5 -1
  3. package/dist/hass.module.mjs +5 -1
  4. package/dist/hass.module.mjs.map +1 -1
  5. package/dist/helpers/frontend.d.mts +19 -0
  6. package/dist/helpers/frontend.mjs +2 -0
  7. package/dist/helpers/frontend.mjs.map +1 -0
  8. package/dist/helpers/index.d.mts +1 -0
  9. package/dist/helpers/index.mjs +1 -0
  10. package/dist/helpers/index.mjs.map +1 -1
  11. package/dist/helpers/interfaces.d.mts +5 -2
  12. package/dist/helpers/interfaces.mjs.map +1 -1
  13. package/dist/mock_assistant/mock-assistant.module.d.mts +2 -0
  14. package/dist/services/addon.service.mjs +2 -1
  15. package/dist/services/addon.service.mjs.map +1 -1
  16. package/dist/services/frontend.service.d.mts +3 -0
  17. package/dist/services/frontend.service.mjs +13 -0
  18. package/dist/services/frontend.service.mjs.map +1 -0
  19. package/dist/services/index.d.mts +1 -0
  20. package/dist/services/index.mjs +1 -0
  21. package/dist/services/index.mjs.map +1 -1
  22. package/dist/testing/addon.spec.mjs +4 -2
  23. package/dist/testing/addon.spec.mjs.map +1 -1
  24. package/dist/testing/frontend.spec.d.mts +1 -0
  25. package/dist/testing/frontend.spec.mjs +60 -0
  26. package/dist/testing/frontend.spec.mjs.map +1 -0
  27. package/dist/user.d.mts +2 -0
  28. package/package.json +1 -1
  29. package/src/dev/mappings.mts +29 -0
  30. package/src/hass.module.mts +6 -0
  31. package/src/helpers/frontend.mts +19 -0
  32. package/src/helpers/index.mts +1 -0
  33. package/src/helpers/interfaces.mts +6 -1
  34. package/src/services/addon.service.mts +2 -1
  35. package/src/services/frontend.service.mts +20 -0
  36. package/src/services/index.mts +1 -0
  37. package/src/testing/addon.spec.mts +4 -2
  38. package/src/testing/frontend.spec.mts +66 -0
  39. package/src/user.mts +4 -0
@@ -86,5 +86,33 @@ declare module "../user.mts" {
86
86
  _downstairs: "switch.kitchen_cabinets" | "switch.living_room_mood_lights";
87
87
  _upstairs: "switch.bedroom_lamp";
88
88
  }
89
+ interface HassThemeMapping {
90
+ "(DO NOT USE/MODIFY)=== LCARS variables": true;
91
+ "(DO NOT USE/MODIFY)=== Base customizations": true;
92
+ "(DO NOT USE/MODIFY)=== card-mod CSS": true;
93
+ "LCARS Default": true;
94
+ "LCARS Classic": true;
95
+ "LCARS Nemesis Blue": true;
96
+ "LCARS Lower Decks I": true;
97
+ "LCARS Lower Decks II": true;
98
+ "LCARS Romulus": true;
99
+ "LCARS Kronos": true;
100
+ "LCARS Cardassia": true;
101
+ "LCARS Zeldaar": true;
102
+ "LCARS Modern": true;
103
+ "LCARS Picard I": true;
104
+ "LCARS Picard II": true;
105
+ "LCARS Red Alert": true;
106
+ "LCARS TNG": true;
107
+ "LCARS TNGbuttons": true;
108
+ "LCARS Transporter": true;
109
+ "LCARS Navigation": true;
110
+ "LCARS 25C": true;
111
+ "LCARS 25C (Red Alert)": true;
112
+ "LCARS 25C (Yellow Alert)": true;
113
+ "LCARS 25C (Blue Alert)": true;
114
+ "LCARS Breen": true;
115
+ "Minimal Ninja": "light" | "dark";
116
+ }
89
117
  }
90
118
  export {};
@@ -1,4 +1,4 @@
1
- import { AddonService, Area, Backup, CallProxy, Configure, Device, EntityManager, EventsService, FetchAPI, FetchInternals, Floor, HassDiagnosticsService, HassFeatureService, IDByExtension, Label, ReferenceService, Registry, WebsocketAPI, Zone } from "./services/index.mts";
1
+ import { AddonService, Area, Backup, CallProxy, Configure, Device, EntityManager, EventsService, FetchAPI, FetchInternals, Floor, FrontendService, HassDiagnosticsService, HassFeatureService, IDByExtension, Label, ReferenceService, Registry, WebsocketAPI, Zone } from "./services/index.mts";
2
2
  export declare const LIB_HASS: import("@digital-alchemy/core").LibraryDefinition<{
3
3
  addon: typeof AddonService;
4
4
  /**
@@ -45,6 +45,10 @@ export declare const LIB_HASS: import("@digital-alchemy/core").LibraryDefinition
45
45
  * floors, like groups of areas
46
46
  */
47
47
  floor: typeof Floor;
48
+ /**
49
+ * frontend interactions
50
+ */
51
+ frontend: typeof FrontendService;
48
52
  /**
49
53
  * search for entity ids in a type safe way
50
54
  */
@@ -1,5 +1,5 @@
1
1
  import { CreateLibrary } from "@digital-alchemy/core";
2
- import { AddonService, Area, Backup, CallProxy, Configure, Device, EntityManager, EventsService, FetchAPI, FetchInternals, Floor, HassDiagnosticsService, HassFeatureService, IDByExtension, Label, ReferenceService, Registry, WebsocketAPI, Zone, } from "./services/index.mjs";
2
+ import { AddonService, Area, Backup, CallProxy, Configure, Device, EntityManager, EventsService, FetchAPI, FetchInternals, Floor, FrontendService, HassDiagnosticsService, HassFeatureService, IDByExtension, Label, ReferenceService, Registry, WebsocketAPI, Zone, } from "./services/index.mjs";
3
3
  export const LIB_HASS = CreateLibrary({
4
4
  configuration: {
5
5
  /**
@@ -160,6 +160,10 @@ export const LIB_HASS = CreateLibrary({
160
160
  * floors, like groups of areas
161
161
  */
162
162
  floor: Floor,
163
+ /**
164
+ * frontend interactions
165
+ */
166
+ frontend: FrontendService,
163
167
  /**
164
168
  * search for entity ids in a type safe way
165
169
  */
@@ -1 +1 @@
1
- {"version":3,"file":"hass.module.mjs","sourceRoot":"","sources":["../src/hass.module.mts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hass.module.mjs","sourceRoot":"","sources":["../src/hass.module.mts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export interface ThemeDefinition {
2
+ "accent-color"?: string;
3
+ "app-header-background-color"?: string;
4
+ "app-header-edit-background-color"?: string;
5
+ "app-header-text-color"?: string;
6
+ "card-mod-root-yaml"?: string;
7
+ "divider-color"?: string;
8
+ "ha-card-border-radius"?: string;
9
+ "ha-card-border-width"?: string;
10
+ "paper-listbox-background-color"?: string;
11
+ "primary-color"?: string;
12
+ "sidebar-background-color"?: string;
13
+ "sidebar-menu-button-background-color"?: string;
14
+ modes?: {
15
+ light?: Record<string, unknown>;
16
+ dark?: Record<string, unknown>;
17
+ };
18
+ [key: string]: unknown;
19
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=frontend.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontend.mjs","sourceRoot":"","sources":["../../src/helpers/frontend.mts"],"names":[],"mappings":""}
@@ -7,6 +7,7 @@ export * from "./entity-state.mts";
7
7
  export * from "./features.mts";
8
8
  export * from "./fetch.mts";
9
9
  export * from "./fetch/index.mts";
10
+ export * from "./frontend.mts";
10
11
  export * from "./id-by.mts";
11
12
  export * from "./interfaces.mts";
12
13
  export * from "./languages.mts";
@@ -7,6 +7,7 @@ export * from "./entity-state.mjs";
7
7
  export * from "./features.mjs";
8
8
  export * from "./fetch.mjs";
9
9
  export * from "./fetch/index.mjs";
10
+ export * from "./frontend.mjs";
10
11
  export * from "./id-by.mjs";
11
12
  export * from "./interfaces.mjs";
12
13
  export * from "./languages.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/helpers/index.mts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/helpers/index.mts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC"}
@@ -2,8 +2,8 @@ import type { RemoveCallback, TBlackHole } from "@digital-alchemy/core";
2
2
  import type EventEmitter from "events";
3
3
  import type { EmptyObject } from "type-fest";
4
4
  import type WS from "ws";
5
- import type { AddonDetails } from "../index.mts";
6
- import type { ALL_DOMAINS, ANY_ENTITY, HassUniqueIdMapping, iCallService, PICK_ENTITY, PICK_FROM_AREA, PICK_FROM_DEVICE, PICK_FROM_FLOOR, PICK_FROM_LABEL, PICK_FROM_PLATFORM, TAreaId, TDeviceId, TFloorId, TLabelId, TPlatformId, TRawDomains, TRawEntityIds, TUniqueId } from "../user.mts";
5
+ import type { AddonDetails, ThemeDefinition } from "../index.mts";
6
+ import type { ALL_DOMAINS, ANY_ENTITY, HassThemeMapping, HassUniqueIdMapping, iCallService, PICK_ENTITY, PICK_FROM_AREA, PICK_FROM_DEVICE, PICK_FROM_FLOOR, PICK_FROM_LABEL, PICK_FROM_PLATFORM, TAreaId, TDeviceId, TFloorId, TLabelId, TPlatformId, TRawDomains, TRawEntityIds, TUniqueId } from "../user.mts";
7
7
  import type { BackupResponse, HomeAssistantBackup } from "./backup.mts";
8
8
  import type { DeviceDetails } from "./device.mts";
9
9
  import type { ByIdProxy } from "./entity-state.mts";
@@ -14,6 +14,9 @@ import type { EntityHistoryDTO, EntityHistoryResult, OnHassEventOptions, SocketS
14
14
  export type HassAddonService = {
15
15
  list: () => Promise<AddonDetails[]>;
16
16
  };
17
+ export type HassFrontendService = {
18
+ getThemes: () => Promise<Record<keyof HassThemeMapping, ThemeDefinition>>;
19
+ };
17
20
  export type HassAreaService = {
18
21
  apply: (area: TAreaId, entities: ANY_ENTITY[]) => Promise<{
19
22
  updated: ANY_ENTITY[];
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.mjs","sourceRoot":"","sources":["../../src/helpers/interfaces.mts"],"names":[],"mappings":"AAwMA,wDAAwD;AACxD,MAAM,CAAN,IAAY,wBAMX;AAND,WAAY,wBAAwB;IAClC,6EAAW,CAAA;IACX,mFAAc,CAAA;IACd,iFAAa,CAAA;IACb,6EAAW,CAAA;IACX,6EAAW,CAAA;AACb,CAAC,EANW,wBAAwB,KAAxB,wBAAwB,QAMnC"}
1
+ {"version":3,"file":"interfaces.mjs","sourceRoot":"","sources":["../../src/helpers/interfaces.mts"],"names":[],"mappings":"AA6MA,wDAAwD;AACxD,MAAM,CAAN,IAAY,wBAMX;AAND,WAAY,wBAAwB;IAClC,6EAAW,CAAA;IACX,mFAAc,CAAA;IACd,iFAAa,CAAA;IACb,6EAAW,CAAA;IACX,6EAAW,CAAA;AACb,CAAC,EANW,wBAAwB,KAAxB,wBAAwB,QAMnC"}
@@ -52,6 +52,7 @@ export declare const createTestRunner: () => import("@digital-alchemy/core").iTe
52
52
  feature: typeof import("../index.mts").HassFeatureService;
53
53
  fetch: typeof import("../index.mts").FetchAPI;
54
54
  floor: typeof import("../index.mts").Floor;
55
+ frontend: typeof import("../index.mts").FrontendService;
55
56
  idBy: typeof import("../index.mts").IDByExtension;
56
57
  internals: typeof import("../index.mts").FetchInternals;
57
58
  label: typeof import("../index.mts").Label;
@@ -129,6 +130,7 @@ export declare const hassTestRunner: import("@digital-alchemy/core").iTestRunner
129
130
  feature: typeof import("../index.mts").HassFeatureService;
130
131
  fetch: typeof import("../index.mts").FetchAPI;
131
132
  floor: typeof import("../index.mts").Floor;
133
+ frontend: typeof import("../index.mts").FrontendService;
132
134
  idBy: typeof import("../index.mts").IDByExtension;
133
135
  internals: typeof import("../index.mts").FetchInternals;
134
136
  label: typeof import("../index.mts").Label;
@@ -1,11 +1,12 @@
1
1
  export function AddonService({ hass, logger }) {
2
2
  async function list() {
3
3
  logger.trace({ name: "list" }, "fetching addon list");
4
- return await hass.socket.sendMessage({
4
+ const { addons } = await hass.socket.sendMessage({
5
5
  endpoint: "/addons",
6
6
  method: "get",
7
7
  type: "supervisor/api",
8
8
  });
9
+ return addons;
9
10
  }
10
11
  return {
11
12
  list,
@@ -1 +1 @@
1
- {"version":3,"file":"addon.service.mjs","sourceRoot":"","sources":["../../src/services/addon.service.mts"],"names":[],"mappings":"AAIA,MAAM,UAAU,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAkB;IAC3D,KAAK,UAAU,IAAI;QACjB,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC;QACtD,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAiB;YACnD,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,gBAAgB;SACvB,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,IAAI;KACL,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"addon.service.mjs","sourceRoot":"","sources":["../../src/services/addon.service.mts"],"names":[],"mappings":"AAIA,MAAM,UAAU,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAkB;IAC3D,KAAK,UAAU,IAAI;QACjB,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC;QACtD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAA6B;YAC3E,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,gBAAgB;SACvB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO;QACL,IAAI;KACL,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { TServiceParams } from "@digital-alchemy/core";
2
+ import type { HassFrontendService } from "../index.mts";
3
+ export declare function FrontendService({ hass, logger }: TServiceParams): HassFrontendService;
@@ -0,0 +1,13 @@
1
+ export function FrontendService({ hass, logger }) {
2
+ async function getThemes() {
3
+ logger.trace({ name: "getThemes" }, "fetching themes");
4
+ const result = await hass.socket.sendMessage({
5
+ type: "frontend/get_themes",
6
+ });
7
+ return result.themes;
8
+ }
9
+ return {
10
+ getThemes,
11
+ };
12
+ }
13
+ //# sourceMappingURL=frontend.service.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontend.service.mjs","sourceRoot":"","sources":["../../src/services/frontend.service.mts"],"names":[],"mappings":"AAKA,MAAM,UAAU,eAAe,CAAC,EAAE,IAAI,EAAE,MAAM,EAAkB;IAC9D,KAAK,UAAU,SAAS;QACtB,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,iBAAiB,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAEzC;YACD,IAAI,EAAE,qBAAqB;SAC5B,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;IAED,OAAO;QACL,SAAS;KACV,CAAC;AACJ,CAAC"}
@@ -10,6 +10,7 @@ export * from "./events.service.mts";
10
10
  export * from "./feature.service.mts";
11
11
  export * from "./fetch-api.service.mts";
12
12
  export * from "./floor.service.mts";
13
+ export * from "./frontend.service.mts";
13
14
  export * from "./id-by.service.mts";
14
15
  export * from "./internal.service.mts";
15
16
  export * from "./label.service.mts";
@@ -10,6 +10,7 @@ export * from "./events.service.mjs";
10
10
  export * from "./feature.service.mjs";
11
11
  export * from "./fetch-api.service.mjs";
12
12
  export * from "./floor.service.mjs";
13
+ export * from "./frontend.service.mjs";
13
14
  export * from "./id-by.service.mjs";
14
15
  export * from "./internal.service.mjs";
15
16
  export * from "./label.service.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/services/index.mts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/services/index.mts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,oBAAoB,CAAC"}
@@ -30,7 +30,9 @@ describe("Addon Service", () => {
30
30
  },
31
31
  ];
32
32
  await hassTestRunner.run(({ lifecycle, hass }) => {
33
- const spy = vi.spyOn(hass.socket, "sendMessage").mockImplementation(async () => mockAddons);
33
+ const spy = vi
34
+ .spyOn(hass.socket, "sendMessage")
35
+ .mockImplementation(async () => ({ addons: mockAddons }));
34
36
  lifecycle.onReady(async () => {
35
37
  const result = await hass.addon.list();
36
38
  expect(spy).toHaveBeenCalledWith({
@@ -45,7 +47,7 @@ describe("Addon Service", () => {
45
47
  it("should return empty array when no addons are available", async () => {
46
48
  expect.assertions(1);
47
49
  await hassTestRunner.run(({ lifecycle, hass }) => {
48
- vi.spyOn(hass.socket, "sendMessage").mockImplementation(async () => []);
50
+ vi.spyOn(hass.socket, "sendMessage").mockImplementation(async () => ({ addons: [] }));
49
51
  lifecycle.onReady(async () => {
50
52
  const result = await hass.addon.list();
51
53
  expect(result).toEqual([]);
@@ -1 +1 @@
1
- {"version":3,"file":"addon.spec.mjs","sourceRoot":"","sources":["../../src/testing/addon.spec.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,cAAc,CAAC,QAAQ,EAAE,CAAC;QAChC,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YAC1D,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACrB,MAAM,UAAU,GAAmB;gBACjC;oBACE,QAAQ,EAAE,KAAK;oBACf,SAAS,EAAE,IAAI;oBACf,KAAK,EAAE,KAAK;oBACZ,WAAW,EAAE,cAAc;oBAC3B,QAAQ,EAAE,KAAK;oBACf,aAAa,EAAE,UAAU;oBACzB,IAAI,EAAE,IAAI;oBACV,IAAI,EAAE,KAAK;oBACX,IAAI,EAAE,YAAY;oBAClB,UAAU,EAAE,MAAM;oBAClB,IAAI,EAAE,YAAY;oBAClB,KAAK,EAAE,QAAQ;oBACf,KAAK,EAAE,SAAS;oBAChB,cAAc,EAAE,KAAK;oBACrB,gBAAgB,EAAE,KAAK;oBACvB,GAAG,EAAE,mBAAmB;oBACxB,OAAO,EAAE,OAAO;oBAChB,cAAc,EAAE,OAAO;iBACxB;aACF,CAAC;YAEF,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC/C,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,kBAAkB,CAAC,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC;gBAE5F,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;oBAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;oBACvC,MAAM,CAAC,GAAG,CAAC,CAAC,oBAAoB,CAAC;wBAC/B,QAAQ,EAAE,SAAS;wBACnB,MAAM,EAAE,KAAK;wBACb,IAAI,EAAE,gBAAgB;qBACvB,CAAC,CAAC;oBACH,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBACrC,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;YACtE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACrB,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC/C,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,kBAAkB,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;gBAExE,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;oBAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;oBACvC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAC7B,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"addon.spec.mjs","sourceRoot":"","sources":["../../src/testing/addon.spec.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,cAAc,CAAC,QAAQ,EAAE,CAAC;QAChC,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YAC1D,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACrB,MAAM,UAAU,GAAmB;gBACjC;oBACE,QAAQ,EAAE,KAAK;oBACf,SAAS,EAAE,IAAI;oBACf,KAAK,EAAE,KAAK;oBACZ,WAAW,EAAE,cAAc;oBAC3B,QAAQ,EAAE,KAAK;oBACf,aAAa,EAAE,UAAU;oBACzB,IAAI,EAAE,IAAI;oBACV,IAAI,EAAE,KAAK;oBACX,IAAI,EAAE,YAAY;oBAClB,UAAU,EAAE,MAAM;oBAClB,IAAI,EAAE,YAAY;oBAClB,KAAK,EAAE,QAAQ;oBACf,KAAK,EAAE,SAAS;oBAChB,cAAc,EAAE,KAAK;oBACrB,gBAAgB,EAAE,KAAK;oBACvB,GAAG,EAAE,mBAAmB;oBACxB,OAAO,EAAE,OAAO;oBAChB,cAAc,EAAE,OAAO;iBACxB;aACF,CAAC;YAEF,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC/C,MAAM,GAAG,GAAG,EAAE;qBACX,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC;qBACjC,kBAAkB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;gBAE5D,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;oBAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;oBACvC,MAAM,CAAC,GAAG,CAAC,CAAC,oBAAoB,CAAC;wBAC/B,QAAQ,EAAE,SAAS;wBACnB,MAAM,EAAE,KAAK;wBACb,IAAI,EAAE,gBAAgB;qBACvB,CAAC,CAAC;oBACH,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBACrC,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;YACtE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACrB,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC/C,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,kBAAkB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;gBAEtF,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;oBAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;oBACvC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAC7B,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,60 @@
1
+ import { hassTestRunner } from "../mock_assistant/index.mjs";
2
+ describe("Frontend Service", () => {
3
+ afterEach(async () => {
4
+ await hassTestRunner.teardown();
5
+ vi.restoreAllMocks();
6
+ });
7
+ describe("getThemes", () => {
8
+ it("should fetch themes and return Record of theme names to definitions", async () => {
9
+ expect.assertions(2);
10
+ const mockThemes = {
11
+ "LCARS Default": {
12
+ "accent-color": "var(--lcars-orange)",
13
+ "card-mod-theme": "LCARS Default",
14
+ "divider-color": "transparent",
15
+ "primary-color": "var(--lcars-ui-tertiary)",
16
+ "sidebar-background-color": "var(--lcars-ui-primary)",
17
+ },
18
+ "Minimal Ninja": {
19
+ "accent-color": "#FFAB00",
20
+ "card-mod-theme": "Minimal Ninja",
21
+ "divider-color": "rgba(145, 158, 171, 0.2)",
22
+ modes: {
23
+ dark: {
24
+ "card-background-color": "#1C252E",
25
+ "primary-text-color": "#ffffff",
26
+ },
27
+ light: {
28
+ "card-background-color": "#ffffff",
29
+ "primary-text-color": "#1C252E",
30
+ },
31
+ },
32
+ "primary-color": "#00A76F",
33
+ },
34
+ };
35
+ await hassTestRunner.run(({ lifecycle, hass }) => {
36
+ const spy = vi
37
+ .spyOn(hass.socket, "sendMessage")
38
+ .mockImplementation(async () => ({ themes: mockThemes }));
39
+ lifecycle.onReady(async () => {
40
+ const result = await hass.frontend.getThemes();
41
+ expect(spy).toHaveBeenCalledWith({
42
+ type: "frontend/get_themes",
43
+ });
44
+ expect(result).toEqual(mockThemes);
45
+ });
46
+ });
47
+ });
48
+ it("should return empty object when no themes are available", async () => {
49
+ expect.assertions(1);
50
+ await hassTestRunner.run(({ lifecycle, hass }) => {
51
+ vi.spyOn(hass.socket, "sendMessage").mockImplementation(async () => ({ themes: {} }));
52
+ lifecycle.onReady(async () => {
53
+ const result = await hass.frontend.getThemes();
54
+ expect(result).toEqual({});
55
+ });
56
+ });
57
+ });
58
+ });
59
+ });
60
+ //# sourceMappingURL=frontend.spec.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontend.spec.mjs","sourceRoot":"","sources":["../../src/testing/frontend.spec.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,cAAc,CAAC,QAAQ,EAAE,CAAC;QAChC,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;QACzB,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;YACnF,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACrB,MAAM,UAAU,GAAoC;gBAClD,eAAe,EAAE;oBACf,cAAc,EAAE,qBAAqB;oBACrC,gBAAgB,EAAE,eAAe;oBACjC,eAAe,EAAE,aAAa;oBAC9B,eAAe,EAAE,0BAA0B;oBAC3C,0BAA0B,EAAE,yBAAyB;iBACtD;gBACD,eAAe,EAAE;oBACf,cAAc,EAAE,SAAS;oBACzB,gBAAgB,EAAE,eAAe;oBACjC,eAAe,EAAE,0BAA0B;oBAC3C,KAAK,EAAE;wBACL,IAAI,EAAE;4BACJ,uBAAuB,EAAE,SAAS;4BAClC,oBAAoB,EAAE,SAAS;yBAChC;wBACD,KAAK,EAAE;4BACL,uBAAuB,EAAE,SAAS;4BAClC,oBAAoB,EAAE,SAAS;yBAChC;qBACF;oBACD,eAAe,EAAE,SAAS;iBAC3B;aACF,CAAC;YAEF,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC/C,MAAM,GAAG,GAAG,EAAE;qBACX,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC;qBACjC,kBAAkB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;gBAE5D,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;oBAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;oBAC/C,MAAM,CAAC,GAAG,CAAC,CAAC,oBAAoB,CAAC;wBAC/B,IAAI,EAAE,qBAAqB;qBAC5B,CAAC,CAAC;oBACH,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBACrC,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;YACvE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACrB,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC/C,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,kBAAkB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;gBAEtF,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;oBAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;oBAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAC7B,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/user.d.mts CHANGED
@@ -19,6 +19,8 @@ export interface iCallService {
19
19
  }
20
20
  export interface HassZoneMapping {
21
21
  }
22
+ export interface HassThemeMapping {
23
+ }
22
24
  export type TAreaId = UnPrefix<keyof HassAreaMapping>;
23
25
  export type TDeviceId = UnPrefix<keyof HassDeviceMapping>;
24
26
  export type TFloorId = UnPrefix<keyof HassFloorMapping>;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "@digital-alchemy/hass",
4
4
  "repository": "https://github.com/Digital-Alchemy-TS/hass",
5
5
  "homepage": "https://docs.digital-alchemy.app",
6
- "version": "25.10.27-beta.0",
6
+ "version": "25.10.27-beta.1",
7
7
  "description": "Typescript APIs for Home Assistant. Includes rest & websocket bindings",
8
8
  "scripts": {
9
9
  "build": "rm -rf dist/; tsc",
@@ -163,4 +163,33 @@ declare module "../user.mts" {
163
163
  _downstairs: "switch.kitchen_cabinets" | "switch.living_room_mood_lights";
164
164
  _upstairs: "switch.bedroom_lamp";
165
165
  }
166
+
167
+ export interface HassThemeMapping {
168
+ "(DO NOT USE/MODIFY)=== LCARS variables": true;
169
+ "(DO NOT USE/MODIFY)=== Base customizations": true;
170
+ "(DO NOT USE/MODIFY)=== card-mod CSS": true;
171
+ "LCARS Default": true;
172
+ "LCARS Classic": true;
173
+ "LCARS Nemesis Blue": true;
174
+ "LCARS Lower Decks I": true;
175
+ "LCARS Lower Decks II": true;
176
+ "LCARS Romulus": true;
177
+ "LCARS Kronos": true;
178
+ "LCARS Cardassia": true;
179
+ "LCARS Zeldaar": true;
180
+ "LCARS Modern": true;
181
+ "LCARS Picard I": true;
182
+ "LCARS Picard II": true;
183
+ "LCARS Red Alert": true;
184
+ "LCARS TNG": true;
185
+ "LCARS TNGbuttons": true;
186
+ "LCARS Transporter": true;
187
+ "LCARS Navigation": true;
188
+ "LCARS 25C": true;
189
+ "LCARS 25C (Red Alert)": true;
190
+ "LCARS 25C (Yellow Alert)": true;
191
+ "LCARS 25C (Blue Alert)": true;
192
+ "LCARS Breen": true;
193
+ "Minimal Ninja": "light" | "dark";
194
+ }
166
195
  }
@@ -12,6 +12,7 @@ import {
12
12
  FetchAPI,
13
13
  FetchInternals,
14
14
  Floor,
15
+ FrontendService,
15
16
  HassDiagnosticsService,
16
17
  HassFeatureService,
17
18
  IDByExtension,
@@ -208,6 +209,11 @@ export const LIB_HASS = CreateLibrary({
208
209
  */
209
210
  floor: Floor,
210
211
 
212
+ /**
213
+ * frontend interactions
214
+ */
215
+ frontend: FrontendService,
216
+
211
217
  /**
212
218
  * search for entity ids in a type safe way
213
219
  */
@@ -0,0 +1,19 @@
1
+ export interface ThemeDefinition {
2
+ "accent-color"?: string;
3
+ "app-header-background-color"?: string;
4
+ "app-header-edit-background-color"?: string;
5
+ "app-header-text-color"?: string;
6
+ "card-mod-root-yaml"?: string;
7
+ "divider-color"?: string;
8
+ "ha-card-border-radius"?: string;
9
+ "ha-card-border-width"?: string;
10
+ "paper-listbox-background-color"?: string;
11
+ "primary-color"?: string;
12
+ "sidebar-background-color"?: string;
13
+ "sidebar-menu-button-background-color"?: string;
14
+ modes?: {
15
+ light?: Record<string, unknown>;
16
+ dark?: Record<string, unknown>;
17
+ };
18
+ [key: string]: unknown;
19
+ }
@@ -7,6 +7,7 @@ export * from "./entity-state.mts";
7
7
  export * from "./features.mts";
8
8
  export * from "./fetch.mts";
9
9
  export * from "./fetch/index.mts";
10
+ export * from "./frontend.mts";
10
11
  export * from "./id-by.mts";
11
12
  export * from "./interfaces.mts";
12
13
  export * from "./languages.mts";
@@ -3,10 +3,11 @@ import type EventEmitter from "events";
3
3
  import type { EmptyObject } from "type-fest";
4
4
  import type WS from "ws";
5
5
 
6
- import type { AddonDetails } from "../index.mts";
6
+ import type { AddonDetails, ThemeDefinition } from "../index.mts";
7
7
  import type {
8
8
  ALL_DOMAINS,
9
9
  ANY_ENTITY,
10
+ HassThemeMapping,
10
11
  HassUniqueIdMapping,
11
12
  iCallService,
12
13
  PICK_ENTITY,
@@ -54,6 +55,10 @@ export type HassAddonService = {
54
55
  list: () => Promise<AddonDetails[]>;
55
56
  };
56
57
 
58
+ export type HassFrontendService = {
59
+ getThemes: () => Promise<Record<keyof HassThemeMapping, ThemeDefinition>>;
60
+ };
61
+
57
62
  export type HassAreaService = {
58
63
  apply: (
59
64
  area: TAreaId,
@@ -5,11 +5,12 @@ import type { AddonDetails, HassAddonService } from "../index.mts";
5
5
  export function AddonService({ hass, logger }: TServiceParams): HassAddonService {
6
6
  async function list() {
7
7
  logger.trace({ name: "list" }, "fetching addon list");
8
- return await hass.socket.sendMessage<AddonDetails[]>({
8
+ const { addons } = await hass.socket.sendMessage<{ addons: AddonDetails[] }>({
9
9
  endpoint: "/addons",
10
10
  method: "get",
11
11
  type: "supervisor/api",
12
12
  });
13
+ return addons;
13
14
  }
14
15
 
15
16
  return {
@@ -0,0 +1,20 @@
1
+ import type { TServiceParams } from "@digital-alchemy/core";
2
+
3
+ import type { HassFrontendService, ThemeDefinition } from "../index.mts";
4
+ import type { HassThemeMapping } from "../user.mts";
5
+
6
+ export function FrontendService({ hass, logger }: TServiceParams): HassFrontendService {
7
+ async function getThemes() {
8
+ logger.trace({ name: "getThemes" }, "fetching themes");
9
+ const result = await hass.socket.sendMessage<{
10
+ themes: Record<keyof HassThemeMapping, ThemeDefinition>;
11
+ }>({
12
+ type: "frontend/get_themes",
13
+ });
14
+ return result.themes;
15
+ }
16
+
17
+ return {
18
+ getThemes,
19
+ };
20
+ }
@@ -10,6 +10,7 @@ export * from "./events.service.mts";
10
10
  export * from "./feature.service.mts";
11
11
  export * from "./fetch-api.service.mts";
12
12
  export * from "./floor.service.mts";
13
+ export * from "./frontend.service.mts";
13
14
  export * from "./id-by.service.mts";
14
15
  export * from "./internal.service.mts";
15
16
  export * from "./label.service.mts";
@@ -34,7 +34,9 @@ describe("Addon Service", () => {
34
34
  ];
35
35
 
36
36
  await hassTestRunner.run(({ lifecycle, hass }) => {
37
- const spy = vi.spyOn(hass.socket, "sendMessage").mockImplementation(async () => mockAddons);
37
+ const spy = vi
38
+ .spyOn(hass.socket, "sendMessage")
39
+ .mockImplementation(async () => ({ addons: mockAddons }));
38
40
 
39
41
  lifecycle.onReady(async () => {
40
42
  const result = await hass.addon.list();
@@ -51,7 +53,7 @@ describe("Addon Service", () => {
51
53
  it("should return empty array when no addons are available", async () => {
52
54
  expect.assertions(1);
53
55
  await hassTestRunner.run(({ lifecycle, hass }) => {
54
- vi.spyOn(hass.socket, "sendMessage").mockImplementation(async () => []);
56
+ vi.spyOn(hass.socket, "sendMessage").mockImplementation(async () => ({ addons: [] }));
55
57
 
56
58
  lifecycle.onReady(async () => {
57
59
  const result = await hass.addon.list();
@@ -0,0 +1,66 @@
1
+ import type { ThemeDefinition } from "../helpers/index.mts";
2
+ import { hassTestRunner } from "../mock_assistant/index.mts";
3
+
4
+ describe("Frontend Service", () => {
5
+ afterEach(async () => {
6
+ await hassTestRunner.teardown();
7
+ vi.restoreAllMocks();
8
+ });
9
+
10
+ describe("getThemes", () => {
11
+ it("should fetch themes and return Record of theme names to definitions", async () => {
12
+ expect.assertions(2);
13
+ const mockThemes: Record<string, ThemeDefinition> = {
14
+ "LCARS Default": {
15
+ "accent-color": "var(--lcars-orange)",
16
+ "card-mod-theme": "LCARS Default",
17
+ "divider-color": "transparent",
18
+ "primary-color": "var(--lcars-ui-tertiary)",
19
+ "sidebar-background-color": "var(--lcars-ui-primary)",
20
+ },
21
+ "Minimal Ninja": {
22
+ "accent-color": "#FFAB00",
23
+ "card-mod-theme": "Minimal Ninja",
24
+ "divider-color": "rgba(145, 158, 171, 0.2)",
25
+ modes: {
26
+ dark: {
27
+ "card-background-color": "#1C252E",
28
+ "primary-text-color": "#ffffff",
29
+ },
30
+ light: {
31
+ "card-background-color": "#ffffff",
32
+ "primary-text-color": "#1C252E",
33
+ },
34
+ },
35
+ "primary-color": "#00A76F",
36
+ },
37
+ };
38
+
39
+ await hassTestRunner.run(({ lifecycle, hass }) => {
40
+ const spy = vi
41
+ .spyOn(hass.socket, "sendMessage")
42
+ .mockImplementation(async () => ({ themes: mockThemes }));
43
+
44
+ lifecycle.onReady(async () => {
45
+ const result = await hass.frontend.getThemes();
46
+ expect(spy).toHaveBeenCalledWith({
47
+ type: "frontend/get_themes",
48
+ });
49
+ expect(result).toEqual(mockThemes);
50
+ });
51
+ });
52
+ });
53
+
54
+ it("should return empty object when no themes are available", async () => {
55
+ expect.assertions(1);
56
+ await hassTestRunner.run(({ lifecycle, hass }) => {
57
+ vi.spyOn(hass.socket, "sendMessage").mockImplementation(async () => ({ themes: {} }));
58
+
59
+ lifecycle.onReady(async () => {
60
+ const result = await hass.frontend.getThemes();
61
+ expect(result).toEqual({});
62
+ });
63
+ });
64
+ });
65
+ });
66
+ });
package/src/user.mts CHANGED
@@ -46,6 +46,10 @@ export interface HassZoneMapping {
46
46
  // "zone": true
47
47
  }
48
48
 
49
+ export interface HassThemeMapping {
50
+ // "{theme_name}": true | "light" | "dark" | "light" | "dark"
51
+ }
52
+
49
53
  // #MARK: extract
50
54
  export type TAreaId = UnPrefix<keyof HassAreaMapping>;
51
55
  export type TDeviceId = UnPrefix<keyof HassDeviceMapping>;