@switchbot/homebridge-switchbot 5.0.0-beta.99 → 5.0.0

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 (282) hide show
  1. package/.changeset/config.json +14 -0
  2. package/.github/copilot-instructions.md +39 -0
  3. package/.github/workflows/ci.yml +4 -1
  4. package/.github/workflows/manual-e2e.yml +6 -3
  5. package/.github/workflows/release.yml +64 -15
  6. package/.github/workflows/stale.yml +2 -4
  7. package/.husky/pre-push +15 -0
  8. package/CHANGELOG.md +126 -134
  9. package/MIGRATION.md +16 -6
  10. package/README.md +84 -3
  11. package/TODO.md +263 -0
  12. package/config.schema.json +229 -36
  13. package/dist/SwitchBotHAPPlatform.d.ts +133 -0
  14. package/dist/SwitchBotHAPPlatform.d.ts.map +1 -0
  15. package/dist/SwitchBotHAPPlatform.js +555 -0
  16. package/dist/SwitchBotHAPPlatform.js.map +1 -0
  17. package/dist/SwitchBotMatterPlatform.d.ts +141 -0
  18. package/dist/SwitchBotMatterPlatform.d.ts.map +1 -0
  19. package/dist/SwitchBotMatterPlatform.js +536 -0
  20. package/dist/SwitchBotMatterPlatform.js.map +1 -0
  21. package/dist/device-types.d.ts +31 -0
  22. package/dist/device-types.d.ts.map +1 -0
  23. package/dist/device-types.js +246 -0
  24. package/dist/device-types.js.map +1 -0
  25. package/dist/deviceCommandMapper.d.ts +10 -0
  26. package/dist/deviceCommandMapper.d.ts.map +1 -0
  27. package/dist/deviceCommandMapper.js +319 -0
  28. package/dist/deviceCommandMapper.js.map +1 -0
  29. package/dist/deviceFactory.d.ts +3 -2
  30. package/dist/deviceFactory.d.ts.map +1 -1
  31. package/dist/deviceFactory.js +107 -29
  32. package/dist/deviceFactory.js.map +1 -1
  33. package/dist/devices/genericDevice.d.ts +59 -37
  34. package/dist/devices/genericDevice.d.ts.map +1 -1
  35. package/dist/devices/genericDevice.js +376 -78
  36. package/dist/devices/genericDevice.js.map +1 -1
  37. package/dist/errors.d.ts +38 -0
  38. package/dist/errors.d.ts.map +1 -0
  39. package/dist/errors.js +32 -0
  40. package/dist/errors.js.map +1 -0
  41. package/dist/homebridge-ui/device-types.js +246 -0
  42. package/dist/homebridge-ui/device-types.js.map +1 -0
  43. package/dist/homebridge-ui/deviceCommandMapper.js +319 -0
  44. package/dist/homebridge-ui/deviceCommandMapper.js.map +1 -0
  45. package/dist/homebridge-ui/endpoints/config.d.ts +3 -0
  46. package/dist/homebridge-ui/endpoints/config.d.ts.map +1 -0
  47. package/dist/homebridge-ui/endpoints/config.js +90 -0
  48. package/dist/homebridge-ui/endpoints/config.js.map +1 -0
  49. package/dist/homebridge-ui/endpoints/devices.d.ts +6 -0
  50. package/dist/homebridge-ui/endpoints/devices.d.ts.map +1 -0
  51. package/dist/homebridge-ui/endpoints/devices.js +144 -0
  52. package/dist/homebridge-ui/endpoints/devices.js.map +1 -0
  53. package/dist/homebridge-ui/endpoints/discovery.d.ts +7 -0
  54. package/dist/homebridge-ui/endpoints/discovery.d.ts.map +1 -0
  55. package/dist/homebridge-ui/endpoints/discovery.js +219 -0
  56. package/dist/homebridge-ui/endpoints/discovery.js.map +1 -0
  57. package/dist/homebridge-ui/errors.js +32 -0
  58. package/dist/homebridge-ui/errors.js.map +1 -0
  59. package/dist/homebridge-ui/homebridge-ui/endpoints/config.js +90 -0
  60. package/dist/homebridge-ui/homebridge-ui/endpoints/config.js.map +1 -0
  61. package/dist/homebridge-ui/homebridge-ui/endpoints/devices.js +144 -0
  62. package/dist/homebridge-ui/homebridge-ui/endpoints/devices.js.map +1 -0
  63. package/dist/homebridge-ui/homebridge-ui/endpoints/discovery.js +219 -0
  64. package/dist/homebridge-ui/homebridge-ui/endpoints/discovery.js.map +1 -0
  65. package/dist/homebridge-ui/homebridge-ui/server.js +11 -0
  66. package/dist/homebridge-ui/homebridge-ui/server.js.map +1 -0
  67. package/dist/homebridge-ui/homebridge-ui/utils/config-parser.js +108 -0
  68. package/dist/homebridge-ui/homebridge-ui/utils/config-parser.js.map +1 -0
  69. package/dist/homebridge-ui/homebridge-ui/utils/device-migration.js +111 -0
  70. package/dist/homebridge-ui/homebridge-ui/utils/device-migration.js.map +1 -0
  71. package/dist/homebridge-ui/homebridge-ui/utils/logger.js +17 -0
  72. package/dist/homebridge-ui/homebridge-ui/utils/logger.js.map +1 -0
  73. package/dist/homebridge-ui/public/css/styles.css +483 -0
  74. package/dist/homebridge-ui/public/index.html +197 -621
  75. package/dist/homebridge-ui/public/js/advanced-settings.d.ts +3 -0
  76. package/dist/homebridge-ui/public/js/advanced-settings.d.ts.map +1 -0
  77. package/dist/homebridge-ui/public/js/advanced-settings.js +95 -0
  78. package/dist/homebridge-ui/public/js/advanced-settings.js.map +1 -0
  79. package/dist/homebridge-ui/public/js/advanced-settings.ts +94 -0
  80. package/dist/homebridge-ui/public/js/api.d.ts +66 -0
  81. package/dist/homebridge-ui/public/js/api.d.ts.map +1 -0
  82. package/dist/homebridge-ui/public/js/api.js +295 -0
  83. package/dist/homebridge-ui/public/js/api.js.map +1 -0
  84. package/dist/homebridge-ui/public/js/api.ts +355 -0
  85. package/dist/homebridge-ui/public/js/app.d.ts +2 -0
  86. package/dist/homebridge-ui/public/js/app.d.ts.map +1 -0
  87. package/dist/homebridge-ui/public/js/app.js +3722 -0
  88. package/dist/homebridge-ui/public/js/app.js.map +7 -0
  89. package/dist/homebridge-ui/public/js/app.ts +22 -0
  90. package/dist/homebridge-ui/public/js/constants.d.ts +2 -0
  91. package/dist/homebridge-ui/public/js/constants.d.ts.map +1 -0
  92. package/dist/homebridge-ui/public/js/constants.js +2 -0
  93. package/dist/homebridge-ui/public/js/constants.js.map +1 -0
  94. package/dist/homebridge-ui/public/js/constants.ts +1 -0
  95. package/dist/homebridge-ui/public/js/credentials.d.ts +3 -0
  96. package/dist/homebridge-ui/public/js/credentials.d.ts.map +1 -0
  97. package/dist/homebridge-ui/public/js/credentials.js +99 -0
  98. package/dist/homebridge-ui/public/js/credentials.js.map +1 -0
  99. package/dist/homebridge-ui/public/js/credentials.ts +105 -0
  100. package/dist/homebridge-ui/public/js/devices-delete.d.ts +3 -0
  101. package/dist/homebridge-ui/public/js/devices-delete.d.ts.map +1 -0
  102. package/dist/homebridge-ui/public/js/devices-delete.js +199 -0
  103. package/dist/homebridge-ui/public/js/devices-delete.js.map +1 -0
  104. package/dist/homebridge-ui/public/js/devices-delete.ts +227 -0
  105. package/dist/homebridge-ui/public/js/devices.d.ts +9 -0
  106. package/dist/homebridge-ui/public/js/devices.d.ts.map +1 -0
  107. package/dist/homebridge-ui/public/js/devices.js +98 -0
  108. package/dist/homebridge-ui/public/js/devices.js.map +1 -0
  109. package/dist/homebridge-ui/public/js/devices.ts +106 -0
  110. package/dist/homebridge-ui/public/js/discovery.d.ts +9 -0
  111. package/dist/homebridge-ui/public/js/discovery.d.ts.map +1 -0
  112. package/dist/homebridge-ui/public/js/discovery.js +1201 -0
  113. package/dist/homebridge-ui/public/js/discovery.js.map +1 -0
  114. package/dist/homebridge-ui/public/js/discovery.ts +1335 -0
  115. package/dist/homebridge-ui/public/js/logger.d.ts +7 -0
  116. package/dist/homebridge-ui/public/js/logger.d.ts.map +1 -0
  117. package/dist/homebridge-ui/public/js/logger.js +17 -0
  118. package/dist/homebridge-ui/public/js/logger.js.map +1 -0
  119. package/dist/homebridge-ui/public/js/logger.ts +17 -0
  120. package/dist/homebridge-ui/public/js/modal.d.ts +5 -0
  121. package/dist/homebridge-ui/public/js/modal.d.ts.map +1 -0
  122. package/dist/homebridge-ui/public/js/modal.js +35 -0
  123. package/dist/homebridge-ui/public/js/modal.js.map +1 -0
  124. package/dist/homebridge-ui/public/js/modal.ts +35 -0
  125. package/dist/homebridge-ui/public/js/modals.d.ts +15 -0
  126. package/dist/homebridge-ui/public/js/modals.d.ts.map +1 -0
  127. package/dist/homebridge-ui/public/js/modals.js +675 -0
  128. package/dist/homebridge-ui/public/js/modals.js.map +1 -0
  129. package/dist/homebridge-ui/public/js/modals.ts +765 -0
  130. package/dist/homebridge-ui/public/js/render.d.ts +71 -0
  131. package/dist/homebridge-ui/public/js/render.d.ts.map +1 -0
  132. package/dist/homebridge-ui/public/js/render.js +960 -0
  133. package/dist/homebridge-ui/public/js/render.js.map +1 -0
  134. package/dist/homebridge-ui/public/js/render.ts +1084 -0
  135. package/dist/homebridge-ui/public/js/toast.d.ts +6 -0
  136. package/dist/homebridge-ui/public/js/toast.d.ts.map +1 -0
  137. package/dist/homebridge-ui/public/js/toast.js +38 -0
  138. package/dist/homebridge-ui/public/js/toast.js.map +1 -0
  139. package/dist/homebridge-ui/public/js/toast.ts +44 -0
  140. package/dist/homebridge-ui/public/js/types.d.ts +23 -0
  141. package/dist/homebridge-ui/public/js/types.d.ts.map +1 -0
  142. package/dist/homebridge-ui/public/js/types.js +2 -0
  143. package/dist/homebridge-ui/public/js/types.js.map +1 -0
  144. package/dist/homebridge-ui/public/js/types.ts +26 -0
  145. package/dist/homebridge-ui/server.d.ts +1 -3
  146. package/dist/homebridge-ui/server.d.ts.map +1 -1
  147. package/dist/homebridge-ui/server.js +8 -471
  148. package/dist/homebridge-ui/server.js.map +1 -1
  149. package/dist/homebridge-ui/settings.js +8 -0
  150. package/dist/homebridge-ui/settings.js.map +1 -0
  151. package/dist/homebridge-ui/switchbotClient.js +247 -0
  152. package/dist/homebridge-ui/switchbotClient.js.map +1 -0
  153. package/dist/homebridge-ui/utils/config-parser.d.ts +39 -0
  154. package/dist/homebridge-ui/utils/config-parser.d.ts.map +1 -0
  155. package/dist/homebridge-ui/utils/config-parser.js +108 -0
  156. package/dist/homebridge-ui/utils/config-parser.js.map +1 -0
  157. package/dist/homebridge-ui/utils/device-migration.d.ts +35 -0
  158. package/dist/homebridge-ui/utils/device-migration.d.ts.map +1 -0
  159. package/dist/homebridge-ui/utils/device-migration.js +111 -0
  160. package/dist/homebridge-ui/utils/device-migration.js.map +1 -0
  161. package/dist/homebridge-ui/utils/logger.d.ts +7 -0
  162. package/dist/homebridge-ui/utils/logger.d.ts.map +1 -0
  163. package/dist/homebridge-ui/utils/logger.js +17 -0
  164. package/dist/homebridge-ui/utils/logger.js.map +1 -0
  165. package/dist/index.d.ts +10 -0
  166. package/dist/index.d.ts.map +1 -1
  167. package/dist/index.js +12 -2
  168. package/dist/index.js.map +1 -1
  169. package/dist/settings.d.ts +1 -0
  170. package/dist/settings.d.ts.map +1 -1
  171. package/dist/settings.js +1 -0
  172. package/dist/settings.js.map +1 -1
  173. package/dist/switchbotClient.d.ts +12 -10
  174. package/dist/switchbotClient.d.ts.map +1 -1
  175. package/dist/switchbotClient.js +156 -103
  176. package/dist/switchbotClient.js.map +1 -1
  177. package/dist/utils.d.ts +76 -1
  178. package/dist/utils.d.ts.map +1 -1
  179. package/dist/utils.js +1121 -4
  180. package/dist/utils.js.map +1 -1
  181. package/docs/assets/highlight.css +16 -2
  182. package/docs/assets/main.js +1 -1
  183. package/docs/index.html +82 -5
  184. package/docs/variables/default.html +3 -1
  185. package/eslint.config.js +9 -5
  186. package/nodemon.json +2 -2
  187. package/package.json +34 -21
  188. package/scripts/build-ui.js +37 -0
  189. package/scripts/free-dev-ports.mjs +105 -0
  190. package/scripts/generate-matter-maps.js +34 -17
  191. package/scripts/sync-device-types.mjs +31 -0
  192. package/src/SwitchBotHAPPlatform.ts +558 -0
  193. package/src/SwitchBotMatterPlatform.ts +538 -0
  194. package/src/device-types.js +246 -0
  195. package/src/device-types.js.map +1 -0
  196. package/src/device-types.ts +261 -0
  197. package/src/deviceCommandMapper.js +319 -0
  198. package/src/deviceCommandMapper.js.map +1 -0
  199. package/src/deviceCommandMapper.ts +333 -0
  200. package/src/deviceFactory.ts +125 -45
  201. package/src/devices/genericDevice.ts +411 -69
  202. package/src/errors.js +32 -0
  203. package/src/errors.js.map +1 -0
  204. package/src/errors.ts +35 -0
  205. package/src/homebridge-ui/endpoints/config.ts +110 -0
  206. package/src/homebridge-ui/endpoints/devices.ts +153 -0
  207. package/src/homebridge-ui/endpoints/discovery.ts +240 -0
  208. package/src/homebridge-ui/public/css/styles.css +483 -0
  209. package/src/homebridge-ui/public/index.html +197 -621
  210. package/src/homebridge-ui/public/js/advanced-settings.ts +94 -0
  211. package/src/homebridge-ui/public/js/api.ts +355 -0
  212. package/src/homebridge-ui/public/js/app.ts +22 -0
  213. package/src/homebridge-ui/public/js/constants.ts +1 -0
  214. package/src/homebridge-ui/public/js/credentials.ts +105 -0
  215. package/src/homebridge-ui/public/js/devices-delete.ts +227 -0
  216. package/src/homebridge-ui/public/js/devices.ts +106 -0
  217. package/src/homebridge-ui/public/js/discovery.ts +1335 -0
  218. package/src/homebridge-ui/public/js/logger.ts +17 -0
  219. package/src/homebridge-ui/public/js/modal.ts +35 -0
  220. package/src/homebridge-ui/public/js/modals.ts +765 -0
  221. package/src/homebridge-ui/public/js/render.ts +1084 -0
  222. package/src/homebridge-ui/public/js/toast.ts +44 -0
  223. package/src/homebridge-ui/public/js/types.ts +26 -0
  224. package/src/homebridge-ui/server.ts +9 -554
  225. package/src/homebridge-ui/utils/config-parser.ts +125 -0
  226. package/src/homebridge-ui/utils/device-migration.ts +144 -0
  227. package/src/homebridge-ui/utils/logger.ts +17 -0
  228. package/src/index.ts +12 -2
  229. package/src/settings.js +8 -0
  230. package/src/settings.js.map +1 -0
  231. package/src/settings.ts +2 -0
  232. package/src/switchbotClient.js +247 -0
  233. package/src/switchbotClient.js.map +1 -0
  234. package/src/switchbotClient.ts +177 -114
  235. package/src/utils.ts +1133 -5
  236. package/test/client/switchbot-client-debounce.spec.ts +35 -0
  237. package/test/client/switchbot-client-openapi.spec.ts +19 -0
  238. package/test/client/switchbotClient.spec.ts +64 -0
  239. package/test/device/device-mapping.spec.ts +23 -0
  240. package/test/device/deviceBase.spec.ts +26 -0
  241. package/test/device/deviceFactory-edge.spec.ts +15 -0
  242. package/test/device/deviceFactory.spec.ts +33 -0
  243. package/test/device/fan-swing.spec.ts +34 -0
  244. package/test/device/genericDevice-blepoll.spec.ts +47 -0
  245. package/test/device/irdevice.spec.ts +9 -0
  246. package/test/device/lock-users.spec.ts +35 -0
  247. package/test/device/matter-descriptors.spec.ts +22 -0
  248. package/test/device/matter-device-state.spec.ts +37 -0
  249. package/test/e2e/run-e2e.spec.ts +18 -19
  250. package/test/errors/errors.spec.ts +10 -0
  251. package/test/helpers/matter-harness.ts +20 -9
  252. package/test/homebridge-ui/server.spec.ts +9 -0
  253. package/test/platform/accessory-restore.spec.ts +37 -0
  254. package/test/platform/matter-childbridge.spec.ts +34 -0
  255. package/test/platform/matter-integration.spec.ts +33 -0
  256. package/test/platform/platform-edge.spec.ts +73 -0
  257. package/test/platform/platform.integration.spec.ts +34 -0
  258. package/test/utils/utils-extra.spec.ts +10 -0
  259. package/test/utils/utils.spec.ts +53 -0
  260. package/todo/TODO.md +80 -0
  261. package/tsconfig.ui.json +11 -0
  262. package/.github/npm-version-script-esm.js +0 -97
  263. package/.github/workflows/beta-release.yml +0 -52
  264. package/dist/platform.d.ts +0 -35
  265. package/dist/platform.d.ts.map +0 -1
  266. package/dist/platform.js +0 -945
  267. package/dist/platform.js.map +0 -1
  268. package/src/platform.ts +0 -963
  269. package/test/accessory-restore.spec.ts +0 -73
  270. package/test/device-mapping.spec.ts +0 -37
  271. package/test/deviceFactory.spec.ts +0 -18
  272. package/test/fan-swing.spec.ts +0 -29
  273. package/test/lock-users.spec.ts +0 -44
  274. package/test/matter-childbridge.spec.ts +0 -55
  275. package/test/matter-descriptors.spec.ts +0 -97
  276. package/test/matter-device-state.spec.ts +0 -101
  277. package/test/matter-integration.spec.ts +0 -70
  278. package/test/platform.integration.spec.ts +0 -55
  279. package/test/switchbot-client-debounce.spec.ts +0 -131
  280. package/test/switchbot-client-openapi.spec.ts +0 -56
  281. package/test/switchbotClient.spec.ts +0 -10
  282. package/test/utils.spec.ts +0 -20
@@ -1,131 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
2
- import { SwitchBotClient } from '../src/switchbotClient'
3
-
4
- describe('SwitchBotClient debounce/coalesce', () => {
5
- let origFetch: any
6
-
7
- beforeEach(() => {
8
- origFetch = (global as any).fetch
9
- vi.useFakeTimers()
10
- })
11
-
12
- afterEach(() => {
13
- (global as any).fetch = origFetch
14
- vi.restoreAllMocks()
15
- vi.useRealTimers()
16
- })
17
-
18
- it('coalesces rapid writes for the same device (last write wins)', async () => {
19
- const respBody = { status: 'ok' }
20
- const fetchMock = vi.fn(async (url: string, opts: any) => ({ json: async () => respBody }))
21
- ;(global as any).fetch = fetchMock
22
-
23
- // Set a short debounce in config to keep the test fast
24
- const c = new SwitchBotClient({ openApiToken: 't', writeDebounceMs: 10 } as any)
25
- await c.init()
26
-
27
- const body1 = { command: 'one' }
28
- const body2 = { command: 'two' }
29
-
30
- const p1 = c.setDeviceState('d-debounce', body1)
31
- const p2 = c.setDeviceState('d-debounce', body2)
32
-
33
- // Fast-forward timers past debounce window
34
- vi.advanceTimersByTime(20)
35
- // Allow pending microtasks to resolve
36
- await Promise.resolve()
37
- await Promise.resolve()
38
-
39
- const [r1, r2] = await Promise.all([p1, p2])
40
- expect(r1).toEqual(respBody)
41
- expect(r2).toEqual(respBody)
42
-
43
- // Only one network call should have been made
44
- expect(fetchMock).toHaveBeenCalledTimes(1)
45
- const calledBody = JSON.parse(fetchMock.mock.calls[0][1].body)
46
- expect(calledBody).toEqual(body2)
47
- })
48
-
49
- it('does not coalesce writes for different devices', async () => {
50
- const respBody = { status: 'ok' }
51
- const fetchMock = vi.fn(async (url: string, opts: any) => ({ json: async () => respBody }))
52
- ;(global as any).fetch = fetchMock
53
-
54
- const c = new SwitchBotClient({ openApiToken: 't', writeDebounceMs: 10 } as any)
55
- await c.init()
56
-
57
- const p1 = c.setDeviceState('d-A', { command: 'a' })
58
- const p2 = c.setDeviceState('d-B', { command: 'b' })
59
-
60
- vi.advanceTimersByTime(20)
61
- await Promise.resolve()
62
- await Promise.resolve()
63
-
64
- await Promise.all([p1, p2])
65
-
66
- expect(fetchMock).toHaveBeenCalledTimes(2)
67
- const b1 = JSON.parse(fetchMock.mock.calls[0][1].body)
68
- const b2 = JSON.parse(fetchMock.mock.calls[1][1].body)
69
- expect(b1).toEqual({ command: 'a' })
70
- expect(b2).toEqual({ command: 'b' })
71
- })
72
-
73
- it('coalesces multiple rapid writes (three) and resolves all promises with last response', async () => {
74
- const respBody = { status: 'ok', val: 'last' }
75
- const fetchMock = vi.fn(async (url: string, opts: any) => ({ json: async () => respBody }))
76
- ;(global as any).fetch = fetchMock
77
-
78
- const c = new SwitchBotClient({ openApiToken: 't', writeDebounceMs: 10 } as any)
79
- await c.init()
80
-
81
- const p1 = c.setDeviceState('d-debounce', { command: 'one' })
82
- const p2 = c.setDeviceState('d-debounce', { command: 'two' })
83
- const p3 = c.setDeviceState('d-debounce', { command: 'three' })
84
-
85
- vi.advanceTimersByTime(20)
86
- await Promise.resolve()
87
- await Promise.resolve()
88
-
89
- const [r1, r2, r3] = await Promise.all([p1, p2, p3])
90
- expect(r1).toEqual(respBody)
91
- expect(r2).toEqual(respBody)
92
- expect(r3).toEqual(respBody)
93
-
94
- expect(fetchMock).toHaveBeenCalledTimes(1)
95
- const calledBody = JSON.parse(fetchMock.mock.calls[0][1].body)
96
- expect(calledBody).toEqual({ command: 'three' })
97
- })
98
-
99
- it('separate writes outside debounce window produce multiple network calls', async () => {
100
- const respBody1 = { status: 'ok', seq: 1 }
101
- const respBody2 = { status: 'ok', seq: 2 }
102
- const fetchMock = vi.fn()
103
- .mockImplementationOnce(async () => ({ json: async () => respBody1 }))
104
- .mockImplementationOnce(async () => ({ json: async () => respBody2 }))
105
- ;(global as any).fetch = fetchMock
106
-
107
- const c = new SwitchBotClient({ openApiToken: 't', writeDebounceMs: 10 } as any)
108
- await c.init()
109
-
110
- const p1 = c.setDeviceState('d-debounce', { command: 'one' })
111
- vi.advanceTimersByTime(20)
112
- await Promise.resolve()
113
- await Promise.resolve()
114
-
115
- const p2 = c.setDeviceState('d-debounce', { command: 'two' })
116
- vi.advanceTimersByTime(20)
117
- await Promise.resolve()
118
- await Promise.resolve()
119
-
120
- const r1 = await p1
121
- const r2 = await p2
122
-
123
- expect(fetchMock).toHaveBeenCalledTimes(2)
124
- const b1 = JSON.parse(fetchMock.mock.calls[0][1].body)
125
- const b2 = JSON.parse(fetchMock.mock.calls[1][1].body)
126
- expect(b1).toEqual({ command: 'one' })
127
- expect(b2).toEqual({ command: 'two' })
128
- expect(r1).toEqual(respBody1)
129
- expect(r2).toEqual(respBody2)
130
- })
131
- })
@@ -1,56 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
2
- import { SwitchBotClient } from '../src/switchbotClient'
3
-
4
- describe('SwitchBotClient OpenAPI fallback', () => {
5
- let origFetch: any
6
-
7
- beforeEach(() => {
8
- origFetch = (global as any).fetch
9
- })
10
-
11
- afterEach(() => {
12
- (global as any).fetch = origFetch
13
- vi.restoreAllMocks()
14
- })
15
-
16
- it('throws when no client and no token', async () => {
17
- const c = new SwitchBotClient({} as any)
18
- await c.init()
19
- await expect(c.getDevice('nope')).rejects.toThrow('No SwitchBot client available')
20
- })
21
-
22
- it('uses OpenAPI when token provided for getDevice', async () => {
23
- const fakeResp = { body: { device: { id: 'd1', state: 'ok' } } }
24
- const fetchMock = vi.fn(async (url: string, opts: any) => ({ json: async () => fakeResp }))
25
- ;(global as any).fetch = fetchMock
26
-
27
- const c = new SwitchBotClient({ openApiToken: 'token-123' } as any)
28
- await c.init()
29
- const res = await c.getDevice('d1')
30
- expect(res).toEqual(fakeResp)
31
- expect(fetchMock).toHaveBeenCalledWith('https://api.switch-bot.com/v1.0/devices/d1', { headers: { Authorization: 'token-123' } })
32
- })
33
-
34
- it('posts commands to OpenAPI for setDeviceState', async () => {
35
- const respBody = { status: 'ok' }
36
- const fetchMock = vi.fn(async (url: string, opts: any) => ({ json: async () => respBody }))
37
- ;(global as any).fetch = fetchMock
38
-
39
- const c = new SwitchBotClient({ openApiToken: 't' } as any)
40
- await c.init()
41
- const body = { command: 'turnOn', parameter: 'default', commandType: 'command' }
42
- const out = await c.setDeviceState('d2', body)
43
- expect(out).toEqual(respBody)
44
- expect(fetchMock).toHaveBeenCalledWith('https://api.switch-bot.com/v1.0/devices/d2/commands', expect.objectContaining({ method: 'POST' }))
45
- const calledBody = JSON.parse((fetchMock.mock.calls[0][1].body))
46
- expect(calledBody).toEqual(body)
47
- })
48
-
49
- it('propagates fetch errors', async () => {
50
- const fetchMock = vi.fn(async () => { throw new Error('network') })
51
- ;(global as any).fetch = fetchMock
52
- const c = new SwitchBotClient({ openApiToken: 't' } as any)
53
- await c.init()
54
- await expect(c.getDevice('x')).rejects.toThrow('network')
55
- })
56
- })
@@ -1,10 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { SwitchBotClient } from '../src/switchbotClient'
3
-
4
- describe('SwitchBotClient', () => {
5
- it('init does not throw and getDevice throws when no token/client', async () => {
6
- const c = new SwitchBotClient({})
7
- await c.init()
8
- await expect(c.getDevice('nope')).rejects.toThrow()
9
- })
10
- })
@@ -1,20 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { createPlatformProxy } from '../src/utils'
3
-
4
- describe('createPlatformProxy', () => {
5
- it('returns Matter platform when preferMatter and enabled', () => {
6
- class HAP {}
7
- class Matter {}
8
- const ProxyCtor: any = createPlatformProxy(HAP, Matter)
9
- const impl = new (ProxyCtor as any)(console, { preferMatter: true, enableMatter: true }, undefined)
10
- expect(impl).toBeInstanceOf(Matter)
11
- })
12
-
13
- it('returns HAP platform when preferMatter is false', () => {
14
- class HAP {}
15
- class Matter {}
16
- const ProxyCtor: any = createPlatformProxy(HAP, Matter)
17
- const impl = new (ProxyCtor as any)(console, { preferMatter: false, enableMatter: true }, undefined)
18
- expect(impl).toBeInstanceOf(HAP)
19
- })
20
- })