@neverinfamous/mysql-mcp 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (751) hide show
  1. package/.env.example +14 -4
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +7 -1
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +6 -1
  4. package/.github/dependabot.yml +15 -0
  5. package/.github/pull_request_template.md +5 -0
  6. package/.github/workflows/codeql.yml +41 -42
  7. package/.github/workflows/docker-publish.yml +248 -210
  8. package/.github/workflows/publish-npm.yml +16 -6
  9. package/CHANGELOG.md +272 -22
  10. package/CODE_OF_CONDUCT.md +2 -0
  11. package/DOCKER_README.md +222 -156
  12. package/Dockerfile +2 -2
  13. package/README.md +210 -176
  14. package/SECURITY.md +0 -8
  15. package/VERSION +1 -1
  16. package/dist/__tests__/mocks/adapter.d.ts +3 -3
  17. package/dist/__tests__/mocks/adapter.d.ts.map +1 -1
  18. package/dist/__tests__/mocks/adapter.js +51 -35
  19. package/dist/__tests__/mocks/adapter.js.map +1 -1
  20. package/dist/__tests__/mocks/index.d.ts +4 -4
  21. package/dist/__tests__/mocks/index.d.ts.map +1 -1
  22. package/dist/__tests__/mocks/index.js +2 -2
  23. package/dist/__tests__/mocks/index.js.map +1 -1
  24. package/dist/__tests__/mocks/mysql.d.ts +2 -2
  25. package/dist/__tests__/mocks/mysql.d.ts.map +1 -1
  26. package/dist/__tests__/mocks/mysql.js +14 -14
  27. package/dist/__tests__/mocks/mysql.js.map +1 -1
  28. package/dist/__tests__/setup.d.ts.map +1 -1
  29. package/dist/__tests__/setup.js +7 -7
  30. package/dist/__tests__/setup.js.map +1 -1
  31. package/dist/adapters/DatabaseAdapter.d.ts +2 -2
  32. package/dist/adapters/DatabaseAdapter.d.ts.map +1 -1
  33. package/dist/adapters/DatabaseAdapter.js +69 -40
  34. package/dist/adapters/DatabaseAdapter.js.map +1 -1
  35. package/dist/adapters/mysql/MySQLAdapter.d.ts +10 -4
  36. package/dist/adapters/mysql/MySQLAdapter.d.ts.map +1 -1
  37. package/dist/adapters/mysql/MySQLAdapter.js +143 -116
  38. package/dist/adapters/mysql/MySQLAdapter.js.map +1 -1
  39. package/dist/adapters/mysql/SchemaManager.d.ts +1 -1
  40. package/dist/adapters/mysql/SchemaManager.d.ts.map +1 -1
  41. package/dist/adapters/mysql/SchemaManager.js +76 -56
  42. package/dist/adapters/mysql/SchemaManager.js.map +1 -1
  43. package/dist/adapters/mysql/index.d.ts +2 -2
  44. package/dist/adapters/mysql/index.js +2 -2
  45. package/dist/adapters/mysql/prompts/backupStrategy.d.ts +1 -1
  46. package/dist/adapters/mysql/prompts/backupStrategy.d.ts.map +1 -1
  47. package/dist/adapters/mysql/prompts/backupStrategy.js +21 -9
  48. package/dist/adapters/mysql/prompts/backupStrategy.js.map +1 -1
  49. package/dist/adapters/mysql/prompts/clusterSetup.d.ts +1 -1
  50. package/dist/adapters/mysql/prompts/clusterSetup.d.ts.map +1 -1
  51. package/dist/adapters/mysql/prompts/clusterSetup.js +3 -3
  52. package/dist/adapters/mysql/prompts/clusterSetup.js.map +1 -1
  53. package/dist/adapters/mysql/prompts/docstoreSetup.d.ts +1 -1
  54. package/dist/adapters/mysql/prompts/docstoreSetup.js +3 -3
  55. package/dist/adapters/mysql/prompts/docstoreSetup.js.map +1 -1
  56. package/dist/adapters/mysql/prompts/eventScheduler.d.ts +1 -1
  57. package/dist/adapters/mysql/prompts/eventScheduler.js +3 -3
  58. package/dist/adapters/mysql/prompts/eventScheduler.js.map +1 -1
  59. package/dist/adapters/mysql/prompts/healthCheck.d.ts +1 -1
  60. package/dist/adapters/mysql/prompts/healthCheck.d.ts.map +1 -1
  61. package/dist/adapters/mysql/prompts/healthCheck.js +10 -6
  62. package/dist/adapters/mysql/prompts/healthCheck.js.map +1 -1
  63. package/dist/adapters/mysql/prompts/index.d.ts +2 -2
  64. package/dist/adapters/mysql/prompts/index.d.ts.map +1 -1
  65. package/dist/adapters/mysql/prompts/index.js +98 -62
  66. package/dist/adapters/mysql/prompts/index.js.map +1 -1
  67. package/dist/adapters/mysql/prompts/indexTuning.d.ts +1 -1
  68. package/dist/adapters/mysql/prompts/indexTuning.d.ts.map +1 -1
  69. package/dist/adapters/mysql/prompts/indexTuning.js +11 -7
  70. package/dist/adapters/mysql/prompts/indexTuning.js.map +1 -1
  71. package/dist/adapters/mysql/prompts/mysqlshSetup.d.ts +1 -1
  72. package/dist/adapters/mysql/prompts/mysqlshSetup.js +4 -4
  73. package/dist/adapters/mysql/prompts/mysqlshSetup.js.map +1 -1
  74. package/dist/adapters/mysql/prompts/proxysqlSetup.d.ts +1 -1
  75. package/dist/adapters/mysql/prompts/proxysqlSetup.js +3 -3
  76. package/dist/adapters/mysql/prompts/proxysqlSetup.js.map +1 -1
  77. package/dist/adapters/mysql/prompts/replicationSetup.d.ts +1 -1
  78. package/dist/adapters/mysql/prompts/replicationSetup.d.ts.map +1 -1
  79. package/dist/adapters/mysql/prompts/replicationSetup.js +13 -7
  80. package/dist/adapters/mysql/prompts/replicationSetup.js.map +1 -1
  81. package/dist/adapters/mysql/prompts/routerSetup.d.ts +1 -1
  82. package/dist/adapters/mysql/prompts/routerSetup.js +3 -3
  83. package/dist/adapters/mysql/prompts/routerSetup.js.map +1 -1
  84. package/dist/adapters/mysql/prompts/spatialSetup.d.ts +1 -1
  85. package/dist/adapters/mysql/prompts/spatialSetup.js +3 -3
  86. package/dist/adapters/mysql/prompts/spatialSetup.js.map +1 -1
  87. package/dist/adapters/mysql/prompts/sysSchema.d.ts +1 -1
  88. package/dist/adapters/mysql/prompts/sysSchema.d.ts.map +1 -1
  89. package/dist/adapters/mysql/prompts/sysSchema.js +3 -3
  90. package/dist/adapters/mysql/prompts/sysSchema.js.map +1 -1
  91. package/dist/adapters/mysql/resources/capabilities.d.ts +2 -2
  92. package/dist/adapters/mysql/resources/capabilities.d.ts.map +1 -1
  93. package/dist/adapters/mysql/resources/capabilities.js +17 -15
  94. package/dist/adapters/mysql/resources/capabilities.js.map +1 -1
  95. package/dist/adapters/mysql/resources/cluster.d.ts +2 -2
  96. package/dist/adapters/mysql/resources/cluster.d.ts.map +1 -1
  97. package/dist/adapters/mysql/resources/cluster.js +17 -15
  98. package/dist/adapters/mysql/resources/cluster.js.map +1 -1
  99. package/dist/adapters/mysql/resources/docstore.d.ts +2 -2
  100. package/dist/adapters/mysql/resources/docstore.d.ts.map +1 -1
  101. package/dist/adapters/mysql/resources/docstore.js +12 -12
  102. package/dist/adapters/mysql/resources/docstore.js.map +1 -1
  103. package/dist/adapters/mysql/resources/events.d.ts +2 -2
  104. package/dist/adapters/mysql/resources/events.d.ts.map +1 -1
  105. package/dist/adapters/mysql/resources/events.js +12 -12
  106. package/dist/adapters/mysql/resources/events.js.map +1 -1
  107. package/dist/adapters/mysql/resources/health.d.ts +2 -2
  108. package/dist/adapters/mysql/resources/health.d.ts.map +1 -1
  109. package/dist/adapters/mysql/resources/health.js +36 -32
  110. package/dist/adapters/mysql/resources/health.js.map +1 -1
  111. package/dist/adapters/mysql/resources/index.d.ts +2 -2
  112. package/dist/adapters/mysql/resources/index.js +19 -19
  113. package/dist/adapters/mysql/resources/index.js.map +1 -1
  114. package/dist/adapters/mysql/resources/indexes.d.ts +2 -2
  115. package/dist/adapters/mysql/resources/indexes.d.ts.map +1 -1
  116. package/dist/adapters/mysql/resources/indexes.js +12 -12
  117. package/dist/adapters/mysql/resources/indexes.js.map +1 -1
  118. package/dist/adapters/mysql/resources/innodb.d.ts +2 -2
  119. package/dist/adapters/mysql/resources/innodb.d.ts.map +1 -1
  120. package/dist/adapters/mysql/resources/innodb.js +37 -36
  121. package/dist/adapters/mysql/resources/innodb.js.map +1 -1
  122. package/dist/adapters/mysql/resources/locks.d.ts +2 -2
  123. package/dist/adapters/mysql/resources/locks.d.ts.map +1 -1
  124. package/dist/adapters/mysql/resources/locks.js +14 -14
  125. package/dist/adapters/mysql/resources/locks.js.map +1 -1
  126. package/dist/adapters/mysql/resources/performance.d.ts +2 -2
  127. package/dist/adapters/mysql/resources/performance.d.ts.map +1 -1
  128. package/dist/adapters/mysql/resources/performance.js +30 -29
  129. package/dist/adapters/mysql/resources/performance.js.map +1 -1
  130. package/dist/adapters/mysql/resources/pool.d.ts +2 -2
  131. package/dist/adapters/mysql/resources/pool.d.ts.map +1 -1
  132. package/dist/adapters/mysql/resources/pool.js +9 -9
  133. package/dist/adapters/mysql/resources/pool.js.map +1 -1
  134. package/dist/adapters/mysql/resources/processlist.d.ts +2 -2
  135. package/dist/adapters/mysql/resources/processlist.d.ts.map +1 -1
  136. package/dist/adapters/mysql/resources/processlist.js +9 -9
  137. package/dist/adapters/mysql/resources/processlist.js.map +1 -1
  138. package/dist/adapters/mysql/resources/replication.d.ts +2 -2
  139. package/dist/adapters/mysql/resources/replication.d.ts.map +1 -1
  140. package/dist/adapters/mysql/resources/replication.js +42 -35
  141. package/dist/adapters/mysql/resources/replication.js.map +1 -1
  142. package/dist/adapters/mysql/resources/schema.d.ts +2 -2
  143. package/dist/adapters/mysql/resources/schema.d.ts.map +1 -1
  144. package/dist/adapters/mysql/resources/schema.js +8 -8
  145. package/dist/adapters/mysql/resources/schema.js.map +1 -1
  146. package/dist/adapters/mysql/resources/spatial.d.ts +2 -2
  147. package/dist/adapters/mysql/resources/spatial.d.ts.map +1 -1
  148. package/dist/adapters/mysql/resources/spatial.js +9 -9
  149. package/dist/adapters/mysql/resources/spatial.js.map +1 -1
  150. package/dist/adapters/mysql/resources/status.d.ts +2 -2
  151. package/dist/adapters/mysql/resources/status.d.ts.map +1 -1
  152. package/dist/adapters/mysql/resources/status.js +10 -10
  153. package/dist/adapters/mysql/resources/status.js.map +1 -1
  154. package/dist/adapters/mysql/resources/sysschema.d.ts +2 -2
  155. package/dist/adapters/mysql/resources/sysschema.d.ts.map +1 -1
  156. package/dist/adapters/mysql/resources/sysschema.js +10 -10
  157. package/dist/adapters/mysql/resources/sysschema.js.map +1 -1
  158. package/dist/adapters/mysql/resources/tables.d.ts +2 -2
  159. package/dist/adapters/mysql/resources/tables.d.ts.map +1 -1
  160. package/dist/adapters/mysql/resources/tables.js +8 -8
  161. package/dist/adapters/mysql/resources/tables.js.map +1 -1
  162. package/dist/adapters/mysql/resources/variables.d.ts +2 -2
  163. package/dist/adapters/mysql/resources/variables.d.ts.map +1 -1
  164. package/dist/adapters/mysql/resources/variables.js +10 -10
  165. package/dist/adapters/mysql/resources/variables.js.map +1 -1
  166. package/dist/adapters/mysql/tools/admin/backup.d.ts +2 -2
  167. package/dist/adapters/mysql/tools/admin/backup.d.ts.map +1 -1
  168. package/dist/adapters/mysql/tools/admin/backup.js +191 -99
  169. package/dist/adapters/mysql/tools/admin/backup.js.map +1 -1
  170. package/dist/adapters/mysql/tools/admin/index.d.ts +2 -2
  171. package/dist/adapters/mysql/tools/admin/index.js +6 -6
  172. package/dist/adapters/mysql/tools/admin/index.js.map +1 -1
  173. package/dist/adapters/mysql/tools/admin/maintenance.d.ts +2 -2
  174. package/dist/adapters/mysql/tools/admin/maintenance.d.ts.map +1 -1
  175. package/dist/adapters/mysql/tools/admin/maintenance.js +93 -62
  176. package/dist/adapters/mysql/tools/admin/maintenance.js.map +1 -1
  177. package/dist/adapters/mysql/tools/admin/monitoring.d.ts +2 -2
  178. package/dist/adapters/mysql/tools/admin/monitoring.d.ts.map +1 -1
  179. package/dist/adapters/mysql/tools/admin/monitoring.js +215 -79
  180. package/dist/adapters/mysql/tools/admin/monitoring.js.map +1 -1
  181. package/dist/adapters/mysql/tools/cluster/group-replication.d.ts +2 -2
  182. package/dist/adapters/mysql/tools/cluster/group-replication.d.ts.map +1 -1
  183. package/dist/adapters/mysql/tools/cluster/group-replication.js +90 -74
  184. package/dist/adapters/mysql/tools/cluster/group-replication.js.map +1 -1
  185. package/dist/adapters/mysql/tools/cluster/index.d.ts +2 -2
  186. package/dist/adapters/mysql/tools/cluster/index.js +3 -3
  187. package/dist/adapters/mysql/tools/cluster/index.js.map +1 -1
  188. package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts +2 -2
  189. package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts.map +1 -1
  190. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js +204 -97
  191. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js.map +1 -1
  192. package/dist/adapters/mysql/tools/core.d.ts +2 -2
  193. package/dist/adapters/mysql/tools/core.d.ts.map +1 -1
  194. package/dist/adapters/mysql/tools/core.js +205 -97
  195. package/dist/adapters/mysql/tools/core.js.map +1 -1
  196. package/dist/adapters/mysql/tools/docstore.d.ts +2 -2
  197. package/dist/adapters/mysql/tools/docstore.d.ts.map +1 -1
  198. package/dist/adapters/mysql/tools/docstore.js +252 -117
  199. package/dist/adapters/mysql/tools/docstore.js.map +1 -1
  200. package/dist/adapters/mysql/tools/events.d.ts +2 -2
  201. package/dist/adapters/mysql/tools/events.d.ts.map +1 -1
  202. package/dist/adapters/mysql/tools/events.js +219 -108
  203. package/dist/adapters/mysql/tools/events.js.map +1 -1
  204. package/dist/adapters/mysql/tools/index.d.ts +19 -19
  205. package/dist/adapters/mysql/tools/index.d.ts.map +1 -1
  206. package/dist/adapters/mysql/tools/index.js +19 -19
  207. package/dist/adapters/mysql/tools/index.js.map +1 -1
  208. package/dist/adapters/mysql/tools/json/core.d.ts +2 -2
  209. package/dist/adapters/mysql/tools/json/core.d.ts.map +1 -1
  210. package/dist/adapters/mysql/tools/json/core.js +221 -127
  211. package/dist/adapters/mysql/tools/json/core.js.map +1 -1
  212. package/dist/adapters/mysql/tools/json/enhanced.d.ts +2 -2
  213. package/dist/adapters/mysql/tools/json/enhanced.d.ts.map +1 -1
  214. package/dist/adapters/mysql/tools/json/enhanced.js +274 -163
  215. package/dist/adapters/mysql/tools/json/enhanced.js.map +1 -1
  216. package/dist/adapters/mysql/tools/json/helpers.d.ts +2 -2
  217. package/dist/adapters/mysql/tools/json/helpers.d.ts.map +1 -1
  218. package/dist/adapters/mysql/tools/json/helpers.js +134 -56
  219. package/dist/adapters/mysql/tools/json/helpers.js.map +1 -1
  220. package/dist/adapters/mysql/tools/json/index.d.ts +2 -2
  221. package/dist/adapters/mysql/tools/json/index.js +6 -6
  222. package/dist/adapters/mysql/tools/json/index.js.map +1 -1
  223. package/dist/adapters/mysql/tools/partitioning.d.ts +2 -2
  224. package/dist/adapters/mysql/tools/partitioning.js +143 -59
  225. package/dist/adapters/mysql/tools/partitioning.js.map +1 -1
  226. package/dist/adapters/mysql/tools/performance/analysis.d.ts +2 -2
  227. package/dist/adapters/mysql/tools/performance/analysis.d.ts.map +1 -1
  228. package/dist/adapters/mysql/tools/performance/analysis.js +122 -86
  229. package/dist/adapters/mysql/tools/performance/analysis.js.map +1 -1
  230. package/dist/adapters/mysql/tools/performance/index.d.ts +2 -2
  231. package/dist/adapters/mysql/tools/performance/index.js +4 -4
  232. package/dist/adapters/mysql/tools/performance/index.js.map +1 -1
  233. package/dist/adapters/mysql/tools/performance/optimization.d.ts +3 -3
  234. package/dist/adapters/mysql/tools/performance/optimization.d.ts.map +1 -1
  235. package/dist/adapters/mysql/tools/performance/optimization.js +195 -73
  236. package/dist/adapters/mysql/tools/performance/optimization.js.map +1 -1
  237. package/dist/adapters/mysql/tools/proxysql.d.ts +2 -2
  238. package/dist/adapters/mysql/tools/proxysql.d.ts.map +1 -1
  239. package/dist/adapters/mysql/tools/proxysql.js +213 -125
  240. package/dist/adapters/mysql/tools/proxysql.js.map +1 -1
  241. package/dist/adapters/mysql/tools/replication.d.ts +2 -2
  242. package/dist/adapters/mysql/tools/replication.d.ts.map +1 -1
  243. package/dist/adapters/mysql/tools/replication.js +117 -66
  244. package/dist/adapters/mysql/tools/replication.js.map +1 -1
  245. package/dist/adapters/mysql/tools/roles.d.ts +2 -2
  246. package/dist/adapters/mysql/tools/roles.d.ts.map +1 -1
  247. package/dist/adapters/mysql/tools/roles.js +276 -84
  248. package/dist/adapters/mysql/tools/roles.js.map +1 -1
  249. package/dist/adapters/mysql/tools/router.d.ts +2 -2
  250. package/dist/adapters/mysql/tools/router.d.ts.map +1 -1
  251. package/dist/adapters/mysql/tools/router.js +174 -109
  252. package/dist/adapters/mysql/tools/router.js.map +1 -1
  253. package/dist/adapters/mysql/tools/schema/constraints.d.ts +2 -2
  254. package/dist/adapters/mysql/tools/schema/constraints.d.ts.map +1 -1
  255. package/dist/adapters/mysql/tools/schema/constraints.js +24 -15
  256. package/dist/adapters/mysql/tools/schema/constraints.js.map +1 -1
  257. package/dist/adapters/mysql/tools/schema/index.d.ts +2 -2
  258. package/dist/adapters/mysql/tools/schema/index.d.ts.map +1 -1
  259. package/dist/adapters/mysql/tools/schema/index.js +7 -7
  260. package/dist/adapters/mysql/tools/schema/index.js.map +1 -1
  261. package/dist/adapters/mysql/tools/schema/management.d.ts +2 -2
  262. package/dist/adapters/mysql/tools/schema/management.d.ts.map +1 -1
  263. package/dist/adapters/mysql/tools/schema/management.js +99 -42
  264. package/dist/adapters/mysql/tools/schema/management.js.map +1 -1
  265. package/dist/adapters/mysql/tools/schema/routines.d.ts +2 -2
  266. package/dist/adapters/mysql/tools/schema/routines.d.ts.map +1 -1
  267. package/dist/adapters/mysql/tools/schema/routines.js +36 -19
  268. package/dist/adapters/mysql/tools/schema/routines.js.map +1 -1
  269. package/dist/adapters/mysql/tools/schema/scheduled_events.d.ts +2 -2
  270. package/dist/adapters/mysql/tools/schema/scheduled_events.d.ts.map +1 -1
  271. package/dist/adapters/mysql/tools/schema/scheduled_events.js +26 -13
  272. package/dist/adapters/mysql/tools/schema/scheduled_events.js.map +1 -1
  273. package/dist/adapters/mysql/tools/schema/triggers.d.ts +2 -2
  274. package/dist/adapters/mysql/tools/schema/triggers.d.ts.map +1 -1
  275. package/dist/adapters/mysql/tools/schema/triggers.js +24 -13
  276. package/dist/adapters/mysql/tools/schema/triggers.js.map +1 -1
  277. package/dist/adapters/mysql/tools/schema/views.d.ts +2 -2
  278. package/dist/adapters/mysql/tools/schema/views.d.ts.map +1 -1
  279. package/dist/adapters/mysql/tools/schema/views.js +59 -28
  280. package/dist/adapters/mysql/tools/schema/views.js.map +1 -1
  281. package/dist/adapters/mysql/tools/security/audit.d.ts +2 -2
  282. package/dist/adapters/mysql/tools/security/audit.d.ts.map +1 -1
  283. package/dist/adapters/mysql/tools/security/audit.js +61 -55
  284. package/dist/adapters/mysql/tools/security/audit.js.map +1 -1
  285. package/dist/adapters/mysql/tools/security/data-protection.d.ts +2 -2
  286. package/dist/adapters/mysql/tools/security/data-protection.d.ts.map +1 -1
  287. package/dist/adapters/mysql/tools/security/data-protection.js +188 -80
  288. package/dist/adapters/mysql/tools/security/data-protection.js.map +1 -1
  289. package/dist/adapters/mysql/tools/security/encryption.d.ts +2 -2
  290. package/dist/adapters/mysql/tools/security/encryption.d.ts.map +1 -1
  291. package/dist/adapters/mysql/tools/security/encryption.js +86 -67
  292. package/dist/adapters/mysql/tools/security/encryption.js.map +1 -1
  293. package/dist/adapters/mysql/tools/security/index.d.ts +2 -2
  294. package/dist/adapters/mysql/tools/security/index.js +4 -4
  295. package/dist/adapters/mysql/tools/security/index.js.map +1 -1
  296. package/dist/adapters/mysql/tools/shell/backup.d.ts +1 -1
  297. package/dist/adapters/mysql/tools/shell/backup.d.ts.map +1 -1
  298. package/dist/adapters/mysql/tools/shell/backup.js +122 -63
  299. package/dist/adapters/mysql/tools/shell/backup.js.map +1 -1
  300. package/dist/adapters/mysql/tools/shell/common.d.ts.map +1 -1
  301. package/dist/adapters/mysql/tools/shell/common.js +34 -36
  302. package/dist/adapters/mysql/tools/shell/common.js.map +1 -1
  303. package/dist/adapters/mysql/tools/shell/data-transfer.d.ts +1 -1
  304. package/dist/adapters/mysql/tools/shell/data-transfer.d.ts.map +1 -1
  305. package/dist/adapters/mysql/tools/shell/data-transfer.js +125 -69
  306. package/dist/adapters/mysql/tools/shell/data-transfer.js.map +1 -1
  307. package/dist/adapters/mysql/tools/shell/index.d.ts +2 -2
  308. package/dist/adapters/mysql/tools/shell/index.js +6 -6
  309. package/dist/adapters/mysql/tools/shell/index.js.map +1 -1
  310. package/dist/adapters/mysql/tools/shell/info.d.ts +1 -1
  311. package/dist/adapters/mysql/tools/shell/info.d.ts.map +1 -1
  312. package/dist/adapters/mysql/tools/shell/info.js +12 -12
  313. package/dist/adapters/mysql/tools/shell/info.js.map +1 -1
  314. package/dist/adapters/mysql/tools/shell/restore.d.ts +1 -1
  315. package/dist/adapters/mysql/tools/shell/restore.d.ts.map +1 -1
  316. package/dist/adapters/mysql/tools/shell/restore.js +77 -42
  317. package/dist/adapters/mysql/tools/shell/restore.js.map +1 -1
  318. package/dist/adapters/mysql/tools/shell/utilities.d.ts +1 -1
  319. package/dist/adapters/mysql/tools/shell/utilities.d.ts.map +1 -1
  320. package/dist/adapters/mysql/tools/shell/utilities.js +42 -18
  321. package/dist/adapters/mysql/tools/shell/utilities.js.map +1 -1
  322. package/dist/adapters/mysql/tools/spatial/geometry.d.ts +2 -2
  323. package/dist/adapters/mysql/tools/spatial/geometry.d.ts.map +1 -1
  324. package/dist/adapters/mysql/tools/spatial/geometry.js +85 -46
  325. package/dist/adapters/mysql/tools/spatial/geometry.js.map +1 -1
  326. package/dist/adapters/mysql/tools/spatial/index.d.ts +2 -2
  327. package/dist/adapters/mysql/tools/spatial/index.js +5 -5
  328. package/dist/adapters/mysql/tools/spatial/index.js.map +1 -1
  329. package/dist/adapters/mysql/tools/spatial/operations.d.ts +2 -2
  330. package/dist/adapters/mysql/tools/spatial/operations.d.ts.map +1 -1
  331. package/dist/adapters/mysql/tools/spatial/operations.js +167 -106
  332. package/dist/adapters/mysql/tools/spatial/operations.js.map +1 -1
  333. package/dist/adapters/mysql/tools/spatial/queries.d.ts +2 -2
  334. package/dist/adapters/mysql/tools/spatial/queries.d.ts.map +1 -1
  335. package/dist/adapters/mysql/tools/spatial/queries.js +144 -100
  336. package/dist/adapters/mysql/tools/spatial/queries.js.map +1 -1
  337. package/dist/adapters/mysql/tools/spatial/setup.d.ts +2 -2
  338. package/dist/adapters/mysql/tools/spatial/setup.d.ts.map +1 -1
  339. package/dist/adapters/mysql/tools/spatial/setup.js +104 -34
  340. package/dist/adapters/mysql/tools/spatial/setup.js.map +1 -1
  341. package/dist/adapters/mysql/tools/stats/comparative.d.ts +2 -2
  342. package/dist/adapters/mysql/tools/stats/comparative.d.ts.map +1 -1
  343. package/dist/adapters/mysql/tools/stats/comparative.js +159 -107
  344. package/dist/adapters/mysql/tools/stats/comparative.js.map +1 -1
  345. package/dist/adapters/mysql/tools/stats/descriptive.d.ts +2 -2
  346. package/dist/adapters/mysql/tools/stats/descriptive.d.ts.map +1 -1
  347. package/dist/adapters/mysql/tools/stats/descriptive.js +268 -205
  348. package/dist/adapters/mysql/tools/stats/descriptive.js.map +1 -1
  349. package/dist/adapters/mysql/tools/stats/index.d.ts +2 -2
  350. package/dist/adapters/mysql/tools/stats/index.js +3 -3
  351. package/dist/adapters/mysql/tools/stats/index.js.map +1 -1
  352. package/dist/adapters/mysql/tools/sysschema/activity.d.ts +2 -2
  353. package/dist/adapters/mysql/tools/sysschema/activity.d.ts.map +1 -1
  354. package/dist/adapters/mysql/tools/sysschema/activity.js +23 -23
  355. package/dist/adapters/mysql/tools/sysschema/activity.js.map +1 -1
  356. package/dist/adapters/mysql/tools/sysschema/index.d.ts +2 -2
  357. package/dist/adapters/mysql/tools/sysschema/index.js +4 -4
  358. package/dist/adapters/mysql/tools/sysschema/index.js.map +1 -1
  359. package/dist/adapters/mysql/tools/sysschema/performance.d.ts +2 -2
  360. package/dist/adapters/mysql/tools/sysschema/performance.d.ts.map +1 -1
  361. package/dist/adapters/mysql/tools/sysschema/performance.js +58 -43
  362. package/dist/adapters/mysql/tools/sysschema/performance.js.map +1 -1
  363. package/dist/adapters/mysql/tools/sysschema/resources.d.ts +2 -2
  364. package/dist/adapters/mysql/tools/sysschema/resources.d.ts.map +1 -1
  365. package/dist/adapters/mysql/tools/sysschema/resources.js +53 -33
  366. package/dist/adapters/mysql/tools/sysschema/resources.js.map +1 -1
  367. package/dist/adapters/mysql/tools/text/fulltext.d.ts +4 -3
  368. package/dist/adapters/mysql/tools/text/fulltext.d.ts.map +1 -1
  369. package/dist/adapters/mysql/tools/text/fulltext.js +211 -54
  370. package/dist/adapters/mysql/tools/text/fulltext.js.map +1 -1
  371. package/dist/adapters/mysql/tools/text/index.d.ts +3 -3
  372. package/dist/adapters/mysql/tools/text/index.d.ts.map +1 -1
  373. package/dist/adapters/mysql/tools/text/index.js +6 -5
  374. package/dist/adapters/mysql/tools/text/index.js.map +1 -1
  375. package/dist/adapters/mysql/tools/text/processing.d.ts +2 -2
  376. package/dist/adapters/mysql/tools/text/processing.d.ts.map +1 -1
  377. package/dist/adapters/mysql/tools/text/processing.js +191 -103
  378. package/dist/adapters/mysql/tools/text/processing.js.map +1 -1
  379. package/dist/adapters/mysql/tools/transactions.d.ts +2 -2
  380. package/dist/adapters/mysql/tools/transactions.js +156 -79
  381. package/dist/adapters/mysql/tools/transactions.js.map +1 -1
  382. package/dist/adapters/mysql/types/proxysql-types.d.ts +7 -2
  383. package/dist/adapters/mysql/types/proxysql-types.d.ts.map +1 -1
  384. package/dist/adapters/mysql/types/proxysql-types.js +52 -30
  385. package/dist/adapters/mysql/types/proxysql-types.js.map +1 -1
  386. package/dist/adapters/mysql/types/router-types.d.ts +1 -1
  387. package/dist/adapters/mysql/types/router-types.js +17 -17
  388. package/dist/adapters/mysql/types/router-types.js.map +1 -1
  389. package/dist/adapters/mysql/types/shell-types.d.ts +1 -2
  390. package/dist/adapters/mysql/types/shell-types.d.ts.map +1 -1
  391. package/dist/adapters/mysql/types/shell-types.js +255 -82
  392. package/dist/adapters/mysql/types/shell-types.js.map +1 -1
  393. package/dist/adapters/mysql/types.d.ts +8 -2
  394. package/dist/adapters/mysql/types.d.ts.map +1 -1
  395. package/dist/adapters/mysql/types.js +269 -128
  396. package/dist/adapters/mysql/types.js.map +1 -1
  397. package/dist/auth/AuthorizationServerDiscovery.d.ts +1 -1
  398. package/dist/auth/AuthorizationServerDiscovery.d.ts.map +1 -1
  399. package/dist/auth/AuthorizationServerDiscovery.js +16 -14
  400. package/dist/auth/AuthorizationServerDiscovery.js.map +1 -1
  401. package/dist/auth/OAuthResourceServer.d.ts +1 -1
  402. package/dist/auth/OAuthResourceServer.d.ts.map +1 -1
  403. package/dist/auth/OAuthResourceServer.js +4 -4
  404. package/dist/auth/OAuthResourceServer.js.map +1 -1
  405. package/dist/auth/TokenValidator.d.ts +1 -1
  406. package/dist/auth/TokenValidator.d.ts.map +1 -1
  407. package/dist/auth/TokenValidator.js +30 -20
  408. package/dist/auth/TokenValidator.js.map +1 -1
  409. package/dist/auth/errors.d.ts.map +1 -1
  410. package/dist/auth/errors.js +24 -24
  411. package/dist/auth/errors.js.map +1 -1
  412. package/dist/auth/index.d.ts +7 -7
  413. package/dist/auth/index.d.ts.map +1 -1
  414. package/dist/auth/index.js +6 -6
  415. package/dist/auth/index.js.map +1 -1
  416. package/dist/auth/middleware.d.ts +2 -2
  417. package/dist/auth/middleware.d.ts.map +1 -1
  418. package/dist/auth/middleware.js +28 -24
  419. package/dist/auth/middleware.js.map +1 -1
  420. package/dist/auth/scopes.d.ts +2 -2
  421. package/dist/auth/scopes.d.ts.map +1 -1
  422. package/dist/auth/scopes.js +22 -16
  423. package/dist/auth/scopes.js.map +1 -1
  424. package/dist/auth/types.d.ts +2 -2
  425. package/dist/auth/types.d.ts.map +1 -1
  426. package/dist/cli/args.d.ts +1 -1
  427. package/dist/cli/args.d.ts.map +1 -1
  428. package/dist/cli/args.js +70 -68
  429. package/dist/cli/args.js.map +1 -1
  430. package/dist/cli.d.ts +1 -1
  431. package/dist/cli.d.ts.map +1 -1
  432. package/dist/cli.js +44 -34
  433. package/dist/cli.js.map +1 -1
  434. package/dist/constants/ServerInstructions.d.ts +2 -2
  435. package/dist/constants/ServerInstructions.d.ts.map +1 -1
  436. package/dist/constants/ServerInstructions.js +228 -36
  437. package/dist/constants/ServerInstructions.js.map +1 -1
  438. package/dist/filtering/ToolConstants.d.ts +6 -6
  439. package/dist/filtering/ToolConstants.d.ts.map +1 -1
  440. package/dist/filtering/ToolConstants.js +229 -208
  441. package/dist/filtering/ToolConstants.js.map +1 -1
  442. package/dist/filtering/ToolFilter.d.ts +2 -2
  443. package/dist/filtering/ToolFilter.d.ts.map +1 -1
  444. package/dist/filtering/ToolFilter.js +35 -36
  445. package/dist/filtering/ToolFilter.js.map +1 -1
  446. package/dist/index.d.ts +9 -9
  447. package/dist/index.d.ts.map +1 -1
  448. package/dist/index.js +7 -7
  449. package/dist/index.js.map +1 -1
  450. package/dist/logging/McpLogging.d.ts +2 -2
  451. package/dist/logging/McpLogging.d.ts.map +1 -1
  452. package/dist/logging/McpLogging.js +16 -13
  453. package/dist/logging/McpLogging.js.map +1 -1
  454. package/dist/logging/index.d.ts +1 -1
  455. package/dist/logging/index.js +1 -1
  456. package/dist/pool/ConnectionPool.d.ts +3 -3
  457. package/dist/pool/ConnectionPool.d.ts.map +1 -1
  458. package/dist/pool/ConnectionPool.js +30 -26
  459. package/dist/pool/ConnectionPool.js.map +1 -1
  460. package/dist/progress/ProgressReporter.d.ts +1 -1
  461. package/dist/progress/ProgressReporter.d.ts.map +1 -1
  462. package/dist/progress/ProgressReporter.js +5 -5
  463. package/dist/progress/ProgressReporter.js.map +1 -1
  464. package/dist/progress/index.d.ts +1 -1
  465. package/dist/progress/index.d.ts.map +1 -1
  466. package/dist/progress/index.js +1 -1
  467. package/dist/progress/index.js.map +1 -1
  468. package/dist/server/McpServer.d.ts +3 -3
  469. package/dist/server/McpServer.d.ts.map +1 -1
  470. package/dist/server/McpServer.js +58 -53
  471. package/dist/server/McpServer.js.map +1 -1
  472. package/dist/transports/http.d.ts +3 -3
  473. package/dist/transports/http.d.ts.map +1 -1
  474. package/dist/transports/http.js +36 -33
  475. package/dist/transports/http.js.map +1 -1
  476. package/dist/transports/index.d.ts +1 -1
  477. package/dist/transports/index.d.ts.map +1 -1
  478. package/dist/transports/index.js +1 -1
  479. package/dist/transports/index.js.map +1 -1
  480. package/dist/types/index.d.ts +6 -6
  481. package/dist/types/index.d.ts.map +1 -1
  482. package/dist/types/index.js +1 -1
  483. package/dist/types/index.js.map +1 -1
  484. package/dist/types/modules/database.d.ts +1 -1
  485. package/dist/types/modules/database.d.ts.map +1 -1
  486. package/dist/types/modules/errors.d.ts.map +1 -1
  487. package/dist/types/modules/errors.js +15 -15
  488. package/dist/types/modules/errors.js.map +1 -1
  489. package/dist/types/modules/oauth.d.ts +1 -1
  490. package/dist/types/modules/oauth.d.ts.map +1 -1
  491. package/dist/types/modules/query.d.ts +8 -8
  492. package/dist/types/modules/query.d.ts.map +1 -1
  493. package/dist/types/modules/server.d.ts +3 -3
  494. package/dist/types/modules/server.d.ts.map +1 -1
  495. package/dist/types/modules/tools.d.ts +6 -6
  496. package/dist/types/modules/tools.d.ts.map +1 -1
  497. package/dist/utils/logger.d.ts +2 -2
  498. package/dist/utils/logger.d.ts.map +1 -1
  499. package/dist/utils/logger.js +58 -55
  500. package/dist/utils/logger.js.map +1 -1
  501. package/dist/utils/promptGenerator.d.ts +1 -1
  502. package/dist/utils/promptGenerator.d.ts.map +1 -1
  503. package/dist/utils/promptGenerator.js +24 -16
  504. package/dist/utils/promptGenerator.js.map +1 -1
  505. package/dist/utils/validators.d.ts +21 -2
  506. package/dist/utils/validators.d.ts.map +1 -1
  507. package/dist/utils/validators.js +101 -13
  508. package/dist/utils/validators.js.map +1 -1
  509. package/eslint.config.js +117 -81
  510. package/package.json +61 -64
  511. package/releases/release-notes.md +32 -26
  512. package/releases/v2.0.0-release-notes.md +99 -51
  513. package/releases/v2.1.0-release-notes.md +14 -5
  514. package/releases/v2.2.0-release-notes.md +239 -0
  515. package/server.json +1 -1
  516. package/src/__tests__/cli.test.ts +302 -247
  517. package/src/__tests__/index.test.ts +21 -21
  518. package/src/__tests__/mocks/adapter.ts +204 -163
  519. package/src/__tests__/mocks/index.ts +30 -23
  520. package/src/__tests__/mocks/mysql.ts +94 -84
  521. package/src/__tests__/perf.test.ts +207 -203
  522. package/src/__tests__/performance.test.ts +173 -164
  523. package/src/__tests__/setup.ts +26 -21
  524. package/src/adapters/DatabaseAdapter.ts +386 -340
  525. package/src/adapters/__tests__/DatabaseAdapter.test.ts +455 -377
  526. package/src/adapters/mysql/MySQLAdapter.ts +550 -486
  527. package/src/adapters/mysql/SchemaManager.ts +251 -208
  528. package/src/adapters/mysql/__tests__/MySQLAdapter.integration.test.ts +150 -147
  529. package/src/adapters/mysql/__tests__/MySQLAdapter.test.ts +590 -477
  530. package/src/adapters/mysql/__tests__/SchemaManager.test.ts +196 -154
  531. package/src/adapters/mysql/index.ts +2 -2
  532. package/src/adapters/mysql/prompts/__tests__/indexTuning.test.ts +33 -26
  533. package/src/adapters/mysql/prompts/__tests__/prompts.test.ts +277 -239
  534. package/src/adapters/mysql/prompts/backupStrategy.ts +29 -17
  535. package/src/adapters/mysql/prompts/clusterSetup.ts +11 -10
  536. package/src/adapters/mysql/prompts/docstoreSetup.ts +10 -10
  537. package/src/adapters/mysql/prompts/eventScheduler.ts +10 -10
  538. package/src/adapters/mysql/prompts/healthCheck.ts +20 -15
  539. package/src/adapters/mysql/prompts/index.ts +194 -144
  540. package/src/adapters/mysql/prompts/indexTuning.ts +22 -17
  541. package/src/adapters/mysql/prompts/mysqlshSetup.ts +11 -11
  542. package/src/adapters/mysql/prompts/proxysqlSetup.ts +10 -10
  543. package/src/adapters/mysql/prompts/replicationSetup.ts +24 -16
  544. package/src/adapters/mysql/prompts/routerSetup.ts +10 -10
  545. package/src/adapters/mysql/prompts/spatialSetup.ts +10 -10
  546. package/src/adapters/mysql/prompts/sysSchema.ts +11 -10
  547. package/src/adapters/mysql/resources/__tests__/capabilities.test.ts +69 -47
  548. package/src/adapters/mysql/resources/__tests__/cluster.test.ts +163 -104
  549. package/src/adapters/mysql/resources/__tests__/docstore.test.ts +88 -81
  550. package/src/adapters/mysql/resources/__tests__/events.test.ts +94 -83
  551. package/src/adapters/mysql/resources/__tests__/health.test.ts +131 -91
  552. package/src/adapters/mysql/resources/__tests__/indexes.test.ts +125 -102
  553. package/src/adapters/mysql/resources/__tests__/innodb.test.ts +86 -62
  554. package/src/adapters/mysql/resources/__tests__/locks.test.ts +142 -104
  555. package/src/adapters/mysql/resources/__tests__/performance.test.ts +81 -58
  556. package/src/adapters/mysql/resources/__tests__/pool.test.ts +45 -40
  557. package/src/adapters/mysql/resources/__tests__/processlist.test.ts +39 -23
  558. package/src/adapters/mysql/resources/__tests__/replication.test.ts +265 -211
  559. package/src/adapters/mysql/resources/__tests__/resources.test.ts +121 -109
  560. package/src/adapters/mysql/resources/__tests__/schema.test.ts +29 -23
  561. package/src/adapters/mysql/resources/__tests__/spatial.test.ts +58 -45
  562. package/src/adapters/mysql/resources/__tests__/status.test.ts +62 -45
  563. package/src/adapters/mysql/resources/__tests__/sysschema.test.ts +99 -60
  564. package/src/adapters/mysql/resources/__tests__/tables.test.ts +41 -32
  565. package/src/adapters/mysql/resources/__tests__/variables.test.ts +77 -49
  566. package/src/adapters/mysql/resources/capabilities.ts +59 -42
  567. package/src/adapters/mysql/resources/cluster.ts +58 -49
  568. package/src/adapters/mysql/resources/docstore.ts +46 -41
  569. package/src/adapters/mysql/resources/events.ts +37 -31
  570. package/src/adapters/mysql/resources/health.ts +98 -74
  571. package/src/adapters/mysql/resources/index.ts +46 -46
  572. package/src/adapters/mysql/resources/indexes.ts +66 -51
  573. package/src/adapters/mysql/resources/innodb.ts +98 -81
  574. package/src/adapters/mysql/resources/locks.ts +43 -40
  575. package/src/adapters/mysql/resources/performance.ts +80 -67
  576. package/src/adapters/mysql/resources/pool.ts +23 -20
  577. package/src/adapters/mysql/resources/processlist.ts +23 -18
  578. package/src/adapters/mysql/resources/replication.ts +124 -105
  579. package/src/adapters/mysql/resources/schema.ts +23 -18
  580. package/src/adapters/mysql/resources/spatial.ts +31 -26
  581. package/src/adapters/mysql/resources/status.ts +27 -22
  582. package/src/adapters/mysql/resources/sysschema.ts +41 -36
  583. package/src/adapters/mysql/resources/tables.ts +23 -18
  584. package/src/adapters/mysql/resources/variables.ts +27 -22
  585. package/src/adapters/mysql/tools/__tests__/cluster.test.ts +419 -311
  586. package/src/adapters/mysql/tools/__tests__/core.test.ts +633 -382
  587. package/src/adapters/mysql/tools/__tests__/docstore.test.ts +782 -413
  588. package/src/adapters/mysql/tools/__tests__/events.test.ts +752 -486
  589. package/src/adapters/mysql/tools/__tests__/json_core.test.ts +326 -259
  590. package/src/adapters/mysql/tools/__tests__/json_enhanced.test.ts +452 -352
  591. package/src/adapters/mysql/tools/__tests__/json_helpers.test.ts +169 -136
  592. package/src/adapters/mysql/tools/__tests__/proxysql.test.ts +576 -340
  593. package/src/adapters/mysql/tools/__tests__/replication.test.ts +697 -393
  594. package/src/adapters/mysql/tools/__tests__/roles.test.ts +423 -166
  595. package/src/adapters/mysql/tools/__tests__/router.test.ts +644 -540
  596. package/src/adapters/mysql/tools/__tests__/security.test.ts +708 -422
  597. package/src/adapters/mysql/tools/__tests__/security_injection.test.ts +246 -173
  598. package/src/adapters/mysql/tools/__tests__/security_integration.test.ts +244 -205
  599. package/src/adapters/mysql/tools/__tests__/spatial.test.ts +413 -300
  600. package/src/adapters/mysql/tools/__tests__/spatial_handler.test.ts +503 -150
  601. package/src/adapters/mysql/tools/__tests__/stats.test.ts +861 -553
  602. package/src/adapters/mysql/tools/__tests__/transactions.test.ts +454 -263
  603. package/src/adapters/mysql/tools/admin/__tests__/backup.test.ts +612 -372
  604. package/src/adapters/mysql/tools/admin/__tests__/maintenance.test.ts +550 -257
  605. package/src/adapters/mysql/tools/admin/__tests__/monitoring.test.ts +549 -352
  606. package/src/adapters/mysql/tools/admin/backup.ts +334 -215
  607. package/src/adapters/mysql/tools/admin/index.ts +46 -46
  608. package/src/adapters/mysql/tools/admin/maintenance.ts +176 -130
  609. package/src/adapters/mysql/tools/admin/monitoring.ts +373 -199
  610. package/src/adapters/mysql/tools/cluster/__tests__/group-replication.test.ts +200 -186
  611. package/src/adapters/mysql/tools/cluster/__tests__/innodb-cluster.test.ts +364 -95
  612. package/src/adapters/mysql/tools/cluster/group-replication.ts +218 -183
  613. package/src/adapters/mysql/tools/cluster/index.ts +27 -27
  614. package/src/adapters/mysql/tools/cluster/innodb-cluster.ts +392 -251
  615. package/src/adapters/mysql/tools/core.ts +408 -285
  616. package/src/adapters/mysql/tools/docstore.ts +478 -276
  617. package/src/adapters/mysql/tools/events.ts +425 -285
  618. package/src/adapters/mysql/tools/index.ts +31 -20
  619. package/src/adapters/mysql/tools/json/__tests__/core.test.ts +456 -199
  620. package/src/adapters/mysql/tools/json/__tests__/enhanced.test.ts +554 -298
  621. package/src/adapters/mysql/tools/json/__tests__/helpers.test.ts +150 -74
  622. package/src/adapters/mysql/tools/json/__tests__/validation.test.ts +106 -72
  623. package/src/adapters/mysql/tools/json/core.ts +364 -263
  624. package/src/adapters/mysql/tools/json/enhanced.ts +368 -229
  625. package/src/adapters/mysql/tools/json/helpers.ts +195 -113
  626. package/src/adapters/mysql/tools/json/index.ts +46 -46
  627. package/src/adapters/mysql/tools/partitioning.ts +242 -140
  628. package/src/adapters/mysql/tools/performance/__tests__/analysis.test.ts +439 -247
  629. package/src/adapters/mysql/tools/performance/__tests__/optimization.test.ts +401 -179
  630. package/src/adapters/mysql/tools/performance/analysis.ts +263 -213
  631. package/src/adapters/mysql/tools/performance/index.ts +33 -33
  632. package/src/adapters/mysql/tools/performance/optimization.ts +407 -190
  633. package/src/adapters/mysql/tools/proxysql.ts +462 -320
  634. package/src/adapters/mysql/tools/replication.ts +233 -180
  635. package/src/adapters/mysql/tools/roles.ts +429 -171
  636. package/src/adapters/mysql/tools/router.ts +410 -292
  637. package/src/adapters/mysql/tools/schema/__tests__/constraints.test.ts +157 -82
  638. package/src/adapters/mysql/tools/schema/__tests__/management.test.ts +226 -101
  639. package/src/adapters/mysql/tools/schema/__tests__/routines.test.ts +80 -35
  640. package/src/adapters/mysql/tools/schema/__tests__/scheduled_events.test.ts +59 -40
  641. package/src/adapters/mysql/tools/schema/__tests__/triggers.test.ts +65 -40
  642. package/src/adapters/mysql/tools/schema/__tests__/views.test.ts +146 -77
  643. package/src/adapters/mysql/tools/schema/constraints.ts +61 -42
  644. package/src/adapters/mysql/tools/schema/index.ts +26 -35
  645. package/src/adapters/mysql/tools/schema/management.ts +167 -94
  646. package/src/adapters/mysql/tools/schema/routines.ts +79 -48
  647. package/src/adapters/mysql/tools/schema/scheduled_events.ts +53 -32
  648. package/src/adapters/mysql/tools/schema/triggers.ts +51 -33
  649. package/src/adapters/mysql/tools/schema/views.ts +96 -53
  650. package/src/adapters/mysql/tools/security/__tests__/audit.test.ts +216 -158
  651. package/src/adapters/mysql/tools/security/__tests__/data-protection.test.ts +154 -98
  652. package/src/adapters/mysql/tools/security/__tests__/encryption.test.ts +174 -138
  653. package/src/adapters/mysql/tools/security/audit.ts +213 -193
  654. package/src/adapters/mysql/tools/security/data-protection.ts +336 -198
  655. package/src/adapters/mysql/tools/security/encryption.ts +233 -193
  656. package/src/adapters/mysql/tools/security/index.ts +26 -26
  657. package/src/adapters/mysql/tools/shell/__tests__/backup.test.ts +443 -283
  658. package/src/adapters/mysql/tools/shell/__tests__/common.test.ts +138 -131
  659. package/src/adapters/mysql/tools/shell/__tests__/data-transfer.test.ts +516 -353
  660. package/src/adapters/mysql/tools/shell/__tests__/info.test.ts +65 -63
  661. package/src/adapters/mysql/tools/shell/__tests__/restore.test.ts +233 -174
  662. package/src/adapters/mysql/tools/shell/__tests__/utilities.test.ts +161 -143
  663. package/src/adapters/mysql/tools/shell/backup.ts +280 -188
  664. package/src/adapters/mysql/tools/shell/common.ts +173 -155
  665. package/src/adapters/mysql/tools/shell/data-transfer.ts +286 -200
  666. package/src/adapters/mysql/tools/shell/index.ts +29 -29
  667. package/src/adapters/mysql/tools/shell/info.ts +35 -31
  668. package/src/adapters/mysql/tools/shell/restore.ts +176 -124
  669. package/src/adapters/mysql/tools/shell/utilities.ts +86 -45
  670. package/src/adapters/mysql/tools/spatial/__tests__/geometry.test.ts +129 -89
  671. package/src/adapters/mysql/tools/spatial/__tests__/operations.test.ts +255 -148
  672. package/src/adapters/mysql/tools/spatial/__tests__/queries.test.ts +340 -245
  673. package/src/adapters/mysql/tools/spatial/geometry.ts +120 -74
  674. package/src/adapters/mysql/tools/spatial/index.ts +33 -33
  675. package/src/adapters/mysql/tools/spatial/operations.ts +243 -171
  676. package/src/adapters/mysql/tools/spatial/queries.ts +221 -165
  677. package/src/adapters/mysql/tools/spatial/setup.ts +157 -73
  678. package/src/adapters/mysql/tools/stats/__tests__/comparative.test.ts +188 -130
  679. package/src/adapters/mysql/tools/stats/comparative.ts +261 -187
  680. package/src/adapters/mysql/tools/stats/descriptive.ts +414 -322
  681. package/src/adapters/mysql/tools/stats/index.ts +23 -23
  682. package/src/adapters/mysql/tools/sysschema/__tests__/activity.test.ts +99 -71
  683. package/src/adapters/mysql/tools/sysschema/__tests__/io_summary_fix.test.ts +21 -18
  684. package/src/adapters/mysql/tools/sysschema/__tests__/performance.test.ts +149 -108
  685. package/src/adapters/mysql/tools/sysschema/__tests__/resources.test.ts +222 -104
  686. package/src/adapters/mysql/tools/sysschema/activity.ts +72 -64
  687. package/src/adapters/mysql/tools/sysschema/index.ts +24 -24
  688. package/src/adapters/mysql/tools/sysschema/performance.ts +140 -115
  689. package/src/adapters/mysql/tools/sysschema/resources.ts +135 -99
  690. package/src/adapters/mysql/tools/text/__tests__/fulltext.test.ts +526 -145
  691. package/src/adapters/mysql/tools/text/__tests__/processing.test.ts +452 -193
  692. package/src/adapters/mysql/tools/text/fulltext.ts +319 -123
  693. package/src/adapters/mysql/tools/text/index.ts +32 -30
  694. package/src/adapters/mysql/tools/text/processing.ts +310 -212
  695. package/src/adapters/mysql/tools/transactions.ts +284 -197
  696. package/src/adapters/mysql/types/__tests__/shell-types.test.ts +204 -202
  697. package/src/adapters/mysql/types/proxysql-types.ts +142 -109
  698. package/src/adapters/mysql/types/router-types.ts +36 -36
  699. package/src/adapters/mysql/types/shell-types.ts +280 -94
  700. package/src/adapters/mysql/types.ts +288 -131
  701. package/src/auth/AuthorizationServerDiscovery.ts +127 -113
  702. package/src/auth/OAuthResourceServer.ts +67 -62
  703. package/src/auth/TokenValidator.ts +136 -119
  704. package/src/auth/__tests__/AuthorizationServerDiscovery.test.ts +295 -274
  705. package/src/auth/__tests__/OAuthResourceServer.test.ts +180 -169
  706. package/src/auth/__tests__/TokenValidator.test.ts +297 -285
  707. package/src/auth/__tests__/errors.test.ts +180 -175
  708. package/src/auth/__tests__/middleware.test.ts +281 -247
  709. package/src/auth/__tests__/scopes.test.ts +136 -134
  710. package/src/auth/errors.ts +56 -56
  711. package/src/auth/index.ts +23 -17
  712. package/src/auth/middleware.ts +161 -139
  713. package/src/auth/scopes.ts +133 -107
  714. package/src/auth/types.ts +155 -155
  715. package/src/cli/__tests__/args.test.ts +241 -216
  716. package/src/cli/__tests__/main.test.ts +191 -158
  717. package/src/cli/args.ts +271 -258
  718. package/src/cli.ts +150 -127
  719. package/src/constants/ServerInstructions.ts +271 -70
  720. package/src/filtering/ToolConstants.ts +287 -266
  721. package/src/filtering/ToolFilter.ts +239 -220
  722. package/src/filtering/__tests__/ToolFilter.test.ts +442 -396
  723. package/src/index.ts +62 -57
  724. package/src/logging/McpLogging.ts +128 -119
  725. package/src/logging/__tests__/McpLogging.test.ts +223 -223
  726. package/src/logging/index.ts +2 -2
  727. package/src/pool/ConnectionPool.ts +260 -246
  728. package/src/pool/__tests__/ConnectionPool.test.ts +452 -418
  729. package/src/progress/ProgressReporter.ts +123 -123
  730. package/src/progress/__tests__/ProgressReporter.test.ts +235 -229
  731. package/src/progress/index.ts +6 -2
  732. package/src/server/McpServer.ts +305 -285
  733. package/src/server/__tests__/McpServer.test.ts +333 -291
  734. package/src/transports/__tests__/http.test.ts +658 -527
  735. package/src/transports/http.ts +237 -203
  736. package/src/transports/index.ts +6 -2
  737. package/src/types/__tests__/types.test.ts +197 -193
  738. package/src/types/index.ts +49 -37
  739. package/src/types/modules/database.ts +65 -63
  740. package/src/types/modules/errors.ts +41 -37
  741. package/src/types/modules/oauth.ts +46 -46
  742. package/src/types/modules/query.ts +75 -75
  743. package/src/types/modules/server.ts +18 -18
  744. package/src/types/modules/tools.ts +181 -178
  745. package/src/utils/__tests__/logger.test.ts +424 -414
  746. package/src/utils/__tests__/validators.test.ts +250 -165
  747. package/src/utils/logger.ts +343 -330
  748. package/src/utils/promptGenerator.ts +58 -47
  749. package/src/utils/validators.ts +217 -91
  750. package/tsconfig.json +41 -50
  751. package/vitest.config.ts +23 -23
@@ -1,603 +1,707 @@
1
1
  /**
2
2
  * mysql-mcp - Router Tools Unit Tests
3
- *
3
+ *
4
4
  * Tests for router tool definitions, annotations, and handler execution.
5
5
  * Mocks https module to test MySQL Router REST API calls.
6
6
  */
7
7
 
8
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
9
- import { getRouterTools } from '../router.js';
10
- import type { MySQLAdapter } from '../../MySQLAdapter.js';
11
- import { createMockMySQLAdapter, createMockRequestContext } from '../../../../__tests__/mocks/index.js';
12
- import { EventEmitter } from 'events';
8
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
9
+ import { getRouterTools } from "../router.js";
10
+ import type { MySQLAdapter } from "../../MySQLAdapter.js";
11
+ import {
12
+ createMockMySQLAdapter,
13
+ createMockRequestContext,
14
+ } from "../../../../__tests__/mocks/index.js";
15
+ import { EventEmitter } from "events";
13
16
 
14
17
  // Mock https module
15
- vi.mock('node:https', () => ({
16
- default: {
17
- request: vi.fn()
18
- }
18
+ vi.mock("node:https", () => ({
19
+ default: {
20
+ request: vi.fn(),
21
+ },
19
22
  }));
20
23
 
21
- import https from 'node:https';
24
+ import https from "node:https";
22
25
  const mockRequest = https.request as ReturnType<typeof vi.fn>;
23
26
 
24
- describe('getRouterTools', () => {
25
- let tools: ReturnType<typeof getRouterTools>;
26
-
27
- beforeEach(() => {
28
- vi.clearAllMocks();
29
- tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
30
- });
27
+ describe("getRouterTools", () => {
28
+ let tools: ReturnType<typeof getRouterTools>;
31
29
 
32
- it('should return 9 router tools', () => {
33
- expect(tools).toHaveLength(9);
34
- });
30
+ beforeEach(() => {
31
+ vi.clearAllMocks();
32
+ tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
33
+ });
35
34
 
36
- it('should have router group for all tools', () => {
37
- for (const tool of tools) {
38
- expect(tool.group).toBe('router');
39
- }
40
- });
35
+ it("should return 9 router tools", () => {
36
+ expect(tools).toHaveLength(9);
37
+ });
41
38
 
42
- it('should have handler functions for all tools', () => {
43
- for (const tool of tools) {
44
- expect(typeof tool.handler).toBe('function');
45
- }
46
- });
39
+ it("should have router group for all tools", () => {
40
+ for (const tool of tools) {
41
+ expect(tool.group).toBe("router");
42
+ }
43
+ });
47
44
 
48
- it('should have inputSchema for all tools', () => {
49
- for (const tool of tools) {
50
- expect(tool.inputSchema).toBeDefined();
51
- }
52
- });
45
+ it("should have handler functions for all tools", () => {
46
+ for (const tool of tools) {
47
+ expect(typeof tool.handler).toBe("function");
48
+ }
49
+ });
53
50
 
54
- it('should include all expected tool names', () => {
55
- const toolNames = tools.map(t => t.name);
56
- expect(toolNames).toContain('mysql_router_status');
57
- expect(toolNames).toContain('mysql_router_routes');
58
- expect(toolNames).toContain('mysql_router_route_status');
59
- expect(toolNames).toContain('mysql_router_route_health');
60
- expect(toolNames).toContain('mysql_router_route_connections');
61
- expect(toolNames).toContain('mysql_router_route_destinations');
62
- expect(toolNames).toContain('mysql_router_route_blocked_hosts');
63
- expect(toolNames).toContain('mysql_router_metadata_status');
64
- expect(toolNames).toContain('mysql_router_pool_status');
65
- });
51
+ it("should have inputSchema for all tools", () => {
52
+ for (const tool of tools) {
53
+ expect(tool.inputSchema).toBeDefined();
54
+ }
55
+ });
56
+
57
+ it("should include all expected tool names", () => {
58
+ const toolNames = tools.map((t) => t.name);
59
+ expect(toolNames).toContain("mysql_router_status");
60
+ expect(toolNames).toContain("mysql_router_routes");
61
+ expect(toolNames).toContain("mysql_router_route_status");
62
+ expect(toolNames).toContain("mysql_router_route_health");
63
+ expect(toolNames).toContain("mysql_router_route_connections");
64
+ expect(toolNames).toContain("mysql_router_route_destinations");
65
+ expect(toolNames).toContain("mysql_router_route_blocked_hosts");
66
+ expect(toolNames).toContain("mysql_router_metadata_status");
67
+ expect(toolNames).toContain("mysql_router_pool_status");
68
+ });
66
69
  });
67
70
 
68
- describe('Tool Structure Validation', () => {
69
- let tools: ReturnType<typeof getRouterTools>;
70
-
71
- beforeEach(() => {
72
- vi.clearAllMocks();
73
- tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
74
- });
75
-
76
- it('mysql_router_status should have correct structure', () => {
77
- const tool = tools.find(t => t.name === 'mysql_router_status')!;
78
- expect(tool.name).toBe('mysql_router_status');
79
- expect(tool.description).toBeDefined();
80
- expect(tool.annotations?.readOnlyHint).toBe(true);
81
- expect(tool.annotations?.openWorldHint).toBe(true);
82
- });
83
-
84
- it('all router tools should be read-only', () => {
85
- for (const tool of tools) {
86
- expect(tool.annotations?.readOnlyHint).toBe(true);
87
- }
88
- });
71
+ describe("Tool Structure Validation", () => {
72
+ let tools: ReturnType<typeof getRouterTools>;
73
+
74
+ beforeEach(() => {
75
+ vi.clearAllMocks();
76
+ tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
77
+ });
78
+
79
+ it("mysql_router_status should have correct structure", () => {
80
+ const tool = tools.find((t) => t.name === "mysql_router_status")!;
81
+ expect(tool.name).toBe("mysql_router_status");
82
+ expect(tool.description).toBeDefined();
83
+ expect(tool.annotations?.readOnlyHint).toBe(true);
84
+ expect(tool.annotations?.openWorldHint).toBe(true);
85
+ });
86
+
87
+ it("all router tools should be read-only", () => {
88
+ for (const tool of tools) {
89
+ expect(tool.annotations?.readOnlyHint).toBe(true);
90
+ }
91
+ });
89
92
 
90
- it('all router tools should have correct requiredScopes', () => {
91
- for (const tool of tools) {
92
- expect(tool.requiredScopes).toContain('read');
93
- }
94
- });
93
+ it("all router tools should have correct requiredScopes", () => {
94
+ for (const tool of tools) {
95
+ expect(tool.requiredScopes).toContain("read");
96
+ }
97
+ });
95
98
 
96
- it('all tools should have openWorldHint true', () => {
97
- for (const tool of tools) {
98
- expect(tool.annotations?.openWorldHint).toBe(true);
99
- }
100
- });
99
+ it("all tools should have openWorldHint true", () => {
100
+ for (const tool of tools) {
101
+ expect(tool.annotations?.openWorldHint).toBe(true);
102
+ }
103
+ });
101
104
 
102
- it('all tools should have idempotentHint true', () => {
103
- for (const tool of tools) {
104
- expect(tool.annotations?.idempotentHint).toBe(true);
105
- }
106
- });
105
+ it("all tools should have idempotentHint true", () => {
106
+ for (const tool of tools) {
107
+ expect(tool.annotations?.idempotentHint).toBe(true);
108
+ }
109
+ });
107
110
  });
108
111
 
109
- describe('Handler Execution', () => {
110
- let tools: ReturnType<typeof getRouterTools>;
111
- let mockContext: ReturnType<typeof createMockRequestContext>;
112
-
113
- beforeEach(() => {
114
- vi.clearAllMocks();
115
- tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
116
- mockContext = createMockRequestContext();
117
- });
118
-
119
- afterEach(() => {
120
- vi.restoreAllMocks();
121
- });
122
-
123
- // Helper to mock successful https response
124
- const mockHttpsResponse = (data: unknown, statusCode = 200) => {
125
- const mockReq = new EventEmitter() as EventEmitter & { end: () => void; destroy: () => void };
126
- mockReq.end = vi.fn();
127
- mockReq.destroy = vi.fn();
128
-
129
- mockRequest.mockImplementation((_options, callback) => {
130
- const mockRes = new EventEmitter() as EventEmitter & { statusCode: number; statusMessage: string };
131
- mockRes.statusCode = statusCode;
132
- mockRes.statusMessage = statusCode === 200 ? 'OK' : 'Error';
133
-
134
- setImmediate(() => {
135
- callback?.(mockRes);
136
- mockRes.emit('data', JSON.stringify(data));
137
- mockRes.emit('end');
138
- });
139
-
140
- return mockReq;
141
- });
112
+ describe("Handler Execution", () => {
113
+ let tools: ReturnType<typeof getRouterTools>;
114
+ let mockContext: ReturnType<typeof createMockRequestContext>;
115
+
116
+ beforeEach(() => {
117
+ vi.clearAllMocks();
118
+ tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
119
+ mockContext = createMockRequestContext();
120
+ });
121
+
122
+ afterEach(() => {
123
+ vi.restoreAllMocks();
124
+ });
125
+
126
+ // Helper to mock successful https response
127
+ const mockHttpsResponse = (data: unknown, statusCode = 200) => {
128
+ const mockReq = new EventEmitter() as EventEmitter & {
129
+ end: () => void;
130
+ destroy: () => void;
142
131
  };
143
-
144
- describe('mysql_router_status', () => {
145
- it('should fetch router status and return result', async () => {
146
- const mockStatus = {
147
- processId: 1234,
148
- version: '8.0.35',
149
- hostname: 'router-host',
150
- timeStarted: '2024-01-01T00:00:00Z'
151
- };
152
- mockHttpsResponse(mockStatus);
153
-
154
- const tool = tools.find(t => t.name === 'mysql_router_status')!;
155
- const result = await tool.handler({}, mockContext);
156
-
157
- expect(mockRequest).toHaveBeenCalled();
158
- const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
159
- expect(options.method).toBe('GET');
160
- expect(options.path).toContain('/router/status');
161
- expect(result).toEqual({
162
- success: true,
163
- status: mockStatus
164
- });
165
- });
166
- });
167
-
168
- describe('mysql_router_routes', () => {
169
- it('should fetch all routes', async () => {
170
- const mockRoutes = {
171
- items: [
172
- { name: 'bootstrap_ro' },
173
- { name: 'bootstrap_rw' }
174
- ]
175
- };
176
- mockHttpsResponse(mockRoutes);
177
-
178
- const tool = tools.find(t => t.name === 'mysql_router_routes')!;
179
- const result = await tool.handler({}, mockContext);
180
-
181
- expect(mockRequest).toHaveBeenCalled();
182
- const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
183
- expect(options.path).toContain('/routes');
184
- expect(result).toEqual({
185
- success: true,
186
- routes: mockRoutes
187
- });
188
- });
189
- });
190
-
191
- describe('mysql_router_route_status', () => {
192
- it('should fetch status for specific route', async () => {
193
- const mockRouteStatus = {
194
- activeConnections: 5,
195
- totalConnections: 100,
196
- blockedHosts: 0
197
- };
198
- mockHttpsResponse(mockRouteStatus);
199
-
200
- const tool = tools.find(t => t.name === 'mysql_router_route_status')!;
201
- const result = await tool.handler({ routeName: 'bootstrap_ro' }, mockContext);
202
-
203
- expect(mockRequest).toHaveBeenCalled();
204
- const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
205
- expect(options.path).toContain('/routes/bootstrap_ro/status');
206
- expect(result).toEqual({
207
- success: true,
208
- routeName: 'bootstrap_ro',
209
- status: mockRouteStatus
210
- });
211
- });
212
-
213
- it('should URL-encode route names', async () => {
214
- mockHttpsResponse({});
215
-
216
- const tool = tools.find(t => t.name === 'mysql_router_route_status')!;
217
- await tool.handler({ routeName: 'route/with/slashes' }, mockContext);
218
-
219
- const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
220
- expect(options.path).toContain('route%2Fwith%2Fslashes');
221
- });
222
- });
223
-
224
- describe('mysql_router_route_health', () => {
225
- it('should check route health', async () => {
226
- const mockHealth = { isAlive: true };
227
- mockHttpsResponse(mockHealth);
228
-
229
- const tool = tools.find(t => t.name === 'mysql_router_route_health')!;
230
- const result = await tool.handler({ routeName: 'bootstrap_ro' }, mockContext);
231
-
232
- expect(mockRequest).toHaveBeenCalled();
233
- const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
234
- expect(options.path).toContain('/routes/bootstrap_ro/health');
235
- expect(result).toEqual({
236
- success: true,
237
- routeName: 'bootstrap_ro',
238
- health: mockHealth
239
- });
240
- });
241
- });
242
-
243
- describe('mysql_router_route_connections', () => {
244
- it('should list active connections', async () => {
245
- const mockConnections = {
246
- items: [
247
- { sourceAddress: '192.168.1.1', destinationAddress: '10.0.0.1', bytesIn: 1024 }
248
- ]
249
- };
250
- mockHttpsResponse(mockConnections);
251
-
252
- const tool = tools.find(t => t.name === 'mysql_router_route_connections')!;
253
- const result = await tool.handler({ routeName: 'bootstrap_rw' }, mockContext);
254
-
255
- expect(mockRequest).toHaveBeenCalled();
256
- const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
257
- expect(options.path).toContain('/routes/bootstrap_rw/connections');
258
- expect(result).toEqual({
259
- success: true,
260
- routeName: 'bootstrap_rw',
261
- connections: mockConnections
262
- });
263
- });
264
- });
265
-
266
- describe('mysql_router_route_destinations', () => {
267
- it('should list backend destinations', async () => {
268
- const mockDestinations = {
269
- items: [
270
- { address: 'mysql-1.example.com', port: 3306 },
271
- { address: 'mysql-2.example.com', port: 3306 }
272
- ]
273
- };
274
- mockHttpsResponse(mockDestinations);
275
-
276
- const tool = tools.find(t => t.name === 'mysql_router_route_destinations')!;
277
- const result = await tool.handler({ routeName: 'bootstrap_ro' }, mockContext);
278
-
279
- expect(mockRequest).toHaveBeenCalled();
280
- const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
281
- expect(options.path).toContain('/routes/bootstrap_ro/destinations');
282
- expect(result).toEqual({
283
- success: true,
284
- routeName: 'bootstrap_ro',
285
- destinations: mockDestinations
286
- });
287
- });
288
- });
289
-
290
- describe('mysql_router_route_blocked_hosts', () => {
291
- it('should list blocked hosts', async () => {
292
- const mockBlockedHosts = {
293
- items: [
294
- { address: '192.168.1.100' }
295
- ]
296
- };
297
- mockHttpsResponse(mockBlockedHosts);
298
-
299
- const tool = tools.find(t => t.name === 'mysql_router_route_blocked_hosts')!;
300
- const result = await tool.handler({ routeName: 'bootstrap_rw' }, mockContext);
301
-
302
- expect(mockRequest).toHaveBeenCalled();
303
- const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
304
- expect(options.path).toContain('/routes/bootstrap_rw/blockedHosts');
305
- expect(result).toEqual({
306
- success: true,
307
- routeName: 'bootstrap_rw',
308
- blockedHosts: mockBlockedHosts
309
- });
310
- });
311
- });
312
-
313
- describe('mysql_router_metadata_status', () => {
314
- it('should fetch metadata cache status', async () => {
315
- const mockMetadata = {
316
- refreshTotal: 100,
317
- refreshSucceeded: 99,
318
- lastRefreshHostName: 'mysql-primary.example.com'
319
- };
320
- mockHttpsResponse(mockMetadata);
321
-
322
- const tool = tools.find(t => t.name === 'mysql_router_metadata_status')!;
323
- const result = await tool.handler({ metadataName: 'my_cluster' }, mockContext);
324
-
325
- expect(mockRequest).toHaveBeenCalled();
326
- const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
327
- expect(options.path).toContain('/metadata/my_cluster/status');
328
- expect(result).toEqual({
329
- success: true,
330
- metadataName: 'my_cluster',
331
- status: mockMetadata
332
- });
333
- });
334
- });
335
-
336
- describe('mysql_router_pool_status', () => {
337
- it('should fetch connection pool status', async () => {
338
- const mockPoolStatus = {
339
- reusedConnections: 50,
340
- idleServerConnections: 10
341
- };
342
- mockHttpsResponse(mockPoolStatus);
343
-
344
- const tool = tools.find(t => t.name === 'mysql_router_pool_status')!;
345
- const result = await tool.handler({ poolName: 'default' }, mockContext);
346
-
347
- expect(mockRequest).toHaveBeenCalled();
348
- const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
349
- expect(options.path).toContain('/connection_pool/default/status');
350
- expect(result).toEqual({
351
- success: true,
352
- poolName: 'default',
353
- status: mockPoolStatus
354
- });
355
- });
356
- });
132
+ mockReq.end = vi.fn();
133
+ mockReq.destroy = vi.fn();
134
+
135
+ mockRequest.mockImplementation((_options, callback) => {
136
+ const mockRes = new EventEmitter() as EventEmitter & {
137
+ statusCode: number;
138
+ statusMessage: string;
139
+ };
140
+ mockRes.statusCode = statusCode;
141
+ mockRes.statusMessage = statusCode === 200 ? "OK" : "Error";
142
+
143
+ setImmediate(() => {
144
+ callback?.(mockRes);
145
+ mockRes.emit("data", JSON.stringify(data));
146
+ mockRes.emit("end");
147
+ });
148
+
149
+ return mockReq;
150
+ });
151
+ };
152
+
153
+ describe("mysql_router_status", () => {
154
+ it("should fetch router status and return result", async () => {
155
+ const mockStatus = {
156
+ processId: 1234,
157
+ version: "8.0.35",
158
+ hostname: "router-host",
159
+ timeStarted: "2024-01-01T00:00:00Z",
160
+ };
161
+ mockHttpsResponse(mockStatus);
162
+
163
+ const tool = tools.find((t) => t.name === "mysql_router_status")!;
164
+ const result = await tool.handler({}, mockContext);
165
+
166
+ expect(mockRequest).toHaveBeenCalled();
167
+ const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
168
+ expect(options.method).toBe("GET");
169
+ expect(options.path).toContain("/router/status");
170
+ expect(result).toEqual({
171
+ success: true,
172
+ status: mockStatus,
173
+ });
174
+ });
175
+ });
176
+
177
+ describe("mysql_router_routes", () => {
178
+ it("should fetch all routes", async () => {
179
+ const mockRoutes = {
180
+ items: [{ name: "bootstrap_ro" }, { name: "bootstrap_rw" }],
181
+ };
182
+ mockHttpsResponse(mockRoutes);
183
+
184
+ const tool = tools.find((t) => t.name === "mysql_router_routes")!;
185
+ const result = await tool.handler({}, mockContext);
186
+
187
+ expect(mockRequest).toHaveBeenCalled();
188
+ const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
189
+ expect(options.path).toContain("/routes");
190
+ expect(result).toEqual({
191
+ success: true,
192
+ routes: mockRoutes,
193
+ });
194
+ });
195
+ });
196
+
197
+ describe("mysql_router_route_status", () => {
198
+ it("should fetch status for specific route", async () => {
199
+ const mockRouteStatus = {
200
+ activeConnections: 5,
201
+ totalConnections: 100,
202
+ blockedHosts: 0,
203
+ };
204
+ mockHttpsResponse(mockRouteStatus);
205
+
206
+ const tool = tools.find((t) => t.name === "mysql_router_route_status")!;
207
+ const result = await tool.handler(
208
+ { routeName: "bootstrap_ro" },
209
+ mockContext,
210
+ );
211
+
212
+ expect(mockRequest).toHaveBeenCalled();
213
+ const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
214
+ expect(options.path).toContain("/routes/bootstrap_ro/status");
215
+ expect(result).toEqual({
216
+ success: true,
217
+ routeName: "bootstrap_ro",
218
+ status: mockRouteStatus,
219
+ });
220
+ });
221
+
222
+ it("should URL-encode route names", async () => {
223
+ mockHttpsResponse({});
224
+
225
+ const tool = tools.find((t) => t.name === "mysql_router_route_status")!;
226
+ await tool.handler({ routeName: "route/with/slashes" }, mockContext);
227
+
228
+ const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
229
+ expect(options.path).toContain("route%2Fwith%2Fslashes");
230
+ });
231
+ });
232
+
233
+ describe("mysql_router_route_health", () => {
234
+ it("should check route health", async () => {
235
+ const mockHealth = { isAlive: true };
236
+ mockHttpsResponse(mockHealth);
237
+
238
+ const tool = tools.find((t) => t.name === "mysql_router_route_health")!;
239
+ const result = await tool.handler(
240
+ { routeName: "bootstrap_ro" },
241
+ mockContext,
242
+ );
243
+
244
+ expect(mockRequest).toHaveBeenCalled();
245
+ const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
246
+ expect(options.path).toContain("/routes/bootstrap_ro/health");
247
+ expect(result).toEqual({
248
+ success: true,
249
+ routeName: "bootstrap_ro",
250
+ health: mockHealth,
251
+ });
252
+ });
253
+ });
254
+
255
+ describe("mysql_router_route_connections", () => {
256
+ it("should list active connections", async () => {
257
+ const mockConnections = {
258
+ items: [
259
+ {
260
+ sourceAddress: "192.168.1.1",
261
+ destinationAddress: "10.0.0.1",
262
+ bytesIn: 1024,
263
+ },
264
+ ],
265
+ };
266
+ mockHttpsResponse(mockConnections);
267
+
268
+ const tool = tools.find(
269
+ (t) => t.name === "mysql_router_route_connections",
270
+ )!;
271
+ const result = await tool.handler(
272
+ { routeName: "bootstrap_rw" },
273
+ mockContext,
274
+ );
275
+
276
+ expect(mockRequest).toHaveBeenCalled();
277
+ const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
278
+ expect(options.path).toContain("/routes/bootstrap_rw/connections");
279
+ expect(result).toEqual({
280
+ success: true,
281
+ routeName: "bootstrap_rw",
282
+ connections: mockConnections,
283
+ });
284
+ });
285
+ });
286
+
287
+ describe("mysql_router_route_destinations", () => {
288
+ it("should list backend destinations", async () => {
289
+ const mockDestinations = {
290
+ items: [
291
+ { address: "mysql-1.example.com", port: 3306 },
292
+ { address: "mysql-2.example.com", port: 3306 },
293
+ ],
294
+ };
295
+ mockHttpsResponse(mockDestinations);
296
+
297
+ const tool = tools.find(
298
+ (t) => t.name === "mysql_router_route_destinations",
299
+ )!;
300
+ const result = await tool.handler(
301
+ { routeName: "bootstrap_ro" },
302
+ mockContext,
303
+ );
304
+
305
+ expect(mockRequest).toHaveBeenCalled();
306
+ const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
307
+ expect(options.path).toContain("/routes/bootstrap_ro/destinations");
308
+ expect(result).toEqual({
309
+ success: true,
310
+ routeName: "bootstrap_ro",
311
+ destinations: mockDestinations,
312
+ });
313
+ });
314
+ });
315
+
316
+ describe("mysql_router_route_blocked_hosts", () => {
317
+ it("should list blocked hosts", async () => {
318
+ const mockBlockedHosts = {
319
+ items: [{ address: "192.168.1.100" }],
320
+ };
321
+ mockHttpsResponse(mockBlockedHosts);
322
+
323
+ const tool = tools.find(
324
+ (t) => t.name === "mysql_router_route_blocked_hosts",
325
+ )!;
326
+ const result = await tool.handler(
327
+ { routeName: "bootstrap_rw" },
328
+ mockContext,
329
+ );
330
+
331
+ expect(mockRequest).toHaveBeenCalled();
332
+ const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
333
+ expect(options.path).toContain("/routes/bootstrap_rw/blockedHosts");
334
+ expect(result).toEqual({
335
+ success: true,
336
+ routeName: "bootstrap_rw",
337
+ blockedHosts: mockBlockedHosts,
338
+ });
339
+ });
340
+ });
341
+
342
+ describe("mysql_router_metadata_status", () => {
343
+ it("should fetch metadata cache status", async () => {
344
+ const mockMetadata = {
345
+ refreshTotal: 100,
346
+ refreshSucceeded: 99,
347
+ lastRefreshHostName: "mysql-primary.example.com",
348
+ };
349
+ mockHttpsResponse(mockMetadata);
350
+
351
+ const tool = tools.find(
352
+ (t) => t.name === "mysql_router_metadata_status",
353
+ )!;
354
+ const result = await tool.handler(
355
+ { metadataName: "my_cluster" },
356
+ mockContext,
357
+ );
358
+
359
+ expect(mockRequest).toHaveBeenCalled();
360
+ const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
361
+ expect(options.path).toContain("/metadata/my_cluster/status");
362
+ expect(result).toEqual({
363
+ success: true,
364
+ metadataName: "my_cluster",
365
+ status: mockMetadata,
366
+ });
367
+ });
368
+ });
369
+
370
+ describe("mysql_router_pool_status", () => {
371
+ it("should fetch connection pool status", async () => {
372
+ const mockPoolStatus = {
373
+ idleServerConnections: 10,
374
+ stashedServerConnections: 5,
375
+ };
376
+ mockHttpsResponse(mockPoolStatus);
377
+
378
+ const tool = tools.find((t) => t.name === "mysql_router_pool_status")!;
379
+ const result = await tool.handler({ poolName: "default" }, mockContext);
380
+
381
+ expect(mockRequest).toHaveBeenCalled();
382
+ const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
383
+ expect(options.path).toContain("/connection_pool/default/status");
384
+ expect(result).toEqual({
385
+ success: true,
386
+ poolName: "default",
387
+ status: mockPoolStatus,
388
+ });
389
+ });
390
+ });
357
391
  });
358
392
 
359
- describe('HTTP Header Handling', () => {
360
- let tools: ReturnType<typeof getRouterTools>;
361
- let mockContext: ReturnType<typeof createMockRequestContext>;
362
-
363
- beforeEach(() => {
364
- vi.clearAllMocks();
365
- tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
366
- mockContext = createMockRequestContext();
367
- });
368
-
369
- it('should send Accept: application/json header', async () => {
370
- const mockReq = new EventEmitter() as EventEmitter & { end: () => void; destroy: () => void };
371
- mockReq.end = vi.fn();
372
- mockReq.destroy = vi.fn();
373
-
374
- mockRequest.mockImplementation((_options, callback) => {
375
- const mockRes = new EventEmitter() as EventEmitter & { statusCode: number; statusMessage: string };
376
- mockRes.statusCode = 200;
377
- mockRes.statusMessage = 'OK';
393
+ describe("HTTP Header Handling", () => {
394
+ let tools: ReturnType<typeof getRouterTools>;
395
+ let mockContext: ReturnType<typeof createMockRequestContext>;
378
396
 
379
- setImmediate(() => {
380
- callback?.(mockRes);
381
- mockRes.emit('data', '{}');
382
- mockRes.emit('end');
383
- });
397
+ beforeEach(() => {
398
+ vi.clearAllMocks();
399
+ tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
400
+ mockContext = createMockRequestContext();
401
+ });
384
402
 
385
- return mockReq;
386
- });
387
-
388
- const tool = tools.find(t => t.name === 'mysql_router_status')!;
389
- await tool.handler({}, mockContext);
390
-
391
- const options = mockRequest.mock.calls[0][0] as Record<string, Record<string, string>>;
392
- expect(options.headers?.Accept).toBe('application/json');
393
- });
403
+ it("should send Accept: application/json header", async () => {
404
+ const mockReq = new EventEmitter() as EventEmitter & {
405
+ end: () => void;
406
+ destroy: () => void;
407
+ };
408
+ mockReq.end = vi.fn();
409
+ mockReq.destroy = vi.fn();
410
+
411
+ mockRequest.mockImplementation((_options, callback) => {
412
+ const mockRes = new EventEmitter() as EventEmitter & {
413
+ statusCode: number;
414
+ statusMessage: string;
415
+ };
416
+ mockRes.statusCode = 200;
417
+ mockRes.statusMessage = "OK";
418
+
419
+ setImmediate(() => {
420
+ callback?.(mockRes);
421
+ mockRes.emit("data", "{}");
422
+ mockRes.emit("end");
423
+ });
424
+
425
+ return mockReq;
426
+ });
427
+
428
+ const tool = tools.find((t) => t.name === "mysql_router_status")!;
429
+ await tool.handler({}, mockContext);
430
+
431
+ const options = mockRequest.mock.calls[0][0] as Record<
432
+ string,
433
+ Record<string, string>
434
+ >;
435
+ expect(options.headers?.Accept).toBe("application/json");
436
+ });
394
437
  });
395
438
 
396
- describe('Error Handling', () => {
397
- let tools: ReturnType<typeof getRouterTools>;
398
- let mockContext: ReturnType<typeof createMockRequestContext>;
399
-
400
- beforeEach(() => {
401
- vi.clearAllMocks();
402
- tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
403
- mockContext = createMockRequestContext();
404
- });
439
+ describe("Error Handling", () => {
440
+ let tools: ReturnType<typeof getRouterTools>;
441
+ let mockContext: ReturnType<typeof createMockRequestContext>;
405
442
 
406
- it('should throw on non-ok response', async () => {
407
- const mockReq = new EventEmitter() as EventEmitter & { end: () => void; destroy: () => void };
408
- mockReq.end = vi.fn();
409
- mockReq.destroy = vi.fn();
443
+ beforeEach(() => {
444
+ vi.clearAllMocks();
445
+ tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
446
+ mockContext = createMockRequestContext();
447
+ });
410
448
 
411
- mockRequest.mockImplementation((_options, callback) => {
412
- const mockRes = new EventEmitter() as EventEmitter & { statusCode: number; statusMessage: string };
413
- mockRes.statusCode = 401;
414
- mockRes.statusMessage = 'Unauthorized';
415
-
416
- setImmediate(() => {
417
- callback?.(mockRes);
418
- mockRes.emit('end');
419
- });
420
-
421
- return mockReq;
422
- });
423
-
424
- const tool = tools.find(t => t.name === 'mysql_router_status')!;
425
-
426
- await expect(tool.handler({}, mockContext)).rejects.toThrow('Router API error: 401 Unauthorized');
427
- });
428
-
429
- it('should throw on 404 response', async () => {
430
- const mockReq = new EventEmitter() as EventEmitter & { end: () => void; destroy: () => void };
431
- mockReq.end = vi.fn();
432
- mockReq.destroy = vi.fn();
433
-
434
- mockRequest.mockImplementation((_options, callback) => {
435
- const mockRes = new EventEmitter() as EventEmitter & { statusCode: number; statusMessage: string };
436
- mockRes.statusCode = 404;
437
- mockRes.statusMessage = 'Not Found';
438
-
439
- setImmediate(() => {
440
- callback?.(mockRes);
441
- mockRes.emit('end');
442
- });
449
+ it("should return unavailable response on 401 Unauthorized", async () => {
450
+ const mockReq = new EventEmitter() as EventEmitter & {
451
+ end: () => void;
452
+ destroy: () => void;
453
+ };
454
+ mockReq.end = vi.fn();
455
+ mockReq.destroy = vi.fn();
443
456
 
444
- return mockReq;
445
- });
457
+ mockRequest.mockImplementation((_options, callback) => {
458
+ const mockRes = new EventEmitter() as EventEmitter & {
459
+ statusCode: number;
460
+ statusMessage: string;
461
+ };
462
+ mockRes.statusCode = 401;
463
+ mockRes.statusMessage = "Unauthorized";
446
464
 
447
- const tool = tools.find(t => t.name === 'mysql_router_route_status')!;
465
+ setImmediate(() => {
466
+ callback?.(mockRes);
467
+ mockRes.emit("end");
468
+ });
448
469
 
449
- await expect(tool.handler({ routeName: 'nonexistent' }, mockContext)).rejects.toThrow('Router API error: 404 Not Found');
470
+ return mockReq;
450
471
  });
451
472
 
452
- it('should throw on network error', async () => {
453
- const mockReq = new EventEmitter() as EventEmitter & { end: () => void; destroy: () => void };
454
- mockReq.end = vi.fn();
455
- mockReq.destroy = vi.fn();
456
-
457
- mockRequest.mockImplementation(() => {
458
- setImmediate(() => {
459
- mockReq.emit('error', new Error('Network error'));
460
- });
461
- return mockReq;
462
- });
463
-
464
- const tool = tools.find(t => t.name === 'mysql_router_status')!;
473
+ const tool = tools.find((t) => t.name === "mysql_router_status")!;
474
+ const result = await tool.handler({}, mockContext);
465
475
 
466
- await expect(tool.handler({}, mockContext)).rejects.toThrow('Network error');
476
+ expect(result).toEqual({
477
+ available: false,
478
+ reason: "Router API error: 401 Unauthorized",
467
479
  });
480
+ });
468
481
 
469
- it('should throw on connection refused', async () => {
470
- const mockReq = new EventEmitter() as EventEmitter & { end: () => void; destroy: () => void };
471
- mockReq.end = vi.fn();
472
- mockReq.destroy = vi.fn();
482
+ it("should return unavailable response on 404 Not Found", async () => {
483
+ const mockReq = new EventEmitter() as EventEmitter & {
484
+ end: () => void;
485
+ destroy: () => void;
486
+ };
487
+ mockReq.end = vi.fn();
488
+ mockReq.destroy = vi.fn();
473
489
 
474
- mockRequest.mockImplementation(() => {
475
- setImmediate(() => {
476
- mockReq.emit('error', new Error('ECONNREFUSED'));
477
- });
478
- return mockReq;
479
- });
490
+ mockRequest.mockImplementation((_options, callback) => {
491
+ const mockRes = new EventEmitter() as EventEmitter & {
492
+ statusCode: number;
493
+ statusMessage: string;
494
+ };
495
+ mockRes.statusCode = 404;
496
+ mockRes.statusMessage = "Not Found";
480
497
 
481
- const tool = tools.find(t => t.name === 'mysql_router_status')!;
498
+ setImmediate(() => {
499
+ callback?.(mockRes);
500
+ mockRes.emit("end");
501
+ });
482
502
 
483
- await expect(tool.handler({}, mockContext)).rejects.toThrow('ECONNREFUSED');
503
+ return mockReq;
484
504
  });
485
- });
486
505
 
487
- describe('Authentication and TLS Handling', () => {
488
- let originalEnv: NodeJS.ProcessEnv;
489
-
490
- beforeEach(() => {
491
- vi.clearAllMocks();
492
- // Save original env
493
- originalEnv = { ...process.env };
494
- // Clear relevant env vars
495
- delete process.env['MYSQL_ROUTER_URL'];
496
- delete process.env['MYSQL_ROUTER_USER'];
497
- delete process.env['MYSQL_ROUTER_PASSWORD'];
498
- delete process.env['MYSQL_ROUTER_INSECURE'];
499
- delete process.env['NODE_TLS_REJECT_UNAUTHORIZED'];
500
- });
506
+ const tool = tools.find((t) => t.name === "mysql_router_route_status")!;
507
+ const result = await tool.handler(
508
+ { routeName: "nonexistent" },
509
+ mockContext,
510
+ );
501
511
 
502
- afterEach(() => {
503
- vi.restoreAllMocks();
504
- // Restore original env
505
- process.env = originalEnv;
512
+ expect(result).toEqual({
513
+ available: false,
514
+ reason: "Router API error: 404 Not Found",
506
515
  });
516
+ });
507
517
 
508
- // Helper to mock response
509
- const setupMockRequest = () => {
510
- const mockReq = new EventEmitter() as EventEmitter & { end: () => void; destroy: () => void };
511
- mockReq.end = vi.fn();
512
- mockReq.destroy = vi.fn();
513
-
514
- mockRequest.mockImplementation((_options, callback) => {
515
- const mockRes = new EventEmitter() as EventEmitter & { statusCode: number; statusMessage: string };
516
- mockRes.statusCode = 200;
517
- mockRes.statusMessage = 'OK';
518
-
519
- setImmediate(() => {
520
- callback?.(mockRes);
521
- mockRes.emit('data', '{}');
522
- mockRes.emit('end');
523
- });
524
-
525
- return mockReq;
526
- });
527
-
528
- return mockReq;
518
+ it("should return unavailable response on network error", async () => {
519
+ const mockReq = new EventEmitter() as EventEmitter & {
520
+ end: () => void;
521
+ destroy: () => void;
529
522
  };
523
+ mockReq.end = vi.fn();
524
+ mockReq.destroy = vi.fn();
530
525
 
531
- it('should add Basic auth header when credentials provided', async () => {
532
- process.env['MYSQL_ROUTER_USER'] = 'admin';
533
- process.env['MYSQL_ROUTER_PASSWORD'] = 'secret';
534
-
535
- setupMockRequest();
536
-
537
- const tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
538
- const tool = tools.find(t => t.name === 'mysql_router_status')!;
539
- await tool.handler({}, createMockRequestContext());
540
-
541
- const options = mockRequest.mock.calls[0][0] as Record<string, Record<string, string>>;
542
- expect(options.headers?.Authorization).toMatch(/^Basic /);
543
- // Verify the encoded value
544
- const expectedAuth = Buffer.from('admin:secret').toString('base64');
545
- expect(options.headers?.Authorization).toBe(`Basic ${expectedAuth}`);
526
+ mockRequest.mockImplementation(() => {
527
+ setImmediate(() => {
528
+ mockReq.emit("error", new Error("Network error"));
529
+ });
530
+ return mockReq;
546
531
  });
547
532
 
548
- it('should not add auth header when no credentials provided', async () => {
549
- setupMockRequest();
550
-
551
- const tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
552
- const tool = tools.find(t => t.name === 'mysql_router_status')!;
553
- await tool.handler({}, createMockRequestContext());
533
+ const tool = tools.find((t) => t.name === "mysql_router_status")!;
534
+ const result = await tool.handler({}, mockContext);
554
535
 
555
- const options = mockRequest.mock.calls[0][0] as Record<string, Record<string, string>>;
556
- expect(options.headers?.Authorization).toBeUndefined();
536
+ expect(result).toEqual({
537
+ available: false,
538
+ reason: "Router API request failed: Network error",
557
539
  });
540
+ });
558
541
 
559
- it('should set rejectUnauthorized=false for HTTPS with insecure=true', async () => {
560
- process.env['MYSQL_ROUTER_URL'] = 'https://localhost:8443';
561
- process.env['MYSQL_ROUTER_INSECURE'] = 'true';
562
-
563
- setupMockRequest();
564
-
565
- const tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
566
- const tool = tools.find(t => t.name === 'mysql_router_status')!;
567
- await tool.handler({}, createMockRequestContext());
542
+ it("should return unavailable response on connection refused", async () => {
543
+ const mockReq = new EventEmitter() as EventEmitter & {
544
+ end: () => void;
545
+ destroy: () => void;
546
+ };
547
+ mockReq.end = vi.fn();
548
+ mockReq.destroy = vi.fn();
568
549
 
569
- const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
570
- // insecure=true means rejectUnauthorized should be false
571
- expect(options.rejectUnauthorized).toBe(false);
550
+ mockRequest.mockImplementation(() => {
551
+ setImmediate(() => {
552
+ const error = new Error("ECONNREFUSED") as NodeJS.ErrnoException;
553
+ error.code = "ECONNREFUSED";
554
+ mockReq.emit("error", error);
555
+ });
556
+ return mockReq;
572
557
  });
573
558
 
574
- it('should set rejectUnauthorized=true for secure HTTPS requests', async () => {
575
- process.env['MYSQL_ROUTER_URL'] = 'https://localhost:8443';
576
- process.env['MYSQL_ROUTER_INSECURE'] = 'false';
559
+ const tool = tools.find((t) => t.name === "mysql_router_status")!;
560
+ const result = await tool.handler({}, mockContext);
577
561
 
578
- setupMockRequest();
579
-
580
- const tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
581
- const tool = tools.find(t => t.name === 'mysql_router_status')!;
582
- await tool.handler({}, createMockRequestContext());
583
-
584
- const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
585
- // insecure=false means rejectUnauthorized should be true
586
- expect(options.rejectUnauthorized).toBe(true);
562
+ expect(result).toEqual({
563
+ available: false,
564
+ reason: expect.stringContaining("Connection refused"),
587
565
  });
566
+ });
567
+ });
588
568
 
589
- it('should not modify NODE_TLS_REJECT_UNAUTHORIZED env var', async () => {
590
- process.env['MYSQL_ROUTER_URL'] = 'https://localhost:8443';
591
- process.env['MYSQL_ROUTER_INSECURE'] = 'true';
592
- const originalValue = process.env['NODE_TLS_REJECT_UNAUTHORIZED'];
593
-
594
- setupMockRequest();
595
-
596
- const tools = getRouterTools(createMockMySQLAdapter() as unknown as MySQLAdapter);
597
- const tool = tools.find(t => t.name === 'mysql_router_status')!;
598
- await tool.handler({}, createMockRequestContext());
599
-
600
- // New implementation should not modify this env var
601
- expect(process.env['NODE_TLS_REJECT_UNAUTHORIZED']).toBe(originalValue);
602
- });
569
+ describe("Authentication and TLS Handling", () => {
570
+ let originalEnv: NodeJS.ProcessEnv;
571
+
572
+ beforeEach(() => {
573
+ vi.clearAllMocks();
574
+ // Save original env
575
+ originalEnv = { ...process.env };
576
+ // Clear relevant env vars
577
+ delete process.env["MYSQL_ROUTER_URL"];
578
+ delete process.env["MYSQL_ROUTER_USER"];
579
+ delete process.env["MYSQL_ROUTER_PASSWORD"];
580
+ delete process.env["MYSQL_ROUTER_INSECURE"];
581
+ delete process.env["NODE_TLS_REJECT_UNAUTHORIZED"];
582
+ });
583
+
584
+ afterEach(() => {
585
+ vi.restoreAllMocks();
586
+ // Restore original env
587
+ process.env = originalEnv;
588
+ });
589
+
590
+ // Helper to mock response
591
+ const setupMockRequest = () => {
592
+ const mockReq = new EventEmitter() as EventEmitter & {
593
+ end: () => void;
594
+ destroy: () => void;
595
+ };
596
+ mockReq.end = vi.fn();
597
+ mockReq.destroy = vi.fn();
598
+
599
+ mockRequest.mockImplementation((_options, callback) => {
600
+ const mockRes = new EventEmitter() as EventEmitter & {
601
+ statusCode: number;
602
+ statusMessage: string;
603
+ };
604
+ mockRes.statusCode = 200;
605
+ mockRes.statusMessage = "OK";
606
+
607
+ setImmediate(() => {
608
+ callback?.(mockRes);
609
+ mockRes.emit("data", "{}");
610
+ mockRes.emit("end");
611
+ });
612
+
613
+ return mockReq;
614
+ });
615
+
616
+ return mockReq;
617
+ };
618
+
619
+ it("should add Basic auth header when credentials provided", async () => {
620
+ process.env["MYSQL_ROUTER_USER"] = "admin";
621
+ process.env["MYSQL_ROUTER_PASSWORD"] = "secret";
622
+
623
+ setupMockRequest();
624
+
625
+ const tools = getRouterTools(
626
+ createMockMySQLAdapter() as unknown as MySQLAdapter,
627
+ );
628
+ const tool = tools.find((t) => t.name === "mysql_router_status")!;
629
+ await tool.handler({}, createMockRequestContext());
630
+
631
+ const options = mockRequest.mock.calls[0][0] as Record<
632
+ string,
633
+ Record<string, string>
634
+ >;
635
+ expect(options.headers?.Authorization).toMatch(/^Basic /);
636
+ // Verify the encoded value
637
+ const expectedAuth = Buffer.from("admin:secret").toString("base64");
638
+ expect(options.headers?.Authorization).toBe(`Basic ${expectedAuth}`);
639
+ });
640
+
641
+ it("should not add auth header when no credentials provided", async () => {
642
+ setupMockRequest();
643
+
644
+ const tools = getRouterTools(
645
+ createMockMySQLAdapter() as unknown as MySQLAdapter,
646
+ );
647
+ const tool = tools.find((t) => t.name === "mysql_router_status")!;
648
+ await tool.handler({}, createMockRequestContext());
649
+
650
+ const options = mockRequest.mock.calls[0][0] as Record<
651
+ string,
652
+ Record<string, string>
653
+ >;
654
+ expect(options.headers?.Authorization).toBeUndefined();
655
+ });
656
+
657
+ it("should set rejectUnauthorized=false for HTTPS with insecure=true", async () => {
658
+ process.env["MYSQL_ROUTER_URL"] = "https://localhost:8443";
659
+ process.env["MYSQL_ROUTER_INSECURE"] = "true";
660
+
661
+ setupMockRequest();
662
+
663
+ const tools = getRouterTools(
664
+ createMockMySQLAdapter() as unknown as MySQLAdapter,
665
+ );
666
+ const tool = tools.find((t) => t.name === "mysql_router_status")!;
667
+ await tool.handler({}, createMockRequestContext());
668
+
669
+ const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
670
+ // insecure=true means rejectUnauthorized should be false
671
+ expect(options.rejectUnauthorized).toBe(false);
672
+ });
673
+
674
+ it("should set rejectUnauthorized=true for secure HTTPS requests", async () => {
675
+ process.env["MYSQL_ROUTER_URL"] = "https://localhost:8443";
676
+ process.env["MYSQL_ROUTER_INSECURE"] = "false";
677
+
678
+ setupMockRequest();
679
+
680
+ const tools = getRouterTools(
681
+ createMockMySQLAdapter() as unknown as MySQLAdapter,
682
+ );
683
+ const tool = tools.find((t) => t.name === "mysql_router_status")!;
684
+ await tool.handler({}, createMockRequestContext());
685
+
686
+ const options = mockRequest.mock.calls[0][0] as Record<string, unknown>;
687
+ // insecure=false means rejectUnauthorized should be true
688
+ expect(options.rejectUnauthorized).toBe(true);
689
+ });
690
+
691
+ it("should not modify NODE_TLS_REJECT_UNAUTHORIZED env var", async () => {
692
+ process.env["MYSQL_ROUTER_URL"] = "https://localhost:8443";
693
+ process.env["MYSQL_ROUTER_INSECURE"] = "true";
694
+ const originalValue = process.env["NODE_TLS_REJECT_UNAUTHORIZED"];
695
+
696
+ setupMockRequest();
697
+
698
+ const tools = getRouterTools(
699
+ createMockMySQLAdapter() as unknown as MySQLAdapter,
700
+ );
701
+ const tool = tools.find((t) => t.name === "mysql_router_status")!;
702
+ await tool.handler({}, createMockRequestContext());
703
+
704
+ // New implementation should not modify this env var
705
+ expect(process.env["NODE_TLS_REJECT_UNAUTHORIZED"]).toBe(originalValue);
706
+ });
603
707
  });