@homeflare/alchemy 0.43.0 → 0.45.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 (612) 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/credential-errors.d.ts +131 -0
  17. package/dist/litellm/credential-errors.d.ts.map +1 -0
  18. package/dist/litellm/credential-form.d.ts +79 -0
  19. package/dist/litellm/credential-form.d.ts.map +1 -0
  20. package/dist/litellm/credential-operations.d.ts +84 -0
  21. package/dist/litellm/credential-operations.d.ts.map +1 -0
  22. package/dist/litellm/credential-rewrite.d.ts +6 -0
  23. package/dist/litellm/credential-rewrite.d.ts.map +1 -0
  24. package/dist/litellm/credential-types.d.ts +87 -0
  25. package/dist/litellm/credential-types.d.ts.map +1 -0
  26. package/dist/litellm/credential-values.d.ts +53 -0
  27. package/dist/litellm/credential-values.d.ts.map +1 -0
  28. package/dist/litellm/credential.d.ts +83 -0
  29. package/dist/litellm/credential.d.ts.map +1 -0
  30. package/dist/litellm/fake-access-group-litellm.d.ts +34 -0
  31. package/dist/litellm/fake-access-group-litellm.d.ts.map +1 -0
  32. package/dist/litellm/fake-credential-litellm.d.ts +54 -0
  33. package/dist/litellm/fake-credential-litellm.d.ts.map +1 -0
  34. package/dist/litellm/fake-keys.d.ts +53 -0
  35. package/dist/litellm/fake-keys.d.ts.map +1 -0
  36. package/dist/litellm/fake-litellm.d.ts +4 -1
  37. package/dist/litellm/fake-litellm.d.ts.map +1 -1
  38. package/dist/litellm/fake-mcp-litellm.d.ts +67 -0
  39. package/dist/litellm/fake-mcp-litellm.d.ts.map +1 -0
  40. package/dist/litellm/fake-model-litellm-post-update.d.ts +49 -0
  41. package/dist/litellm/fake-model-litellm-post-update.d.ts.map +1 -0
  42. package/dist/litellm/fake-model-litellm.d.ts +48 -0
  43. package/dist/litellm/fake-model-litellm.d.ts.map +1 -0
  44. package/dist/litellm/fake-policy-attachment-litellm.d.ts +33 -0
  45. package/dist/litellm/fake-policy-attachment-litellm.d.ts.map +1 -0
  46. package/dist/litellm/fake-policy-litellm.d.ts +32 -0
  47. package/dist/litellm/fake-policy-litellm.d.ts.map +1 -0
  48. package/dist/litellm/fake-registry-base.d.ts +42 -0
  49. package/dist/litellm/fake-registry-base.d.ts.map +1 -0
  50. package/dist/litellm/fake-stack.d.ts +8 -1
  51. package/dist/litellm/fake-stack.d.ts.map +1 -1
  52. package/dist/litellm/fake-team-litellm.d.ts +47 -0
  53. package/dist/litellm/fake-team-litellm.d.ts.map +1 -0
  54. package/dist/litellm/fake-tool-litellm.d.ts +28 -0
  55. package/dist/litellm/fake-tool-litellm.d.ts.map +1 -0
  56. package/dist/litellm/fake-toolset-litellm.d.ts +29 -0
  57. package/dist/litellm/fake-toolset-litellm.d.ts.map +1 -0
  58. package/dist/litellm/index.d.ts +18 -0
  59. package/dist/litellm/index.d.ts.map +1 -1
  60. package/dist/litellm/index.js +3078 -2
  61. package/dist/litellm/index.js.map +65 -4
  62. package/dist/litellm/key-errors.d.ts +169 -0
  63. package/dist/litellm/key-errors.d.ts.map +1 -0
  64. package/dist/litellm/key-form.d.ts +119 -0
  65. package/dist/litellm/key-form.d.ts.map +1 -0
  66. package/dist/litellm/key-harness.d.ts +41 -0
  67. package/dist/litellm/key-harness.d.ts.map +1 -0
  68. package/dist/litellm/key-metadata-errors.d.ts +30 -0
  69. package/dist/litellm/key-metadata-errors.d.ts.map +1 -0
  70. package/dist/litellm/key-metadata.d.ts +22 -0
  71. package/dist/litellm/key-metadata.d.ts.map +1 -0
  72. package/dist/litellm/key-operations.d.ts +63 -0
  73. package/dist/litellm/key-operations.d.ts.map +1 -0
  74. package/dist/litellm/key-secret.d.ts +33 -0
  75. package/dist/litellm/key-secret.d.ts.map +1 -0
  76. package/dist/litellm/key.d.ts +78 -0
  77. package/dist/litellm/key.d.ts.map +1 -0
  78. package/dist/litellm/mcp-server-credential.d.ts +50 -0
  79. package/dist/litellm/mcp-server-credential.d.ts.map +1 -0
  80. package/dist/litellm/mcp-server-errors.d.ts +101 -0
  81. package/dist/litellm/mcp-server-errors.d.ts.map +1 -0
  82. package/dist/litellm/mcp-server-form.d.ts +56 -0
  83. package/dist/litellm/mcp-server-form.d.ts.map +1 -0
  84. package/dist/litellm/mcp-server-locate.d.ts +26 -0
  85. package/dist/litellm/mcp-server-locate.d.ts.map +1 -0
  86. package/dist/litellm/mcp-server-operations.d.ts +63 -0
  87. package/dist/litellm/mcp-server-operations.d.ts.map +1 -0
  88. package/dist/litellm/mcp-server-shadow.d.ts +24 -0
  89. package/dist/litellm/mcp-server-shadow.d.ts.map +1 -0
  90. package/dist/litellm/mcp-server-types.d.ts +118 -0
  91. package/dist/litellm/mcp-server-types.d.ts.map +1 -0
  92. package/dist/litellm/mcp-server-url.d.ts +11 -0
  93. package/dist/litellm/mcp-server-url.d.ts.map +1 -0
  94. package/dist/litellm/mcp-server.d.ts +95 -0
  95. package/dist/litellm/mcp-server.d.ts.map +1 -0
  96. package/dist/litellm/model-claim.d.ts +24 -0
  97. package/dist/litellm/model-claim.d.ts.map +1 -0
  98. package/dist/litellm/model-credential.d.ts +12 -0
  99. package/dist/litellm/model-credential.d.ts.map +1 -0
  100. package/dist/litellm/model-errors.d.ts +119 -0
  101. package/dist/litellm/model-errors.d.ts.map +1 -0
  102. package/dist/litellm/model-form.d.ts +78 -0
  103. package/dist/litellm/model-form.d.ts.map +1 -0
  104. package/dist/litellm/model-locate.d.ts +13 -0
  105. package/dist/litellm/model-locate.d.ts.map +1 -0
  106. package/dist/litellm/model-operations.d.ts +59 -0
  107. package/dist/litellm/model-operations.d.ts.map +1 -0
  108. package/dist/litellm/model-types.d.ts +91 -0
  109. package/dist/litellm/model-types.d.ts.map +1 -0
  110. package/dist/litellm/model.d.ts +88 -0
  111. package/dist/litellm/model.d.ts.map +1 -0
  112. package/dist/litellm/policy-attachment-form.d.ts +19 -0
  113. package/dist/litellm/policy-attachment-form.d.ts.map +1 -0
  114. package/dist/litellm/policy-attachment-operations.d.ts +31 -0
  115. package/dist/litellm/policy-attachment-operations.d.ts.map +1 -0
  116. package/dist/litellm/policy-attachment-types.d.ts +48 -0
  117. package/dist/litellm/policy-attachment-types.d.ts.map +1 -0
  118. package/dist/litellm/policy-attachment.d.ts +61 -0
  119. package/dist/litellm/policy-attachment.d.ts.map +1 -0
  120. package/dist/litellm/policy-form.d.ts +22 -0
  121. package/dist/litellm/policy-form.d.ts.map +1 -0
  122. package/dist/litellm/policy-operations.d.ts +42 -0
  123. package/dist/litellm/policy-operations.d.ts.map +1 -0
  124. package/dist/litellm/policy-types.d.ts +57 -0
  125. package/dist/litellm/policy-types.d.ts.map +1 -0
  126. package/dist/litellm/policy.d.ts +65 -0
  127. package/dist/litellm/policy.d.ts.map +1 -0
  128. package/dist/litellm/providers.d.ts +1 -1
  129. package/dist/litellm/providers.d.ts.map +1 -1
  130. package/dist/litellm/registry-errors.d.ts +62 -0
  131. package/dist/litellm/registry-errors.d.ts.map +1 -0
  132. package/dist/litellm/registry-support.d.ts +42 -0
  133. package/dist/litellm/registry-support.d.ts.map +1 -0
  134. package/dist/litellm/team-form.d.ts +26 -0
  135. package/dist/litellm/team-form.d.ts.map +1 -0
  136. package/dist/litellm/team-members.d.ts +10 -0
  137. package/dist/litellm/team-members.d.ts.map +1 -0
  138. package/dist/litellm/team-operations.d.ts +38 -0
  139. package/dist/litellm/team-operations.d.ts.map +1 -0
  140. package/dist/litellm/team-permission.d.ts +35 -0
  141. package/dist/litellm/team-permission.d.ts.map +1 -0
  142. package/dist/litellm/team-types.d.ts +101 -0
  143. package/dist/litellm/team-types.d.ts.map +1 -0
  144. package/dist/litellm/team.d.ts +67 -0
  145. package/dist/litellm/team.d.ts.map +1 -0
  146. package/dist/litellm/tool-policy-form.d.ts +21 -0
  147. package/dist/litellm/tool-policy-form.d.ts.map +1 -0
  148. package/dist/litellm/tool-policy-operations.d.ts +30 -0
  149. package/dist/litellm/tool-policy-operations.d.ts.map +1 -0
  150. package/dist/litellm/tool-policy-types.d.ts +46 -0
  151. package/dist/litellm/tool-policy-types.d.ts.map +1 -0
  152. package/dist/litellm/tool-policy.d.ts +62 -0
  153. package/dist/litellm/tool-policy.d.ts.map +1 -0
  154. package/dist/litellm/toolset-form.d.ts +20 -0
  155. package/dist/litellm/toolset-form.d.ts.map +1 -0
  156. package/dist/litellm/toolset-operations.d.ts +39 -0
  157. package/dist/litellm/toolset-operations.d.ts.map +1 -0
  158. package/dist/litellm/toolset-types.d.ts +46 -0
  159. package/dist/litellm/toolset-types.d.ts.map +1 -0
  160. package/dist/litellm/toolset.d.ts +55 -0
  161. package/dist/litellm/toolset.d.ts.map +1 -0
  162. package/dist/openbao/index.js +35 -1
  163. package/dist/openbao/index.js.map +3 -3
  164. package/dist/ownership/rows.d.ts +11 -0
  165. package/dist/ownership/rows.d.ts.map +1 -1
  166. package/dist/postgres/connection.d.ts +14 -2
  167. package/dist/postgres/connection.d.ts.map +1 -1
  168. package/dist/postgres/database-sql.d.ts +27 -8
  169. package/dist/postgres/database-sql.d.ts.map +1 -1
  170. package/dist/postgres/fake-grants-parse.d.ts +37 -0
  171. package/dist/postgres/fake-grants-parse.d.ts.map +1 -0
  172. package/dist/postgres/fake-grants-read.d.ts +61 -0
  173. package/dist/postgres/fake-grants-read.d.ts.map +1 -0
  174. package/dist/postgres/fake-grants-sql.d.ts +46 -0
  175. package/dist/postgres/fake-grants-sql.d.ts.map +1 -0
  176. package/dist/postgres/fake-grants-write.d.ts +29 -0
  177. package/dist/postgres/fake-grants-write.d.ts.map +1 -0
  178. package/dist/postgres/fake-role-sql.d.ts +41 -0
  179. package/dist/postgres/fake-role-sql.d.ts.map +1 -0
  180. package/dist/postgres/fake-schema-sql.d.ts +42 -0
  181. package/dist/postgres/fake-schema-sql.d.ts.map +1 -0
  182. package/dist/postgres/fake-sql-parse.d.ts +23 -0
  183. package/dist/postgres/fake-sql-parse.d.ts.map +1 -0
  184. package/dist/postgres/fake-sql-quote.d.ts +12 -0
  185. package/dist/postgres/fake-sql-quote.d.ts.map +1 -0
  186. package/dist/postgres/fake-sql.d.ts +42 -0
  187. package/dist/postgres/fake-sql.d.ts.map +1 -1
  188. package/dist/postgres/grants-attrs.d.ts +115 -0
  189. package/dist/postgres/grants-attrs.d.ts.map +1 -0
  190. package/dist/postgres/grants-declare.d.ts +88 -0
  191. package/dist/postgres/grants-declare.d.ts.map +1 -0
  192. package/dist/postgres/grants-diff.d.ts +25 -0
  193. package/dist/postgres/grants-diff.d.ts.map +1 -0
  194. package/dist/postgres/grants-errors.d.ts +137 -0
  195. package/dist/postgres/grants-errors.d.ts.map +1 -0
  196. package/dist/postgres/grants-existence.d.ts +14 -0
  197. package/dist/postgres/grants-existence.d.ts.map +1 -0
  198. package/dist/postgres/grants-ops.d.ts +65 -0
  199. package/dist/postgres/grants-ops.d.ts.map +1 -0
  200. package/dist/postgres/grants-ownership.d.ts +18 -0
  201. package/dist/postgres/grants-ownership.d.ts.map +1 -0
  202. package/dist/postgres/grants-plan-restore.d.ts +22 -0
  203. package/dist/postgres/grants-plan-restore.d.ts.map +1 -0
  204. package/dist/postgres/grants-plan.d.ts +65 -0
  205. package/dist/postgres/grants-plan.d.ts.map +1 -0
  206. package/dist/postgres/grants-read-defaults.d.ts +17 -0
  207. package/dist/postgres/grants-read-defaults.d.ts.map +1 -0
  208. package/dist/postgres/grants-read.d.ts +77 -0
  209. package/dist/postgres/grants-read.d.ts.map +1 -0
  210. package/dist/postgres/grants-refuse.d.ts +25 -0
  211. package/dist/postgres/grants-refuse.d.ts.map +1 -0
  212. package/dist/postgres/grants-sql.d.ts +42 -0
  213. package/dist/postgres/grants-sql.d.ts.map +1 -0
  214. package/dist/postgres/grants-words.d.ts +29 -0
  215. package/dist/postgres/grants-words.d.ts.map +1 -0
  216. package/dist/postgres/grants.d.ts +37 -0
  217. package/dist/postgres/grants.d.ts.map +1 -0
  218. package/dist/postgres/index.d.ts +31 -6
  219. package/dist/postgres/index.d.ts.map +1 -1
  220. package/dist/postgres/index.js +1998 -37
  221. package/dist/postgres/index.js.map +46 -7
  222. package/dist/postgres/installed-classifier.d.ts +13 -0
  223. package/dist/postgres/installed-classifier.d.ts.map +1 -0
  224. package/dist/postgres/providers.d.ts +16 -8
  225. package/dist/postgres/providers.d.ts.map +1 -1
  226. package/dist/postgres/psql-executor.d.ts +4 -0
  227. package/dist/postgres/psql-executor.d.ts.map +1 -1
  228. package/dist/postgres/role-attrs.d.ts +112 -0
  229. package/dist/postgres/role-attrs.d.ts.map +1 -0
  230. package/dist/postgres/role-diff.d.ts +22 -0
  231. package/dist/postgres/role-diff.d.ts.map +1 -0
  232. package/dist/postgres/role-errors.d.ts +132 -0
  233. package/dist/postgres/role-errors.d.ts.map +1 -0
  234. package/dist/postgres/role-membership-sql.d.ts +78 -0
  235. package/dist/postgres/role-membership-sql.d.ts.map +1 -0
  236. package/dist/postgres/role-provider.d.ts +11 -0
  237. package/dist/postgres/role-provider.d.ts.map +1 -0
  238. package/dist/postgres/role-scram.d.ts +8 -0
  239. package/dist/postgres/role-scram.d.ts.map +1 -0
  240. package/dist/postgres/role-secrets.d.ts +38 -0
  241. package/dist/postgres/role-secrets.d.ts.map +1 -0
  242. package/dist/postgres/role-sql.d.ts +68 -0
  243. package/dist/postgres/role-sql.d.ts.map +1 -0
  244. package/dist/postgres/role.d.ts +57 -0
  245. package/dist/postgres/role.d.ts.map +1 -0
  246. package/dist/postgres/schema-assert.d.ts +50 -0
  247. package/dist/postgres/schema-assert.d.ts.map +1 -0
  248. package/dist/postgres/schema-attrs.d.ts +51 -0
  249. package/dist/postgres/schema-attrs.d.ts.map +1 -0
  250. package/dist/postgres/schema-delete.d.ts +28 -0
  251. package/dist/postgres/schema-delete.d.ts.map +1 -0
  252. package/dist/postgres/schema-diff.d.ts +14 -0
  253. package/dist/postgres/schema-diff.d.ts.map +1 -0
  254. package/dist/postgres/schema-errors.d.ts +139 -0
  255. package/dist/postgres/schema-errors.d.ts.map +1 -0
  256. package/dist/postgres/schema-identity.d.ts +8 -0
  257. package/dist/postgres/schema-identity.d.ts.map +1 -0
  258. package/dist/postgres/schema-reconcile.d.ts +12 -0
  259. package/dist/postgres/schema-reconcile.d.ts.map +1 -0
  260. package/dist/postgres/schema-sql.d.ts +45 -0
  261. package/dist/postgres/schema-sql.d.ts.map +1 -0
  262. package/dist/postgres/schema-test-kit.d.ts +67 -0
  263. package/dist/postgres/schema-test-kit.d.ts.map +1 -0
  264. package/dist/postgres/schema.d.ts +54 -0
  265. package/dist/postgres/schema.d.ts.map +1 -0
  266. package/dist/proxmox/index.js +35 -1
  267. package/dist/proxmox/index.js.map +3 -3
  268. package/dist/release/fake-engine.d.ts +10 -0
  269. package/dist/release/fake-engine.d.ts.map +1 -1
  270. package/dist/release/index.js +35 -1
  271. package/dist/release/index.js.map +3 -3
  272. package/dist/valkey/acl-attrs.d.ts +94 -0
  273. package/dist/valkey/acl-attrs.d.ts.map +1 -0
  274. package/dist/valkey/acl-compare.d.ts +28 -0
  275. package/dist/valkey/acl-compare.d.ts.map +1 -0
  276. package/dist/valkey/acl-connection.d.ts +6 -0
  277. package/dist/valkey/acl-connection.d.ts.map +1 -0
  278. package/dist/valkey/acl-form.d.ts +62 -0
  279. package/dist/valkey/acl-form.d.ts.map +1 -0
  280. package/dist/valkey/acl-managed.d.ts +4 -0
  281. package/dist/valkey/acl-managed.d.ts.map +1 -0
  282. package/dist/valkey/acl-ops.d.ts +37 -0
  283. package/dist/valkey/acl-ops.d.ts.map +1 -0
  284. package/dist/valkey/acl-profiles.d.ts +53 -0
  285. package/dist/valkey/acl-profiles.d.ts.map +1 -0
  286. package/dist/valkey/acl-reconcile.d.ts +26 -0
  287. package/dist/valkey/acl-reconcile.d.ts.map +1 -0
  288. package/dist/valkey/acl.d.ts +24 -0
  289. package/dist/valkey/acl.d.ts.map +1 -0
  290. package/dist/valkey/connection-service.d.ts +22 -0
  291. package/dist/valkey/connection-service.d.ts.map +1 -0
  292. package/dist/valkey/connection.d.ts +59 -0
  293. package/dist/valkey/connection.d.ts.map +1 -0
  294. package/dist/valkey/errors.d.ts +165 -0
  295. package/dist/valkey/errors.d.ts.map +1 -0
  296. package/dist/valkey/fake-acl.d.ts +29 -0
  297. package/dist/valkey/fake-acl.d.ts.map +1 -0
  298. package/dist/valkey/fake-valkey.d.ts +35 -0
  299. package/dist/valkey/fake-valkey.d.ts.map +1 -0
  300. package/dist/valkey/handler-test-fixture.d.ts +20 -0
  301. package/dist/valkey/handler-test-fixture.d.ts.map +1 -0
  302. package/dist/valkey/index.d.ts +18 -0
  303. package/dist/valkey/index.d.ts.map +1 -0
  304. package/dist/valkey/index.js +964 -0
  305. package/dist/valkey/index.js.map +27 -0
  306. package/dist/valkey/instance-attrs.d.ts +46 -0
  307. package/dist/valkey/instance-attrs.d.ts.map +1 -0
  308. package/dist/valkey/instance-form.d.ts +22 -0
  309. package/dist/valkey/instance-form.d.ts.map +1 -0
  310. package/dist/valkey/instance.d.ts +48 -0
  311. package/dist/valkey/instance.d.ts.map +1 -0
  312. package/dist/valkey/provider-socket-fixture.d.ts +8 -0
  313. package/dist/valkey/provider-socket-fixture.d.ts.map +1 -0
  314. package/dist/valkey/providers.d.ts +16 -0
  315. package/dist/valkey/providers.d.ts.map +1 -0
  316. package/dist/valkey/resp.d.ts +38 -0
  317. package/dist/valkey/resp.d.ts.map +1 -0
  318. package/dist/valkey/transport-error.d.ts +36 -0
  319. package/dist/valkey/transport-error.d.ts.map +1 -0
  320. package/dist/valkey/transport.d.ts +50 -0
  321. package/dist/valkey/transport.d.ts.map +1 -0
  322. package/docs/litellm-access-group.md +105 -0
  323. package/docs/litellm-credential.md +60 -0
  324. package/docs/litellm-key-metadata.md +56 -0
  325. package/docs/litellm-key.md +194 -0
  326. package/docs/litellm-mcp.md +187 -0
  327. package/docs/litellm-model.md +111 -0
  328. package/docs/litellm-policy-attachment.md +86 -0
  329. package/docs/litellm-policy.md +103 -0
  330. package/docs/litellm-team.md +117 -0
  331. package/docs/litellm-tool-policy.md +90 -0
  332. package/docs/litellm-toolset.md +92 -0
  333. package/docs/litellm.md +16 -9
  334. package/docs/peers.md +15 -6
  335. package/docs/postgres-grants-example.md +55 -0
  336. package/docs/postgres-grants.md +157 -0
  337. package/docs/postgres-role.md +126 -0
  338. package/docs/postgres-schema.md +139 -0
  339. package/docs/postgres.md +20 -3
  340. package/docs/valkey-transport.md +29 -0
  341. package/docs/valkey.md +187 -0
  342. package/package.json +6 -2
  343. package/src/ceph/ceph-argv.test.ts +1 -1
  344. package/src/launchd/sudo-allowlist.test.ts +2 -2
  345. package/src/linux/sudo-allowlist.test.ts +3 -3
  346. package/src/linux/sudo-runner.test.ts +2 -2
  347. package/src/litellm/access-group-form.ts +105 -0
  348. package/src/litellm/access-group-operations.ts +92 -0
  349. package/src/litellm/access-group-types.ts +49 -0
  350. package/src/litellm/access-group.test.ts +197 -0
  351. package/src/litellm/access-group.ts +151 -0
  352. package/src/litellm/credential-errors.ts +183 -0
  353. package/src/litellm/credential-form.test.ts +151 -0
  354. package/src/litellm/credential-form.ts +211 -0
  355. package/src/litellm/credential-guards.test.ts +241 -0
  356. package/src/litellm/credential-operations.ts +208 -0
  357. package/src/litellm/credential-recovery.test.ts +93 -0
  358. package/src/litellm/credential-rewrite.test.ts +164 -0
  359. package/src/litellm/credential-rewrite.ts +50 -0
  360. package/src/litellm/credential-types.ts +117 -0
  361. package/src/litellm/credential-values.ts +94 -0
  362. package/src/litellm/credential.test.ts +218 -0
  363. package/src/litellm/credential.ts +227 -0
  364. package/src/litellm/fake-access-group-litellm.ts +127 -0
  365. package/src/litellm/fake-credential-litellm.ts +216 -0
  366. package/src/litellm/fake-keys.ts +190 -0
  367. package/src/litellm/fake-litellm.ts +19 -9
  368. package/src/litellm/fake-mcp-litellm.ts +214 -0
  369. package/src/litellm/fake-model-litellm-post-update.ts +103 -0
  370. package/src/litellm/fake-model-litellm.ts +233 -0
  371. package/src/litellm/fake-policy-attachment-litellm.ts +97 -0
  372. package/src/litellm/fake-policy-litellm.ts +186 -0
  373. package/src/litellm/fake-registry-base.ts +69 -0
  374. package/src/litellm/fake-stack.ts +17 -1
  375. package/src/litellm/fake-team-litellm.ts +229 -0
  376. package/src/litellm/fake-tool-litellm.ts +88 -0
  377. package/src/litellm/fake-toolset-litellm.ts +110 -0
  378. package/src/litellm/index.ts +140 -0
  379. package/src/litellm/key-delete.test.ts +212 -0
  380. package/src/litellm/key-errors.ts +241 -0
  381. package/src/litellm/key-form.ts +200 -0
  382. package/src/litellm/key-harness.ts +121 -0
  383. package/src/litellm/key-metadata-errors.ts +49 -0
  384. package/src/litellm/key-metadata.test.ts +156 -0
  385. package/src/litellm/key-metadata.ts +74 -0
  386. package/src/litellm/key-operations.ts +184 -0
  387. package/src/litellm/key-rotation.test.ts +110 -0
  388. package/src/litellm/key-scope.test.ts +135 -0
  389. package/src/litellm/key-secret.test.ts +248 -0
  390. package/src/litellm/key-secret.ts +137 -0
  391. package/src/litellm/key-transport.test.ts +166 -0
  392. package/src/litellm/key.test.ts +231 -0
  393. package/src/litellm/key.ts +213 -0
  394. package/src/litellm/mcp-server-adopt.test.ts +86 -0
  395. package/src/litellm/mcp-server-alias.test.ts +184 -0
  396. package/src/litellm/mcp-server-credential.ts +85 -0
  397. package/src/litellm/mcp-server-errors.ts +141 -0
  398. package/src/litellm/mcp-server-exports.test.ts +15 -0
  399. package/src/litellm/mcp-server-form.test.ts +241 -0
  400. package/src/litellm/mcp-server-form.ts +233 -0
  401. package/src/litellm/mcp-server-handlers.test.ts +150 -0
  402. package/src/litellm/mcp-server-locate.ts +66 -0
  403. package/src/litellm/mcp-server-operations.ts +111 -0
  404. package/src/litellm/mcp-server-registry.test.ts +146 -0
  405. package/src/litellm/mcp-server-retype.test.ts +114 -0
  406. package/src/litellm/mcp-server-shadow.test.ts +91 -0
  407. package/src/litellm/mcp-server-shadow.ts +45 -0
  408. package/src/litellm/mcp-server-tools.test.ts +85 -0
  409. package/src/litellm/mcp-server-types.ts +143 -0
  410. package/src/litellm/mcp-server-url.ts +66 -0
  411. package/src/litellm/mcp-server.test.ts +213 -0
  412. package/src/litellm/mcp-server.ts +225 -0
  413. package/src/litellm/model-claim.ts +69 -0
  414. package/src/litellm/model-credential.ts +45 -0
  415. package/src/litellm/model-errors.ts +168 -0
  416. package/src/litellm/model-foreign-row.test.ts +173 -0
  417. package/src/litellm/model-form.test.ts +228 -0
  418. package/src/litellm/model-form.ts +223 -0
  419. package/src/litellm/model-locate.test.ts +128 -0
  420. package/src/litellm/model-locate.ts +67 -0
  421. package/src/litellm/model-operations.test.ts +93 -0
  422. package/src/litellm/model-operations.ts +146 -0
  423. package/src/litellm/model-params-preserve.test.ts +119 -0
  424. package/src/litellm/model-recovery.test.ts +57 -0
  425. package/src/litellm/model-types.ts +112 -0
  426. package/src/litellm/model.test.ts +222 -0
  427. package/src/litellm/model.ts +237 -0
  428. package/src/litellm/policy-attachment-form.ts +103 -0
  429. package/src/litellm/policy-attachment-operations.ts +74 -0
  430. package/src/litellm/policy-attachment-types.ts +48 -0
  431. package/src/litellm/policy-attachment.test.ts +198 -0
  432. package/src/litellm/policy-attachment.ts +178 -0
  433. package/src/litellm/policy-form.ts +122 -0
  434. package/src/litellm/policy-operations.ts +112 -0
  435. package/src/litellm/policy-types.ts +58 -0
  436. package/src/litellm/policy.test.ts +214 -0
  437. package/src/litellm/policy.ts +146 -0
  438. package/src/litellm/providers.ts +24 -3
  439. package/src/litellm/registry-errors.ts +88 -0
  440. package/src/litellm/registry-exports.test.ts +66 -0
  441. package/src/litellm/registry-support.ts +109 -0
  442. package/src/litellm/team-form.ts +140 -0
  443. package/src/litellm/team-members.test.ts +150 -0
  444. package/src/litellm/team-members.ts +58 -0
  445. package/src/litellm/team-operations.ts +90 -0
  446. package/src/litellm/team-permission.ts +159 -0
  447. package/src/litellm/team-read.test.ts +89 -0
  448. package/src/litellm/team-types.ts +106 -0
  449. package/src/litellm/team.test.ts +206 -0
  450. package/src/litellm/team.ts +159 -0
  451. package/src/litellm/tool-policy-form.ts +94 -0
  452. package/src/litellm/tool-policy-operations.ts +58 -0
  453. package/src/litellm/tool-policy-types.ts +48 -0
  454. package/src/litellm/tool-policy.test.ts +172 -0
  455. package/src/litellm/tool-policy.ts +125 -0
  456. package/src/litellm/toolset-form.ts +104 -0
  457. package/src/litellm/toolset-operations.ts +90 -0
  458. package/src/litellm/toolset-types.ts +47 -0
  459. package/src/litellm/toolset.test.ts +198 -0
  460. package/src/litellm/toolset.ts +151 -0
  461. package/src/ownership/ownership.test.ts +33 -1
  462. package/src/ownership/rows.ts +53 -0
  463. package/src/postgres/connection.ts +42 -7
  464. package/src/postgres/database-bigint-serialization.test.ts +1 -0
  465. package/src/postgres/database-refusals.test.ts +2 -2
  466. package/src/postgres/database-sql.ts +36 -9
  467. package/src/postgres/fake-grants-parse.ts +189 -0
  468. package/src/postgres/fake-grants-read.ts +250 -0
  469. package/src/postgres/fake-grants-sql.ts +207 -0
  470. package/src/postgres/fake-grants-write.ts +90 -0
  471. package/src/postgres/fake-role-sql.ts +240 -0
  472. package/src/postgres/fake-schema-semantics.test.ts +36 -0
  473. package/src/postgres/fake-schema-sql.ts +146 -0
  474. package/src/postgres/fake-sql-parse.ts +86 -0
  475. package/src/postgres/fake-sql-quote.ts +36 -0
  476. package/src/postgres/fake-sql.ts +166 -46
  477. package/src/postgres/fixtures/pg-REL_18_6-acl.h.txt +147 -0
  478. package/src/postgres/fixtures/pg-REL_18_6-aclexplode-func.txt +31 -0
  479. package/src/postgres/fixtures/pg-REL_18_6-alter-default-privileges-synopsis.txt +82 -0
  480. package/src/postgres/fixtures/pg-REL_18_6-alter_role.sgml.txt +44 -0
  481. package/src/postgres/fixtures/pg-REL_18_6-create_role.sgml.txt +26 -0
  482. package/src/postgres/fixtures/pg-REL_18_6-grant-synopsis.txt +95 -0
  483. package/src/postgres/fixtures/pg-REL_18_6-pg_attribute.h.txt +24 -0
  484. package/src/postgres/fixtures/pg-REL_18_6-pg_auth_members.h.txt +62 -0
  485. package/src/postgres/fixtures/pg-REL_18_6-pg_authid.h.txt +70 -0
  486. package/src/postgres/fixtures/pg-REL_18_6-pg_class.h.txt +33 -0
  487. package/src/postgres/fixtures/pg-REL_18_6-pg_default_acl.h.txt +81 -0
  488. package/src/postgres/fixtures/pg-REL_18_6-pg_namespace.h.txt +28 -0
  489. package/src/postgres/fixtures/pg-REL_18_6-revoke-synopsis.txt +124 -0
  490. package/src/postgres/grants-acl.test.ts +61 -0
  491. package/src/postgres/grants-attrs.ts +185 -0
  492. package/src/postgres/grants-database.test.ts +158 -0
  493. package/src/postgres/grants-declare.ts +172 -0
  494. package/src/postgres/grants-delete-proof.test.ts +154 -0
  495. package/src/postgres/grants-diff.ts +101 -0
  496. package/src/postgres/grants-errors.ts +215 -0
  497. package/src/postgres/grants-existence-guards.test.ts +113 -0
  498. package/src/postgres/grants-existence.ts +101 -0
  499. package/src/postgres/grants-lifecycle-guards.test.ts +208 -0
  500. package/src/postgres/grants-lifecycle-repair.test.ts +208 -0
  501. package/src/postgres/grants-lifecycle.test.ts +181 -0
  502. package/src/postgres/grants-ops.ts +229 -0
  503. package/src/postgres/grants-owner-revoke.test.ts +121 -0
  504. package/src/postgres/grants-ownership.ts +49 -0
  505. package/src/postgres/grants-plan-collateral.test.ts +202 -0
  506. package/src/postgres/grants-plan-diff.test.ts +204 -0
  507. package/src/postgres/grants-plan-restore.ts +43 -0
  508. package/src/postgres/grants-plan-revocations.test.ts +69 -0
  509. package/src/postgres/grants-plan.test.ts +148 -0
  510. package/src/postgres/grants-plan.ts +245 -0
  511. package/src/postgres/grants-provenance.test.ts +134 -0
  512. package/src/postgres/grants-psql-lifecycle.test.ts +105 -0
  513. package/src/postgres/grants-read-absent.test.ts +91 -0
  514. package/src/postgres/grants-read-defaults.ts +51 -0
  515. package/src/postgres/grants-read.ts +250 -0
  516. package/src/postgres/grants-refusals.test.ts +136 -0
  517. package/src/postgres/grants-refuse.ts +119 -0
  518. package/src/postgres/grants-relkind-wire.test.ts +111 -0
  519. package/src/postgres/grants-repair-plan.test.ts +201 -0
  520. package/src/postgres/grants-sql.test.ts +128 -0
  521. package/src/postgres/grants-sql.ts +144 -0
  522. package/src/postgres/grants-words.ts +34 -0
  523. package/src/postgres/grants.ts +110 -0
  524. package/src/postgres/index.ts +129 -5
  525. package/src/postgres/installed-classifier.ts +36 -0
  526. package/src/postgres/providers.ts +33 -9
  527. package/src/postgres/psql-executor-escaping.test.ts +67 -0
  528. package/src/postgres/psql-executor.test.ts +63 -2
  529. package/src/postgres/psql-executor.ts +74 -34
  530. package/src/postgres/role-adopt.test.ts +98 -0
  531. package/src/postgres/role-attrs.ts +137 -0
  532. package/src/postgres/role-diff.ts +93 -0
  533. package/src/postgres/role-errors.ts +206 -0
  534. package/src/postgres/role-guard.test.ts +60 -0
  535. package/src/postgres/role-identity.test.ts +197 -0
  536. package/src/postgres/role-lifecycle.test.ts +228 -0
  537. package/src/postgres/role-membership-options.test.ts +73 -0
  538. package/src/postgres/role-membership-repair.test.ts +153 -0
  539. package/src/postgres/role-membership-sql.ts +223 -0
  540. package/src/postgres/role-password-ascii.test.ts +53 -0
  541. package/src/postgres/role-password-transports.test.ts +123 -0
  542. package/src/postgres/role-password.test.ts +158 -0
  543. package/src/postgres/role-privilege.test.ts +107 -0
  544. package/src/postgres/role-provenance.test.ts +200 -0
  545. package/src/postgres/role-provider.ts +105 -0
  546. package/src/postgres/role-refusals.test.ts +225 -0
  547. package/src/postgres/role-scram.test.ts +38 -0
  548. package/src/postgres/role-scram.ts +40 -0
  549. package/src/postgres/role-secrets.ts +61 -0
  550. package/src/postgres/role-sql.ts +213 -0
  551. package/src/postgres/role-valid-until.test.ts +68 -0
  552. package/src/postgres/role.ts +226 -0
  553. package/src/postgres/schema-assert.ts +139 -0
  554. package/src/postgres/schema-attrs.ts +71 -0
  555. package/src/postgres/schema-delete-proofs.test.ts +192 -0
  556. package/src/postgres/schema-delete.ts +96 -0
  557. package/src/postgres/schema-diff.ts +44 -0
  558. package/src/postgres/schema-drop-2bp01.test.ts +146 -0
  559. package/src/postgres/schema-errors.ts +209 -0
  560. package/src/postgres/schema-handlers.test.ts +193 -0
  561. package/src/postgres/schema-identity.ts +39 -0
  562. package/src/postgres/schema-lifecycle.test.ts +246 -0
  563. package/src/postgres/schema-race.test.ts +70 -0
  564. package/src/postgres/schema-reconcile.ts +100 -0
  565. package/src/postgres/schema-refusals.test.ts +144 -0
  566. package/src/postgres/schema-socket.test.ts +162 -0
  567. package/src/postgres/schema-sql.ts +130 -0
  568. package/src/postgres/schema-takeover.test.ts +149 -0
  569. package/src/postgres/schema-test-kit.ts +85 -0
  570. package/src/postgres/schema.ts +130 -0
  571. package/src/release/binary-alias.test.ts +3 -3
  572. package/src/release/binary-claims.test.ts +3 -3
  573. package/src/release/binary-directory-umask.test.ts +65 -0
  574. package/src/release/fake-engine.ts +15 -0
  575. package/src/valkey/acl-attrs.ts +98 -0
  576. package/src/valkey/acl-compare.ts +57 -0
  577. package/src/valkey/acl-connection.ts +13 -0
  578. package/src/valkey/acl-delete.test.ts +127 -0
  579. package/src/valkey/acl-form.ts +239 -0
  580. package/src/valkey/acl-managed.ts +13 -0
  581. package/src/valkey/acl-ops.ts +122 -0
  582. package/src/valkey/acl-ownership.test.ts +118 -0
  583. package/src/valkey/acl-prefix.test.ts +38 -0
  584. package/src/valkey/acl-profiles.ts +81 -0
  585. package/src/valkey/acl-reconcile.ts +180 -0
  586. package/src/valkey/acl-reserved.test.ts +69 -0
  587. package/src/valkey/acl-revocation.test.ts +94 -0
  588. package/src/valkey/acl-seat-prefix.test.ts +111 -0
  589. package/src/valkey/acl-validation.test.ts +54 -0
  590. package/src/valkey/acl.test.ts +215 -0
  591. package/src/valkey/acl.ts +169 -0
  592. package/src/valkey/connection-service.ts +46 -0
  593. package/src/valkey/connection.ts +180 -0
  594. package/src/valkey/errors.ts +239 -0
  595. package/src/valkey/fake-acl.ts +128 -0
  596. package/src/valkey/fake-valkey.ts +224 -0
  597. package/src/valkey/handler-test-fixture.ts +43 -0
  598. package/src/valkey/handlers.test.ts +205 -0
  599. package/src/valkey/index.ts +54 -0
  600. package/src/valkey/instance-attrs.ts +48 -0
  601. package/src/valkey/instance-form.ts +104 -0
  602. package/src/valkey/instance.test.ts +108 -0
  603. package/src/valkey/instance.ts +160 -0
  604. package/src/valkey/provider-socket-fixture.ts +71 -0
  605. package/src/valkey/providers.test.ts +129 -0
  606. package/src/valkey/providers.ts +21 -0
  607. package/src/valkey/resp.ts +212 -0
  608. package/src/valkey/transport-bounds.test.ts +150 -0
  609. package/src/valkey/transport-error.ts +37 -0
  610. package/src/valkey/transport.test.ts +158 -0
  611. package/src/valkey/transport.ts +109 -0
  612. package/src/valkey/upstream-bounds.test.ts +14 -0
@@ -0,0 +1,239 @@
1
+ /**
2
+ * `Valkey` family's failures as typed tags (S21).
3
+ *
4
+ * ⛔ NONE OF THESE IS A STATUS-CODE OR MESSAGE MATCH. They are raised by this family's own code
5
+ * from facts it already checked — missing env vars, mismatched live state, failed read-back —
6
+ * never from sniffing a server error's text. Socket/protocol errors use their own tags in
7
+ * `transport.ts`.
8
+ */
9
+ import * as Data from 'effect/Data';
10
+
11
+ /** The live instance does not match an asserted property. Like `Postgres.DatabaseDrift`, this
12
+ * family asserts properties at create and refuses drift rather than silently issuing a
13
+ * reconfiguration that could drop state. */
14
+ export class ValkeyInstanceDrift extends Data.TaggedError('ValkeyInstanceDrift')<{
15
+ readonly instance: string;
16
+ readonly prop: string;
17
+ readonly declared: unknown;
18
+ readonly live: unknown;
19
+ }> {
20
+ override get message(): string {
21
+ return (
22
+ `Valkey.Instance "${this.instance}": ${this.prop} is declared as ` +
23
+ `${JSON.stringify(this.declared)} but the live instance has ${JSON.stringify(this.live)}. ` +
24
+ 'Update the declaration to match the live value, or change it by hand and re-plan.'
25
+ );
26
+ }
27
+ }
28
+
29
+ /** `Valkey.Instance` found the instance unreachable or refused authentication when reading it.
30
+ * `host` is optional because it is the connection layer's value (`connection.ts`), never a prop
31
+ * this resource holds — a reconcile that only knows its own declaration names the port. */
32
+ export class ValkeyInstanceUnreachable extends Data.TaggedError('ValkeyInstanceUnreachable')<{
33
+ readonly instance: string;
34
+ readonly host?: string;
35
+ readonly port: number;
36
+ }> {
37
+ override get message(): string {
38
+ return (
39
+ `Valkey.Instance "${this.instance}" at ${this.host === undefined ? '' : `${this.host}:`}` +
40
+ `${String(this.port)}: could not verify the instance. Check that the Quadlet container is ` +
41
+ 'running and the ACL/password is correct.'
42
+ );
43
+ }
44
+ }
45
+
46
+ /** An ACL LIST line could not be parsed. Neither the message nor error data retain the
47
+ * raw line: error serialization must not expose its password hash. */
48
+ export class ValkeyAclParseError extends Data.TaggedError('ValkeyAclParseError')<{
49
+ // No raw ACL data.
50
+ }> {
51
+ override get message(): string {
52
+ return (
53
+ 'Valkey.AclFile: cannot parse an ACL LIST line. The line is withheld from this message ' +
54
+ 'because it can carry a password hash.'
55
+ );
56
+ }
57
+ }
58
+
59
+ /** A declared ACL user is missing a referenced password; a user with no password can authenticate
60
+ * as nobody, which would bypass isolation. */
61
+ export class ValkeyAclPasswordMissing extends Data.TaggedError('ValkeyAclPasswordMissing')<{
62
+ readonly instance: string;
63
+ readonly user: string;
64
+ readonly variable: string;
65
+ }> {
66
+ override get message(): string {
67
+ return (
68
+ `Valkey.AclFile "${this.instance}": ACL user "${this.user}" references environment ` +
69
+ `variable ${this.variable}, which is missing or empty at call time.`
70
+ );
71
+ }
72
+ }
73
+
74
+ /** The stack's own connection password is a `{ fromEnv }` reference that resolved to nothing at
75
+ * call time. Distinct from `ValkeyInstanceUnreachable` (nothing answered on the wire) and from
76
+ * `ValkeyAclPasswordMissing` (a DECLARED ACL user's password): this one is the credential the
77
+ * stack itself authenticates with to reach an instance. */
78
+ export class ValkeyAuthPasswordMissing extends Data.TaggedError('ValkeyAuthPasswordMissing')<{
79
+ readonly username: string | undefined;
80
+ readonly variable: string;
81
+ }> {
82
+ override get message(): string {
83
+ const who = this.username === undefined ? '' : ` as "${this.username}"`;
84
+ return (
85
+ `Valkey connection${who}: password environment variable ${this.variable} is missing or ` +
86
+ 'empty at call time. Render the secret into the deploying process environment and re-plan.'
87
+ );
88
+ }
89
+ }
90
+
91
+ /** The live ACL after a reconcile does not match the declaration on read-back — the write was lost
92
+ * or a concurrent mutator changed it before we could verify. */
93
+ export class ValkeyAclReadbackFailed extends Data.TaggedError('ValkeyAclReadbackFailed')<{
94
+ readonly instance: string;
95
+ readonly user: string;
96
+ }> {
97
+ override get message(): string {
98
+ return (
99
+ `Valkey.AclFile "${this.instance}": ACL reconciliation for "${this.user}" reported success, ` +
100
+ 'but readback contradicts the declared rules or removal. Re-plan.'
101
+ );
102
+ }
103
+ }
104
+
105
+ /** A `seat`-profile user's key prefix escapes its own keyspace. The seat profile exists to pin
106
+ * each seat to keys beginning with its own name (`~<name>:…`); `keyPrefix` goes on the wire as
107
+ * `~<keyPrefix>`, so `*` is every key and `grok:*` is another seat's. Refused before any write —
108
+ * a `service` user is the profile that owns a whole instance. */
109
+ export class ValkeyAclSeatKeyPrefix extends Data.TaggedError('ValkeyAclSeatKeyPrefix')<{
110
+ readonly instance: string;
111
+ readonly user: string;
112
+ readonly keyPrefix: string;
113
+ }> {
114
+ override get message(): string {
115
+ return (
116
+ `Valkey.AclFile "${this.instance}": ACL user "${this.user}" declares key prefix ` +
117
+ `"${this.keyPrefix}". A seat user is limited to "${this.user}:*"; a user that owns ` +
118
+ 'every key on the instance declares profile "service".'
119
+ );
120
+ }
121
+ }
122
+
123
+ /** A declaration names `default` or the connection username. `ACL SETUSER` `reset` would replace
124
+ * the credential this kit authenticates with (`~* +@all`) with a profile that cannot run `ACL`,
125
+ * and the next `ACL LIST` answers `NOPERM`. Refused before any write. */
126
+ export class ValkeyAclReservedUser extends Data.TaggedError('ValkeyAclReservedUser')<{
127
+ readonly instance: string;
128
+ readonly user: string;
129
+ }> {
130
+ override get message(): string {
131
+ return (
132
+ `Valkey.AclFile "${this.instance}": refusing to manage ACL user "${this.user}". ` +
133
+ 'That name is `default` or the connection username. ACL SETUSER reset would replace the ' +
134
+ 'credential this kit authenticates with, and the next ACL LIST would answer NOPERM.'
135
+ );
136
+ }
137
+ }
138
+
139
+ /** A live or stored ACL user is keyed under one name but its line carries another — the parsed
140
+ * `user` name disagrees with the record key this family stores it under. The record key is this
141
+ * family's identity, so the mismatch means the ACL was changed by something else. */
142
+ export class ValkeyAclUserNameMismatch extends Data.TaggedError('ValkeyAclUserNameMismatch')<{
143
+ readonly instance: string;
144
+ readonly recordKey: string;
145
+ readonly user: string;
146
+ }> {
147
+ override get message(): string {
148
+ return (
149
+ `Valkey.AclFile "${this.instance}": ACL user "${this.user}" was found keyed under ` +
150
+ `"${this.recordKey}". This family keys every user by its own name; re-plan or fix the ` +
151
+ 'ACL by hand on the instance.'
152
+ );
153
+ }
154
+ }
155
+
156
+ export type ValkeyError =
157
+ | ValkeyInstanceDrift
158
+ | ValkeyInstanceUnreachable
159
+ | ValkeyAclParseError
160
+ | ValkeyAclPasswordMissing
161
+ | ValkeyAclReadbackFailed
162
+ | ValkeyAclUserNameMismatch
163
+ | ValkeyAclReservedUser
164
+ | ValkeyAclSeatKeyPrefix
165
+ | ValkeyAclMonitorKeyPrefix
166
+ | ValkeyAclNameGlob
167
+ | ValkeyAclChannelPatterns
168
+ | ValkeyAclFileRendered
169
+ | ValkeyAuthPasswordMissing;
170
+
171
+ /** A `monitor`-profile user was declared with a key prefix. The monitor profile exists for the
172
+ * key-less `redis_exporter` identity (ct100#117): its rules carry `resetkeys`, and a `~` pattern
173
+ * next to them would contradict the key-less shape the profile is fixed to. Refused before any
174
+ * write. */
175
+ export class ValkeyAclMonitorKeyPrefix extends Data.TaggedError('ValkeyAclMonitorKeyPrefix')<{
176
+ readonly instance: string;
177
+ readonly user: string;
178
+ readonly keyPrefix: string;
179
+ }> {
180
+ override get message(): string {
181
+ return (
182
+ `Valkey.AclFile "${this.instance}": ACL user "${this.user}" declares profile "monitor" ` +
183
+ `with key prefix "${this.keyPrefix}". The monitor profile is key-less (resetkeys); omit ` +
184
+ 'the keyPrefix.'
185
+ );
186
+ }
187
+ }
188
+
189
+ /** A username carries glob characters (`*`, `?`, `[`, `]`). Names are interpolated into key and
190
+ * channel patterns (`~<name>:*`, `&<name>:*`), so a glob in the name would widen the patterns
191
+ * the profile is fixed to — `seat*` would reach `seat2:*`. Refused before any write. */
192
+ export class ValkeyAclNameGlob extends Data.TaggedError('ValkeyAclNameGlob')<{
193
+ readonly instance: string;
194
+ readonly user: string;
195
+ readonly chars: string;
196
+ }> {
197
+ override get message(): string {
198
+ return (
199
+ `Valkey.AclFile "${this.instance}": ACL user "${this.user}" contains glob characters ` +
200
+ `(${this.chars}). A name is interpolated into key and channel patterns, so a glob would ` +
201
+ 'widen the isolation the profile fixes. Use a glob-free name.'
202
+ );
203
+ }
204
+ }
205
+
206
+ /** The instance renders its ACL from a file (`--aclfile`, answered by `CONFIG GET aclfile`), so
207
+ * the FILE is the source of truth and this family cannot manage it: the kit speaks RESP only, it
208
+ * can neither write the file nor outlast the renderer that owns it (CT100: openbao-agent renders
209
+ * `/etc/valkey/*-acl.conf` and mounts it read-only — a runtime `ACL SETUSER` there is reverted by
210
+ * the next render/restart, measured 2026-09-30 as a WRONGPASS seat). Declare those users in the
211
+ * rendering template instead, or use kit-owned runtime ACL management without a configured ACL file. */
212
+ export class ValkeyAclFileRendered extends Data.TaggedError('ValkeyAclFileRendered')<{
213
+ readonly instance: string;
214
+ readonly path: string;
215
+ }> {
216
+ override get message(): string {
217
+ return (
218
+ `Valkey.AclFile "${this.instance}": the instance loads its ACL from "${this.path}" ` +
219
+ '(CONFIG GET aclfile), so the file — not this family — is the source of truth. The kit ' +
220
+ 'speaks RESP only and can neither write that file nor survive the renderer that owns it; ' +
221
+ 'a runtime ACL SETUSER there is reverted on the next render or restart. Declare the users ' +
222
+ 'in the rendering template. Adoption also reconciles and is refused. ACL reads require ' +
223
+ 'ACL LIST permission, which CT100 rendered users do not have.'
224
+ );
225
+ }
226
+ }
227
+
228
+ /** A fixed profile cannot widen its channel boundary by declaration. */
229
+ export class ValkeyAclChannelPatterns extends Data.TaggedError('ValkeyAclChannelPatterns')<{
230
+ readonly instance: string;
231
+ readonly user: string;
232
+ }> {
233
+ override get message(): string {
234
+ return (
235
+ `Valkey.AclFile "${this.instance}": invalid channel patterns for "${this.user}". ` +
236
+ 'Seats require <name>:*; monitors require no channels.'
237
+ );
238
+ }
239
+ }
@@ -0,0 +1,128 @@
1
+ /** ACL state model for the recording fake. Valkey's ACL docs specify additive SETUSER,
2
+ * reset, hash-only LIST echoes, and channel checks; this is not a complete ACL evaluator. */
3
+ import { createHash } from 'node:crypto';
4
+ /** One user's ACL state — the fake's parsed mirror of what a real server keeps per user. */
5
+ export interface FakeAclUser {
6
+ on: boolean;
7
+ nopass: boolean;
8
+ /** The stored `#<sha256>` tokens, empty when the user has no passwords. */
9
+ passwords: ReadonlyArray<string>;
10
+ /** Key patterns with their `~`, e.g. `['~claude:*']`. */
11
+ keys: ReadonlyArray<string>;
12
+ /** Channel patterns with their `&`; `['&*']` is what `allchannels` echoes as. */
13
+ channels: ReadonlyArray<string>;
14
+ /** The `+`/`-` rule tokens, with the `-@all` baseline the echo keeps. */
15
+ rules: ReadonlyArray<string>;
16
+ }
17
+
18
+ export const sha256 = (value: string): string => createHash('sha256').update(value).digest('hex');
19
+
20
+ /** A user straight out of `reset`: off, no password, no patterns, the `-@all` baseline. */
21
+ export const freshUser = (): FakeAclUser => ({
22
+ on: false,
23
+ nopass: false,
24
+ passwords: [],
25
+ keys: [],
26
+ channels: [],
27
+ rules: ['-@all'],
28
+ });
29
+
30
+ /** Apply one `ACL SETUSER` rule token, in order — the fake's model of the server's own
31
+ * incremental semantics (`reset` resets, `+@all` cancels the `-@all` baseline, and so on). */
32
+ export const applyToken = (user: FakeAclUser, token: string): void => {
33
+ switch (token) {
34
+ case 'reset':
35
+ Object.assign(user, freshUser());
36
+ break;
37
+ case 'reseton':
38
+ case 'resetoff':
39
+ user.on = false;
40
+ break;
41
+ case 'resetkeys':
42
+ user.keys = [];
43
+ break;
44
+ case 'resetchannels':
45
+ user.channels = [];
46
+ break;
47
+ case 'resetpass':
48
+ user.passwords = [];
49
+ user.nopass = false;
50
+ break;
51
+ case 'on':
52
+ user.on = true;
53
+ break;
54
+ case 'off':
55
+ user.on = false;
56
+ break;
57
+ case 'nopass':
58
+ user.nopass = true;
59
+ user.passwords = [];
60
+ break;
61
+ case 'allkeys':
62
+ user.keys = ['~*'];
63
+ break;
64
+ case 'allchannels':
65
+ user.channels = ['&*'];
66
+ break;
67
+ default:
68
+ if (token.startsWith('#')) {
69
+ user.passwords = [...new Set([...user.passwords, token])];
70
+ user.nopass = false;
71
+ } else if (token.startsWith('>')) {
72
+ user.passwords = [...new Set([...user.passwords, `#${sha256(token.slice(1))}`])];
73
+ user.nopass = false;
74
+ } else if (token.startsWith('<') || token.startsWith('!')) {
75
+ const hash = token[0] === '<' ? sha256(token.slice(1)) : token.slice(1);
76
+ user.passwords = user.passwords.filter((password) => password !== `#${hash}`);
77
+ } else if (token.startsWith('~')) {
78
+ user.keys = [...user.keys, token];
79
+ } else if (token.startsWith('&')) {
80
+ user.channels = [...user.channels, token];
81
+ } else if (token === '-@all' || token === '+@all') {
82
+ user.rules = [token];
83
+ } else if (token.startsWith('+') || token.startsWith('-')) {
84
+ const rules = [...user.rules];
85
+ const i = rules.indexOf(token);
86
+ if (i >= 0) rules.splice(i, 1);
87
+ user.rules = [...rules, token];
88
+ }
89
+ }
90
+ };
91
+
92
+ /** The `ACL LIST` echo for one user — the MEASURED shape: flags, password hash, key patterns,
93
+ * the bare `resetchannels` marker before the channel patterns, then the rule tokens. */
94
+ export const renderUser = (name: string, user: FakeAclUser): string =>
95
+ [
96
+ 'user',
97
+ name,
98
+ user.on ? 'on' : 'off',
99
+ user.nopass ? 'nopass' : '',
100
+ ...user.passwords,
101
+ ...user.keys,
102
+ 'resetchannels',
103
+ ...user.channels,
104
+ ...user.rules,
105
+ ]
106
+ .filter((part) => part !== '')
107
+ .join(' ');
108
+
109
+ /** Tokenize a seeded `ACL LIST` line the way the fake would have stored the SETUSER that made
110
+ * it, so a seed and a write land in the same shape. */
111
+ export const seedUser = (line: string): FakeAclUser => {
112
+ const user = freshUser();
113
+ const parts = line.split(' ');
114
+ if (parts[2] === 'on' || parts[2] === 'off') applyToken(user, parts[2]);
115
+ for (const part of parts.slice(3)) applyToken(user, part);
116
+ return user;
117
+ };
118
+
119
+ /** Does `channel` match one of the session user's `&` patterns? Glob, the way the server's
120
+ * `&pat:*` works for PUBLISH. */
121
+ export const channelAllowed = (user: FakeAclUser, channel: string): boolean =>
122
+ user.channels.some((pattern) => {
123
+ const glob = pattern
124
+ .slice(1)
125
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&')
126
+ .replace(/\*/g, '.*');
127
+ return new RegExp(`^${glob}$`).test(channel);
128
+ });
@@ -0,0 +1,224 @@
1
+ /**
2
+ * A recording fake `ValkeyExecutor` that answers the way a REAL valkey 8.1.10 answers, not the
3
+ * way this family's code writes (S28: tests read back from the fake's own in-memory state, not
4
+ * from the command list). No socket, no `node:net` — it re-derives exactly the commands this
5
+ * family ever issues (`INFO`, `CONFIG GET`, `AUTH`, `ACL LIST/SETUSER/DELUSER/SAVE`, `PING`,
6
+ * `PUBLISH`) against per-user ACL state, with the echo and error shapes MEASURED against a
7
+ * disposable 8.1.10 scratch container (2026-09-30):
8
+ *
9
+ * ★ `ACL LIST` echoes the server's normalised form, not the SETUSER argument list: the `reset`
10
+ * baseline appears as an explicit `-@all` token (cancelled only by `+@all`), `allchannels`
11
+ * echoes as `&*`, an empty channel list echoes the bare `resetchannels` marker, `reset` and
12
+ * the password VALUE are dropped (only the `#<sha256>` hash echoes).
13
+ * ★ `AUTH` compares the sha256 of the presented password and refuses with the measured
14
+ * WRONGPASS text; `PUBLISH` refuses by CHANNEL with the measured NOPERM text.
15
+ * ★ `ACL SAVE` errors with the measured "not configured to use an ACL file" text while no
16
+ * `aclfile` is configured — which is why the write path never calls it — and answers `OK`
17
+ * once `config.aclfile` names a writable file.
18
+ */
19
+ import {
20
+ type FakeAclUser,
21
+ applyToken,
22
+ channelAllowed,
23
+ freshUser,
24
+ renderUser,
25
+ seedUser,
26
+ sha256,
27
+ } from './fake-acl.ts';
28
+ import * as Effect from 'effect/Effect';
29
+ import { memoryBytes } from './instance-form.ts';
30
+ import type { ValkeyExecutor, ValkeyReply, ValkeyServerError } from './transport.ts';
31
+
32
+ export interface RecordedCommand {
33
+ readonly args: ReadonlyArray<string>;
34
+ }
35
+
36
+ export interface FakeValkey extends ValkeyExecutor {
37
+ readonly commands: ReadonlyArray<RecordedCommand>;
38
+ /** Mutable on purpose: a test seeds a value a "competing" write would have produced before
39
+ * the fake ever sees it. The `aclfile` entry is what `CONFIG GET aclfile` answers. */
40
+ readonly config: Map<string, string>;
41
+ /** The live ACL as `ACL LIST` echoes it, keyed by username — the fake's own report, not the
42
+ * command list (S28). */
43
+ readonly acl: Map<string, string>;
44
+ /** Which usernames the fake accepts an `AUTH` for, and at which plaintext (test fixtures). */
45
+ readonly passwords: Map<string, string>;
46
+ }
47
+
48
+ export interface FakeValkeyOptions {
49
+ readonly config?: Readonly<Record<string, string>>;
50
+ /** Seed users as `ACL LIST` lines, parsed with the same tokenizer as SETUSER. */
51
+ readonly acl?: Readonly<Record<string, string>>;
52
+ readonly passwords?: Readonly<Record<string, string>>;
53
+ /** Fail the NEXT write (`ACL SETUSER`/`ACL DELUSER`) once, the way a concurrent mutator would. */
54
+ readonly raceNextWrite?: boolean;
55
+ /** Re-add this user after EVERY successful ACL write — a concurrent mutator that survives the
56
+ * reconcile's writes, so the read-back (never the write reply) is what catches it. */
57
+ readonly reAddAfterWrite?: { readonly name: string; readonly line: string };
58
+ /** The version `INFO` reports as `valkey_version` (with a `redis_version` fallback line). */
59
+ readonly version?: string;
60
+ /** `INFO` `tcp_port`. Defaults to 0, the reply a server that omitted the line would give. */
61
+ readonly port?: number;
62
+ }
63
+
64
+ export const makeFakeValkey = (options: FakeValkeyOptions = {}): FakeValkey => {
65
+ const commands: RecordedCommand[] = [];
66
+ const config = new Map(Object.entries({ aclfile: '', ...options.config }));
67
+ const users = new Map<string, FakeAclUser>(
68
+ Object.entries(options.acl ?? {}).map(([name, line]) => [name, seedUser(line)]),
69
+ );
70
+ const passwords = new Map(Object.entries(options.passwords ?? {}));
71
+ const acl = new Map<string, string>();
72
+ const resync = (): void => {
73
+ acl.clear();
74
+ for (const [name, user] of users) acl.set(name, renderUser(name, user));
75
+ };
76
+ resync();
77
+ let raceRemaining = options.raceNextWrite === true ? 1 : 0;
78
+ const reAdd = options.reAddAfterWrite;
79
+ const afterWrite = (): void => {
80
+ if (reAdd !== undefined) {
81
+ users.set(reAdd.name, seedUser(reAdd.line));
82
+ resync();
83
+ }
84
+ };
85
+ let session = 'default';
86
+
87
+ const reply = (value: string | null | ReadonlyArray<string | null>): ValkeyReply =>
88
+ typeof value === 'string' || value === null
89
+ ? ({ kind: 'bulk', value } as const)
90
+ : ({ kind: 'array', values: value } as const);
91
+ const error = (message: string): ValkeyReply => ({ kind: 'error', message }) as const;
92
+
93
+ const send = (args: ReadonlyArray<string>): Effect.Effect<ValkeyReply, ValkeyServerError> =>
94
+ Effect.sync(() => {
95
+ commands.push({ args });
96
+ users.clear();
97
+ for (const [name, line] of acl) users.set(name, seedUser(line));
98
+ const [cmd, ...rest] = args;
99
+
100
+ switch (cmd) {
101
+ case 'PING':
102
+ return reply('PONG');
103
+
104
+ case 'AUTH': {
105
+ const [user, pass] = rest.length > 1 ? rest : ['default', rest[0]];
106
+ if (pass === undefined) {
107
+ return error('ERR wrong number of arguments for AUTH');
108
+ }
109
+ const known = users.get(user ?? 'default');
110
+ const configured = passwords.get(user ?? 'default');
111
+ const ok =
112
+ known !== undefined
113
+ ? known.on && (known.nopass || known.passwords.includes(`#${sha256(pass)}`))
114
+ : configured !== undefined && configured === pass;
115
+ if (!ok) return error('WRONGPASS invalid username-password pair or user is disabled.');
116
+ session = user ?? 'default';
117
+ return reply('OK');
118
+ }
119
+
120
+ case 'INFO': {
121
+ const version = options.version ?? '8.1.10';
122
+ const port = options.port ?? 0;
123
+ return reply(
124
+ [
125
+ '# Server',
126
+ `valkey_version:${version}`,
127
+ 'redis_version:7.2.4',
128
+ 'redis_mode:standalone',
129
+ `tcp_port:${String(port)}`,
130
+ '# Persistence',
131
+ 'loading:0',
132
+ '# Keyspace',
133
+ ].join('\r\n'),
134
+ );
135
+ }
136
+
137
+ case 'CONFIG': {
138
+ if (rest[0] !== 'GET') {
139
+ return error(`ERR CONFIG ${rest[0]} not supported by fake`);
140
+ }
141
+ const out: Array<string | null> = [];
142
+ for (const key of rest.slice(1)) {
143
+ const raw = config.get(key);
144
+ if (raw === undefined) continue; // a real server omits keys it has no answer for
145
+ out.push(key);
146
+ if (key === 'maxmemory') {
147
+ const bytes = memoryBytes(raw);
148
+ out.push(bytes === undefined ? raw : String(bytes));
149
+ } else {
150
+ out.push(raw);
151
+ }
152
+ }
153
+ return reply(out);
154
+ }
155
+
156
+ case 'PUBLISH': {
157
+ const [channel] = rest;
158
+ const me = users.get(session);
159
+ if (me === undefined || session === 'default') return reply('0');
160
+ const mayRun = me.rules.includes('+@all') || me.rules.includes('+@pubsub');
161
+ if (!mayRun) {
162
+ return error(`NOPERM User ${session} has no permissions to run the 'publish' command`);
163
+ }
164
+ if (!channelAllowed(me, channel ?? '')) {
165
+ return error('NOPERM No permissions to access a channel');
166
+ }
167
+ return reply('0');
168
+ }
169
+
170
+ case 'ACL': {
171
+ const sub = rest[0];
172
+ if (sub === 'LIST') {
173
+ return reply([...acl.values()] as Array<string | null>);
174
+ }
175
+ if (sub === 'SETUSER') {
176
+ if (raceRemaining > 0) {
177
+ raceRemaining -= 1;
178
+ return error('ERR fake race');
179
+ }
180
+ const username = rest[1];
181
+ if (username === undefined) {
182
+ return error('ERR wrong number of arguments for SETUSER');
183
+ }
184
+ const user = users.get(username) ?? freshUser();
185
+ for (const token of rest.slice(2)) applyToken(user, token);
186
+ users.set(username, user);
187
+ resync();
188
+ afterWrite();
189
+ return reply('OK');
190
+ }
191
+ if (sub === 'DELUSER') {
192
+ if (raceRemaining > 0) {
193
+ raceRemaining -= 1;
194
+ return error('ERR fake race');
195
+ }
196
+ let removed = 0;
197
+ for (const name of rest.slice(1)) {
198
+ if (users.delete(name)) removed += 1;
199
+ }
200
+ resync();
201
+ afterWrite();
202
+ return reply(String(removed));
203
+ }
204
+ if (sub === 'SAVE') {
205
+ if ((config.get('aclfile') ?? '') === '') {
206
+ return error(
207
+ 'ERR This instance is not configured to use an ACL file. You may want to ' +
208
+ 'specify users via the ACL SETUSER command and then issue a CONFIG REWRITE ' +
209
+ '(assuming you have a configuration file set) in order to store users in the ' +
210
+ 'configuration.',
211
+ );
212
+ }
213
+ return reply('OK');
214
+ }
215
+ return error(`ERR ACL ${sub} not supported by fake`);
216
+ }
217
+
218
+ default:
219
+ return error(`ERR unknown command '${cmd}'`);
220
+ }
221
+ });
222
+
223
+ return { send, commands, config, acl, passwords };
224
+ };
@@ -0,0 +1,43 @@
1
+ /** Test-only connection injection: no listener, module mock or live endpoint. */
2
+ import * as Effect from 'effect/Effect';
3
+ import {
4
+ type ValkeyConnection,
5
+ type ValkeyConnectionConfig,
6
+ auth,
7
+ type withValkey,
8
+ } from './connection.ts';
9
+ import type { Environment } from '../secrets/write-only.ts';
10
+ import type { ValkeyExecutor } from './transport.ts';
11
+ import { valkeyConnection } from './connection.ts';
12
+
13
+ export const config: ValkeyConnectionConfig = {
14
+ instance: 'scratch',
15
+ host: '127.0.0.1',
16
+ port: 0,
17
+ username: 'admin',
18
+ password: { fromEnv: 'TEST_VALKEY_ADMIN_PW' },
19
+ };
20
+ export const env: Environment = { TEST_VALKEY_ADMIN_PW: 'FAKE-admin' };
21
+ export const connection =
22
+ (executor: ValkeyExecutor, credentials: Environment = env): typeof withValkey =>
23
+ (build) =>
24
+ Effect.gen(function* () {
25
+ yield* auth(executor, config, credentials);
26
+ return yield* build(executor, config);
27
+ });
28
+ export const run = <A, E>(effect: Effect.Effect<A, E, ValkeyConnection>): Promise<A> =>
29
+ Effect.runPromise(effect.pipe(Effect.provide(valkeyConnection(config))));
30
+ export const context = {
31
+ id: 'scratch',
32
+ fqn: 'scratch',
33
+ instanceId: 'scratch',
34
+ session: undefined as never,
35
+ bindings: [],
36
+ oldBindings: [],
37
+ newBindings: [],
38
+ };
39
+
40
+ export const required = <T>(value: T | undefined): T => {
41
+ if (value === undefined) throw new Error('missing test fixture or handler');
42
+ return value;
43
+ };