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