@neverinfamous/mysql-mcp 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (802) hide show
  1. package/.env.example +14 -4
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +7 -1
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +6 -1
  4. package/.github/dependabot.yml +15 -0
  5. package/.github/pull_request_template.md +5 -0
  6. package/.github/workflows/codeql.yml +41 -42
  7. package/.github/workflows/docker-publish.yml +247 -210
  8. package/.github/workflows/publish-npm.yml +16 -6
  9. package/CHANGELOG.md +357 -22
  10. package/CODE_MODE.md +245 -0
  11. package/CODE_OF_CONDUCT.md +2 -0
  12. package/DOCKER_README.md +250 -161
  13. package/Dockerfile +2 -2
  14. package/README.md +239 -182
  15. package/SECURITY.md +0 -8
  16. package/VERSION +1 -1
  17. package/dist/__tests__/mocks/adapter.d.ts +3 -3
  18. package/dist/__tests__/mocks/adapter.d.ts.map +1 -1
  19. package/dist/__tests__/mocks/adapter.js +51 -35
  20. package/dist/__tests__/mocks/adapter.js.map +1 -1
  21. package/dist/__tests__/mocks/index.d.ts +4 -4
  22. package/dist/__tests__/mocks/index.d.ts.map +1 -1
  23. package/dist/__tests__/mocks/index.js +2 -2
  24. package/dist/__tests__/mocks/index.js.map +1 -1
  25. package/dist/__tests__/mocks/mysql.d.ts +2 -2
  26. package/dist/__tests__/mocks/mysql.d.ts.map +1 -1
  27. package/dist/__tests__/mocks/mysql.js +14 -14
  28. package/dist/__tests__/mocks/mysql.js.map +1 -1
  29. package/dist/__tests__/setup.d.ts.map +1 -1
  30. package/dist/__tests__/setup.js +7 -7
  31. package/dist/__tests__/setup.js.map +1 -1
  32. package/dist/adapters/DatabaseAdapter.d.ts +2 -2
  33. package/dist/adapters/DatabaseAdapter.d.ts.map +1 -1
  34. package/dist/adapters/DatabaseAdapter.js +69 -40
  35. package/dist/adapters/DatabaseAdapter.js.map +1 -1
  36. package/dist/adapters/mysql/MySQLAdapter.d.ts +14 -4
  37. package/dist/adapters/mysql/MySQLAdapter.d.ts.map +1 -1
  38. package/dist/adapters/mysql/MySQLAdapter.js +152 -116
  39. package/dist/adapters/mysql/MySQLAdapter.js.map +1 -1
  40. package/dist/adapters/mysql/SchemaManager.d.ts +1 -1
  41. package/dist/adapters/mysql/SchemaManager.d.ts.map +1 -1
  42. package/dist/adapters/mysql/SchemaManager.js +76 -56
  43. package/dist/adapters/mysql/SchemaManager.js.map +1 -1
  44. package/dist/adapters/mysql/index.d.ts +2 -2
  45. package/dist/adapters/mysql/index.js +2 -2
  46. package/dist/adapters/mysql/prompts/backupStrategy.d.ts +1 -1
  47. package/dist/adapters/mysql/prompts/backupStrategy.d.ts.map +1 -1
  48. package/dist/adapters/mysql/prompts/backupStrategy.js +21 -9
  49. package/dist/adapters/mysql/prompts/backupStrategy.js.map +1 -1
  50. package/dist/adapters/mysql/prompts/clusterSetup.d.ts +1 -1
  51. package/dist/adapters/mysql/prompts/clusterSetup.d.ts.map +1 -1
  52. package/dist/adapters/mysql/prompts/clusterSetup.js +3 -3
  53. package/dist/adapters/mysql/prompts/clusterSetup.js.map +1 -1
  54. package/dist/adapters/mysql/prompts/docstoreSetup.d.ts +1 -1
  55. package/dist/adapters/mysql/prompts/docstoreSetup.js +3 -3
  56. package/dist/adapters/mysql/prompts/docstoreSetup.js.map +1 -1
  57. package/dist/adapters/mysql/prompts/eventScheduler.d.ts +1 -1
  58. package/dist/adapters/mysql/prompts/eventScheduler.js +3 -3
  59. package/dist/adapters/mysql/prompts/eventScheduler.js.map +1 -1
  60. package/dist/adapters/mysql/prompts/healthCheck.d.ts +1 -1
  61. package/dist/adapters/mysql/prompts/healthCheck.d.ts.map +1 -1
  62. package/dist/adapters/mysql/prompts/healthCheck.js +10 -6
  63. package/dist/adapters/mysql/prompts/healthCheck.js.map +1 -1
  64. package/dist/adapters/mysql/prompts/index.d.ts +10 -3
  65. package/dist/adapters/mysql/prompts/index.d.ts.map +1 -1
  66. package/dist/adapters/mysql/prompts/index.js +106 -63
  67. package/dist/adapters/mysql/prompts/index.js.map +1 -1
  68. package/dist/adapters/mysql/prompts/indexTuning.d.ts +1 -1
  69. package/dist/adapters/mysql/prompts/indexTuning.d.ts.map +1 -1
  70. package/dist/adapters/mysql/prompts/indexTuning.js +11 -7
  71. package/dist/adapters/mysql/prompts/indexTuning.js.map +1 -1
  72. package/dist/adapters/mysql/prompts/mysqlshSetup.d.ts +1 -1
  73. package/dist/adapters/mysql/prompts/mysqlshSetup.js +4 -4
  74. package/dist/adapters/mysql/prompts/mysqlshSetup.js.map +1 -1
  75. package/dist/adapters/mysql/prompts/proxysqlSetup.d.ts +1 -1
  76. package/dist/adapters/mysql/prompts/proxysqlSetup.js +3 -3
  77. package/dist/adapters/mysql/prompts/proxysqlSetup.js.map +1 -1
  78. package/dist/adapters/mysql/prompts/replicationSetup.d.ts +1 -1
  79. package/dist/adapters/mysql/prompts/replicationSetup.d.ts.map +1 -1
  80. package/dist/adapters/mysql/prompts/replicationSetup.js +13 -7
  81. package/dist/adapters/mysql/prompts/replicationSetup.js.map +1 -1
  82. package/dist/adapters/mysql/prompts/routerSetup.d.ts +1 -1
  83. package/dist/adapters/mysql/prompts/routerSetup.d.ts.map +1 -1
  84. package/dist/adapters/mysql/prompts/routerSetup.js +8 -3
  85. package/dist/adapters/mysql/prompts/routerSetup.js.map +1 -1
  86. package/dist/adapters/mysql/prompts/spatialSetup.d.ts +1 -1
  87. package/dist/adapters/mysql/prompts/spatialSetup.js +3 -3
  88. package/dist/adapters/mysql/prompts/spatialSetup.js.map +1 -1
  89. package/dist/adapters/mysql/prompts/sysSchema.d.ts +1 -1
  90. package/dist/adapters/mysql/prompts/sysSchema.d.ts.map +1 -1
  91. package/dist/adapters/mysql/prompts/sysSchema.js +3 -3
  92. package/dist/adapters/mysql/prompts/sysSchema.js.map +1 -1
  93. package/dist/adapters/mysql/resources/capabilities.d.ts +2 -2
  94. package/dist/adapters/mysql/resources/capabilities.d.ts.map +1 -1
  95. package/dist/adapters/mysql/resources/capabilities.js +19 -16
  96. package/dist/adapters/mysql/resources/capabilities.js.map +1 -1
  97. package/dist/adapters/mysql/resources/cluster.d.ts +2 -2
  98. package/dist/adapters/mysql/resources/cluster.d.ts.map +1 -1
  99. package/dist/adapters/mysql/resources/cluster.js +17 -15
  100. package/dist/adapters/mysql/resources/cluster.js.map +1 -1
  101. package/dist/adapters/mysql/resources/docstore.d.ts +2 -2
  102. package/dist/adapters/mysql/resources/docstore.d.ts.map +1 -1
  103. package/dist/adapters/mysql/resources/docstore.js +12 -12
  104. package/dist/adapters/mysql/resources/docstore.js.map +1 -1
  105. package/dist/adapters/mysql/resources/events.d.ts +2 -2
  106. package/dist/adapters/mysql/resources/events.d.ts.map +1 -1
  107. package/dist/adapters/mysql/resources/events.js +12 -12
  108. package/dist/adapters/mysql/resources/events.js.map +1 -1
  109. package/dist/adapters/mysql/resources/health.d.ts +2 -2
  110. package/dist/adapters/mysql/resources/health.d.ts.map +1 -1
  111. package/dist/adapters/mysql/resources/health.js +36 -32
  112. package/dist/adapters/mysql/resources/health.js.map +1 -1
  113. package/dist/adapters/mysql/resources/index.d.ts +11 -3
  114. package/dist/adapters/mysql/resources/index.d.ts.map +1 -1
  115. package/dist/adapters/mysql/resources/index.js +28 -20
  116. package/dist/adapters/mysql/resources/index.js.map +1 -1
  117. package/dist/adapters/mysql/resources/indexes.d.ts +2 -2
  118. package/dist/adapters/mysql/resources/indexes.d.ts.map +1 -1
  119. package/dist/adapters/mysql/resources/indexes.js +12 -12
  120. package/dist/adapters/mysql/resources/indexes.js.map +1 -1
  121. package/dist/adapters/mysql/resources/innodb.d.ts +2 -2
  122. package/dist/adapters/mysql/resources/innodb.d.ts.map +1 -1
  123. package/dist/adapters/mysql/resources/innodb.js +37 -36
  124. package/dist/adapters/mysql/resources/innodb.js.map +1 -1
  125. package/dist/adapters/mysql/resources/locks.d.ts +2 -2
  126. package/dist/adapters/mysql/resources/locks.d.ts.map +1 -1
  127. package/dist/adapters/mysql/resources/locks.js +14 -14
  128. package/dist/adapters/mysql/resources/locks.js.map +1 -1
  129. package/dist/adapters/mysql/resources/performance.d.ts +2 -2
  130. package/dist/adapters/mysql/resources/performance.d.ts.map +1 -1
  131. package/dist/adapters/mysql/resources/performance.js +30 -29
  132. package/dist/adapters/mysql/resources/performance.js.map +1 -1
  133. package/dist/adapters/mysql/resources/pool.d.ts +2 -2
  134. package/dist/adapters/mysql/resources/pool.d.ts.map +1 -1
  135. package/dist/adapters/mysql/resources/pool.js +9 -9
  136. package/dist/adapters/mysql/resources/pool.js.map +1 -1
  137. package/dist/adapters/mysql/resources/processlist.d.ts +2 -2
  138. package/dist/adapters/mysql/resources/processlist.d.ts.map +1 -1
  139. package/dist/adapters/mysql/resources/processlist.js +9 -9
  140. package/dist/adapters/mysql/resources/processlist.js.map +1 -1
  141. package/dist/adapters/mysql/resources/replication.d.ts +2 -2
  142. package/dist/adapters/mysql/resources/replication.d.ts.map +1 -1
  143. package/dist/adapters/mysql/resources/replication.js +42 -35
  144. package/dist/adapters/mysql/resources/replication.js.map +1 -1
  145. package/dist/adapters/mysql/resources/schema.d.ts +2 -2
  146. package/dist/adapters/mysql/resources/schema.d.ts.map +1 -1
  147. package/dist/adapters/mysql/resources/schema.js +8 -8
  148. package/dist/adapters/mysql/resources/schema.js.map +1 -1
  149. package/dist/adapters/mysql/resources/spatial.d.ts +2 -2
  150. package/dist/adapters/mysql/resources/spatial.d.ts.map +1 -1
  151. package/dist/adapters/mysql/resources/spatial.js +9 -9
  152. package/dist/adapters/mysql/resources/spatial.js.map +1 -1
  153. package/dist/adapters/mysql/resources/status.d.ts +2 -2
  154. package/dist/adapters/mysql/resources/status.d.ts.map +1 -1
  155. package/dist/adapters/mysql/resources/status.js +10 -10
  156. package/dist/adapters/mysql/resources/status.js.map +1 -1
  157. package/dist/adapters/mysql/resources/sysschema.d.ts +2 -2
  158. package/dist/adapters/mysql/resources/sysschema.d.ts.map +1 -1
  159. package/dist/adapters/mysql/resources/sysschema.js +10 -10
  160. package/dist/adapters/mysql/resources/sysschema.js.map +1 -1
  161. package/dist/adapters/mysql/resources/tables.d.ts +2 -2
  162. package/dist/adapters/mysql/resources/tables.d.ts.map +1 -1
  163. package/dist/adapters/mysql/resources/tables.js +8 -8
  164. package/dist/adapters/mysql/resources/tables.js.map +1 -1
  165. package/dist/adapters/mysql/resources/variables.d.ts +2 -2
  166. package/dist/adapters/mysql/resources/variables.d.ts.map +1 -1
  167. package/dist/adapters/mysql/resources/variables.js +10 -10
  168. package/dist/adapters/mysql/resources/variables.js.map +1 -1
  169. package/dist/adapters/mysql/tools/admin/backup.d.ts +2 -2
  170. package/dist/adapters/mysql/tools/admin/backup.d.ts.map +1 -1
  171. package/dist/adapters/mysql/tools/admin/backup.js +193 -101
  172. package/dist/adapters/mysql/tools/admin/backup.js.map +1 -1
  173. package/dist/adapters/mysql/tools/admin/index.d.ts +2 -2
  174. package/dist/adapters/mysql/tools/admin/index.js +6 -6
  175. package/dist/adapters/mysql/tools/admin/index.js.map +1 -1
  176. package/dist/adapters/mysql/tools/admin/maintenance.d.ts +2 -2
  177. package/dist/adapters/mysql/tools/admin/maintenance.d.ts.map +1 -1
  178. package/dist/adapters/mysql/tools/admin/maintenance.js +97 -66
  179. package/dist/adapters/mysql/tools/admin/maintenance.js.map +1 -1
  180. package/dist/adapters/mysql/tools/admin/monitoring.d.ts +2 -2
  181. package/dist/adapters/mysql/tools/admin/monitoring.d.ts.map +1 -1
  182. package/dist/adapters/mysql/tools/admin/monitoring.js +215 -79
  183. package/dist/adapters/mysql/tools/admin/monitoring.js.map +1 -1
  184. package/dist/adapters/mysql/tools/cluster/group-replication.d.ts +2 -2
  185. package/dist/adapters/mysql/tools/cluster/group-replication.d.ts.map +1 -1
  186. package/dist/adapters/mysql/tools/cluster/group-replication.js +90 -74
  187. package/dist/adapters/mysql/tools/cluster/group-replication.js.map +1 -1
  188. package/dist/adapters/mysql/tools/cluster/index.d.ts +2 -2
  189. package/dist/adapters/mysql/tools/cluster/index.js +3 -3
  190. package/dist/adapters/mysql/tools/cluster/index.js.map +1 -1
  191. package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts +2 -2
  192. package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts.map +1 -1
  193. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js +225 -97
  194. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js.map +1 -1
  195. package/dist/adapters/mysql/tools/codemode/index.d.ts +38 -0
  196. package/dist/adapters/mysql/tools/codemode/index.d.ts.map +1 -0
  197. package/dist/adapters/mysql/tools/codemode/index.js +203 -0
  198. package/dist/adapters/mysql/tools/codemode/index.js.map +1 -0
  199. package/dist/adapters/mysql/tools/core.d.ts +2 -2
  200. package/dist/adapters/mysql/tools/core.d.ts.map +1 -1
  201. package/dist/adapters/mysql/tools/core.js +234 -114
  202. package/dist/adapters/mysql/tools/core.js.map +1 -1
  203. package/dist/adapters/mysql/tools/docstore.d.ts +2 -2
  204. package/dist/adapters/mysql/tools/docstore.d.ts.map +1 -1
  205. package/dist/adapters/mysql/tools/docstore.js +252 -117
  206. package/dist/adapters/mysql/tools/docstore.js.map +1 -1
  207. package/dist/adapters/mysql/tools/events.d.ts +2 -2
  208. package/dist/adapters/mysql/tools/events.d.ts.map +1 -1
  209. package/dist/adapters/mysql/tools/events.js +236 -113
  210. package/dist/adapters/mysql/tools/events.js.map +1 -1
  211. package/dist/adapters/mysql/tools/index.d.ts +19 -19
  212. package/dist/adapters/mysql/tools/index.d.ts.map +1 -1
  213. package/dist/adapters/mysql/tools/index.js +19 -19
  214. package/dist/adapters/mysql/tools/index.js.map +1 -1
  215. package/dist/adapters/mysql/tools/json/core.d.ts +2 -2
  216. package/dist/adapters/mysql/tools/json/core.d.ts.map +1 -1
  217. package/dist/adapters/mysql/tools/json/core.js +225 -131
  218. package/dist/adapters/mysql/tools/json/core.js.map +1 -1
  219. package/dist/adapters/mysql/tools/json/enhanced.d.ts +2 -2
  220. package/dist/adapters/mysql/tools/json/enhanced.d.ts.map +1 -1
  221. package/dist/adapters/mysql/tools/json/enhanced.js +274 -163
  222. package/dist/adapters/mysql/tools/json/enhanced.js.map +1 -1
  223. package/dist/adapters/mysql/tools/json/helpers.d.ts +2 -2
  224. package/dist/adapters/mysql/tools/json/helpers.d.ts.map +1 -1
  225. package/dist/adapters/mysql/tools/json/helpers.js +141 -57
  226. package/dist/adapters/mysql/tools/json/helpers.js.map +1 -1
  227. package/dist/adapters/mysql/tools/json/index.d.ts +2 -2
  228. package/dist/adapters/mysql/tools/json/index.js +6 -6
  229. package/dist/adapters/mysql/tools/json/index.js.map +1 -1
  230. package/dist/adapters/mysql/tools/partitioning.d.ts +2 -2
  231. package/dist/adapters/mysql/tools/partitioning.d.ts.map +1 -1
  232. package/dist/adapters/mysql/tools/partitioning.js +180 -64
  233. package/dist/adapters/mysql/tools/partitioning.js.map +1 -1
  234. package/dist/adapters/mysql/tools/performance/analysis.d.ts +2 -2
  235. package/dist/adapters/mysql/tools/performance/analysis.d.ts.map +1 -1
  236. package/dist/adapters/mysql/tools/performance/analysis.js +184 -101
  237. package/dist/adapters/mysql/tools/performance/analysis.js.map +1 -1
  238. package/dist/adapters/mysql/tools/performance/index.d.ts +2 -2
  239. package/dist/adapters/mysql/tools/performance/index.js +4 -4
  240. package/dist/adapters/mysql/tools/performance/index.js.map +1 -1
  241. package/dist/adapters/mysql/tools/performance/optimization.d.ts +3 -3
  242. package/dist/adapters/mysql/tools/performance/optimization.d.ts.map +1 -1
  243. package/dist/adapters/mysql/tools/performance/optimization.js +229 -77
  244. package/dist/adapters/mysql/tools/performance/optimization.js.map +1 -1
  245. package/dist/adapters/mysql/tools/proxysql.d.ts +2 -2
  246. package/dist/adapters/mysql/tools/proxysql.d.ts.map +1 -1
  247. package/dist/adapters/mysql/tools/proxysql.js +213 -125
  248. package/dist/adapters/mysql/tools/proxysql.js.map +1 -1
  249. package/dist/adapters/mysql/tools/replication.d.ts +2 -2
  250. package/dist/adapters/mysql/tools/replication.d.ts.map +1 -1
  251. package/dist/adapters/mysql/tools/replication.js +117 -66
  252. package/dist/adapters/mysql/tools/replication.js.map +1 -1
  253. package/dist/adapters/mysql/tools/roles.d.ts +2 -2
  254. package/dist/adapters/mysql/tools/roles.d.ts.map +1 -1
  255. package/dist/adapters/mysql/tools/roles.js +276 -84
  256. package/dist/adapters/mysql/tools/roles.js.map +1 -1
  257. package/dist/adapters/mysql/tools/router.d.ts +2 -2
  258. package/dist/adapters/mysql/tools/router.d.ts.map +1 -1
  259. package/dist/adapters/mysql/tools/router.js +174 -109
  260. package/dist/adapters/mysql/tools/router.js.map +1 -1
  261. package/dist/adapters/mysql/tools/schema/constraints.d.ts +2 -2
  262. package/dist/adapters/mysql/tools/schema/constraints.d.ts.map +1 -1
  263. package/dist/adapters/mysql/tools/schema/constraints.js +24 -15
  264. package/dist/adapters/mysql/tools/schema/constraints.js.map +1 -1
  265. package/dist/adapters/mysql/tools/schema/index.d.ts +2 -2
  266. package/dist/adapters/mysql/tools/schema/index.d.ts.map +1 -1
  267. package/dist/adapters/mysql/tools/schema/index.js +7 -7
  268. package/dist/adapters/mysql/tools/schema/index.js.map +1 -1
  269. package/dist/adapters/mysql/tools/schema/management.d.ts +2 -2
  270. package/dist/adapters/mysql/tools/schema/management.d.ts.map +1 -1
  271. package/dist/adapters/mysql/tools/schema/management.js +99 -42
  272. package/dist/adapters/mysql/tools/schema/management.js.map +1 -1
  273. package/dist/adapters/mysql/tools/schema/routines.d.ts +2 -2
  274. package/dist/adapters/mysql/tools/schema/routines.d.ts.map +1 -1
  275. package/dist/adapters/mysql/tools/schema/routines.js +36 -19
  276. package/dist/adapters/mysql/tools/schema/routines.js.map +1 -1
  277. package/dist/adapters/mysql/tools/schema/scheduled_events.d.ts +2 -2
  278. package/dist/adapters/mysql/tools/schema/scheduled_events.d.ts.map +1 -1
  279. package/dist/adapters/mysql/tools/schema/scheduled_events.js +26 -13
  280. package/dist/adapters/mysql/tools/schema/scheduled_events.js.map +1 -1
  281. package/dist/adapters/mysql/tools/schema/triggers.d.ts +2 -2
  282. package/dist/adapters/mysql/tools/schema/triggers.d.ts.map +1 -1
  283. package/dist/adapters/mysql/tools/schema/triggers.js +24 -13
  284. package/dist/adapters/mysql/tools/schema/triggers.js.map +1 -1
  285. package/dist/adapters/mysql/tools/schema/views.d.ts +2 -2
  286. package/dist/adapters/mysql/tools/schema/views.d.ts.map +1 -1
  287. package/dist/adapters/mysql/tools/schema/views.js +59 -28
  288. package/dist/adapters/mysql/tools/schema/views.js.map +1 -1
  289. package/dist/adapters/mysql/tools/security/audit.d.ts +2 -2
  290. package/dist/adapters/mysql/tools/security/audit.d.ts.map +1 -1
  291. package/dist/adapters/mysql/tools/security/audit.js +61 -55
  292. package/dist/adapters/mysql/tools/security/audit.js.map +1 -1
  293. package/dist/adapters/mysql/tools/security/data-protection.d.ts +2 -2
  294. package/dist/adapters/mysql/tools/security/data-protection.d.ts.map +1 -1
  295. package/dist/adapters/mysql/tools/security/data-protection.js +193 -80
  296. package/dist/adapters/mysql/tools/security/data-protection.js.map +1 -1
  297. package/dist/adapters/mysql/tools/security/encryption.d.ts +2 -2
  298. package/dist/adapters/mysql/tools/security/encryption.d.ts.map +1 -1
  299. package/dist/adapters/mysql/tools/security/encryption.js +86 -67
  300. package/dist/adapters/mysql/tools/security/encryption.js.map +1 -1
  301. package/dist/adapters/mysql/tools/security/index.d.ts +2 -2
  302. package/dist/adapters/mysql/tools/security/index.js +4 -4
  303. package/dist/adapters/mysql/tools/security/index.js.map +1 -1
  304. package/dist/adapters/mysql/tools/shell/backup.d.ts +1 -1
  305. package/dist/adapters/mysql/tools/shell/backup.d.ts.map +1 -1
  306. package/dist/adapters/mysql/tools/shell/backup.js +122 -63
  307. package/dist/adapters/mysql/tools/shell/backup.js.map +1 -1
  308. package/dist/adapters/mysql/tools/shell/common.d.ts.map +1 -1
  309. package/dist/adapters/mysql/tools/shell/common.js +61 -37
  310. package/dist/adapters/mysql/tools/shell/common.js.map +1 -1
  311. package/dist/adapters/mysql/tools/shell/data-transfer.d.ts +1 -1
  312. package/dist/adapters/mysql/tools/shell/data-transfer.d.ts.map +1 -1
  313. package/dist/adapters/mysql/tools/shell/data-transfer.js +125 -69
  314. package/dist/adapters/mysql/tools/shell/data-transfer.js.map +1 -1
  315. package/dist/adapters/mysql/tools/shell/index.d.ts +2 -2
  316. package/dist/adapters/mysql/tools/shell/index.js +6 -6
  317. package/dist/adapters/mysql/tools/shell/index.js.map +1 -1
  318. package/dist/adapters/mysql/tools/shell/info.d.ts +1 -1
  319. package/dist/adapters/mysql/tools/shell/info.d.ts.map +1 -1
  320. package/dist/adapters/mysql/tools/shell/info.js +12 -12
  321. package/dist/adapters/mysql/tools/shell/info.js.map +1 -1
  322. package/dist/adapters/mysql/tools/shell/restore.d.ts +1 -1
  323. package/dist/adapters/mysql/tools/shell/restore.d.ts.map +1 -1
  324. package/dist/adapters/mysql/tools/shell/restore.js +128 -43
  325. package/dist/adapters/mysql/tools/shell/restore.js.map +1 -1
  326. package/dist/adapters/mysql/tools/shell/utilities.d.ts +1 -1
  327. package/dist/adapters/mysql/tools/shell/utilities.d.ts.map +1 -1
  328. package/dist/adapters/mysql/tools/shell/utilities.js +42 -18
  329. package/dist/adapters/mysql/tools/shell/utilities.js.map +1 -1
  330. package/dist/adapters/mysql/tools/spatial/geometry.d.ts +2 -2
  331. package/dist/adapters/mysql/tools/spatial/geometry.d.ts.map +1 -1
  332. package/dist/adapters/mysql/tools/spatial/geometry.js +85 -46
  333. package/dist/adapters/mysql/tools/spatial/geometry.js.map +1 -1
  334. package/dist/adapters/mysql/tools/spatial/index.d.ts +2 -2
  335. package/dist/adapters/mysql/tools/spatial/index.js +5 -5
  336. package/dist/adapters/mysql/tools/spatial/index.js.map +1 -1
  337. package/dist/adapters/mysql/tools/spatial/operations.d.ts +2 -2
  338. package/dist/adapters/mysql/tools/spatial/operations.d.ts.map +1 -1
  339. package/dist/adapters/mysql/tools/spatial/operations.js +175 -106
  340. package/dist/adapters/mysql/tools/spatial/operations.js.map +1 -1
  341. package/dist/adapters/mysql/tools/spatial/queries.d.ts +2 -2
  342. package/dist/adapters/mysql/tools/spatial/queries.d.ts.map +1 -1
  343. package/dist/adapters/mysql/tools/spatial/queries.js +144 -100
  344. package/dist/adapters/mysql/tools/spatial/queries.js.map +1 -1
  345. package/dist/adapters/mysql/tools/spatial/setup.d.ts +2 -2
  346. package/dist/adapters/mysql/tools/spatial/setup.d.ts.map +1 -1
  347. package/dist/adapters/mysql/tools/spatial/setup.js +122 -34
  348. package/dist/adapters/mysql/tools/spatial/setup.js.map +1 -1
  349. package/dist/adapters/mysql/tools/stats/comparative.d.ts +2 -2
  350. package/dist/adapters/mysql/tools/stats/comparative.d.ts.map +1 -1
  351. package/dist/adapters/mysql/tools/stats/comparative.js +159 -107
  352. package/dist/adapters/mysql/tools/stats/comparative.js.map +1 -1
  353. package/dist/adapters/mysql/tools/stats/descriptive.d.ts +2 -2
  354. package/dist/adapters/mysql/tools/stats/descriptive.d.ts.map +1 -1
  355. package/dist/adapters/mysql/tools/stats/descriptive.js +268 -205
  356. package/dist/adapters/mysql/tools/stats/descriptive.js.map +1 -1
  357. package/dist/adapters/mysql/tools/stats/index.d.ts +2 -2
  358. package/dist/adapters/mysql/tools/stats/index.js +3 -3
  359. package/dist/adapters/mysql/tools/stats/index.js.map +1 -1
  360. package/dist/adapters/mysql/tools/sysschema/activity.d.ts +2 -2
  361. package/dist/adapters/mysql/tools/sysschema/activity.d.ts.map +1 -1
  362. package/dist/adapters/mysql/tools/sysschema/activity.js +23 -23
  363. package/dist/adapters/mysql/tools/sysschema/activity.js.map +1 -1
  364. package/dist/adapters/mysql/tools/sysschema/index.d.ts +2 -2
  365. package/dist/adapters/mysql/tools/sysschema/index.js +4 -4
  366. package/dist/adapters/mysql/tools/sysschema/index.js.map +1 -1
  367. package/dist/adapters/mysql/tools/sysschema/performance.d.ts +2 -2
  368. package/dist/adapters/mysql/tools/sysschema/performance.d.ts.map +1 -1
  369. package/dist/adapters/mysql/tools/sysschema/performance.js +58 -43
  370. package/dist/adapters/mysql/tools/sysschema/performance.js.map +1 -1
  371. package/dist/adapters/mysql/tools/sysschema/resources.d.ts +2 -2
  372. package/dist/adapters/mysql/tools/sysschema/resources.d.ts.map +1 -1
  373. package/dist/adapters/mysql/tools/sysschema/resources.js +58 -33
  374. package/dist/adapters/mysql/tools/sysschema/resources.js.map +1 -1
  375. package/dist/adapters/mysql/tools/text/fulltext.d.ts +4 -3
  376. package/dist/adapters/mysql/tools/text/fulltext.d.ts.map +1 -1
  377. package/dist/adapters/mysql/tools/text/fulltext.js +214 -55
  378. package/dist/adapters/mysql/tools/text/fulltext.js.map +1 -1
  379. package/dist/adapters/mysql/tools/text/index.d.ts +3 -3
  380. package/dist/adapters/mysql/tools/text/index.d.ts.map +1 -1
  381. package/dist/adapters/mysql/tools/text/index.js +6 -5
  382. package/dist/adapters/mysql/tools/text/index.js.map +1 -1
  383. package/dist/adapters/mysql/tools/text/processing.d.ts +2 -2
  384. package/dist/adapters/mysql/tools/text/processing.d.ts.map +1 -1
  385. package/dist/adapters/mysql/tools/text/processing.js +175 -122
  386. package/dist/adapters/mysql/tools/text/processing.js.map +1 -1
  387. package/dist/adapters/mysql/tools/transactions.d.ts +2 -2
  388. package/dist/adapters/mysql/tools/transactions.d.ts.map +1 -1
  389. package/dist/adapters/mysql/tools/transactions.js +162 -85
  390. package/dist/adapters/mysql/tools/transactions.js.map +1 -1
  391. package/dist/adapters/mysql/types/proxysql-types.d.ts +7 -2
  392. package/dist/adapters/mysql/types/proxysql-types.d.ts.map +1 -1
  393. package/dist/adapters/mysql/types/proxysql-types.js +52 -30
  394. package/dist/adapters/mysql/types/proxysql-types.js.map +1 -1
  395. package/dist/adapters/mysql/types/router-types.d.ts +1 -1
  396. package/dist/adapters/mysql/types/router-types.js +17 -17
  397. package/dist/adapters/mysql/types/router-types.js.map +1 -1
  398. package/dist/adapters/mysql/types/shell-types.d.ts +1 -2
  399. package/dist/adapters/mysql/types/shell-types.d.ts.map +1 -1
  400. package/dist/adapters/mysql/types/shell-types.js +255 -82
  401. package/dist/adapters/mysql/types/shell-types.js.map +1 -1
  402. package/dist/adapters/mysql/types.d.ts +976 -80
  403. package/dist/adapters/mysql/types.d.ts.map +1 -1
  404. package/dist/adapters/mysql/types.js +1317 -170
  405. package/dist/adapters/mysql/types.js.map +1 -1
  406. package/dist/auth/AuthorizationServerDiscovery.d.ts +1 -1
  407. package/dist/auth/AuthorizationServerDiscovery.d.ts.map +1 -1
  408. package/dist/auth/AuthorizationServerDiscovery.js +16 -14
  409. package/dist/auth/AuthorizationServerDiscovery.js.map +1 -1
  410. package/dist/auth/OAuthResourceServer.d.ts +1 -1
  411. package/dist/auth/OAuthResourceServer.d.ts.map +1 -1
  412. package/dist/auth/OAuthResourceServer.js +4 -4
  413. package/dist/auth/OAuthResourceServer.js.map +1 -1
  414. package/dist/auth/TokenValidator.d.ts +1 -1
  415. package/dist/auth/TokenValidator.d.ts.map +1 -1
  416. package/dist/auth/TokenValidator.js +30 -20
  417. package/dist/auth/TokenValidator.js.map +1 -1
  418. package/dist/auth/errors.d.ts.map +1 -1
  419. package/dist/auth/errors.js +24 -24
  420. package/dist/auth/errors.js.map +1 -1
  421. package/dist/auth/index.d.ts +7 -7
  422. package/dist/auth/index.d.ts.map +1 -1
  423. package/dist/auth/index.js +6 -6
  424. package/dist/auth/index.js.map +1 -1
  425. package/dist/auth/middleware.d.ts +2 -2
  426. package/dist/auth/middleware.d.ts.map +1 -1
  427. package/dist/auth/middleware.js +28 -24
  428. package/dist/auth/middleware.js.map +1 -1
  429. package/dist/auth/scopes.d.ts +2 -2
  430. package/dist/auth/scopes.d.ts.map +1 -1
  431. package/dist/auth/scopes.js +23 -16
  432. package/dist/auth/scopes.js.map +1 -1
  433. package/dist/auth/types.d.ts +2 -2
  434. package/dist/auth/types.d.ts.map +1 -1
  435. package/dist/cli/args.d.ts +1 -1
  436. package/dist/cli/args.d.ts.map +1 -1
  437. package/dist/cli/args.js +82 -68
  438. package/dist/cli/args.js.map +1 -1
  439. package/dist/cli.d.ts +1 -1
  440. package/dist/cli.d.ts.map +1 -1
  441. package/dist/cli.js +44 -34
  442. package/dist/cli.js.map +1 -1
  443. package/dist/codemode/api.d.ts +69 -0
  444. package/dist/codemode/api.d.ts.map +1 -0
  445. package/dist/codemode/api.js +1035 -0
  446. package/dist/codemode/api.js.map +1 -0
  447. package/dist/codemode/index.d.ts +13 -0
  448. package/dist/codemode/index.d.ts.map +1 -0
  449. package/dist/codemode/index.js +17 -0
  450. package/dist/codemode/index.js.map +1 -0
  451. package/dist/codemode/sandbox-factory.d.ts +72 -0
  452. package/dist/codemode/sandbox-factory.d.ts.map +1 -0
  453. package/dist/codemode/sandbox-factory.js +88 -0
  454. package/dist/codemode/sandbox-factory.js.map +1 -0
  455. package/dist/codemode/sandbox.d.ts +96 -0
  456. package/dist/codemode/sandbox.d.ts.map +1 -0
  457. package/dist/codemode/sandbox.js +345 -0
  458. package/dist/codemode/sandbox.js.map +1 -0
  459. package/dist/codemode/security.d.ts +44 -0
  460. package/dist/codemode/security.d.ts.map +1 -0
  461. package/dist/codemode/security.js +149 -0
  462. package/dist/codemode/security.js.map +1 -0
  463. package/dist/codemode/types.d.ts +137 -0
  464. package/dist/codemode/types.d.ts.map +1 -0
  465. package/dist/codemode/types.js +46 -0
  466. package/dist/codemode/types.js.map +1 -0
  467. package/dist/codemode/worker-sandbox.d.ts +82 -0
  468. package/dist/codemode/worker-sandbox.d.ts.map +1 -0
  469. package/dist/codemode/worker-sandbox.js +244 -0
  470. package/dist/codemode/worker-sandbox.js.map +1 -0
  471. package/dist/codemode/worker-script.d.ts +8 -0
  472. package/dist/codemode/worker-script.d.ts.map +1 -0
  473. package/dist/codemode/worker-script.js +113 -0
  474. package/dist/codemode/worker-script.js.map +1 -0
  475. package/dist/constants/ServerInstructions.d.ts +2 -2
  476. package/dist/constants/ServerInstructions.d.ts.map +1 -1
  477. package/dist/constants/ServerInstructions.js +252 -36
  478. package/dist/constants/ServerInstructions.js.map +1 -1
  479. package/dist/filtering/ToolConstants.d.ts +12 -12
  480. package/dist/filtering/ToolConstants.d.ts.map +1 -1
  481. package/dist/filtering/ToolConstants.js +253 -214
  482. package/dist/filtering/ToolConstants.js.map +1 -1
  483. package/dist/filtering/ToolFilter.d.ts +2 -2
  484. package/dist/filtering/ToolFilter.d.ts.map +1 -1
  485. package/dist/filtering/ToolFilter.js +47 -36
  486. package/dist/filtering/ToolFilter.js.map +1 -1
  487. package/dist/index.d.ts +9 -9
  488. package/dist/index.d.ts.map +1 -1
  489. package/dist/index.js +7 -7
  490. package/dist/index.js.map +1 -1
  491. package/dist/logging/McpLogging.d.ts +2 -2
  492. package/dist/logging/McpLogging.d.ts.map +1 -1
  493. package/dist/logging/McpLogging.js +16 -13
  494. package/dist/logging/McpLogging.js.map +1 -1
  495. package/dist/logging/index.d.ts +1 -1
  496. package/dist/logging/index.js +1 -1
  497. package/dist/pool/ConnectionPool.d.ts +3 -3
  498. package/dist/pool/ConnectionPool.d.ts.map +1 -1
  499. package/dist/pool/ConnectionPool.js +30 -26
  500. package/dist/pool/ConnectionPool.js.map +1 -1
  501. package/dist/progress/ProgressReporter.d.ts +1 -1
  502. package/dist/progress/ProgressReporter.d.ts.map +1 -1
  503. package/dist/progress/ProgressReporter.js +5 -5
  504. package/dist/progress/ProgressReporter.js.map +1 -1
  505. package/dist/progress/index.d.ts +1 -1
  506. package/dist/progress/index.d.ts.map +1 -1
  507. package/dist/progress/index.js +1 -1
  508. package/dist/progress/index.js.map +1 -1
  509. package/dist/server/McpServer.d.ts +3 -3
  510. package/dist/server/McpServer.d.ts.map +1 -1
  511. package/dist/server/McpServer.js +58 -53
  512. package/dist/server/McpServer.js.map +1 -1
  513. package/dist/transports/http.d.ts +3 -3
  514. package/dist/transports/http.d.ts.map +1 -1
  515. package/dist/transports/http.js +36 -33
  516. package/dist/transports/http.js.map +1 -1
  517. package/dist/transports/index.d.ts +1 -1
  518. package/dist/transports/index.d.ts.map +1 -1
  519. package/dist/transports/index.js +1 -1
  520. package/dist/transports/index.js.map +1 -1
  521. package/dist/types/index.d.ts +6 -6
  522. package/dist/types/index.d.ts.map +1 -1
  523. package/dist/types/index.js +1 -1
  524. package/dist/types/index.js.map +1 -1
  525. package/dist/types/modules/database.d.ts +1 -1
  526. package/dist/types/modules/database.d.ts.map +1 -1
  527. package/dist/types/modules/errors.d.ts.map +1 -1
  528. package/dist/types/modules/errors.js +15 -15
  529. package/dist/types/modules/errors.js.map +1 -1
  530. package/dist/types/modules/oauth.d.ts +1 -1
  531. package/dist/types/modules/oauth.d.ts.map +1 -1
  532. package/dist/types/modules/query.d.ts +8 -8
  533. package/dist/types/modules/query.d.ts.map +1 -1
  534. package/dist/types/modules/server.d.ts +5 -3
  535. package/dist/types/modules/server.d.ts.map +1 -1
  536. package/dist/types/modules/tools.d.ts +6 -6
  537. package/dist/types/modules/tools.d.ts.map +1 -1
  538. package/dist/utils/logger.d.ts +2 -2
  539. package/dist/utils/logger.d.ts.map +1 -1
  540. package/dist/utils/logger.js +58 -55
  541. package/dist/utils/logger.js.map +1 -1
  542. package/dist/utils/promptGenerator.d.ts +1 -1
  543. package/dist/utils/promptGenerator.d.ts.map +1 -1
  544. package/dist/utils/promptGenerator.js +24 -16
  545. package/dist/utils/promptGenerator.js.map +1 -1
  546. package/dist/utils/validators.d.ts +21 -2
  547. package/dist/utils/validators.d.ts.map +1 -1
  548. package/dist/utils/validators.js +101 -13
  549. package/dist/utils/validators.js.map +1 -1
  550. package/eslint.config.js +117 -81
  551. package/package.json +66 -64
  552. package/releases/release-notes.md +32 -26
  553. package/releases/v2.0.0-release-notes.md +99 -51
  554. package/releases/v2.1.0-release-notes.md +14 -5
  555. package/releases/v2.2.0-release-notes.md +239 -0
  556. package/releases/v2.3.0-release-notes.md +191 -0
  557. package/server.json +1 -1
  558. package/src/__tests__/cli.test.ts +302 -247
  559. package/src/__tests__/index.test.ts +21 -21
  560. package/src/__tests__/mocks/adapter.ts +204 -163
  561. package/src/__tests__/mocks/index.ts +30 -23
  562. package/src/__tests__/mocks/mysql.ts +94 -84
  563. package/src/__tests__/perf.test.ts +207 -203
  564. package/src/__tests__/performance.test.ts +173 -164
  565. package/src/__tests__/setup.ts +26 -21
  566. package/src/adapters/DatabaseAdapter.ts +386 -340
  567. package/src/adapters/__tests__/DatabaseAdapter.test.ts +455 -377
  568. package/src/adapters/mysql/MySQLAdapter.ts +560 -486
  569. package/src/adapters/mysql/SchemaManager.ts +251 -208
  570. package/src/adapters/mysql/__tests__/MySQLAdapter.integration.test.ts +150 -147
  571. package/src/adapters/mysql/__tests__/MySQLAdapter.test.ts +590 -477
  572. package/src/adapters/mysql/__tests__/SchemaManager.test.ts +196 -154
  573. package/src/adapters/mysql/index.ts +2 -2
  574. package/src/adapters/mysql/prompts/__tests__/indexTuning.test.ts +33 -26
  575. package/src/adapters/mysql/prompts/__tests__/prompts.test.ts +277 -239
  576. package/src/adapters/mysql/prompts/backupStrategy.ts +29 -17
  577. package/src/adapters/mysql/prompts/clusterSetup.ts +11 -10
  578. package/src/adapters/mysql/prompts/docstoreSetup.ts +10 -10
  579. package/src/adapters/mysql/prompts/eventScheduler.ts +10 -10
  580. package/src/adapters/mysql/prompts/healthCheck.ts +20 -15
  581. package/src/adapters/mysql/prompts/index.ts +202 -145
  582. package/src/adapters/mysql/prompts/indexTuning.ts +22 -17
  583. package/src/adapters/mysql/prompts/mysqlshSetup.ts +11 -11
  584. package/src/adapters/mysql/prompts/proxysqlSetup.ts +10 -10
  585. package/src/adapters/mysql/prompts/replicationSetup.ts +24 -16
  586. package/src/adapters/mysql/prompts/routerSetup.ts +15 -10
  587. package/src/adapters/mysql/prompts/spatialSetup.ts +10 -10
  588. package/src/adapters/mysql/prompts/sysSchema.ts +11 -10
  589. package/src/adapters/mysql/resources/__tests__/capabilities.test.ts +118 -47
  590. package/src/adapters/mysql/resources/__tests__/cluster.test.ts +163 -104
  591. package/src/adapters/mysql/resources/__tests__/docstore.test.ts +88 -81
  592. package/src/adapters/mysql/resources/__tests__/events.test.ts +94 -83
  593. package/src/adapters/mysql/resources/__tests__/health.test.ts +131 -91
  594. package/src/adapters/mysql/resources/__tests__/indexes.test.ts +125 -102
  595. package/src/adapters/mysql/resources/__tests__/innodb.test.ts +86 -62
  596. package/src/adapters/mysql/resources/__tests__/locks.test.ts +142 -104
  597. package/src/adapters/mysql/resources/__tests__/performance.test.ts +81 -58
  598. package/src/adapters/mysql/resources/__tests__/pool.test.ts +45 -40
  599. package/src/adapters/mysql/resources/__tests__/processlist.test.ts +39 -23
  600. package/src/adapters/mysql/resources/__tests__/replication.test.ts +265 -211
  601. package/src/adapters/mysql/resources/__tests__/resources.test.ts +121 -109
  602. package/src/adapters/mysql/resources/__tests__/schema.test.ts +29 -23
  603. package/src/adapters/mysql/resources/__tests__/spatial.test.ts +58 -45
  604. package/src/adapters/mysql/resources/__tests__/status.test.ts +62 -45
  605. package/src/adapters/mysql/resources/__tests__/sysschema.test.ts +99 -60
  606. package/src/adapters/mysql/resources/__tests__/tables.test.ts +41 -32
  607. package/src/adapters/mysql/resources/__tests__/variables.test.ts +77 -49
  608. package/src/adapters/mysql/resources/capabilities.ts +61 -42
  609. package/src/adapters/mysql/resources/cluster.ts +58 -49
  610. package/src/adapters/mysql/resources/docstore.ts +46 -41
  611. package/src/adapters/mysql/resources/events.ts +37 -31
  612. package/src/adapters/mysql/resources/health.ts +98 -74
  613. package/src/adapters/mysql/resources/index.ts +55 -47
  614. package/src/adapters/mysql/resources/indexes.ts +66 -51
  615. package/src/adapters/mysql/resources/innodb.ts +98 -81
  616. package/src/adapters/mysql/resources/locks.ts +43 -40
  617. package/src/adapters/mysql/resources/performance.ts +80 -67
  618. package/src/adapters/mysql/resources/pool.ts +23 -20
  619. package/src/adapters/mysql/resources/processlist.ts +23 -18
  620. package/src/adapters/mysql/resources/replication.ts +124 -105
  621. package/src/adapters/mysql/resources/schema.ts +23 -18
  622. package/src/adapters/mysql/resources/spatial.ts +31 -26
  623. package/src/adapters/mysql/resources/status.ts +27 -22
  624. package/src/adapters/mysql/resources/sysschema.ts +41 -36
  625. package/src/adapters/mysql/resources/tables.ts +23 -18
  626. package/src/adapters/mysql/resources/variables.ts +27 -22
  627. package/src/adapters/mysql/tools/__tests__/cluster.test.ts +419 -311
  628. package/src/adapters/mysql/tools/__tests__/core.test.ts +701 -382
  629. package/src/adapters/mysql/tools/__tests__/docstore.test.ts +782 -413
  630. package/src/adapters/mysql/tools/__tests__/events.test.ts +806 -486
  631. package/src/adapters/mysql/tools/__tests__/json_core.test.ts +326 -259
  632. package/src/adapters/mysql/tools/__tests__/json_enhanced.test.ts +452 -352
  633. package/src/adapters/mysql/tools/__tests__/json_helpers.test.ts +203 -128
  634. package/src/adapters/mysql/tools/__tests__/proxysql.test.ts +576 -340
  635. package/src/adapters/mysql/tools/__tests__/replication.test.ts +796 -390
  636. package/src/adapters/mysql/tools/__tests__/roles.test.ts +423 -166
  637. package/src/adapters/mysql/tools/__tests__/router.test.ts +644 -540
  638. package/src/adapters/mysql/tools/__tests__/security.test.ts +746 -421
  639. package/src/adapters/mysql/tools/__tests__/security_injection.test.ts +246 -173
  640. package/src/adapters/mysql/tools/__tests__/security_integration.test.ts +244 -205
  641. package/src/adapters/mysql/tools/__tests__/spatial.test.ts +443 -298
  642. package/src/adapters/mysql/tools/__tests__/spatial_handler.test.ts +535 -150
  643. package/src/adapters/mysql/tools/__tests__/stats.test.ts +861 -553
  644. package/src/adapters/mysql/tools/__tests__/transactions.test.ts +452 -263
  645. package/src/adapters/mysql/tools/admin/__tests__/backup.test.ts +612 -372
  646. package/src/adapters/mysql/tools/admin/__tests__/maintenance.test.ts +550 -257
  647. package/src/adapters/mysql/tools/admin/__tests__/monitoring.test.ts +549 -352
  648. package/src/adapters/mysql/tools/admin/backup.ts +339 -215
  649. package/src/adapters/mysql/tools/admin/index.ts +46 -46
  650. package/src/adapters/mysql/tools/admin/maintenance.ts +180 -130
  651. package/src/adapters/mysql/tools/admin/monitoring.ts +373 -199
  652. package/src/adapters/mysql/tools/cluster/__tests__/group-replication.test.ts +200 -186
  653. package/src/adapters/mysql/tools/cluster/__tests__/innodb-cluster.test.ts +399 -95
  654. package/src/adapters/mysql/tools/cluster/group-replication.ts +218 -183
  655. package/src/adapters/mysql/tools/cluster/index.ts +27 -27
  656. package/src/adapters/mysql/tools/cluster/innodb-cluster.ts +413 -251
  657. package/src/adapters/mysql/tools/codemode/index.ts +249 -0
  658. package/src/adapters/mysql/tools/core.ts +425 -285
  659. package/src/adapters/mysql/tools/docstore.ts +478 -276
  660. package/src/adapters/mysql/tools/events.ts +441 -285
  661. package/src/adapters/mysql/tools/index.ts +31 -20
  662. package/src/adapters/mysql/tools/json/__tests__/core.test.ts +456 -199
  663. package/src/adapters/mysql/tools/json/__tests__/enhanced.test.ts +554 -298
  664. package/src/adapters/mysql/tools/json/__tests__/helpers.test.ts +195 -74
  665. package/src/adapters/mysql/tools/json/__tests__/validation.test.ts +106 -72
  666. package/src/adapters/mysql/tools/json/core.ts +368 -263
  667. package/src/adapters/mysql/tools/json/enhanced.ts +368 -229
  668. package/src/adapters/mysql/tools/json/helpers.ts +205 -113
  669. package/src/adapters/mysql/tools/json/index.ts +46 -46
  670. package/src/adapters/mysql/tools/partitioning.ts +289 -140
  671. package/src/adapters/mysql/tools/performance/__tests__/analysis.test.ts +664 -249
  672. package/src/adapters/mysql/tools/performance/__tests__/optimization.test.ts +436 -179
  673. package/src/adapters/mysql/tools/performance/analysis.ts +319 -215
  674. package/src/adapters/mysql/tools/performance/index.ts +33 -33
  675. package/src/adapters/mysql/tools/performance/optimization.ts +438 -183
  676. package/src/adapters/mysql/tools/proxysql.ts +462 -320
  677. package/src/adapters/mysql/tools/replication.ts +233 -180
  678. package/src/adapters/mysql/tools/roles.ts +429 -171
  679. package/src/adapters/mysql/tools/router.ts +410 -292
  680. package/src/adapters/mysql/tools/schema/__tests__/constraints.test.ts +157 -82
  681. package/src/adapters/mysql/tools/schema/__tests__/management.test.ts +226 -101
  682. package/src/adapters/mysql/tools/schema/__tests__/routines.test.ts +80 -35
  683. package/src/adapters/mysql/tools/schema/__tests__/scheduled_events.test.ts +59 -40
  684. package/src/adapters/mysql/tools/schema/__tests__/triggers.test.ts +65 -40
  685. package/src/adapters/mysql/tools/schema/__tests__/views.test.ts +146 -77
  686. package/src/adapters/mysql/tools/schema/constraints.ts +61 -42
  687. package/src/adapters/mysql/tools/schema/index.ts +26 -35
  688. package/src/adapters/mysql/tools/schema/management.ts +167 -94
  689. package/src/adapters/mysql/tools/schema/routines.ts +79 -48
  690. package/src/adapters/mysql/tools/schema/scheduled_events.ts +53 -32
  691. package/src/adapters/mysql/tools/schema/triggers.ts +51 -33
  692. package/src/adapters/mysql/tools/schema/views.ts +96 -53
  693. package/src/adapters/mysql/tools/security/__tests__/audit.test.ts +216 -158
  694. package/src/adapters/mysql/tools/security/__tests__/data-protection.test.ts +154 -98
  695. package/src/adapters/mysql/tools/security/__tests__/encryption.test.ts +174 -138
  696. package/src/adapters/mysql/tools/security/audit.ts +213 -193
  697. package/src/adapters/mysql/tools/security/data-protection.ts +342 -198
  698. package/src/adapters/mysql/tools/security/encryption.ts +233 -193
  699. package/src/adapters/mysql/tools/security/index.ts +26 -26
  700. package/src/adapters/mysql/tools/shell/__tests__/backup.test.ts +443 -283
  701. package/src/adapters/mysql/tools/shell/__tests__/common.test.ts +183 -130
  702. package/src/adapters/mysql/tools/shell/__tests__/data-transfer.test.ts +516 -353
  703. package/src/adapters/mysql/tools/shell/__tests__/info.test.ts +65 -63
  704. package/src/adapters/mysql/tools/shell/__tests__/restore.test.ts +260 -174
  705. package/src/adapters/mysql/tools/shell/__tests__/utilities.test.ts +161 -143
  706. package/src/adapters/mysql/tools/shell/backup.ts +280 -188
  707. package/src/adapters/mysql/tools/shell/common.ts +203 -153
  708. package/src/adapters/mysql/tools/shell/data-transfer.ts +286 -200
  709. package/src/adapters/mysql/tools/shell/index.ts +29 -29
  710. package/src/adapters/mysql/tools/shell/info.ts +35 -31
  711. package/src/adapters/mysql/tools/shell/restore.ts +236 -121
  712. package/src/adapters/mysql/tools/shell/utilities.ts +86 -45
  713. package/src/adapters/mysql/tools/spatial/__tests__/geometry.test.ts +129 -89
  714. package/src/adapters/mysql/tools/spatial/__tests__/operations.test.ts +284 -148
  715. package/src/adapters/mysql/tools/spatial/__tests__/queries.test.ts +340 -245
  716. package/src/adapters/mysql/tools/spatial/geometry.ts +120 -74
  717. package/src/adapters/mysql/tools/spatial/index.ts +33 -33
  718. package/src/adapters/mysql/tools/spatial/operations.ts +254 -171
  719. package/src/adapters/mysql/tools/spatial/queries.ts +221 -165
  720. package/src/adapters/mysql/tools/spatial/setup.ts +180 -73
  721. package/src/adapters/mysql/tools/stats/__tests__/comparative.test.ts +188 -130
  722. package/src/adapters/mysql/tools/stats/comparative.ts +261 -187
  723. package/src/adapters/mysql/tools/stats/descriptive.ts +414 -322
  724. package/src/adapters/mysql/tools/stats/index.ts +23 -23
  725. package/src/adapters/mysql/tools/sysschema/__tests__/activity.test.ts +99 -71
  726. package/src/adapters/mysql/tools/sysschema/__tests__/io_summary_fix.test.ts +21 -18
  727. package/src/adapters/mysql/tools/sysschema/__tests__/performance.test.ts +149 -108
  728. package/src/adapters/mysql/tools/sysschema/__tests__/resources.test.ts +243 -104
  729. package/src/adapters/mysql/tools/sysschema/activity.ts +72 -64
  730. package/src/adapters/mysql/tools/sysschema/index.ts +24 -24
  731. package/src/adapters/mysql/tools/sysschema/performance.ts +140 -115
  732. package/src/adapters/mysql/tools/sysschema/resources.ts +140 -99
  733. package/src/adapters/mysql/tools/text/__tests__/fulltext.test.ts +526 -145
  734. package/src/adapters/mysql/tools/text/__tests__/processing.test.ts +452 -193
  735. package/src/adapters/mysql/tools/text/fulltext.ts +327 -123
  736. package/src/adapters/mysql/tools/text/index.ts +32 -30
  737. package/src/adapters/mysql/tools/text/processing.ts +281 -212
  738. package/src/adapters/mysql/tools/transactions.ts +288 -197
  739. package/src/adapters/mysql/types/__tests__/shell-types.test.ts +204 -202
  740. package/src/adapters/mysql/types/proxysql-types.ts +142 -109
  741. package/src/adapters/mysql/types/router-types.ts +36 -36
  742. package/src/adapters/mysql/types/shell-types.ts +280 -94
  743. package/src/adapters/mysql/types.ts +1475 -164
  744. package/src/auth/AuthorizationServerDiscovery.ts +127 -113
  745. package/src/auth/OAuthResourceServer.ts +67 -62
  746. package/src/auth/TokenValidator.ts +136 -119
  747. package/src/auth/__tests__/AuthorizationServerDiscovery.test.ts +295 -274
  748. package/src/auth/__tests__/OAuthResourceServer.test.ts +180 -169
  749. package/src/auth/__tests__/TokenValidator.test.ts +297 -285
  750. package/src/auth/__tests__/errors.test.ts +180 -175
  751. package/src/auth/__tests__/middleware.test.ts +281 -247
  752. package/src/auth/__tests__/scopes.test.ts +136 -134
  753. package/src/auth/errors.ts +56 -56
  754. package/src/auth/index.ts +23 -17
  755. package/src/auth/middleware.ts +161 -139
  756. package/src/auth/scopes.ts +134 -107
  757. package/src/auth/types.ts +155 -155
  758. package/src/cli/__tests__/args.test.ts +241 -216
  759. package/src/cli/__tests__/main.test.ts +191 -158
  760. package/src/cli/args.ts +285 -258
  761. package/src/cli.ts +150 -127
  762. package/src/codemode/api.ts +1224 -0
  763. package/src/codemode/index.ts +51 -0
  764. package/src/codemode/sandbox-factory.ts +146 -0
  765. package/src/codemode/sandbox.ts +450 -0
  766. package/src/codemode/security.ts +188 -0
  767. package/src/codemode/types.ts +194 -0
  768. package/src/codemode/worker-sandbox.ts +326 -0
  769. package/src/codemode/worker-script.ts +144 -0
  770. package/src/constants/ServerInstructions.ts +295 -70
  771. package/src/filtering/ToolConstants.ts +311 -272
  772. package/src/filtering/ToolFilter.ts +254 -220
  773. package/src/filtering/__tests__/ToolFilter.test.ts +469 -396
  774. package/src/index.ts +62 -57
  775. package/src/logging/McpLogging.ts +128 -119
  776. package/src/logging/__tests__/McpLogging.test.ts +223 -223
  777. package/src/logging/index.ts +2 -2
  778. package/src/pool/ConnectionPool.ts +260 -246
  779. package/src/pool/__tests__/ConnectionPool.test.ts +452 -418
  780. package/src/progress/ProgressReporter.ts +123 -123
  781. package/src/progress/__tests__/ProgressReporter.test.ts +235 -229
  782. package/src/progress/index.ts +6 -2
  783. package/src/server/McpServer.ts +305 -285
  784. package/src/server/__tests__/McpServer.test.ts +333 -291
  785. package/src/transports/__tests__/http.test.ts +658 -527
  786. package/src/transports/http.ts +237 -203
  787. package/src/transports/index.ts +6 -2
  788. package/src/types/__tests__/types.test.ts +197 -193
  789. package/src/types/index.ts +49 -37
  790. package/src/types/modules/database.ts +65 -63
  791. package/src/types/modules/errors.ts +41 -37
  792. package/src/types/modules/oauth.ts +46 -46
  793. package/src/types/modules/query.ts +75 -75
  794. package/src/types/modules/server.ts +21 -18
  795. package/src/types/modules/tools.ts +182 -178
  796. package/src/utils/__tests__/logger.test.ts +424 -414
  797. package/src/utils/__tests__/validators.test.ts +250 -165
  798. package/src/utils/logger.ts +344 -330
  799. package/src/utils/promptGenerator.ts +58 -47
  800. package/src/utils/validators.ts +217 -91
  801. package/tsconfig.json +41 -50
  802. package/vitest.config.ts +23 -23
@@ -1,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
  });