@homeflare/alchemy 0.42.0 → 0.44.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 (648) hide show
  1. package/README.md +10 -1
  2. package/dist/caddy/index.js +35 -1
  3. package/dist/caddy/index.js.map +3 -3
  4. package/dist/launchd/index.js +35 -1
  5. package/dist/launchd/index.js.map +3 -3
  6. package/dist/linux/index.js +35 -1
  7. package/dist/linux/index.js.map +3 -3
  8. package/dist/litellm/access-group-form.d.ts +26 -0
  9. package/dist/litellm/access-group-form.d.ts.map +1 -0
  10. package/dist/litellm/access-group-operations.d.ts +37 -0
  11. package/dist/litellm/access-group-operations.d.ts.map +1 -0
  12. package/dist/litellm/access-group-types.d.ts +49 -0
  13. package/dist/litellm/access-group-types.d.ts.map +1 -0
  14. package/dist/litellm/access-group.d.ts +55 -0
  15. package/dist/litellm/access-group.d.ts.map +1 -0
  16. package/dist/litellm/budget-errors.d.ts +36 -0
  17. package/dist/litellm/budget-errors.d.ts.map +1 -0
  18. package/dist/litellm/budget-form.d.ts +50 -0
  19. package/dist/litellm/budget-form.d.ts.map +1 -0
  20. package/dist/litellm/budget-operations.d.ts +20 -0
  21. package/dist/litellm/budget-operations.d.ts.map +1 -0
  22. package/dist/litellm/budget.d.ts +61 -0
  23. package/dist/litellm/budget.d.ts.map +1 -0
  24. package/dist/litellm/credential-errors.d.ts +131 -0
  25. package/dist/litellm/credential-errors.d.ts.map +1 -0
  26. package/dist/litellm/credential-form.d.ts +79 -0
  27. package/dist/litellm/credential-form.d.ts.map +1 -0
  28. package/dist/litellm/credential-operations.d.ts +84 -0
  29. package/dist/litellm/credential-operations.d.ts.map +1 -0
  30. package/dist/litellm/credential-rewrite.d.ts +6 -0
  31. package/dist/litellm/credential-rewrite.d.ts.map +1 -0
  32. package/dist/litellm/credential-types.d.ts +87 -0
  33. package/dist/litellm/credential-types.d.ts.map +1 -0
  34. package/dist/litellm/credential-values.d.ts +53 -0
  35. package/dist/litellm/credential-values.d.ts.map +1 -0
  36. package/dist/litellm/credential.d.ts +83 -0
  37. package/dist/litellm/credential.d.ts.map +1 -0
  38. package/dist/litellm/fake-access-group-litellm.d.ts +34 -0
  39. package/dist/litellm/fake-access-group-litellm.d.ts.map +1 -0
  40. package/dist/litellm/fake-credential-litellm.d.ts +54 -0
  41. package/dist/litellm/fake-credential-litellm.d.ts.map +1 -0
  42. package/dist/litellm/fake-keys.d.ts +53 -0
  43. package/dist/litellm/fake-keys.d.ts.map +1 -0
  44. package/dist/litellm/fake-litellm.d.ts +9 -1
  45. package/dist/litellm/fake-litellm.d.ts.map +1 -1
  46. package/dist/litellm/fake-mcp-litellm.d.ts +67 -0
  47. package/dist/litellm/fake-mcp-litellm.d.ts.map +1 -0
  48. package/dist/litellm/fake-model-litellm-post-update.d.ts +49 -0
  49. package/dist/litellm/fake-model-litellm-post-update.d.ts.map +1 -0
  50. package/dist/litellm/fake-model-litellm.d.ts +48 -0
  51. package/dist/litellm/fake-model-litellm.d.ts.map +1 -0
  52. package/dist/litellm/fake-policy-attachment-litellm.d.ts +33 -0
  53. package/dist/litellm/fake-policy-attachment-litellm.d.ts.map +1 -0
  54. package/dist/litellm/fake-policy-litellm.d.ts +32 -0
  55. package/dist/litellm/fake-policy-litellm.d.ts.map +1 -0
  56. package/dist/litellm/fake-registry-base.d.ts +42 -0
  57. package/dist/litellm/fake-registry-base.d.ts.map +1 -0
  58. package/dist/litellm/fake-stack.d.ts +8 -1
  59. package/dist/litellm/fake-stack.d.ts.map +1 -1
  60. package/dist/litellm/fake-team-litellm.d.ts +47 -0
  61. package/dist/litellm/fake-team-litellm.d.ts.map +1 -0
  62. package/dist/litellm/fake-tool-litellm.d.ts +28 -0
  63. package/dist/litellm/fake-tool-litellm.d.ts.map +1 -0
  64. package/dist/litellm/fake-toolset-litellm.d.ts +29 -0
  65. package/dist/litellm/fake-toolset-litellm.d.ts.map +1 -0
  66. package/dist/litellm/index.d.ts +20 -0
  67. package/dist/litellm/index.d.ts.map +1 -1
  68. package/dist/litellm/index.js +3201 -2
  69. package/dist/litellm/index.js.map +70 -5
  70. package/dist/litellm/key-errors.d.ts +169 -0
  71. package/dist/litellm/key-errors.d.ts.map +1 -0
  72. package/dist/litellm/key-form.d.ts +119 -0
  73. package/dist/litellm/key-form.d.ts.map +1 -0
  74. package/dist/litellm/key-harness.d.ts +41 -0
  75. package/dist/litellm/key-harness.d.ts.map +1 -0
  76. package/dist/litellm/key-metadata-errors.d.ts +30 -0
  77. package/dist/litellm/key-metadata-errors.d.ts.map +1 -0
  78. package/dist/litellm/key-metadata.d.ts +22 -0
  79. package/dist/litellm/key-metadata.d.ts.map +1 -0
  80. package/dist/litellm/key-operations.d.ts +63 -0
  81. package/dist/litellm/key-operations.d.ts.map +1 -0
  82. package/dist/litellm/key-secret.d.ts +33 -0
  83. package/dist/litellm/key-secret.d.ts.map +1 -0
  84. package/dist/litellm/key.d.ts +78 -0
  85. package/dist/litellm/key.d.ts.map +1 -0
  86. package/dist/litellm/mcp-server-credential.d.ts +50 -0
  87. package/dist/litellm/mcp-server-credential.d.ts.map +1 -0
  88. package/dist/litellm/mcp-server-errors.d.ts +101 -0
  89. package/dist/litellm/mcp-server-errors.d.ts.map +1 -0
  90. package/dist/litellm/mcp-server-form.d.ts +56 -0
  91. package/dist/litellm/mcp-server-form.d.ts.map +1 -0
  92. package/dist/litellm/mcp-server-locate.d.ts +26 -0
  93. package/dist/litellm/mcp-server-locate.d.ts.map +1 -0
  94. package/dist/litellm/mcp-server-operations.d.ts +63 -0
  95. package/dist/litellm/mcp-server-operations.d.ts.map +1 -0
  96. package/dist/litellm/mcp-server-shadow.d.ts +24 -0
  97. package/dist/litellm/mcp-server-shadow.d.ts.map +1 -0
  98. package/dist/litellm/mcp-server-types.d.ts +118 -0
  99. package/dist/litellm/mcp-server-types.d.ts.map +1 -0
  100. package/dist/litellm/mcp-server-url.d.ts +11 -0
  101. package/dist/litellm/mcp-server-url.d.ts.map +1 -0
  102. package/dist/litellm/mcp-server.d.ts +95 -0
  103. package/dist/litellm/mcp-server.d.ts.map +1 -0
  104. package/dist/litellm/model-claim.d.ts +24 -0
  105. package/dist/litellm/model-claim.d.ts.map +1 -0
  106. package/dist/litellm/model-credential.d.ts +12 -0
  107. package/dist/litellm/model-credential.d.ts.map +1 -0
  108. package/dist/litellm/model-errors.d.ts +119 -0
  109. package/dist/litellm/model-errors.d.ts.map +1 -0
  110. package/dist/litellm/model-form.d.ts +78 -0
  111. package/dist/litellm/model-form.d.ts.map +1 -0
  112. package/dist/litellm/model-locate.d.ts +13 -0
  113. package/dist/litellm/model-locate.d.ts.map +1 -0
  114. package/dist/litellm/model-operations.d.ts +59 -0
  115. package/dist/litellm/model-operations.d.ts.map +1 -0
  116. package/dist/litellm/model-types.d.ts +91 -0
  117. package/dist/litellm/model-types.d.ts.map +1 -0
  118. package/dist/litellm/model.d.ts +88 -0
  119. package/dist/litellm/model.d.ts.map +1 -0
  120. package/dist/litellm/operations.d.ts +22 -0
  121. package/dist/litellm/operations.d.ts.map +1 -1
  122. package/dist/litellm/policy-attachment-form.d.ts +19 -0
  123. package/dist/litellm/policy-attachment-form.d.ts.map +1 -0
  124. package/dist/litellm/policy-attachment-operations.d.ts +31 -0
  125. package/dist/litellm/policy-attachment-operations.d.ts.map +1 -0
  126. package/dist/litellm/policy-attachment-types.d.ts +48 -0
  127. package/dist/litellm/policy-attachment-types.d.ts.map +1 -0
  128. package/dist/litellm/policy-attachment.d.ts +61 -0
  129. package/dist/litellm/policy-attachment.d.ts.map +1 -0
  130. package/dist/litellm/policy-form.d.ts +22 -0
  131. package/dist/litellm/policy-form.d.ts.map +1 -0
  132. package/dist/litellm/policy-operations.d.ts +42 -0
  133. package/dist/litellm/policy-operations.d.ts.map +1 -0
  134. package/dist/litellm/policy-types.d.ts +57 -0
  135. package/dist/litellm/policy-types.d.ts.map +1 -0
  136. package/dist/litellm/policy.d.ts +65 -0
  137. package/dist/litellm/policy.d.ts.map +1 -0
  138. package/dist/litellm/providers.d.ts +1 -1
  139. package/dist/litellm/providers.d.ts.map +1 -1
  140. package/dist/litellm/registry-errors.d.ts +62 -0
  141. package/dist/litellm/registry-errors.d.ts.map +1 -0
  142. package/dist/litellm/registry-support.d.ts +42 -0
  143. package/dist/litellm/registry-support.d.ts.map +1 -0
  144. package/dist/litellm/team-form.d.ts +26 -0
  145. package/dist/litellm/team-form.d.ts.map +1 -0
  146. package/dist/litellm/team-members.d.ts +10 -0
  147. package/dist/litellm/team-members.d.ts.map +1 -0
  148. package/dist/litellm/team-operations.d.ts +38 -0
  149. package/dist/litellm/team-operations.d.ts.map +1 -0
  150. package/dist/litellm/team-permission.d.ts +35 -0
  151. package/dist/litellm/team-permission.d.ts.map +1 -0
  152. package/dist/litellm/team-types.d.ts +101 -0
  153. package/dist/litellm/team-types.d.ts.map +1 -0
  154. package/dist/litellm/team.d.ts +67 -0
  155. package/dist/litellm/team.d.ts.map +1 -0
  156. package/dist/litellm/tool-policy-form.d.ts +21 -0
  157. package/dist/litellm/tool-policy-form.d.ts.map +1 -0
  158. package/dist/litellm/tool-policy-operations.d.ts +30 -0
  159. package/dist/litellm/tool-policy-operations.d.ts.map +1 -0
  160. package/dist/litellm/tool-policy-types.d.ts +46 -0
  161. package/dist/litellm/tool-policy-types.d.ts.map +1 -0
  162. package/dist/litellm/tool-policy.d.ts +62 -0
  163. package/dist/litellm/tool-policy.d.ts.map +1 -0
  164. package/dist/litellm/toolset-form.d.ts +20 -0
  165. package/dist/litellm/toolset-form.d.ts.map +1 -0
  166. package/dist/litellm/toolset-operations.d.ts +39 -0
  167. package/dist/litellm/toolset-operations.d.ts.map +1 -0
  168. package/dist/litellm/toolset-types.d.ts +46 -0
  169. package/dist/litellm/toolset-types.d.ts.map +1 -0
  170. package/dist/litellm/toolset.d.ts +55 -0
  171. package/dist/litellm/toolset.d.ts.map +1 -0
  172. package/dist/openbao/auth-role-form.d.ts +9 -0
  173. package/dist/openbao/auth-role-form.d.ts.map +1 -1
  174. package/dist/openbao/auth-role-wire.d.ts.map +1 -1
  175. package/dist/openbao/fake-engines-roles.d.ts.map +1 -1
  176. package/dist/openbao/index.js +43 -6
  177. package/dist/openbao/index.js.map +5 -5
  178. package/dist/ownership/rows.d.ts +11 -0
  179. package/dist/ownership/rows.d.ts.map +1 -1
  180. package/dist/postgres/connection.d.ts +32 -2
  181. package/dist/postgres/connection.d.ts.map +1 -1
  182. package/dist/postgres/database-sql.d.ts +28 -9
  183. package/dist/postgres/database-sql.d.ts.map +1 -1
  184. package/dist/postgres/database.d.ts +1 -1
  185. package/dist/postgres/database.d.ts.map +1 -1
  186. package/dist/postgres/fake-grants-parse.d.ts +37 -0
  187. package/dist/postgres/fake-grants-parse.d.ts.map +1 -0
  188. package/dist/postgres/fake-grants-read.d.ts +61 -0
  189. package/dist/postgres/fake-grants-read.d.ts.map +1 -0
  190. package/dist/postgres/fake-grants-sql.d.ts +46 -0
  191. package/dist/postgres/fake-grants-sql.d.ts.map +1 -0
  192. package/dist/postgres/fake-grants-write.d.ts +29 -0
  193. package/dist/postgres/fake-grants-write.d.ts.map +1 -0
  194. package/dist/postgres/fake-role-sql.d.ts +40 -0
  195. package/dist/postgres/fake-role-sql.d.ts.map +1 -0
  196. package/dist/postgres/fake-schema-sql.d.ts +42 -0
  197. package/dist/postgres/fake-schema-sql.d.ts.map +1 -0
  198. package/dist/postgres/fake-sql-parse.d.ts +23 -0
  199. package/dist/postgres/fake-sql-parse.d.ts.map +1 -0
  200. package/dist/postgres/fake-sql-quote.d.ts +12 -0
  201. package/dist/postgres/fake-sql-quote.d.ts.map +1 -0
  202. package/dist/postgres/fake-sql.d.ts +42 -0
  203. package/dist/postgres/fake-sql.d.ts.map +1 -1
  204. package/dist/postgres/grants-attrs.d.ts +115 -0
  205. package/dist/postgres/grants-attrs.d.ts.map +1 -0
  206. package/dist/postgres/grants-declare.d.ts +88 -0
  207. package/dist/postgres/grants-declare.d.ts.map +1 -0
  208. package/dist/postgres/grants-diff.d.ts +25 -0
  209. package/dist/postgres/grants-diff.d.ts.map +1 -0
  210. package/dist/postgres/grants-errors.d.ts +137 -0
  211. package/dist/postgres/grants-errors.d.ts.map +1 -0
  212. package/dist/postgres/grants-existence.d.ts +14 -0
  213. package/dist/postgres/grants-existence.d.ts.map +1 -0
  214. package/dist/postgres/grants-ops.d.ts +65 -0
  215. package/dist/postgres/grants-ops.d.ts.map +1 -0
  216. package/dist/postgres/grants-ownership.d.ts +18 -0
  217. package/dist/postgres/grants-ownership.d.ts.map +1 -0
  218. package/dist/postgres/grants-plan-restore.d.ts +22 -0
  219. package/dist/postgres/grants-plan-restore.d.ts.map +1 -0
  220. package/dist/postgres/grants-plan.d.ts +65 -0
  221. package/dist/postgres/grants-plan.d.ts.map +1 -0
  222. package/dist/postgres/grants-read-defaults.d.ts +17 -0
  223. package/dist/postgres/grants-read-defaults.d.ts.map +1 -0
  224. package/dist/postgres/grants-read.d.ts +77 -0
  225. package/dist/postgres/grants-read.d.ts.map +1 -0
  226. package/dist/postgres/grants-refuse.d.ts +25 -0
  227. package/dist/postgres/grants-refuse.d.ts.map +1 -0
  228. package/dist/postgres/grants-sql.d.ts +42 -0
  229. package/dist/postgres/grants-sql.d.ts.map +1 -0
  230. package/dist/postgres/grants-words.d.ts +29 -0
  231. package/dist/postgres/grants-words.d.ts.map +1 -0
  232. package/dist/postgres/grants.d.ts +37 -0
  233. package/dist/postgres/grants.d.ts.map +1 -0
  234. package/dist/postgres/index.d.ts +35 -8
  235. package/dist/postgres/index.d.ts.map +1 -1
  236. package/dist/postgres/index.js +2063 -39
  237. package/dist/postgres/index.js.map +47 -7
  238. package/dist/postgres/installed-classifier.d.ts +13 -0
  239. package/dist/postgres/installed-classifier.d.ts.map +1 -0
  240. package/dist/postgres/providers.d.ts +17 -7
  241. package/dist/postgres/providers.d.ts.map +1 -1
  242. package/dist/postgres/psql-executor.d.ts +25 -0
  243. package/dist/postgres/psql-executor.d.ts.map +1 -0
  244. package/dist/postgres/role-attrs.d.ts +109 -0
  245. package/dist/postgres/role-attrs.d.ts.map +1 -0
  246. package/dist/postgres/role-diff.d.ts +22 -0
  247. package/dist/postgres/role-diff.d.ts.map +1 -0
  248. package/dist/postgres/role-errors.d.ts +126 -0
  249. package/dist/postgres/role-errors.d.ts.map +1 -0
  250. package/dist/postgres/role-membership-sql.d.ts +75 -0
  251. package/dist/postgres/role-membership-sql.d.ts.map +1 -0
  252. package/dist/postgres/role-provider.d.ts +11 -0
  253. package/dist/postgres/role-provider.d.ts.map +1 -0
  254. package/dist/postgres/role-scram.d.ts +6 -0
  255. package/dist/postgres/role-scram.d.ts.map +1 -0
  256. package/dist/postgres/role-secrets.d.ts +30 -0
  257. package/dist/postgres/role-secrets.d.ts.map +1 -0
  258. package/dist/postgres/role-sql.d.ts +68 -0
  259. package/dist/postgres/role-sql.d.ts.map +1 -0
  260. package/dist/postgres/role.d.ts +57 -0
  261. package/dist/postgres/role.d.ts.map +1 -0
  262. package/dist/postgres/schema-assert.d.ts +50 -0
  263. package/dist/postgres/schema-assert.d.ts.map +1 -0
  264. package/dist/postgres/schema-attrs.d.ts +51 -0
  265. package/dist/postgres/schema-attrs.d.ts.map +1 -0
  266. package/dist/postgres/schema-delete.d.ts +28 -0
  267. package/dist/postgres/schema-delete.d.ts.map +1 -0
  268. package/dist/postgres/schema-diff.d.ts +14 -0
  269. package/dist/postgres/schema-diff.d.ts.map +1 -0
  270. package/dist/postgres/schema-errors.d.ts +139 -0
  271. package/dist/postgres/schema-errors.d.ts.map +1 -0
  272. package/dist/postgres/schema-identity.d.ts +8 -0
  273. package/dist/postgres/schema-identity.d.ts.map +1 -0
  274. package/dist/postgres/schema-reconcile.d.ts +12 -0
  275. package/dist/postgres/schema-reconcile.d.ts.map +1 -0
  276. package/dist/postgres/schema-sql.d.ts +45 -0
  277. package/dist/postgres/schema-sql.d.ts.map +1 -0
  278. package/dist/postgres/schema-test-kit.d.ts +67 -0
  279. package/dist/postgres/schema-test-kit.d.ts.map +1 -0
  280. package/dist/postgres/schema.d.ts +54 -0
  281. package/dist/postgres/schema.d.ts.map +1 -0
  282. package/dist/proxmox/ceph-flag-types.d.ts +57 -0
  283. package/dist/proxmox/ceph-flag-types.d.ts.map +1 -0
  284. package/dist/proxmox/ceph-flag-wire.d.ts +77 -0
  285. package/dist/proxmox/ceph-flag-wire.d.ts.map +1 -0
  286. package/dist/proxmox/ceph-flag.d.ts +15 -50
  287. package/dist/proxmox/ceph-flag.d.ts.map +1 -1
  288. package/dist/proxmox/ceph-osd-write.d.ts +10 -13
  289. package/dist/proxmox/ceph-osd-write.d.ts.map +1 -1
  290. package/dist/proxmox/index.js +806 -740
  291. package/dist/proxmox/index.js.map +9 -8
  292. package/dist/release/fake-engine.d.ts +10 -0
  293. package/dist/release/fake-engine.d.ts.map +1 -1
  294. package/dist/release/index.js +35 -1
  295. package/dist/release/index.js.map +3 -3
  296. package/dist/valkey/acl-attrs.d.ts +94 -0
  297. package/dist/valkey/acl-attrs.d.ts.map +1 -0
  298. package/dist/valkey/acl-compare.d.ts +28 -0
  299. package/dist/valkey/acl-compare.d.ts.map +1 -0
  300. package/dist/valkey/acl-connection.d.ts +6 -0
  301. package/dist/valkey/acl-connection.d.ts.map +1 -0
  302. package/dist/valkey/acl-form.d.ts +62 -0
  303. package/dist/valkey/acl-form.d.ts.map +1 -0
  304. package/dist/valkey/acl-managed.d.ts +4 -0
  305. package/dist/valkey/acl-managed.d.ts.map +1 -0
  306. package/dist/valkey/acl-ops.d.ts +37 -0
  307. package/dist/valkey/acl-ops.d.ts.map +1 -0
  308. package/dist/valkey/acl-profiles.d.ts +53 -0
  309. package/dist/valkey/acl-profiles.d.ts.map +1 -0
  310. package/dist/valkey/acl-reconcile.d.ts +26 -0
  311. package/dist/valkey/acl-reconcile.d.ts.map +1 -0
  312. package/dist/valkey/acl.d.ts +24 -0
  313. package/dist/valkey/acl.d.ts.map +1 -0
  314. package/dist/valkey/connection-service.d.ts +22 -0
  315. package/dist/valkey/connection-service.d.ts.map +1 -0
  316. package/dist/valkey/connection.d.ts +59 -0
  317. package/dist/valkey/connection.d.ts.map +1 -0
  318. package/dist/valkey/errors.d.ts +165 -0
  319. package/dist/valkey/errors.d.ts.map +1 -0
  320. package/dist/valkey/fake-acl.d.ts +29 -0
  321. package/dist/valkey/fake-acl.d.ts.map +1 -0
  322. package/dist/valkey/fake-valkey.d.ts +35 -0
  323. package/dist/valkey/fake-valkey.d.ts.map +1 -0
  324. package/dist/valkey/handler-test-fixture.d.ts +20 -0
  325. package/dist/valkey/handler-test-fixture.d.ts.map +1 -0
  326. package/dist/valkey/index.d.ts +18 -0
  327. package/dist/valkey/index.d.ts.map +1 -0
  328. package/dist/valkey/index.js +964 -0
  329. package/dist/valkey/index.js.map +27 -0
  330. package/dist/valkey/instance-attrs.d.ts +46 -0
  331. package/dist/valkey/instance-attrs.d.ts.map +1 -0
  332. package/dist/valkey/instance-form.d.ts +22 -0
  333. package/dist/valkey/instance-form.d.ts.map +1 -0
  334. package/dist/valkey/instance.d.ts +48 -0
  335. package/dist/valkey/instance.d.ts.map +1 -0
  336. package/dist/valkey/provider-socket-fixture.d.ts +8 -0
  337. package/dist/valkey/provider-socket-fixture.d.ts.map +1 -0
  338. package/dist/valkey/providers.d.ts +16 -0
  339. package/dist/valkey/providers.d.ts.map +1 -0
  340. package/dist/valkey/resp.d.ts +38 -0
  341. package/dist/valkey/resp.d.ts.map +1 -0
  342. package/dist/valkey/transport-error.d.ts +36 -0
  343. package/dist/valkey/transport-error.d.ts.map +1 -0
  344. package/dist/valkey/transport.d.ts +50 -0
  345. package/dist/valkey/transport.d.ts.map +1 -0
  346. package/docs/litellm-access-group.md +105 -0
  347. package/docs/litellm-budget.md +55 -0
  348. package/docs/litellm-credential.md +60 -0
  349. package/docs/litellm-key-metadata.md +56 -0
  350. package/docs/litellm-key.md +194 -0
  351. package/docs/litellm-mcp.md +187 -0
  352. package/docs/litellm-model.md +111 -0
  353. package/docs/litellm-policy-attachment.md +86 -0
  354. package/docs/litellm-policy.md +103 -0
  355. package/docs/litellm-team.md +117 -0
  356. package/docs/litellm-tool-policy.md +90 -0
  357. package/docs/litellm-toolset.md +92 -0
  358. package/docs/litellm.md +16 -8
  359. package/docs/peers.md +15 -6
  360. package/docs/postgres-grants-example.md +55 -0
  361. package/docs/postgres-grants.md +157 -0
  362. package/docs/postgres-role.md +114 -0
  363. package/docs/postgres-schema.md +139 -0
  364. package/docs/postgres.md +39 -0
  365. package/docs/proxmox-sdk-migration.md +45 -0
  366. package/docs/valkey-transport.md +29 -0
  367. package/docs/valkey.md +187 -0
  368. package/package.json +7 -3
  369. package/src/litellm/access-group-form.ts +105 -0
  370. package/src/litellm/access-group-operations.ts +92 -0
  371. package/src/litellm/access-group-types.ts +49 -0
  372. package/src/litellm/access-group.test.ts +197 -0
  373. package/src/litellm/access-group.ts +151 -0
  374. package/src/litellm/budget-errors.ts +38 -0
  375. package/src/litellm/budget-form.ts +94 -0
  376. package/src/litellm/budget-operations.ts +51 -0
  377. package/src/litellm/budget.test.ts +105 -0
  378. package/src/litellm/budget.ts +127 -0
  379. package/src/litellm/credential-errors.ts +183 -0
  380. package/src/litellm/credential-form.test.ts +151 -0
  381. package/src/litellm/credential-form.ts +211 -0
  382. package/src/litellm/credential-guards.test.ts +241 -0
  383. package/src/litellm/credential-operations.ts +208 -0
  384. package/src/litellm/credential-recovery.test.ts +93 -0
  385. package/src/litellm/credential-rewrite.test.ts +164 -0
  386. package/src/litellm/credential-rewrite.ts +50 -0
  387. package/src/litellm/credential-types.ts +117 -0
  388. package/src/litellm/credential-values.ts +94 -0
  389. package/src/litellm/credential.test.ts +218 -0
  390. package/src/litellm/credential.ts +227 -0
  391. package/src/litellm/fake-access-group-litellm.ts +127 -0
  392. package/src/litellm/fake-credential-litellm.ts +216 -0
  393. package/src/litellm/fake-keys.ts +190 -0
  394. package/src/litellm/fake-litellm.ts +66 -7
  395. package/src/litellm/fake-mcp-litellm.ts +214 -0
  396. package/src/litellm/fake-model-litellm-post-update.ts +103 -0
  397. package/src/litellm/fake-model-litellm.ts +233 -0
  398. package/src/litellm/fake-policy-attachment-litellm.ts +97 -0
  399. package/src/litellm/fake-policy-litellm.ts +186 -0
  400. package/src/litellm/fake-registry-base.ts +69 -0
  401. package/src/litellm/fake-stack.ts +17 -1
  402. package/src/litellm/fake-team-litellm.ts +229 -0
  403. package/src/litellm/fake-tool-litellm.ts +88 -0
  404. package/src/litellm/fake-toolset-litellm.ts +110 -0
  405. package/src/litellm/index.ts +153 -0
  406. package/src/litellm/key-delete.test.ts +212 -0
  407. package/src/litellm/key-errors.ts +241 -0
  408. package/src/litellm/key-form.ts +200 -0
  409. package/src/litellm/key-harness.ts +121 -0
  410. package/src/litellm/key-metadata-errors.ts +49 -0
  411. package/src/litellm/key-metadata.test.ts +156 -0
  412. package/src/litellm/key-metadata.ts +74 -0
  413. package/src/litellm/key-operations.ts +184 -0
  414. package/src/litellm/key-rotation.test.ts +110 -0
  415. package/src/litellm/key-scope.test.ts +135 -0
  416. package/src/litellm/key-secret.test.ts +248 -0
  417. package/src/litellm/key-secret.ts +137 -0
  418. package/src/litellm/key-transport.test.ts +166 -0
  419. package/src/litellm/key.test.ts +231 -0
  420. package/src/litellm/key.ts +213 -0
  421. package/src/litellm/mcp-server-adopt.test.ts +86 -0
  422. package/src/litellm/mcp-server-alias.test.ts +184 -0
  423. package/src/litellm/mcp-server-credential.ts +85 -0
  424. package/src/litellm/mcp-server-errors.ts +141 -0
  425. package/src/litellm/mcp-server-exports.test.ts +15 -0
  426. package/src/litellm/mcp-server-form.test.ts +241 -0
  427. package/src/litellm/mcp-server-form.ts +233 -0
  428. package/src/litellm/mcp-server-handlers.test.ts +150 -0
  429. package/src/litellm/mcp-server-locate.ts +66 -0
  430. package/src/litellm/mcp-server-operations.ts +111 -0
  431. package/src/litellm/mcp-server-registry.test.ts +146 -0
  432. package/src/litellm/mcp-server-retype.test.ts +114 -0
  433. package/src/litellm/mcp-server-shadow.test.ts +91 -0
  434. package/src/litellm/mcp-server-shadow.ts +45 -0
  435. package/src/litellm/mcp-server-tools.test.ts +85 -0
  436. package/src/litellm/mcp-server-types.ts +143 -0
  437. package/src/litellm/mcp-server-url.ts +66 -0
  438. package/src/litellm/mcp-server.test.ts +213 -0
  439. package/src/litellm/mcp-server.ts +225 -0
  440. package/src/litellm/model-claim.ts +69 -0
  441. package/src/litellm/model-credential.ts +45 -0
  442. package/src/litellm/model-errors.ts +168 -0
  443. package/src/litellm/model-foreign-row.test.ts +173 -0
  444. package/src/litellm/model-form.test.ts +228 -0
  445. package/src/litellm/model-form.ts +223 -0
  446. package/src/litellm/model-locate.test.ts +128 -0
  447. package/src/litellm/model-locate.ts +67 -0
  448. package/src/litellm/model-operations.test.ts +93 -0
  449. package/src/litellm/model-operations.ts +146 -0
  450. package/src/litellm/model-params-preserve.test.ts +119 -0
  451. package/src/litellm/model-recovery.test.ts +57 -0
  452. package/src/litellm/model-types.ts +112 -0
  453. package/src/litellm/model.test.ts +222 -0
  454. package/src/litellm/model.ts +237 -0
  455. package/src/litellm/operations.ts +1 -1
  456. package/src/litellm/policy-attachment-form.ts +103 -0
  457. package/src/litellm/policy-attachment-operations.ts +74 -0
  458. package/src/litellm/policy-attachment-types.ts +48 -0
  459. package/src/litellm/policy-attachment.test.ts +198 -0
  460. package/src/litellm/policy-attachment.ts +178 -0
  461. package/src/litellm/policy-form.ts +122 -0
  462. package/src/litellm/policy-operations.ts +112 -0
  463. package/src/litellm/policy-types.ts +58 -0
  464. package/src/litellm/policy.test.ts +214 -0
  465. package/src/litellm/policy.ts +146 -0
  466. package/src/litellm/providers.ts +25 -1
  467. package/src/litellm/registry-errors.ts +88 -0
  468. package/src/litellm/registry-exports.test.ts +66 -0
  469. package/src/litellm/registry-support.ts +109 -0
  470. package/src/litellm/team-form.ts +140 -0
  471. package/src/litellm/team-members.test.ts +150 -0
  472. package/src/litellm/team-members.ts +58 -0
  473. package/src/litellm/team-operations.ts +90 -0
  474. package/src/litellm/team-permission.ts +159 -0
  475. package/src/litellm/team-read.test.ts +89 -0
  476. package/src/litellm/team-types.ts +106 -0
  477. package/src/litellm/team.test.ts +206 -0
  478. package/src/litellm/team.ts +159 -0
  479. package/src/litellm/tool-policy-form.ts +94 -0
  480. package/src/litellm/tool-policy-operations.ts +58 -0
  481. package/src/litellm/tool-policy-types.ts +48 -0
  482. package/src/litellm/tool-policy.test.ts +172 -0
  483. package/src/litellm/tool-policy.ts +125 -0
  484. package/src/litellm/toolset-form.ts +104 -0
  485. package/src/litellm/toolset-operations.ts +90 -0
  486. package/src/litellm/toolset-types.ts +47 -0
  487. package/src/litellm/toolset.test.ts +198 -0
  488. package/src/litellm/toolset.ts +151 -0
  489. package/src/openbao/auth-role-form.test.ts +37 -0
  490. package/src/openbao/auth-role-form.ts +12 -1
  491. package/src/openbao/auth-role-wire.test.ts +1 -0
  492. package/src/openbao/auth-role-wire.ts +13 -1
  493. package/src/openbao/distilled-retry.test.ts +1 -0
  494. package/src/openbao/fake-engines-roles.ts +7 -1
  495. package/src/ownership/ownership.test.ts +33 -1
  496. package/src/ownership/rows.ts +53 -0
  497. package/src/postgres/connection.ts +72 -3
  498. package/src/postgres/database-bigint-serialization.test.ts +1 -0
  499. package/src/postgres/database-refusals.test.ts +2 -2
  500. package/src/postgres/database-sql.ts +40 -12
  501. package/src/postgres/database.ts +3 -2
  502. package/src/postgres/fake-grants-parse.ts +189 -0
  503. package/src/postgres/fake-grants-read.ts +250 -0
  504. package/src/postgres/fake-grants-sql.ts +207 -0
  505. package/src/postgres/fake-grants-write.ts +90 -0
  506. package/src/postgres/fake-role-sql.ts +220 -0
  507. package/src/postgres/fake-schema-semantics.test.ts +36 -0
  508. package/src/postgres/fake-schema-sql.ts +146 -0
  509. package/src/postgres/fake-sql-parse.ts +86 -0
  510. package/src/postgres/fake-sql-quote.ts +36 -0
  511. package/src/postgres/fake-sql.ts +161 -46
  512. package/src/postgres/fixtures/pg-REL_18_6-acl.h.txt +147 -0
  513. package/src/postgres/fixtures/pg-REL_18_6-aclexplode-func.txt +31 -0
  514. package/src/postgres/fixtures/pg-REL_18_6-alter-default-privileges-synopsis.txt +82 -0
  515. package/src/postgres/fixtures/pg-REL_18_6-alter_role.sgml.txt +44 -0
  516. package/src/postgres/fixtures/pg-REL_18_6-create_role.sgml.txt +26 -0
  517. package/src/postgres/fixtures/pg-REL_18_6-grant-synopsis.txt +95 -0
  518. package/src/postgres/fixtures/pg-REL_18_6-pg_attribute.h.txt +24 -0
  519. package/src/postgres/fixtures/pg-REL_18_6-pg_auth_members.h.txt +62 -0
  520. package/src/postgres/fixtures/pg-REL_18_6-pg_authid.h.txt +70 -0
  521. package/src/postgres/fixtures/pg-REL_18_6-pg_class.h.txt +33 -0
  522. package/src/postgres/fixtures/pg-REL_18_6-pg_default_acl.h.txt +81 -0
  523. package/src/postgres/fixtures/pg-REL_18_6-pg_namespace.h.txt +28 -0
  524. package/src/postgres/fixtures/pg-REL_18_6-revoke-synopsis.txt +124 -0
  525. package/src/postgres/grants-acl.test.ts +61 -0
  526. package/src/postgres/grants-attrs.ts +185 -0
  527. package/src/postgres/grants-database.test.ts +158 -0
  528. package/src/postgres/grants-declare.ts +172 -0
  529. package/src/postgres/grants-delete-proof.test.ts +154 -0
  530. package/src/postgres/grants-diff.ts +101 -0
  531. package/src/postgres/grants-errors.ts +215 -0
  532. package/src/postgres/grants-existence-guards.test.ts +113 -0
  533. package/src/postgres/grants-existence.ts +101 -0
  534. package/src/postgres/grants-lifecycle-guards.test.ts +208 -0
  535. package/src/postgres/grants-lifecycle-repair.test.ts +208 -0
  536. package/src/postgres/grants-lifecycle.test.ts +181 -0
  537. package/src/postgres/grants-ops.ts +229 -0
  538. package/src/postgres/grants-owner-revoke.test.ts +121 -0
  539. package/src/postgres/grants-ownership.ts +49 -0
  540. package/src/postgres/grants-plan-collateral.test.ts +202 -0
  541. package/src/postgres/grants-plan-diff.test.ts +204 -0
  542. package/src/postgres/grants-plan-restore.ts +43 -0
  543. package/src/postgres/grants-plan-revocations.test.ts +69 -0
  544. package/src/postgres/grants-plan.test.ts +148 -0
  545. package/src/postgres/grants-plan.ts +245 -0
  546. package/src/postgres/grants-provenance.test.ts +134 -0
  547. package/src/postgres/grants-psql-lifecycle.test.ts +105 -0
  548. package/src/postgres/grants-read-absent.test.ts +91 -0
  549. package/src/postgres/grants-read-defaults.ts +51 -0
  550. package/src/postgres/grants-read.ts +250 -0
  551. package/src/postgres/grants-refusals.test.ts +136 -0
  552. package/src/postgres/grants-refuse.ts +119 -0
  553. package/src/postgres/grants-relkind-wire.test.ts +111 -0
  554. package/src/postgres/grants-repair-plan.test.ts +201 -0
  555. package/src/postgres/grants-sql.test.ts +128 -0
  556. package/src/postgres/grants-sql.ts +144 -0
  557. package/src/postgres/grants-words.ts +34 -0
  558. package/src/postgres/grants.ts +110 -0
  559. package/src/postgres/index.ts +137 -7
  560. package/src/postgres/installed-classifier.ts +36 -0
  561. package/src/postgres/providers.ts +44 -7
  562. package/src/postgres/psql-executor-escaping.test.ts +67 -0
  563. package/src/postgres/psql-executor.test.ts +167 -0
  564. package/src/postgres/psql-executor.ts +170 -0
  565. package/src/postgres/role-adopt.test.ts +98 -0
  566. package/src/postgres/role-attrs.ts +134 -0
  567. package/src/postgres/role-diff.ts +89 -0
  568. package/src/postgres/role-errors.ts +198 -0
  569. package/src/postgres/role-guard.test.ts +60 -0
  570. package/src/postgres/role-identity.test.ts +185 -0
  571. package/src/postgres/role-lifecycle.test.ts +228 -0
  572. package/src/postgres/role-membership-sql.ts +198 -0
  573. package/src/postgres/role-password.test.ts +158 -0
  574. package/src/postgres/role-privilege.test.ts +80 -0
  575. package/src/postgres/role-provenance.test.ts +200 -0
  576. package/src/postgres/role-provider.ts +104 -0
  577. package/src/postgres/role-refusals.test.ts +250 -0
  578. package/src/postgres/role-scram.test.ts +38 -0
  579. package/src/postgres/role-scram.ts +38 -0
  580. package/src/postgres/role-secrets.ts +46 -0
  581. package/src/postgres/role-sql.ts +211 -0
  582. package/src/postgres/role-valid-until.test.ts +68 -0
  583. package/src/postgres/role.ts +218 -0
  584. package/src/postgres/schema-assert.ts +139 -0
  585. package/src/postgres/schema-attrs.ts +71 -0
  586. package/src/postgres/schema-delete-proofs.test.ts +192 -0
  587. package/src/postgres/schema-delete.ts +96 -0
  588. package/src/postgres/schema-diff.ts +44 -0
  589. package/src/postgres/schema-drop-2bp01.test.ts +146 -0
  590. package/src/postgres/schema-errors.ts +209 -0
  591. package/src/postgres/schema-handlers.test.ts +193 -0
  592. package/src/postgres/schema-identity.ts +39 -0
  593. package/src/postgres/schema-lifecycle.test.ts +246 -0
  594. package/src/postgres/schema-race.test.ts +70 -0
  595. package/src/postgres/schema-reconcile.ts +100 -0
  596. package/src/postgres/schema-refusals.test.ts +144 -0
  597. package/src/postgres/schema-socket.test.ts +161 -0
  598. package/src/postgres/schema-sql.ts +130 -0
  599. package/src/postgres/schema-takeover.test.ts +149 -0
  600. package/src/postgres/schema-test-kit.ts +85 -0
  601. package/src/postgres/schema.ts +130 -0
  602. package/src/proxmox/ceph-flag-types.ts +70 -0
  603. package/src/proxmox/ceph-flag-wire.test.ts +72 -0
  604. package/src/proxmox/ceph-flag-wire.ts +123 -0
  605. package/src/proxmox/ceph-flag.ts +77 -130
  606. package/src/proxmox/ceph-osd-write.ts +10 -13
  607. package/src/release/binary-alias.test.ts +3 -3
  608. package/src/release/binary-claims.test.ts +3 -3
  609. package/src/release/binary-directory-umask.test.ts +65 -0
  610. package/src/release/fake-engine.ts +15 -0
  611. package/src/valkey/acl-attrs.ts +98 -0
  612. package/src/valkey/acl-compare.ts +57 -0
  613. package/src/valkey/acl-connection.ts +13 -0
  614. package/src/valkey/acl-delete.test.ts +127 -0
  615. package/src/valkey/acl-form.ts +239 -0
  616. package/src/valkey/acl-managed.ts +13 -0
  617. package/src/valkey/acl-ops.ts +122 -0
  618. package/src/valkey/acl-ownership.test.ts +118 -0
  619. package/src/valkey/acl-prefix.test.ts +38 -0
  620. package/src/valkey/acl-profiles.ts +81 -0
  621. package/src/valkey/acl-reconcile.ts +180 -0
  622. package/src/valkey/acl-reserved.test.ts +69 -0
  623. package/src/valkey/acl-revocation.test.ts +94 -0
  624. package/src/valkey/acl-seat-prefix.test.ts +111 -0
  625. package/src/valkey/acl-validation.test.ts +54 -0
  626. package/src/valkey/acl.test.ts +215 -0
  627. package/src/valkey/acl.ts +169 -0
  628. package/src/valkey/connection-service.ts +46 -0
  629. package/src/valkey/connection.ts +180 -0
  630. package/src/valkey/errors.ts +239 -0
  631. package/src/valkey/fake-acl.ts +128 -0
  632. package/src/valkey/fake-valkey.ts +224 -0
  633. package/src/valkey/handler-test-fixture.ts +43 -0
  634. package/src/valkey/handlers.test.ts +205 -0
  635. package/src/valkey/index.ts +54 -0
  636. package/src/valkey/instance-attrs.ts +48 -0
  637. package/src/valkey/instance-form.ts +104 -0
  638. package/src/valkey/instance.test.ts +108 -0
  639. package/src/valkey/instance.ts +160 -0
  640. package/src/valkey/provider-socket-fixture.ts +71 -0
  641. package/src/valkey/providers.test.ts +129 -0
  642. package/src/valkey/providers.ts +21 -0
  643. package/src/valkey/resp.ts +212 -0
  644. package/src/valkey/transport-bounds.test.ts +150 -0
  645. package/src/valkey/transport-error.ts +37 -0
  646. package/src/valkey/transport.test.ts +158 -0
  647. package/src/valkey/transport.ts +109 -0
  648. package/src/valkey/upstream-bounds.test.ts +14 -0
@@ -1745,143 +1745,57 @@ var ProxmoxCephDaemonProvider = () => Provider4.effect(ProxmoxCephDaemon, Effect
1745
1745
  })));
1746
1746
  // src/proxmox/ceph-flag.ts
1747
1747
  import { Resource as Resource5 } from "alchemy";
1748
- import * as Provider5 from "alchemy/Provider";
1749
- import * as Effect16 from "effect/Effect";
1750
-
1751
- // src/proxmox/resource.ts
1752
1748
  import { isResolved as isResolved5 } from "alchemy/Diff";
1749
+ import * as Provider5 from "alchemy/Provider";
1753
1750
  import * as Effect15 from "effect/Effect";
1754
1751
 
1755
- // src/proxmox/client.ts
1752
+ // src/proxmox/ceph-flag-wire.ts
1753
+ import * as cluster3 from "@distilled.cloud/proxmox/cluster";
1756
1754
  import * as Effect14 from "effect/Effect";
1757
- import * as HttpClient5 from "effect/unstable/http/HttpClient";
1758
- import * as HttpClientRequest2 from "effect/unstable/http/HttpClientRequest";
1759
- class PveError extends Error {
1760
- status;
1761
- method;
1762
- path;
1763
- constructor(status, method, path, detail) {
1764
- super(`PVE ${method} ${path} -> ${String(status)}: ${detail}`);
1765
- this.status = status;
1766
- this.method = method;
1767
- this.path = path;
1768
- this.name = "PveError";
1769
- }
1770
- }
1771
- var clusterExhausted = (method, path, attempts) => new PveError(0, method, path, `all members failed: ${attempts.map((a) => `${a.member} (${a.why})`).join("; ")}`);
1772
- var encode = (form) => {
1773
- const params = new URLSearchParams;
1774
- for (const [key, value] of Object.entries(form)) {
1775
- if (typeof value === "string")
1776
- params.append(key, value);
1777
- else
1778
- for (const item of value)
1779
- params.append(key, item);
1780
- }
1781
- return params.toString();
1782
- };
1783
- var buildRequest = (method, apiBase, path, credential, target, form) => {
1784
- const url = `${apiBase}/${path}`;
1785
- return HttpClientRequest2.make(method)(url).pipe(HttpClientRequest2.setHeaders({ Authorization: authorization(credential, target) }), form === undefined ? (self) => self : HttpClientRequest2.bodyText(encode(form), "application/x-www-form-urlencoded"));
1786
- };
1787
- var executeOne = (target, credential, method, path, form, apiBase) => Effect14.gen(function* () {
1788
- const client = yield* HttpClient5.HttpClient;
1789
- const request = buildRequest(method, apiBase, path, credential, target, form);
1790
- return yield* client.execute(request).pipe(Effect14.mapError((cause) => new PveError(0, method, path, String(cause))));
1791
- });
1792
- var readResponse = (response, method, path) => Effect14.gen(function* () {
1793
- if (response.status < 200 || response.status >= 300) {
1794
- const detail = yield* response.text.pipe(Effect14.orElseSucceed(() => ""));
1795
- return yield* Effect14.fail(new PveError(response.status, method, path, detail.slice(0, 300)));
1796
- }
1797
- const body = yield* response.json.pipe(Effect14.mapError((cause) => new PveError(0, method, path, String(cause))));
1798
- return body.data;
1799
- });
1800
- var pveWith = (target, credential, method, path, form) => Effect14.gen(function* () {
1801
- const response = target.scheme === "pve" ? yield* executeOnCluster(target, method, path, (apiBase) => buildRequest(method, apiBase, path, credential, target, form)).pipe(Effect14.mapError((failure) => failure.tag === "cluster" ? clusterExhausted(failure.method, failure.path, failure.attempts) : new PveError(0, method, path, String(failure)))) : yield* executeOne(target, credential, method, path, form, target.api);
1802
- return yield* readResponse(response, method, path);
1803
- });
1804
- var pve = (target, role, method, path, form) => Effect14.gen(function* () {
1805
- const credential = yield* leased(target, role);
1806
- return yield* pveWith(target, credential, method, path, form);
1755
+ var CEPH_FLAG_UPDATE = "pve:PUT /cluster/ceph/flags/{flag}";
1756
+ var attributesOf3 = (live, props) => ({
1757
+ flag: props.flag,
1758
+ value: bool(live)
1807
1759
  });
1808
-
1809
- // src/proxmox/resource.ts
1810
- var pveOperations = (spec) => {
1811
- const { guardCreate: guardCreate2, guardUpdate: guardUpdate2 } = specGuards(spec);
1812
- const read = (props) => pve(props.target, spec.readRole ?? "read", "GET", spec.path(props)).pipe(Effect15.map((data) => data == null ? undefined : spec.attributes(data, props)), Effect15.orElseSucceed(() => {
1813
- return;
1814
- }));
1815
- return {
1816
- guardCreate: guardCreate2,
1817
- guardUpdate: guardUpdate2,
1818
- read,
1819
- diff: (news, output) => Effect15.gen(function* () {
1820
- if (!isResolved5(news))
1821
- return;
1822
- yield* guardCreate2(news, output === undefined);
1823
- yield* guardUpdate2(news);
1824
- if (output === undefined)
1825
- return;
1826
- const live = yield* read(news);
1827
- if (live === undefined) {
1828
- yield* guardCreate2(news, true);
1829
- return { action: "update" };
1830
- }
1831
- if (spec.matches(live, news))
1832
- return { action: "noop" };
1833
- return spec.updateForm === undefined ? { action: "replace" } : { action: "update" };
1834
- }),
1835
- reconcile: (news) => Effect15.gen(function* () {
1836
- const live = yield* read(news);
1837
- yield* guardCreate2(news, live === undefined);
1838
- yield* guardUpdate2(news);
1839
- if (live === undefined) {
1840
- yield* pve(news.target, "provision", "POST", spec.collection(news), spec.createForm(news));
1841
- } else if (spec.updateForm !== undefined) {
1842
- const form = formToSend(spec.matches, live, news, spec.updateForm(news));
1843
- if (form !== undefined) {
1844
- yield* pve(news.target, "provision", "PUT", spec.path(news), form);
1845
- }
1846
- }
1847
- const after = yield* read(news);
1848
- if (after === undefined) {
1849
- return yield* Effect15.die(new Error(`${spec.path(news)}: the write returned no error but the object is still absent. ` + 'PVE wraps every answer in {"data":...} and can report success on a call that did ' + "nothing -- read back rather than trusting the status code."));
1850
- }
1851
- return after;
1852
- }),
1853
- destroy: (olds) => pve(olds.target, "provision", "DELETE", spec.path(olds))
1854
- };
1855
- };
1856
- var pveHandlers = (spec) => {
1857
- const ops = pveOperations(spec);
1858
- return {
1859
- list: () => Effect15.succeed([]),
1860
- read: ({ olds }) => ops.read(olds),
1861
- diff: ({ news, output }) => ops.diff(news, output),
1862
- reconcile: ({ news }) => ops.reconcile(news),
1863
- delete: ({ olds }) => ops.destroy(olds)
1864
- };
1760
+ var scalarFlagOrDie = (live, props) => {
1761
+ const scalar = typeof live === "boolean" || live === 0 || live === 1 || live === "0" || live === "1";
1762
+ return scalar ? Effect14.succeed(live) : Effect14.die(new Error(`cluster/ceph/flags/${props.flag}: GET answered ${JSON.stringify(live)}, not a bare ` + "boolean. This endpoint's success is a scalar; an empty object is what the protocol " + 'substitutes for `{"data":null}`. Check `ceph osd dump | head -1` and the cluster ' + "log rather than trust a coerced `false`."));
1865
1763
  };
1764
+ var readClusterCephFlag = (props) => runPve(props.target, "read", false, cluster3.getClusterCephFlag({ flag: props.flag })).pipe(Effect14.flatMap((live) => scalarFlagOrDie(live, props)), Effect14.map((live) => attributesOf3(live, props)));
1765
+ var readClusterCephFlagForDiff = (props) => readOrUnreadable(readClusterCephFlag(props));
1766
+ var updateForm = (props) => ({ value: flag(props.value) ?? "0" });
1767
+ var writeClusterCephFlag = (props) => runPve(props.target, "provision", true, cluster3.putClusterCephFlag({ flag: props.flag, value: updateForm(props).value }));
1866
1768
 
1867
1769
  // src/proxmox/ceph-flag.ts
1868
1770
  var ProxmoxCephFlag = Resource5("Proxmox.CephFlag");
1869
- var handlers = pveHandlers({
1870
- attributes: (live, props) => ({ flag: props.flag, value: bool(live) }),
1871
- collection: () => "cluster/ceph/flags",
1872
- createForm: (props) => ({ [props.flag]: flag(props.value) ?? "0" }),
1873
- endpoint: { update: "pve:PUT /cluster/ceph/flags/{flag}" },
1874
- matches: (attributes, props) => attributes.value === props.value,
1875
- path: (props) => `cluster/ceph/flags/${props.flag}`,
1876
- updateForm: (props) => ({ value: flag(props.value) ?? "0" })
1877
- });
1878
- var ProxmoxCephFlagProvider = () => Provider5.effect(ProxmoxCephFlag, Effect16.succeed(ProxmoxCephFlag.Provider.of({
1879
- ...handlers,
1880
- delete: () => Effect16.void,
1881
- reconcile: Effect16.fn(function* ({ news }) {
1882
- const after = yield* handlers.reconcile({ news });
1771
+ var matches3 = (attributes, props) => attributes.value === props.value;
1772
+ var ProxmoxCephFlagProvider = () => Provider5.effect(ProxmoxCephFlag, Effect15.succeed(ProxmoxCephFlag.Provider.of({
1773
+ list: () => Effect15.succeed([]),
1774
+ read: ({ olds }) => readClusterCephFlag(olds),
1775
+ diff: Effect15.fn(function* ({ news, output }) {
1776
+ if (!isResolved5(news))
1777
+ return;
1778
+ yield* guardWrite2(CEPH_FLAG_UPDATE, updateForm(news), false);
1779
+ if (output === undefined)
1780
+ return;
1781
+ const live = yield* readClusterCephFlagForDiff(news);
1782
+ if (live === UNREADABLE) {
1783
+ yield* unreadableWarning("Proxmox.CephFlag", news.flag, news.target.mount, mintTier(news.target, "read"));
1784
+ return { action: "noop" };
1785
+ }
1786
+ return { action: matches3(live, news) ? "noop" : "update" };
1787
+ }),
1788
+ delete: () => Effect15.void,
1789
+ reconcile: Effect15.fn(function* ({ news }) {
1790
+ const live = yield* readClusterCephFlag(news);
1791
+ const form = formToSend(matches3, live, news, updateForm(news));
1792
+ if (form !== undefined) {
1793
+ yield* guardWrite2(CEPH_FLAG_UPDATE, updateForm(news), false);
1794
+ yield* writeClusterCephFlag(news);
1795
+ }
1796
+ const after = yield* readClusterCephFlag(news);
1883
1797
  if (after.value !== news.value) {
1884
- return yield* Effect16.die(new Error(`cluster/ceph/flags/${news.flag}: the PUT returned no error but ceph still ` + `reports the flag ${after.value ? "set" : "clear"} rather than ` + `${news.value ? "set" : "clear"}. This endpoint's success is documented as a ` + "null body, so the status code proves nothing -- check `ceph osd dump | " + "head -1` and the cluster log. `pause` in particular is two ceph flags read " + "as one; see the header."));
1798
+ return yield* Effect15.die(new Error(`cluster/ceph/flags/${news.flag}: the PUT returned no error but ceph still ` + `reports the flag ${after.value ? "set" : "clear"} rather than ` + `${news.value ? "set" : "clear"}. This endpoint's success is documented as a ` + "null body, so the status code proves nothing -- check `ceph osd dump | " + "head -1` and the cluster log. `pause` in particular is two ceph flags read " + "as one; see the header."));
1885
1799
  }
1886
1800
  return after;
1887
1801
  })
@@ -1890,11 +1804,11 @@ var ProxmoxCephFlagProvider = () => Provider5.effect(ProxmoxCephFlag, Effect16.s
1890
1804
  import { Resource as Resource6 } from "alchemy";
1891
1805
  import { isResolved as isResolved6 } from "alchemy/Diff";
1892
1806
  import * as Provider6 from "alchemy/Provider";
1893
- import * as Effect18 from "effect/Effect";
1807
+ import * as Effect17 from "effect/Effect";
1894
1808
 
1895
1809
  // src/proxmox/ceph-fs-distilled.ts
1896
1810
  import * as nodes2 from "@distilled.cloud/proxmox/nodes";
1897
- import * as Effect17 from "effect/Effect";
1811
+ import * as Effect16 from "effect/Effect";
1898
1812
 
1899
1813
  // src/proxmox/ceph-fs-wire.ts
1900
1814
  var readRow = (live, props) => {
@@ -1922,40 +1836,40 @@ var notCreated2 = (props) => new Error(`${objectPath(props)}: the create task fi
1922
1836
  var notDestroyed = (props) => new Error(`${objectPath(props)}: the destroy task finished but the filesystem is still in ` + `GET nodes/${props.node}/ceph/fs. PVE refuses to destroy a CephFS while a PVE storage entry ` + "of type cephfs still references it and is not disabled.");
1923
1837
 
1924
1838
  // src/proxmox/ceph-fs-distilled.ts
1925
- var readFs = (props) => runPve(props.target, "read", false, nodes2.listNodeCephFs({ node: props.node })).pipe(Effect17.map((rows) => readRow(rows, props)));
1839
+ var readFs = (props) => runPve(props.target, "read", false, nodes2.listNodeCephFs({ node: props.node })).pipe(Effect16.map((rows) => readRow(rows, props)));
1926
1840
  var toDistilledCreate = (props) => ({
1927
1841
  ...createForm2(props),
1928
1842
  name: props.name,
1929
1843
  node: props.node
1930
1844
  });
1931
- var settleTask = (props, upid) => Effect17.gen(function* () {
1845
+ var settleTask = (props, upid) => Effect16.gen(function* () {
1932
1846
  for (let attempt = 0;attempt < POLL_ATTEMPTS; attempt += 1) {
1933
- const status = yield* runPve(props.target, "read", false, nodes2.getNodeTaskStatus({ node: props.node, upid })).pipe(Effect17.orElseSucceed(() => {
1847
+ const status = yield* runPve(props.target, "read", false, nodes2.getNodeTaskStatus({ node: props.node, upid })).pipe(Effect16.orElseSucceed(() => {
1934
1848
  return;
1935
1849
  }));
1936
1850
  if (status?.status === "stopped") {
1937
1851
  if (status.exitstatus === "OK")
1938
1852
  return;
1939
- return yield* Effect17.die(new Error(`${objectPath(props)}: PVE task ${upid} finished with "${status.exitstatus ?? "no exit status"}". ` + "The write returned HTTP 200 because it only forked the worker -- the real error is " + `in \`pvesh get /nodes/${props.node}/tasks/${upid}/log\`.`));
1853
+ return yield* Effect16.die(new Error(`${objectPath(props)}: PVE task ${upid} finished with "${status.exitstatus ?? "no exit status"}". ` + "The write returned HTTP 200 because it only forked the worker -- the real error is " + `in \`pvesh get /nodes/${props.node}/tasks/${upid}/log\`.`));
1940
1854
  }
1941
- yield* Effect17.sleep(POLL_SECONDS * 1000);
1855
+ yield* Effect16.sleep(POLL_SECONDS * 1000);
1942
1856
  }
1943
- return yield* Effect17.die(new Error(`${objectPath(props)}: PVE task ${upid} was still running after ` + `${String(POLL_ATTEMPTS * POLL_SECONDS)}s, or its status could not be read. Check the ` + "task log, and check that the `read` role holds Sys.Audit on " + `/nodes/${props.node} -- each call mints a new token, so the poller is never the task ` + "owner and is answered 403 rather than told to wait."));
1857
+ return yield* Effect16.die(new Error(`${objectPath(props)}: PVE task ${upid} was still running after ` + `${String(POLL_ATTEMPTS * POLL_SECONDS)}s, or its status could not be read. Check the ` + "task log, and check that the `read` role holds Sys.Audit on " + `/nodes/${props.node} -- each call mints a new token, so the poller is never the task ` + "owner and is answered 403 rather than told to wait."));
1944
1858
  });
1945
- var createFs = (props) => Effect17.gen(function* () {
1859
+ var createFs = (props) => Effect16.gen(function* () {
1946
1860
  const upid = yield* runPve(props.target, "provision", true, nodes2.updateNodeCephFs(toDistilledCreate(props)));
1947
1861
  if (upid === "") {
1948
- return yield* Effect17.die(new Error(`${objectPath(props)}: POST returned no task id. PVE wraps every answer in ` + '{"data":...} and can report success on a call that did nothing.'));
1862
+ return yield* Effect16.die(new Error(`${objectPath(props)}: POST returned no task id. PVE wraps every answer in ` + '{"data":...} and can report success on a call that did nothing.'));
1949
1863
  }
1950
1864
  yield* settleTask(props, upid);
1951
1865
  });
1952
- var destroyFs = (props) => Effect17.gen(function* () {
1866
+ var destroyFs = (props) => Effect16.gen(function* () {
1953
1867
  const upid = yield* runPve(props.target, "provision", true, nodes2.deleteNodeCephFs({
1954
1868
  node: props.node,
1955
1869
  name: props.name,
1956
1870
  ...props["remove-pools"] === true ? { remove_pools: "1" } : {},
1957
1871
  ...props["remove-storages"] === true ? { remove_storages: "1" } : {}
1958
- })).pipe(Effect17.catchTag("CephFsNotFound", () => Effect17.succeed("")));
1872
+ })).pipe(Effect16.catchTag("CephFsNotFound", () => Effect16.succeed("")));
1959
1873
  if (upid !== "")
1960
1874
  yield* settleTask(props, upid);
1961
1875
  });
@@ -1964,12 +1878,12 @@ var destroyFs = (props) => Effect17.gen(function* () {
1964
1878
  var ProxmoxCephFs = Resource6("Proxmox.CephFs", {
1965
1879
  defaultRemovalPolicy: "retain"
1966
1880
  });
1967
- var ProxmoxCephFsProvider = () => Provider6.effect(ProxmoxCephFs, Effect18.succeed(ProxmoxCephFs.Provider.of({
1968
- list: () => Effect18.succeed([]),
1969
- read: Effect18.fn(function* ({ olds }) {
1881
+ var ProxmoxCephFsProvider = () => Provider6.effect(ProxmoxCephFs, Effect17.succeed(ProxmoxCephFs.Provider.of({
1882
+ list: () => Effect17.succeed([]),
1883
+ read: Effect17.fn(function* ({ olds }) {
1970
1884
  return yield* readFs(olds);
1971
1885
  }),
1972
- diff: Effect18.fn(function* ({ news, output }) {
1886
+ diff: Effect17.fn(function* ({ news, output }) {
1973
1887
  if (!isResolved6(news))
1974
1888
  return;
1975
1889
  yield* guardWrite2(CEPH_FS_CREATE, createForm2(news), output === undefined);
@@ -1985,34 +1899,34 @@ var ProxmoxCephFsProvider = () => Provider6.effect(ProxmoxCephFs, Effect18.succe
1985
1899
  }
1986
1900
  return { action: "noop" };
1987
1901
  }),
1988
- reconcile: Effect18.fn(function* ({ news }) {
1902
+ reconcile: Effect17.fn(function* ({ news }) {
1989
1903
  const live = yield* readFs(news);
1990
1904
  if (live !== undefined)
1991
1905
  return live;
1992
1906
  yield* createFs(news);
1993
1907
  const after = yield* readFs(news);
1994
1908
  if (after === undefined)
1995
- return yield* Effect18.die(notCreated2(news));
1909
+ return yield* Effect17.die(notCreated2(news));
1996
1910
  return after;
1997
1911
  }),
1998
- delete: Effect18.fn(function* ({ olds }) {
1912
+ delete: Effect17.fn(function* ({ olds }) {
1999
1913
  if ((yield* readFs(olds)) === undefined)
2000
1914
  return;
2001
1915
  yield* destroyFs(olds);
2002
1916
  const after = yield* readFs(olds);
2003
1917
  if (after !== undefined)
2004
- return yield* Effect18.die(notDestroyed(olds));
1918
+ return yield* Effect17.die(notDestroyed(olds));
2005
1919
  })
2006
1920
  })));
2007
1921
  // src/proxmox/ceph-osd.ts
2008
1922
  import { Resource as Resource7 } from "alchemy";
2009
1923
  import { isResolved as isResolved7 } from "alchemy/Diff";
2010
1924
  import * as Provider7 from "alchemy/Provider";
2011
- import * as Effect21 from "effect/Effect";
1925
+ import * as Effect20 from "effect/Effect";
2012
1926
 
2013
1927
  // src/proxmox/ceph-osd-tree.ts
2014
1928
  import * as nodes3 from "@distilled.cloud/proxmox/nodes";
2015
- import * as Effect19 from "effect/Effect";
1929
+ import * as Effect18 from "effect/Effect";
2016
1930
  var branches = (node) => (Array.isArray(node["children"]) ? node["children"] : []).filter((child) => typeof child === "object" && child !== null);
2017
1931
  var osdLeaves = (tree) => {
2018
1932
  const root = tree["root"];
@@ -2038,23 +1952,23 @@ var osdAttributes = (leaf, props) => ({
2038
1952
  status: text(leaf["status"]),
2039
1953
  total_space: num(leaf["total_space"], 0)
2040
1954
  });
2041
- var readOsd = (props) => runPve(props.target, "read", false, nodes3.getNodeCephOsd({ node: props.node })).pipe(Effect19.map((t) => {
1955
+ var readOsd = (props) => runPve(props.target, "read", false, nodes3.getNodeCephOsd({ node: props.node })).pipe(Effect18.map((t) => {
2042
1956
  const leaf = findOsd(t, props.osdid);
2043
1957
  return leaf === undefined ? undefined : osdAttributes(leaf, props);
2044
1958
  }));
2045
1959
 
2046
1960
  // src/proxmox/ceph-osd-write.ts
2047
1961
  import * as nodes4 from "@distilled.cloud/proxmox/nodes";
2048
- import * as Effect20 from "effect/Effect";
1962
+ import * as Effect19 from "effect/Effect";
2049
1963
  var OSD_CREATE_ENDPOINT = "pve:POST /nodes/{node}/ceph/osd";
2050
1964
  var describe = (props) => `osd.${String(props.osdid)} on ${props.node}`;
2051
1965
  var createOsdForm = (props, dev) => ({
2052
1966
  dev,
2053
1967
  ...props.device_class === undefined ? {} : { "crush-device-class": props.device_class }
2054
1968
  });
2055
- var createOsd = Effect20.fn(function* (news) {
1969
+ var createOsd = Effect19.fn(function* (news) {
2056
1970
  if (news.dev === undefined) {
2057
- return yield* Effect20.die(new Error(`${describe(news)}: no such OSD in the CRUSH tree, and no \`dev\` was declared. ` + "Without a device this resource is an ASSERTION over an OSD that must already " + "exist. Declare `dev` to let it create one -- which WIPES that device -- or fix " + "the declaration; if the disk was there yesterday, a replica is missing and Ceph " + "is degraded."));
1971
+ return yield* Effect19.die(new Error(`${describe(news)}: no such OSD in the CRUSH tree, and no \`dev\` was declared. ` + "Without a device this resource is an ASSERTION over an OSD that must already " + "exist. Declare `dev` to let it create one -- which WIPES that device -- or fix " + "the declaration; if the disk was there yesterday, a replica is missing and Ceph " + "is degraded."));
2058
1972
  }
2059
1973
  const form = createOsdForm(news, news.dev);
2060
1974
  yield* guardForm(OSD_CREATE_ENDPOINT, form, true);
@@ -2065,7 +1979,7 @@ var createOsd = Effect20.fn(function* (news) {
2065
1979
  }));
2066
1980
  const created = yield* readOsd(news);
2067
1981
  if (created === undefined) {
2068
- return yield* Effect20.die(new Error(`${describe(news)}: the create returned no error but osd.${String(news.osdid)} is ` + "still absent. Ceph allocates OSD ids and cannot be told which to use, so it most " + "likely assigned a different number -- check `ceph osd tree`, and declare the id it " + "actually gave the device rather than deploying again."));
1982
+ return yield* Effect19.die(new Error(`${describe(news)}: the create returned no error but osd.${String(news.osdid)} is ` + "still absent. Ceph allocates OSD ids and cannot be told which to use, so it most " + "likely assigned a different number -- check `ceph osd tree`, and declare the id it " + "actually gave the device rather than deploying again."));
2069
1983
  }
2070
1984
  return created;
2071
1985
  });
@@ -2081,12 +1995,12 @@ var ProxmoxCephOsd = Resource7("Proxmox.CephOsd", {
2081
1995
  });
2082
1996
  var settled = (live, props) => (props.host === undefined || props.host === live.host) && (props.device_class === undefined || props.device_class === live.device_class);
2083
1997
  var describe2 = (props) => `osd.${String(props.osdid)} (read via nodes/${props.node}/ceph/osd)`;
2084
- var handlers2 = {
2085
- list: () => Effect21.succeed([]),
2086
- read: Effect21.fn(function* ({ olds }) {
1998
+ var handlers = {
1999
+ list: () => Effect20.succeed([]),
2000
+ read: Effect20.fn(function* ({ olds }) {
2087
2001
  return yield* readOsd(olds);
2088
2002
  }),
2089
- diff: Effect21.fn(function* ({
2003
+ diff: Effect20.fn(function* ({
2090
2004
  news,
2091
2005
  output
2092
2006
  }) {
@@ -2099,27 +2013,27 @@ var handlers2 = {
2099
2013
  return { action: "update" };
2100
2014
  return settled(live, news) ? { action: "noop" } : { action: "update" };
2101
2015
  }),
2102
- reconcile: Effect21.fn(function* ({ news }) {
2016
+ reconcile: Effect20.fn(function* ({ news }) {
2103
2017
  const live = yield* readOsd(news);
2104
2018
  if (live === undefined) {
2105
2019
  return yield* createOsd(news);
2106
2020
  }
2107
2021
  if (!settled(live, news)) {
2108
- return yield* Effect21.die(new Error(`${describe2(news)}: exists but not as declared -- live host=${live.host} ` + `device_class=${live.device_class}. Nothing here moves an OSD between hosts or ` + "reclassifies it; fix the declaration, or move it deliberately with `ceph osd crush " + "move` / `ceph osd crush set-device-class` and deploy again."));
2022
+ return yield* Effect20.die(new Error(`${describe2(news)}: exists but not as declared -- live host=${live.host} ` + `device_class=${live.device_class}. Nothing here moves an OSD between hosts or ` + "reclassifies it; fix the declaration, or move it deliberately with `ceph osd crush " + "move` / `ceph osd crush set-device-class` and deploy again."));
2109
2023
  }
2110
2024
  return live;
2111
2025
  }),
2112
- delete: Effect21.fn(function* ({ olds }) {
2026
+ delete: Effect20.fn(function* ({ olds }) {
2113
2027
  yield* destroyOsd(olds);
2114
2028
  })
2115
2029
  };
2116
- var ProxmoxCephOsdProvider = () => Provider7.effect(ProxmoxCephOsd, Effect21.succeed(ProxmoxCephOsd.Provider.of(handlers2)));
2030
+ var ProxmoxCephOsdProvider = () => Provider7.effect(ProxmoxCephOsd, Effect20.succeed(ProxmoxCephOsd.Provider.of(handlers)));
2117
2031
  // src/proxmox/ceph-pool.ts
2118
2032
  import { Resource as Resource8 } from "alchemy";
2119
2033
  import { isResolved as isResolved8 } from "alchemy/Diff";
2120
2034
  import * as Provider8 from "alchemy/Provider";
2121
2035
  import * as nodes7 from "@distilled.cloud/proxmox/nodes";
2122
- import * as Effect24 from "effect/Effect";
2036
+ import * as Effect23 from "effect/Effect";
2123
2037
 
2124
2038
  // src/proxmox/ceph-pool-form.ts
2125
2039
  var object = (props) => `nodes/${props.node}/ceph/pool/${props.name}`;
@@ -2148,22 +2062,22 @@ var createBody = (props) => ({
2148
2062
 
2149
2063
  // src/proxmox/ceph-pool-settle.ts
2150
2064
  import * as nodes5 from "@distilled.cloud/proxmox/nodes";
2151
- import * as Effect22 from "effect/Effect";
2152
- var confirmAbsent = (props, describe3) => runPve(props.target, "read", false, nodes5.listNodeCephPool({ node: props.node })).pipe(Effect22.flatMap((rows) => rows.some((row) => row.pool_name === props.name) ? Effect22.die(new Error(`${describe3}: the cluster lists this pool but its status could not be read, ` + "so this deploy will NOT create over it. Check that the node is up and that the " + "read role holds Sys.Audit or Datastore.Audit on / -- a create here would apply " + "pg_num to a live pool and start a PG merge.")) : Effect22.void));
2153
- var settle = (props, read, done) => Effect22.gen(function* () {
2065
+ import * as Effect21 from "effect/Effect";
2066
+ var confirmAbsent = (props, describe3) => runPve(props.target, "read", false, nodes5.listNodeCephPool({ node: props.node })).pipe(Effect21.flatMap((rows) => rows.some((row) => row.pool_name === props.name) ? Effect21.die(new Error(`${describe3}: the cluster lists this pool but its status could not be read, ` + "so this deploy will NOT create over it. Check that the node is up and that the " + "read role holds Sys.Audit or Datastore.Audit on / -- a create here would apply " + "pg_num to a live pool and start a PG merge.")) : Effect21.void));
2067
+ var settle = (props, read, done) => Effect21.gen(function* () {
2154
2068
  for (let attempt = 0;attempt < 30; attempt += 1) {
2155
2069
  const live = yield* read(props);
2156
2070
  if (done(live))
2157
2071
  return live;
2158
- yield* Effect22.sleep("2 seconds");
2072
+ yield* Effect21.sleep("2 seconds");
2159
2073
  }
2160
2074
  return yield* read(props);
2161
2075
  });
2162
2076
 
2163
2077
  // src/proxmox/ceph-pool-wire.ts
2164
2078
  import * as nodes6 from "@distilled.cloud/proxmox/nodes";
2165
- import * as Effect23 from "effect/Effect";
2166
- var attributesOf3 = (live, props) => {
2079
+ import * as Effect22 from "effect/Effect";
2080
+ var attributesOf4 = (live, props) => {
2167
2081
  const row = live;
2168
2082
  if (typeof row["name"] !== "string")
2169
2083
  return;
@@ -2185,7 +2099,7 @@ var attributesOf3 = (live, props) => {
2185
2099
  target_size_ratio: num(row["target_size_ratio"], UNSET)
2186
2100
  };
2187
2101
  };
2188
- var readPoolStatus = (props) => runPve(props.target, "read", false, nodes6.getNodeCephPoolStatus({ name: props.name, node: props.node, verbose: "1" })).pipe(Effect23.map((live) => attributesOf3(live, props)), Effect23.catchTag("CephPoolNotFound", () => Effect23.succeed(undefined)));
2102
+ var readPoolStatus = (props) => runPve(props.target, "read", false, nodes6.getNodeCephPoolStatus({ name: props.name, node: props.node, verbose: "1" })).pipe(Effect22.map((live) => attributesOf4(live, props)), Effect22.catchTag("CephPoolNotFound", () => Effect22.succeed(undefined)));
2189
2103
  var CEPH_POOL_CREATE = "pve:POST /nodes/{node}/ceph/pool";
2190
2104
  var CEPH_POOL_UPDATE = "pve:PUT /nodes/{node}/ceph/pool/{name}";
2191
2105
  var toDistilledCreate2 = (props) => ({
@@ -2202,11 +2116,11 @@ var toDistilledUpdate = (props) => ({
2202
2116
  var ProxmoxCephPool = Resource8("Proxmox.CephPool", {
2203
2117
  defaultRemovalPolicy: "retain"
2204
2118
  });
2205
- var matches3 = (attributes, props) => same(props.size, attributes.size, attributes.nosizechange) && same(props.min_size, attributes.min_size, attributes.nosizechange) && same(props.pg_autoscale_mode, attributes.pg_autoscale_mode) && same(hint(props.pg_num_min), attributes.pg_num_min, attributes.nopgchange) && same(props.crush_rule, attributes.crush_rule, attributes.crush_rule === "") && same(hint(props.target_size), attributes.target_size);
2206
- var ProxmoxCephPoolProvider = () => Provider8.effect(ProxmoxCephPool, Effect24.succeed(ProxmoxCephPool.Provider.of({
2207
- list: () => Effect24.succeed([]),
2119
+ var matches4 = (attributes, props) => same(props.size, attributes.size, attributes.nosizechange) && same(props.min_size, attributes.min_size, attributes.nosizechange) && same(props.pg_autoscale_mode, attributes.pg_autoscale_mode) && same(hint(props.pg_num_min), attributes.pg_num_min, attributes.nopgchange) && same(props.crush_rule, attributes.crush_rule, attributes.crush_rule === "") && same(hint(props.target_size), attributes.target_size);
2120
+ var ProxmoxCephPoolProvider = () => Provider8.effect(ProxmoxCephPool, Effect23.succeed(ProxmoxCephPool.Provider.of({
2121
+ list: () => Effect23.succeed([]),
2208
2122
  read: ({ olds }) => readPoolStatus(olds),
2209
- diff: Effect24.fn(function* ({ news, output }) {
2123
+ diff: Effect23.fn(function* ({ news, output }) {
2210
2124
  if (!isResolved8(news))
2211
2125
  return;
2212
2126
  yield* guardWrite2(CEPH_POOL_CREATE, createBody(news), output === undefined);
@@ -2218,9 +2132,9 @@ var ProxmoxCephPoolProvider = () => Provider8.effect(ProxmoxCephPool, Effect24.s
2218
2132
  yield* guardWrite2(CEPH_POOL_CREATE, createBody(news), true);
2219
2133
  return { action: "update" };
2220
2134
  }
2221
- return matches3(live, news) ? { action: "noop" } : { action: "update" };
2135
+ return matches4(live, news) ? { action: "noop" } : { action: "update" };
2222
2136
  }),
2223
- reconcile: Effect24.fn(function* ({ news }) {
2137
+ reconcile: Effect23.fn(function* ({ news }) {
2224
2138
  const live = yield* readPoolStatus(news);
2225
2139
  let upid;
2226
2140
  if (live === undefined) {
@@ -2228,36 +2142,36 @@ var ProxmoxCephPoolProvider = () => Provider8.effect(ProxmoxCephPool, Effect24.s
2228
2142
  yield* confirmAbsent(news, object(news));
2229
2143
  upid = yield* runPve(news.target, "provision", true, nodes7.createNodeCephPool(toDistilledCreate2(news)));
2230
2144
  } else {
2231
- const form = formToSend(matches3, live, news, updateBody(news));
2145
+ const form = formToSend(matches4, live, news, updateBody(news));
2232
2146
  if (form !== undefined) {
2233
2147
  yield* guardWrite2(CEPH_POOL_UPDATE, updateBody(news), false);
2234
2148
  upid = yield* runPve(news.target, "provision", true, nodes7.putNodeCephPool(toDistilledUpdate(news)));
2235
2149
  }
2236
2150
  }
2237
- const after = yield* settle(news, readPoolStatus, (row) => row !== undefined && matches3(row, news));
2238
- if (after === undefined || !matches3(after, news)) {
2239
- return yield* Effect24.die(new Error(`${object(news)}: the write returned no error but the pool still does not match ` + `the declaration after 60s. PVE answered with task ${upid ?? "(none)"} -- read ` + "its log with `pvesh get /nodes/<node>/tasks/<upid>/log` to see what Ceph " + "refused."));
2151
+ const after = yield* settle(news, readPoolStatus, (row) => row !== undefined && matches4(row, news));
2152
+ if (after === undefined || !matches4(after, news)) {
2153
+ return yield* Effect23.die(new Error(`${object(news)}: the write returned no error but the pool still does not match ` + `the declaration after 60s. PVE answered with task ${upid ?? "(none)"} -- read ` + "its log with `pvesh get /nodes/<node>/tasks/<upid>/log` to see what Ceph " + "refused."));
2240
2154
  }
2241
2155
  return after;
2242
2156
  }),
2243
- delete: Effect24.fn(function* ({ olds }) {
2157
+ delete: Effect23.fn(function* ({ olds }) {
2244
2158
  yield* runPve(olds.target, "provision", true, nodes7.deleteNodeCephPool({ name: olds.name, node: olds.node }));
2245
2159
  const left = yield* settle(olds, readPoolStatus, (row) => row === undefined);
2246
2160
  if (left !== undefined) {
2247
- return yield* Effect24.die(new Error(`${object(olds)}: the DELETE returned no error but the pool is still there after ` + "60s. Either a storage on it still holds RBD images, or the mons are running " + "with mon_allow_pool_delete false."));
2161
+ return yield* Effect23.die(new Error(`${object(olds)}: the DELETE returned no error but the pool is still there after ` + "60s. Either a storage on it still holds RBD images, or the mons are running " + "with mon_allow_pool_delete false."));
2248
2162
  }
2249
2163
  })
2250
2164
  })));
2251
2165
  // src/proxmox/firewall-alias.ts
2252
2166
  import { Resource as Resource9 } from "alchemy";
2253
2167
  import * as Provider9 from "alchemy/Provider";
2254
- import * as Effect26 from "effect/Effect";
2168
+ import * as Effect25 from "effect/Effect";
2255
2169
 
2256
2170
  // src/proxmox/firewall-alias-lifecycle.ts
2257
2171
  import { isResolved as isResolved9 } from "alchemy/Diff";
2258
- import * as cluster3 from "@distilled.cloud/proxmox/cluster";
2172
+ import * as cluster4 from "@distilled.cloud/proxmox/cluster";
2259
2173
  import { ProxmoxParseError as ProxmoxParseError2 } from "@distilled.cloud/proxmox/Errors";
2260
- import * as Effect25 from "effect/Effect";
2174
+ import * as Effect24 from "effect/Effect";
2261
2175
 
2262
2176
  // src/proxmox/firewall-alias-form.ts
2263
2177
  var fold = (name) => name.trim().toLowerCase();
@@ -2299,20 +2213,20 @@ var firewallAliasSpec = {
2299
2213
 
2300
2214
  // src/proxmox/firewall-alias-lifecycle.ts
2301
2215
  var { guardCreate: guardCreate2, guardUpdate: guardUpdate2 } = specGuards(firewallAliasSpec);
2302
- var readFirewallAlias = (props) => runPve(props.target, "read", false, cluster3.getClusterFirewallAlias({ name: props.name })).pipe(Effect25.flatMap((live) => {
2216
+ var readFirewallAlias = (props) => runPve(props.target, "read", false, cluster4.getClusterFirewallAlias({ name: props.name })).pipe(Effect24.flatMap((live) => {
2303
2217
  if (live === null || typeof live !== "object" || Array.isArray(live) || !("name" in live) || typeof live.name !== "string" || fold(live.name) !== fold(props.name) || !("cidr" in live) || typeof live.cidr !== "string" || cidr(live.cidr) === "") {
2304
- return Effect25.fail(new ProxmoxParseError2({
2218
+ return Effect24.fail(new ProxmoxParseError2({
2305
2219
  body: undefined,
2306
2220
  cause: "Firewall alias response does not match the requested vendor identity"
2307
2221
  }));
2308
2222
  }
2309
- return Effect25.succeed(firewallAliasSpec.attributes({ ...live }, props));
2310
- }), Effect25.catchTag("FirewallAliasNotFound", () => Effect25.succeed(undefined)));
2311
- var deleteFirewallAlias = (props) => runPve(props.target, "provision", true, cluster3.deleteClusterFirewallAlias({ name: props.name }));
2223
+ return Effect24.succeed(firewallAliasSpec.attributes({ ...live }, props));
2224
+ }), Effect24.catchTag("FirewallAliasNotFound", () => Effect24.succeed(undefined)));
2225
+ var deleteFirewallAlias = (props) => runPve(props.target, "provision", true, cluster4.deleteClusterFirewallAlias({ name: props.name }));
2312
2226
  var firewallAliasHandlers = {
2313
- list: () => Effect25.succeed([]),
2227
+ list: () => Effect24.succeed([]),
2314
2228
  read: ({ olds }) => readFirewallAlias(olds),
2315
- diff: Effect25.fn(function* ({
2229
+ diff: Effect24.fn(function* ({
2316
2230
  news,
2317
2231
  output
2318
2232
  }) {
@@ -2331,20 +2245,20 @@ var firewallAliasHandlers = {
2331
2245
  }
2332
2246
  return { action: firewallAliasSpec.matches(live, news) ? "noop" : "update" };
2333
2247
  }),
2334
- reconcile: Effect25.fn(function* ({ news }) {
2248
+ reconcile: Effect24.fn(function* ({ news }) {
2335
2249
  const live = yield* readFirewallAlias(news);
2336
2250
  yield* guardCreate2(news, live === undefined);
2337
2251
  yield* guardUpdate2(news);
2338
2252
  if (live === undefined) {
2339
- yield* runPve(news.target, "provision", true, cluster3.createClusterFirewallAlias(firewallAliasSpec.createForm(news)));
2253
+ yield* runPve(news.target, "provision", true, cluster4.createClusterFirewallAlias(firewallAliasSpec.createForm(news)));
2340
2254
  } else {
2341
2255
  const form = formToSend(firewallAliasSpec.matches, live, news, firewallAliasSpec.updateForm(news));
2342
2256
  if (form !== undefined)
2343
- yield* runPve(news.target, "provision", true, cluster3.putClusterFirewallAlias({ ...form, name: news.name }));
2257
+ yield* runPve(news.target, "provision", true, cluster4.putClusterFirewallAlias({ ...form, name: news.name }));
2344
2258
  }
2345
2259
  const after = yield* readFirewallAlias(news);
2346
2260
  if (after === undefined)
2347
- return yield* Effect25.fail(new Error(`${firewallAliasSpec.path(news)}: write returned success but the resource is still absent`));
2261
+ return yield* Effect24.fail(new Error(`${firewallAliasSpec.path(news)}: write returned success but the resource is still absent`));
2348
2262
  return after;
2349
2263
  }),
2350
2264
  delete: ({ olds }) => deleteFirewallAlias(olds)
@@ -2352,17 +2266,17 @@ var firewallAliasHandlers = {
2352
2266
 
2353
2267
  // src/proxmox/firewall-alias.ts
2354
2268
  var ProxmoxFirewallAlias = Resource9("Proxmox.FirewallAlias");
2355
- var ProxmoxFirewallAliasProvider = () => Provider9.effect(ProxmoxFirewallAlias, Effect26.succeed(ProxmoxFirewallAlias.Provider.of(firewallAliasHandlers)));
2269
+ var ProxmoxFirewallAliasProvider = () => Provider9.effect(ProxmoxFirewallAlias, Effect25.succeed(ProxmoxFirewallAlias.Provider.of(firewallAliasHandlers)));
2356
2270
  // src/proxmox/group.ts
2357
2271
  import { Resource as Resource10 } from "alchemy";
2358
2272
  import { isResolved as isResolved10 } from "alchemy/Diff";
2359
2273
  import * as Provider10 from "alchemy/Provider";
2360
2274
  import * as access4 from "@distilled.cloud/proxmox/access";
2361
- import * as Effect28 from "effect/Effect";
2275
+ import * as Effect27 from "effect/Effect";
2362
2276
 
2363
2277
  // src/proxmox/group-wire.ts
2364
2278
  import * as access3 from "@distilled.cloud/proxmox/access";
2365
- import * as Effect27 from "effect/Effect";
2279
+ import * as Effect26 from "effect/Effect";
2366
2280
  var GROUP_CREATE = "pve:POST /access/groups";
2367
2281
  var GROUP_UPDATE = "pve:PUT /access/groups/{groupid}";
2368
2282
  var storedComment = (comment2) => {
@@ -2377,34 +2291,34 @@ var createForm3 = (props) => ({
2377
2291
  comment: storedComment(props.comment),
2378
2292
  groupid: props.groupid
2379
2293
  });
2380
- var updateForm = (props) => ({
2294
+ var updateForm2 = (props) => ({
2381
2295
  comment: storedComment(props.comment),
2382
2296
  groupid: props.groupid
2383
2297
  });
2384
- var attributesOf4 = (live, props) => ({
2298
+ var attributesOf5 = (live, props) => ({
2385
2299
  comment: text(live.comment),
2386
2300
  groupid: props.groupid,
2387
2301
  members: memberList(live.members)
2388
2302
  });
2389
- var matches4 = (attributes, props) => attributes.comment === storedComment(props.comment);
2390
- var readGroupOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, access3.getAccessGroup({ groupid: props.groupid }))).pipe(Effect27.map((live) => live === UNREADABLE ? UNREADABLE : live.members === undefined ? undefined : attributesOf4(live, props)));
2391
- var readGroup = (props) => readGroupOrFail(props).pipe(Effect27.catchTag("GroupNotFound", () => Effect27.succeed(undefined)));
2303
+ var matches5 = (attributes, props) => attributes.comment === storedComment(props.comment);
2304
+ var readGroupOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, access3.getAccessGroup({ groupid: props.groupid }))).pipe(Effect26.map((live) => live === UNREADABLE ? UNREADABLE : live.members === undefined ? undefined : attributesOf5(live, props)));
2305
+ var readGroup = (props) => readGroupOrFail(props).pipe(Effect26.catchTag("GroupNotFound", () => Effect26.succeed(undefined)));
2392
2306
  var dropUnreadable3 = (live) => live === UNREADABLE ? undefined : live;
2393
2307
 
2394
2308
  // src/proxmox/group.ts
2395
2309
  var ProxmoxGroup = Resource10("Proxmox.Group", {
2396
2310
  defaultRemovalPolicy: "retain"
2397
2311
  });
2398
- var ProxmoxGroupProvider = () => Provider10.effect(ProxmoxGroup, Effect28.succeed(ProxmoxGroup.Provider.of({
2399
- list: () => Effect28.succeed([]),
2400
- read: Effect28.fn(function* ({ olds, output }) {
2312
+ var ProxmoxGroupProvider = () => Provider10.effect(ProxmoxGroup, Effect27.succeed(ProxmoxGroup.Provider.of({
2313
+ list: () => Effect27.succeed([]),
2314
+ read: Effect27.fn(function* ({ olds, output }) {
2401
2315
  return dropUnreadable3(yield* output === undefined ? readGroup(olds) : readGroupOrFail(olds));
2402
2316
  }),
2403
- diff: Effect28.fn(function* ({ news, output }) {
2317
+ diff: Effect27.fn(function* ({ news, output }) {
2404
2318
  if (!isResolved10(news))
2405
2319
  return;
2406
2320
  yield* guardWrite2(GROUP_CREATE, createForm3(news), output === undefined);
2407
- yield* guardWrite2(GROUP_UPDATE, updateForm(news), false);
2321
+ yield* guardWrite2(GROUP_UPDATE, updateForm2(news), false);
2408
2322
  if (output === undefined)
2409
2323
  return;
2410
2324
  const live = yield* readGroupOrFail(news);
@@ -2416,31 +2330,149 @@ var ProxmoxGroupProvider = () => Provider10.effect(ProxmoxGroup, Effect28.succee
2416
2330
  yield* guardWrite2(GROUP_CREATE, createForm3(news), true);
2417
2331
  return { action: "update" };
2418
2332
  }
2419
- return matches4(live, news) ? { action: "noop" } : { action: "update" };
2333
+ return matches5(live, news) ? { action: "noop" } : { action: "update" };
2420
2334
  }),
2421
- reconcile: Effect28.fn(function* ({ news }) {
2335
+ reconcile: Effect27.fn(function* ({ news }) {
2422
2336
  const before = dropUnreadable3(yield* readGroup(news));
2423
2337
  yield* guardWrite2(GROUP_CREATE, createForm3(news), before === undefined);
2424
- yield* guardWrite2(GROUP_UPDATE, updateForm(news), false);
2338
+ yield* guardWrite2(GROUP_UPDATE, updateForm2(news), false);
2425
2339
  if (before === undefined) {
2426
2340
  yield* runPve(news.target, "provision", true, access4.createAccessGroup(createForm3(news)));
2427
- } else if (!matches4(before, news)) {
2428
- yield* runPve(news.target, "provision", true, access4.putAccessGroup(updateForm(news)));
2341
+ } else if (!matches5(before, news)) {
2342
+ yield* runPve(news.target, "provision", true, access4.putAccessGroup(updateForm2(news)));
2429
2343
  }
2430
2344
  const after = dropUnreadable3(yield* readGroup(news));
2431
2345
  if (after === undefined) {
2432
- return yield* Effect28.die(new Error(`access/groups/${news.groupid}: the write returned no error but the group is ` + 'still absent. PVE wraps every answer in {"data":...} and can report success ' + "on a call that did nothing -- read back rather than trusting the status code."));
2346
+ return yield* Effect27.die(new Error(`access/groups/${news.groupid}: the write returned no error but the group is ` + 'still absent. PVE wraps every answer in {"data":...} and can report success ' + "on a call that did nothing -- read back rather than trusting the status code."));
2433
2347
  }
2434
2348
  return after;
2435
2349
  }),
2436
- delete: Effect28.fn(function* ({ olds }) {
2350
+ delete: Effect27.fn(function* ({ olds }) {
2437
2351
  yield* runPve(olds.target, "provision", true, access4.deleteAccessGroup({ groupid: olds.groupid }));
2438
2352
  })
2439
2353
  })));
2440
2354
  // src/proxmox/ha-resource.ts
2441
2355
  import { Resource as Resource11 } from "alchemy";
2442
2356
  import * as Provider11 from "alchemy/Provider";
2357
+ import * as Effect30 from "effect/Effect";
2358
+
2359
+ // src/proxmox/resource.ts
2360
+ import { isResolved as isResolved11 } from "alchemy/Diff";
2443
2361
  import * as Effect29 from "effect/Effect";
2362
+
2363
+ // src/proxmox/client.ts
2364
+ import * as Effect28 from "effect/Effect";
2365
+ import * as HttpClient5 from "effect/unstable/http/HttpClient";
2366
+ import * as HttpClientRequest2 from "effect/unstable/http/HttpClientRequest";
2367
+ class PveError extends Error {
2368
+ status;
2369
+ method;
2370
+ path;
2371
+ constructor(status, method, path, detail) {
2372
+ super(`PVE ${method} ${path} -> ${String(status)}: ${detail}`);
2373
+ this.status = status;
2374
+ this.method = method;
2375
+ this.path = path;
2376
+ this.name = "PveError";
2377
+ }
2378
+ }
2379
+ var clusterExhausted = (method, path, attempts) => new PveError(0, method, path, `all members failed: ${attempts.map((a) => `${a.member} (${a.why})`).join("; ")}`);
2380
+ var encode = (form) => {
2381
+ const params = new URLSearchParams;
2382
+ for (const [key, value] of Object.entries(form)) {
2383
+ if (typeof value === "string")
2384
+ params.append(key, value);
2385
+ else
2386
+ for (const item of value)
2387
+ params.append(key, item);
2388
+ }
2389
+ return params.toString();
2390
+ };
2391
+ var buildRequest = (method, apiBase, path, credential, target, form) => {
2392
+ const url = `${apiBase}/${path}`;
2393
+ return HttpClientRequest2.make(method)(url).pipe(HttpClientRequest2.setHeaders({ Authorization: authorization(credential, target) }), form === undefined ? (self) => self : HttpClientRequest2.bodyText(encode(form), "application/x-www-form-urlencoded"));
2394
+ };
2395
+ var executeOne = (target, credential, method, path, form, apiBase) => Effect28.gen(function* () {
2396
+ const client = yield* HttpClient5.HttpClient;
2397
+ const request = buildRequest(method, apiBase, path, credential, target, form);
2398
+ return yield* client.execute(request).pipe(Effect28.mapError((cause) => new PveError(0, method, path, String(cause))));
2399
+ });
2400
+ var readResponse = (response, method, path) => Effect28.gen(function* () {
2401
+ if (response.status < 200 || response.status >= 300) {
2402
+ const detail = yield* response.text.pipe(Effect28.orElseSucceed(() => ""));
2403
+ return yield* Effect28.fail(new PveError(response.status, method, path, detail.slice(0, 300)));
2404
+ }
2405
+ const body2 = yield* response.json.pipe(Effect28.mapError((cause) => new PveError(0, method, path, String(cause))));
2406
+ return body2.data;
2407
+ });
2408
+ var pveWith = (target, credential, method, path, form) => Effect28.gen(function* () {
2409
+ const response = target.scheme === "pve" ? yield* executeOnCluster(target, method, path, (apiBase) => buildRequest(method, apiBase, path, credential, target, form)).pipe(Effect28.mapError((failure) => failure.tag === "cluster" ? clusterExhausted(failure.method, failure.path, failure.attempts) : new PveError(0, method, path, String(failure)))) : yield* executeOne(target, credential, method, path, form, target.api);
2410
+ return yield* readResponse(response, method, path);
2411
+ });
2412
+ var pve = (target, role, method, path, form) => Effect28.gen(function* () {
2413
+ const credential = yield* leased(target, role);
2414
+ return yield* pveWith(target, credential, method, path, form);
2415
+ });
2416
+
2417
+ // src/proxmox/resource.ts
2418
+ var pveOperations = (spec) => {
2419
+ const { guardCreate: guardCreate3, guardUpdate: guardUpdate3 } = specGuards(spec);
2420
+ const read = (props) => pve(props.target, spec.readRole ?? "read", "GET", spec.path(props)).pipe(Effect29.map((data) => data == null ? undefined : spec.attributes(data, props)), Effect29.orElseSucceed(() => {
2421
+ return;
2422
+ }));
2423
+ return {
2424
+ guardCreate: guardCreate3,
2425
+ guardUpdate: guardUpdate3,
2426
+ read,
2427
+ diff: (news, output) => Effect29.gen(function* () {
2428
+ if (!isResolved11(news))
2429
+ return;
2430
+ yield* guardCreate3(news, output === undefined);
2431
+ yield* guardUpdate3(news);
2432
+ if (output === undefined)
2433
+ return;
2434
+ const live = yield* read(news);
2435
+ if (live === undefined) {
2436
+ yield* guardCreate3(news, true);
2437
+ return { action: "update" };
2438
+ }
2439
+ if (spec.matches(live, news))
2440
+ return { action: "noop" };
2441
+ return spec.updateForm === undefined ? { action: "replace" } : { action: "update" };
2442
+ }),
2443
+ reconcile: (news) => Effect29.gen(function* () {
2444
+ const live = yield* read(news);
2445
+ yield* guardCreate3(news, live === undefined);
2446
+ yield* guardUpdate3(news);
2447
+ if (live === undefined) {
2448
+ yield* pve(news.target, "provision", "POST", spec.collection(news), spec.createForm(news));
2449
+ } else if (spec.updateForm !== undefined) {
2450
+ const form = formToSend(spec.matches, live, news, spec.updateForm(news));
2451
+ if (form !== undefined) {
2452
+ yield* pve(news.target, "provision", "PUT", spec.path(news), form);
2453
+ }
2454
+ }
2455
+ const after = yield* read(news);
2456
+ if (after === undefined) {
2457
+ return yield* Effect29.die(new Error(`${spec.path(news)}: the write returned no error but the object is still absent. ` + 'PVE wraps every answer in {"data":...} and can report success on a call that did ' + "nothing -- read back rather than trusting the status code."));
2458
+ }
2459
+ return after;
2460
+ }),
2461
+ destroy: (olds) => pve(olds.target, "provision", "DELETE", spec.path(olds))
2462
+ };
2463
+ };
2464
+ var pveHandlers = (spec) => {
2465
+ const ops = pveOperations(spec);
2466
+ return {
2467
+ list: () => Effect29.succeed([]),
2468
+ read: ({ olds }) => ops.read(olds),
2469
+ diff: ({ news, output }) => ops.diff(news, output),
2470
+ reconcile: ({ news }) => ops.reconcile(news),
2471
+ delete: ({ olds }) => ops.destroy(olds)
2472
+ };
2473
+ };
2474
+
2475
+ // src/proxmox/ha-resource.ts
2444
2476
  var ProxmoxHaResource = Resource11("Proxmox.HaResource");
2445
2477
  var kind = (sid) => sid.split(":")[0] ?? "";
2446
2478
  var shape3 = (props) => ({
@@ -2449,7 +2481,7 @@ var shape3 = (props) => ({
2449
2481
  max_restart: String(props.max_restart ?? 1),
2450
2482
  state: props.state ?? "started"
2451
2483
  });
2452
- var handlers3 = pveHandlers({
2484
+ var handlers2 = pveHandlers({
2453
2485
  attributes: (live, props) => ({
2454
2486
  comment: typeof live["comment"] === "string" ? live["comment"] : "",
2455
2487
  max_relocate: num(live["max_relocate"], 1),
@@ -2468,11 +2500,11 @@ var handlers3 = pveHandlers({
2468
2500
  path: (props) => `cluster/ha/resources/${props.sid}`,
2469
2501
  updateForm: shape3
2470
2502
  });
2471
- var ProxmoxHaResourceProvider = () => Provider11.effect(ProxmoxHaResource, Effect29.succeed(ProxmoxHaResource.Provider.of(handlers3)));
2503
+ var ProxmoxHaResourceProvider = () => Provider11.effect(ProxmoxHaResource, Effect30.succeed(ProxmoxHaResource.Provider.of(handlers2)));
2472
2504
  // src/proxmox/ha-rule.ts
2473
2505
  import { Resource as Resource12 } from "alchemy";
2474
2506
  import * as Provider12 from "alchemy/Provider";
2475
- import * as Effect30 from "effect/Effect";
2507
+ import * as Effect31 from "effect/Effect";
2476
2508
 
2477
2509
  // src/proxmox/ha-rule-form.ts
2478
2510
  var nodeList = (value) => {
@@ -2520,7 +2552,7 @@ var clearList = (props) => Object.entries(optional(props)).filter(([, value]) =>
2520
2552
 
2521
2553
  // src/proxmox/ha-rule.ts
2522
2554
  var ProxmoxHaRule = Resource12("Proxmox.HaRule");
2523
- var handlers4 = pveHandlers({
2555
+ var handlers3 = pveHandlers({
2524
2556
  attributes: (live, props) => {
2525
2557
  const liveType = text(live["type"]);
2526
2558
  if (liveType !== "" && liveType !== props.type)
@@ -2549,43 +2581,43 @@ var handlers4 = pveHandlers({
2549
2581
  return withClears(fields, clear);
2550
2582
  }
2551
2583
  });
2552
- var ProxmoxHaRuleProvider = () => Provider12.effect(ProxmoxHaRule, Effect30.succeed(ProxmoxHaRule.Provider.of(handlers4)));
2584
+ var ProxmoxHaRuleProvider = () => Provider12.effect(ProxmoxHaRule, Effect31.succeed(ProxmoxHaRule.Provider.of(handlers3)));
2553
2585
  // src/proxmox/lxc.ts
2554
2586
  import { Resource as Resource13 } from "alchemy";
2555
- import { isResolved as isResolved11 } from "alchemy/Diff";
2587
+ import { isResolved as isResolved12 } from "alchemy/Diff";
2556
2588
  import * as Provider13 from "alchemy/Provider";
2557
- import * as Effect41 from "effect/Effect";
2589
+ import * as Effect42 from "effect/Effect";
2558
2590
 
2559
2591
  // src/ownership/adopt.ts
2560
2592
  import { AdoptPolicy } from "alchemy/AdoptPolicy";
2561
2593
  import { AlchemyContext } from "alchemy/AlchemyContext";
2562
2594
  import { Stack as Stack3 } from "alchemy/Stack";
2563
- import * as Effect34 from "effect/Effect";
2595
+ import * as Effect35 from "effect/Effect";
2564
2596
  import * as Option5 from "effect/Option";
2565
2597
 
2566
2598
  // src/ownership/resume.ts
2567
2599
  import { Unowned } from "alchemy/AdoptPolicy";
2568
2600
  import { Artifacts } from "alchemy/Artifacts";
2569
- import * as Effect31 from "effect/Effect";
2601
+ import * as Effect32 from "effect/Effect";
2570
2602
  import * as Option2 from "effect/Option";
2571
2603
  var PROVEN = "homeflare/ownership/resumes";
2572
2604
  var UNFINISHED = "homeflare/ownership/unfinished";
2573
- var note = (key, instanceId) => Effect31.gen(function* () {
2574
- const bag = yield* Effect31.serviceOption(Artifacts);
2605
+ var note = (key, instanceId) => Effect32.gen(function* () {
2606
+ const bag = yield* Effect32.serviceOption(Artifacts);
2575
2607
  if (Option2.isSome(bag))
2576
2608
  yield* bag.value.set(key, instanceId);
2577
2609
  });
2578
- var noted = (key, instanceId) => Effect31.gen(function* () {
2579
- const bag = yield* Effect31.serviceOption(Artifacts);
2610
+ var noted = (key, instanceId) => Effect32.gen(function* () {
2611
+ const bag = yield* Effect32.serviceOption(Artifacts);
2580
2612
  if (Option2.isNone(bag))
2581
2613
  return false;
2582
2614
  return (yield* bag.value.get(key)) === instanceId;
2583
2615
  });
2584
- var noteUnfinished = (instanceId) => Effect31.as(note(UNFINISHED, instanceId), undefined);
2585
- var noteResume = (instanceId, recovered) => Effect31.gen(function* () {
2616
+ var noteUnfinished = (instanceId) => Effect32.as(note(UNFINISHED, instanceId), undefined);
2617
+ var noteResume = (instanceId, recovered) => Effect32.gen(function* () {
2586
2618
  yield* noteUnfinished(instanceId);
2587
- const unproven = () => Effect31.succeed(undefined);
2588
- const found = yield* recovered.pipe(Effect31.catch(unproven), Effect31.catchDefect(unproven));
2619
+ const unproven = () => Effect32.succeed(undefined);
2620
+ const found = yield* recovered.pipe(Effect32.catch(unproven), Effect32.catchDefect(unproven));
2589
2621
  if (found === undefined || found === null || Unowned.is(found))
2590
2622
  return;
2591
2623
  yield* note(PROVEN, instanceId);
@@ -2596,7 +2628,7 @@ var provingResumes = (service) => {
2596
2628
  const { diff, read } = service;
2597
2629
  if (diff === undefined || read === undefined)
2598
2630
  return service;
2599
- const proving = (input) => Effect31.gen(function* () {
2631
+ const proving = (input) => Effect32.gen(function* () {
2600
2632
  if (input.output === undefined) {
2601
2633
  yield* noteResume(input.instanceId, read({ ...input, output: undefined }));
2602
2634
  }
@@ -2608,12 +2640,12 @@ var provingResumes = (service) => {
2608
2640
  // src/ownership/rows.ts
2609
2641
  import { Stack as Stack2 } from "alchemy/Stack";
2610
2642
  import { State, isActionState } from "alchemy/State/State";
2611
- import * as Effect33 from "effect/Effect";
2643
+ import * as Effect34 from "effect/Effect";
2612
2644
  import * as Option4 from "effect/Option";
2613
2645
 
2614
2646
  // src/ownership/whole.ts
2615
2647
  import { Stack } from "alchemy/Stack";
2616
- import * as Effect32 from "effect/Effect";
2648
+ import * as Effect33 from "effect/Effect";
2617
2649
  import * as Option3 from "effect/Option";
2618
2650
  var absent = (value) => value === undefined || value === null;
2619
2651
  var isPlainObject = (value) => {
@@ -2639,22 +2671,22 @@ var carries = (declared, recorded) => {
2639
2671
  }
2640
2672
  return true;
2641
2673
  };
2642
- var wholeDeclaration = (fqn, props) => Effect32.map(Effect32.serviceOption(Stack), (stack) => {
2674
+ var wholeDeclaration = (fqn, props) => Effect33.map(Effect33.serviceOption(Stack), (stack) => {
2643
2675
  const declared = Option3.isSome(stack) ? stack.value.resources[fqn] : undefined;
2644
2676
  return declared !== undefined && carries(declared.Props, props);
2645
2677
  });
2646
2678
 
2647
2679
  // src/ownership/rows.ts
2648
- var storeOf = Effect33.gen(function* () {
2649
- const stack = yield* Effect33.serviceOption(Stack2);
2650
- const state = yield* Effect33.serviceOption(State);
2680
+ var storeOf = Effect34.gen(function* () {
2681
+ const stack = yield* Effect34.serviceOption(Stack2);
2682
+ const state = yield* Effect34.serviceOption(State);
2651
2683
  if (Option4.isNone(stack) || Option4.isNone(state))
2652
2684
  return;
2653
2685
  const store = yield* state.value;
2654
2686
  const where = { stack: stack.value.name, stage: stack.value.stage };
2655
2687
  return { resources: stack.value.resources, store, where };
2656
2688
  });
2657
- var rowAt = (store, where, fqn) => store.get({ ...where, fqn }).pipe(Effect33.orElseSucceed(() => {
2689
+ var rowAt = (store, where, fqn) => store.get({ ...where, fqn }).pipe(Effect34.orElseSucceed(() => {
2658
2690
  return;
2659
2691
  }));
2660
2692
  var generationOf = (row, instanceId) => {
@@ -2667,7 +2699,7 @@ var generationOf = (row, instanceId) => {
2667
2699
  }
2668
2700
  return;
2669
2701
  };
2670
- var recordedGeneration = (fqn, instanceId) => Effect33.gen(function* () {
2702
+ var recordedGeneration = (fqn, instanceId) => Effect34.gen(function* () {
2671
2703
  const found = yield* storeOf;
2672
2704
  if (found === undefined)
2673
2705
  return;
@@ -2678,14 +2710,48 @@ var recordedGeneration = (fqn, instanceId) => Effect33.gen(function* () {
2678
2710
  }
2679
2711
  return;
2680
2712
  });
2681
- var recordedInstance = (fqn, instanceId) => Effect33.gen(function* () {
2713
+ var recordedInstance = (fqn, instanceId) => Effect34.gen(function* () {
2682
2714
  const generation = yield* recordedGeneration(fqn, instanceId);
2683
2715
  if (generation === undefined)
2684
2716
  return "absent";
2685
2717
  return (yield* wholeDeclaration(fqn, generation.props)) ? "whole" : "partial";
2686
2718
  });
2687
- var isCreate = (fqn, instanceId) => Effect33.map(recordedGeneration(fqn, instanceId), (generation) => generation?.status === "creating");
2688
- var forgetRefusedCreate = (fqn, instanceId) => Effect33.gen(function* () {
2719
+ var isCreate = (fqn, instanceId) => Effect34.map(recordedGeneration(fqn, instanceId), (generation) => generation?.status === "creating");
2720
+ var idOf = (attr) => {
2721
+ if (typeof attr !== "object" || attr === null)
2722
+ return;
2723
+ const id = attr.id;
2724
+ return typeof id === "string" && id !== "" ? id : undefined;
2725
+ };
2726
+ var olderGenerationIds = (fqn, instanceId) => Effect34.gen(function* () {
2727
+ const found = yield* storeOf;
2728
+ if (found === undefined)
2729
+ return [];
2730
+ const ids = [];
2731
+ for (const at of [fqn, ...found.resources[fqn]?.FormerFqns ?? []]) {
2732
+ collectOlder(yield* rowAt(found.store, found.where, at), instanceId, ids);
2733
+ }
2734
+ return ids;
2735
+ });
2736
+ var collectOlder = (row, instanceId, ids) => {
2737
+ let at = row;
2738
+ let seen = false;
2739
+ while (typeof at === "object" && at !== null && !isActionState(at)) {
2740
+ const generation = at;
2741
+ if (!seen) {
2742
+ seen = generation.instanceId === instanceId;
2743
+ at = generation.old;
2744
+ continue;
2745
+ }
2746
+ if (generation.instanceId !== instanceId) {
2747
+ const id = idOf(generation.attr);
2748
+ if (id !== undefined)
2749
+ ids.push(id);
2750
+ }
2751
+ at = generation.old;
2752
+ }
2753
+ };
2754
+ var forgetRefusedCreate = (fqn, instanceId) => Effect34.gen(function* () {
2689
2755
  const found = yield* storeOf;
2690
2756
  if (found === undefined)
2691
2757
  return;
@@ -2694,32 +2760,32 @@ var forgetRefusedCreate = (fqn, instanceId) => Effect33.gen(function* () {
2694
2760
  if (mine?.status !== "creating" || mine.instanceId !== instanceId || mine.attr !== undefined) {
2695
2761
  return;
2696
2762
  }
2697
- yield* found.store.delete({ ...found.where, fqn }).pipe(Effect33.ignore);
2763
+ yield* found.store.delete({ ...found.where, fqn }).pipe(Effect34.ignore);
2698
2764
  });
2699
2765
 
2700
2766
  // src/ownership/adopt.ts
2701
- var adoptEnabled = (fqn) => Effect34.gen(function* () {
2702
- const stack = yield* Effect34.serviceOption(Stack3);
2767
+ var adoptEnabled = (fqn) => Effect35.gen(function* () {
2768
+ const stack = yield* Effect35.serviceOption(Stack3);
2703
2769
  const scoped = Option5.isSome(stack) ? stack.value.resources[fqn]?.Adopt : undefined;
2704
2770
  if (scoped !== undefined)
2705
2771
  return scoped;
2706
- const policy = yield* Effect34.serviceOption(AdoptPolicy);
2772
+ const policy = yield* Effect35.serviceOption(AdoptPolicy);
2707
2773
  if (Option5.isSome(policy))
2708
2774
  return policy.value;
2709
- const context = yield* Effect34.serviceOption(AlchemyContext);
2775
+ const context = yield* Effect35.serviceOption(AlchemyContext);
2710
2776
  return Option5.isSome(context) ? context.value.adopt : false;
2711
2777
  });
2712
- var adoptable = (owner) => Effect34.gen(function* () {
2778
+ var adoptable = (owner) => Effect35.gen(function* () {
2713
2779
  if (yield* isCreate(owner.fqn, owner.instanceId))
2714
2780
  return true;
2715
2781
  return yield* unfinished(owner.instanceId);
2716
2782
  });
2717
- var adoptsAtApply = (owner) => Effect34.gen(function* () {
2783
+ var adoptsAtApply = (owner) => Effect35.gen(function* () {
2718
2784
  if (!(yield* adoptEnabled(owner.fqn)))
2719
2785
  return false;
2720
2786
  return yield* adoptable(owner);
2721
2787
  });
2722
- var refuseTakeover = (owner, what) => Effect34.gen(function* () {
2788
+ var refuseTakeover = (owner, what) => Effect35.gen(function* () {
2723
2789
  if (owner.output !== undefined)
2724
2790
  return;
2725
2791
  if (yield* resumes(owner.instanceId))
@@ -2729,25 +2795,25 @@ var refuseTakeover = (owner, what) => Effect34.gen(function* () {
2729
2795
  return;
2730
2796
  yield* forgetRefusedCreate(owner.fqn, owner.instanceId);
2731
2797
  const remedy = may ? "Deploy with --adopt (or wrap the resource in adopt(true)) to take it over, or remove it first." : "It is the new identity of a replace, which --adopt does not cover: remove it first.";
2732
- return yield* Effect34.die(new Error(`${what}: already exists, and this stack holds no state for it — the plan could not ask ` + "first (a prop was still an Output, a replace moved onto it, or it appeared after the " + `plan). Nothing was written. ${remedy}`));
2798
+ return yield* Effect35.die(new Error(`${what}: already exists, and this stack holds no state for it — the plan could not ask ` + "first (a prop was still an Output, a replace moved onto it, or it appeared after the " + `plan). Nothing was written. ${remedy}`));
2733
2799
  });
2734
2800
  var claimFor = (owner) => (what) => refuseTakeover(owner, what);
2735
2801
 
2736
2802
  // src/ownership/probe.ts
2737
2803
  import { Unowned as Unowned2 } from "alchemy/AdoptPolicy";
2738
- import * as Effect35 from "effect/Effect";
2739
- var provenOurs = (ask, settled2) => Effect35.gen(function* () {
2804
+ import * as Effect36 from "effect/Effect";
2805
+ var provenOurs = (ask, settled2) => Effect36.gen(function* () {
2740
2806
  const recorded = yield* recordedInstance(ask.fqn, ask.instanceId);
2741
2807
  if (recorded === "absent")
2742
2808
  return false;
2743
2809
  if (recorded === "partial") {
2744
- yield* Effect35.logWarning(`${ask.fqn}: the interrupted create's state row lacks part of the declaration (a prop ` + "was still an Output when it was written), so the live object is not proven ours");
2810
+ yield* Effect36.logWarning(`${ask.fqn}: the interrupted create's state row lacks part of the declaration (a prop ` + "was still an Output when it was written), so the live object is not proven ours");
2745
2811
  return false;
2746
2812
  }
2747
- const unproven = (reason) => Effect35.as(Effect35.logWarning(`${ask.fqn}: the interrupted create's object could not be compared with its props ` + `(${reason instanceof Error ? reason.message : String(reason)}), so it is not treated as ours`), false);
2748
- return yield* settled2.pipe(Effect35.catch(unproven), Effect35.catchDefect(unproven));
2813
+ const unproven = (reason) => Effect36.as(Effect36.logWarning(`${ask.fqn}: the interrupted create's object could not be compared with its props ` + `(${reason instanceof Error ? reason.message : String(reason)}), so it is not treated as ours`), false);
2814
+ return yield* settled2.pipe(Effect36.catch(unproven), Effect36.catchDefect(unproven));
2749
2815
  });
2750
- var ownedRead = (ask, found, settled2) => Effect35.gen(function* () {
2816
+ var ownedRead = (ask, found, settled2) => Effect36.gen(function* () {
2751
2817
  if (found === undefined || ask.output !== undefined)
2752
2818
  return found;
2753
2819
  return (yield* provenOurs(ask, settled2)) ? found : Unowned2(found);
@@ -2805,8 +2871,8 @@ var optionMap = (value, family, defaultKey) => {
2805
2871
  return out;
2806
2872
  };
2807
2873
  var sameMap = (left, right) => left.size === right.size && [...left].every(([key, value]) => right.get(key) === value);
2808
- var sortedForm = (map13) => [...map13].map(([key, value]) => `${key}=${value}`).sort().join(",");
2809
- var printMap = (map13, lead = []) => [...lead.filter((key) => map13.has(key)), ...[...map13.keys()].filter((k) => !lead.includes(k))].map((key) => `${key}=${map13.get(key) ?? ""}`).join(",");
2874
+ var sortedForm = (map14) => [...map14].map(([key, value]) => `${key}=${value}`).sort().join(",");
2875
+ var printMap = (map14, lead = []) => [...lead.filter((key) => map14.has(key)), ...[...map14.keys()].filter((k) => !lead.includes(k))].map((key) => `${key}=${map14.get(key) ?? ""}`).join(",");
2810
2876
  var netMaps = (declared, live) => {
2811
2877
  const want = optionMap(declared, "net");
2812
2878
  const have = optionMap(live, "net");
@@ -3202,11 +3268,11 @@ var identityRefusals = (news, olds, output) => {
3202
3268
  };
3203
3269
 
3204
3270
  // src/proxmox/lxc-adoption.ts
3205
- import * as Effect40 from "effect/Effect";
3271
+ import * as Effect41 from "effect/Effect";
3206
3272
 
3207
3273
  // src/ownership/adopting.ts
3208
- import * as Effect36 from "effect/Effect";
3209
- var adopting = (owner, settled2) => Effect36.gen(function* () {
3274
+ import * as Effect37 from "effect/Effect";
3275
+ var adopting = (owner, settled2) => Effect37.gen(function* () {
3210
3276
  if (owner.output === undefined)
3211
3277
  return false;
3212
3278
  const generation = yield* recordedGeneration(owner.fqn, owner.instanceId);
@@ -3218,7 +3284,7 @@ var adopting = (owner, settled2) => Effect36.gen(function* () {
3218
3284
  });
3219
3285
 
3220
3286
  // src/proxmox/lxc-lifecycle.ts
3221
- import * as Effect39 from "effect/Effect";
3287
+ import * as Effect40 from "effect/Effect";
3222
3288
  import * as nodes10 from "@distilled.cloud/proxmox/nodes";
3223
3289
 
3224
3290
  // src/proxmox/lxc-errors.ts
@@ -3227,44 +3293,44 @@ class LxcRefusedError extends Error {
3227
3293
  }
3228
3294
 
3229
3295
  // src/proxmox/lxc-read.ts
3230
- import * as cluster4 from "@distilled.cloud/proxmox/cluster";
3296
+ import * as cluster5 from "@distilled.cloud/proxmox/cluster";
3231
3297
  import * as nodes8 from "@distilled.cloud/proxmox/nodes";
3232
- import * as Effect37 from "effect/Effect";
3233
- var readLive = (where) => Effect37.gen(function* () {
3298
+ import * as Effect38 from "effect/Effect";
3299
+ var readLive = (where) => Effect38.gen(function* () {
3234
3300
  const credential = yield* leased(where.target, "read");
3235
- const answer = yield* runPveWith(where.target, credential, false, nodes8.getNodeLxcConfig({ node: where.node, vmid: String(where.vmid) })).pipe(Effect37.map((data) => ({ data, error: undefined })), Effect37.catchTag("LxcConfigNotFound", (error) => Effect37.succeed({ data: undefined, error })));
3301
+ const answer = yield* runPveWith(where.target, credential, false, nodes8.getNodeLxcConfig({ node: where.node, vmid: String(where.vmid) })).pipe(Effect38.map((data) => ({ data, error: undefined })), Effect38.catchTag("LxcConfigNotFound", (error) => Effect38.succeed({ data: undefined, error })));
3236
3302
  if (answer.error === undefined) {
3237
3303
  const live = answer.data;
3238
3304
  if (live === null || typeof live !== "object" || Array.isArray(live) || !("digest" in live) || typeof live.digest !== "string" || live.digest === "") {
3239
- return yield* Effect37.fail(new LxcRefusedError(`CT ${String(where.vmid)}: config read did not return a valid digest-bearing config.`));
3305
+ return yield* Effect38.fail(new LxcRefusedError(`CT ${String(where.vmid)}: config read did not return a valid digest-bearing config.`));
3240
3306
  }
3241
3307
  return live;
3242
3308
  }
3243
- const rows = yield* runPveWith(where.target, credential, false, cluster4.listClusterResources({ type: "vm" }));
3309
+ const rows = yield* runPveWith(where.target, credential, false, cluster5.listClusterResources({ type: "vm" }));
3244
3310
  if (!Array.isArray(rows) || rows.some((row) => !Number.isSafeInteger(Number(row?.vmid)) || Number(row?.vmid) <= 0 || typeof row?.node !== "string" || row.node === "" || !["lxc", "qemu"].includes(row.type))) {
3245
- return yield* Effect37.fail(new LxcRefusedError("The cluster guest index did not identify its rows."));
3311
+ return yield* Effect38.fail(new LxcRefusedError("The cluster guest index did not identify its rows."));
3246
3312
  }
3247
3313
  const found = rows.find((row) => Number(row.vmid) === where.vmid);
3248
3314
  if (found !== undefined && found.node === where.node && found.type === "lxc") {
3249
- return yield* Effect37.fail(answer.error);
3315
+ return yield* Effect38.fail(answer.error);
3250
3316
  }
3251
3317
  if (found !== undefined) {
3252
- return yield* Effect37.fail(new LxcRefusedError(`vmid ${String(where.vmid)} is a ${text(found.type, "guest")} on ` + `${text(found.node, "?")}, not a container on ${where.node}. A migration is not an ` + "update and vmids are cluster-wide: declare the node it is on, or pick a free vmid."));
3318
+ return yield* Effect38.fail(new LxcRefusedError(`vmid ${String(where.vmid)} is a ${text(found.type, "guest")} on ` + `${text(found.node, "?")}, not a container on ${where.node}. A migration is not an ` + "update and vmids are cluster-wide: declare the node it is on, or pick a free vmid."));
3253
3319
  }
3254
3320
  return;
3255
3321
  });
3256
3322
 
3257
3323
  // src/proxmox/lxc-task.ts
3258
3324
  import * as nodes9 from "@distilled.cloud/proxmox/nodes";
3259
- import * as Effect38 from "effect/Effect";
3260
- var lxcTask = (where, operation, what, polls) => Effect38.gen(function* () {
3325
+ import * as Effect39 from "effect/Effect";
3326
+ var lxcTask = (where, operation, what, polls) => Effect39.gen(function* () {
3261
3327
  const credential = yield* mint(where.target, "provision");
3262
3328
  const upid = text(yield* runPveWith(where.target, credential, true, operation));
3263
3329
  if (upid === "")
3264
- return yield* Effect38.fail(new LxcRefusedError(`${what}: PVE returned no task id, so the write cannot be confirmed and is not claimed.`));
3330
+ return yield* Effect39.fail(new LxcRefusedError(`${what}: PVE returned no task id, so the write cannot be confirmed and is not claimed.`));
3265
3331
  let exit = "still running when this provider stopped waiting";
3266
3332
  for (let attempt = 0;attempt < polls; attempt++) {
3267
- const status = yield* runPveWith(where.target, credential, false, nodes9.getNodeTaskStatus({ node: where.node, upid })).pipe(Effect38.orElseSucceed(() => {
3333
+ const status = yield* runPveWith(where.target, credential, false, nodes9.getNodeTaskStatus({ node: where.node, upid })).pipe(Effect39.orElseSucceed(() => {
3268
3334
  return;
3269
3335
  }));
3270
3336
  if (status === undefined || status.status === undefined) {
@@ -3275,10 +3341,10 @@ var lxcTask = (where, operation, what, polls) => Effect38.gen(function* () {
3275
3341
  exit = text(status.exitstatus, "stopped with no exitstatus");
3276
3342
  break;
3277
3343
  }
3278
- yield* Effect38.sleep("1 second");
3344
+ yield* Effect39.sleep("1 second");
3279
3345
  }
3280
3346
  if (exit !== "OK")
3281
- return yield* Effect38.fail(new LxcRefusedError(`${what}: task ${upid} ended "${exit}". Read \`pvesh get /nodes/${where.node}/tasks/` + `${upid}/log\` before running the deploy again.`));
3347
+ return yield* Effect39.fail(new LxcRefusedError(`${what}: task ${upid} ended "${exit}". Read \`pvesh get /nodes/${where.node}/tasks/` + `${upid}/log\` before running the deploy again.`));
3282
3348
  });
3283
3349
 
3284
3350
  // src/proxmox/lxc-lifecycle.ts
@@ -3289,13 +3355,13 @@ var LXC_ENDPOINTS = {
3289
3355
  };
3290
3356
  var CREATE_POLLS = 180;
3291
3357
  var TASK_POLLS = 60;
3292
- var attributesOf5 = (where, live) => ({
3358
+ var attributesOf6 = (where, live) => ({
3293
3359
  config: storedConfig(live),
3294
3360
  node: where.node,
3295
3361
  rawKeys: rawKeysOf(live),
3296
3362
  vmid: where.vmid
3297
3363
  });
3298
- var createGuest = (props) => Effect39.gen(function* () {
3364
+ var createGuest = (props) => Effect40.gen(function* () {
3299
3365
  const form = createForm4(props);
3300
3366
  yield* guardForm(LXC_ENDPOINTS.create, form, true);
3301
3367
  return yield* lxcTask(props, nodes10.createNodeLxc({
@@ -3305,7 +3371,7 @@ var createGuest = (props) => Effect39.gen(function* () {
3305
3371
  ostemplate: text(form["ostemplate"])
3306
3372
  }), `create CT ${String(props.vmid)}`, CREATE_POLLS);
3307
3373
  });
3308
- var updateGuest = (props, change, digest) => Effect39.gen(function* () {
3374
+ var updateGuest = (props, change, digest) => Effect40.gen(function* () {
3309
3375
  if (Object.keys(change.put).length > 0 || change.clear.length > 0) {
3310
3376
  const form = withClears({ ...change.put, ...digest === "" ? {} : { digest } }, change.clear);
3311
3377
  yield* guardForm(LXC_ENDPOINTS.update, form, false);
@@ -3317,47 +3383,47 @@ var updateGuest = (props, change, digest) => Effect39.gen(function* () {
3317
3383
  yield* lxcTask(props, nodes10.putNodeLxcResize({ ...grown, node: props.node, vmid: String(props.vmid) }), `grow ${grow.disk} of CT ${String(props.vmid)} to ${grow.size}`, TASK_POLLS);
3318
3384
  }
3319
3385
  });
3320
- var destroyGuest = (where, declared) => Effect39.gen(function* () {
3386
+ var destroyGuest = (where, declared) => Effect40.gen(function* () {
3321
3387
  const live = yield* readLive(where);
3322
3388
  if (live === undefined)
3323
3389
  return;
3324
3390
  const drift = judge(declared, live).drift;
3325
3391
  if (drift.length > 0) {
3326
- return yield* Effect39.fail(new LxcRefusedError(`destroy CT ${String(where.vmid)}: the guest on ${where.node} no longer matches its last ` + `declaration (${drift.join(", ")}), so it may not be the guest this stack made. ` + "Nothing was deleted. Delete it by hand if it should go, or declare it again."));
3392
+ return yield* Effect40.fail(new LxcRefusedError(`destroy CT ${String(where.vmid)}: the guest on ${where.node} no longer matches its last ` + `declaration (${drift.join(", ")}), so it may not be the guest this stack made. ` + "Nothing was deleted. Delete it by hand if it should go, or declare it again."));
3327
3393
  }
3328
3394
  yield* lxcTask(where, nodes10.deleteNodeLxc({ node: where.node, vmid: String(where.vmid) }), `destroy CT ${String(where.vmid)}`, TASK_POLLS);
3329
3395
  });
3330
3396
 
3331
3397
  // src/proxmox/lxc-adoption.ts
3332
3398
  var adoptionRefusal = (props, drift) => `CT ${String(props.vmid)} on ${props.node}: adopting it would change ${drift.join(", ")}. An ` + "adoption never changes a guest, so nothing is written. Declare what is live for these keys " + "(the plan names keys, never values) and plan again; change them after the adoption, as an " + "update.";
3333
- var refuseAdoptedDrift = (owner, props, live, change) => Effect40.gen(function* () {
3399
+ var refuseAdoptedDrift = (owner, props, live, change) => Effect41.gen(function* () {
3334
3400
  if (change.drift.length === 0)
3335
3401
  return;
3336
- const settled2 = (recorded) => Effect40.sync(() => judge(recorded, live).drift.length === 0);
3402
+ const settled2 = (recorded) => Effect41.sync(() => judge(recorded, live).drift.length === 0);
3337
3403
  if (!(yield* adopting(owner, settled2)))
3338
3404
  return;
3339
- return yield* Effect40.fail(new LxcRefusedError(adoptionRefusal(props, change.drift)));
3405
+ return yield* Effect41.fail(new LxcRefusedError(adoptionRefusal(props, change.drift)));
3340
3406
  });
3341
3407
 
3342
3408
  // src/proxmox/lxc.ts
3343
3409
  var ProxmoxLxc = Resource13("Proxmox.Lxc", { defaultRemovalPolicy: "retain" });
3344
- var refused = (reasons) => Effect41.fail(new LxcRefusedError(reasons.join(`
3410
+ var refused = (reasons) => Effect42.fail(new LxcRefusedError(reasons.join(`
3345
3411
  `)));
3346
- var diff = (owner, news, olds) => Effect41.gen(function* () {
3412
+ var diff = (owner, news, olds) => Effect42.gen(function* () {
3347
3413
  const { output } = owner;
3348
3414
  const identity2 = identityRefusals(news, olds, output);
3349
3415
  if (identity2.length > 0)
3350
3416
  return yield* refused(identity2);
3351
3417
  if (output === undefined)
3352
3418
  return;
3353
- if (!isResolved11(news))
3419
+ if (!isResolved12(news))
3354
3420
  return;
3355
3421
  const live = yield* readLive(news);
3356
3422
  if (live === undefined) {
3357
3423
  const refusals = createRefusals(news);
3358
3424
  if (refusals.length > 0)
3359
3425
  return yield* refused(refusals);
3360
- yield* Effect41.logWarning(`Proxmox.Lxc ${news.node}/${String(news.vmid)}: the cluster lists no guest with this ` + "vmid -- a deploy CREATES it again from ostemplate, with new, empty volumes.");
3426
+ yield* Effect42.logWarning(`Proxmox.Lxc ${news.node}/${String(news.vmid)}: the cluster lists no guest with this ` + "vmid -- a deploy CREATES it again from ostemplate, with new, empty volumes.");
3361
3427
  return { action: "update" };
3362
3428
  }
3363
3429
  const change = judge(news, live);
@@ -3368,10 +3434,10 @@ var diff = (owner, news, olds) => Effect41.gen(function* () {
3368
3434
  if (change.drift.length === 0 && !moved)
3369
3435
  return { action: "noop" };
3370
3436
  const what = change.drift.length === 0 ? `the guest is on ${news.node} now, not ${output.node} -- a deploy re-records it, ` + "writing nothing." : `live config differs from the declaration in ${change.drift.join(", ")} -- a ` + "deploy writes these.";
3371
- yield* Effect41.logWarning(`Proxmox.Lxc ${news.node}/${String(news.vmid)}: ${what}`);
3437
+ yield* Effect42.logWarning(`Proxmox.Lxc ${news.node}/${String(news.vmid)}: ${what}`);
3372
3438
  return { action: "update" };
3373
3439
  });
3374
- var reconcile = (owner, news) => Effect41.gen(function* () {
3440
+ var reconcile = (owner, news) => Effect42.gen(function* () {
3375
3441
  const { output } = owner;
3376
3442
  const identity2 = identityRefusals(news, news, output);
3377
3443
  if (identity2.length > 0)
@@ -3410,22 +3476,22 @@ var reconcile = (owner, news) => Effect41.gen(function* () {
3410
3476
  `CT ${String(news.vmid)}: after the write, ${left.join(", ")} still differ from the ` + "declaration. PVE may have normalised the value (tags are lower-cased by default) -- " + "declare what it stores."
3411
3477
  ]);
3412
3478
  }
3413
- return attributesOf5(news, after);
3479
+ return attributesOf6(news, after);
3414
3480
  });
3415
3481
  var whereOf = (olds, output) => ({
3416
3482
  node: output?.node ?? olds.node,
3417
3483
  target: olds.target,
3418
3484
  vmid: output?.vmid ?? olds.vmid
3419
3485
  });
3420
- var read = (owner, olds) => Effect41.gen(function* () {
3486
+ var read = (owner, olds) => Effect42.gen(function* () {
3421
3487
  const where = whereOf(olds, owner.output);
3422
3488
  const live = yield* readLive(where);
3423
3489
  if (live === undefined)
3424
3490
  return;
3425
- const settled2 = Effect41.sync(() => judge(olds, live).drift.length === 0);
3426
- return yield* ownedRead(owner, attributesOf5(where, live), settled2);
3491
+ const settled2 = Effect42.sync(() => judge(olds, live).drift.length === 0);
3492
+ return yield* ownedRead(owner, attributesOf6(where, live), settled2);
3427
3493
  });
3428
- var handlers5 = {
3494
+ var handlers4 = {
3429
3495
  delete: ({ olds, output }) => destroyGuest(whereOf(olds, output), olds),
3430
3496
  diff: ({
3431
3497
  fqn,
@@ -3434,7 +3500,7 @@ var handlers5 = {
3434
3500
  olds,
3435
3501
  output
3436
3502
  }) => diff({ fqn, instanceId, output }, news, olds),
3437
- list: () => Effect41.succeed([]),
3503
+ list: () => Effect42.succeed([]),
3438
3504
  read: ({
3439
3505
  fqn,
3440
3506
  instanceId,
@@ -3448,11 +3514,11 @@ var handlers5 = {
3448
3514
  output
3449
3515
  }) => reconcile({ fqn, instanceId, output }, news)
3450
3516
  };
3451
- var ProxmoxLxcProvider = () => Provider13.effect(ProxmoxLxc, Effect41.succeed(ProxmoxLxc.Provider.of(handlers5)).pipe(Effect41.map(provingResumes)));
3517
+ var ProxmoxLxcProvider = () => Provider13.effect(ProxmoxLxc, Effect42.succeed(ProxmoxLxc.Provider.of(handlers4)).pipe(Effect42.map(provingResumes)));
3452
3518
  // src/proxmox/metric-server.ts
3453
3519
  import { Resource as Resource14 } from "alchemy";
3454
- import { isResolved as isResolved12 } from "alchemy/Diff";
3455
- import * as cluster6 from "@distilled.cloud/proxmox/cluster";
3520
+ import { isResolved as isResolved13 } from "alchemy/Diff";
3521
+ import * as cluster7 from "@distilled.cloud/proxmox/cluster";
3456
3522
 
3457
3523
  // src/proxmox/metric-server-form.ts
3458
3524
  var UNSET2 = -1;
@@ -3566,15 +3632,15 @@ var metricServerSpec = {
3566
3632
  };
3567
3633
 
3568
3634
  // src/proxmox/metric-server-distilled.ts
3569
- import * as cluster5 from "@distilled.cloud/proxmox/cluster";
3635
+ import * as cluster6 from "@distilled.cloud/proxmox/cluster";
3570
3636
  import { ProxmoxParseError as ProxmoxParseError3 } from "@distilled.cloud/proxmox/Errors";
3571
- import * as Effect42 from "effect/Effect";
3637
+ import * as Effect43 from "effect/Effect";
3572
3638
  import * as Schema2 from "effect/Schema";
3573
- var readMetricServerRow = (props) => runPve(props.target, "read", false, cluster5.getClusterMetricsServer({ id: props.id })).pipe(Effect42.flatMap((body4) => Schema2.decodeUnknownEffect(Schema2.Record(Schema2.String, Schema2.Unknown))(body4).pipe(Effect42.mapError(() => new ProxmoxParseError3({
3639
+ var readMetricServerRow = (props) => runPve(props.target, "read", false, cluster6.getClusterMetricsServer({ id: props.id })).pipe(Effect43.flatMap((body4) => Schema2.decodeUnknownEffect(Schema2.Record(Schema2.String, Schema2.Unknown))(body4).pipe(Effect43.mapError(() => new ProxmoxParseError3({
3574
3640
  body: undefined,
3575
3641
  cause: "Metric server response must be an object"
3576
- })))), Effect42.catchTag("MetricServerNotFound", () => Effect42.succeed(undefined)), Effect42.catchTag("NotFound", () => Effect42.succeed(undefined)));
3577
- var readMetricServer = (props) => readMetricServerRow(props).pipe(Effect42.map((row) => row === undefined ? undefined : metricServerSpec.attributes(row, props)));
3642
+ })))), Effect43.catchTag("MetricServerNotFound", () => Effect43.succeed(undefined)), Effect43.catchTag("NotFound", () => Effect43.succeed(undefined)));
3643
+ var readMetricServer = (props) => readMetricServerRow(props).pipe(Effect43.map((row) => row === undefined ? undefined : metricServerSpec.attributes(row, props)));
3578
3644
  var metricServerRequest = (props, form) => ({
3579
3645
  ...asForm2({
3580
3646
  api_path_prefix: form["api-path-prefix"],
@@ -3599,22 +3665,22 @@ var metricServerRequest = (props, form) => ({
3599
3665
  port: String(props.port),
3600
3666
  server: props.server
3601
3667
  });
3602
- var deleteMetricServer = (props) => Effect42.gen(function* () {
3668
+ var deleteMetricServer = (props) => Effect43.gen(function* () {
3603
3669
  if ((yield* readMetricServerRow(props)) === undefined)
3604
3670
  return;
3605
- yield* runPve(props.target, "provision", true, cluster5.deleteClusterMetricsServer({ id: props.id }));
3671
+ yield* runPve(props.target, "provision", true, cluster6.deleteClusterMetricsServer({ id: props.id }));
3606
3672
  });
3607
3673
 
3608
3674
  // src/proxmox/metric-server.ts
3609
3675
  import * as Provider14 from "alchemy/Provider";
3610
- import * as Effect43 from "effect/Effect";
3676
+ import * as Effect44 from "effect/Effect";
3611
3677
  var ProxmoxMetricServer = Resource14("Proxmox.MetricServer");
3612
3678
  var { guardCreate: guardCreate3, guardUpdate: guardUpdate3 } = specGuards(metricServerSpec);
3613
- var ProxmoxMetricServerProvider = () => Provider14.effect(ProxmoxMetricServer, Effect43.succeed(ProxmoxMetricServer.Provider.of({
3614
- list: () => Effect43.succeed([]),
3679
+ var ProxmoxMetricServerProvider = () => Provider14.effect(ProxmoxMetricServer, Effect44.succeed(ProxmoxMetricServer.Provider.of({
3680
+ list: () => Effect44.succeed([]),
3615
3681
  read: ({ olds }) => readMetricServer(olds),
3616
- diff: Effect43.fn(function* ({ news, output }) {
3617
- if (!isResolved12(news))
3682
+ diff: Effect44.fn(function* ({ news, output }) {
3683
+ if (!isResolved13(news))
3618
3684
  return;
3619
3685
  yield* guardCreate3(news, output === undefined);
3620
3686
  yield* guardUpdate3(news);
@@ -3627,36 +3693,36 @@ var ProxmoxMetricServerProvider = () => Provider14.effect(ProxmoxMetricServer, E
3627
3693
  }
3628
3694
  return { action: metricServerSpec.matches(live, news) ? "noop" : "update" };
3629
3695
  }),
3630
- reconcile: Effect43.fn(function* ({ news }) {
3696
+ reconcile: Effect44.fn(function* ({ news }) {
3631
3697
  const live = yield* readMetricServer(news);
3632
3698
  yield* guardCreate3(news, live === undefined);
3633
3699
  yield* guardUpdate3(news);
3634
3700
  if (live === undefined) {
3635
- yield* runPve(news.target, "provision", true, cluster6.updateClusterMetricsServer({
3701
+ yield* runPve(news.target, "provision", true, cluster7.updateClusterMetricsServer({
3636
3702
  ...metricServerRequest(news, metricServerSpec.createForm(news)),
3637
3703
  type: news.type
3638
3704
  }));
3639
3705
  } else {
3640
3706
  const form = formToSend(metricServerSpec.matches, live, news, metricServerSpec.updateForm(news));
3641
3707
  if (form !== undefined)
3642
- yield* runPve(news.target, "provision", true, cluster6.putClusterMetricsServer(metricServerRequest(news, form)));
3708
+ yield* runPve(news.target, "provision", true, cluster7.putClusterMetricsServer(metricServerRequest(news, form)));
3643
3709
  }
3644
3710
  const after = yield* readMetricServer(news);
3645
3711
  if (after === undefined)
3646
- return yield* Effect43.fail(new Error(`${metricServerSpec.path(news)}: write returned success but the resource is still absent`));
3712
+ return yield* Effect44.fail(new Error(`${metricServerSpec.path(news)}: write returned success but the resource is still absent`));
3647
3713
  return after;
3648
3714
  }),
3649
3715
  delete: ({ olds }) => deleteMetricServer(olds)
3650
3716
  })));
3651
3717
  // src/proxmox/network-apply.ts
3652
3718
  import { Resource as Resource15 } from "alchemy";
3653
- import { isResolved as isResolved13 } from "alchemy/Diff";
3719
+ import { isResolved as isResolved14 } from "alchemy/Diff";
3654
3720
  import * as Provider15 from "alchemy/Provider";
3655
- import * as Effect46 from "effect/Effect";
3721
+ import * as Effect47 from "effect/Effect";
3656
3722
 
3657
3723
  // src/proxmox/network-apply-run.ts
3658
3724
  import * as nodes12 from "@distilled.cloud/proxmox/nodes";
3659
- import * as Effect45 from "effect/Effect";
3725
+ import * as Effect46 from "effect/Effect";
3660
3726
 
3661
3727
  // src/proxmox/apply-endpoints.ts
3662
3728
  var NETWORK_APPLY_ENDPOINT = "pve:PUT /nodes/{node}/network";
@@ -3665,10 +3731,10 @@ var guardNetworkApply = guardForm(NETWORK_APPLY_ENDPOINT, {}, true);
3665
3731
  var guardSdnApply = guardForm(SDN_APPLY_ENDPOINT, {}, true);
3666
3732
 
3667
3733
  // src/proxmox/network-apply-read.ts
3668
- import * as cluster7 from "@distilled.cloud/proxmox/cluster";
3734
+ import * as cluster8 from "@distilled.cloud/proxmox/cluster";
3669
3735
  import * as nodes11 from "@distilled.cloud/proxmox/nodes";
3670
- import * as Effect44 from "effect/Effect";
3671
- var stagedDiff = (target, node) => Effect44.gen(function* () {
3736
+ import * as Effect45 from "effect/Effect";
3737
+ var stagedDiff = (target, node) => Effect45.gen(function* () {
3672
3738
  const credential = yield* leased(target, "read");
3673
3739
  const live = yield* runPveWith(target, credential, false, nodes11.listNodeNetwork({ node }));
3674
3740
  return Array.isArray(live) ? "" : live.changes;
@@ -3680,36 +3746,36 @@ var pendingLines = (diff2) => {
3680
3746
  `).filter((line) => (line.startsWith("+") || line.startsWith("-")) && !line.startsWith("+++") && !line.startsWith("---")).length;
3681
3747
  return Math.max(changed, 1);
3682
3748
  };
3683
- var pendingCount = (target, node) => stagedDiff(target, node).pipe(Effect44.map(pendingLines));
3684
- var clusterHealth = (target) => runPve(target, "read", false, cluster7.listClusterStatus({})).pipe(Effect44.map((rows) => {
3749
+ var pendingCount = (target, node) => stagedDiff(target, node).pipe(Effect45.map(pendingLines));
3750
+ var clusterHealth = (target) => runPve(target, "read", false, cluster8.listClusterStatus({})).pipe(Effect45.map((rows) => {
3685
3751
  const all = rows ?? [];
3686
- const cluster8 = all.find((row) => row.type === "cluster");
3752
+ const cluster9 = all.find((row) => row.type === "cluster");
3687
3753
  return {
3688
3754
  offline: all.filter((row) => row.type === "node" && !bool(row.online)).map((row) => text(row.name, "<unnamed>")),
3689
- quorate: cluster8 === undefined ? true : bool(cluster8.quorate)
3755
+ quorate: cluster9 === undefined ? true : bool(cluster9.quorate)
3690
3756
  };
3691
3757
  }));
3692
- var degradedReason = (target) => clusterHealth(target).pipe(Effect44.map((health) => health.quorate && health.offline.length === 0 ? undefined : `quorate=${String(health.quorate)} offline=[${health.offline.join(", ")}]`));
3758
+ var degradedReason = (target) => clusterHealth(target).pipe(Effect45.map((health) => health.quorate && health.offline.length === 0 ? undefined : `quorate=${String(health.quorate)} offline=[${health.offline.join(", ")}]`));
3693
3759
  var UNREACHABLE = "the task could not be read -- the node stopped answering, or this lease cannot see it";
3694
3760
  var STILL_RUNNING = "still running when this provider stopped waiting";
3695
3761
  var ATTEMPTS = 30;
3696
- var awaitTask = (target, credential, node, upid, attempts = ATTEMPTS) => Effect44.gen(function* () {
3762
+ var awaitTask = (target, credential, node, upid, attempts = ATTEMPTS) => Effect45.gen(function* () {
3697
3763
  for (let attempt = 0;attempt < attempts; attempt += 1) {
3698
- const status = yield* runPveWith(target, credential, false, nodes11.getNodeTaskStatus({ node, upid })).pipe(Effect44.orElseSucceed(() => {
3764
+ const status = yield* runPveWith(target, credential, false, nodes11.getNodeTaskStatus({ node, upid })).pipe(Effect45.orElseSucceed(() => {
3699
3765
  return;
3700
3766
  }));
3701
3767
  if (status === undefined)
3702
3768
  return UNREACHABLE;
3703
3769
  if (status.status === "stopped")
3704
3770
  return text(status.exitstatus, "stopped with no exitstatus");
3705
- yield* Effect44.sleep("1 second");
3771
+ yield* Effect45.sleep("1 second");
3706
3772
  }
3707
3773
  return STILL_RUNNING;
3708
3774
  });
3709
3775
 
3710
3776
  // src/proxmox/network-apply-run.ts
3711
- var refuse = (node, why) => Effect45.die(new Error(`Proxmox.NetworkApply ${node}: ${why}`));
3712
- var applyNetwork = (props) => Effect45.gen(function* () {
3777
+ var refuse = (node, why) => Effect46.die(new Error(`Proxmox.NetworkApply ${node}: ${why}`));
3778
+ var applyNetwork = (props) => Effect46.gen(function* () {
3713
3779
  const node = props.node;
3714
3780
  const staged = yield* pendingCount(props.target, node);
3715
3781
  if (staged === 0)
@@ -3741,27 +3807,27 @@ var applyNetwork = (props) => Effect45.gen(function* () {
3741
3807
 
3742
3808
  // src/proxmox/network-apply.ts
3743
3809
  var ProxmoxNetworkApply = Resource15("Proxmox.NetworkApply");
3744
- var read2 = (props) => pendingCount(props.target, props.node).pipe(Effect46.map((pending) => ({ node: props.node, pending })));
3745
- var diff2 = (news) => Effect46.gen(function* () {
3746
- if (!isResolved13(news))
3810
+ var read2 = (props) => pendingCount(props.target, props.node).pipe(Effect47.map((pending) => ({ node: props.node, pending })));
3811
+ var diff2 = (news) => Effect47.gen(function* () {
3812
+ if (!isResolved14(news))
3747
3813
  return;
3748
3814
  const { pending } = yield* read2(news);
3749
3815
  return pending === 0 ? { action: "noop" } : { action: "update" };
3750
3816
  });
3751
- var handlers6 = {
3752
- delete: () => Effect46.void,
3817
+ var handlers5 = {
3818
+ delete: () => Effect47.void,
3753
3819
  diff: ({ news }) => diff2(news),
3754
- list: () => Effect46.succeed([]),
3820
+ list: () => Effect47.succeed([]),
3755
3821
  read: ({ olds }) => read2(olds),
3756
3822
  reconcile: ({ news }) => applyNetwork(news)
3757
3823
  };
3758
- var ProxmoxNetworkApplyProvider = () => Provider15.effect(ProxmoxNetworkApply, Effect46.succeed(ProxmoxNetworkApply.Provider.of(handlers6)));
3824
+ var ProxmoxNetworkApplyProvider = () => Provider15.effect(ProxmoxNetworkApply, Effect47.succeed(ProxmoxNetworkApply.Provider.of(handlers5)));
3759
3825
  // src/proxmox/node-network.ts
3760
3826
  import { Resource as Resource16 } from "alchemy";
3761
- import { isResolved as isResolved14 } from "alchemy/Diff";
3827
+ import { isResolved as isResolved15 } from "alchemy/Diff";
3762
3828
  import * as Provider16 from "alchemy/Provider";
3763
3829
  import * as nodes14 from "@distilled.cloud/proxmox/nodes";
3764
- import * as Effect48 from "effect/Effect";
3830
+ import * as Effect49 from "effect/Effect";
3765
3831
 
3766
3832
  // src/proxmox/node-network-form.ts
3767
3833
  var NODE_NETWORK_CREATE = "pve:POST /nodes/{node}/network";
@@ -3794,7 +3860,7 @@ var createForm5 = (props) => ({
3794
3860
  ...body4(props),
3795
3861
  iface: props.iface
3796
3862
  });
3797
- var updateForm2 = (props) => {
3863
+ var updateForm3 = (props) => {
3798
3864
  const clear = [
3799
3865
  ...props.cidr === undefined ? ["cidr"] : [],
3800
3866
  ...props.bridge_vlan_aware === false ? ["bridge_vlan_aware"] : []
@@ -3804,8 +3870,8 @@ var updateForm2 = (props) => {
3804
3870
 
3805
3871
  // src/proxmox/node-network-wire.ts
3806
3872
  import * as nodes13 from "@distilled.cloud/proxmox/nodes";
3807
- import * as Effect47 from "effect/Effect";
3808
- var attributesOf6 = (live, props) => {
3873
+ import * as Effect48 from "effect/Effect";
3874
+ var attributesOf7 = (live, props) => {
3809
3875
  const data = live;
3810
3876
  const liveType = text(data["type"]);
3811
3877
  if (liveType !== "" && liveType !== props.type)
@@ -3838,16 +3904,16 @@ var attributesOf6 = (live, props) => {
3838
3904
  "vlan-raw-device": text(data["vlan-raw-device"])
3839
3905
  };
3840
3906
  };
3841
- var readInterfaceOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, nodes13.getNodeNetwork({ iface: props.iface, node: props.node })).pipe(Effect47.catchTag("NetworkInterfaceNotFound", () => Effect47.succeed(undefined)))).pipe(Effect47.map((live) => {
3907
+ var readInterfaceOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, nodes13.getNodeNetwork({ iface: props.iface, node: props.node })).pipe(Effect48.catchTag("NetworkInterfaceNotFound", () => Effect48.succeed(undefined)))).pipe(Effect48.map((live) => {
3842
3908
  if (live === UNREADABLE)
3843
3909
  return UNREADABLE;
3844
- return live === undefined ? undefined : attributesOf6(live, props);
3910
+ return live === undefined ? undefined : attributesOf7(live, props);
3845
3911
  }));
3846
- var readInterface = (props) => readInterfaceOrFail(props).pipe(Effect47.orElseSucceed(() => {
3912
+ var readInterface = (props) => readInterfaceOrFail(props).pipe(Effect48.orElseSucceed(() => {
3847
3913
  return;
3848
3914
  }));
3849
3915
  var dropUnreadable4 = (live) => live === UNREADABLE ? undefined : live;
3850
- var matches5 = (attributes, props) => attributes.cidr === (props.cidr ?? "") && same2(props.gateway, attributes.gateway) && same2(props.autostart, attributes.autostart) && same2(props.mtu, attributes.mtu) && sameComment(props.comments, attributes.comments) && sameList(props.bridge_ports, attributes.bridge_ports) && sameList(props.bridge_vids, attributes.bridge_vids) && same2(props.bridge_vlan_aware, attributes.bridge_vlan_aware) && sameList(props.slaves, attributes.slaves) && same2(props.bond_mode, attributes.bond_mode) && same2(props.bond_xmit_hash_policy, attributes.bond_xmit_hash_policy) && same2(props["bond-primary"], attributes["bond-primary"]) && same2(props["vlan-id"], attributes["vlan-id"]) && same2(props["vlan-raw-device"], attributes["vlan-raw-device"]);
3916
+ var matches6 = (attributes, props) => attributes.cidr === (props.cidr ?? "") && same2(props.gateway, attributes.gateway) && same2(props.autostart, attributes.autostart) && same2(props.mtu, attributes.mtu) && sameComment(props.comments, attributes.comments) && sameList(props.bridge_ports, attributes.bridge_ports) && sameList(props.bridge_vids, attributes.bridge_vids) && same2(props.bridge_vlan_aware, attributes.bridge_vlan_aware) && sameList(props.slaves, attributes.slaves) && same2(props.bond_mode, attributes.bond_mode) && same2(props.bond_xmit_hash_policy, attributes.bond_xmit_hash_policy) && same2(props["bond-primary"], attributes["bond-primary"]) && same2(props["vlan-id"], attributes["vlan-id"]) && same2(props["vlan-raw-device"], attributes["vlan-raw-device"]);
3851
3917
 
3852
3918
  // src/proxmox/node-network.ts
3853
3919
  var ProxmoxNodeNetwork = Resource16("Proxmox.NodeNetwork", {
@@ -3864,20 +3930,20 @@ var toDistilledCreate3 = (props) => ({
3864
3930
  node: props.node
3865
3931
  });
3866
3932
  var toDistilledUpdate2 = (props) => ({
3867
- ...toDistilled(updateForm2(props)),
3933
+ ...toDistilled(updateForm3(props)),
3868
3934
  iface: props.iface,
3869
3935
  node: props.node
3870
3936
  });
3871
- var ProxmoxNodeNetworkProvider = () => Provider16.effect(ProxmoxNodeNetwork, Effect48.succeed(ProxmoxNodeNetwork.Provider.of({
3872
- list: () => Effect48.succeed([]),
3873
- read: Effect48.fn(function* ({ olds, output }) {
3937
+ var ProxmoxNodeNetworkProvider = () => Provider16.effect(ProxmoxNodeNetwork, Effect49.succeed(ProxmoxNodeNetwork.Provider.of({
3938
+ list: () => Effect49.succeed([]),
3939
+ read: Effect49.fn(function* ({ olds, output }) {
3874
3940
  return dropUnreadable4(yield* output === undefined ? readInterface(olds) : readInterfaceOrFail(olds));
3875
3941
  }),
3876
- diff: Effect48.fn(function* ({ news, output }) {
3877
- if (!isResolved14(news))
3942
+ diff: Effect49.fn(function* ({ news, output }) {
3943
+ if (!isResolved15(news))
3878
3944
  return;
3879
3945
  yield* guardWrite2(NODE_NETWORK_CREATE, createForm5(news), output === undefined);
3880
- yield* guardWrite2(NODE_NETWORK_UPDATE, updateForm2(news), false);
3946
+ yield* guardWrite2(NODE_NETWORK_UPDATE, updateForm3(news), false);
3881
3947
  if (output === undefined)
3882
3948
  return;
3883
3949
  const live = yield* readInterfaceOrFail(news);
@@ -3889,35 +3955,35 @@ var ProxmoxNodeNetworkProvider = () => Provider16.effect(ProxmoxNodeNetwork, Eff
3889
3955
  yield* guardWrite2(NODE_NETWORK_CREATE, createForm5(news), true);
3890
3956
  return { action: "update" };
3891
3957
  }
3892
- return matches5(live, news) ? { action: "noop" } : { action: "update" };
3958
+ return matches6(live, news) ? { action: "noop" } : { action: "update" };
3893
3959
  }),
3894
- reconcile: Effect48.fn(function* ({ news }) {
3960
+ reconcile: Effect49.fn(function* ({ news }) {
3895
3961
  const before = dropUnreadable4(yield* readInterface(news));
3896
3962
  yield* guardWrite2(NODE_NETWORK_CREATE, createForm5(news), before === undefined);
3897
- yield* guardWrite2(NODE_NETWORK_UPDATE, updateForm2(news), false);
3963
+ yield* guardWrite2(NODE_NETWORK_UPDATE, updateForm3(news), false);
3898
3964
  if (before === undefined) {
3899
3965
  yield* runPve(news.target, "provision", true, nodes14.createNodeNetwork(toDistilledCreate3(news)));
3900
- } else if (!matches5(before, news)) {
3966
+ } else if (!matches6(before, news)) {
3901
3967
  yield* runPve(news.target, "provision", true, nodes14.putNodeNetwork2(toDistilledUpdate2(news)));
3902
3968
  }
3903
3969
  const after = dropUnreadable4(yield* readInterface(news));
3904
3970
  if (after === undefined) {
3905
- return yield* Effect48.die(new Error(`nodes/${news.node}/network/${news.iface}: wrote with no error, but the ` + 'interface is still absent -- PVE wraps every answer in {"data":...} and can ' + "report success on a call that did nothing, so read back rather than trust it."));
3971
+ return yield* Effect49.die(new Error(`nodes/${news.node}/network/${news.iface}: wrote with no error, but the ` + 'interface is still absent -- PVE wraps every answer in {"data":...} and can ' + "report success on a call that did nothing, so read back rather than trust it."));
3906
3972
  }
3907
3973
  return after;
3908
3974
  }),
3909
- delete: Effect48.fn(function* ({ olds }) {
3975
+ delete: Effect49.fn(function* ({ olds }) {
3910
3976
  yield* runPve(olds.target, "provision", true, nodes14.deleteNodeNetwork2({ iface: olds.iface, node: olds.node }));
3911
3977
  })
3912
3978
  })));
3913
3979
  // src/proxmox/notification-matcher.ts
3914
3980
  import { Resource as Resource17 } from "alchemy";
3915
3981
  import * as Provider17 from "alchemy/Provider";
3916
- import * as Effect52 from "effect/Effect";
3982
+ import * as Effect53 from "effect/Effect";
3917
3983
 
3918
3984
  // src/proxmox/notification-matcher-lifecycle.ts
3919
- import { isResolved as isResolved15 } from "alchemy/Diff";
3920
- import * as Effect51 from "effect/Effect";
3985
+ import { isResolved as isResolved16 } from "alchemy/Diff";
3986
+ import * as Effect52 from "effect/Effect";
3921
3987
 
3922
3988
  // src/proxmox/notification-matcher-form.ts
3923
3989
  var list = (value) => Array.isArray(value) ? value.map((item) => String(item)) : [];
@@ -3994,49 +4060,49 @@ var matcherUpdateForm = (fields) => {
3994
4060
  };
3995
4061
 
3996
4062
  // src/proxmox/notification-matcher-distilled.ts
3997
- import * as cluster8 from "@distilled.cloud/proxmox/cluster";
3998
- import * as Effect50 from "effect/Effect";
4063
+ import * as cluster9 from "@distilled.cloud/proxmox/cluster";
4064
+ import * as Effect51 from "effect/Effect";
3999
4065
 
4000
4066
  // src/proxmox/notification-sdk-input.ts
4001
4067
  import { ProxmoxParseError as ProxmoxParseError4 } from "@distilled.cloud/proxmox/Errors";
4002
4068
  import * as Data2 from "effect/Data";
4003
- import * as Effect49 from "effect/Effect";
4069
+ import * as Effect50 from "effect/Effect";
4004
4070
  import * as Schema3 from "effect/Schema";
4005
4071
 
4006
4072
  class NotificationRequestInvalid extends Data2.TaggedError("NotificationRequestInvalid") {
4007
4073
  }
4008
- var notificationRequest = (schema, fields) => Schema3.decodeUnknownEffect(Schema3.toType(schema), { onExcessProperty: "error" })(Object.fromEntries(Object.entries(fields).map(([key, value]) => [key.replaceAll("-", "_"), value]))).pipe(Effect49.mapError(() => new NotificationRequestInvalid({ operation: "PVE notification write" })));
4009
- var notificationResponse = (schema) => (body5) => Schema3.decodeUnknownEffect(Schema3.toType(schema))(body5).pipe(Effect49.as(body5), Effect49.mapError(() => new ProxmoxParseError4({
4074
+ var notificationRequest = (schema, fields) => Schema3.decodeUnknownEffect(Schema3.toType(schema), { onExcessProperty: "error" })(Object.fromEntries(Object.entries(fields).map(([key, value]) => [key.replaceAll("-", "_"), value]))).pipe(Effect50.mapError(() => new NotificationRequestInvalid({ operation: "PVE notification write" })));
4075
+ var notificationResponse = (schema) => (body5) => Schema3.decodeUnknownEffect(Schema3.toType(schema))(body5).pipe(Effect50.as(body5), Effect50.mapError(() => new ProxmoxParseError4({
4010
4076
  body: undefined,
4011
4077
  cause: "PVE notification response does not match its SDK schema"
4012
4078
  })));
4013
4079
 
4014
4080
  // src/proxmox/notification-matcher-distilled.ts
4015
- var readMatcher = (props) => runPve(props.target, "read", false, cluster8.getClusterNotificationMatcher({ name: props.name })).pipe(Effect50.flatMap(notificationResponse(cluster8.GetClusterNotificationMatcherResponse)), Effect50.map((live) => matcherAttributes({
4081
+ var readMatcher = (props) => runPve(props.target, "read", false, cluster9.getClusterNotificationMatcher({ name: props.name })).pipe(Effect51.flatMap(notificationResponse(cluster9.GetClusterNotificationMatcherResponse)), Effect51.map((live) => matcherAttributes({
4016
4082
  ...live,
4017
4083
  "invert-match": live.invert_match,
4018
4084
  "match-calendar": live.match_calendar,
4019
4085
  "match-field": live.match_field,
4020
4086
  "match-severity": live.match_severity
4021
- }, props.name)), Effect50.catchTag("NotFound", () => Effect50.succeed(undefined)));
4022
- var createMatcher = (props) => Effect50.gen(function* () {
4023
- const input = yield* notificationRequest(cluster8.CreateClusterNotificationMatcherRequest, matcherCreateForm(props));
4024
- yield* runPve(props.target, "provision", true, cluster8.createClusterNotificationMatcher(input));
4087
+ }, props.name)), Effect51.catchTag("NotFound", () => Effect51.succeed(undefined)));
4088
+ var createMatcher = (props) => Effect51.gen(function* () {
4089
+ const input = yield* notificationRequest(cluster9.CreateClusterNotificationMatcherRequest, matcherCreateForm(props));
4090
+ yield* runPve(props.target, "provision", true, cluster9.createClusterNotificationMatcher(input));
4025
4091
  });
4026
- var updateMatcher = (props) => Effect50.gen(function* () {
4027
- const input = yield* notificationRequest(cluster8.PutClusterNotificationMatcherRequest, {
4092
+ var updateMatcher = (props) => Effect51.gen(function* () {
4093
+ const input = yield* notificationRequest(cluster9.PutClusterNotificationMatcherRequest, {
4028
4094
  ...matcherUpdateForm(props),
4029
4095
  name: props.name
4030
4096
  });
4031
- yield* runPve(props.target, "provision", true, cluster8.putClusterNotificationMatcher(input));
4097
+ yield* runPve(props.target, "provision", true, cluster9.putClusterNotificationMatcher(input));
4032
4098
  });
4033
- var deleteMatcher = (props) => runPve(props.target, "provision", true, cluster8.deleteClusterNotificationMatcher({ name: props.name })).pipe(Effect50.catchTag("NotFound", () => Effect50.void));
4099
+ var deleteMatcher = (props) => runPve(props.target, "provision", true, cluster9.deleteClusterNotificationMatcher({ name: props.name })).pipe(Effect51.catchTag("NotFound", () => Effect51.void));
4034
4100
 
4035
4101
  // src/proxmox/notification-matcher-lifecycle.ts
4036
- var guard = (props, create) => guardForm("pve:POST /cluster/notifications/matchers", matcherCreateForm(props), create).pipe(Effect51.andThen(guardForm("pve:PUT /cluster/notifications/matchers/{name}", matcherUpdateForm(props), false)));
4102
+ var guard = (props, create) => guardForm("pve:POST /cluster/notifications/matchers", matcherCreateForm(props), create).pipe(Effect52.andThen(guardForm("pve:PUT /cluster/notifications/matchers/{name}", matcherUpdateForm(props), false)));
4037
4103
  var matcherHandlers = {
4038
- list: () => Effect51.succeed([]),
4039
- read: ({ olds }) => Effect51.gen(function* () {
4104
+ list: () => Effect52.succeed([]),
4105
+ read: ({ olds }) => Effect52.gen(function* () {
4040
4106
  const live = yield* readMatcher(olds);
4041
4107
  yield* guard(olds, live === undefined);
4042
4108
  return live;
@@ -4045,8 +4111,8 @@ var matcherHandlers = {
4045
4111
  news,
4046
4112
  olds,
4047
4113
  output
4048
- }) => Effect51.gen(function* () {
4049
- if (!isResolved15(news))
4114
+ }) => Effect52.gen(function* () {
4115
+ if (!isResolved16(news))
4050
4116
  return;
4051
4117
  if (olds.name !== news.name)
4052
4118
  return { action: "replace" };
@@ -4060,7 +4126,7 @@ var matcherHandlers = {
4060
4126
  }
4061
4127
  return { action: matcherMatches(live, news) ? "noop" : "update" };
4062
4128
  }),
4063
- reconcile: ({ news }) => Effect51.gen(function* () {
4129
+ reconcile: ({ news }) => Effect52.gen(function* () {
4064
4130
  const live = yield* readMatcher(news);
4065
4131
  yield* guard(news, live === undefined);
4066
4132
  if (live === undefined)
@@ -4069,7 +4135,7 @@ var matcherHandlers = {
4069
4135
  yield* updateMatcher(news);
4070
4136
  const after = yield* readMatcher(news);
4071
4137
  if (after === undefined)
4072
- return yield* Effect51.die(new Error(`Notification matcher ${news.name}: write returned but read-back is absent.`));
4138
+ return yield* Effect52.die(new Error(`Notification matcher ${news.name}: write returned but read-back is absent.`));
4073
4139
  return after;
4074
4140
  }),
4075
4141
  delete: ({ olds }) => deleteMatcher(olds)
@@ -4077,15 +4143,15 @@ var matcherHandlers = {
4077
4143
 
4078
4144
  // src/proxmox/notification-matcher.ts
4079
4145
  var ProxmoxNotificationMatcher = Resource17("Proxmox.NotificationMatcher");
4080
- var ProxmoxNotificationMatcherProvider = () => Provider17.effect(ProxmoxNotificationMatcher, Effect52.succeed(ProxmoxNotificationMatcher.Provider.of(matcherHandlers)));
4146
+ var ProxmoxNotificationMatcherProvider = () => Provider17.effect(ProxmoxNotificationMatcher, Effect53.succeed(ProxmoxNotificationMatcher.Provider.of(matcherHandlers)));
4081
4147
  // src/proxmox/notification-target.ts
4082
4148
  import { Resource as Resource18 } from "alchemy";
4083
4149
  import * as Provider18 from "alchemy/Provider";
4084
- import * as Effect55 from "effect/Effect";
4150
+ import * as Effect56 from "effect/Effect";
4085
4151
 
4086
4152
  // src/proxmox/notification-target-lifecycle.ts
4087
- import { isResolved as isResolved16 } from "alchemy/Diff";
4088
- import * as Effect54 from "effect/Effect";
4153
+ import { isResolved as isResolved17 } from "alchemy/Diff";
4154
+ import * as Effect55 from "effect/Effect";
4089
4155
 
4090
4156
  // src/proxmox/notification-target-endpoint.ts
4091
4157
  var ENDPOINTS = {
@@ -4168,30 +4234,30 @@ var targetSpec = {
4168
4234
  };
4169
4235
 
4170
4236
  // src/proxmox/notification-target-distilled.ts
4171
- import * as cluster9 from "@distilled.cloud/proxmox/cluster";
4172
- import * as Effect53 from "effect/Effect";
4237
+ import * as cluster10 from "@distilled.cloud/proxmox/cluster";
4238
+ import * as Effect54 from "effect/Effect";
4173
4239
  var read3 = (props) => {
4174
4240
  const request = { name: props.name };
4175
4241
  switch (props.type) {
4176
4242
  case "gotify":
4177
- return cluster9.getClusterNotificationEndpointGotify(request).pipe(Effect53.flatMap(notificationResponse(cluster9.GetClusterNotificationEndpointGotifyResponse)), Effect53.map((row) => ({ ...row })));
4243
+ return cluster10.getClusterNotificationEndpointGotify(request).pipe(Effect54.flatMap(notificationResponse(cluster10.GetClusterNotificationEndpointGotifyResponse)), Effect54.map((row) => ({ ...row })));
4178
4244
  case "sendmail":
4179
- return cluster9.getClusterNotificationEndpointSendmail(request).pipe(Effect53.flatMap(notificationResponse(cluster9.GetClusterNotificationEndpointSendmailResponse)), Effect53.map((row) => ({
4245
+ return cluster10.getClusterNotificationEndpointSendmail(request).pipe(Effect54.flatMap(notificationResponse(cluster10.GetClusterNotificationEndpointSendmailResponse)), Effect54.map((row) => ({
4180
4246
  ...row,
4181
4247
  "from-address": row.from_address,
4182
4248
  "mailto-user": row.mailto_user
4183
4249
  })));
4184
4250
  case "smtp":
4185
- return cluster9.getClusterNotificationEndpointSmtp(request).pipe(Effect53.flatMap(notificationResponse(cluster9.GetClusterNotificationEndpointSmtpResponse)), Effect53.map((row) => ({
4251
+ return cluster10.getClusterNotificationEndpointSmtp(request).pipe(Effect54.flatMap(notificationResponse(cluster10.GetClusterNotificationEndpointSmtpResponse)), Effect54.map((row) => ({
4186
4252
  ...row,
4187
4253
  "from-address": row.from_address,
4188
4254
  "mailto-user": row.mailto_user
4189
4255
  })));
4190
4256
  case "webhook":
4191
- return cluster9.getClusterNotificationEndpointWebhook(request).pipe(Effect53.flatMap(notificationResponse(cluster9.GetClusterNotificationEndpointWebhookResponse)), Effect53.map((row) => ({ ...row })));
4257
+ return cluster10.getClusterNotificationEndpointWebhook(request).pipe(Effect54.flatMap(notificationResponse(cluster10.GetClusterNotificationEndpointWebhookResponse)), Effect54.map((row) => ({ ...row })));
4192
4258
  }
4193
4259
  };
4194
- var readTarget = (props) => runPve(props.target, "read", false, read3(props)).pipe(Effect53.map((row) => targetSpec.attributes(row, props)), Effect53.catchTag("NotFound", () => Effect53.succeed(undefined)));
4260
+ var readTarget = (props) => runPve(props.target, "read", false, read3(props)).pipe(Effect54.map((row) => targetSpec.attributes(row, props)), Effect54.catchTag("NotFound", () => Effect54.succeed(undefined)));
4195
4261
  var fields = (props, create) => {
4196
4262
  const form = {
4197
4263
  ...create ? createShape(props) : shape4(props),
@@ -4225,40 +4291,40 @@ var fields = (props, create) => {
4225
4291
  };
4226
4292
  var validateTargetWrite = (props, create) => {
4227
4293
  const schema = create ? {
4228
- sendmail: cluster9.CreateClusterNotificationEndpointSendmailRequest,
4229
- smtp: cluster9.CreateClusterNotificationEndpointSmtpRequest,
4230
- gotify: cluster9.CreateClusterNotificationEndpointGotifyRequest,
4231
- webhook: cluster9.CreateClusterNotificationEndpointWebhookRequest
4294
+ sendmail: cluster10.CreateClusterNotificationEndpointSendmailRequest,
4295
+ smtp: cluster10.CreateClusterNotificationEndpointSmtpRequest,
4296
+ gotify: cluster10.CreateClusterNotificationEndpointGotifyRequest,
4297
+ webhook: cluster10.CreateClusterNotificationEndpointWebhookRequest
4232
4298
  }[props.type] : {
4233
- sendmail: cluster9.PutClusterNotificationEndpointSendmailRequest,
4234
- smtp: cluster9.PutClusterNotificationEndpointSmtpRequest,
4235
- gotify: cluster9.PutClusterNotificationEndpointGotifyRequest,
4236
- webhook: cluster9.PutClusterNotificationEndpointWebhookRequest
4299
+ sendmail: cluster10.PutClusterNotificationEndpointSendmailRequest,
4300
+ smtp: cluster10.PutClusterNotificationEndpointSmtpRequest,
4301
+ gotify: cluster10.PutClusterNotificationEndpointGotifyRequest,
4302
+ webhook: cluster10.PutClusterNotificationEndpointWebhookRequest
4237
4303
  }[props.type];
4238
- return notificationRequest(schema, fields(props, create)).pipe(Effect53.asVoid);
4304
+ return notificationRequest(schema, fields(props, create)).pipe(Effect54.asVoid);
4239
4305
  };
4240
4306
  var createTarget = (props) => {
4241
4307
  const form = fields(props, true);
4242
- const operation = props.type === "sendmail" ? notificationRequest(cluster9.CreateClusterNotificationEndpointSendmailRequest, form).pipe(Effect53.flatMap(cluster9.createClusterNotificationEndpointSendmail)) : props.type === "smtp" ? notificationRequest(cluster9.CreateClusterNotificationEndpointSmtpRequest, form).pipe(Effect53.flatMap(cluster9.createClusterNotificationEndpointSmtp)) : props.type === "gotify" ? notificationRequest(cluster9.CreateClusterNotificationEndpointGotifyRequest, form).pipe(Effect53.flatMap(cluster9.createClusterNotificationEndpointGotify)) : notificationRequest(cluster9.CreateClusterNotificationEndpointWebhookRequest, form).pipe(Effect53.flatMap(cluster9.createClusterNotificationEndpointWebhook));
4308
+ const operation = props.type === "sendmail" ? notificationRequest(cluster10.CreateClusterNotificationEndpointSendmailRequest, form).pipe(Effect54.flatMap(cluster10.createClusterNotificationEndpointSendmail)) : props.type === "smtp" ? notificationRequest(cluster10.CreateClusterNotificationEndpointSmtpRequest, form).pipe(Effect54.flatMap(cluster10.createClusterNotificationEndpointSmtp)) : props.type === "gotify" ? notificationRequest(cluster10.CreateClusterNotificationEndpointGotifyRequest, form).pipe(Effect54.flatMap(cluster10.createClusterNotificationEndpointGotify)) : notificationRequest(cluster10.CreateClusterNotificationEndpointWebhookRequest, form).pipe(Effect54.flatMap(cluster10.createClusterNotificationEndpointWebhook));
4243
4309
  return runPve(props.target, "provision", true, operation);
4244
4310
  };
4245
4311
  var updateTarget = (props) => {
4246
4312
  const form = fields(props, false);
4247
- const operation = props.type === "sendmail" ? notificationRequest(cluster9.PutClusterNotificationEndpointSendmailRequest, form).pipe(Effect53.flatMap(cluster9.putClusterNotificationEndpointSendmail)) : props.type === "smtp" ? notificationRequest(cluster9.PutClusterNotificationEndpointSmtpRequest, form).pipe(Effect53.flatMap(cluster9.putClusterNotificationEndpointSmtp)) : props.type === "gotify" ? notificationRequest(cluster9.PutClusterNotificationEndpointGotifyRequest, form).pipe(Effect53.flatMap(cluster9.putClusterNotificationEndpointGotify)) : notificationRequest(cluster9.PutClusterNotificationEndpointWebhookRequest, form).pipe(Effect53.flatMap(cluster9.putClusterNotificationEndpointWebhook));
4313
+ const operation = props.type === "sendmail" ? notificationRequest(cluster10.PutClusterNotificationEndpointSendmailRequest, form).pipe(Effect54.flatMap(cluster10.putClusterNotificationEndpointSendmail)) : props.type === "smtp" ? notificationRequest(cluster10.PutClusterNotificationEndpointSmtpRequest, form).pipe(Effect54.flatMap(cluster10.putClusterNotificationEndpointSmtp)) : props.type === "gotify" ? notificationRequest(cluster10.PutClusterNotificationEndpointGotifyRequest, form).pipe(Effect54.flatMap(cluster10.putClusterNotificationEndpointGotify)) : notificationRequest(cluster10.PutClusterNotificationEndpointWebhookRequest, form).pipe(Effect54.flatMap(cluster10.putClusterNotificationEndpointWebhook));
4248
4314
  return runPve(props.target, "provision", true, operation);
4249
4315
  };
4250
4316
  var deleteTarget = (props) => {
4251
4317
  const request = { name: props.name };
4252
- const operation = props.type === "sendmail" ? cluster9.deleteClusterNotificationEndpointSendmail(request) : props.type === "smtp" ? cluster9.deleteClusterNotificationEndpointSmtp(request) : props.type === "gotify" ? cluster9.deleteClusterNotificationEndpointGotify(request) : cluster9.deleteClusterNotificationEndpointWebhook(request);
4253
- return runPve(props.target, "provision", true, operation).pipe(Effect53.catchTag("NotFound", () => Effect53.void));
4318
+ const operation = props.type === "sendmail" ? cluster10.deleteClusterNotificationEndpointSendmail(request) : props.type === "smtp" ? cluster10.deleteClusterNotificationEndpointSmtp(request) : props.type === "gotify" ? cluster10.deleteClusterNotificationEndpointGotify(request) : cluster10.deleteClusterNotificationEndpointWebhook(request);
4319
+ return runPve(props.target, "provision", true, operation).pipe(Effect54.catchTag("NotFound", () => Effect54.void));
4254
4320
  };
4255
4321
 
4256
4322
  // src/proxmox/notification-target-lifecycle.ts
4257
4323
  var { guardCreate: guardCreate4, guardUpdate: guardUpdate4 } = specGuards(targetSpec);
4258
- var guard2 = (props, create) => guardCreate4(props, create).pipe(Effect54.andThen(guardUpdate4(props)));
4324
+ var guard2 = (props, create) => guardCreate4(props, create).pipe(Effect55.andThen(guardUpdate4(props)));
4259
4325
  var targetHandlers = {
4260
- list: () => Effect54.succeed([]),
4261
- read: ({ olds }) => Effect54.gen(function* () {
4326
+ list: () => Effect55.succeed([]),
4327
+ read: ({ olds }) => Effect55.gen(function* () {
4262
4328
  const live = yield* readTarget(olds);
4263
4329
  yield* guard2(olds, live === undefined);
4264
4330
  return live;
@@ -4267,8 +4333,8 @@ var targetHandlers = {
4267
4333
  news,
4268
4334
  olds,
4269
4335
  output
4270
- }) => Effect54.gen(function* () {
4271
- if (!isResolved16(news))
4336
+ }) => Effect55.gen(function* () {
4337
+ if (!isResolved17(news))
4272
4338
  return;
4273
4339
  if (olds.name !== news.name || olds.type !== news.type) {
4274
4340
  const destination = yield* readTarget(news);
@@ -4286,7 +4352,7 @@ var targetHandlers = {
4286
4352
  }
4287
4353
  return { action: targetSpec.matches(live, news) ? "noop" : "update" };
4288
4354
  }),
4289
- reconcile: ({ news }) => Effect54.gen(function* () {
4355
+ reconcile: ({ news }) => Effect55.gen(function* () {
4290
4356
  const live = yield* readTarget(news);
4291
4357
  yield* guard2(news, live === undefined);
4292
4358
  if (live === undefined)
@@ -4295,7 +4361,7 @@ var targetHandlers = {
4295
4361
  yield* updateTarget(news);
4296
4362
  const after = yield* readTarget(news);
4297
4363
  if (after === undefined)
4298
- return yield* Effect54.die(new Error(`Notification target ${news.name}: write returned but read-back is absent.`));
4364
+ return yield* Effect55.die(new Error(`Notification target ${news.name}: write returned but read-back is absent.`));
4299
4365
  return after;
4300
4366
  }),
4301
4367
  delete: ({ olds }) => deleteTarget(olds)
@@ -4303,15 +4369,15 @@ var targetHandlers = {
4303
4369
 
4304
4370
  // src/proxmox/notification-target.ts
4305
4371
  var ProxmoxNotificationTarget = Resource18("Proxmox.NotificationTarget");
4306
- var ProxmoxNotificationTargetProvider = () => Provider18.effect(ProxmoxNotificationTarget, Effect55.succeed(ProxmoxNotificationTarget.Provider.of(targetHandlers)));
4372
+ var ProxmoxNotificationTargetProvider = () => Provider18.effect(ProxmoxNotificationTarget, Effect56.succeed(ProxmoxNotificationTarget.Provider.of(targetHandlers)));
4307
4373
  // src/proxmox/pbs-datastore.ts
4308
4374
  import { Resource as Resource19 } from "alchemy";
4309
4375
  import * as Provider19 from "alchemy/Provider";
4310
- import * as Effect61 from "effect/Effect";
4376
+ import * as Effect62 from "effect/Effect";
4311
4377
 
4312
4378
  // src/proxmox/pbs-datastore-lifecycle.ts
4313
- import { isResolved as isResolved17 } from "alchemy/Diff";
4314
- import * as Effect60 from "effect/Effect";
4379
+ import { isResolved as isResolved18 } from "alchemy/Diff";
4380
+ import * as Effect61 from "effect/Effect";
4315
4381
 
4316
4382
  // src/proxmox/pbs-datastore-form.ts
4317
4383
  var attributes = (live, props) => ({
@@ -4336,7 +4402,7 @@ var attributes = (live, props) => ({
4336
4402
  "verify-new": bool(live["verify-new"])
4337
4403
  });
4338
4404
  var same4 = (declared, live) => declared === undefined || declared === live;
4339
- var matches6 = (live, props) => same4(props.comment, live.comment) && same4(props["gc-schedule"]?.trim(), live["gc-schedule"]) && same4(props["prune-schedule"]?.trim(), live["prune-schedule"]) && same4(props["keep-last"], live["keep-last"]) && same4(props["keep-hourly"], live["keep-hourly"]) && same4(props["keep-daily"], live["keep-daily"]) && same4(props["keep-weekly"], live["keep-weekly"]) && same4(props["keep-monthly"], live["keep-monthly"]) && same4(props["keep-yearly"], live["keep-yearly"]) && same4(props["notify-user"], live["notify-user"]) && same4(props["counter-reset-schedule"]?.trim(), live["counter-reset-schedule"]) && (props["notification-thresholds"] === undefined || propertyString(props["notification-thresholds"]) === live["notification-thresholds"]) && same4(props["verify-new"], live["verify-new"]) && (props.notify === undefined || propertyString(props.notify) === live.notify) && (props.tuning === undefined || propertyString(props.tuning) === live.tuning) && (props["maintenance-mode"] === undefined || propertyString(props["maintenance-mode"], "type") === live["maintenance-mode"]);
4405
+ var matches7 = (live, props) => same4(props.comment, live.comment) && same4(props["gc-schedule"]?.trim(), live["gc-schedule"]) && same4(props["prune-schedule"]?.trim(), live["prune-schedule"]) && same4(props["keep-last"], live["keep-last"]) && same4(props["keep-hourly"], live["keep-hourly"]) && same4(props["keep-daily"], live["keep-daily"]) && same4(props["keep-weekly"], live["keep-weekly"]) && same4(props["keep-monthly"], live["keep-monthly"]) && same4(props["keep-yearly"], live["keep-yearly"]) && same4(props["notify-user"], live["notify-user"]) && same4(props["counter-reset-schedule"]?.trim(), live["counter-reset-schedule"]) && (props["notification-thresholds"] === undefined || propertyString(props["notification-thresholds"]) === live["notification-thresholds"]) && same4(props["verify-new"], live["verify-new"]) && (props.notify === undefined || propertyString(props.notify) === live.notify) && (props.tuning === undefined || propertyString(props.tuning) === live.tuning) && (props["maintenance-mode"] === undefined || propertyString(props["maintenance-mode"], "type") === live["maintenance-mode"]);
4340
4406
  var set2 = (key, value) => value === undefined ? {} : { [key]: value };
4341
4407
  var count = (value) => value === undefined ? undefined : String(value);
4342
4408
  var mutable = (props) => ({
@@ -4363,23 +4429,23 @@ var createForm6 = (props) => ({
4363
4429
  path: props.path,
4364
4430
  ...props.backend === undefined ? {} : { backend: props.backend }
4365
4431
  });
4366
- var updateForm3 = (props) => mutable(props);
4432
+ var updateForm4 = (props) => mutable(props);
4367
4433
  var object2 = (props) => `config/datastore/${props.name}`;
4368
4434
 
4369
4435
  // src/proxmox/pbs-datastore-wire.ts
4370
4436
  import * as config from "@distilled.cloud/proxmox-backup/config";
4371
- import * as Effect57 from "effect/Effect";
4437
+ import * as Effect58 from "effect/Effect";
4372
4438
 
4373
4439
  // src/proxmox/distilled-pbs.ts
4374
4440
  import { credentials } from "@distilled.cloud/proxmox-backup/Credentials";
4375
4441
  import * as Retry from "@distilled.cloud/proxmox-backup/Retry";
4376
- import * as Effect56 from "effect/Effect";
4377
- var runPbsWith = (target, credential, op, timeout5 = MEMBER_TIMEOUT) => op.pipe(Retry.none, Effect56.provide(credentials({
4442
+ import * as Effect57 from "effect/Effect";
4443
+ var runPbsWith = (target, credential, op, timeout5 = MEMBER_TIMEOUT) => op.pipe(Retry.none, Effect57.provide(credentials({
4378
4444
  baseUrl: target.api,
4379
4445
  secret: credential.secret,
4380
4446
  tokenId: credential.tokenId
4381
- })), Effect56.timeout(timeout5));
4382
- var runPbs = (target, role, op) => Effect56.gen(function* () {
4447
+ })), Effect57.timeout(timeout5));
4448
+ var runPbs = (target, role, op) => Effect57.gen(function* () {
4383
4449
  const credential = yield* leased(target, role);
4384
4450
  return yield* runPbsWith(target, credential, op);
4385
4451
  });
@@ -4410,7 +4476,7 @@ var createRequest = (props) => ({
4410
4476
  ...props.backend === undefined ? {} : { backend: props.backend }
4411
4477
  });
4412
4478
  var updateRequest = (props) => ({
4413
- ...members(updateForm3(props)),
4479
+ ...members(updateForm4(props)),
4414
4480
  name: props.name
4415
4481
  });
4416
4482
  var wire = (row) => ({
@@ -4429,53 +4495,53 @@ var wire = (row) => ({
4429
4495
  "prune-schedule": row.prune_schedule,
4430
4496
  "verify-new": row.verify_new
4431
4497
  });
4432
- var readOne = (props) => runPbs(props.target, "read", config.getConfigDatastore({ name: props.name })).pipe(Effect57.map((live) => attributes(wire(live), props)), Effect57.catchTag("DatastoreNotFound", () => Effect57.succeed(undefined)));
4498
+ var readOne = (props) => runPbs(props.target, "read", config.getConfigDatastore({ name: props.name })).pipe(Effect58.map((live) => attributes(wire(live), props)), Effect58.catchTag("DatastoreNotFound", () => Effect58.succeed(undefined)));
4433
4499
  var createOne = (props) => runPbs(props.target, "provision", config.createConfigDatastore(createRequest(props)));
4434
4500
  var updateOne = (props) => runPbs(props.target, "provision", config.putConfigDatastore(updateRequest(props)));
4435
- var deleteOne = (props) => Effect57.gen(function* () {
4501
+ var deleteOne = (props) => Effect58.gen(function* () {
4436
4502
  if ((yield* readOne(props)) === undefined)
4437
4503
  return;
4438
4504
  return yield* runPbs(props.target, "provision", config.deleteConfigDatastore({ name: props.name }));
4439
4505
  });
4440
4506
 
4441
4507
  // src/proxmox/pbs-datastore-guard.ts
4442
- import * as Effect58 from "effect/Effect";
4508
+ import * as Effect59 from "effect/Effect";
4443
4509
  var samePath = (left, right) => {
4444
4510
  const trim = (value) => value.length > 1 ? value.replace(/\/+$/, "") : value;
4445
4511
  return trim(left) === trim(right);
4446
4512
  };
4447
- var guardPath = (live, props) => live.path === "" || samePath(live.path, props.path) ? Effect58.void : Effect58.die(new Error(`${object2(props)}: declared path ${props.path} but PBS holds ${live.path}. \`path\` ` + "is create-only, so this cannot be reconciled and will NOT be planned as a silent " + "noop: backups would keep landing in the old directory behind a green plan. Correct " + "the declaration, or remove the datastore and declare a new one -- the contents live, " + "because `destroy-data` is never sent."));
4448
- var guardBackend = (live, props) => props.backend === undefined || propertyString(props.backend) === live.backend ? Effect58.void : Effect58.die(new Error(`${object2(props)}: declared backend ${props.backend} but PBS holds ` + `${live.backend === "" ? "(none — a local datastore)" : live.backend}. \`backend\` ` + "is create-only: PBS has no update for it, so this cannot be reconciled and will NOT " + "be planned as a silent noop. Correct the declaration to match what is really there, " + "or remove the datastore and declare a new one -- the contents live, because " + "`destroy-data` is never sent."));
4449
- var settle2 = (read4, done) => Effect58.gen(function* () {
4513
+ var guardPath = (live, props) => live.path === "" || samePath(live.path, props.path) ? Effect59.void : Effect59.die(new Error(`${object2(props)}: declared path ${props.path} but PBS holds ${live.path}. \`path\` ` + "is create-only, so this cannot be reconciled and will NOT be planned as a silent " + "noop: backups would keep landing in the old directory behind a green plan. Correct " + "the declaration, or remove the datastore and declare a new one -- the contents live, " + "because `destroy-data` is never sent."));
4514
+ var guardBackend = (live, props) => props.backend === undefined || propertyString(props.backend) === live.backend ? Effect59.void : Effect59.die(new Error(`${object2(props)}: declared backend ${props.backend} but PBS holds ` + `${live.backend === "" ? "(none — a local datastore)" : live.backend}. \`backend\` ` + "is create-only: PBS has no update for it, so this cannot be reconciled and will NOT " + "be planned as a silent noop. Correct the declaration to match what is really there, " + "or remove the datastore and declare a new one -- the contents live, because " + "`destroy-data` is never sent."));
4515
+ var settle2 = (read4, done) => Effect59.gen(function* () {
4450
4516
  for (let attempt = 0;attempt < 60; attempt += 1) {
4451
4517
  const live = yield* read4;
4452
4518
  if (done(live))
4453
4519
  return live;
4454
- yield* Effect58.sleep("2 seconds");
4520
+ yield* Effect59.sleep("2 seconds");
4455
4521
  }
4456
4522
  return yield* read4;
4457
4523
  });
4458
4524
 
4459
4525
  // src/proxmox/pbs-datastore-endpoint.ts
4460
- import * as Effect59 from "effect/Effect";
4526
+ import * as Effect60 from "effect/Effect";
4461
4527
  var DATASTORE_ENDPOINT = {
4462
4528
  create: "pbs:POST /config/datastore",
4463
4529
  update: "pbs:PUT /config/datastore/{name}"
4464
4530
  };
4465
- var guardDatastoreForms = (props) => Effect59.gen(function* () {
4531
+ var guardDatastoreForms = (props) => Effect60.gen(function* () {
4466
4532
  yield* guardForm(DATASTORE_ENDPOINT.create, createForm6(props), true);
4467
- yield* guardForm(DATASTORE_ENDPOINT.update, updateForm3(props), false);
4533
+ yield* guardForm(DATASTORE_ENDPOINT.update, updateForm4(props), false);
4468
4534
  });
4469
4535
 
4470
4536
  // src/proxmox/pbs-datastore-lifecycle.ts
4471
- var handlers7 = {
4472
- list: () => Effect60.succeed([]),
4537
+ var handlers6 = {
4538
+ list: () => Effect61.succeed([]),
4473
4539
  read: ({ olds }) => readOne(olds),
4474
4540
  diff: ({
4475
4541
  news,
4476
4542
  output
4477
- }) => Effect60.gen(function* () {
4478
- if (!isResolved17(news))
4543
+ }) => Effect61.gen(function* () {
4544
+ if (!isResolved18(news))
4479
4545
  return;
4480
4546
  yield* guardDatastoreForms(news);
4481
4547
  if (output === undefined)
@@ -4485,9 +4551,9 @@ var handlers7 = {
4485
4551
  return { action: "update" };
4486
4552
  yield* guardPath(live, news);
4487
4553
  yield* guardBackend(live, news);
4488
- return matches6(live, news) ? { action: "noop" } : { action: "update" };
4554
+ return matches7(live, news) ? { action: "noop" } : { action: "update" };
4489
4555
  }),
4490
- reconcile: Effect60.fn(function* ({ news }) {
4556
+ reconcile: Effect61.fn(function* ({ news }) {
4491
4557
  yield* guardDatastoreForms(news);
4492
4558
  const live = yield* readOne(news);
4493
4559
  if (live === undefined) {
@@ -4495,22 +4561,22 @@ var handlers7 = {
4495
4561
  } else {
4496
4562
  yield* guardPath(live, news);
4497
4563
  yield* guardBackend(live, news);
4498
- const form = formToSend(matches6, live, news, updateForm3(news));
4564
+ const form = formToSend(matches7, live, news, updateForm4(news));
4499
4565
  if (form !== undefined) {
4500
4566
  yield* updateOne(news);
4501
4567
  }
4502
4568
  }
4503
- const after = yield* settle2(readOne(news), (row) => row !== undefined && matches6(row, news));
4504
- if (after === undefined || !matches6(after, news)) {
4505
- return yield* Effect60.die(new Error(`${object2(news)}: the write returned no error but the datastore still does not ` + "match the declaration after 120s. Check the PBS task list " + "-- read it with `proxmox-backup-manager task log <upid>`. A slow disk is a " + "plausible cause (see `settle`); a create over an existing chunk store is not, " + "because PBS refuses that outright rather than timing out."));
4569
+ const after = yield* settle2(readOne(news), (row) => row !== undefined && matches7(row, news));
4570
+ if (after === undefined || !matches7(after, news)) {
4571
+ return yield* Effect61.die(new Error(`${object2(news)}: the write returned no error but the datastore still does not ` + "match the declaration after 120s. Check the PBS task list " + "-- read it with `proxmox-backup-manager task log <upid>`. A slow disk is a " + "plausible cause (see `settle`); a create over an existing chunk store is not, " + "because PBS refuses that outright rather than timing out."));
4506
4572
  }
4507
4573
  return after;
4508
4574
  }),
4509
- delete: Effect60.fn(function* ({ olds }) {
4575
+ delete: Effect61.fn(function* ({ olds }) {
4510
4576
  yield* deleteOne(olds);
4511
4577
  const left = yield* settle2(readOne(olds), (row) => row === undefined);
4512
4578
  if (left !== undefined) {
4513
- return yield* Effect60.die(new Error(`${object2(olds)}: the DELETE returned no error but the datastore is still in ` + "datastore.cfg after 120s. Either a backup, verify or GC task still holds it, " + "or the provision role lacks Datastore.Allocate on /datastore/" + `${olds.name}. Read the task log with \`proxmox-backup-manager task log <upid>\`.`));
4579
+ return yield* Effect61.die(new Error(`${object2(olds)}: the DELETE returned no error but the datastore is still in ` + "datastore.cfg after 120s. Either a backup, verify or GC task still holds it, " + "or the provision role lacks Datastore.Allocate on /datastore/" + `${olds.name}. Read the task log with \`proxmox-backup-manager task log <upid>\`.`));
4514
4580
  }
4515
4581
  })
4516
4582
  };
@@ -4519,36 +4585,36 @@ var handlers7 = {
4519
4585
  var PbsDatastore = Resource19("Pbs.Datastore", {
4520
4586
  defaultRemovalPolicy: "retain"
4521
4587
  });
4522
- var PbsDatastoreProvider = () => Provider19.effect(PbsDatastore, Effect61.succeed(PbsDatastore.Provider.of(handlers7)));
4588
+ var PbsDatastoreProvider = () => Provider19.effect(PbsDatastore, Effect62.succeed(PbsDatastore.Provider.of(handlers6)));
4523
4589
  // src/proxmox/pbs-notification-matcher.ts
4524
4590
  import { Resource as Resource20 } from "alchemy";
4525
4591
  import * as Provider20 from "alchemy/Provider";
4526
- import { isResolved as isResolved18 } from "alchemy/Diff";
4527
- import * as Effect64 from "effect/Effect";
4592
+ import { isResolved as isResolved19 } from "alchemy/Diff";
4593
+ import * as Effect65 from "effect/Effect";
4528
4594
 
4529
4595
  // src/proxmox/pbs-notification-matcher-distilled.ts
4530
4596
  import * as config2 from "@distilled.cloud/proxmox-backup/config";
4531
- import * as Effect63 from "effect/Effect";
4597
+ import * as Effect64 from "effect/Effect";
4532
4598
 
4533
4599
  // src/proxmox/pbs-notification-input.ts
4534
4600
  import * as Data3 from "effect/Data";
4535
- import * as Effect62 from "effect/Effect";
4601
+ import * as Effect63 from "effect/Effect";
4536
4602
  import * as Schema4 from "effect/Schema";
4537
4603
 
4538
4604
  class PbsNotificationInputRefusal extends Data3.TaggedError("PbsNotificationInputRefusal") {
4539
4605
  }
4540
- var notificationInput = (schema, fields2) => Schema4.decodeUnknownEffect(Schema4.toType(schema))(fields2).pipe(Effect62.mapError(() => new PbsNotificationInputRefusal({
4606
+ var notificationInput = (schema, fields2) => Schema4.decodeUnknownEffect(Schema4.toType(schema))(fields2).pipe(Effect63.mapError(() => new PbsNotificationInputRefusal({
4541
4607
  message: "PBS notification fields do not match the SDK request schema; no PBS request was sent."
4542
4608
  })));
4543
4609
 
4544
4610
  // src/proxmox/pbs-notification-matcher-distilled.ts
4545
- var readMatcher2 = (props) => runPbs(props.target, "read", config2.getConfigNotificationMatcher({ name: props.name })).pipe(Effect63.map((row) => matcherAttributes({
4611
+ var readMatcher2 = (props) => runPbs(props.target, "read", config2.getConfigNotificationMatcher({ name: props.name })).pipe(Effect64.map((row) => matcherAttributes({
4546
4612
  ...row,
4547
4613
  "invert-match": row.invert_match,
4548
4614
  "match-calendar": row.match_calendar,
4549
4615
  "match-field": row.match_field,
4550
4616
  "match-severity": row.match_severity
4551
- }, props.name)), Effect63.catchTag("NotFound", () => Effect63.succeed(undefined)));
4617
+ }, props.name)), Effect64.catchTag("NotFound", () => Effect64.succeed(undefined)));
4552
4618
  var requestFields = (props, form) => ({
4553
4619
  ...form,
4554
4620
  invert_match: form["invert-match"],
@@ -4557,23 +4623,23 @@ var requestFields = (props, form) => ({
4557
4623
  match_severity: form["match-severity"],
4558
4624
  name: props.name
4559
4625
  });
4560
- var createMatcher2 = (props, form) => runPbs(props.target, "provision", notificationInput(config2.CreateConfigNotificationMatcherRequest, requestFields(props, form)).pipe(Effect63.flatMap(config2.createConfigNotificationMatcher)));
4561
- var updateMatcher2 = (props, form) => runPbs(props.target, "provision", notificationInput(config2.PutConfigNotificationMatcherRequest, requestFields(props, form)).pipe(Effect63.flatMap(config2.putConfigNotificationMatcher)));
4562
- var deleteMatcher2 = (props) => runPbs(props.target, "provision", config2.deleteConfigNotificationMatcher({ name: props.name })).pipe(Effect63.catchTag("NotFound", () => Effect63.void));
4626
+ var createMatcher2 = (props, form) => runPbs(props.target, "provision", notificationInput(config2.CreateConfigNotificationMatcherRequest, requestFields(props, form)).pipe(Effect64.flatMap(config2.createConfigNotificationMatcher)));
4627
+ var updateMatcher2 = (props, form) => runPbs(props.target, "provision", notificationInput(config2.PutConfigNotificationMatcherRequest, requestFields(props, form)).pipe(Effect64.flatMap(config2.putConfigNotificationMatcher)));
4628
+ var deleteMatcher2 = (props) => runPbs(props.target, "provision", config2.deleteConfigNotificationMatcher({ name: props.name })).pipe(Effect64.catchTag("NotFound", () => Effect64.void));
4563
4629
 
4564
4630
  // src/proxmox/pbs-notification-matcher.ts
4565
4631
  var PbsNotificationMatcher = Resource20("Pbs.NotificationMatcher");
4566
4632
  var guardCreate5 = (props, requirePresence) => guardForm("pbs:POST /config/notifications/matchers", matcherCreateForm(props), requirePresence);
4567
4633
  var guardUpdate5 = (props) => guardForm("pbs:PUT /config/notifications/matchers/{name}", matcherUpdateForm(props), false);
4568
- var handlers8 = {
4569
- list: () => Effect64.succeed([]),
4634
+ var handlers7 = {
4635
+ list: () => Effect65.succeed([]),
4570
4636
  read: ({ olds }) => readMatcher2(olds),
4571
4637
  diff: ({
4572
4638
  news,
4573
4639
  olds,
4574
4640
  output
4575
- }) => Effect64.gen(function* () {
4576
- if (!isResolved18(news))
4641
+ }) => Effect65.gen(function* () {
4642
+ if (!isResolved19(news))
4577
4643
  return;
4578
4644
  yield* guardCreate5(news, output === undefined);
4579
4645
  yield* guardUpdate5(news);
@@ -4588,7 +4654,7 @@ var handlers8 = {
4588
4654
  }
4589
4655
  return { action: matcherMatches(live, news) ? "noop" : "update" };
4590
4656
  }),
4591
- reconcile: ({ news }) => Effect64.gen(function* () {
4657
+ reconcile: ({ news }) => Effect65.gen(function* () {
4592
4658
  const live = yield* readMatcher2(news);
4593
4659
  yield* guardCreate5(news, live === undefined);
4594
4660
  yield* guardUpdate5(news);
@@ -4598,24 +4664,24 @@ var handlers8 = {
4598
4664
  yield* updateMatcher2(news, matcherUpdateForm(news));
4599
4665
  const after = yield* readMatcher2(news);
4600
4666
  if (after === undefined)
4601
- return yield* Effect64.fail(new Error(`config/notifications/matchers/${news.name}: the write returned no error but the matcher is still absent.`));
4667
+ return yield* Effect65.fail(new Error(`config/notifications/matchers/${news.name}: the write returned no error but the matcher is still absent.`));
4602
4668
  return after;
4603
4669
  }),
4604
4670
  delete: ({ olds }) => deleteMatcher2(olds)
4605
4671
  };
4606
- var PbsNotificationMatcherProvider = () => Provider20.effect(PbsNotificationMatcher, Effect64.succeed(PbsNotificationMatcher.Provider.of(handlers8)));
4672
+ var PbsNotificationMatcherProvider = () => Provider20.effect(PbsNotificationMatcher, Effect65.succeed(PbsNotificationMatcher.Provider.of(handlers7)));
4607
4673
  // src/proxmox/pbs-notification-target.ts
4608
4674
  import { Resource as Resource21 } from "alchemy";
4609
4675
  import * as Provider21 from "alchemy/Provider";
4610
- import * as Effect67 from "effect/Effect";
4676
+ import * as Effect68 from "effect/Effect";
4611
4677
 
4612
4678
  // src/proxmox/pbs-notification-target-lifecycle.ts
4613
- import { isResolved as isResolved19 } from "alchemy/Diff";
4614
- import * as Effect66 from "effect/Effect";
4679
+ import { isResolved as isResolved20 } from "alchemy/Diff";
4680
+ import * as Effect67 from "effect/Effect";
4615
4681
 
4616
4682
  // src/proxmox/pbs-notification-target-distilled.ts
4617
4683
  import * as config3 from "@distilled.cloud/proxmox-backup/config";
4618
- import * as Effect65 from "effect/Effect";
4684
+ import * as Effect66 from "effect/Effect";
4619
4685
 
4620
4686
  // src/proxmox/pbs-notification-target-wire.ts
4621
4687
  import { Buffer as Buffer2 } from "node:buffer";
@@ -4716,22 +4782,22 @@ var requestFields2 = (props, form) => ({
4716
4782
  var read4 = (props) => {
4717
4783
  switch (props.type) {
4718
4784
  case "sendmail":
4719
- return config3.getConfigNotificationEndpointSendmail({ name: props.name }).pipe(Effect65.map((row) => ({
4785
+ return config3.getConfigNotificationEndpointSendmail({ name: props.name }).pipe(Effect66.map((row) => ({
4720
4786
  ...row,
4721
4787
  "from-address": row.from_address,
4722
4788
  "mailto-user": row.mailto_user
4723
4789
  })));
4724
4790
  case "smtp":
4725
- return config3.getConfigNotificationEndpointSmtp({ name: props.name }).pipe(Effect65.map((row) => ({
4791
+ return config3.getConfigNotificationEndpointSmtp({ name: props.name }).pipe(Effect66.map((row) => ({
4726
4792
  ...row,
4727
4793
  "from-address": row.from_address,
4728
4794
  "mailto-user": row.mailto_user
4729
4795
  })));
4730
4796
  case "webhook":
4731
- return config3.getConfigNotificationEndpointWebhook({ name: props.name }).pipe(Effect65.map((row) => ({ ...row })));
4797
+ return config3.getConfigNotificationEndpointWebhook({ name: props.name }).pipe(Effect66.map((row) => ({ ...row })));
4732
4798
  }
4733
4799
  };
4734
- var readTarget2 = (props) => runPbs(props.target, "read", read4(props)).pipe(Effect65.map((row) => targetAttributes(row, props)), Effect65.catchTag("NotFound", () => Effect65.succeed(undefined)));
4800
+ var readTarget2 = (props) => runPbs(props.target, "read", read4(props)).pipe(Effect66.map((row) => targetAttributes(row, props)), Effect66.catchTag("NotFound", () => Effect66.succeed(undefined)));
4735
4801
  var validateTargetWrite2 = (props, form, mode) => {
4736
4802
  const schema = mode === "create" ? {
4737
4803
  sendmail: config3.CreateConfigNotificationEndpointSendmailRequest,
@@ -4742,22 +4808,22 @@ var validateTargetWrite2 = (props, form, mode) => {
4742
4808
  smtp: config3.PutConfigNotificationEndpointSmtpRequest,
4743
4809
  webhook: config3.PutConfigNotificationEndpointWebhookRequest
4744
4810
  }[props.type];
4745
- return notificationInput(schema, requestFields2(props, form)).pipe(Effect65.asVoid);
4811
+ return notificationInput(schema, requestFields2(props, form)).pipe(Effect66.asVoid);
4746
4812
  };
4747
4813
  var createTarget2 = (props, form) => {
4748
4814
  const fields2 = requestFields2(props, form);
4749
- const operation = props.type === "sendmail" ? notificationInput(config3.CreateConfigNotificationEndpointSendmailRequest, fields2).pipe(Effect65.flatMap(config3.createConfigNotificationEndpointSendmail)) : props.type === "smtp" ? notificationInput(config3.CreateConfigNotificationEndpointSmtpRequest, fields2).pipe(Effect65.flatMap(config3.createConfigNotificationEndpointSmtp)) : notificationInput(config3.CreateConfigNotificationEndpointWebhookRequest, fields2).pipe(Effect65.flatMap(config3.createConfigNotificationEndpointWebhook));
4815
+ const operation = props.type === "sendmail" ? notificationInput(config3.CreateConfigNotificationEndpointSendmailRequest, fields2).pipe(Effect66.flatMap(config3.createConfigNotificationEndpointSendmail)) : props.type === "smtp" ? notificationInput(config3.CreateConfigNotificationEndpointSmtpRequest, fields2).pipe(Effect66.flatMap(config3.createConfigNotificationEndpointSmtp)) : notificationInput(config3.CreateConfigNotificationEndpointWebhookRequest, fields2).pipe(Effect66.flatMap(config3.createConfigNotificationEndpointWebhook));
4750
4816
  return runPbs(props.target, "provision", operation);
4751
4817
  };
4752
4818
  var updateTarget2 = (props, form) => {
4753
4819
  const fields2 = requestFields2(props, form);
4754
- const operation = props.type === "sendmail" ? notificationInput(config3.PutConfigNotificationEndpointSendmailRequest, fields2).pipe(Effect65.flatMap(config3.putConfigNotificationEndpointSendmail)) : props.type === "smtp" ? notificationInput(config3.PutConfigNotificationEndpointSmtpRequest, fields2).pipe(Effect65.flatMap(config3.putConfigNotificationEndpointSmtp)) : notificationInput(config3.PutConfigNotificationEndpointWebhookRequest, fields2).pipe(Effect65.flatMap(config3.putConfigNotificationEndpointWebhook));
4820
+ const operation = props.type === "sendmail" ? notificationInput(config3.PutConfigNotificationEndpointSendmailRequest, fields2).pipe(Effect66.flatMap(config3.putConfigNotificationEndpointSendmail)) : props.type === "smtp" ? notificationInput(config3.PutConfigNotificationEndpointSmtpRequest, fields2).pipe(Effect66.flatMap(config3.putConfigNotificationEndpointSmtp)) : notificationInput(config3.PutConfigNotificationEndpointWebhookRequest, fields2).pipe(Effect66.flatMap(config3.putConfigNotificationEndpointWebhook));
4755
4821
  return runPbs(props.target, "provision", operation);
4756
4822
  };
4757
4823
  var deleteTarget2 = (props) => {
4758
4824
  const request = { name: props.name };
4759
4825
  const operation = props.type === "sendmail" ? config3.deleteConfigNotificationEndpointSendmail(request) : props.type === "smtp" ? config3.deleteConfigNotificationEndpointSmtp(request) : config3.deleteConfigNotificationEndpointWebhook(request);
4760
- return runPbs(props.target, "provision", operation).pipe(Effect65.catchTag("NotFound", () => Effect65.void));
4826
+ return runPbs(props.target, "provision", operation).pipe(Effect66.catchTag("NotFound", () => Effect66.void));
4761
4827
  };
4762
4828
 
4763
4829
  // src/proxmox/pbs-notification-target-endpoint.ts
@@ -4948,7 +5014,7 @@ var targetForm = (props, groups, carry, mode) => {
4948
5014
  var path = (props) => `config/notifications/endpoints/${props.type}/${props.name}`;
4949
5015
  var refuse2 = (props) => {
4950
5016
  const reasons = refusals(props);
4951
- return reasons.length === 0 ? Effect66.void : Effect66.die(new Error(`${path(props)}: ${reasons.join("; ")}.`));
5017
+ return reasons.length === 0 ? Effect67.void : Effect67.die(new Error(`${path(props)}: ${reasons.join("; ")}.`));
4952
5018
  };
4953
5019
  var toCarry = (live, props, groups, sealed) => {
4954
5020
  const header = headerState(live, props, groups) === "stale";
@@ -4960,17 +5026,17 @@ var requireValues = (props, groups, carry) => {
4960
5026
  ...carry.header ? groups.header.missing : [],
4961
5027
  ...carry.sealed ? groups.sealed.missing : []
4962
5028
  ];
4963
- return missing.length === 0 ? Effect66.void : Effect66.die(new Error(`${path(props)}: this write must send write-only values, and ${missing.join(", ")} ` + "is unset or empty in the deploying environment. Export it and deploy again."));
5029
+ return missing.length === 0 ? Effect67.void : Effect67.die(new Error(`${path(props)}: this write must send write-only values, and ${missing.join(", ")} ` + "is unset or empty in the deploying environment. Export it and deploy again."));
4964
5030
  };
4965
- var handlers9 = {
4966
- list: () => Effect66.succeed([]),
4967
- read: ({ olds, output }) => (output === undefined ? refuse2(olds) : Effect66.void).pipe(Effect66.andThen(readTarget2(olds)), Effect66.map((live) => live === undefined ? undefined : { ...live, sealed: output?.sealed ?? "" })),
5031
+ var handlers8 = {
5032
+ list: () => Effect67.succeed([]),
5033
+ read: ({ olds, output }) => (output === undefined ? refuse2(olds) : Effect67.void).pipe(Effect67.andThen(readTarget2(olds)), Effect67.map((live) => live === undefined ? undefined : { ...live, sealed: output?.sealed ?? "" })),
4968
5034
  diff: ({
4969
5035
  news,
4970
5036
  olds,
4971
5037
  output
4972
- }) => Effect66.gen(function* () {
4973
- if (output === undefined || !isResolved19(news))
5038
+ }) => Effect67.gen(function* () {
5039
+ if (output === undefined || !isResolved20(news))
4974
5040
  return;
4975
5041
  yield* refuse2(news);
4976
5042
  if (olds !== undefined && (olds.type !== news.type || olds.name !== news.name)) {
@@ -4991,7 +5057,7 @@ var handlers9 = {
4991
5057
  return { action: "update" };
4992
5058
  return toCarry(live, news, resolveGroups(news), output.sealed) === undefined ? { action: "noop" } : { action: "update" };
4993
5059
  }),
4994
- reconcile: ({ news, output }) => Effect66.gen(function* () {
5060
+ reconcile: ({ news, output }) => Effect67.gen(function* () {
4995
5061
  yield* refuse2(news);
4996
5062
  const groups = resolveGroups(news);
4997
5063
  const live = yield* readTarget2(news);
@@ -5016,7 +5082,7 @@ var handlers9 = {
5016
5082
  }
5017
5083
  const after = yield* readTarget2(news);
5018
5084
  if (after === undefined) {
5019
- return yield* Effect66.die(new Error(`${path(news)}: the write returned no error but the target is still absent.`));
5085
+ return yield* Effect67.die(new Error(`${path(news)}: the write returned no error but the target is still absent.`));
5020
5086
  }
5021
5087
  return { ...after, sealed };
5022
5088
  }),
@@ -5025,15 +5091,15 @@ var handlers9 = {
5025
5091
 
5026
5092
  // src/proxmox/pbs-notification-target.ts
5027
5093
  var PbsNotificationTarget = Resource21("Pbs.NotificationTarget");
5028
- var PbsNotificationTargetProvider = () => Provider21.effect(PbsNotificationTarget, Effect67.succeed(PbsNotificationTarget.Provider.of(handlers9)));
5094
+ var PbsNotificationTargetProvider = () => Provider21.effect(PbsNotificationTarget, Effect68.succeed(PbsNotificationTarget.Provider.of(handlers8)));
5029
5095
  // src/proxmox/pbs-prune-job.ts
5030
5096
  import { Resource as Resource22 } from "alchemy";
5031
5097
  import * as Provider22 from "alchemy/Provider";
5032
- import * as Effect70 from "effect/Effect";
5098
+ import * as Effect71 from "effect/Effect";
5033
5099
 
5034
5100
  // src/proxmox/pbs-prune-job-lifecycle.ts
5035
- import { isResolved as isResolved20 } from "alchemy/Diff";
5036
- import * as Effect69 from "effect/Effect";
5101
+ import { isResolved as isResolved21 } from "alchemy/Diff";
5102
+ import * as Effect70 from "effect/Effect";
5037
5103
 
5038
5104
  // src/proxmox/pbs-prune-job-form.ts
5039
5105
  var KEEP_KEYS = [
@@ -5111,7 +5177,7 @@ var spec = {
5111
5177
 
5112
5178
  // src/proxmox/pbs-prune-job-wire.ts
5113
5179
  import * as config4 from "@distilled.cloud/proxmox-backup/config";
5114
- import * as Effect68 from "effect/Effect";
5180
+ import * as Effect69 from "effect/Effect";
5115
5181
  var members2 = (form) => ({
5116
5182
  ...form["comment"] === undefined ? {} : { comment: form["comment"] },
5117
5183
  ...form["disable"] === undefined ? {} : { disable: form["disable"] },
@@ -5146,10 +5212,10 @@ var wire2 = (row) => ({
5146
5212
  "keep-yearly": row.keep_yearly,
5147
5213
  "max-depth": row.max_depth
5148
5214
  });
5149
- var readOne2 = (props) => runPbs(props.target, "read", config4.getConfigPrune({ id: props.id })).pipe(Effect68.map((row) => spec.attributes(wire2(row), props)), Effect68.catchTag("PruneJobNotFound", () => Effect68.succeed(undefined)));
5215
+ var readOne2 = (props) => runPbs(props.target, "read", config4.getConfigPrune({ id: props.id })).pipe(Effect69.map((row) => spec.attributes(wire2(row), props)), Effect69.catchTag("PruneJobNotFound", () => Effect69.succeed(undefined)));
5150
5216
  var createOne2 = (props) => runPbs(props.target, "provision", config4.createConfigPrune(createRequest2(props)));
5151
5217
  var updateOne2 = (props) => runPbs(props.target, "provision", config4.putConfigPrune(updateRequest2(props)));
5152
- var deleteOne2 = (props) => Effect68.gen(function* () {
5218
+ var deleteOne2 = (props) => Effect69.gen(function* () {
5153
5219
  if ((yield* readOne2(props)) === undefined)
5154
5220
  return;
5155
5221
  return yield* runPbs(props.target, "provision", config4.deleteConfigPrune({ id: props.id }));
@@ -5157,14 +5223,14 @@ var deleteOne2 = (props) => Effect68.gen(function* () {
5157
5223
 
5158
5224
  // src/proxmox/pbs-prune-job-lifecycle.ts
5159
5225
  var { guardCreate: guardCreate6, guardUpdate: guardUpdate6 } = specGuards(spec);
5160
- var handlers10 = {
5161
- list: () => Effect69.succeed([]),
5226
+ var handlers9 = {
5227
+ list: () => Effect70.succeed([]),
5162
5228
  read: ({ olds }) => readOne2(olds),
5163
5229
  diff: ({
5164
5230
  news,
5165
5231
  output
5166
- }) => Effect69.gen(function* () {
5167
- if (!isResolved20(news))
5232
+ }) => Effect70.gen(function* () {
5233
+ if (!isResolved21(news))
5168
5234
  return;
5169
5235
  yield* guardCreate6(news, output === undefined);
5170
5236
  yield* guardUpdate6(news);
@@ -5177,7 +5243,7 @@ var handlers10 = {
5177
5243
  }
5178
5244
  return { action: spec.matches(live, news) ? "noop" : "update" };
5179
5245
  }),
5180
- reconcile: ({ news }) => Effect69.gen(function* () {
5246
+ reconcile: ({ news }) => Effect70.gen(function* () {
5181
5247
  const live = yield* readOne2(news);
5182
5248
  yield* guardCreate6(news, live === undefined);
5183
5249
  yield* guardUpdate6(news);
@@ -5187,7 +5253,7 @@ var handlers10 = {
5187
5253
  yield* updateOne2(news);
5188
5254
  const after = yield* readOne2(news);
5189
5255
  if (after === undefined) {
5190
- return yield* Effect69.fail(new Error(`${spec.path(news)}: write succeeded but job is absent.`));
5256
+ return yield* Effect70.fail(new Error(`${spec.path(news)}: write succeeded but job is absent.`));
5191
5257
  }
5192
5258
  return after;
5193
5259
  }),
@@ -5196,15 +5262,15 @@ var handlers10 = {
5196
5262
 
5197
5263
  // src/proxmox/pbs-prune-job.ts
5198
5264
  var PbsPruneJob = Resource22("Pbs.PruneJob");
5199
- var PbsPruneJobProvider = () => Provider22.effect(PbsPruneJob, Effect70.succeed(PbsPruneJob.Provider.of(handlers10)));
5265
+ var PbsPruneJobProvider = () => Provider22.effect(PbsPruneJob, Effect71.succeed(PbsPruneJob.Provider.of(handlers9)));
5200
5266
  // src/proxmox/pbs-sync-job.ts
5201
5267
  import { Resource as Resource23 } from "alchemy";
5202
5268
  import * as Provider23 from "alchemy/Provider";
5203
- import * as Effect73 from "effect/Effect";
5269
+ import * as Effect74 from "effect/Effect";
5204
5270
 
5205
5271
  // src/proxmox/pbs-sync-job-lifecycle.ts
5206
- import { isResolved as isResolved21 } from "alchemy/Diff";
5207
- import * as Effect72 from "effect/Effect";
5272
+ import { isResolved as isResolved22 } from "alchemy/Diff";
5273
+ import * as Effect73 from "effect/Effect";
5208
5274
 
5209
5275
  // src/proxmox/pbs-sync-job-form.ts
5210
5276
  var UNSET4 = -1;
@@ -5281,7 +5347,7 @@ var spec2 = {
5281
5347
 
5282
5348
  // src/proxmox/pbs-sync-job-wire.ts
5283
5349
  import * as config5 from "@distilled.cloud/proxmox-backup/config";
5284
- import * as Effect71 from "effect/Effect";
5350
+ import * as Effect72 from "effect/Effect";
5285
5351
  var members3 = (form) => ({
5286
5352
  ...form["remote-store"] === undefined ? {} : { remote_store: form["remote-store"] },
5287
5353
  ...form["remove-vanished"] === undefined ? {} : { remove_vanished: form["remove-vanished"] },
@@ -5320,10 +5386,10 @@ var wire3 = (row) => ({
5320
5386
  "sync-direction": row.sync_direction,
5321
5387
  "group-filter": row.group_filter
5322
5388
  });
5323
- var readOne3 = (props) => runPbs(props.target, "read", config5.getConfigSync({ id: props.id })).pipe(Effect71.map((row) => spec2.attributes(wire3(row), props)), Effect71.catchTag("SyncJobNotFound", () => Effect71.succeed(undefined)));
5389
+ var readOne3 = (props) => runPbs(props.target, "read", config5.getConfigSync({ id: props.id })).pipe(Effect72.map((row) => spec2.attributes(wire3(row), props)), Effect72.catchTag("SyncJobNotFound", () => Effect72.succeed(undefined)));
5324
5390
  var createOne3 = (props) => runPbs(props.target, "provision", config5.syncConfig(createRequest3(props)));
5325
5391
  var updateOne3 = (props) => runPbs(props.target, "provision", config5.putConfigSync(updateRequest3(props)));
5326
- var deleteOne3 = (props) => Effect71.gen(function* () {
5392
+ var deleteOne3 = (props) => Effect72.gen(function* () {
5327
5393
  if ((yield* readOne3(props)) === undefined)
5328
5394
  return;
5329
5395
  return yield* runPbs(props.target, "provision", config5.deleteConfigSync({ id: props.id }));
@@ -5331,11 +5397,11 @@ var deleteOne3 = (props) => Effect71.gen(function* () {
5331
5397
 
5332
5398
  // src/proxmox/pbs-sync-job-lifecycle.ts
5333
5399
  var { guardCreate: guardCreate7, guardUpdate: guardUpdate7 } = specGuards(spec2);
5334
- var handlers11 = {
5335
- list: () => Effect72.succeed([]),
5400
+ var handlers10 = {
5401
+ list: () => Effect73.succeed([]),
5336
5402
  read: ({ olds }) => readOne3(olds),
5337
- diff: ({ news, output }) => Effect72.gen(function* () {
5338
- if (!isResolved21(news))
5403
+ diff: ({ news, output }) => Effect73.gen(function* () {
5404
+ if (!isResolved22(news))
5339
5405
  return;
5340
5406
  yield* guardCreate7(news, output === undefined);
5341
5407
  yield* guardUpdate7(news);
@@ -5348,7 +5414,7 @@ var handlers11 = {
5348
5414
  }
5349
5415
  return { action: spec2.matches(live, news) ? "noop" : "update" };
5350
5416
  }),
5351
- reconcile: ({ news }) => Effect72.gen(function* () {
5417
+ reconcile: ({ news }) => Effect73.gen(function* () {
5352
5418
  const live = yield* readOne3(news);
5353
5419
  yield* guardCreate7(news, live === undefined);
5354
5420
  yield* guardUpdate7(news);
@@ -5358,7 +5424,7 @@ var handlers11 = {
5358
5424
  yield* updateOne3(news);
5359
5425
  const after = yield* readOne3(news);
5360
5426
  if (after === undefined) {
5361
- return yield* Effect72.fail(new Error(`${spec2.path(news)}: write succeeded but job is absent.`));
5427
+ return yield* Effect73.fail(new Error(`${spec2.path(news)}: write succeeded but job is absent.`));
5362
5428
  }
5363
5429
  return after;
5364
5430
  }),
@@ -5367,15 +5433,15 @@ var handlers11 = {
5367
5433
 
5368
5434
  // src/proxmox/pbs-sync-job.ts
5369
5435
  var PbsSyncJob = Resource23("Pbs.SyncJob");
5370
- var PbsSyncJobProvider = () => Provider23.effect(PbsSyncJob, Effect73.succeed(PbsSyncJob.Provider.of(handlers11)));
5436
+ var PbsSyncJobProvider = () => Provider23.effect(PbsSyncJob, Effect74.succeed(PbsSyncJob.Provider.of(handlers10)));
5371
5437
  // src/proxmox/pbs-verify-job.ts
5372
5438
  import { Resource as Resource24 } from "alchemy";
5373
5439
  import * as Provider24 from "alchemy/Provider";
5374
- import * as Effect76 from "effect/Effect";
5440
+ import * as Effect77 from "effect/Effect";
5375
5441
 
5376
5442
  // src/proxmox/pbs-verify-job-lifecycle.ts
5377
- import { isResolved as isResolved22 } from "alchemy/Diff";
5378
- import * as Effect75 from "effect/Effect";
5443
+ import { isResolved as isResolved23 } from "alchemy/Diff";
5444
+ import * as Effect76 from "effect/Effect";
5379
5445
 
5380
5446
  // src/proxmox/pbs-verify-job-form.ts
5381
5447
  var rechecks = (ignoreVerified, outdatedAfter) => {
@@ -5422,7 +5488,7 @@ var spec3 = {
5422
5488
 
5423
5489
  // src/proxmox/pbs-verify-job-wire.ts
5424
5490
  import * as config6 from "@distilled.cloud/proxmox-backup/config";
5425
- import * as Effect74 from "effect/Effect";
5491
+ import * as Effect75 from "effect/Effect";
5426
5492
  var members4 = (form) => ({
5427
5493
  ...form["ignore-verified"] === undefined ? {} : { ignore_verified: form["ignore-verified"] },
5428
5494
  ...form["store"] === undefined ? {} : { store: form["store"] },
@@ -5447,10 +5513,10 @@ var wire4 = (row) => ({
5447
5513
  "max-depth": row.max_depth,
5448
5514
  "outdated-after": row.outdated_after
5449
5515
  });
5450
- var readOne4 = (props) => runPbs(props.target, "read", config6.getConfigVerify({ id: props.id })).pipe(Effect74.map((row) => spec3.attributes(wire4(row), props)), Effect74.catchTag("VerifyJobNotFound", () => Effect74.succeed(undefined)));
5516
+ var readOne4 = (props) => runPbs(props.target, "read", config6.getConfigVerify({ id: props.id })).pipe(Effect75.map((row) => spec3.attributes(wire4(row), props)), Effect75.catchTag("VerifyJobNotFound", () => Effect75.succeed(undefined)));
5451
5517
  var createOne4 = (props) => runPbs(props.target, "provision", config6.verifyConfig(createRequest4(props)));
5452
5518
  var updateOne4 = (props) => runPbs(props.target, "provision", config6.putConfigVerify(updateRequest4(props)));
5453
- var deleteOne4 = (props) => Effect74.gen(function* () {
5519
+ var deleteOne4 = (props) => Effect75.gen(function* () {
5454
5520
  if ((yield* readOne4(props)) === undefined)
5455
5521
  return;
5456
5522
  return yield* runPbs(props.target, "provision", config6.deleteConfigVerify({ id: props.id }));
@@ -5458,14 +5524,14 @@ var deleteOne4 = (props) => Effect74.gen(function* () {
5458
5524
 
5459
5525
  // src/proxmox/pbs-verify-job-lifecycle.ts
5460
5526
  var { guardCreate: guardCreate8, guardUpdate: guardUpdate8 } = specGuards(spec3);
5461
- var handlers12 = {
5462
- list: () => Effect75.succeed([]),
5527
+ var handlers11 = {
5528
+ list: () => Effect76.succeed([]),
5463
5529
  read: ({ olds }) => readOne4(olds),
5464
5530
  diff: ({
5465
5531
  news,
5466
5532
  output
5467
- }) => Effect75.gen(function* () {
5468
- if (!isResolved22(news))
5533
+ }) => Effect76.gen(function* () {
5534
+ if (!isResolved23(news))
5469
5535
  return;
5470
5536
  yield* guardCreate8(news, output === undefined);
5471
5537
  yield* guardUpdate8(news);
@@ -5478,7 +5544,7 @@ var handlers12 = {
5478
5544
  }
5479
5545
  return { action: spec3.matches(live, news) ? "noop" : "update" };
5480
5546
  }),
5481
- reconcile: ({ news }) => Effect75.gen(function* () {
5547
+ reconcile: ({ news }) => Effect76.gen(function* () {
5482
5548
  const live = yield* readOne4(news);
5483
5549
  yield* guardCreate8(news, live === undefined);
5484
5550
  yield* guardUpdate8(news);
@@ -5488,7 +5554,7 @@ var handlers12 = {
5488
5554
  yield* updateOne4(news);
5489
5555
  const after = yield* readOne4(news);
5490
5556
  if (after === undefined) {
5491
- return yield* Effect75.fail(new Error(`${spec3.path(news)}: write succeeded but job is absent.`));
5557
+ return yield* Effect76.fail(new Error(`${spec3.path(news)}: write succeeded but job is absent.`));
5492
5558
  }
5493
5559
  return after;
5494
5560
  }),
@@ -5497,15 +5563,15 @@ var handlers12 = {
5497
5563
 
5498
5564
  // src/proxmox/pbs-verify-job.ts
5499
5565
  var PbsVerifyJob = Resource24("Pbs.VerifyJob");
5500
- var PbsVerifyJobProvider = () => Provider24.effect(PbsVerifyJob, Effect76.succeed(PbsVerifyJob.Provider.of(handlers12)));
5566
+ var PbsVerifyJobProvider = () => Provider24.effect(PbsVerifyJob, Effect77.succeed(PbsVerifyJob.Provider.of(handlers11)));
5501
5567
  // src/proxmox/pool.ts
5502
5568
  import { Resource as Resource25 } from "alchemy";
5503
- import { isResolved as isResolved23 } from "alchemy/Diff";
5569
+ import { isResolved as isResolved24 } from "alchemy/Diff";
5504
5570
  import * as Provider25 from "alchemy/Provider";
5505
5571
  import * as pools from "@distilled.cloud/proxmox/pools";
5506
5572
  import { ProxmoxParseError as ProxmoxParseError5 } from "@distilled.cloud/proxmox/Errors";
5507
5573
  import * as Schema5 from "effect/Schema";
5508
- import * as Effect77 from "effect/Effect";
5574
+ import * as Effect78 from "effect/Effect";
5509
5575
  var ProxmoxPool = Resource25("Proxmox.Pool");
5510
5576
  var poolCreateForm = (props) => ({
5511
5577
  comment: props.comment ?? "",
@@ -5531,16 +5597,16 @@ var spec4 = {
5531
5597
  updateForm: poolUpdateForm
5532
5598
  };
5533
5599
  var { guardCreate: guardCreate9, guardUpdate: guardUpdate9 } = specGuards(spec4);
5534
- var readPool = (props) => runPve(props.target, "read", false, pools.getPool({ poolid: props.poolid })).pipe(Effect77.flatMap((live) => Schema5.decodeUnknownEffect(Schema5.toType(pools.GetPoolResponse))(live).pipe(Effect77.mapError(() => new ProxmoxParseError5({
5600
+ var readPool = (props) => runPve(props.target, "read", false, pools.getPool({ poolid: props.poolid })).pipe(Effect78.flatMap((live) => Schema5.decodeUnknownEffect(Schema5.toType(pools.GetPoolResponse))(live).pipe(Effect78.mapError(() => new ProxmoxParseError5({
5535
5601
  body: undefined,
5536
5602
  cause: "Pool response does not match its vendor schema"
5537
- })), Effect77.as(live))), Effect77.map((live) => spec4.attributes({ ...live }, props)), Effect77.catchTag("PoolNotFound", () => Effect77.succeed(undefined)), Effect77.catchTag("NotFound", () => Effect77.succeed(undefined)));
5538
- var deletePool2 = (props) => runPve(props.target, "provision", true, pools.deletePool({ poolid: props.poolid })).pipe(Effect77.catchTag("PoolNotFound", () => Effect77.void), Effect77.catchTag("NotFound", () => Effect77.void));
5539
- var ProxmoxPoolProvider = () => Provider25.effect(ProxmoxPool, Effect77.succeed(ProxmoxPool.Provider.of({
5540
- list: () => Effect77.succeed([]),
5603
+ })), Effect78.as(live))), Effect78.map((live) => spec4.attributes({ ...live }, props)), Effect78.catchTag("PoolNotFound", () => Effect78.succeed(undefined)), Effect78.catchTag("NotFound", () => Effect78.succeed(undefined)));
5604
+ var deletePool2 = (props) => runPve(props.target, "provision", true, pools.deletePool({ poolid: props.poolid })).pipe(Effect78.catchTag("PoolNotFound", () => Effect78.void), Effect78.catchTag("NotFound", () => Effect78.void));
5605
+ var ProxmoxPoolProvider = () => Provider25.effect(ProxmoxPool, Effect78.succeed(ProxmoxPool.Provider.of({
5606
+ list: () => Effect78.succeed([]),
5541
5607
  read: ({ olds }) => readPool(olds),
5542
- diff: Effect77.fn(function* ({ news, output }) {
5543
- if (!isResolved23(news))
5608
+ diff: Effect78.fn(function* ({ news, output }) {
5609
+ if (!isResolved24(news))
5544
5610
  return;
5545
5611
  yield* guardCreate9(news, output === undefined);
5546
5612
  yield* guardUpdate9(news);
@@ -5553,7 +5619,7 @@ var ProxmoxPoolProvider = () => Provider25.effect(ProxmoxPool, Effect77.succeed(
5553
5619
  }
5554
5620
  return { action: spec4.matches(live, news) ? "noop" : "update" };
5555
5621
  }),
5556
- reconcile: Effect77.fn(function* ({ news }) {
5622
+ reconcile: Effect78.fn(function* ({ news }) {
5557
5623
  const live = yield* readPool(news);
5558
5624
  yield* guardCreate9(news, live === undefined);
5559
5625
  yield* guardUpdate9(news);
@@ -5569,7 +5635,7 @@ var ProxmoxPoolProvider = () => Provider25.effect(ProxmoxPool, Effect77.succeed(
5569
5635
  }
5570
5636
  const after = yield* readPool(news);
5571
5637
  if (after === undefined)
5572
- return yield* Effect77.fail(new Error(`pools/${news.poolid}: write returned success but the pool is still absent`));
5638
+ return yield* Effect78.fail(new Error(`pools/${news.poolid}: write returned success but the pool is still absent`));
5573
5639
  return after;
5574
5640
  }),
5575
5641
  delete: ({ olds }) => deletePool2(olds)
@@ -5766,14 +5832,14 @@ echo 'provision baseline: done. Next: point the OpenBao proxmox mount at these u
5766
5832
  // src/proxmox/provision-declare.ts
5767
5833
  import { adopt } from "alchemy/AdoptPolicy";
5768
5834
  import * as RemovalPolicy from "alchemy/RemovalPolicy";
5769
- import * as Effect81 from "effect/Effect";
5835
+ import * as Effect82 from "effect/Effect";
5770
5836
 
5771
5837
  // src/proxmox/role.ts
5772
5838
  import { Resource as Resource26 } from "alchemy";
5773
- import { isResolved as isResolved24 } from "alchemy/Diff";
5839
+ import { isResolved as isResolved25 } from "alchemy/Diff";
5774
5840
  import * as Provider26 from "alchemy/Provider";
5775
5841
  import * as access5 from "@distilled.cloud/proxmox/access";
5776
- import * as Effect78 from "effect/Effect";
5842
+ import * as Effect79 from "effect/Effect";
5777
5843
 
5778
5844
  // src/proxmox/role-wire.ts
5779
5845
  var ROLE_CREATE = "pve:POST /access/roles";
@@ -5783,36 +5849,36 @@ var createForm7 = (props) => ({
5783
5849
  privs: canonical2(props.privs).join(","),
5784
5850
  roleid: props.roleid
5785
5851
  });
5786
- var updateForm4 = (props) => ({
5852
+ var updateForm5 = (props) => ({
5787
5853
  privs: canonical2(props.privs).join(","),
5788
5854
  roleid: props.roleid
5789
5855
  });
5790
5856
  var find2 = (rows, roleid) => rows.find((row) => row.roleid === roleid);
5791
- var attributesOf7 = (row, props) => ({
5857
+ var attributesOf8 = (row, props) => ({
5792
5858
  privs: canonical2(row.privs === undefined ? [] : row.privs.split(",")),
5793
5859
  roleid: props.roleid
5794
5860
  });
5795
- var matches7 = (attributes2, props) => canonical2(attributes2.privs).join(",") === canonical2(props.privs).join(",");
5861
+ var matches8 = (attributes2, props) => canonical2(attributes2.privs).join(",") === canonical2(props.privs).join(",");
5796
5862
 
5797
5863
  // src/proxmox/role.ts
5798
5864
  var ProxmoxRole = Resource26("Proxmox.Role");
5799
- var readRole = (props) => readOrUnreadable(runPve(props.target, "read", false, access5.listAccessRoles({}))).pipe(Effect78.map((rows) => {
5865
+ var readRole = (props) => readOrUnreadable(runPve(props.target, "read", false, access5.listAccessRoles({}))).pipe(Effect79.map((rows) => {
5800
5866
  if (rows === UNREADABLE)
5801
5867
  return UNREADABLE;
5802
5868
  const row = find2(rows, props.roleid);
5803
- return row === undefined ? undefined : attributesOf7(row, props);
5869
+ return row === undefined ? undefined : attributesOf8(row, props);
5804
5870
  }));
5805
5871
  var dropUnreadable5 = (live) => live === UNREADABLE ? undefined : live;
5806
- var ProxmoxRoleProvider = () => Provider26.effect(ProxmoxRole, Effect78.succeed(ProxmoxRole.Provider.of({
5807
- list: () => Effect78.succeed([]),
5808
- read: Effect78.fn(function* ({ olds }) {
5872
+ var ProxmoxRoleProvider = () => Provider26.effect(ProxmoxRole, Effect79.succeed(ProxmoxRole.Provider.of({
5873
+ list: () => Effect79.succeed([]),
5874
+ read: Effect79.fn(function* ({ olds }) {
5809
5875
  return dropUnreadable5(yield* readRole(olds));
5810
5876
  }),
5811
- diff: Effect78.fn(function* ({ news, output }) {
5812
- if (!isResolved24(news))
5877
+ diff: Effect79.fn(function* ({ news, output }) {
5878
+ if (!isResolved25(news))
5813
5879
  return;
5814
5880
  yield* guardWrite2(ROLE_CREATE, createForm7(news), output === undefined);
5815
- yield* guardWrite2(ROLE_UPDATE, updateForm4(news), false);
5881
+ yield* guardWrite2(ROLE_UPDATE, updateForm5(news), false);
5816
5882
  if (output === undefined)
5817
5883
  return;
5818
5884
  const live = yield* readRole(news);
@@ -5824,38 +5890,38 @@ var ProxmoxRoleProvider = () => Provider26.effect(ProxmoxRole, Effect78.succeed(
5824
5890
  yield* guardWrite2(ROLE_CREATE, createForm7(news), true);
5825
5891
  return { action: "update" };
5826
5892
  }
5827
- return matches7(live, news) ? { action: "noop" } : { action: "update" };
5893
+ return matches8(live, news) ? { action: "noop" } : { action: "update" };
5828
5894
  }),
5829
- reconcile: Effect78.fn(function* ({ news }) {
5895
+ reconcile: Effect79.fn(function* ({ news }) {
5830
5896
  const before = dropUnreadable5(yield* readRole(news));
5831
5897
  yield* guardWrite2(ROLE_CREATE, createForm7(news), before === undefined);
5832
- yield* guardWrite2(ROLE_UPDATE, updateForm4(news), false);
5898
+ yield* guardWrite2(ROLE_UPDATE, updateForm5(news), false);
5833
5899
  if (before === undefined) {
5834
5900
  yield* runPve(news.target, "provision", true, access5.createAccessRole(createForm7(news)));
5835
- } else if (!matches7(before, news)) {
5836
- yield* runPve(news.target, "provision", true, access5.putAccessRole(updateForm4(news)));
5901
+ } else if (!matches8(before, news)) {
5902
+ yield* runPve(news.target, "provision", true, access5.putAccessRole(updateForm5(news)));
5837
5903
  }
5838
5904
  const after = dropUnreadable5(yield* readRole(news));
5839
5905
  if (after === undefined) {
5840
- return yield* Effect78.die(new Error(`access/roles/${news.roleid}: the write returned no error but the role is ` + 'still absent. PVE wraps every answer in {"data":...} and can report success ' + "on a call that did nothing -- read back rather than trusting the status code."));
5906
+ return yield* Effect79.die(new Error(`access/roles/${news.roleid}: the write returned no error but the role is ` + 'still absent. PVE wraps every answer in {"data":...} and can report success ' + "on a call that did nothing -- read back rather than trusting the status code."));
5841
5907
  }
5842
5908
  return after;
5843
5909
  }),
5844
- delete: Effect78.fn(function* ({ olds }) {
5910
+ delete: Effect79.fn(function* ({ olds }) {
5845
5911
  yield* runPve(olds.target, "provision", true, access5.deleteAccessRole({ roleid: olds.roleid }));
5846
5912
  })
5847
5913
  })));
5848
5914
 
5849
5915
  // src/proxmox/user.ts
5850
5916
  import { Resource as Resource27 } from "alchemy";
5851
- import { isResolved as isResolved25 } from "alchemy/Diff";
5917
+ import { isResolved as isResolved26 } from "alchemy/Diff";
5852
5918
  import * as Provider27 from "alchemy/Provider";
5853
5919
  import * as access7 from "@distilled.cloud/proxmox/access";
5854
- import * as Effect80 from "effect/Effect";
5920
+ import * as Effect81 from "effect/Effect";
5855
5921
 
5856
5922
  // src/proxmox/user-wire.ts
5857
5923
  import * as access6 from "@distilled.cloud/proxmox/access";
5858
- import * as Effect79 from "effect/Effect";
5924
+ import * as Effect80 from "effect/Effect";
5859
5925
  var USER_CREATE = "pve:POST /access/users";
5860
5926
  var USER_UPDATE = "pve:PUT /access/users/{userid}";
5861
5927
  var int2 = (value) => {
@@ -5881,11 +5947,11 @@ var createForm8 = (props) => ({
5881
5947
  ...shape8(props),
5882
5948
  userid: props.userid
5883
5949
  });
5884
- var updateForm5 = (props) => ({
5950
+ var updateForm6 = (props) => ({
5885
5951
  ...shape8(props),
5886
5952
  userid: props.userid
5887
5953
  });
5888
- var attributesOf8 = (live, props) => ({
5954
+ var attributesOf9 = (live, props) => ({
5889
5955
  comment: text(live.comment),
5890
5956
  email: text(live.email),
5891
5957
  enable: bool(live.enable, true),
@@ -5896,23 +5962,23 @@ var attributesOf8 = (live, props) => ({
5896
5962
  tokens: tokenNames(live.tokens),
5897
5963
  userid: props.userid
5898
5964
  });
5899
- var matches8 = (attributes2, props) => attributes2.comment === (props.comment ?? "") && attributes2.email === (props.email ?? "") && attributes2.enable === (props.enable !== false) && attributes2.expire === (props.expire ?? 0) && attributes2.firstname === (props.firstname ?? "") && attributes2.lastname === (props.lastname ?? "") && attributes2.groups.join(",") === groupSet(props.groups).join(",");
5900
- var readUserOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, access6.getAccessUser({ userid: props.userid }))).pipe(Effect79.map((live) => live === UNREADABLE ? UNREADABLE : attributesOf8(live, props)));
5901
- var readUser = (props) => readUserOrFail(props).pipe(Effect79.catchTag("UserNotFound", () => Effect79.succeed(undefined)));
5965
+ var matches9 = (attributes2, props) => attributes2.comment === (props.comment ?? "") && attributes2.email === (props.email ?? "") && attributes2.enable === (props.enable !== false) && attributes2.expire === (props.expire ?? 0) && attributes2.firstname === (props.firstname ?? "") && attributes2.lastname === (props.lastname ?? "") && attributes2.groups.join(",") === groupSet(props.groups).join(",");
5966
+ var readUserOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, access6.getAccessUser({ userid: props.userid }))).pipe(Effect80.map((live) => live === UNREADABLE ? UNREADABLE : attributesOf9(live, props)));
5967
+ var readUser = (props) => readUserOrFail(props).pipe(Effect80.catchTag("UserNotFound", () => Effect80.succeed(undefined)));
5902
5968
  var dropUnreadable6 = (live) => live === UNREADABLE ? undefined : live;
5903
5969
 
5904
5970
  // src/proxmox/user.ts
5905
5971
  var ProxmoxUser = Resource27("Proxmox.User");
5906
- var ProxmoxUserProvider = () => Provider27.effect(ProxmoxUser, Effect80.succeed(ProxmoxUser.Provider.of({
5907
- list: () => Effect80.succeed([]),
5908
- read: Effect80.fn(function* ({ olds, output }) {
5972
+ var ProxmoxUserProvider = () => Provider27.effect(ProxmoxUser, Effect81.succeed(ProxmoxUser.Provider.of({
5973
+ list: () => Effect81.succeed([]),
5974
+ read: Effect81.fn(function* ({ olds, output }) {
5909
5975
  return dropUnreadable6(yield* output === undefined ? readUser(olds) : readUserOrFail(olds));
5910
5976
  }),
5911
- diff: Effect80.fn(function* ({ news, output }) {
5912
- if (!isResolved25(news))
5977
+ diff: Effect81.fn(function* ({ news, output }) {
5978
+ if (!isResolved26(news))
5913
5979
  return;
5914
5980
  yield* guardWrite2(USER_CREATE, createForm8(news), output === undefined);
5915
- yield* guardWrite2(USER_UPDATE, updateForm5(news), false);
5981
+ yield* guardWrite2(USER_UPDATE, updateForm6(news), false);
5916
5982
  if (output === undefined)
5917
5983
  return;
5918
5984
  const live = yield* readUserOrFail(news);
@@ -5924,31 +5990,31 @@ var ProxmoxUserProvider = () => Provider27.effect(ProxmoxUser, Effect80.succeed(
5924
5990
  yield* guardWrite2(USER_CREATE, createForm8(news), true);
5925
5991
  return { action: "update" };
5926
5992
  }
5927
- return matches8(live, news) ? { action: "noop" } : { action: "update" };
5993
+ return matches9(live, news) ? { action: "noop" } : { action: "update" };
5928
5994
  }),
5929
- reconcile: Effect80.fn(function* ({ news }) {
5995
+ reconcile: Effect81.fn(function* ({ news }) {
5930
5996
  const before = dropUnreadable6(yield* readUser(news));
5931
5997
  yield* guardWrite2(USER_CREATE, createForm8(news), before === undefined);
5932
- yield* guardWrite2(USER_UPDATE, updateForm5(news), false);
5998
+ yield* guardWrite2(USER_UPDATE, updateForm6(news), false);
5933
5999
  if (before === undefined) {
5934
6000
  yield* runPve(news.target, "provision", true, access7.createAccessUser(createForm8(news)));
5935
- } else if (!matches8(before, news)) {
5936
- yield* runPve(news.target, "provision", true, access7.putAccessUser(updateForm5(news)));
6001
+ } else if (!matches9(before, news)) {
6002
+ yield* runPve(news.target, "provision", true, access7.putAccessUser(updateForm6(news)));
5937
6003
  }
5938
6004
  const after = dropUnreadable6(yield* readUser(news));
5939
6005
  if (after === undefined) {
5940
- return yield* Effect80.die(new Error(`access/users/${news.userid}: the write returned no error but the account is ` + 'still absent. PVE wraps every answer in {"data":...} and can report success ' + "on a call that did nothing -- read back rather than trusting the status code."));
6006
+ return yield* Effect81.die(new Error(`access/users/${news.userid}: the write returned no error but the account is ` + 'still absent. PVE wraps every answer in {"data":...} and can report success ' + "on a call that did nothing -- read back rather than trusting the status code."));
5941
6007
  }
5942
6008
  return after;
5943
6009
  }),
5944
- delete: Effect80.fn(function* ({ olds }) {
6010
+ delete: Effect81.fn(function* ({ olds }) {
5945
6011
  yield* runPve(olds.target, "provision", true, access7.deleteAccessUser({ userid: olds.userid }));
5946
6012
  })
5947
6013
  })));
5948
6014
 
5949
6015
  // src/proxmox/provision-declare.ts
5950
- var declareProvisionBaseline = (id, target, names2 = {}, options = {}) => Effect81.gen(function* () {
5951
- const baseline = yield* Effect81.try({
6016
+ var declareProvisionBaseline = (id, target, names2 = {}, options = {}) => Effect82.gen(function* () {
6017
+ const baseline = yield* Effect82.try({
5952
6018
  catch: (cause) => cause instanceof Error ? cause : new Error(String(cause)),
5953
6019
  try: () => provisionBaseline(names2)
5954
6020
  });
@@ -5962,13 +6028,13 @@ var declareProvisionBaseline = (id, target, names2 = {}, options = {}) => Effect
5962
6028
  target
5963
6029
  }));
5964
6030
  const group = yield* owned(ProxmoxGroup(`${id}-mint-group`, { ...baseline.group, target }));
5965
- const users = yield* Effect81.all(baseline.users.map((user) => owned(ProxmoxUser(`${id}-${user.lane}-user`, {
6031
+ const users = yield* Effect82.all(baseline.users.map((user) => owned(ProxmoxUser(`${id}-${user.lane}-user`, {
5966
6032
  comment: user.comment,
5967
6033
  groups: [...user.groups],
5968
6034
  target,
5969
6035
  userid: user.userid
5970
6036
  }))));
5971
- const grants = yield* Effect81.all(baseline.grants.map((grant) => owned(ProxmoxAcl(`${id}-${grant.lane}-grant`, {
6037
+ const grants = yield* Effect82.all(baseline.grants.map((grant) => owned(ProxmoxAcl(`${id}-${grant.lane}-grant`, {
5972
6038
  path: "/",
5973
6039
  propagate: true,
5974
6040
  roleid: grant.roleid,
@@ -5981,12 +6047,12 @@ var declareProvisionBaseline = (id, target, names2 = {}, options = {}) => Effect
5981
6047
  // src/proxmox/qemu.ts
5982
6048
  import { Resource as Resource28 } from "alchemy";
5983
6049
  import * as Provider28 from "alchemy/Provider";
5984
- import * as Effect85 from "effect/Effect";
6050
+ import * as Effect86 from "effect/Effect";
5985
6051
 
5986
6052
  // src/proxmox/qemu-lifecycle.ts
5987
- import { isResolved as isResolved26 } from "alchemy/Diff";
6053
+ import { isResolved as isResolved27 } from "alchemy/Diff";
5988
6054
  import * as nodes17 from "@distilled.cloud/proxmox/nodes";
5989
- import * as Effect84 from "effect/Effect";
6055
+ import * as Effect85 from "effect/Effect";
5990
6056
 
5991
6057
  // src/proxmox/qemu-props.ts
5992
6058
  var NOT_CONFIG2 = new Set(["node", "target", "vmid"]);
@@ -6047,7 +6113,7 @@ var createForm9 = (props) => ({
6047
6113
  ...form(props),
6048
6114
  vmid: String(props.vmid)
6049
6115
  });
6050
- var updateForm6 = form;
6116
+ var updateForm7 = form;
6051
6117
 
6052
6118
  // src/proxmox/qemu-errors.ts
6053
6119
  class QemuRefusedError extends Error {
@@ -6142,7 +6208,7 @@ var netPairs = (value) => new Map(value.split(",").map((part) => part.trim()).fi
6142
6208
  const at = part.indexOf("=");
6143
6209
  return at === -1 ? [part, ""] : [part.slice(0, at), part.slice(at + 1)];
6144
6210
  }));
6145
- var modelKey = (map31) => NIC_MODELS.find((model) => map31.has(model));
6211
+ var modelKey = (map32) => NIC_MODELS.find((model) => map32.has(model));
6146
6212
  var netMaps2 = (declared2, live) => {
6147
6213
  const want = netPairs(declared2);
6148
6214
  const have = netPairs(live);
@@ -6213,44 +6279,44 @@ var judge2 = (props, config7) => {
6213
6279
  var identityRefusal = (vmid, was) => was === undefined || vmid === was ? undefined : `vmid: ${String(was)} -> ${String(vmid)} is a different VM. Declare it as a new resource; ` + "this one is retained when its declaration goes.";
6214
6280
 
6215
6281
  // src/proxmox/qemu-read.ts
6216
- import * as cluster10 from "@distilled.cloud/proxmox/cluster";
6282
+ import * as cluster11 from "@distilled.cloud/proxmox/cluster";
6217
6283
  import * as nodes15 from "@distilled.cloud/proxmox/nodes";
6218
- import * as Effect82 from "effect/Effect";
6284
+ import * as Effect83 from "effect/Effect";
6219
6285
  var guestTypes = ["lxc", "qemu"];
6220
- var readVm = (props) => Effect82.gen(function* () {
6286
+ var readVm = (props) => Effect83.gen(function* () {
6221
6287
  const credential = yield* leased(props.target, "read");
6222
- const answer = yield* runPveWith(props.target, credential, false, nodes15.getNodeQemuConfig({ node: props.node, vmid: String(props.vmid) })).pipe(Effect82.map((data) => ({ data, error: undefined })), Effect82.catchTag("QemuConfigNotFound", (error) => Effect82.succeed({ data: undefined, error })));
6288
+ const answer = yield* runPveWith(props.target, credential, false, nodes15.getNodeQemuConfig({ node: props.node, vmid: String(props.vmid) })).pipe(Effect83.map((data) => ({ data, error: undefined })), Effect83.catchTag("QemuConfigNotFound", (error) => Effect83.succeed({ data: undefined, error })));
6223
6289
  if (answer.error === undefined) {
6224
6290
  const live = answer.data;
6225
6291
  if (typeof live.digest !== "string" || live.digest === "") {
6226
- return yield* Effect82.fail(new QemuRefusedError(`VM ${String(props.vmid)}: config read did not return a digest-bearing config.`));
6292
+ return yield* Effect83.fail(new QemuRefusedError(`VM ${String(props.vmid)}: config read did not return a digest-bearing config.`));
6227
6293
  }
6228
6294
  return live;
6229
6295
  }
6230
- const rows = yield* runPveWith(props.target, credential, false, cluster10.listClusterResources({ type: "vm" }));
6296
+ const rows = yield* runPveWith(props.target, credential, false, cluster11.listClusterResources({ type: "vm" }));
6231
6297
  if (!Array.isArray(rows) || rows.some((row) => !Number.isSafeInteger(Number(row?.vmid)) || Number(row?.vmid) <= 0 || typeof row?.node !== "string" || row.node === "" || !guestTypes.includes(row.type))) {
6232
- return yield* Effect82.fail(new QemuRefusedError("The cluster guest index did not identify its rows."));
6298
+ return yield* Effect83.fail(new QemuRefusedError("The cluster guest index did not identify its rows."));
6233
6299
  }
6234
6300
  const found = rows.find((row) => Number(row.vmid) === props.vmid);
6235
6301
  if (found === undefined)
6236
6302
  return;
6237
6303
  if (found.node === props.node && found.type === "qemu")
6238
- return yield* Effect82.fail(answer.error);
6239
- return yield* Effect82.fail(new QemuRefusedError(`vmid ${String(props.vmid)} is a ${text(found.type, "guest")} on ` + `${text(found.node, "?")}, not a VM on ${props.node}. A migration is not an ` + "update and vmids are cluster-wide: declare the node it is on, or pick a free vmid."));
6304
+ return yield* Effect83.fail(answer.error);
6305
+ return yield* Effect83.fail(new QemuRefusedError(`vmid ${String(props.vmid)} is a ${text(found.type, "guest")} on ` + `${text(found.node, "?")}, not a VM on ${props.node}. A migration is not an ` + "update and vmids are cluster-wide: declare the node it is on, or pick a free vmid."));
6240
6306
  });
6241
6307
 
6242
6308
  // src/proxmox/qemu-task.ts
6243
6309
  import * as nodes16 from "@distilled.cloud/proxmox/nodes";
6244
- import * as Effect83 from "effect/Effect";
6245
- var qemuTask = (props, operation, what, polls) => Effect83.gen(function* () {
6310
+ import * as Effect84 from "effect/Effect";
6311
+ var qemuTask = (props, operation, what, polls) => Effect84.gen(function* () {
6246
6312
  const credential = yield* mint(props.target, "provision");
6247
6313
  const upid = text(yield* runPveWith(props.target, credential, true, operation));
6248
6314
  if (upid === "") {
6249
- return yield* Effect83.fail(new QemuRefusedError(`${what}: PVE returned no task id, so the write cannot be confirmed and is not claimed.`));
6315
+ return yield* Effect84.fail(new QemuRefusedError(`${what}: PVE returned no task id, so the write cannot be confirmed and is not claimed.`));
6250
6316
  }
6251
6317
  let exit = "still running when this provider stopped waiting";
6252
6318
  for (let attempt = 0;attempt < polls; attempt++) {
6253
- const status = yield* runPveWith(props.target, credential, false, nodes16.getNodeTaskStatus({ node: props.node, upid })).pipe(Effect83.orElseSucceed(() => {
6319
+ const status = yield* runPveWith(props.target, credential, false, nodes16.getNodeTaskStatus({ node: props.node, upid })).pipe(Effect84.orElseSucceed(() => {
6254
6320
  return;
6255
6321
  }));
6256
6322
  if (status === undefined || status.status === undefined) {
@@ -6261,66 +6327,66 @@ var qemuTask = (props, operation, what, polls) => Effect83.gen(function* () {
6261
6327
  exit = text(status.exitstatus, "stopped with no exitstatus");
6262
6328
  break;
6263
6329
  }
6264
- yield* Effect83.sleep("1 second");
6330
+ yield* Effect84.sleep("1 second");
6265
6331
  }
6266
6332
  if (exit !== "OK") {
6267
- return yield* Effect83.fail(new QemuRefusedError(`${what}: task ${upid} ended "${exit}". Read the task log before running the deploy again.`));
6333
+ return yield* Effect84.fail(new QemuRefusedError(`${what}: task ${upid} ended "${exit}". Read the task log before running the deploy again.`));
6268
6334
  }
6269
6335
  });
6270
6336
 
6271
6337
  // src/proxmox/qemu-lifecycle.ts
6272
6338
  var CREATE_POLLS2 = 180;
6273
6339
  var DELETE_POLLS = 60;
6274
- var attributesOf9 = (live, props) => ({
6340
+ var attributesOf10 = (live, props) => ({
6275
6341
  config: storedConfig2(live),
6276
6342
  node: props.node,
6277
6343
  vmid: props.vmid
6278
6344
  });
6279
- var matches9 = (attributes2, props) => declaredKeys2(props).filter(isManagedKey2).every((key) => attributes2.config[key] === wireValue2(declaredValue2(props, key)));
6345
+ var matches10 = (attributes2, props) => declaredKeys2(props).filter(isManagedKey2).every((key) => attributes2.config[key] === wireValue2(declaredValue2(props, key)));
6280
6346
  var spec5 = {
6281
- attributes: attributesOf9,
6347
+ attributes: attributesOf10,
6282
6348
  collection: (props) => `nodes/${props.node}/qemu`,
6283
6349
  createForm: createForm9,
6284
6350
  endpoint: {
6285
6351
  create: "pve:POST /nodes/{node}/qemu",
6286
6352
  update: "pve:PUT /nodes/{node}/qemu/{vmid}/config"
6287
6353
  },
6288
- matches: matches9,
6354
+ matches: matches10,
6289
6355
  path: (props) => `nodes/${props.node}/qemu/${String(props.vmid)}/config`,
6290
- updateForm: updateForm6
6356
+ updateForm: updateForm7
6291
6357
  };
6292
6358
  var { guardCreate: guardCreate10, guardUpdate: guardUpdate10 } = specGuards(spec5);
6293
- var readQemu = (props) => readVm(props).pipe(Effect84.map((live) => live === undefined ? undefined : attributesOf9(live, props)));
6294
- var deleteQemu = (props) => qemuTask(props, nodes17.deleteNodeQemu({ node: props.node, vmid: String(props.vmid) }), `destroy VM ${String(props.vmid)}`, DELETE_POLLS).pipe(Effect84.catchTag("QemuConfigNotFound", () => Effect84.void));
6359
+ var readQemu = (props) => readVm(props).pipe(Effect85.map((live) => live === undefined ? undefined : attributesOf10(live, props)));
6360
+ var deleteQemu = (props) => qemuTask(props, nodes17.deleteNodeQemu({ node: props.node, vmid: String(props.vmid) }), `destroy VM ${String(props.vmid)}`, DELETE_POLLS).pipe(Effect85.catchTag("QemuConfigNotFound", () => Effect85.void));
6295
6361
  var refuseUnmanaged = (props) => {
6296
6362
  const refused2 = formRefusals(props);
6297
- return refused2.length === 0 ? Effect84.void : Effect84.fail(new QemuRefusedError(refused2.join(`
6363
+ return refused2.length === 0 ? Effect85.void : Effect85.fail(new QemuRefusedError(refused2.join(`
6298
6364
  `)));
6299
6365
  };
6300
- var refuseChange = (change) => change.refuse.length === 0 ? Effect84.void : Effect84.fail(new QemuRefusedError(change.refuse.join(`
6366
+ var refuseChange = (change) => change.refuse.length === 0 ? Effect85.void : Effect85.fail(new QemuRefusedError(change.refuse.join(`
6301
6367
  `)));
6302
6368
  var qemuHandlers = {
6303
- list: () => Effect84.succeed([]),
6304
- read: Effect84.fn(function* ({
6369
+ list: () => Effect85.succeed([]),
6370
+ read: Effect85.fn(function* ({
6305
6371
  fqn,
6306
6372
  instanceId,
6307
6373
  olds,
6308
6374
  output
6309
6375
  }) {
6310
6376
  const found = yield* readQemu(olds);
6311
- const settled2 = Effect84.sync(() => found !== undefined && judge2(olds, found.config).drift.length === 0);
6377
+ const settled2 = Effect85.sync(() => found !== undefined && judge2(olds, found.config).drift.length === 0);
6312
6378
  return yield* ownedRead({ fqn, instanceId, output }, found, settled2);
6313
6379
  }),
6314
- diff: Effect84.fn(function* ({
6380
+ diff: Effect85.fn(function* ({
6315
6381
  news,
6316
6382
  olds,
6317
6383
  output
6318
6384
  }) {
6319
- if (!isResolved26(news))
6385
+ if (!isResolved27(news))
6320
6386
  return;
6321
6387
  const identity2 = identityRefusal(news.vmid, output?.vmid ?? olds.vmid);
6322
6388
  if (identity2 !== undefined)
6323
- return yield* Effect84.fail(new QemuRefusedError(identity2));
6389
+ return yield* Effect85.fail(new QemuRefusedError(identity2));
6324
6390
  yield* refuseUnmanaged(news);
6325
6391
  yield* guardCreate10(news, output === undefined);
6326
6392
  yield* guardUpdate10(news);
@@ -6328,7 +6394,7 @@ var qemuHandlers = {
6328
6394
  return;
6329
6395
  const live = yield* readQemu(news);
6330
6396
  if (live === undefined) {
6331
- yield* Effect84.logWarning(`Proxmox.Vm ${news.node}/${String(news.vmid)}: the cluster lists no VM with this vmid -- ` + "a deploy CREATES it again, with new, empty volumes.");
6397
+ yield* Effect85.logWarning(`Proxmox.Vm ${news.node}/${String(news.vmid)}: the cluster lists no VM with this vmid -- ` + "a deploy CREATES it again, with new, empty volumes.");
6332
6398
  yield* guardCreate10(news, true);
6333
6399
  return { action: "update" };
6334
6400
  }
@@ -6336,7 +6402,7 @@ var qemuHandlers = {
6336
6402
  yield* refuseChange(change);
6337
6403
  return { action: change.drift.length === 0 ? "noop" : "update" };
6338
6404
  }),
6339
- reconcile: Effect84.fn(function* ({
6405
+ reconcile: Effect85.fn(function* ({
6340
6406
  fqn,
6341
6407
  instanceId,
6342
6408
  news,
@@ -6345,7 +6411,7 @@ var qemuHandlers = {
6345
6411
  }) {
6346
6412
  const identity2 = identityRefusal(news.vmid, output?.vmid ?? olds?.vmid);
6347
6413
  if (identity2 !== undefined)
6348
- return yield* Effect84.fail(new QemuRefusedError(identity2));
6414
+ return yield* Effect85.fail(new QemuRefusedError(identity2));
6349
6415
  yield* refuseUnmanaged(news);
6350
6416
  const live = yield* readQemu(news);
6351
6417
  yield* guardCreate10(news, live === undefined);
@@ -6362,11 +6428,11 @@ var qemuHandlers = {
6362
6428
  }
6363
6429
  const after = yield* readQemu(news);
6364
6430
  if (after === undefined) {
6365
- return yield* Effect84.fail(new QemuRefusedError(`${spec5.path(news)}: write returned success but the VM is still absent`));
6431
+ return yield* Effect85.fail(new QemuRefusedError(`${spec5.path(news)}: write returned success but the VM is still absent`));
6366
6432
  }
6367
6433
  const left = judge2(news, after.config);
6368
6434
  if (left.drift.length > 0) {
6369
- return yield* Effect84.fail(new QemuRefusedError(`${spec5.path(news)}: after the write, ${left.drift.join(", ")} still differ from the ` + "declaration. PVE may have normalised the value -- declare what it stores."));
6435
+ return yield* Effect85.fail(new QemuRefusedError(`${spec5.path(news)}: after the write, ${left.drift.join(", ")} still differ from the ` + "declaration. PVE may have normalised the value -- declare what it stores."));
6370
6436
  }
6371
6437
  return after;
6372
6438
  }),
@@ -6375,16 +6441,16 @@ var qemuHandlers = {
6375
6441
 
6376
6442
  // src/proxmox/qemu.ts
6377
6443
  var ProxmoxVm = Resource28("Proxmox.Vm", { defaultRemovalPolicy: "retain" });
6378
- var ProxmoxVmProvider = () => Provider28.effect(ProxmoxVm, Effect85.succeed(ProxmoxVm.Provider.of(qemuHandlers)));
6444
+ var ProxmoxVmProvider = () => Provider28.effect(ProxmoxVm, Effect86.succeed(ProxmoxVm.Provider.of(qemuHandlers)));
6379
6445
  // src/proxmox/storage-download.ts
6380
6446
  import { Resource as Resource29 } from "alchemy";
6381
6447
  import * as Provider29 from "alchemy/Provider";
6382
- import * as Effect88 from "effect/Effect";
6448
+ import * as Effect89 from "effect/Effect";
6383
6449
 
6384
6450
  // src/proxmox/storage-download-lifecycle.ts
6385
- import { isResolved as isResolved27 } from "alchemy/Diff";
6451
+ import { isResolved as isResolved28 } from "alchemy/Diff";
6386
6452
  import * as nodes19 from "@distilled.cloud/proxmox/nodes";
6387
- import * as Effect87 from "effect/Effect";
6453
+ import * as Effect88 from "effect/Effect";
6388
6454
 
6389
6455
  // src/proxmox/storage-download-identity.ts
6390
6456
  var PINNED = [
@@ -6419,16 +6485,16 @@ class StorageDownloadRefusedError extends Error {
6419
6485
 
6420
6486
  // src/proxmox/storage-download-task.ts
6421
6487
  import * as nodes18 from "@distilled.cloud/proxmox/nodes";
6422
- import * as Effect86 from "effect/Effect";
6423
- var storageDownloadTask = (where, operation, what, polls) => Effect86.gen(function* () {
6488
+ import * as Effect87 from "effect/Effect";
6489
+ var storageDownloadTask = (where, operation, what, polls) => Effect87.gen(function* () {
6424
6490
  const credential = yield* mint(where.target, "provision");
6425
6491
  const upid = text(yield* runPveWith(where.target, credential, true, operation));
6426
6492
  if (upid === "") {
6427
- return yield* Effect86.fail(new StorageDownloadRefusedError(`${what}: PVE returned no task id, so the write cannot be confirmed and is not claimed.`));
6493
+ return yield* Effect87.fail(new StorageDownloadRefusedError(`${what}: PVE returned no task id, so the write cannot be confirmed and is not claimed.`));
6428
6494
  }
6429
6495
  let exit = "still running when this provider stopped waiting";
6430
6496
  for (let attempt = 0;attempt < polls; attempt++) {
6431
- const status = yield* runPveWith(where.target, credential, false, nodes18.getNodeTaskStatus({ node: where.node, upid })).pipe(Effect86.orElseSucceed(() => {
6497
+ const status = yield* runPveWith(where.target, credential, false, nodes18.getNodeTaskStatus({ node: where.node, upid })).pipe(Effect87.orElseSucceed(() => {
6432
6498
  return;
6433
6499
  }));
6434
6500
  if (status === undefined || status.status === undefined) {
@@ -6439,10 +6505,10 @@ var storageDownloadTask = (where, operation, what, polls) => Effect86.gen(functi
6439
6505
  exit = text(status.exitstatus, "stopped with no exitstatus");
6440
6506
  break;
6441
6507
  }
6442
- yield* Effect86.sleep("1 second");
6508
+ yield* Effect87.sleep("1 second");
6443
6509
  }
6444
6510
  if (exit !== "OK") {
6445
- return yield* Effect86.fail(new StorageDownloadRefusedError(`${what}: task ${upid} ended "${exit}". Read the task log before running the deploy again.`));
6511
+ return yield* Effect87.fail(new StorageDownloadRefusedError(`${what}: task ${upid} ended "${exit}". Read the task log before running the deploy again.`));
6446
6512
  }
6447
6513
  });
6448
6514
 
@@ -6468,14 +6534,14 @@ var createRefusals2 = (props) => {
6468
6534
  }
6469
6535
  return refuse3.concat(formViolations(DOWNLOAD_ENDPOINT, downloadForm(props), true).map((why) => `${props.filename}: ${why}`));
6470
6536
  };
6471
- var readDownload = (props) => Effect87.gen(function* () {
6537
+ var readDownload = (props) => Effect88.gen(function* () {
6472
6538
  const rows = yield* runPve(props.target, "read", false, nodes19.listNodeStorageContent({
6473
6539
  content: "import",
6474
6540
  node: props.node,
6475
6541
  storage: props.storage
6476
6542
  }));
6477
6543
  if (!Array.isArray(rows)) {
6478
- return yield* Effect87.fail(new StorageDownloadRefusedError(`${props.storage}: the content list did not come back as a list.`));
6544
+ return yield* Effect88.fail(new StorageDownloadRefusedError(`${props.storage}: the content list did not come back as a list.`));
6479
6545
  }
6480
6546
  const found = rows.find((row) => row.volid.endsWith(`/${props.filename}`));
6481
6547
  if (found === undefined)
@@ -6489,7 +6555,7 @@ var readDownload = (props) => Effect87.gen(function* () {
6489
6555
  volid: text(found.volid, "")
6490
6556
  };
6491
6557
  });
6492
- var destroyDownload = (props) => Effect87.gen(function* () {
6558
+ var destroyDownload = (props) => Effect88.gen(function* () {
6493
6559
  const live = yield* readDownload(props);
6494
6560
  if (live === undefined)
6495
6561
  return;
@@ -6500,26 +6566,26 @@ var destroyDownload = (props) => Effect87.gen(function* () {
6500
6566
  }), `delete ${live.volid}`, DELETE_POLLS2);
6501
6567
  });
6502
6568
  var storageDownloadHandlers = {
6503
- list: () => Effect87.succeed([]),
6504
- read: Effect87.fn(function* ({
6569
+ list: () => Effect88.succeed([]),
6570
+ read: Effect88.fn(function* ({
6505
6571
  fqn,
6506
6572
  instanceId,
6507
6573
  olds,
6508
6574
  output
6509
6575
  }) {
6510
6576
  const found = yield* readDownload(olds);
6511
- return yield* ownedRead({ fqn, instanceId, output }, found, Effect87.succeed(true));
6577
+ return yield* ownedRead({ fqn, instanceId, output }, found, Effect88.succeed(true));
6512
6578
  }),
6513
- diff: Effect87.fn(function* ({
6579
+ diff: Effect88.fn(function* ({
6514
6580
  news,
6515
6581
  olds,
6516
6582
  output
6517
6583
  }) {
6518
- if (!isResolved27(news))
6584
+ if (!isResolved28(news))
6519
6585
  return;
6520
6586
  const refused2 = createRefusals2(news);
6521
6587
  if (refused2.length > 0) {
6522
- return yield* Effect87.fail(new StorageDownloadRefusedError(refused2.join(`
6588
+ return yield* Effect88.fail(new StorageDownloadRefusedError(refused2.join(`
6523
6589
  `)));
6524
6590
  }
6525
6591
  if (output === undefined)
@@ -6529,11 +6595,11 @@ var storageDownloadHandlers = {
6529
6595
  return { action: "replace" };
6530
6596
  const live = yield* readDownload(news);
6531
6597
  if (identity2.kind === "pin-changed" && live !== undefined) {
6532
- return yield* Effect87.fail(new StorageDownloadRefusedError(identity2.refuse));
6598
+ return yield* Effect88.fail(new StorageDownloadRefusedError(identity2.refuse));
6533
6599
  }
6534
6600
  return { action: live === undefined ? "update" : "noop" };
6535
6601
  }),
6536
- reconcile: Effect87.fn(function* ({
6602
+ reconcile: Effect88.fn(function* ({
6537
6603
  fqn,
6538
6604
  instanceId,
6539
6605
  news,
@@ -6541,7 +6607,7 @@ var storageDownloadHandlers = {
6541
6607
  }) {
6542
6608
  const refused2 = createRefusals2(news);
6543
6609
  if (refused2.length > 0) {
6544
- return yield* Effect87.fail(new StorageDownloadRefusedError(refused2.join(`
6610
+ return yield* Effect88.fail(new StorageDownloadRefusedError(refused2.join(`
6545
6611
  `)));
6546
6612
  }
6547
6613
  const live = yield* readDownload(news);
@@ -6552,7 +6618,7 @@ var storageDownloadHandlers = {
6552
6618
  }
6553
6619
  const after = yield* readDownload(news);
6554
6620
  if (after === undefined) {
6555
- return yield* Effect87.fail(new StorageDownloadRefusedError(`${news.filename}: the write returned no error but ${news.storage} still has no ` + "matching content — PVE may have normalised the filename; read it back by hand."));
6621
+ return yield* Effect88.fail(new StorageDownloadRefusedError(`${news.filename}: the write returned no error but ${news.storage} still has no ` + "matching content — PVE may have normalised the filename; read it back by hand."));
6556
6622
  }
6557
6623
  return after;
6558
6624
  }),
@@ -6561,17 +6627,17 @@ var storageDownloadHandlers = {
6561
6627
 
6562
6628
  // src/proxmox/storage-download.ts
6563
6629
  var ProxmoxStorageDownload = Resource29("Proxmox.StorageDownload");
6564
- var ProxmoxStorageDownloadProvider = () => Provider29.effect(ProxmoxStorageDownload, Effect88.succeed(ProxmoxStorageDownload.Provider.of(storageDownloadHandlers)));
6630
+ var ProxmoxStorageDownloadProvider = () => Provider29.effect(ProxmoxStorageDownload, Effect89.succeed(ProxmoxStorageDownload.Provider.of(storageDownloadHandlers)));
6565
6631
  // src/proxmox/replication-job.ts
6566
6632
  import { Resource as Resource30 } from "alchemy";
6567
6633
  import * as Provider30 from "alchemy/Provider";
6568
- import * as Effect90 from "effect/Effect";
6634
+ import * as Effect91 from "effect/Effect";
6569
6635
 
6570
6636
  // src/proxmox/replication-job-lifecycle.ts
6571
- import { isResolved as isResolved28 } from "alchemy/Diff";
6572
- import * as cluster11 from "@distilled.cloud/proxmox/cluster";
6637
+ import { isResolved as isResolved29 } from "alchemy/Diff";
6638
+ import * as cluster12 from "@distilled.cloud/proxmox/cluster";
6573
6639
  import { ProxmoxParseError as ProxmoxParseError6 } from "@distilled.cloud/proxmox/Errors";
6574
- import * as Effect89 from "effect/Effect";
6640
+ import * as Effect90 from "effect/Effect";
6575
6641
  import * as Schema6 from "effect/Schema";
6576
6642
 
6577
6643
  // src/proxmox/replication-job-form.ts
@@ -6632,21 +6698,21 @@ var malformed = () => new ProxmoxParseError6({
6632
6698
  body: undefined,
6633
6699
  cause: "Replication job response does not match the requested vendor identity"
6634
6700
  });
6635
- var readReplicationJob = (props) => runPve(props.target, "read", false, cluster11.getClusterReplication({ id: jobId(props) })).pipe(Effect89.flatMap((live) => Schema6.decodeUnknownEffect(Schema6.toType(cluster11.GetClusterReplicationResponse))({
6701
+ var readReplicationJob = (props) => runPve(props.target, "read", false, cluster12.getClusterReplication({ id: jobId(props) })).pipe(Effect90.flatMap((live) => Schema6.decodeUnknownEffect(Schema6.toType(cluster12.GetClusterReplicationResponse))({
6636
6702
  ...live,
6637
6703
  guest: int(live.guest, Number.NaN),
6638
6704
  jobnum: int(live.jobnum, Number.NaN),
6639
6705
  rate: undefined
6640
- }).pipe(Effect89.mapError(malformed), Effect89.as(live))), Effect89.flatMap((live) => live.id === jobId(props) && int(live.guest, Number.NaN) === props.guest && int(live.jobnum, Number.NaN) === props.jobnum ? Effect89.succeed(replicationJobSpec.attributes({ ...live }, props)) : Effect89.fail(malformed())), Effect89.catchTag("ReplicationJobNotFound", () => Effect89.succeed(undefined)));
6641
- var deleteReplicationJob = (props) => runPve(props.target, "provision", true, cluster11.deleteClusterReplication({ id: jobId(props) })).pipe(Effect89.catchTag("ReplicationJobNotFound", () => Effect89.void));
6706
+ }).pipe(Effect90.mapError(malformed), Effect90.as(live))), Effect90.flatMap((live) => live.id === jobId(props) && int(live.guest, Number.NaN) === props.guest && int(live.jobnum, Number.NaN) === props.jobnum ? Effect90.succeed(replicationJobSpec.attributes({ ...live }, props)) : Effect90.fail(malformed())), Effect90.catchTag("ReplicationJobNotFound", () => Effect90.succeed(undefined)));
6707
+ var deleteReplicationJob = (props) => runPve(props.target, "provision", true, cluster12.deleteClusterReplication({ id: jobId(props) })).pipe(Effect90.catchTag("ReplicationJobNotFound", () => Effect90.void));
6642
6708
  var replicationJobHandlers = {
6643
- list: () => Effect89.succeed([]),
6709
+ list: () => Effect90.succeed([]),
6644
6710
  read: ({ olds }) => readReplicationJob(olds),
6645
- diff: Effect89.fn(function* ({
6711
+ diff: Effect90.fn(function* ({
6646
6712
  news,
6647
6713
  output
6648
6714
  }) {
6649
- if (!isResolved28(news))
6715
+ if (!isResolved29(news))
6650
6716
  return;
6651
6717
  yield* guardCreate11(news, output === undefined);
6652
6718
  yield* guardUpdate11(news);
@@ -6659,20 +6725,20 @@ var replicationJobHandlers = {
6659
6725
  }
6660
6726
  return { action: replicationJobSpec.matches(live, news) ? "noop" : "update" };
6661
6727
  }),
6662
- reconcile: Effect89.fn(function* ({ news }) {
6728
+ reconcile: Effect90.fn(function* ({ news }) {
6663
6729
  const live = yield* readReplicationJob(news);
6664
6730
  yield* guardCreate11(news, live === undefined);
6665
6731
  yield* guardUpdate11(news);
6666
6732
  if (live === undefined) {
6667
- yield* runPve(news.target, "provision", true, cluster11.createClusterReplication(replicationJobSpec.createForm(news)));
6733
+ yield* runPve(news.target, "provision", true, cluster12.createClusterReplication(replicationJobSpec.createForm(news)));
6668
6734
  } else {
6669
6735
  const form2 = formToSend(replicationJobSpec.matches, live, news, replicationJobSpec.updateForm(news));
6670
6736
  if (form2 !== undefined)
6671
- yield* runPve(news.target, "provision", true, cluster11.putClusterReplication({ ...form2, id: jobId(news) }));
6737
+ yield* runPve(news.target, "provision", true, cluster12.putClusterReplication({ ...form2, id: jobId(news) }));
6672
6738
  }
6673
6739
  const after = yield* readReplicationJob(news);
6674
6740
  if (after === undefined)
6675
- return yield* Effect89.fail(new Error(`${replicationJobSpec.path(news)}: write returned success but the resource is still absent`));
6741
+ return yield* Effect90.fail(new Error(`${replicationJobSpec.path(news)}: write returned success but the resource is still absent`));
6676
6742
  return after;
6677
6743
  }),
6678
6744
  delete: ({ olds }) => deleteReplicationJob(olds)
@@ -6680,15 +6746,15 @@ var replicationJobHandlers = {
6680
6746
 
6681
6747
  // src/proxmox/replication-job.ts
6682
6748
  var ProxmoxReplicationJob = Resource30("Proxmox.ReplicationJob");
6683
- var ProxmoxReplicationJobProvider = () => Provider30.effect(ProxmoxReplicationJob, Effect90.succeed(ProxmoxReplicationJob.Provider.of(replicationJobHandlers)));
6749
+ var ProxmoxReplicationJobProvider = () => Provider30.effect(ProxmoxReplicationJob, Effect91.succeed(ProxmoxReplicationJob.Provider.of(replicationJobHandlers)));
6684
6750
  // src/proxmox/sdn-apply.ts
6685
6751
  import { Resource as Resource31 } from "alchemy";
6686
- import { isResolved as isResolved29 } from "alchemy/Diff";
6752
+ import { isResolved as isResolved30 } from "alchemy/Diff";
6687
6753
  import * as Provider31 from "alchemy/Provider";
6688
- import * as Effect92 from "effect/Effect";
6754
+ import * as Effect93 from "effect/Effect";
6689
6755
 
6690
6756
  // src/proxmox/sdn-apply-read.ts
6691
- import * as Effect91 from "effect/Effect";
6757
+ import * as Effect92 from "effect/Effect";
6692
6758
  var MARKED = [
6693
6759
  "cluster/sdn/zones",
6694
6760
  "cluster/sdn/vnets",
@@ -6697,7 +6763,7 @@ var MARKED = [
6697
6763
  "cluster/sdn/route-maps"
6698
6764
  ];
6699
6765
  var subsystemAbsent = (error) => error instanceof PveError && error.status === 501;
6700
- var markedPending = (target) => Effect91.all(MARKED.map((collection) => pve(target, "read", "GET", `${collection}?pending=1`).pipe(Effect91.map((rows) => (rows ?? []).filter((row) => row.state !== undefined).length), Effect91.catchIf(subsystemAbsent, () => Effect91.succeed(0)))), { concurrency: "unbounded" }).pipe(Effect91.map((counts) => counts.reduce((total, count2) => total + count2, 0)));
6766
+ var markedPending = (target) => Effect92.all(MARKED.map((collection) => pve(target, "read", "GET", `${collection}?pending=1`).pipe(Effect92.map((rows) => (rows ?? []).filter((row) => row.state !== undefined).length), Effect92.catchIf(subsystemAbsent, () => Effect92.succeed(0)))), { concurrency: "unbounded" }).pipe(Effect92.map((counts) => counts.reduce((total, count2) => total + count2, 0)));
6701
6767
  var fabricStaged = (staged, running) => {
6702
6768
  if (staged === undefined && running === undefined)
6703
6769
  return 0;
@@ -6705,9 +6771,9 @@ var fabricStaged = (staged, running) => {
6705
6771
  return "inconsistent";
6706
6772
  return staged === running ? 0 : 1;
6707
6773
  };
6708
- var fabricPending = (target) => Effect91.all(["pending", "running"].map((view) => pve(target, "read", "GET", `cluster/sdn/fabrics/all?${view}=1`).pipe(Effect91.map(canonical3), Effect91.catchIf(subsystemAbsent, () => Effect91.succeed(undefined)))), { concurrency: "unbounded" }).pipe(Effect91.flatMap(([staged, running]) => {
6774
+ var fabricPending = (target) => Effect92.all(["pending", "running"].map((view) => pve(target, "read", "GET", `cluster/sdn/fabrics/all?${view}=1`).pipe(Effect92.map(canonical3), Effect92.catchIf(subsystemAbsent, () => Effect92.succeed(undefined)))), { concurrency: "unbounded" }).pipe(Effect92.flatMap(([staged, running]) => {
6709
6775
  const verdict = fabricStaged(staged, running);
6710
- return verdict === "inconsistent" ? Effect91.die(new Error("cluster/sdn/fabrics/all answered 501 for one of ?pending=1 and ?running=1 and not " + "the other. Refusing to read that as a staged fabric change.")) : Effect91.succeed(verdict);
6776
+ return verdict === "inconsistent" ? Effect92.die(new Error("cluster/sdn/fabrics/all answered 501 for one of ?pending=1 and ?running=1 and not " + "the other. Refusing to read that as a staged fabric change.")) : Effect92.succeed(verdict);
6711
6777
  }));
6712
6778
  var canonical3 = (value) => JSON.stringify(sortDeep(value));
6713
6779
  var sortDeep = (value) => {
@@ -6720,23 +6786,23 @@ var sortDeep = (value) => {
6720
6786
  }
6721
6787
  return value;
6722
6788
  };
6723
- var sdnPendingCount = (target) => Effect91.all([markedPending(target), fabricPending(target)], { concurrency: "unbounded" }).pipe(Effect91.map(([marked, fabric]) => marked + fabric));
6789
+ var sdnPendingCount = (target) => Effect92.all([markedPending(target), fabricPending(target)], { concurrency: "unbounded" }).pipe(Effect92.map(([marked, fabric]) => marked + fabric));
6724
6790
 
6725
6791
  // src/proxmox/sdn-apply.ts
6726
6792
  var ProxmoxSdnApply = Resource31("Proxmox.SdnApply");
6727
- var read5 = (props) => sdnPendingCount(props.target).pipe(Effect92.map((pending) => ({ pending })));
6728
- var ProxmoxSdnApplyProvider = () => Provider31.effect(ProxmoxSdnApply, Effect92.succeed(ProxmoxSdnApply.Provider.of({
6729
- list: () => Effect92.succeed([]),
6730
- read: Effect92.fn(function* ({ olds }) {
6793
+ var read5 = (props) => sdnPendingCount(props.target).pipe(Effect93.map((pending) => ({ pending })));
6794
+ var ProxmoxSdnApplyProvider = () => Provider31.effect(ProxmoxSdnApply, Effect93.succeed(ProxmoxSdnApply.Provider.of({
6795
+ list: () => Effect93.succeed([]),
6796
+ read: Effect93.fn(function* ({ olds }) {
6731
6797
  return yield* read5(olds);
6732
6798
  }),
6733
- diff: Effect92.fn(function* ({ news }) {
6734
- if (!isResolved29(news))
6799
+ diff: Effect93.fn(function* ({ news }) {
6800
+ if (!isResolved30(news))
6735
6801
  return;
6736
6802
  const { pending } = yield* read5(news);
6737
6803
  return pending === 0 ? { action: "noop" } : { action: "update" };
6738
6804
  }),
6739
- reconcile: Effect92.fn(function* ({ news }) {
6805
+ reconcile: Effect93.fn(function* ({ news }) {
6740
6806
  const staged = yield* read5(news);
6741
6807
  if (staged.pending === 0)
6742
6808
  return staged;
@@ -6744,16 +6810,16 @@ var ProxmoxSdnApplyProvider = () => Provider31.effect(ProxmoxSdnApply, Effect92.
6744
6810
  yield* pve(news.target, "provision", "PUT", "cluster/sdn");
6745
6811
  const after = yield* read5(news);
6746
6812
  if (after.pending !== 0) {
6747
- return yield* Effect92.die(new Error(`PUT /cluster/sdn returned no error but ${String(after.pending)} SDN object(s) ` + "are still staged. The running config does not match the declared one -- check " + "`pvesh get /cluster/sdn/zones --pending 1` for the objects PVE refused."));
6813
+ return yield* Effect93.die(new Error(`PUT /cluster/sdn returned no error but ${String(after.pending)} SDN object(s) ` + "are still staged. The running config does not match the declared one -- check " + "`pvesh get /cluster/sdn/zones --pending 1` for the objects PVE refused."));
6748
6814
  }
6749
6815
  return after;
6750
6816
  }),
6751
- delete: () => Effect92.void
6817
+ delete: () => Effect93.void
6752
6818
  })));
6753
6819
  // src/proxmox/sdn-subnet.ts
6754
6820
  import { Resource as Resource32 } from "alchemy";
6755
6821
  import * as Provider32 from "alchemy/Provider";
6756
- import * as Effect93 from "effect/Effect";
6822
+ import * as Effect94 from "effect/Effect";
6757
6823
 
6758
6824
  // src/proxmox/sdn-subnet-form.ts
6759
6825
  var subnetId = (props) => `${props.zone}-${props.cidr.replace("/", "-")}`;
@@ -6777,14 +6843,14 @@ var createForm10 = (props) => ({
6777
6843
  subnet: props.cidr,
6778
6844
  type: "subnet"
6779
6845
  });
6780
- var updateForm7 = (props) => {
6846
+ var updateForm8 = (props) => {
6781
6847
  const clear = Object.entries(optional3(props)).filter(([, value]) => value === undefined).map(([key]) => key);
6782
6848
  return withClears(body5(props), clear);
6783
6849
  };
6784
6850
 
6785
6851
  // src/proxmox/sdn-subnet.ts
6786
6852
  var ProxmoxSdnSubnet = Resource32("Proxmox.SdnSubnet");
6787
- var handlers13 = pveHandlers({
6853
+ var handlers12 = pveHandlers({
6788
6854
  attributes: (live, props) => {
6789
6855
  const liveVnet = text(live["vnet"]);
6790
6856
  if (liveVnet !== "" && liveVnet !== props.vnet)
@@ -6811,13 +6877,13 @@ var handlers13 = pveHandlers({
6811
6877
  },
6812
6878
  matches: (attributes2, props) => attributes2.gateway === (props.gateway ?? "") && attributes2.snat === (props.snat === true) && attributes2.dnszoneprefix === (props.dnszoneprefix ?? "") && attributes2.dhcpDnsServer === (props.dhcpDnsServer ?? "") && attributes2.dhcpRange === declaredRanges(props.dhcpRange),
6813
6879
  path: (props) => `cluster/sdn/vnets/${props.vnet}/subnets/${subnetId(props)}`,
6814
- updateForm: updateForm7
6880
+ updateForm: updateForm8
6815
6881
  });
6816
- var ProxmoxSdnSubnetProvider = () => Provider32.effect(ProxmoxSdnSubnet, Effect93.succeed(ProxmoxSdnSubnet.Provider.of(handlers13)));
6882
+ var ProxmoxSdnSubnetProvider = () => Provider32.effect(ProxmoxSdnSubnet, Effect94.succeed(ProxmoxSdnSubnet.Provider.of(handlers12)));
6817
6883
  // src/proxmox/sdn-vnet.ts
6818
6884
  import { Resource as Resource33 } from "alchemy";
6819
6885
  import * as Provider33 from "alchemy/Provider";
6820
- import * as Effect94 from "effect/Effect";
6886
+ import * as Effect95 from "effect/Effect";
6821
6887
  var ProxmoxSdnVnet = Resource33("Proxmox.SdnVnet");
6822
6888
  var tagOf = (value) => typeof value === "number" ? value : undefined;
6823
6889
  var shape10 = (props) => {
@@ -6830,14 +6896,14 @@ var shape10 = (props) => {
6830
6896
  ...props.tag === undefined ? {} : { tag: String(props.tag) }
6831
6897
  };
6832
6898
  };
6833
- var updateForm8 = (props) => {
6899
+ var updateForm9 = (props) => {
6834
6900
  const unset2 = [
6835
6901
  ...(props.alias ?? "") === "" ? ["alias"] : [],
6836
6902
  ...props.tag === undefined ? ["tag"] : []
6837
6903
  ];
6838
6904
  return withClears(shape10(props), unset2);
6839
6905
  };
6840
- var handlers14 = pveHandlers({
6906
+ var handlers13 = pveHandlers({
6841
6907
  readRole: "provision",
6842
6908
  attributes: (live, props) => ({
6843
6909
  alias: typeof live["alias"] === "string" ? live["alias"] : "",
@@ -6853,13 +6919,13 @@ var handlers14 = pveHandlers({
6853
6919
  endpoint: { create: "pve:POST /cluster/sdn/vnets", update: "pve:PUT /cluster/sdn/vnets/{vnet}" },
6854
6920
  matches: (attributes2, props) => attributes2.zone === props.zone && attributes2.alias === (props.alias ?? "") && attributes2.tag === props.tag && attributes2.vlanaware === (props.vlanaware === true) && attributes2.isolatePorts === (props.isolatePorts === true),
6855
6921
  path: (props) => `cluster/sdn/vnets/${props.vnet}`,
6856
- updateForm: updateForm8
6922
+ updateForm: updateForm9
6857
6923
  });
6858
- var ProxmoxSdnVnetProvider = () => Provider33.effect(ProxmoxSdnVnet, Effect94.succeed(ProxmoxSdnVnet.Provider.of(handlers14)));
6924
+ var ProxmoxSdnVnetProvider = () => Provider33.effect(ProxmoxSdnVnet, Effect95.succeed(ProxmoxSdnVnet.Provider.of(handlers13)));
6859
6925
  // src/proxmox/sdn-zone.ts
6860
6926
  import { Resource as Resource34 } from "alchemy";
6861
6927
  import * as Provider34 from "alchemy/Provider";
6862
- import * as Effect95 from "effect/Effect";
6928
+ import * as Effect96 from "effect/Effect";
6863
6929
  var ProxmoxSdnZone = Resource34("Proxmox.SdnZone");
6864
6930
  var sameIpam = (live, declared2) => (live === "" ? "pve" : live) === (declared2 === undefined || declared2 === "" ? "pve" : declared2);
6865
6931
  var body6 = (props) => ({
@@ -6880,7 +6946,7 @@ var clearable = {
6880
6946
  vlan: ["dns", "dnszone", "ipam", "mtu", "nodes"],
6881
6947
  vxlan: ["dns", "dnszone", "ipam", "mtu", "nodes"]
6882
6948
  };
6883
- var handlers15 = pveHandlers({
6949
+ var handlers14 = pveHandlers({
6884
6950
  readRole: "provision",
6885
6951
  attributes: (live, props) => {
6886
6952
  const liveType = text(live["type"]);
@@ -6912,13 +6978,13 @@ var handlers15 = pveHandlers({
6912
6978
  return withClears(fields2, clear);
6913
6979
  }
6914
6980
  });
6915
- var ProxmoxSdnZoneProvider = () => Provider34.effect(ProxmoxSdnZone, Effect95.succeed(ProxmoxSdnZone.Provider.of(handlers15)));
6981
+ var ProxmoxSdnZoneProvider = () => Provider34.effect(ProxmoxSdnZone, Effect96.succeed(ProxmoxSdnZone.Provider.of(handlers14)));
6916
6982
  // src/proxmox/storage.ts
6917
6983
  import { Resource as Resource35 } from "alchemy";
6918
- import { isResolved as isResolved30 } from "alchemy/Diff";
6984
+ import { isResolved as isResolved31 } from "alchemy/Diff";
6919
6985
  import * as Provider35 from "alchemy/Provider";
6920
6986
  import * as storage2 from "@distilled.cloud/proxmox/storage";
6921
- import * as Effect97 from "effect/Effect";
6987
+ import * as Effect98 from "effect/Effect";
6922
6988
 
6923
6989
  // src/proxmox/storage-plugin-options.ts
6924
6990
  var SHARED_ACCEPTED_TYPES = new Set(["dir", "lvm", "btrfs", "esxi"]);
@@ -6926,12 +6992,12 @@ var sharedAccepted = (type) => SHARED_ACCEPTED_TYPES.has(type);
6926
6992
 
6927
6993
  // src/proxmox/storage-wire.ts
6928
6994
  import * as storage from "@distilled.cloud/proxmox/storage";
6929
- import * as Effect96 from "effect/Effect";
6995
+ import * as Effect97 from "effect/Effect";
6930
6996
  var str2 = (value, fallback = "") => typeof value === "string" ? value : fallback;
6931
6997
  var tokens = (value) => value.split(",").map((part) => part.trim()).filter((part) => part !== "").sort().join(",");
6932
6998
  var sameList2 = (declared2, live) => declared2 === undefined || tokens(declared2) === tokens(live);
6933
6999
  var same7 = (declared2, live) => declared2 === undefined || declared2 === live;
6934
- var attributesOf10 = (live, props) => {
7000
+ var attributesOf11 = (live, props) => {
6935
7001
  const data = live;
6936
7002
  return {
6937
7003
  comment: str2(data["comment"]),
@@ -6945,8 +7011,8 @@ var attributesOf10 = (live, props) => {
6945
7011
  type: str2(data["type"], props.type)
6946
7012
  };
6947
7013
  };
6948
- var readStorageOrFail = (props) => readOrUnreadable(runPve(props.target, "provision", false, storage.getStorage({ storage: props.storage }))).pipe(Effect96.map((live) => live === UNREADABLE ? UNREADABLE : attributesOf10(live, props)));
6949
- var readStorage = (props) => readStorageOrFail(props).pipe(Effect96.catchTag("StorageNotFound", () => Effect96.succeed(undefined)));
7014
+ var readStorageOrFail = (props) => readOrUnreadable(runPve(props.target, "provision", false, storage.getStorage({ storage: props.storage }))).pipe(Effect97.map((live) => live === UNREADABLE ? UNREADABLE : attributesOf11(live, props)));
7015
+ var readStorage = (props) => readStorageOrFail(props).pipe(Effect97.catchTag("StorageNotFound", () => Effect97.succeed(undefined)));
6950
7016
  var dropUnreadable7 = (live) => live === UNREADABLE ? undefined : live;
6951
7017
  var changedProps = (live, props) => ({
6952
7018
  ...sameList2(props.content, live.content) ? {} : { content: props.content },
@@ -6957,7 +7023,7 @@ var changedProps = (live, props) => ({
6957
7023
  ...same7(props.preallocation, live.preallocation) ? {} : { preallocation: props.preallocation },
6958
7024
  ...same7(props.comment, live.comment) ? {} : { comment: props.comment }
6959
7025
  });
6960
- var matches10 = (attributes2, props) => !sharedAccepted(props.type) && !same7(props.shared, attributes2.shared) ? Effect96.die(new Error(`storage/${props.storage}: declared shared: ${String(props.shared)}, but PVE reports ` + `${String(attributes2.shared)} and '${props.type}' storages never accept a 'shared' ` + "write (storage-plugin-options.ts) -- remove the declared shared or set it to match " + "what PVE already reports; this value can never be applied.")) : Effect96.succeed(Object.keys(changedProps(attributes2, props)).length === 0);
7026
+ var matches11 = (attributes2, props) => !sharedAccepted(props.type) && !same7(props.shared, attributes2.shared) ? Effect97.die(new Error(`storage/${props.storage}: declared shared: ${String(props.shared)}, but PVE reports ` + `${String(attributes2.shared)} and '${props.type}' storages never accept a 'shared' ` + "write (storage-plugin-options.ts) -- remove the declared shared or set it to match " + "what PVE already reports; this value can never be applied.")) : Effect97.succeed(Object.keys(changedProps(attributes2, props)).length === 0);
6961
7027
 
6962
7028
  // src/proxmox/storage-form.ts
6963
7029
  var STORAGE_CREATE = "pve:POST /storage";
@@ -6980,7 +7046,7 @@ var createForm11 = (props) => ({
6980
7046
  storage: props.storage,
6981
7047
  type: props.type
6982
7048
  });
6983
- var updateForm9 = (props, live) => ({
7049
+ var updateForm10 = (props, live) => ({
6984
7050
  ...mutable2(props.type, live === undefined ? props : changedProps(live, props)),
6985
7051
  storage: props.storage
6986
7052
  });
@@ -6991,16 +7057,16 @@ var toDistilledUpdate3 = (form2) => underscored(form2);
6991
7057
  var ProxmoxStorage = Resource35("Proxmox.Storage", {
6992
7058
  defaultRemovalPolicy: "retain"
6993
7059
  });
6994
- var ProxmoxStorageProvider = () => Provider35.effect(ProxmoxStorage, Effect97.succeed(ProxmoxStorage.Provider.of({
6995
- list: () => Effect97.succeed([]),
6996
- read: Effect97.fn(function* ({ olds, output }) {
7060
+ var ProxmoxStorageProvider = () => Provider35.effect(ProxmoxStorage, Effect98.succeed(ProxmoxStorage.Provider.of({
7061
+ list: () => Effect98.succeed([]),
7062
+ read: Effect98.fn(function* ({ olds, output }) {
6997
7063
  return dropUnreadable7(yield* output === undefined ? readStorage(olds) : readStorageOrFail(olds));
6998
7064
  }),
6999
- diff: Effect97.fn(function* ({ news, output }) {
7000
- if (!isResolved30(news))
7065
+ diff: Effect98.fn(function* ({ news, output }) {
7066
+ if (!isResolved31(news))
7001
7067
  return;
7002
7068
  yield* guardWrite2(STORAGE_CREATE, createForm11(news), output === undefined);
7003
- yield* guardWrite2(STORAGE_UPDATE, updateForm9(news, undefined), false);
7069
+ yield* guardWrite2(STORAGE_UPDATE, updateForm10(news, undefined), false);
7004
7070
  if (output === undefined)
7005
7071
  return;
7006
7072
  const live = yield* readStorageOrFail(news);
@@ -7012,61 +7078,61 @@ var ProxmoxStorageProvider = () => Provider35.effect(ProxmoxStorage, Effect97.su
7012
7078
  yield* guardWrite2(STORAGE_CREATE, createForm11(news), true);
7013
7079
  return { action: "update" };
7014
7080
  }
7015
- return (yield* matches10(live, news)) ? { action: "noop" } : { action: "update" };
7081
+ return (yield* matches11(live, news)) ? { action: "noop" } : { action: "update" };
7016
7082
  }),
7017
- reconcile: Effect97.fn(function* ({ news }) {
7083
+ reconcile: Effect98.fn(function* ({ news }) {
7018
7084
  const before = dropUnreadable7(yield* readStorage(news));
7019
7085
  yield* guardWrite2(STORAGE_CREATE, createForm11(news), before === undefined);
7020
- const update2 = updateForm9(news, before);
7086
+ const update2 = updateForm10(news, before);
7021
7087
  yield* guardWrite2(STORAGE_UPDATE, update2, false);
7022
7088
  if (before === undefined) {
7023
7089
  yield* runPve(news.target, "provision", true, storage2.createStorage(toDistilledCreate4(news)));
7024
- } else if (!(yield* matches10(before, news))) {
7090
+ } else if (!(yield* matches11(before, news))) {
7025
7091
  yield* runPve(news.target, "provision", true, storage2.putStorage(toDistilledUpdate3(update2)));
7026
7092
  }
7027
7093
  const after = dropUnreadable7(yield* readStorage(news));
7028
7094
  if (after === undefined) {
7029
- return yield* Effect97.die(new Error(`storage/${news.storage}: the write returned no error but the storage is still ` + 'absent. PVE wraps every answer in {"data":...} and can report success on a ' + "call that did nothing -- read back rather than trusting the status code."));
7095
+ return yield* Effect98.die(new Error(`storage/${news.storage}: the write returned no error but the storage is still ` + 'absent. PVE wraps every answer in {"data":...} and can report success on a ' + "call that did nothing -- read back rather than trusting the status code."));
7030
7096
  }
7031
7097
  return after;
7032
7098
  }),
7033
- delete: Effect97.fn(function* ({ olds }) {
7099
+ delete: Effect98.fn(function* ({ olds }) {
7034
7100
  yield* runPve(olds.target, "provision", true, storage2.deleteStorage({ storage: olds.storage }));
7035
7101
  })
7036
7102
  })));
7037
7103
  // src/proxmox/zfs-pool.ts
7038
7104
  import { Resource as Resource36 } from "alchemy";
7039
- import { isResolved as isResolved31 } from "alchemy/Diff";
7105
+ import { isResolved as isResolved32 } from "alchemy/Diff";
7040
7106
  import * as Provider36 from "alchemy/Provider";
7041
- import * as Effect100 from "effect/Effect";
7107
+ import * as Effect101 from "effect/Effect";
7042
7108
 
7043
7109
  // src/proxmox/zfs-pool-wire.ts
7044
7110
  import * as nodes20 from "@distilled.cloud/proxmox/nodes";
7045
- import * as Effect98 from "effect/Effect";
7111
+ import * as Effect99 from "effect/Effect";
7046
7112
  var leafDevices = (children) => Array.isArray(children) ? children.flatMap((entry) => {
7047
7113
  const vdev = entry;
7048
7114
  const nested = leafDevices(vdev.children);
7049
7115
  return nested.length > 0 ? nested : [text(vdev.name)].filter((name) => name !== "");
7050
7116
  }) : [];
7051
- var attributesOf11 = (live, props) => ({
7117
+ var attributesOf12 = (live, props) => ({
7052
7118
  devices: leafDevices(live.children).join(","),
7053
7119
  errors: text(live.errors, "unknown"),
7054
7120
  name: props.name,
7055
7121
  node: props.node,
7056
7122
  state: text(live.state, "unknown")
7057
7123
  });
7058
- var readPoolOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, nodes20.getNodeDiskZfs({ name: props.name, node: props.node }))).pipe(Effect98.map((live) => {
7124
+ var readPoolOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, nodes20.getNodeDiskZfs({ name: props.name, node: props.node }))).pipe(Effect99.map((live) => {
7059
7125
  if (live === UNREADABLE)
7060
7126
  return UNREADABLE;
7061
- return text(live.name) === "" ? undefined : attributesOf11(live, props);
7127
+ return text(live.name) === "" ? undefined : attributesOf12(live, props);
7062
7128
  }));
7063
- var readPool2 = (props) => readPoolOrFail(props).pipe(Effect98.orElseSucceed(() => {
7129
+ var readPool2 = (props) => readPoolOrFail(props).pipe(Effect99.orElseSucceed(() => {
7064
7130
  return;
7065
7131
  }));
7066
7132
  var dropUnreadable8 = (live) => live === UNREADABLE ? undefined : live;
7067
7133
 
7068
7134
  // src/proxmox/zfs-pool-form.ts
7069
- import * as Effect99 from "effect/Effect";
7135
+ import * as Effect100 from "effect/Effect";
7070
7136
  import * as nodes21 from "@distilled.cloud/proxmox/nodes";
7071
7137
  var ZFS_POOL_CREATE = "pve:POST /nodes/{node}/disks/zfs";
7072
7138
  var zfsPoolCreateEndpoint = (props) => props.devices === undefined || props.raidlevel === undefined ? undefined : ZFS_POOL_CREATE;
@@ -7087,25 +7153,25 @@ var toDistilledCreate5 = (props) => {
7087
7153
  };
7088
7154
  };
7089
7155
  var SETTLE_ATTEMPTS = 30;
7090
- var createPool2 = (props, read6) => Effect99.gen(function* () {
7156
+ var createPool2 = (props, read6) => Effect100.gen(function* () {
7091
7157
  const existing = yield* read6(props);
7092
7158
  if (existing !== undefined)
7093
7159
  return existing;
7094
7160
  if (props.devices === undefined || props.raidlevel === undefined) {
7095
- return yield* Effect99.die(new Error(`${props.node}/${props.name}: this is an adopt-only declaration (no \`devices\` or ` + "`raidlevel`) and the pool is not there to adopt. An adopt-only Proxmox.ZfsPool never " + "creates -- declare both fields for a pool this resource should build, or point this " + "declaration at a pool that already exists on this node."));
7161
+ return yield* Effect100.die(new Error(`${props.node}/${props.name}: this is an adopt-only declaration (no \`devices\` or ` + "`raidlevel`) and the pool is not there to adopt. An adopt-only Proxmox.ZfsPool never " + "creates -- declare both fields for a pool this resource should build, or point this " + "declaration at a pool that already exists on this node."));
7096
7162
  }
7097
7163
  yield* guardForm(zfsPoolCreateEndpoint(props), asForm2(createForm12(props)), true);
7098
7164
  const upid = yield* runPve(props.target, "provision", true, nodes21.createNodeDiskZfs(toDistilledCreate5(props)));
7099
- const settle3 = (attempts) => Effect99.gen(function* () {
7165
+ const settle3 = (attempts) => Effect100.gen(function* () {
7100
7166
  const live = yield* read6(props);
7101
7167
  if (live !== undefined || attempts <= 0)
7102
7168
  return live;
7103
- yield* Effect99.sleep("2 seconds");
7169
+ yield* Effect100.sleep("2 seconds");
7104
7170
  return yield* settle3(attempts - 1);
7105
7171
  });
7106
7172
  const after = yield* settle3(SETTLE_ATTEMPTS);
7107
7173
  if (after === undefined) {
7108
- return yield* Effect99.die(new Error(`nodes/${props.node}/disks/zfs/${props.name}: POST returned ${text(upid, "(no UPID)")} ` + "but the pool has not appeared. That POST only forks a `zfscreate` worker, so the task " + `holds the real error -- read it with \`pvesh get /nodes/${props.node}/tasks/<upid>/log\`. ` + "NOTHING WAS RETRIED AND NOTHING WAS CLEANED UP: if the worker reached `zpool create`, " + "the declared devices have already been written to. DO NOT RE-RUN THIS DEPLOY BEFORE " + 'READING THAT LOG: `read` cannot tell "the worker is still running" from "the pool is ' + 'genuinely gone", so a re-run this soon can POST a SECOND `zpool create` at the SAME ' + "devices while the first one is still mid-write -- confirm the task finished (one way " + "or the other) before trying again."));
7174
+ return yield* Effect100.die(new Error(`nodes/${props.node}/disks/zfs/${props.name}: POST returned ${text(upid, "(no UPID)")} ` + "but the pool has not appeared. That POST only forks a `zfscreate` worker, so the task " + `holds the real error -- read it with \`pvesh get /nodes/${props.node}/tasks/<upid>/log\`. ` + "NOTHING WAS RETRIED AND NOTHING WAS CLEANED UP: if the worker reached `zpool create`, " + "the declared devices have already been written to. DO NOT RE-RUN THIS DEPLOY BEFORE " + 'READING THAT LOG: `read` cannot tell "the worker is still running" from "the pool is ' + 'genuinely gone", so a re-run this soon can POST a SECOND `zpool create` at the SAME ' + "devices while the first one is still mid-write -- confirm the task finished (one way " + "or the other) before trying again."));
7109
7175
  }
7110
7176
  return after;
7111
7177
  });
@@ -7115,13 +7181,13 @@ var destroyPool = (props) => runPve(props.target, "provision", true, nodes21.del
7115
7181
  var ProxmoxZfsPool = Resource36("Proxmox.ZfsPool", {
7116
7182
  defaultRemovalPolicy: "retain"
7117
7183
  });
7118
- var ProxmoxZfsPoolProvider = () => Provider36.effect(ProxmoxZfsPool, Effect100.succeed(ProxmoxZfsPool.Provider.of({
7119
- list: () => Effect100.succeed([]),
7120
- read: Effect100.fn(function* ({ olds, output }) {
7184
+ var ProxmoxZfsPoolProvider = () => Provider36.effect(ProxmoxZfsPool, Effect101.succeed(ProxmoxZfsPool.Provider.of({
7185
+ list: () => Effect101.succeed([]),
7186
+ read: Effect101.fn(function* ({ olds, output }) {
7121
7187
  return dropUnreadable8(yield* output === undefined ? readPool2(olds) : readPoolOrFail(olds));
7122
7188
  }),
7123
- diff: Effect100.fn(function* ({ news, output }) {
7124
- if (!isResolved31(news))
7189
+ diff: Effect101.fn(function* ({ news, output }) {
7190
+ if (!isResolved32(news))
7125
7191
  return;
7126
7192
  yield* guardForm(zfsPoolCreateEndpoint(news), asForm2(createForm12(news)), output === undefined);
7127
7193
  if (output === undefined)
@@ -7137,10 +7203,10 @@ var ProxmoxZfsPoolProvider = () => Provider36.effect(ProxmoxZfsPool, Effect100.s
7137
7203
  }
7138
7204
  return { action: "noop" };
7139
7205
  }),
7140
- reconcile: Effect100.fn(function* ({ news }) {
7141
- return yield* createPool2(news, (props) => readPool2(props).pipe(Effect100.map(dropUnreadable8)));
7206
+ reconcile: Effect101.fn(function* ({ news }) {
7207
+ return yield* createPool2(news, (props) => readPool2(props).pipe(Effect101.map(dropUnreadable8)));
7142
7208
  }),
7143
- delete: Effect100.fn(function* ({ olds }) {
7209
+ delete: Effect101.fn(function* ({ olds }) {
7144
7210
  yield* destroyPool(olds);
7145
7211
  })
7146
7212
  })));
@@ -7223,5 +7289,5 @@ export {
7223
7289
  violations
7224
7290
  };
7225
7291
 
7226
- //# debugId=71934628F9E3FB7664756E2164756E21
7292
+ //# debugId=E0B844E10EA9EF3D64756E2164756E21
7227
7293
  //# sourceMappingURL=index.js.map