@neverinfamous/mysql-mcp 2.2.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 (213) hide show
  1. package/.github/workflows/docker-publish.yml +1 -2
  2. package/CHANGELOG.md +85 -0
  3. package/CODE_MODE.md +245 -0
  4. package/DOCKER_README.md +59 -36
  5. package/README.md +65 -42
  6. package/VERSION +1 -1
  7. package/dist/adapters/mysql/MySQLAdapter.d.ts +4 -0
  8. package/dist/adapters/mysql/MySQLAdapter.d.ts.map +1 -1
  9. package/dist/adapters/mysql/MySQLAdapter.js +9 -0
  10. package/dist/adapters/mysql/MySQLAdapter.js.map +1 -1
  11. package/dist/adapters/mysql/prompts/index.d.ts +8 -1
  12. package/dist/adapters/mysql/prompts/index.d.ts.map +1 -1
  13. package/dist/adapters/mysql/prompts/index.js +8 -1
  14. package/dist/adapters/mysql/prompts/index.js.map +1 -1
  15. package/dist/adapters/mysql/prompts/routerSetup.d.ts.map +1 -1
  16. package/dist/adapters/mysql/prompts/routerSetup.js +5 -0
  17. package/dist/adapters/mysql/prompts/routerSetup.js.map +1 -1
  18. package/dist/adapters/mysql/resources/capabilities.d.ts.map +1 -1
  19. package/dist/adapters/mysql/resources/capabilities.js +6 -5
  20. package/dist/adapters/mysql/resources/capabilities.js.map +1 -1
  21. package/dist/adapters/mysql/resources/index.d.ts +9 -1
  22. package/dist/adapters/mysql/resources/index.d.ts.map +1 -1
  23. package/dist/adapters/mysql/resources/index.js +9 -1
  24. package/dist/adapters/mysql/resources/index.js.map +1 -1
  25. package/dist/adapters/mysql/tools/admin/backup.d.ts.map +1 -1
  26. package/dist/adapters/mysql/tools/admin/backup.js +3 -3
  27. package/dist/adapters/mysql/tools/admin/backup.js.map +1 -1
  28. package/dist/adapters/mysql/tools/admin/maintenance.d.ts.map +1 -1
  29. package/dist/adapters/mysql/tools/admin/maintenance.js +5 -5
  30. package/dist/adapters/mysql/tools/admin/maintenance.js.map +1 -1
  31. package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts.map +1 -1
  32. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js +26 -5
  33. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js.map +1 -1
  34. package/dist/adapters/mysql/tools/codemode/index.d.ts +38 -0
  35. package/dist/adapters/mysql/tools/codemode/index.d.ts.map +1 -0
  36. package/dist/adapters/mysql/tools/codemode/index.js +203 -0
  37. package/dist/adapters/mysql/tools/codemode/index.js.map +1 -0
  38. package/dist/adapters/mysql/tools/core.d.ts.map +1 -1
  39. package/dist/adapters/mysql/tools/core.js +32 -20
  40. package/dist/adapters/mysql/tools/core.js.map +1 -1
  41. package/dist/adapters/mysql/tools/events.js +18 -6
  42. package/dist/adapters/mysql/tools/events.js.map +1 -1
  43. package/dist/adapters/mysql/tools/json/core.d.ts.map +1 -1
  44. package/dist/adapters/mysql/tools/json/core.js +5 -5
  45. package/dist/adapters/mysql/tools/json/core.js.map +1 -1
  46. package/dist/adapters/mysql/tools/json/helpers.d.ts.map +1 -1
  47. package/dist/adapters/mysql/tools/json/helpers.js +9 -3
  48. package/dist/adapters/mysql/tools/json/helpers.js.map +1 -1
  49. package/dist/adapters/mysql/tools/partitioning.d.ts.map +1 -1
  50. package/dist/adapters/mysql/tools/partitioning.js +38 -6
  51. package/dist/adapters/mysql/tools/partitioning.js.map +1 -1
  52. package/dist/adapters/mysql/tools/performance/analysis.d.ts.map +1 -1
  53. package/dist/adapters/mysql/tools/performance/analysis.js +67 -20
  54. package/dist/adapters/mysql/tools/performance/analysis.js.map +1 -1
  55. package/dist/adapters/mysql/tools/performance/optimization.d.ts.map +1 -1
  56. package/dist/adapters/mysql/tools/performance/optimization.js +36 -6
  57. package/dist/adapters/mysql/tools/performance/optimization.js.map +1 -1
  58. package/dist/adapters/mysql/tools/security/data-protection.d.ts.map +1 -1
  59. package/dist/adapters/mysql/tools/security/data-protection.js +9 -4
  60. package/dist/adapters/mysql/tools/security/data-protection.js.map +1 -1
  61. package/dist/adapters/mysql/tools/shell/common.d.ts.map +1 -1
  62. package/dist/adapters/mysql/tools/shell/common.js +28 -2
  63. package/dist/adapters/mysql/tools/shell/common.js.map +1 -1
  64. package/dist/adapters/mysql/tools/shell/restore.d.ts.map +1 -1
  65. package/dist/adapters/mysql/tools/shell/restore.js +54 -4
  66. package/dist/adapters/mysql/tools/shell/restore.js.map +1 -1
  67. package/dist/adapters/mysql/tools/spatial/operations.d.ts.map +1 -1
  68. package/dist/adapters/mysql/tools/spatial/operations.js +10 -2
  69. package/dist/adapters/mysql/tools/spatial/operations.js.map +1 -1
  70. package/dist/adapters/mysql/tools/spatial/setup.d.ts.map +1 -1
  71. package/dist/adapters/mysql/tools/spatial/setup.js +18 -0
  72. package/dist/adapters/mysql/tools/spatial/setup.js.map +1 -1
  73. package/dist/adapters/mysql/tools/sysschema/resources.d.ts.map +1 -1
  74. package/dist/adapters/mysql/tools/sysschema/resources.js +5 -0
  75. package/dist/adapters/mysql/tools/sysschema/resources.js.map +1 -1
  76. package/dist/adapters/mysql/tools/text/fulltext.d.ts.map +1 -1
  77. package/dist/adapters/mysql/tools/text/fulltext.js +6 -4
  78. package/dist/adapters/mysql/tools/text/fulltext.js.map +1 -1
  79. package/dist/adapters/mysql/tools/text/processing.d.ts.map +1 -1
  80. package/dist/adapters/mysql/tools/text/processing.js +10 -45
  81. package/dist/adapters/mysql/tools/text/processing.js.map +1 -1
  82. package/dist/adapters/mysql/tools/transactions.d.ts.map +1 -1
  83. package/dist/adapters/mysql/tools/transactions.js +8 -8
  84. package/dist/adapters/mysql/tools/transactions.js.map +1 -1
  85. package/dist/adapters/mysql/types.d.ts +968 -78
  86. package/dist/adapters/mysql/types.d.ts.map +1 -1
  87. package/dist/adapters/mysql/types.js +1084 -78
  88. package/dist/adapters/mysql/types.js.map +1 -1
  89. package/dist/auth/scopes.d.ts.map +1 -1
  90. package/dist/auth/scopes.js +1 -0
  91. package/dist/auth/scopes.js.map +1 -1
  92. package/dist/cli/args.d.ts.map +1 -1
  93. package/dist/cli/args.js +12 -0
  94. package/dist/cli/args.js.map +1 -1
  95. package/dist/codemode/api.d.ts +69 -0
  96. package/dist/codemode/api.d.ts.map +1 -0
  97. package/dist/codemode/api.js +1035 -0
  98. package/dist/codemode/api.js.map +1 -0
  99. package/dist/codemode/index.d.ts +13 -0
  100. package/dist/codemode/index.d.ts.map +1 -0
  101. package/dist/codemode/index.js +17 -0
  102. package/dist/codemode/index.js.map +1 -0
  103. package/dist/codemode/sandbox-factory.d.ts +72 -0
  104. package/dist/codemode/sandbox-factory.d.ts.map +1 -0
  105. package/dist/codemode/sandbox-factory.js +88 -0
  106. package/dist/codemode/sandbox-factory.js.map +1 -0
  107. package/dist/codemode/sandbox.d.ts +96 -0
  108. package/dist/codemode/sandbox.d.ts.map +1 -0
  109. package/dist/codemode/sandbox.js +345 -0
  110. package/dist/codemode/sandbox.js.map +1 -0
  111. package/dist/codemode/security.d.ts +44 -0
  112. package/dist/codemode/security.d.ts.map +1 -0
  113. package/dist/codemode/security.js +149 -0
  114. package/dist/codemode/security.js.map +1 -0
  115. package/dist/codemode/types.d.ts +137 -0
  116. package/dist/codemode/types.d.ts.map +1 -0
  117. package/dist/codemode/types.js +46 -0
  118. package/dist/codemode/types.js.map +1 -0
  119. package/dist/codemode/worker-sandbox.d.ts +82 -0
  120. package/dist/codemode/worker-sandbox.d.ts.map +1 -0
  121. package/dist/codemode/worker-sandbox.js +244 -0
  122. package/dist/codemode/worker-sandbox.js.map +1 -0
  123. package/dist/codemode/worker-script.d.ts +8 -0
  124. package/dist/codemode/worker-script.d.ts.map +1 -0
  125. package/dist/codemode/worker-script.js +113 -0
  126. package/dist/codemode/worker-script.js.map +1 -0
  127. package/dist/constants/ServerInstructions.d.ts +1 -1
  128. package/dist/constants/ServerInstructions.d.ts.map +1 -1
  129. package/dist/constants/ServerInstructions.js +33 -9
  130. package/dist/constants/ServerInstructions.js.map +1 -1
  131. package/dist/filtering/ToolConstants.d.ts +11 -11
  132. package/dist/filtering/ToolConstants.d.ts.map +1 -1
  133. package/dist/filtering/ToolConstants.js +37 -19
  134. package/dist/filtering/ToolConstants.js.map +1 -1
  135. package/dist/filtering/ToolFilter.d.ts.map +1 -1
  136. package/dist/filtering/ToolFilter.js +12 -0
  137. package/dist/filtering/ToolFilter.js.map +1 -1
  138. package/dist/server/McpServer.js +1 -1
  139. package/dist/server/McpServer.js.map +1 -1
  140. package/dist/types/modules/server.d.ts +2 -0
  141. package/dist/types/modules/server.d.ts.map +1 -1
  142. package/dist/types/modules/tools.d.ts +1 -1
  143. package/dist/types/modules/tools.d.ts.map +1 -1
  144. package/dist/utils/logger.d.ts +1 -1
  145. package/dist/utils/logger.d.ts.map +1 -1
  146. package/dist/utils/logger.js.map +1 -1
  147. package/package.json +12 -7
  148. package/releases/v2.2.0-release-notes.md +18 -18
  149. package/releases/v2.3.0-release-notes.md +191 -0
  150. package/src/__tests__/perf.test.ts +12 -12
  151. package/src/adapters/mysql/MySQLAdapter.ts +10 -0
  152. package/src/adapters/mysql/__tests__/MySQLAdapter.test.ts +1 -1
  153. package/src/adapters/mysql/prompts/index.ts +8 -1
  154. package/src/adapters/mysql/prompts/routerSetup.ts +5 -0
  155. package/src/adapters/mysql/resources/__tests__/capabilities.test.ts +50 -1
  156. package/src/adapters/mysql/resources/capabilities.ts +6 -4
  157. package/src/adapters/mysql/resources/index.ts +9 -1
  158. package/src/adapters/mysql/tools/__tests__/core.test.ts +68 -0
  159. package/src/adapters/mysql/tools/__tests__/events.test.ts +56 -2
  160. package/src/adapters/mysql/tools/__tests__/json_core.test.ts +1 -1
  161. package/src/adapters/mysql/tools/__tests__/json_helpers.test.ts +46 -4
  162. package/src/adapters/mysql/tools/__tests__/replication.test.ts +144 -42
  163. package/src/adapters/mysql/tools/__tests__/security.test.ts +39 -0
  164. package/src/adapters/mysql/tools/__tests__/spatial.test.ts +39 -7
  165. package/src/adapters/mysql/tools/__tests__/spatial_handler.test.ts +35 -3
  166. package/src/adapters/mysql/tools/__tests__/transactions.test.ts +3 -5
  167. package/src/adapters/mysql/tools/admin/backup.ts +8 -3
  168. package/src/adapters/mysql/tools/admin/maintenance.ts +8 -4
  169. package/src/adapters/mysql/tools/cluster/__tests__/innodb-cluster.test.ts +35 -0
  170. package/src/adapters/mysql/tools/cluster/innodb-cluster.ts +26 -5
  171. package/src/adapters/mysql/tools/codemode/index.ts +249 -0
  172. package/src/adapters/mysql/tools/core.ts +44 -27
  173. package/src/adapters/mysql/tools/events.ts +23 -7
  174. package/src/adapters/mysql/tools/json/__tests__/helpers.test.ts +59 -14
  175. package/src/adapters/mysql/tools/json/core.ts +8 -4
  176. package/src/adapters/mysql/tools/json/helpers.ts +13 -3
  177. package/src/adapters/mysql/tools/partitioning.ts +53 -6
  178. package/src/adapters/mysql/tools/performance/__tests__/analysis.test.ts +227 -4
  179. package/src/adapters/mysql/tools/performance/__tests__/optimization.test.ts +35 -0
  180. package/src/adapters/mysql/tools/performance/analysis.ts +75 -21
  181. package/src/adapters/mysql/tools/performance/optimization.ts +44 -6
  182. package/src/adapters/mysql/tools/security/data-protection.ts +10 -4
  183. package/src/adapters/mysql/tools/shell/__tests__/common.test.ts +46 -0
  184. package/src/adapters/mysql/tools/shell/__tests__/restore.test.ts +28 -1
  185. package/src/adapters/mysql/tools/shell/common.ts +34 -2
  186. package/src/adapters/mysql/tools/shell/restore.ts +70 -7
  187. package/src/adapters/mysql/tools/spatial/__tests__/operations.test.ts +29 -0
  188. package/src/adapters/mysql/tools/spatial/operations.ts +13 -2
  189. package/src/adapters/mysql/tools/spatial/setup.ts +23 -0
  190. package/src/adapters/mysql/tools/sysschema/__tests__/resources.test.ts +21 -0
  191. package/src/adapters/mysql/tools/sysschema/resources.ts +5 -0
  192. package/src/adapters/mysql/tools/text/fulltext.ts +13 -5
  193. package/src/adapters/mysql/tools/text/processing.ts +20 -49
  194. package/src/adapters/mysql/tools/transactions.ts +11 -7
  195. package/src/adapters/mysql/types.ts +1241 -87
  196. package/src/auth/scopes.ts +1 -0
  197. package/src/cli/args.ts +14 -0
  198. package/src/codemode/api.ts +1224 -0
  199. package/src/codemode/index.ts +51 -0
  200. package/src/codemode/sandbox-factory.ts +146 -0
  201. package/src/codemode/sandbox.ts +450 -0
  202. package/src/codemode/security.ts +188 -0
  203. package/src/codemode/types.ts +194 -0
  204. package/src/codemode/worker-sandbox.ts +326 -0
  205. package/src/codemode/worker-script.ts +144 -0
  206. package/src/constants/ServerInstructions.ts +33 -9
  207. package/src/filtering/ToolConstants.ts +37 -19
  208. package/src/filtering/ToolFilter.ts +15 -0
  209. package/src/filtering/__tests__/ToolFilter.test.ts +65 -38
  210. package/src/server/McpServer.ts +1 -1
  211. package/src/types/modules/server.ts +3 -0
  212. package/src/types/modules/tools.ts +2 -1
  213. package/src/utils/logger.ts +2 -1
@@ -2,13 +2,177 @@
2
2
  * MySQL Adapter - Zod Schemas
3
3
  *
4
4
  * Input validation schemas for all MySQL tools.
5
+ *
6
+ * DUAL-SCHEMA PATTERN (Split Schema):
7
+ * Base schemas (SchemaBase) are exported for MCP inputSchema visibility.
8
+ * Transformed schemas (Schema) are exported for handler parsing with alias resolution.
9
+ * This ensures MCP clients see all parameter names (including aliases) while
10
+ * handlers receive normalized data with canonical parameter names.
5
11
  */
6
12
  import { z } from "zod";
7
13
  // =============================================================================
14
+ // Preprocess Utilities
15
+ // =============================================================================
16
+ /**
17
+ * Convert undefined input to empty object for optional-param tools.
18
+ * Used with z.preprocess() to handle tools called with no arguments.
19
+ */
20
+ function defaultToEmpty(input) {
21
+ return input ?? {};
22
+ }
23
+ /**
24
+ * Preprocess table parameters:
25
+ * - Alias: tableName/name → table
26
+ */
27
+ function preprocessTableParams(input) {
28
+ if (typeof input !== "object" || input === null)
29
+ return input;
30
+ const result = { ...input };
31
+ if (result["table"] === undefined) {
32
+ if (result["tableName"] !== undefined)
33
+ result["table"] = result["tableName"];
34
+ else if (result["name"] !== undefined)
35
+ result["table"] = result["name"];
36
+ }
37
+ return result;
38
+ }
39
+ /**
40
+ * Preprocess query parameters:
41
+ * - Alias: sql → query
42
+ * - Alias: tx/txId → transactionId
43
+ */
44
+ function preprocessQueryParams(input) {
45
+ if (typeof input !== "object" || input === null)
46
+ return input;
47
+ const result = { ...input };
48
+ if (result["query"] === undefined && result["sql"] !== undefined) {
49
+ result["query"] = result["sql"];
50
+ }
51
+ if (result["transactionId"] === undefined) {
52
+ if (result["txId"] !== undefined)
53
+ result["transactionId"] = result["txId"];
54
+ else if (result["tx"] !== undefined)
55
+ result["transactionId"] = result["tx"];
56
+ }
57
+ return result;
58
+ }
59
+ /**
60
+ * Preprocess transaction ID parameters:
61
+ * - Alias: tx/txId → transactionId
62
+ */
63
+ function preprocessTransactionIdParams(input) {
64
+ const normalized = defaultToEmpty(input);
65
+ if (normalized["transactionId"] === undefined) {
66
+ if (normalized["txId"] !== undefined)
67
+ normalized["transactionId"] = normalized["txId"];
68
+ else if (normalized["tx"] !== undefined)
69
+ normalized["transactionId"] = normalized["tx"];
70
+ }
71
+ return normalized;
72
+ }
73
+ /**
74
+ * Preprocess savepoint parameters:
75
+ * - Alias: tx/txId → transactionId
76
+ * - Alias: name → savepoint
77
+ */
78
+ function preprocessSavepointParams(input) {
79
+ if (typeof input !== "object" || input === null)
80
+ return input;
81
+ const result = { ...input };
82
+ if (result["transactionId"] === undefined) {
83
+ if (result["txId"] !== undefined)
84
+ result["transactionId"] = result["txId"];
85
+ else if (result["tx"] !== undefined)
86
+ result["transactionId"] = result["tx"];
87
+ }
88
+ if (result["savepoint"] === undefined && result["name"] !== undefined) {
89
+ result["savepoint"] = result["name"];
90
+ }
91
+ return result;
92
+ }
93
+ /**
94
+ * Preprocess create table parameters:
95
+ * - Alias: table/tableName → name
96
+ */
97
+ function preprocessCreateTableParams(input) {
98
+ if (typeof input !== "object" || input === null)
99
+ return input;
100
+ const result = { ...input };
101
+ if (result["name"] === undefined) {
102
+ if (result["table"] !== undefined)
103
+ result["name"] = result["table"];
104
+ else if (result["tableName"] !== undefined)
105
+ result["name"] = result["tableName"];
106
+ }
107
+ return result;
108
+ }
109
+ /**
110
+ * Preprocess transaction execute parameters:
111
+ * - Alias: queries/sqls → statements
112
+ */
113
+ function preprocessTransactionExecuteParams(input) {
114
+ if (typeof input !== "object" || input === null)
115
+ return input;
116
+ const result = { ...input };
117
+ if (result["statements"] === undefined) {
118
+ if (result["queries"] !== undefined)
119
+ result["statements"] = result["queries"];
120
+ else if (result["sqls"] !== undefined)
121
+ result["statements"] = result["sqls"];
122
+ }
123
+ return result;
124
+ }
125
+ // =============================================================================
8
126
  // Core Tools Schemas
9
127
  // =============================================================================
10
- export const ReadQuerySchema = z.object({
11
- query: z.string().describe("SQL SELECT query to execute"),
128
+ // --- ReadQuery ---
129
+ // Base schema for MCP visibility (AI sees: query, sql, params, transactionId, txId, tx)
130
+ export const ReadQuerySchemaBase = z.object({
131
+ query: z.string().optional().describe("SQL SELECT query to execute"),
132
+ sql: z.string().optional().describe("Alias for query"),
133
+ params: z
134
+ .array(z.unknown())
135
+ .optional()
136
+ .describe("Query parameters for prepared statement"),
137
+ transactionId: z
138
+ .string()
139
+ .optional()
140
+ .describe("Optional transaction ID for executing within a transaction"),
141
+ txId: z.string().optional().describe("Alias for transactionId"),
142
+ tx: z.string().optional().describe("Alias for transactionId"),
143
+ });
144
+ // Transformed schema for handler parsing (normalizes aliases)
145
+ export const ReadQuerySchema = z
146
+ .preprocess(preprocessQueryParams, z.object({
147
+ query: z.string().optional().describe("SQL SELECT query to execute"),
148
+ sql: z.string().optional().describe("Alias for query"),
149
+ params: z
150
+ .array(z.unknown())
151
+ .optional()
152
+ .describe("Query parameters for prepared statement"),
153
+ transactionId: z
154
+ .string()
155
+ .optional()
156
+ .describe("Optional transaction ID for executing within a transaction"),
157
+ txId: z.string().optional().describe("Alias for transactionId"),
158
+ tx: z.string().optional().describe("Alias for transactionId"),
159
+ }))
160
+ .transform((data) => ({
161
+ query: data.query ?? data.sql ?? "",
162
+ params: data.params,
163
+ transactionId: data.transactionId ?? data.txId ?? data.tx,
164
+ }))
165
+ .refine((data) => data.query !== "", {
166
+ message: "query (or sql alias) is required",
167
+ });
168
+ // --- WriteQuery ---
169
+ // Base schema for MCP visibility
170
+ export const WriteQuerySchemaBase = z.object({
171
+ query: z
172
+ .string()
173
+ .optional()
174
+ .describe("SQL INSERT/UPDATE/DELETE query to execute"),
175
+ sql: z.string().optional().describe("Alias for query"),
12
176
  params: z
13
177
  .array(z.unknown())
14
178
  .optional()
@@ -17,9 +181,17 @@ export const ReadQuerySchema = z.object({
17
181
  .string()
18
182
  .optional()
19
183
  .describe("Optional transaction ID for executing within a transaction"),
184
+ txId: z.string().optional().describe("Alias for transactionId"),
185
+ tx: z.string().optional().describe("Alias for transactionId"),
20
186
  });
21
- export const WriteQuerySchema = z.object({
22
- query: z.string().describe("SQL INSERT/UPDATE/DELETE query"),
187
+ // Transformed schema for handler parsing
188
+ export const WriteQuerySchema = z
189
+ .preprocess(preprocessQueryParams, z.object({
190
+ query: z
191
+ .string()
192
+ .optional()
193
+ .describe("SQL INSERT/UPDATE/DELETE query to execute"),
194
+ sql: z.string().optional().describe("Alias for query"),
23
195
  params: z
24
196
  .array(z.unknown())
25
197
  .optional()
@@ -28,18 +200,46 @@ export const WriteQuerySchema = z.object({
28
200
  .string()
29
201
  .optional()
30
202
  .describe("Optional transaction ID for executing within a transaction"),
203
+ txId: z.string().optional().describe("Alias for transactionId"),
204
+ tx: z.string().optional().describe("Alias for transactionId"),
205
+ }))
206
+ .transform((data) => ({
207
+ query: data.query ?? data.sql ?? "",
208
+ params: data.params,
209
+ transactionId: data.transactionId ?? data.txId ?? data.tx,
210
+ }))
211
+ .refine((data) => data.query !== "", {
212
+ message: "query (or sql alias) is required",
31
213
  });
214
+ // --- ListTables ---
32
215
  export const ListTablesSchema = z.object({
33
216
  database: z
34
217
  .string()
35
218
  .optional()
36
219
  .describe("Database name (defaults to connected database)"),
37
220
  });
38
- export const DescribeTableSchema = z.object({
39
- table: z.string().describe("Table name to describe"),
221
+ // --- DescribeTable ---
222
+ // Base schema for MCP visibility
223
+ export const DescribeTableSchemaBase = z.object({
224
+ table: z.string().optional().describe("Table name to describe"),
225
+ tableName: z.string().optional().describe("Alias for table"),
226
+ name: z.string().optional().describe("Alias for table"),
227
+ });
228
+ // Transformed schema for handler parsing
229
+ export const DescribeTableSchema = z
230
+ .preprocess(preprocessTableParams, DescribeTableSchemaBase)
231
+ .transform((data) => ({
232
+ table: data.table ?? data.tableName ?? data.name ?? "",
233
+ }))
234
+ .refine((data) => data.table !== "", {
235
+ message: "table (or tableName/name alias) is required",
40
236
  });
41
- export const CreateTableSchema = z.object({
42
- name: z.string().describe("Table name"),
237
+ // --- CreateTable ---
238
+ // Base schema for MCP visibility
239
+ export const CreateTableSchemaBase = z.object({
240
+ name: z.string().optional().describe("Table name"),
241
+ table: z.string().optional().describe("Alias for name"),
242
+ tableName: z.string().optional().describe("Alias for name"),
43
243
  columns: z
44
244
  .array(z.object({
45
245
  name: z.string().describe("Column name"),
@@ -76,17 +276,49 @@ export const CreateTableSchema = z.object({
76
276
  .default(false)
77
277
  .describe("Add IF NOT EXISTS clause"),
78
278
  });
79
- export const DropTableSchema = z.object({
80
- table: z.string().describe("Table name to drop"),
279
+ // Transformed schema for handler parsing
280
+ export const CreateTableSchema = z
281
+ .preprocess(preprocessCreateTableParams, CreateTableSchemaBase)
282
+ .transform((data) => ({
283
+ name: data.name ?? data.table ?? data.tableName ?? "",
284
+ columns: data.columns,
285
+ engine: data.engine,
286
+ charset: data.charset,
287
+ collate: data.collate,
288
+ comment: data.comment,
289
+ ifNotExists: data.ifNotExists,
290
+ }))
291
+ .refine((data) => data.name !== "", {
292
+ message: "name (or table/tableName alias) is required",
293
+ });
294
+ // --- DropTable ---
295
+ // Base schema for MCP visibility
296
+ export const DropTableSchemaBase = z.object({
297
+ table: z.string().optional().describe("Table name to drop"),
298
+ tableName: z.string().optional().describe("Alias for table"),
299
+ name: z.string().optional().describe("Alias for table"),
81
300
  ifExists: z
82
301
  .boolean()
83
302
  .optional()
84
303
  .default(true)
85
304
  .describe("Add IF EXISTS clause"),
86
305
  });
87
- export const CreateIndexSchema = z.object({
306
+ // Transformed schema for handler parsing
307
+ export const DropTableSchema = z
308
+ .preprocess(preprocessTableParams, DropTableSchemaBase)
309
+ .transform((data) => ({
310
+ table: data.table ?? data.tableName ?? data.name ?? "",
311
+ ifExists: data.ifExists,
312
+ }))
313
+ .refine((data) => data.table !== "", {
314
+ message: "table (or tableName/name alias) is required",
315
+ });
316
+ // --- CreateIndex ---
317
+ // Base schema for MCP visibility
318
+ export const CreateIndexSchemaBase = z.object({
88
319
  name: z.string().describe("Index name"),
89
- table: z.string().describe("Table name"),
320
+ table: z.string().optional().describe("Table name"),
321
+ tableName: z.string().optional().describe("Alias for table"),
90
322
  columns: z.array(z.string()).describe("Column names to index"),
91
323
  unique: z.boolean().optional().default(false).describe("Create unique index"),
92
324
  type: z
@@ -99,13 +331,40 @@ export const CreateIndexSchema = z.object({
99
331
  .default(false)
100
332
  .describe("Add IF NOT EXISTS clause"),
101
333
  });
102
- export const GetIndexesSchema = z.object({
103
- table: z.string().describe("Table name"),
334
+ // Transformed schema for handler parsing
335
+ export const CreateIndexSchema = z
336
+ .preprocess(preprocessTableParams, CreateIndexSchemaBase)
337
+ .transform((data) => ({
338
+ name: data.name,
339
+ table: data.table ?? data.tableName ?? "",
340
+ columns: data.columns,
341
+ unique: data.unique,
342
+ type: data.type,
343
+ ifNotExists: data.ifNotExists,
344
+ }))
345
+ .refine((data) => data.table !== "", {
346
+ message: "table (or tableName alias) is required",
347
+ });
348
+ // --- GetIndexes ---
349
+ // Base schema for MCP visibility
350
+ export const GetIndexesSchemaBase = z.object({
351
+ table: z.string().optional().describe("Table name"),
352
+ tableName: z.string().optional().describe("Alias for table"),
353
+ });
354
+ // Transformed schema for handler parsing
355
+ export const GetIndexesSchema = z
356
+ .preprocess(preprocessTableParams, GetIndexesSchemaBase)
357
+ .transform((data) => ({
358
+ table: data.table ?? data.tableName ?? "",
359
+ }))
360
+ .refine((data) => data.table !== "", {
361
+ message: "table (or tableName alias) is required",
104
362
  });
105
363
  // =============================================================================
106
364
  // Transaction Schemas
107
365
  // =============================================================================
108
- export const TransactionBeginSchema = z.object({
366
+ // --- TransactionBegin ---
367
+ export const TransactionBeginSchema = z.preprocess(defaultToEmpty, z.object({
109
368
  isolationLevel: z
110
369
  .enum([
111
370
  "READ UNCOMMITTED",
@@ -115,18 +374,53 @@ export const TransactionBeginSchema = z.object({
115
374
  ])
116
375
  .optional()
117
376
  .describe("Transaction isolation level"),
377
+ }));
378
+ // --- TransactionId ---
379
+ // Base schema for MCP visibility
380
+ export const TransactionIdSchemaBase = z.object({
381
+ transactionId: z
382
+ .string()
383
+ .optional()
384
+ .describe("Transaction ID from begin operation"),
385
+ txId: z.string().optional().describe("Alias for transactionId"),
386
+ tx: z.string().optional().describe("Alias for transactionId"),
118
387
  });
119
- export const TransactionIdSchema = z.object({
120
- transactionId: z.string().describe("Transaction ID from begin operation"),
388
+ // Transformed schema for handler parsing
389
+ export const TransactionIdSchema = z
390
+ .preprocess(preprocessTransactionIdParams, TransactionIdSchemaBase)
391
+ .transform((data) => ({
392
+ transactionId: data.transactionId ?? data.txId ?? data.tx ?? "",
393
+ }))
394
+ .refine((data) => data.transactionId !== "", {
395
+ message: "transactionId (or txId/tx alias) is required. Get one from mysql_transaction_begin first.",
121
396
  });
122
- export const TransactionSavepointSchema = z.object({
123
- transactionId: z.string().describe("Transaction ID"),
124
- savepoint: z.string().describe("Savepoint name"),
397
+ // --- TransactionSavepoint ---
398
+ // Base schema for MCP visibility
399
+ export const TransactionSavepointSchemaBase = z.object({
400
+ transactionId: z.string().optional().describe("Transaction ID"),
401
+ txId: z.string().optional().describe("Alias for transactionId"),
402
+ tx: z.string().optional().describe("Alias for transactionId"),
403
+ savepoint: z.string().optional().describe("Savepoint name"),
404
+ name: z.string().optional().describe("Alias for savepoint"),
125
405
  });
126
- export const TransactionExecuteSchema = z.object({
406
+ // Transformed schema for handler parsing
407
+ export const TransactionSavepointSchema = z
408
+ .preprocess(preprocessSavepointParams, TransactionSavepointSchemaBase)
409
+ .transform((data) => ({
410
+ transactionId: data.transactionId ?? data.txId ?? data.tx ?? "",
411
+ savepoint: data.savepoint ?? data.name ?? "",
412
+ }))
413
+ .refine((data) => data.transactionId !== "" && data.savepoint !== "", {
414
+ message: 'Both transactionId and savepoint are required. Example: {transactionId: "...", savepoint: "sp1"}',
415
+ });
416
+ // --- TransactionExecute ---
417
+ // Base schema for MCP visibility
418
+ export const TransactionExecuteSchemaBase = z.object({
127
419
  statements: z
128
420
  .array(z.string())
421
+ .optional()
129
422
  .describe("SQL statements to execute atomically"),
423
+ queries: z.array(z.string()).optional().describe("Alias for statements"),
130
424
  isolationLevel: z
131
425
  .enum([
132
426
  "READ UNCOMMITTED",
@@ -137,36 +431,181 @@ export const TransactionExecuteSchema = z.object({
137
431
  .optional()
138
432
  .describe("Transaction isolation level"),
139
433
  });
434
+ // Transformed schema for handler parsing
435
+ export const TransactionExecuteSchema = z
436
+ .preprocess(preprocessTransactionExecuteParams, TransactionExecuteSchemaBase)
437
+ .transform((data) => ({
438
+ statements: data.statements ?? data.queries ?? [],
439
+ isolationLevel: data.isolationLevel,
440
+ }));
441
+ // =============================================================================
442
+ // Preprocess: JSON/Text column params (table, column, where aliases)
443
+ // =============================================================================
444
+ function preprocessJsonColumnParams(val) {
445
+ if (val == null || typeof val !== "object")
446
+ return val ?? {};
447
+ const v = val;
448
+ return {
449
+ ...v,
450
+ table: v["table"] ?? v["tableName"] ?? v["name"],
451
+ column: v["column"] ?? v["col"],
452
+ where: v["where"] ?? v["filter"],
453
+ };
454
+ }
455
+ export function preprocessQueryOnlyParams(val) {
456
+ if (val == null || typeof val !== "object")
457
+ return val ?? {};
458
+ const v = val;
459
+ return {
460
+ ...v,
461
+ query: v["query"] ?? v["sql"],
462
+ };
463
+ }
140
464
  // =============================================================================
141
465
  // JSON Schemas
142
466
  // =============================================================================
143
- export const JsonExtractSchema = z.object({
144
- table: z.string().describe("Table name"),
145
- column: z.string().describe("JSON column name"),
467
+ // --- JsonExtract ---
468
+ export const JsonExtractSchemaBase = z.object({
469
+ table: z.string().optional().describe("Table name"),
470
+ tableName: z.string().optional().describe("Alias for table"),
471
+ name: z.string().optional().describe("Alias for table"),
472
+ column: z.string().optional().describe("JSON column name"),
473
+ col: z.string().optional().describe("Alias for column"),
146
474
  path: z.string().describe("JSON path (e.g., $.name or $[0])"),
147
475
  where: z.string().optional().describe("WHERE clause for filtering rows"),
476
+ filter: z.string().optional().describe("Alias for where"),
148
477
  });
149
- export const JsonSetSchema = z.object({
150
- table: z.string().describe("Table name"),
151
- column: z.string().describe("JSON column name"),
478
+ export const JsonExtractSchema = z
479
+ .preprocess(preprocessJsonColumnParams, z.object({
480
+ table: z.string().optional(),
481
+ tableName: z.string().optional(),
482
+ name: z.string().optional(),
483
+ column: z.string().optional(),
484
+ col: z.string().optional(),
485
+ path: z.string(),
486
+ where: z.string().optional(),
487
+ filter: z.string().optional(),
488
+ }))
489
+ .transform((data) => ({
490
+ table: data.table ?? data.tableName ?? data.name ?? "",
491
+ column: data.column ?? data.col ?? "",
492
+ path: data.path,
493
+ where: data.where ?? data.filter,
494
+ }))
495
+ .refine((data) => data.table !== "", {
496
+ message: "table (or tableName/name alias) is required",
497
+ })
498
+ .refine((data) => data.column !== "", {
499
+ message: "column (or col alias) is required",
500
+ });
501
+ // --- JsonSet ---
502
+ export const JsonSetSchemaBase = z.object({
503
+ table: z.string().optional().describe("Table name"),
504
+ tableName: z.string().optional().describe("Alias for table"),
505
+ name: z.string().optional().describe("Alias for table"),
506
+ column: z.string().optional().describe("JSON column name"),
507
+ col: z.string().optional().describe("Alias for column"),
152
508
  path: z.string().describe("JSON path to set"),
153
509
  value: z.unknown().describe("Value to set"),
154
- where: z.string().describe("WHERE clause to identify rows"),
510
+ where: z.string().optional().describe("WHERE clause to identify rows"),
511
+ filter: z.string().optional().describe("Alias for where"),
512
+ });
513
+ export const JsonSetSchema = z
514
+ .preprocess(preprocessJsonColumnParams, z.object({
515
+ table: z.string().optional(),
516
+ tableName: z.string().optional(),
517
+ name: z.string().optional(),
518
+ column: z.string().optional(),
519
+ col: z.string().optional(),
520
+ path: z.string(),
521
+ value: z.unknown(),
522
+ where: z.string().optional(),
523
+ filter: z.string().optional(),
524
+ }))
525
+ .transform((data) => ({
526
+ table: data.table ?? data.tableName ?? data.name ?? "",
527
+ column: data.column ?? data.col ?? "",
528
+ path: data.path,
529
+ value: data.value,
530
+ where: data.where ?? data.filter ?? "",
531
+ }))
532
+ .refine((data) => data.table !== "", {
533
+ message: "table (or tableName/name alias) is required",
534
+ })
535
+ .refine((data) => data.column !== "", {
536
+ message: "column (or col alias) is required",
537
+ })
538
+ .refine((data) => data.where !== "", {
539
+ message: "where (or filter alias) is required",
155
540
  });
156
- export const JsonContainsSchema = z.object({
157
- table: z.string().describe("Table name"),
158
- column: z.string().describe("JSON column name"),
541
+ // --- JsonContains ---
542
+ export const JsonContainsSchemaBase = z.object({
543
+ table: z.string().optional().describe("Table name"),
544
+ tableName: z.string().optional().describe("Alias for table"),
545
+ name: z.string().optional().describe("Alias for table"),
546
+ column: z.string().optional().describe("JSON column name"),
547
+ col: z.string().optional().describe("Alias for column"),
159
548
  value: z.unknown().describe("Value to search for"),
160
549
  path: z.string().optional().describe("Optional JSON path to search within"),
161
550
  });
162
- export const JsonKeysSchema = z.object({
163
- table: z.string().describe("Table name"),
164
- column: z.string().describe("JSON column name"),
551
+ export const JsonContainsSchema = z
552
+ .preprocess(preprocessJsonColumnParams, z.object({
553
+ table: z.string().optional(),
554
+ tableName: z.string().optional(),
555
+ name: z.string().optional(),
556
+ column: z.string().optional(),
557
+ col: z.string().optional(),
558
+ value: z.unknown(),
559
+ path: z.string().optional(),
560
+ }))
561
+ .transform((data) => ({
562
+ table: data.table ?? data.tableName ?? data.name ?? "",
563
+ column: data.column ?? data.col ?? "",
564
+ value: data.value,
565
+ path: data.path,
566
+ }))
567
+ .refine((data) => data.table !== "", {
568
+ message: "table (or tableName/name alias) is required",
569
+ })
570
+ .refine((data) => data.column !== "", {
571
+ message: "column (or col alias) is required",
572
+ });
573
+ // --- JsonKeys ---
574
+ export const JsonKeysSchemaBase = z.object({
575
+ table: z.string().optional().describe("Table name"),
576
+ tableName: z.string().optional().describe("Alias for table"),
577
+ name: z.string().optional().describe("Alias for table"),
578
+ column: z.string().optional().describe("JSON column name"),
579
+ col: z.string().optional().describe("Alias for column"),
165
580
  path: z.string().optional().describe("Optional JSON path (defaults to root)"),
166
581
  });
167
- export const JsonSearchSchema = z.object({
168
- table: z.string().describe("Table name"),
169
- column: z.string().describe("JSON column name"),
582
+ export const JsonKeysSchema = z
583
+ .preprocess(preprocessJsonColumnParams, z.object({
584
+ table: z.string().optional(),
585
+ tableName: z.string().optional(),
586
+ name: z.string().optional(),
587
+ column: z.string().optional(),
588
+ col: z.string().optional(),
589
+ path: z.string().optional(),
590
+ }))
591
+ .transform((data) => ({
592
+ table: data.table ?? data.tableName ?? data.name ?? "",
593
+ column: data.column ?? data.col ?? "",
594
+ path: data.path,
595
+ }))
596
+ .refine((data) => data.table !== "", {
597
+ message: "table (or tableName/name alias) is required",
598
+ })
599
+ .refine((data) => data.column !== "", {
600
+ message: "column (or col alias) is required",
601
+ });
602
+ // --- JsonSearch ---
603
+ export const JsonSearchSchemaBase = z.object({
604
+ table: z.string().optional().describe("Table name"),
605
+ tableName: z.string().optional().describe("Alias for table"),
606
+ name: z.string().optional().describe("Alias for table"),
607
+ column: z.string().optional().describe("JSON column name"),
608
+ col: z.string().optional().describe("Alias for column"),
170
609
  searchValue: z.string().describe("String value to search for"),
171
610
  mode: z
172
611
  .enum(["one", "all"])
@@ -174,65 +613,397 @@ export const JsonSearchSchema = z.object({
174
613
  .default("one")
175
614
  .describe("Search mode"),
176
615
  });
616
+ export const JsonSearchSchema = z
617
+ .preprocess(preprocessJsonColumnParams, z.object({
618
+ table: z.string().optional(),
619
+ tableName: z.string().optional(),
620
+ name: z.string().optional(),
621
+ column: z.string().optional(),
622
+ col: z.string().optional(),
623
+ searchValue: z.string(),
624
+ mode: z.enum(["one", "all"]).optional().default("one"),
625
+ }))
626
+ .transform((data) => ({
627
+ table: data.table ?? data.tableName ?? data.name ?? "",
628
+ column: data.column ?? data.col ?? "",
629
+ searchValue: data.searchValue,
630
+ mode: data.mode,
631
+ }))
632
+ .refine((data) => data.table !== "", {
633
+ message: "table (or tableName/name alias) is required",
634
+ })
635
+ .refine((data) => data.column !== "", {
636
+ message: "column (or col alias) is required",
637
+ });
638
+ // --- JsonValidate (no table/column — no aliases needed) ---
177
639
  export const JsonValidateSchema = z.object({
178
640
  value: z.string().describe("JSON string to validate"),
179
641
  });
180
642
  // =============================================================================
181
643
  // Text Schemas
182
644
  // =============================================================================
183
- export const RegexpMatchSchema = z.object({
184
- table: z.string().describe("Table name"),
185
- column: z.string().describe("Column name"),
645
+ // --- RegexpMatch ---
646
+ export const RegexpMatchSchemaBase = z.object({
647
+ table: z.string().optional().describe("Table name"),
648
+ tableName: z.string().optional().describe("Alias for table"),
649
+ name: z.string().optional().describe("Alias for table"),
650
+ column: z.string().optional().describe("Column name"),
651
+ col: z.string().optional().describe("Alias for column"),
186
652
  pattern: z.string().describe("Regular expression pattern"),
187
653
  where: z
188
654
  .string()
189
655
  .optional()
190
656
  .describe("Additional WHERE clause for filtering"),
657
+ filter: z.string().optional().describe("Alias for where"),
191
658
  });
192
- export const LikeSearchSchema = z.object({
193
- table: z.string().describe("Table name"),
194
- column: z.string().describe("Column name"),
659
+ export const RegexpMatchSchema = z
660
+ .preprocess(preprocessJsonColumnParams, z.object({
661
+ table: z.string().optional(),
662
+ tableName: z.string().optional(),
663
+ name: z.string().optional(),
664
+ column: z.string().optional(),
665
+ col: z.string().optional(),
666
+ pattern: z.string(),
667
+ where: z.string().optional(),
668
+ filter: z.string().optional(),
669
+ }))
670
+ .transform((data) => ({
671
+ table: data.table ?? data.tableName ?? data.name ?? "",
672
+ column: data.column ?? data.col ?? "",
673
+ pattern: data.pattern,
674
+ where: data.where ?? data.filter,
675
+ }))
676
+ .refine((data) => data.table !== "", {
677
+ message: "table (or tableName/name alias) is required",
678
+ })
679
+ .refine((data) => data.column !== "", {
680
+ message: "column (or col alias) is required",
681
+ });
682
+ // --- LikeSearch ---
683
+ export const LikeSearchSchemaBase = z.object({
684
+ table: z.string().optional().describe("Table name"),
685
+ tableName: z.string().optional().describe("Alias for table"),
686
+ name: z.string().optional().describe("Alias for table"),
687
+ column: z.string().optional().describe("Column name"),
688
+ col: z.string().optional().describe("Alias for column"),
195
689
  pattern: z.string().describe("LIKE pattern with % and _ wildcards"),
196
690
  where: z
197
691
  .string()
198
692
  .optional()
199
693
  .describe("Additional WHERE clause for filtering"),
694
+ filter: z.string().optional().describe("Alias for where"),
200
695
  });
201
- export const SoundexSchema = z.object({
202
- table: z.string().describe("Table name"),
203
- column: z.string().describe("Column name"),
696
+ export const LikeSearchSchema = z
697
+ .preprocess(preprocessJsonColumnParams, z.object({
698
+ table: z.string().optional(),
699
+ tableName: z.string().optional(),
700
+ name: z.string().optional(),
701
+ column: z.string().optional(),
702
+ col: z.string().optional(),
703
+ pattern: z.string(),
704
+ where: z.string().optional(),
705
+ filter: z.string().optional(),
706
+ }))
707
+ .transform((data) => ({
708
+ table: data.table ?? data.tableName ?? data.name ?? "",
709
+ column: data.column ?? data.col ?? "",
710
+ pattern: data.pattern,
711
+ where: data.where ?? data.filter,
712
+ }))
713
+ .refine((data) => data.table !== "", {
714
+ message: "table (or tableName/name alias) is required",
715
+ })
716
+ .refine((data) => data.column !== "", {
717
+ message: "column (or col alias) is required",
718
+ });
719
+ // --- Soundex ---
720
+ export const SoundexSchemaBase = z.object({
721
+ table: z.string().optional().describe("Table name"),
722
+ tableName: z.string().optional().describe("Alias for table"),
723
+ name: z.string().optional().describe("Alias for table"),
724
+ column: z.string().optional().describe("Column name"),
725
+ col: z.string().optional().describe("Alias for column"),
204
726
  value: z.string().describe("Value to match phonetically"),
205
727
  where: z
206
728
  .string()
207
729
  .optional()
208
730
  .describe("Additional WHERE clause for filtering"),
731
+ filter: z.string().optional().describe("Alias for where"),
732
+ });
733
+ export const SoundexSchema = z
734
+ .preprocess(preprocessJsonColumnParams, z.object({
735
+ table: z.string().optional(),
736
+ tableName: z.string().optional(),
737
+ name: z.string().optional(),
738
+ column: z.string().optional(),
739
+ col: z.string().optional(),
740
+ value: z.string(),
741
+ where: z.string().optional(),
742
+ filter: z.string().optional(),
743
+ }))
744
+ .transform((data) => ({
745
+ table: data.table ?? data.tableName ?? data.name ?? "",
746
+ column: data.column ?? data.col ?? "",
747
+ value: data.value,
748
+ where: data.where ?? data.filter,
749
+ }))
750
+ .refine((data) => data.table !== "", {
751
+ message: "table (or tableName/name alias) is required",
752
+ })
753
+ .refine((data) => data.column !== "", {
754
+ message: "column (or col alias) is required",
755
+ });
756
+ // --- Substring ---
757
+ export const SubstringSchemaBase = z.object({
758
+ table: z.string().optional().describe("Table name"),
759
+ tableName: z.string().optional().describe("Alias for table"),
760
+ name: z.string().optional().describe("Alias for table"),
761
+ column: z.string().describe("Column name"),
762
+ start: z.number().describe("Starting position (1-indexed)"),
763
+ length: z.number().optional().describe("Number of characters"),
764
+ where: z
765
+ .string()
766
+ .optional()
767
+ .describe("Additional WHERE clause for filtering"),
768
+ filter: z.string().optional().describe("Alias for where"),
769
+ });
770
+ export const SubstringSchema = z
771
+ .preprocess(preprocessJsonColumnParams, z.object({
772
+ table: z.string().optional(),
773
+ tableName: z.string().optional(),
774
+ name: z.string().optional(),
775
+ column: z.string(),
776
+ start: z.number(),
777
+ length: z.number().optional(),
778
+ where: z.string().optional(),
779
+ filter: z.string().optional(),
780
+ }))
781
+ .transform((data) => ({
782
+ table: data.table ?? data.tableName ?? data.name ?? "",
783
+ column: data.column,
784
+ start: data.start,
785
+ length: data.length,
786
+ where: data.where ?? data.filter,
787
+ }))
788
+ .refine((data) => data.table !== "", {
789
+ message: "table (or tableName/name alias) is required",
790
+ });
791
+ // --- Concat ---
792
+ export const ConcatSchemaBase = z.object({
793
+ table: z.string().optional().describe("Table name"),
794
+ tableName: z.string().optional().describe("Alias for table"),
795
+ name: z.string().optional().describe("Alias for table"),
796
+ columns: z.array(z.string()).describe("Columns to concatenate"),
797
+ separator: z
798
+ .string()
799
+ .optional()
800
+ .default(" ")
801
+ .describe("Separator between values"),
802
+ alias: z
803
+ .string()
804
+ .optional()
805
+ .default("concatenated")
806
+ .describe("Result column name"),
807
+ where: z
808
+ .string()
809
+ .optional()
810
+ .describe("Additional WHERE clause for filtering"),
811
+ filter: z.string().optional().describe("Alias for where"),
812
+ includeSourceColumns: z
813
+ .boolean()
814
+ .optional()
815
+ .default(true)
816
+ .describe("Include individual source columns in output (default: true). Set to false for minimal payload."),
209
817
  });
210
- export const FulltextCreateSchema = z.object({
211
- table: z.string().describe("Table name"),
212
- columns: z.array(z.string()).describe("Columns to include in index"),
818
+ export const ConcatSchema = z
819
+ .preprocess(preprocessJsonColumnParams, z.object({
820
+ table: z.string().optional(),
821
+ tableName: z.string().optional(),
822
+ name: z.string().optional(),
823
+ columns: z.array(z.string()),
824
+ separator: z.string().optional().default(" "),
825
+ alias: z.string().optional().default("concatenated"),
826
+ where: z.string().optional(),
827
+ filter: z.string().optional(),
828
+ includeSourceColumns: z.boolean().optional().default(true),
829
+ }))
830
+ .transform((data) => ({
831
+ table: data.table ?? data.tableName ?? data.name ?? "",
832
+ columns: data.columns,
833
+ separator: data.separator,
834
+ alias: data.alias,
835
+ where: data.where ?? data.filter,
836
+ includeSourceColumns: data.includeSourceColumns,
837
+ }))
838
+ .refine((data) => data.table !== "", {
839
+ message: "table (or tableName/name alias) is required",
840
+ });
841
+ // --- CollationConvert ---
842
+ export const CollationConvertSchemaBase = z.object({
843
+ table: z.string().optional().describe("Table name"),
844
+ tableName: z.string().optional().describe("Alias for table"),
845
+ name: z.string().optional().describe("Alias for table"),
846
+ column: z.string().optional().describe("Column name"),
847
+ col: z.string().optional().describe("Alias for column"),
848
+ charset: z.string().describe("Target character set (e.g., utf8mb4)"),
849
+ collation: z.string().optional().describe("Target collation"),
850
+ where: z
851
+ .string()
852
+ .optional()
853
+ .describe("Additional WHERE clause for filtering"),
854
+ filter: z.string().optional().describe("Alias for where"),
855
+ });
856
+ export const CollationConvertSchema = z
857
+ .preprocess(preprocessJsonColumnParams, z.object({
858
+ table: z.string().optional(),
859
+ tableName: z.string().optional(),
860
+ name: z.string().optional(),
861
+ column: z.string().optional(),
862
+ col: z.string().optional(),
863
+ charset: z.string(),
864
+ collation: z.string().optional(),
865
+ where: z.string().optional(),
866
+ filter: z.string().optional(),
867
+ }))
868
+ .transform((data) => ({
869
+ table: data.table ?? data.tableName ?? data.name ?? "",
870
+ column: data.column ?? data.col ?? "",
871
+ charset: data.charset,
872
+ collation: data.collation,
873
+ where: data.where ?? data.filter,
874
+ }))
875
+ .refine((data) => data.table !== "", {
876
+ message: "table (or tableName/name alias) is required",
877
+ })
878
+ .refine((data) => data.column !== "", {
879
+ message: "column (or col alias) is required",
880
+ });
881
+ // --- FulltextCreate ---
882
+ export const FulltextCreateSchemaBase = z.object({
883
+ table: z.string().optional().describe("Table name"),
884
+ tableName: z.string().optional().describe("Alias for table"),
885
+ name: z.string().optional().describe("Alias for table"),
886
+ columns: z
887
+ .array(z.string())
888
+ .optional()
889
+ .describe("Columns to include in index"),
213
890
  indexName: z.string().optional().describe("Optional index name"),
214
891
  });
215
- export const FulltextSearchSchema = z.object({
216
- table: z.string().describe("Table name"),
217
- columns: z.array(z.string()).describe("Columns to search"),
218
- query: z.string().describe("Search query"),
892
+ export const FulltextCreateSchema = z
893
+ .preprocess(preprocessTableParams, z.object({
894
+ table: z.string().optional(),
895
+ tableName: z.string().optional(),
896
+ name: z.string().optional(),
897
+ columns: z.array(z.string()).optional(),
898
+ indexName: z.string().optional(),
899
+ }))
900
+ .transform((data) => ({
901
+ table: data.table ?? data.tableName ?? data.name ?? "",
902
+ columns: data.columns ?? [],
903
+ indexName: data.indexName,
904
+ }))
905
+ .refine((data) => data.table !== "", {
906
+ message: "table (or tableName/name alias) is required",
907
+ })
908
+ .refine((data) => data.columns.length > 0, {
909
+ message: "columns is required",
910
+ });
911
+ // --- FulltextSearch ---
912
+ export const FulltextSearchSchemaBase = z.object({
913
+ table: z.string().optional().describe("Table name"),
914
+ tableName: z.string().optional().describe("Alias for table"),
915
+ name: z.string().optional().describe("Alias for table"),
916
+ columns: z.array(z.string()).optional().describe("Columns to search"),
917
+ query: z.string().optional().describe("Search query"),
918
+ sql: z.string().optional().describe("Alias for query"),
219
919
  mode: z
220
920
  .enum(["NATURAL", "BOOLEAN", "EXPANSION"])
221
921
  .optional()
222
922
  .default("NATURAL")
223
923
  .describe("Search mode"),
224
924
  });
925
+ export const FulltextSearchSchema = z
926
+ .preprocess((val) => {
927
+ const v1 = preprocessTableParams(val);
928
+ return preprocessQueryOnlyParams(v1);
929
+ }, z.object({
930
+ table: z.string().optional(),
931
+ tableName: z.string().optional(),
932
+ name: z.string().optional(),
933
+ columns: z.array(z.string()).optional(),
934
+ query: z.string().optional(),
935
+ sql: z.string().optional(),
936
+ mode: z
937
+ .enum(["NATURAL", "BOOLEAN", "EXPANSION"])
938
+ .optional()
939
+ .default("NATURAL"),
940
+ }))
941
+ .transform((data) => ({
942
+ table: data.table ?? data.tableName ?? data.name ?? "",
943
+ columns: data.columns ?? [],
944
+ query: data.query ?? data.sql ?? "",
945
+ mode: data.mode,
946
+ }))
947
+ .refine((data) => data.table !== "", {
948
+ message: "table (or tableName/name alias) is required",
949
+ })
950
+ .refine((data) => data.columns.length > 0, { message: "columns is required" })
951
+ .refine((data) => data.query !== "", {
952
+ message: "query (or sql alias) is required",
953
+ });
225
954
  // =============================================================================
226
955
  // Performance Schemas
227
956
  // =============================================================================
228
- export const ExplainSchema = z.object({
229
- query: z.string().describe("SQL query to explain"),
957
+ // --- Explain ---
958
+ export const ExplainSchemaBase = z.object({
959
+ query: z.string().optional().describe("SQL query to explain"),
960
+ sql: z.string().optional().describe("Alias for query"),
230
961
  format: z
231
962
  .enum(["TRADITIONAL", "JSON", "TREE"])
232
963
  .optional()
233
964
  .default("JSON")
234
965
  .describe("Output format"),
235
966
  });
967
+ export const ExplainSchema = z
968
+ .preprocess(preprocessQueryOnlyParams, z.object({
969
+ query: z.string().optional(),
970
+ sql: z.string().optional(),
971
+ format: z
972
+ .enum(["TRADITIONAL", "JSON", "TREE"])
973
+ .optional()
974
+ .default("JSON"),
975
+ }))
976
+ .transform((data) => ({
977
+ query: data.query ?? data.sql ?? "",
978
+ format: data.format,
979
+ }))
980
+ .refine((data) => data.query !== "", {
981
+ message: "query (or sql alias) is required",
982
+ });
983
+ // --- ExplainAnalyze ---
984
+ export const ExplainAnalyzeSchemaBase = z.object({
985
+ query: z.string().optional().describe("SQL query to analyze"),
986
+ sql: z.string().optional().describe("Alias for query"),
987
+ format: z
988
+ .enum(["JSON", "TREE"])
989
+ .optional()
990
+ .default("TREE")
991
+ .describe("Output format"),
992
+ });
993
+ export const ExplainAnalyzeSchema = z
994
+ .preprocess(preprocessQueryOnlyParams, z.object({
995
+ query: z.string().optional(),
996
+ sql: z.string().optional(),
997
+ format: z.enum(["JSON", "TREE"]).optional().default("TREE"),
998
+ }))
999
+ .transform((data) => ({
1000
+ query: data.query ?? data.sql ?? "",
1001
+ format: data.format,
1002
+ }))
1003
+ .refine((data) => data.query !== "", {
1004
+ message: "query (or sql alias) is required",
1005
+ });
1006
+ // --- SlowQuery (no table/query aliases — simple passthrough) ---
236
1007
  export const SlowQuerySchema = z.object({
237
1008
  limit: z
238
1009
  .number()
@@ -241,8 +1012,11 @@ export const SlowQuerySchema = z.object({
241
1012
  .describe("Number of slow queries to return"),
242
1013
  minTime: z.number().optional().describe("Minimum query time in seconds"),
243
1014
  });
244
- export const IndexUsageSchema = z.object({
1015
+ // --- IndexUsage ---
1016
+ export const IndexUsageSchemaBase = z.object({
245
1017
  table: z.string().optional().describe("Filter by table name"),
1018
+ tableName: z.string().optional().describe("Alias for table"),
1019
+ name: z.string().optional().describe("Alias for table"),
246
1020
  limit: z
247
1021
  .number()
248
1022
  .int()
@@ -251,31 +1025,146 @@ export const IndexUsageSchema = z.object({
251
1025
  .default(10)
252
1026
  .describe("Maximum number of indexes to return"),
253
1027
  });
254
- export const TableStatsSchema = z.object({
255
- table: z.string().describe("Table name"),
1028
+ export const IndexUsageSchema = z
1029
+ .preprocess(preprocessTableParams, z.object({
1030
+ table: z.string().optional(),
1031
+ tableName: z.string().optional(),
1032
+ name: z.string().optional(),
1033
+ limit: z.number().int().positive().optional().default(10),
1034
+ }))
1035
+ .transform((data) => ({
1036
+ table: data.table ?? data.tableName ?? data.name,
1037
+ limit: data.limit,
1038
+ }));
1039
+ // --- TableStats ---
1040
+ export const TableStatsSchemaBase = z.object({
1041
+ table: z.string().optional().describe("Table name"),
1042
+ tableName: z.string().optional().describe("Alias for table"),
1043
+ name: z.string().optional().describe("Alias for table"),
256
1044
  });
1045
+ export const TableStatsSchema = z
1046
+ .preprocess(preprocessTableParams, z.object({
1047
+ table: z.string().optional(),
1048
+ tableName: z.string().optional(),
1049
+ name: z.string().optional(),
1050
+ }))
1051
+ .transform((data) => ({
1052
+ table: data.table ?? data.tableName ?? data.name ?? "",
1053
+ }))
1054
+ .refine((data) => data.table !== "", {
1055
+ message: "table (or tableName/name alias) is required",
1056
+ });
1057
+ // =============================================================================
1058
+ // Preprocess: Admin table params (normalizes singular 'table' to 'tables' array)
1059
+ // =============================================================================
1060
+ function preprocessAdminTableParams(val) {
1061
+ if (val == null || typeof val !== "object")
1062
+ return val ?? {};
1063
+ const v = val;
1064
+ // If 'table' is passed as a string and 'tables' is not set, wrap it into an array
1065
+ if (typeof v["table"] === "string" && !Array.isArray(v["tables"])) {
1066
+ return { ...v, tables: [v["table"]] };
1067
+ }
1068
+ // Also support tableName/name aliases → tables
1069
+ if (typeof v["tableName"] === "string" && !Array.isArray(v["tables"])) {
1070
+ return { ...v, tables: [v["tableName"]] };
1071
+ }
1072
+ if (typeof v["name"] === "string" && !Array.isArray(v["tables"])) {
1073
+ return { ...v, tables: [v["name"]] };
1074
+ }
1075
+ return v;
1076
+ }
257
1077
  // =============================================================================
258
1078
  // Admin Schemas
259
1079
  // =============================================================================
260
- export const OptimizeTableSchema = z.object({
261
- tables: z.array(z.string()).describe("Table names to optimize"),
1080
+ // --- OptimizeTable ---
1081
+ export const OptimizeTableSchemaBase = z.object({
1082
+ tables: z.array(z.string()).optional().describe("Table names to optimize"),
1083
+ table: z.string().optional().describe("Single table name (alias for tables)"),
1084
+ tableName: z.string().optional().describe("Alias for table"),
1085
+ name: z.string().optional().describe("Alias for table"),
1086
+ });
1087
+ export const OptimizeTableSchema = z
1088
+ .preprocess(preprocessAdminTableParams, z.object({
1089
+ tables: z.array(z.string()).optional(),
1090
+ table: z.string().optional(),
1091
+ tableName: z.string().optional(),
1092
+ name: z.string().optional(),
1093
+ }))
1094
+ .transform((data) => ({
1095
+ tables: data.tables ?? [],
1096
+ }))
1097
+ .refine((data) => data.tables.length > 0, {
1098
+ message: "tables (or table/tableName/name alias) is required",
262
1099
  });
263
- export const AnalyzeTableSchema = z.object({
264
- tables: z.array(z.string()).describe("Table names to analyze"),
1100
+ // --- AnalyzeTable ---
1101
+ export const AnalyzeTableSchemaBase = z.object({
1102
+ tables: z.array(z.string()).optional().describe("Table names to analyze"),
1103
+ table: z.string().optional().describe("Single table name (alias for tables)"),
1104
+ tableName: z.string().optional().describe("Alias for table"),
1105
+ name: z.string().optional().describe("Alias for table"),
265
1106
  });
266
- export const CheckTableSchema = z.object({
267
- tables: z.array(z.string()).describe("Table names to check"),
1107
+ export const AnalyzeTableSchema = z
1108
+ .preprocess(preprocessAdminTableParams, z.object({
1109
+ tables: z.array(z.string()).optional(),
1110
+ table: z.string().optional(),
1111
+ tableName: z.string().optional(),
1112
+ name: z.string().optional(),
1113
+ }))
1114
+ .transform((data) => ({
1115
+ tables: data.tables ?? [],
1116
+ }))
1117
+ .refine((data) => data.tables.length > 0, {
1118
+ message: "tables (or table/tableName/name alias) is required",
1119
+ });
1120
+ // --- CheckTable ---
1121
+ export const CheckTableSchemaBase = z.object({
1122
+ tables: z.array(z.string()).optional().describe("Table names to check"),
1123
+ table: z.string().optional().describe("Single table name (alias for tables)"),
1124
+ tableName: z.string().optional().describe("Alias for table"),
1125
+ name: z.string().optional().describe("Alias for table"),
268
1126
  option: z
269
1127
  .enum(["QUICK", "FAST", "MEDIUM", "EXTENDED", "CHANGED"])
270
1128
  .optional()
271
1129
  .describe("Check option"),
272
1130
  });
273
- export const FlushTablesSchema = z.object({
1131
+ export const CheckTableSchema = z
1132
+ .preprocess(preprocessAdminTableParams, z.object({
1133
+ tables: z.array(z.string()).optional(),
1134
+ table: z.string().optional(),
1135
+ tableName: z.string().optional(),
1136
+ name: z.string().optional(),
1137
+ option: z
1138
+ .enum(["QUICK", "FAST", "MEDIUM", "EXTENDED", "CHANGED"])
1139
+ .optional(),
1140
+ }))
1141
+ .transform((data) => ({
1142
+ tables: data.tables ?? [],
1143
+ option: data.option,
1144
+ }))
1145
+ .refine((data) => data.tables.length > 0, {
1146
+ message: "tables (or table/tableName/name alias) is required",
1147
+ });
1148
+ // --- FlushTables ---
1149
+ export const FlushTablesSchemaBase = z.object({
274
1150
  tables: z
275
1151
  .array(z.string())
276
1152
  .optional()
277
1153
  .describe("Specific tables to flush (empty for all)"),
1154
+ table: z.string().optional().describe("Single table name (alias for tables)"),
1155
+ tableName: z.string().optional().describe("Alias for table"),
1156
+ name: z.string().optional().describe("Alias for table"),
278
1157
  });
1158
+ export const FlushTablesSchema = z
1159
+ .preprocess(preprocessAdminTableParams, z.object({
1160
+ tables: z.array(z.string()).optional(),
1161
+ table: z.string().optional(),
1162
+ tableName: z.string().optional(),
1163
+ name: z.string().optional(),
1164
+ }))
1165
+ .transform((data) => ({
1166
+ tables: data.tables,
1167
+ }));
279
1168
  export const KillQuerySchema = z.object({
280
1169
  processId: z.number().describe("Process ID to kill"),
281
1170
  connection: z
@@ -314,14 +1203,18 @@ export const ShowVariablesSchema = z.object({
314
1203
  // =============================================================================
315
1204
  // Backup Schemas
316
1205
  // =============================================================================
317
- export const ExportTableSchema = z.object({
318
- table: z.string().describe("Table name"),
1206
+ // --- ExportTable ---
1207
+ export const ExportTableSchemaBase = z.object({
1208
+ table: z.string().optional().describe("Table name"),
1209
+ tableName: z.string().optional().describe("Alias for table"),
1210
+ name: z.string().optional().describe("Alias for table"),
319
1211
  format: z
320
1212
  .enum(["SQL", "CSV"])
321
1213
  .optional()
322
1214
  .default("SQL")
323
1215
  .describe("Export format"),
324
1216
  where: z.string().optional().describe("WHERE clause to filter rows"),
1217
+ filter: z.string().optional().describe("Alias for where"),
325
1218
  limit: z
326
1219
  .number()
327
1220
  .int()
@@ -330,12 +1223,48 @@ export const ExportTableSchema = z.object({
330
1223
  .default(100)
331
1224
  .describe("Maximum number of rows to export (default: 100). Set higher to export more rows."),
332
1225
  });
333
- export const ImportDataSchema = z.object({
334
- table: z.string().describe("Table name"),
1226
+ export const ExportTableSchema = z
1227
+ .preprocess(preprocessTableParams, z.object({
1228
+ table: z.string().optional(),
1229
+ tableName: z.string().optional(),
1230
+ name: z.string().optional(),
1231
+ format: z.enum(["SQL", "CSV"]).optional().default("SQL"),
1232
+ where: z.string().optional(),
1233
+ filter: z.string().optional(),
1234
+ limit: z.number().int().positive().optional().default(100),
1235
+ }))
1236
+ .transform((data) => ({
1237
+ table: data.table ?? data.tableName ?? data.name ?? "",
1238
+ format: data.format,
1239
+ where: data.where ?? data.filter,
1240
+ limit: data.limit,
1241
+ }))
1242
+ .refine((data) => data.table !== "", {
1243
+ message: "table (or tableName/name alias) is required",
1244
+ });
1245
+ // --- ImportData ---
1246
+ export const ImportDataSchemaBase = z.object({
1247
+ table: z.string().optional().describe("Table name"),
1248
+ tableName: z.string().optional().describe("Alias for table"),
1249
+ name: z.string().optional().describe("Alias for table"),
335
1250
  data: z
336
1251
  .array(z.record(z.string(), z.unknown()))
337
1252
  .describe("Array of row objects to insert"),
338
1253
  });
1254
+ export const ImportDataSchema = z
1255
+ .preprocess(preprocessTableParams, z.object({
1256
+ table: z.string().optional(),
1257
+ tableName: z.string().optional(),
1258
+ name: z.string().optional(),
1259
+ data: z.array(z.record(z.string(), z.unknown())),
1260
+ }))
1261
+ .transform((data) => ({
1262
+ table: data.table ?? data.tableName ?? data.name ?? "",
1263
+ data: data.data,
1264
+ }))
1265
+ .refine((data) => data.table !== "", {
1266
+ message: "table (or tableName/name alias) is required",
1267
+ });
339
1268
  // =============================================================================
340
1269
  // Replication Schemas
341
1270
  // =============================================================================
@@ -351,11 +1280,29 @@ export const BinlogEventsSchema = z.object({
351
1280
  // =============================================================================
352
1281
  // Partitioning Schemas
353
1282
  // =============================================================================
354
- export const PartitionInfoSchema = z.object({
355
- table: z.string().describe("Table name"),
1283
+ // --- PartitionInfo ---
1284
+ export const PartitionInfoSchemaBase = z.object({
1285
+ table: z.string().optional().describe("Table name"),
1286
+ tableName: z.string().optional().describe("Alias for table"),
1287
+ name: z.string().optional().describe("Alias for table"),
356
1288
  });
357
- export const AddPartitionSchema = z.object({
358
- table: z.string().describe("Table name"),
1289
+ export const PartitionInfoSchema = z
1290
+ .preprocess(preprocessTableParams, z.object({
1291
+ table: z.string().optional(),
1292
+ tableName: z.string().optional(),
1293
+ name: z.string().optional(),
1294
+ }))
1295
+ .transform((data) => ({
1296
+ table: data.table ?? data.tableName ?? data.name ?? "",
1297
+ }))
1298
+ .refine((data) => data.table !== "", {
1299
+ message: "table (or tableName/name alias) is required",
1300
+ });
1301
+ // --- AddPartition ---
1302
+ export const AddPartitionSchemaBase = z.object({
1303
+ table: z.string().optional().describe("Table name"),
1304
+ tableName: z.string().optional().describe("Alias for table"),
1305
+ name: z.string().optional().describe("Alias for table"),
359
1306
  partitionName: z.string().describe("New partition name"),
360
1307
  partitionType: z
361
1308
  .enum(["RANGE", "LIST", "HASH", "KEY"])
@@ -364,15 +1311,53 @@ export const AddPartitionSchema = z.object({
364
1311
  .string()
365
1312
  .describe('Partition boundary value only - e.g., "2024" for RANGE, "1,2,3" for LIST, "4" for HASH/KEY partitions count. Do NOT include "LESS THAN" or "VALUES IN" keywords.'),
366
1313
  });
367
- export const DropPartitionSchema = z.object({
368
- table: z.string().describe("Table name"),
1314
+ export const AddPartitionSchema = z
1315
+ .preprocess(preprocessTableParams, z.object({
1316
+ table: z.string().optional(),
1317
+ tableName: z.string().optional(),
1318
+ name: z.string().optional(),
1319
+ partitionName: z.string(),
1320
+ partitionType: z.enum(["RANGE", "LIST", "HASH", "KEY"]),
1321
+ value: z.string(),
1322
+ }))
1323
+ .transform((data) => ({
1324
+ table: data.table ?? data.tableName ?? data.name ?? "",
1325
+ partitionName: data.partitionName,
1326
+ partitionType: data.partitionType,
1327
+ value: data.value,
1328
+ }))
1329
+ .refine((data) => data.table !== "", {
1330
+ message: "table (or tableName/name alias) is required",
1331
+ });
1332
+ // --- DropPartition ---
1333
+ export const DropPartitionSchemaBase = z.object({
1334
+ table: z.string().optional().describe("Table name"),
1335
+ tableName: z.string().optional().describe("Alias for table"),
1336
+ name: z.string().optional().describe("Alias for table"),
369
1337
  partitionName: z.string().describe("Partition name to drop"),
370
1338
  });
371
- export const ReorganizePartitionSchema = z.object({
372
- table: z.string().describe("Table name"),
1339
+ export const DropPartitionSchema = z
1340
+ .preprocess(preprocessTableParams, z.object({
1341
+ table: z.string().optional(),
1342
+ tableName: z.string().optional(),
1343
+ name: z.string().optional(),
1344
+ partitionName: z.string(),
1345
+ }))
1346
+ .transform((data) => ({
1347
+ table: data.table ?? data.tableName ?? data.name ?? "",
1348
+ partitionName: data.partitionName,
1349
+ }))
1350
+ .refine((data) => data.table !== "", {
1351
+ message: "table (or tableName/name alias) is required",
1352
+ });
1353
+ // --- ReorganizePartition ---
1354
+ export const ReorganizePartitionSchemaBase = z.object({
1355
+ table: z.string().optional().describe("Table name"),
1356
+ tableName: z.string().optional().describe("Alias for table"),
1357
+ name: z.string().optional().describe("Alias for table"),
373
1358
  fromPartitions: z.array(z.string()).describe("Source partition names"),
374
1359
  partitionType: z
375
- .enum(["RANGE", "LIST"])
1360
+ .enum(["RANGE", "LIST", "HASH", "KEY"])
376
1361
  .describe("Partition type (RANGE or LIST). HASH/KEY partitions cannot be reorganized."),
377
1362
  toPartitions: z
378
1363
  .array(z.object({
@@ -383,4 +1368,25 @@ export const ReorganizePartitionSchema = z.object({
383
1368
  }))
384
1369
  .describe("New partition definitions"),
385
1370
  });
1371
+ export const ReorganizePartitionSchema = z
1372
+ .preprocess(preprocessTableParams, z.object({
1373
+ table: z.string().optional(),
1374
+ tableName: z.string().optional(),
1375
+ name: z.string().optional(),
1376
+ fromPartitions: z.array(z.string()),
1377
+ partitionType: z.enum(["RANGE", "LIST"]),
1378
+ toPartitions: z.array(z.object({
1379
+ name: z.string(),
1380
+ value: z.string(),
1381
+ })),
1382
+ }))
1383
+ .transform((data) => ({
1384
+ table: data.table ?? data.tableName ?? data.name ?? "",
1385
+ fromPartitions: data.fromPartitions,
1386
+ partitionType: data.partitionType,
1387
+ toPartitions: data.toPartitions,
1388
+ }))
1389
+ .refine((data) => data.table !== "", {
1390
+ message: "table (or tableName/name alias) is required",
1391
+ });
386
1392
  //# sourceMappingURL=types.js.map