schema-navigator-mcp 0.2.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 (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +215 -0
  3. package/dist/db/pg-adapter.d.ts +17 -0
  4. package/dist/db/pg-adapter.js +74 -0
  5. package/dist/db/pg-adapter.js.map +1 -0
  6. package/dist/db/postgres.d.ts +19 -0
  7. package/dist/db/postgres.js +34 -0
  8. package/dist/db/postgres.js.map +1 -0
  9. package/dist/db/supabase-adapter.d.ts +45 -0
  10. package/dist/db/supabase-adapter.js +148 -0
  11. package/dist/db/supabase-adapter.js.map +1 -0
  12. package/dist/db/types.d.ts +25 -0
  13. package/dist/db/types.js +2 -0
  14. package/dist/db/types.js.map +1 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.js +80 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/server.d.ts +4 -0
  19. package/dist/server.js +129 -0
  20. package/dist/server.js.map +1 -0
  21. package/dist/tools/constraints.d.ts +22 -0
  22. package/dist/tools/constraints.js +80 -0
  23. package/dist/tools/constraints.js.map +1 -0
  24. package/dist/tools/functions.d.ts +20 -0
  25. package/dist/tools/functions.js +118 -0
  26. package/dist/tools/functions.js.map +1 -0
  27. package/dist/tools/overview.d.ts +29 -0
  28. package/dist/tools/overview.js +142 -0
  29. package/dist/tools/overview.js.map +1 -0
  30. package/dist/tools/policies.d.ts +29 -0
  31. package/dist/tools/policies.js +96 -0
  32. package/dist/tools/policies.js.map +1 -0
  33. package/dist/tools/relations.d.ts +18 -0
  34. package/dist/tools/relations.js +72 -0
  35. package/dist/tools/relations.js.map +1 -0
  36. package/dist/tools/search.d.ts +13 -0
  37. package/dist/tools/search.js +77 -0
  38. package/dist/tools/search.js.map +1 -0
  39. package/dist/tools/table-profile.d.ts +68 -0
  40. package/dist/tools/table-profile.js +477 -0
  41. package/dist/tools/table-profile.js.map +1 -0
  42. package/dist/utils/check-parser.d.ts +17 -0
  43. package/dist/utils/check-parser.js +61 -0
  44. package/dist/utils/check-parser.js.map +1 -0
  45. package/dist/utils/pg-array.d.ts +6 -0
  46. package/dist/utils/pg-array.js +42 -0
  47. package/dist/utils/pg-array.js.map +1 -0
  48. package/package.json +67 -0
@@ -0,0 +1,477 @@
1
+ import { readOnlyMultiQuery, getIsPostgres } from "../db/postgres.js";
2
+ import { parseCheckExpression } from "../utils/check-parser.js";
3
+ import { parsePgArray } from "../utils/pg-array.js";
4
+ export async function schemaTable(tableName, schema) {
5
+ const isPg = getIsPostgres();
6
+ // Detect object type
7
+ const objectType = await detectObjectType(tableName, schema, isPg);
8
+ if (!objectType) {
9
+ return { error: `Table '${tableName}' not found in schema '${schema}'` };
10
+ }
11
+ if (objectType === "view") {
12
+ return profileView(tableName, schema, isPg);
13
+ }
14
+ if (objectType === "materialized view") {
15
+ return profileMatview(tableName, schema, isPg);
16
+ }
17
+ return profileTable(tableName, schema, isPg);
18
+ }
19
+ async function detectObjectType(name, schema, isPg) {
20
+ if (isPg) {
21
+ const queries = [
22
+ {
23
+ sql: `
24
+ SELECT CASE c.relkind
25
+ WHEN 'r' THEN 'table'
26
+ WHEN 'p' THEN 'partitioned table'
27
+ WHEN 'v' THEN 'view'
28
+ WHEN 'm' THEN 'materialized view'
29
+ END AS object_type
30
+ FROM pg_class c
31
+ JOIN pg_namespace n ON n.oid = c.relnamespace
32
+ WHERE n.nspname = $1 AND c.relname = $2
33
+ AND c.relkind IN ('r', 'p', 'v', 'm')
34
+ `,
35
+ params: [schema, name],
36
+ },
37
+ ];
38
+ const [result] = await readOnlyMultiQuery(queries);
39
+ return result.rows[0]?.object_type ?? null;
40
+ }
41
+ // Fallback: information_schema
42
+ const queries = [
43
+ {
44
+ sql: `SELECT table_type FROM information_schema.tables WHERE table_schema = $1 AND table_name = $2`,
45
+ params: [schema, name],
46
+ },
47
+ ];
48
+ const [result] = await readOnlyMultiQuery(queries);
49
+ if (result.rows.length === 0)
50
+ return null;
51
+ const tt = result.rows[0].table_type;
52
+ return tt === "VIEW" ? "view" : "table";
53
+ }
54
+ async function profileTable(tableName, schema, isPg) {
55
+ const queries = buildTableQueries(tableName, schema, isPg);
56
+ const results = await readOnlyMultiQuery(queries);
57
+ let idx = 0;
58
+ // Q1: Columns
59
+ const columnsResult = results[idx++];
60
+ const columns = columnsResult.rows.map((r) => ({
61
+ name: r.column_name,
62
+ type: r.data_type,
63
+ nullable: r.is_nullable === "YES",
64
+ default: r.column_default ?? null,
65
+ comment: r.description ?? null,
66
+ }));
67
+ // Q2: Constraints + FKs + Checks
68
+ const constraintsResult = results[idx++];
69
+ const constraints = [];
70
+ const fksOut = [];
71
+ for (const r of constraintsResult.rows) {
72
+ const conType = r.constraint_type;
73
+ if (conType === "FOREIGN KEY") {
74
+ fksOut.push({
75
+ constraint_name: r.constraint_name,
76
+ column: r.column_name,
77
+ foreign_table: r.foreign_table,
78
+ foreign_column: r.foreign_column,
79
+ on_delete: r.delete_rule ?? "NO ACTION",
80
+ on_update: r.update_rule ?? "NO ACTION",
81
+ });
82
+ }
83
+ else if (conType === "CHECK") {
84
+ const parsed = parseCheckExpression(r.check_clause);
85
+ const constraint = {
86
+ name: r.constraint_name,
87
+ type: "CHECK",
88
+ columns: parsed.column ? [parsed.column] : [],
89
+ definition: r.check_clause,
90
+ };
91
+ if (parsed.type === "values" && parsed.allowed_values) {
92
+ constraint.allowed_values = parsed.allowed_values;
93
+ }
94
+ constraints.push(constraint);
95
+ }
96
+ else {
97
+ constraints.push({
98
+ name: r.constraint_name,
99
+ type: conType,
100
+ columns: r.column_name ? [r.column_name] : [],
101
+ });
102
+ }
103
+ }
104
+ // Q3: Indexes
105
+ const indexesResult = results[idx++];
106
+ const indexes = isPg
107
+ ? indexesResult.rows.map((r) => ({
108
+ name: r.indexname,
109
+ columns: r.indexdef,
110
+ unique: r.indexdef.includes("UNIQUE"),
111
+ definition: r.indexdef,
112
+ }))
113
+ : [];
114
+ // Q4: RLS + Triggers
115
+ const rlsTriggersResult = results[idx++];
116
+ let rlsEnabled = null;
117
+ const policies = [];
118
+ const triggers = [];
119
+ if (isPg) {
120
+ // RLS enabled flag from sub-results
121
+ // Parse combined results
122
+ for (const r of rlsTriggersResult.rows) {
123
+ if (r.policyname != null) {
124
+ policies.push({
125
+ name: r.policyname,
126
+ command: r.cmd,
127
+ roles: parsePgArray(r.roles),
128
+ using: r.qual ?? null,
129
+ with_check: r.with_check ?? null,
130
+ });
131
+ }
132
+ else if (r.trigger_name != null) {
133
+ triggers.push({
134
+ name: r.trigger_name,
135
+ event: r.event_manipulation,
136
+ timing: r.action_timing,
137
+ function: r.action_statement ?? "",
138
+ });
139
+ }
140
+ }
141
+ }
142
+ // Q5: Size + Row count + GRANTs + RLS flag
143
+ const metaResult = results[idx++];
144
+ let size = null;
145
+ let rowCount = null;
146
+ const grants = [];
147
+ if (isPg && metaResult.rows.length > 0) {
148
+ for (const r of metaResult.rows) {
149
+ if (r.total_size != null) {
150
+ size = r.total_size;
151
+ rowCount = r.row_estimate != null ? Number(r.row_estimate) : null;
152
+ rlsEnabled = r.rls_enabled;
153
+ }
154
+ else if (r.grantee != null) {
155
+ grants.push({
156
+ grantee: r.grantee,
157
+ privileges: parsePgArray(r.privileges),
158
+ });
159
+ }
160
+ }
161
+ }
162
+ // Inbound FKs
163
+ let fksIn = [];
164
+ if (isPg) {
165
+ const inboundResult = results[idx++];
166
+ fksIn = inboundResult.rows.map((r) => ({
167
+ constraint_name: r.constraint_name,
168
+ column: r.foreign_column,
169
+ foreign_table: r.source_table,
170
+ foreign_column: r.source_column,
171
+ on_delete: r.delete_rule ?? "NO ACTION",
172
+ on_update: r.update_rule ?? "NO ACTION",
173
+ }));
174
+ }
175
+ return {
176
+ object_type: "table",
177
+ schema,
178
+ name: tableName,
179
+ columns,
180
+ constraints,
181
+ fks_out: fksOut,
182
+ fks_in: fksIn,
183
+ indexes,
184
+ triggers,
185
+ policies,
186
+ rls_enabled: rlsEnabled,
187
+ grants,
188
+ size,
189
+ row_count: rowCount,
190
+ };
191
+ }
192
+ function buildTableQueries(tableName, schema, isPg) {
193
+ const queries = [];
194
+ // Q1: Columns with comments
195
+ if (isPg) {
196
+ queries.push({
197
+ sql: `
198
+ SELECT
199
+ c.column_name, c.data_type, c.is_nullable, c.column_default,
200
+ pgd.description
201
+ FROM information_schema.columns c
202
+ LEFT JOIN pg_catalog.pg_statio_all_tables st
203
+ ON st.schemaname = c.table_schema AND st.relname = c.table_name
204
+ LEFT JOIN pg_catalog.pg_description pgd
205
+ ON pgd.objoid = st.relid AND pgd.objsubid = c.ordinal_position
206
+ WHERE c.table_schema = $1 AND c.table_name = $2
207
+ ORDER BY c.ordinal_position
208
+ `,
209
+ params: [schema, tableName],
210
+ });
211
+ }
212
+ else {
213
+ queries.push({
214
+ sql: `
215
+ SELECT column_name, data_type, is_nullable, column_default, NULL AS description
216
+ FROM information_schema.columns
217
+ WHERE table_schema = $1 AND table_name = $2
218
+ ORDER BY ordinal_position
219
+ `,
220
+ params: [schema, tableName],
221
+ });
222
+ }
223
+ // Q2: Constraints + FKs + Checks
224
+ queries.push({
225
+ sql: `
226
+ SELECT
227
+ tc.constraint_name, tc.constraint_type,
228
+ kcu.column_name,
229
+ ccu.table_name AS foreign_table,
230
+ ccu.column_name AS foreign_column,
231
+ rc.delete_rule, rc.update_rule,
232
+ cc.check_clause
233
+ FROM information_schema.table_constraints tc
234
+ LEFT JOIN information_schema.key_column_usage kcu
235
+ ON kcu.constraint_name = tc.constraint_name AND kcu.constraint_schema = tc.constraint_schema
236
+ LEFT JOIN information_schema.constraint_column_usage ccu
237
+ ON ccu.constraint_name = tc.constraint_name AND ccu.constraint_schema = tc.constraint_schema
238
+ AND tc.constraint_type = 'FOREIGN KEY'
239
+ LEFT JOIN information_schema.referential_constraints rc
240
+ ON rc.constraint_name = tc.constraint_name AND rc.constraint_schema = tc.constraint_schema
241
+ LEFT JOIN information_schema.check_constraints cc
242
+ ON cc.constraint_name = tc.constraint_name AND cc.constraint_schema = tc.constraint_schema
243
+ WHERE tc.table_schema = $1 AND tc.table_name = $2
244
+ ORDER BY tc.constraint_type, tc.constraint_name
245
+ `,
246
+ params: [schema, tableName],
247
+ });
248
+ // Q3: Indexes (Postgres only)
249
+ if (isPg) {
250
+ queries.push({
251
+ sql: `SELECT indexname, indexdef FROM pg_indexes WHERE schemaname = $1 AND tablename = $2`,
252
+ params: [schema, tableName],
253
+ });
254
+ }
255
+ else {
256
+ queries.push({ sql: `SELECT 1 WHERE false` });
257
+ }
258
+ // Q4: RLS Policies + Triggers
259
+ if (isPg) {
260
+ queries.push({
261
+ sql: `
262
+ (SELECT policyname, cmd, roles, qual, with_check, NULL AS trigger_name, NULL AS event_manipulation, NULL AS action_timing, NULL AS action_statement
263
+ FROM pg_policies WHERE schemaname = $1 AND tablename = $2)
264
+ UNION ALL
265
+ (SELECT NULL, NULL, NULL, NULL, NULL, trigger_name, event_manipulation, action_timing, action_statement
266
+ FROM information_schema.triggers WHERE trigger_schema = $1 AND event_object_table = $2)
267
+ `,
268
+ params: [schema, tableName],
269
+ });
270
+ }
271
+ else {
272
+ queries.push({
273
+ sql: `
274
+ SELECT trigger_name, event_manipulation, action_timing, action_statement,
275
+ NULL AS policyname, NULL AS cmd, NULL AS roles, NULL AS qual, NULL AS with_check
276
+ FROM information_schema.triggers
277
+ WHERE trigger_schema = $1 AND event_object_table = $2
278
+ `,
279
+ params: [schema, tableName],
280
+ });
281
+ }
282
+ // Q5: Size + Row count + GRANTs + RLS flag
283
+ if (isPg) {
284
+ queries.push({
285
+ sql: `
286
+ (SELECT
287
+ pg_size_pretty(pg_total_relation_size(c.oid)) AS total_size,
288
+ c.reltuples::bigint AS row_estimate,
289
+ c.relrowsecurity AS rls_enabled,
290
+ NULL AS grantee, NULL AS privileges
291
+ FROM pg_class c
292
+ JOIN pg_namespace n ON n.oid = c.relnamespace
293
+ WHERE n.nspname = $1 AND c.relname = $2)
294
+ UNION ALL
295
+ (SELECT NULL, NULL, NULL, grantee,
296
+ array_agg(privilege_type ORDER BY privilege_type) AS privileges
297
+ FROM information_schema.role_table_grants
298
+ WHERE table_schema = $1 AND table_name = $2
299
+ GROUP BY grantee)
300
+ `,
301
+ params: [schema, tableName],
302
+ });
303
+ }
304
+ else {
305
+ queries.push({ sql: `SELECT 1 WHERE false` });
306
+ }
307
+ // Q6: Inbound FKs (Postgres only)
308
+ if (isPg) {
309
+ queries.push({
310
+ sql: `
311
+ SELECT
312
+ tc.constraint_name,
313
+ kcu.table_name AS source_table,
314
+ kcu.column_name AS source_column,
315
+ ccu.column_name AS foreign_column,
316
+ rc.delete_rule, rc.update_rule
317
+ FROM information_schema.table_constraints tc
318
+ JOIN information_schema.key_column_usage kcu
319
+ ON kcu.constraint_name = tc.constraint_name AND kcu.constraint_schema = tc.constraint_schema
320
+ JOIN information_schema.constraint_column_usage ccu
321
+ ON ccu.constraint_name = tc.constraint_name AND ccu.constraint_schema = tc.constraint_schema
322
+ JOIN information_schema.referential_constraints rc
323
+ ON rc.constraint_name = tc.constraint_name AND rc.constraint_schema = tc.constraint_schema
324
+ WHERE ccu.table_schema = $1 AND ccu.table_name = $2
325
+ AND tc.constraint_type = 'FOREIGN KEY'
326
+ `,
327
+ params: [schema, tableName],
328
+ });
329
+ }
330
+ return queries;
331
+ }
332
+ async function profileView(viewName, schema, isPg) {
333
+ const queries = [];
334
+ // Columns
335
+ if (isPg) {
336
+ queries.push({
337
+ sql: `
338
+ SELECT c.column_name, c.data_type, c.is_nullable, c.column_default, pgd.description
339
+ FROM information_schema.columns c
340
+ LEFT JOIN pg_catalog.pg_statio_all_tables st ON st.schemaname = c.table_schema AND st.relname = c.table_name
341
+ LEFT JOIN pg_catalog.pg_description pgd ON pgd.objoid = st.relid AND pgd.objsubid = c.ordinal_position
342
+ WHERE c.table_schema = $1 AND c.table_name = $2
343
+ ORDER BY c.ordinal_position
344
+ `,
345
+ params: [schema, viewName],
346
+ });
347
+ }
348
+ else {
349
+ queries.push({
350
+ sql: `SELECT column_name, data_type, is_nullable, column_default, NULL AS description
351
+ FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 ORDER BY ordinal_position`,
352
+ params: [schema, viewName],
353
+ });
354
+ }
355
+ // View definition + is_updatable
356
+ queries.push({
357
+ sql: `SELECT view_definition, is_updatable FROM information_schema.views WHERE table_schema = $1 AND table_name = $2`,
358
+ params: [schema, viewName],
359
+ });
360
+ const results = await readOnlyMultiQuery(queries);
361
+ const columns = results[0].rows.map((r) => ({
362
+ name: r.column_name,
363
+ type: r.data_type,
364
+ nullable: r.is_nullable === "YES",
365
+ default: r.column_default ?? null,
366
+ comment: r.description ?? null,
367
+ }));
368
+ const viewDef = results[1].rows[0];
369
+ return {
370
+ object_type: "view",
371
+ schema,
372
+ name: viewName,
373
+ columns,
374
+ constraints: [],
375
+ fks_out: [],
376
+ fks_in: [],
377
+ indexes: [],
378
+ triggers: [],
379
+ policies: [],
380
+ rls_enabled: null,
381
+ grants: [],
382
+ size: null,
383
+ row_count: null,
384
+ view_definition: viewDef?.view_definition ?? undefined,
385
+ is_updatable: viewDef?.is_updatable === "YES",
386
+ };
387
+ }
388
+ async function profileMatview(matviewName, schema, isPg) {
389
+ if (!isPg) {
390
+ return {
391
+ object_type: "materialized view",
392
+ schema,
393
+ name: matviewName,
394
+ columns: [],
395
+ constraints: [],
396
+ fks_out: [],
397
+ fks_in: [],
398
+ indexes: [],
399
+ triggers: [],
400
+ policies: [],
401
+ rls_enabled: null,
402
+ grants: [],
403
+ size: null,
404
+ row_count: null,
405
+ };
406
+ }
407
+ const queries = [
408
+ // Columns
409
+ {
410
+ sql: `
411
+ SELECT a.attname AS column_name,
412
+ pg_catalog.format_type(a.atttypid, a.atttypmod) AS data_type,
413
+ NOT a.attnotnull AS is_nullable,
414
+ pg_get_expr(d.adbin, d.adrelid) AS column_default,
415
+ col_description(c.oid, a.attnum) AS description
416
+ FROM pg_class c
417
+ JOIN pg_namespace n ON n.oid = c.relnamespace
418
+ JOIN pg_attribute a ON a.attrelid = c.oid AND a.attnum > 0 AND NOT a.attisdropped
419
+ LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = a.attnum
420
+ WHERE n.nspname = $1 AND c.relname = $2 AND c.relkind = 'm'
421
+ ORDER BY a.attnum
422
+ `,
423
+ params: [schema, matviewName],
424
+ },
425
+ // Definition + populated + size
426
+ {
427
+ sql: `
428
+ SELECT
429
+ definition,
430
+ ispopulated AS is_populated,
431
+ pg_size_pretty(pg_total_relation_size(($1 || '.' || $2)::regclass)) AS size
432
+ FROM pg_matviews
433
+ WHERE schemaname = $1 AND matviewname = $2
434
+ `,
435
+ params: [schema, matviewName],
436
+ },
437
+ // Indexes
438
+ {
439
+ sql: `SELECT indexname, indexdef FROM pg_indexes WHERE schemaname = $1 AND tablename = $2`,
440
+ params: [schema, matviewName],
441
+ },
442
+ ];
443
+ const results = await readOnlyMultiQuery(queries);
444
+ const columns = results[0].rows.map((r) => ({
445
+ name: r.column_name,
446
+ type: r.data_type,
447
+ nullable: r.is_nullable,
448
+ default: r.column_default ?? null,
449
+ comment: r.description ?? null,
450
+ }));
451
+ const meta = results[1].rows[0];
452
+ const indexes = results[2].rows.map((r) => ({
453
+ name: r.indexname,
454
+ columns: r.indexdef,
455
+ unique: r.indexdef.includes("UNIQUE"),
456
+ definition: r.indexdef,
457
+ }));
458
+ return {
459
+ object_type: "materialized view",
460
+ schema,
461
+ name: matviewName,
462
+ columns,
463
+ constraints: [],
464
+ fks_out: [],
465
+ fks_in: [],
466
+ indexes,
467
+ triggers: [],
468
+ policies: [],
469
+ rls_enabled: null,
470
+ grants: [],
471
+ size: meta?.size ?? null,
472
+ row_count: null,
473
+ view_definition: meta?.definition ?? undefined,
474
+ is_populated: meta?.is_populated,
475
+ };
476
+ }
477
+ //# sourceMappingURL=table-profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-profile.js","sourceRoot":"","sources":["../../src/tools/table-profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export interface CheckResult {
2
+ column: string | null;
3
+ type: "values" | "range" | "unknown";
4
+ allowed_values?: string[];
5
+ expression: string;
6
+ }
7
+ /**
8
+ * Parse PostgreSQL CHECK constraint expressions into allowed values.
9
+ *
10
+ * Handles 5 real patterns:
11
+ * 1. (status = ANY (ARRAY['pending'::text, 'processing'::text]))
12
+ * 2. ((currency)::text = ANY ((ARRAY['BGN'::character varying])::text[]))
13
+ * 3. ((tier IS NULL) OR (tier = ANY (ARRAY[...])))
14
+ * 4. (amount >= (0)::numeric) — range check
15
+ * 5. id IS NOT NULL — auto-generated (skip)
16
+ */
17
+ export declare function parseCheckExpression(expression: string): CheckResult;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Parse PostgreSQL CHECK constraint expressions into allowed values.
3
+ *
4
+ * Handles 5 real patterns:
5
+ * 1. (status = ANY (ARRAY['pending'::text, 'processing'::text]))
6
+ * 2. ((currency)::text = ANY ((ARRAY['BGN'::character varying])::text[]))
7
+ * 3. ((tier IS NULL) OR (tier = ANY (ARRAY[...])))
8
+ * 4. (amount >= (0)::numeric) — range check
9
+ * 5. id IS NOT NULL — auto-generated (skip)
10
+ */
11
+ export function parseCheckExpression(expression) {
12
+ // Pattern 5: Skip auto-generated NOT NULL constraints
13
+ if (/^\(?[\w."]+\s+IS\s+NOT\s+NULL\)?$/i.test(expression.trim())) {
14
+ return { column: null, type: "unknown", expression };
15
+ }
16
+ // Try to extract column name
17
+ const column = extractColumn(expression);
18
+ // Pattern 1-3: ANY (ARRAY[...]) with various castings
19
+ const arrayMatch = expression.match(/ARRAY\[([^\]]+)\]/i);
20
+ if (arrayMatch) {
21
+ const values = extractArrayValues(arrayMatch[1]);
22
+ if (values.length > 0) {
23
+ return { column, type: "values", allowed_values: values, expression };
24
+ }
25
+ }
26
+ // Pattern 4: Range checks (>=, <=, >, <, BETWEEN)
27
+ if (/[><=]+\s*\(?[\d.]+\)?/.test(expression)) {
28
+ return { column, type: "range", expression };
29
+ }
30
+ return { column, type: "unknown", expression };
31
+ }
32
+ function extractColumn(expression) {
33
+ // Match: ((column_name)::type = ...) or (column_name = ...)
34
+ const patterns = [
35
+ /\(\((\w+)\)::/, // ((column)::type
36
+ /\((\w+)\s*=\s*ANY/, // (column = ANY
37
+ /\(\((\w+)\)\s*=\s*ANY/, // ((column) = ANY — parenthesized
38
+ /\((\w+)\s*[><=]/, // (column >= ...
39
+ /OR\s*\((\w+)\s*=\s*ANY/i, // OR (column = ANY (nullable wrapper)
40
+ ];
41
+ for (const pattern of patterns) {
42
+ const match = expression.match(pattern);
43
+ if (match)
44
+ return match[1];
45
+ }
46
+ return null;
47
+ }
48
+ function extractArrayValues(arrayContent) {
49
+ // Split by commas, strip casts and quotes
50
+ return arrayContent
51
+ .split(",")
52
+ .map((v) => {
53
+ // Remove ::text, ::character varying, etc.
54
+ let cleaned = v.replace(/::\w[\w\s]*/g, "").trim();
55
+ // Remove surrounding quotes and un-escape doubled single quotes
56
+ cleaned = cleaned.replace(/^'(.*)'$/, "$1").replace(/''/g, "'");
57
+ return cleaned;
58
+ })
59
+ .filter((v) => v.length > 0);
60
+ }
61
+ //# sourceMappingURL=check-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-parser.js","sourceRoot":"","sources":["../../src/utils/check-parser.ts"],"names":[],"mappings":"AAOA;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAAkB;IACrD,sDAAsD;IACtD,IAAI,oCAAoC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACjE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;IACvD,CAAC;IAED,6BAA6B;IAC7B,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IAEzC,sDAAsD;IACtD,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC1D,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACjD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;QACxE,CAAC;IACH,CAAC;IAED,kDAAkD;IAClD,IAAI,uBAAuB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IAC/C,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;AACjD,CAAC;AAED,SAAS,aAAa,CAAC,UAAkB;IACvC,4DAA4D;IAC5D,MAAM,QAAQ,GAAG;QACf,eAAe,EAAY,kBAAkB;QAC7C,mBAAmB,EAAQ,gBAAgB;QAC3C,uBAAuB,EAAI,kCAAkC;QAC7D,iBAAiB,EAAU,iBAAiB;QAC5C,yBAAyB,EAAE,sCAAsC;KAClE,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,kBAAkB,CAAC,YAAoB;IAC9C,0CAA0C;IAC1C,OAAO,YAAY;SAChB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,2CAA2C;QAC3C,IAAI,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACnD,gEAAgE;QAChE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAChE,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Parse PostgreSQL text[] values that the pg driver may return as
3
+ * string literals like {value1,value2,"quoted,value"} instead of
4
+ * native JavaScript arrays.
5
+ */
6
+ export declare function parsePgArray(value: unknown): string[];
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Parse PostgreSQL text[] values that the pg driver may return as
3
+ * string literals like {value1,value2,"quoted,value"} instead of
4
+ * native JavaScript arrays.
5
+ */
6
+ export function parsePgArray(value) {
7
+ if (Array.isArray(value))
8
+ return value;
9
+ if (typeof value !== "string")
10
+ return [];
11
+ const inner = value.replace(/^\{|\}$/g, "");
12
+ if (inner.length === 0)
13
+ return [];
14
+ const result = [];
15
+ let current = "";
16
+ let inQuotes = false;
17
+ for (let i = 0; i < inner.length; i++) {
18
+ const ch = inner[i];
19
+ if (ch === '"' && !inQuotes) {
20
+ inQuotes = true;
21
+ }
22
+ else if (ch === '"' && inQuotes) {
23
+ if (inner[i + 1] === '"') {
24
+ current += '"'; // escaped quote
25
+ i++;
26
+ }
27
+ else {
28
+ inQuotes = false;
29
+ }
30
+ }
31
+ else if (ch === "," && !inQuotes) {
32
+ result.push(current);
33
+ current = "";
34
+ }
35
+ else {
36
+ current += ch;
37
+ }
38
+ }
39
+ result.push(current);
40
+ return result.filter((s) => s.length > 0);
41
+ }
42
+ //# sourceMappingURL=pg-array.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-array.js","sourceRoot":"","sources":["../../src/utils/pg-array.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IAEzC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC5C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAElC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC5B,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,IAAI,QAAQ,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACzB,OAAO,IAAI,GAAG,CAAC,CAAC,gBAAgB;gBAChC,CAAC,EAAE,CAAC;YACN,CAAC;iBAAM,CAAC;gBACN,QAAQ,GAAG,KAAK,CAAC;YACnB,CAAC;QACH,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrB,OAAO,GAAG,EAAE,CAAC;QACf,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAErB,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC5C,CAAC"}