@neverinfamous/mysql-mcp 2.3.0 → 3.0.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 (347) hide show
  1. package/.dockerignore +1 -0
  2. package/.gitattributes +18 -0
  3. package/.github/workflows/codeql.yml +2 -10
  4. package/.github/workflows/docker-publish.yml +15 -13
  5. package/CHANGELOG.md +287 -1
  6. package/DOCKER_README.md +100 -265
  7. package/Dockerfile +5 -0
  8. package/README.md +124 -59
  9. package/VERSION +1 -1
  10. package/dist/__tests__/mocks/adapter.d.ts.map +1 -1
  11. package/dist/__tests__/mocks/adapter.js +2 -0
  12. package/dist/__tests__/mocks/adapter.js.map +1 -1
  13. package/dist/adapters/DatabaseAdapter.d.ts.map +1 -1
  14. package/dist/adapters/DatabaseAdapter.js +50 -9
  15. package/dist/adapters/DatabaseAdapter.js.map +1 -1
  16. package/dist/adapters/mysql/MySQLAdapter.d.ts +6 -0
  17. package/dist/adapters/mysql/MySQLAdapter.d.ts.map +1 -1
  18. package/dist/adapters/mysql/MySQLAdapter.js +8 -0
  19. package/dist/adapters/mysql/MySQLAdapter.js.map +1 -1
  20. package/dist/adapters/mysql/SchemaManager.js +16 -15
  21. package/dist/adapters/mysql/SchemaManager.js.map +1 -1
  22. package/dist/adapters/mysql/prompts/index.js +10 -20
  23. package/dist/adapters/mysql/prompts/index.js.map +1 -1
  24. package/dist/adapters/mysql/prompts/proxysqlSetup.js +1 -1
  25. package/dist/adapters/mysql/resources/docstore.d.ts.map +1 -1
  26. package/dist/adapters/mysql/resources/docstore.js +10 -7
  27. package/dist/adapters/mysql/resources/docstore.js.map +1 -1
  28. package/dist/adapters/mysql/resources/events.js +11 -8
  29. package/dist/adapters/mysql/resources/events.js.map +1 -1
  30. package/dist/adapters/mysql/resources/indexes.d.ts.map +1 -1
  31. package/dist/adapters/mysql/resources/indexes.js +12 -15
  32. package/dist/adapters/mysql/resources/indexes.js.map +1 -1
  33. package/dist/adapters/mysql/resources/innodb.d.ts.map +1 -1
  34. package/dist/adapters/mysql/resources/innodb.js +20 -17
  35. package/dist/adapters/mysql/resources/innodb.js.map +1 -1
  36. package/dist/adapters/mysql/resources/locks.d.ts.map +1 -1
  37. package/dist/adapters/mysql/resources/locks.js +9 -6
  38. package/dist/adapters/mysql/resources/locks.js.map +1 -1
  39. package/dist/adapters/mysql/resources/performance.d.ts.map +1 -1
  40. package/dist/adapters/mysql/resources/performance.js +15 -15
  41. package/dist/adapters/mysql/resources/performance.js.map +1 -1
  42. package/dist/adapters/mysql/resources/spatial.d.ts.map +1 -1
  43. package/dist/adapters/mysql/resources/spatial.js +9 -6
  44. package/dist/adapters/mysql/resources/spatial.js.map +1 -1
  45. package/dist/adapters/mysql/resources/sysschema.d.ts.map +1 -1
  46. package/dist/adapters/mysql/resources/sysschema.js +12 -9
  47. package/dist/adapters/mysql/resources/sysschema.js.map +1 -1
  48. package/dist/adapters/mysql/tools/admin/backup.d.ts.map +1 -1
  49. package/dist/adapters/mysql/tools/admin/backup.js +170 -121
  50. package/dist/adapters/mysql/tools/admin/backup.js.map +1 -1
  51. package/dist/adapters/mysql/tools/admin/maintenance.d.ts.map +1 -1
  52. package/dist/adapters/mysql/tools/admin/maintenance.js +106 -57
  53. package/dist/adapters/mysql/tools/admin/maintenance.js.map +1 -1
  54. package/dist/adapters/mysql/tools/admin/monitoring.d.ts.map +1 -1
  55. package/dist/adapters/mysql/tools/admin/monitoring.js +183 -101
  56. package/dist/adapters/mysql/tools/admin/monitoring.js.map +1 -1
  57. package/dist/adapters/mysql/tools/cluster/group-replication.d.ts.map +1 -1
  58. package/dist/adapters/mysql/tools/cluster/group-replication.js +164 -120
  59. package/dist/adapters/mysql/tools/cluster/group-replication.js.map +1 -1
  60. package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts.map +1 -1
  61. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js +212 -145
  62. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js.map +1 -1
  63. package/dist/adapters/mysql/tools/codemode/index.d.ts.map +1 -1
  64. package/dist/adapters/mysql/tools/codemode/index.js +6 -4
  65. package/dist/adapters/mysql/tools/codemode/index.js.map +1 -1
  66. package/dist/adapters/mysql/tools/core.d.ts.map +1 -1
  67. package/dist/adapters/mysql/tools/core.js +152 -29
  68. package/dist/adapters/mysql/tools/core.js.map +1 -1
  69. package/dist/adapters/mysql/tools/docstore.d.ts.map +1 -1
  70. package/dist/adapters/mysql/tools/docstore.js +340 -163
  71. package/dist/adapters/mysql/tools/docstore.js.map +1 -1
  72. package/dist/adapters/mysql/tools/events.d.ts.map +1 -1
  73. package/dist/adapters/mysql/tools/events.js +284 -198
  74. package/dist/adapters/mysql/tools/events.js.map +1 -1
  75. package/dist/adapters/mysql/tools/json/core.d.ts.map +1 -1
  76. package/dist/adapters/mysql/tools/json/core.js +11 -39
  77. package/dist/adapters/mysql/tools/json/core.js.map +1 -1
  78. package/dist/adapters/mysql/tools/json/enhanced.d.ts.map +1 -1
  79. package/dist/adapters/mysql/tools/json/enhanced.js +15 -33
  80. package/dist/adapters/mysql/tools/json/enhanced.js.map +1 -1
  81. package/dist/adapters/mysql/tools/json/helpers.d.ts.map +1 -1
  82. package/dist/adapters/mysql/tools/json/helpers.js +13 -24
  83. package/dist/adapters/mysql/tools/json/helpers.js.map +1 -1
  84. package/dist/adapters/mysql/tools/partitioning.js +3 -0
  85. package/dist/adapters/mysql/tools/partitioning.js.map +1 -1
  86. package/dist/adapters/mysql/tools/performance/analysis.d.ts.map +1 -1
  87. package/dist/adapters/mysql/tools/performance/analysis.js +89 -60
  88. package/dist/adapters/mysql/tools/performance/analysis.js.map +1 -1
  89. package/dist/adapters/mysql/tools/performance/optimization.d.ts.map +1 -1
  90. package/dist/adapters/mysql/tools/performance/optimization.js +151 -127
  91. package/dist/adapters/mysql/tools/performance/optimization.js.map +1 -1
  92. package/dist/adapters/mysql/tools/proxysql.d.ts +1 -1
  93. package/dist/adapters/mysql/tools/proxysql.d.ts.map +1 -1
  94. package/dist/adapters/mysql/tools/proxysql.js +289 -176
  95. package/dist/adapters/mysql/tools/proxysql.js.map +1 -1
  96. package/dist/adapters/mysql/tools/replication.js +75 -49
  97. package/dist/adapters/mysql/tools/replication.js.map +1 -1
  98. package/dist/adapters/mysql/tools/roles.d.ts.map +1 -1
  99. package/dist/adapters/mysql/tools/roles.js +224 -182
  100. package/dist/adapters/mysql/tools/roles.js.map +1 -1
  101. package/dist/adapters/mysql/tools/router.d.ts.map +1 -1
  102. package/dist/adapters/mysql/tools/router.js +168 -67
  103. package/dist/adapters/mysql/tools/router.js.map +1 -1
  104. package/dist/adapters/mysql/tools/schema/constraints.d.ts.map +1 -1
  105. package/dist/adapters/mysql/tools/schema/constraints.js +21 -3
  106. package/dist/adapters/mysql/tools/schema/constraints.js.map +1 -1
  107. package/dist/adapters/mysql/tools/schema/management.d.ts.map +1 -1
  108. package/dist/adapters/mysql/tools/schema/management.js +61 -14
  109. package/dist/adapters/mysql/tools/schema/management.js.map +1 -1
  110. package/dist/adapters/mysql/tools/schema/routines.d.ts.map +1 -1
  111. package/dist/adapters/mysql/tools/schema/routines.js +27 -4
  112. package/dist/adapters/mysql/tools/schema/routines.js.map +1 -1
  113. package/dist/adapters/mysql/tools/schema/scheduled_events.d.ts.map +1 -1
  114. package/dist/adapters/mysql/tools/schema/scheduled_events.js +24 -3
  115. package/dist/adapters/mysql/tools/schema/scheduled_events.js.map +1 -1
  116. package/dist/adapters/mysql/tools/schema/triggers.d.ts.map +1 -1
  117. package/dist/adapters/mysql/tools/schema/triggers.js +23 -2
  118. package/dist/adapters/mysql/tools/schema/triggers.js.map +1 -1
  119. package/dist/adapters/mysql/tools/schema/views.d.ts.map +1 -1
  120. package/dist/adapters/mysql/tools/schema/views.js +47 -7
  121. package/dist/adapters/mysql/tools/schema/views.js.map +1 -1
  122. package/dist/adapters/mysql/tools/security/audit.d.ts.map +1 -1
  123. package/dist/adapters/mysql/tools/security/audit.js +102 -34
  124. package/dist/adapters/mysql/tools/security/audit.js.map +1 -1
  125. package/dist/adapters/mysql/tools/security/data-protection.d.ts.map +1 -1
  126. package/dist/adapters/mysql/tools/security/data-protection.js +264 -205
  127. package/dist/adapters/mysql/tools/security/data-protection.js.map +1 -1
  128. package/dist/adapters/mysql/tools/security/encryption.d.ts.map +1 -1
  129. package/dist/adapters/mysql/tools/security/encryption.js +137 -104
  130. package/dist/adapters/mysql/tools/security/encryption.js.map +1 -1
  131. package/dist/adapters/mysql/tools/shell/backup.d.ts.map +1 -1
  132. package/dist/adapters/mysql/tools/shell/backup.js +71 -59
  133. package/dist/adapters/mysql/tools/shell/backup.js.map +1 -1
  134. package/dist/adapters/mysql/tools/shell/restore.d.ts.map +1 -1
  135. package/dist/adapters/mysql/tools/shell/restore.js +61 -47
  136. package/dist/adapters/mysql/tools/shell/restore.js.map +1 -1
  137. package/dist/adapters/mysql/tools/spatial/geometry.d.ts.map +1 -1
  138. package/dist/adapters/mysql/tools/spatial/geometry.js +19 -5
  139. package/dist/adapters/mysql/tools/spatial/geometry.js.map +1 -1
  140. package/dist/adapters/mysql/tools/spatial/operations.d.ts.map +1 -1
  141. package/dist/adapters/mysql/tools/spatial/operations.js +42 -17
  142. package/dist/adapters/mysql/tools/spatial/operations.js.map +1 -1
  143. package/dist/adapters/mysql/tools/spatial/queries.d.ts.map +1 -1
  144. package/dist/adapters/mysql/tools/spatial/queries.js +109 -57
  145. package/dist/adapters/mysql/tools/spatial/queries.js.map +1 -1
  146. package/dist/adapters/mysql/tools/spatial/setup.d.ts.map +1 -1
  147. package/dist/adapters/mysql/tools/spatial/setup.js +103 -50
  148. package/dist/adapters/mysql/tools/spatial/setup.js.map +1 -1
  149. package/dist/adapters/mysql/tools/stats/comparative.d.ts.map +1 -1
  150. package/dist/adapters/mysql/tools/stats/comparative.js +128 -79
  151. package/dist/adapters/mysql/tools/stats/comparative.js.map +1 -1
  152. package/dist/adapters/mysql/tools/stats/descriptive.d.ts.map +1 -1
  153. package/dist/adapters/mysql/tools/stats/descriptive.js +174 -102
  154. package/dist/adapters/mysql/tools/stats/descriptive.js.map +1 -1
  155. package/dist/adapters/mysql/tools/sysschema/activity.d.ts.map +1 -1
  156. package/dist/adapters/mysql/tools/sysschema/activity.js +50 -25
  157. package/dist/adapters/mysql/tools/sysschema/activity.js.map +1 -1
  158. package/dist/adapters/mysql/tools/sysschema/performance.d.ts.map +1 -1
  159. package/dist/adapters/mysql/tools/sysschema/performance.js +121 -66
  160. package/dist/adapters/mysql/tools/sysschema/performance.js.map +1 -1
  161. package/dist/adapters/mysql/tools/sysschema/resources.d.ts.map +1 -1
  162. package/dist/adapters/mysql/tools/sysschema/resources.js +101 -64
  163. package/dist/adapters/mysql/tools/sysschema/resources.js.map +1 -1
  164. package/dist/adapters/mysql/tools/text/fulltext.d.ts.map +1 -1
  165. package/dist/adapters/mysql/tools/text/fulltext.js +18 -32
  166. package/dist/adapters/mysql/tools/text/fulltext.js.map +1 -1
  167. package/dist/adapters/mysql/tools/transactions.d.ts.map +1 -1
  168. package/dist/adapters/mysql/tools/transactions.js +48 -23
  169. package/dist/adapters/mysql/tools/transactions.js.map +1 -1
  170. package/dist/adapters/mysql/types/proxysql-types.d.ts +15 -0
  171. package/dist/adapters/mysql/types/proxysql-types.d.ts.map +1 -1
  172. package/dist/adapters/mysql/types/proxysql-types.js +33 -1
  173. package/dist/adapters/mysql/types/proxysql-types.js.map +1 -1
  174. package/dist/adapters/mysql/types/router-types.d.ts +1 -1
  175. package/dist/adapters/mysql/types/router-types.js +1 -1
  176. package/dist/adapters/mysql/types/router-types.js.map +1 -1
  177. package/dist/adapters/mysql/types/shell-types.js +2 -2
  178. package/dist/adapters/mysql/types/shell-types.js.map +1 -1
  179. package/dist/adapters/mysql/types.d.ts +485 -21
  180. package/dist/adapters/mysql/types.d.ts.map +1 -1
  181. package/dist/adapters/mysql/types.js +546 -19
  182. package/dist/adapters/mysql/types.js.map +1 -1
  183. package/dist/auth/scopes.js +1 -1
  184. package/dist/auth/scopes.js.map +1 -1
  185. package/dist/codemode/api.d.ts +3 -2
  186. package/dist/codemode/api.d.ts.map +1 -1
  187. package/dist/codemode/api.js +80 -5
  188. package/dist/codemode/api.js.map +1 -1
  189. package/dist/codemode/sandbox-factory.js +1 -1
  190. package/dist/codemode/sandbox-factory.js.map +1 -1
  191. package/dist/codemode/types.d.ts +26 -0
  192. package/dist/codemode/types.d.ts.map +1 -1
  193. package/dist/codemode/types.js +2 -0
  194. package/dist/codemode/types.js.map +1 -1
  195. package/dist/codemode/worker-sandbox.d.ts +4 -2
  196. package/dist/codemode/worker-sandbox.d.ts.map +1 -1
  197. package/dist/codemode/worker-sandbox.js +66 -7
  198. package/dist/codemode/worker-sandbox.js.map +1 -1
  199. package/dist/codemode/worker-script.d.ts +3 -0
  200. package/dist/codemode/worker-script.d.ts.map +1 -1
  201. package/dist/codemode/worker-script.js +128 -75
  202. package/dist/codemode/worker-script.js.map +1 -1
  203. package/dist/constants/ServerInstructions.d.ts +1 -1
  204. package/dist/constants/ServerInstructions.d.ts.map +1 -1
  205. package/dist/constants/ServerInstructions.js +37 -31
  206. package/dist/constants/ServerInstructions.js.map +1 -1
  207. package/dist/filtering/ToolConstants.d.ts +1 -1
  208. package/dist/filtering/ToolConstants.d.ts.map +1 -1
  209. package/dist/filtering/ToolConstants.js +1 -2
  210. package/dist/filtering/ToolConstants.js.map +1 -1
  211. package/dist/pool/ConnectionPool.d.ts.map +1 -1
  212. package/dist/pool/ConnectionPool.js.map +1 -1
  213. package/dist/transports/http.d.ts.map +1 -1
  214. package/dist/transports/http.js +6 -0
  215. package/dist/transports/http.js.map +1 -1
  216. package/dist/utils/validators.d.ts +1 -1
  217. package/dist/utils/validators.d.ts.map +1 -1
  218. package/dist/utils/validators.js.map +1 -1
  219. package/package.json +4 -4
  220. package/releases/v2.3.0-release-notes.md +20 -20
  221. package/releases/v2.3.1-release-notes.md +34 -0
  222. package/releases/v3.0.0-release-notes.md +81 -0
  223. package/src/__tests__/mocks/adapter.ts +3 -0
  224. package/src/__tests__/perf.test.ts +6 -6
  225. package/src/adapters/DatabaseAdapter.ts +58 -9
  226. package/src/adapters/__tests__/DatabaseAdapter.test.ts +89 -8
  227. package/src/adapters/mysql/MySQLAdapter.ts +17 -2
  228. package/src/adapters/mysql/SchemaManager.ts +21 -21
  229. package/src/adapters/mysql/__tests__/MySQLAdapter.test.ts +1 -1
  230. package/src/adapters/mysql/prompts/index.ts +12 -22
  231. package/src/adapters/mysql/prompts/proxysqlSetup.ts +1 -1
  232. package/src/adapters/mysql/resources/docstore.ts +13 -10
  233. package/src/adapters/mysql/resources/events.ts +12 -12
  234. package/src/adapters/mysql/resources/indexes.ts +17 -19
  235. package/src/adapters/mysql/resources/innodb.ts +23 -22
  236. package/src/adapters/mysql/resources/locks.ts +9 -7
  237. package/src/adapters/mysql/resources/performance.ts +23 -18
  238. package/src/adapters/mysql/resources/spatial.ts +9 -7
  239. package/src/adapters/mysql/resources/sysschema.ts +12 -11
  240. package/src/adapters/mysql/tools/__tests__/core.test.ts +126 -55
  241. package/src/adapters/mysql/tools/__tests__/docstore.test.ts +459 -88
  242. package/src/adapters/mysql/tools/__tests__/events.test.ts +281 -103
  243. package/src/adapters/mysql/tools/__tests__/proxysql.test.ts +128 -28
  244. package/src/adapters/mysql/tools/__tests__/replication.test.ts +48 -2
  245. package/src/adapters/mysql/tools/__tests__/roles.test.ts +15 -18
  246. package/src/adapters/mysql/tools/__tests__/router.test.ts +32 -5
  247. package/src/adapters/mysql/tools/__tests__/security.test.ts +126 -2
  248. package/src/adapters/mysql/tools/__tests__/security_injection.test.ts +84 -76
  249. package/src/adapters/mysql/tools/__tests__/security_integration.test.ts +47 -50
  250. package/src/adapters/mysql/tools/__tests__/spatial.test.ts +11 -10
  251. package/src/adapters/mysql/tools/__tests__/spatial_handler.test.ts +54 -38
  252. package/src/adapters/mysql/tools/__tests__/stats.test.ts +285 -152
  253. package/src/adapters/mysql/tools/__tests__/transactions.test.ts +13 -13
  254. package/src/adapters/mysql/tools/admin/__tests__/backup.test.ts +171 -25
  255. package/src/adapters/mysql/tools/admin/__tests__/maintenance.test.ts +240 -4
  256. package/src/adapters/mysql/tools/admin/__tests__/monitoring-summary.test.ts +274 -0
  257. package/src/adapters/mysql/tools/admin/__tests__/monitoring.test.ts +94 -5
  258. package/src/adapters/mysql/tools/admin/backup.ts +193 -143
  259. package/src/adapters/mysql/tools/admin/maintenance.ts +118 -69
  260. package/src/adapters/mysql/tools/admin/monitoring.ts +201 -125
  261. package/src/adapters/mysql/tools/cluster/__tests__/group-replication.test.ts +69 -0
  262. package/src/adapters/mysql/tools/cluster/__tests__/innodb-cluster.test.ts +141 -0
  263. package/src/adapters/mysql/tools/cluster/group-replication.ts +172 -132
  264. package/src/adapters/mysql/tools/cluster/innodb-cluster.ts +231 -157
  265. package/src/adapters/mysql/tools/codemode/__tests__/codemode-tool.test.ts +227 -0
  266. package/src/adapters/mysql/tools/codemode/index.ts +5 -3
  267. package/src/adapters/mysql/tools/core.ts +152 -38
  268. package/src/adapters/mysql/tools/docstore.ts +422 -205
  269. package/src/adapters/mysql/tools/events.ts +334 -233
  270. package/src/adapters/mysql/tools/json/__tests__/core.test.ts +20 -0
  271. package/src/adapters/mysql/tools/json/__tests__/enhanced.test.ts +82 -50
  272. package/src/adapters/mysql/tools/json/__tests__/helpers.test.ts +42 -3
  273. package/src/adapters/mysql/tools/json/core.ts +21 -42
  274. package/src/adapters/mysql/tools/json/enhanced.ts +22 -37
  275. package/src/adapters/mysql/tools/json/helpers.ts +21 -25
  276. package/src/adapters/mysql/tools/partitioning.ts +3 -0
  277. package/src/adapters/mysql/tools/performance/__tests__/analysis.test.ts +98 -5
  278. package/src/adapters/mysql/tools/performance/__tests__/optimization-coverage.test.ts +515 -0
  279. package/src/adapters/mysql/tools/performance/__tests__/optimization.test.ts +187 -0
  280. package/src/adapters/mysql/tools/performance/analysis.ts +95 -69
  281. package/src/adapters/mysql/tools/performance/optimization.ts +182 -153
  282. package/src/adapters/mysql/tools/proxysql.ts +314 -209
  283. package/src/adapters/mysql/tools/replication.ts +84 -57
  284. package/src/adapters/mysql/tools/roles.ts +274 -226
  285. package/src/adapters/mysql/tools/router.ts +181 -85
  286. package/src/adapters/mysql/tools/schema/__tests__/constraints.test.ts +13 -0
  287. package/src/adapters/mysql/tools/schema/__tests__/management.test.ts +60 -25
  288. package/src/adapters/mysql/tools/schema/__tests__/scheduled_events.test.ts +11 -0
  289. package/src/adapters/mysql/tools/schema/__tests__/triggers.test.ts +25 -4
  290. package/src/adapters/mysql/tools/schema/__tests__/views.test.ts +46 -14
  291. package/src/adapters/mysql/tools/schema/constraints.ts +22 -3
  292. package/src/adapters/mysql/tools/schema/management.ts +60 -15
  293. package/src/adapters/mysql/tools/schema/routines.ts +26 -4
  294. package/src/adapters/mysql/tools/schema/scheduled_events.ts +25 -3
  295. package/src/adapters/mysql/tools/schema/triggers.ts +27 -2
  296. package/src/adapters/mysql/tools/schema/views.ts +46 -8
  297. package/src/adapters/mysql/tools/security/__tests__/audit.test.ts +90 -4
  298. package/src/adapters/mysql/tools/security/audit.ts +113 -39
  299. package/src/adapters/mysql/tools/security/data-protection.ts +293 -233
  300. package/src/adapters/mysql/tools/security/encryption.ts +172 -139
  301. package/src/adapters/mysql/tools/shell/__tests__/backup.test.ts +29 -0
  302. package/src/adapters/mysql/tools/shell/backup.ts +90 -73
  303. package/src/adapters/mysql/tools/shell/restore.ts +62 -48
  304. package/src/adapters/mysql/tools/spatial/__tests__/operations.test.ts +22 -14
  305. package/src/adapters/mysql/tools/spatial/__tests__/queries.test.ts +65 -51
  306. package/src/adapters/mysql/tools/spatial/geometry.ts +23 -7
  307. package/src/adapters/mysql/tools/spatial/operations.ts +60 -31
  308. package/src/adapters/mysql/tools/spatial/queries.ts +142 -65
  309. package/src/adapters/mysql/tools/spatial/setup.ts +121 -55
  310. package/src/adapters/mysql/tools/stats/__tests__/comparative.test.ts +12 -10
  311. package/src/adapters/mysql/tools/stats/comparative.ts +150 -98
  312. package/src/adapters/mysql/tools/stats/descriptive.ts +204 -127
  313. package/src/adapters/mysql/tools/sysschema/__tests__/error-paths.test.ts +222 -0
  314. package/src/adapters/mysql/tools/sysschema/__tests__/performance.test.ts +45 -0
  315. package/src/adapters/mysql/tools/sysschema/__tests__/resources.test.ts +6 -3
  316. package/src/adapters/mysql/tools/sysschema/activity.ts +52 -27
  317. package/src/adapters/mysql/tools/sysschema/performance.ts +132 -68
  318. package/src/adapters/mysql/tools/sysschema/resources.ts +105 -67
  319. package/src/adapters/mysql/tools/text/__tests__/fulltext.test.ts +45 -17
  320. package/src/adapters/mysql/tools/text/fulltext.ts +27 -38
  321. package/src/adapters/mysql/tools/transactions.ts +49 -24
  322. package/src/adapters/mysql/types/proxysql-types.ts +38 -1
  323. package/src/adapters/mysql/types/router-types.ts +1 -1
  324. package/src/adapters/mysql/types/shell-types.ts +2 -2
  325. package/src/adapters/mysql/types.ts +632 -19
  326. package/src/auth/__tests__/scopes.test.ts +2 -2
  327. package/src/auth/scopes.ts +1 -1
  328. package/src/codemode/__tests__/api.test.ts +417 -0
  329. package/src/codemode/__tests__/sandbox-factory.test.ts +158 -0
  330. package/src/codemode/__tests__/sandbox.test.ts +301 -0
  331. package/src/codemode/__tests__/security.test.ts +368 -0
  332. package/src/codemode/__tests__/worker-sandbox.test.ts +179 -0
  333. package/src/codemode/__tests__/worker-script.test.ts +226 -0
  334. package/src/codemode/api.ts +89 -5
  335. package/src/codemode/sandbox-factory.ts +1 -1
  336. package/src/codemode/types.ts +34 -0
  337. package/src/codemode/worker-sandbox.ts +74 -7
  338. package/src/codemode/worker-script.ts +157 -86
  339. package/src/constants/ServerInstructions.ts +37 -31
  340. package/src/filtering/ToolConstants.ts +1 -2
  341. package/src/filtering/__tests__/ToolFilter.test.ts +9 -9
  342. package/src/pool/ConnectionPool.ts +4 -1
  343. package/src/transports/__tests__/http.test.ts +15 -3
  344. package/src/transports/http.ts +12 -0
  345. package/src/utils/validators.ts +2 -1
  346. package/vitest.config.ts +3 -1
  347. package/CODE_MODE.md +0 -245
@@ -4,13 +4,30 @@
4
4
  * Tools for SSL/TLS monitoring, encryption status, and password validation.
5
5
  */
6
6
 
7
- import { z } from "zod";
7
+ import { z, ZodError } from "zod";
8
8
  import type { MySQLAdapter } from "../../MySQLAdapter.js";
9
9
  import type {
10
10
  ToolDefinition,
11
11
  RequestContext,
12
12
  } from "../../../../types/index.js";
13
13
 
14
+ // =============================================================================
15
+ // Helpers
16
+ // =============================================================================
17
+
18
+ /** Extract human-readable messages from a ZodError instead of raw JSON array */
19
+ function formatZodError(error: ZodError): string {
20
+ return error.issues.map((i) => i.message).join("; ");
21
+ }
22
+
23
+ /** Strip verbose adapter prefixes from error messages */
24
+ function stripErrorPrefix(msg: string): string {
25
+ return msg
26
+ .replace(/^Query failed:\s*/i, "")
27
+ .replace(/^Execute failed:\s*/i, "")
28
+ .trim();
29
+ }
30
+
14
31
  // =============================================================================
15
32
  // Zod Schemas
16
33
  // =============================================================================
@@ -41,73 +58,69 @@ export function createSecuritySSLStatusTool(
41
58
  idempotentHint: true,
42
59
  },
43
60
  handler: async (_params: unknown, _context: RequestContext) => {
44
- // Get SSL status
45
- const statusResult = await adapter.executeQuery(
46
- "SHOW STATUS LIKE 'Ssl%'",
47
- );
48
-
49
- const status: Record<string, unknown> = Object.fromEntries(
50
- (statusResult.rows ?? []).map((r) => {
51
- const record = r;
52
- const varName =
53
- typeof record["Variable_name"] === "string"
54
- ? record["Variable_name"]
55
- : "";
56
- return [varName, record["Value"]];
57
- }),
58
- );
59
-
60
- // Get SSL variables
61
- const varsResult = await adapter.executeQuery(
62
- "SHOW VARIABLES LIKE '%ssl%'",
63
- );
64
-
65
- const variables: Record<string, unknown> = Object.fromEntries(
66
- (varsResult.rows ?? []).map((r) => {
67
- const record = r;
68
- const varName =
69
- typeof record["Variable_name"] === "string"
70
- ? record["Variable_name"]
71
- : "";
72
- return [varName, record["Value"]];
73
- }),
74
- );
61
+ try {
62
+ // Get SSL status
63
+ const statusResult = await adapter.executeQuery(
64
+ "SHOW STATUS LIKE 'Ssl%'",
65
+ );
75
66
 
76
- // Check current connection
77
- // We use raw status/variables now, but @@ssl_cipher is still valid
78
- // const connResult = await adapter.executeQuery("SELECT @@ssl_cipher as cipher"); // Removing unused query for now as we get cipher from status
67
+ const status: Record<string, unknown> = Object.fromEntries(
68
+ (statusResult.rows ?? []).map((r) => {
69
+ const record = r;
70
+ const varName =
71
+ typeof record["Variable_name"] === "string"
72
+ ? record["Variable_name"]
73
+ : "";
74
+ return [varName, record["Value"]];
75
+ }),
76
+ );
79
77
 
80
- // Actually, wait, status['Ssl_cipher'] gives the cipher.
81
- // But let's check if we need @@ssl_cipher.
82
- // The original code used: sslEnabled: str(status['Ssl_cipher']) !== ''
83
- // So we don't strictly need @@ssl_cipher if Ssl_cipher status is reliable.
84
- // Let's just remove the unused query entirely.
78
+ // Get SSL variables
79
+ const varsResult = await adapter.executeQuery(
80
+ "SHOW VARIABLES LIKE '%ssl%'",
81
+ );
85
82
 
86
- // const connRow = connResult.rows?.[0]; // deleted
83
+ const variables: Record<string, unknown> = Object.fromEntries(
84
+ (varsResult.rows ?? []).map((r) => {
85
+ const record = r;
86
+ const varName =
87
+ typeof record["Variable_name"] === "string"
88
+ ? record["Variable_name"]
89
+ : "";
90
+ return [varName, record["Value"]];
91
+ }),
92
+ );
87
93
 
88
- // Helper to safely extract string values
89
- const str = (val: unknown, defaultVal = ""): string =>
90
- typeof val === "string" ? val : defaultVal;
94
+ // Helper to safely extract string values
95
+ const str = (val: unknown, defaultVal = ""): string =>
96
+ typeof val === "string" && val !== "" ? val : defaultVal;
91
97
 
92
- return {
93
- sslEnabled: str(status["Ssl_cipher"]) !== "",
94
- currentCipher: str(status["Ssl_cipher"], "None"),
95
- sslVersion: str(status["Ssl_version"], "N/A"),
96
- serverCertVerification: false, // Unknown in recent versions via variables
97
- configuration: {
98
- sslCa: str(variables["ssl_ca"]),
99
- sslCert: str(variables["ssl_cert"]),
100
- sslKey: str(variables["ssl_key"]),
101
- requireSecureTransport: str(
102
- variables["require_secure_transport"],
103
- "OFF",
104
- ),
105
- },
106
- sessionStats: {
107
- acceptedConnects: str(status["Ssl_accepts"], "0"),
108
- finishedConnects: str(status["Ssl_finished_accepts"], "0"),
109
- },
110
- };
98
+ return {
99
+ sslEnabled: str(status["Ssl_cipher"]) !== "",
100
+ currentCipher: str(status["Ssl_cipher"], "None"),
101
+ sslVersion: str(status["Ssl_version"], "N/A"),
102
+ serverCertVerification: false, // Unknown in recent versions via variables
103
+ configuration: {
104
+ sslCa: str(variables["ssl_ca"]),
105
+ sslCert: str(variables["ssl_cert"]),
106
+ sslKey: str(variables["ssl_key"]),
107
+ requireSecureTransport: str(
108
+ variables["require_secure_transport"],
109
+ "OFF",
110
+ ),
111
+ },
112
+ sessionStats: {
113
+ acceptedConnects: str(status["Ssl_accepts"], "0"),
114
+ finishedConnects: str(status["Ssl_finished_accepts"], "0"),
115
+ },
116
+ };
117
+ } catch (error) {
118
+ if (error instanceof ZodError) {
119
+ return { success: false, error: formatZodError(error) };
120
+ }
121
+ const message = error instanceof Error ? error.message : String(error);
122
+ return { success: false, error: stripErrorPrefix(message) };
123
+ }
111
124
  },
112
125
  };
113
126
  }
@@ -130,15 +143,16 @@ export function createSecurityEncryptionStatusTool(
130
143
  idempotentHint: true,
131
144
  },
132
145
  handler: async (_params: unknown, _context: RequestContext) => {
133
- // Check for keyring plugins
134
- const keyringResult = await adapter.executeQuery(`
146
+ try {
147
+ // Check for keyring plugins
148
+ const keyringResult = await adapter.executeQuery(`
135
149
  SELECT PLUGIN_NAME, PLUGIN_STATUS
136
150
  FROM information_schema.PLUGINS
137
151
  WHERE PLUGIN_NAME LIKE 'keyring%'
138
152
  `);
139
153
 
140
- // Check encrypted tablespaces
141
- const tablespaceResult = await adapter.executeQuery(`
154
+ // Check encrypted tablespaces
155
+ const tablespaceResult = await adapter.executeQuery(`
142
156
  SELECT
143
157
  NAME,
144
158
  ENCRYPTION
@@ -146,49 +160,56 @@ export function createSecurityEncryptionStatusTool(
146
160
  WHERE ENCRYPTION = 'Y'
147
161
  `);
148
162
 
149
- // Check encryption variables
150
- const varsResult = await adapter.executeQuery(
151
- "SHOW VARIABLES LIKE '%encrypt%'",
152
- );
163
+ // Check encryption variables
164
+ const varsResult = await adapter.executeQuery(
165
+ "SHOW VARIABLES LIKE '%encrypt%'",
166
+ );
153
167
 
154
- const variables: Record<string, unknown> = Object.fromEntries(
155
- (varsResult.rows ?? []).map((r) => {
156
- const record = r;
157
- const varName =
158
- typeof record["Variable_name"] === "string"
159
- ? record["Variable_name"]
160
- : "";
161
- return [varName, record["Value"]];
162
- }),
163
- );
168
+ const variables: Record<string, unknown> = Object.fromEntries(
169
+ (varsResult.rows ?? []).map((r) => {
170
+ const record = r;
171
+ const varName =
172
+ typeof record["Variable_name"] === "string"
173
+ ? record["Variable_name"]
174
+ : "";
175
+ return [varName, record["Value"]];
176
+ }),
177
+ );
164
178
 
165
- // Check redo/undo log encryption
166
- const innodbVarsResult = await adapter.executeQuery(
167
- "SHOW VARIABLES LIKE 'innodb_%encrypt%'",
168
- );
179
+ // Check redo/undo log encryption
180
+ const innodbVarsResult = await adapter.executeQuery(
181
+ "SHOW VARIABLES LIKE 'innodb_%encrypt%'",
182
+ );
169
183
 
170
- const innodbVars: Record<string, unknown> = Object.fromEntries(
171
- (innodbVarsResult.rows ?? []).map((r) => {
172
- const record = r;
173
- const varName =
174
- typeof record["Variable_name"] === "string"
175
- ? record["Variable_name"]
176
- : "";
177
- return [varName, record["Value"]];
178
- }),
179
- );
184
+ const innodbVars: Record<string, unknown> = Object.fromEntries(
185
+ (innodbVarsResult.rows ?? []).map((r) => {
186
+ const record = r;
187
+ const varName =
188
+ typeof record["Variable_name"] === "string"
189
+ ? record["Variable_name"]
190
+ : "";
191
+ return [varName, record["Value"]];
192
+ }),
193
+ );
180
194
 
181
- return {
182
- keyringPlugins: keyringResult.rows ?? [],
183
- keyringInstalled: (keyringResult.rows?.length ?? 0) > 0,
184
- encryptedTablespaces: tablespaceResult.rows ?? [],
185
- encryptedTablespaceCount: tablespaceResult.rows?.length ?? 0,
186
- encryptionSettings: {
187
- ...variables,
188
- ...innodbVars,
189
- },
190
- tdeAvailable: (keyringResult.rows?.length ?? 0) > 0,
191
- };
195
+ return {
196
+ keyringPlugins: keyringResult.rows ?? [],
197
+ keyringInstalled: (keyringResult.rows?.length ?? 0) > 0,
198
+ encryptedTablespaces: tablespaceResult.rows ?? [],
199
+ encryptedTablespaceCount: tablespaceResult.rows?.length ?? 0,
200
+ encryptionSettings: {
201
+ ...variables,
202
+ ...innodbVars,
203
+ },
204
+ tdeAvailable: (keyringResult.rows?.length ?? 0) > 0,
205
+ };
206
+ } catch (error) {
207
+ if (error instanceof ZodError) {
208
+ return { success: false, error: formatZodError(error) };
209
+ }
210
+ const message = error instanceof Error ? error.message : String(error);
211
+ return { success: false, error: stripErrorPrefix(message) };
212
+ }
192
213
  },
193
214
  };
194
215
  }
@@ -212,36 +233,36 @@ export function createSecurityPasswordValidateTool(
212
233
  idempotentHint: true,
213
234
  },
214
235
  handler: async (params: unknown, _context: RequestContext) => {
215
- const { password } = PasswordValidateSchema.parse(params);
236
+ try {
237
+ const { password } = PasswordValidateSchema.parse(params);
216
238
 
217
- // First check if validate_password component is installed
218
- // by checking for its variables
219
- const policyResult = await adapter.executeQuery(
220
- "SHOW VARIABLES LIKE 'validate_password%'",
221
- );
239
+ // First check if validate_password component is installed
240
+ // by checking for its variables
241
+ const policyResult = await adapter.executeQuery(
242
+ "SHOW VARIABLES LIKE 'validate_password%'",
243
+ );
222
244
 
223
- const policy: Record<string, unknown> = Object.fromEntries(
224
- (policyResult.rows ?? []).map((r) => {
225
- const record = r;
226
- const varName =
227
- typeof record["Variable_name"] === "string"
228
- ? record["Variable_name"]
229
- : "";
230
- return [varName, record["Value"]];
231
- }),
232
- );
245
+ const policy: Record<string, unknown> = Object.fromEntries(
246
+ (policyResult.rows ?? []).map((r) => {
247
+ const record = r;
248
+ const varName =
249
+ typeof record["Variable_name"] === "string"
250
+ ? record["Variable_name"]
251
+ : "";
252
+ return [varName, record["Value"]];
253
+ }),
254
+ );
233
255
 
234
- // If no validate_password variables exist, component is not installed
235
- if (Object.keys(policy).length === 0) {
236
- return {
237
- available: false,
238
- message: "Password validation component not installed",
239
- suggestion:
240
- 'Install with: INSTALL COMPONENT "file://component_validate_password"',
241
- };
242
- }
256
+ // If no validate_password variables exist, component is not installed
257
+ if (Object.keys(policy).length === 0) {
258
+ return {
259
+ available: false,
260
+ message: "Password validation component not installed",
261
+ suggestion:
262
+ 'Install with: INSTALL COMPONENT "file://component_validate_password"',
263
+ };
264
+ }
243
265
 
244
- try {
245
266
  // Use validate_password function
246
267
  const result = await adapter.executeQuery(
247
268
  "SELECT VALIDATE_PASSWORD_STRENGTH(?) as strength",
@@ -264,13 +285,25 @@ export function createSecurityPasswordValidateTool(
264
285
  meetsPolicy: strength >= 50, // General guideline
265
286
  policy,
266
287
  };
267
- } catch {
268
- return {
269
- available: false,
270
- message: "Password validation function failed",
271
- suggestion:
272
- 'Reinstall with: INSTALL COMPONENT "file://component_validate_password"',
273
- };
288
+ } catch (error) {
289
+ if (error instanceof ZodError) {
290
+ return { success: false, error: formatZodError(error) };
291
+ }
292
+ const message = error instanceof Error ? error.message : String(error);
293
+ // Check for known component-not-installed errors
294
+ const lower = message.toLowerCase();
295
+ if (
296
+ lower.includes("validate_password_strength") ||
297
+ lower.includes("function")
298
+ ) {
299
+ return {
300
+ available: false,
301
+ message: "Password validation function failed",
302
+ suggestion:
303
+ 'Reinstall with: INSTALL COMPONENT "file://component_validate_password"',
304
+ };
305
+ }
306
+ return { success: false, error: stripErrorPrefix(message) };
274
307
  }
275
308
  },
276
309
  };
@@ -299,6 +299,20 @@ describe("Shell Backup Tools", () => {
299
299
  expect(result.success).toBe(false);
300
300
  expect(result.error).toContain("Table not found");
301
301
  });
302
+
303
+ it("should return structured error for empty schemas array", async () => {
304
+ const tool = createShellDumpSchemasTool();
305
+ const result = (await tool.handler(
306
+ {
307
+ schemas: [],
308
+ outputDir: "/backup",
309
+ },
310
+ mockContext,
311
+ )) as any;
312
+
313
+ expect(result.success).toBe(false);
314
+ expect(result.error).toContain("At least one schema name is required");
315
+ });
302
316
  });
303
317
 
304
318
  describe("mysqlsh_dump_tables", () => {
@@ -454,5 +468,20 @@ describe("Shell Backup Tools", () => {
454
468
  expect(result.success).toBe(false);
455
469
  expect(result.error).toContain("Connection timeout");
456
470
  });
471
+
472
+ it("should return structured error for empty tables array", async () => {
473
+ const tool = createShellDumpTablesTool();
474
+ const result = (await tool.handler(
475
+ {
476
+ schema: "s",
477
+ tables: [],
478
+ outputDir: "/o",
479
+ },
480
+ mockContext,
481
+ )) as any;
482
+
483
+ expect(result.success).toBe(false);
484
+ expect(result.error).toContain("At least one table name is required");
485
+ });
457
486
  });
458
487
  });
@@ -4,6 +4,7 @@
4
4
  * Tools for creating database dumps using MySQL Shell.
5
5
  */
6
6
 
7
+ import { ZodError } from "zod";
7
8
  import type {
8
9
  ToolDefinition,
9
10
  RequestContext,
@@ -15,6 +16,11 @@ import {
15
16
  } from "../../types/shell-types.js";
16
17
  import { escapeForJS, execShellJS } from "./common.js";
17
18
 
19
+ /** Extract human-readable messages from a ZodError instead of raw JSON array */
20
+ function formatZodError(error: ZodError): string {
21
+ return error.issues.map((i) => i.message).join("; ");
22
+ }
23
+
18
24
  /**
19
25
  * Dump entire MySQL instance
20
26
  */
@@ -126,47 +132,54 @@ export function createShellDumpSchemasTool(): ToolDefinition {
126
132
  openWorldHint: true,
127
133
  },
128
134
  handler: async (params: unknown, _context: RequestContext) => {
129
- const {
130
- schemas,
131
- outputDir,
132
- threads,
133
- compression,
134
- dryRun,
135
- includeTables,
136
- excludeTables,
137
- ddlOnly,
138
- } = ShellDumpSchemasInputSchema.parse(params);
135
+ try {
136
+ const {
137
+ schemas,
138
+ outputDir,
139
+ threads,
140
+ compression,
141
+ dryRun,
142
+ includeTables,
143
+ excludeTables,
144
+ ddlOnly,
145
+ } = ShellDumpSchemasInputSchema.parse(params);
139
146
 
140
- const escapedPath = outputDir.replace(/\\/g, "\\\\");
147
+ if (schemas.length === 0) {
148
+ return {
149
+ success: false,
150
+ error: "At least one schema name is required",
151
+ };
152
+ }
141
153
 
142
- const options: string[] = [];
143
- if (threads) {
144
- options.push(`threads: ${threads}`);
145
- }
146
- if (compression && compression !== "zstd") {
147
- options.push(`compression: "${compression}"`);
148
- }
149
- if (dryRun) {
150
- options.push("dryRun: true");
151
- }
152
- if (includeTables && includeTables.length > 0) {
153
- options.push(`includeTables: ${JSON.stringify(includeTables)}`);
154
- }
155
- if (excludeTables && excludeTables.length > 0) {
156
- options.push(`excludeTables: ${JSON.stringify(excludeTables)}`);
157
- }
158
- // ddlOnly mode disables all metadata that requires extra privileges
159
- if (ddlOnly) {
160
- options.push("events: false");
161
- options.push("triggers: false");
162
- options.push("routines: false");
163
- }
154
+ const escapedPath = outputDir.replace(/\\/g, "\\\\");
164
155
 
165
- const optionsStr =
166
- options.length > 0 ? `, { ${options.join(", ")} }` : "";
167
- const jsCode = `return util.dumpSchemas(${JSON.stringify(schemas)}, "${escapedPath}"${optionsStr});`;
156
+ const options: string[] = [];
157
+ if (threads) {
158
+ options.push(`threads: ${threads}`);
159
+ }
160
+ if (compression && compression !== "zstd") {
161
+ options.push(`compression: "${compression}"`);
162
+ }
163
+ if (dryRun) {
164
+ options.push("dryRun: true");
165
+ }
166
+ if (includeTables && includeTables.length > 0) {
167
+ options.push(`includeTables: ${JSON.stringify(includeTables)}`);
168
+ }
169
+ if (excludeTables && excludeTables.length > 0) {
170
+ options.push(`excludeTables: ${JSON.stringify(excludeTables)}`);
171
+ }
172
+ // ddlOnly mode disables all metadata that requires extra privileges
173
+ if (ddlOnly) {
174
+ options.push("events: false");
175
+ options.push("triggers: false");
176
+ options.push("routines: false");
177
+ }
178
+
179
+ const optionsStr =
180
+ options.length > 0 ? `, { ${options.join(", ")} }` : "";
181
+ const jsCode = `return util.dumpSchemas(${JSON.stringify(schemas)}, "${escapedPath}"${optionsStr});`;
168
182
 
169
- try {
170
183
  const result = await execShellJS(jsCode, { timeout: 3600000 });
171
184
  return {
172
185
  success: true,
@@ -177,6 +190,9 @@ export function createShellDumpSchemasTool(): ToolDefinition {
177
190
  result,
178
191
  };
179
192
  } catch (error) {
193
+ if (error instanceof ZodError) {
194
+ return { success: false, error: formatZodError(error) };
195
+ }
180
196
  const errorMessage =
181
197
  error instanceof Error ? error.message : String(error);
182
198
  if (
@@ -186,13 +202,11 @@ export function createShellDumpSchemasTool(): ToolDefinition {
186
202
  ) {
187
203
  return {
188
204
  success: false,
189
- schemas,
190
- outputDir,
191
205
  error: `Dump failed due to missing privileges: ${errorMessage}.`,
192
206
  hint: "Set ddlOnly: true to skip events, triggers, and routines.",
193
207
  };
194
208
  }
195
- return { success: false, schemas, outputDir, error: errorMessage };
209
+ return { success: false, error: errorMessage };
196
210
  }
197
211
  },
198
212
  };
@@ -215,34 +229,43 @@ export function createShellDumpTablesTool(): ToolDefinition {
215
229
  openWorldHint: true,
216
230
  },
217
231
  handler: async (params: unknown, _context: RequestContext) => {
218
- const { schema, tables, outputDir, threads, compression, where, all } =
219
- ShellDumpTablesInputSchema.parse(params);
232
+ try {
233
+ const { schema, tables, outputDir, threads, compression, where, all } =
234
+ ShellDumpTablesInputSchema.parse(params);
220
235
 
221
- const escapedPath = outputDir.replace(/\\/g, "\\\\");
236
+ if (tables.length === 0) {
237
+ return {
238
+ success: false,
239
+ error: "At least one table name is required",
240
+ };
241
+ }
222
242
 
223
- const options: string[] = [];
224
- if (threads) {
225
- options.push(`threads: ${threads}`);
226
- }
227
- if (compression && compression !== "zstd") {
228
- options.push(`compression: "${compression}"`);
229
- }
230
- if (where && Object.keys(where).length > 0) {
231
- const whereEntries = Object.entries(where)
232
- .map(([tbl, cond]) => `"${escapeForJS(tbl)}": "${escapeForJS(cond)}"`)
233
- .join(", ");
234
- options.push(`where: { ${whereEntries} }`);
235
- }
236
- // When all is explicitly false, disable triggers/routines dumping
237
- if (!all) {
238
- options.push("triggers: false");
239
- }
243
+ const escapedPath = outputDir.replace(/\\/g, "\\\\");
240
244
 
241
- const optionsStr =
242
- options.length > 0 ? `, { ${options.join(", ")} }` : "";
243
- const jsCode = `return util.dumpTables("${schema}", ${JSON.stringify(tables)}, "${escapedPath}"${optionsStr});`;
245
+ const options: string[] = [];
246
+ if (threads) {
247
+ options.push(`threads: ${threads}`);
248
+ }
249
+ if (compression && compression !== "zstd") {
250
+ options.push(`compression: "${compression}"`);
251
+ }
252
+ if (where && Object.keys(where).length > 0) {
253
+ const whereEntries = Object.entries(where)
254
+ .map(
255
+ ([tbl, cond]) => `"${escapeForJS(tbl)}": "${escapeForJS(cond)}"`,
256
+ )
257
+ .join(", ");
258
+ options.push(`where: { ${whereEntries} }`);
259
+ }
260
+ // When all is explicitly false, disable triggers/routines dumping
261
+ if (!all) {
262
+ options.push("triggers: false");
263
+ }
264
+
265
+ const optionsStr =
266
+ options.length > 0 ? `, { ${options.join(", ")} }` : "";
267
+ const jsCode = `return util.dumpTables("${schema}", ${JSON.stringify(tables)}, "${escapedPath}"${optionsStr});`;
244
268
 
245
- try {
246
269
  const result = await execShellJS(jsCode, { timeout: 3600000 });
247
270
  return {
248
271
  success: true,
@@ -253,6 +276,9 @@ export function createShellDumpTablesTool(): ToolDefinition {
253
276
  result,
254
277
  };
255
278
  } catch (error) {
279
+ if (error instanceof ZodError) {
280
+ return { success: false, error: formatZodError(error) };
281
+ }
256
282
  const errorMessage =
257
283
  error instanceof Error ? error.message : String(error);
258
284
 
@@ -269,9 +295,6 @@ export function createShellDumpTablesTool(): ToolDefinition {
269
295
 
270
296
  return {
271
297
  success: false,
272
- schema,
273
- tables,
274
- outputDir,
275
298
  error: `Dump failed due to missing privileges: ${errorMessage}.`,
276
299
  hint:
277
300
  specificPrivilege === "EVENT" || specificPrivilege === "TRIGGER"
@@ -284,9 +307,6 @@ export function createShellDumpTablesTool(): ToolDefinition {
284
307
  if (errorMessage.includes("Fatal error during dump")) {
285
308
  return {
286
309
  success: false,
287
- schema,
288
- tables,
289
- outputDir,
290
310
  error: errorMessage.includes("Writing schema metadata")
291
311
  ? `Dump failed while writing schema metadata: ${errorMessage}.`
292
312
  : `Dump failed: ${errorMessage}.`,
@@ -296,9 +316,6 @@ export function createShellDumpTablesTool(): ToolDefinition {
296
316
 
297
317
  return {
298
318
  success: false,
299
- schema,
300
- tables,
301
- outputDir,
302
319
  error: errorMessage,
303
320
  };
304
321
  }