@homeflare/alchemy 0.38.0 → 0.40.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 (353) hide show
  1. package/README.md +32 -8
  2. package/dist/ceph/auth-entity.d.ts +34 -0
  3. package/dist/ceph/auth-entity.d.ts.map +1 -0
  4. package/dist/ceph/ceph-argv-config.d.ts +10 -0
  5. package/dist/ceph/ceph-argv-config.d.ts.map +1 -0
  6. package/dist/ceph/ceph-argv.d.ts +19 -0
  7. package/dist/ceph/ceph-argv.d.ts.map +1 -0
  8. package/dist/ceph/ceph-auth-form.d.ts +54 -0
  9. package/dist/ceph/ceph-auth-form.d.ts.map +1 -0
  10. package/dist/ceph/ceph-auth-parse.d.ts +56 -0
  11. package/dist/ceph/ceph-auth-parse.d.ts.map +1 -0
  12. package/dist/ceph/ceph-auth-reconcile.d.ts +35 -0
  13. package/dist/ceph/ceph-auth-reconcile.d.ts.map +1 -0
  14. package/dist/ceph/ceph-config-options.d.ts +23 -0
  15. package/dist/ceph/ceph-config-options.d.ts.map +1 -0
  16. package/dist/ceph/ceph-key-leak-assert.d.ts +25 -0
  17. package/dist/ceph/ceph-key-leak-assert.d.ts.map +1 -0
  18. package/dist/ceph/ceph-transport.d.ts +37 -0
  19. package/dist/ceph/ceph-transport.d.ts.map +1 -0
  20. package/dist/ceph/fake-ceph-dial.d.ts +35 -0
  21. package/dist/ceph/fake-ceph-dial.d.ts.map +1 -0
  22. package/dist/ceph/index.d.ts +13 -0
  23. package/dist/ceph/index.d.ts.map +1 -0
  24. package/dist/ceph/index.js +1609 -0
  25. package/dist/ceph/index.js.map +38 -0
  26. package/dist/forgejo/index.js +4 -2
  27. package/dist/forgejo/index.js.map +3 -3
  28. package/dist/forgejo/team-member.d.ts +25 -0
  29. package/dist/forgejo/team-member.d.ts.map +1 -1
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/proxmox/generated/constraints/index.d.ts +1 -1
  33. package/dist/proxmox/generated/constraints/index.d.ts.map +1 -1
  34. package/dist/proxmox/generated/constraints/pve-access.d.ts +1 -1
  35. package/dist/proxmox/generated/constraints/pve-cluster-backup.d.ts +1 -1
  36. package/dist/proxmox/generated/constraints/pve-cluster-ceph.d.ts +1 -1
  37. package/dist/proxmox/generated/constraints/pve-cluster-firewall.d.ts +1 -1
  38. package/dist/proxmox/generated/constraints/pve-cluster-ha.d.ts +1 -1
  39. package/dist/proxmox/generated/constraints/pve-cluster-metrics.d.ts +1 -1
  40. package/dist/proxmox/generated/constraints/pve-cluster-notifications.d.ts +1 -1
  41. package/dist/proxmox/generated/constraints/pve-cluster-replication.d.ts +1 -1
  42. package/dist/proxmox/generated/constraints/pve-cluster-sdn.d.ts +1 -1
  43. package/dist/proxmox/generated/constraints/pve-nodes-ceph.d.ts +1 -1
  44. package/dist/proxmox/generated/constraints/pve-nodes-disks.d.ts +1 -1
  45. package/dist/proxmox/generated/constraints/pve-nodes-lxc.d.ts +1 -1
  46. package/dist/proxmox/generated/constraints/pve-nodes-network.d.ts +1 -1
  47. package/dist/proxmox/generated/constraints/pve-nodes-qemu.d.ts +1 -1
  48. package/dist/proxmox/generated/constraints/pve-nodes-storage.d.ts +23 -0
  49. package/dist/proxmox/generated/constraints/pve-nodes-storage.d.ts.map +1 -0
  50. package/dist/proxmox/generated/constraints/pve-pools.d.ts +1 -1
  51. package/dist/proxmox/generated/constraints/pve-storage.d.ts +1 -1
  52. package/dist/proxmox/index.d.ts +14 -3
  53. package/dist/proxmox/index.d.ts.map +1 -1
  54. package/dist/proxmox/index.js +574 -133
  55. package/dist/proxmox/index.js.map +33 -23
  56. package/dist/proxmox/qemu-form.d.ts +27 -18
  57. package/dist/proxmox/qemu-form.d.ts.map +1 -1
  58. package/dist/proxmox/qemu-judge.d.ts +30 -0
  59. package/dist/proxmox/qemu-judge.d.ts.map +1 -0
  60. package/dist/proxmox/qemu-lifecycle.d.ts +16 -2
  61. package/dist/proxmox/qemu-lifecycle.d.ts.map +1 -1
  62. package/dist/proxmox/qemu-net.d.ts +9 -0
  63. package/dist/proxmox/qemu-net.d.ts.map +1 -0
  64. package/dist/proxmox/qemu-props.d.ts +112 -0
  65. package/dist/proxmox/qemu-props.d.ts.map +1 -0
  66. package/dist/proxmox/qemu-volume.d.ts +27 -0
  67. package/dist/proxmox/qemu-volume.d.ts.map +1 -0
  68. package/dist/proxmox/qemu.d.ts +14 -27
  69. package/dist/proxmox/qemu.d.ts.map +1 -1
  70. package/dist/proxmox/storage-download-errors.d.ts +5 -0
  71. package/dist/proxmox/storage-download-errors.d.ts.map +1 -0
  72. package/dist/proxmox/storage-download-identity.d.ts +27 -0
  73. package/dist/proxmox/storage-download-identity.d.ts.map +1 -0
  74. package/dist/proxmox/storage-download-lifecycle.d.ts +97 -0
  75. package/dist/proxmox/storage-download-lifecycle.d.ts.map +1 -0
  76. package/dist/proxmox/storage-download-props.d.ts +36 -0
  77. package/dist/proxmox/storage-download-props.d.ts.map +1 -0
  78. package/dist/proxmox/storage-download-task.d.ts +17 -0
  79. package/dist/proxmox/storage-download-task.d.ts.map +1 -0
  80. package/dist/proxmox/storage-download.d.ts +44 -0
  81. package/dist/proxmox/storage-download.d.ts.map +1 -0
  82. package/dist/talos/credentials-write.d.ts +46 -0
  83. package/dist/talos/credentials-write.d.ts.map +1 -0
  84. package/dist/talos/credentials.d.ts +51 -9
  85. package/dist/talos/credentials.d.ts.map +1 -1
  86. package/dist/talos/fake-process.d.ts +56 -0
  87. package/dist/talos/fake-process.d.ts.map +1 -0
  88. package/dist/talos/index.d.ts +19 -4
  89. package/dist/talos/index.d.ts.map +1 -1
  90. package/dist/talos/index.js +357 -173
  91. package/dist/talos/index.js.map +16 -10
  92. package/dist/talos/kubeconfig-attrs.d.ts +4 -0
  93. package/dist/talos/kubeconfig-attrs.d.ts.map +1 -0
  94. package/dist/talos/kubeconfig.d.ts +41 -23
  95. package/dist/talos/kubeconfig.d.ts.map +1 -1
  96. package/dist/talos/machine-config-fixtures.d.ts +60 -0
  97. package/dist/talos/machine-config-fixtures.d.ts.map +1 -0
  98. package/dist/talos/machine-config-poll.d.ts +43 -0
  99. package/dist/talos/machine-config-poll.d.ts.map +1 -0
  100. package/dist/talos/machine-config-read.d.ts +49 -0
  101. package/dist/talos/machine-config-read.d.ts.map +1 -0
  102. package/dist/talos/resource.d.ts +18 -0
  103. package/dist/talos/resource.d.ts.map +1 -1
  104. package/dist/talos/talos-bootstrap-etcd.d.ts +38 -0
  105. package/dist/talos/talos-bootstrap-etcd.d.ts.map +1 -0
  106. package/dist/talos/talos-bootstrap.d.ts +87 -0
  107. package/dist/talos/talos-bootstrap.d.ts.map +1 -1
  108. package/dist/talos/talos-cluster-health.d.ts +43 -1
  109. package/dist/talos/talos-cluster-health.d.ts.map +1 -1
  110. package/dist/talos/talos-errors.d.ts +68 -0
  111. package/dist/talos/talos-errors.d.ts.map +1 -0
  112. package/dist/talos/talos-machine-config.d.ts +51 -15
  113. package/dist/talos/talos-machine-config.d.ts.map +1 -1
  114. package/dist/talos/talosctl.d.ts +7 -0
  115. package/dist/talos/talosctl.d.ts.map +1 -1
  116. package/dist/talos/values.d.ts +23 -3
  117. package/dist/talos/values.d.ts.map +1 -1
  118. package/dist/telemetry/fake-collector.d.ts +36 -0
  119. package/dist/telemetry/fake-collector.d.ts.map +1 -0
  120. package/dist/telemetry/index.d.ts +11 -0
  121. package/dist/telemetry/index.d.ts.map +1 -0
  122. package/dist/telemetry/index.js +223 -0
  123. package/dist/telemetry/index.js.map +12 -0
  124. package/dist/telemetry/layer.d.ts +86 -0
  125. package/dist/telemetry/layer.d.ts.map +1 -0
  126. package/dist/telemetry/redact-serialization.d.ts +21 -0
  127. package/dist/telemetry/redact-serialization.d.ts.map +1 -0
  128. package/dist/telemetry/redact.d.ts +46 -0
  129. package/dist/telemetry/redact.d.ts.map +1 -0
  130. package/dist/unifi/acl-rule-drift.d.ts +22 -0
  131. package/dist/unifi/acl-rule-drift.d.ts.map +1 -0
  132. package/dist/unifi/acl-rule-form.d.ts +90 -0
  133. package/dist/unifi/acl-rule-form.d.ts.map +1 -0
  134. package/dist/unifi/acl-rule-ordering-form.d.ts +49 -0
  135. package/dist/unifi/acl-rule-ordering-form.d.ts.map +1 -0
  136. package/dist/unifi/acl-rule-ordering.d.ts +54 -0
  137. package/dist/unifi/acl-rule-ordering.d.ts.map +1 -0
  138. package/dist/unifi/acl-rule.d.ts +49 -0
  139. package/dist/unifi/acl-rule.d.ts.map +1 -0
  140. package/dist/unifi/dns-policy-drift.d.ts +21 -0
  141. package/dist/unifi/dns-policy-drift.d.ts.map +1 -0
  142. package/dist/unifi/dns-policy-form.d.ts +97 -0
  143. package/dist/unifi/dns-policy-form.d.ts.map +1 -0
  144. package/dist/unifi/dns-policy.d.ts +55 -0
  145. package/dist/unifi/dns-policy.d.ts.map +1 -0
  146. package/dist/unifi/drift.d.ts +27 -0
  147. package/dist/unifi/drift.d.ts.map +1 -0
  148. package/dist/unifi/fake-unifi.d.ts +5 -1
  149. package/dist/unifi/fake-unifi.d.ts.map +1 -1
  150. package/dist/unifi/firewall-policy-drift.d.ts +26 -0
  151. package/dist/unifi/firewall-policy-drift.d.ts.map +1 -0
  152. package/dist/unifi/firewall-policy-form.d.ts +102 -0
  153. package/dist/unifi/firewall-policy-form.d.ts.map +1 -0
  154. package/dist/unifi/firewall-policy-ordering-form.d.ts +66 -0
  155. package/dist/unifi/firewall-policy-ordering-form.d.ts.map +1 -0
  156. package/dist/unifi/firewall-policy-ordering.d.ts +57 -0
  157. package/dist/unifi/firewall-policy-ordering.d.ts.map +1 -0
  158. package/dist/unifi/firewall-policy.d.ts +57 -0
  159. package/dist/unifi/firewall-policy.d.ts.map +1 -0
  160. package/dist/unifi/firewall-zone-form.d.ts +6 -0
  161. package/dist/unifi/firewall-zone-form.d.ts.map +1 -1
  162. package/dist/unifi/firewall-zone.d.ts +1 -1
  163. package/dist/unifi/firewall-zone.d.ts.map +1 -1
  164. package/dist/unifi/index.d.ts +11 -3
  165. package/dist/unifi/index.d.ts.map +1 -1
  166. package/dist/unifi/index.js +725 -60
  167. package/dist/unifi/index.js.map +31 -9
  168. package/dist/unifi/network-drift.d.ts +26 -0
  169. package/dist/unifi/network-drift.d.ts.map +1 -0
  170. package/dist/unifi/network-form.d.ts +40 -7
  171. package/dist/unifi/network-form.d.ts.map +1 -1
  172. package/dist/unifi/network.d.ts +1 -0
  173. package/dist/unifi/network.d.ts.map +1 -1
  174. package/dist/unifi/paginate.d.ts +24 -0
  175. package/dist/unifi/paginate.d.ts.map +1 -0
  176. package/dist/unifi/providers.d.ts +1 -1
  177. package/dist/unifi/providers.d.ts.map +1 -1
  178. package/dist/unifi/resource.d.ts +36 -1
  179. package/dist/unifi/resource.d.ts.map +1 -1
  180. package/dist/unifi/scan-source.d.ts +11 -0
  181. package/dist/unifi/scan-source.d.ts.map +1 -0
  182. package/dist/unifi/traffic-matching-list-drift.d.ts +22 -0
  183. package/dist/unifi/traffic-matching-list-drift.d.ts.map +1 -0
  184. package/dist/unifi/traffic-matching-list-form.d.ts +56 -0
  185. package/dist/unifi/traffic-matching-list-form.d.ts.map +1 -0
  186. package/dist/unifi/traffic-matching-list.d.ts +51 -0
  187. package/dist/unifi/traffic-matching-list.d.ts.map +1 -0
  188. package/dist/unifi/wifi-broadcast-drift.d.ts +22 -0
  189. package/dist/unifi/wifi-broadcast-drift.d.ts.map +1 -0
  190. package/dist/unifi/wifi-broadcast-form.d.ts +127 -0
  191. package/dist/unifi/wifi-broadcast-form.d.ts.map +1 -0
  192. package/dist/unifi/wifi-broadcast.d.ts +73 -0
  193. package/dist/unifi/wifi-broadcast.d.ts.map +1 -0
  194. package/docs/telemetry-spike.md +94 -0
  195. package/docs/telemetry.md +109 -0
  196. package/docs/unifi-acl-rule.md +122 -0
  197. package/docs/unifi-dns-policy.md +75 -0
  198. package/docs/unifi-firewall-policy.md +109 -0
  199. package/docs/unifi-traffic-matching-list.md +82 -0
  200. package/docs/unifi-wifi.md +120 -0
  201. package/docs/unifi.md +64 -3
  202. package/package.json +10 -2
  203. package/src/ceph/auth-entity.ts +74 -0
  204. package/src/ceph/ceph-argv-config.ts +78 -0
  205. package/src/ceph/ceph-argv.test.ts +226 -0
  206. package/src/ceph/ceph-argv.ts +189 -0
  207. package/src/ceph/ceph-auth-form.test.ts +103 -0
  208. package/src/ceph/ceph-auth-form.ts +107 -0
  209. package/src/ceph/ceph-auth-parse.test.ts +155 -0
  210. package/src/ceph/ceph-auth-parse.ts +121 -0
  211. package/src/ceph/ceph-auth-reconcile-secrecy.test.ts +82 -0
  212. package/src/ceph/ceph-auth-reconcile.test.ts +233 -0
  213. package/src/ceph/ceph-auth-reconcile.ts +119 -0
  214. package/src/ceph/ceph-config-options.test.ts +44 -0
  215. package/src/ceph/ceph-config-options.ts +36 -0
  216. package/src/ceph/ceph-key-leak-assert.ts +35 -0
  217. package/src/ceph/ceph-no-output-logging.test.ts +52 -0
  218. package/src/ceph/ceph-transport.test.ts +125 -0
  219. package/src/ceph/ceph-transport.ts +117 -0
  220. package/src/ceph/fake-ceph-dial.ts +55 -0
  221. package/src/ceph/index.ts +12 -0
  222. package/src/forgejo/team-member.test.ts +14 -0
  223. package/src/forgejo/team-member.ts +28 -1
  224. package/src/index.ts +1 -0
  225. package/src/proxmox/constraints-required.test.ts +1 -0
  226. package/src/proxmox/generated/constraints/index.ts +3 -1
  227. package/src/proxmox/generated/constraints/pve-access.ts +1 -1
  228. package/src/proxmox/generated/constraints/pve-cluster-backup.ts +1 -1
  229. package/src/proxmox/generated/constraints/pve-cluster-ceph.ts +1 -1
  230. package/src/proxmox/generated/constraints/pve-cluster-firewall.ts +1 -1
  231. package/src/proxmox/generated/constraints/pve-cluster-ha.ts +1 -1
  232. package/src/proxmox/generated/constraints/pve-cluster-metrics.ts +1 -1
  233. package/src/proxmox/generated/constraints/pve-cluster-notifications.ts +1 -1
  234. package/src/proxmox/generated/constraints/pve-cluster-replication.ts +1 -1
  235. package/src/proxmox/generated/constraints/pve-cluster-sdn.ts +1 -1
  236. package/src/proxmox/generated/constraints/pve-nodes-ceph.ts +1 -1
  237. package/src/proxmox/generated/constraints/pve-nodes-disks.ts +1 -1
  238. package/src/proxmox/generated/constraints/pve-nodes-lxc.ts +1 -1
  239. package/src/proxmox/generated/constraints/pve-nodes-network.ts +1 -1
  240. package/src/proxmox/generated/constraints/pve-nodes-qemu.ts +1 -1
  241. package/src/proxmox/generated/constraints/pve-nodes-storage.ts +30 -0
  242. package/src/proxmox/generated/constraints/pve-pools.ts +1 -1
  243. package/src/proxmox/generated/constraints/pve-storage.ts +1 -1
  244. package/src/proxmox/index.test.ts +11 -6
  245. package/src/proxmox/index.ts +19 -3
  246. package/src/proxmox/qemu-form.ts +49 -13
  247. package/src/proxmox/qemu-identity.test.ts +30 -0
  248. package/src/proxmox/qemu-judge.test.ts +65 -0
  249. package/src/proxmox/qemu-judge.ts +84 -0
  250. package/src/proxmox/qemu-lifecycle.test.ts +78 -19
  251. package/src/proxmox/qemu-lifecycle.ts +131 -32
  252. package/src/proxmox/qemu-net.test.ts +48 -0
  253. package/src/proxmox/qemu-net.ts +78 -0
  254. package/src/proxmox/qemu-ownership.test.ts +44 -0
  255. package/src/proxmox/qemu-props.test.ts +87 -0
  256. package/src/proxmox/qemu-props.ts +157 -0
  257. package/src/proxmox/qemu-volume.test.ts +229 -0
  258. package/src/proxmox/qemu-volume.ts +178 -0
  259. package/src/proxmox/qemu.ts +15 -29
  260. package/src/proxmox/storage-download-errors.ts +7 -0
  261. package/src/proxmox/storage-download-identity.test.ts +54 -0
  262. package/src/proxmox/storage-download-identity.ts +50 -0
  263. package/src/proxmox/storage-download-lifecycle.ts +226 -0
  264. package/src/proxmox/storage-download-ownership.test.ts +50 -0
  265. package/src/proxmox/storage-download-props.ts +38 -0
  266. package/src/proxmox/storage-download-task.ts +72 -0
  267. package/src/proxmox/storage-download.test.ts +216 -0
  268. package/src/proxmox/storage-download.ts +58 -0
  269. package/src/talos/credentials-write.test.ts +81 -0
  270. package/src/talos/credentials-write.ts +95 -0
  271. package/src/talos/credentials.test.ts +157 -0
  272. package/src/talos/credentials.ts +160 -90
  273. package/src/talos/fake-process.ts +94 -0
  274. package/src/talos/index.ts +39 -4
  275. package/src/talos/kubeconfig-attrs.ts +55 -0
  276. package/src/talos/kubeconfig.test.ts +256 -0
  277. package/src/talos/kubeconfig.ts +170 -90
  278. package/src/talos/machine-config-fixtures.ts +86 -0
  279. package/src/talos/machine-config-poll.test.ts +57 -0
  280. package/src/talos/machine-config-poll.ts +82 -0
  281. package/src/talos/machine-config-read.ts +118 -0
  282. package/src/talos/resource.ts +19 -0
  283. package/src/talos/secrets-gate.test.ts +63 -0
  284. package/src/talos/talos-bootstrap-etcd.ts +71 -0
  285. package/src/talos/talos-bootstrap.test.ts +218 -0
  286. package/src/talos/talos-bootstrap.ts +151 -45
  287. package/src/talos/talos-cluster-health.test.ts +143 -0
  288. package/src/talos/talos-cluster-health.ts +91 -28
  289. package/src/talos/talos-errors.ts +85 -0
  290. package/src/talos/talos-machine-config.test.ts +189 -0
  291. package/src/talos/talos-machine-config.ts +102 -88
  292. package/src/talos/talosctl.ts +8 -0
  293. package/src/talos/values.test.ts +34 -6
  294. package/src/talos/values.ts +41 -7
  295. package/src/telemetry/fake-collector.ts +59 -0
  296. package/src/telemetry/http-client-sealing.test.ts +82 -0
  297. package/src/telemetry/index.ts +10 -0
  298. package/src/telemetry/layer.test.ts +204 -0
  299. package/src/telemetry/layer.ts +152 -0
  300. package/src/telemetry/redact-serialization.ts +178 -0
  301. package/src/telemetry/redact.test.ts +124 -0
  302. package/src/telemetry/redact.ts +147 -0
  303. package/src/unifi/acl-rule-drift.ts +57 -0
  304. package/src/unifi/acl-rule-form.ts +135 -0
  305. package/src/unifi/acl-rule-ordering-form.ts +79 -0
  306. package/src/unifi/acl-rule-ordering.test.ts +141 -0
  307. package/src/unifi/acl-rule-ordering.ts +70 -0
  308. package/src/unifi/acl-rule.test.ts +183 -0
  309. package/src/unifi/acl-rule.ts +61 -0
  310. package/src/unifi/discriminated-filter-decode.test.ts +134 -0
  311. package/src/unifi/dns-policy-drift.ts +48 -0
  312. package/src/unifi/dns-policy-form.ts +142 -0
  313. package/src/unifi/dns-policy.test.ts +154 -0
  314. package/src/unifi/dns-policy.ts +67 -0
  315. package/src/unifi/drift.test.ts +78 -0
  316. package/src/unifi/drift.ts +56 -0
  317. package/src/unifi/errors-and-secrets.test.ts +127 -0
  318. package/src/unifi/fake-unifi.ts +5 -1
  319. package/src/unifi/firewall-policy-drift.test.ts +151 -0
  320. package/src/unifi/firewall-policy-drift.ts +55 -0
  321. package/src/unifi/firewall-policy-filter-roundtrip.test.ts +143 -0
  322. package/src/unifi/firewall-policy-form.ts +146 -0
  323. package/src/unifi/firewall-policy-ordering-form.ts +111 -0
  324. package/src/unifi/firewall-policy-ordering.test.ts +185 -0
  325. package/src/unifi/firewall-policy-ordering.ts +87 -0
  326. package/src/unifi/firewall-policy.test.ts +183 -0
  327. package/src/unifi/firewall-policy.ts +73 -0
  328. package/src/unifi/firewall-zone-form.ts +31 -2
  329. package/src/unifi/firewall-zone.test.ts +21 -1
  330. package/src/unifi/firewall-zone.ts +1 -1
  331. package/src/unifi/get-only-guard.test.ts +165 -0
  332. package/src/unifi/index.ts +78 -1
  333. package/src/unifi/network-drift.test.ts +207 -0
  334. package/src/unifi/network-drift.ts +80 -0
  335. package/src/unifi/network-form.ts +11 -39
  336. package/src/unifi/network.test.ts +7 -82
  337. package/src/unifi/network.ts +6 -6
  338. package/src/unifi/paginate.test.ts +252 -0
  339. package/src/unifi/paginate.ts +141 -0
  340. package/src/unifi/providers.ts +19 -1
  341. package/src/unifi/resource.ts +73 -3
  342. package/src/unifi/scan-source.ts +64 -0
  343. package/src/unifi/traffic-matching-list-drift.ts +40 -0
  344. package/src/unifi/traffic-matching-list-form.ts +77 -0
  345. package/src/unifi/traffic-matching-list.test.ts +202 -0
  346. package/src/unifi/traffic-matching-list.ts +78 -0
  347. package/src/unifi/wifi-broadcast-details-call.test.ts +92 -0
  348. package/src/unifi/wifi-broadcast-drift.ts +69 -0
  349. package/src/unifi/wifi-broadcast-form.ts +211 -0
  350. package/src/unifi/wifi-broadcast-secrets.test.ts +145 -0
  351. package/src/unifi/wifi-broadcast.test.ts +155 -0
  352. package/src/unifi/wifi-broadcast.ts +90 -0
  353. package/src/unifi/write-op-reference.test.ts +190 -0
@@ -9,6 +9,73 @@ class UnifiWriteRefused extends Data.TaggedError("UnifiWriteRefused") {
9
9
  }
10
10
  }
11
11
  var refuseWrite = (type, identity, action) => Effect.fail(new UnifiWriteRefused({ type, identity, action }));
12
+ // src/unifi/resource.ts
13
+ import { Unowned } from "alchemy/AdoptPolicy";
14
+ import { isResolved } from "alchemy/Diff";
15
+ import { CredentialsFromEnv } from "@distilled.cloud/unifi-network/Credentials";
16
+ import * as Effect2 from "effect/Effect";
17
+ import * as HttpClient from "effect/unstable/http/HttpClient";
18
+ var unifiOperations = (spec) => {
19
+ const read = (props) => spec.fetchLive(props).pipe(Effect2.map((live) => live === undefined ? undefined : spec.attributes(live, props)));
20
+ return {
21
+ read,
22
+ readHandler: ({ olds, output }) => Effect2.gen(function* () {
23
+ const attrs = yield* read(olds);
24
+ if (attrs === undefined)
25
+ return;
26
+ return output !== undefined ? attrs : Unowned(attrs);
27
+ }),
28
+ diff: (news, output) => Effect2.gen(function* () {
29
+ if (output === undefined || !isResolved(news))
30
+ return;
31
+ const live = yield* read(news);
32
+ if (live === undefined)
33
+ return { action: "update" };
34
+ return spec.matches(live, news) ? { action: "noop" } : { action: "update" };
35
+ }),
36
+ reconcile: (news) => Effect2.gen(function* () {
37
+ const live = yield* read(news);
38
+ if (live === undefined)
39
+ return yield* refuseWrite(spec.type, spec.describe(news), "create");
40
+ if (!spec.matches(live, news)) {
41
+ return yield* refuseWrite(spec.type, spec.describe(news), "update");
42
+ }
43
+ return live;
44
+ }),
45
+ destroy: (olds) => refuseWrite(spec.type, spec.describe(olds), "delete")
46
+ };
47
+ };
48
+
49
+ class UnifiNonGetRequest extends Error {
50
+ method;
51
+ path;
52
+ constructor(method, path) {
53
+ super(`UniFi HttpClient guard: refused ${method} ${path} -- ${UNIFI_READ_ONLY_POLICY}. This is a ` + "defect, not a recoverable condition: something under src/unifi tried to send a non-GET " + "request, which policy.ts's per-operation refusal should already have made impossible. " + "Fix the kit code that produced this request.");
54
+ this.method = method;
55
+ this.path = path;
56
+ this.name = "UnifiNonGetRequest";
57
+ }
58
+ }
59
+ var requestPath = (url) => {
60
+ try {
61
+ return new URL(url).pathname;
62
+ } catch {
63
+ return "<unparseable request url>";
64
+ }
65
+ };
66
+ var guardGetOnly = (client) => client.pipe(HttpClient.mapRequestEffect((request) => request.method === "GET" ? Effect2.succeed(request) : Effect2.die(new UnifiNonGetRequest(request.method, requestPath(request.url)))));
67
+ var GetOnlyHttpClient = HttpClient.layerMergedContext(Effect2.map(HttpClient.HttpClient, guardGetOnly));
68
+ var unifiHandlers = (spec) => {
69
+ const ops = unifiOperations(spec);
70
+ const withCredentials = (effect) => effect.pipe(Effect2.provide(GetOnlyHttpClient), Effect2.provide(CredentialsFromEnv));
71
+ return {
72
+ list: () => Effect2.succeed([]),
73
+ read: (args) => withCredentials(ops.readHandler(args)),
74
+ diff: (args) => withCredentials(ops.diff(args.news, args.output)),
75
+ reconcile: (args) => withCredentials(ops.reconcile(args.news)),
76
+ delete: (args) => withCredentials(ops.destroy(args.olds))
77
+ };
78
+ };
12
79
  // src/unifi/network.ts
13
80
  import { Resource } from "alchemy";
14
81
  import { adopt } from "alchemy/AdoptPolicy";
@@ -17,7 +84,6 @@ import * as networks from "@distilled.cloud/unifi-network/networks";
17
84
  import * as Effect3 from "effect/Effect";
18
85
 
19
86
  // src/unifi/network-form.ts
20
- import { deepEqual } from "alchemy/Diff";
21
87
  var sortedSet = (values) => [...new Set(values)].sort();
22
88
  var normalizeDhcpGuarding = (value) => value == null ? value : { ...value, trustedDhcpServerIpAddresses: sortedSet(value.trustedDhcpServerIpAddresses) };
23
89
  var normalizeIpv6Configuration = (value) => value == null ? value : {
@@ -43,15 +109,6 @@ var attributesOf = (live, props) => ({
43
109
  zoneId: live.zoneId,
44
110
  deviceId: live.deviceId
45
111
  });
46
- var matches = (attributes, props) => attributes.name === props.name && attributes.enabled === props.enabled && attributes.management === props.management && attributes.vlanId === props.vlanId && deepEqual(normalizeDhcpGuarding(attributes.dhcpGuarding), normalizeDhcpGuarding(props.dhcpGuarding), {
47
- stripNullish: true
48
- }) && deepEqual(attributes.cellularBackupEnabled, props.cellularBackupEnabled, {
49
- stripNullish: true
50
- }) && deepEqual(attributes.internetAccessEnabled, props.internetAccessEnabled, {
51
- stripNullish: true
52
- }) && deepEqual(attributes.ipv4Configuration, props.ipv4Configuration, { stripNullish: true }) && deepEqual(normalizeIpv6Configuration(attributes.ipv6Configuration), normalizeIpv6Configuration(props.ipv6Configuration), { stripNullish: true }) && deepEqual(attributes.isolationEnabled, props.isolationEnabled, { stripNullish: true }) && deepEqual(attributes.mdnsForwardingEnabled, props.mdnsForwardingEnabled, {
53
- stripNullish: true
54
- }) && deepEqual(attributes.zoneId, props.zoneId, { stripNullish: true }) && deepEqual(attributes.deviceId, props.deviceId, { stripNullish: true });
55
112
  var declareNetwork = (live, siteId) => ({
56
113
  siteId,
57
114
  networkId: live.id,
@@ -70,52 +127,61 @@ var declareNetwork = (live, siteId) => ({
70
127
  deviceId: live.deviceId
71
128
  });
72
129
 
73
- // src/unifi/resource.ts
74
- import { Unowned } from "alchemy/AdoptPolicy";
75
- import { isResolved } from "alchemy/Diff";
76
- import { CredentialsFromEnv } from "@distilled.cloud/unifi-network/Credentials";
77
- import * as Effect2 from "effect/Effect";
78
- var unifiOperations = (spec) => {
79
- const read = (props) => spec.fetchLive(props).pipe(Effect2.map((live) => live === undefined ? undefined : spec.attributes(live, props)));
80
- return {
81
- read,
82
- readHandler: ({ olds, output }) => Effect2.gen(function* () {
83
- const attrs = yield* read(olds);
84
- if (attrs === undefined)
85
- return;
86
- return output !== undefined ? attrs : Unowned(attrs);
87
- }),
88
- diff: (news, output) => Effect2.gen(function* () {
89
- if (output === undefined || !isResolved(news))
90
- return;
91
- const live = yield* read(news);
92
- if (live === undefined)
93
- return { action: "update" };
94
- return spec.matches(live, news) ? { action: "noop" } : { action: "update" };
95
- }),
96
- reconcile: (news) => Effect2.gen(function* () {
97
- const live = yield* read(news);
98
- if (live === undefined)
99
- return yield* refuseWrite(spec.type, spec.describe(news), "create");
100
- if (!spec.matches(live, news)) {
101
- return yield* refuseWrite(spec.type, spec.describe(news), "update");
102
- }
103
- return live;
104
- }),
105
- destroy: (olds) => refuseWrite(spec.type, spec.describe(olds), "delete")
106
- };
107
- };
108
- var unifiHandlers = (spec) => {
109
- const ops = unifiOperations(spec);
110
- const withCredentials = (effect) => Effect2.provide(effect, CredentialsFromEnv);
111
- return {
112
- list: () => Effect2.succeed([]),
113
- read: (args) => withCredentials(ops.readHandler(args)),
114
- diff: (args) => withCredentials(ops.diff(args.news, args.output)),
115
- reconcile: (args) => withCredentials(ops.reconcile(args.news)),
116
- delete: (args) => withCredentials(ops.destroy(args.olds))
117
- };
118
- };
130
+ // src/unifi/drift.ts
131
+ import { deepEqual } from "alchemy/Diff";
132
+ var defaultEqual = (live, declared) => deepEqual(live, declared, { stripNullish: true });
133
+ var makeDriftOf = (fields) => (attributes, props) => fields.flatMap(({ field, live, declared, equal = defaultEqual }) => {
134
+ const liveValue = live(attributes);
135
+ const declaredValue = declared(props);
136
+ return equal(liveValue, declaredValue) ? [] : [{ field, live: liveValue, declared: declaredValue }];
137
+ });
138
+
139
+ // src/unifi/network-drift.ts
140
+ var fieldDrift = makeDriftOf([
141
+ { field: "name", live: (a) => a.name, declared: (p) => p.name },
142
+ { field: "enabled", live: (a) => a.enabled, declared: (p) => p.enabled },
143
+ { field: "management", live: (a) => a.management, declared: (p) => p.management },
144
+ { field: "vlanId", live: (a) => a.vlanId, declared: (p) => p.vlanId },
145
+ {
146
+ field: "dhcpGuarding",
147
+ live: (a) => normalizeDhcpGuarding(a.dhcpGuarding),
148
+ declared: (p) => normalizeDhcpGuarding(p.dhcpGuarding)
149
+ },
150
+ {
151
+ field: "cellularBackupEnabled",
152
+ live: (a) => a.cellularBackupEnabled,
153
+ declared: (p) => p.cellularBackupEnabled
154
+ },
155
+ {
156
+ field: "internetAccessEnabled",
157
+ live: (a) => a.internetAccessEnabled,
158
+ declared: (p) => p.internetAccessEnabled
159
+ },
160
+ {
161
+ field: "ipv4Configuration",
162
+ live: (a) => a.ipv4Configuration,
163
+ declared: (p) => p.ipv4Configuration
164
+ },
165
+ {
166
+ field: "ipv6Configuration",
167
+ live: (a) => normalizeIpv6Configuration(a.ipv6Configuration),
168
+ declared: (p) => normalizeIpv6Configuration(p.ipv6Configuration)
169
+ },
170
+ {
171
+ field: "isolationEnabled",
172
+ live: (a) => a.isolationEnabled,
173
+ declared: (p) => p.isolationEnabled
174
+ },
175
+ {
176
+ field: "mdnsForwardingEnabled",
177
+ live: (a) => a.mdnsForwardingEnabled,
178
+ declared: (p) => p.mdnsForwardingEnabled
179
+ },
180
+ { field: "zoneId", live: (a) => a.zoneId, declared: (p) => p.zoneId },
181
+ { field: "deviceId", live: (a) => a.deviceId, declared: (p) => p.deviceId }
182
+ ]);
183
+ var matches = (attributes, props) => fieldDrift(attributes, props).length === 0;
184
+ var driftOf = (live, props) => fieldDrift(attributesOf(live, props), props);
119
185
 
120
186
  // src/unifi/network.ts
121
187
  var UnifiNetwork = Resource("Unifi.Network", {
@@ -147,7 +213,17 @@ var attributesOf2 = (live, props) => ({
147
213
  networkIds: sortedSet2(live.networkIds),
148
214
  metadataOrigin: live.metadata.origin
149
215
  });
150
- var matches2 = (attributes, props) => attributes.name === props.name && attributes.networkIds.join(",") === sortedSet2(props.networkIds).join(",");
216
+ var fieldDrift2 = makeDriftOf([
217
+ { field: "name", live: (a) => a.name, declared: (p) => p.name },
218
+ {
219
+ field: "networkIds",
220
+ live: (a) => a.networkIds,
221
+ declared: (p) => sortedSet2(p.networkIds),
222
+ equal: (live, declared) => live.join(",") === declared.join(",")
223
+ }
224
+ ]);
225
+ var matches2 = (attributes, props) => fieldDrift2(attributes, props).length === 0;
226
+ var driftOf2 = (live, props) => fieldDrift2(attributesOf2(live, props), props);
151
227
  var declareFirewallZone = (live, siteId) => ({
152
228
  siteId,
153
229
  firewallZoneId: live.id,
@@ -169,22 +245,611 @@ var spec2 = {
169
245
  };
170
246
  var handlers2 = unifiHandlers(spec2);
171
247
  var UnifiFirewallZoneProvider = () => Provider2.effect(UnifiFirewallZone, Effect4.succeed(UnifiFirewallZone.Provider.of(handlers2)));
248
+ // src/unifi/dns-policy.ts
249
+ import { Resource as Resource3 } from "alchemy";
250
+ import { adopt as adopt3 } from "alchemy/AdoptPolicy";
251
+ import * as Provider3 from "alchemy/Provider";
252
+ import * as dnsPolicies from "@distilled.cloud/unifi-network/dns_policies";
253
+ import * as Effect5 from "effect/Effect";
254
+
255
+ // src/unifi/dns-policy-form.ts
256
+ var attributesOf3 = (live, props) => ({
257
+ siteId: props.siteId,
258
+ dnsPolicyId: live.id,
259
+ enabled: live.enabled,
260
+ type: live.type,
261
+ domain: live.domain,
262
+ ipv6Address: live.ipv6Address,
263
+ ttlSeconds: live.ttlSeconds,
264
+ ipv4Address: live.ipv4Address,
265
+ targetDomain: live.targetDomain,
266
+ ipAddress: live.ipAddress,
267
+ mailServerDomain: live.mailServerDomain,
268
+ priority: live.priority,
269
+ port: live.port,
270
+ protocol: live.protocol,
271
+ serverDomain: live.serverDomain,
272
+ service: live.service,
273
+ weight: live.weight,
274
+ text: live.text,
275
+ metadataOrigin: live.metadata.origin
276
+ });
277
+ var declareDnsPolicy = (live, siteId) => ({
278
+ siteId,
279
+ dnsPolicyId: live.id,
280
+ enabled: live.enabled,
281
+ type: live.type,
282
+ domain: live.domain,
283
+ ipv6Address: live.ipv6Address,
284
+ ttlSeconds: live.ttlSeconds,
285
+ ipv4Address: live.ipv4Address,
286
+ targetDomain: live.targetDomain,
287
+ ipAddress: live.ipAddress,
288
+ mailServerDomain: live.mailServerDomain,
289
+ priority: live.priority,
290
+ port: live.port,
291
+ protocol: live.protocol,
292
+ serverDomain: live.serverDomain,
293
+ service: live.service,
294
+ weight: live.weight,
295
+ text: live.text
296
+ });
297
+
298
+ // src/unifi/dns-policy-drift.ts
299
+ var fieldDrift3 = makeDriftOf([
300
+ { field: "enabled", live: (a) => a.enabled, declared: (p) => p.enabled },
301
+ { field: "type", live: (a) => a.type, declared: (p) => p.type },
302
+ { field: "domain", live: (a) => a.domain, declared: (p) => p.domain },
303
+ { field: "ipv6Address", live: (a) => a.ipv6Address, declared: (p) => p.ipv6Address },
304
+ { field: "ttlSeconds", live: (a) => a.ttlSeconds, declared: (p) => p.ttlSeconds },
305
+ { field: "ipv4Address", live: (a) => a.ipv4Address, declared: (p) => p.ipv4Address },
306
+ { field: "targetDomain", live: (a) => a.targetDomain, declared: (p) => p.targetDomain },
307
+ { field: "ipAddress", live: (a) => a.ipAddress, declared: (p) => p.ipAddress },
308
+ {
309
+ field: "mailServerDomain",
310
+ live: (a) => a.mailServerDomain,
311
+ declared: (p) => p.mailServerDomain
312
+ },
313
+ { field: "priority", live: (a) => a.priority, declared: (p) => p.priority },
314
+ { field: "port", live: (a) => a.port, declared: (p) => p.port },
315
+ { field: "protocol", live: (a) => a.protocol, declared: (p) => p.protocol },
316
+ { field: "serverDomain", live: (a) => a.serverDomain, declared: (p) => p.serverDomain },
317
+ { field: "service", live: (a) => a.service, declared: (p) => p.service },
318
+ { field: "weight", live: (a) => a.weight, declared: (p) => p.weight },
319
+ { field: "text", live: (a) => a.text, declared: (p) => p.text }
320
+ ]);
321
+ var matches3 = (attributes, props) => fieldDrift3(attributes, props).length === 0;
322
+ var driftOf3 = (live, props) => fieldDrift3(attributesOf3(live, props), props);
323
+
324
+ // src/unifi/dns-policy.ts
325
+ var UnifiDnsPolicy = Resource3("Unifi.DnsPolicy", {
326
+ defaultRemovalPolicy: "retain"
327
+ });
328
+ var dnsPolicy = (id, props) => UnifiDnsPolicy(id, props).pipe(adopt3(true));
329
+ var spec3 = {
330
+ type: "Unifi.DnsPolicy",
331
+ describe: (props) => `sites/${props.siteId}/dns/policies/${props.dnsPolicyId}`,
332
+ fetchLive: (props) => dnsPolicies.getDnsPolicy({ siteId: props.siteId, dnsPolicyId: props.dnsPolicyId }).pipe(Effect5.catchTag("NotFound", () => Effect5.succeed(undefined))),
333
+ attributes: attributesOf3,
334
+ matches: matches3
335
+ };
336
+ var handlers3 = unifiHandlers(spec3);
337
+ var UnifiDnsPolicyProvider = () => Provider3.effect(UnifiDnsPolicy, Effect5.succeed(UnifiDnsPolicy.Provider.of(handlers3)));
338
+ // src/unifi/acl-rule.ts
339
+ import { Resource as Resource4 } from "alchemy";
340
+ import { adopt as adopt4 } from "alchemy/AdoptPolicy";
341
+ import * as Provider4 from "alchemy/Provider";
342
+ import * as aclRules from "@distilled.cloud/unifi-network/access_control_acl_rules";
343
+ import * as Effect6 from "effect/Effect";
344
+
345
+ // src/unifi/acl-rule-form.ts
346
+ var sortedSet3 = (values) => [...new Set(values)].sort();
347
+ var normalizeDeviceFilter = (value) => value == null ? value : {
348
+ ...value,
349
+ ...value.deviceIds !== undefined ? { deviceIds: sortedSet3(value.deviceIds) } : {}
350
+ };
351
+ var normalizeProtocolFilter = (value) => value == null ? undefined : sortedSet3(value);
352
+ var attributesOf4 = (live, props) => ({
353
+ siteId: props.siteId,
354
+ aclRuleId: live.id,
355
+ action: live.action,
356
+ description: live.description,
357
+ destinationFilter: live.destinationFilter,
358
+ enabled: live.enabled,
359
+ enforcingDeviceFilter: normalizeDeviceFilter(live.enforcingDeviceFilter),
360
+ index: live.index,
361
+ name: live.name,
362
+ sourceFilter: live.sourceFilter,
363
+ type: live.type,
364
+ protocolFilter: normalizeProtocolFilter(live.protocolFilter),
365
+ networkIdFilter: live.networkIdFilter,
366
+ metadataOrigin: live.metadata.origin
367
+ });
368
+ var declareAclRule = (live, siteId) => ({
369
+ siteId,
370
+ aclRuleId: live.id,
371
+ action: live.action,
372
+ description: live.description,
373
+ destinationFilter: live.destinationFilter,
374
+ enabled: live.enabled,
375
+ enforcingDeviceFilter: normalizeDeviceFilter(live.enforcingDeviceFilter),
376
+ name: live.name,
377
+ sourceFilter: live.sourceFilter,
378
+ type: live.type,
379
+ protocolFilter: normalizeProtocolFilter(live.protocolFilter),
380
+ networkIdFilter: live.networkIdFilter
381
+ });
382
+
383
+ // src/unifi/acl-rule-drift.ts
384
+ var fieldDrift4 = makeDriftOf([
385
+ { field: "action", live: (a) => a.action, declared: (p) => p.action },
386
+ { field: "description", live: (a) => a.description, declared: (p) => p.description },
387
+ {
388
+ field: "destinationFilter",
389
+ live: (a) => a.destinationFilter,
390
+ declared: (p) => p.destinationFilter
391
+ },
392
+ { field: "enabled", live: (a) => a.enabled, declared: (p) => p.enabled },
393
+ {
394
+ field: "enforcingDeviceFilter",
395
+ live: (a) => normalizeDeviceFilter(a.enforcingDeviceFilter),
396
+ declared: (p) => normalizeDeviceFilter(p.enforcingDeviceFilter)
397
+ },
398
+ { field: "name", live: (a) => a.name, declared: (p) => p.name },
399
+ { field: "sourceFilter", live: (a) => a.sourceFilter, declared: (p) => p.sourceFilter },
400
+ { field: "type", live: (a) => a.type, declared: (p) => p.type },
401
+ {
402
+ field: "protocolFilter",
403
+ live: (a) => normalizeProtocolFilter(a.protocolFilter),
404
+ declared: (p) => normalizeProtocolFilter(p.protocolFilter)
405
+ },
406
+ { field: "networkIdFilter", live: (a) => a.networkIdFilter, declared: (p) => p.networkIdFilter }
407
+ ]);
408
+ var matches4 = (attributes, props) => fieldDrift4(attributes, props).length === 0;
409
+ var driftOf4 = (live, props) => fieldDrift4(attributesOf4(live, props), props);
410
+
411
+ // src/unifi/acl-rule.ts
412
+ var UnifiAclRule = Resource4("Unifi.AclRule", {
413
+ defaultRemovalPolicy: "retain"
414
+ });
415
+ var aclRule = (id, props) => UnifiAclRule(id, props).pipe(adopt4(true));
416
+ var spec4 = {
417
+ type: "Unifi.AclRule",
418
+ describe: (props) => `sites/${props.siteId}/acl-rules/${props.aclRuleId}`,
419
+ fetchLive: (props) => aclRules.getAclRule({ siteId: props.siteId, aclRuleId: props.aclRuleId }).pipe(Effect6.catchTag("NotFound", () => Effect6.succeed(undefined))),
420
+ attributes: attributesOf4,
421
+ matches: matches4
422
+ };
423
+ var handlers4 = unifiHandlers(spec4);
424
+ var UnifiAclRuleProvider = () => Provider4.effect(UnifiAclRule, Effect6.succeed(UnifiAclRule.Provider.of(handlers4)));
425
+ // src/unifi/acl-rule-ordering.ts
426
+ import { Resource as Resource5 } from "alchemy";
427
+ import { adopt as adopt5 } from "alchemy/AdoptPolicy";
428
+ import * as Provider5 from "alchemy/Provider";
429
+ import * as aclRules2 from "@distilled.cloud/unifi-network/access_control_acl_rules";
430
+ import * as Effect7 from "effect/Effect";
431
+
432
+ // src/unifi/acl-rule-ordering-form.ts
433
+ var attributesOf5 = (live, props) => ({
434
+ siteId: props.siteId,
435
+ orderedAclRuleIds: live.orderedAclRuleIds
436
+ });
437
+ var declareAclRuleOrdering = (live, siteId) => ({
438
+ siteId,
439
+ orderedAclRuleIds: live.orderedAclRuleIds
440
+ });
441
+ var fieldDrift5 = makeDriftOf([
442
+ {
443
+ field: "orderedAclRuleIds",
444
+ live: (a) => a.orderedAclRuleIds,
445
+ declared: (p) => p.orderedAclRuleIds
446
+ }
447
+ ]);
448
+ var matches5 = (attributes, props) => fieldDrift5(attributes, props).length === 0;
449
+ var driftOf5 = (live, props) => fieldDrift5(attributesOf5(live, props), props);
450
+
451
+ // src/unifi/acl-rule-ordering.ts
452
+ var UnifiAclRuleOrdering = Resource5("Unifi.AclRuleOrdering", {
453
+ defaultRemovalPolicy: "retain"
454
+ });
455
+ var aclRuleOrdering = (id, props) => UnifiAclRuleOrdering(id, props).pipe(adopt5(true));
456
+ var spec5 = {
457
+ type: "Unifi.AclRuleOrdering",
458
+ describe: (props) => `sites/${props.siteId}/acl-rules/ordering`,
459
+ fetchLive: (props) => aclRules2.getAclRuleOrdering({ siteId: props.siteId }).pipe(Effect7.catchTag("NotFound", () => Effect7.succeed(undefined))),
460
+ attributes: attributesOf5,
461
+ matches: matches5
462
+ };
463
+ var handlers5 = unifiHandlers(spec5);
464
+ var UnifiAclRuleOrderingProvider = () => Provider5.effect(UnifiAclRuleOrdering, Effect7.succeed(UnifiAclRuleOrdering.Provider.of(handlers5)));
465
+ // src/unifi/wifi-broadcast.ts
466
+ import { Resource as Resource6 } from "alchemy";
467
+ import { adopt as adopt6 } from "alchemy/AdoptPolicy";
468
+ import * as Provider6 from "alchemy/Provider";
469
+ import * as wifiBroadcasts from "@distilled.cloud/unifi-network/wifi_broadcasts";
470
+ import * as Effect9 from "effect/Effect";
471
+
472
+ // src/unifi/wifi-broadcast-form.ts
473
+ var sortedStrings = (values) => [...new Set(values)].sort();
474
+ var sortedFrequencies = (values) => [...new Set(values)].sort((a, b) => a - b);
475
+ var refKey = (ref) => `${ref.type}:${ref.networkId ?? ""}`;
476
+ var normalizeRef = (ref) => ref === undefined ? undefined : { type: ref.type, ...ref.networkId !== undefined ? { networkId: ref.networkId } : {} };
477
+ var sortedRefs = (values) => {
478
+ const byKey = new Map(values.map((ref) => [refKey(ref), normalizeRef(ref)]));
479
+ return [...byKey.values()].sort((a, b) => refKey(a).localeCompare(refKey(b)));
480
+ };
481
+ var normalizeHotspot = (value) => value === undefined ? undefined : { type: value.type };
482
+ var normalizeDeviceFilter2 = (value) => value == null ? value : {
483
+ type: value.type,
484
+ ...value.deviceIds !== undefined ? { deviceIds: sortedStrings(value.deviceIds) } : {},
485
+ ...value.deviceTagIds !== undefined ? { deviceTagIds: sortedStrings(value.deviceTagIds) } : {}
486
+ };
487
+ var normalizeFrequencies = (value) => value === undefined ? value : sortedFrequencies(value);
488
+ var normalizeSecurityConfiguration = (value) => ({
489
+ type: value.type,
490
+ ...value.presharedKeyNetworkIds !== undefined ? { presharedKeyNetworkIds: sortedRefs(value.presharedKeyNetworkIds) } : {}
491
+ });
492
+ var attributesOf6 = (live, props) => ({
493
+ siteId: props.siteId,
494
+ wifiBroadcastId: live.id,
495
+ name: live.name,
496
+ enabled: live.enabled,
497
+ type: live.type,
498
+ network: normalizeRef(live.network),
499
+ broadcastingDeviceFilter: normalizeDeviceFilter2(live.broadcastingDeviceFilter),
500
+ broadcastingFrequenciesGHz: normalizeFrequencies(live.broadcastingFrequenciesGHz),
501
+ hotspotConfiguration: normalizeHotspot(live.hotspotConfiguration),
502
+ securityConfiguration: normalizeSecurityConfiguration(live.securityConfiguration),
503
+ metadataOrigin: live.metadata.origin
504
+ });
505
+ var declareWifiBroadcast = (live, siteId) => ({
506
+ siteId,
507
+ wifiBroadcastId: live.id,
508
+ name: live.name,
509
+ enabled: live.enabled,
510
+ type: live.type,
511
+ network: normalizeRef(live.network),
512
+ broadcastingDeviceFilter: normalizeDeviceFilter2(live.broadcastingDeviceFilter),
513
+ broadcastingFrequenciesGHz: normalizeFrequencies(live.broadcastingFrequenciesGHz),
514
+ hotspotConfiguration: normalizeHotspot(live.hotspotConfiguration),
515
+ securityConfiguration: normalizeSecurityConfiguration(live.securityConfiguration)
516
+ });
517
+
518
+ // src/unifi/wifi-broadcast-drift.ts
519
+ var fieldDrift6 = makeDriftOf([
520
+ { field: "name", live: (a) => a.name, declared: (p) => p.name },
521
+ { field: "enabled", live: (a) => a.enabled, declared: (p) => p.enabled },
522
+ { field: "type", live: (a) => a.type, declared: (p) => p.type },
523
+ {
524
+ field: "network",
525
+ live: (a) => a.network,
526
+ declared: (p) => normalizeRef(p.network)
527
+ },
528
+ {
529
+ field: "broadcastingDeviceFilter",
530
+ live: (a) => a.broadcastingDeviceFilter,
531
+ declared: (p) => normalizeDeviceFilter2(p.broadcastingDeviceFilter)
532
+ },
533
+ {
534
+ field: "broadcastingFrequenciesGHz",
535
+ live: (a) => a.broadcastingFrequenciesGHz,
536
+ declared: (p) => normalizeFrequencies(p.broadcastingFrequenciesGHz)
537
+ },
538
+ {
539
+ field: "hotspotConfiguration",
540
+ live: (a) => a.hotspotConfiguration,
541
+ declared: (p) => normalizeHotspot(p.hotspotConfiguration)
542
+ },
543
+ {
544
+ field: "securityConfiguration",
545
+ live: (a) => a.securityConfiguration,
546
+ declared: (p) => normalizeSecurityConfiguration(p.securityConfiguration)
547
+ }
548
+ ]);
549
+ var matches6 = (attributes, props) => fieldDrift6(attributes, props).length === 0;
550
+ var driftOf6 = (live, props) => fieldDrift6(attributesOf6(live, props), props);
551
+
552
+ // src/unifi/paginate.ts
553
+ import * as Data2 from "effect/Data";
554
+ import * as Effect8 from "effect/Effect";
555
+ var MAX_PAGES = 1000;
556
+
557
+ class UnifiPaginationInconsistent extends Data2.TaggedError("UnifiPaginationInconsistent") {
558
+ get message() {
559
+ return `UniFi pager: ${this.reason} -- ${this.detail}. The paged response contradicted itself (or ` + "the walk ran implausibly long); the rows collected so far cannot be trusted and are not returned.";
560
+ }
561
+ }
562
+ var numOrPlaceholder = (value) => typeof value === "number" && Number.isFinite(value) ? String(value) : "<non-numeric>";
563
+ var pageAll = (fetchPage, request) => Effect8.gen(function* () {
564
+ const rows = [];
565
+ const startOffset = request.offset ?? 0;
566
+ let offset = startOffset;
567
+ let totalCount;
568
+ for (let pageCount = 1;; pageCount++) {
569
+ if (pageCount > MAX_PAGES) {
570
+ return yield* new UnifiPaginationInconsistent({
571
+ reason: "page-ceiling",
572
+ detail: `stopped after ${MAX_PAGES} pages at offset ${offset} without reaching totalCount`
573
+ });
574
+ }
575
+ const page = yield* fetchPage({ ...request, offset });
576
+ if (page.offset !== offset) {
577
+ return yield* new UnifiPaginationInconsistent({
578
+ reason: "offset-mismatch",
579
+ detail: `requested offset ${offset}, page echoed ${numOrPlaceholder(page.offset)} -- rows may be duplicated or skipped`
580
+ });
581
+ }
582
+ if (totalCount !== undefined && page.totalCount !== totalCount) {
583
+ return yield* new UnifiPaginationInconsistent({
584
+ reason: "total-count-changed",
585
+ detail: `totalCount changed from ${numOrPlaceholder(totalCount)} to ${numOrPlaceholder(page.totalCount)} between page calls`
586
+ });
587
+ }
588
+ totalCount = page.totalCount;
589
+ rows.push(...page.data);
590
+ if (page.data.length === 0)
591
+ break;
592
+ offset += page.data.length;
593
+ if (offset >= totalCount)
594
+ break;
595
+ }
596
+ const expected = totalCount - startOffset;
597
+ if (rows.length !== expected) {
598
+ return yield* new UnifiPaginationInconsistent({
599
+ reason: "row-count-mismatch",
600
+ detail: `collected ${rows.length} rows but totalCount(${numOrPlaceholder(totalCount)}) - startOffset(${startOffset}) = ${numOrPlaceholder(expected)}`
601
+ });
602
+ }
603
+ return rows;
604
+ });
605
+
606
+ // src/unifi/wifi-broadcast.ts
607
+ var UnifiWifiBroadcast = Resource6("Unifi.WifiBroadcast", {
608
+ defaultRemovalPolicy: "retain"
609
+ });
610
+ var wifiBroadcast = (id, props) => UnifiWifiBroadcast(id, props).pipe(adopt6(true));
611
+ var spec6 = {
612
+ type: "Unifi.WifiBroadcast",
613
+ describe: (props) => `sites/${props.siteId}/wifi/broadcasts/${props.wifiBroadcastId}`,
614
+ fetchLive: (props) => pageAll(wifiBroadcasts.getWifiBroadcastPage, { siteId: props.siteId }).pipe(Effect9.catchTag("NotFound", () => Effect9.succeed(undefined)), Effect9.map((rows) => rows?.find((row) => row.id === props.wifiBroadcastId))),
615
+ attributes: attributesOf6,
616
+ matches: matches6
617
+ };
618
+ var handlers6 = unifiHandlers(spec6);
619
+ var UnifiWifiBroadcastProvider = () => Provider6.effect(UnifiWifiBroadcast, Effect9.succeed(UnifiWifiBroadcast.Provider.of(handlers6)));
620
+ // src/unifi/firewall-policy.ts
621
+ import { Resource as Resource7 } from "alchemy";
622
+ import { adopt as adopt7 } from "alchemy/AdoptPolicy";
623
+ import * as Provider7 from "alchemy/Provider";
624
+ import * as firewall2 from "@distilled.cloud/unifi-network/firewall";
625
+ import * as Effect10 from "effect/Effect";
626
+
627
+ // src/unifi/firewall-policy-form.ts
628
+ var sortedSet4 = (values) => [...new Set(values)].sort();
629
+ var normalizeConnectionStateFilter = (value) => value == null ? undefined : sortedSet4(value);
630
+ var attributesOf7 = (live, props) => ({
631
+ siteId: props.siteId,
632
+ firewallPolicyId: live.id,
633
+ action: live.action,
634
+ connectionStateFilter: normalizeConnectionStateFilter(live.connectionStateFilter),
635
+ description: live.description,
636
+ destination: live.destination,
637
+ enabled: live.enabled,
638
+ index: live.index,
639
+ ipProtocolScope: live.ipProtocolScope,
640
+ ipsecFilter: live.ipsecFilter,
641
+ loggingEnabled: live.loggingEnabled,
642
+ name: live.name,
643
+ schedule: live.schedule,
644
+ source: live.source,
645
+ metadataOrigin: live.metadata.origin
646
+ });
647
+ var declareFirewallPolicy = (live, siteId) => ({
648
+ siteId,
649
+ firewallPolicyId: live.id,
650
+ action: live.action,
651
+ connectionStateFilter: normalizeConnectionStateFilter(live.connectionStateFilter),
652
+ description: live.description,
653
+ destination: live.destination,
654
+ enabled: live.enabled,
655
+ ipProtocolScope: live.ipProtocolScope,
656
+ ipsecFilter: live.ipsecFilter,
657
+ loggingEnabled: live.loggingEnabled,
658
+ name: live.name,
659
+ schedule: live.schedule,
660
+ source: live.source
661
+ });
662
+
663
+ // src/unifi/firewall-policy-drift.ts
664
+ var fieldDrift7 = makeDriftOf([
665
+ { field: "action", live: (a) => a.action, declared: (p) => p.action },
666
+ {
667
+ field: "connectionStateFilter",
668
+ live: (a) => normalizeConnectionStateFilter(a.connectionStateFilter),
669
+ declared: (p) => normalizeConnectionStateFilter(p.connectionStateFilter)
670
+ },
671
+ { field: "description", live: (a) => a.description, declared: (p) => p.description },
672
+ { field: "destination", live: (a) => a.destination, declared: (p) => p.destination },
673
+ { field: "enabled", live: (a) => a.enabled, declared: (p) => p.enabled },
674
+ { field: "ipProtocolScope", live: (a) => a.ipProtocolScope, declared: (p) => p.ipProtocolScope },
675
+ { field: "ipsecFilter", live: (a) => a.ipsecFilter, declared: (p) => p.ipsecFilter },
676
+ { field: "loggingEnabled", live: (a) => a.loggingEnabled, declared: (p) => p.loggingEnabled },
677
+ { field: "name", live: (a) => a.name, declared: (p) => p.name },
678
+ { field: "schedule", live: (a) => a.schedule, declared: (p) => p.schedule },
679
+ { field: "source", live: (a) => a.source, declared: (p) => p.source }
680
+ ]);
681
+ var matches7 = (attributes, props) => fieldDrift7(attributes, props).length === 0;
682
+ var driftOf7 = (live, props) => fieldDrift7(attributesOf7(live, props), props);
683
+
684
+ // src/unifi/firewall-policy.ts
685
+ var UnifiFirewallPolicy = Resource7("Unifi.FirewallPolicy", {
686
+ defaultRemovalPolicy: "retain"
687
+ });
688
+ var firewallPolicy = (id, props) => UnifiFirewallPolicy(id, props).pipe(adopt7(true));
689
+ var spec7 = {
690
+ type: "Unifi.FirewallPolicy",
691
+ describe: (props) => `sites/${props.siteId}/firewall/policies/${props.firewallPolicyId}`,
692
+ fetchLive: (props) => firewall2.getFirewallPolicy({ siteId: props.siteId, firewallPolicyId: props.firewallPolicyId }).pipe(Effect10.catchTag("NotFound", () => Effect10.succeed(undefined))),
693
+ attributes: attributesOf7,
694
+ matches: matches7
695
+ };
696
+ var handlers7 = unifiHandlers(spec7);
697
+ var UnifiFirewallPolicyProvider = () => Provider7.effect(UnifiFirewallPolicy, Effect10.succeed(UnifiFirewallPolicy.Provider.of(handlers7)));
698
+ // src/unifi/firewall-policy-ordering.ts
699
+ import { Resource as Resource8 } from "alchemy";
700
+ import { adopt as adopt8 } from "alchemy/AdoptPolicy";
701
+ import * as Provider8 from "alchemy/Provider";
702
+ import * as firewall3 from "@distilled.cloud/unifi-network/firewall";
703
+ import * as Effect11 from "effect/Effect";
704
+
705
+ // src/unifi/firewall-policy-ordering-form.ts
706
+ var attributesOf8 = (live, props) => ({
707
+ siteId: props.siteId,
708
+ sourceFirewallZoneId: props.sourceFirewallZoneId,
709
+ destinationFirewallZoneId: props.destinationFirewallZoneId,
710
+ beforeSystemDefined: live.orderedFirewallPolicyIds.beforeSystemDefined,
711
+ afterSystemDefined: live.orderedFirewallPolicyIds.afterSystemDefined
712
+ });
713
+ var declareFirewallPolicyOrdering = (live, siteId, sourceFirewallZoneId, destinationFirewallZoneId) => ({
714
+ siteId,
715
+ sourceFirewallZoneId,
716
+ destinationFirewallZoneId,
717
+ beforeSystemDefined: live.orderedFirewallPolicyIds.beforeSystemDefined,
718
+ afterSystemDefined: live.orderedFirewallPolicyIds.afterSystemDefined
719
+ });
720
+ var fieldDrift8 = makeDriftOf([
721
+ {
722
+ field: "beforeSystemDefined",
723
+ live: (a) => a.beforeSystemDefined,
724
+ declared: (p) => p.beforeSystemDefined
725
+ },
726
+ {
727
+ field: "afterSystemDefined",
728
+ live: (a) => a.afterSystemDefined,
729
+ declared: (p) => p.afterSystemDefined
730
+ }
731
+ ]);
732
+ var matches8 = (attributes, props) => fieldDrift8(attributes, props).length === 0;
733
+ var driftOf8 = (live, props) => fieldDrift8(attributesOf8(live, props), props);
734
+
735
+ // src/unifi/firewall-policy-ordering.ts
736
+ var UnifiFirewallPolicyOrdering = Resource8("Unifi.FirewallPolicyOrdering", { defaultRemovalPolicy: "retain" });
737
+ var firewallPolicyOrdering = (id, props) => UnifiFirewallPolicyOrdering(id, props).pipe(adopt8(true));
738
+ var spec8 = {
739
+ type: "Unifi.FirewallPolicyOrdering",
740
+ describe: (props) => `sites/${props.siteId}/firewall/policies/ordering` + `?sourceFirewallZoneId=${props.sourceFirewallZoneId}` + `&destinationFirewallZoneId=${props.destinationFirewallZoneId}`,
741
+ fetchLive: (props) => firewall3.getFirewallPolicyOrdering({
742
+ siteId: props.siteId,
743
+ sourceFirewallZoneId: props.sourceFirewallZoneId,
744
+ destinationFirewallZoneId: props.destinationFirewallZoneId
745
+ }).pipe(Effect11.catchTag("NotFound", () => Effect11.succeed(undefined))),
746
+ attributes: attributesOf8,
747
+ matches: matches8
748
+ };
749
+ var handlers8 = unifiHandlers(spec8);
750
+ var UnifiFirewallPolicyOrderingProvider = () => Provider8.effect(UnifiFirewallPolicyOrdering, Effect11.succeed(UnifiFirewallPolicyOrdering.Provider.of(handlers8)));
751
+ // src/unifi/traffic-matching-list.ts
752
+ import { Resource as Resource9 } from "alchemy";
753
+ import { adopt as adopt9 } from "alchemy/AdoptPolicy";
754
+ import * as Provider9 from "alchemy/Provider";
755
+ import * as trafficMatchingLists from "@distilled.cloud/unifi-network/traffic_matching_lists";
756
+ import * as Effect12 from "effect/Effect";
757
+
758
+ // src/unifi/traffic-matching-list-form.ts
759
+ var attributesOf9 = (live, props) => ({
760
+ siteId: props.siteId,
761
+ trafficMatchingListId: live.id,
762
+ name: live.name,
763
+ type: live.type,
764
+ items: live.items
765
+ });
766
+ var declareTrafficMatchingList = (live, siteId) => ({
767
+ siteId,
768
+ trafficMatchingListId: live.id,
769
+ name: live.name,
770
+ type: live.type,
771
+ items: live.items
772
+ });
773
+
774
+ // src/unifi/traffic-matching-list-drift.ts
775
+ var fieldDrift9 = makeDriftOf([
776
+ { field: "name", live: (a) => a.name, declared: (p) => p.name },
777
+ { field: "type", live: (a) => a.type, declared: (p) => p.type },
778
+ { field: "items", live: (a) => a.items, declared: (p) => p.items }
779
+ ]);
780
+ var matches9 = (attributes, props) => fieldDrift9(attributes, props).length === 0;
781
+ var driftOf9 = (live, props) => fieldDrift9(attributesOf9(live, props), props);
782
+
783
+ // src/unifi/traffic-matching-list.ts
784
+ var UnifiTrafficMatchingList = Resource9("Unifi.TrafficMatchingList", { defaultRemovalPolicy: "retain" });
785
+ var trafficMatchingList = (id, props) => UnifiTrafficMatchingList(id, props).pipe(adopt9(true));
786
+ var spec9 = {
787
+ type: "Unifi.TrafficMatchingList",
788
+ describe: (props) => `sites/${props.siteId}/traffic-matching-lists/${props.trafficMatchingListId}`,
789
+ fetchLive: (props) => trafficMatchingLists.getTrafficMatchingList({
790
+ siteId: props.siteId,
791
+ trafficMatchingListId: props.trafficMatchingListId
792
+ }).pipe(Effect12.catchTag("NotFound", () => Effect12.succeed(undefined))),
793
+ attributes: attributesOf9,
794
+ matches: matches9
795
+ };
796
+ var handlers9 = unifiHandlers(spec9);
797
+ var UnifiTrafficMatchingListProvider = () => Provider9.effect(UnifiTrafficMatchingList, Effect12.succeed(UnifiTrafficMatchingList.Provider.of(handlers9)));
172
798
  // src/unifi/providers.ts
173
799
  import * as Layer from "effect/Layer";
174
- var providers = () => Layer.mergeAll(UnifiNetworkProvider(), UnifiFirewallZoneProvider());
800
+ var providers = () => Layer.mergeAll(UnifiNetworkProvider(), UnifiFirewallZoneProvider(), UnifiDnsPolicyProvider(), UnifiAclRuleProvider(), UnifiAclRuleOrderingProvider(), UnifiWifiBroadcastProvider(), UnifiFirewallPolicyProvider(), UnifiFirewallPolicyOrderingProvider(), UnifiTrafficMatchingListProvider());
175
801
  export {
802
+ GetOnlyHttpClient,
176
803
  UNIFI_READ_ONLY_POLICY,
804
+ UnifiAclRule,
805
+ UnifiAclRuleOrdering,
806
+ UnifiAclRuleOrderingProvider,
807
+ UnifiAclRuleProvider,
808
+ UnifiDnsPolicy,
809
+ UnifiDnsPolicyProvider,
810
+ UnifiFirewallPolicy,
811
+ UnifiFirewallPolicyOrdering,
812
+ UnifiFirewallPolicyOrderingProvider,
813
+ UnifiFirewallPolicyProvider,
177
814
  UnifiFirewallZone,
178
815
  UnifiFirewallZoneProvider,
179
816
  UnifiNetwork,
180
817
  UnifiNetworkProvider,
818
+ UnifiNonGetRequest,
819
+ UnifiTrafficMatchingList,
820
+ UnifiTrafficMatchingListProvider,
821
+ UnifiWifiBroadcast,
822
+ UnifiWifiBroadcastProvider,
181
823
  UnifiWriteRefused,
824
+ aclRule,
825
+ driftOf4 as aclRuleDriftOf,
826
+ aclRuleOrdering,
827
+ driftOf5 as aclRuleOrderingDriftOf,
828
+ declareAclRule,
829
+ declareAclRuleOrdering,
830
+ declareDnsPolicy,
831
+ declareFirewallPolicy,
832
+ declareFirewallPolicyOrdering,
182
833
  declareFirewallZone,
183
834
  declareNetwork,
835
+ declareTrafficMatchingList,
836
+ declareWifiBroadcast,
837
+ dnsPolicy,
838
+ driftOf3 as dnsPolicyDriftOf,
839
+ firewallPolicy,
840
+ driftOf7 as firewallPolicyDriftOf,
841
+ firewallPolicyOrdering,
842
+ driftOf8 as firewallPolicyOrderingDriftOf,
184
843
  firewallZone,
844
+ driftOf2 as firewallZoneDriftOf,
185
845
  network,
186
- providers
846
+ driftOf as networkDriftOf,
847
+ providers,
848
+ trafficMatchingList,
849
+ driftOf9 as trafficMatchingListDriftOf,
850
+ wifiBroadcast,
851
+ driftOf6 as wifiBroadcastDriftOf
187
852
  };
188
853
 
189
- //# debugId=033CFC419E398B0664756E2164756E21
854
+ //# debugId=8F60CB2F43A8D0E164756E2164756E21
190
855
  //# sourceMappingURL=index.js.map