@neverinfamous/mysql-mcp 2.1.0 → 2.2.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 (751) hide show
  1. package/.env.example +14 -4
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +7 -1
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +6 -1
  4. package/.github/dependabot.yml +15 -0
  5. package/.github/pull_request_template.md +5 -0
  6. package/.github/workflows/codeql.yml +41 -42
  7. package/.github/workflows/docker-publish.yml +248 -210
  8. package/.github/workflows/publish-npm.yml +16 -6
  9. package/CHANGELOG.md +272 -22
  10. package/CODE_OF_CONDUCT.md +2 -0
  11. package/DOCKER_README.md +222 -156
  12. package/Dockerfile +2 -2
  13. package/README.md +210 -176
  14. package/SECURITY.md +0 -8
  15. package/VERSION +1 -1
  16. package/dist/__tests__/mocks/adapter.d.ts +3 -3
  17. package/dist/__tests__/mocks/adapter.d.ts.map +1 -1
  18. package/dist/__tests__/mocks/adapter.js +51 -35
  19. package/dist/__tests__/mocks/adapter.js.map +1 -1
  20. package/dist/__tests__/mocks/index.d.ts +4 -4
  21. package/dist/__tests__/mocks/index.d.ts.map +1 -1
  22. package/dist/__tests__/mocks/index.js +2 -2
  23. package/dist/__tests__/mocks/index.js.map +1 -1
  24. package/dist/__tests__/mocks/mysql.d.ts +2 -2
  25. package/dist/__tests__/mocks/mysql.d.ts.map +1 -1
  26. package/dist/__tests__/mocks/mysql.js +14 -14
  27. package/dist/__tests__/mocks/mysql.js.map +1 -1
  28. package/dist/__tests__/setup.d.ts.map +1 -1
  29. package/dist/__tests__/setup.js +7 -7
  30. package/dist/__tests__/setup.js.map +1 -1
  31. package/dist/adapters/DatabaseAdapter.d.ts +2 -2
  32. package/dist/adapters/DatabaseAdapter.d.ts.map +1 -1
  33. package/dist/adapters/DatabaseAdapter.js +69 -40
  34. package/dist/adapters/DatabaseAdapter.js.map +1 -1
  35. package/dist/adapters/mysql/MySQLAdapter.d.ts +10 -4
  36. package/dist/adapters/mysql/MySQLAdapter.d.ts.map +1 -1
  37. package/dist/adapters/mysql/MySQLAdapter.js +143 -116
  38. package/dist/adapters/mysql/MySQLAdapter.js.map +1 -1
  39. package/dist/adapters/mysql/SchemaManager.d.ts +1 -1
  40. package/dist/adapters/mysql/SchemaManager.d.ts.map +1 -1
  41. package/dist/adapters/mysql/SchemaManager.js +76 -56
  42. package/dist/adapters/mysql/SchemaManager.js.map +1 -1
  43. package/dist/adapters/mysql/index.d.ts +2 -2
  44. package/dist/adapters/mysql/index.js +2 -2
  45. package/dist/adapters/mysql/prompts/backupStrategy.d.ts +1 -1
  46. package/dist/adapters/mysql/prompts/backupStrategy.d.ts.map +1 -1
  47. package/dist/adapters/mysql/prompts/backupStrategy.js +21 -9
  48. package/dist/adapters/mysql/prompts/backupStrategy.js.map +1 -1
  49. package/dist/adapters/mysql/prompts/clusterSetup.d.ts +1 -1
  50. package/dist/adapters/mysql/prompts/clusterSetup.d.ts.map +1 -1
  51. package/dist/adapters/mysql/prompts/clusterSetup.js +3 -3
  52. package/dist/adapters/mysql/prompts/clusterSetup.js.map +1 -1
  53. package/dist/adapters/mysql/prompts/docstoreSetup.d.ts +1 -1
  54. package/dist/adapters/mysql/prompts/docstoreSetup.js +3 -3
  55. package/dist/adapters/mysql/prompts/docstoreSetup.js.map +1 -1
  56. package/dist/adapters/mysql/prompts/eventScheduler.d.ts +1 -1
  57. package/dist/adapters/mysql/prompts/eventScheduler.js +3 -3
  58. package/dist/adapters/mysql/prompts/eventScheduler.js.map +1 -1
  59. package/dist/adapters/mysql/prompts/healthCheck.d.ts +1 -1
  60. package/dist/adapters/mysql/prompts/healthCheck.d.ts.map +1 -1
  61. package/dist/adapters/mysql/prompts/healthCheck.js +10 -6
  62. package/dist/adapters/mysql/prompts/healthCheck.js.map +1 -1
  63. package/dist/adapters/mysql/prompts/index.d.ts +2 -2
  64. package/dist/adapters/mysql/prompts/index.d.ts.map +1 -1
  65. package/dist/adapters/mysql/prompts/index.js +98 -62
  66. package/dist/adapters/mysql/prompts/index.js.map +1 -1
  67. package/dist/adapters/mysql/prompts/indexTuning.d.ts +1 -1
  68. package/dist/adapters/mysql/prompts/indexTuning.d.ts.map +1 -1
  69. package/dist/adapters/mysql/prompts/indexTuning.js +11 -7
  70. package/dist/adapters/mysql/prompts/indexTuning.js.map +1 -1
  71. package/dist/adapters/mysql/prompts/mysqlshSetup.d.ts +1 -1
  72. package/dist/adapters/mysql/prompts/mysqlshSetup.js +4 -4
  73. package/dist/adapters/mysql/prompts/mysqlshSetup.js.map +1 -1
  74. package/dist/adapters/mysql/prompts/proxysqlSetup.d.ts +1 -1
  75. package/dist/adapters/mysql/prompts/proxysqlSetup.js +3 -3
  76. package/dist/adapters/mysql/prompts/proxysqlSetup.js.map +1 -1
  77. package/dist/adapters/mysql/prompts/replicationSetup.d.ts +1 -1
  78. package/dist/adapters/mysql/prompts/replicationSetup.d.ts.map +1 -1
  79. package/dist/adapters/mysql/prompts/replicationSetup.js +13 -7
  80. package/dist/adapters/mysql/prompts/replicationSetup.js.map +1 -1
  81. package/dist/adapters/mysql/prompts/routerSetup.d.ts +1 -1
  82. package/dist/adapters/mysql/prompts/routerSetup.js +3 -3
  83. package/dist/adapters/mysql/prompts/routerSetup.js.map +1 -1
  84. package/dist/adapters/mysql/prompts/spatialSetup.d.ts +1 -1
  85. package/dist/adapters/mysql/prompts/spatialSetup.js +3 -3
  86. package/dist/adapters/mysql/prompts/spatialSetup.js.map +1 -1
  87. package/dist/adapters/mysql/prompts/sysSchema.d.ts +1 -1
  88. package/dist/adapters/mysql/prompts/sysSchema.d.ts.map +1 -1
  89. package/dist/adapters/mysql/prompts/sysSchema.js +3 -3
  90. package/dist/adapters/mysql/prompts/sysSchema.js.map +1 -1
  91. package/dist/adapters/mysql/resources/capabilities.d.ts +2 -2
  92. package/dist/adapters/mysql/resources/capabilities.d.ts.map +1 -1
  93. package/dist/adapters/mysql/resources/capabilities.js +17 -15
  94. package/dist/adapters/mysql/resources/capabilities.js.map +1 -1
  95. package/dist/adapters/mysql/resources/cluster.d.ts +2 -2
  96. package/dist/adapters/mysql/resources/cluster.d.ts.map +1 -1
  97. package/dist/adapters/mysql/resources/cluster.js +17 -15
  98. package/dist/adapters/mysql/resources/cluster.js.map +1 -1
  99. package/dist/adapters/mysql/resources/docstore.d.ts +2 -2
  100. package/dist/adapters/mysql/resources/docstore.d.ts.map +1 -1
  101. package/dist/adapters/mysql/resources/docstore.js +12 -12
  102. package/dist/adapters/mysql/resources/docstore.js.map +1 -1
  103. package/dist/adapters/mysql/resources/events.d.ts +2 -2
  104. package/dist/adapters/mysql/resources/events.d.ts.map +1 -1
  105. package/dist/adapters/mysql/resources/events.js +12 -12
  106. package/dist/adapters/mysql/resources/events.js.map +1 -1
  107. package/dist/adapters/mysql/resources/health.d.ts +2 -2
  108. package/dist/adapters/mysql/resources/health.d.ts.map +1 -1
  109. package/dist/adapters/mysql/resources/health.js +36 -32
  110. package/dist/adapters/mysql/resources/health.js.map +1 -1
  111. package/dist/adapters/mysql/resources/index.d.ts +2 -2
  112. package/dist/adapters/mysql/resources/index.js +19 -19
  113. package/dist/adapters/mysql/resources/index.js.map +1 -1
  114. package/dist/adapters/mysql/resources/indexes.d.ts +2 -2
  115. package/dist/adapters/mysql/resources/indexes.d.ts.map +1 -1
  116. package/dist/adapters/mysql/resources/indexes.js +12 -12
  117. package/dist/adapters/mysql/resources/indexes.js.map +1 -1
  118. package/dist/adapters/mysql/resources/innodb.d.ts +2 -2
  119. package/dist/adapters/mysql/resources/innodb.d.ts.map +1 -1
  120. package/dist/adapters/mysql/resources/innodb.js +37 -36
  121. package/dist/adapters/mysql/resources/innodb.js.map +1 -1
  122. package/dist/adapters/mysql/resources/locks.d.ts +2 -2
  123. package/dist/adapters/mysql/resources/locks.d.ts.map +1 -1
  124. package/dist/adapters/mysql/resources/locks.js +14 -14
  125. package/dist/adapters/mysql/resources/locks.js.map +1 -1
  126. package/dist/adapters/mysql/resources/performance.d.ts +2 -2
  127. package/dist/adapters/mysql/resources/performance.d.ts.map +1 -1
  128. package/dist/adapters/mysql/resources/performance.js +30 -29
  129. package/dist/adapters/mysql/resources/performance.js.map +1 -1
  130. package/dist/adapters/mysql/resources/pool.d.ts +2 -2
  131. package/dist/adapters/mysql/resources/pool.d.ts.map +1 -1
  132. package/dist/adapters/mysql/resources/pool.js +9 -9
  133. package/dist/adapters/mysql/resources/pool.js.map +1 -1
  134. package/dist/adapters/mysql/resources/processlist.d.ts +2 -2
  135. package/dist/adapters/mysql/resources/processlist.d.ts.map +1 -1
  136. package/dist/adapters/mysql/resources/processlist.js +9 -9
  137. package/dist/adapters/mysql/resources/processlist.js.map +1 -1
  138. package/dist/adapters/mysql/resources/replication.d.ts +2 -2
  139. package/dist/adapters/mysql/resources/replication.d.ts.map +1 -1
  140. package/dist/adapters/mysql/resources/replication.js +42 -35
  141. package/dist/adapters/mysql/resources/replication.js.map +1 -1
  142. package/dist/adapters/mysql/resources/schema.d.ts +2 -2
  143. package/dist/adapters/mysql/resources/schema.d.ts.map +1 -1
  144. package/dist/adapters/mysql/resources/schema.js +8 -8
  145. package/dist/adapters/mysql/resources/schema.js.map +1 -1
  146. package/dist/adapters/mysql/resources/spatial.d.ts +2 -2
  147. package/dist/adapters/mysql/resources/spatial.d.ts.map +1 -1
  148. package/dist/adapters/mysql/resources/spatial.js +9 -9
  149. package/dist/adapters/mysql/resources/spatial.js.map +1 -1
  150. package/dist/adapters/mysql/resources/status.d.ts +2 -2
  151. package/dist/adapters/mysql/resources/status.d.ts.map +1 -1
  152. package/dist/adapters/mysql/resources/status.js +10 -10
  153. package/dist/adapters/mysql/resources/status.js.map +1 -1
  154. package/dist/adapters/mysql/resources/sysschema.d.ts +2 -2
  155. package/dist/adapters/mysql/resources/sysschema.d.ts.map +1 -1
  156. package/dist/adapters/mysql/resources/sysschema.js +10 -10
  157. package/dist/adapters/mysql/resources/sysschema.js.map +1 -1
  158. package/dist/adapters/mysql/resources/tables.d.ts +2 -2
  159. package/dist/adapters/mysql/resources/tables.d.ts.map +1 -1
  160. package/dist/adapters/mysql/resources/tables.js +8 -8
  161. package/dist/adapters/mysql/resources/tables.js.map +1 -1
  162. package/dist/adapters/mysql/resources/variables.d.ts +2 -2
  163. package/dist/adapters/mysql/resources/variables.d.ts.map +1 -1
  164. package/dist/adapters/mysql/resources/variables.js +10 -10
  165. package/dist/adapters/mysql/resources/variables.js.map +1 -1
  166. package/dist/adapters/mysql/tools/admin/backup.d.ts +2 -2
  167. package/dist/adapters/mysql/tools/admin/backup.d.ts.map +1 -1
  168. package/dist/adapters/mysql/tools/admin/backup.js +191 -99
  169. package/dist/adapters/mysql/tools/admin/backup.js.map +1 -1
  170. package/dist/adapters/mysql/tools/admin/index.d.ts +2 -2
  171. package/dist/adapters/mysql/tools/admin/index.js +6 -6
  172. package/dist/adapters/mysql/tools/admin/index.js.map +1 -1
  173. package/dist/adapters/mysql/tools/admin/maintenance.d.ts +2 -2
  174. package/dist/adapters/mysql/tools/admin/maintenance.d.ts.map +1 -1
  175. package/dist/adapters/mysql/tools/admin/maintenance.js +93 -62
  176. package/dist/adapters/mysql/tools/admin/maintenance.js.map +1 -1
  177. package/dist/adapters/mysql/tools/admin/monitoring.d.ts +2 -2
  178. package/dist/adapters/mysql/tools/admin/monitoring.d.ts.map +1 -1
  179. package/dist/adapters/mysql/tools/admin/monitoring.js +215 -79
  180. package/dist/adapters/mysql/tools/admin/monitoring.js.map +1 -1
  181. package/dist/adapters/mysql/tools/cluster/group-replication.d.ts +2 -2
  182. package/dist/adapters/mysql/tools/cluster/group-replication.d.ts.map +1 -1
  183. package/dist/adapters/mysql/tools/cluster/group-replication.js +90 -74
  184. package/dist/adapters/mysql/tools/cluster/group-replication.js.map +1 -1
  185. package/dist/adapters/mysql/tools/cluster/index.d.ts +2 -2
  186. package/dist/adapters/mysql/tools/cluster/index.js +3 -3
  187. package/dist/adapters/mysql/tools/cluster/index.js.map +1 -1
  188. package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts +2 -2
  189. package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts.map +1 -1
  190. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js +204 -97
  191. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js.map +1 -1
  192. package/dist/adapters/mysql/tools/core.d.ts +2 -2
  193. package/dist/adapters/mysql/tools/core.d.ts.map +1 -1
  194. package/dist/adapters/mysql/tools/core.js +205 -97
  195. package/dist/adapters/mysql/tools/core.js.map +1 -1
  196. package/dist/adapters/mysql/tools/docstore.d.ts +2 -2
  197. package/dist/adapters/mysql/tools/docstore.d.ts.map +1 -1
  198. package/dist/adapters/mysql/tools/docstore.js +252 -117
  199. package/dist/adapters/mysql/tools/docstore.js.map +1 -1
  200. package/dist/adapters/mysql/tools/events.d.ts +2 -2
  201. package/dist/adapters/mysql/tools/events.d.ts.map +1 -1
  202. package/dist/adapters/mysql/tools/events.js +219 -108
  203. package/dist/adapters/mysql/tools/events.js.map +1 -1
  204. package/dist/adapters/mysql/tools/index.d.ts +19 -19
  205. package/dist/adapters/mysql/tools/index.d.ts.map +1 -1
  206. package/dist/adapters/mysql/tools/index.js +19 -19
  207. package/dist/adapters/mysql/tools/index.js.map +1 -1
  208. package/dist/adapters/mysql/tools/json/core.d.ts +2 -2
  209. package/dist/adapters/mysql/tools/json/core.d.ts.map +1 -1
  210. package/dist/adapters/mysql/tools/json/core.js +221 -127
  211. package/dist/adapters/mysql/tools/json/core.js.map +1 -1
  212. package/dist/adapters/mysql/tools/json/enhanced.d.ts +2 -2
  213. package/dist/adapters/mysql/tools/json/enhanced.d.ts.map +1 -1
  214. package/dist/adapters/mysql/tools/json/enhanced.js +274 -163
  215. package/dist/adapters/mysql/tools/json/enhanced.js.map +1 -1
  216. package/dist/adapters/mysql/tools/json/helpers.d.ts +2 -2
  217. package/dist/adapters/mysql/tools/json/helpers.d.ts.map +1 -1
  218. package/dist/adapters/mysql/tools/json/helpers.js +134 -56
  219. package/dist/adapters/mysql/tools/json/helpers.js.map +1 -1
  220. package/dist/adapters/mysql/tools/json/index.d.ts +2 -2
  221. package/dist/adapters/mysql/tools/json/index.js +6 -6
  222. package/dist/adapters/mysql/tools/json/index.js.map +1 -1
  223. package/dist/adapters/mysql/tools/partitioning.d.ts +2 -2
  224. package/dist/adapters/mysql/tools/partitioning.js +143 -59
  225. package/dist/adapters/mysql/tools/partitioning.js.map +1 -1
  226. package/dist/adapters/mysql/tools/performance/analysis.d.ts +2 -2
  227. package/dist/adapters/mysql/tools/performance/analysis.d.ts.map +1 -1
  228. package/dist/adapters/mysql/tools/performance/analysis.js +122 -86
  229. package/dist/adapters/mysql/tools/performance/analysis.js.map +1 -1
  230. package/dist/adapters/mysql/tools/performance/index.d.ts +2 -2
  231. package/dist/adapters/mysql/tools/performance/index.js +4 -4
  232. package/dist/adapters/mysql/tools/performance/index.js.map +1 -1
  233. package/dist/adapters/mysql/tools/performance/optimization.d.ts +3 -3
  234. package/dist/adapters/mysql/tools/performance/optimization.d.ts.map +1 -1
  235. package/dist/adapters/mysql/tools/performance/optimization.js +195 -73
  236. package/dist/adapters/mysql/tools/performance/optimization.js.map +1 -1
  237. package/dist/adapters/mysql/tools/proxysql.d.ts +2 -2
  238. package/dist/adapters/mysql/tools/proxysql.d.ts.map +1 -1
  239. package/dist/adapters/mysql/tools/proxysql.js +213 -125
  240. package/dist/adapters/mysql/tools/proxysql.js.map +1 -1
  241. package/dist/adapters/mysql/tools/replication.d.ts +2 -2
  242. package/dist/adapters/mysql/tools/replication.d.ts.map +1 -1
  243. package/dist/adapters/mysql/tools/replication.js +117 -66
  244. package/dist/adapters/mysql/tools/replication.js.map +1 -1
  245. package/dist/adapters/mysql/tools/roles.d.ts +2 -2
  246. package/dist/adapters/mysql/tools/roles.d.ts.map +1 -1
  247. package/dist/adapters/mysql/tools/roles.js +276 -84
  248. package/dist/adapters/mysql/tools/roles.js.map +1 -1
  249. package/dist/adapters/mysql/tools/router.d.ts +2 -2
  250. package/dist/adapters/mysql/tools/router.d.ts.map +1 -1
  251. package/dist/adapters/mysql/tools/router.js +174 -109
  252. package/dist/adapters/mysql/tools/router.js.map +1 -1
  253. package/dist/adapters/mysql/tools/schema/constraints.d.ts +2 -2
  254. package/dist/adapters/mysql/tools/schema/constraints.d.ts.map +1 -1
  255. package/dist/adapters/mysql/tools/schema/constraints.js +24 -15
  256. package/dist/adapters/mysql/tools/schema/constraints.js.map +1 -1
  257. package/dist/adapters/mysql/tools/schema/index.d.ts +2 -2
  258. package/dist/adapters/mysql/tools/schema/index.d.ts.map +1 -1
  259. package/dist/adapters/mysql/tools/schema/index.js +7 -7
  260. package/dist/adapters/mysql/tools/schema/index.js.map +1 -1
  261. package/dist/adapters/mysql/tools/schema/management.d.ts +2 -2
  262. package/dist/adapters/mysql/tools/schema/management.d.ts.map +1 -1
  263. package/dist/adapters/mysql/tools/schema/management.js +99 -42
  264. package/dist/adapters/mysql/tools/schema/management.js.map +1 -1
  265. package/dist/adapters/mysql/tools/schema/routines.d.ts +2 -2
  266. package/dist/adapters/mysql/tools/schema/routines.d.ts.map +1 -1
  267. package/dist/adapters/mysql/tools/schema/routines.js +36 -19
  268. package/dist/adapters/mysql/tools/schema/routines.js.map +1 -1
  269. package/dist/adapters/mysql/tools/schema/scheduled_events.d.ts +2 -2
  270. package/dist/adapters/mysql/tools/schema/scheduled_events.d.ts.map +1 -1
  271. package/dist/adapters/mysql/tools/schema/scheduled_events.js +26 -13
  272. package/dist/adapters/mysql/tools/schema/scheduled_events.js.map +1 -1
  273. package/dist/adapters/mysql/tools/schema/triggers.d.ts +2 -2
  274. package/dist/adapters/mysql/tools/schema/triggers.d.ts.map +1 -1
  275. package/dist/adapters/mysql/tools/schema/triggers.js +24 -13
  276. package/dist/adapters/mysql/tools/schema/triggers.js.map +1 -1
  277. package/dist/adapters/mysql/tools/schema/views.d.ts +2 -2
  278. package/dist/adapters/mysql/tools/schema/views.d.ts.map +1 -1
  279. package/dist/adapters/mysql/tools/schema/views.js +59 -28
  280. package/dist/adapters/mysql/tools/schema/views.js.map +1 -1
  281. package/dist/adapters/mysql/tools/security/audit.d.ts +2 -2
  282. package/dist/adapters/mysql/tools/security/audit.d.ts.map +1 -1
  283. package/dist/adapters/mysql/tools/security/audit.js +61 -55
  284. package/dist/adapters/mysql/tools/security/audit.js.map +1 -1
  285. package/dist/adapters/mysql/tools/security/data-protection.d.ts +2 -2
  286. package/dist/adapters/mysql/tools/security/data-protection.d.ts.map +1 -1
  287. package/dist/adapters/mysql/tools/security/data-protection.js +188 -80
  288. package/dist/adapters/mysql/tools/security/data-protection.js.map +1 -1
  289. package/dist/adapters/mysql/tools/security/encryption.d.ts +2 -2
  290. package/dist/adapters/mysql/tools/security/encryption.d.ts.map +1 -1
  291. package/dist/adapters/mysql/tools/security/encryption.js +86 -67
  292. package/dist/adapters/mysql/tools/security/encryption.js.map +1 -1
  293. package/dist/adapters/mysql/tools/security/index.d.ts +2 -2
  294. package/dist/adapters/mysql/tools/security/index.js +4 -4
  295. package/dist/adapters/mysql/tools/security/index.js.map +1 -1
  296. package/dist/adapters/mysql/tools/shell/backup.d.ts +1 -1
  297. package/dist/adapters/mysql/tools/shell/backup.d.ts.map +1 -1
  298. package/dist/adapters/mysql/tools/shell/backup.js +122 -63
  299. package/dist/adapters/mysql/tools/shell/backup.js.map +1 -1
  300. package/dist/adapters/mysql/tools/shell/common.d.ts.map +1 -1
  301. package/dist/adapters/mysql/tools/shell/common.js +34 -36
  302. package/dist/adapters/mysql/tools/shell/common.js.map +1 -1
  303. package/dist/adapters/mysql/tools/shell/data-transfer.d.ts +1 -1
  304. package/dist/adapters/mysql/tools/shell/data-transfer.d.ts.map +1 -1
  305. package/dist/adapters/mysql/tools/shell/data-transfer.js +125 -69
  306. package/dist/adapters/mysql/tools/shell/data-transfer.js.map +1 -1
  307. package/dist/adapters/mysql/tools/shell/index.d.ts +2 -2
  308. package/dist/adapters/mysql/tools/shell/index.js +6 -6
  309. package/dist/adapters/mysql/tools/shell/index.js.map +1 -1
  310. package/dist/adapters/mysql/tools/shell/info.d.ts +1 -1
  311. package/dist/adapters/mysql/tools/shell/info.d.ts.map +1 -1
  312. package/dist/adapters/mysql/tools/shell/info.js +12 -12
  313. package/dist/adapters/mysql/tools/shell/info.js.map +1 -1
  314. package/dist/adapters/mysql/tools/shell/restore.d.ts +1 -1
  315. package/dist/adapters/mysql/tools/shell/restore.d.ts.map +1 -1
  316. package/dist/adapters/mysql/tools/shell/restore.js +77 -42
  317. package/dist/adapters/mysql/tools/shell/restore.js.map +1 -1
  318. package/dist/adapters/mysql/tools/shell/utilities.d.ts +1 -1
  319. package/dist/adapters/mysql/tools/shell/utilities.d.ts.map +1 -1
  320. package/dist/adapters/mysql/tools/shell/utilities.js +42 -18
  321. package/dist/adapters/mysql/tools/shell/utilities.js.map +1 -1
  322. package/dist/adapters/mysql/tools/spatial/geometry.d.ts +2 -2
  323. package/dist/adapters/mysql/tools/spatial/geometry.d.ts.map +1 -1
  324. package/dist/adapters/mysql/tools/spatial/geometry.js +85 -46
  325. package/dist/adapters/mysql/tools/spatial/geometry.js.map +1 -1
  326. package/dist/adapters/mysql/tools/spatial/index.d.ts +2 -2
  327. package/dist/adapters/mysql/tools/spatial/index.js +5 -5
  328. package/dist/adapters/mysql/tools/spatial/index.js.map +1 -1
  329. package/dist/adapters/mysql/tools/spatial/operations.d.ts +2 -2
  330. package/dist/adapters/mysql/tools/spatial/operations.d.ts.map +1 -1
  331. package/dist/adapters/mysql/tools/spatial/operations.js +167 -106
  332. package/dist/adapters/mysql/tools/spatial/operations.js.map +1 -1
  333. package/dist/adapters/mysql/tools/spatial/queries.d.ts +2 -2
  334. package/dist/adapters/mysql/tools/spatial/queries.d.ts.map +1 -1
  335. package/dist/adapters/mysql/tools/spatial/queries.js +144 -100
  336. package/dist/adapters/mysql/tools/spatial/queries.js.map +1 -1
  337. package/dist/adapters/mysql/tools/spatial/setup.d.ts +2 -2
  338. package/dist/adapters/mysql/tools/spatial/setup.d.ts.map +1 -1
  339. package/dist/adapters/mysql/tools/spatial/setup.js +104 -34
  340. package/dist/adapters/mysql/tools/spatial/setup.js.map +1 -1
  341. package/dist/adapters/mysql/tools/stats/comparative.d.ts +2 -2
  342. package/dist/adapters/mysql/tools/stats/comparative.d.ts.map +1 -1
  343. package/dist/adapters/mysql/tools/stats/comparative.js +159 -107
  344. package/dist/adapters/mysql/tools/stats/comparative.js.map +1 -1
  345. package/dist/adapters/mysql/tools/stats/descriptive.d.ts +2 -2
  346. package/dist/adapters/mysql/tools/stats/descriptive.d.ts.map +1 -1
  347. package/dist/adapters/mysql/tools/stats/descriptive.js +268 -205
  348. package/dist/adapters/mysql/tools/stats/descriptive.js.map +1 -1
  349. package/dist/adapters/mysql/tools/stats/index.d.ts +2 -2
  350. package/dist/adapters/mysql/tools/stats/index.js +3 -3
  351. package/dist/adapters/mysql/tools/stats/index.js.map +1 -1
  352. package/dist/adapters/mysql/tools/sysschema/activity.d.ts +2 -2
  353. package/dist/adapters/mysql/tools/sysschema/activity.d.ts.map +1 -1
  354. package/dist/adapters/mysql/tools/sysschema/activity.js +23 -23
  355. package/dist/adapters/mysql/tools/sysschema/activity.js.map +1 -1
  356. package/dist/adapters/mysql/tools/sysschema/index.d.ts +2 -2
  357. package/dist/adapters/mysql/tools/sysschema/index.js +4 -4
  358. package/dist/adapters/mysql/tools/sysschema/index.js.map +1 -1
  359. package/dist/adapters/mysql/tools/sysschema/performance.d.ts +2 -2
  360. package/dist/adapters/mysql/tools/sysschema/performance.d.ts.map +1 -1
  361. package/dist/adapters/mysql/tools/sysschema/performance.js +58 -43
  362. package/dist/adapters/mysql/tools/sysschema/performance.js.map +1 -1
  363. package/dist/adapters/mysql/tools/sysschema/resources.d.ts +2 -2
  364. package/dist/adapters/mysql/tools/sysschema/resources.d.ts.map +1 -1
  365. package/dist/adapters/mysql/tools/sysschema/resources.js +53 -33
  366. package/dist/adapters/mysql/tools/sysschema/resources.js.map +1 -1
  367. package/dist/adapters/mysql/tools/text/fulltext.d.ts +4 -3
  368. package/dist/adapters/mysql/tools/text/fulltext.d.ts.map +1 -1
  369. package/dist/adapters/mysql/tools/text/fulltext.js +211 -54
  370. package/dist/adapters/mysql/tools/text/fulltext.js.map +1 -1
  371. package/dist/adapters/mysql/tools/text/index.d.ts +3 -3
  372. package/dist/adapters/mysql/tools/text/index.d.ts.map +1 -1
  373. package/dist/adapters/mysql/tools/text/index.js +6 -5
  374. package/dist/adapters/mysql/tools/text/index.js.map +1 -1
  375. package/dist/adapters/mysql/tools/text/processing.d.ts +2 -2
  376. package/dist/adapters/mysql/tools/text/processing.d.ts.map +1 -1
  377. package/dist/adapters/mysql/tools/text/processing.js +191 -103
  378. package/dist/adapters/mysql/tools/text/processing.js.map +1 -1
  379. package/dist/adapters/mysql/tools/transactions.d.ts +2 -2
  380. package/dist/adapters/mysql/tools/transactions.js +156 -79
  381. package/dist/adapters/mysql/tools/transactions.js.map +1 -1
  382. package/dist/adapters/mysql/types/proxysql-types.d.ts +7 -2
  383. package/dist/adapters/mysql/types/proxysql-types.d.ts.map +1 -1
  384. package/dist/adapters/mysql/types/proxysql-types.js +52 -30
  385. package/dist/adapters/mysql/types/proxysql-types.js.map +1 -1
  386. package/dist/adapters/mysql/types/router-types.d.ts +1 -1
  387. package/dist/adapters/mysql/types/router-types.js +17 -17
  388. package/dist/adapters/mysql/types/router-types.js.map +1 -1
  389. package/dist/adapters/mysql/types/shell-types.d.ts +1 -2
  390. package/dist/adapters/mysql/types/shell-types.d.ts.map +1 -1
  391. package/dist/adapters/mysql/types/shell-types.js +255 -82
  392. package/dist/adapters/mysql/types/shell-types.js.map +1 -1
  393. package/dist/adapters/mysql/types.d.ts +8 -2
  394. package/dist/adapters/mysql/types.d.ts.map +1 -1
  395. package/dist/adapters/mysql/types.js +269 -128
  396. package/dist/adapters/mysql/types.js.map +1 -1
  397. package/dist/auth/AuthorizationServerDiscovery.d.ts +1 -1
  398. package/dist/auth/AuthorizationServerDiscovery.d.ts.map +1 -1
  399. package/dist/auth/AuthorizationServerDiscovery.js +16 -14
  400. package/dist/auth/AuthorizationServerDiscovery.js.map +1 -1
  401. package/dist/auth/OAuthResourceServer.d.ts +1 -1
  402. package/dist/auth/OAuthResourceServer.d.ts.map +1 -1
  403. package/dist/auth/OAuthResourceServer.js +4 -4
  404. package/dist/auth/OAuthResourceServer.js.map +1 -1
  405. package/dist/auth/TokenValidator.d.ts +1 -1
  406. package/dist/auth/TokenValidator.d.ts.map +1 -1
  407. package/dist/auth/TokenValidator.js +30 -20
  408. package/dist/auth/TokenValidator.js.map +1 -1
  409. package/dist/auth/errors.d.ts.map +1 -1
  410. package/dist/auth/errors.js +24 -24
  411. package/dist/auth/errors.js.map +1 -1
  412. package/dist/auth/index.d.ts +7 -7
  413. package/dist/auth/index.d.ts.map +1 -1
  414. package/dist/auth/index.js +6 -6
  415. package/dist/auth/index.js.map +1 -1
  416. package/dist/auth/middleware.d.ts +2 -2
  417. package/dist/auth/middleware.d.ts.map +1 -1
  418. package/dist/auth/middleware.js +28 -24
  419. package/dist/auth/middleware.js.map +1 -1
  420. package/dist/auth/scopes.d.ts +2 -2
  421. package/dist/auth/scopes.d.ts.map +1 -1
  422. package/dist/auth/scopes.js +22 -16
  423. package/dist/auth/scopes.js.map +1 -1
  424. package/dist/auth/types.d.ts +2 -2
  425. package/dist/auth/types.d.ts.map +1 -1
  426. package/dist/cli/args.d.ts +1 -1
  427. package/dist/cli/args.d.ts.map +1 -1
  428. package/dist/cli/args.js +70 -68
  429. package/dist/cli/args.js.map +1 -1
  430. package/dist/cli.d.ts +1 -1
  431. package/dist/cli.d.ts.map +1 -1
  432. package/dist/cli.js +44 -34
  433. package/dist/cli.js.map +1 -1
  434. package/dist/constants/ServerInstructions.d.ts +2 -2
  435. package/dist/constants/ServerInstructions.d.ts.map +1 -1
  436. package/dist/constants/ServerInstructions.js +228 -36
  437. package/dist/constants/ServerInstructions.js.map +1 -1
  438. package/dist/filtering/ToolConstants.d.ts +6 -6
  439. package/dist/filtering/ToolConstants.d.ts.map +1 -1
  440. package/dist/filtering/ToolConstants.js +229 -208
  441. package/dist/filtering/ToolConstants.js.map +1 -1
  442. package/dist/filtering/ToolFilter.d.ts +2 -2
  443. package/dist/filtering/ToolFilter.d.ts.map +1 -1
  444. package/dist/filtering/ToolFilter.js +35 -36
  445. package/dist/filtering/ToolFilter.js.map +1 -1
  446. package/dist/index.d.ts +9 -9
  447. package/dist/index.d.ts.map +1 -1
  448. package/dist/index.js +7 -7
  449. package/dist/index.js.map +1 -1
  450. package/dist/logging/McpLogging.d.ts +2 -2
  451. package/dist/logging/McpLogging.d.ts.map +1 -1
  452. package/dist/logging/McpLogging.js +16 -13
  453. package/dist/logging/McpLogging.js.map +1 -1
  454. package/dist/logging/index.d.ts +1 -1
  455. package/dist/logging/index.js +1 -1
  456. package/dist/pool/ConnectionPool.d.ts +3 -3
  457. package/dist/pool/ConnectionPool.d.ts.map +1 -1
  458. package/dist/pool/ConnectionPool.js +30 -26
  459. package/dist/pool/ConnectionPool.js.map +1 -1
  460. package/dist/progress/ProgressReporter.d.ts +1 -1
  461. package/dist/progress/ProgressReporter.d.ts.map +1 -1
  462. package/dist/progress/ProgressReporter.js +5 -5
  463. package/dist/progress/ProgressReporter.js.map +1 -1
  464. package/dist/progress/index.d.ts +1 -1
  465. package/dist/progress/index.d.ts.map +1 -1
  466. package/dist/progress/index.js +1 -1
  467. package/dist/progress/index.js.map +1 -1
  468. package/dist/server/McpServer.d.ts +3 -3
  469. package/dist/server/McpServer.d.ts.map +1 -1
  470. package/dist/server/McpServer.js +58 -53
  471. package/dist/server/McpServer.js.map +1 -1
  472. package/dist/transports/http.d.ts +3 -3
  473. package/dist/transports/http.d.ts.map +1 -1
  474. package/dist/transports/http.js +36 -33
  475. package/dist/transports/http.js.map +1 -1
  476. package/dist/transports/index.d.ts +1 -1
  477. package/dist/transports/index.d.ts.map +1 -1
  478. package/dist/transports/index.js +1 -1
  479. package/dist/transports/index.js.map +1 -1
  480. package/dist/types/index.d.ts +6 -6
  481. package/dist/types/index.d.ts.map +1 -1
  482. package/dist/types/index.js +1 -1
  483. package/dist/types/index.js.map +1 -1
  484. package/dist/types/modules/database.d.ts +1 -1
  485. package/dist/types/modules/database.d.ts.map +1 -1
  486. package/dist/types/modules/errors.d.ts.map +1 -1
  487. package/dist/types/modules/errors.js +15 -15
  488. package/dist/types/modules/errors.js.map +1 -1
  489. package/dist/types/modules/oauth.d.ts +1 -1
  490. package/dist/types/modules/oauth.d.ts.map +1 -1
  491. package/dist/types/modules/query.d.ts +8 -8
  492. package/dist/types/modules/query.d.ts.map +1 -1
  493. package/dist/types/modules/server.d.ts +3 -3
  494. package/dist/types/modules/server.d.ts.map +1 -1
  495. package/dist/types/modules/tools.d.ts +6 -6
  496. package/dist/types/modules/tools.d.ts.map +1 -1
  497. package/dist/utils/logger.d.ts +2 -2
  498. package/dist/utils/logger.d.ts.map +1 -1
  499. package/dist/utils/logger.js +58 -55
  500. package/dist/utils/logger.js.map +1 -1
  501. package/dist/utils/promptGenerator.d.ts +1 -1
  502. package/dist/utils/promptGenerator.d.ts.map +1 -1
  503. package/dist/utils/promptGenerator.js +24 -16
  504. package/dist/utils/promptGenerator.js.map +1 -1
  505. package/dist/utils/validators.d.ts +21 -2
  506. package/dist/utils/validators.d.ts.map +1 -1
  507. package/dist/utils/validators.js +101 -13
  508. package/dist/utils/validators.js.map +1 -1
  509. package/eslint.config.js +117 -81
  510. package/package.json +61 -64
  511. package/releases/release-notes.md +32 -26
  512. package/releases/v2.0.0-release-notes.md +99 -51
  513. package/releases/v2.1.0-release-notes.md +14 -5
  514. package/releases/v2.2.0-release-notes.md +239 -0
  515. package/server.json +1 -1
  516. package/src/__tests__/cli.test.ts +302 -247
  517. package/src/__tests__/index.test.ts +21 -21
  518. package/src/__tests__/mocks/adapter.ts +204 -163
  519. package/src/__tests__/mocks/index.ts +30 -23
  520. package/src/__tests__/mocks/mysql.ts +94 -84
  521. package/src/__tests__/perf.test.ts +207 -203
  522. package/src/__tests__/performance.test.ts +173 -164
  523. package/src/__tests__/setup.ts +26 -21
  524. package/src/adapters/DatabaseAdapter.ts +386 -340
  525. package/src/adapters/__tests__/DatabaseAdapter.test.ts +455 -377
  526. package/src/adapters/mysql/MySQLAdapter.ts +550 -486
  527. package/src/adapters/mysql/SchemaManager.ts +251 -208
  528. package/src/adapters/mysql/__tests__/MySQLAdapter.integration.test.ts +150 -147
  529. package/src/adapters/mysql/__tests__/MySQLAdapter.test.ts +590 -477
  530. package/src/adapters/mysql/__tests__/SchemaManager.test.ts +196 -154
  531. package/src/adapters/mysql/index.ts +2 -2
  532. package/src/adapters/mysql/prompts/__tests__/indexTuning.test.ts +33 -26
  533. package/src/adapters/mysql/prompts/__tests__/prompts.test.ts +277 -239
  534. package/src/adapters/mysql/prompts/backupStrategy.ts +29 -17
  535. package/src/adapters/mysql/prompts/clusterSetup.ts +11 -10
  536. package/src/adapters/mysql/prompts/docstoreSetup.ts +10 -10
  537. package/src/adapters/mysql/prompts/eventScheduler.ts +10 -10
  538. package/src/adapters/mysql/prompts/healthCheck.ts +20 -15
  539. package/src/adapters/mysql/prompts/index.ts +194 -144
  540. package/src/adapters/mysql/prompts/indexTuning.ts +22 -17
  541. package/src/adapters/mysql/prompts/mysqlshSetup.ts +11 -11
  542. package/src/adapters/mysql/prompts/proxysqlSetup.ts +10 -10
  543. package/src/adapters/mysql/prompts/replicationSetup.ts +24 -16
  544. package/src/adapters/mysql/prompts/routerSetup.ts +10 -10
  545. package/src/adapters/mysql/prompts/spatialSetup.ts +10 -10
  546. package/src/adapters/mysql/prompts/sysSchema.ts +11 -10
  547. package/src/adapters/mysql/resources/__tests__/capabilities.test.ts +69 -47
  548. package/src/adapters/mysql/resources/__tests__/cluster.test.ts +163 -104
  549. package/src/adapters/mysql/resources/__tests__/docstore.test.ts +88 -81
  550. package/src/adapters/mysql/resources/__tests__/events.test.ts +94 -83
  551. package/src/adapters/mysql/resources/__tests__/health.test.ts +131 -91
  552. package/src/adapters/mysql/resources/__tests__/indexes.test.ts +125 -102
  553. package/src/adapters/mysql/resources/__tests__/innodb.test.ts +86 -62
  554. package/src/adapters/mysql/resources/__tests__/locks.test.ts +142 -104
  555. package/src/adapters/mysql/resources/__tests__/performance.test.ts +81 -58
  556. package/src/adapters/mysql/resources/__tests__/pool.test.ts +45 -40
  557. package/src/adapters/mysql/resources/__tests__/processlist.test.ts +39 -23
  558. package/src/adapters/mysql/resources/__tests__/replication.test.ts +265 -211
  559. package/src/adapters/mysql/resources/__tests__/resources.test.ts +121 -109
  560. package/src/adapters/mysql/resources/__tests__/schema.test.ts +29 -23
  561. package/src/adapters/mysql/resources/__tests__/spatial.test.ts +58 -45
  562. package/src/adapters/mysql/resources/__tests__/status.test.ts +62 -45
  563. package/src/adapters/mysql/resources/__tests__/sysschema.test.ts +99 -60
  564. package/src/adapters/mysql/resources/__tests__/tables.test.ts +41 -32
  565. package/src/adapters/mysql/resources/__tests__/variables.test.ts +77 -49
  566. package/src/adapters/mysql/resources/capabilities.ts +59 -42
  567. package/src/adapters/mysql/resources/cluster.ts +58 -49
  568. package/src/adapters/mysql/resources/docstore.ts +46 -41
  569. package/src/adapters/mysql/resources/events.ts +37 -31
  570. package/src/adapters/mysql/resources/health.ts +98 -74
  571. package/src/adapters/mysql/resources/index.ts +46 -46
  572. package/src/adapters/mysql/resources/indexes.ts +66 -51
  573. package/src/adapters/mysql/resources/innodb.ts +98 -81
  574. package/src/adapters/mysql/resources/locks.ts +43 -40
  575. package/src/adapters/mysql/resources/performance.ts +80 -67
  576. package/src/adapters/mysql/resources/pool.ts +23 -20
  577. package/src/adapters/mysql/resources/processlist.ts +23 -18
  578. package/src/adapters/mysql/resources/replication.ts +124 -105
  579. package/src/adapters/mysql/resources/schema.ts +23 -18
  580. package/src/adapters/mysql/resources/spatial.ts +31 -26
  581. package/src/adapters/mysql/resources/status.ts +27 -22
  582. package/src/adapters/mysql/resources/sysschema.ts +41 -36
  583. package/src/adapters/mysql/resources/tables.ts +23 -18
  584. package/src/adapters/mysql/resources/variables.ts +27 -22
  585. package/src/adapters/mysql/tools/__tests__/cluster.test.ts +419 -311
  586. package/src/adapters/mysql/tools/__tests__/core.test.ts +633 -382
  587. package/src/adapters/mysql/tools/__tests__/docstore.test.ts +782 -413
  588. package/src/adapters/mysql/tools/__tests__/events.test.ts +752 -486
  589. package/src/adapters/mysql/tools/__tests__/json_core.test.ts +326 -259
  590. package/src/adapters/mysql/tools/__tests__/json_enhanced.test.ts +452 -352
  591. package/src/adapters/mysql/tools/__tests__/json_helpers.test.ts +169 -136
  592. package/src/adapters/mysql/tools/__tests__/proxysql.test.ts +576 -340
  593. package/src/adapters/mysql/tools/__tests__/replication.test.ts +697 -393
  594. package/src/adapters/mysql/tools/__tests__/roles.test.ts +423 -166
  595. package/src/adapters/mysql/tools/__tests__/router.test.ts +644 -540
  596. package/src/adapters/mysql/tools/__tests__/security.test.ts +708 -422
  597. package/src/adapters/mysql/tools/__tests__/security_injection.test.ts +246 -173
  598. package/src/adapters/mysql/tools/__tests__/security_integration.test.ts +244 -205
  599. package/src/adapters/mysql/tools/__tests__/spatial.test.ts +413 -300
  600. package/src/adapters/mysql/tools/__tests__/spatial_handler.test.ts +503 -150
  601. package/src/adapters/mysql/tools/__tests__/stats.test.ts +861 -553
  602. package/src/adapters/mysql/tools/__tests__/transactions.test.ts +454 -263
  603. package/src/adapters/mysql/tools/admin/__tests__/backup.test.ts +612 -372
  604. package/src/adapters/mysql/tools/admin/__tests__/maintenance.test.ts +550 -257
  605. package/src/adapters/mysql/tools/admin/__tests__/monitoring.test.ts +549 -352
  606. package/src/adapters/mysql/tools/admin/backup.ts +334 -215
  607. package/src/adapters/mysql/tools/admin/index.ts +46 -46
  608. package/src/adapters/mysql/tools/admin/maintenance.ts +176 -130
  609. package/src/adapters/mysql/tools/admin/monitoring.ts +373 -199
  610. package/src/adapters/mysql/tools/cluster/__tests__/group-replication.test.ts +200 -186
  611. package/src/adapters/mysql/tools/cluster/__tests__/innodb-cluster.test.ts +364 -95
  612. package/src/adapters/mysql/tools/cluster/group-replication.ts +218 -183
  613. package/src/adapters/mysql/tools/cluster/index.ts +27 -27
  614. package/src/adapters/mysql/tools/cluster/innodb-cluster.ts +392 -251
  615. package/src/adapters/mysql/tools/core.ts +408 -285
  616. package/src/adapters/mysql/tools/docstore.ts +478 -276
  617. package/src/adapters/mysql/tools/events.ts +425 -285
  618. package/src/adapters/mysql/tools/index.ts +31 -20
  619. package/src/adapters/mysql/tools/json/__tests__/core.test.ts +456 -199
  620. package/src/adapters/mysql/tools/json/__tests__/enhanced.test.ts +554 -298
  621. package/src/adapters/mysql/tools/json/__tests__/helpers.test.ts +150 -74
  622. package/src/adapters/mysql/tools/json/__tests__/validation.test.ts +106 -72
  623. package/src/adapters/mysql/tools/json/core.ts +364 -263
  624. package/src/adapters/mysql/tools/json/enhanced.ts +368 -229
  625. package/src/adapters/mysql/tools/json/helpers.ts +195 -113
  626. package/src/adapters/mysql/tools/json/index.ts +46 -46
  627. package/src/adapters/mysql/tools/partitioning.ts +242 -140
  628. package/src/adapters/mysql/tools/performance/__tests__/analysis.test.ts +439 -247
  629. package/src/adapters/mysql/tools/performance/__tests__/optimization.test.ts +401 -179
  630. package/src/adapters/mysql/tools/performance/analysis.ts +263 -213
  631. package/src/adapters/mysql/tools/performance/index.ts +33 -33
  632. package/src/adapters/mysql/tools/performance/optimization.ts +407 -190
  633. package/src/adapters/mysql/tools/proxysql.ts +462 -320
  634. package/src/adapters/mysql/tools/replication.ts +233 -180
  635. package/src/adapters/mysql/tools/roles.ts +429 -171
  636. package/src/adapters/mysql/tools/router.ts +410 -292
  637. package/src/adapters/mysql/tools/schema/__tests__/constraints.test.ts +157 -82
  638. package/src/adapters/mysql/tools/schema/__tests__/management.test.ts +226 -101
  639. package/src/adapters/mysql/tools/schema/__tests__/routines.test.ts +80 -35
  640. package/src/adapters/mysql/tools/schema/__tests__/scheduled_events.test.ts +59 -40
  641. package/src/adapters/mysql/tools/schema/__tests__/triggers.test.ts +65 -40
  642. package/src/adapters/mysql/tools/schema/__tests__/views.test.ts +146 -77
  643. package/src/adapters/mysql/tools/schema/constraints.ts +61 -42
  644. package/src/adapters/mysql/tools/schema/index.ts +26 -35
  645. package/src/adapters/mysql/tools/schema/management.ts +167 -94
  646. package/src/adapters/mysql/tools/schema/routines.ts +79 -48
  647. package/src/adapters/mysql/tools/schema/scheduled_events.ts +53 -32
  648. package/src/adapters/mysql/tools/schema/triggers.ts +51 -33
  649. package/src/adapters/mysql/tools/schema/views.ts +96 -53
  650. package/src/adapters/mysql/tools/security/__tests__/audit.test.ts +216 -158
  651. package/src/adapters/mysql/tools/security/__tests__/data-protection.test.ts +154 -98
  652. package/src/adapters/mysql/tools/security/__tests__/encryption.test.ts +174 -138
  653. package/src/adapters/mysql/tools/security/audit.ts +213 -193
  654. package/src/adapters/mysql/tools/security/data-protection.ts +336 -198
  655. package/src/adapters/mysql/tools/security/encryption.ts +233 -193
  656. package/src/adapters/mysql/tools/security/index.ts +26 -26
  657. package/src/adapters/mysql/tools/shell/__tests__/backup.test.ts +443 -283
  658. package/src/adapters/mysql/tools/shell/__tests__/common.test.ts +138 -131
  659. package/src/adapters/mysql/tools/shell/__tests__/data-transfer.test.ts +516 -353
  660. package/src/adapters/mysql/tools/shell/__tests__/info.test.ts +65 -63
  661. package/src/adapters/mysql/tools/shell/__tests__/restore.test.ts +233 -174
  662. package/src/adapters/mysql/tools/shell/__tests__/utilities.test.ts +161 -143
  663. package/src/adapters/mysql/tools/shell/backup.ts +280 -188
  664. package/src/adapters/mysql/tools/shell/common.ts +173 -155
  665. package/src/adapters/mysql/tools/shell/data-transfer.ts +286 -200
  666. package/src/adapters/mysql/tools/shell/index.ts +29 -29
  667. package/src/adapters/mysql/tools/shell/info.ts +35 -31
  668. package/src/adapters/mysql/tools/shell/restore.ts +176 -124
  669. package/src/adapters/mysql/tools/shell/utilities.ts +86 -45
  670. package/src/adapters/mysql/tools/spatial/__tests__/geometry.test.ts +129 -89
  671. package/src/adapters/mysql/tools/spatial/__tests__/operations.test.ts +255 -148
  672. package/src/adapters/mysql/tools/spatial/__tests__/queries.test.ts +340 -245
  673. package/src/adapters/mysql/tools/spatial/geometry.ts +120 -74
  674. package/src/adapters/mysql/tools/spatial/index.ts +33 -33
  675. package/src/adapters/mysql/tools/spatial/operations.ts +243 -171
  676. package/src/adapters/mysql/tools/spatial/queries.ts +221 -165
  677. package/src/adapters/mysql/tools/spatial/setup.ts +157 -73
  678. package/src/adapters/mysql/tools/stats/__tests__/comparative.test.ts +188 -130
  679. package/src/adapters/mysql/tools/stats/comparative.ts +261 -187
  680. package/src/adapters/mysql/tools/stats/descriptive.ts +414 -322
  681. package/src/adapters/mysql/tools/stats/index.ts +23 -23
  682. package/src/adapters/mysql/tools/sysschema/__tests__/activity.test.ts +99 -71
  683. package/src/adapters/mysql/tools/sysschema/__tests__/io_summary_fix.test.ts +21 -18
  684. package/src/adapters/mysql/tools/sysschema/__tests__/performance.test.ts +149 -108
  685. package/src/adapters/mysql/tools/sysschema/__tests__/resources.test.ts +222 -104
  686. package/src/adapters/mysql/tools/sysschema/activity.ts +72 -64
  687. package/src/adapters/mysql/tools/sysschema/index.ts +24 -24
  688. package/src/adapters/mysql/tools/sysschema/performance.ts +140 -115
  689. package/src/adapters/mysql/tools/sysschema/resources.ts +135 -99
  690. package/src/adapters/mysql/tools/text/__tests__/fulltext.test.ts +526 -145
  691. package/src/adapters/mysql/tools/text/__tests__/processing.test.ts +452 -193
  692. package/src/adapters/mysql/tools/text/fulltext.ts +319 -123
  693. package/src/adapters/mysql/tools/text/index.ts +32 -30
  694. package/src/adapters/mysql/tools/text/processing.ts +310 -212
  695. package/src/adapters/mysql/tools/transactions.ts +284 -197
  696. package/src/adapters/mysql/types/__tests__/shell-types.test.ts +204 -202
  697. package/src/adapters/mysql/types/proxysql-types.ts +142 -109
  698. package/src/adapters/mysql/types/router-types.ts +36 -36
  699. package/src/adapters/mysql/types/shell-types.ts +280 -94
  700. package/src/adapters/mysql/types.ts +288 -131
  701. package/src/auth/AuthorizationServerDiscovery.ts +127 -113
  702. package/src/auth/OAuthResourceServer.ts +67 -62
  703. package/src/auth/TokenValidator.ts +136 -119
  704. package/src/auth/__tests__/AuthorizationServerDiscovery.test.ts +295 -274
  705. package/src/auth/__tests__/OAuthResourceServer.test.ts +180 -169
  706. package/src/auth/__tests__/TokenValidator.test.ts +297 -285
  707. package/src/auth/__tests__/errors.test.ts +180 -175
  708. package/src/auth/__tests__/middleware.test.ts +281 -247
  709. package/src/auth/__tests__/scopes.test.ts +136 -134
  710. package/src/auth/errors.ts +56 -56
  711. package/src/auth/index.ts +23 -17
  712. package/src/auth/middleware.ts +161 -139
  713. package/src/auth/scopes.ts +133 -107
  714. package/src/auth/types.ts +155 -155
  715. package/src/cli/__tests__/args.test.ts +241 -216
  716. package/src/cli/__tests__/main.test.ts +191 -158
  717. package/src/cli/args.ts +271 -258
  718. package/src/cli.ts +150 -127
  719. package/src/constants/ServerInstructions.ts +271 -70
  720. package/src/filtering/ToolConstants.ts +287 -266
  721. package/src/filtering/ToolFilter.ts +239 -220
  722. package/src/filtering/__tests__/ToolFilter.test.ts +442 -396
  723. package/src/index.ts +62 -57
  724. package/src/logging/McpLogging.ts +128 -119
  725. package/src/logging/__tests__/McpLogging.test.ts +223 -223
  726. package/src/logging/index.ts +2 -2
  727. package/src/pool/ConnectionPool.ts +260 -246
  728. package/src/pool/__tests__/ConnectionPool.test.ts +452 -418
  729. package/src/progress/ProgressReporter.ts +123 -123
  730. package/src/progress/__tests__/ProgressReporter.test.ts +235 -229
  731. package/src/progress/index.ts +6 -2
  732. package/src/server/McpServer.ts +305 -285
  733. package/src/server/__tests__/McpServer.test.ts +333 -291
  734. package/src/transports/__tests__/http.test.ts +658 -527
  735. package/src/transports/http.ts +237 -203
  736. package/src/transports/index.ts +6 -2
  737. package/src/types/__tests__/types.test.ts +197 -193
  738. package/src/types/index.ts +49 -37
  739. package/src/types/modules/database.ts +65 -63
  740. package/src/types/modules/errors.ts +41 -37
  741. package/src/types/modules/oauth.ts +46 -46
  742. package/src/types/modules/query.ts +75 -75
  743. package/src/types/modules/server.ts +18 -18
  744. package/src/types/modules/tools.ts +181 -178
  745. package/src/utils/__tests__/logger.test.ts +424 -414
  746. package/src/utils/__tests__/validators.test.ts +250 -165
  747. package/src/utils/logger.ts +343 -330
  748. package/src/utils/promptGenerator.ts +58 -47
  749. package/src/utils/validators.ts +217 -91
  750. package/tsconfig.json +41 -50
  751. package/vitest.config.ts +23 -23
@@ -1,478 +1,782 @@
1
1
  /**
2
2
  * mysql-mcp - Replication Tools Unit Tests
3
- *
3
+ *
4
4
  * Tests for replication and partitioning tool definitions and handler execution.
5
5
  */
6
6
 
7
- import { describe, it, expect, vi, beforeEach } from 'vitest';
8
- import { getReplicationTools } from '../replication.js';
9
- import { getPartitioningTools } from '../partitioning.js';
10
- import type { MySQLAdapter } from '../../MySQLAdapter.js';
11
- import { createMockMySQLAdapter, createMockRequestContext, createMockQueryResult } from '../../../../__tests__/mocks/index.js';
7
+ import { describe, it, expect, vi, beforeEach } from "vitest";
8
+ import { getReplicationTools } from "../replication.js";
9
+ import { getPartitioningTools } from "../partitioning.js";
10
+ import type { MySQLAdapter } from "../../MySQLAdapter.js";
11
+ import {
12
+ createMockMySQLAdapter,
13
+ createMockRequestContext,
14
+ createMockQueryResult,
15
+ } from "../../../../__tests__/mocks/index.js";
16
+
17
+ describe("getReplicationTools", () => {
18
+ let tools: ReturnType<typeof getReplicationTools>;
19
+
20
+ beforeEach(() => {
21
+ vi.clearAllMocks();
22
+ tools = getReplicationTools(
23
+ createMockMySQLAdapter() as unknown as MySQLAdapter,
24
+ );
25
+ });
26
+
27
+ it("should return 5 replication tools", () => {
28
+ expect(tools).toHaveLength(5);
29
+ });
30
+
31
+ it("should have replication group for all tools", () => {
32
+ for (const tool of tools) {
33
+ expect(tool.group).toBe("replication");
34
+ }
35
+ });
36
+
37
+ it("should have handler functions for all tools", () => {
38
+ for (const tool of tools) {
39
+ expect(typeof tool.handler).toBe("function");
40
+ }
41
+ });
42
+
43
+ it("should have inputSchema for all tools", () => {
44
+ for (const tool of tools) {
45
+ expect(tool.inputSchema).toBeDefined();
46
+ }
47
+ });
48
+
49
+ it("should include expected tool names", () => {
50
+ const names = tools.map((t) => t.name);
51
+ expect(names).toContain("mysql_master_status");
52
+ expect(names).toContain("mysql_slave_status");
53
+ expect(names).toContain("mysql_binlog_events");
54
+ expect(names).toContain("mysql_gtid_status");
55
+ expect(names).toContain("mysql_replication_lag");
56
+ });
57
+ });
12
58
 
13
- describe('getReplicationTools', () => {
14
- let tools: ReturnType<typeof getReplicationTools>;
59
+ describe("getPartitioningTools", () => {
60
+ let tools: ReturnType<typeof getPartitioningTools>;
61
+
62
+ beforeEach(() => {
63
+ vi.clearAllMocks();
64
+ tools = getPartitioningTools(
65
+ createMockMySQLAdapter() as unknown as MySQLAdapter,
66
+ );
67
+ });
68
+
69
+ it("should return 4 partitioning tools", () => {
70
+ expect(tools).toHaveLength(4);
71
+ });
72
+
73
+ it("should have partitioning group for all tools", () => {
74
+ for (const tool of tools) {
75
+ expect(tool.group).toBe("partitioning");
76
+ }
77
+ });
78
+
79
+ it("should have handler functions for all tools", () => {
80
+ for (const tool of tools) {
81
+ expect(typeof tool.handler).toBe("function");
82
+ }
83
+ });
84
+
85
+ it("should have inputSchema for all tools", () => {
86
+ for (const tool of tools) {
87
+ expect(tool.inputSchema).toBeDefined();
88
+ }
89
+ });
90
+
91
+ it("should include expected tool names", () => {
92
+ const names = tools.map((t) => t.name);
93
+ expect(names).toContain("mysql_partition_info");
94
+ expect(names).toContain("mysql_add_partition");
95
+ expect(names).toContain("mysql_drop_partition");
96
+ expect(names).toContain("mysql_reorganize_partition");
97
+ });
98
+ });
15
99
 
16
- beforeEach(() => {
17
- vi.clearAllMocks();
18
- tools = getReplicationTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
100
+ describe("Replication Handler Execution", () => {
101
+ let mockAdapter: ReturnType<typeof createMockMySQLAdapter>;
102
+ let tools: ReturnType<typeof getReplicationTools>;
103
+ let mockContext: ReturnType<typeof createMockRequestContext>;
104
+
105
+ beforeEach(() => {
106
+ vi.clearAllMocks();
107
+ mockAdapter = createMockMySQLAdapter();
108
+ tools = getReplicationTools(mockAdapter as unknown as MySQLAdapter);
109
+ mockContext = createMockRequestContext();
110
+ });
111
+
112
+ describe("mysql_master_status", () => {
113
+ it("should query master status", async () => {
114
+ mockAdapter.executeQuery.mockResolvedValue(
115
+ createMockQueryResult([{ File: "mysql-bin.000001", Position: 12345 }]),
116
+ );
117
+
118
+ const tool = tools.find((t) => t.name === "mysql_master_status")!;
119
+ const result = await tool.handler({}, mockContext);
120
+
121
+ expect(mockAdapter.executeQuery).toHaveBeenCalled();
122
+ expect(result).toBeDefined();
19
123
  });
124
+ });
20
125
 
21
- it('should return 5 replication tools', () => {
22
- expect(tools).toHaveLength(5);
23
- });
126
+ describe("mysql_slave_status", () => {
127
+ it("should query replica status", async () => {
128
+ mockAdapter.executeQuery.mockResolvedValue(
129
+ createMockQueryResult([
130
+ { Replica_IO_Running: "Yes", Replica_SQL_Running: "Yes" },
131
+ ]),
132
+ );
24
133
 
25
- it('should have replication group for all tools', () => {
26
- for (const tool of tools) {
27
- expect(tool.group).toBe('replication');
28
- }
29
- });
134
+ const tool = tools.find((t) => t.name === "mysql_slave_status")!;
135
+ const result = await tool.handler({}, mockContext);
30
136
 
31
- it('should have handler functions for all tools', () => {
32
- for (const tool of tools) {
33
- expect(typeof tool.handler).toBe('function');
34
- }
137
+ expect(mockAdapter.executeQuery).toHaveBeenCalled();
138
+ expect(result).toBeDefined();
35
139
  });
36
-
37
- it('should have inputSchema for all tools', () => {
38
- for (const tool of tools) {
39
- expect(tool.inputSchema).toBeDefined();
40
- }
140
+ });
141
+
142
+ describe("mysql_binlog_events", () => {
143
+ it("should query binlog events with explicit logFile", async () => {
144
+ mockAdapter.executeQuery.mockResolvedValue(
145
+ createMockQueryResult([
146
+ { Log_name: "mysql-bin.000001", Event_type: "Query" },
147
+ ]),
148
+ );
149
+
150
+ const tool = tools.find((t) => t.name === "mysql_binlog_events")!;
151
+ await tool.handler({ logFile: "mysql-bin.000001" }, mockContext);
152
+
153
+ // With explicit logFile, no master status query needed
154
+ const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
155
+ expect(call).toContain("BINLOG EVENTS");
156
+ expect(call).toContain("IN 'mysql-bin.000001'");
41
157
  });
42
158
 
43
- it('should include expected tool names', () => {
44
- const names = tools.map(t => t.name);
45
- expect(names).toContain('mysql_master_status');
46
- expect(names).toContain('mysql_slave_status');
47
- expect(names).toContain('mysql_binlog_events');
48
- expect(names).toContain('mysql_gtid_status');
49
- expect(names).toContain('mysql_replication_lag');
50
- });
51
- });
159
+ it("should limit events", async () => {
160
+ mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
52
161
 
53
- describe('getPartitioningTools', () => {
54
- let tools: ReturnType<typeof getPartitioningTools>;
162
+ const tool = tools.find((t) => t.name === "mysql_binlog_events")!;
163
+ await tool.handler(
164
+ { logFile: "mysql-bin.000001", limit: 10 },
165
+ mockContext,
166
+ );
55
167
 
56
- beforeEach(() => {
57
- vi.clearAllMocks();
58
- tools = getPartitioningTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
168
+ const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
169
+ expect(call).toContain("LIMIT 10");
59
170
  });
60
171
 
61
- it('should return 4 partitioning tools', () => {
62
- expect(tools).toHaveLength(4);
172
+ it("should auto-resolve current binlog file when logFile is omitted", async () => {
173
+ // First call: SHOW BINARY LOG STATUS, second call: SHOW BINLOG EVENTS
174
+ mockAdapter.executeQuery
175
+ .mockResolvedValueOnce(
176
+ createMockQueryResult([{ File: "mysql-bin.000010", Position: 154 }]),
177
+ )
178
+ .mockResolvedValueOnce(
179
+ createMockQueryResult([
180
+ { Log_name: "mysql-bin.000010", Event_type: "Query" },
181
+ ]),
182
+ );
183
+
184
+ const tool = tools.find((t) => t.name === "mysql_binlog_events")!;
185
+ await tool.handler({}, mockContext);
186
+
187
+ expect(mockAdapter.executeQuery).toHaveBeenCalledTimes(2);
188
+ const binlogCall = mockAdapter.executeQuery.mock.calls[1][0] as string;
189
+ expect(binlogCall).toContain("IN 'mysql-bin.000010'");
63
190
  });
191
+ });
64
192
 
65
- it('should have partitioning group for all tools', () => {
66
- for (const tool of tools) {
67
- expect(tool.group).toBe('partitioning');
68
- }
69
- });
193
+ describe("mysql_gtid_status", () => {
194
+ it("should query GTID status", async () => {
195
+ mockAdapter.executeQuery.mockResolvedValue(
196
+ createMockQueryResult([
197
+ { Variable_name: "gtid_executed", Value: "uuid:1-100" },
198
+ ]),
199
+ );
70
200
 
71
- it('should have handler functions for all tools', () => {
72
- for (const tool of tools) {
73
- expect(typeof tool.handler).toBe('function');
74
- }
75
- });
201
+ const tool = tools.find((t) => t.name === "mysql_gtid_status")!;
202
+ const result = await tool.handler({}, mockContext);
76
203
 
77
- it('should have inputSchema for all tools', () => {
78
- for (const tool of tools) {
79
- expect(tool.inputSchema).toBeDefined();
80
- }
204
+ expect(mockAdapter.executeQuery).toHaveBeenCalled();
205
+ expect(result).toBeDefined();
81
206
  });
207
+ });
82
208
 
83
- it('should include expected tool names', () => {
84
- const names = tools.map(t => t.name);
85
- expect(names).toContain('mysql_partition_info');
86
- expect(names).toContain('mysql_add_partition');
87
- expect(names).toContain('mysql_drop_partition');
88
- expect(names).toContain('mysql_reorganize_partition');
89
- });
90
- });
209
+ describe("mysql_replication_lag", () => {
210
+ it("should calculate replication lag", async () => {
211
+ mockAdapter.executeQuery.mockResolvedValue(
212
+ createMockQueryResult([{ Seconds_Behind_Master: 5 }]),
213
+ );
91
214
 
92
- describe('Replication Handler Execution', () => {
93
- let mockAdapter: ReturnType<typeof createMockMySQLAdapter>;
94
- let tools: ReturnType<typeof getReplicationTools>;
95
- let mockContext: ReturnType<typeof createMockRequestContext>;
215
+ const tool = tools.find((t) => t.name === "mysql_replication_lag")!;
216
+ const result = await tool.handler({}, mockContext);
96
217
 
97
- beforeEach(() => {
98
- vi.clearAllMocks();
99
- mockAdapter = createMockMySQLAdapter();
100
- tools = getReplicationTools(mockAdapter as unknown as MySQLAdapter);
101
- mockContext = createMockRequestContext();
218
+ expect(mockAdapter.executeQuery).toHaveBeenCalled();
219
+ expect(result).toBeDefined();
102
220
  });
221
+ });
222
+ });
103
223
 
104
- describe('mysql_master_status', () => {
105
- it('should query master status', async () => {
106
- mockAdapter.executeQuery.mockResolvedValue(
107
- createMockQueryResult([{ File: 'mysql-bin.000001', Position: 12345 }])
108
- );
109
-
110
- const tool = tools.find(t => t.name === 'mysql_master_status')!;
111
- const result = await tool.handler({}, mockContext);
112
-
113
- expect(mockAdapter.executeQuery).toHaveBeenCalled();
114
- expect(result).toBeDefined();
115
- });
224
+ describe("Partitioning Handler Execution", () => {
225
+ let mockAdapter: ReturnType<typeof createMockMySQLAdapter>;
226
+ let tools: ReturnType<typeof getPartitioningTools>;
227
+ let mockContext: ReturnType<typeof createMockRequestContext>;
228
+
229
+ beforeEach(() => {
230
+ vi.clearAllMocks();
231
+ mockAdapter = createMockMySQLAdapter();
232
+ tools = getPartitioningTools(mockAdapter as unknown as MySQLAdapter);
233
+ mockContext = createMockRequestContext();
234
+ });
235
+
236
+ describe("mysql_partition_info", () => {
237
+ it("should query partition info", async () => {
238
+ // First call: existence check, second call: partition query
239
+ mockAdapter.executeQuery
240
+ .mockResolvedValueOnce(createMockQueryResult([{ TABLE_NAME: "logs" }]))
241
+ .mockResolvedValueOnce(
242
+ createMockQueryResult([
243
+ {
244
+ PARTITION_NAME: "p0",
245
+ TABLE_ROWS: 1000,
246
+ PARTITION_METHOD: "RANGE",
247
+ },
248
+ ]),
249
+ );
250
+
251
+ const tool = tools.find((t) => t.name === "mysql_partition_info")!;
252
+ await tool.handler({ table: "logs" }, mockContext);
253
+
254
+ expect(mockAdapter.executeQuery).toHaveBeenCalledTimes(2);
255
+ const call = mockAdapter.executeQuery.mock.calls[1][0] as string;
256
+ expect(call).toContain("PARTITIONS");
116
257
  });
117
258
 
118
- describe('mysql_slave_status', () => {
119
- it('should query replica status', async () => {
120
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([
121
- { Replica_IO_Running: 'Yes', Replica_SQL_Running: 'Yes' }
122
- ]));
259
+ it("should detect non-partitioned table", async () => {
260
+ mockAdapter.executeQuery
261
+ .mockResolvedValueOnce(createMockQueryResult([{ TABLE_NAME: "users" }]))
262
+ .mockResolvedValueOnce(
263
+ createMockQueryResult([{ PARTITION_NAME: null, TABLE_ROWS: 1000 }]),
264
+ );
123
265
 
124
- const tool = tools.find(t => t.name === 'mysql_slave_status')!;
125
- const result = await tool.handler({}, mockContext);
266
+ const tool = tools.find((t) => t.name === "mysql_partition_info")!;
267
+ const result = (await tool.handler({ table: "users" }, mockContext)) as {
268
+ partitioned: boolean;
269
+ };
126
270
 
127
- expect(mockAdapter.executeQuery).toHaveBeenCalled();
128
- expect(result).toBeDefined();
129
- });
271
+ expect(result.partitioned).toBe(false);
130
272
  });
131
273
 
132
- describe('mysql_binlog_events', () => {
133
- it('should query binlog events', async () => {
134
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([
135
- { Log_name: 'mysql-bin.000001', Event_type: 'Query' }
136
- ]));
274
+ it("should detect partitioned table with method and expression", async () => {
275
+ mockAdapter.executeQuery
276
+ .mockResolvedValueOnce(createMockQueryResult([{ TABLE_NAME: "logs" }]))
277
+ .mockResolvedValueOnce(
278
+ createMockQueryResult([
279
+ {
280
+ PARTITION_NAME: "p0",
281
+ PARTITION_METHOD: "RANGE",
282
+ PARTITION_EXPRESSION: "TO_DAYS(created_at)",
283
+ },
284
+ ]),
285
+ );
286
+
287
+ const tool = tools.find((t) => t.name === "mysql_partition_info")!;
288
+ const result = (await tool.handler({ table: "logs" }, mockContext)) as {
289
+ partitioned: boolean;
290
+ method: string;
291
+ };
292
+
293
+ expect(result.partitioned).toBe(true);
294
+ expect(result.method).toBe("RANGE");
295
+ });
296
+ });
297
+
298
+ describe("mysql_add_partition", () => {
299
+ it("should add a RANGE partition", async () => {
300
+ mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
301
+
302
+ const tool = tools.find((t) => t.name === "mysql_add_partition")!;
303
+ const result = await tool.handler(
304
+ {
305
+ table: "logs",
306
+ partitionName: "p2024",
307
+ partitionType: "RANGE",
308
+ value: "2024",
309
+ },
310
+ mockContext,
311
+ );
312
+
313
+ expect(mockAdapter.executeQuery).toHaveBeenCalled();
314
+ const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
315
+ expect(call).toContain("ADD PARTITION");
316
+ expect(call).toContain("VALUES LESS THAN");
317
+ expect(result).toHaveProperty("success", true);
318
+ });
137
319
 
138
- const tool = tools.find(t => t.name === 'mysql_binlog_events')!;
139
- await tool.handler({ logName: 'mysql-bin.000001' }, mockContext);
320
+ it("should add a LIST partition", async () => {
321
+ mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
322
+
323
+ const tool = tools.find((t) => t.name === "mysql_add_partition")!;
324
+ await tool.handler(
325
+ {
326
+ table: "regions",
327
+ partitionName: "p_east",
328
+ partitionType: "LIST",
329
+ value: "'NY', 'NJ', 'PA'",
330
+ },
331
+ mockContext,
332
+ );
333
+
334
+ const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
335
+ expect(call).toContain("VALUES IN");
336
+ });
140
337
 
141
- expect(mockAdapter.executeQuery).toHaveBeenCalled();
142
- const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
143
- expect(call).toContain('BINLOG EVENTS');
144
- });
338
+ it("should add HASH partitions", async () => {
339
+ mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
340
+
341
+ const tool = tools.find((t) => t.name === "mysql_add_partition")!;
342
+ await tool.handler(
343
+ {
344
+ table: "data",
345
+ partitionName: "hash_p",
346
+ partitionType: "HASH",
347
+ value: "4",
348
+ },
349
+ mockContext,
350
+ );
351
+
352
+ const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
353
+ expect(call).toContain("PARTITIONS 4");
354
+ });
145
355
 
146
- it('should limit events', async () => {
147
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
356
+ it("should add KEY partitions", async () => {
357
+ mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
358
+
359
+ const tool = tools.find((t) => t.name === "mysql_add_partition")!;
360
+ await tool.handler(
361
+ {
362
+ table: "data",
363
+ partitionName: "key_p",
364
+ partitionType: "KEY",
365
+ value: "8",
366
+ },
367
+ mockContext,
368
+ );
369
+
370
+ const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
371
+ expect(call).toContain("PARTITIONS 8");
372
+ });
373
+ });
374
+
375
+ describe("mysql_drop_partition", () => {
376
+ it("should drop a partition", async () => {
377
+ mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
378
+
379
+ const tool = tools.find((t) => t.name === "mysql_drop_partition")!;
380
+ const result = await tool.handler(
381
+ {
382
+ table: "logs",
383
+ partitionName: "p2020",
384
+ },
385
+ mockContext,
386
+ );
387
+
388
+ expect(mockAdapter.executeQuery).toHaveBeenCalled();
389
+ const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
390
+ expect(call).toContain("DROP PARTITION");
391
+ expect(result).toHaveProperty("success", true);
392
+ });
393
+ });
394
+
395
+ describe("mysql_reorganize_partition", () => {
396
+ it("should reorganize partitions", async () => {
397
+ mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
398
+
399
+ const tool = tools.find((t) => t.name === "mysql_reorganize_partition")!;
400
+ const result = await tool.handler(
401
+ {
402
+ table: "logs",
403
+ fromPartitions: ["p2023"],
404
+ partitionType: "RANGE",
405
+ toPartitions: [
406
+ { name: "p2023_h1", value: "202307" },
407
+ { name: "p2023_h2", value: "202401" },
408
+ ],
409
+ },
410
+ mockContext,
411
+ );
412
+
413
+ expect(mockAdapter.executeQuery).toHaveBeenCalled();
414
+ const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
415
+ expect(call).toContain("REORGANIZE PARTITION");
416
+ expect(result).toHaveProperty("success", true);
417
+ });
148
418
 
149
- const tool = tools.find(t => t.name === 'mysql_binlog_events')!;
150
- await tool.handler({ logName: 'mysql-bin.000001', limit: 10 }, mockContext);
419
+ it("should return structured error for non-partitioned table", async () => {
420
+ mockAdapter.executeQuery.mockRejectedValue(
421
+ new Error(
422
+ "Partition management on a not partitioned table is not possible",
423
+ ),
424
+ );
425
+
426
+ const tool = tools.find((t) => t.name === "mysql_reorganize_partition")!;
427
+ const result = (await tool.handler(
428
+ {
429
+ table: "users",
430
+ fromPartitions: ["p1"],
431
+ partitionType: "RANGE",
432
+ toPartitions: [{ name: "p1a", value: "50" }],
433
+ },
434
+ mockContext,
435
+ )) as { success: boolean; error: string };
436
+
437
+ expect(result.success).toBe(false);
438
+ expect(result.error).toContain("not partitioned");
439
+ });
151
440
 
152
- const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
153
- expect(call).toContain('LIMIT 10');
154
- });
441
+ it("should return structured error for nonexistent partition", async () => {
442
+ mockAdapter.executeQuery.mockRejectedValue(
443
+ new Error("Error in list of partitions to REORGANIZE"),
444
+ );
445
+
446
+ const tool = tools.find((t) => t.name === "mysql_reorganize_partition")!;
447
+ const result = (await tool.handler(
448
+ {
449
+ table: "logs",
450
+ fromPartitions: ["nonexistent"],
451
+ partitionType: "RANGE",
452
+ toPartitions: [{ name: "p_new", value: "2030" }],
453
+ },
454
+ mockContext,
455
+ )) as { success: boolean; fromPartitions: string[]; error: string };
456
+
457
+ expect(result.success).toBe(false);
458
+ expect(result.fromPartitions).toEqual(["nonexistent"]);
459
+ expect(result.error).toContain("do not exist");
155
460
  });
461
+ });
156
462
 
157
- describe('mysql_gtid_status', () => {
158
- it('should query GTID status', async () => {
159
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([
160
- { Variable_name: 'gtid_executed', Value: 'uuid:1-100' }
161
- ]));
463
+ describe("mysql_partition_info existence check", () => {
464
+ it("should return exists: false for nonexistent table", async () => {
465
+ mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
162
466
 
163
- const tool = tools.find(t => t.name === 'mysql_gtid_status')!;
164
- const result = await tool.handler({}, mockContext);
467
+ const tool = tools.find((t) => t.name === "mysql_partition_info")!;
468
+ const result = (await tool.handler(
469
+ { table: "nonexistent" },
470
+ mockContext,
471
+ )) as { exists: boolean; table: string };
165
472
 
166
- expect(mockAdapter.executeQuery).toHaveBeenCalled();
167
- expect(result).toBeDefined();
168
- });
473
+ expect(result.exists).toBe(false);
474
+ expect(result.table).toBe("nonexistent");
475
+ });
476
+ });
477
+
478
+ describe("mysql_add_partition error handling", () => {
479
+ it("should return structured error for non-partitioned table", async () => {
480
+ mockAdapter.executeQuery.mockRejectedValue(
481
+ new Error(
482
+ "Partition management on a not partitioned table is not possible",
483
+ ),
484
+ );
485
+
486
+ const tool = tools.find((t) => t.name === "mysql_add_partition")!;
487
+ const result = (await tool.handler(
488
+ {
489
+ table: "users",
490
+ partitionName: "p1",
491
+ partitionType: "RANGE",
492
+ value: "100",
493
+ },
494
+ mockContext,
495
+ )) as { success: boolean; error: string };
496
+
497
+ expect(result.success).toBe(false);
498
+ expect(result.error).toContain("not partitioned");
169
499
  });
170
500
 
171
- describe('mysql_replication_lag', () => {
172
- it('should calculate replication lag', async () => {
173
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([
174
- { Seconds_Behind_Master: 5 }
175
- ]));
176
-
177
- const tool = tools.find(t => t.name === 'mysql_replication_lag')!;
178
- const result = await tool.handler({}, mockContext);
501
+ it("should return structured error for MAXVALUE conflict", async () => {
502
+ mockAdapter.executeQuery.mockRejectedValue(
503
+ new Error("MAXVALUE can only be used in last partition definition"),
504
+ );
505
+
506
+ const tool = tools.find((t) => t.name === "mysql_add_partition")!;
507
+ const result = (await tool.handler(
508
+ {
509
+ table: "logs",
510
+ partitionName: "p2025",
511
+ partitionType: "RANGE",
512
+ value: "2026",
513
+ },
514
+ mockContext,
515
+ )) as { success: boolean; error: string };
516
+
517
+ expect(result.success).toBe(false);
518
+ expect(result.error).toContain("MAXVALUE");
519
+ expect(result.error).toContain("mysql_reorganize_partition");
520
+ });
179
521
 
180
- expect(mockAdapter.executeQuery).toHaveBeenCalled();
181
- expect(result).toBeDefined();
182
- });
522
+ it("should return structured error for duplicate partition values", async () => {
523
+ mockAdapter.executeQuery.mockRejectedValue(
524
+ new Error("Multiple definition of same constant in list partitioning"),
525
+ );
526
+
527
+ const tool = tools.find((t) => t.name === "mysql_add_partition")!;
528
+ const result = (await tool.handler(
529
+ {
530
+ table: "regions",
531
+ partitionName: "p_dup",
532
+ partitionType: "LIST",
533
+ value: "'east'",
534
+ },
535
+ mockContext,
536
+ )) as { success: boolean; error: string };
537
+
538
+ expect(result.success).toBe(false);
539
+ expect(result.error).toContain("already exist");
540
+ });
541
+ });
542
+
543
+ describe("mysql_drop_partition error handling", () => {
544
+ it("should return structured error for non-partitioned table", async () => {
545
+ mockAdapter.executeQuery.mockRejectedValue(
546
+ new Error(
547
+ "Partition management on a not partitioned table is not possible",
548
+ ),
549
+ );
550
+
551
+ const tool = tools.find((t) => t.name === "mysql_drop_partition")!;
552
+ const result = (await tool.handler(
553
+ { table: "users", partitionName: "p1" },
554
+ mockContext,
555
+ )) as { success: boolean; error: string };
556
+
557
+ expect(result.success).toBe(false);
558
+ expect(result.error).toContain("not partitioned");
183
559
  });
184
- });
185
560
 
186
- describe('Partitioning Handler Execution', () => {
187
- let mockAdapter: ReturnType<typeof createMockMySQLAdapter>;
188
- let tools: ReturnType<typeof getPartitioningTools>;
189
- let mockContext: ReturnType<typeof createMockRequestContext>;
190
-
191
- beforeEach(() => {
192
- vi.clearAllMocks();
193
- mockAdapter = createMockMySQLAdapter();
194
- tools = getPartitioningTools(mockAdapter as unknown as MySQLAdapter);
195
- mockContext = createMockRequestContext();
196
- });
197
-
198
- describe('mysql_partition_info', () => {
199
- it('should query partition info', async () => {
200
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([
201
- { PARTITION_NAME: 'p0', TABLE_ROWS: 1000, PARTITION_METHOD: 'RANGE' }
202
- ]));
203
-
204
- const tool = tools.find(t => t.name === 'mysql_partition_info')!;
205
- await tool.handler({ table: 'logs' }, mockContext);
206
-
207
- expect(mockAdapter.executeQuery).toHaveBeenCalled();
208
- const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
209
- expect(call).toContain('PARTITIONS');
210
- });
211
-
212
- it('should detect non-partitioned table', async () => {
213
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([
214
- { PARTITION_NAME: null, TABLE_ROWS: 1000 }
215
- ]));
216
-
217
- const tool = tools.find(t => t.name === 'mysql_partition_info')!;
218
- const result = await tool.handler({ table: 'users' }, mockContext) as { partitioned: boolean };
219
-
220
- expect(result.partitioned).toBe(false);
221
- });
222
-
223
- it('should detect partitioned table with method and expression', async () => {
224
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([
225
- { PARTITION_NAME: 'p0', PARTITION_METHOD: 'RANGE', PARTITION_EXPRESSION: 'TO_DAYS(created_at)' }
226
- ]));
227
-
228
- const tool = tools.find(t => t.name === 'mysql_partition_info')!;
229
- const result = await tool.handler({ table: 'logs' }, mockContext) as { partitioned: boolean; method: string };
230
-
231
- expect(result.partitioned).toBe(true);
232
- expect(result.method).toBe('RANGE');
233
- });
234
- });
235
-
236
- describe('mysql_add_partition', () => {
237
- it('should add a RANGE partition', async () => {
238
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
239
-
240
- const tool = tools.find(t => t.name === 'mysql_add_partition')!;
241
- const result = await tool.handler({
242
- table: 'logs',
243
- partitionName: 'p2024',
244
- partitionType: 'RANGE',
245
- value: '2024'
246
- }, mockContext);
247
-
248
- expect(mockAdapter.executeQuery).toHaveBeenCalled();
249
- const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
250
- expect(call).toContain('ADD PARTITION');
251
- expect(call).toContain('VALUES LESS THAN');
252
- expect(result).toHaveProperty('success', true);
253
- });
254
-
255
- it('should add a LIST partition', async () => {
256
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
257
-
258
- const tool = tools.find(t => t.name === 'mysql_add_partition')!;
259
- await tool.handler({
260
- table: 'regions',
261
- partitionName: 'p_east',
262
- partitionType: 'LIST',
263
- value: "'NY', 'NJ', 'PA'"
264
- }, mockContext);
265
-
266
- const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
267
- expect(call).toContain('VALUES IN');
268
- });
269
-
270
- it('should add HASH partitions', async () => {
271
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
272
-
273
- const tool = tools.find(t => t.name === 'mysql_add_partition')!;
274
- await tool.handler({
275
- table: 'data',
276
- partitionName: 'hash_p',
277
- partitionType: 'HASH',
278
- value: '4'
279
- }, mockContext);
280
-
281
- const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
282
- expect(call).toContain('PARTITIONS 4');
283
- });
284
-
285
- it('should add KEY partitions', async () => {
286
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
287
-
288
- const tool = tools.find(t => t.name === 'mysql_add_partition')!;
289
- await tool.handler({
290
- table: 'data',
291
- partitionName: 'key_p',
292
- partitionType: 'KEY',
293
- value: '8'
294
- }, mockContext);
295
-
296
- const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
297
- expect(call).toContain('PARTITIONS 8');
298
- });
299
- });
300
-
301
- describe('mysql_drop_partition', () => {
302
- it('should drop a partition', async () => {
303
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
304
-
305
- const tool = tools.find(t => t.name === 'mysql_drop_partition')!;
306
- const result = await tool.handler({
307
- table: 'logs',
308
- partitionName: 'p2020'
309
- }, mockContext);
310
-
311
- expect(mockAdapter.executeQuery).toHaveBeenCalled();
312
- const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
313
- expect(call).toContain('DROP PARTITION');
314
- expect(result).toHaveProperty('success', true);
315
- });
316
- });
317
-
318
- describe('mysql_reorganize_partition', () => {
319
- it('should reorganize partitions', async () => {
320
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
321
-
322
- const tool = tools.find(t => t.name === 'mysql_reorganize_partition')!;
323
- const result = await tool.handler({
324
- table: 'logs',
325
- fromPartitions: ['p2023'],
326
- partitionType: 'RANGE',
327
- toPartitions: [
328
- { name: 'p2023_h1', value: '202307' },
329
- { name: 'p2023_h2', value: '202401' }
330
- ]
331
- }, mockContext);
332
-
333
- expect(mockAdapter.executeQuery).toHaveBeenCalled();
334
- const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
335
- expect(call).toContain('REORGANIZE PARTITION');
336
- expect(result).toHaveProperty('success', true);
337
- });
561
+ it("should return structured error for nonexistent partition", async () => {
562
+ mockAdapter.executeQuery.mockRejectedValue(
563
+ new Error("Error in list of partitions to DROP"),
564
+ );
565
+
566
+ const tool = tools.find((t) => t.name === "mysql_drop_partition")!;
567
+ const result = (await tool.handler(
568
+ { table: "logs", partitionName: "nonexistent" },
569
+ mockContext,
570
+ )) as {
571
+ success: boolean;
572
+ partitionName: string;
573
+ error: string;
574
+ };
575
+
576
+ expect(result.success).toBe(false);
577
+ expect(result.partitionName).toBe("nonexistent");
578
+ expect(result.error).toContain("does not exist");
338
579
  });
580
+ });
339
581
  });
340
582
 
341
- describe('Replication Fallback Handling', () => {
342
- let mockAdapter: ReturnType<typeof createMockMySQLAdapter>;
343
- let tools: ReturnType<typeof getReplicationTools>;
344
- let mockContext: ReturnType<typeof createMockRequestContext>;
345
-
346
- beforeEach(() => {
347
- vi.clearAllMocks();
348
- mockAdapter = createMockMySQLAdapter();
349
- tools = getReplicationTools(mockAdapter as unknown as MySQLAdapter);
350
- mockContext = createMockRequestContext();
583
+ describe("Replication Fallback Handling", () => {
584
+ let mockAdapter: ReturnType<typeof createMockMySQLAdapter>;
585
+ let tools: ReturnType<typeof getReplicationTools>;
586
+ let mockContext: ReturnType<typeof createMockRequestContext>;
587
+
588
+ beforeEach(() => {
589
+ vi.clearAllMocks();
590
+ mockAdapter = createMockMySQLAdapter();
591
+ tools = getReplicationTools(mockAdapter as unknown as MySQLAdapter);
592
+ mockContext = createMockRequestContext();
593
+ });
594
+
595
+ describe("mysql_master_status fallback", () => {
596
+ it("should fallback to SHOW MASTER STATUS on error", async () => {
597
+ // First call fails (new syntax), second succeeds (old syntax)
598
+ mockAdapter.executeQuery
599
+ .mockRejectedValueOnce(new Error("Unknown command"))
600
+ .mockResolvedValueOnce(
601
+ createMockQueryResult([{ File: "mysql-bin.000001" }]),
602
+ );
603
+
604
+ const tool = tools.find((t) => t.name === "mysql_master_status")!;
605
+ const result = await tool.handler({}, mockContext);
606
+
607
+ expect(mockAdapter.executeQuery).toHaveBeenCalledTimes(2);
608
+ expect(result).toHaveProperty("status");
351
609
  });
352
610
 
353
- describe('mysql_master_status fallback', () => {
354
- it('should fallback to SHOW MASTER STATUS on error', async () => {
355
- // First call fails (new syntax), second succeeds (old syntax)
356
- mockAdapter.executeQuery
357
- .mockRejectedValueOnce(new Error('Unknown command'))
358
- .mockResolvedValueOnce(createMockQueryResult([{ File: 'mysql-bin.000001' }]));
611
+ it("should return error when binary logging is disabled", async () => {
612
+ mockAdapter.executeQuery
613
+ .mockRejectedValueOnce(new Error("Unknown command"))
614
+ .mockRejectedValueOnce(new Error("Binary logging not enabled"));
359
615
 
360
- const tool = tools.find(t => t.name === 'mysql_master_status')!;
361
- const result = await tool.handler({}, mockContext);
616
+ const tool = tools.find((t) => t.name === "mysql_master_status")!;
617
+ const result = (await tool.handler({}, mockContext)) as { error: string };
362
618
 
363
- expect(mockAdapter.executeQuery).toHaveBeenCalledTimes(2);
364
- expect(result).toHaveProperty('status');
365
- });
619
+ expect(result.error).toContain("Binary logging");
620
+ });
621
+ });
366
622
 
367
- it('should return error when binary logging is disabled', async () => {
368
- mockAdapter.executeQuery
369
- .mockRejectedValueOnce(new Error('Unknown command'))
370
- .mockRejectedValueOnce(new Error('Binary logging not enabled'));
623
+ describe("mysql_slave_status fallback", () => {
624
+ it("should fallback to SHOW SLAVE STATUS on error", async () => {
625
+ mockAdapter.executeQuery
626
+ .mockRejectedValueOnce(new Error("Unknown command"))
627
+ .mockResolvedValueOnce(
628
+ createMockQueryResult([{ Slave_IO_Running: "Yes" }]),
629
+ );
371
630
 
372
- const tool = tools.find(t => t.name === 'mysql_master_status')!;
373
- const result = await tool.handler({}, mockContext) as { error: string };
631
+ const tool = tools.find((t) => t.name === "mysql_slave_status")!;
632
+ const result = await tool.handler({}, mockContext);
374
633
 
375
- expect(result.error).toContain('Binary logging');
376
- });
634
+ expect(mockAdapter.executeQuery).toHaveBeenCalledTimes(2);
635
+ expect(result).toHaveProperty("status");
377
636
  });
378
637
 
379
- describe('mysql_slave_status fallback', () => {
380
- it('should fallback to SHOW SLAVE STATUS on error', async () => {
381
- mockAdapter.executeQuery
382
- .mockRejectedValueOnce(new Error('Unknown command'))
383
- .mockResolvedValueOnce(createMockQueryResult([{ Slave_IO_Running: 'Yes' }]));
638
+ it("should return message when not configured as replica", async () => {
639
+ mockAdapter.executeQuery
640
+ .mockRejectedValueOnce(new Error("Unknown command"))
641
+ .mockRejectedValueOnce(new Error("Not configured"));
384
642
 
385
- const tool = tools.find(t => t.name === 'mysql_slave_status')!;
386
- const result = await tool.handler({}, mockContext);
643
+ const tool = tools.find((t) => t.name === "mysql_slave_status")!;
644
+ const result = (await tool.handler({}, mockContext)) as {
645
+ message: string;
646
+ };
387
647
 
388
- expect(mockAdapter.executeQuery).toHaveBeenCalledTimes(2);
389
- expect(result).toHaveProperty('status');
390
- });
648
+ expect(result.message).toContain("not configured");
649
+ });
650
+ });
391
651
 
392
- it('should return message when not configured as replica', async () => {
393
- mockAdapter.executeQuery
394
- .mockRejectedValueOnce(new Error('Unknown command'))
395
- .mockRejectedValueOnce(new Error('Not configured'));
652
+ describe("mysql_binlog_events options", () => {
653
+ it("should include log file when specified", async () => {
654
+ mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
396
655
 
397
- const tool = tools.find(t => t.name === 'mysql_slave_status')!;
398
- const result = await tool.handler({}, mockContext) as { message: string };
656
+ const tool = tools.find((t) => t.name === "mysql_binlog_events")!;
657
+ await tool.handler({ logFile: "mysql-bin.000005" }, mockContext);
399
658
 
400
- expect(result.message).toContain('not configured');
401
- });
659
+ // With explicit logFile, first call is the binlog query itself
660
+ const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
661
+ expect(call).toContain("IN 'mysql-bin.000005'");
402
662
  });
403
663
 
404
- describe('mysql_binlog_events options', () => {
405
- it('should include log file when specified', async () => {
406
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
664
+ it("should include position when specified", async () => {
665
+ // First call: master status (logFile not provided), second: binlog events
666
+ mockAdapter.executeQuery
667
+ .mockResolvedValueOnce(
668
+ createMockQueryResult([{ File: "mysql-bin.000001", Position: 4 }]),
669
+ )
670
+ .mockResolvedValueOnce(createMockQueryResult([]));
407
671
 
408
- const tool = tools.find(t => t.name === 'mysql_binlog_events')!;
409
- await tool.handler({ logFile: 'mysql-bin.000005' }, mockContext);
672
+ const tool = tools.find((t) => t.name === "mysql_binlog_events")!;
673
+ await tool.handler({ position: 12345 }, mockContext);
410
674
 
411
- const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
412
- expect(call).toContain("IN 'mysql-bin.000005'");
413
- });
675
+ // Second call is the actual SHOW BINLOG EVENTS query
676
+ const call = mockAdapter.executeQuery.mock.calls[1][0] as string;
677
+ expect(call).toContain("FROM 12345");
678
+ });
414
679
 
415
- it('should include position when specified', async () => {
416
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
680
+ it("should return graceful error for nonexistent binlog file", async () => {
681
+ mockAdapter.executeQuery.mockRejectedValue(
682
+ new Error("Could not find target log"),
683
+ );
417
684
 
418
- const tool = tools.find(t => t.name === 'mysql_binlog_events')!;
419
- await tool.handler({ position: 12345 }, mockContext);
685
+ const tool = tools.find((t) => t.name === "mysql_binlog_events")!;
686
+ const result = (await tool.handler(
687
+ { logFile: "nonexistent.000001" },
688
+ mockContext,
689
+ )) as { success: boolean; logFile: string; error: string };
420
690
 
421
- const call = mockAdapter.executeQuery.mock.calls[0][0] as string;
422
- expect(call).toContain('FROM 12345');
423
- });
691
+ expect(result.success).toBe(false);
692
+ expect(result.logFile).toBe("nonexistent.000001");
693
+ expect(result.error).toContain("not found");
424
694
  });
425
695
 
426
- describe('mysql_replication_lag fallback', () => {
427
- it('should return lag from replica status', async () => {
428
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([{
429
- Seconds_Behind_Source: 5,
430
- Replica_IO_Running: 'Yes',
431
- Replica_SQL_Running: 'Yes',
432
- Last_Error: ''
433
- }]));
434
-
435
- const tool = tools.find(t => t.name === 'mysql_replication_lag')!;
436
- const result = await tool.handler({}, mockContext) as { lagSeconds: number };
437
-
438
- expect(result.lagSeconds).toBe(5);
439
- });
696
+ it("should return graceful error for generic binlog query failure", async () => {
697
+ // All calls fail (master status and binlog events)
698
+ mockAdapter.executeQuery.mockRejectedValue(
699
+ new Error("Binary logging not enabled"),
700
+ );
440
701
 
441
- it('should fallback to SHOW SLAVE STATUS on error', async () => {
442
- mockAdapter.executeQuery
443
- .mockRejectedValueOnce(new Error('Unknown command'))
444
- .mockResolvedValueOnce(createMockQueryResult([{
445
- Seconds_Behind_Master: 10,
446
- Slave_IO_Running: 'Yes',
447
- Slave_SQL_Running: 'Yes',
448
- Last_Error: ''
449
- }]));
702
+ const tool = tools.find((t) => t.name === "mysql_binlog_events")!;
703
+ const result = (await tool.handler({}, mockContext)) as {
704
+ success: boolean;
705
+ error: string;
706
+ };
450
707
 
451
- const tool = tools.find(t => t.name === 'mysql_replication_lag')!;
452
- const result = await tool.handler({}, mockContext) as { lagSeconds: number };
708
+ expect(result.success).toBe(false);
709
+ expect(result.error).toContain("Failed to read binlog events");
710
+ });
711
+ });
712
+
713
+ describe("mysql_replication_lag fallback", () => {
714
+ it("should return lag from replica status", async () => {
715
+ mockAdapter.executeQuery.mockResolvedValue(
716
+ createMockQueryResult([
717
+ {
718
+ Seconds_Behind_Source: 5,
719
+ Replica_IO_Running: "Yes",
720
+ Replica_SQL_Running: "Yes",
721
+ Last_Error: "",
722
+ },
723
+ ]),
724
+ );
725
+
726
+ const tool = tools.find((t) => t.name === "mysql_replication_lag")!;
727
+ const result = (await tool.handler({}, mockContext)) as {
728
+ lagSeconds: number;
729
+ };
730
+
731
+ expect(result.lagSeconds).toBe(5);
732
+ });
453
733
 
454
- expect(result.lagSeconds).toBe(10);
455
- });
734
+ it("should fallback to SHOW SLAVE STATUS on error", async () => {
735
+ mockAdapter.executeQuery
736
+ .mockRejectedValueOnce(new Error("Unknown command"))
737
+ .mockResolvedValueOnce(
738
+ createMockQueryResult([
739
+ {
740
+ Seconds_Behind_Master: 10,
741
+ Slave_IO_Running: "Yes",
742
+ Slave_SQL_Running: "Yes",
743
+ Last_Error: "",
744
+ },
745
+ ]),
746
+ );
747
+
748
+ const tool = tools.find((t) => t.name === "mysql_replication_lag")!;
749
+ const result = (await tool.handler({}, mockContext)) as {
750
+ lagSeconds: number;
751
+ };
752
+
753
+ expect(result.lagSeconds).toBe(10);
754
+ });
456
755
 
457
- it('should return message when not a replica after both fail', async () => {
458
- mockAdapter.executeQuery
459
- .mockRejectedValueOnce(new Error('Unknown command'))
460
- .mockRejectedValueOnce(new Error('Not configured'));
756
+ it("should return message when not a replica after both fail", async () => {
757
+ mockAdapter.executeQuery
758
+ .mockRejectedValueOnce(new Error("Unknown command"))
759
+ .mockRejectedValueOnce(new Error("Not configured"));
461
760
 
462
- const tool = tools.find(t => t.name === 'mysql_replication_lag')!;
463
- const result = await tool.handler({}, mockContext) as { lagSeconds: null; message: string };
761
+ const tool = tools.find((t) => t.name === "mysql_replication_lag")!;
762
+ const result = (await tool.handler({}, mockContext)) as {
763
+ lagSeconds: null;
764
+ message: string;
765
+ };
464
766
 
465
- expect(result.lagSeconds).toBeNull();
466
- expect(result.message).toContain('not configured');
467
- });
767
+ expect(result.lagSeconds).toBeNull();
768
+ expect(result.message).toContain("not configured");
769
+ });
468
770
 
469
- it('should return null lag when replica status returns empty', async () => {
470
- mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
771
+ it("should return null lag when replica status returns empty", async () => {
772
+ mockAdapter.executeQuery.mockResolvedValue(createMockQueryResult([]));
471
773
 
472
- const tool = tools.find(t => t.name === 'mysql_replication_lag')!;
473
- const result = await tool.handler({}, mockContext) as { lagSeconds: null };
774
+ const tool = tools.find((t) => t.name === "mysql_replication_lag")!;
775
+ const result = (await tool.handler({}, mockContext)) as {
776
+ lagSeconds: null;
777
+ };
474
778
 
475
- expect(result.lagSeconds).toBeNull();
476
- });
779
+ expect(result.lagSeconds).toBeNull();
477
780
  });
781
+ });
478
782
  });