@digital-alchemy/hass 25.10.26 → 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 (53) hide show
  1. package/dist/dev/mappings.d.mts +28 -0
  2. package/dist/hass.module.d.mts +6 -1
  3. package/dist/hass.module.mjs +6 -1
  4. package/dist/hass.module.mjs.map +1 -1
  5. package/dist/helpers/addon.d.mts +20 -0
  6. package/dist/helpers/addon.mjs +2 -0
  7. package/dist/helpers/addon.mjs.map +1 -0
  8. package/dist/helpers/countries.d.mts +2 -0
  9. package/dist/helpers/countries.mjs +254 -0
  10. package/dist/helpers/countries.mjs.map +1 -0
  11. package/dist/helpers/frontend.d.mts +19 -0
  12. package/dist/helpers/frontend.mjs +2 -0
  13. package/dist/helpers/frontend.mjs.map +1 -0
  14. package/dist/helpers/index.d.mts +4 -0
  15. package/dist/helpers/index.mjs +4 -0
  16. package/dist/helpers/index.mjs.map +1 -1
  17. package/dist/helpers/interfaces.d.mts +8 -1
  18. package/dist/helpers/interfaces.mjs.map +1 -1
  19. package/dist/helpers/languages.d.mts +2 -0
  20. package/dist/helpers/languages.mjs +67 -0
  21. package/dist/helpers/languages.mjs.map +1 -0
  22. package/dist/mock_assistant/mock-assistant.module.d.mts +4 -0
  23. package/dist/services/addon.service.d.mts +3 -0
  24. package/dist/services/addon.service.mjs +15 -0
  25. package/dist/services/addon.service.mjs.map +1 -0
  26. package/dist/services/frontend.service.d.mts +3 -0
  27. package/dist/services/frontend.service.mjs +13 -0
  28. package/dist/services/frontend.service.mjs.map +1 -0
  29. package/dist/services/index.d.mts +2 -0
  30. package/dist/services/index.mjs +2 -0
  31. package/dist/services/index.mjs.map +1 -1
  32. package/dist/testing/addon.spec.d.mts +1 -0
  33. package/dist/testing/addon.spec.mjs +59 -0
  34. package/dist/testing/addon.spec.mjs.map +1 -0
  35. package/dist/testing/frontend.spec.d.mts +1 -0
  36. package/dist/testing/frontend.spec.mjs +60 -0
  37. package/dist/testing/frontend.spec.mjs.map +1 -0
  38. package/dist/user.d.mts +2 -0
  39. package/package.json +1 -1
  40. package/src/dev/mappings.mts +29 -0
  41. package/src/hass.module.mts +9 -0
  42. package/src/helpers/addon.mts +20 -0
  43. package/src/helpers/countries.mts +255 -0
  44. package/src/helpers/frontend.mts +19 -0
  45. package/src/helpers/index.mts +4 -0
  46. package/src/helpers/interfaces.mts +10 -0
  47. package/src/helpers/languages.mts +67 -0
  48. package/src/services/addon.service.mts +19 -0
  49. package/src/services/frontend.service.mts +20 -0
  50. package/src/services/index.mts +2 -0
  51. package/src/testing/addon.spec.mts +65 -0
  52. package/src/testing/frontend.spec.mts +66 -0
  53. package/src/user.mts +4 -0
@@ -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
+ }
@@ -1,3 +1,4 @@
1
+ export * from "./addon.service.mts";
1
2
  export * from "./area.service.mts";
2
3
  export * from "./backup.service.mts";
3
4
  export * from "./call-proxy.service.mts";
@@ -9,6 +10,7 @@ export * from "./events.service.mts";
9
10
  export * from "./feature.service.mts";
10
11
  export * from "./fetch-api.service.mts";
11
12
  export * from "./floor.service.mts";
13
+ export * from "./frontend.service.mts";
12
14
  export * from "./id-by.service.mts";
13
15
  export * from "./internal.service.mts";
14
16
  export * from "./label.service.mts";
@@ -0,0 +1,65 @@
1
+ import type { AddonDetails } from "../helpers/index.mts";
2
+ import { hassTestRunner } from "../mock_assistant/index.mts";
3
+
4
+ describe("Addon Service", () => {
5
+ afterEach(async () => {
6
+ await hassTestRunner.teardown();
7
+ vi.restoreAllMocks();
8
+ });
9
+
10
+ describe("list", () => {
11
+ it("should fetch addon list via supervisor API", async () => {
12
+ expect.assertions(2);
13
+ const mockAddons: AddonDetails[] = [
14
+ {
15
+ advanced: false,
16
+ available: true,
17
+ build: false,
18
+ description: "A test addon",
19
+ detached: false,
20
+ homeassistant: "2024.1.0",
21
+ icon: true,
22
+ logo: false,
23
+ name: "Test Addon",
24
+ repository: "test",
25
+ slug: "test_addon",
26
+ stage: "stable",
27
+ state: "started",
28
+ system_managed: false,
29
+ update_available: false,
30
+ url: "http://test.local",
31
+ version: "1.0.0",
32
+ version_latest: "1.0.0",
33
+ },
34
+ ];
35
+
36
+ await hassTestRunner.run(({ lifecycle, hass }) => {
37
+ const spy = vi
38
+ .spyOn(hass.socket, "sendMessage")
39
+ .mockImplementation(async () => ({ addons: mockAddons }));
40
+
41
+ lifecycle.onReady(async () => {
42
+ const result = await hass.addon.list();
43
+ expect(spy).toHaveBeenCalledWith({
44
+ endpoint: "/addons",
45
+ method: "get",
46
+ type: "supervisor/api",
47
+ });
48
+ expect(result).toEqual(mockAddons);
49
+ });
50
+ });
51
+ });
52
+
53
+ it("should return empty array when no addons are available", async () => {
54
+ expect.assertions(1);
55
+ await hassTestRunner.run(({ lifecycle, hass }) => {
56
+ vi.spyOn(hass.socket, "sendMessage").mockImplementation(async () => ({ addons: [] }));
57
+
58
+ lifecycle.onReady(async () => {
59
+ const result = await hass.addon.list();
60
+ expect(result).toEqual([]);
61
+ });
62
+ });
63
+ });
64
+ });
65
+ });
@@ -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>;