@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,101 @@
1
+ /**
2
+ * The offline half of `Postgres.Grants`' diff engine: the read-back projection
3
+ * (`attributesOf`) and the plan-time comparison (`grantsDiffer`). Pure — no client, no
4
+ * `Effect` — so `reconcile`'s read-back and the engine's `diff` project and compare one
5
+ * way. The repair and revocation statement lists live in `grants-plan.ts`.
6
+ */
7
+ import type { PostgresGrantsAttributes } from './grants-attrs.ts';
8
+ import type { DeclaredGrants, DeclaredNames } from './grants-declare.ts';
9
+ import { liveColumnWords, liveDefaultWords, liveTableWords, wordsDiffer } from './grants-plan.ts';
10
+ import type { LiveGrants } from './grants-read.ts';
11
+ import { relkindIsPublicRevocable } from './grants-words.ts';
12
+
13
+ /** The read-back projection: live catalog words, restricted to the names this declaration
14
+ * (or, for `read`, the last one) claims — plus the one-directional PUBLIC fact and the
15
+ * ownership facts. The PUBLIC-tables fact is scoped to the relkinds the bulk revoke
16
+ * statement actually reaches; an owned object records an empty word list (the ACL rows say
17
+ * nothing; ownership carries the privileges). */
18
+ export const attributesOf = (live: LiveGrants, names: DeclaredNames): PostgresGrantsAttributes => ({
19
+ role: names.role,
20
+ database: names.database,
21
+ schema: names.schema,
22
+ schemaPrivileges: live.schema.role,
23
+ tables: names.tables.map((table) => ({
24
+ table,
25
+ privileges: liveTableWords(live, table),
26
+ })),
27
+ columns: names.columns.map(({ table, column }) => ({
28
+ table,
29
+ column,
30
+ privileges: liveColumnWords(live, table, column),
31
+ })),
32
+ defaults: names.defaults.map((forRole) => ({
33
+ forRole,
34
+ privileges: liveDefaultWords(live, forRole),
35
+ })),
36
+ publicSchemaRevoked: live.schema.public.length === 0,
37
+ publicTablesRevoked:
38
+ live.tables.every(
39
+ (table) => !relkindIsPublicRevocable(table.relkind) || table.public.length === 0,
40
+ ) && live.columns.every((column) => column.public.length === 0),
41
+ schemaOwnedByRole: live.schemaOwnedByRole,
42
+ ownedTables: names.tables.filter((table) => live.ownedTables.includes(table)),
43
+ });
44
+
45
+ /** The engine's plan-time comparison: the new declaration against the recorded (or freshly
46
+ * read) attributes. PUBLIC is one-directional — a declaration that does not revoke
47
+ * PUBLIC leaves whatever it holds alone, so live PUBLIC privileges with
48
+ * `revokeFromPublic: false` are never drift. Everything else is full equality, grant-option
49
+ * marks included; a changed NAME SET (a table added to or removed from the declaration)
50
+ * answers `true` so one reconcile re-records the projection in the new shape. Owned objects
51
+ * are skipped exactly as the repair skips them: their word list is meaningless (the owner
52
+ * holds everything implicitly), so only a name-set change on one can answer `true`. */
53
+ export const grantsDiffer = (declared: DeclaredGrants, live: PostgresGrantsAttributes): boolean => {
54
+ if (
55
+ declared.role !== live.role ||
56
+ declared.database !== live.database ||
57
+ declared.schema !== live.schema
58
+ ) {
59
+ return true;
60
+ }
61
+ if (declared.publicSchemaRevoked && !live.publicSchemaRevoked) return true;
62
+ if (declared.publicTablesRevoked && !live.publicTablesRevoked) return true;
63
+ if (!live.schemaOwnedByRole && wordsDiffer(declared.schemaPrivileges, live.schemaPrivileges)) {
64
+ return true;
65
+ }
66
+ if (declared.tables.length !== live.tables.length) return true;
67
+ const ownedTables = new Set(live.ownedTables);
68
+ if (
69
+ declared.tables.some(
70
+ (table, index) =>
71
+ table.table !== (live.tables[index]?.table ?? null) ||
72
+ (!ownedTables.has(table.table) &&
73
+ wordsDiffer(table.privileges, live.tables[index]?.privileges ?? [])),
74
+ )
75
+ ) {
76
+ return true;
77
+ }
78
+ if (declared.columns.length !== live.columns.length) return true;
79
+ if (
80
+ declared.columns.some(
81
+ (column, index) =>
82
+ column.table !== (live.columns[index]?.table ?? null) ||
83
+ column.column !== (live.columns[index]?.column ?? null) ||
84
+ (!ownedTables.has(column.table) &&
85
+ wordsDiffer(column.privileges, live.columns[index]?.privileges ?? [])),
86
+ )
87
+ ) {
88
+ return true;
89
+ }
90
+ if (declared.defaults.length !== live.defaults.length) return true;
91
+ if (
92
+ declared.defaults.some(
93
+ (entry, index) =>
94
+ entry.forRole !== (live.defaults[index]?.forRole ?? null) ||
95
+ wordsDiffer(entry.privileges, live.defaults[index]?.privileges ?? []),
96
+ )
97
+ ) {
98
+ return true;
99
+ }
100
+ return false;
101
+ };
@@ -0,0 +1,215 @@
1
+ /**
2
+ * `Postgres.Grants`' failures as typed tags, following the `Postgres.Schema` pattern (S21).
3
+ *
4
+ * ⛔ NONE OF THESE IS A STATUS-CODE OR MESSAGE MATCH. Every one is raised by this family's
5
+ * own code from a fact it already checked (a byte count, a vocabulary, a live catalog
6
+ * row, a re-planned statement list) — never from sniffing a driver error's text. The one
7
+ * driver error this family EXPECTS (a grant naming a relation or column that does not
8
+ * exist, a revoke that would need CASCADE) propagates as the raw `SqlError` on purpose:
9
+ * the docs page names the cases.
10
+ */
11
+ import * as Data from 'effect/Data';
12
+
13
+ /** A declared privilege word is outside the vocabulary its prop draws from — e.g. `TRUNCATE`
14
+ * on a column grant (table-wide only at REL_18_6) or `EXECUTE` anywhere (this family never
15
+ * leaves the table/schema/column words). */
16
+ export class PostgresGrantsPrivilegeRefused extends Data.TaggedError(
17
+ 'PostgresGrantsPrivilegeRefused',
18
+ )<{
19
+ readonly prop: string;
20
+ readonly word: string;
21
+ }> {
22
+ override get message(): string {
23
+ return (
24
+ `Postgres.Grants: "${this.prop}" declares "${this.word}", which is not in the vocabulary ` +
25
+ 'PostgreSQL 18 grants on that object class (see grants-attrs.ts for the three sets, traced ' +
26
+ 'to acl.h at REL_18_6). Column grants take select/insert/update/references only — TRUNCATE, ' +
27
+ 'TRIGGER and MAINTAIN are table-wide.'
28
+ );
29
+ }
30
+ }
31
+
32
+ /** A declared name would be silently truncated (same rule as `PostgresDatabaseNameRefused`):
33
+ * roles, schemas, tables and columns are all `NameData`. */
34
+ export class PostgresGrantsNameRefused extends Data.TaggedError('PostgresGrantsNameRefused')<{
35
+ readonly name: string;
36
+ readonly byteLength: number;
37
+ readonly limit: number;
38
+ }> {
39
+ override get message(): string {
40
+ return (
41
+ `Postgres.Grants: the name "${this.name}" is ${String(this.byteLength)} UTF-8 bytes, over the ` +
42
+ `${String(this.limit)}-byte limit (NAMEDATALEN 64, minus the terminator). PostgreSQL would ` +
43
+ 'accept the statement and silently truncate the name with only a NOTICE, so this plan refuses ' +
44
+ 'it instead of granting on an object no later read will ever find again.'
45
+ );
46
+ }
47
+ }
48
+
49
+ /** Two declaration entries name the same object (one table twice, one column pair twice,
50
+ * one `forRole` twice) — silently merging them would hide which entry the operator meant.
51
+ * The same refusal fires when one word list declares a base word both plain and
52
+ * `*`-marked: the server keeps ONE aclitem per grantee per grantor, so those two states
53
+ * can never both hold and the set would never converge. */
54
+ export class PostgresGrantsDuplicateObject extends Data.TaggedError(
55
+ 'PostgresGrantsDuplicateObject',
56
+ )<{
57
+ readonly prop: string;
58
+ readonly name: string;
59
+ }> {
60
+ override get message(): string {
61
+ return (
62
+ `Postgres.Grants: "${this.prop}" declares "${this.name}" twice. Merge the entries into one — ` +
63
+ 'the declaration must state each object at most once, and each privilege word in exactly one ' +
64
+ 'form: plain, or WITH GRANT OPTION (`select` and `select*` cannot both hold, the server keeps ' +
65
+ 'one aclitem per grantee per grantor).'
66
+ );
67
+ }
68
+ }
69
+
70
+ /** A logical id's `role`, `database` or `schema` changed. Those three name WHAT the grant set
71
+ * is about; changing one is a different grant set, not an edit of this one. */
72
+ export class PostgresGrantsRetargetRefused extends Data.TaggedError(
73
+ 'PostgresGrantsRetargetRefused',
74
+ )<{
75
+ readonly prop: string;
76
+ readonly from: string;
77
+ readonly to: string;
78
+ }> {
79
+ override get message(): string {
80
+ return (
81
+ `Postgres.Grants: the declared ${this.prop} changed from "${this.from}" to "${this.to}". A ` +
82
+ 'retarget is refused at plan — declare a new logical id for the new target and delete the old ' +
83
+ 'one (its retain policy keeps the grants until a destroy revokes them).'
84
+ );
85
+ }
86
+ }
87
+
88
+ /** `current_database()` is not the database the declaration names. The handlers open the
89
+ * declared database (`withPg`'s override — the family connection stays on the maintenance
90
+ * database); this fires when that open did not land there. Granting in the wrong database
91
+ * would succeed silently and read back as drift forever. */
92
+ export class PostgresGrantsDatabaseMismatch extends Data.TaggedError(
93
+ 'PostgresGrantsDatabaseMismatch',
94
+ )<{
95
+ readonly declared: string;
96
+ readonly connected: string;
97
+ }> {
98
+ override get message(): string {
99
+ return (
100
+ `Postgres.Grants: the declaration names database "${this.declared}" but ` +
101
+ `current_database() is "${this.connected}". The handlers open the declared database and ` +
102
+ 'prove it before any GRANT or REVOKE — a mismatch means that open did not land there.'
103
+ );
104
+ }
105
+ }
106
+
107
+ /** `reconcile` refuses to repair into a schema the catalogs do not have: grants belong to an
108
+ * existing container (`Postgres.Schema` creates one; this family never creates anything). */
109
+ export class PostgresGrantsSchemaMissing extends Data.TaggedError('PostgresGrantsSchemaMissing')<{
110
+ readonly schema: string;
111
+ }> {
112
+ override get message(): string {
113
+ return (
114
+ `Postgres.Grants: schema "${this.schema}" is not in pg_namespace. Grants are written into a ` +
115
+ 'schema that already exists — declare a Postgres.Schema (or create it by hand) before the ' +
116
+ 'grant set that scopes to it.'
117
+ );
118
+ }
119
+ }
120
+
121
+ /** `reconcile` refuses to apply into a database `pg_database` does not have. `read` and `delete`
122
+ * treat a missing database as absence (first create / no-op), but a reconcile names a container
123
+ * it must write into — probing first turns what would be an untyped connect failure
124
+ * (`ConnectionError` over psql, `UnknownError` 3D000 over the socket) into a typed refusal. */
125
+ export class PostgresGrantsDatabaseMissing extends Data.TaggedError(
126
+ 'PostgresGrantsDatabaseMissing',
127
+ )<{
128
+ readonly database: string;
129
+ }> {
130
+ override get message(): string {
131
+ return (
132
+ `Postgres.Grants: database "${this.database}" is not in pg_database. Grants are written into ` +
133
+ 'a database that already exists — declare a Postgres.Database (or create it by hand) before ' +
134
+ 'the grant set that scopes to it.'
135
+ );
136
+ }
137
+ }
138
+
139
+ /** The grantee role, or a default-privileges `forRole` creator, is not in `pg_roles` —
140
+ * checked before any statement runs, the way `Postgres.Schema` checks its `AUTHORIZATION`
141
+ * owner. */
142
+ export class PostgresGrantsRoleMissing extends Data.TaggedError('PostgresGrantsRoleMissing')<{
143
+ readonly role: string;
144
+ }> {
145
+ override get message(): string {
146
+ return (
147
+ `Postgres.Grants: role "${this.role}" is not in pg_roles. GRANT and ALTER DEFAULT PRIVILEGES ` +
148
+ 'would fail against it — create the role (a group role per seat, membership owned by a human) ' +
149
+ 'before declaring its grants.'
150
+ );
151
+ }
152
+ }
153
+
154
+ /** A declared table is not a relation in the schema. The resource refuses before any
155
+ * statement, because a GRANT/REVOKE on a missing relation would surface as a raw 42P01
156
+ * after earlier statements had already landed — and the state row would stay `creating`. */
157
+ export class PostgresGrantsTableMissing extends Data.TaggedError('PostgresGrantsTableMissing')<{
158
+ readonly schema: string;
159
+ readonly table: string;
160
+ }> {
161
+ override get message(): string {
162
+ return (
163
+ `Postgres.Grants: table "${this.schema}"."${this.table}" does not exist. The declaration ` +
164
+ 'names a relation before it is created; create the table (or fix the name) before granting.'
165
+ );
166
+ }
167
+ }
168
+
169
+ /** A declared column is not an attribute of its table. The resource refuses before any
170
+ * statement, matching the table-missing guard. */
171
+ export class PostgresGrantsColumnMissing extends Data.TaggedError('PostgresGrantsColumnMissing')<{
172
+ readonly schema: string;
173
+ readonly table: string;
174
+ readonly column: string;
175
+ }> {
176
+ override get message(): string {
177
+ return (
178
+ `Postgres.Grants: column "${this.column}" of "${this.schema}"."${this.table}" does not ` +
179
+ 'exist. Declare the column (or fix its name) before granting on it.'
180
+ );
181
+ }
182
+ }
183
+
184
+ /** The repair ran clean, but the immediate re-read (S10) still plans statements: a grant this
185
+ * family cannot revoke survived (its grantor still holds the grant option, or the executing
186
+ * role is neither the owner nor that grantor). Re-planning forever would hide it as silent
187
+ * drift, so it fails loud with the surviving statements. */
188
+ export class PostgresGrantsRepairRefused extends Data.TaggedError('PostgresGrantsRepairRefused')<{
189
+ readonly schema: string;
190
+ readonly role: string;
191
+ readonly remaining: ReadonlyArray<string>;
192
+ }> {
193
+ override get message(): string {
194
+ return (
195
+ `Postgres.Grants: the repair on schema "${this.schema}" for role "${this.role}" re-read as ` +
196
+ `still drifted; these statements would run again: ${this.remaining.join(' ; ')}. A grant made ` +
197
+ 'by another role survives this resource\u2019s REVOKE (only its grantor or the object\u2019s ' +
198
+ 'owner can revoke it) — revoke it as that grantor or the owner, or declare the privilege so ' +
199
+ 'the set matches.'
200
+ );
201
+ }
202
+ }
203
+
204
+ export type PostgresGrantsError =
205
+ | PostgresGrantsPrivilegeRefused
206
+ | PostgresGrantsNameRefused
207
+ | PostgresGrantsDuplicateObject
208
+ | PostgresGrantsRetargetRefused
209
+ | PostgresGrantsDatabaseMismatch
210
+ | PostgresGrantsDatabaseMissing
211
+ | PostgresGrantsSchemaMissing
212
+ | PostgresGrantsRoleMissing
213
+ | PostgresGrantsTableMissing
214
+ | PostgresGrantsColumnMissing
215
+ | PostgresGrantsRepairRefused;
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Existence guards: every declared table and column must exist before any statement runs.
3
+ * Missing objects fail typed `PostgresGrantsTableMissing` / `PostgresGrantsColumnMissing`
4
+ * without touching catalogs. A dotted table name must not collide with a dotted column
5
+ * name: the existence query compares the pair, not `relname || '.' || attname`.
6
+ */
7
+ import { describe, expect, test } from 'bun:test';
8
+ import * as Effect from 'effect/Effect';
9
+ import type { PostgresGrantsProps } from './grants-attrs.ts';
10
+ import { makeFakeGrants } from './fake-grants-sql.ts';
11
+ import { PostgresGrantsColumnMissing, PostgresGrantsTableMissing } from './grants-errors.ts';
12
+ import { reconcileWithClient } from './grants-ops.ts';
13
+
14
+ const run = <A, E>(eff: Effect.Effect<A, E>): Promise<A> => Effect.runPromise(eff);
15
+ const fails = <A, E>(eff: Effect.Effect<A, E>): Promise<E> => Effect.runPromise(Effect.flip(eff));
16
+
17
+ const isWrite = (text: string): boolean => /^(GRANT|REVOKE|ALTER)/.test(text);
18
+
19
+ const catalog = {
20
+ schemas: ['app'],
21
+ roles: ['postgres', 'seat_writer'],
22
+ tables: [{ schema: 'app', table: 'widgets', columns: ['id'] }],
23
+ };
24
+
25
+ const baseProps: PostgresGrantsProps = {
26
+ role: 'seat_writer',
27
+ database: 'agents',
28
+ schema: 'app',
29
+ schemaUsage: true,
30
+ };
31
+
32
+ describe('reconcile: declared objects must exist before statements run', () => {
33
+ test('a missing table fails as PostgresGrantsTableMissing without writing', async () => {
34
+ const fake = makeFakeGrants(catalog);
35
+ const error = await fails(
36
+ reconcileWithClient(
37
+ fake,
38
+ {
39
+ ...baseProps,
40
+ tables: [
41
+ { table: 'widgets', privileges: ['select'] },
42
+ { table: 'ghost', privileges: ['select'] },
43
+ ],
44
+ },
45
+ undefined,
46
+ ),
47
+ );
48
+ expect(error).toBeInstanceOf(PostgresGrantsTableMissing);
49
+ expect((error as PostgresGrantsTableMissing).table).toBe('ghost');
50
+ expect(fake.statements.map((s) => s.text).filter(isWrite)).toEqual([]);
51
+ });
52
+
53
+ test('a missing column fails as PostgresGrantsColumnMissing without writing', async () => {
54
+ const fake = makeFakeGrants(catalog);
55
+ const error = await fails(
56
+ reconcileWithClient(
57
+ fake,
58
+ {
59
+ ...baseProps,
60
+ tables: [{ table: 'widgets', privileges: ['select'] }],
61
+ columnGrants: [{ table: 'widgets', column: 'qty', privileges: ['update'] }],
62
+ },
63
+ undefined,
64
+ ),
65
+ );
66
+ expect(error).toBeInstanceOf(PostgresGrantsColumnMissing);
67
+ expect((error as PostgresGrantsColumnMissing).column).toBe('qty');
68
+ expect(fake.statements.map((s) => s.text).filter(isWrite)).toEqual([]);
69
+ });
70
+
71
+ test('a real table and column proceed past the guards', async () => {
72
+ const fake = makeFakeGrants(catalog);
73
+ await run(
74
+ reconcileWithClient(
75
+ fake,
76
+ {
77
+ ...baseProps,
78
+ tables: [{ table: 'widgets', privileges: ['select'] }],
79
+ columnGrants: [{ table: 'widgets', column: 'id', privileges: ['update'] }],
80
+ },
81
+ undefined,
82
+ ),
83
+ );
84
+ expect(fake.statements.map((s) => s.text).some(isWrite)).toBe(true);
85
+ });
86
+ });
87
+
88
+ describe('column existence compares the (table, column) pair', () => {
89
+ test('table `a.b` column `c` does not make table `a` column `b.c` look present', async () => {
90
+ const fake = makeFakeGrants({
91
+ ...catalog,
92
+ tables: [
93
+ { schema: 'app', table: 'a.b', columns: ['c'] },
94
+ { schema: 'app', table: 'a', columns: ['id'] },
95
+ ],
96
+ });
97
+ const error = await fails(
98
+ reconcileWithClient(
99
+ fake,
100
+ {
101
+ ...baseProps,
102
+ tables: [{ table: 'a', privileges: ['select'] }],
103
+ columnGrants: [{ table: 'a', column: 'b.c', privileges: ['select'] }],
104
+ },
105
+ undefined,
106
+ ),
107
+ );
108
+ expect(error).toBeInstanceOf(PostgresGrantsColumnMissing);
109
+ expect((error as PostgresGrantsColumnMissing).table).toBe('a');
110
+ expect((error as PostgresGrantsColumnMissing).column).toBe('b.c');
111
+ expect(fake.statements.map((s) => s.text).filter(isWrite)).toEqual([]);
112
+ });
113
+ });
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Pre-statement existence guards for `Postgres.Grants`: every declared table and column
3
+ * must exist in the schema before any GRANT/REVOKE runs. A missing object would fail
4
+ * as a raw 42P01/42703 after earlier statements had already landed, leaving the state
5
+ * row `creating` and the resume failing OwnedBySomeoneElse.
6
+ */
7
+ import * as Effect from 'effect/Effect';
8
+ import type { SqlError } from 'effect/unstable/sql/SqlError';
9
+ import type { PgExecutor } from './database-sql.ts';
10
+ import type { DeclaredGrants } from './grants-declare.ts';
11
+ import { PostgresGrantsColumnMissing, PostgresGrantsTableMissing } from './grants-errors.ts';
12
+
13
+ /** One JSON string, never a JS array: the psql transport accepts only string parameters
14
+ * (`psql-executor.ts`). `json_array_elements_text` expands that array to text
15
+ * (`func.sgml@REL_18_6`). */
16
+ const TABLES_PRESENT_SQL = `SELECT
17
+ c.relname AS table
18
+ FROM pg_class c
19
+ WHERE c.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = $1)
20
+ AND c.relname::text IN (SELECT json_array_elements_text($2::json))`;
21
+
22
+ const findMissingTable = (
23
+ pg: PgExecutor,
24
+ schema: string,
25
+ tables: ReadonlyArray<string>,
26
+ ): Effect.Effect<string | undefined, SqlError> =>
27
+ tables.length === 0
28
+ ? Effect.succeed(undefined)
29
+ : Effect.map(
30
+ pg.unsafe<{ readonly table: string }>(TABLES_PRESENT_SQL, [schema, JSON.stringify(tables)]),
31
+ (rows) => {
32
+ const present = new Set(rows.map((row) => row.table));
33
+ return tables.find((table) => !present.has(table));
34
+ },
35
+ );
36
+
37
+ /** Pairs, not `relname || '.' || attname`. A table named `a.b` with column `c` and a
38
+ * table named `a` with column `b.c` are the same concatenated string and one of them
39
+ * would read as present. `->>` yields text (`func.sgml@REL_18_6`); the parameter is
40
+ * one JSON string so the psql transport accepts it. */
41
+ const COLUMNS_PRESENT_SQL = `SELECT
42
+ c.relname AS table,
43
+ a.attname AS column
44
+ FROM pg_attribute a
45
+ JOIN pg_class c ON c.oid = a.attrelid
46
+ WHERE c.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = $1)
47
+ AND a.attnum > 0
48
+ AND NOT a.attisdropped
49
+ AND (c.relname, a.attname) IN (
50
+ SELECT x->>0, x->>1 FROM json_array_elements($2::json) x
51
+ )`;
52
+
53
+ const findMissingColumn = (
54
+ pg: PgExecutor,
55
+ schema: string,
56
+ columns: ReadonlyArray<{ readonly table: string; readonly column: string }>,
57
+ ): Effect.Effect<{ readonly table: string; readonly column: string } | undefined, SqlError> =>
58
+ columns.length === 0
59
+ ? Effect.succeed(undefined)
60
+ : Effect.map(
61
+ pg.unsafe<{ readonly table: string; readonly column: string }>(COLUMNS_PRESENT_SQL, [
62
+ schema,
63
+ JSON.stringify(columns.map(({ table, column }) => [table, column])),
64
+ ]),
65
+ (rows) => {
66
+ const present = new Set(rows.map((row) => `${row.table}\u0000${row.column}`));
67
+ return columns.find(({ table, column }) => !present.has(`${table}\u0000${column}`));
68
+ },
69
+ );
70
+
71
+ /** Fail typed before any statement if a declared table or column does not exist. */
72
+ export const requireDeclaredObjectsExist = (
73
+ pg: PgExecutor,
74
+ declared: DeclaredGrants,
75
+ ): Effect.Effect<void, PostgresGrantsTableMissing | PostgresGrantsColumnMissing | SqlError> =>
76
+ Effect.gen(function* () {
77
+ const missingTable = yield* findMissingTable(
78
+ pg,
79
+ declared.schema,
80
+ declared.tables.map((table) => table.table),
81
+ );
82
+ if (missingTable !== undefined) {
83
+ return yield* Effect.fail(
84
+ new PostgresGrantsTableMissing({ schema: declared.schema, table: missingTable }),
85
+ );
86
+ }
87
+ const missingColumn = yield* findMissingColumn(
88
+ pg,
89
+ declared.schema,
90
+ declared.columns.map((column) => ({ table: column.table, column: column.column })),
91
+ );
92
+ if (missingColumn !== undefined) {
93
+ return yield* Effect.fail(
94
+ new PostgresGrantsColumnMissing({
95
+ schema: declared.schema,
96
+ table: missingColumn.table,
97
+ column: missingColumn.column,
98
+ }),
99
+ );
100
+ }
101
+ });