dbgraph 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.
- package/LICENSE +21 -0
- package/README.md +347 -0
- package/dist/bin/dbgraph.d.ts +8 -0
- package/dist/bin/dbgraph.d.ts.map +1 -0
- package/dist/bin/dbgraph.js +382 -0
- package/dist/bin/dbgraph.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +158 -0
- package/dist/config.js.map +1 -0
- package/dist/context/formatter.d.ts +94 -0
- package/dist/context/formatter.d.ts.map +1 -0
- package/dist/context/formatter.js +288 -0
- package/dist/context/formatter.js.map +1 -0
- package/dist/context/index.d.ts +77 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +458 -0
- package/dist/context/index.js.map +1 -0
- package/dist/db/index.d.ts +26 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +127 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrations.d.ts +8 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +39 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/queries.d.ts +46 -0
- package/dist/db/queries.d.ts.map +1 -0
- package/dist/db/queries.js +436 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/db/schema.sql +113 -0
- package/dist/db/sqlite-adapter.d.ts +30 -0
- package/dist/db/sqlite-adapter.d.ts.map +1 -0
- package/dist/db/sqlite-adapter.js +78 -0
- package/dist/db/sqlite-adapter.js.map +1 -0
- package/dist/directory.d.ts +37 -0
- package/dist/directory.d.ts.map +1 -0
- package/dist/directory.js +160 -0
- package/dist/directory.js.map +1 -0
- package/dist/errors.d.ts +46 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +90 -0
- package/dist/errors.js.map +1 -0
- package/dist/graph/traversal.d.ts +157 -0
- package/dist/graph/traversal.d.ts.map +1 -0
- package/dist/graph/traversal.js +531 -0
- package/dist/graph/traversal.js.map +1 -0
- package/dist/index.d.ts +183 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +435 -0
- package/dist/index.js.map +1 -0
- package/dist/introspect/base.d.ts +62 -0
- package/dist/introspect/base.d.ts.map +1 -0
- package/dist/introspect/base.js +107 -0
- package/dist/introspect/base.js.map +1 -0
- package/dist/introspect/connection.d.ts +30 -0
- package/dist/introspect/connection.d.ts.map +1 -0
- package/dist/introspect/connection.js +232 -0
- package/dist/introspect/connection.js.map +1 -0
- package/dist/introspect/index.d.ts +23 -0
- package/dist/introspect/index.d.ts.map +1 -0
- package/dist/introspect/index.js +46 -0
- package/dist/introspect/index.js.map +1 -0
- package/dist/introspect/mysql.d.ts +64 -0
- package/dist/introspect/mysql.d.ts.map +1 -0
- package/dist/introspect/mysql.js +360 -0
- package/dist/introspect/mysql.js.map +1 -0
- package/dist/introspect/postgres.d.ts +55 -0
- package/dist/introspect/postgres.d.ts.map +1 -0
- package/dist/introspect/postgres.js +372 -0
- package/dist/introspect/postgres.js.map +1 -0
- package/dist/introspect/sqlite.d.ts +33 -0
- package/dist/introspect/sqlite.d.ts.map +1 -0
- package/dist/introspect/sqlite.js +207 -0
- package/dist/introspect/sqlite.js.map +1 -0
- package/dist/mcp/engine.d.ts +92 -0
- package/dist/mcp/engine.d.ts.map +1 -0
- package/dist/mcp/engine.js +261 -0
- package/dist/mcp/engine.js.map +1 -0
- package/dist/mcp/index.d.ts +33 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +119 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server-instructions.d.ts +9 -0
- package/dist/mcp/server-instructions.d.ts.map +1 -0
- package/dist/mcp/server-instructions.js +71 -0
- package/dist/mcp/server-instructions.js.map +1 -0
- package/dist/mcp/session.d.ts +35 -0
- package/dist/mcp/session.d.ts.map +1 -0
- package/dist/mcp/session.js +140 -0
- package/dist/mcp/session.js.map +1 -0
- package/dist/mcp/tools.d.ts +99 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +499 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/transport.d.ts +78 -0
- package/dist/mcp/transport.d.ts.map +1 -0
- package/dist/mcp/transport.js +182 -0
- package/dist/mcp/transport.js.map +1 -0
- package/dist/search/query-parser.d.ts +66 -0
- package/dist/search/query-parser.d.ts.map +1 -0
- package/dist/search/query-parser.js +163 -0
- package/dist/search/query-parser.js.map +1 -0
- package/dist/search/query-utils.d.ts +78 -0
- package/dist/search/query-utils.d.ts.map +1 -0
- package/dist/search/query-utils.js +203 -0
- package/dist/search/query-utils.js.map +1 -0
- package/dist/types.d.ts +279 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +47 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +40 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +190 -0
- package/dist/utils.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PostgreSQL Introspector
|
|
4
|
+
*
|
|
5
|
+
* Extracts schemas, tables, columns, primary keys, foreign keys,
|
|
6
|
+
* indexes, and views from a PostgreSQL database using
|
|
7
|
+
* `information_schema` + `pg_catalog` queries.
|
|
8
|
+
*
|
|
9
|
+
* Connection: uses `connection.ts` which wraps the `pg` package.
|
|
10
|
+
* The driver import is guarded so a missing `pg` is reported at
|
|
11
|
+
* connect() time, not at module load time.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.PostgresIntrospector = void 0;
|
|
15
|
+
const base_1 = require("./base");
|
|
16
|
+
const connection_1 = require("./connection");
|
|
17
|
+
// =============================================================================
|
|
18
|
+
// PostgresIntrospector
|
|
19
|
+
// =============================================================================
|
|
20
|
+
class PostgresIntrospector extends base_1.BaseIntrospector {
|
|
21
|
+
constructor(config) {
|
|
22
|
+
super(config);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Full schema introspection pipeline.
|
|
26
|
+
*
|
|
27
|
+
* 1. Connect to DB
|
|
28
|
+
* 2. Query schemas, tables, columns, PKs, FKs, indexes, views in batch
|
|
29
|
+
* 3. Build Node[] and Edge[] from the raw data
|
|
30
|
+
* 4. Close connection and return IntrospectResult
|
|
31
|
+
*/
|
|
32
|
+
async extractAll() {
|
|
33
|
+
const startTime = Date.now();
|
|
34
|
+
const errors = [];
|
|
35
|
+
const nodes = [];
|
|
36
|
+
const edges = [];
|
|
37
|
+
let conn;
|
|
38
|
+
try {
|
|
39
|
+
conn = await (0, connection_1.createConnection)(this.config);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
return {
|
|
43
|
+
nodes: [],
|
|
44
|
+
edges: [],
|
|
45
|
+
durationMs: Date.now() - startTime,
|
|
46
|
+
errors: [err.message],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
// ----- 1. Determine which schemas to introspect -----
|
|
51
|
+
const hasFilter = this.config.schemas !== undefined && this.config.schemas.length > 0;
|
|
52
|
+
const schemaFilter = new Set(this.config.schemas ?? []);
|
|
53
|
+
const schemas = await this.querySchemas(conn);
|
|
54
|
+
// Apply user-configured schema filter
|
|
55
|
+
const targetSchemas = hasFilter
|
|
56
|
+
? schemas.filter((r) => schemaFilter.has(r.schema_name))
|
|
57
|
+
: schemas;
|
|
58
|
+
if (targetSchemas.length === 0) {
|
|
59
|
+
errors.push(hasFilter
|
|
60
|
+
? `No matching schemas found. Filter: ${this.config.schemas.join(', ')}`
|
|
61
|
+
: 'No non-system schemas found');
|
|
62
|
+
return { nodes, edges, durationMs: Date.now() - startTime, errors };
|
|
63
|
+
}
|
|
64
|
+
const schemaNames = targetSchemas.map((r) => r.schema_name);
|
|
65
|
+
// ----- 2. Fetch all raw metadata in parallel -----
|
|
66
|
+
const [tables, columns, pks, fks, indexes, views] = await Promise.all([
|
|
67
|
+
this.queryTables(conn, schemaNames),
|
|
68
|
+
this.queryColumns(conn, schemaNames),
|
|
69
|
+
this.queryPrimaryKeys(conn, schemaNames),
|
|
70
|
+
this.queryForeignKeys(conn, schemaNames),
|
|
71
|
+
this.queryIndexes(conn, schemaNames),
|
|
72
|
+
this.queryViews(conn, schemaNames),
|
|
73
|
+
]);
|
|
74
|
+
// ----- 3. Build schema nodes -----
|
|
75
|
+
const schemaNodeById = new Map(); // key = schema name
|
|
76
|
+
for (const s of targetSchemas) {
|
|
77
|
+
const qual = this.qn(s.schema_name);
|
|
78
|
+
const fp = this.schemaFilePath(s.schema_name);
|
|
79
|
+
const node = this.makeNode('schema', s.schema_name, qual, fp);
|
|
80
|
+
nodes.push(node);
|
|
81
|
+
schemaNodeById.set(s.schema_name, node);
|
|
82
|
+
}
|
|
83
|
+
// ----- 4. Build table nodes + contains edges (schema → table) -----
|
|
84
|
+
const tableNodeByKey = new Map(); // key = schema.table
|
|
85
|
+
for (const t of tables) {
|
|
86
|
+
const schemaNode = schemaNodeById.get(t.schema_name);
|
|
87
|
+
if (!schemaNode)
|
|
88
|
+
continue;
|
|
89
|
+
const key = this.tableKey(t.schema_name, t.table_name);
|
|
90
|
+
const kind = t.table_type === 'VIEW' ? 'view' : 'table';
|
|
91
|
+
const qual = this.qn(t.schema_name, t.table_name);
|
|
92
|
+
const fp = this.schemaFilePath(t.schema_name);
|
|
93
|
+
const node = this.makeNode(kind, t.table_name, qual, fp, {
|
|
94
|
+
docstring: t.comment ?? undefined,
|
|
95
|
+
});
|
|
96
|
+
nodes.push(node);
|
|
97
|
+
tableNodeByKey.set(key, node);
|
|
98
|
+
edges.push(this.containEdge(schemaNode.id, node.id));
|
|
99
|
+
}
|
|
100
|
+
// ----- 5. Build column nodes + contains edges (table → column) -----
|
|
101
|
+
const columnNodeByKey = new Map(); // key = schema.table.column
|
|
102
|
+
for (const c of columns) {
|
|
103
|
+
const tableKey = this.tableKey(c.schema_name, c.table_name);
|
|
104
|
+
const tableNode = tableNodeByKey.get(tableKey);
|
|
105
|
+
if (!tableNode)
|
|
106
|
+
continue;
|
|
107
|
+
const colKey = this.columnKey(c.schema_name, c.table_name, c.column_name);
|
|
108
|
+
const qual = this.qn(c.schema_name, c.table_name, c.column_name);
|
|
109
|
+
const fp = this.schemaFilePath(c.schema_name);
|
|
110
|
+
const node = this.makeNode('column', c.column_name, qual, fp, {
|
|
111
|
+
startLine: c.ordinal_position ?? 0,
|
|
112
|
+
metadata: {
|
|
113
|
+
dataType: c.data_type,
|
|
114
|
+
isNullable: c.is_nullable === 'YES',
|
|
115
|
+
defaultValue: c.column_default ?? null,
|
|
116
|
+
maxLength: c.character_maximum_length ?? null,
|
|
117
|
+
numericPrecision: c.numeric_precision ?? null,
|
|
118
|
+
numericScale: c.numeric_scale ?? null,
|
|
119
|
+
udtName: c.udt_name ?? null,
|
|
120
|
+
collation: c.collation_name ?? null,
|
|
121
|
+
},
|
|
122
|
+
docstring: c.description ?? undefined,
|
|
123
|
+
});
|
|
124
|
+
nodes.push(node);
|
|
125
|
+
columnNodeByKey.set(colKey, node);
|
|
126
|
+
edges.push(this.containEdge(tableNode.id, node.id));
|
|
127
|
+
}
|
|
128
|
+
// ----- 6. Primary key edges (table → column) -----
|
|
129
|
+
for (const pk of pks) {
|
|
130
|
+
const colKey = this.columnKey(pk.schema_name, pk.table_name, pk.column_name);
|
|
131
|
+
const colNode = columnNodeByKey.get(colKey);
|
|
132
|
+
const tableKey = this.tableKey(pk.schema_name, pk.table_name);
|
|
133
|
+
const tableNode = tableNodeByKey.get(tableKey);
|
|
134
|
+
if (colNode && tableNode) {
|
|
135
|
+
edges.push(this.makeEdge(tableNode.id, colNode.id, 'primary_key', {
|
|
136
|
+
constraintName: pk.constraint_name,
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// ----- 7. Foreign key references edges (column → referenced column) -----
|
|
141
|
+
for (const fk of fks) {
|
|
142
|
+
const fromKey = this.columnKey(fk.schema_name, fk.table_name, fk.column_name);
|
|
143
|
+
const toKey = this.columnKey(fk.ref_table_schema, fk.ref_table_name, fk.ref_column_name);
|
|
144
|
+
const fromNode = columnNodeByKey.get(fromKey);
|
|
145
|
+
const toNode = columnNodeByKey.get(toKey);
|
|
146
|
+
if (fromNode && toNode) {
|
|
147
|
+
edges.push(this.makeEdge(fromNode.id, toNode.id, 'references', {
|
|
148
|
+
constraintName: fk.constraint_name,
|
|
149
|
+
onUpdate: fk.update_rule,
|
|
150
|
+
onDelete: fk.delete_rule,
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// ----- 8. Index nodes + indexed_by edges (table → index, column → index) -----
|
|
155
|
+
// Group index rows by index name to get column lists
|
|
156
|
+
const indexGroups = new Map();
|
|
157
|
+
for (const idx of indexes) {
|
|
158
|
+
const indexKey = `${idx.schema_name}.${idx.table_name}.${idx.indexname}`;
|
|
159
|
+
if (!indexGroups.has(indexKey)) {
|
|
160
|
+
indexGroups.set(indexKey, {
|
|
161
|
+
schema: idx.schema_name,
|
|
162
|
+
table: idx.table_name,
|
|
163
|
+
indexdef: idx.indexdef,
|
|
164
|
+
columns: [],
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Parse column list from indexdef (simplified — extracts first parenthesized group)
|
|
169
|
+
for (const [key, grp] of indexGroups) {
|
|
170
|
+
const match = grp.indexdef.match(/\(([^)]+)\)/);
|
|
171
|
+
if (match && match[1]) {
|
|
172
|
+
grp.columns = match[1].split(',').map((s) => s.trim().replace(/^"|"$/g, ''));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
for (const [_key, grp] of indexGroups) {
|
|
176
|
+
const tableKey = this.tableKey(grp.schema, grp.table);
|
|
177
|
+
const tableNode = tableNodeByKey.get(tableKey);
|
|
178
|
+
if (!tableNode)
|
|
179
|
+
continue;
|
|
180
|
+
// Extract a short index name from the DEFINE for the node name
|
|
181
|
+
const idxName = _key.split('.').pop();
|
|
182
|
+
const qual = this.qn(grp.schema, grp.table, idxName);
|
|
183
|
+
const fp = this.schemaFilePath(grp.schema);
|
|
184
|
+
const unique = grp.indexdef.toUpperCase().includes('UNIQUE');
|
|
185
|
+
const node = this.makeNode('index', idxName, qual, fp, {
|
|
186
|
+
signature: grp.indexdef,
|
|
187
|
+
metadata: { unique, columns: grp.columns },
|
|
188
|
+
});
|
|
189
|
+
nodes.push(node);
|
|
190
|
+
edges.push(this.containEdge(tableNode.id, node.id));
|
|
191
|
+
edges.push(this.makeEdge(tableNode.id, node.id, 'indexed_by'));
|
|
192
|
+
}
|
|
193
|
+
// ----- 9. View nodes — attach their definitions as signatures -----
|
|
194
|
+
// viewDefMap keys match the tableKey(schema, viewName) we used
|
|
195
|
+
// during table/view node creation in step 4.
|
|
196
|
+
const viewDefMap = new Map();
|
|
197
|
+
for (const v of views) {
|
|
198
|
+
const key = this.tableKey(v.schema_name, v.table_name);
|
|
199
|
+
if (v.view_definition)
|
|
200
|
+
viewDefMap.set(key, v.view_definition);
|
|
201
|
+
}
|
|
202
|
+
for (const node of nodes) {
|
|
203
|
+
if (node.kind !== 'view')
|
|
204
|
+
continue;
|
|
205
|
+
// qualifiedName = alias.schema.viewname → extract last two parts
|
|
206
|
+
const parts = node.qualifiedName.split('.');
|
|
207
|
+
if (parts.length < 3)
|
|
208
|
+
continue;
|
|
209
|
+
const schema = parts[parts.length - 2];
|
|
210
|
+
const viewName = parts[parts.length - 1];
|
|
211
|
+
const def = viewDefMap.get(this.tableKey(schema, viewName));
|
|
212
|
+
if (def)
|
|
213
|
+
node.signature = def;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
errors.push(`Introspection error: ${err.message}`);
|
|
218
|
+
}
|
|
219
|
+
finally {
|
|
220
|
+
await conn.close();
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
nodes,
|
|
224
|
+
edges,
|
|
225
|
+
durationMs: Date.now() - startTime,
|
|
226
|
+
errors,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
// ===========================================================================
|
|
230
|
+
// Query Methods
|
|
231
|
+
//
|
|
232
|
+
// Each method includes the schema_name in its result set so callers can
|
|
233
|
+
// group by schema at build time.
|
|
234
|
+
// ===========================================================================
|
|
235
|
+
/**
|
|
236
|
+
* Query: non-system schemas.
|
|
237
|
+
*/
|
|
238
|
+
async querySchemas(conn) {
|
|
239
|
+
return (await conn.query(`-- Schemas
|
|
240
|
+
SELECT schema_name
|
|
241
|
+
FROM information_schema.schemata
|
|
242
|
+
WHERE schema_name NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
|
|
243
|
+
AND schema_name NOT LIKE 'pg_%'
|
|
244
|
+
ORDER BY schema_name`));
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Query: tables and views (BASE TABLE or VIEW) with optional pg_catalog
|
|
248
|
+
* comment.
|
|
249
|
+
*/
|
|
250
|
+
async queryTables(conn, schemaNames) {
|
|
251
|
+
if (schemaNames.length === 0)
|
|
252
|
+
return [];
|
|
253
|
+
return (await conn.query(`SELECT t.table_schema AS schema_name,
|
|
254
|
+
t.table_name,
|
|
255
|
+
t.table_type,
|
|
256
|
+
pg_catalog.obj_description(
|
|
257
|
+
(quote_ident(t.table_schema) || '.' || quote_ident(t.table_name))::regclass,
|
|
258
|
+
'pg_class'
|
|
259
|
+
) AS comment
|
|
260
|
+
FROM information_schema.tables t
|
|
261
|
+
WHERE t.table_schema = ANY($1)
|
|
262
|
+
AND t.table_type IN ('BASE TABLE', 'VIEW')
|
|
263
|
+
ORDER BY t.table_name`, [schemaNames]));
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Query: column metadata + pg_catalog column description.
|
|
267
|
+
*/
|
|
268
|
+
async queryColumns(conn, schemaNames) {
|
|
269
|
+
if (schemaNames.length === 0)
|
|
270
|
+
return [];
|
|
271
|
+
return (await conn.query(`SELECT c.table_schema AS schema_name,
|
|
272
|
+
c.table_name,
|
|
273
|
+
c.column_name,
|
|
274
|
+
c.data_type,
|
|
275
|
+
c.is_nullable,
|
|
276
|
+
c.column_default,
|
|
277
|
+
c.character_maximum_length,
|
|
278
|
+
c.numeric_precision,
|
|
279
|
+
c.numeric_scale,
|
|
280
|
+
c.datetime_precision,
|
|
281
|
+
c.ordinal_position,
|
|
282
|
+
c.udt_name,
|
|
283
|
+
c.collation_name,
|
|
284
|
+
pg_catalog.col_description(
|
|
285
|
+
(quote_ident(c.table_schema) || '.' || quote_ident(c.table_name))::regclass,
|
|
286
|
+
c.ordinal_position::integer
|
|
287
|
+
) AS description
|
|
288
|
+
FROM information_schema.columns c
|
|
289
|
+
WHERE c.table_schema = ANY($1)
|
|
290
|
+
ORDER BY c.table_name, c.ordinal_position`, [schemaNames]));
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Query: columns that are part of a PRIMARY KEY constraint.
|
|
294
|
+
*/
|
|
295
|
+
async queryPrimaryKeys(conn, schemaNames) {
|
|
296
|
+
if (schemaNames.length === 0)
|
|
297
|
+
return [];
|
|
298
|
+
return (await conn.query(`SELECT tc.table_schema AS schema_name,
|
|
299
|
+
tc.table_name,
|
|
300
|
+
tc.constraint_name,
|
|
301
|
+
kcu.column_name
|
|
302
|
+
FROM information_schema.table_constraints tc
|
|
303
|
+
JOIN information_schema.key_column_usage kcu
|
|
304
|
+
ON tc.constraint_catalog = kcu.constraint_catalog
|
|
305
|
+
AND tc.constraint_schema = kcu.constraint_schema
|
|
306
|
+
AND tc.constraint_name = kcu.constraint_name
|
|
307
|
+
WHERE tc.table_schema = ANY($1)
|
|
308
|
+
AND tc.constraint_type = 'PRIMARY KEY'
|
|
309
|
+
ORDER BY tc.table_name, kcu.ordinal_position`, [schemaNames]));
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Query: foreign key columns + referenced table/column + referential actions.
|
|
313
|
+
*/
|
|
314
|
+
async queryForeignKeys(conn, schemaNames) {
|
|
315
|
+
if (schemaNames.length === 0)
|
|
316
|
+
return [];
|
|
317
|
+
return (await conn.query(`SELECT tc.table_schema AS schema_name,
|
|
318
|
+
tc.table_name,
|
|
319
|
+
tc.constraint_name,
|
|
320
|
+
kcu.column_name,
|
|
321
|
+
ccu.table_schema AS ref_table_schema,
|
|
322
|
+
ccu.table_name AS ref_table_name,
|
|
323
|
+
ccu.column_name AS ref_column_name,
|
|
324
|
+
rc.update_rule,
|
|
325
|
+
rc.delete_rule
|
|
326
|
+
FROM information_schema.table_constraints tc
|
|
327
|
+
JOIN information_schema.key_column_usage kcu
|
|
328
|
+
ON tc.constraint_catalog = kcu.constraint_catalog
|
|
329
|
+
AND tc.constraint_schema = kcu.constraint_schema
|
|
330
|
+
AND tc.constraint_name = kcu.constraint_name
|
|
331
|
+
JOIN information_schema.constraint_column_usage ccu
|
|
332
|
+
ON ccu.constraint_catalog = tc.constraint_catalog
|
|
333
|
+
AND ccu.constraint_schema = tc.constraint_schema
|
|
334
|
+
AND ccu.constraint_name = tc.constraint_name
|
|
335
|
+
JOIN information_schema.referential_constraints rc
|
|
336
|
+
ON rc.constraint_catalog = tc.constraint_catalog
|
|
337
|
+
AND rc.constraint_schema = tc.constraint_schema
|
|
338
|
+
AND rc.constraint_name = tc.constraint_name
|
|
339
|
+
WHERE tc.table_schema = ANY($1)
|
|
340
|
+
AND tc.constraint_type = 'FOREIGN KEY'
|
|
341
|
+
ORDER BY tc.table_name, tc.constraint_name, kcu.ordinal_position`, [schemaNames]));
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Query: index definitions from pg_indexes.
|
|
345
|
+
*/
|
|
346
|
+
async queryIndexes(conn, schemaNames) {
|
|
347
|
+
if (schemaNames.length === 0)
|
|
348
|
+
return [];
|
|
349
|
+
return (await conn.query(`SELECT pi.schemaname AS schema_name,
|
|
350
|
+
pi.tablename AS table_name,
|
|
351
|
+
pi.indexname,
|
|
352
|
+
pi.indexdef
|
|
353
|
+
FROM pg_indexes pi
|
|
354
|
+
WHERE pi.schemaname = ANY($1)
|
|
355
|
+
ORDER BY pi.tablename, pi.indexname`, [schemaNames]));
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Query: view definitions.
|
|
359
|
+
*/
|
|
360
|
+
async queryViews(conn, schemaNames) {
|
|
361
|
+
if (schemaNames.length === 0)
|
|
362
|
+
return [];
|
|
363
|
+
return (await conn.query(`SELECT v.table_schema AS schema_name,
|
|
364
|
+
v.table_name,
|
|
365
|
+
v.view_definition
|
|
366
|
+
FROM information_schema.views v
|
|
367
|
+
WHERE v.table_schema = ANY($1)
|
|
368
|
+
ORDER BY v.table_name`, [schemaNames]));
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
exports.PostgresIntrospector = PostgresIntrospector;
|
|
372
|
+
//# sourceMappingURL=postgres.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/introspect/postgres.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Introspector
|
|
3
|
+
*
|
|
4
|
+
* Extracts tables, columns, primary keys, foreign keys, indexes,
|
|
5
|
+
* and views from a SQLite database using `sqlite_master` and
|
|
6
|
+
* `PRAGMA` queries (accessed via table-valued functions).
|
|
7
|
+
*
|
|
8
|
+
* Connection: uses `connection.ts` which wraps the built-in
|
|
9
|
+
* `node:sqlite` module (Node >= 22.5). No external driver needed.
|
|
10
|
+
*
|
|
11
|
+
* Schema model:
|
|
12
|
+
* - SQLite has a flat namespace — the "schema" concept is modeled
|
|
13
|
+
* as a single node named "main".
|
|
14
|
+
* - Virtual tables (FTS, etc.) are included; they appear in
|
|
15
|
+
* sqlite_master alongside regular tables.
|
|
16
|
+
*/
|
|
17
|
+
import { IntrospectResult, DbConnectionConfig } from '../types';
|
|
18
|
+
import { BaseIntrospector } from './base';
|
|
19
|
+
export declare class SQLiteIntrospector extends BaseIntrospector {
|
|
20
|
+
constructor(config: DbConnectionConfig);
|
|
21
|
+
/**
|
|
22
|
+
* Full schema introspection pipeline for a SQLite database.
|
|
23
|
+
*
|
|
24
|
+
* 1. Open the SQLite file
|
|
25
|
+
* 2. Query `sqlite_master` for tables/views
|
|
26
|
+
* 3. For each table: columns (PRAGMA table_info), FKs, indexes
|
|
27
|
+
* 4. For each index: index columns (PRAGMA index_info)
|
|
28
|
+
* 5. Build Node[] + Edge[]
|
|
29
|
+
* 6. Close and return result
|
|
30
|
+
*/
|
|
31
|
+
extractAll(): Promise<IntrospectResult>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/introspect/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAKnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AA2D1C,qBAAa,kBAAmB,SAAQ,gBAAgB;gBAC1C,MAAM,EAAE,kBAAkB;IAItC;;;;;;;;;OASG;IACG,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC;CAyM9C"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SQLite Introspector
|
|
4
|
+
*
|
|
5
|
+
* Extracts tables, columns, primary keys, foreign keys, indexes,
|
|
6
|
+
* and views from a SQLite database using `sqlite_master` and
|
|
7
|
+
* `PRAGMA` queries (accessed via table-valued functions).
|
|
8
|
+
*
|
|
9
|
+
* Connection: uses `connection.ts` which wraps the built-in
|
|
10
|
+
* `node:sqlite` module (Node >= 22.5). No external driver needed.
|
|
11
|
+
*
|
|
12
|
+
* Schema model:
|
|
13
|
+
* - SQLite has a flat namespace — the "schema" concept is modeled
|
|
14
|
+
* as a single node named "main".
|
|
15
|
+
* - Virtual tables (FTS, etc.) are included; they appear in
|
|
16
|
+
* sqlite_master alongside regular tables.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.SQLiteIntrospector = void 0;
|
|
20
|
+
const base_1 = require("./base");
|
|
21
|
+
const connection_1 = require("./connection");
|
|
22
|
+
// =============================================================================
|
|
23
|
+
// Constants
|
|
24
|
+
// =============================================================================
|
|
25
|
+
/** The implicit schema name for the main SQLite database */
|
|
26
|
+
const MAIN_SCHEMA = 'main';
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// SQLiteIntrospector
|
|
29
|
+
// =============================================================================
|
|
30
|
+
class SQLiteIntrospector extends base_1.BaseIntrospector {
|
|
31
|
+
constructor(config) {
|
|
32
|
+
super(config);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Full schema introspection pipeline for a SQLite database.
|
|
36
|
+
*
|
|
37
|
+
* 1. Open the SQLite file
|
|
38
|
+
* 2. Query `sqlite_master` for tables/views
|
|
39
|
+
* 3. For each table: columns (PRAGMA table_info), FKs, indexes
|
|
40
|
+
* 4. For each index: index columns (PRAGMA index_info)
|
|
41
|
+
* 5. Build Node[] + Edge[]
|
|
42
|
+
* 6. Close and return result
|
|
43
|
+
*/
|
|
44
|
+
async extractAll() {
|
|
45
|
+
const startTime = Date.now();
|
|
46
|
+
const errors = [];
|
|
47
|
+
const nodes = [];
|
|
48
|
+
const edges = [];
|
|
49
|
+
let conn;
|
|
50
|
+
try {
|
|
51
|
+
conn = await (0, connection_1.createConnection)(this.config);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
return {
|
|
55
|
+
nodes: [],
|
|
56
|
+
edges: [],
|
|
57
|
+
durationMs: Date.now() - startTime,
|
|
58
|
+
errors: [err.message],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
// ----- 1. Fetch all objects from sqlite_master -----
|
|
63
|
+
const masterRows = (await conn.query(`SELECT type, name, tbl_name, sql
|
|
64
|
+
FROM sqlite_master
|
|
65
|
+
WHERE type IN ('table', 'view')
|
|
66
|
+
AND name NOT LIKE 'sqlite_%'
|
|
67
|
+
ORDER BY type, name`));
|
|
68
|
+
if (masterRows.length === 0) {
|
|
69
|
+
errors.push('No user tables or views found in the database');
|
|
70
|
+
return { nodes, edges, durationMs: Date.now() - startTime, errors };
|
|
71
|
+
}
|
|
72
|
+
// Separate tables and views
|
|
73
|
+
const tables = masterRows.filter((r) => r.type === 'table');
|
|
74
|
+
const views = masterRows.filter((r) => r.type === 'view');
|
|
75
|
+
// ----- 2. Build a single "schema" node for this database -----
|
|
76
|
+
const schemaQual = this.qn(MAIN_SCHEMA);
|
|
77
|
+
const schemaFp = this.schemaFilePath(MAIN_SCHEMA);
|
|
78
|
+
const schemaNode = this.makeNode('schema', MAIN_SCHEMA, schemaQual, schemaFp);
|
|
79
|
+
nodes.push(schemaNode);
|
|
80
|
+
// ----- 3. Build table nodes + contains edges (schema → table) -----
|
|
81
|
+
const tableNodeByKey = new Map(); // key = table_name
|
|
82
|
+
for (const t of tables) {
|
|
83
|
+
const qual = this.qn(MAIN_SCHEMA, t.name);
|
|
84
|
+
const fp = this.schemaFilePath(MAIN_SCHEMA);
|
|
85
|
+
const node = this.makeNode('table', t.name, qual, fp, {
|
|
86
|
+
signature: t.sql ?? undefined,
|
|
87
|
+
});
|
|
88
|
+
nodes.push(node);
|
|
89
|
+
tableNodeByKey.set(t.name, node);
|
|
90
|
+
edges.push(this.containEdge(schemaNode.id, node.id));
|
|
91
|
+
}
|
|
92
|
+
// ----- 4. For each table: columns, PKs, FKs, indexes -----
|
|
93
|
+
const columnNodeByKey = new Map(); // key = table.column
|
|
94
|
+
const pkEdges = [];
|
|
95
|
+
const fkEdges = [];
|
|
96
|
+
const indexNodes = [];
|
|
97
|
+
for (const t of tables) {
|
|
98
|
+
const tableNode = tableNodeByKey.get(t.name);
|
|
99
|
+
if (!tableNode)
|
|
100
|
+
continue;
|
|
101
|
+
// ----- 4a. Columns via pragma_table_info -----
|
|
102
|
+
const colRows = (await conn.query(`SELECT cid, name, type, notnull, dflt_value, pk
|
|
103
|
+
FROM pragma_table_info(?)`, [t.name]));
|
|
104
|
+
for (const col of colRows) {
|
|
105
|
+
const colKey = `${t.name}.${col.name}`;
|
|
106
|
+
const qual = this.qn(MAIN_SCHEMA, t.name, col.name);
|
|
107
|
+
const fp = this.schemaFilePath(MAIN_SCHEMA);
|
|
108
|
+
const node = this.makeNode('column', col.name, qual, fp, {
|
|
109
|
+
startLine: col.cid + 1,
|
|
110
|
+
metadata: {
|
|
111
|
+
dataType: col.type || 'TEXT',
|
|
112
|
+
isNullable: col.notnull === 0,
|
|
113
|
+
defaultValue: col.dflt_value ?? null,
|
|
114
|
+
isPrimaryKey: col.pk === 1,
|
|
115
|
+
// SQLite types don't have precision/scale/length in the
|
|
116
|
+
// traditional sense, but we report what's in the DDL type
|
|
117
|
+
collation: null,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
nodes.push(node);
|
|
121
|
+
columnNodeByKey.set(colKey, node);
|
|
122
|
+
edges.push(this.containEdge(tableNode.id, node.id));
|
|
123
|
+
// Primary key flag from pragma result
|
|
124
|
+
if (col.pk === 1) {
|
|
125
|
+
pkEdges.push(this.makeEdge(tableNode.id, node.id, 'primary_key', {
|
|
126
|
+
constraintName: `pk_${t.name}`,
|
|
127
|
+
pkOrdinal: col.pk,
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// ----- 4b. Foreign keys via pragma_foreign_key_list -----
|
|
132
|
+
const fkRows = (await conn.query(`SELECT id, seq, "table", "from", "to", on_update, on_delete, match
|
|
133
|
+
FROM pragma_foreign_key_list(?)`, [t.name]));
|
|
134
|
+
for (const fk of fkRows) {
|
|
135
|
+
const fromKey = `${t.name}.${fk.from}`;
|
|
136
|
+
const toKey = `${fk.table}.${fk.to}`;
|
|
137
|
+
const fromNode = columnNodeByKey.get(fromKey);
|
|
138
|
+
const toNode = columnNodeByKey.get(toKey);
|
|
139
|
+
if (fromNode && toNode) {
|
|
140
|
+
fkEdges.push(this.makeEdge(fromNode.id, toNode.id, 'references', {
|
|
141
|
+
constraintName: `fk_${t.name}_${fk.from}`,
|
|
142
|
+
onUpdate: fk.on_update,
|
|
143
|
+
onDelete: fk.on_delete,
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// ----- 4c. Index list via pragma_index_list -----
|
|
148
|
+
const idxListRows = (await conn.query(`SELECT seq, name, unique, origin, partial
|
|
149
|
+
FROM pragma_index_list(?)`, [t.name]));
|
|
150
|
+
for (const idx of idxListRows) {
|
|
151
|
+
// Skip auto-generated indexes for UNIQUE / PK constraints
|
|
152
|
+
if (idx.origin === 'pk')
|
|
153
|
+
continue;
|
|
154
|
+
if (idx.origin === 'u' && idx.name.startsWith('sqlite_autoindex_'))
|
|
155
|
+
continue;
|
|
156
|
+
// Get index columns
|
|
157
|
+
const idxColRows = (await conn.query(`SELECT seqno, cid, name
|
|
158
|
+
FROM pragma_index_info(?)`, [idx.name]));
|
|
159
|
+
const colNames = idxColRows
|
|
160
|
+
.sort((a, b) => a.seqno - b.seqno)
|
|
161
|
+
.map((r) => r.name);
|
|
162
|
+
const qual = this.qn(MAIN_SCHEMA, t.name, idx.name);
|
|
163
|
+
const fp = this.schemaFilePath(MAIN_SCHEMA);
|
|
164
|
+
const node = this.makeNode('index', idx.name, qual, fp, {
|
|
165
|
+
metadata: {
|
|
166
|
+
unique: idx.unique === 1,
|
|
167
|
+
columns: colNames,
|
|
168
|
+
origin: idx.origin,
|
|
169
|
+
partial: idx.partial === 1,
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
indexNodes.push(node);
|
|
173
|
+
edges.push(this.containEdge(tableNode.id, node.id));
|
|
174
|
+
edges.push(this.makeEdge(tableNode.id, node.id, 'indexed_by'));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Add all deferred edges and index nodes
|
|
178
|
+
edges.push(...pkEdges);
|
|
179
|
+
edges.push(...fkEdges);
|
|
180
|
+
nodes.push(...indexNodes);
|
|
181
|
+
// ----- 5. Build view nodes + contains edges -----
|
|
182
|
+
for (const v of views) {
|
|
183
|
+
const qual = this.qn(MAIN_SCHEMA, v.name);
|
|
184
|
+
const fp = this.schemaFilePath(MAIN_SCHEMA);
|
|
185
|
+
const node = this.makeNode('view', v.name, qual, fp, {
|
|
186
|
+
signature: v.sql ?? undefined,
|
|
187
|
+
});
|
|
188
|
+
nodes.push(node);
|
|
189
|
+
edges.push(this.containEdge(schemaNode.id, node.id));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
errors.push(`Introspection error: ${err.message}`);
|
|
194
|
+
}
|
|
195
|
+
finally {
|
|
196
|
+
await conn.close();
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
nodes,
|
|
200
|
+
edges,
|
|
201
|
+
durationMs: Date.now() - startTime,
|
|
202
|
+
errors,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
exports.SQLiteIntrospector = SQLiteIntrospector;
|
|
207
|
+
//# sourceMappingURL=sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/introspect/sqlite.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAUH,iCAA0C;AAC1C,6CAA8D;AA+C9D,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF,4DAA4D;AAC5D,MAAM,WAAW,GAAG,MAAM,CAAC;AAE3B,gFAAgF;AAChF,qBAAqB;AACrB,gFAAgF;AAEhF,MAAa,kBAAmB,SAAQ,uBAAgB;IACtD,YAAY,MAA0B;QACpC,KAAK,CAAC,MAAM,CAAC,CAAC;IAChB,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,UAAU;QACd,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAW,EAAE,CAAC;QACzB,MAAM,KAAK,GAAW,EAAE,CAAC;QAEzB,IAAI,IAAkB,CAAC;QACvB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,IAAA,6BAAgB,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO;gBACL,KAAK,EAAE,EAAE;gBACT,KAAK,EAAE,EAAE;gBACT,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;gBAClC,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;aACtB,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,sDAAsD;YACtD,MAAM,UAAU,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAClC;;;;6BAIqB,CACtB,CAAgB,CAAC;YAElB,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5B,MAAM,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;gBAC7D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE,CAAC;YACtE,CAAC;YAED,4BAA4B;YAC5B,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;YAC5D,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;YAE1D,gEAAgE;YAChE,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;YACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;YAClD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC9E,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAEvB,qEAAqE;YACrE,MAAM,cAAc,GAAG,IAAI,GAAG,EAAgB,CAAC,CAAC,mBAAmB;YAEnE,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;gBAC1C,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;gBAE5C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;oBACpD,SAAS,EAAE,CAAC,CAAC,GAAG,IAAI,SAAS;iBAC9B,CAAC,CAAC;gBACH,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjB,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBACjC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACvD,CAAC;YAED,4DAA4D;YAC5D,MAAM,eAAe,GAAG,IAAI,GAAG,EAAgB,CAAC,CAAC,qBAAqB;YACtE,MAAM,OAAO,GAAW,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAW,EAAE,CAAC;YAC3B,MAAM,UAAU,GAAW,EAAE,CAAC;YAE9B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAC7C,IAAI,CAAC,SAAS;oBAAE,SAAS;gBAEzB,gDAAgD;gBAChD,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAC/B;qCAC2B,EAC3B,CAAC,CAAC,CAAC,IAAI,CAAC,CACT,CAAmB,CAAC;gBAErB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;oBAC1B,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;oBACvC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;oBACpD,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;oBAE5C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;wBACvD,SAAS,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;wBACtB,QAAQ,EAAE;4BACR,QAAQ,EAAE,GAAG,CAAC,IAAI,IAAI,MAAM;4BAC5B,UAAU,EAAE,GAAG,CAAC,OAAO,KAAK,CAAC;4BAC7B,YAAY,EAAE,GAAG,CAAC,UAAU,IAAI,IAAI;4BACpC,YAAY,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC;4BAC1B,wDAAwD;4BACxD,0DAA0D;4BAC1D,SAAS,EAAE,IAAI;yBAChB;qBACF,CAAC,CAAC;oBACH,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACjB,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;oBAClC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;oBAEpD,sCAAsC;oBACtC,IAAI,GAAG,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;wBACjB,OAAO,CAAC,IAAI,CACV,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE;4BAClD,cAAc,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE;4BAC9B,SAAS,EAAE,GAAG,CAAC,EAAE;yBAClB,CAAC,CACH,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAED,2DAA2D;gBAC3D,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAC9B;2CACiC,EACjC,CAAC,CAAC,CAAC,IAAI,CAAC,CACT,CAAgB,CAAC;gBAElB,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;oBACxB,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;oBACvC,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;oBAErC,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBAC9C,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;oBAE1C,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;wBACvB,OAAO,CAAC,IAAI,CACV,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,YAAY,EAAE;4BAClD,cAAc,EAAE,MAAM,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE;4BACzC,QAAQ,EAAE,EAAE,CAAC,SAAS;4BACtB,QAAQ,EAAE,EAAE,CAAC,SAAS;yBACvB,CAAC,CACH,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAED,mDAAmD;gBACnD,MAAM,WAAW,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CACnC;qCAC2B,EAC3B,CAAC,CAAC,CAAC,IAAI,CAAC,CACT,CAAmB,CAAC;gBAErB,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;oBAC9B,0DAA0D;oBAC1D,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI;wBAAE,SAAS;oBAClC,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC;wBAAE,SAAS;oBAE7E,oBAAoB;oBACpB,MAAM,UAAU,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAClC;uCAC2B,EAC3B,CAAC,GAAG,CAAC,IAAI,CAAC,CACX,CAAmB,CAAC;oBAErB,MAAM,QAAQ,GAAG,UAAU;yBACxB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;yBACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBAEtB,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;oBACpD,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;oBAE5C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;wBACtD,QAAQ,EAAE;4BACR,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,CAAC;4BACxB,OAAO,EAAE,QAAQ;4BACjB,MAAM,EAAE,GAAG,CAAC,MAAM;4BAClB,OAAO,EAAE,GAAG,CAAC,OAAO,KAAK,CAAC;yBAC3B;qBACF,CAAC,CAAC;oBACH,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACtB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;oBACpD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC;gBACjE,CAAC;YACH,CAAC;YAED,yCAAyC;YACzC,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;YAE1B,mDAAmD;YACnD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;gBAC1C,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;gBAE5C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;oBACnD,SAAS,EAAE,CAAC,CAAC,GAAG,IAAI,SAAS;iBAC9B,CAAC,CAAC;gBACH,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,MAAM,CAAC,IAAI,CAAC,wBAAwB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACrD,CAAC;gBAAS,CAAC;YACT,MAAM,IAAK,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC;QAED,OAAO;YACL,KAAK;YACL,KAAK;YACL,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;YAClC,MAAM;SACP,CAAC;IACJ,CAAC;CACF;AAxND,gDAwNC"}
|