amaran-light-cli 1.11.0 → 1.12.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 (363) hide show
  1. package/README.md +108 -14
  2. package/dist/__tests__/autoCct.test.js +27 -0
  3. package/dist/__tests__/autoCct.test.js.map +1 -1
  4. package/dist/__tests__/bleHttpControl.test.d.ts +2 -0
  5. package/dist/__tests__/bleHttpControl.test.d.ts.map +1 -0
  6. package/dist/__tests__/bleHttpControl.test.js +230 -0
  7. package/dist/__tests__/bleHttpControl.test.js.map +1 -0
  8. package/dist/__tests__/bleStack.test.d.ts +2 -0
  9. package/dist/__tests__/bleStack.test.d.ts.map +1 -0
  10. package/dist/__tests__/bleStack.test.js +1239 -0
  11. package/dist/__tests__/bleStack.test.js.map +1 -0
  12. package/dist/__tests__/cctUtil.test.js +9 -4
  13. package/dist/__tests__/cctUtil.test.js.map +1 -1
  14. package/dist/__tests__/circadianDashboardSettings.test.d.ts +2 -0
  15. package/dist/__tests__/circadianDashboardSettings.test.d.ts.map +1 -0
  16. package/dist/__tests__/circadianDashboardSettings.test.js +82 -0
  17. package/dist/__tests__/circadianDashboardSettings.test.js.map +1 -0
  18. package/dist/__tests__/circadianIsolation.test.d.ts +2 -0
  19. package/dist/__tests__/circadianIsolation.test.d.ts.map +1 -0
  20. package/dist/__tests__/circadianIsolation.test.js +30 -0
  21. package/dist/__tests__/circadianIsolation.test.js.map +1 -0
  22. package/dist/__tests__/cli.config.test.js +49 -0
  23. package/dist/__tests__/cli.config.test.js.map +1 -1
  24. package/dist/__tests__/cli.smoke.test.js +34 -0
  25. package/dist/__tests__/cli.smoke.test.js.map +1 -1
  26. package/dist/__tests__/currentCct.test.d.ts +2 -0
  27. package/dist/__tests__/currentCct.test.d.ts.map +1 -0
  28. package/dist/__tests__/currentCct.test.js +29 -0
  29. package/dist/__tests__/currentCct.test.js.map +1 -0
  30. package/dist/__tests__/dashboard.test.d.ts +2 -0
  31. package/dist/__tests__/dashboard.test.d.ts.map +1 -0
  32. package/dist/__tests__/dashboard.test.js +126 -0
  33. package/dist/__tests__/dashboard.test.js.map +1 -0
  34. package/dist/__tests__/daylightSimulationParseUtils.test.d.ts +2 -0
  35. package/dist/__tests__/daylightSimulationParseUtils.test.d.ts.map +1 -0
  36. package/dist/__tests__/daylightSimulationParseUtils.test.js +16 -0
  37. package/dist/__tests__/daylightSimulationParseUtils.test.js.map +1 -0
  38. package/dist/__tests__/desktopImport.test.d.ts +2 -0
  39. package/dist/__tests__/desktopImport.test.d.ts.map +1 -0
  40. package/dist/__tests__/desktopImport.test.js +234 -0
  41. package/dist/__tests__/desktopImport.test.js.map +1 -0
  42. package/dist/__tests__/lightControl.basic.test.d.ts +2 -0
  43. package/dist/__tests__/lightControl.basic.test.d.ts.map +1 -0
  44. package/dist/__tests__/lightControl.basic.test.js +119 -0
  45. package/dist/__tests__/lightControl.basic.test.js.map +1 -0
  46. package/dist/__tests__/lightControl.colorEffects.test.d.ts +2 -0
  47. package/dist/__tests__/lightControl.colorEffects.test.d.ts.map +1 -0
  48. package/dist/__tests__/lightControl.colorEffects.test.js +170 -0
  49. package/dist/__tests__/lightControl.colorEffects.test.js.map +1 -0
  50. package/dist/__tests__/lightControl.management.test.d.ts +2 -0
  51. package/dist/__tests__/lightControl.management.test.d.ts.map +1 -0
  52. package/dist/__tests__/lightControl.management.test.js +90 -0
  53. package/dist/__tests__/lightControl.management.test.js.map +1 -0
  54. package/dist/__tests__/lightControlTestUtils.d.ts +10 -0
  55. package/dist/__tests__/lightControlTestUtils.d.ts.map +1 -0
  56. package/dist/__tests__/lightControlTestUtils.js +57 -0
  57. package/dist/__tests__/lightControlTestUtils.js.map +1 -0
  58. package/dist/__tests__/meshConfiguration.test.d.ts +2 -0
  59. package/dist/__tests__/meshConfiguration.test.d.ts.map +1 -0
  60. package/dist/__tests__/meshConfiguration.test.js +78 -0
  61. package/dist/__tests__/meshConfiguration.test.js.map +1 -0
  62. package/dist/__tests__/nativeGroups.test.d.ts +2 -0
  63. package/dist/__tests__/nativeGroups.test.d.ts.map +1 -0
  64. package/dist/__tests__/nativeGroups.test.js +104 -0
  65. package/dist/__tests__/nativeGroups.test.js.map +1 -0
  66. package/dist/__tests__/programApi.test.d.ts +2 -0
  67. package/dist/__tests__/programApi.test.d.ts.map +1 -0
  68. package/dist/__tests__/programApi.test.js +73 -0
  69. package/dist/__tests__/programApi.test.js.map +1 -0
  70. package/dist/__tests__/programs.test.d.ts +2 -0
  71. package/dist/__tests__/programs.test.d.ts.map +1 -0
  72. package/dist/__tests__/programs.test.js +176 -0
  73. package/dist/__tests__/programs.test.js.map +1 -0
  74. package/dist/__tests__/scheduleMaker.test.d.ts +2 -0
  75. package/dist/__tests__/scheduleMaker.test.d.ts.map +1 -0
  76. package/dist/__tests__/scheduleMaker.test.js +25 -0
  77. package/dist/__tests__/scheduleMaker.test.js.map +1 -0
  78. package/dist/ble/async.d.ts +2 -0
  79. package/dist/ble/async.d.ts.map +1 -0
  80. package/dist/ble/async.js +15 -0
  81. package/dist/ble/async.js.map +1 -0
  82. package/dist/ble/colors.d.ts +5 -0
  83. package/dist/ble/colors.d.ts.map +1 -0
  84. package/dist/ble/colors.js +44 -0
  85. package/dist/ble/colors.js.map +1 -0
  86. package/dist/ble/configuration.d.ts +22 -0
  87. package/dist/ble/configuration.d.ts.map +1 -0
  88. package/dist/ble/configuration.js +122 -0
  89. package/dist/ble/configuration.js.map +1 -0
  90. package/dist/ble/controller.d.ts +118 -0
  91. package/dist/ble/controller.d.ts.map +1 -0
  92. package/dist/ble/controller.js +931 -0
  93. package/dist/ble/controller.js.map +1 -0
  94. package/dist/ble/crypto.d.ts +34 -0
  95. package/dist/ble/crypto.d.ts.map +1 -0
  96. package/dist/ble/crypto.js +178 -0
  97. package/dist/ble/crypto.js.map +1 -0
  98. package/dist/ble/daemon.d.ts +2 -0
  99. package/dist/ble/daemon.d.ts.map +1 -0
  100. package/dist/ble/daemon.js +76 -0
  101. package/dist/ble/daemon.js.map +1 -0
  102. package/dist/ble/dashboard.d.ts +331 -0
  103. package/dist/ble/dashboard.d.ts.map +1 -0
  104. package/dist/ble/dashboard.js +280 -0
  105. package/dist/ble/dashboard.js.map +1 -0
  106. package/dist/ble/desktop.d.ts +4 -0
  107. package/dist/ble/desktop.d.ts.map +1 -0
  108. package/dist/ble/desktop.js +33 -0
  109. package/dist/ble/desktop.js.map +1 -0
  110. package/dist/ble/desktopLibrary.d.ts +12 -0
  111. package/dist/ble/desktopLibrary.d.ts.map +1 -0
  112. package/dist/ble/desktopLibrary.js +346 -0
  113. package/dist/ble/desktopLibrary.js.map +1 -0
  114. package/dist/ble/effects.d.ts +34 -0
  115. package/dist/ble/effects.d.ts.map +1 -0
  116. package/dist/ble/effects.js +138 -0
  117. package/dist/ble/effects.js.map +1 -0
  118. package/dist/ble/fan.d.ts +244 -0
  119. package/dist/ble/fan.d.ts.map +1 -0
  120. package/dist/ble/fan.js +46 -0
  121. package/dist/ble/fan.js.map +1 -0
  122. package/dist/ble/library.d.ts +341 -0
  123. package/dist/ble/library.d.ts.map +1 -0
  124. package/dist/ble/library.js +201 -0
  125. package/dist/ble/library.js.map +1 -0
  126. package/dist/ble/media.d.ts +133 -0
  127. package/dist/ble/media.d.ts.map +1 -0
  128. package/dist/ble/media.js +186 -0
  129. package/dist/ble/media.js.map +1 -0
  130. package/dist/ble/nativeGroups.d.ts +22 -0
  131. package/dist/ble/nativeGroups.d.ts.map +1 -0
  132. package/dist/ble/nativeGroups.js +114 -0
  133. package/dist/ble/nativeGroups.js.map +1 -0
  134. package/dist/ble/packets.d.ts +3 -0
  135. package/dist/ble/packets.d.ts.map +1 -0
  136. package/dist/ble/packets.js +15 -0
  137. package/dist/ble/packets.js.map +1 -0
  138. package/dist/ble/programs.d.ts +318 -0
  139. package/dist/ble/programs.d.ts.map +1 -0
  140. package/dist/ble/programs.js +329 -0
  141. package/dist/ble/programs.js.map +1 -0
  142. package/dist/ble/provisioning.d.ts +13 -0
  143. package/dist/ble/provisioning.d.ts.map +1 -0
  144. package/dist/ble/provisioning.js +39 -0
  145. package/dist/ble/provisioning.js.map +1 -0
  146. package/dist/ble/server.d.ts +18 -0
  147. package/dist/ble/server.d.ts.map +1 -0
  148. package/dist/ble/server.js +548 -0
  149. package/dist/ble/server.js.map +1 -0
  150. package/dist/ble/service.d.ts +2 -0
  151. package/dist/ble/service.d.ts.map +1 -0
  152. package/dist/ble/service.js +77 -0
  153. package/dist/ble/service.js.map +1 -0
  154. package/dist/ble/settings.d.ts +18 -0
  155. package/dist/ble/settings.d.ts.map +1 -0
  156. package/dist/ble/settings.js +25 -0
  157. package/dist/ble/settings.js.map +1 -0
  158. package/dist/ble/setup.d.ts +2 -0
  159. package/dist/ble/setup.d.ts.map +1 -0
  160. package/dist/ble/setup.js +31 -0
  161. package/dist/ble/setup.js.map +1 -0
  162. package/dist/ble/storage.d.ts +94 -0
  163. package/dist/ble/storage.d.ts.map +1 -0
  164. package/dist/ble/storage.js +132 -0
  165. package/dist/ble/storage.js.map +1 -0
  166. package/dist/ble/telink.d.ts +63 -0
  167. package/dist/ble/telink.d.ts.map +1 -0
  168. package/dist/ble/telink.js +108 -0
  169. package/dist/ble/telink.js.map +1 -0
  170. package/dist/ble/transitions.d.ts +3 -0
  171. package/dist/ble/transitions.d.ts.map +1 -0
  172. package/dist/ble/transitions.js +28 -0
  173. package/dist/ble/transitions.js.map +1 -0
  174. package/dist/ble/transport.d.ts +48 -0
  175. package/dist/ble/transport.d.ts.map +1 -0
  176. package/dist/ble/transport.js +370 -0
  177. package/dist/ble/transport.js.map +1 -0
  178. package/dist/circadian.d.ts +3 -0
  179. package/dist/circadian.d.ts.map +1 -1
  180. package/dist/circadian.js +2 -0
  181. package/dist/circadian.js.map +1 -1
  182. package/dist/cli.d.ts +3 -2
  183. package/dist/cli.d.ts.map +1 -1
  184. package/dist/cli.js +125 -6
  185. package/dist/cli.js.map +1 -1
  186. package/dist/commands/__tests__/newCommands.test.js +3 -4
  187. package/dist/commands/__tests__/newCommands.test.js.map +1 -1
  188. package/dist/commands/cmdUtils.d.ts +5 -2
  189. package/dist/commands/cmdUtils.d.ts.map +1 -1
  190. package/dist/commands/cmdUtils.js +29 -10
  191. package/dist/commands/cmdUtils.js.map +1 -1
  192. package/dist/commands/daylightSimulation/autoCct.d.ts.map +1 -1
  193. package/dist/commands/daylightSimulation/autoCct.js +67 -197
  194. package/dist/commands/daylightSimulation/autoCct.js.map +1 -1
  195. package/dist/commands/daylightSimulation/graphSchedule.d.ts +1 -1
  196. package/dist/commands/daylightSimulation/graphSchedule.d.ts.map +1 -1
  197. package/dist/commands/daylightSimulation/printSchedule.d.ts +1 -1
  198. package/dist/commands/daylightSimulation/printSchedule.d.ts.map +1 -1
  199. package/dist/commands/daylightSimulation/printSchedule.js +2 -2
  200. package/dist/commands/daylightSimulation/printSchedule.js.map +1 -1
  201. package/dist/commands/daylightSimulation/service.d.ts +1 -1
  202. package/dist/commands/daylightSimulation/service.d.ts.map +1 -1
  203. package/dist/commands/daylightSimulation/service.js +5 -3
  204. package/dist/commands/daylightSimulation/service.js.map +1 -1
  205. package/dist/commands/daylightSimulation/simulateSchedule.d.ts +1 -1
  206. package/dist/commands/daylightSimulation/simulateSchedule.d.ts.map +1 -1
  207. package/dist/commands/daylightSimulation/simulateSchedule.js +5 -4
  208. package/dist/commands/daylightSimulation/simulateSchedule.js.map +1 -1
  209. package/dist/commands/deviceControl/ble.d.ts +4 -0
  210. package/dist/commands/deviceControl/ble.d.ts.map +1 -0
  211. package/dist/commands/deviceControl/ble.js +214 -0
  212. package/dist/commands/deviceControl/ble.js.map +1 -0
  213. package/dist/commands/deviceControl/cct.d.ts.map +1 -1
  214. package/dist/commands/deviceControl/cct.js +41 -11
  215. package/dist/commands/deviceControl/cct.js.map +1 -1
  216. package/dist/commands/deviceControl/color.d.ts.map +1 -1
  217. package/dist/commands/deviceControl/color.js +13 -3
  218. package/dist/commands/deviceControl/color.js.map +1 -1
  219. package/dist/commands/deviceControl/config.d.ts.map +1 -1
  220. package/dist/commands/deviceControl/config.js +26 -3
  221. package/dist/commands/deviceControl/config.js.map +1 -1
  222. package/dist/commands/deviceControl/{discover.d.ts → desktop.d.ts} +3 -2
  223. package/dist/commands/deviceControl/desktop.d.ts.map +1 -0
  224. package/dist/commands/deviceControl/desktop.js +66 -0
  225. package/dist/commands/deviceControl/desktop.js.map +1 -0
  226. package/dist/commands/deviceControl/effect.d.ts.map +1 -1
  227. package/dist/commands/deviceControl/effect.js +90 -159
  228. package/dist/commands/deviceControl/effect.js.map +1 -1
  229. package/dist/commands/deviceControl/fan.d.ts.map +1 -1
  230. package/dist/commands/deviceControl/fan.js +77 -95
  231. package/dist/commands/deviceControl/fan.js.map +1 -1
  232. package/dist/commands/deviceControl/group.d.ts.map +1 -1
  233. package/dist/commands/deviceControl/group.js +43 -6
  234. package/dist/commands/deviceControl/group.js.map +1 -1
  235. package/dist/commands/deviceControl/hsi.d.ts.map +1 -1
  236. package/dist/commands/deviceControl/hsi.js +3 -1
  237. package/dist/commands/deviceControl/hsi.js.map +1 -1
  238. package/dist/commands/deviceControl/info.d.ts.map +1 -1
  239. package/dist/commands/deviceControl/info.js +0 -50
  240. package/dist/commands/deviceControl/info.js.map +1 -1
  241. package/dist/commands/deviceControl/intensity.d.ts.map +1 -1
  242. package/dist/commands/deviceControl/intensity.js +32 -8
  243. package/dist/commands/deviceControl/intensity.js.map +1 -1
  244. package/dist/commands/deviceControl/list.d.ts.map +1 -1
  245. package/dist/commands/deviceControl/list.js +3 -2
  246. package/dist/commands/deviceControl/list.js.map +1 -1
  247. package/dist/commands/deviceControl/power.d.ts.map +1 -1
  248. package/dist/commands/deviceControl/power.js +9 -3
  249. package/dist/commands/deviceControl/power.js.map +1 -1
  250. package/dist/commands/deviceControl/preset.d.ts.map +1 -1
  251. package/dist/commands/deviceControl/preset.js +56 -19
  252. package/dist/commands/deviceControl/preset.js.map +1 -1
  253. package/dist/commands/deviceControl/program.d.ts +4 -0
  254. package/dist/commands/deviceControl/program.d.ts.map +1 -0
  255. package/dist/commands/deviceControl/program.js +199 -0
  256. package/dist/commands/deviceControl/program.js.map +1 -0
  257. package/dist/commands/deviceControl/quickshot.d.ts.map +1 -1
  258. package/dist/commands/deviceControl/quickshot.js +75 -13
  259. package/dist/commands/deviceControl/quickshot.js.map +1 -1
  260. package/dist/commands/deviceControl/scene.d.ts.map +1 -1
  261. package/dist/commands/deviceControl/scene.js +72 -9
  262. package/dist/commands/deviceControl/scene.js.map +1 -1
  263. package/dist/commands/deviceControl/status.d.ts.map +1 -1
  264. package/dist/commands/deviceControl/status.js +26 -3
  265. package/dist/commands/deviceControl/status.js.map +1 -1
  266. package/dist/commands/parseUtils.d.ts +1 -1
  267. package/dist/commands/parseUtils.d.ts.map +1 -1
  268. package/dist/commands/parseUtils.js +1 -11
  269. package/dist/commands/parseUtils.js.map +1 -1
  270. package/dist/commands-api.d.ts +1 -1
  271. package/dist/commands-api.d.ts.map +1 -1
  272. package/dist/commands-api.js +1 -1
  273. package/dist/commands-api.js.map +1 -1
  274. package/dist/commands.d.ts.map +1 -1
  275. package/dist/commands.js +4 -2
  276. package/dist/commands.js.map +1 -1
  277. package/dist/config.d.ts +82 -0
  278. package/dist/config.d.ts.map +1 -1
  279. package/dist/config.js +13 -2
  280. package/dist/config.js.map +1 -1
  281. package/dist/daylightSimulation/cctUtil.d.ts.map +1 -1
  282. package/dist/daylightSimulation/cctUtil.js +2 -2
  283. package/dist/daylightSimulation/cctUtil.js.map +1 -1
  284. package/dist/daylightSimulation/constants.d.ts +10 -0
  285. package/dist/daylightSimulation/constants.d.ts.map +1 -1
  286. package/dist/daylightSimulation/constants.js +4 -0
  287. package/dist/daylightSimulation/constants.js.map +1 -1
  288. package/dist/daylightSimulation/currentCct.d.ts +42 -0
  289. package/dist/daylightSimulation/currentCct.d.ts.map +1 -0
  290. package/dist/daylightSimulation/currentCct.js +217 -0
  291. package/dist/daylightSimulation/currentCct.js.map +1 -0
  292. package/dist/daylightSimulation/dashboardSettings.d.ts +47 -0
  293. package/dist/daylightSimulation/dashboardSettings.d.ts.map +1 -0
  294. package/dist/daylightSimulation/dashboardSettings.js +95 -0
  295. package/dist/daylightSimulation/dashboardSettings.js.map +1 -0
  296. package/dist/daylightSimulation/dashboardStatus.d.ts +72 -0
  297. package/dist/daylightSimulation/dashboardStatus.d.ts.map +1 -0
  298. package/dist/daylightSimulation/dashboardStatus.js +191 -0
  299. package/dist/daylightSimulation/dashboardStatus.js.map +1 -0
  300. package/dist/daylightSimulation/parseUtils.d.ts +3 -0
  301. package/dist/daylightSimulation/parseUtils.d.ts.map +1 -0
  302. package/dist/daylightSimulation/parseUtils.js +25 -0
  303. package/dist/daylightSimulation/parseUtils.js.map +1 -0
  304. package/dist/daylightSimulation/scheduleMaker.d.ts +2 -2
  305. package/dist/daylightSimulation/scheduleMaker.d.ts.map +1 -1
  306. package/dist/daylightSimulation/scheduleMaker.js +6 -6
  307. package/dist/daylightSimulation/scheduleMaker.js.map +1 -1
  308. package/dist/daylightSimulation/types.d.ts +13 -2
  309. package/dist/daylightSimulation/types.d.ts.map +1 -1
  310. package/dist/daylightSimulation/types.js +0 -2
  311. package/dist/daylightSimulation/types.js.map +1 -1
  312. package/dist/device-control.d.ts +1 -0
  313. package/dist/device-control.d.ts.map +1 -1
  314. package/dist/device-control.js +1 -0
  315. package/dist/device-control.js.map +1 -1
  316. package/dist/deviceControl/bleHttpControl.d.ts +129 -0
  317. package/dist/deviceControl/bleHttpControl.d.ts.map +1 -0
  318. package/dist/deviceControl/bleHttpControl.js +753 -0
  319. package/dist/deviceControl/bleHttpControl.js.map +1 -0
  320. package/dist/deviceControl/lightControl.d.ts +8 -68
  321. package/dist/deviceControl/lightControl.d.ts.map +1 -1
  322. package/dist/deviceControl/lightControl.js +6 -246
  323. package/dist/deviceControl/lightControl.js.map +1 -1
  324. package/dist/deviceControl/lightControlCommands.d.ts +68 -0
  325. package/dist/deviceControl/lightControlCommands.d.ts.map +1 -0
  326. package/dist/deviceControl/lightControlCommands.js +244 -0
  327. package/dist/deviceControl/lightControlCommands.js.map +1 -0
  328. package/dist/deviceControl/types.d.ts +75 -4
  329. package/dist/deviceControl/types.d.ts.map +1 -1
  330. package/dist/deviceControl/types.js +1 -0
  331. package/dist/deviceControl/types.js.map +1 -1
  332. package/dist/index.d.ts +2 -1
  333. package/dist/index.d.ts.map +1 -1
  334. package/dist/index.js +1 -0
  335. package/dist/index.js.map +1 -1
  336. package/dist/test/MockLightServer.d.ts +1 -0
  337. package/dist/test/MockLightServer.d.ts.map +1 -1
  338. package/dist/test/MockLightServer.js +5 -0
  339. package/dist/test/MockLightServer.js.map +1 -1
  340. package/docs/CHANGELOG.md +37 -0
  341. package/docs/DIRECT_BLE.md +359 -0
  342. package/package.json +8 -4
  343. package/scripts/ble-cli-check.ts +129 -0
  344. package/scripts/ble-config-probe.ts +109 -0
  345. package/scripts/ble-effects-check.ts +82 -0
  346. package/scripts/ble-extended-probe.ts +44 -0
  347. package/scripts/ble-fan-check.ts +129 -0
  348. package/scripts/ble-feature-probe.ts +37 -0
  349. package/scripts/ble-followup-check.ts +165 -0
  350. package/scripts/ble-hardware-check.ts +99 -0
  351. package/scripts/ble-live-extended-check.ts +205 -0
  352. package/scripts/ble-non-ota-check.ts +193 -0
  353. package/scripts/ble-probe.ts +45 -0
  354. package/scripts/calibrate-webcam.ts +152 -0
  355. package/scripts/desktop-reference.ts +85 -0
  356. package/scripts/webcam.ts +129 -0
  357. package/dist/__tests__/lightControl.test.d.ts +0 -2
  358. package/dist/__tests__/lightControl.test.d.ts.map +0 -1
  359. package/dist/__tests__/lightControl.test.js +0 -424
  360. package/dist/__tests__/lightControl.test.js.map +0 -1
  361. package/dist/commands/deviceControl/discover.d.ts.map +0 -1
  362. package/dist/commands/deviceControl/discover.js +0 -29
  363. package/dist/commands/deviceControl/discover.js.map +0 -1
@@ -0,0 +1,170 @@
1
+ import { setupLightControllerSuite, TEST_NODE_ID } from './lightControlTestUtils.js';
2
+ describe('LightController color, effects, and hardware commands', () => {
3
+ const fixture = setupLightControllerSuite(18090);
4
+ it('should set HSI for all lights', async () => {
5
+ const controller = await fixture.createReadyController();
6
+ await new Promise((resolve) => {
7
+ controller.setHSIForAllLights(120, 80, 100, 5600, 0, (success, msg) => {
8
+ expect(success).toBe(true);
9
+ expect(msg).toBe('OK');
10
+ resolve();
11
+ });
12
+ });
13
+ const state = fixture.server.getDeviceState(TEST_NODE_ID);
14
+ expect(state?.hue).toBe(120);
15
+ expect(state?.sat).toBe(80);
16
+ expect(state?.intensity).toBe(100);
17
+ expect(state?.work_mode).toBe('HSI');
18
+ }, 5000);
19
+ it('should set color for all lights', async () => {
20
+ const controller = await fixture.createReadyController();
21
+ await new Promise((resolve) => {
22
+ controller.setColorForAllLights('red', 100, (success, msg) => {
23
+ expect(success).toBe(true);
24
+ expect(msg).toBe('OK');
25
+ resolve();
26
+ });
27
+ });
28
+ }, 5000);
29
+ it('should set system effect for all lights', async () => {
30
+ const controller = await fixture.createReadyController();
31
+ await new Promise((resolve) => {
32
+ controller.setSystemEffectForAllLights('flash', 100, (success, msg) => {
33
+ expect(success).toBe(true);
34
+ expect(msg).toBe('OK');
35
+ resolve();
36
+ });
37
+ });
38
+ }, 5000);
39
+ it('should get intensity and CCT', async () => {
40
+ const controller = await fixture.createReadyController();
41
+ await new Promise((resolve) => {
42
+ controller.setIntensity(TEST_NODE_ID, 750, (success) => {
43
+ expect(success).toBe(true);
44
+ resolve();
45
+ });
46
+ });
47
+ await new Promise((resolve) => {
48
+ controller.getIntensity(TEST_NODE_ID, (success, _msg, data) => {
49
+ expect(success).toBe(true);
50
+ expect(data).toBe(750);
51
+ resolve();
52
+ });
53
+ });
54
+ await new Promise((resolve) => {
55
+ controller.setCCT(TEST_NODE_ID, 4500, undefined, (success) => {
56
+ expect(success).toBe(true);
57
+ resolve();
58
+ });
59
+ });
60
+ await new Promise((resolve) => {
61
+ controller.getCCT(TEST_NODE_ID, (success, _msg, data) => {
62
+ expect(success).toBe(true);
63
+ // biome-ignore lint/suspicious/noExplicitAny: Mock data comparison
64
+ expect(data.cct).toBe(4500);
65
+ resolve();
66
+ });
67
+ });
68
+ }, 5000);
69
+ it('should set and get RGB', async () => {
70
+ const controller = await fixture.createReadyController();
71
+ await new Promise((resolve) => {
72
+ controller.setRGB(TEST_NODE_ID, 255, 0, 128, 500, (success) => {
73
+ expect(success).toBe(true);
74
+ resolve();
75
+ });
76
+ });
77
+ await new Promise((resolve) => {
78
+ controller.getRGB(TEST_NODE_ID, (success, _msg, data) => {
79
+ expect(success).toBe(true);
80
+ // biome-ignore lint/suspicious/noExplicitAny: Mock data comparison
81
+ expect(data.r).toBe(255);
82
+ // biome-ignore lint/suspicious/noExplicitAny: Mock data comparison
83
+ expect(data.b).toBe(128);
84
+ // biome-ignore lint/suspicious/noExplicitAny: Mock data comparison
85
+ expect(data.intensity).toBe(500);
86
+ resolve();
87
+ });
88
+ });
89
+ }, 5000);
90
+ it('should set and get XY', async () => {
91
+ const controller = await fixture.createReadyController();
92
+ await new Promise((resolve) => {
93
+ controller.setXY(TEST_NODE_ID, 0.3, 0.4, 600, (success) => {
94
+ expect(success).toBe(true);
95
+ resolve();
96
+ });
97
+ });
98
+ await new Promise((resolve) => {
99
+ controller.getXY(TEST_NODE_ID, (success, _msg, data) => {
100
+ expect(success).toBe(true);
101
+ // biome-ignore lint/suspicious/noExplicitAny: Mock data comparison
102
+ expect(data.x).toBe(0.3);
103
+ // biome-ignore lint/suspicious/noExplicitAny: Mock data comparison
104
+ expect(data.y).toBe(0.4);
105
+ resolve();
106
+ });
107
+ });
108
+ }, 5000);
109
+ it('should manage custom effects', async () => {
110
+ const controller = await fixture.createReadyController();
111
+ await new Promise((resolve) => {
112
+ controller.setEffect(TEST_NODE_ID, 'Strobe', { speed: 10 }, (success) => {
113
+ expect(success).toBe(true);
114
+ resolve();
115
+ });
116
+ });
117
+ await new Promise((resolve) => {
118
+ controller.getEffect(TEST_NODE_ID, (success, _msg, data) => {
119
+ expect(success).toBe(true);
120
+ expect(data).toBe('Strobe');
121
+ resolve();
122
+ });
123
+ });
124
+ }, 5000);
125
+ it('should control fan', async () => {
126
+ const controller = await fixture.createReadyController();
127
+ await new Promise((resolve) => {
128
+ controller.setFanMode(TEST_NODE_ID, 1, (success) => {
129
+ expect(success).toBe(true);
130
+ resolve();
131
+ });
132
+ });
133
+ await new Promise((resolve) => {
134
+ controller.getFanMode(TEST_NODE_ID, (success, _msg, data) => {
135
+ expect(success).toBe(true);
136
+ expect(data).toBe(1);
137
+ resolve();
138
+ });
139
+ });
140
+ await new Promise((resolve) => {
141
+ controller.setFanSpeed(TEST_NODE_ID, 2200, (success) => {
142
+ expect(success).toBe(true);
143
+ resolve();
144
+ });
145
+ });
146
+ await new Promise((resolve) => {
147
+ controller.getFanSpeed(TEST_NODE_ID, (success, _msg, data) => {
148
+ expect(success).toBe(true);
149
+ expect(data).toBe(2200);
150
+ resolve();
151
+ });
152
+ });
153
+ }, 5000);
154
+ it('should control effect speed and intensity', async () => {
155
+ const controller = await fixture.createReadyController();
156
+ await new Promise((resolve) => {
157
+ controller.setEffectSpeed(TEST_NODE_ID, 50, (success) => {
158
+ expect(success).toBe(true);
159
+ resolve();
160
+ });
161
+ });
162
+ await new Promise((resolve) => {
163
+ controller.setEffectIntensity(TEST_NODE_ID, 800, (success) => {
164
+ expect(success).toBe(true);
165
+ resolve();
166
+ });
167
+ });
168
+ });
169
+ });
170
+ //# sourceMappingURL=lightControl.colorEffects.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lightControl.colorEffects.test.js","sourceRoot":"","sources":["../../src/__tests__/lightControl.colorEffects.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=lightControl.management.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lightControl.management.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/lightControl.management.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,90 @@
1
+ import { setupLightControllerSuite, TEST_NODE_ID } from './lightControlTestUtils.js';
2
+ describe('LightController scenes, presets, quickshots, and groups', () => {
3
+ const fixture = setupLightControllerSuite(18091);
4
+ it('should handle scene management', async () => {
5
+ const controller = await fixture.createReadyController();
6
+ await new Promise((resolve) => {
7
+ controller.saveScene('Midnight', (success, _msg, data) => {
8
+ expect(success).toBe(true);
9
+ // biome-ignore lint/suspicious/noExplicitAny: Mock data comparison
10
+ expect(data.id).toBe('scene-123');
11
+ resolve();
12
+ });
13
+ });
14
+ await new Promise((resolve) => {
15
+ controller.recallScene('scene-123', (success) => {
16
+ expect(success).toBe(true);
17
+ resolve();
18
+ });
19
+ });
20
+ }, 5000);
21
+ it('should set preset', async () => {
22
+ const controller = await fixture.createReadyController();
23
+ await new Promise((resolve) => {
24
+ controller.setPreset(TEST_NODE_ID, 'preset-456', (success, _msg, data) => {
25
+ expect(success).toBe(true);
26
+ // biome-ignore lint/suspicious/noExplicitAny: Mock data comparison
27
+ expect(data.id).toBe('preset-456');
28
+ resolve();
29
+ });
30
+ });
31
+ });
32
+ it('should get quickshot list', async () => {
33
+ const controller = await fixture.createReadyController();
34
+ await new Promise((resolve) => {
35
+ controller.getQuickshotList((success, _msg, data) => {
36
+ expect(success).toBe(true);
37
+ // biome-ignore lint/suspicious/noExplicitAny: Mock data comparison
38
+ expect(data.data.length).toBeGreaterThan(0);
39
+ resolve();
40
+ });
41
+ });
42
+ });
43
+ it('should set quickshot', async () => {
44
+ const controller = await fixture.createReadyController();
45
+ await new Promise((resolve) => {
46
+ controller.setQuickshot('qs-123', (success, _msg, data) => {
47
+ expect(success).toBe(true);
48
+ expect(data).toBe('qs-123');
49
+ resolve();
50
+ });
51
+ });
52
+ });
53
+ it('should manage groups', async () => {
54
+ const controller = await fixture.createReadyController();
55
+ let createdGroupId = '';
56
+ await new Promise((resolve) => {
57
+ controller.createGroup('All Room', (success, _msg, data) => {
58
+ expect(success).toBe(true);
59
+ // biome-ignore lint/suspicious/noExplicitAny: Mock data comparison
60
+ createdGroupId = data.id;
61
+ resolve();
62
+ });
63
+ });
64
+ await new Promise((resolve) => {
65
+ controller.addToGroup(createdGroupId, TEST_NODE_ID, (success) => {
66
+ expect(success).toBe(true);
67
+ resolve();
68
+ });
69
+ });
70
+ await new Promise((resolve) => {
71
+ controller.getGroupList((success) => {
72
+ expect(success).toBe(true);
73
+ resolve();
74
+ });
75
+ });
76
+ await new Promise((resolve) => {
77
+ controller.removeFromGroup(createdGroupId, TEST_NODE_ID, (success) => {
78
+ expect(success).toBe(true);
79
+ resolve();
80
+ });
81
+ });
82
+ await new Promise((resolve) => {
83
+ controller.deleteGroup(createdGroupId, (success) => {
84
+ expect(success).toBe(true);
85
+ resolve();
86
+ });
87
+ });
88
+ });
89
+ });
90
+ //# sourceMappingURL=lightControl.management.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lightControl.management.test.js","sourceRoot":"","sources":["../../src/__tests__/lightControl.management.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import LightController from '../deviceControl/lightControl.js';
2
+ import { MockLightServer } from '../test/MockLightServer.js';
3
+ export declare const TEST_NODE_ID = "400J5-F2C008";
4
+ export declare function setupLightControllerSuite(testPort: number): {
5
+ createController: (onInitialized?: () => void) => LightController;
6
+ createReadyController: (onInitialized?: () => void) => Promise<LightController>;
7
+ readonly controller: LightController | undefined;
8
+ readonly server: MockLightServer;
9
+ };
10
+ //# sourceMappingURL=lightControlTestUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lightControlTestUtils.d.ts","sourceRoot":"","sources":["../../src/__tests__/lightControlTestUtils.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM;uCA8Bd,MAAM,IAAI;4CAKC,MAAM,IAAI;;;EA4BhE"}
@@ -0,0 +1,57 @@
1
+ import LightController from '../deviceControl/lightControl.js';
2
+ import { MockLightServer } from '../test/MockLightServer.js';
3
+ export const TEST_NODE_ID = '400J5-F2C008';
4
+ export function setupLightControllerSuite(testPort) {
5
+ const wsUrl = `ws://localhost:${testPort}`;
6
+ let server;
7
+ let controller;
8
+ beforeAll(async () => {
9
+ server = new MockLightServer(testPort);
10
+ await server.ready;
11
+ });
12
+ afterAll(async () => {
13
+ await new Promise((resolve, reject) => {
14
+ server.close((err) => {
15
+ if (err) {
16
+ reject(err);
17
+ return;
18
+ }
19
+ resolve();
20
+ });
21
+ });
22
+ });
23
+ afterEach(async () => {
24
+ if (controller) {
25
+ await controller.disconnect();
26
+ controller = undefined;
27
+ }
28
+ server.resetState();
29
+ });
30
+ const createController = (onInitialized) => {
31
+ controller = new LightController(wsUrl, 'test_client', onInitialized, false);
32
+ return controller;
33
+ };
34
+ const createReadyController = async (onInitialized) => {
35
+ const readyController = await new Promise((resolve, reject) => {
36
+ const timeout = setTimeout(() => reject(new Error('Controller initialization timeout')), 2000);
37
+ const nextController = new LightController(wsUrl, 'test_client', () => {
38
+ clearTimeout(timeout);
39
+ onInitialized?.();
40
+ resolve(nextController);
41
+ }, false);
42
+ controller = nextController;
43
+ });
44
+ return readyController;
45
+ };
46
+ return {
47
+ createController,
48
+ createReadyController,
49
+ get controller() {
50
+ return controller;
51
+ },
52
+ get server() {
53
+ return server;
54
+ },
55
+ };
56
+ }
57
+ //# sourceMappingURL=lightControlTestUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lightControlTestUtils.js","sourceRoot":"","sources":["../../src/__tests__/lightControlTestUtils.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,MAAM,CAAC,MAAM,YAAY,GAAG,cAAc,CAAC;AAE3C,MAAM,UAAU,yBAAyB,CAAC,QAAgB;IACxD,MAAM,KAAK,GAAG,kBAAkB,QAAQ,EAAE,CAAC;IAC3C,IAAI,MAAuB,CAAC;IAC5B,IAAI,UAAuC,CAAC;IAE5C,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,MAAM,CAAC,KAAK,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,KAAK,IAAI,EAAE;QAClB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACnB,IAAI,GAAG,EAAE,CAAC;oBACR,MAAM,CAAC,GAAG,CAAC,CAAC;oBACZ,OAAO;gBACT,CAAC;gBACD,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,UAAU,CAAC,UAAU,EAAE,CAAC;YAC9B,UAAU,GAAG,SAAS,CAAC;QACzB,CAAC;QACD,MAAM,CAAC,UAAU,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,MAAM,gBAAgB,GAAG,CAAC,aAA0B,EAAE,EAAE;QACtD,UAAU,GAAG,IAAI,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;QAC7E,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;IAEF,MAAM,qBAAqB,GAAG,KAAK,EAAE,aAA0B,EAAE,EAAE;QACjE,MAAM,eAAe,GAAG,MAAM,IAAI,OAAO,CAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC7E,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YAC/F,MAAM,cAAc,GAAG,IAAI,eAAe,CACxC,KAAK,EACL,aAAa,EACb,GAAG,EAAE;gBACH,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,aAAa,EAAE,EAAE,CAAC;gBAClB,OAAO,CAAC,cAAc,CAAC,CAAC;YAC1B,CAAC,EACD,KAAK,CACN,CAAC;YACF,UAAU,GAAG,cAAc,CAAC;QAC9B,CAAC,CAAC,CAAC;QACH,OAAO,eAAe,CAAC;IACzB,CAAC,CAAC;IAEF,OAAO;QACL,gBAAgB;QAChB,qBAAqB;QACrB,IAAI,UAAU;YACZ,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,IAAI,MAAM;YACR,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=meshConfiguration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meshConfiguration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/meshConfiguration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,78 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { changeSubscription, composition, subscriptions } from '../ble/configuration.js';
3
+ import { VerifiedController } from '../ble/controller.js';
4
+ import { MeshCrypto } from '../ble/crypto.js';
5
+ import { createBleServer } from '../ble/server.js';
6
+ const net = '7dd7364cd842ad18c17c2b820c84c3d6';
7
+ const app = '63964771734fbd76e3b40519d1d94a48';
8
+ const device = '2b7e151628aed2a6abf7158809cf4f3c';
9
+ describe('Device Key configuration', () => {
10
+ it('uses Device nonces independently of application encryption', () => {
11
+ const crypto = new MeshCrypto(net, app);
12
+ const data = Buffer.from('800800', 'hex');
13
+ const lower = crypto.deviceAccess(device, data, 128, 32766, 6, 0);
14
+ const message = { source: 32766, destination: 6, sequence: 128, iv: 0, control: false, transport: lower };
15
+ expect(lower[0]).toBe(0);
16
+ expect(crypto.readDeviceAccess(device, lower.subarray(1), message)).toEqual(data);
17
+ expect(() => crypto.readAccess(lower.subarray(1), message)).toThrow();
18
+ expect(() => crypto.readDeviceAccess(app, lower.subarray(1), message)).toThrow();
19
+ expect(() => crypto.deviceAccess(device, Buffer.alloc(12), 129, 32766, 6, 0)).toThrow('segmented');
20
+ });
21
+ it('decodes Desktop-captured composition without trusting truncated elements', () => {
22
+ const raw = Buffer.from('020011020102333369000A0000000A01000002000300001002100410061007100013011311020000', 'hex');
23
+ const result = composition(raw, 6);
24
+ expect(result.company).toBe(0x0211);
25
+ expect(result.models).toHaveLength(11);
26
+ expect(result.models.at(-1)).toEqual({ element: 6, company: 0x0211, model: 0 });
27
+ expect(() => composition(raw.subarray(0, -1), 6)).toThrow('Truncated');
28
+ });
29
+ it('encodes vendor group requests and verifies status plus subscription readback', async () => {
30
+ const model = { element: 6, company: 0x0211, model: 0 };
31
+ const configuration = vi.fn(async (_address, data, accept) => {
32
+ const response = data[1] === 0x1b ? Buffer.from('801f00060000c111020000', 'hex') : Buffer.from('802c0006001102000000c1', 'hex');
33
+ expect(accept(response)).toBe(true);
34
+ return response;
35
+ });
36
+ await changeSubscription({ configuration }, 6, model, 0xc100, false);
37
+ expect(configuration.mock.calls[0][1].toString('hex')).toBe('801b060000c111020000');
38
+ expect(configuration.mock.calls[1][1].toString('hex')).toBe('802b060011020000');
39
+ await expect(subscriptions({ configuration }, 6, model)).resolves.toEqual([0xc100]);
40
+ await expect(changeSubscription({ configuration }, 6, model, 0xffff, false)).rejects.toThrow('Group address');
41
+ });
42
+ it('never exposes Device Keys through the HTTP metadata', async () => {
43
+ const config = {
44
+ netKey: net,
45
+ appKey: app,
46
+ source: 32766,
47
+ lights: [{ key: 'test', name: 'Test', mac: '', address: 6, model: '200x-s', deviceKey: device }],
48
+ };
49
+ const link = {
50
+ ready: true,
51
+ connect: async () => undefined,
52
+ disconnect: async () => undefined,
53
+ send: async () => undefined,
54
+ readState: async () => ({
55
+ mode: 'cct',
56
+ sleep: false,
57
+ intensity: 10,
58
+ cct: 3200,
59
+ observedAt: new Date().toISOString(),
60
+ }),
61
+ };
62
+ const server = createBleServer(new VerifiedController(config, link));
63
+ await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
64
+ const address = server.address();
65
+ if (!address || typeof address === 'string')
66
+ throw new Error('No test address');
67
+ try {
68
+ const response = await (await fetch(`http://127.0.0.1:${address.port}/health`)).text();
69
+ expect(response).not.toContain(device);
70
+ expect(response).not.toContain('deviceKey');
71
+ expect(JSON.parse(response).lights[0].key).toBe('test');
72
+ }
73
+ finally {
74
+ await new Promise((resolve) => server.close(() => resolve()));
75
+ }
76
+ });
77
+ });
78
+ //# sourceMappingURL=meshConfiguration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meshConfiguration.test.js","sourceRoot":"","sources":["../../src/__tests__/meshConfiguration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=nativeGroups.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeGroups.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/nativeGroups.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,104 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { LocalLibrary } from '../ble/library.js';
3
+ import { NativeGroups } from '../ble/nativeGroups.js';
4
+ import { provisioningAdvertisement } from '../ble/provisioning.js';
5
+ const config = {
6
+ netKey: '0'.repeat(32),
7
+ appKey: '1'.repeat(32),
8
+ source: 32766,
9
+ lights: [
10
+ { key: 'desk', name: 'Desk', mac: '', address: 6, model: '200x-s' },
11
+ { key: 'back', name: 'Back', mac: '', address: 10, model: '150c' },
12
+ ],
13
+ };
14
+ function link() {
15
+ const groups = new Map([
16
+ [6, new Set([0xc000])],
17
+ [10, new Set([0xc000])],
18
+ ]);
19
+ let fail = false;
20
+ const configuration = vi.fn(async (address, request, accept) => {
21
+ const opcode = request.readUInt16BE();
22
+ let data;
23
+ if (opcode === 0x8008)
24
+ data = Buffer.from('020011020000000001000300000001000010', 'hex');
25
+ else if (opcode === 0x8015)
26
+ data = Buffer.from('801700000000', 'hex');
27
+ else {
28
+ const set = groups.get(address);
29
+ if (!set)
30
+ throw new Error('unknown fixture');
31
+ if (opcode === 0x801b || opcode === 0x801c) {
32
+ if (fail && address === 10 && opcode === 0x801b)
33
+ throw new Error('lost connection');
34
+ const group = request.readUInt16LE(4);
35
+ if (opcode === 0x801b)
36
+ set.add(group);
37
+ else
38
+ set.delete(group);
39
+ data = Buffer.concat([Buffer.from([0x80, 0x1f, 0]), request.subarray(2)]);
40
+ }
41
+ else {
42
+ const addresses = Buffer.alloc(opcode === 0x804b ? 2 : set.size * 2);
43
+ if (opcode !== 0x804b)
44
+ [...set].forEach((value, index) => {
45
+ addresses.writeUInt16LE(value, index * 2);
46
+ });
47
+ data = Buffer.concat([Buffer.from([0x80, opcode === 0x804b ? 0x4c : 0x2a, 0]), request.subarray(2), addresses]);
48
+ }
49
+ }
50
+ expect(accept(data)).toBe(true);
51
+ return data;
52
+ });
53
+ return {
54
+ configuration,
55
+ groups,
56
+ fail: (value) => {
57
+ fail = value;
58
+ },
59
+ };
60
+ }
61
+ describe('native group lifecycle', () => {
62
+ it('adds, synchronizes and removes only its owned address', async () => {
63
+ const transport = link(), library = new LocalLibrary();
64
+ const group = library.createGroup('Work');
65
+ library.updateGroup(group.id, 'desk', false);
66
+ const native = new NativeGroups(config, transport, library);
67
+ const enabled = await native.enable(group.id);
68
+ expect(enabled.native?.status).toBe('ready');
69
+ expect(transport.groups.get(6)?.has(0xc100)).toBe(true);
70
+ expect(transport.groups.get(10)?.has(0xc100)).toBe(false);
71
+ await native.member(group.id, 'back', false);
72
+ expect(transport.groups.get(10)?.has(0xc100)).toBe(true);
73
+ await native.disable(group.id);
74
+ expect(transport.groups.get(6)).toEqual(new Set([0xc000]));
75
+ expect(transport.groups.get(10)).toEqual(new Set([0xc000]));
76
+ expect(library.group(group.id).native).toBeUndefined();
77
+ });
78
+ it('journals a partial operation and can resume or disable without deleting unrelated subscriptions', async () => {
79
+ const transport = link(), library = new LocalLibrary();
80
+ const group = library.createGroup('Work');
81
+ for (const key of ['desk', 'back'])
82
+ library.updateGroup(group.id, key, false);
83
+ const native = new NativeGroups(config, transport, library);
84
+ transport.fail(true);
85
+ await expect(native.enable(group.id)).rejects.toThrow('did not verify');
86
+ expect(library.group(group.id).native?.status).toBe('pending');
87
+ expect(() => library.deleteGroup(group.id)).toThrow('Disable native');
88
+ transport.fail(false);
89
+ await native.sync(group.id);
90
+ expect(library.group(group.id).native?.status).toBe('ready');
91
+ await native.disable(group.id);
92
+ expect(transport.groups.get(6)).toEqual(new Set([0xc000]));
93
+ });
94
+ it('refuses an address already used by another group and only parses provisioning advertisements', async () => {
95
+ const transport = link(), library = new LocalLibrary();
96
+ const group = library.createGroup('Work');
97
+ library.updateGroup(group.id, 'desk', false);
98
+ await expect(new NativeGroups(config, transport, library).enable(group.id, 0xc000)).rejects.toThrow('unused');
99
+ expect(library.group(group.id).native).toBeUndefined();
100
+ expect(provisioningAdvertisement(Buffer.alloc(9))).toBeUndefined();
101
+ expect(provisioningAdvertisement(Buffer.alloc(18))).toEqual({ uuid: '0'.repeat(32), oobInformation: '0000' });
102
+ });
103
+ });
104
+ //# sourceMappingURL=nativeGroups.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeGroups.test.js","sourceRoot":"","sources":["../../src/__tests__/nativeGroups.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAGnE,MAAM,MAAM,GAAe;IACzB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;IACtB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;IACtB,MAAM,EAAE,KAAK;IACb,MAAM,EAAE;QACN,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE;QACnE,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;KACnE;CACF,CAAC;AACF,SAAS,IAAI;IACX,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC;QACrB,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QACtB,CAAC,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;KACxB,CAAC,CAAC;IACH,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,MAAM,aAAa,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,OAAe,EAAE,OAAe,EAAE,MAAiC,EAAE,EAAE;QACxG,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QACtC,IAAI,IAAY,CAAC;QACjB,IAAI,MAAM,KAAK,MAAM;YAAE,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;aACpF,IAAI,MAAM,KAAK,MAAM;YAAE,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;aACjE,CAAC;YACJ,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAChC,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC7C,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC3C,IAAI,IAAI,IAAI,OAAO,KAAK,EAAE,IAAI,MAAM,KAAK,MAAM;oBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBACpF,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;gBACtC,IAAI,MAAM,KAAK,MAAM;oBAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;;oBACjC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACvB,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5E,CAAC;iBAAM,CAAC;gBACN,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;gBACrE,IAAI,MAAM,KAAK,MAAM;oBACnB,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;wBAChC,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;oBAC5C,CAAC,CAAC,CAAC;gBACL,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;YAClH,CAAC;QACH,CAAC;QACD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IACH,OAAO;QACL,aAAa;QACb,MAAM;QACN,IAAI,EAAE,CAAC,KAAc,EAAE,EAAE;YACvB,IAAI,GAAG,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,SAAS,GAAG,IAAI,EAAE,EACtB,OAAO,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC1C,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1D,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAC7C,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzD,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/B,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC;IACzD,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,iGAAiG,EAAE,KAAK,IAAI,EAAE;QAC/G,MAAM,SAAS,GAAG,IAAI,EAAE,EACtB,OAAO,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC1C,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;YAAE,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QAC9E,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC5D,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACxE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/D,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACtE,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5B,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7D,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/B,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,8FAA8F,EAAE,KAAK,IAAI,EAAE;QAC5G,MAAM,SAAS,GAAG,IAAI,EAAE,EACtB,OAAO,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC1C,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAC7C,MAAM,MAAM,CAAC,IAAI,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9G,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC;QACvD,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QACnE,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,CAAC;IAChH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=programApi.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"programApi.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/programApi.test.ts"],"names":[],"mappings":""}