@sigma4life/mysql-mcp-server 1.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 (149) hide show
  1. package/.env.example +35 -0
  2. package/.github/workflows/ci.yml +18 -0
  3. package/AUTHENTICATION.md +24 -0
  4. package/CLAUDE.md +37 -0
  5. package/CONTRIBUTING.md +19 -0
  6. package/LICENSE +21 -0
  7. package/QUERY_ACCESS_SETUP.md +65 -0
  8. package/README.md +144 -0
  9. package/SECURITY.md +10 -0
  10. package/TESTING.md +54 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +197 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/core/cache.d.ts +11 -0
  16. package/dist/core/cache.d.ts.map +1 -0
  17. package/dist/core/cache.js +30 -0
  18. package/dist/core/cache.js.map +1 -0
  19. package/dist/core/config.d.ts +24 -0
  20. package/dist/core/config.d.ts.map +1 -0
  21. package/dist/core/config.js +63 -0
  22. package/dist/core/config.js.map +1 -0
  23. package/dist/core/database-url.d.ts +11 -0
  24. package/dist/core/database-url.d.ts.map +1 -0
  25. package/dist/core/database-url.js +37 -0
  26. package/dist/core/database-url.js.map +1 -0
  27. package/dist/core/database-url.test.d.ts +2 -0
  28. package/dist/core/database-url.test.d.ts.map +1 -0
  29. package/dist/core/database-url.test.js +22 -0
  30. package/dist/core/database-url.test.js.map +1 -0
  31. package/dist/core/logger.d.ts +3 -0
  32. package/dist/core/logger.d.ts.map +1 -0
  33. package/dist/core/logger.js +17 -0
  34. package/dist/core/logger.js.map +1 -0
  35. package/dist/core/mcp.d.ts +14 -0
  36. package/dist/core/mcp.d.ts.map +1 -0
  37. package/dist/core/mcp.js +23 -0
  38. package/dist/core/mcp.js.map +1 -0
  39. package/dist/core/query-safety.d.ts +10 -0
  40. package/dist/core/query-safety.d.ts.map +1 -0
  41. package/dist/core/query-safety.js +50 -0
  42. package/dist/core/query-safety.js.map +1 -0
  43. package/dist/core/query-safety.test.d.ts +2 -0
  44. package/dist/core/query-safety.test.d.ts.map +1 -0
  45. package/dist/core/query-safety.test.js +30 -0
  46. package/dist/core/query-safety.test.js.map +1 -0
  47. package/dist/core/schema-types.d.ts +53 -0
  48. package/dist/core/schema-types.d.ts.map +1 -0
  49. package/dist/core/schema-types.js +2 -0
  50. package/dist/core/schema-types.js.map +1 -0
  51. package/dist/core/security/access-control.d.ts +32 -0
  52. package/dist/core/security/access-control.d.ts.map +1 -0
  53. package/dist/core/security/access-control.js +244 -0
  54. package/dist/core/security/access-control.js.map +1 -0
  55. package/dist/core/security/config-loader.d.ts +20 -0
  56. package/dist/core/security/config-loader.d.ts.map +1 -0
  57. package/dist/core/security/config-loader.js +227 -0
  58. package/dist/core/security/config-loader.js.map +1 -0
  59. package/dist/core/security/types.d.ts +64 -0
  60. package/dist/core/security/types.d.ts.map +1 -0
  61. package/dist/core/security/types.js +28 -0
  62. package/dist/core/security/types.js.map +1 -0
  63. package/dist/core/sql-parser.d.ts +23 -0
  64. package/dist/core/sql-parser.d.ts.map +1 -0
  65. package/dist/core/sql-parser.js +460 -0
  66. package/dist/core/sql-parser.js.map +1 -0
  67. package/dist/core/sql-parser.test.d.ts +2 -0
  68. package/dist/core/sql-parser.test.d.ts.map +1 -0
  69. package/dist/core/sql-parser.test.js +21 -0
  70. package/dist/core/sql-parser.test.js.map +1 -0
  71. package/dist/handlers/accessible-schema.d.ts +53 -0
  72. package/dist/handlers/accessible-schema.d.ts.map +1 -0
  73. package/dist/handlers/accessible-schema.js +192 -0
  74. package/dist/handlers/accessible-schema.js.map +1 -0
  75. package/dist/handlers/data.d.ts +17 -0
  76. package/dist/handlers/data.d.ts.map +1 -0
  77. package/dist/handlers/data.js +30 -0
  78. package/dist/handlers/data.js.map +1 -0
  79. package/dist/handlers/relationships.d.ts +14 -0
  80. package/dist/handlers/relationships.d.ts.map +1 -0
  81. package/dist/handlers/relationships.js +77 -0
  82. package/dist/handlers/relationships.js.map +1 -0
  83. package/dist/handlers/schema.d.ts +14 -0
  84. package/dist/handlers/schema.d.ts.map +1 -0
  85. package/dist/handlers/schema.js +104 -0
  86. package/dist/handlers/schema.js.map +1 -0
  87. package/dist/handlers/search.d.ts +14 -0
  88. package/dist/handlers/search.d.ts.map +1 -0
  89. package/dist/handlers/search.js +18 -0
  90. package/dist/handlers/search.js.map +1 -0
  91. package/dist/handlers/validation.d.ts +32 -0
  92. package/dist/handlers/validation.d.ts.map +1 -0
  93. package/dist/handlers/validation.js +116 -0
  94. package/dist/handlers/validation.js.map +1 -0
  95. package/dist/index.d.ts +3 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +294 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/mysql/connection.d.ts +15 -0
  100. package/dist/mysql/connection.d.ts.map +1 -0
  101. package/dist/mysql/connection.js +57 -0
  102. package/dist/mysql/connection.js.map +1 -0
  103. package/dist/mysql/identifiers.d.ts +3 -0
  104. package/dist/mysql/identifiers.d.ts.map +1 -0
  105. package/dist/mysql/identifiers.js +10 -0
  106. package/dist/mysql/identifiers.js.map +1 -0
  107. package/dist/mysql/identifiers.test.d.ts +2 -0
  108. package/dist/mysql/identifiers.test.d.ts.map +1 -0
  109. package/dist/mysql/identifiers.test.js +11 -0
  110. package/dist/mysql/identifiers.test.js.map +1 -0
  111. package/dist/mysql/queries.d.ts +49 -0
  112. package/dist/mysql/queries.d.ts.map +1 -0
  113. package/dist/mysql/queries.js +206 -0
  114. package/dist/mysql/queries.js.map +1 -0
  115. package/docs/clients/claude-code.md +28 -0
  116. package/docs/clients/claude-desktop.md +35 -0
  117. package/docs/clients/codex.md +28 -0
  118. package/docs/clients/cursor.md +26 -0
  119. package/docs/clients/opencode.md +35 -0
  120. package/docs/clients/vscode.md +25 -0
  121. package/package.json +49 -0
  122. package/query-access.example.json +21 -0
  123. package/src/cli.ts +221 -0
  124. package/src/core/cache.ts +41 -0
  125. package/src/core/config.ts +97 -0
  126. package/src/core/database-url.test.ts +28 -0
  127. package/src/core/database-url.ts +47 -0
  128. package/src/core/logger.ts +24 -0
  129. package/src/core/mcp.ts +23 -0
  130. package/src/core/query-safety.test.ts +36 -0
  131. package/src/core/query-safety.ts +63 -0
  132. package/src/core/schema-types.ts +58 -0
  133. package/src/core/security/access-control.ts +321 -0
  134. package/src/core/security/config-loader.ts +315 -0
  135. package/src/core/security/types.ts +114 -0
  136. package/src/core/sql-parser.test.ts +37 -0
  137. package/src/core/sql-parser.ts +572 -0
  138. package/src/handlers/accessible-schema.ts +314 -0
  139. package/src/handlers/data.ts +66 -0
  140. package/src/handlers/relationships.ts +114 -0
  141. package/src/handlers/schema.ts +154 -0
  142. package/src/handlers/search.ts +34 -0
  143. package/src/handlers/validation.ts +165 -0
  144. package/src/index.ts +337 -0
  145. package/src/mysql/connection.ts +68 -0
  146. package/src/mysql/identifiers.test.ts +12 -0
  147. package/src/mysql/identifiers.ts +10 -0
  148. package/src/mysql/queries.ts +285 -0
  149. package/tsconfig.json +24 -0
@@ -0,0 +1,460 @@
1
+ /**
2
+ * SQL Parser Utility for Access Control
3
+ *
4
+ * Uses node-sql-parser to parse SQL and extract:
5
+ * - Tables (including JOINs, subqueries, CTEs)
6
+ * - Columns being selected
7
+ * - SELECT * detection
8
+ * - Alias resolution
9
+ */
10
+ import pkg from "node-sql-parser";
11
+ const { Parser } = pkg;
12
+ import { logger } from "./logger.js";
13
+ const parser = new Parser();
14
+ const PARSER_OPTIONS = { database: "MySQL" };
15
+ /**
16
+ * Parse a SQL query and extract tables, columns, and SELECT * usage
17
+ */
18
+ export function parseQuery(sql, database) {
19
+ const result = {
20
+ tables: [],
21
+ columns: [],
22
+ hasSelectStar: false,
23
+ selectStarTables: [],
24
+ aliases: new Map(),
25
+ };
26
+ try {
27
+ const ast = parser.astify(sql, PARSER_OPTIONS);
28
+ logger.debug(`Parsed SQL AST: ${JSON.stringify(ast, null, 2)}`);
29
+ // Handle both single statement and array of statements
30
+ const statements = Array.isArray(ast) ? ast : [ast];
31
+ for (const stmt of statements) {
32
+ if (stmt && stmt.type === "select") {
33
+ processSelectStatement(stmt, database, database, result);
34
+ }
35
+ }
36
+ }
37
+ catch (error) {
38
+ logger.warn(`SQL parsing failed, falling back to regex: ${error.message}`);
39
+ // Fallback to regex-based parsing for queries the parser can't handle
40
+ return parseQueryWithRegex(sql, database);
41
+ }
42
+ return result;
43
+ }
44
+ /**
45
+ * Process a SELECT statement and extract table/column info
46
+ * @param cteNames - Set of CTE names to skip when processing FROM clause (passed down from parent)
47
+ */
48
+ function processSelectStatement(stmt, database, defaultSchema, result, cteNames = new Set()) {
49
+ // Process CTEs (WITH clause) - collect CTE names first, then process bodies
50
+ if (stmt.with) {
51
+ // First pass: collect all CTE names
52
+ for (const cte of stmt.with) {
53
+ if (cte.name?.value) {
54
+ cteNames.add(cte.name.value.toLowerCase());
55
+ }
56
+ }
57
+ // Second pass: process CTE bodies (real tables inside CTEs still need validation)
58
+ for (const cte of stmt.with) {
59
+ // Fix: CTE body is in cte.stmt.ast, not cte.stmt directly
60
+ if (cte.stmt?.ast) {
61
+ processSelectStatement(cte.stmt.ast, database, defaultSchema, result, cteNames);
62
+ }
63
+ }
64
+ }
65
+ // Process FROM clause (tables) - pass cteNames to skip CTE references
66
+ if (stmt.from) {
67
+ processFromClause(stmt.from, database, defaultSchema, result, cteNames);
68
+ }
69
+ // Process SELECT columns
70
+ if (stmt.columns) {
71
+ processColumns(stmt.columns, database, defaultSchema, result);
72
+ }
73
+ // Process subqueries in WHERE, HAVING, etc.
74
+ if (stmt.where) {
75
+ processExpression(stmt.where, database, defaultSchema, result, cteNames);
76
+ }
77
+ }
78
+ /**
79
+ * Process FROM clause to extract tables
80
+ * @param cteNames - Set of CTE names to skip (they're query-scoped aliases, not real tables)
81
+ */
82
+ function processFromClause(from, database, defaultSchema, result, cteNames = new Set()) {
83
+ for (const item of from) {
84
+ if (!item)
85
+ continue;
86
+ // Handle regular table reference
87
+ if (item.table) {
88
+ // Check if this is a CTE reference - skip adding to tables but track alias
89
+ if (cteNames.has(item.table.toLowerCase())) {
90
+ // CTE reference - register alias pointing to __cte__ marker
91
+ const cteRef = {
92
+ database,
93
+ schema: "__cte__",
94
+ table: item.table,
95
+ alias: item.as?.toLowerCase(),
96
+ };
97
+ result.aliases.set((item.as || item.table).toLowerCase(), cteRef);
98
+ }
99
+ else {
100
+ // Real table reference
101
+ const tableRef = extractTableRef(item, database, defaultSchema);
102
+ result.tables.push(tableRef);
103
+ // Track alias
104
+ if (item.as) {
105
+ result.aliases.set(item.as.toLowerCase(), tableRef);
106
+ }
107
+ }
108
+ }
109
+ // Handle subquery in FROM
110
+ if (item.expr && item.expr.ast) {
111
+ processSelectStatement(item.expr.ast, database, defaultSchema, result, cteNames);
112
+ // Track subquery alias
113
+ if (item.as) {
114
+ // Subquery alias doesn't map to a real table
115
+ result.aliases.set(item.as.toLowerCase(), {
116
+ database,
117
+ schema: "__subquery__",
118
+ table: item.as,
119
+ alias: item.as,
120
+ });
121
+ }
122
+ }
123
+ // Handle JOINs
124
+ if (item.join) {
125
+ // The join target is in item itself after the join keyword
126
+ // Recursively process the joined table
127
+ }
128
+ }
129
+ }
130
+ /**
131
+ * Extract table reference from AST node
132
+ */
133
+ function extractTableRef(item, database, defaultSchema) {
134
+ // node-sql-parser may provide schema as 'db' property
135
+ const schema = item.db || defaultSchema;
136
+ const table = item.table;
137
+ const alias = item.as || undefined;
138
+ return {
139
+ database,
140
+ schema: schema.toLowerCase(),
141
+ table: table,
142
+ alias: alias?.toLowerCase(),
143
+ };
144
+ }
145
+ /**
146
+ * Process SELECT columns
147
+ */
148
+ function processColumns(columns, database, defaultSchema, result) {
149
+ // Handle SELECT *
150
+ if (columns === "*") {
151
+ result.hasSelectStar = true;
152
+ result.selectStarTables.push("*");
153
+ return;
154
+ }
155
+ if (!Array.isArray(columns)) {
156
+ return;
157
+ }
158
+ for (const col of columns) {
159
+ if (!col)
160
+ continue;
161
+ // Handle column expressions
162
+ if (col.expr) {
163
+ processColumnExpression(col.expr, database, defaultSchema, result);
164
+ }
165
+ }
166
+ }
167
+ /**
168
+ * Process a column expression to extract column references
169
+ */
170
+ function processColumnExpression(expr, database, defaultSchema, result) {
171
+ if (!expr)
172
+ return;
173
+ // Handle star expression (SELECT * or table.*)
174
+ // node-sql-parser returns this as type='star' OR type='column_ref' with column='*'
175
+ if (expr.type === "star") {
176
+ result.hasSelectStar = true;
177
+ if (expr.table) {
178
+ result.selectStarTables.push(expr.table);
179
+ }
180
+ else {
181
+ result.selectStarTables.push("*");
182
+ }
183
+ return;
184
+ }
185
+ // Handle column reference - check for SELECT * variant (column_ref with column='*')
186
+ if (expr.type === "column_ref") {
187
+ // Check if this is actually SELECT * or table.*
188
+ if (expr.column === "*") {
189
+ result.hasSelectStar = true;
190
+ if (expr.table) {
191
+ result.selectStarTables.push(expr.table);
192
+ }
193
+ else {
194
+ result.selectStarTables.push("*");
195
+ }
196
+ return;
197
+ }
198
+ const colRef = extractColumnRef(expr, database, defaultSchema, result);
199
+ if (colRef) {
200
+ result.columns.push(colRef);
201
+ }
202
+ return;
203
+ }
204
+ // Handle function calls - extract column references from arguments
205
+ if (expr.type === "function" || expr.type === "aggr_func") {
206
+ if (expr.args) {
207
+ if (expr.args.type === "expr_list") {
208
+ for (const arg of expr.args.value || []) {
209
+ processColumnExpression(arg, database, defaultSchema, result);
210
+ }
211
+ }
212
+ else if (expr.args.expr) {
213
+ processColumnExpression(expr.args.expr, database, defaultSchema, result);
214
+ }
215
+ }
216
+ return;
217
+ }
218
+ // Handle binary expressions (e.g., col1 + col2)
219
+ if (expr.type === "binary_expr") {
220
+ processColumnExpression(expr.left, database, defaultSchema, result);
221
+ processColumnExpression(expr.right, database, defaultSchema, result);
222
+ return;
223
+ }
224
+ // Handle CASE expressions
225
+ if (expr.type === "case") {
226
+ if (expr.args) {
227
+ for (const arg of expr.args) {
228
+ if (arg.cond)
229
+ processColumnExpression(arg.cond, database, defaultSchema, result);
230
+ if (arg.result)
231
+ processColumnExpression(arg.result, database, defaultSchema, result);
232
+ }
233
+ }
234
+ return;
235
+ }
236
+ // Handle subqueries in SELECT
237
+ if (expr.type === "select" || expr.ast) {
238
+ const subStmt = expr.ast || expr;
239
+ processSelectStatement(subStmt, database, defaultSchema, result);
240
+ }
241
+ }
242
+ /**
243
+ * Extract column reference from AST node
244
+ */
245
+ function extractColumnRef(expr, database, defaultSchema, result) {
246
+ const column = expr.column;
247
+ const tableOrAlias = expr.table;
248
+ if (!column)
249
+ return null;
250
+ // If table/alias is specified, resolve it
251
+ if (tableOrAlias) {
252
+ const aliasLower = tableOrAlias.toLowerCase();
253
+ const resolved = result.aliases.get(aliasLower);
254
+ if (resolved) {
255
+ // Skip subquery columns - we can't validate them against config
256
+ if (resolved.schema === "__subquery__") {
257
+ return null;
258
+ }
259
+ // Skip CTE columns - they're query-scoped aliases, real tables in CTE body already validated
260
+ if (resolved.schema === "__cte__") {
261
+ return null;
262
+ }
263
+ return {
264
+ database: resolved.database,
265
+ schema: resolved.schema,
266
+ table: resolved.table,
267
+ column: column,
268
+ };
269
+ }
270
+ // Table name used directly (not alias)
271
+ const tableRef = result.tables.find((t) => t.table.toLowerCase() === aliasLower ||
272
+ t.alias?.toLowerCase() === aliasLower);
273
+ if (tableRef) {
274
+ return {
275
+ database: tableRef.database,
276
+ schema: tableRef.schema,
277
+ table: tableRef.table,
278
+ column: column,
279
+ };
280
+ }
281
+ // Unknown table reference - use as-is
282
+ return {
283
+ database,
284
+ schema: defaultSchema,
285
+ table: tableOrAlias,
286
+ column: column,
287
+ };
288
+ }
289
+ // No table specified - try to infer from single table query
290
+ if (result.tables.length === 1) {
291
+ const tableRef = result.tables[0];
292
+ return {
293
+ database: tableRef.database,
294
+ schema: tableRef.schema,
295
+ table: tableRef.table,
296
+ column: column,
297
+ };
298
+ }
299
+ // Ambiguous - column without table in multi-table query
300
+ // Return with unknown table marker
301
+ return {
302
+ database,
303
+ schema: defaultSchema,
304
+ table: "__unknown__",
305
+ column: column,
306
+ };
307
+ }
308
+ /**
309
+ * Process expressions (WHERE, HAVING, etc.) for subqueries
310
+ * @param cteNames - Set of CTE names to pass to nested SELECT statements
311
+ */
312
+ function processExpression(expr, database, defaultSchema, result, cteNames = new Set()) {
313
+ if (!expr)
314
+ return;
315
+ // Handle subqueries
316
+ if (expr.type === "select" || expr.ast) {
317
+ const subStmt = expr.ast || expr;
318
+ processSelectStatement(subStmt, database, defaultSchema, result, cteNames);
319
+ return;
320
+ }
321
+ // Handle binary expressions
322
+ if (expr.left)
323
+ processExpression(expr.left, database, defaultSchema, result, cteNames);
324
+ if (expr.right)
325
+ processExpression(expr.right, database, defaultSchema, result, cteNames);
326
+ // Handle IN clause with subquery
327
+ if (expr.value && Array.isArray(expr.value)) {
328
+ for (const v of expr.value) {
329
+ processExpression(v, database, defaultSchema, result, cteNames);
330
+ }
331
+ }
332
+ }
333
+ /**
334
+ * Fallback regex-based parsing for queries the AST parser can't handle
335
+ */
336
+ function parseQueryWithRegex(sql, database) {
337
+ const result = {
338
+ tables: [],
339
+ columns: [],
340
+ hasSelectStar: false,
341
+ selectStarTables: [],
342
+ aliases: new Map(),
343
+ };
344
+ const normalizedSql = sql.replace(/\s+/g, " ").trim();
345
+ // Extract CTE names from WITH clause before processing FROM/JOIN
346
+ // Pattern matches: WITH name AS (...), name2 AS (...)
347
+ // Also handles RECURSIVE: WITH RECURSIVE name AS (...)
348
+ const cteNames = new Set();
349
+ const ctePattern = /(?:WITH\s+(?:RECURSIVE\s+)?|,\s*)(`?[\w]+`?)\s+AS\s*\(/gi;
350
+ let match;
351
+ while ((match = ctePattern.exec(normalizedSql)) !== null) {
352
+ const cteName = match[1].replace(/`/g, "").toLowerCase();
353
+ cteNames.add(cteName);
354
+ logger.debug(`Regex parser found CTE name: ${cteName}`);
355
+ }
356
+ // Detect SELECT *
357
+ const selectStarPattern = /SELECT\s+(DISTINCT\s+)?(\*|[\w.]+\.\*)/gi;
358
+ while ((match = selectStarPattern.exec(normalizedSql)) !== null) {
359
+ result.hasSelectStar = true;
360
+ const starExpr = match[2];
361
+ if (starExpr === "*") {
362
+ result.selectStarTables.push("*");
363
+ }
364
+ else {
365
+ // table.* format
366
+ const tablePart = starExpr.replace(".*", "");
367
+ result.selectStarTables.push(tablePart);
368
+ }
369
+ }
370
+ // Helper function to add a table reference (skips CTEs)
371
+ const addTableRef = (tableName, alias) => {
372
+ // Handle schema.table format
373
+ const tableParts = tableName.split(".");
374
+ const table = tableParts.length > 1 ? tableParts[1] : tableParts[0];
375
+ const schema = tableParts.length > 1 ? tableParts[0] : database;
376
+ // Skip if this is a CTE name
377
+ if (cteNames.has(table.toLowerCase())) {
378
+ // Register CTE alias but don't add to tables
379
+ const cteRef = {
380
+ database,
381
+ schema: "__cte__",
382
+ table: table,
383
+ alias: alias?.toLowerCase(),
384
+ };
385
+ result.aliases.set((alias || table).toLowerCase(), cteRef);
386
+ logger.debug(`Regex parser skipping CTE reference: ${table}`);
387
+ return;
388
+ }
389
+ const tableRef = {
390
+ database,
391
+ schema: schema.toLowerCase(),
392
+ table: table,
393
+ alias: alias?.toLowerCase(),
394
+ };
395
+ result.tables.push(tableRef);
396
+ if (alias) {
397
+ result.aliases.set(alias.toLowerCase(), tableRef);
398
+ }
399
+ };
400
+ // Extract tables from FROM clause (basic pattern)
401
+ const fromPattern = /FROM\s+(`?[\w.]+`?(?:\s+(?:AS\s+)?[\w]+)?)/gi;
402
+ while ((match = fromPattern.exec(normalizedSql)) !== null) {
403
+ const tableExpr = match[1].trim();
404
+ const parts = tableExpr.split(/\s+/);
405
+ const tableName = parts[0].replace(/`/g, "");
406
+ const alias = parts.length > 1 ? parts[parts.length - 1] : undefined;
407
+ addTableRef(tableName, alias);
408
+ }
409
+ // Extract tables from JOIN clauses
410
+ const joinPattern = /JOIN\s+(`?[\w.]+`?(?:\s+(?:AS\s+)?[\w]+)?)/gi;
411
+ while ((match = joinPattern.exec(normalizedSql)) !== null) {
412
+ const tableExpr = match[1].trim();
413
+ const parts = tableExpr.split(/\s+/);
414
+ const tableName = parts[0].replace(/`/g, "");
415
+ const alias = parts.length > 1 ? parts[parts.length - 1] : undefined;
416
+ addTableRef(tableName, alias);
417
+ }
418
+ logger.debug(`Regex parsing result: ${JSON.stringify(result, replacer, 2)}`);
419
+ return result;
420
+ }
421
+ /**
422
+ * JSON replacer to handle Map serialization
423
+ */
424
+ function replacer(_key, value) {
425
+ if (value instanceof Map) {
426
+ return Object.fromEntries(value);
427
+ }
428
+ return value;
429
+ }
430
+ /**
431
+ * Check if a query contains SELECT * or table.*
432
+ */
433
+ export function hasSelectStar(sql) {
434
+ const pattern = /SELECT\s+(DISTINCT\s+)?(\*|[\w.]+\.\*)/i;
435
+ return pattern.test(sql);
436
+ }
437
+ /**
438
+ * Extract table names from a simple SQL query (utility function)
439
+ */
440
+ export function extractTableNames(sql) {
441
+ const tables = [];
442
+ const normalizedSql = sql.replace(/\s+/g, " ").trim();
443
+ // FROM clause
444
+ const fromMatch = normalizedSql.match(/FROM\s+(`?[\w.]+`?)/i);
445
+ if (fromMatch) {
446
+ const tableName = fromMatch[1].replace(/`/g, "");
447
+ const parts = tableName.split(".");
448
+ tables.push(parts[parts.length - 1]);
449
+ }
450
+ // JOIN clauses
451
+ const joinPattern = /JOIN\s+(`?[\w.]+`?)/gi;
452
+ let match;
453
+ while ((match = joinPattern.exec(normalizedSql)) !== null) {
454
+ const tableName = match[1].replace(/`/g, "");
455
+ const parts = tableName.split(".");
456
+ tables.push(parts[parts.length - 1]);
457
+ }
458
+ return tables;
459
+ }
460
+ //# sourceMappingURL=sql-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-parser.js","sourceRoot":"","sources":["../../src/core/sql-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sql-parser.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-parser.test.d.ts","sourceRoot":"","sources":["../../src/core/sql-parser.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+ import { parseQuery } from './sql-parser.js';
4
+ test('parseQuery extracts MySQL table aliases and columns', () => {
5
+ const parsed = parseQuery('SELECT c.id, c.email, o.total FROM customers c JOIN orders o ON o.customer_id = c.id', 'app_db');
6
+ assert.equal(parsed.hasSelectStar, false);
7
+ assert.deepEqual(parsed.tables.map((table) => table.table), ['customers', 'orders']);
8
+ assert.deepEqual(parsed.columns.map((column) => `${column.table}.${column.column}`), ['customers.id', 'customers.email', 'orders.total']);
9
+ });
10
+ test('parseQuery detects SELECT star', () => {
11
+ const parsed = parseQuery('SELECT * FROM customers', 'app_db');
12
+ assert.equal(parsed.hasSelectStar, true);
13
+ assert.deepEqual(parsed.selectStarTables, ['*']);
14
+ });
15
+ test('parseQuery handles CTE source tables but skips CTE references', () => {
16
+ const parsed = parseQuery('WITH recent_orders AS (SELECT id, customer_id FROM orders) SELECT c.email FROM customers c JOIN recent_orders r ON r.customer_id = c.id', 'app_db');
17
+ assert(parsed.tables.some((table) => table.table === 'orders'));
18
+ assert(parsed.tables.some((table) => table.table === 'customers'));
19
+ assert(!parsed.tables.some((table) => table.table === 'recent_orders'));
20
+ });
21
+ //# sourceMappingURL=sql-parser.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-parser.test.js","sourceRoot":"","sources":["../../src/core/sql-parser.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,IAAI,CAAC,qDAAqD,EAAE,GAAG,EAAE;IAC/D,MAAM,MAAM,GAAG,UAAU,CACvB,sFAAsF,EACtF,QAAQ,CACT,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAC1C,MAAM,CAAC,SAAS,CACd,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EACzC,CAAC,WAAW,EAAE,QAAQ,CAAC,CACxB,CAAC;IACF,MAAM,CAAC,SAAS,CACd,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,EAClE,CAAC,cAAc,EAAE,iBAAiB,EAAE,cAAc,CAAC,CACpD,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,yBAAyB,EAAE,QAAQ,CAAC,CAAC;IAC/D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+DAA+D,EAAE,GAAG,EAAE;IACzE,MAAM,MAAM,GAAG,UAAU,CACvB,yIAAyI,EACzI,QAAQ,CACT,CAAC;IAEF,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC;IAChE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC;IACnE,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,eAAe,CAAC,CAAC,CAAC;AAC1E,CAAC,CAAC,CAAC"}
@@ -0,0 +1,53 @@
1
+ export interface AccessibleColumn {
2
+ name: string;
3
+ dataType: string;
4
+ nullable: boolean;
5
+ isIdentity: boolean;
6
+ isPrimaryKey: boolean;
7
+ isForeignKey: boolean;
8
+ description?: string | null;
9
+ }
10
+ export interface AccessibleTable {
11
+ schema: string;
12
+ name: string;
13
+ type: 'TABLE' | 'VIEW';
14
+ columnAccessMode?: 'inclusion' | 'exclusion';
15
+ accessibleColumns: AccessibleColumn[];
16
+ blockedColumns?: string[];
17
+ allowedColumnsList?: string[];
18
+ }
19
+ export interface AccessibleSchemaResult {
20
+ database: string;
21
+ requireExplicitColumns: boolean;
22
+ configuredSchemas: string[];
23
+ tables: AccessibleTable[];
24
+ notes?: string[];
25
+ }
26
+ export interface AccessibleColumnInfo extends AccessibleColumn {
27
+ isAccessible: boolean;
28
+ accessDeniedReason?: string;
29
+ }
30
+ export interface AccessibleTableInfo {
31
+ database: string;
32
+ schema: string;
33
+ table: string;
34
+ type: 'TABLE' | 'VIEW';
35
+ isAccessible: boolean;
36
+ accessDeniedReason?: string;
37
+ columnAccessMode?: 'inclusion' | 'exclusion';
38
+ columns?: AccessibleColumnInfo[];
39
+ indexes?: unknown[];
40
+ foreignKeys?: unknown[];
41
+ accessibleColumnCount?: number;
42
+ totalColumnCount?: number;
43
+ }
44
+ export declare function getAccessibleSchema(args: {
45
+ database?: string;
46
+ schema?: string;
47
+ }): Promise<AccessibleSchemaResult>;
48
+ export declare function getAccessibleTableInfo(args: {
49
+ database?: string;
50
+ table: string;
51
+ schema?: string;
52
+ }): Promise<AccessibleTableInfo>;
53
+ //# sourceMappingURL=accessible-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessible-schema.d.ts","sourceRoot":"","sources":["../../src/handlers/accessible-schema.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;IAC7C,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB,EAAE,OAAO,CAAC;IAChC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC5D,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;IAC7C,OAAO,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA8HD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAuDlC;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA8D/B"}