@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
@@ -0,0 +1,90 @@
1
+ /**
2
+ * `Unifi.AclRule`'s wire shape — the declarable subset of `ACLRule` (`getAclRule`'s own decode
3
+ * target — `ACLRuleObject` is the structurally-identical page-list item type, unused here), and
4
+ * how a live read
5
+ * becomes both plan attributes and a rendered declaration. Rule ORDER is a separate resource
6
+ * (`acl-rule-ordering.ts`, T5) — this file is one rule's own fields only.
7
+ *
8
+ * ⚠️ `sourceFilter`/`destinationFilter` STAY `unknown`, ON THE SDK'S OWN AUTHORITY.
9
+ * `access_control_acl_rules.ts`'s own comment on both ("Shape varies by variant — widened by
10
+ * scripts/convert.ts; see README") says the OpenAPI discriminator these vary over was flattened
11
+ * at generation time (T10), same as `network-form.ts`'s `ipv4Configuration`. A3 (typing these
12
+ * per-discriminator) is scoped OUT of this PR — see the plan's family inventory — so both stay
13
+ * opaque JSON, compared with plain `deepEqual`, honest about not being decoded.
14
+ *
15
+ * ⚠️ KNOWN GAP UNTIL A3 (T15, red team, Minor finding 4): the vendor's own variant DTOs for these
16
+ * filters carry SET-LIKE arrays too (`networkIds`, `ipAddressesOrSubnets`, `portFilter`,
17
+ * `macAddresses` — `docs/unifi-acl-rule.md`'s own field notes). Because the filter stays opaque,
18
+ * `deepEqual` compares those nested arrays order-sensitively, the same false-`update` risk this
19
+ * file already removes for `deviceIds`/`protocolFilter` by normalizing them — but here there is
20
+ * no decoded field to normalize. Accepted as a known gap, not fixed, until A3 types the filter
21
+ * per-discriminator and can apply `sortedSet` to its own array fields.
22
+ *
23
+ * ⛔ `index` IS ATTRIBUTES-ONLY, NEVER DECLARED. `CreateAclRuleRequest`'s own field comment:
24
+ * "ACL rule index. This property is deprecated and has no effect. Use the dedicated ACL rule
25
+ * reordering endpoint." The live object's current position is `acl-rule-ordering.ts`'s concern
26
+ * (`ACLRuleOrdering.orderedAclRuleIds`), not this resource's declared identity — reporting it
27
+ * here without comparing it avoids a field that can never converge under this family's own
28
+ * `matches` (nothing here could ever change it) from silently pretending to be declarable.
29
+ *
30
+ * ⛔ `enforcingDeviceFilter.deviceIds` AND `protocolFilter` ARE SETS, NOT SEQUENCES — same
31
+ * reasoning `firewall-zone-form.ts` gives for `networkIds`: "IDs of the Switch-capable devices
32
+ * used to enforce the ACL rule" and "Protocols this ACL rule will be applied to" both describe
33
+ * membership, with no indication either list is ordered like `acl-rule-ordering.ts`'s rule-id
34
+ * sequence. Left alone, a console that returns either in a different order between calls would
35
+ * plan a spurious `update` that this read-only family's `reconcile` then refuses forever.
36
+ */
37
+ import type * as aclRules from '@distilled.cloud/unifi-network/access_control_acl_rules';
38
+ /** ★ EXPORTED so `acl-rule-drift.ts` normalizes both live and declared sides identically — see
39
+ * `network-form.ts`'s own header for why a normalizer applied to only one side is a bug class. */
40
+ export declare const normalizeDeviceFilter: (value: aclRules.ACLRuleDeviceFilter | undefined) => aclRules.ACLRuleDeviceFilter | undefined;
41
+ export declare const normalizeProtocolFilter: (value: readonly string[] | undefined) => string[] | undefined;
42
+ /** ⚠️ EVERY OPTIONAL FIELD SPELLS OUT `| undefined` — `exactOptionalPropertyTypes`; see
43
+ * `network-form.ts`'s own header. */
44
+ export interface AclRuleProps {
45
+ siteId: string;
46
+ aclRuleId: string;
47
+ /** `ALLOW` or `BLOCK` (also accepts a future vendor value the spec did not enumerate). */
48
+ action: string;
49
+ description?: string | undefined;
50
+ /** Traffic destination filter — opaque, see the header. */
51
+ destinationFilter?: unknown;
52
+ enabled: boolean;
53
+ /** Devices enforcing this rule — compared as a SET, see the header. */
54
+ enforcingDeviceFilter?: aclRules.ACLRuleDeviceFilter | undefined;
55
+ name: string;
56
+ /** Traffic source filter — opaque, see the header. */
57
+ sourceFilter?: unknown;
58
+ type: string;
59
+ /** Protocols this rule applies to — compared as a SET, see the header. */
60
+ protocolFilter?: string[] | undefined;
61
+ networkIdFilter?: string | undefined;
62
+ }
63
+ export interface AclRuleAttributes {
64
+ siteId: string;
65
+ aclRuleId: string;
66
+ action: string;
67
+ description: string | undefined;
68
+ destinationFilter: unknown;
69
+ enabled: boolean;
70
+ enforcingDeviceFilter: aclRules.ACLRuleDeviceFilter | undefined;
71
+ /** ACL rule index (current priority position) — server-derived, never declared; see header. */
72
+ index: number;
73
+ name: string;
74
+ sourceFilter: unknown;
75
+ type: string;
76
+ protocolFilter: string[] | undefined;
77
+ networkIdFilter: string | undefined;
78
+ /** `metadata.origin` — server-derived, never declared; see `firewall-zone-form.ts`'s own. */
79
+ metadataOrigin: string;
80
+ }
81
+ export declare const attributesOf: (live: aclRules.ACLRule, props: AclRuleProps) => AclRuleAttributes;
82
+ /**
83
+ * The declaration renderer (task spec: "given one live object, return the props a declaration
84
+ * needs so its plan is noop"). A later import script feeds `getAclRule`'s own response straight in
85
+ * and writes the result as `aclRule('<id>', declareAclRule(live, siteId))` — no field is invented
86
+ * or defaulted beyond what `attributesOf` already reports, so `matches(attributesOf(live, props),
87
+ * declareAclRule(live, siteId))` is `true` by construction (`acl-rule.test.ts` proves it).
88
+ */
89
+ export declare const declareAclRule: (live: aclRules.ACLRule, siteId: string) => AclRuleProps;
90
+ //# sourceMappingURL=acl-rule-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acl-rule-form.d.ts","sourceRoot":"","sources":["../../src/unifi/acl-rule-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,KAAK,KAAK,QAAQ,MAAM,yDAAyD,CAAC;AAIzF;mGACmG;AACnG,eAAO,MAAM,qBAAqB,UACzB,QAAQ,CAAC,mBAAmB,GAAG,SAAS,KAC9C,QAAQ,CAAC,mBAAmB,GAAG,SAM3B,CAAC;AAER,eAAO,MAAM,uBAAuB,UAC3B,SAAS,MAAM,EAAE,GAAG,SAAS,KACnC,MAAM,EAAE,GAAG,SAA2D,CAAC;AAE1E;sCACsC;AACtC,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,0FAA0F;IAC1F,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,uEAAuE;IACvE,qBAAqB,CAAC,EAAE,QAAQ,CAAC,mBAAmB,GAAG,SAAS,CAAC;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,qBAAqB,EAAE,QAAQ,CAAC,mBAAmB,GAAG,SAAS,CAAC;IAChE,+FAA+F;IAC/F,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACrC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,6FAA6F;IAC7F,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,YAAY,SAAU,QAAQ,CAAC,OAAO,SAAS,YAAY,KAAG,iBAezE,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,SAAU,QAAQ,CAAC,OAAO,UAAU,MAAM,KAAG,YAatE,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * `Unifi.AclRuleOrdering`'s wire shape — ONE resource per site (`getAclRuleOrdering`'s own scope,
3
+ * `GET /v1/sites/{siteId}/acl-rules/ordering`), not per rule. Compare with `firewall-zone-form.ts`'s
4
+ * `networkIds`, which is a genuine SET: this file's `orderedAclRuleIds` is the opposite case.
5
+ *
6
+ * ⛔ T5 — `orderedAclRuleIds` IS A SEQUENCE, NEVER RUN THROUGH `sortedSet`. The endpoint's own name
7
+ * (`updateAclRuleOrdering`) and its field's own vendor comment on `ACLRule.index` ("Lower index
8
+ * has higher priority") both say this list's POSITION is the entire value it carries — rule
9
+ * priority. `firewall-zone-form.ts`'s `sortedSet`/`network-form.ts`'s three set normalizers all
10
+ * exist to stop the OPPOSITE mistake (treating a set as if order mattered); applying the same
11
+ * fix here would silently discard the one thing this resource represents. `drift.ts`'s
12
+ * `defaultEqual` (`deepEqual`) already compares arrays element-by-element without sorting them
13
+ * (its header: "sorts object KEYS but NOT ARRAY ELEMENTS") — so leaving this field un-normalized
14
+ * is what makes the comparison order-sensitive, not an oversight to "fix" later.
15
+ *
16
+ * ★ `makeDriftOf` (`drift.ts`), NO CUSTOM `equal` — same framework every other family's
17
+ * `matches`/`driftOf` share (MEDIUM-4). Its default `deepEqual` is ALREADY order-sensitive for
18
+ * arrays (see the paragraph above), so the absence of a custom `equal` here, unlike
19
+ * `firewall-zone-form.ts`'s `networkIds` entry, is itself the "never sortedSet" rule in force —
20
+ * not an oversight.
21
+ */
22
+ import type * as aclRules from '@distilled.cloud/unifi-network/access_control_acl_rules';
23
+ export interface AclRuleOrderingProps {
24
+ siteId: string;
25
+ /** Rule IDs in priority order, highest priority first — never compared as a set (see header). */
26
+ orderedAclRuleIds: string[];
27
+ }
28
+ export interface AclRuleOrderingAttributes {
29
+ siteId: string;
30
+ orderedAclRuleIds: string[];
31
+ }
32
+ export declare const attributesOf: (live: aclRules.ACLRuleOrdering, props: AclRuleOrderingProps) => AclRuleOrderingAttributes;
33
+ /**
34
+ * The declaration renderer (task spec: "given one live object, return the props a declaration
35
+ * needs so its plan is noop"). A later import script feeds `getAclRuleOrdering`'s own response
36
+ * straight in and writes the result as `aclRuleOrdering('site-1', declareAclRuleOrdering(live,
37
+ * siteId))` — `matches(attributesOf(live, props), declareAclRuleOrdering(live, siteId))` is `true`
38
+ * by construction (`acl-rule-ordering.test.ts` proves it).
39
+ */
40
+ export declare const declareAclRuleOrdering: (live: aclRules.ACLRuleOrdering, siteId: string) => AclRuleOrderingProps;
41
+ export declare const matches: (attributes: AclRuleOrderingAttributes, props: AclRuleOrderingProps) => boolean;
42
+ /**
43
+ * Per-field live-vs-declared drift straight from one live read — the task's own API
44
+ * (`driftOf(live, props)`). Only one field exists, so this either reports nothing or the whole
45
+ * ordered pair, never a per-position breakdown -- a future consumer wanting "which rule moved"
46
+ * would need to diff the two arrays itself.
47
+ */
48
+ export declare const driftOf: (live: aclRules.ACLRuleOrdering, props: AclRuleOrderingProps) => import("./drift.ts").FieldDrift[];
49
+ //# sourceMappingURL=acl-rule-ordering-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acl-rule-ordering-form.d.ts","sourceRoot":"","sources":["../../src/unifi/acl-rule-ordering-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,KAAK,QAAQ,MAAM,yDAAyD,CAAC;AAGzF,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,iGAAiG;IACjG,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,eAAO,MAAM,YAAY,SACjB,QAAQ,CAAC,eAAe,SACvB,oBAAoB,KAC1B,yBAGD,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,SAC3B,QAAQ,CAAC,eAAe,UACtB,MAAM,KACb,oBAGD,CAAC;AAUH,eAAO,MAAM,OAAO,eACN,yBAAyB,SAC9B,oBAAoB,KAC1B,OAAqD,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,OAAO,SAAU,QAAQ,CAAC,eAAe,SAAS,oBAAoB,sCACrC,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * `Unifi.AclRuleOrdering` — the ONE ordered list of user-defined ACL rule IDs for a site
3
+ * (`getAclRuleOrdering`/`updateAclRuleOrdering`, `GET`/`PUT /v1/sites/{siteId}/acl-rules/ordering`),
4
+ * READ-ONLY (`policy.ts`). T5's per-family variant of the ordering trap `docs/unifi-api-notes.md`
5
+ * warns about for `Unifi.FirewallPolicyOrdering` (`firewall-policy-ordering.ts`, keyed per zone
6
+ * pair rather than site-wide — see its own header for why): the endpoint replaces the WHOLE list
7
+ * on a write, so a partial or resorted body would drop or reorder every OTHER rule too.
8
+ * This family never writes at all, but its `matches`/`driftOf` (`acl-rule-ordering-form.ts`) are
9
+ * still order-preserving, never `sortedSet`, so a future write path inherits a correct comparison
10
+ * rather than one that has to be fixed alongside the first `update`.
11
+ *
12
+ * ★ ONE OBJECT PER SITE, NOT PER RULE — unlike `acl-rule.ts`, there is no per-object id in the
13
+ * wire response at all (`ACLRuleOrdering` is just `{ orderedAclRuleIds }`); the resource's own
14
+ * `id` (the stack-chosen string passed to `aclRuleOrdering(id, props)`) is a label the DECLARER
15
+ * picks, same as `firewallZone`/`network`, not something read back from the vendor.
16
+ */
17
+ import { Resource } from 'alchemy';
18
+ import * as Provider from 'alchemy/Provider';
19
+ import * as aclRules from '@distilled.cloud/unifi-network/access_control_acl_rules';
20
+ import * as Effect from 'effect/Effect';
21
+ import { type AclRuleOrderingAttributes, type AclRuleOrderingProps } from './acl-rule-ordering-form.ts';
22
+ import type { UnifiRequirements, UnifiSpec } from './resource.ts';
23
+ export type { AclRuleOrderingAttributes, AclRuleOrderingProps } from './acl-rule-ordering-form.ts';
24
+ export { declareAclRuleOrdering, driftOf } from './acl-rule-ordering-form.ts';
25
+ export interface UnifiAclRuleOrdering extends Resource<'Unifi.AclRuleOrdering', AclRuleOrderingProps, AclRuleOrderingAttributes, never, UnifiRequirements> {
26
+ }
27
+ export declare const UnifiAclRuleOrdering: import("alchemy").ResourceClass<UnifiAclRuleOrdering>;
28
+ /** `aclRuleOrdering('site-1', props)` — `adopt(true)` piped on by default (H5); see `network.ts`. */
29
+ export declare const aclRuleOrdering: (id: string, props: AclRuleOrderingProps) => Effect.Effect<UnifiAclRuleOrdering, never, import("effect/unstable/http/HttpClient").HttpClient>;
30
+ /** ★ EXPORTED for direct testing against a fake `Credentials` layer — see `network.ts`'s own. */
31
+ export declare const spec: UnifiSpec<AclRuleOrderingProps, aclRules.ACLRuleOrdering, AclRuleOrderingAttributes, aclRules.GetAclRuleOrderingError>;
32
+ export declare const handlers: {
33
+ list: () => Effect.Effect<never[], never, never>;
34
+ read: (args: {
35
+ olds: AclRuleOrderingProps;
36
+ output: AclRuleOrderingAttributes | undefined;
37
+ }) => Effect.Effect<AclRuleOrderingAttributes | undefined, aclRules.UnifiNetworkOpError, import("effect/unstable/http/HttpClient").HttpClient>;
38
+ diff: (args: {
39
+ news: import("alchemy").Input<AclRuleOrderingProps>;
40
+ output: AclRuleOrderingAttributes | undefined;
41
+ }) => Effect.Effect<{
42
+ readonly action: 'update';
43
+ } | {
44
+ readonly action: 'noop';
45
+ } | undefined, aclRules.UnifiNetworkOpError, import("effect/unstable/http/HttpClient").HttpClient>;
46
+ reconcile: (args: {
47
+ news: AclRuleOrderingProps;
48
+ }) => Effect.Effect<AclRuleOrderingAttributes, import("./policy.ts").UnifiWriteRefused | aclRules.UnifiNetworkOpError, import("effect/unstable/http/HttpClient").HttpClient>;
49
+ delete: (args: {
50
+ olds: AclRuleOrderingProps;
51
+ }) => Effect.Effect<never, import("./policy.ts").UnifiWriteRefused, import("effect/unstable/http/HttpClient").HttpClient>;
52
+ };
53
+ export declare const UnifiAclRuleOrderingProvider: () => import("effect/Layer").Layer<Provider.Provider<UnifiAclRuleOrdering>, never, import("effect/unstable/http/HttpClient").HttpClient>;
54
+ //# sourceMappingURL=acl-rule-ordering.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acl-rule-ordering.d.ts","sourceRoot":"","sources":["../../src/unifi/acl-rule-ordering.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,QAAQ,MAAM,yDAAyD,CAAC;AACpF,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EAG1B,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAGlE,YAAY,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnG,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAE9E,MAAM,WAAW,oBAAqB,SAAQ,QAAQ,CACpD,uBAAuB,EACvB,oBAAoB,EACpB,yBAAyB,EACzB,KAAK,EACL,iBAAiB,CAClB;CAAG;AAEJ,eAAO,MAAM,oBAAoB,uDAE/B,CAAC;AAEH,qGAAqG;AACrG,eAAO,MAAM,eAAe,OAAQ,MAAM,SAAS,oBAAoB,qGACpB,CAAC;AAEpD,iGAAiG;AACjG,eAAO,MAAM,IAAI,EAAE,SAAS,CAC1B,oBAAoB,EACpB,QAAQ,CAAC,eAAe,EACxB,yBAAyB,EACzB,QAAQ,CAAC,uBAAuB,CAUjC,CAAC;AAEF,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;CAAsB,CAAC;AAE5C,eAAO,MAAM,4BAA4B,0IAC0D,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * `Unifi.AclRule` — one user-defined ACL rule on a UniFi Network site, READ-ONLY (`policy.ts`).
3
+ * `Unifi.AclRuleOrdering` (`acl-rule-ordering.ts`) is the sibling resource for rule ORDER (T5) —
4
+ * one per site, never this file's concern.
5
+ *
6
+ * ★ T11 GATE — see `dns-policy.ts`'s own header for the full closure-diff record: `Access Control
7
+ * (ACL Rules)` (7 ops, including `getAclRuleOrdering`/`updateAclRuleOrdering`) is
8
+ * byte-identical between 10.4.57 and 10.6.97, and unreachable from any of the 14 schemas that DID
9
+ * change. Full breakdown: `docs/unifi-acl-rule.md`.
10
+ */
11
+ import { Resource } from 'alchemy';
12
+ import * as Provider from 'alchemy/Provider';
13
+ import * as aclRules from '@distilled.cloud/unifi-network/access_control_acl_rules';
14
+ import * as Effect from 'effect/Effect';
15
+ import { type AclRuleAttributes, type AclRuleProps } from './acl-rule-form.ts';
16
+ import type { UnifiRequirements, UnifiSpec } from './resource.ts';
17
+ export type { AclRuleAttributes, AclRuleProps } from './acl-rule-form.ts';
18
+ export { declareAclRule } from './acl-rule-form.ts';
19
+ export { driftOf } from './acl-rule-drift.ts';
20
+ export interface UnifiAclRule extends Resource<'Unifi.AclRule', AclRuleProps, AclRuleAttributes, never, UnifiRequirements> {
21
+ }
22
+ export declare const UnifiAclRule: import("alchemy").ResourceClass<UnifiAclRule>;
23
+ /** `aclRule('block-iot-wan', props)` — `adopt(true)` piped on by default (H5); see `network.ts`. */
24
+ export declare const aclRule: (id: string, props: AclRuleProps) => Effect.Effect<UnifiAclRule, never, import("effect/unstable/http/HttpClient").HttpClient>;
25
+ /** ★ EXPORTED for direct testing against a fake `Credentials` layer — see `network.ts`'s own. */
26
+ export declare const spec: UnifiSpec<AclRuleProps, aclRules.ACLRule, AclRuleAttributes, aclRules.GetAclRuleError>;
27
+ export declare const handlers: {
28
+ list: () => Effect.Effect<never[], never, never>;
29
+ read: (args: {
30
+ olds: AclRuleProps;
31
+ output: AclRuleAttributes | undefined;
32
+ }) => Effect.Effect<AclRuleAttributes | undefined, aclRules.UnifiNetworkOpError, import("effect/unstable/http/HttpClient").HttpClient>;
33
+ diff: (args: {
34
+ news: import("alchemy").Input<AclRuleProps>;
35
+ output: AclRuleAttributes | undefined;
36
+ }) => Effect.Effect<{
37
+ readonly action: 'update';
38
+ } | {
39
+ readonly action: 'noop';
40
+ } | undefined, aclRules.UnifiNetworkOpError, import("effect/unstable/http/HttpClient").HttpClient>;
41
+ reconcile: (args: {
42
+ news: AclRuleProps;
43
+ }) => Effect.Effect<AclRuleAttributes, import("./policy.ts").UnifiWriteRefused | aclRules.UnifiNetworkOpError, import("effect/unstable/http/HttpClient").HttpClient>;
44
+ delete: (args: {
45
+ olds: AclRuleProps;
46
+ }) => Effect.Effect<never, import("./policy.ts").UnifiWriteRefused, import("effect/unstable/http/HttpClient").HttpClient>;
47
+ };
48
+ export declare const UnifiAclRuleProvider: () => import("effect/Layer").Layer<Provider.Provider<UnifiAclRule>, never, import("effect/unstable/http/HttpClient").HttpClient>;
49
+ //# sourceMappingURL=acl-rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acl-rule.d.ts","sourceRoot":"","sources":["../../src/unifi/acl-rule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,QAAQ,MAAM,yDAAyD,CAAC;AACpF,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAgB,MAAM,oBAAoB,CAAC;AAE7F,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAGlE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,MAAM,WAAW,YAAa,SAAQ,QAAQ,CAC5C,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,KAAK,EACL,iBAAiB,CAClB;CAAG;AAEJ,eAAO,MAAM,YAAY,+CAEvB,CAAC;AAEH,oGAAoG;AACpG,eAAO,MAAM,OAAO,OAAQ,MAAM,SAAS,YAAY,6FACZ,CAAC;AAE5C,iGAAiG;AACjG,eAAO,MAAM,IAAI,EAAE,SAAS,CAC1B,YAAY,EACZ,QAAQ,CAAC,OAAO,EAChB,iBAAiB,EACjB,QAAQ,CAAC,eAAe,CAUzB,CAAC;AAEF,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;CAAsB,CAAC;AAE5C,eAAO,MAAM,oBAAoB,kIACkD,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `Unifi.DnsPolicy`'s `matches` AND `driftOf` (B6) — both built on the ONE field list below, the
3
+ * same `fieldDrift`-is-the-only-comparison shape `network-drift.ts`'s own header explains (MEDIUM-4,
4
+ * red team, 2026-09-26): `matches(attrs, props) === (driftOf(live, props).length === 0)` is true
5
+ * BY CONSTRUCTION, never two hand-kept-in-sync comparisons.
6
+ *
7
+ * ★ NO CUSTOM `equal` ANYWHERE. Every field is a scalar and `drift.ts`'s `defaultEqual`
8
+ * (`deepEqual` with `stripNullish: true`) already gives UniFi's `null`-for-unset-optional
9
+ * reality the same tolerance `network-drift.ts`/`firewall-zone-form.ts` rely on — see
10
+ * `dns-policy-form.ts`'s own header for why no field here needs a set/order normalizer.
11
+ */
12
+ import type * as dnsPolicies from '@distilled.cloud/unifi-network/dns_policies';
13
+ import { type DnsPolicyAttributes, type DnsPolicyProps } from './dns-policy-form.ts';
14
+ export declare const matches: (attributes: DnsPolicyAttributes, props: DnsPolicyProps) => boolean;
15
+ /**
16
+ * Per-field live-vs-declared drift straight from one live read — the task's own API
17
+ * (`driftOf(live, props)`), so `homeflare-network`'s pre-import drift check never has to derive
18
+ * `attributesOf` itself just to call this.
19
+ */
20
+ export declare const driftOf: (live: dnsPolicies.DNSPolicy, props: DnsPolicyProps) => import("./drift.ts").FieldDrift[];
21
+ //# sourceMappingURL=dns-policy-drift.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dns-policy-drift.d.ts","sourceRoot":"","sources":["../../src/unifi/dns-policy-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,KAAK,WAAW,MAAM,6CAA6C,CAAC;AAEhF,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,cAAc,EAAgB,MAAM,sBAAsB,CAAC;AAyBnG,eAAO,MAAM,OAAO,eAAgB,mBAAmB,SAAS,cAAc,KAAG,OACrC,CAAC;AAE7C;;;;GAIG;AACH,eAAO,MAAM,OAAO,SAAU,WAAW,CAAC,SAAS,SAAS,cAAc,sCAC5B,CAAC"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * `Unifi.DnsPolicy`'s wire shape — the declarable subset of `DNSPolicy`, and how a live read
3
+ * becomes both plan attributes and a rendered declaration.
4
+ *
5
+ * ★ ONE FLAT DTO FOR EVERY DNS RECORD `type` (`A_RECORD`/`AAAA_RECORD`/`CNAME_RECORD`/
6
+ * `FORWARD_DOMAIN`/`MX_RECORD`/`SRV_RECORD`/`TXT_RECORD` — the pinned spec's `DNS policy` schema
7
+ * DOES discriminate on `type`, via `discriminator.mapping` to 7 variant DTOs; see
8
+ * `docs/unifi-dns-policy.md`'s "One flat DTO" section, corrected 2026-09-26). Unlike
9
+ * `access_control_acl_rules.ts`'s `sourceFilter`/`destinationFilter` or `firewall.ts`'s policy
10
+ * filters, NONE of `dns_policies.ts`'s fields were widened to `unknown` by the converter (T10) —
11
+ * `scripts/convert.ts` flattens the 7 variants into one struct instead, because no two variants
12
+ * collide on a field name, so every optional field still decodes as a plain scalar and there is
13
+ * no discriminated-variant trap here to flag or defer past this PR.
14
+ *
15
+ * ⚠️ PROPS MIRROR `UpdateDnsPolicyRequest`, NOT `DNSPolicy` — same split `network-form.ts` and
16
+ * `firewall-zone-form.ts` both use. `id` and `metadata` are server-derived (no writable field
17
+ * accepts either), so they are attributes-only, reported but never compared or declared.
18
+ * Everything else in `DnsPolicyProps` is exactly what `updateDnsPolicy`/`createDnsPolicy` would
19
+ * accept, even though this family never calls either.
20
+ *
21
+ * ⛔ NO ARRAY FIELD ANYWHERE IN THIS SHAPE. Every field below is a scalar (`string`/`number`/
22
+ * `boolean`), so none of `network-form.ts`'s/`firewall-zone-form.ts`'s `sortedSet` normalizing
23
+ * is needed — `deepEqual`'s default `stripNullish` handling (`drift.ts`) is the whole story.
24
+ */
25
+ import type * as dnsPolicies from '@distilled.cloud/unifi-network/dns_policies';
26
+ /**
27
+ * ⚠️ EVERY OPTIONAL FIELD SPELLS OUT `| undefined` ON PURPOSE (`exactOptionalPropertyTypes` —
28
+ * see `network-form.ts`'s own header for why `declareDnsPolicy` below needs it: it assigns a
29
+ * live optional field straight through, so the target type must admit an explicit `undefined`,
30
+ * not just omission).
31
+ */
32
+ export interface DnsPolicyProps {
33
+ siteId: string;
34
+ dnsPolicyId: string;
35
+ enabled: boolean;
36
+ /** DNS record type: `A_RECORD`, `AAAA_RECORD`, `CNAME_RECORD`, `FORWARD_DOMAIN`, `MX_RECORD`,
37
+ * `SRV_RECORD` or `TXT_RECORD` (the discriminator's own mapping keys, see the header). */
38
+ type: string;
39
+ domain?: string | undefined;
40
+ ipv6Address?: string | undefined;
41
+ /** Time to live in seconds. */
42
+ ttlSeconds?: number | undefined;
43
+ ipv4Address?: string | undefined;
44
+ targetDomain?: string | undefined;
45
+ /** IP address of the DNS Server that the DNS query is forwarded to. */
46
+ ipAddress?: string | undefined;
47
+ mailServerDomain?: string | undefined;
48
+ /** Priority. A lower number is preferred. */
49
+ priority?: number | undefined;
50
+ port?: number | undefined;
51
+ /** Protocol used by the service. */
52
+ protocol?: string | undefined;
53
+ /** Domain of the server that is running the service. */
54
+ serverDomain?: string | undefined;
55
+ /** Service associated with this SRV record. */
56
+ service?: string | undefined;
57
+ /** Weight. A relative value applicable for records with the same priority. A lower number is
58
+ * preferred. */
59
+ weight?: number | undefined;
60
+ /** The text value associated with this TXT DNS record. Text can contain up to four
61
+ * 255-character strings. Lines containing commas must be enclosed in double quotes ("). */
62
+ text?: string | undefined;
63
+ }
64
+ export interface DnsPolicyAttributes {
65
+ siteId: string;
66
+ dnsPolicyId: string;
67
+ enabled: boolean;
68
+ type: string;
69
+ domain: string | undefined;
70
+ ipv6Address: string | undefined;
71
+ ttlSeconds: number | undefined;
72
+ ipv4Address: string | undefined;
73
+ targetDomain: string | undefined;
74
+ ipAddress: string | undefined;
75
+ mailServerDomain: string | undefined;
76
+ priority: number | undefined;
77
+ port: number | undefined;
78
+ protocol: string | undefined;
79
+ serverDomain: string | undefined;
80
+ service: string | undefined;
81
+ weight: number | undefined;
82
+ text: string | undefined;
83
+ /** `metadata.origin` (e.g. `USER`) — server-derived, never declared; see
84
+ * `firewall-zone-form.ts`'s own `metadataOrigin` for the same split. */
85
+ metadataOrigin: string;
86
+ }
87
+ export declare const attributesOf: (live: dnsPolicies.DNSPolicy, props: DnsPolicyProps) => DnsPolicyAttributes;
88
+ /**
89
+ * The declaration renderer (task spec: "given one live object, return the props a declaration
90
+ * needs so its plan is noop"). A later import script feeds `getDnsPolicy`'s own response straight
91
+ * in and writes the result into `alchemy.run.ts` as `dnsPolicy('<id>', declareDnsPolicy(live,
92
+ * siteId))` — no field is invented or defaulted here beyond what `attributesOf` already reports,
93
+ * so `matches(attributesOf(live, props), declareDnsPolicy(live, siteId))` is `true` by
94
+ * construction (`dns-policy.test.ts` proves it) for any live object this SDK can decode.
95
+ */
96
+ export declare const declareDnsPolicy: (live: dnsPolicies.DNSPolicy, siteId: string) => DnsPolicyProps;
97
+ //# sourceMappingURL=dns-policy-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dns-policy-form.d.ts","sourceRoot":"","sources":["../../src/unifi/dns-policy-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,KAAK,WAAW,MAAM,6CAA6C,CAAC;AAEhF;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB;+FAC2F;IAC3F,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B;qBACiB;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B;gGAC4F;IAC5F,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB;6EACyE;IACzE,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,YAAY,SACjB,WAAW,CAAC,SAAS,SACpB,cAAc,KACpB,mBAoBD,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,SAAU,WAAW,CAAC,SAAS,UAAU,MAAM,KAAG,cAmB7E,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * `Unifi.DnsPolicy` — one DNS policy on a UniFi Network site, READ-ONLY (`policy.ts`).
3
+ *
4
+ * ★ T11 GATE, CHECKED 2026-09-26, CORRECTED SAME DAY (red team, Important finding 1): `DNS
5
+ * Policies` is 5 operations, `Access Control (ACL Rules)` (`acl-rule.ts`) is 7 — 12 total.
6
+ * Diffed the pinned 10.4.57 spec against a 10.6.97 mirror (`beezly/unifi-apis`, diffing aid
7
+ * only, `docs/unifi-acl-rule.md` records the sha256 + mirror commit): all 12 full operation
8
+ * objects (parameters, request body, responses, unresolved `$ref`s included) are byte-identical
9
+ * across versions. ⚠️ The schema closure is 46, not 17 — a `$ref`-only walk misses every schema
10
+ * reachable only via a `discriminator.mapping` (both `DNS policy` and `ACL rule` discriminate on
11
+ * `type`); the 46-schema closure, `$ref` + `mapping` together, shares zero names with the 14
12
+ * schemas that DID change between the two versions (all in `Switching`, `Filtering`, or one
13
+ * `UniFi Devices` enum — none of it DNS- or ACL-shaped). Same reachability method
14
+ * `spec-version-provenance.md` (distilled package) used for Networks/FirewallZones, extended to
15
+ * follow `mapping` too; full breakdown in `docs/unifi-acl-rule.md`, not repeated per family.
16
+ */
17
+ import { Resource } from 'alchemy';
18
+ import * as Provider from 'alchemy/Provider';
19
+ import * as dnsPolicies from '@distilled.cloud/unifi-network/dns_policies';
20
+ import * as Effect from 'effect/Effect';
21
+ import { type DnsPolicyAttributes, type DnsPolicyProps } from './dns-policy-form.ts';
22
+ import type { UnifiRequirements, UnifiSpec } from './resource.ts';
23
+ export type { DnsPolicyAttributes, DnsPolicyProps } from './dns-policy-form.ts';
24
+ export { declareDnsPolicy } from './dns-policy-form.ts';
25
+ export { driftOf } from './dns-policy-drift.ts';
26
+ export interface UnifiDnsPolicy extends Resource<'Unifi.DnsPolicy', DnsPolicyProps, DnsPolicyAttributes, never, UnifiRequirements> {
27
+ }
28
+ export declare const UnifiDnsPolicy: import("alchemy").ResourceClass<UnifiDnsPolicy>;
29
+ /** `dnsPolicy('lan-forwarding', props)` — `adopt(true)` piped on by default (H5); see `network.ts`. */
30
+ export declare const dnsPolicy: (id: string, props: DnsPolicyProps) => Effect.Effect<UnifiDnsPolicy, never, import("effect/unstable/http/HttpClient").HttpClient>;
31
+ /** ★ EXPORTED for direct testing against a fake `Credentials` layer — see `network.ts`'s own. */
32
+ export declare const spec: UnifiSpec<DnsPolicyProps, dnsPolicies.DNSPolicy, DnsPolicyAttributes, dnsPolicies.GetDnsPolicyError>;
33
+ export declare const handlers: {
34
+ list: () => Effect.Effect<never[], never, never>;
35
+ read: (args: {
36
+ olds: DnsPolicyProps;
37
+ output: DnsPolicyAttributes | undefined;
38
+ }) => Effect.Effect<DnsPolicyAttributes | undefined, dnsPolicies.UnifiNetworkOpError, import("effect/unstable/http/HttpClient").HttpClient>;
39
+ diff: (args: {
40
+ news: import("alchemy").Input<DnsPolicyProps>;
41
+ output: DnsPolicyAttributes | undefined;
42
+ }) => Effect.Effect<{
43
+ readonly action: 'update';
44
+ } | {
45
+ readonly action: 'noop';
46
+ } | undefined, dnsPolicies.UnifiNetworkOpError, import("effect/unstable/http/HttpClient").HttpClient>;
47
+ reconcile: (args: {
48
+ news: DnsPolicyProps;
49
+ }) => Effect.Effect<DnsPolicyAttributes, import("./policy.ts").UnifiWriteRefused | dnsPolicies.UnifiNetworkOpError, import("effect/unstable/http/HttpClient").HttpClient>;
50
+ delete: (args: {
51
+ olds: DnsPolicyProps;
52
+ }) => Effect.Effect<never, import("./policy.ts").UnifiWriteRefused, import("effect/unstable/http/HttpClient").HttpClient>;
53
+ };
54
+ export declare const UnifiDnsPolicyProvider: () => import("effect/Layer").Layer<Provider.Provider<UnifiDnsPolicy>, never, import("effect/unstable/http/HttpClient").HttpClient>;
55
+ //# sourceMappingURL=dns-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dns-policy.d.ts","sourceRoot":"","sources":["../../src/unifi/dns-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,WAAW,MAAM,6CAA6C,CAAC;AAC3E,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,cAAc,EAAgB,MAAM,sBAAsB,CAAC;AAEnG,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAGlE,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,MAAM,WAAW,cAAe,SAAQ,QAAQ,CAC9C,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,KAAK,EACL,iBAAiB,CAClB;CAAG;AAEJ,eAAO,MAAM,cAAc,iDAEzB,CAAC;AAEH,uGAAuG;AACvG,eAAO,MAAM,SAAS,OAAQ,MAAM,SAAS,cAAc,+FACd,CAAC;AAE9C,iGAAiG;AACjG,eAAO,MAAM,IAAI,EAAE,SAAS,CAC1B,cAAc,EACd,WAAW,CAAC,SAAS,EACrB,mBAAmB,EACnB,WAAW,CAAC,iBAAiB,CAU9B,CAAC;AAEF,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;CAAsB,CAAC;AAE5C,eAAO,MAAM,sBAAsB,oIACoD,CAAC"}
@@ -0,0 +1,27 @@
1
+ /** One field whose live and declared values differ, as `makeDriftOf` reports it. */
2
+ export interface FieldDrift {
3
+ readonly field: string;
4
+ readonly live: unknown;
5
+ readonly declared: unknown;
6
+ }
7
+ /** One field's comparison recipe for `makeDriftOf`. */
8
+ export interface DriftField<Attributes, Props> {
9
+ readonly field: string;
10
+ readonly live: (attributes: Attributes) => unknown;
11
+ readonly declared: (props: Props) => unknown;
12
+ /**
13
+ * Defaults to `alchemy/Diff`'s `deepEqual` with `stripNullish: true` — the same tolerance
14
+ * every `matches` in this directory already gives UniFi's `null`-for-unset optionals (see
15
+ * `network-form.ts`'s header). Pass one explicitly for a field `matches` compares as a
16
+ * normalized SET (`firewall-zone-form.ts`'s `networkIds`), where plain `deepEqual` would
17
+ * report order as drift `matches` never would.
18
+ */
19
+ readonly equal?: (live: unknown, declared: unknown) => boolean;
20
+ }
21
+ /**
22
+ * Builds a `(attributes, props) => FieldDrift[]` from a field list — the framework a family's own
23
+ * `*-form.ts` calls once, then wraps as `driftOf(live, props)` by feeding it `attributesOf(live,
24
+ * props)` (the task's own API: callers have a live SDK object, not `Attributes`, on hand).
25
+ */
26
+ export declare const makeDriftOf: <Attributes, Props>(fields: readonly DriftField<Attributes, Props>[]) => (attributes: Attributes, props: Props) => FieldDrift[];
27
+ //# sourceMappingURL=drift.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift.d.ts","sourceRoot":"","sources":["../../src/unifi/drift.ts"],"names":[],"mappings":"AAgBA,oFAAoF;AACpF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,uDAAuD;AACvD,MAAM,WAAW,UAAU,CAAC,UAAU,EAAE,KAAK;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,OAAO,CAAC;IACnD,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;IAC7C;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC;CAChE;AAKD;;;;GAIG;AACH,eAAO,MAAM,WAAW,GACrB,UAAU,EAAE,KAAK,UAAU,SAAS,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,kBACvD,UAAU,SAAS,KAAK,KAAG,UAAU,EAO9C,CAAC"}
@@ -18,7 +18,11 @@ export type Seen = {
18
18
  readonly method: string;
19
19
  readonly path: string;
20
20
  };
21
- /** No documented failure envelope (see `protocol.ts`) — plain text is all a failure needs. */
21
+ /**
22
+ * Plain-text failure. `protocol.ts`'s `errorEnvelope` also decodes a documented JSON shape
23
+ * (`components.schemas["Error Message"]`, A1/T8) when a scenario needs that instead — see
24
+ * `errors-and-secrets.test.ts`'s `envelopeBody` helper for a fixture in that shape.
25
+ */
22
26
  export declare const fakeFailure: (status: number, detail: string) => Response;
23
27
  /**
24
28
  * `route` decides every response; this wrapper only records what was sent and adapts to
@@ -1 +1 @@
1
- {"version":3,"file":"fake-unifi.d.ts","sourceRoot":"","sources":["../../src/unifi/fake-unifi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,KAAK,WAAW,EAAe,MAAM,4CAA4C,CAAC;AAC3F,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,eAAO,MAAM,SAAS,wDAAwD,CAAC;AAC/E,eAAO,MAAM,QAAQ,0BAA0B,CAAC;AAEhD,MAAM,MAAM,IAAI,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE,8FAA8F;AAC9F,eAAO,MAAM,WAAW,WAAY,MAAM,UAAU,MAAM,aAAqC,CAAC;AAEhG;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,UAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,QAAQ;;;CAUtE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,YAChB,OAAO,UAAU,CAAC,KAAK,UACzB,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,kGAC+D,CAAC"}
1
+ {"version":3,"file":"fake-unifi.d.ts","sourceRoot":"","sources":["../../src/unifi/fake-unifi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,KAAK,WAAW,EAAe,MAAM,4CAA4C,CAAC;AAC3F,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,eAAO,MAAM,SAAS,wDAAwD,CAAC;AAC/E,eAAO,MAAM,QAAQ,0BAA0B,CAAC;AAEhD,MAAM,MAAM,IAAI,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE;;;;GAIG;AACH,eAAO,MAAM,WAAW,WAAY,MAAM,UAAU,MAAM,aAAqC,CAAC;AAEhG;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,UAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,QAAQ;;;CAUtE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,YAChB,OAAO,UAAU,CAAC,KAAK,UACzB,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,kGAC+D,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * `Unifi.FirewallPolicy`'s `matches` AND `driftOf` (B6) — both built on the ONE field list below,
3
+ * the same `fieldDrift`-is-the-only-comparison shape `network-drift.ts`'s header explains (MEDIUM-4,
4
+ * red team, 2026-09-26): `matches(attrs, props) === (driftOf(live, props).length === 0)` is true
5
+ * BY CONSTRUCTION, never two hand-kept-in-sync comparisons.
6
+ *
7
+ * ⚠️ `stripNullish: true` ON EVERY FIELD BY DEFAULT (`drift.ts`'s `defaultEqual`) — same "UniFi's
8
+ * JSON answers `null`, a declaration omits" tolerance every other family here relies on.
9
+ * ⛔ `connectionStateFilter` RUNS THROUGH `firewall-policy-form.ts`'s normalizer on BOTH sides
10
+ * before comparing — never applied to only `live` or only `declared` (the specific gap MEDIUM-4's
11
+ * own mutant found in `network-drift.ts`; see its header, and `acl-rule-drift.ts`'s own repeat of
12
+ * this same rule for `protocolFilter`/`enforcingDeviceFilter`).
13
+ * ★ `action`/`destination`/`ipProtocolScope`/`schedule`/`source` compare with the plain default
14
+ * `equal` (whole-value `deepEqual`) — see `firewall-policy-form.ts`'s header for the accepted
15
+ * known gap this leaves in their own nested set-like arrays.
16
+ */
17
+ import type * as firewall from '@distilled.cloud/unifi-network/firewall';
18
+ import { type FirewallPolicyAttributes, type FirewallPolicyProps } from './firewall-policy-form.ts';
19
+ export declare const matches: (attributes: FirewallPolicyAttributes, props: FirewallPolicyProps) => boolean;
20
+ /**
21
+ * Per-field live-vs-declared drift straight from one live read — the task's own API
22
+ * (`driftOf(live, props)`), so `homeflare-network`'s pre-import drift check never has to derive
23
+ * `attributesOf` itself just to call this.
24
+ */
25
+ export declare const driftOf: (live: firewall.FirewallPolicy, props: FirewallPolicyProps) => import("./drift.ts").FieldDrift[];
26
+ //# sourceMappingURL=firewall-policy-drift.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firewall-policy-drift.d.ts","sourceRoot":"","sources":["../../src/unifi/firewall-policy-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,KAAK,QAAQ,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EAGzB,MAAM,2BAA2B,CAAC;AAoBnC,eAAO,MAAM,OAAO,eACN,wBAAwB,SAC7B,mBAAmB,KACzB,OAAqD,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,OAAO,SAAU,QAAQ,CAAC,cAAc,SAAS,mBAAmB,sCACnC,CAAC"}