@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,439 +1,758 @@
1
1
  /**
2
2
  * mysql-mcp - Core Tools Unit Tests
3
- *
3
+ *
4
4
  * Tests for core database operations with focus on tool definitions,
5
5
  * schema validation, and handler execution behavior.
6
6
  */
7
7
 
8
- import { describe, it, expect, vi, beforeEach } from 'vitest';
9
- import { getCoreTools } from '../core.js';
10
- import type { MySQLAdapter } from '../../MySQLAdapter.js';
11
- import { createMockMySQLAdapter, createMockQueryResult, createMockRequestContext } from '../../../../__tests__/mocks/index.js';
8
+ import { describe, it, expect, vi, beforeEach } from "vitest";
9
+ import { getCoreTools } from "../core.js";
10
+ import type { MySQLAdapter } from "../../MySQLAdapter.js";
11
+ import {
12
+ createMockMySQLAdapter,
13
+ createMockQueryResult,
14
+ createMockRequestContext,
15
+ } from "../../../../__tests__/mocks/index.js";
16
+
17
+ describe("getCoreTools", () => {
18
+ let adapter: MySQLAdapter;
19
+ let tools: ReturnType<typeof getCoreTools>;
20
+
21
+ beforeEach(() => {
22
+ vi.clearAllMocks();
23
+ adapter = createMockMySQLAdapter() as unknown as MySQLAdapter;
24
+ tools = getCoreTools(adapter);
25
+ });
26
+
27
+ it("should return 8 core tools", () => {
28
+ expect(tools).toHaveLength(8);
29
+ });
30
+
31
+ it("should include all expected tool names", () => {
32
+ const toolNames = tools.map((t) => t.name);
33
+ expect(toolNames).toContain("mysql_read_query");
34
+ expect(toolNames).toContain("mysql_write_query");
35
+ expect(toolNames).toContain("mysql_list_tables");
36
+ expect(toolNames).toContain("mysql_describe_table");
37
+ expect(toolNames).toContain("mysql_create_table");
38
+ expect(toolNames).toContain("mysql_drop_table");
39
+ expect(toolNames).toContain("mysql_create_index");
40
+ expect(toolNames).toContain("mysql_get_indexes");
41
+ });
42
+
43
+ it("should have core group for all tools", () => {
44
+ for (const tool of tools) {
45
+ expect(tool.group).toBe("core");
46
+ }
47
+ });
48
+
49
+ it("should have handler functions for all tools", () => {
50
+ for (const tool of tools) {
51
+ expect(typeof tool.handler).toBe("function");
52
+ }
53
+ });
54
+
55
+ it("should have inputSchema for all tools", () => {
56
+ for (const tool of tools) {
57
+ expect(tool.inputSchema).toBeDefined();
58
+ }
59
+ });
60
+ });
61
+
62
+ describe("Tool Annotations", () => {
63
+ let tools: ReturnType<typeof getCoreTools>;
64
+
65
+ beforeEach(() => {
66
+ tools = getCoreTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
67
+ });
68
+
69
+ it("mysql_read_query should be read-only", () => {
70
+ const tool = tools.find((t) => t.name === "mysql_read_query")!;
71
+ expect(tool.annotations?.readOnlyHint).toBe(true);
72
+ });
73
+
74
+ it("mysql_write_query should not be read-only", () => {
75
+ const tool = tools.find((t) => t.name === "mysql_write_query")!;
76
+ expect(tool.annotations?.readOnlyHint).toBe(false);
77
+ });
78
+
79
+ it("mysql_list_tables should be read-only", () => {
80
+ const tool = tools.find((t) => t.name === "mysql_list_tables")!;
81
+ expect(tool.annotations?.readOnlyHint).toBe(true);
82
+ });
83
+
84
+ it("mysql_describe_table should be read-only", () => {
85
+ const tool = tools.find((t) => t.name === "mysql_describe_table")!;
86
+ expect(tool.annotations?.readOnlyHint).toBe(true);
87
+ });
88
+
89
+ it("mysql_drop_table should be destructive", () => {
90
+ const tool = tools.find((t) => t.name === "mysql_drop_table")!;
91
+ expect(tool.annotations?.destructiveHint).toBe(true);
92
+ });
93
+
94
+ it("mysql_get_indexes should be read-only", () => {
95
+ const tool = tools.find((t) => t.name === "mysql_get_indexes")!;
96
+ expect(tool.annotations?.readOnlyHint).toBe(true);
97
+ });
98
+ });
12
99
 
13
- describe('getCoreTools', () => {
14
- let adapter: MySQLAdapter;
15
- let tools: ReturnType<typeof getCoreTools>;
100
+ describe("Required Scopes", () => {
101
+ let tools: ReturnType<typeof getCoreTools>;
102
+
103
+ beforeEach(() => {
104
+ tools = getCoreTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
105
+ });
106
+
107
+ it("read_query should require read scope", () => {
108
+ const tool = tools.find((t) => t.name === "mysql_read_query")!;
109
+ expect(tool.requiredScopes).toContain("read");
110
+ });
111
+
112
+ it("write_query should require write scope", () => {
113
+ const tool = tools.find((t) => t.name === "mysql_write_query")!;
114
+ expect(tool.requiredScopes).toContain("write");
115
+ });
116
+
117
+ it("drop_table should require admin scope", () => {
118
+ const tool = tools.find((t) => t.name === "mysql_drop_table")!;
119
+ expect(
120
+ tool.requiredScopes?.some((s) => s === "write" || s === "admin"),
121
+ ).toBe(true);
122
+ });
123
+ });
16
124
 
17
- beforeEach(() => {
18
- vi.clearAllMocks();
19
- adapter = createMockMySQLAdapter() as unknown as MySQLAdapter;
20
- tools = getCoreTools(adapter);
125
+ describe("Handler Execution", () => {
126
+ let mockAdapter: ReturnType<typeof createMockMySQLAdapter>;
127
+ let tools: ReturnType<typeof getCoreTools>;
128
+ let mockContext: ReturnType<typeof createMockRequestContext>;
129
+
130
+ beforeEach(() => {
131
+ vi.clearAllMocks();
132
+ mockAdapter = createMockMySQLAdapter();
133
+ tools = getCoreTools(mockAdapter as unknown as MySQLAdapter);
134
+ mockContext = createMockRequestContext();
135
+ });
136
+
137
+ describe("mysql_read_query", () => {
138
+ it("should execute read query and return result", async () => {
139
+ const expectedResult = createMockQueryResult([{ id: 1, name: "test" }]);
140
+ mockAdapter.executeReadQuery.mockResolvedValue(expectedResult);
141
+
142
+ const tool = tools.find((t) => t.name === "mysql_read_query")!;
143
+ const result = await tool.handler(
144
+ { query: "SELECT * FROM users" },
145
+ mockContext,
146
+ );
147
+
148
+ expect(mockAdapter.executeReadQuery).toHaveBeenCalledWith(
149
+ "SELECT * FROM users",
150
+ undefined,
151
+ undefined,
152
+ );
153
+ expect(result).toBeDefined();
21
154
  });
22
155
 
23
- it('should return 8 core tools', () => {
24
- expect(tools).toHaveLength(8);
156
+ it("should pass parameters to executeReadQuery", async () => {
157
+ const tool = tools.find((t) => t.name === "mysql_read_query")!;
158
+ await tool.handler(
159
+ { query: "SELECT * FROM users WHERE id = ?", params: [1] },
160
+ mockContext,
161
+ );
162
+
163
+ expect(mockAdapter.executeReadQuery).toHaveBeenCalledWith(
164
+ "SELECT * FROM users WHERE id = ?",
165
+ [1],
166
+ undefined,
167
+ );
25
168
  });
26
169
 
27
- it('should include all expected tool names', () => {
28
- const toolNames = tools.map(t => t.name);
29
- expect(toolNames).toContain('mysql_read_query');
30
- expect(toolNames).toContain('mysql_write_query');
31
- expect(toolNames).toContain('mysql_list_tables');
32
- expect(toolNames).toContain('mysql_describe_table');
33
- expect(toolNames).toContain('mysql_create_table');
34
- expect(toolNames).toContain('mysql_drop_table');
35
- expect(toolNames).toContain('mysql_create_index');
36
- expect(toolNames).toContain('mysql_get_indexes');
170
+ it("should pass transactionId to executeReadQuery when provided", async () => {
171
+ const tool = tools.find((t) => t.name === "mysql_read_query")!;
172
+ await tool.handler(
173
+ { query: "SELECT * FROM users", transactionId: "txn-123" },
174
+ mockContext,
175
+ );
176
+
177
+ expect(mockAdapter.executeReadQuery).toHaveBeenCalledWith(
178
+ "SELECT * FROM users",
179
+ undefined,
180
+ "txn-123",
181
+ );
37
182
  });
38
183
 
39
- it('should have core group for all tools', () => {
40
- for (const tool of tools) {
41
- expect(tool.group).toBe('core');
42
- }
184
+ it("should return structured error for nonexistent table", async () => {
185
+ mockAdapter.executeReadQuery.mockRejectedValue(
186
+ new Error("Table 'testdb.nonexistent' doesn't exist"),
187
+ );
188
+
189
+ const tool = tools.find((t) => t.name === "mysql_read_query")!;
190
+ const result = await tool.handler(
191
+ { query: "SELECT * FROM nonexistent" },
192
+ mockContext,
193
+ );
194
+
195
+ expect(result).toHaveProperty("success", false);
196
+ expect((result as Record<string, unknown>).error).toContain(
197
+ "doesn't exist",
198
+ );
43
199
  });
44
200
 
45
- it('should have handler functions for all tools', () => {
46
- for (const tool of tools) {
47
- expect(typeof tool.handler).toBe('function');
48
- }
201
+ it("should return structured error for non-table errors in read query", async () => {
202
+ mockAdapter.executeReadQuery.mockRejectedValue(
203
+ new Error("Access denied"),
204
+ );
205
+
206
+ const tool = tools.find((t) => t.name === "mysql_read_query")!;
207
+ const result = await tool.handler(
208
+ { query: "SELECT * FROM users" },
209
+ mockContext,
210
+ );
211
+
212
+ expect((result as Record<string, unknown>).success).toBe(false);
213
+ expect((result as Record<string, unknown>).error).toContain(
214
+ "Access denied",
215
+ );
216
+ });
217
+ });
218
+
219
+ describe("mysql_write_query", () => {
220
+ it("should execute write query and return affected rows", async () => {
221
+ mockAdapter.executeWriteQuery.mockResolvedValue({
222
+ rows: [],
223
+ rowsAffected: 5,
224
+ executionTimeMs: 10,
225
+ });
226
+
227
+ const tool = tools.find((t) => t.name === "mysql_write_query")!;
228
+ const result = await tool.handler(
229
+ { query: "UPDATE users SET status = 1" },
230
+ mockContext,
231
+ );
232
+
233
+ expect(mockAdapter.executeWriteQuery).toHaveBeenCalledWith(
234
+ "UPDATE users SET status = 1",
235
+ undefined,
236
+ undefined,
237
+ );
238
+ expect(result).toBeDefined();
49
239
  });
50
240
 
51
- it('should have inputSchema for all tools', () => {
52
- for (const tool of tools) {
53
- expect(tool.inputSchema).toBeDefined();
54
- }
241
+ it("should pass transactionId to executeWriteQuery when provided", async () => {
242
+ mockAdapter.executeWriteQuery.mockResolvedValue({
243
+ rows: [],
244
+ rowsAffected: 1,
245
+ executionTimeMs: 5,
246
+ });
247
+
248
+ const tool = tools.find((t) => t.name === "mysql_write_query")!;
249
+ await tool.handler(
250
+ { query: "INSERT INTO users VALUES (1)", transactionId: "txn-456" },
251
+ mockContext,
252
+ );
253
+
254
+ expect(mockAdapter.executeWriteQuery).toHaveBeenCalledWith(
255
+ "INSERT INTO users VALUES (1)",
256
+ undefined,
257
+ "txn-456",
258
+ );
55
259
  });
56
- });
57
260
 
58
- describe('Tool Annotations', () => {
59
- let tools: ReturnType<typeof getCoreTools>;
261
+ it("should return structured error for nonexistent table", async () => {
262
+ mockAdapter.executeWriteQuery.mockRejectedValue(
263
+ new Error("Table 'testdb.nonexistent' doesn't exist"),
264
+ );
265
+
266
+ const tool = tools.find((t) => t.name === "mysql_write_query")!;
267
+ const result = await tool.handler(
268
+ { query: "INSERT INTO nonexistent (id) VALUES (1)" },
269
+ mockContext,
270
+ );
271
+
272
+ expect(result).toHaveProperty("success", false);
273
+ expect((result as Record<string, unknown>).error).toContain(
274
+ "doesn't exist",
275
+ );
276
+ });
60
277
 
61
- beforeEach(() => {
62
- tools = getCoreTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
278
+ it("should return structured error for non-table errors in write query", async () => {
279
+ mockAdapter.executeWriteQuery.mockRejectedValue(
280
+ new Error("Access denied"),
281
+ );
282
+
283
+ const tool = tools.find((t) => t.name === "mysql_write_query")!;
284
+ const result = await tool.handler(
285
+ { query: "INSERT INTO users VALUES (1)" },
286
+ mockContext,
287
+ );
288
+
289
+ expect((result as Record<string, unknown>).success).toBe(false);
290
+ expect((result as Record<string, unknown>).error).toContain(
291
+ "Access denied",
292
+ );
63
293
  });
294
+ });
295
+
296
+ describe("mysql_list_tables", () => {
297
+ it("should call listTables adapter method", async () => {
298
+ const tool = tools.find((t) => t.name === "mysql_list_tables")!;
299
+ await tool.handler({}, mockContext);
64
300
 
65
- it('mysql_read_query should be read-only', () => {
66
- const tool = tools.find(t => t.name === 'mysql_read_query')!;
67
- expect(tool.annotations?.readOnlyHint).toBe(true);
301
+ expect(mockAdapter.listTables).toHaveBeenCalled();
68
302
  });
303
+ });
304
+
305
+ describe("mysql_describe_table", () => {
306
+ it("should call describeTable with table name", async () => {
307
+ const tool = tools.find((t) => t.name === "mysql_describe_table")!;
308
+ await tool.handler({ table: "users" }, mockContext);
69
309
 
70
- it('mysql_write_query should not be read-only', () => {
71
- const tool = tools.find(t => t.name === 'mysql_write_query')!;
72
- expect(tool.annotations?.readOnlyHint).toBe(false);
310
+ expect(mockAdapter.describeTable).toHaveBeenCalledWith("users");
73
311
  });
312
+ });
74
313
 
75
- it('mysql_list_tables should be read-only', () => {
76
- const tool = tools.find(t => t.name === 'mysql_list_tables')!;
77
- expect(tool.annotations?.readOnlyHint).toBe(true);
314
+ describe("mysql_get_indexes", () => {
315
+ it("should call getTableIndexes with table name", async () => {
316
+ const tool = tools.find((t) => t.name === "mysql_get_indexes")!;
317
+ await tool.handler({ table: "users" }, mockContext);
318
+
319
+ expect(mockAdapter.getTableIndexes).toHaveBeenCalledWith("users");
320
+ });
321
+ });
322
+
323
+ describe("mysql_create_table", () => {
324
+ it("should execute CREATE TABLE with columns", async () => {
325
+ mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
326
+
327
+ const tool = tools.find((t) => t.name === "mysql_create_table")!;
328
+ const result = await tool.handler(
329
+ {
330
+ name: "new_table",
331
+ columns: [
332
+ {
333
+ name: "id",
334
+ type: "INT",
335
+ primaryKey: true,
336
+ autoIncrement: true,
337
+ nullable: false,
338
+ },
339
+ { name: "name", type: "VARCHAR(255)", nullable: true },
340
+ ],
341
+ engine: "InnoDB",
342
+ charset: "utf8mb4",
343
+ collate: "utf8mb4_unicode_ci",
344
+ },
345
+ mockContext,
346
+ );
347
+
348
+ expect(mockAdapter.executeQuery).toHaveBeenCalled();
349
+ expect(result).toHaveProperty("success", true);
350
+ expect(result).toHaveProperty("tableName", "new_table");
78
351
  });
79
352
 
80
- it('mysql_describe_table should be read-only', () => {
81
- const tool = tools.find(t => t.name === 'mysql_describe_table')!;
82
- expect(tool.annotations?.readOnlyHint).toBe(true);
353
+ it("should handle column defaults correctly", async () => {
354
+ mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
355
+
356
+ const tool = tools.find((t) => t.name === "mysql_create_table")!;
357
+ await tool.handler(
358
+ {
359
+ name: "with_defaults",
360
+ columns: [
361
+ { name: "id", type: "INT", primaryKey: true },
362
+ {
363
+ name: "created_at",
364
+ type: "TIMESTAMP",
365
+ default: "CURRENT_TIMESTAMP",
366
+ },
367
+ { name: "status", type: "INT", default: 0 },
368
+ { name: "label", type: "VARCHAR(50)", default: "pending" },
369
+ ],
370
+ engine: "InnoDB",
371
+ charset: "utf8mb4",
372
+ collate: "utf8mb4_unicode_ci",
373
+ },
374
+ mockContext,
375
+ );
376
+
377
+ expect(mockAdapter.executeQuery).toHaveBeenCalled();
378
+ const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
379
+ expect(sqlCall).toContain("CURRENT_TIMESTAMP");
83
380
  });
84
381
 
85
- it('mysql_drop_table should be destructive', () => {
86
- const tool = tools.find(t => t.name === 'mysql_drop_table')!;
87
- expect(tool.annotations?.destructiveHint).toBe(true);
382
+ it("should handle IF NOT EXISTS clause", async () => {
383
+ mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
384
+
385
+ const tool = tools.find((t) => t.name === "mysql_create_table")!;
386
+ await tool.handler(
387
+ {
388
+ name: "test_table",
389
+ columns: [{ name: "id", type: "INT" }],
390
+ engine: "InnoDB",
391
+ charset: "utf8mb4",
392
+ collate: "utf8mb4_unicode_ci",
393
+ ifNotExists: true,
394
+ },
395
+ mockContext,
396
+ );
397
+
398
+ const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
399
+ expect(sqlCall).toContain("IF NOT EXISTS");
88
400
  });
89
401
 
90
- it('mysql_get_indexes should be read-only', () => {
91
- const tool = tools.find(t => t.name === 'mysql_get_indexes')!;
92
- expect(tool.annotations?.readOnlyHint).toBe(true);
402
+ it("should handle unique columns", async () => {
403
+ mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
404
+
405
+ const tool = tools.find((t) => t.name === "mysql_create_table")!;
406
+ await tool.handler(
407
+ {
408
+ name: "with_unique",
409
+ columns: [
410
+ { name: "id", type: "INT", primaryKey: true },
411
+ { name: "email", type: "VARCHAR(255)", unique: true },
412
+ ],
413
+ engine: "InnoDB",
414
+ charset: "utf8mb4",
415
+ collate: "utf8mb4_unicode_ci",
416
+ },
417
+ mockContext,
418
+ );
419
+
420
+ const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
421
+ expect(sqlCall).toContain("UNIQUE");
93
422
  });
94
- });
95
423
 
96
- describe('Required Scopes', () => {
97
- let tools: ReturnType<typeof getCoreTools>;
424
+ it("should handle qualified table names", async () => {
425
+ mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
426
+
427
+ const tool = tools.find((t) => t.name === "mysql_create_table")!;
428
+ const result = await tool.handler(
429
+ {
430
+ name: "db.table",
431
+ columns: [{ name: "id", type: "INT" }],
432
+ },
433
+ mockContext,
434
+ );
435
+
436
+ // First call should be USE statement
437
+ const useCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
438
+ expect(useCall).toBe("USE `db`");
439
+ // Second call should be CREATE TABLE
440
+ const sqlCall = mockAdapter.executeQuery.mock.calls[1]?.[0] as string;
441
+ expect(sqlCall).toContain("`db`.`table`");
442
+ expect(result).toHaveProperty("success", true);
443
+ });
98
444
 
99
- beforeEach(() => {
100
- tools = getCoreTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
445
+ it("should return graceful error when table already exists", async () => {
446
+ mockAdapter.executeQuery.mockRejectedValue(
447
+ new Error("Table 'test_table' already exists"),
448
+ );
449
+
450
+ const tool = tools.find((t) => t.name === "mysql_create_table")!;
451
+ const result = await tool.handler(
452
+ {
453
+ name: "test_table",
454
+ columns: [{ name: "id", type: "INT" }],
455
+ },
456
+ mockContext,
457
+ );
458
+
459
+ expect(result).toHaveProperty("success", false);
460
+ expect(result).toHaveProperty(
461
+ "reason",
462
+ "Table 'test_table' already exists",
463
+ );
101
464
  });
102
465
 
103
- it('read_query should require read scope', () => {
104
- const tool = tools.find(t => t.name === 'mysql_read_query')!;
105
- expect(tool.requiredScopes).toContain('read');
466
+ it("should re-throw non-existence errors in create table", async () => {
467
+ mockAdapter.executeQuery.mockRejectedValue(new Error("Access denied"));
468
+
469
+ const tool = tools.find((t) => t.name === "mysql_create_table")!;
470
+
471
+ await expect(
472
+ tool.handler(
473
+ {
474
+ name: "test_table",
475
+ columns: [{ name: "id", type: "INT" }],
476
+ },
477
+ mockContext,
478
+ ),
479
+ ).rejects.toThrow("Access denied");
106
480
  });
481
+ });
482
+
483
+ describe("mysql_drop_table", () => {
484
+ it("should execute DROP TABLE", async () => {
485
+ mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
486
+
487
+ const tool = tools.find((t) => t.name === "mysql_drop_table")!;
488
+ const result = await tool.handler({ table: "old_table" }, mockContext);
107
489
 
108
- it('write_query should require write scope', () => {
109
- const tool = tools.find(t => t.name === 'mysql_write_query')!;
110
- expect(tool.requiredScopes).toContain('write');
490
+ expect(mockAdapter.executeQuery).toHaveBeenCalled();
491
+ const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
492
+ expect(sqlCall).toContain("DROP TABLE");
493
+ expect(result).toHaveProperty("success", true);
111
494
  });
112
495
 
113
- it('drop_table should require admin scope', () => {
114
- const tool = tools.find(t => t.name === 'mysql_drop_table')!;
115
- expect(tool.requiredScopes?.some(s => s === 'write' || s === 'admin')).toBe(true);
496
+ it("should handle IF EXISTS clause", async () => {
497
+ mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
498
+
499
+ const tool = tools.find((t) => t.name === "mysql_drop_table")!;
500
+ await tool.handler({ table: "old_table", ifExists: true }, mockContext);
501
+
502
+ const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
503
+ expect(sqlCall).toContain("IF EXISTS");
116
504
  });
117
- });
118
505
 
119
- describe('Handler Execution', () => {
120
- let mockAdapter: ReturnType<typeof createMockMySQLAdapter>;
121
- let tools: ReturnType<typeof getCoreTools>;
122
- let mockContext: ReturnType<typeof createMockRequestContext>;
506
+ it("should reject invalid table names", async () => {
507
+ const tool = tools.find((t) => t.name === "mysql_drop_table")!;
123
508
 
124
- beforeEach(() => {
125
- vi.clearAllMocks();
126
- mockAdapter = createMockMySQLAdapter();
127
- tools = getCoreTools(mockAdapter as unknown as MySQLAdapter);
128
- mockContext = createMockRequestContext();
509
+ await expect(
510
+ tool.handler({ table: "invalid-name" }, mockContext),
511
+ ).rejects.toThrow("Invalid table name");
129
512
  });
130
513
 
131
- describe('mysql_read_query', () => {
132
- it('should execute read query and return result', async () => {
133
- const expectedResult = createMockQueryResult([{ id: 1, name: 'test' }]);
134
- mockAdapter.executeReadQuery.mockResolvedValue(expectedResult);
514
+ it("should handle qualified table names", async () => {
515
+ mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
516
+ const tool = tools.find((t) => t.name === "mysql_drop_table")!;
135
517
 
136
- const tool = tools.find(t => t.name === 'mysql_read_query')!;
137
- const result = await tool.handler({ query: 'SELECT * FROM users' }, mockContext);
518
+ await tool.handler({ table: "db.table" }, mockContext);
138
519
 
139
- expect(mockAdapter.executeReadQuery).toHaveBeenCalledWith('SELECT * FROM users', undefined, undefined);
140
- expect(result).toBeDefined();
141
- });
520
+ const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
521
+ expect(sqlCall).toContain("DROP TABLE IF EXISTS `db`.`table`");
522
+ });
142
523
 
143
- it('should pass parameters to executeReadQuery', async () => {
144
- const tool = tools.find(t => t.name === 'mysql_read_query')!;
145
- await tool.handler({ query: 'SELECT * FROM users WHERE id = ?', params: [1] }, mockContext);
524
+ it("should return graceful error when table does not exist", async () => {
525
+ mockAdapter.executeQuery.mockRejectedValue(
526
+ new Error("Unknown table 'testdb.nonexistent'"),
527
+ );
528
+
529
+ const tool = tools.find((t) => t.name === "mysql_drop_table")!;
530
+ const result = await tool.handler(
531
+ { table: "nonexistent", ifExists: false },
532
+ mockContext,
533
+ );
534
+
535
+ expect(result).toHaveProperty("success", false);
536
+ expect(result).toHaveProperty(
537
+ "reason",
538
+ "Table 'nonexistent' does not exist",
539
+ );
540
+ });
146
541
 
147
- expect(mockAdapter.executeReadQuery).toHaveBeenCalledWith('SELECT * FROM users WHERE id = ?', [1], undefined);
148
- });
542
+ it("should return skipped indicator when ifExists is true and table absent", async () => {
543
+ mockAdapter.describeTable.mockResolvedValue({ columns: [] });
544
+ mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
149
545
 
150
- it('should pass transactionId to executeReadQuery when provided', async () => {
151
- const tool = tools.find(t => t.name === 'mysql_read_query')!;
152
- await tool.handler({ query: 'SELECT * FROM users', transactionId: 'txn-123' }, mockContext);
546
+ const tool = tools.find((t) => t.name === "mysql_drop_table")!;
547
+ const result = await tool.handler(
548
+ { table: "absent_table", ifExists: true },
549
+ mockContext,
550
+ );
551
+
552
+ expect(result).toHaveProperty("success", true);
553
+ expect(result).toHaveProperty("skipped", true);
554
+ expect(result).toHaveProperty("reason", "Table did not exist");
555
+ });
556
+
557
+ it("should re-throw non-existence errors in drop table", async () => {
558
+ mockAdapter.executeQuery.mockRejectedValue(new Error("Access denied"));
559
+
560
+ const tool = tools.find((t) => t.name === "mysql_drop_table")!;
561
+
562
+ await expect(
563
+ tool.handler({ table: "some_table", ifExists: false }, mockContext),
564
+ ).rejects.toThrow("Access denied");
565
+ });
566
+ });
567
+
568
+ describe("mysql_create_index", () => {
569
+ it("should execute CREATE INDEX", async () => {
570
+ mockAdapter.getTableIndexes.mockResolvedValue([]);
571
+ mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
572
+
573
+ const tool = tools.find((t) => t.name === "mysql_create_index")!;
574
+ const result = await tool.handler(
575
+ {
576
+ name: "idx_users_email",
577
+ table: "users",
578
+ columns: ["email"],
579
+ },
580
+ mockContext,
581
+ );
582
+
583
+ expect(mockAdapter.executeQuery).toHaveBeenCalled();
584
+ expect(result).toHaveProperty("success", true);
585
+ expect(result).toHaveProperty("indexName", "idx_users_email");
586
+ });
587
+
588
+ it("should create UNIQUE index", async () => {
589
+ mockAdapter.getTableIndexes.mockResolvedValue([]);
590
+ mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
591
+
592
+ const tool = tools.find((t) => t.name === "mysql_create_index")!;
593
+ await tool.handler(
594
+ {
595
+ name: "idx_unique",
596
+ table: "users",
597
+ columns: ["email"],
598
+ unique: true,
599
+ },
600
+ mockContext,
601
+ );
602
+
603
+ const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
604
+ expect(sqlCall).toContain("UNIQUE");
605
+ });
606
+
607
+ it("should skip if index exists and ifNotExists is true", async () => {
608
+ mockAdapter.getTableIndexes.mockResolvedValue([
609
+ {
610
+ name: "idx_existing",
611
+ columns: ["col1"],
612
+ type: "BTREE",
613
+ unique: false,
614
+ },
615
+ ]);
616
+
617
+ const tool = tools.find((t) => t.name === "mysql_create_index")!;
618
+ const result = await tool.handler(
619
+ {
620
+ name: "idx_existing",
621
+ table: "users",
622
+ columns: ["col1"],
623
+ ifNotExists: true,
624
+ },
625
+ mockContext,
626
+ );
627
+
628
+ expect(result).toHaveProperty("skipped", true);
629
+ expect(mockAdapter.executeQuery).not.toHaveBeenCalled();
630
+ });
631
+
632
+ it("should reject invalid index names", async () => {
633
+ const tool = tools.find((t) => t.name === "mysql_create_index")!;
634
+
635
+ await expect(
636
+ tool.handler(
637
+ {
638
+ name: "invalid-name",
639
+ table: "users",
640
+ columns: ["email"],
641
+ },
642
+ mockContext,
643
+ ),
644
+ ).rejects.toThrow("Invalid index name");
645
+ });
646
+
647
+ it("should reject invalid table names", async () => {
648
+ const tool = tools.find((t) => t.name === "mysql_create_index")!;
649
+
650
+ await expect(
651
+ tool.handler(
652
+ {
653
+ name: "valid_name",
654
+ table: "invalid-table",
655
+ columns: ["email"],
656
+ },
657
+ mockContext,
658
+ ),
659
+ ).rejects.toThrow("Invalid table name");
660
+ });
661
+
662
+ it("should handle qualified table names", async () => {
663
+ mockAdapter.getTableIndexes.mockResolvedValue([]);
664
+ mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
665
+
666
+ const tool = tools.find((t) => t.name === "mysql_create_index")!;
667
+ await tool.handler(
668
+ {
669
+ name: "idx_test",
670
+ table: "db.table",
671
+ columns: ["id"],
672
+ },
673
+ mockContext,
674
+ );
675
+
676
+ const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
677
+ expect(sqlCall).toContain("ON `db`.`table`");
678
+ });
679
+
680
+ it("should include warning when HASH type is requested", async () => {
681
+ mockAdapter.getTableIndexes.mockResolvedValue([]);
682
+ mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
683
+
684
+ const tool = tools.find((t) => t.name === "mysql_create_index")!;
685
+ const result = await tool.handler(
686
+ {
687
+ name: "idx_hash",
688
+ table: "users",
689
+ columns: ["email"],
690
+ type: "HASH",
691
+ },
692
+ mockContext,
693
+ );
694
+
695
+ expect(result).toHaveProperty("success", true);
696
+ expect(result).toHaveProperty("warning");
697
+ expect((result as Record<string, unknown>).warning).toContain("MEMORY");
698
+ });
699
+
700
+ it("should return graceful error when duplicate index name exists", async () => {
701
+ mockAdapter.executeQuery.mockRejectedValue(
702
+ new Error("Duplicate key name 'idx_existing'"),
703
+ );
704
+
705
+ const tool = tools.find((t) => t.name === "mysql_create_index")!;
706
+ const result = await tool.handler(
707
+ {
708
+ name: "idx_existing",
709
+ table: "users",
710
+ columns: ["email"],
711
+ },
712
+ mockContext,
713
+ );
714
+
715
+ expect(result).toHaveProperty("success", false);
716
+ expect(result).toHaveProperty(
717
+ "reason",
718
+ "Index 'idx_existing' already exists on table 'users'",
719
+ );
720
+ });
153
721
 
154
- expect(mockAdapter.executeReadQuery).toHaveBeenCalledWith('SELECT * FROM users', undefined, 'txn-123');
155
- });
722
+ it("should return exists: false when table does not exist", async () => {
723
+ mockAdapter.executeQuery.mockRejectedValue(
724
+ new Error("Table 'testdb.nonexistent' doesn't exist"),
725
+ );
726
+
727
+ const tool = tools.find((t) => t.name === "mysql_create_index")!;
728
+ const result = await tool.handler(
729
+ {
730
+ name: "idx_test",
731
+ table: "nonexistent",
732
+ columns: ["col1"],
733
+ },
734
+ mockContext,
735
+ );
736
+
737
+ expect(result).toHaveProperty("exists", false);
738
+ expect(result).toHaveProperty("table", "nonexistent");
156
739
  });
157
740
 
158
- describe('mysql_write_query', () => {
159
- it('should execute write query and return affected rows', async () => {
160
- mockAdapter.executeWriteQuery.mockResolvedValue({
161
- rows: [],
162
- rowsAffected: 5,
163
- executionTimeMs: 10
164
- });
165
-
166
- const tool = tools.find(t => t.name === 'mysql_write_query')!;
167
- const result = await tool.handler({ query: 'UPDATE users SET status = 1' }, mockContext);
168
-
169
- expect(mockAdapter.executeWriteQuery).toHaveBeenCalledWith('UPDATE users SET status = 1', undefined, undefined);
170
- expect(result).toBeDefined();
171
- });
172
-
173
- it('should pass transactionId to executeWriteQuery when provided', async () => {
174
- mockAdapter.executeWriteQuery.mockResolvedValue({
175
- rows: [],
176
- rowsAffected: 1,
177
- executionTimeMs: 5
178
- });
179
-
180
- const tool = tools.find(t => t.name === 'mysql_write_query')!;
181
- await tool.handler({ query: 'INSERT INTO users VALUES (1)', transactionId: 'txn-456' }, mockContext);
182
-
183
- expect(mockAdapter.executeWriteQuery).toHaveBeenCalledWith('INSERT INTO users VALUES (1)', undefined, 'txn-456');
184
- });
185
- });
186
-
187
-
188
- describe('mysql_list_tables', () => {
189
- it('should call listTables adapter method', async () => {
190
- const tool = tools.find(t => t.name === 'mysql_list_tables')!;
191
- await tool.handler({}, mockContext);
192
-
193
- expect(mockAdapter.listTables).toHaveBeenCalled();
194
- });
195
- });
196
-
197
- describe('mysql_describe_table', () => {
198
- it('should call describeTable with table name', async () => {
199
- const tool = tools.find(t => t.name === 'mysql_describe_table')!;
200
- await tool.handler({ table: 'users' }, mockContext);
201
-
202
- expect(mockAdapter.describeTable).toHaveBeenCalledWith('users');
203
- });
204
- });
205
-
206
- describe('mysql_get_indexes', () => {
207
- it('should call getTableIndexes with table name', async () => {
208
- const tool = tools.find(t => t.name === 'mysql_get_indexes')!;
209
- await tool.handler({ table: 'users' }, mockContext);
210
-
211
- expect(mockAdapter.getTableIndexes).toHaveBeenCalledWith('users');
212
- });
213
- });
214
-
215
- describe('mysql_create_table', () => {
216
- it('should execute CREATE TABLE with columns', async () => {
217
- mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
218
-
219
- const tool = tools.find(t => t.name === 'mysql_create_table')!;
220
- const result = await tool.handler({
221
- name: 'new_table',
222
- columns: [
223
- { name: 'id', type: 'INT', primaryKey: true, autoIncrement: true, nullable: false },
224
- { name: 'name', type: 'VARCHAR(255)', nullable: true }
225
- ],
226
- engine: 'InnoDB',
227
- charset: 'utf8mb4',
228
- collate: 'utf8mb4_unicode_ci'
229
- }, mockContext);
230
-
231
- expect(mockAdapter.executeQuery).toHaveBeenCalled();
232
- expect(result).toHaveProperty('success', true);
233
- expect(result).toHaveProperty('tableName', 'new_table');
234
- });
235
-
236
- it('should handle column defaults correctly', async () => {
237
- mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
238
-
239
- const tool = tools.find(t => t.name === 'mysql_create_table')!;
240
- await tool.handler({
241
- name: 'with_defaults',
242
- columns: [
243
- { name: 'id', type: 'INT', primaryKey: true },
244
- { name: 'created_at', type: 'TIMESTAMP', default: 'CURRENT_TIMESTAMP' },
245
- { name: 'status', type: 'INT', default: 0 },
246
- { name: 'label', type: 'VARCHAR(50)', default: 'pending' }
247
- ],
248
- engine: 'InnoDB',
249
- charset: 'utf8mb4',
250
- collate: 'utf8mb4_unicode_ci'
251
- }, mockContext);
252
-
253
- expect(mockAdapter.executeQuery).toHaveBeenCalled();
254
- const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
255
- expect(sqlCall).toContain('CURRENT_TIMESTAMP');
256
- });
257
-
258
- it('should handle IF NOT EXISTS clause', async () => {
259
- mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
260
-
261
- const tool = tools.find(t => t.name === 'mysql_create_table')!;
262
- await tool.handler({
263
- name: 'test_table',
264
- columns: [{ name: 'id', type: 'INT' }],
265
- engine: 'InnoDB',
266
- charset: 'utf8mb4',
267
- collate: 'utf8mb4_unicode_ci',
268
- ifNotExists: true
269
- }, mockContext);
270
-
271
- const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
272
- expect(sqlCall).toContain('IF NOT EXISTS');
273
- });
274
-
275
- it('should handle unique columns', async () => {
276
- mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
277
-
278
- const tool = tools.find(t => t.name === 'mysql_create_table')!;
279
- await tool.handler({
280
- name: 'with_unique',
281
- columns: [
282
- { name: 'id', type: 'INT', primaryKey: true },
283
- { name: 'email', type: 'VARCHAR(255)', unique: true }
284
- ],
285
- engine: 'InnoDB',
286
- charset: 'utf8mb4',
287
- collate: 'utf8mb4_unicode_ci'
288
- }, mockContext);
289
-
290
- const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
291
- expect(sqlCall).toContain('UNIQUE');
292
- });
293
-
294
- it('should handle qualified table names', async () => {
295
- mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
296
-
297
- const tool = tools.find(t => t.name === 'mysql_create_table')!;
298
- const result = await tool.handler({
299
- name: 'db.table',
300
- columns: [{ name: 'id', type: 'INT' }]
301
- }, mockContext);
302
-
303
- // First call should be USE statement
304
- const useCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
305
- expect(useCall).toBe('USE `db`');
306
- // Second call should be CREATE TABLE
307
- const sqlCall = mockAdapter.executeQuery.mock.calls[1]?.[0] as string;
308
- expect(sqlCall).toContain('`db`.`table`');
309
- expect(result).toHaveProperty('success', true);
310
- });
311
-
312
- });
313
-
314
- describe('mysql_drop_table', () => {
315
- it('should execute DROP TABLE', async () => {
316
- mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
317
-
318
- const tool = tools.find(t => t.name === 'mysql_drop_table')!;
319
- const result = await tool.handler({ table: 'old_table' }, mockContext);
320
-
321
- expect(mockAdapter.executeQuery).toHaveBeenCalled();
322
- const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
323
- expect(sqlCall).toContain('DROP TABLE');
324
- expect(result).toHaveProperty('success', true);
325
- });
326
-
327
- it('should handle IF EXISTS clause', async () => {
328
- mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
329
-
330
- const tool = tools.find(t => t.name === 'mysql_drop_table')!;
331
- await tool.handler({ table: 'old_table', ifExists: true }, mockContext);
332
-
333
- const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
334
- expect(sqlCall).toContain('IF EXISTS');
335
- });
336
-
337
- it('should reject invalid table names', async () => {
338
- const tool = tools.find(t => t.name === 'mysql_drop_table')!;
339
-
340
- await expect(tool.handler({ table: 'invalid-name' }, mockContext)).rejects.toThrow('Invalid table name');
341
- });
342
-
343
- it('should handle qualified table names', async () => {
344
- mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
345
- const tool = tools.find(t => t.name === 'mysql_drop_table')!;
346
-
347
- await tool.handler({ table: 'db.table' }, mockContext);
348
-
349
- const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
350
- expect(sqlCall).toContain('DROP TABLE IF EXISTS `db`.`table`');
351
- });
352
- });
353
-
354
- describe('mysql_create_index', () => {
355
- it('should execute CREATE INDEX', async () => {
356
- mockAdapter.getTableIndexes.mockResolvedValue([]);
357
- mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
358
-
359
- const tool = tools.find(t => t.name === 'mysql_create_index')!;
360
- const result = await tool.handler({
361
- name: 'idx_users_email',
362
- table: 'users',
363
- columns: ['email']
364
- }, mockContext);
365
-
366
- expect(mockAdapter.executeQuery).toHaveBeenCalled();
367
- expect(result).toHaveProperty('success', true);
368
- expect(result).toHaveProperty('indexName', 'idx_users_email');
369
- });
370
-
371
- it('should create UNIQUE index', async () => {
372
- mockAdapter.getTableIndexes.mockResolvedValue([]);
373
- mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
374
-
375
- const tool = tools.find(t => t.name === 'mysql_create_index')!;
376
- await tool.handler({
377
- name: 'idx_unique',
378
- table: 'users',
379
- columns: ['email'],
380
- unique: true
381
- }, mockContext);
382
-
383
- const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
384
- expect(sqlCall).toContain('UNIQUE');
385
- });
386
-
387
- it('should skip if index exists and ifNotExists is true', async () => {
388
- mockAdapter.getTableIndexes.mockResolvedValue([
389
- { name: 'idx_existing', columns: ['col1'], type: 'BTREE', unique: false }
390
- ]);
391
-
392
- const tool = tools.find(t => t.name === 'mysql_create_index')!;
393
- const result = await tool.handler({
394
- name: 'idx_existing',
395
- table: 'users',
396
- columns: ['col1'],
397
- ifNotExists: true
398
- }, mockContext);
399
-
400
- expect(result).toHaveProperty('skipped', true);
401
- expect(mockAdapter.executeQuery).not.toHaveBeenCalled();
402
- });
403
-
404
- it('should reject invalid index names', async () => {
405
- const tool = tools.find(t => t.name === 'mysql_create_index')!;
406
-
407
- await expect(tool.handler({
408
- name: 'invalid-name',
409
- table: 'users',
410
- columns: ['email']
411
- }, mockContext)).rejects.toThrow('Invalid index name');
412
- });
413
-
414
- it('should reject invalid table names', async () => {
415
- const tool = tools.find(t => t.name === 'mysql_create_index')!;
416
-
417
- await expect(tool.handler({
418
- name: 'valid_name',
419
- table: 'invalid-table',
420
- columns: ['email']
421
- }, mockContext)).rejects.toThrow('Invalid table name');
422
- });
423
-
424
- it('should handle qualified table names', async () => {
425
- mockAdapter.getTableIndexes.mockResolvedValue([]);
426
- mockAdapter.executeQuery.mockResolvedValue({ rows: [], rowsAffected: 0 });
427
-
428
- const tool = tools.find(t => t.name === 'mysql_create_index')!;
429
- await tool.handler({
430
- name: 'idx_test',
431
- table: 'db.table',
432
- columns: ['id']
433
- }, mockContext);
434
-
435
- const sqlCall = mockAdapter.executeQuery.mock.calls[0]?.[0] as string;
436
- expect(sqlCall).toContain('ON `db`.`table`');
437
- });
741
+ it("should re-throw non-index errors in create index", async () => {
742
+ mockAdapter.executeQuery.mockRejectedValue(new Error("Access denied"));
743
+
744
+ const tool = tools.find((t) => t.name === "mysql_create_index")!;
745
+
746
+ await expect(
747
+ tool.handler(
748
+ {
749
+ name: "idx_test",
750
+ table: "users",
751
+ columns: ["email"],
752
+ },
753
+ mockContext,
754
+ ),
755
+ ).rejects.toThrow("Access denied");
438
756
  });
757
+ });
439
758
  });