@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
@@ -1,10 +1,20 @@
1
- import { z } from "zod";
1
+ import { z, ZodError } from "zod";
2
2
  import type { MySQLAdapter } from "../../MySQLAdapter.js";
3
3
  import type {
4
4
  ToolDefinition,
5
5
  RequestContext,
6
6
  } from "../../../../types/index.js";
7
7
 
8
+ /** Extract human-readable messages from a ZodError instead of raw JSON array */
9
+ function formatZodError(error: ZodError): string {
10
+ return error.issues.map((i) => i.message).join("; ");
11
+ }
12
+
13
+ const ListConstraintsSchemaBase = z.object({
14
+ table: z.string().describe("Table name"),
15
+ type: z.string().optional().describe("Filter by constraint type"),
16
+ });
17
+
8
18
  const ListConstraintsSchema = z.object({
9
19
  table: z.string().describe("Table name"),
10
20
  type: z
@@ -25,14 +35,23 @@ export function createListConstraintsTool(
25
35
  description:
26
36
  "List all constraints (primary key, foreign key, unique, check) for a table.",
27
37
  group: "schema",
28
- inputSchema: ListConstraintsSchema,
38
+ inputSchema: ListConstraintsSchemaBase,
29
39
  requiredScopes: ["read"],
30
40
  annotations: {
31
41
  readOnlyHint: true,
32
42
  idempotentHint: true,
33
43
  },
34
44
  handler: async (params: unknown, _context: RequestContext) => {
35
- const { table, type } = ListConstraintsSchema.parse(params);
45
+ let parsed;
46
+ try {
47
+ parsed = ListConstraintsSchema.parse(params);
48
+ } catch (error: unknown) {
49
+ if (error instanceof ZodError) {
50
+ return { success: false, error: formatZodError(error) };
51
+ }
52
+ throw error;
53
+ }
54
+ const { table, type } = parsed;
36
55
 
37
56
  const parts = table.split(".");
38
57
  let schemaName: string | null = null;
@@ -1,4 +1,9 @@
1
- import { z } from "zod";
1
+ import { z, ZodError } from "zod";
2
+
3
+ /** Extract human-readable messages from a ZodError instead of raw JSON array */
4
+ function formatZodError(error: ZodError): string {
5
+ return error.issues.map((i) => i.message).join("; ");
6
+ }
2
7
  import type { MySQLAdapter } from "../../MySQLAdapter.js";
3
8
  import type {
4
9
  ToolDefinition,
@@ -41,7 +46,16 @@ export function createListSchemasTool(adapter: MySQLAdapter): ToolDefinition {
41
46
  idempotentHint: true,
42
47
  },
43
48
  handler: async (params: unknown, _context: RequestContext) => {
44
- const { pattern } = ListSchemasSchema.parse(params);
49
+ let parsed;
50
+ try {
51
+ parsed = ListSchemasSchema.parse(params);
52
+ } catch (error: unknown) {
53
+ if (error instanceof ZodError) {
54
+ return { success: false, error: formatZodError(error) };
55
+ }
56
+ throw error;
57
+ }
58
+ const { pattern } = parsed;
45
59
 
46
60
  let query = `
47
61
  SELECT
@@ -85,12 +99,26 @@ export function createCreateSchemaTool(adapter: MySQLAdapter): ToolDefinition {
85
99
  readOnlyHint: false,
86
100
  },
87
101
  handler: async (params: unknown, _context: RequestContext) => {
88
- const { name, charset, collation, ifNotExists } =
89
- CreateSchemaSchema.parse(params);
102
+ let parsed;
103
+ try {
104
+ parsed = CreateSchemaSchema.parse(params);
105
+ } catch (error: unknown) {
106
+ if (error instanceof ZodError) {
107
+ return { success: false, error: formatZodError(error) };
108
+ }
109
+ throw error;
110
+ }
111
+ const { name, charset, collation, ifNotExists } = parsed;
90
112
 
91
- // Validate schema name
92
113
  if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
93
- throw new Error("Invalid schema name");
114
+ return { success: false, error: "Invalid schema name" };
115
+ }
116
+
117
+ if (!/^[a-zA-Z0-9_]+$/.test(charset)) {
118
+ return { success: false, error: `Invalid charset: ${charset}` };
119
+ }
120
+ if (!/^[a-zA-Z0-9_]+$/.test(collation)) {
121
+ return { success: false, error: `Invalid collation: ${collation}` };
94
122
  }
95
123
 
96
124
  // Pre-check: detect no-op when ifNotExists is true
@@ -120,10 +148,15 @@ export function createCreateSchemaTool(adapter: MySQLAdapter): ToolDefinition {
120
148
  if (message.toLowerCase().includes("database exists")) {
121
149
  return {
122
150
  success: false,
123
- reason: `Schema '${name}' already exists`,
151
+ error: `Schema '${name}' already exists`,
124
152
  };
125
153
  }
126
- throw err;
154
+ return {
155
+ success: false,
156
+ error: message
157
+ .replace(/^Query failed:\s*/i, "")
158
+ .replace(/^Execute failed:\s*/i, ""),
159
+ };
127
160
  }
128
161
  },
129
162
  };
@@ -146,14 +179,21 @@ export function createDropSchemaTool(adapter: MySQLAdapter): ToolDefinition {
146
179
  destructiveHint: true,
147
180
  },
148
181
  handler: async (params: unknown, _context: RequestContext) => {
149
- const { name, ifExists } = DropSchemaSchema.parse(params);
182
+ let parsed;
183
+ try {
184
+ parsed = DropSchemaSchema.parse(params);
185
+ } catch (error: unknown) {
186
+ if (error instanceof ZodError) {
187
+ return { success: false, error: formatZodError(error) };
188
+ }
189
+ throw error;
190
+ }
191
+ const { name, ifExists } = parsed;
150
192
 
151
- // Validate schema name
152
193
  if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
153
- throw new Error("Invalid schema name");
194
+ return { success: false, error: "Invalid schema name" };
154
195
  }
155
196
 
156
- // Protect system schemas
157
197
  const systemSchemas = [
158
198
  "mysql",
159
199
  "information_schema",
@@ -161,7 +201,7 @@ export function createDropSchemaTool(adapter: MySQLAdapter): ToolDefinition {
161
201
  "sys",
162
202
  ];
163
203
  if (systemSchemas.includes(name.toLowerCase())) {
164
- throw new Error("Cannot drop system schema");
204
+ return { success: false, error: "Cannot drop system schema" };
165
205
  }
166
206
 
167
207
  // Pre-check: detect no-op when ifExists is true
@@ -194,10 +234,15 @@ export function createDropSchemaTool(adapter: MySQLAdapter): ToolDefinition {
194
234
  ) {
195
235
  return {
196
236
  success: false,
197
- reason: `Schema '${name}' does not exist`,
237
+ error: `Schema '${name}' does not exist`,
198
238
  };
199
239
  }
200
- throw err;
240
+ return {
241
+ success: false,
242
+ error: message
243
+ .replace(/^Query failed:\s*/i, "")
244
+ .replace(/^Execute failed:\s*/i, ""),
245
+ };
201
246
  }
202
247
  },
203
248
  };
@@ -1,4 +1,9 @@
1
- import { z } from "zod";
1
+ import { z, ZodError } from "zod";
2
+
3
+ /** Extract human-readable messages from a ZodError instead of raw JSON array */
4
+ function formatZodError(error: ZodError): string {
5
+ return error.issues.map((i) => i.message).join("; ");
6
+ }
2
7
  import type { MySQLAdapter } from "../../MySQLAdapter.js";
3
8
  import type {
4
9
  ToolDefinition,
@@ -10,7 +15,6 @@ const ListObjectsSchema = z.object({
10
15
  .string()
11
16
  .optional()
12
17
  .describe("Schema name (defaults to current database)"),
13
- type: z.enum(["PROCEDURE", "FUNCTION"]).optional().describe("Filter by type"),
14
18
  });
15
19
 
16
20
  /**
@@ -31,7 +35,16 @@ export function createListStoredProceduresTool(
31
35
  idempotentHint: true,
32
36
  },
33
37
  handler: async (params: unknown, _context: RequestContext) => {
34
- const { schema } = ListObjectsSchema.parse(params);
38
+ let parsed;
39
+ try {
40
+ parsed = ListObjectsSchema.parse(params);
41
+ } catch (error: unknown) {
42
+ if (error instanceof ZodError) {
43
+ return { success: false, error: formatZodError(error) };
44
+ }
45
+ throw error;
46
+ }
47
+ const { schema } = parsed;
35
48
 
36
49
  // P154: Schema existence check when explicitly provided
37
50
  if (schema) {
@@ -97,7 +110,16 @@ export function createListFunctionsTool(adapter: MySQLAdapter): ToolDefinition {
97
110
  idempotentHint: true,
98
111
  },
99
112
  handler: async (params: unknown, _context: RequestContext) => {
100
- const { schema } = ListObjectsSchema.parse(params);
113
+ let parsed;
114
+ try {
115
+ parsed = ListObjectsSchema.parse(params);
116
+ } catch (error: unknown) {
117
+ if (error instanceof ZodError) {
118
+ return { success: false, error: formatZodError(error) };
119
+ }
120
+ throw error;
121
+ }
122
+ const { schema } = parsed;
101
123
 
102
124
  // P154: Schema existence check when explicitly provided
103
125
  if (schema) {
@@ -1,10 +1,23 @@
1
- import { z } from "zod";
1
+ import { z, ZodError } from "zod";
2
2
  import type { MySQLAdapter } from "../../MySQLAdapter.js";
3
3
  import type {
4
4
  ToolDefinition,
5
5
  RequestContext,
6
6
  } from "../../../../types/index.js";
7
7
 
8
+ /** Extract human-readable messages from a ZodError instead of raw JSON array */
9
+ function formatZodError(error: ZodError): string {
10
+ return error.issues.map((i) => i.message).join("; ");
11
+ }
12
+
13
+ const ListEventsSchemaBase = z.object({
14
+ schema: z
15
+ .string()
16
+ .optional()
17
+ .describe("Schema name (defaults to current database)"),
18
+ status: z.string().optional().describe("Filter by status"),
19
+ });
20
+
8
21
  const ListEventsSchema = z.object({
9
22
  schema: z
10
23
  .string()
@@ -26,14 +39,23 @@ export function createListEventsTool(adapter: MySQLAdapter): ToolDefinition {
26
39
  description:
27
40
  "List all scheduled events with execution status and schedule info.",
28
41
  group: "schema",
29
- inputSchema: ListEventsSchema,
42
+ inputSchema: ListEventsSchemaBase,
30
43
  requiredScopes: ["read"],
31
44
  annotations: {
32
45
  readOnlyHint: true,
33
46
  idempotentHint: true,
34
47
  },
35
48
  handler: async (params: unknown, _context: RequestContext) => {
36
- const { schema, status } = ListEventsSchema.parse(params);
49
+ let parsed;
50
+ try {
51
+ parsed = ListEventsSchema.parse(params);
52
+ } catch (error: unknown) {
53
+ if (error instanceof ZodError) {
54
+ return { success: false, error: formatZodError(error) };
55
+ }
56
+ throw error;
57
+ }
58
+ const { schema, status } = parsed;
37
59
 
38
60
  // P154: Schema existence check when explicitly provided
39
61
  if (schema) {
@@ -1,4 +1,9 @@
1
- import { z } from "zod";
1
+ import { z, ZodError } from "zod";
2
+
3
+ /** Extract human-readable messages from a ZodError instead of raw JSON array */
4
+ function formatZodError(error: ZodError): string {
5
+ return error.issues.map((i) => i.message).join("; ");
6
+ }
2
7
  import type { MySQLAdapter } from "../../MySQLAdapter.js";
3
8
  import type {
4
9
  ToolDefinition,
@@ -29,7 +34,16 @@ export function createListTriggersTool(adapter: MySQLAdapter): ToolDefinition {
29
34
  idempotentHint: true,
30
35
  },
31
36
  handler: async (params: unknown, _context: RequestContext) => {
32
- const { table, schema } = ListTriggersSchema.parse(params);
37
+ let parsed;
38
+ try {
39
+ parsed = ListTriggersSchema.parse(params);
40
+ } catch (error: unknown) {
41
+ if (error instanceof ZodError) {
42
+ return { success: false, error: formatZodError(error) };
43
+ }
44
+ throw error;
45
+ }
46
+ const { table, schema } = parsed;
33
47
 
34
48
  // P154: Schema existence check when explicitly provided
35
49
  if (schema) {
@@ -42,6 +56,17 @@ export function createListTriggersTool(adapter: MySQLAdapter): ToolDefinition {
42
56
  }
43
57
  }
44
58
 
59
+ // P154: Table existence check when explicitly provided
60
+ if (table) {
61
+ const tableCheck = await adapter.executeQuery(
62
+ "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = COALESCE(?, DATABASE()) AND TABLE_NAME = ?",
63
+ [schema ?? null, table],
64
+ );
65
+ if (!tableCheck.rows || tableCheck.rows.length === 0) {
66
+ return { exists: false, table };
67
+ }
68
+ }
69
+
45
70
  let query = `
46
71
  SELECT
47
72
  TRIGGER_NAME as name,
@@ -1,4 +1,9 @@
1
- import { z } from "zod";
1
+ import { z, ZodError } from "zod";
2
+
3
+ /** Extract human-readable messages from a ZodError instead of raw JSON array */
4
+ function formatZodError(error: ZodError): string {
5
+ return error.issues.map((i) => i.message).join("; ");
6
+ }
2
7
  import type { MySQLAdapter } from "../../MySQLAdapter.js";
3
8
  import type {
4
9
  ToolDefinition,
@@ -16,6 +21,14 @@ const ListViewsSchema = z.object({
16
21
  .describe("Schema name (defaults to current database)"),
17
22
  });
18
23
 
24
+ const CreateViewSchemaBase = z.object({
25
+ name: z.string().describe("View name"),
26
+ definition: z.string().describe("SELECT statement defining the view"),
27
+ orReplace: z.boolean().default(false).describe("Use CREATE OR REPLACE"),
28
+ algorithm: z.string().default("UNDEFINED").describe("View algorithm"),
29
+ checkOption: z.string().default("NONE").describe("WITH CHECK OPTION"),
30
+ });
31
+
19
32
  const CreateViewSchema = z.object({
20
33
  name: z.string().describe("View name"),
21
34
  definition: z.string().describe("SELECT statement defining the view"),
@@ -47,7 +60,16 @@ export function createListViewsTool(adapter: MySQLAdapter): ToolDefinition {
47
60
  idempotentHint: true,
48
61
  },
49
62
  handler: async (params: unknown, _context: RequestContext) => {
50
- const { schema } = ListViewsSchema.parse(params);
63
+ let parsed;
64
+ try {
65
+ parsed = ListViewsSchema.parse(params);
66
+ } catch (error: unknown) {
67
+ if (error instanceof ZodError) {
68
+ return { success: false, error: formatZodError(error) };
69
+ }
70
+ throw error;
71
+ }
72
+ const { schema } = parsed;
51
73
 
52
74
  // P154: Schema existence check when explicitly provided
53
75
  if (schema) {
@@ -92,16 +114,29 @@ export function createCreateViewTool(adapter: MySQLAdapter): ToolDefinition {
92
114
  description:
93
115
  "Create or replace a view with specified algorithm and check option.",
94
116
  group: "schema",
95
- inputSchema: CreateViewSchema,
117
+ inputSchema: CreateViewSchemaBase,
96
118
  requiredScopes: ["write"],
97
119
  annotations: {
98
120
  readOnlyHint: false,
99
121
  },
100
122
  handler: async (params: unknown, _context: RequestContext) => {
101
- const { name, definition, orReplace, algorithm, checkOption } =
102
- CreateViewSchema.parse(params);
123
+ let parsed;
124
+ try {
125
+ parsed = CreateViewSchema.parse(params);
126
+ } catch (error: unknown) {
127
+ if (error instanceof ZodError) {
128
+ return { success: false, error: formatZodError(error) };
129
+ }
130
+ throw error;
131
+ }
132
+ const { name, definition, orReplace, algorithm, checkOption } = parsed;
103
133
 
104
- validateQualifiedIdentifier(name, "view");
134
+ try {
135
+ validateQualifiedIdentifier(name, "view");
136
+ } catch (err: unknown) {
137
+ const message = err instanceof Error ? err.message : String(err);
138
+ return { success: false, error: message };
139
+ }
105
140
 
106
141
  const fullViewName = escapeQualifiedTable(name);
107
142
 
@@ -114,18 +149,21 @@ export function createCreateViewTool(adapter: MySQLAdapter): ToolDefinition {
114
149
 
115
150
  try {
116
151
  await adapter.executeQuery(sql);
152
+ adapter.clearSchemaCache();
117
153
  return { success: true, viewName: name };
118
154
  } catch (err: unknown) {
119
155
  const message = err instanceof Error ? err.message : String(err);
120
156
  if (message.toLowerCase().includes("already exists")) {
121
157
  return {
122
158
  success: false,
123
- reason: `View '${name}' already exists`,
159
+ error: `View '${name}' already exists`,
124
160
  };
125
161
  }
126
162
  return {
127
163
  success: false,
128
- reason: message,
164
+ error: message
165
+ .replace(/^Query failed:\s*/i, "")
166
+ .replace(/^Execute failed:\s*/i, ""),
129
167
  };
130
168
  }
131
169
  },
@@ -85,7 +85,7 @@ describe("Security Audit Tools", () => {
85
85
  expect(queryCall).toContain("user LIKE ?");
86
86
  expect(queryCall).toContain("event_type = ?");
87
87
  expect(queryCall).toContain("timestamp >= ?");
88
- expect(queryParams).toHaveLength(3);
88
+ expect(queryParams).toHaveLength(4);
89
89
  });
90
90
 
91
91
  it("should fallback to performance_schema if audit_log is missing", async () => {
@@ -134,10 +134,64 @@ describe("Security Audit Tools", () => {
134
134
  );
135
135
 
136
136
  const queryCall = mockAdapter.executeQuery.mock.calls[1][0] as string;
137
- const queryParams = mockAdapter.executeQuery.mock.calls[1][1] as any[];
138
137
 
139
- expect(queryCall).toContain("CURRENT_USER LIKE ?");
140
- expect(queryParams[0]).toContain("test_user");
138
+ expect(queryCall).toContain("t.PROCESSLIST_USER LIKE '%test_user%'");
139
+ });
140
+
141
+ it("should apply eventType filter in fallback mode", async () => {
142
+ mockAdapter.executeQuery.mockResolvedValueOnce(createMockQueryResult([])); // No audit log
143
+ mockAdapter.executeQuery.mockResolvedValueOnce(createMockQueryResult([]));
144
+
145
+ const tool = createSecurityAuditTool(
146
+ mockAdapter as unknown as MySQLAdapter,
147
+ );
148
+ await tool.handler(
149
+ {
150
+ limit: 10,
151
+ eventType: "CONNECT",
152
+ },
153
+ mockContext,
154
+ );
155
+
156
+ const queryCall = mockAdapter.executeQuery.mock.calls[1][0] as string;
157
+
158
+ expect(queryCall).toContain("e.EVENT_NAME LIKE '%CONNECT%'");
159
+ });
160
+
161
+ it("should include filtersIgnored when startTime used in fallback mode", async () => {
162
+ mockAdapter.executeQuery.mockResolvedValueOnce(createMockQueryResult([])); // No audit log
163
+ mockAdapter.executeQuery.mockResolvedValueOnce(createMockQueryResult([]));
164
+
165
+ const tool = createSecurityAuditTool(
166
+ mockAdapter as unknown as MySQLAdapter,
167
+ );
168
+ const result = (await tool.handler(
169
+ {
170
+ limit: 10,
171
+ startTime: "2023-01-01",
172
+ },
173
+ mockContext,
174
+ )) as { filtersIgnored?: string[]; note?: string };
175
+
176
+ expect(result.filtersIgnored).toEqual(["startTime"]);
177
+ expect(result.note).toContain("picosecond");
178
+ });
179
+
180
+ it("should return structured error for non-audit failures", async () => {
181
+ mockAdapter.executeQuery.mockRejectedValue(
182
+ new Error("Connection lost to host"),
183
+ );
184
+
185
+ const tool = createSecurityAuditTool(
186
+ mockAdapter as unknown as MySQLAdapter,
187
+ );
188
+ const result = (await tool.handler({}, mockContext)) as {
189
+ success: boolean;
190
+ error: string;
191
+ };
192
+
193
+ expect(result.success).toBe(false);
194
+ expect(result.error).toBe("Connection lost to host");
141
195
  });
142
196
 
143
197
  it("should handle error when checking audit log", async () => {
@@ -152,6 +206,22 @@ describe("Security Audit Tools", () => {
152
206
 
153
207
  expect(result.available).toBe(false);
154
208
  });
209
+
210
+ it("should not include duplicated message field in error response", async () => {
211
+ mockAdapter.executeQuery.mockRejectedValue(new Error("Access denied"));
212
+
213
+ const tool = createSecurityAuditTool(
214
+ mockAdapter as unknown as MySQLAdapter,
215
+ );
216
+ const result = (await tool.handler({}, mockContext)) as Record<
217
+ string,
218
+ unknown
219
+ >;
220
+
221
+ expect(result.success).toBe(false);
222
+ expect(result).toHaveProperty("error");
223
+ expect(result).not.toHaveProperty("message");
224
+ });
155
225
  });
156
226
 
157
227
  describe("createSecurityFirewallStatusTool", () => {
@@ -235,5 +305,21 @@ describe("Security Audit Tools", () => {
235
305
 
236
306
  expect(result.available).toBe(false);
237
307
  });
308
+
309
+ it("should not include duplicated message field in error response", async () => {
310
+ mockAdapter.executeQuery.mockRejectedValue(new Error("Table missing"));
311
+
312
+ const tool = createSecurityFirewallRulesTool(
313
+ mockAdapter as unknown as MySQLAdapter,
314
+ );
315
+ const result = (await tool.handler({}, mockContext)) as Record<
316
+ string,
317
+ unknown
318
+ >;
319
+
320
+ expect(result.success).toBe(false);
321
+ expect(result).toHaveProperty("error");
322
+ expect(result).not.toHaveProperty("message");
323
+ });
238
324
  });
239
325
  });