homematic-manager 3.0.0-beta.2 → 3.0.0-beta.21

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 (332) hide show
  1. package/README.md +2 -1
  2. package/data/easymode-time-selectors.json +285 -0
  3. package/data/icons/106_hm-lc-sw1-dr.webp +0 -0
  4. package/data/icons/108_hm-rc-dis-h-x-eu.webp +0 -0
  5. package/data/icons/109_hm-lc-sw1-pl-ct.webp +0 -0
  6. package/data/icons/110_hm-es-pmsw1-dr.webp +0 -0
  7. package/data/icons/112_hmip-wrc2.webp +0 -0
  8. package/data/icons/113_hmip-psm-ch.webp +0 -0
  9. package/data/icons/113_hmip-psm-it.webp +0 -0
  10. package/data/icons/113_hmip-psm-pe.webp +0 -0
  11. package/data/icons/113_hmip-psm-uk.webp +0 -0
  12. package/data/icons/113_hmip-psm.webp +0 -0
  13. package/data/icons/114_hm-lc-dim1t-fm-lf_3.webp +0 -0
  14. package/data/icons/116_hm-rc-4-3_brc-h3.webp +0 -0
  15. package/data/icons/118_hmip-swdo.webp +0 -0
  16. package/data/icons/119_hmip-rc8.webp +0 -0
  17. package/data/icons/120_hmip-etrv.webp +0 -0
  18. package/data/icons/121_hmip-wth.webp +0 -0
  19. package/data/icons/123_oligo.smart.ip.hm.webp +0 -0
  20. package/data/icons/125_hmip-smi.webp +0 -0
  21. package/data/icons/130_hmip-srh.webp +0 -0
  22. package/data/icons/131_hmip-wrc6.webp +0 -0
  23. package/data/icons/132_hmip-smo.webp +0 -0
  24. package/data/icons/133_hmip-asir.webp +0 -0
  25. package/data/icons/134_hmip-fsm.webp +0 -0
  26. package/data/icons/135_hmip-fsm16.webp +0 -0
  27. package/data/icons/136_hmip-miob.webp +0 -0
  28. package/data/icons/137_hmip-fal-c6.webp +0 -0
  29. package/data/icons/138_hmip-fal-c10.webp +0 -0
  30. package/data/icons/140_alpha-ip-rgb.webp +0 -0
  31. package/data/icons/141_alpha-ip-rgba.webp +0 -0
  32. package/data/icons/144_hmip-wgc.webp +0 -0
  33. package/data/icons/145_hmip-froll_hmip-fbl.webp +0 -0
  34. package/data/icons/146_hmip-sth.webp +0 -0
  35. package/data/icons/147_hmip-sthd.webp +0 -0
  36. package/data/icons/148_hmip-stho.webp +0 -0
  37. package/data/icons/149_hmip-sam.webp +0 -0
  38. package/data/icons/151_hmip-pcbs-bat.webp +0 -0
  39. package/data/icons/152_hmip-swdo-i.webp +0 -0
  40. package/data/icons/153_hmip-spi.webp +0 -0
  41. package/data/icons/154_hmip-spdr.webp +0 -0
  42. package/data/icons/155_hmip-whs2.webp +0 -0
  43. package/data/icons/156_hmip-mod-oc8.webp +0 -0
  44. package/data/icons/158_hmip-etrv-uk.webp +0 -0
  45. package/data/icons/159_hmip-mod-rc8.webp +0 -0
  46. package/data/icons/160_hmipw-drs4.webp +0 -0
  47. package/data/icons/161_hmipw-drs8.webp +0 -0
  48. package/data/icons/162_hmipw-drap.webp +0 -0
  49. package/data/icons/163_hmipw-drbl4.webp +0 -0
  50. package/data/icons/164_hmipw-dri16.webp +0 -0
  51. package/data/icons/165_hmipw-fio6.webp +0 -0
  52. package/data/icons/166_hmipw-drd3.webp +0 -0
  53. package/data/icons/167_hmipw-dri32.webp +0 -0
  54. package/data/icons/168_hmip-smi55.webp +0 -0
  55. package/data/icons/169_hmip-swo-pr.webp +0 -0
  56. package/data/icons/170_hmip-swo-pl.webp +0 -0
  57. package/data/icons/171_hmip-swo-b.webp +0 -0
  58. package/data/icons/172_hmip-swd.webp +0 -0
  59. package/data/icons/173_hmip-bsl.webp +0 -0
  60. package/data/icons/174_hmip-slo.webp +0 -0
  61. package/data/icons/175_hmip-group-heating.webp +0 -0
  62. package/data/icons/177_hmip-dbb.webp +0 -0
  63. package/data/icons/178_hmip-etrv-b1.webp +0 -0
  64. package/data/icons/179_hmip-swdm-b2.webp +0 -0
  65. package/data/icons/180_hmip-etrv-b.webp +0 -0
  66. package/data/icons/181_hmip-swdm.webp +0 -0
  67. package/data/icons/182_hmip-fci1.webp +0 -0
  68. package/data/icons/183_hmip-mod-tm.webp +0 -0
  69. package/data/icons/184_hmip-pcbs2.webp +0 -0
  70. package/data/icons/185_hmip-FCI6.webp +0 -0
  71. package/data/icons/186_hmip-mp3p.webp +0 -0
  72. package/data/icons/187_hmip-rcb1.webp +0 -0
  73. package/data/icons/188_hmip-etrv-c.webp +0 -0
  74. package/data/icons/190_hmip-sci.webp +0 -0
  75. package/data/icons/191_hmip-mod-ho.webp +0 -0
  76. package/data/icons/192_hmip-asir-o.webp +0 -0
  77. package/data/icons/193_hmip-wt.webp +0 -0
  78. package/data/icons/194_hmip-wrcd.webp +0 -0
  79. package/data/icons/195_hmipw-smi55.webp +0 -0
  80. package/data/icons/196_hmip-ASIR-2.webp +0 -0
  81. package/data/icons/197_hmip-swdo-pl.webp +0 -0
  82. package/data/icons/198_hmip-falmot-c12.webp +0 -0
  83. package/data/icons/199_hmip-mio16-pcb.webp +0 -0
  84. package/data/icons/200_hmip-wth-b.webp +0 -0
  85. package/data/icons/201_hmip-stv.webp +0 -0
  86. package/data/icons/202_hmip-wrcr.webp +0 -0
  87. package/data/icons/203_hmip-fsi16.webp +0 -0
  88. package/data/icons/204_hmip-drdi3.webp +0 -0
  89. package/data/icons/205_hmip-drsi4.webp +0 -0
  90. package/data/icons/206_hmip-drbli4.webp +0 -0
  91. package/data/icons/207_hmip-srdo.webp +0 -0
  92. package/data/icons/208_hmip-dsd-pcb.webp +0 -0
  93. package/data/icons/209_hmip-etrv-b-uk.webp +0 -0
  94. package/data/icons/210_hmip-ste2-pcb.webp +0 -0
  95. package/data/icons/211_hmip-drg-dali.webp +0 -0
  96. package/data/icons/211_hmip-drsi1.webp +0 -0
  97. package/data/icons/212_hmip-sfd.webp +0 -0
  98. package/data/icons/212_hmipw-scthd.webp +0 -0
  99. package/data/icons/213_hmip-smo230.webp +0 -0
  100. package/data/icons/213_hmip-wua.webp +0 -0
  101. package/data/icons/214_hmip-dld.webp +0 -0
  102. package/data/icons/215_hmip-psm-pe-2.webp +0 -0
  103. package/data/icons/215_hmip-scth230.webp +0 -0
  104. package/data/icons/216_hmip-etrv-e.webp +0 -0
  105. package/data/icons/216_hmip-psm-ch-2.webp +0 -0
  106. package/data/icons/217_hmip-usbsm.webp +0 -0
  107. package/data/icons/218_hmip-dls.webp +0 -0
  108. package/data/icons/219_hmip-fwi.webp +0 -0
  109. package/data/icons/220_hmip-wsc.webp +0 -0
  110. package/data/icons/221_hmip-sti.webp +0 -0
  111. package/data/icons/221_hmip-wkp.webp +0 -0
  112. package/data/icons/222_hmipw-wgd.webp +0 -0
  113. package/data/icons/223_hmip-mod-wd-vk.webp +0 -0
  114. package/data/icons/224_hmip-etrv-cl.webp +0 -0
  115. package/data/icons/225_hmip-rgbw.webp +0 -0
  116. package/data/icons/226_hmip-esi.webp +0 -0
  117. package/data/icons/227_hmip-lsc.webp +0 -0
  118. package/data/icons/228_elv-sh-sw1-bat.webp +0 -0
  119. package/data/icons/229_elv-sh-bm-s.webp +0 -0
  120. package/data/icons/230_hmip-etrv-f.webp +0 -0
  121. package/data/icons/231_elv-sh-cth.webp +0 -0
  122. package/data/icons/232_elv-sh-taco.webp +0 -0
  123. package/data/icons/233_hmip-flc.webp +0 -0
  124. package/data/icons/234_hmip-etrv-3.webp +0 -0
  125. package/data/icons/235_hmip-psmco.webp +0 -0
  126. package/data/icons/236_elv-sh-sb8.webp +0 -0
  127. package/data/icons/237_elv-sh-ctv.webp +0 -0
  128. package/data/icons/238_elv-sh-cap.webp +0 -0
  129. package/data/icons/239_hmip-wgs-f.webp +0 -0
  130. package/data/icons/240_hmip-wgtc-f.webp +0 -0
  131. package/data/icons/241_hmip-wgt-f.webp +0 -0
  132. package/data/icons/242_elv-sh-smsi.webp +0 -0
  133. package/data/icons/243_elv-sh-crc.webp +0 -0
  134. package/data/icons/244_elv-sh-krco.webp +0 -0
  135. package/data/icons/245_hmip-falmot-c8.webp +0 -0
  136. package/data/icons/246_elv-sh-wsm.webp +0 -0
  137. package/data/icons/247_hmip-hap-2.webp +0 -0
  138. package/data/icons/248_hmip-dlp.webp +0 -0
  139. package/data/icons/249_elv-sh-psmci.webp +0 -0
  140. package/data/icons/250_elv-sh-sps25.webp +0 -0
  141. package/data/icons/252_elv-sh-pti2.webp +0 -0
  142. package/data/icons/253_hmip-udi-smi55.webp +0 -0
  143. package/data/icons/254_hmip-udi-pb2.webp +0 -0
  144. package/data/icons/256_ELV-SH-SMS2.webp +0 -0
  145. package/data/icons/257_ELV-SH-FSI.webp +0 -0
  146. package/data/icons/258_hmip-m-td15.webp +0 -0
  147. package/data/icons/259_elv-sh-dusi.webp +0 -0
  148. package/data/icons/260_hmip-wss.webp +0 -0
  149. package/data/icons/54a_lc-ddc1-pcb.webp +0 -0
  150. package/data/icons/72_hm-rc-brc-h.webp +0 -0
  151. package/data/icons/73_hm-atent.webp +0 -0
  152. package/data/icons/79_hm-lc-dim1pwm-cv.webp +0 -0
  153. package/data/icons/84_hm-rc-4-3.webp +0 -0
  154. package/data/icons/85_hm-rc-sec4-3.webp +0 -0
  155. package/data/icons/86_hm-rc-key4-3.webp +0 -0
  156. package/data/icons/CCU3-1-50.webp +0 -0
  157. package/data/icons/CCU3.webp +0 -0
  158. package/data/icons/hm-coupling-dim.webp +0 -0
  159. package/data/icons/hm-coupling-group.webp +0 -0
  160. package/data/icons/hm-coupling-onoff.webp +0 -0
  161. package/data/icons/hm-coupling-rgb-dim.webp +0 -0
  162. package/data/icons/hm-coupling-rgb.webp +0 -0
  163. package/data/icons/hm-coupling-rgbw-dim.webp +0 -0
  164. package/data/icons/hm-coupling-rgbw.webp +0 -0
  165. package/data/icons/hm-coupling-white-dim.webp +0 -0
  166. package/data/icons/hm-coupling-white.webp +0 -0
  167. package/data/icons/hm-hue_gateway.webp +0 -0
  168. package/data/icons/hm-lightify_gateway.webp +0 -0
  169. package/data/icons/hm_resc-win-pcb-sc.webp +0 -0
  170. package/data/icons/unknown_device.webp +0 -0
  171. package/data/manifest.json +7 -1
  172. package/data/master-metadata.json +1997 -33
  173. package/data/profiles/ACCESS_RECEIVER.json +26 -13
  174. package/data/profiles/ACOUSTIC_SIGNAL_VIRTUAL_RECEIVER.json +3270 -76
  175. package/data/profiles/ACTOR_SECURITY.json +90 -10
  176. package/data/profiles/ACTOR_WINDOW.json +580 -43
  177. package/data/profiles/ALARMACTUATOR.json +564 -37
  178. package/data/profiles/ALARM_COND_SWITCH_RECEIVER.json +36 -4
  179. package/data/profiles/ALARM_SWITCH_VIRTUAL_RECEIVER.json +735 -33
  180. package/data/profiles/ARMING.json +115 -5
  181. package/data/profiles/BLIND.json +1038 -49
  182. package/data/profiles/BLIND_VIRTUAL_RECEIVER.json +4624 -124
  183. package/data/profiles/CLIMATECONTROL_FLOOR_PUMP_TRANSCEIVER.json +27 -1
  184. package/data/profiles/DIMMER.json +2233 -71
  185. package/data/profiles/DIMMER_VIRTUAL_RECEIVER.json +5773 -102
  186. package/data/profiles/DIMMER_woLongKeyPress.json +117 -4
  187. package/data/profiles/DOOR_RECEIVER.json +138 -10
  188. package/data/profiles/DUAL_WHITE_BRIGHTNESS.json +305 -11
  189. package/data/profiles/DUAL_WHITE_COLOR.json +730 -23
  190. package/data/profiles/HEATING_KEY_RECEIVER.json +127 -10
  191. package/data/profiles/HMW_BLIND.json +555 -20
  192. package/data/profiles/HMW_DIMMER.json +1337 -47
  193. package/data/profiles/HMW_INPUT_OUTPUT.json +375 -20
  194. package/data/profiles/HMW_SWITCH.json +375 -20
  195. package/data/profiles/JALOUSIE.json +1320 -52
  196. package/data/profiles/KEYMATIC.json +120 -12
  197. package/data/profiles/REMOTECONTROL_RECEIVER.json +10 -2
  198. package/data/profiles/RGBW_AUTOMATIC.json +46 -6
  199. package/data/profiles/RGBW_COLOR.json +14 -4
  200. package/data/profiles/SERVO_VIRTUAL_RECEIVER.json +117 -3
  201. package/data/profiles/SHUTTER_VIRTUAL_RECEIVER.json +4263 -128
  202. package/data/profiles/SIGNAL_CHIME.json +195 -14
  203. package/data/profiles/SIGNAL_CHIMEM.json +195 -14
  204. package/data/profiles/SIGNAL_LED.json +195 -14
  205. package/data/profiles/SIGNAL_LEDM.json +195 -14
  206. package/data/profiles/SIMPLE_SWITCH_RECEIVER.json +113 -9
  207. package/data/profiles/STATUS_INDICATOR.json +1073 -45
  208. package/data/profiles/SWITCH.json +1412 -60
  209. package/data/profiles/SWITCH_PANIC.json +315 -13
  210. package/data/profiles/SWITCH_SENSOR.json +243 -11
  211. package/data/profiles/SWITCH_VIRTUAL_RECEIVER.json +3963 -131
  212. package/data/profiles/UNIVERSAL_ACTOR.json +4319 -90
  213. package/data/profiles/UNIVERSAL_LIGHT_RECEIVER_LSC.json +6094 -196
  214. package/data/profiles/UNIVERSAL_LIGHT_RECEIVER_PWM.json +4920 -101
  215. package/data/profiles/UNIVERSAL_LIGHT_RECEIVER_RGB(W).json +2353 -80
  216. package/data/profiles/UNIVERSAL_LIGHT_RECEIVER_RGBW_DALI.json +6116 -176
  217. package/data/profiles/UNIVERSAL_LIGHT_RECEIVER_TW.json +3844 -104
  218. package/data/profiles/VIRTUAL_DIMMER.json +305 -11
  219. package/data/profiles/VIRTUAL_DUAL_WHITE_COLOR.json +730 -23
  220. package/data/profiles/WATER_SWITCH_VIRTUAL_RECEIVER.json +3903 -128
  221. package/data/profiles/WINDOW_DRIVE_RECEIVER.json +220 -8
  222. package/data/profiles/WINMATIC.json +505 -23
  223. package/dist/cli.js +24 -0
  224. package/dist/occulite.d.ts +86 -0
  225. package/dist/occulite.js +140 -0
  226. package/dist/options.d.ts +37 -6
  227. package/dist/options.js +49 -6
  228. package/dist/server.d.ts +47 -4
  229. package/dist/server.js +237 -27
  230. package/dist/sessions.d.ts +9 -1
  231. package/dist/sessions.js +8 -2
  232. package/dist/testSupport.js +9 -2
  233. package/node_modules/@homematic-manager/backend/dist/api/backend.d.ts +33 -0
  234. package/node_modules/@homematic-manager/backend/dist/api/backend.js +558 -46
  235. package/node_modules/@homematic-manager/backend/dist/cache/names.d.ts +9 -0
  236. package/node_modules/@homematic-manager/backend/dist/cache/names.js +21 -0
  237. package/node_modules/@homematic-manager/backend/dist/config/defaults.js +10 -1
  238. package/node_modules/@homematic-manager/backend/dist/config/store.d.ts +28 -1
  239. package/node_modules/@homematic-manager/backend/dist/config/store.js +59 -3
  240. package/node_modules/@homematic-manager/backend/dist/devices/installMode.js +9 -0
  241. package/node_modules/@homematic-manager/backend/dist/errors.d.ts +18 -0
  242. package/node_modules/@homematic-manager/backend/dist/errors.js +51 -2
  243. package/node_modules/@homematic-manager/backend/dist/images/deviceImages.d.ts +6 -0
  244. package/node_modules/@homematic-manager/backend/dist/images/deviceImages.js +38 -2
  245. package/node_modules/@homematic-manager/backend/dist/index.d.ts +3 -1
  246. package/node_modules/@homematic-manager/backend/dist/index.js +4 -1
  247. package/node_modules/@homematic-manager/backend/dist/interfaces/manager.d.ts +70 -8
  248. package/node_modules/@homematic-manager/backend/dist/interfaces/manager.js +333 -44
  249. package/node_modules/@homematic-manager/backend/dist/meta/client.d.ts +120 -0
  250. package/node_modules/@homematic-manager/backend/dist/meta/client.js +307 -0
  251. package/node_modules/@homematic-manager/backend/dist/meta/credentials.d.ts +38 -0
  252. package/node_modules/@homematic-manager/backend/dist/meta/credentials.js +53 -0
  253. package/node_modules/@homematic-manager/backend/dist/meta/index.d.ts +12 -0
  254. package/node_modules/@homematic-manager/backend/dist/meta/index.js +12 -0
  255. package/node_modules/@homematic-manager/backend/dist/meta/localProvider.d.ts +47 -0
  256. package/node_modules/@homematic-manager/backend/dist/meta/localProvider.js +119 -0
  257. package/node_modules/@homematic-manager/backend/dist/meta/occuliteProvider.d.ts +79 -0
  258. package/node_modules/@homematic-manager/backend/dist/meta/occuliteProvider.js +305 -0
  259. package/node_modules/@homematic-manager/backend/dist/meta/provider.d.ts +68 -0
  260. package/node_modules/@homematic-manager/backend/dist/meta/provider.js +19 -0
  261. package/node_modules/@homematic-manager/backend/dist/meta/regaProvider.d.ts +84 -0
  262. package/node_modules/@homematic-manager/backend/dist/meta/regaProvider.js +403 -0
  263. package/node_modules/@homematic-manager/backend/dist/meta/service.d.ts +137 -0
  264. package/node_modules/@homematic-manager/backend/dist/meta/service.js +412 -0
  265. package/node_modules/@homematic-manager/backend/dist/rega/client.d.ts +11 -0
  266. package/node_modules/@homematic-manager/backend/dist/rega/client.js +13 -0
  267. package/node_modules/@homematic-manager/backend/dist/rega/scripts.d.ts +51 -0
  268. package/node_modules/@homematic-manager/backend/dist/rega/scripts.js +171 -0
  269. package/node_modules/@homematic-manager/backend/dist/rpc/client.d.ts +18 -5
  270. package/node_modules/@homematic-manager/backend/dist/rpc/client.js +11 -5
  271. package/node_modules/@homematic-manager/backend/dist/rpc/log.d.ts +86 -0
  272. package/node_modules/@homematic-manager/backend/dist/rpc/log.js +241 -0
  273. package/node_modules/@homematic-manager/backend/dist/rpc/origin.d.ts +30 -0
  274. package/node_modules/@homematic-manager/backend/dist/rpc/origin.js +35 -0
  275. package/node_modules/@homematic-manager/backend/dist/rpc/server.d.ts +12 -0
  276. package/node_modules/@homematic-manager/backend/dist/rpc/server.js +37 -5
  277. package/node_modules/@homematic-manager/backend/dist/util/net.d.ts +86 -1
  278. package/node_modules/@homematic-manager/backend/dist/util/net.js +223 -9
  279. package/node_modules/@homematic-manager/backend/package.json +1 -1
  280. package/node_modules/@homematic-manager/core/dist/api/types.d.ts +397 -10
  281. package/node_modules/@homematic-manager/core/dist/api/types.js +23 -2
  282. package/node_modules/@homematic-manager/core/dist/data/memory.d.ts +3 -1
  283. package/node_modules/@homematic-manager/core/dist/data/memory.js +3 -0
  284. package/node_modules/@homematic-manager/core/dist/data/types.d.ts +60 -0
  285. package/node_modules/@homematic-manager/core/dist/data/types.js +2 -0
  286. package/node_modules/@homematic-manager/core/dist/devices/index.d.ts +19 -0
  287. package/node_modules/@homematic-manager/core/dist/devices/index.js +53 -0
  288. package/node_modules/@homematic-manager/core/dist/easymodes/engine.d.ts +3 -1
  289. package/node_modules/@homematic-manager/core/dist/easymodes/engine.js +1 -0
  290. package/node_modules/@homematic-manager/core/dist/easymodes/form.d.ts +43 -0
  291. package/node_modules/@homematic-manager/core/dist/easymodes/form.js +84 -0
  292. package/node_modules/@homematic-manager/core/dist/i18n/messages.js +61 -0
  293. package/node_modules/@homematic-manager/core/dist/index.d.ts +3 -0
  294. package/node_modules/@homematic-manager/core/dist/index.js +4 -0
  295. package/node_modules/@homematic-manager/core/dist/interfaces/table.d.ts +23 -2
  296. package/node_modules/@homematic-manager/core/dist/interfaces/table.js +18 -1
  297. package/node_modules/@homematic-manager/core/dist/meta/document.d.ts +71 -0
  298. package/node_modules/@homematic-manager/core/dist/meta/document.js +260 -0
  299. package/node_modules/@homematic-manager/core/dist/meta/follow.d.ts +27 -0
  300. package/node_modules/@homematic-manager/core/dist/meta/follow.js +180 -0
  301. package/node_modules/@homematic-manager/core/dist/meta/index.d.ts +16 -0
  302. package/node_modules/@homematic-manager/core/dist/meta/index.js +16 -0
  303. package/node_modules/@homematic-manager/core/dist/meta/paths.d.ts +96 -0
  304. package/node_modules/@homematic-manager/core/dist/meta/paths.js +182 -0
  305. package/node_modules/@homematic-manager/core/dist/meta/slug.d.ts +22 -0
  306. package/node_modules/@homematic-manager/core/dist/meta/slug.js +59 -0
  307. package/node_modules/@homematic-manager/core/dist/meta/store.d.ts +147 -0
  308. package/node_modules/@homematic-manager/core/dist/meta/store.js +537 -0
  309. package/node_modules/@homematic-manager/core/dist/meta/tree.d.ts +19 -0
  310. package/node_modules/@homematic-manager/core/dist/meta/tree.js +53 -0
  311. package/node_modules/@homematic-manager/core/dist/meta/types.d.ts +143 -0
  312. package/node_modules/@homematic-manager/core/dist/meta/types.js +63 -0
  313. package/node_modules/@homematic-manager/core/dist/meta/view.d.ts +50 -0
  314. package/node_modules/@homematic-manager/core/dist/meta/view.js +103 -0
  315. package/node_modules/@homematic-manager/core/dist/rpc/methods.d.ts +10 -0
  316. package/node_modules/@homematic-manager/core/dist/rpc/methods.js +51 -1
  317. package/node_modules/@homematic-manager/core/dist/rpc/text.d.ts +22 -0
  318. package/node_modules/@homematic-manager/core/dist/rpc/text.js +46 -0
  319. package/node_modules/@homematic-manager/core/dist/rssi/index.d.ts +125 -13
  320. package/node_modules/@homematic-manager/core/dist/rssi/index.js +146 -29
  321. package/node_modules/@homematic-manager/core/dist/serviceMessages/index.d.ts +28 -2
  322. package/node_modules/@homematic-manager/core/dist/serviceMessages/index.js +44 -6
  323. package/node_modules/@homematic-manager/core/package.json +1 -1
  324. package/package.json +3 -3
  325. package/ui/assets/index-D-NsbBVS.css +1 -0
  326. package/ui/assets/index-DNUNMBbb.js +16 -0
  327. package/ui/favicon.ico +0 -0
  328. package/ui/index.html +3 -2
  329. package/node_modules/@homematic-manager/backend/dist/write/log.d.ts +0 -51
  330. package/node_modules/@homematic-manager/backend/dist/write/log.js +0 -151
  331. package/ui/assets/index-lB-HxsKR.js +0 -13
  332. package/ui/assets/index-qbhgN2pA.css +0 -1
@@ -0,0 +1,412 @@
1
+ /**
2
+ * D-40: which metadata provider is in charge, and everything the backend calls on it.
3
+ *
4
+ * The selection is openccu-lite's rule and no other: **`GET /api/meta/v1/version` on the configured
5
+ * host**, once per connect. A box answers with `{"api":"meta",…}` and its store is used; a CCU
6
+ * answers 404 or HTML and everything stays as it was. No `/VERSION` sniffing, no host names, no
7
+ * ports - a user who moves a profile between a CCU and a box must not have to edit anything
8
+ * (their invariant 2). `metaProvider: 'local'` skips the probe, `'occulite'` insists on the box.
9
+ * Task 27 adds the third answer: with no box, a ReGa that is on and answered
10
+ * (`options.rega.available`) becomes the store - its rooms and functions are the CCU's own - and
11
+ * `'rega'` insists on that.
12
+ *
13
+ * The service is also where the store's identity meets this application's. The store keys objects
14
+ * by **ref** (`<interface>.<address>`); the grids, the caches and the whole existing API key names
15
+ * by address, because a Homematic address is unique across the interfaces of one CCU in practice.
16
+ * So the ref is resolved here, in one place, from the device caches - and never guessed anywhere
17
+ * else.
18
+ */
19
+ import path from 'node:path';
20
+ import { makeRef, parseRef, slugId, summarise, } from '@homematic-manager/core';
21
+ import { validationError } from '../errors.js';
22
+ import { MetaApiClient, DETECT_TIMEOUT_MS } from './client.js';
23
+ import { normaliseSid, readLocalToken } from './credentials.js';
24
+ import { LocalMetaProvider } from './localProvider.js';
25
+ import { OcculiteProvider } from './occuliteProvider.js';
26
+ import { RegaMetaProvider } from './regaProvider.js';
27
+ /**
28
+ * The base URL of the box.
29
+ *
30
+ * `local` means "we are the addon on the box itself", where everything is behind the loopback
31
+ * lighttpd; otherwise it is the configured host with the scheme the profile uses for the CCU.
32
+ * `metaUrl` overrides both, for a reverse proxy on a strange port and for the integration tests.
33
+ */
34
+ export function metaBaseUrl(connection) {
35
+ const configured = (connection.metaUrl ?? '').trim();
36
+ if (configured !== '') {
37
+ return configured.replace(/\/$/, '');
38
+ }
39
+ if (connection.local === true) {
40
+ return 'http://127.0.0.1';
41
+ }
42
+ const host = connection.host.trim();
43
+ if (host === '') {
44
+ return '';
45
+ }
46
+ return `${connection.tls ? 'https' : 'http'}://${host}`;
47
+ }
48
+ /** Everything the metadata store is, for one connection. */
49
+ export class MetaService {
50
+ #options;
51
+ #provider;
52
+ /** `auto` chose ReGa: the first read decides whether it stays (found by the e2e suite). */
53
+ #autoRega = false;
54
+ #version;
55
+ /** The session of the person looking at the page; writes go out as this one. */
56
+ #sessionCredential;
57
+ #localToken;
58
+ constructor(options, provider, version) {
59
+ this.#options = options;
60
+ this.#provider = provider;
61
+ this.#version = version;
62
+ }
63
+ /**
64
+ * Probes the box and builds the provider that fits.
65
+ *
66
+ * Never throws: a probe that fails means "no box", which is what every CCU, every Homegear and
67
+ * every desktop answers, and the `local` provider is a complete answer to it.
68
+ */
69
+ static async create(options) {
70
+ const choice = options.connection.metaProvider ?? 'auto';
71
+ const localToken = await readLocalToken(options.localTokenFile);
72
+ const service = new MetaService(options, placeholderProvider(options));
73
+ service.#localToken = localToken;
74
+ if (choice === 'local') {
75
+ service.#provider = service.#buildLocal();
76
+ return service;
77
+ }
78
+ if (choice === 'rega') {
79
+ if (options.rega === undefined) {
80
+ options.onNotice('warn', 'the profile asks for ReGa as the store of rooms and functions, but ReGa is switched off: ' +
81
+ 'names and rooms stay in this profile');
82
+ service.#provider = service.#buildLocal();
83
+ return service;
84
+ }
85
+ service.#provider = service.#buildRega(options.rega);
86
+ return service;
87
+ }
88
+ const baseUrl = metaBaseUrl(options.connection);
89
+ const version = baseUrl === ''
90
+ ? undefined
91
+ : await service.#client(baseUrl).version(options.detectTimeoutMs ?? DETECT_TIMEOUT_MS);
92
+ if (version === undefined) {
93
+ if (choice === 'occulite') {
94
+ options.onNotice('warn', `no openccu-lite metadata API at ${baseUrl || 'the configured host'}: the profile asks for it, ` +
95
+ 'so names and rooms stay in this profile until the box answers');
96
+ }
97
+ if (options.rega?.available === true) {
98
+ options.onNotice('info', 'rooms and functions come from ReGa');
99
+ service.#provider = service.#buildRega(options.rega);
100
+ service.#autoRega = true;
101
+ return service;
102
+ }
103
+ service.#provider = service.#buildLocal();
104
+ return service;
105
+ }
106
+ service.#version = version;
107
+ options.onNotice('info', `openccu-lite detected at ${baseUrl} (${version.implementation ?? 'metadata API v1'}): ` +
108
+ 'names, rooms and functions come from the box');
109
+ service.#provider = service.#buildOcculite(baseUrl, version);
110
+ return service;
111
+ }
112
+ get kind() {
113
+ return this.#provider.kind;
114
+ }
115
+ /** True when this connection talks to an openccu-lite box. */
116
+ get onBox() {
117
+ return this.#provider.kind === 'occulite';
118
+ }
119
+ state() {
120
+ return this.#provider.state();
121
+ }
122
+ document() {
123
+ return this.#provider.document();
124
+ }
125
+ enums() {
126
+ return this.#provider.document().enums;
127
+ }
128
+ /** Every object as the UI shows it: the name, the paths, and the paths as names. */
129
+ objects() {
130
+ const document = this.#provider.document();
131
+ const views = {};
132
+ for (const [ref, object] of Object.entries(document.objects)) {
133
+ const summary = summarise(document.enums, object);
134
+ views[ref] = {
135
+ name: summary.name,
136
+ enums: [...object.enums],
137
+ rooms: [...summary.rooms],
138
+ functions: [...summary.functions],
139
+ ...(summary.orphaned ? { orphaned: true } : {}),
140
+ };
141
+ }
142
+ return views;
143
+ }
144
+ async start() {
145
+ await this.#provider.start();
146
+ if (this.#autoRega && !this.#provider.state().reachable) {
147
+ // ReGa answered `getChannels` but not the rooms-and-functions script - hm-simulator's
148
+ // mock, or a ReGa that runs no script at all. `auto` promised a store that works, so
149
+ // this is the profile's; a profile that says `rega` insists and stays unreachable.
150
+ this.#autoRega = false;
151
+ await this.#provider.stop();
152
+ this.#options.onNotice('warn', 'rooms and functions stay in this profile: ReGa did not answer the script that reads them');
153
+ this.#provider = this.#buildLocal();
154
+ await this.#provider.start();
155
+ this.#options.onStateChanged(this.#provider.state());
156
+ }
157
+ this.applyNames();
158
+ }
159
+ async stop() {
160
+ await this.#provider.stop();
161
+ }
162
+ /** Reads the store again - what `meta.refresh` is, and what a ReGa without a change stream needs. */
163
+ async refresh() {
164
+ await this.#provider.refresh();
165
+ }
166
+ /**
167
+ * The session the addon should write as (openccu-lite's embedding contract: `?sid=@…@`).
168
+ *
169
+ * Reads keep using the box's local token, which is read-only by design; a write is attributed
170
+ * to the person who opened the page. Without a session the writes go out with whatever the
171
+ * reads use, which on the box means the box answers 403 and the UI says so.
172
+ */
173
+ setSessionCredential(sid) {
174
+ const next = normaliseSid(sid);
175
+ if (next === this.#sessionCredential) {
176
+ return;
177
+ }
178
+ this.#sessionCredential = next;
179
+ // On the box this is the moment the addon learns who is looking at the page, and without a
180
+ // local token file it is the moment it gets a credential at all - so read everything again
181
+ // rather than wait for the event stream's next reconnect. Never awaited and never thrown:
182
+ // the caller is an HTTP request handler, and a box that refuses is a state, not an error.
183
+ void this.#provider.refresh();
184
+ }
185
+ /** Copies the store's names into the name cache. Returns true when anything changed. */
186
+ applyNames() {
187
+ const document = this.#provider.document();
188
+ const entries = [];
189
+ for (const [ref, object] of Object.entries(document.objects)) {
190
+ const parsed = parseRef(ref);
191
+ if (parsed) {
192
+ entries.push({ address: parsed.address, name: object.name });
193
+ }
194
+ }
195
+ return this.#options.names.applyMeta(entries);
196
+ }
197
+ /*
198
+ * writes
199
+ */
200
+ /** The rename: what `names.set` writes into the store after the local cache has it. */
201
+ async setNames(entries) {
202
+ const named = entries
203
+ .map((entry) => ({ ref: this.refFor(entry.address), name: entry.name }))
204
+ .filter((entry) => entry.ref !== undefined);
205
+ if (named.length === 0) {
206
+ return;
207
+ }
208
+ await this.#provider.setNames(named);
209
+ }
210
+ async setMembership(entries) {
211
+ await this.#provider.setMembership(entries);
212
+ }
213
+ /**
214
+ * The interaction of the whole feature: select rows, assign them to a room.
215
+ *
216
+ * One revision for the whole selection - the store is asked once with the complete membership
217
+ * of every object, not once per object, so a consumer of the change stream sees one change and
218
+ * the box writes its file once.
219
+ */
220
+ async assign(refs, nodePath, on) {
221
+ const document = this.#provider.document();
222
+ const entries = [];
223
+ for (const ref of this.#provider.kind === 'rega' ? channelsOfDevices(refs, document) : refs) {
224
+ const object = document.objects[ref];
225
+ const current = object?.enums ?? [];
226
+ const has = current.includes(nodePath);
227
+ if (has === on) {
228
+ continue;
229
+ }
230
+ const paths = on ? [...current, nodePath] : current.filter((path) => path !== nodePath);
231
+ if (object === undefined && !on) {
232
+ continue;
233
+ }
234
+ if (object === undefined) {
235
+ // the store never invents objects, but it does hold metadata about an address the
236
+ // interface reports; a channel that has no entry yet gets one with the name the
237
+ // application already shows
238
+ const parsed = parseRef(ref);
239
+ const name = (parsed ? this.#options.names.get(parsed.address) : undefined) ?? parsed?.address ?? ref;
240
+ await this.#provider.setNames([{ ref, name }]);
241
+ }
242
+ entries.push({ ref, paths });
243
+ }
244
+ await this.setMembership(entries);
245
+ }
246
+ async createEnum(id, name) {
247
+ await this.#provider.createEnum(id, name);
248
+ }
249
+ async updateEnum(id, name) {
250
+ await this.#provider.updateEnum(id, name);
251
+ }
252
+ async deleteEnum(id, detach) {
253
+ await this.#provider.deleteEnum(id, detach);
254
+ }
255
+ /**
256
+ * A node under a parent. The id is derived from the name and never changes afterwards, which is
257
+ * what keeps every membership pointing at the same node when the room is renamed.
258
+ */
259
+ async createNode(enumId, parent, name, options = {}) {
260
+ const document = this.#provider.document();
261
+ const definition = document.enums[enumId];
262
+ if (!definition) {
263
+ throw validationError(`${enumId} is not a taxonomy of this store`);
264
+ }
265
+ const siblings = siblingIds(definition, parent, enumId);
266
+ const id = slugId(name, siblings);
267
+ return this.#provider.createNode(enumId, parent ?? null, id, name, options);
268
+ }
269
+ async updateNode(nodePath, patch) {
270
+ await this.#provider.updateNode(nodePath, patch);
271
+ }
272
+ async deleteNode(nodePath, detach) {
273
+ await this.#provider.deleteNode(nodePath, detach);
274
+ }
275
+ async import(document, mode) {
276
+ await this.#provider.import(document, mode);
277
+ }
278
+ /**
279
+ * The ref of an address: the interface that reports it, or the one the store already uses.
280
+ *
281
+ * The second half matters after a restart with the box unreachable, and for a channel of a
282
+ * device that has just been deleted: the store still has the entry, and a rename of it should
283
+ * go to the same ref rather than to a new one.
284
+ */
285
+ refFor(address) {
286
+ const interfaceName = this.#options.interfaceOf(address);
287
+ if (interfaceName !== undefined && interfaceName !== '') {
288
+ return makeRef(interfaceName, address);
289
+ }
290
+ for (const ref of Object.keys(this.#provider.document().objects)) {
291
+ if (parseRef(ref)?.address === address) {
292
+ return ref;
293
+ }
294
+ }
295
+ return undefined;
296
+ }
297
+ #client(baseUrl) {
298
+ return new MetaApiClient({
299
+ baseUrl,
300
+ credential: () => this.#readCredential(),
301
+ writeCredential: () => this.#writeCredential(),
302
+ ...(this.#options.fetch === undefined ? {} : { fetch: this.#options.fetch }),
303
+ });
304
+ }
305
+ /**
306
+ * Reads: the configured API token, else the box's local token, else the session.
307
+ *
308
+ * The token in the profile wins because it is the one a user off the box configured on purpose;
309
+ * the local token is what an addon has without anybody configuring anything.
310
+ */
311
+ #readCredential() {
312
+ const configured = (this.#options.connection.metaToken ?? '').trim();
313
+ return configured !== '' ? configured : (this.#localToken ?? this.#sessionCredential);
314
+ }
315
+ /** Writes: the user's session first - the local token may not write, and should not. */
316
+ #writeCredential() {
317
+ const configured = (this.#options.connection.metaToken ?? '').trim();
318
+ return this.#sessionCredential ?? (configured !== '' ? configured : this.#localToken);
319
+ }
320
+ #buildLocal() {
321
+ return new LocalMetaProvider({
322
+ file: path.join(this.#options.dataDir, 'meta.json'),
323
+ onChanged: () => {
324
+ this.applyNames();
325
+ this.#options.onChanged();
326
+ },
327
+ onStateChanged: this.#options.onStateChanged,
328
+ onNotice: this.#options.onNotice,
329
+ });
330
+ }
331
+ #buildRega(rega) {
332
+ const language = this.#options.connection.language;
333
+ return new RegaMetaProvider({
334
+ exec: rega.exec,
335
+ interfaceOf: this.#options.interfaceOf,
336
+ // the stock rooms are shown the way the WebUI shows them; `auto` and Turkish (which
337
+ // the WebUI does not have) fall back to the CCU's own German
338
+ language: language === 'en' ? 'en' : 'de',
339
+ onChanged: () => {
340
+ this.applyNames();
341
+ this.#options.onChanged();
342
+ },
343
+ onStateChanged: this.#options.onStateChanged,
344
+ onNotice: this.#options.onNotice,
345
+ });
346
+ }
347
+ #buildOcculite(baseUrl, version) {
348
+ return new OcculiteProvider({
349
+ client: this.#client(baseUrl),
350
+ cacheFile: path.join(this.#options.cacheDir, 'occulite-meta.json'),
351
+ ...(version.implementation === undefined ? {} : { implementation: version.implementation }),
352
+ onChanged: () => {
353
+ this.applyNames();
354
+ this.#options.onChanged();
355
+ },
356
+ onStateChanged: this.#options.onStateChanged,
357
+ onNotice: this.#options.onNotice,
358
+ });
359
+ }
360
+ /** The version the box answered with, for the settings dialog and the log. */
361
+ get version() {
362
+ return this.#version;
363
+ }
364
+ }
365
+ /** The ids already taken among the siblings a new node would join. */
366
+ /**
367
+ * The refs an assignment on ReGa works on: a device is replaced by its channels, `:0` aside.
368
+ *
369
+ * ReGa files channels, so a device holds no path of its own, and the ReGa provider applies a
370
+ * device's membership list to each of its channels as their complete list. Handing it the device's
371
+ * empty list plus the one room took the channels out of every other room and function, and a
372
+ * removal through the device removed nothing (task 49). Channel by channel, each keeps its own list
373
+ * and only the one path changes. A device the document knows no channels of stays as it is.
374
+ */
375
+ function channelsOfDevices(refs, document) {
376
+ const result = new Set();
377
+ for (const ref of refs) {
378
+ const parsed = parseRef(ref);
379
+ const channels = parsed === undefined || parsed.address.includes(':')
380
+ ? []
381
+ : Object.keys(document.objects).filter((key) => key.startsWith(`${ref}:`) && !key.endsWith(':0'));
382
+ for (const entry of channels.length === 0 ? [ref] : channels) {
383
+ result.add(entry);
384
+ }
385
+ }
386
+ return [...result];
387
+ }
388
+ function siblingIds(definition, parent, enumId) {
389
+ if (parent === null || parent === undefined || parent === enumId) {
390
+ return definition.tree.map((node) => node.id);
391
+ }
392
+ const ids = parent.split('/').slice(1);
393
+ let nodes = definition.tree;
394
+ for (const id of ids) {
395
+ const found = nodes.find((node) => node.id === id);
396
+ if (!found) {
397
+ return [];
398
+ }
399
+ nodes = found.children ?? [];
400
+ }
401
+ return nodes.map((node) => node.id);
402
+ }
403
+ /** A provider that exists only between `new` and the decision which one it really is. */
404
+ function placeholderProvider(options) {
405
+ return new LocalMetaProvider({
406
+ file: path.join(options.dataDir, 'meta.json'),
407
+ onChanged: options.onChanged,
408
+ onStateChanged: options.onStateChanged,
409
+ onNotice: options.onNotice,
410
+ });
411
+ }
412
+ //# sourceMappingURL=service.js.map
@@ -65,6 +65,17 @@ export declare class RegaService {
65
65
  * state and in a notice, and the local names stay as they are.
66
66
  */
67
67
  refreshNames(): Promise<boolean>;
68
+ /**
69
+ * Runs one script and answers with what it wrote.
70
+ *
71
+ * Task 27: the ReGa metadata provider's transport. Unlike everything else here it *throws* -
72
+ * the provider turns the failure into its own state, and a write the user asked for has to be
73
+ * reported as refused rather than quietly lost. Rejects at once when ReGa is off (D-2).
74
+ */
75
+ exec(script: string): Promise<{
76
+ output: string;
77
+ objects: Record<string, string>;
78
+ }>;
68
79
  /**
69
80
  * Renames on the CCU. The local store has already been updated by the caller, so a failure here
70
81
  * only means that the CCU still shows the old name - reported, never thrown.
@@ -95,6 +95,19 @@ export class RegaService {
95
95
  return false;
96
96
  }
97
97
  }
98
+ /**
99
+ * Runs one script and answers with what it wrote.
100
+ *
101
+ * Task 27: the ReGa metadata provider's transport. Unlike everything else here it *throws* -
102
+ * the provider turns the failure into its own state, and a write the user asked for has to be
103
+ * reported as refused rather than quietly lost. Rejects at once when ReGa is off (D-2).
104
+ */
105
+ exec(script) {
106
+ if (!this.#client) {
107
+ return Promise.reject(new Error('ReGa is switched off'));
108
+ }
109
+ return this.#client.exec(script);
110
+ }
98
111
  /**
99
112
  * Renames on the CCU. The local store has already been updated by the caller, so a failure here
100
113
  * only means that the CCU still shows the old name - reported, never thrown.
@@ -78,6 +78,57 @@ export declare function acknowledgeAlarmScript(interfaceName: string, address: s
78
78
  * clever escape that turns out to be wrong loses control of the interpreter.
79
79
  */
80
80
  export declare function isPlainRegaName(value: string): boolean;
81
+ /** Everything the ReGa metadata provider reads, in one script and one JSON document. */
82
+ export declare const META_READ_SCRIPT = "string sDevId;\nstring sChnId;\nstring sEnumId;\nstring sMember;\nstring sIface;\nobject oIface;\nboolean bFirst = true;\nboolean bFirstMember = true;\nWrite('{\"objects\":[');\nforeach (sDevId, root.Devices().EnumUsedIDs()) {\n object oDevice = dom.GetObject(sDevId);\n if (oDevice.ReadyConfig()) {\n sIface = \"\";\n oIface = dom.GetObject(oDevice.Interface());\n if (oIface) { sIface = oIface.Name(); }\n if (bFirst) { bFirst = false; } else { Write(','); }\n Write('{\"id\":' # sDevId # ',\"address\":\"' # oDevice.Address() # '\",\"interface\":\"' # sIface # '\",\"name\":\"');\n WriteURL(oDevice.Name());\n Write('\"}');\n foreach (sChnId, oDevice.Channels()) {\n object oChannel = dom.GetObject(sChnId);\n Write(',{\"id\":' # sChnId # ',\"address\":\"' # oChannel.Address() # '\",\"interface\":\"' # sIface # '\",\"name\":\"');\n WriteURL(oChannel.Name());\n Write('\"}');\n }\n }\n}\nWrite('],\"rooms\":[');\nbFirst = true;\nforeach (sEnumId, dom.GetObject(ID_ROOMS).EnumUsedIDs()) {\n object oRoom = dom.GetObject(sEnumId);\n if (bFirst) { bFirst = false; } else { Write(','); }\n Write('{\"id\":' # sEnumId # ',\"name\":\"');\n WriteURL(oRoom.Name());\n Write('\",\"channels\":[');\n bFirstMember = true;\n foreach (sMember, oRoom.EnumUsedIDs()) {\n if (bFirstMember) { bFirstMember = false; } else { Write(','); }\n Write(sMember);\n }\n Write(']}');\n}\nWrite('],\"functions\":[');\nbFirst = true;\nforeach (sEnumId, dom.GetObject(ID_FUNCTIONS).EnumUsedIDs()) {\n object oFunction = dom.GetObject(sEnumId);\n if (bFirst) { bFirst = false; } else { Write(','); }\n Write('{\"id\":' # sEnumId # ',\"name\":\"');\n WriteURL(oFunction.Name());\n Write('\",\"channels\":[');\n bFirstMember = true;\n foreach (sMember, oFunction.EnumUsedIDs()) {\n if (bFirstMember) { bFirstMember = false; } else { Write(','); }\n Write(sMember);\n }\n Write(']}');\n}\nWrite(']}');\n";
83
+ /** One device or channel as ReGa lists it. */
84
+ export interface RegaMetaObject {
85
+ readonly id: number;
86
+ readonly address: string;
87
+ /** `BidCos-RF`, `HmIP-RF`, … - empty when ReGa does not name the interface. */
88
+ readonly interfaceName: string;
89
+ readonly name: string;
90
+ }
91
+ /** One room or one function: its ReGa id, its name and the channel ids in it. */
92
+ export interface RegaMetaEnum {
93
+ readonly id: number;
94
+ readonly name: string;
95
+ readonly channels: readonly number[];
96
+ }
97
+ export interface RegaMetaSnapshot {
98
+ readonly objects: readonly RegaMetaObject[];
99
+ readonly rooms: readonly RegaMetaEnum[];
100
+ readonly functions: readonly RegaMetaEnum[];
101
+ }
102
+ /**
103
+ * Decodes what ReGa's `WriteURL()` produces: `%XX` and `%uXXXX` escapes whose bytes are ISO-8859-1
104
+ * characters, not UTF-8 sequences - which is why `decodeURIComponent` would throw on `K%FCche`.
105
+ * The same rule `homematic-rega` applies to its own scripts' output.
106
+ */
107
+ export declare function unescapeRegaUrl(value: string): string;
108
+ /** Reads what {@link META_READ_SCRIPT} wrote. Throws on anything that is not the expected shape. */
109
+ export declare function parseMetaSnapshot(output: string): RegaMetaSnapshot;
110
+ /** Which of ReGa's two lists a node belongs to. */
111
+ export type RegaEnumKind = 'room' | 'function';
112
+ /**
113
+ * A new room or function: an enum object, named, and put into ReGa's list of them. The script
114
+ * writes the new id, which is the only thing the caller needs to address it from then on.
115
+ */
116
+ export declare function createEnumNodeScript(kind: RegaEnumKind, name: string): string;
117
+ /** Reads the id {@link createEnumNodeScript} wrote, or `undefined` when ReGa wrote something else. */
118
+ export declare function parseCreatedId(output: string): number | undefined;
119
+ /**
120
+ * Removes a room or function: out of ReGa's list first, then the object itself. The memberships go
121
+ * with it, which is what the caller has already confirmed with the user (`has-members`).
122
+ */
123
+ export declare function deleteEnumNodeScript(kind: RegaEnumKind, id: number): string;
124
+ /** One membership change: a channel into or out of one room or function. */
125
+ export interface RegaMembershipChange {
126
+ readonly enumId: number;
127
+ readonly channelId: number;
128
+ readonly on: boolean;
129
+ }
130
+ /** `Add` / `Remove` on the enum, one statement per change; `undefined` when there is none. */
131
+ export declare function membershipScript(changes: readonly RegaMembershipChange[]): string | undefined;
81
132
  /**
82
133
  * D-32: does this user exist, and what is their level?
83
134
  *