@neverinfamous/mysql-mcp 2.3.0 → 3.0.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 (347) hide show
  1. package/.dockerignore +1 -0
  2. package/.gitattributes +18 -0
  3. package/.github/workflows/codeql.yml +2 -10
  4. package/.github/workflows/docker-publish.yml +15 -13
  5. package/CHANGELOG.md +287 -1
  6. package/DOCKER_README.md +100 -265
  7. package/Dockerfile +5 -0
  8. package/README.md +124 -59
  9. package/VERSION +1 -1
  10. package/dist/__tests__/mocks/adapter.d.ts.map +1 -1
  11. package/dist/__tests__/mocks/adapter.js +2 -0
  12. package/dist/__tests__/mocks/adapter.js.map +1 -1
  13. package/dist/adapters/DatabaseAdapter.d.ts.map +1 -1
  14. package/dist/adapters/DatabaseAdapter.js +50 -9
  15. package/dist/adapters/DatabaseAdapter.js.map +1 -1
  16. package/dist/adapters/mysql/MySQLAdapter.d.ts +6 -0
  17. package/dist/adapters/mysql/MySQLAdapter.d.ts.map +1 -1
  18. package/dist/adapters/mysql/MySQLAdapter.js +8 -0
  19. package/dist/adapters/mysql/MySQLAdapter.js.map +1 -1
  20. package/dist/adapters/mysql/SchemaManager.js +16 -15
  21. package/dist/adapters/mysql/SchemaManager.js.map +1 -1
  22. package/dist/adapters/mysql/prompts/index.js +10 -20
  23. package/dist/adapters/mysql/prompts/index.js.map +1 -1
  24. package/dist/adapters/mysql/prompts/proxysqlSetup.js +1 -1
  25. package/dist/adapters/mysql/resources/docstore.d.ts.map +1 -1
  26. package/dist/adapters/mysql/resources/docstore.js +10 -7
  27. package/dist/adapters/mysql/resources/docstore.js.map +1 -1
  28. package/dist/adapters/mysql/resources/events.js +11 -8
  29. package/dist/adapters/mysql/resources/events.js.map +1 -1
  30. package/dist/adapters/mysql/resources/indexes.d.ts.map +1 -1
  31. package/dist/adapters/mysql/resources/indexes.js +12 -15
  32. package/dist/adapters/mysql/resources/indexes.js.map +1 -1
  33. package/dist/adapters/mysql/resources/innodb.d.ts.map +1 -1
  34. package/dist/adapters/mysql/resources/innodb.js +20 -17
  35. package/dist/adapters/mysql/resources/innodb.js.map +1 -1
  36. package/dist/adapters/mysql/resources/locks.d.ts.map +1 -1
  37. package/dist/adapters/mysql/resources/locks.js +9 -6
  38. package/dist/adapters/mysql/resources/locks.js.map +1 -1
  39. package/dist/adapters/mysql/resources/performance.d.ts.map +1 -1
  40. package/dist/adapters/mysql/resources/performance.js +15 -15
  41. package/dist/adapters/mysql/resources/performance.js.map +1 -1
  42. package/dist/adapters/mysql/resources/spatial.d.ts.map +1 -1
  43. package/dist/adapters/mysql/resources/spatial.js +9 -6
  44. package/dist/adapters/mysql/resources/spatial.js.map +1 -1
  45. package/dist/adapters/mysql/resources/sysschema.d.ts.map +1 -1
  46. package/dist/adapters/mysql/resources/sysschema.js +12 -9
  47. package/dist/adapters/mysql/resources/sysschema.js.map +1 -1
  48. package/dist/adapters/mysql/tools/admin/backup.d.ts.map +1 -1
  49. package/dist/adapters/mysql/tools/admin/backup.js +170 -121
  50. package/dist/adapters/mysql/tools/admin/backup.js.map +1 -1
  51. package/dist/adapters/mysql/tools/admin/maintenance.d.ts.map +1 -1
  52. package/dist/adapters/mysql/tools/admin/maintenance.js +106 -57
  53. package/dist/adapters/mysql/tools/admin/maintenance.js.map +1 -1
  54. package/dist/adapters/mysql/tools/admin/monitoring.d.ts.map +1 -1
  55. package/dist/adapters/mysql/tools/admin/monitoring.js +183 -101
  56. package/dist/adapters/mysql/tools/admin/monitoring.js.map +1 -1
  57. package/dist/adapters/mysql/tools/cluster/group-replication.d.ts.map +1 -1
  58. package/dist/adapters/mysql/tools/cluster/group-replication.js +164 -120
  59. package/dist/adapters/mysql/tools/cluster/group-replication.js.map +1 -1
  60. package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts.map +1 -1
  61. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js +212 -145
  62. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js.map +1 -1
  63. package/dist/adapters/mysql/tools/codemode/index.d.ts.map +1 -1
  64. package/dist/adapters/mysql/tools/codemode/index.js +6 -4
  65. package/dist/adapters/mysql/tools/codemode/index.js.map +1 -1
  66. package/dist/adapters/mysql/tools/core.d.ts.map +1 -1
  67. package/dist/adapters/mysql/tools/core.js +152 -29
  68. package/dist/adapters/mysql/tools/core.js.map +1 -1
  69. package/dist/adapters/mysql/tools/docstore.d.ts.map +1 -1
  70. package/dist/adapters/mysql/tools/docstore.js +340 -163
  71. package/dist/adapters/mysql/tools/docstore.js.map +1 -1
  72. package/dist/adapters/mysql/tools/events.d.ts.map +1 -1
  73. package/dist/adapters/mysql/tools/events.js +284 -198
  74. package/dist/adapters/mysql/tools/events.js.map +1 -1
  75. package/dist/adapters/mysql/tools/json/core.d.ts.map +1 -1
  76. package/dist/adapters/mysql/tools/json/core.js +11 -39
  77. package/dist/adapters/mysql/tools/json/core.js.map +1 -1
  78. package/dist/adapters/mysql/tools/json/enhanced.d.ts.map +1 -1
  79. package/dist/adapters/mysql/tools/json/enhanced.js +15 -33
  80. package/dist/adapters/mysql/tools/json/enhanced.js.map +1 -1
  81. package/dist/adapters/mysql/tools/json/helpers.d.ts.map +1 -1
  82. package/dist/adapters/mysql/tools/json/helpers.js +13 -24
  83. package/dist/adapters/mysql/tools/json/helpers.js.map +1 -1
  84. package/dist/adapters/mysql/tools/partitioning.js +3 -0
  85. package/dist/adapters/mysql/tools/partitioning.js.map +1 -1
  86. package/dist/adapters/mysql/tools/performance/analysis.d.ts.map +1 -1
  87. package/dist/adapters/mysql/tools/performance/analysis.js +89 -60
  88. package/dist/adapters/mysql/tools/performance/analysis.js.map +1 -1
  89. package/dist/adapters/mysql/tools/performance/optimization.d.ts.map +1 -1
  90. package/dist/adapters/mysql/tools/performance/optimization.js +151 -127
  91. package/dist/adapters/mysql/tools/performance/optimization.js.map +1 -1
  92. package/dist/adapters/mysql/tools/proxysql.d.ts +1 -1
  93. package/dist/adapters/mysql/tools/proxysql.d.ts.map +1 -1
  94. package/dist/adapters/mysql/tools/proxysql.js +289 -176
  95. package/dist/adapters/mysql/tools/proxysql.js.map +1 -1
  96. package/dist/adapters/mysql/tools/replication.js +75 -49
  97. package/dist/adapters/mysql/tools/replication.js.map +1 -1
  98. package/dist/adapters/mysql/tools/roles.d.ts.map +1 -1
  99. package/dist/adapters/mysql/tools/roles.js +224 -182
  100. package/dist/adapters/mysql/tools/roles.js.map +1 -1
  101. package/dist/adapters/mysql/tools/router.d.ts.map +1 -1
  102. package/dist/adapters/mysql/tools/router.js +168 -67
  103. package/dist/adapters/mysql/tools/router.js.map +1 -1
  104. package/dist/adapters/mysql/tools/schema/constraints.d.ts.map +1 -1
  105. package/dist/adapters/mysql/tools/schema/constraints.js +21 -3
  106. package/dist/adapters/mysql/tools/schema/constraints.js.map +1 -1
  107. package/dist/adapters/mysql/tools/schema/management.d.ts.map +1 -1
  108. package/dist/adapters/mysql/tools/schema/management.js +61 -14
  109. package/dist/adapters/mysql/tools/schema/management.js.map +1 -1
  110. package/dist/adapters/mysql/tools/schema/routines.d.ts.map +1 -1
  111. package/dist/adapters/mysql/tools/schema/routines.js +27 -4
  112. package/dist/adapters/mysql/tools/schema/routines.js.map +1 -1
  113. package/dist/adapters/mysql/tools/schema/scheduled_events.d.ts.map +1 -1
  114. package/dist/adapters/mysql/tools/schema/scheduled_events.js +24 -3
  115. package/dist/adapters/mysql/tools/schema/scheduled_events.js.map +1 -1
  116. package/dist/adapters/mysql/tools/schema/triggers.d.ts.map +1 -1
  117. package/dist/adapters/mysql/tools/schema/triggers.js +23 -2
  118. package/dist/adapters/mysql/tools/schema/triggers.js.map +1 -1
  119. package/dist/adapters/mysql/tools/schema/views.d.ts.map +1 -1
  120. package/dist/adapters/mysql/tools/schema/views.js +47 -7
  121. package/dist/adapters/mysql/tools/schema/views.js.map +1 -1
  122. package/dist/adapters/mysql/tools/security/audit.d.ts.map +1 -1
  123. package/dist/adapters/mysql/tools/security/audit.js +102 -34
  124. package/dist/adapters/mysql/tools/security/audit.js.map +1 -1
  125. package/dist/adapters/mysql/tools/security/data-protection.d.ts.map +1 -1
  126. package/dist/adapters/mysql/tools/security/data-protection.js +264 -205
  127. package/dist/adapters/mysql/tools/security/data-protection.js.map +1 -1
  128. package/dist/adapters/mysql/tools/security/encryption.d.ts.map +1 -1
  129. package/dist/adapters/mysql/tools/security/encryption.js +137 -104
  130. package/dist/adapters/mysql/tools/security/encryption.js.map +1 -1
  131. package/dist/adapters/mysql/tools/shell/backup.d.ts.map +1 -1
  132. package/dist/adapters/mysql/tools/shell/backup.js +71 -59
  133. package/dist/adapters/mysql/tools/shell/backup.js.map +1 -1
  134. package/dist/adapters/mysql/tools/shell/restore.d.ts.map +1 -1
  135. package/dist/adapters/mysql/tools/shell/restore.js +61 -47
  136. package/dist/adapters/mysql/tools/shell/restore.js.map +1 -1
  137. package/dist/adapters/mysql/tools/spatial/geometry.d.ts.map +1 -1
  138. package/dist/adapters/mysql/tools/spatial/geometry.js +19 -5
  139. package/dist/adapters/mysql/tools/spatial/geometry.js.map +1 -1
  140. package/dist/adapters/mysql/tools/spatial/operations.d.ts.map +1 -1
  141. package/dist/adapters/mysql/tools/spatial/operations.js +42 -17
  142. package/dist/adapters/mysql/tools/spatial/operations.js.map +1 -1
  143. package/dist/adapters/mysql/tools/spatial/queries.d.ts.map +1 -1
  144. package/dist/adapters/mysql/tools/spatial/queries.js +109 -57
  145. package/dist/adapters/mysql/tools/spatial/queries.js.map +1 -1
  146. package/dist/adapters/mysql/tools/spatial/setup.d.ts.map +1 -1
  147. package/dist/adapters/mysql/tools/spatial/setup.js +103 -50
  148. package/dist/adapters/mysql/tools/spatial/setup.js.map +1 -1
  149. package/dist/adapters/mysql/tools/stats/comparative.d.ts.map +1 -1
  150. package/dist/adapters/mysql/tools/stats/comparative.js +128 -79
  151. package/dist/adapters/mysql/tools/stats/comparative.js.map +1 -1
  152. package/dist/adapters/mysql/tools/stats/descriptive.d.ts.map +1 -1
  153. package/dist/adapters/mysql/tools/stats/descriptive.js +174 -102
  154. package/dist/adapters/mysql/tools/stats/descriptive.js.map +1 -1
  155. package/dist/adapters/mysql/tools/sysschema/activity.d.ts.map +1 -1
  156. package/dist/adapters/mysql/tools/sysschema/activity.js +50 -25
  157. package/dist/adapters/mysql/tools/sysschema/activity.js.map +1 -1
  158. package/dist/adapters/mysql/tools/sysschema/performance.d.ts.map +1 -1
  159. package/dist/adapters/mysql/tools/sysschema/performance.js +121 -66
  160. package/dist/adapters/mysql/tools/sysschema/performance.js.map +1 -1
  161. package/dist/adapters/mysql/tools/sysschema/resources.d.ts.map +1 -1
  162. package/dist/adapters/mysql/tools/sysschema/resources.js +101 -64
  163. package/dist/adapters/mysql/tools/sysschema/resources.js.map +1 -1
  164. package/dist/adapters/mysql/tools/text/fulltext.d.ts.map +1 -1
  165. package/dist/adapters/mysql/tools/text/fulltext.js +18 -32
  166. package/dist/adapters/mysql/tools/text/fulltext.js.map +1 -1
  167. package/dist/adapters/mysql/tools/transactions.d.ts.map +1 -1
  168. package/dist/adapters/mysql/tools/transactions.js +48 -23
  169. package/dist/adapters/mysql/tools/transactions.js.map +1 -1
  170. package/dist/adapters/mysql/types/proxysql-types.d.ts +15 -0
  171. package/dist/adapters/mysql/types/proxysql-types.d.ts.map +1 -1
  172. package/dist/adapters/mysql/types/proxysql-types.js +33 -1
  173. package/dist/adapters/mysql/types/proxysql-types.js.map +1 -1
  174. package/dist/adapters/mysql/types/router-types.d.ts +1 -1
  175. package/dist/adapters/mysql/types/router-types.js +1 -1
  176. package/dist/adapters/mysql/types/router-types.js.map +1 -1
  177. package/dist/adapters/mysql/types/shell-types.js +2 -2
  178. package/dist/adapters/mysql/types/shell-types.js.map +1 -1
  179. package/dist/adapters/mysql/types.d.ts +485 -21
  180. package/dist/adapters/mysql/types.d.ts.map +1 -1
  181. package/dist/adapters/mysql/types.js +546 -19
  182. package/dist/adapters/mysql/types.js.map +1 -1
  183. package/dist/auth/scopes.js +1 -1
  184. package/dist/auth/scopes.js.map +1 -1
  185. package/dist/codemode/api.d.ts +3 -2
  186. package/dist/codemode/api.d.ts.map +1 -1
  187. package/dist/codemode/api.js +80 -5
  188. package/dist/codemode/api.js.map +1 -1
  189. package/dist/codemode/sandbox-factory.js +1 -1
  190. package/dist/codemode/sandbox-factory.js.map +1 -1
  191. package/dist/codemode/types.d.ts +26 -0
  192. package/dist/codemode/types.d.ts.map +1 -1
  193. package/dist/codemode/types.js +2 -0
  194. package/dist/codemode/types.js.map +1 -1
  195. package/dist/codemode/worker-sandbox.d.ts +4 -2
  196. package/dist/codemode/worker-sandbox.d.ts.map +1 -1
  197. package/dist/codemode/worker-sandbox.js +66 -7
  198. package/dist/codemode/worker-sandbox.js.map +1 -1
  199. package/dist/codemode/worker-script.d.ts +3 -0
  200. package/dist/codemode/worker-script.d.ts.map +1 -1
  201. package/dist/codemode/worker-script.js +128 -75
  202. package/dist/codemode/worker-script.js.map +1 -1
  203. package/dist/constants/ServerInstructions.d.ts +1 -1
  204. package/dist/constants/ServerInstructions.d.ts.map +1 -1
  205. package/dist/constants/ServerInstructions.js +37 -31
  206. package/dist/constants/ServerInstructions.js.map +1 -1
  207. package/dist/filtering/ToolConstants.d.ts +1 -1
  208. package/dist/filtering/ToolConstants.d.ts.map +1 -1
  209. package/dist/filtering/ToolConstants.js +1 -2
  210. package/dist/filtering/ToolConstants.js.map +1 -1
  211. package/dist/pool/ConnectionPool.d.ts.map +1 -1
  212. package/dist/pool/ConnectionPool.js.map +1 -1
  213. package/dist/transports/http.d.ts.map +1 -1
  214. package/dist/transports/http.js +6 -0
  215. package/dist/transports/http.js.map +1 -1
  216. package/dist/utils/validators.d.ts +1 -1
  217. package/dist/utils/validators.d.ts.map +1 -1
  218. package/dist/utils/validators.js.map +1 -1
  219. package/package.json +4 -4
  220. package/releases/v2.3.0-release-notes.md +20 -20
  221. package/releases/v2.3.1-release-notes.md +34 -0
  222. package/releases/v3.0.0-release-notes.md +81 -0
  223. package/src/__tests__/mocks/adapter.ts +3 -0
  224. package/src/__tests__/perf.test.ts +6 -6
  225. package/src/adapters/DatabaseAdapter.ts +58 -9
  226. package/src/adapters/__tests__/DatabaseAdapter.test.ts +89 -8
  227. package/src/adapters/mysql/MySQLAdapter.ts +17 -2
  228. package/src/adapters/mysql/SchemaManager.ts +21 -21
  229. package/src/adapters/mysql/__tests__/MySQLAdapter.test.ts +1 -1
  230. package/src/adapters/mysql/prompts/index.ts +12 -22
  231. package/src/adapters/mysql/prompts/proxysqlSetup.ts +1 -1
  232. package/src/adapters/mysql/resources/docstore.ts +13 -10
  233. package/src/adapters/mysql/resources/events.ts +12 -12
  234. package/src/adapters/mysql/resources/indexes.ts +17 -19
  235. package/src/adapters/mysql/resources/innodb.ts +23 -22
  236. package/src/adapters/mysql/resources/locks.ts +9 -7
  237. package/src/adapters/mysql/resources/performance.ts +23 -18
  238. package/src/adapters/mysql/resources/spatial.ts +9 -7
  239. package/src/adapters/mysql/resources/sysschema.ts +12 -11
  240. package/src/adapters/mysql/tools/__tests__/core.test.ts +126 -55
  241. package/src/adapters/mysql/tools/__tests__/docstore.test.ts +459 -88
  242. package/src/adapters/mysql/tools/__tests__/events.test.ts +281 -103
  243. package/src/adapters/mysql/tools/__tests__/proxysql.test.ts +128 -28
  244. package/src/adapters/mysql/tools/__tests__/replication.test.ts +48 -2
  245. package/src/adapters/mysql/tools/__tests__/roles.test.ts +15 -18
  246. package/src/adapters/mysql/tools/__tests__/router.test.ts +32 -5
  247. package/src/adapters/mysql/tools/__tests__/security.test.ts +126 -2
  248. package/src/adapters/mysql/tools/__tests__/security_injection.test.ts +84 -76
  249. package/src/adapters/mysql/tools/__tests__/security_integration.test.ts +47 -50
  250. package/src/adapters/mysql/tools/__tests__/spatial.test.ts +11 -10
  251. package/src/adapters/mysql/tools/__tests__/spatial_handler.test.ts +54 -38
  252. package/src/adapters/mysql/tools/__tests__/stats.test.ts +285 -152
  253. package/src/adapters/mysql/tools/__tests__/transactions.test.ts +13 -13
  254. package/src/adapters/mysql/tools/admin/__tests__/backup.test.ts +171 -25
  255. package/src/adapters/mysql/tools/admin/__tests__/maintenance.test.ts +240 -4
  256. package/src/adapters/mysql/tools/admin/__tests__/monitoring-summary.test.ts +274 -0
  257. package/src/adapters/mysql/tools/admin/__tests__/monitoring.test.ts +94 -5
  258. package/src/adapters/mysql/tools/admin/backup.ts +193 -143
  259. package/src/adapters/mysql/tools/admin/maintenance.ts +118 -69
  260. package/src/adapters/mysql/tools/admin/monitoring.ts +201 -125
  261. package/src/adapters/mysql/tools/cluster/__tests__/group-replication.test.ts +69 -0
  262. package/src/adapters/mysql/tools/cluster/__tests__/innodb-cluster.test.ts +141 -0
  263. package/src/adapters/mysql/tools/cluster/group-replication.ts +172 -132
  264. package/src/adapters/mysql/tools/cluster/innodb-cluster.ts +231 -157
  265. package/src/adapters/mysql/tools/codemode/__tests__/codemode-tool.test.ts +227 -0
  266. package/src/adapters/mysql/tools/codemode/index.ts +5 -3
  267. package/src/adapters/mysql/tools/core.ts +152 -38
  268. package/src/adapters/mysql/tools/docstore.ts +422 -205
  269. package/src/adapters/mysql/tools/events.ts +334 -233
  270. package/src/adapters/mysql/tools/json/__tests__/core.test.ts +20 -0
  271. package/src/adapters/mysql/tools/json/__tests__/enhanced.test.ts +82 -50
  272. package/src/adapters/mysql/tools/json/__tests__/helpers.test.ts +42 -3
  273. package/src/adapters/mysql/tools/json/core.ts +21 -42
  274. package/src/adapters/mysql/tools/json/enhanced.ts +22 -37
  275. package/src/adapters/mysql/tools/json/helpers.ts +21 -25
  276. package/src/adapters/mysql/tools/partitioning.ts +3 -0
  277. package/src/adapters/mysql/tools/performance/__tests__/analysis.test.ts +98 -5
  278. package/src/adapters/mysql/tools/performance/__tests__/optimization-coverage.test.ts +515 -0
  279. package/src/adapters/mysql/tools/performance/__tests__/optimization.test.ts +187 -0
  280. package/src/adapters/mysql/tools/performance/analysis.ts +95 -69
  281. package/src/adapters/mysql/tools/performance/optimization.ts +182 -153
  282. package/src/adapters/mysql/tools/proxysql.ts +314 -209
  283. package/src/adapters/mysql/tools/replication.ts +84 -57
  284. package/src/adapters/mysql/tools/roles.ts +274 -226
  285. package/src/adapters/mysql/tools/router.ts +181 -85
  286. package/src/adapters/mysql/tools/schema/__tests__/constraints.test.ts +13 -0
  287. package/src/adapters/mysql/tools/schema/__tests__/management.test.ts +60 -25
  288. package/src/adapters/mysql/tools/schema/__tests__/scheduled_events.test.ts +11 -0
  289. package/src/adapters/mysql/tools/schema/__tests__/triggers.test.ts +25 -4
  290. package/src/adapters/mysql/tools/schema/__tests__/views.test.ts +46 -14
  291. package/src/adapters/mysql/tools/schema/constraints.ts +22 -3
  292. package/src/adapters/mysql/tools/schema/management.ts +60 -15
  293. package/src/adapters/mysql/tools/schema/routines.ts +26 -4
  294. package/src/adapters/mysql/tools/schema/scheduled_events.ts +25 -3
  295. package/src/adapters/mysql/tools/schema/triggers.ts +27 -2
  296. package/src/adapters/mysql/tools/schema/views.ts +46 -8
  297. package/src/adapters/mysql/tools/security/__tests__/audit.test.ts +90 -4
  298. package/src/adapters/mysql/tools/security/audit.ts +113 -39
  299. package/src/adapters/mysql/tools/security/data-protection.ts +293 -233
  300. package/src/adapters/mysql/tools/security/encryption.ts +172 -139
  301. package/src/adapters/mysql/tools/shell/__tests__/backup.test.ts +29 -0
  302. package/src/adapters/mysql/tools/shell/backup.ts +90 -73
  303. package/src/adapters/mysql/tools/shell/restore.ts +62 -48
  304. package/src/adapters/mysql/tools/spatial/__tests__/operations.test.ts +22 -14
  305. package/src/adapters/mysql/tools/spatial/__tests__/queries.test.ts +65 -51
  306. package/src/adapters/mysql/tools/spatial/geometry.ts +23 -7
  307. package/src/adapters/mysql/tools/spatial/operations.ts +60 -31
  308. package/src/adapters/mysql/tools/spatial/queries.ts +142 -65
  309. package/src/adapters/mysql/tools/spatial/setup.ts +121 -55
  310. package/src/adapters/mysql/tools/stats/__tests__/comparative.test.ts +12 -10
  311. package/src/adapters/mysql/tools/stats/comparative.ts +150 -98
  312. package/src/adapters/mysql/tools/stats/descriptive.ts +204 -127
  313. package/src/adapters/mysql/tools/sysschema/__tests__/error-paths.test.ts +222 -0
  314. package/src/adapters/mysql/tools/sysschema/__tests__/performance.test.ts +45 -0
  315. package/src/adapters/mysql/tools/sysschema/__tests__/resources.test.ts +6 -3
  316. package/src/adapters/mysql/tools/sysschema/activity.ts +52 -27
  317. package/src/adapters/mysql/tools/sysschema/performance.ts +132 -68
  318. package/src/adapters/mysql/tools/sysschema/resources.ts +105 -67
  319. package/src/adapters/mysql/tools/text/__tests__/fulltext.test.ts +45 -17
  320. package/src/adapters/mysql/tools/text/fulltext.ts +27 -38
  321. package/src/adapters/mysql/tools/transactions.ts +49 -24
  322. package/src/adapters/mysql/types/proxysql-types.ts +38 -1
  323. package/src/adapters/mysql/types/router-types.ts +1 -1
  324. package/src/adapters/mysql/types/shell-types.ts +2 -2
  325. package/src/adapters/mysql/types.ts +632 -19
  326. package/src/auth/__tests__/scopes.test.ts +2 -2
  327. package/src/auth/scopes.ts +1 -1
  328. package/src/codemode/__tests__/api.test.ts +417 -0
  329. package/src/codemode/__tests__/sandbox-factory.test.ts +158 -0
  330. package/src/codemode/__tests__/sandbox.test.ts +301 -0
  331. package/src/codemode/__tests__/security.test.ts +368 -0
  332. package/src/codemode/__tests__/worker-sandbox.test.ts +179 -0
  333. package/src/codemode/__tests__/worker-script.test.ts +226 -0
  334. package/src/codemode/api.ts +89 -5
  335. package/src/codemode/sandbox-factory.ts +1 -1
  336. package/src/codemode/types.ts +34 -0
  337. package/src/codemode/worker-sandbox.ts +74 -7
  338. package/src/codemode/worker-script.ts +157 -86
  339. package/src/constants/ServerInstructions.ts +37 -31
  340. package/src/filtering/ToolConstants.ts +1 -2
  341. package/src/filtering/__tests__/ToolFilter.test.ts +9 -9
  342. package/src/pool/ConnectionPool.ts +4 -1
  343. package/src/transports/__tests__/http.test.ts +15 -3
  344. package/src/transports/http.ts +12 -0
  345. package/src/utils/validators.ts +2 -1
  346. package/vitest.config.ts +3 -1
  347. package/CODE_MODE.md +0 -245
@@ -483,49 +483,117 @@ describe("Event Create Advanced", () => {
483
483
  expect(call).toContain("DISABLE");
484
484
  });
485
485
 
486
- it("should throw error for invalid event name", async () => {
486
+ it("should return structured error for invalid event name", async () => {
487
487
  const tool = tools.find((t) => t.name === "mysql_event_create")!;
488
488
 
489
- await expect(
490
- tool.handler(
491
- {
492
- name: "123-invalid",
493
- schedule: { type: "ONE TIME", executeAt: "2024-12-31 23:59:59" },
494
- body: "SELECT 1",
495
- },
496
- mockContext,
497
- ),
498
- ).rejects.toThrow("Invalid event name");
489
+ const result = await tool.handler(
490
+ {
491
+ name: "123-invalid",
492
+ schedule: { type: "ONE TIME", executeAt: "2024-12-31 23:59:59" },
493
+ body: "SELECT 1",
494
+ },
495
+ mockContext,
496
+ );
497
+
498
+ expect(result).toEqual({ success: false, error: "Invalid event name" });
499
499
  });
500
500
 
501
- it("should throw error when executeAt is missing for ONE TIME events", async () => {
501
+ it("should return structured error when executeAt is missing for ONE TIME events", async () => {
502
502
  const tool = tools.find((t) => t.name === "mysql_event_create")!;
503
503
 
504
- await expect(
505
- tool.handler(
506
- {
507
- name: "bad_event",
508
- schedule: { type: "ONE TIME" },
509
- body: "SELECT 1",
510
- },
511
- mockContext,
512
- ),
513
- ).rejects.toThrow("executeAt is required");
504
+ const result = await tool.handler(
505
+ {
506
+ name: "bad_event",
507
+ schedule: { type: "ONE TIME" },
508
+ body: "SELECT 1",
509
+ },
510
+ mockContext,
511
+ );
512
+
513
+ expect(result).toEqual({
514
+ success: false,
515
+ error: "executeAt is required for ONE TIME events",
516
+ });
514
517
  });
515
518
 
516
- it("should throw error when interval is missing for RECURRING events", async () => {
519
+ it("should return structured error when interval is missing for RECURRING events", async () => {
517
520
  const tool = tools.find((t) => t.name === "mysql_event_create")!;
518
521
 
519
- await expect(
520
- tool.handler(
521
- {
522
- name: "bad_recurring",
523
- schedule: { type: "RECURRING" },
524
- body: "SELECT 1",
522
+ const result = await tool.handler(
523
+ {
524
+ name: "bad_recurring",
525
+ schedule: { type: "RECURRING" },
526
+ body: "SELECT 1",
527
+ },
528
+ mockContext,
529
+ );
530
+
531
+ expect(result).toEqual({
532
+ success: false,
533
+ error: "interval and intervalUnit are required for RECURRING events",
534
+ });
535
+ });
536
+
537
+ it("should return structured error for invalid schedule type on create", async () => {
538
+ const tool = tools.find((t) => t.name === "mysql_event_create")!;
539
+
540
+ const result = await tool.handler(
541
+ {
542
+ name: "my_event",
543
+ schedule: { type: "INVALID_TYPE" },
544
+ body: "SELECT 1",
545
+ },
546
+ mockContext,
547
+ );
548
+
549
+ expect(result).toHaveProperty("success", false);
550
+ expect(result).toHaveProperty("error");
551
+ expect((result as { error: string }).error).toContain(
552
+ "Invalid schedule type",
553
+ );
554
+ });
555
+
556
+ it("should return structured error for invalid onCompletion on create", async () => {
557
+ const tool = tools.find((t) => t.name === "mysql_event_create")!;
558
+
559
+ const result = await tool.handler(
560
+ {
561
+ name: "my_event",
562
+ schedule: { type: "ONE TIME", executeAt: "2024-12-31 23:59:59" },
563
+ body: "SELECT 1",
564
+ onCompletion: "INVALID_VALUE",
565
+ },
566
+ mockContext,
567
+ );
568
+
569
+ expect(result).toHaveProperty("success", false);
570
+ expect(result).toHaveProperty("error");
571
+ expect((result as { error: string }).error).toContain(
572
+ "Invalid onCompletion",
573
+ );
574
+ });
575
+
576
+ it("should return structured error for invalid intervalUnit on create", async () => {
577
+ const tool = tools.find((t) => t.name === "mysql_event_create")!;
578
+
579
+ const result = await tool.handler(
580
+ {
581
+ name: "my_event",
582
+ schedule: {
583
+ type: "RECURRING",
584
+ interval: 1,
585
+ intervalUnit: "INVALID_UNIT",
525
586
  },
526
- mockContext,
527
- ),
528
- ).rejects.toThrow("interval and intervalUnit are required");
587
+ body: "SELECT 1",
588
+ },
589
+ mockContext,
590
+ );
591
+
592
+ expect(result).toHaveProperty("success", false);
593
+ expect(result).toHaveProperty("error");
594
+ expect((result as { error: string }).error).toContain(
595
+ "Invalid intervalUnit",
596
+ );
529
597
  });
530
598
  });
531
599
 
@@ -629,73 +697,118 @@ describe("Event Alter Advanced", () => {
629
697
  expect(call).toContain("COMMENT 'Updated comment'");
630
698
  });
631
699
 
632
- it("should throw error for invalid event name", async () => {
700
+ it("should return structured error for invalid event name", async () => {
633
701
  const tool = tools.find((t) => t.name === "mysql_event_alter")!;
634
702
 
635
- await expect(
636
- tool.handler(
637
- {
638
- name: "invalid-name",
639
- enabled: true,
640
- },
641
- mockContext,
642
- ),
643
- ).rejects.toThrow("Invalid event name");
703
+ const result = await tool.handler(
704
+ {
705
+ name: "invalid-name",
706
+ enabled: true,
707
+ },
708
+ mockContext,
709
+ );
710
+
711
+ expect(result).toEqual({ success: false, error: "Invalid event name" });
644
712
  });
645
713
 
646
- it("should throw error for invalid new event name", async () => {
714
+ it("should return structured error for invalid new event name", async () => {
647
715
  const tool = tools.find((t) => t.name === "mysql_event_alter")!;
648
716
 
649
- await expect(
650
- tool.handler(
651
- {
652
- name: "valid_name",
653
- newName: "123-invalid",
654
- },
655
- mockContext,
656
- ),
657
- ).rejects.toThrow("Invalid new event name");
717
+ const result = await tool.handler(
718
+ {
719
+ name: "valid_name",
720
+ newName: "123-invalid",
721
+ },
722
+ mockContext,
723
+ );
724
+
725
+ expect(result).toEqual({ success: false, error: "Invalid new event name" });
658
726
  });
659
727
 
660
- it("should throw error when no modifications specified", async () => {
728
+ it("should return structured error when no modifications specified", async () => {
661
729
  const tool = tools.find((t) => t.name === "mysql_event_alter")!;
662
730
 
663
- await expect(
664
- tool.handler(
665
- {
666
- name: "my_event",
667
- },
668
- mockContext,
669
- ),
670
- ).rejects.toThrow("No modifications specified");
731
+ const result = await tool.handler(
732
+ {
733
+ name: "my_event",
734
+ },
735
+ mockContext,
736
+ );
737
+
738
+ expect(result).toEqual({
739
+ success: false,
740
+ error: "No modifications specified",
741
+ });
671
742
  });
672
743
 
673
- it("should throw error when executeAt missing for ONE TIME alter", async () => {
744
+ it("should return structured error when executeAt missing for ONE TIME alter", async () => {
674
745
  const tool = tools.find((t) => t.name === "mysql_event_alter")!;
675
746
 
676
- await expect(
677
- tool.handler(
678
- {
679
- name: "my_event",
680
- schedule: { type: "ONE TIME" },
681
- },
682
- mockContext,
683
- ),
684
- ).rejects.toThrow("executeAt is required");
747
+ const result = await tool.handler(
748
+ {
749
+ name: "my_event",
750
+ schedule: { type: "ONE TIME" },
751
+ },
752
+ mockContext,
753
+ );
754
+
755
+ expect(result).toEqual({
756
+ success: false,
757
+ error: "executeAt is required for ONE TIME events",
758
+ });
685
759
  });
686
760
 
687
- it("should throw error when interval missing for RECURRING alter", async () => {
761
+ it("should return structured error when interval missing for RECURRING alter", async () => {
688
762
  const tool = tools.find((t) => t.name === "mysql_event_alter")!;
689
763
 
690
- await expect(
691
- tool.handler(
692
- {
693
- name: "my_event",
694
- schedule: { type: "RECURRING" },
695
- },
696
- mockContext,
697
- ),
698
- ).rejects.toThrow("interval and intervalUnit are required");
764
+ const result = await tool.handler(
765
+ {
766
+ name: "my_event",
767
+ schedule: { type: "RECURRING" },
768
+ },
769
+ mockContext,
770
+ );
771
+
772
+ expect(result).toEqual({
773
+ success: false,
774
+ error: "interval and intervalUnit are required for RECURRING events",
775
+ });
776
+ });
777
+
778
+ it("should return structured error for invalid onCompletion on alter", async () => {
779
+ const tool = tools.find((t) => t.name === "mysql_event_alter")!;
780
+
781
+ const result = await tool.handler(
782
+ {
783
+ name: "my_event",
784
+ onCompletion: "INVALID_VALUE",
785
+ },
786
+ mockContext,
787
+ );
788
+
789
+ expect(result).toHaveProperty("success", false);
790
+ expect(result).toHaveProperty("error");
791
+ expect((result as { error: string }).error).toContain(
792
+ "Invalid onCompletion",
793
+ );
794
+ });
795
+
796
+ it("should return structured error for invalid schedule type on alter", async () => {
797
+ const tool = tools.find((t) => t.name === "mysql_event_alter")!;
798
+
799
+ const result = await tool.handler(
800
+ {
801
+ name: "my_event",
802
+ schedule: { type: "INVALID_TYPE" },
803
+ },
804
+ mockContext,
805
+ );
806
+
807
+ expect(result).toHaveProperty("success", false);
808
+ expect(result).toHaveProperty("error");
809
+ expect((result as { error: string }).error).toContain(
810
+ "Invalid schedule type",
811
+ );
699
812
  });
700
813
  });
701
814
 
@@ -711,17 +824,17 @@ describe("Event Drop Advanced", () => {
711
824
  mockContext = createMockRequestContext();
712
825
  });
713
826
 
714
- it("should throw error for invalid event name", async () => {
827
+ it("should return structured error for invalid event name", async () => {
715
828
  const tool = tools.find((t) => t.name === "mysql_event_drop")!;
716
829
 
717
- await expect(
718
- tool.handler(
719
- {
720
- name: "invalid-event-name",
721
- },
722
- mockContext,
723
- ),
724
- ).rejects.toThrow("Invalid event name");
830
+ const result = await tool.handler(
831
+ {
832
+ name: "invalid-event-name",
833
+ },
834
+ mockContext,
835
+ );
836
+
837
+ expect(result).toEqual({ success: false, error: "Invalid event name" });
725
838
  });
726
839
 
727
840
  it("should drop without IF EXISTS when ifExists is false", async () => {
@@ -771,7 +884,7 @@ describe("Event Graceful Error Handling", () => {
771
884
 
772
885
  expect(result).toEqual({
773
886
  success: false,
774
- reason: "Event 'my_event' already exists",
887
+ error: "Event already exists",
775
888
  });
776
889
  });
777
890
 
@@ -792,7 +905,7 @@ describe("Event Graceful Error Handling", () => {
792
905
 
793
906
  expect(result).toEqual({
794
907
  success: false,
795
- reason: "Event 'ghost_event' does not exist",
908
+ error: "Event does not exist",
796
909
  });
797
910
  });
798
911
 
@@ -813,23 +926,88 @@ describe("Event Graceful Error Handling", () => {
813
926
 
814
927
  expect(result).toEqual({
815
928
  success: false,
816
- reason: "Event 'ghost_event' does not exist",
929
+ error: "Event does not exist",
817
930
  });
818
931
  });
819
932
 
820
- it("should rethrow unexpected errors from create", async () => {
933
+ it("should return structured error for unexpected errors from create", async () => {
821
934
  mockAdapter.executeQuery.mockRejectedValue(new Error("Connection lost"));
822
935
 
823
936
  const tool = tools.find((t) => t.name === "mysql_event_create")!;
824
- await expect(
825
- tool.handler(
826
- {
827
- name: "my_event",
828
- schedule: { type: "ONE TIME", executeAt: "2024-12-31 23:59:59" },
829
- body: "SELECT 1",
830
- },
831
- mockContext,
937
+ const result = await tool.handler(
938
+ {
939
+ name: "my_event",
940
+ schedule: { type: "ONE TIME", executeAt: "2024-12-31 23:59:59" },
941
+ body: "SELECT 1",
942
+ },
943
+ mockContext,
944
+ );
945
+
946
+ expect(result).toEqual({ success: false, error: "Connection lost" });
947
+ });
948
+
949
+ it("should strip error prefix from create error messages", async () => {
950
+ mockAdapter.executeQuery.mockRejectedValue(
951
+ new Error(
952
+ "Query failed: Execute failed: You have an error in your SQL syntax",
832
953
  ),
833
- ).rejects.toThrow("Connection lost");
954
+ );
955
+
956
+ const tool = tools.find((t) => t.name === "mysql_event_create")!;
957
+ const result = await tool.handler(
958
+ {
959
+ name: "my_event",
960
+ schedule: { type: "ONE TIME", executeAt: "2024-12-31 23:59:59" },
961
+ body: "SELECTT * FROMM",
962
+ },
963
+ mockContext,
964
+ );
965
+
966
+ expect(result).toEqual({
967
+ success: false,
968
+ error: "You have an error in your SQL syntax",
969
+ });
970
+ });
971
+
972
+ it("should return structured error when event_list query fails", async () => {
973
+ mockAdapter.executeQuery.mockRejectedValue(
974
+ new Error("Connection lost during query"),
975
+ );
976
+
977
+ const tool = tools.find((t) => t.name === "mysql_event_list")!;
978
+ const result = await tool.handler({}, mockContext);
979
+
980
+ expect(result).toEqual({
981
+ success: false,
982
+ error: "Connection lost during query",
983
+ });
984
+ });
985
+
986
+ it("should return structured error when event_status query fails", async () => {
987
+ mockAdapter.executeQuery.mockRejectedValue(
988
+ new Error("Connection lost during query"),
989
+ );
990
+
991
+ const tool = tools.find((t) => t.name === "mysql_event_status")!;
992
+ const result = await tool.handler({ name: "test_event" }, mockContext);
993
+
994
+ expect(result).toEqual({
995
+ success: false,
996
+ error: "Connection lost during query",
997
+ });
998
+ });
999
+
1000
+ it("should return structured error when scheduler_status query fails", async () => {
1001
+ mockAdapter.executeQuery.mockRejectedValue(
1002
+ new Error("Connection lost during query"),
1003
+ );
1004
+
1005
+ const tool = tools.find((t) => t.name === "mysql_scheduler_status")!;
1006
+ const result = await tool.handler({}, mockContext);
1007
+
1008
+ expect(result).toEqual({
1009
+ success: false,
1010
+ error: "Connection lost during query",
1011
+ });
834
1012
  });
835
1013
  });
@@ -34,8 +34,8 @@ describe("getProxySQLTools", () => {
34
34
  );
35
35
  });
36
36
 
37
- it("should return 12 proxysql tools", () => {
38
- expect(tools).toHaveLength(12);
37
+ it("should return 11 proxysql tools", () => {
38
+ expect(tools).toHaveLength(11);
39
39
  });
40
40
 
41
41
  it("should have proxysql group for all tools", () => {
@@ -60,7 +60,6 @@ describe("getProxySQLTools", () => {
60
60
  const toolNames = tools.map((t) => t.name);
61
61
  expect(toolNames).toContain("proxysql_status");
62
62
  expect(toolNames).toContain("proxysql_servers");
63
- expect(toolNames).toContain("proxysql_hostgroups");
64
63
  expect(toolNames).toContain("proxysql_query_rules");
65
64
  expect(toolNames).toContain("proxysql_query_digest");
66
65
  expect(toolNames).toContain("proxysql_connection_pool");
@@ -313,26 +312,16 @@ describe("Handler Execution", () => {
313
312
  );
314
313
  expect(result).toHaveProperty("count", 1);
315
314
  });
316
- });
317
-
318
- describe("proxysql_hostgroups", () => {
319
- it("should return connection pool stats", async () => {
320
- const mockPools = [
321
- { hostgroup: 1, srv_host: "mysql1", ConnUsed: 5, ConnFree: 10 },
322
- ];
323
- mockQuery.mockResolvedValue([mockPools]);
324
315
 
325
- const tool = tools.find((t) => t.name === "proxysql_hostgroups")!;
326
- const result = await tool.handler({}, mockContext);
316
+ it("should return structured error for negative hostgroup_id", async () => {
317
+ const tool = tools.find((t) => t.name === "proxysql_servers")!;
318
+ const result = (await tool.handler(
319
+ { hostgroup_id: -1 },
320
+ mockContext,
321
+ )) as { success: boolean; error: string };
327
322
 
328
- expect(mockQuery).toHaveBeenCalledWith(
329
- "SELECT * FROM stats_mysql_connection_pool",
330
- );
331
- expect(result).toEqual({
332
- success: true,
333
- hostgroups: mockPools,
334
- count: 1,
335
- });
323
+ expect(result.success).toBe(false);
324
+ expect(result.error).toBeDefined();
336
325
  });
337
326
  });
338
327
 
@@ -360,6 +349,17 @@ describe("Handler Execution", () => {
360
349
  "SELECT * FROM mysql_query_rules LIMIT 10",
361
350
  );
362
351
  });
352
+
353
+ it("should return structured error for negative limit", async () => {
354
+ const tool = tools.find((t) => t.name === "proxysql_query_rules")!;
355
+ const result = (await tool.handler({ limit: -1 }, mockContext)) as {
356
+ success: boolean;
357
+ error: string;
358
+ };
359
+
360
+ expect(result.success).toBe(false);
361
+ expect(result.error).toBeDefined();
362
+ });
363
363
  });
364
364
 
365
365
  describe("proxysql_query_digest", () => {
@@ -393,6 +393,17 @@ describe("Handler Execution", () => {
393
393
  expect.stringContaining("LIMIT 25"),
394
394
  );
395
395
  });
396
+
397
+ it("should return structured error for negative limit", async () => {
398
+ const tool = tools.find((t) => t.name === "proxysql_query_digest")!;
399
+ const result = (await tool.handler({ limit: -1 }, mockContext)) as {
400
+ success: boolean;
401
+ error: string;
402
+ };
403
+
404
+ expect(result.success).toBe(false);
405
+ expect(result.error).toBeDefined();
406
+ });
396
407
  });
397
408
 
398
409
  describe("proxysql_connection_pool", () => {
@@ -419,6 +430,17 @@ describe("Handler Execution", () => {
419
430
  "SELECT * FROM stats_mysql_connection_pool WHERE hostgroup = 2",
420
431
  );
421
432
  });
433
+
434
+ it("should return structured error for negative hostgroup_id", async () => {
435
+ const tool = tools.find((t) => t.name === "proxysql_connection_pool")!;
436
+ const result = (await tool.handler(
437
+ { hostgroup_id: -1 },
438
+ mockContext,
439
+ )) as { success: boolean; error: string };
440
+
441
+ expect(result.success).toBe(false);
442
+ expect(result.error).toBeDefined();
443
+ });
422
444
  });
423
445
 
424
446
  describe("proxysql_users", () => {
@@ -557,6 +579,28 @@ describe("Handler Execution", () => {
557
579
  // totalVarsAvailable should reflect total count
558
580
  expect(result.totalVarsAvailable).toBe(4);
559
581
  });
582
+
583
+ it("should return structured error for negative limit", async () => {
584
+ const tool = tools.find((t) => t.name === "proxysql_global_variables")!;
585
+ const result = (await tool.handler({ limit: -1 }, mockContext)) as {
586
+ success: boolean;
587
+ error: string;
588
+ };
589
+
590
+ expect(result.success).toBe(false);
591
+ expect(result.error).toBeDefined();
592
+ });
593
+
594
+ it("should return structured error for unsafe like pattern", async () => {
595
+ const tool = tools.find((t) => t.name === "proxysql_global_variables")!;
596
+ const result = (await tool.handler(
597
+ { like: "'; DROP TABLE --" },
598
+ mockContext,
599
+ )) as { success: boolean; error: string };
600
+
601
+ expect(result.success).toBe(false);
602
+ expect(result.error).toContain("Invalid like pattern");
603
+ });
560
604
  });
561
605
 
562
606
  describe("proxysql_memory_stats", () => {
@@ -633,26 +677,82 @@ describe("Connection Error Handling", () => {
633
677
  mockContext = createMockRequestContext();
634
678
  });
635
679
 
636
- it("should propagate connection errors", async () => {
680
+ it("should return structured error on connection failure", async () => {
637
681
  mockCreateConnection.mockRejectedValue(new Error("Connection refused"));
638
682
 
639
683
  const tool = tools.find((t) => t.name === "proxysql_status")!;
684
+ const result = (await tool.handler({}, mockContext)) as {
685
+ success: boolean;
686
+ error: string;
687
+ };
640
688
 
641
- await expect(tool.handler({}, mockContext)).rejects.toThrow(
642
- "Connection refused",
643
- );
689
+ expect(result.success).toBe(false);
690
+ expect(result.error).toContain("Connection refused");
644
691
  });
645
692
 
646
- it("should propagate query errors", async () => {
693
+ it("should return structured error on query failure", async () => {
647
694
  mockCreateConnection.mockResolvedValue({
648
695
  query: vi.fn().mockRejectedValue(new Error("Access denied")),
649
696
  end: mockEnd,
650
697
  });
651
698
 
652
699
  const tool = tools.find((t) => t.name === "proxysql_status")!;
700
+ const result = (await tool.handler({}, mockContext)) as {
701
+ success: boolean;
702
+ error: string;
703
+ };
704
+
705
+ expect(result.success).toBe(false);
706
+ expect(result.error).toContain("Access denied");
707
+ });
708
+ });
653
709
 
654
- await expect(tool.handler({}, mockContext)).rejects.toThrow(
655
- "Access denied",
710
+ describe("Crash Tests (all 12 handlers)", () => {
711
+ let tools: ReturnType<typeof getProxySQLTools>;
712
+ let mockContext: ReturnType<typeof createMockRequestContext>;
713
+
714
+ beforeEach(() => {
715
+ vi.clearAllMocks();
716
+ tools = getProxySQLTools(
717
+ createMockMySQLAdapter() as unknown as MySQLAdapter,
656
718
  );
719
+ mockContext = createMockRequestContext();
720
+
721
+ // All tools will fail on query
722
+ mockCreateConnection.mockResolvedValue({
723
+ query: vi.fn().mockRejectedValue(new Error("ProxySQL unavailable")),
724
+ end: mockEnd,
725
+ });
657
726
  });
727
+
728
+ const toolNames = [
729
+ "proxysql_status",
730
+ "proxysql_runtime_status",
731
+ "proxysql_servers",
732
+ "proxysql_query_rules",
733
+ "proxysql_query_digest",
734
+ "proxysql_connection_pool",
735
+ "proxysql_users",
736
+ "proxysql_global_variables",
737
+ "proxysql_memory_stats",
738
+ "proxysql_commands",
739
+ "proxysql_process_list",
740
+ ];
741
+
742
+ for (const toolName of toolNames) {
743
+ it(`${toolName} should return { success: false, error } on query failure`, async () => {
744
+ const tool = tools.find((t) => t.name === toolName)!;
745
+ const params =
746
+ toolName === "proxysql_commands"
747
+ ? { command: "LOAD MYSQL USERS TO RUNTIME" }
748
+ : {};
749
+ const result = (await tool.handler(params, mockContext)) as {
750
+ success: boolean;
751
+ error: string;
752
+ };
753
+
754
+ expect(result.success).toBe(false);
755
+ expect(result.error).toContain("ProxySQL unavailable");
756
+ });
757
+ }
658
758
  });