@calebmabry/postgres-mcp-server 0.1.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 (63) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +223 -0
  3. package/dist/config.d.ts +44 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +53 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/db.d.ts +46 -0
  8. package/dist/db.d.ts.map +1 -0
  9. package/dist/db.js +140 -0
  10. package/dist/db.js.map +1 -0
  11. package/dist/http-server.d.ts +3 -0
  12. package/dist/http-server.d.ts.map +1 -0
  13. package/dist/http-server.js +184 -0
  14. package/dist/http-server.js.map +1 -0
  15. package/dist/index.d.ts +3 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +33 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/logger.d.ts +8 -0
  20. package/dist/logger.d.ts.map +1 -0
  21. package/dist/logger.js +85 -0
  22. package/dist/logger.js.map +1 -0
  23. package/dist/register-tools.d.ts +6 -0
  24. package/dist/register-tools.d.ts.map +1 -0
  25. package/dist/register-tools.js +83 -0
  26. package/dist/register-tools.js.map +1 -0
  27. package/dist/tools/describe.d.ts +31 -0
  28. package/dist/tools/describe.d.ts.map +1 -0
  29. package/dist/tools/describe.js +61 -0
  30. package/dist/tools/describe.js.map +1 -0
  31. package/dist/tools/functions.d.ts +20 -0
  32. package/dist/tools/functions.d.ts.map +1 -0
  33. package/dist/tools/functions.js +65 -0
  34. package/dist/tools/functions.js.map +1 -0
  35. package/dist/tools/indexes.d.ts +17 -0
  36. package/dist/tools/indexes.d.ts.map +1 -0
  37. package/dist/tools/indexes.js +82 -0
  38. package/dist/tools/indexes.js.map +1 -0
  39. package/dist/tools/list.d.ts +22 -0
  40. package/dist/tools/list.d.ts.map +1 -0
  41. package/dist/tools/list.js +64 -0
  42. package/dist/tools/list.js.map +1 -0
  43. package/dist/tools/performance.d.ts +26 -0
  44. package/dist/tools/performance.d.ts.map +1 -0
  45. package/dist/tools/performance.js +125 -0
  46. package/dist/tools/performance.js.map +1 -0
  47. package/dist/tools/query.d.ts +6 -0
  48. package/dist/tools/query.d.ts.map +1 -0
  49. package/dist/tools/query.js +318 -0
  50. package/dist/tools/query.js.map +1 -0
  51. package/dist/tools/schemas.d.ts +10 -0
  52. package/dist/tools/schemas.d.ts.map +1 -0
  53. package/dist/tools/schemas.js +51 -0
  54. package/dist/tools/schemas.js.map +1 -0
  55. package/dist/validation.d.ts +159 -0
  56. package/dist/validation.d.ts.map +1 -0
  57. package/dist/validation.js +90 -0
  58. package/dist/validation.js.map +1 -0
  59. package/dist/version.d.ts +3 -0
  60. package/dist/version.d.ts.map +1 -0
  61. package/dist/version.js +11 -0
  62. package/dist/version.js.map +1 -0
  63. package/package.json +78 -0
@@ -0,0 +1,318 @@
1
+ import { getPool } from "../db.js";
2
+ import { config } from "../config.js";
3
+ import { QueryInputSchema, validateInput, } from "../validation.js";
4
+ import NodeSQL from "node-sql-parser/build/postgresql.js";
5
+ export const MAX_PAGE_SIZE = config.query.maxPageSize;
6
+ export const DEFAULT_PAGE_SIZE = config.query.defaultPageSize;
7
+ // Set to 'false' to disable automatic LIMIT application
8
+ const AUTO_LIMIT = config.query.autoLimit;
9
+ // Maximum payload size in bytes (default 5MB)
10
+ export const MAX_PAYLOAD_SIZE = config.query.maxPayloadSize;
11
+ const sqlParser = new NodeSQL.Parser();
12
+ function isReadOnlyMode() {
13
+ // Check environment variable directly to support test configuration changes
14
+ return process.env.READ_ONLY !== "false";
15
+ }
16
+ // Dangerous operations that are never allowed
17
+ const DANGEROUS_OPERATIONS = [
18
+ "DROP",
19
+ "CREATE",
20
+ "ALTER",
21
+ "TRUNCATE",
22
+ "GRANT",
23
+ "REVOKE",
24
+ "VACUUM",
25
+ "ANALYZE",
26
+ "CLUSTER",
27
+ "REINDEX",
28
+ "COPY",
29
+ "BACKUP",
30
+ "RESTORE",
31
+ "ATTACH",
32
+ "DETACH",
33
+ "PRAGMA",
34
+ ];
35
+ function validateSqlSafety(sqlString) {
36
+ if (!sqlString || typeof sqlString !== "string") {
37
+ return {
38
+ isValid: false,
39
+ error: "SQL query is required and must be a string",
40
+ };
41
+ }
42
+ const trimmedSql = sqlString.trim();
43
+ if (!trimmedSql) {
44
+ return { isValid: false, error: "SQL query cannot be empty" };
45
+ }
46
+ // Check for dangerous operations BEFORE parsing (since parser may not support them)
47
+ const upperSql = trimmedSql.toUpperCase();
48
+ const sqlWords = upperSql.split(/\s+/);
49
+ const firstWord = sqlWords[0];
50
+ if (DANGEROUS_OPERATIONS.includes(firstWord)) {
51
+ return {
52
+ isValid: false,
53
+ error: `Dangerous operation '${firstWord}' is not allowed`,
54
+ };
55
+ }
56
+ // Handle EXPLAIN queries - they're read-only and don't need parsing
57
+ if (firstWord === 'EXPLAIN') {
58
+ // EXPLAIN is allowed in both read-only and write modes
59
+ return { isValid: true };
60
+ }
61
+ // Handle MERGE and UPSERT - not allowed in read-only mode
62
+ if (firstWord === 'MERGE' || firstWord === 'UPSERT') {
63
+ if (isReadOnlyMode()) {
64
+ return {
65
+ isValid: false,
66
+ error: "Only SELECT, WITH, and EXPLAIN queries are allowed in read-only mode",
67
+ };
68
+ }
69
+ // These operations require WHERE clauses in write mode, but parser can't handle them
70
+ // For now, we'll reject them since we can't safely validate them
71
+ return {
72
+ isValid: false,
73
+ error: "MERGE and UPSERT operations are not currently supported",
74
+ };
75
+ }
76
+ // Parse SQL to understand its structure
77
+ let ast;
78
+ try {
79
+ ast = sqlParser.astify(trimmedSql);
80
+ }
81
+ catch (parseError) {
82
+ return {
83
+ isValid: false,
84
+ error: "Invalid SQL syntax - unable to parse query",
85
+ };
86
+ }
87
+ // Convert to array if single statement
88
+ const statements = Array.isArray(ast) ? ast : [ast];
89
+ // Validate each statement
90
+ for (const statement of statements) {
91
+ const statementType = statement.type?.toUpperCase();
92
+ // Check for dangerous operations
93
+ if (DANGEROUS_OPERATIONS.includes(statementType)) {
94
+ return {
95
+ isValid: false,
96
+ error: `Dangerous operation '${statementType}' is not allowed`,
97
+ };
98
+ }
99
+ // In read-only mode, only allow SELECT, WITH (CTE), and EXPLAIN
100
+ if (isReadOnlyMode()) {
101
+ const allowedTypes = ["SELECT", "WITH", "EXPLAIN"];
102
+ if (!allowedTypes.includes(statementType)) {
103
+ return {
104
+ isValid: false,
105
+ error: "Only SELECT, WITH, and EXPLAIN queries are allowed in read-only mode",
106
+ };
107
+ }
108
+ }
109
+ else {
110
+ // Even in write mode, validate UPDATE and DELETE have WHERE clauses
111
+ if (statementType === "UPDATE" || statementType === "DELETE") {
112
+ // Type guard to check if statement has a where property
113
+ if (!("where" in statement) || !statement.where) {
114
+ return {
115
+ isValid: false,
116
+ error: `${statementType} operations must include a WHERE clause`,
117
+ };
118
+ }
119
+ // Check for dangerous WHERE patterns that effectively disable the clause
120
+ // These are patterns like WHERE 1=1, WHERE TRUE, WHERE 1, WHERE '1'='1'
121
+ const where = statement.where;
122
+ // Check for WHERE TRUE
123
+ if (where && where.type === 'bool' && where.value === true) {
124
+ return {
125
+ isValid: false,
126
+ error: `${statementType} operations cannot use trivial WHERE clauses like WHERE 1=1 or WHERE TRUE`,
127
+ };
128
+ }
129
+ // Check for WHERE 1 (just a constant value)
130
+ if (where && where.type === 'number') {
131
+ return {
132
+ isValid: false,
133
+ error: `${statementType} operations cannot use trivial WHERE clauses like WHERE 1=1 or WHERE TRUE`,
134
+ };
135
+ }
136
+ // Check for WHERE 1=1 pattern (binary expression comparing same constants)
137
+ if (where && where.type === 'binary_expr' && where.operator === '=') {
138
+ const left = where.left;
139
+ const right = where.right;
140
+ // Both sides are the same constant number
141
+ if (left && right && left.type === 'number' && right.type === 'number' && left.value === right.value) {
142
+ return {
143
+ isValid: false,
144
+ error: `${statementType} operations cannot use trivial WHERE clauses like WHERE 1=1 or WHERE TRUE`,
145
+ };
146
+ }
147
+ // Both sides are the same string literal
148
+ if (left && right && left.type === 'single_quote_string' && right.type === 'single_quote_string' && left.value === right.value) {
149
+ return {
150
+ isValid: false,
151
+ error: `${statementType} operations cannot use trivial WHERE clauses like WHERE 1=1 or WHERE TRUE`,
152
+ };
153
+ }
154
+ // Both sides are the same identifier (double-quoted or column reference)
155
+ // In PostgreSQL, "1"="1" would be comparing column "1" to column "1"
156
+ if (left && right && left.type === 'column_ref' && right.type === 'column_ref') {
157
+ // Extract values from nested structure
158
+ const leftExpr = left.column?.expr || left.column;
159
+ const rightExpr = right.column?.expr || right.column;
160
+ // Check if both are double_quote_string with same value
161
+ if (leftExpr && rightExpr &&
162
+ leftExpr.type === 'double_quote_string' &&
163
+ rightExpr.type === 'double_quote_string' &&
164
+ leftExpr.value === rightExpr.value) {
165
+ return {
166
+ isValid: false,
167
+ error: `${statementType} operations cannot use trivial WHERE clauses like WHERE 1=1 or WHERE TRUE`,
168
+ };
169
+ }
170
+ // Check if both are the same column name
171
+ if (typeof leftExpr === 'string' && typeof rightExpr === 'string' && leftExpr === rightExpr) {
172
+ return {
173
+ isValid: false,
174
+ error: `${statementType} operations cannot use trivial WHERE clauses like WHERE 1=1 or WHERE TRUE`,
175
+ };
176
+ }
177
+ }
178
+ }
179
+ }
180
+ }
181
+ }
182
+ return { isValid: true };
183
+ }
184
+ function isReadOnlyQuery(sqlString) {
185
+ const upperSql = sqlString.trim().toUpperCase();
186
+ return (upperSql.startsWith("SELECT") ||
187
+ upperSql.startsWith("WITH") ||
188
+ upperSql.startsWith("EXPLAIN"));
189
+ }
190
+ function isSingleRowAggregate(upperSql) {
191
+ // Check if it's an aggregate query that should return a single row
192
+ const hasAggregates = upperSql.includes("COUNT(") ||
193
+ upperSql.includes("SUM(") ||
194
+ upperSql.includes("AVG(") ||
195
+ upperSql.includes("MAX(") ||
196
+ upperSql.includes("MIN(");
197
+ const hasGroupBy = upperSql.includes("GROUP BY");
198
+ // Single row aggregate: has aggregates but no GROUP BY
199
+ return hasAggregates && !hasGroupBy;
200
+ }
201
+ function applyPagination(sqlString, pageSize, offset) {
202
+ // Strip trailing semicolons to avoid syntax errors when adding LIMIT/OFFSET
203
+ const cleanedSql = sqlString.trim().replace(/;+$/, '');
204
+ const upperSql = cleanedSql.toUpperCase();
205
+ // Don't modify if already has LIMIT or OFFSET
206
+ if (upperSql.includes("LIMIT") || upperSql.includes("OFFSET")) {
207
+ return {
208
+ sql: cleanedSql,
209
+ actualPageSize: pageSize || DEFAULT_PAGE_SIZE,
210
+ actualOffset: offset || 0,
211
+ };
212
+ }
213
+ // Use client-specified pageSize or default, capped at MAX_PAGE_SIZE
214
+ const actualPageSize = Math.min(pageSize || DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE);
215
+ const actualOffset = offset || 0;
216
+ // Don't add LIMIT to single-row aggregates
217
+ if (isSingleRowAggregate(upperSql)) {
218
+ return { sql: cleanedSql, actualPageSize, actualOffset };
219
+ }
220
+ // If AUTO_LIMIT is disabled and no pageSize was explicitly provided, don't add LIMIT
221
+ if (!AUTO_LIMIT && !pageSize) {
222
+ return { sql: cleanedSql, actualPageSize, actualOffset };
223
+ }
224
+ let paginatedSql = `${cleanedSql} LIMIT ${actualPageSize}`;
225
+ if (actualOffset > 0) {
226
+ paginatedSql += ` OFFSET ${actualOffset}`;
227
+ }
228
+ return { sql: paginatedSql, actualPageSize, actualOffset };
229
+ }
230
+ function validateParameters(parameters) {
231
+ for (const param of parameters) {
232
+ if (param !== null &&
233
+ typeof param !== "string" &&
234
+ typeof param !== "number" &&
235
+ typeof param !== "boolean") {
236
+ return {
237
+ error: "Invalid parameter type - only string, number, boolean, and null are allowed",
238
+ };
239
+ }
240
+ if (typeof param === "number" && !Number.isFinite(param)) {
241
+ return { error: "Invalid numeric parameter - must be finite number" };
242
+ }
243
+ }
244
+ return null;
245
+ }
246
+ export async function queryTool(input) {
247
+ try {
248
+ const inputValidation = validateInput(QueryInputSchema, input);
249
+ if (!inputValidation.success) {
250
+ return { error: `Input validation failed: ${inputValidation.error}` };
251
+ }
252
+ const validatedInput = inputValidation.data;
253
+ const sqlValidation = validateSqlSafety(validatedInput.sql);
254
+ if (!sqlValidation.isValid) {
255
+ return { error: sqlValidation.error };
256
+ }
257
+ const pool = getPool();
258
+ const trimmedSql = validatedInput.sql.trim();
259
+ const params = validatedInput.parameters ?? [];
260
+ if (params.length > 0) {
261
+ const paramError = validateParameters(params);
262
+ if (paramError)
263
+ return paramError;
264
+ }
265
+ if (isReadOnlyQuery(trimmedSql)) {
266
+ const { sql: paginatedSql, actualPageSize, actualOffset, } = applyPagination(trimmedSql, validatedInput.pageSize, validatedInput.offset);
267
+ // Execute the query
268
+ const result = params.length > 0
269
+ ? await pool.query(paginatedSql, params)
270
+ : await pool.query(paginatedSql);
271
+ // Check payload size after query execution
272
+ const payloadJson = JSON.stringify(result.rows);
273
+ const payloadSize = Buffer.byteLength(payloadJson, 'utf8');
274
+ if (payloadSize > MAX_PAYLOAD_SIZE) {
275
+ const sizeMB = (payloadSize / (1024 * 1024)).toFixed(2);
276
+ const maxMB = (MAX_PAYLOAD_SIZE / (1024 * 1024)).toFixed(2);
277
+ return {
278
+ error: `Query result payload (${sizeMB}MB) exceeds maximum allowed size (${maxMB}MB). Please reduce pageSize or add more specific WHERE conditions to limit results.`,
279
+ };
280
+ }
281
+ // Determine if there are more rows available
282
+ const hasMore = result.rows.length === actualPageSize;
283
+ return {
284
+ rows: result.rows,
285
+ rowCount: result.rows.length,
286
+ pagination: {
287
+ hasMore,
288
+ pageSize: actualPageSize,
289
+ offset: actualOffset,
290
+ },
291
+ };
292
+ }
293
+ else {
294
+ // For write operations (when not in read-only mode)
295
+ const cleanedSql = trimmedSql.replace(/;+$/, '');
296
+ const result = params.length > 0
297
+ ? await pool.query(cleanedSql, params)
298
+ : await pool.query(cleanedSql);
299
+ return {
300
+ rowCount: result.rowCount ?? 0,
301
+ };
302
+ }
303
+ }
304
+ catch (error) {
305
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
306
+ // Extract PostgreSQL-specific error details if available
307
+ const pgError = error;
308
+ const errorCode = pgError?.code || "UNKNOWN";
309
+ const hint = pgError?.hint;
310
+ const sanitizedError = errorMessage.replace(/\s+/g, " ").trim();
311
+ return {
312
+ error: sanitizedError,
313
+ code: errorCode,
314
+ hint: hint,
315
+ };
316
+ }
317
+ }
318
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/tools/query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface SchemaInfo {
2
+ schema_name: string;
3
+ schema_owner: string;
4
+ }
5
+ export interface ListSchemasOutput {
6
+ schemas?: SchemaInfo[];
7
+ error?: string;
8
+ }
9
+ export declare function listSchemasTool(input: unknown): Promise<ListSchemasOutput>;
10
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/tools/schemas.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,iBAAiB,CAAC,CAiD5B"}
@@ -0,0 +1,51 @@
1
+ import { getDb } from "../db.js";
2
+ import { sql } from "kysely";
3
+ import { ListSchemasInputSchema, validateInput } from "../validation.js";
4
+ export async function listSchemasTool(input) {
5
+ try {
6
+ const validation = validateInput(ListSchemasInputSchema, input);
7
+ if (!validation.success) {
8
+ return { error: `Input validation failed: ${validation.error}` };
9
+ }
10
+ const validatedInput = validation.data;
11
+ const db = getDb();
12
+ const includeSystem = validatedInput.includeSystemSchemas || false;
13
+ let query = sql `
14
+ SELECT
15
+ schema_name,
16
+ schema_owner
17
+ FROM information_schema.schemata
18
+ `;
19
+ if (!includeSystem) {
20
+ query = sql `
21
+ SELECT
22
+ schema_name,
23
+ schema_owner
24
+ FROM information_schema.schemata
25
+ WHERE schema_name NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
26
+ AND schema_name NOT LIKE 'pg_temp_%'
27
+ AND schema_name NOT LIKE 'pg_toast_temp_%'
28
+ ORDER BY schema_name
29
+ `;
30
+ }
31
+ else {
32
+ query = sql `
33
+ SELECT
34
+ schema_name,
35
+ schema_owner
36
+ FROM information_schema.schemata
37
+ ORDER BY schema_name
38
+ `;
39
+ }
40
+ const result = await query.execute(db);
41
+ return {
42
+ schemas: result.rows,
43
+ };
44
+ }
45
+ catch (error) {
46
+ return {
47
+ error: error instanceof Error ? error.message : "Unknown error occurred",
48
+ };
49
+ }
50
+ }
51
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/tools/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAYzE,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAc;IAEd,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,aAAa,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;QAChE,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO,EAAE,KAAK,EAAE,4BAA4B,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC;QACnE,CAAC;QAED,MAAM,cAAc,GAAG,UAAU,CAAC,IAAI,CAAC;QACvC,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;QACnB,MAAM,aAAa,GAAG,cAAc,CAAC,oBAAoB,IAAI,KAAK,CAAC;QAEnE,IAAI,KAAK,GAAG,GAAG,CAAY;;;;;KAK1B,CAAC;QAEF,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,KAAK,GAAG,GAAG,CAAY;;;;;;;;;OAStB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,GAAG,CAAY;;;;;;OAMtB,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAEvC,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,IAAI;SACrB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,159 @@
1
+ import { z } from 'zod';
2
+ export declare const QueryInputSchema: z.ZodObject<{
3
+ sql: z.ZodString;
4
+ parameters: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>, "many">>;
5
+ pageSize: z.ZodOptional<z.ZodNumber>;
6
+ offset: z.ZodOptional<z.ZodNumber>;
7
+ }, "strip", z.ZodTypeAny, {
8
+ sql: string;
9
+ parameters?: (string | number | boolean | null)[] | undefined;
10
+ pageSize?: number | undefined;
11
+ offset?: number | undefined;
12
+ }, {
13
+ sql: string;
14
+ parameters?: (string | number | boolean | null)[] | undefined;
15
+ pageSize?: number | undefined;
16
+ offset?: number | undefined;
17
+ }>;
18
+ export declare const QueryOutputSchema: z.ZodObject<{
19
+ rows: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodAny>, "many">>;
20
+ rowCount: z.ZodOptional<z.ZodNumber>;
21
+ error: z.ZodOptional<z.ZodString>;
22
+ code: z.ZodOptional<z.ZodString>;
23
+ hint: z.ZodOptional<z.ZodString>;
24
+ pagination: z.ZodOptional<z.ZodObject<{
25
+ hasMore: z.ZodBoolean;
26
+ pageSize: z.ZodNumber;
27
+ offset: z.ZodNumber;
28
+ totalRows: z.ZodOptional<z.ZodNumber>;
29
+ }, "strip", z.ZodTypeAny, {
30
+ pageSize: number;
31
+ offset: number;
32
+ hasMore: boolean;
33
+ totalRows?: number | undefined;
34
+ }, {
35
+ pageSize: number;
36
+ offset: number;
37
+ hasMore: boolean;
38
+ totalRows?: number | undefined;
39
+ }>>;
40
+ }, "strip", z.ZodTypeAny, {
41
+ error?: string | undefined;
42
+ code?: string | undefined;
43
+ rows?: Record<string, any>[] | undefined;
44
+ rowCount?: number | undefined;
45
+ hint?: string | undefined;
46
+ pagination?: {
47
+ pageSize: number;
48
+ offset: number;
49
+ hasMore: boolean;
50
+ totalRows?: number | undefined;
51
+ } | undefined;
52
+ }, {
53
+ error?: string | undefined;
54
+ code?: string | undefined;
55
+ rows?: Record<string, any>[] | undefined;
56
+ rowCount?: number | undefined;
57
+ hint?: string | undefined;
58
+ pagination?: {
59
+ pageSize: number;
60
+ offset: number;
61
+ hasMore: boolean;
62
+ totalRows?: number | undefined;
63
+ } | undefined;
64
+ }>;
65
+ export declare const DescribeTableInputSchema: z.ZodObject<{
66
+ schema: z.ZodString;
67
+ table: z.ZodString;
68
+ }, "strip", z.ZodTypeAny, {
69
+ schema: string;
70
+ table: string;
71
+ }, {
72
+ schema: string;
73
+ table: string;
74
+ }>;
75
+ export declare const ListTablesInputSchema: z.ZodObject<{
76
+ schema: z.ZodOptional<z.ZodString>;
77
+ }, "strip", z.ZodTypeAny, {
78
+ schema?: string | undefined;
79
+ }, {
80
+ schema?: string | undefined;
81
+ }>;
82
+ export declare const ListSchemasInputSchema: z.ZodObject<{
83
+ includeSystemSchemas: z.ZodOptional<z.ZodBoolean>;
84
+ }, "strip", z.ZodTypeAny, {
85
+ includeSystemSchemas?: boolean | undefined;
86
+ }, {
87
+ includeSystemSchemas?: boolean | undefined;
88
+ }>;
89
+ export declare const ListIndexesInputSchema: z.ZodObject<{
90
+ schema: z.ZodString;
91
+ table: z.ZodOptional<z.ZodString>;
92
+ }, "strip", z.ZodTypeAny, {
93
+ schema: string;
94
+ table?: string | undefined;
95
+ }, {
96
+ schema: string;
97
+ table?: string | undefined;
98
+ }>;
99
+ export declare const ExplainQueryInputSchema: z.ZodObject<{
100
+ sql: z.ZodString;
101
+ analyze: z.ZodOptional<z.ZodBoolean>;
102
+ buffers: z.ZodOptional<z.ZodBoolean>;
103
+ costs: z.ZodOptional<z.ZodBoolean>;
104
+ format: z.ZodOptional<z.ZodEnum<["text", "json", "xml", "yaml"]>>;
105
+ }, "strip", z.ZodTypeAny, {
106
+ sql: string;
107
+ analyze?: boolean | undefined;
108
+ buffers?: boolean | undefined;
109
+ costs?: boolean | undefined;
110
+ format?: "text" | "json" | "xml" | "yaml" | undefined;
111
+ }, {
112
+ sql: string;
113
+ analyze?: boolean | undefined;
114
+ buffers?: boolean | undefined;
115
+ costs?: boolean | undefined;
116
+ format?: "text" | "json" | "xml" | "yaml" | undefined;
117
+ }>;
118
+ export declare const GetTableStatsInputSchema: z.ZodObject<{
119
+ schema: z.ZodString;
120
+ table: z.ZodOptional<z.ZodString>;
121
+ }, "strip", z.ZodTypeAny, {
122
+ schema: string;
123
+ table?: string | undefined;
124
+ }, {
125
+ schema: string;
126
+ table?: string | undefined;
127
+ }>;
128
+ export declare const ListViewsInputSchema: z.ZodObject<{
129
+ schema: z.ZodOptional<z.ZodString>;
130
+ }, "strip", z.ZodTypeAny, {
131
+ schema?: string | undefined;
132
+ }, {
133
+ schema?: string | undefined;
134
+ }>;
135
+ export declare const ListFunctionsInputSchema: z.ZodObject<{
136
+ schema: z.ZodOptional<z.ZodString>;
137
+ }, "strip", z.ZodTypeAny, {
138
+ schema?: string | undefined;
139
+ }, {
140
+ schema?: string | undefined;
141
+ }>;
142
+ export declare function validateInput<T>(schema: z.ZodSchema<T>, input: unknown): {
143
+ success: true;
144
+ data: T;
145
+ } | {
146
+ success: false;
147
+ error: string;
148
+ };
149
+ export type QueryInput = z.infer<typeof QueryInputSchema>;
150
+ export type QueryOutput = z.infer<typeof QueryOutputSchema>;
151
+ export type DescribeTableInput = z.infer<typeof DescribeTableInputSchema>;
152
+ export type ListTablesInput = z.infer<typeof ListTablesInputSchema>;
153
+ export type ListSchemasInput = z.infer<typeof ListSchemasInputSchema>;
154
+ export type ListIndexesInput = z.infer<typeof ListIndexesInputSchema>;
155
+ export type ExplainQueryInput = z.infer<typeof ExplainQueryInputSchema>;
156
+ export type GetTableStatsInput = z.infer<typeof GetTableStatsInputSchema>;
157
+ export type ListViewsInput = z.infer<typeof ListViewsInputSchema>;
158
+ export type ListFunctionsInput = z.infer<typeof ListFunctionsInputSchema>;
159
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;EAU3B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAY5B,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;EAKnC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;EAIhC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;EAEjC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;EAMjC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;EAMlC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;EAMnC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;EAI/B,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;EAInC,CAAC;AAEH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAiBvI;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC1E,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACpE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACtE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACtE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC1E,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
@@ -0,0 +1,90 @@
1
+ import { z } from 'zod';
2
+ export const QueryInputSchema = z.object({
3
+ sql: z.string().min(1, "SQL query cannot be empty").max(50000, "SQL query too long"),
4
+ parameters: z.array(z.union([
5
+ z.string(),
6
+ z.number(),
7
+ z.boolean(),
8
+ z.null()
9
+ ])).optional().describe("Optional array of parameters for parameterized queries"),
10
+ pageSize: z.number().min(1).max(500).optional().describe("Number of rows to return (1-500, default: 100)"),
11
+ offset: z.number().min(0).optional().describe("Number of rows to skip for pagination")
12
+ });
13
+ export const QueryOutputSchema = z.object({
14
+ rows: z.array(z.record(z.any())).optional().describe("Query result rows (for SELECT queries)"),
15
+ rowCount: z.number().optional().describe("Number of rows affected/returned"),
16
+ error: z.string().optional().describe("Error message if query failed"),
17
+ code: z.string().optional().describe("Error code for categorized errors"),
18
+ hint: z.string().optional().describe("Helpful hint for resolving errors"),
19
+ pagination: z.object({
20
+ hasMore: z.boolean().describe("Whether more rows are available"),
21
+ pageSize: z.number().describe("Actual page size used"),
22
+ offset: z.number().describe("Offset used for this query"),
23
+ totalRows: z.number().optional().describe("Total rows available (if determinable)")
24
+ }).optional().describe("Pagination metadata for SELECT queries")
25
+ });
26
+ export const DescribeTableInputSchema = z.object({
27
+ schema: z.string().min(1, "Schema name is required").max(63, "Schema name too long")
28
+ .regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/, "Invalid schema name format"),
29
+ table: z.string().min(1, "Table name is required").max(63, "Table name too long")
30
+ .regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/, "Invalid table name format")
31
+ });
32
+ export const ListTablesInputSchema = z.object({
33
+ schema: z.string().min(1).max(63)
34
+ .regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/, "Invalid schema name format")
35
+ .optional()
36
+ });
37
+ export const ListSchemasInputSchema = z.object({
38
+ includeSystemSchemas: z.boolean().optional()
39
+ });
40
+ export const ListIndexesInputSchema = z.object({
41
+ schema: z.string().min(1, "Schema name is required").max(63, "Schema name too long")
42
+ .regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/, "Invalid schema name format"),
43
+ table: z.string().min(1).max(63)
44
+ .regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/, "Invalid table name format")
45
+ .optional()
46
+ });
47
+ export const ExplainQueryInputSchema = z.object({
48
+ sql: z.string().min(1, "SQL query cannot be empty").max(50000, "SQL query too long"),
49
+ analyze: z.boolean().optional(),
50
+ buffers: z.boolean().optional(),
51
+ costs: z.boolean().optional(),
52
+ format: z.enum(['text', 'json', 'xml', 'yaml']).optional()
53
+ });
54
+ export const GetTableStatsInputSchema = z.object({
55
+ schema: z.string().min(1, "Schema name is required").max(63, "Schema name too long")
56
+ .regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/, "Invalid schema name format"),
57
+ table: z.string().min(1).max(63)
58
+ .regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/, "Invalid table name format")
59
+ .optional()
60
+ });
61
+ export const ListViewsInputSchema = z.object({
62
+ schema: z.string().min(1).max(63)
63
+ .regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/, "Invalid schema name format")
64
+ .optional()
65
+ });
66
+ export const ListFunctionsInputSchema = z.object({
67
+ schema: z.string().min(1).max(63)
68
+ .regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/, "Invalid schema name format")
69
+ .optional()
70
+ });
71
+ export function validateInput(schema, input) {
72
+ try {
73
+ const data = schema.parse(input);
74
+ return { success: true, data };
75
+ }
76
+ catch (error) {
77
+ if (error instanceof z.ZodError) {
78
+ const firstError = error.errors[0];
79
+ return {
80
+ success: false,
81
+ error: `${firstError.path.join('.')}: ${firstError.message}`
82
+ };
83
+ }
84
+ return {
85
+ success: false,
86
+ error: 'Invalid input format'
87
+ };
88
+ }
89
+ }
90
+ //# sourceMappingURL=validation.js.map