@eamonboyle/mssql-mcp 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +169 -22
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +74 -0
- package/dist/config.js.map +1 -0
- package/dist/db.d.ts +29 -24
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +144 -112
- package/dist/db.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +382 -122
- package/dist/index.js.map +1 -1
- package/dist/mcpResults.d.ts +49 -0
- package/dist/mcpResults.d.ts.map +1 -0
- package/dist/mcpResults.js +246 -0
- package/dist/mcpResults.js.map +1 -0
- package/dist/promptRegistry.d.ts +16 -0
- package/dist/promptRegistry.d.ts.map +1 -0
- package/dist/promptRegistry.js +112 -0
- package/dist/promptRegistry.js.map +1 -0
- package/dist/resourceRegistry.d.ts +14 -0
- package/dist/resourceRegistry.d.ts.map +1 -0
- package/dist/resourceRegistry.js +311 -0
- package/dist/resourceRegistry.js.map +1 -0
- package/dist/schema.d.ts +57 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +390 -0
- package/dist/schema.js.map +1 -0
- package/dist/serverState.d.ts +28 -0
- package/dist/serverState.d.ts.map +1 -0
- package/dist/serverState.js +99 -0
- package/dist/serverState.js.map +1 -0
- package/dist/sql.d.ts +7 -0
- package/dist/sql.d.ts.map +1 -0
- package/dist/sql.js +73 -0
- package/dist/sql.js.map +1 -0
- package/dist/toolRegistry.d.ts +20 -0
- package/dist/toolRegistry.d.ts.map +1 -0
- package/dist/toolRegistry.js +547 -0
- package/dist/toolRegistry.js.map +1 -0
- package/dist/tools/AnalyzeTableTool.d.ts +37 -0
- package/dist/tools/AnalyzeTableTool.d.ts.map +1 -0
- package/dist/tools/AnalyzeTableTool.js +81 -0
- package/dist/tools/AnalyzeTableTool.js.map +1 -0
- package/dist/tools/CreateIndexTool.d.ts +30 -23
- package/dist/tools/CreateIndexTool.d.ts.map +1 -1
- package/dist/tools/CreateIndexTool.js +47 -77
- package/dist/tools/CreateIndexTool.js.map +1 -1
- package/dist/tools/CreateTableTool.d.ts +18 -11
- package/dist/tools/CreateTableTool.d.ts.map +1 -1
- package/dist/tools/CreateTableTool.js +37 -61
- package/dist/tools/CreateTableTool.js.map +1 -1
- package/dist/tools/DeleteDataTool.d.ts +22 -0
- package/dist/tools/DeleteDataTool.d.ts.map +1 -0
- package/dist/tools/DeleteDataTool.js +38 -0
- package/dist/tools/DeleteDataTool.js.map +1 -0
- package/dist/tools/DescribeObjectTool.d.ts +21 -0
- package/dist/tools/DescribeObjectTool.d.ts.map +1 -0
- package/dist/tools/DescribeObjectTool.js +31 -0
- package/dist/tools/DescribeObjectTool.js.map +1 -0
- package/dist/tools/DescribeRelationshipsTool.d.ts +20 -0
- package/dist/tools/DescribeRelationshipsTool.d.ts.map +1 -0
- package/dist/tools/DescribeRelationshipsTool.js +24 -0
- package/dist/tools/DescribeRelationshipsTool.js.map +1 -0
- package/dist/tools/DescribeTableTool.d.ts +19 -20
- package/dist/tools/DescribeTableTool.d.ts.map +1 -1
- package/dist/tools/DescribeTableTool.js +23 -44
- package/dist/tools/DescribeTableTool.js.map +1 -1
- package/dist/tools/DropTableTool.d.ts +13 -11
- package/dist/tools/DropTableTool.d.ts.map +1 -1
- package/dist/tools/DropTableTool.js +30 -44
- package/dist/tools/DropTableTool.js.map +1 -1
- package/dist/tools/ExplainQueryTool.d.ts +32 -0
- package/dist/tools/ExplainQueryTool.d.ts.map +1 -0
- package/dist/tools/ExplainQueryTool.js +102 -0
- package/dist/tools/ExplainQueryTool.js.map +1 -0
- package/dist/tools/InsertDataTool.d.ts +20 -16
- package/dist/tools/InsertDataTool.d.ts.map +1 -1
- package/dist/tools/InsertDataTool.js +91 -108
- package/dist/tools/InsertDataTool.js.map +1 -1
- package/dist/tools/ListDatabasesTool.d.ts +16 -0
- package/dist/tools/ListDatabasesTool.d.ts.map +1 -0
- package/dist/tools/ListDatabasesTool.js +26 -0
- package/dist/tools/ListDatabasesTool.js.map +1 -0
- package/dist/tools/ListForeignKeysTool.d.ts +19 -0
- package/dist/tools/ListForeignKeysTool.d.ts.map +1 -0
- package/dist/tools/ListForeignKeysTool.js +24 -0
- package/dist/tools/ListForeignKeysTool.js.map +1 -0
- package/dist/tools/ListObjectsTool.d.ts +20 -0
- package/dist/tools/ListObjectsTool.d.ts.map +1 -0
- package/dist/tools/ListObjectsTool.js +26 -0
- package/dist/tools/ListObjectsTool.js.map +1 -0
- package/dist/tools/ListTableTool.d.ts +20 -16
- package/dist/tools/ListTableTool.d.ts.map +1 -1
- package/dist/tools/ListTableTool.js +32 -51
- package/dist/tools/ListTableTool.js.map +1 -1
- package/dist/tools/PreviewDeleteTool.d.ts +28 -0
- package/dist/tools/PreviewDeleteTool.d.ts.map +1 -0
- package/dist/tools/PreviewDeleteTool.js +31 -0
- package/dist/tools/PreviewDeleteTool.js.map +1 -0
- package/dist/tools/PreviewUpdateTool.d.ts +30 -0
- package/dist/tools/PreviewUpdateTool.d.ts.map +1 -0
- package/dist/tools/PreviewUpdateTool.js +34 -0
- package/dist/tools/PreviewUpdateTool.js.map +1 -0
- package/dist/tools/ReadDataTool.d.ts +35 -33
- package/dist/tools/ReadDataTool.d.ts.map +1 -1
- package/dist/tools/ReadDataTool.js +92 -105
- package/dist/tools/ReadDataTool.js.map +1 -1
- package/dist/tools/SearchDataTool.d.ts +27 -0
- package/dist/tools/SearchDataTool.d.ts.map +1 -0
- package/dist/tools/SearchDataTool.js +61 -0
- package/dist/tools/SearchDataTool.js.map +1 -0
- package/dist/tools/UpdateDataTool.d.ts +22 -16
- package/dist/tools/UpdateDataTool.d.ts.map +1 -1
- package/dist/tools/UpdateDataTool.js +48 -65
- package/dist/tools/UpdateDataTool.js.map +1 -1
- package/dist/validation.d.ts +13 -13
- package/dist/validation.js +133 -133
- package/dist/validation.js.map +1 -1
- package/dist/writePreview.d.ts +20 -0
- package/dist/writePreview.d.ts.map +1 -0
- package/dist/writePreview.js +27 -0
- package/dist/writePreview.js.map +1 -0
- package/dist/writePreviewGrant.d.ts +18 -0
- package/dist/writePreviewGrant.d.ts.map +1 -0
- package/dist/writePreviewGrant.js +71 -0
- package/dist/writePreviewGrant.js.map +1 -0
- package/dist/writePreviewGrantStore.d.ts +10 -0
- package/dist/writePreviewGrantStore.d.ts.map +1 -0
- package/dist/writePreviewGrantStore.js +47 -0
- package/dist/writePreviewGrantStore.js.map +1 -0
- package/dist/writeSafety.d.ts +21 -0
- package/dist/writeSafety.d.ts.map +1 -0
- package/dist/writeSafety.js +169 -0
- package/dist/writeSafety.js.map +1 -0
- package/package.json +6 -5
- package/dist/__tests__/db.test.d.ts +0 -2
- package/dist/__tests__/db.test.d.ts.map +0 -1
- package/dist/__tests__/db.test.js +0 -204
- package/dist/__tests__/db.test.js.map +0 -1
- package/dist/__tests__/validation.test.d.ts +0 -2
- package/dist/__tests__/validation.test.d.ts.map +0 -1
- package/dist/__tests__/validation.test.js +0 -111
- package/dist/__tests__/validation.test.js.map +0 -1
package/dist/schema.js
ADDED
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
import sql from "mssql";
|
|
2
|
+
import { getAllowedDatabases, getDefaultDatabaseName, getSqlRequest, } from "./db.js";
|
|
3
|
+
import { getFriendlyObjectType, getObjectTypeCodes } from "./sql.js";
|
|
4
|
+
export async function listDatabaseTables(databaseName, schemaName) {
|
|
5
|
+
const { request, error } = await getSqlRequest(databaseName);
|
|
6
|
+
if (error) {
|
|
7
|
+
throw new Error(error);
|
|
8
|
+
}
|
|
9
|
+
if (schemaName) {
|
|
10
|
+
request.input("schemaName", sql.NVarChar, schemaName);
|
|
11
|
+
}
|
|
12
|
+
const schemaFilter = schemaName ? "AND TABLE_SCHEMA = @schemaName" : "";
|
|
13
|
+
const result = await request.query(`
|
|
14
|
+
SELECT
|
|
15
|
+
TABLE_SCHEMA AS schemaName,
|
|
16
|
+
TABLE_NAME AS tableName
|
|
17
|
+
FROM INFORMATION_SCHEMA.TABLES
|
|
18
|
+
WHERE TABLE_TYPE = 'BASE TABLE'
|
|
19
|
+
${schemaFilter}
|
|
20
|
+
ORDER BY TABLE_SCHEMA, TABLE_NAME
|
|
21
|
+
`);
|
|
22
|
+
return result.recordset;
|
|
23
|
+
}
|
|
24
|
+
export async function describeTableSchema(tableName, databaseName, schemaName) {
|
|
25
|
+
const { request, error } = await getSqlRequest(databaseName);
|
|
26
|
+
if (error) {
|
|
27
|
+
throw new Error(error);
|
|
28
|
+
}
|
|
29
|
+
request.input("tableName", sql.NVarChar, tableName);
|
|
30
|
+
if (schemaName) {
|
|
31
|
+
request.input("schemaName", sql.NVarChar, schemaName);
|
|
32
|
+
}
|
|
33
|
+
const schemaFilter = schemaName ? "AND c.TABLE_SCHEMA = @schemaName" : "";
|
|
34
|
+
const result = await request.query(`
|
|
35
|
+
SELECT
|
|
36
|
+
c.TABLE_SCHEMA AS schemaName,
|
|
37
|
+
c.COLUMN_NAME AS name,
|
|
38
|
+
c.DATA_TYPE AS type,
|
|
39
|
+
c.IS_NULLABLE AS isNullable,
|
|
40
|
+
c.COLUMN_DEFAULT AS defaultValue,
|
|
41
|
+
c.CHARACTER_MAXIMUM_LENGTH AS maxLength,
|
|
42
|
+
c.NUMERIC_PRECISION AS numericPrecision,
|
|
43
|
+
c.NUMERIC_SCALE AS numericScale
|
|
44
|
+
FROM INFORMATION_SCHEMA.COLUMNS c
|
|
45
|
+
WHERE c.TABLE_NAME = @tableName
|
|
46
|
+
${schemaFilter}
|
|
47
|
+
ORDER BY c.ORDINAL_POSITION
|
|
48
|
+
`);
|
|
49
|
+
return result.recordset;
|
|
50
|
+
}
|
|
51
|
+
export async function listDatabaseObjects(databaseName, objectTypes, schemaName) {
|
|
52
|
+
const { request, error } = await getSqlRequest(databaseName);
|
|
53
|
+
if (error) {
|
|
54
|
+
throw new Error(error);
|
|
55
|
+
}
|
|
56
|
+
const typeCodes = getObjectTypeCodes(objectTypes);
|
|
57
|
+
const typePlaceholders = typeCodes
|
|
58
|
+
.map((code, index) => {
|
|
59
|
+
const parameterName = `typeCode${index}`;
|
|
60
|
+
request.input(parameterName, sql.NVarChar, code);
|
|
61
|
+
return `@${parameterName}`;
|
|
62
|
+
})
|
|
63
|
+
.join(", ");
|
|
64
|
+
if (schemaName) {
|
|
65
|
+
request.input("schemaName", sql.NVarChar, schemaName);
|
|
66
|
+
}
|
|
67
|
+
const schemaFilter = schemaName ? "AND s.name = @schemaName" : "";
|
|
68
|
+
const result = await request.query(`
|
|
69
|
+
SELECT
|
|
70
|
+
o.name,
|
|
71
|
+
s.name AS schemaName,
|
|
72
|
+
o.type AS typeCode,
|
|
73
|
+
o.type_desc AS typeDescription,
|
|
74
|
+
o.create_date AS createdAt,
|
|
75
|
+
o.modify_date AS modifiedAt
|
|
76
|
+
FROM sys.objects o
|
|
77
|
+
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
|
|
78
|
+
WHERE o.is_ms_shipped = 0
|
|
79
|
+
AND o.type IN (${typePlaceholders})
|
|
80
|
+
${schemaFilter}
|
|
81
|
+
ORDER BY s.name, o.name
|
|
82
|
+
`);
|
|
83
|
+
return result.recordset.map((row) => ({
|
|
84
|
+
...row,
|
|
85
|
+
objectType: getFriendlyObjectType(row.typeCode),
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
export async function describeDatabaseObject(objectName, databaseName, schemaName, objectTypes) {
|
|
89
|
+
const { request, error } = await getSqlRequest(databaseName);
|
|
90
|
+
if (error) {
|
|
91
|
+
throw new Error(error);
|
|
92
|
+
}
|
|
93
|
+
request.input("objectName", sql.NVarChar, objectName);
|
|
94
|
+
if (schemaName) {
|
|
95
|
+
request.input("schemaName", sql.NVarChar, schemaName);
|
|
96
|
+
}
|
|
97
|
+
let typeFilter = "";
|
|
98
|
+
if (objectTypes && objectTypes.length > 0) {
|
|
99
|
+
const typeCodes = getObjectTypeCodes(objectTypes);
|
|
100
|
+
const typePlaceholders = typeCodes
|
|
101
|
+
.map((code, index) => {
|
|
102
|
+
const parameterName = `describeTypeCode${index}`;
|
|
103
|
+
request.input(parameterName, sql.NVarChar, code);
|
|
104
|
+
return `@${parameterName}`;
|
|
105
|
+
})
|
|
106
|
+
.join(", ");
|
|
107
|
+
typeFilter = `AND o.type IN (${typePlaceholders})`;
|
|
108
|
+
}
|
|
109
|
+
const schemaFilter = schemaName ? "AND s.name = @schemaName" : "";
|
|
110
|
+
const objectResult = await request.query(`
|
|
111
|
+
SELECT TOP (2)
|
|
112
|
+
o.object_id AS objectId,
|
|
113
|
+
o.name,
|
|
114
|
+
s.name AS schemaName,
|
|
115
|
+
o.type AS typeCode,
|
|
116
|
+
o.type_desc AS typeDescription,
|
|
117
|
+
o.create_date AS createdAt,
|
|
118
|
+
o.modify_date AS modifiedAt,
|
|
119
|
+
sm.definition
|
|
120
|
+
FROM sys.objects o
|
|
121
|
+
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
|
|
122
|
+
LEFT JOIN sys.sql_modules sm ON sm.object_id = o.object_id
|
|
123
|
+
WHERE o.is_ms_shipped = 0
|
|
124
|
+
AND o.name = @objectName
|
|
125
|
+
${schemaFilter}
|
|
126
|
+
${typeFilter}
|
|
127
|
+
ORDER BY s.name, o.type, o.name
|
|
128
|
+
`);
|
|
129
|
+
const objectRows = objectResult.recordset;
|
|
130
|
+
if (objectRows.length > 1) {
|
|
131
|
+
const matches = objectRows
|
|
132
|
+
.map((row) => `${row.schemaName}.${row.name} (${getFriendlyObjectType(row.typeCode)})`)
|
|
133
|
+
.join(", ");
|
|
134
|
+
throw new Error(`Multiple objects named '${objectName}' matched the request. Specify schemaName or objectTypes to disambiguate. Matches: ${matches}.`);
|
|
135
|
+
}
|
|
136
|
+
const objectRow = objectRows[0];
|
|
137
|
+
if (!objectRow) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
request.input("objectId", sql.Int, objectRow.objectId);
|
|
141
|
+
const detailsResult = await request.query(`
|
|
142
|
+
SELECT
|
|
143
|
+
c.name,
|
|
144
|
+
t.name AS dataType,
|
|
145
|
+
c.max_length AS maxLength,
|
|
146
|
+
c.precision,
|
|
147
|
+
c.scale,
|
|
148
|
+
c.is_nullable AS isNullable,
|
|
149
|
+
c.is_identity AS isIdentity,
|
|
150
|
+
dc.definition AS defaultValue
|
|
151
|
+
FROM sys.columns c
|
|
152
|
+
INNER JOIN sys.types t ON t.user_type_id = c.user_type_id
|
|
153
|
+
LEFT JOIN sys.default_constraints dc
|
|
154
|
+
ON dc.parent_object_id = c.object_id
|
|
155
|
+
AND dc.parent_column_id = c.column_id
|
|
156
|
+
WHERE c.object_id = @objectId
|
|
157
|
+
ORDER BY c.column_id;
|
|
158
|
+
|
|
159
|
+
SELECT
|
|
160
|
+
i.name,
|
|
161
|
+
i.type_desc AS type,
|
|
162
|
+
i.is_unique AS isUnique,
|
|
163
|
+
c.name AS columnName,
|
|
164
|
+
ic.key_ordinal AS keyOrdinal
|
|
165
|
+
FROM sys.indexes i
|
|
166
|
+
INNER JOIN sys.index_columns ic
|
|
167
|
+
ON ic.object_id = i.object_id
|
|
168
|
+
AND ic.index_id = i.index_id
|
|
169
|
+
INNER JOIN sys.columns c
|
|
170
|
+
ON c.object_id = ic.object_id
|
|
171
|
+
AND c.column_id = ic.column_id
|
|
172
|
+
WHERE i.object_id = @objectId
|
|
173
|
+
AND i.is_hypothetical = 0
|
|
174
|
+
AND i.name IS NOT NULL
|
|
175
|
+
ORDER BY i.name, ic.key_ordinal
|
|
176
|
+
`);
|
|
177
|
+
const detailRecordsets = Array.isArray(detailsResult.recordsets)
|
|
178
|
+
? detailsResult.recordsets
|
|
179
|
+
: [];
|
|
180
|
+
const columnsRecordset = (Array.isArray(detailRecordsets[0])
|
|
181
|
+
? detailRecordsets[0]
|
|
182
|
+
: []);
|
|
183
|
+
const indexesRecordset = (Array.isArray(detailRecordsets[1])
|
|
184
|
+
? detailRecordsets[1]
|
|
185
|
+
: []);
|
|
186
|
+
const indexes = new Map();
|
|
187
|
+
for (const row of indexesRecordset) {
|
|
188
|
+
if (!indexes.has(row.name)) {
|
|
189
|
+
indexes.set(row.name, {
|
|
190
|
+
name: row.name,
|
|
191
|
+
type: row.type,
|
|
192
|
+
isUnique: row.isUnique,
|
|
193
|
+
columns: [],
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
indexes.get(row.name)?.columns.push(row.columnName);
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
name: objectRow.name,
|
|
200
|
+
schemaName: objectRow.schemaName,
|
|
201
|
+
objectType: getFriendlyObjectType(objectRow.typeCode),
|
|
202
|
+
typeCode: objectRow.typeCode,
|
|
203
|
+
typeDescription: objectRow.typeDescription,
|
|
204
|
+
createdAt: objectRow.createdAt,
|
|
205
|
+
modifiedAt: objectRow.modifiedAt,
|
|
206
|
+
definition: objectRow.definition,
|
|
207
|
+
columns: columnsRecordset,
|
|
208
|
+
indexes: [...indexes.values()],
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
export function listConfiguredDatabases() {
|
|
212
|
+
const defaultName = getDefaultDatabaseName();
|
|
213
|
+
return getAllowedDatabases().map((name) => ({
|
|
214
|
+
name,
|
|
215
|
+
isDefault: defaultName === name,
|
|
216
|
+
}));
|
|
217
|
+
}
|
|
218
|
+
export async function getDatabaseSchemaSummary(databaseName) {
|
|
219
|
+
const { request, error } = await getSqlRequest(databaseName);
|
|
220
|
+
if (error) {
|
|
221
|
+
throw new Error(error);
|
|
222
|
+
}
|
|
223
|
+
const result = await request.query(`
|
|
224
|
+
SELECT
|
|
225
|
+
CASE
|
|
226
|
+
WHEN o.type = 'U' THEN 'table'
|
|
227
|
+
WHEN o.type = 'V' THEN 'view'
|
|
228
|
+
WHEN o.type = 'P' THEN 'procedure'
|
|
229
|
+
WHEN o.type IN ('FN', 'IF', 'TF', 'FS', 'FT') THEN 'function'
|
|
230
|
+
WHEN o.type = 'TR' THEN 'trigger'
|
|
231
|
+
ELSE 'other'
|
|
232
|
+
END AS objectType,
|
|
233
|
+
COUNT(*) AS objectCount
|
|
234
|
+
FROM sys.objects o
|
|
235
|
+
WHERE o.is_ms_shipped = 0
|
|
236
|
+
GROUP BY CASE
|
|
237
|
+
WHEN o.type = 'U' THEN 'table'
|
|
238
|
+
WHEN o.type = 'V' THEN 'view'
|
|
239
|
+
WHEN o.type = 'P' THEN 'procedure'
|
|
240
|
+
WHEN o.type IN ('FN', 'IF', 'TF', 'FS', 'FT') THEN 'function'
|
|
241
|
+
WHEN o.type = 'TR' THEN 'trigger'
|
|
242
|
+
ELSE 'other'
|
|
243
|
+
END;
|
|
244
|
+
|
|
245
|
+
SELECT
|
|
246
|
+
s.name AS schemaName,
|
|
247
|
+
COUNT(*) AS objectCount
|
|
248
|
+
FROM sys.objects o
|
|
249
|
+
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
|
|
250
|
+
WHERE o.is_ms_shipped = 0
|
|
251
|
+
GROUP BY s.name
|
|
252
|
+
ORDER BY objectCount DESC, s.name;
|
|
253
|
+
`);
|
|
254
|
+
const recordsets = Array.isArray(result.recordsets) ? result.recordsets : [];
|
|
255
|
+
return {
|
|
256
|
+
objectCounts: recordsets[0] ?? [],
|
|
257
|
+
schemaCounts: recordsets[1] ?? [],
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
export async function listForeignKeys(databaseName, schemaName) {
|
|
261
|
+
const { request, error } = await getSqlRequest(databaseName);
|
|
262
|
+
if (error) {
|
|
263
|
+
throw new Error(error);
|
|
264
|
+
}
|
|
265
|
+
if (schemaName) {
|
|
266
|
+
request.input("schemaName", sql.NVarChar, schemaName);
|
|
267
|
+
}
|
|
268
|
+
const schemaFilter = schemaName
|
|
269
|
+
? "AND (ps.name = @schemaName OR rs.name = @schemaName)"
|
|
270
|
+
: "";
|
|
271
|
+
const result = await request.query(`
|
|
272
|
+
SELECT
|
|
273
|
+
fk.name AS foreignKeyName,
|
|
274
|
+
ps.name AS parentSchemaName,
|
|
275
|
+
pt.name AS parentTableName,
|
|
276
|
+
pc.name AS parentColumnName,
|
|
277
|
+
rs.name AS referencedSchemaName,
|
|
278
|
+
rt.name AS referencedTableName,
|
|
279
|
+
rc.name AS referencedColumnName,
|
|
280
|
+
fk.delete_referential_action_desc AS onDelete,
|
|
281
|
+
fk.update_referential_action_desc AS onUpdate
|
|
282
|
+
FROM sys.foreign_keys fk
|
|
283
|
+
INNER JOIN sys.foreign_key_columns fkc
|
|
284
|
+
ON fkc.constraint_object_id = fk.object_id
|
|
285
|
+
INNER JOIN sys.tables pt
|
|
286
|
+
ON pt.object_id = fk.parent_object_id
|
|
287
|
+
INNER JOIN sys.schemas ps
|
|
288
|
+
ON ps.schema_id = pt.schema_id
|
|
289
|
+
INNER JOIN sys.columns pc
|
|
290
|
+
ON pc.object_id = pt.object_id
|
|
291
|
+
AND pc.column_id = fkc.parent_column_id
|
|
292
|
+
INNER JOIN sys.tables rt
|
|
293
|
+
ON rt.object_id = fk.referenced_object_id
|
|
294
|
+
INNER JOIN sys.schemas rs
|
|
295
|
+
ON rs.schema_id = rt.schema_id
|
|
296
|
+
INNER JOIN sys.columns rc
|
|
297
|
+
ON rc.object_id = rt.object_id
|
|
298
|
+
AND rc.column_id = fkc.referenced_column_id
|
|
299
|
+
WHERE 1 = 1
|
|
300
|
+
${schemaFilter}
|
|
301
|
+
ORDER BY ps.name, pt.name, fk.name, fkc.constraint_column_id
|
|
302
|
+
`);
|
|
303
|
+
return result.recordset;
|
|
304
|
+
}
|
|
305
|
+
export async function describeRelationships(tableName, databaseName, schemaName) {
|
|
306
|
+
const foreignKeys = await listForeignKeys(databaseName, schemaName);
|
|
307
|
+
return foreignKeys.filter((row) => row.parentTableName === tableName || row.referencedTableName === tableName);
|
|
308
|
+
}
|
|
309
|
+
export async function describeObjectDependencies(objectName, databaseName, schemaName) {
|
|
310
|
+
const { request, error } = await getSqlRequest(databaseName);
|
|
311
|
+
if (error) {
|
|
312
|
+
throw new Error(error);
|
|
313
|
+
}
|
|
314
|
+
request.input("objectName", sql.NVarChar, objectName);
|
|
315
|
+
if (schemaName) {
|
|
316
|
+
request.input("schemaName", sql.NVarChar, schemaName);
|
|
317
|
+
}
|
|
318
|
+
const schemaFilter = schemaName ? "AND s.name = @schemaName" : "";
|
|
319
|
+
const result = await request.query(`
|
|
320
|
+
SELECT
|
|
321
|
+
referencingSchema.name AS referencingSchemaName,
|
|
322
|
+
referencing.name AS referencingObjectName,
|
|
323
|
+
referencing.type_desc AS referencingType,
|
|
324
|
+
referenced.referenced_schema_name AS referencedSchemaName,
|
|
325
|
+
referenced.referenced_entity_name AS referencedEntityName
|
|
326
|
+
FROM sys.objects target
|
|
327
|
+
INNER JOIN sys.schemas s ON s.schema_id = target.schema_id
|
|
328
|
+
INNER JOIN sys.sql_expression_dependencies referenced
|
|
329
|
+
ON referenced.referenced_id = target.object_id
|
|
330
|
+
INNER JOIN sys.objects referencing
|
|
331
|
+
ON referencing.object_id = referenced.referencing_id
|
|
332
|
+
INNER JOIN sys.schemas referencingSchema
|
|
333
|
+
ON referencingSchema.schema_id = referencing.schema_id
|
|
334
|
+
WHERE target.name = @objectName
|
|
335
|
+
${schemaFilter}
|
|
336
|
+
ORDER BY referencingSchema.name, referencing.name;
|
|
337
|
+
`);
|
|
338
|
+
return result.recordset;
|
|
339
|
+
}
|
|
340
|
+
export async function analyzeTable(tableName, databaseName, schemaName) {
|
|
341
|
+
const { request, error } = await getSqlRequest(databaseName);
|
|
342
|
+
if (error) {
|
|
343
|
+
throw new Error(error);
|
|
344
|
+
}
|
|
345
|
+
request.input("tableName", sql.NVarChar, tableName);
|
|
346
|
+
if (schemaName) {
|
|
347
|
+
request.input("schemaName", sql.NVarChar, schemaName);
|
|
348
|
+
}
|
|
349
|
+
const schemaFilter = schemaName ? "AND s.name = @schemaName" : "";
|
|
350
|
+
const result = await request.query(`
|
|
351
|
+
SELECT TOP (1)
|
|
352
|
+
s.name AS schemaName,
|
|
353
|
+
t.name AS tableName,
|
|
354
|
+
SUM(p.row_count) AS [rowCount],
|
|
355
|
+
CAST(SUM(a.total_pages) * 8.0 / 1024 AS DECIMAL(12, 2)) AS reservedMB,
|
|
356
|
+
CAST(SUM(a.used_pages) * 8.0 / 1024 AS DECIMAL(12, 2)) AS usedMB
|
|
357
|
+
FROM sys.tables t
|
|
358
|
+
INNER JOIN sys.schemas s ON s.schema_id = t.schema_id
|
|
359
|
+
INNER JOIN sys.dm_db_partition_stats p ON p.object_id = t.object_id
|
|
360
|
+
INNER JOIN sys.partitions sp ON sp.partition_id = p.partition_id
|
|
361
|
+
INNER JOIN sys.allocation_units a ON a.container_id = sp.hobt_id
|
|
362
|
+
WHERE t.name = @tableName
|
|
363
|
+
${schemaFilter}
|
|
364
|
+
GROUP BY s.name, t.name
|
|
365
|
+
ORDER BY s.name, t.name;
|
|
366
|
+
|
|
367
|
+
SELECT
|
|
368
|
+
i.name,
|
|
369
|
+
i.type_desc AS type,
|
|
370
|
+
i.is_unique AS isUnique,
|
|
371
|
+
i.is_primary_key AS isPrimaryKey
|
|
372
|
+
FROM sys.indexes i
|
|
373
|
+
INNER JOIN sys.tables t ON t.object_id = i.object_id
|
|
374
|
+
INNER JOIN sys.schemas s ON s.schema_id = t.schema_id
|
|
375
|
+
WHERE t.name = @tableName
|
|
376
|
+
${schemaFilter}
|
|
377
|
+
AND i.index_id > 0
|
|
378
|
+
ORDER BY i.name;
|
|
379
|
+
`);
|
|
380
|
+
const recordsets = Array.isArray(result.recordsets) ? result.recordsets : [];
|
|
381
|
+
const rawRows = recordsets[1];
|
|
382
|
+
const indexes = rawRows !== undefined && rawRows !== null
|
|
383
|
+
? Array.from(rawRows)
|
|
384
|
+
: [];
|
|
385
|
+
return {
|
|
386
|
+
summary: recordsets[0]?.[0] ?? null,
|
|
387
|
+
indexes,
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
interface StoredQueryPlan {
|
|
2
|
+
id: string;
|
|
3
|
+
databaseName: string | null;
|
|
4
|
+
query: string;
|
|
5
|
+
planXml: string;
|
|
6
|
+
createdAt: string;
|
|
7
|
+
}
|
|
8
|
+
interface StoredQueryResult {
|
|
9
|
+
id: string;
|
|
10
|
+
databaseName: string | null;
|
|
11
|
+
label: string;
|
|
12
|
+
payload: unknown;
|
|
13
|
+
createdAt: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class ServerState {
|
|
16
|
+
private readonly queryPlans;
|
|
17
|
+
private readonly queryResults;
|
|
18
|
+
private purgeExpiredQueryArtifacts;
|
|
19
|
+
private evictOldestByCreatedAt;
|
|
20
|
+
storeQueryPlan(databaseName: string | undefined, query: string, planXml: string): StoredQueryPlan;
|
|
21
|
+
getQueryPlan(id: string): StoredQueryPlan | undefined;
|
|
22
|
+
listQueryPlans(): StoredQueryPlan[];
|
|
23
|
+
storeQueryResult(databaseName: string | undefined, label: string, payload: unknown): StoredQueryResult;
|
|
24
|
+
getQueryResult(id: string): StoredQueryResult | undefined;
|
|
25
|
+
listQueryResults(): StoredQueryResult[];
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=serverState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverState.d.ts","sourceRoot":"","sources":["../src/serverState.ts"],"names":[],"mappings":"AAEA,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAoBD,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsC;IACjE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwC;IAErE,OAAO,CAAC,0BAA0B;IAalC,OAAO,CAAC,sBAAsB;IAkB9B,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAiB/E,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAKrD,cAAc,IAAI,eAAe,EAAE;IAOnC,gBAAgB,CACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO;IAwBlB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAKzD,gBAAgB,IAAI,iBAAiB,EAAE;CAMxC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
const DEFAULT_MAX_QUERY_PLANS = 100;
|
|
3
|
+
const DEFAULT_MAX_QUERY_RESULTS = 100;
|
|
4
|
+
const QUERY_ARTIFACT_TTL_MS = 60 * 60 * 1000;
|
|
5
|
+
function hashParts(parts) {
|
|
6
|
+
const hash = createHash("sha256");
|
|
7
|
+
for (const part of parts) {
|
|
8
|
+
hash.update(part ?? "");
|
|
9
|
+
hash.update("\0");
|
|
10
|
+
}
|
|
11
|
+
return hash.digest("hex").slice(0, 16);
|
|
12
|
+
}
|
|
13
|
+
function parseIsoMs(iso) {
|
|
14
|
+
const t = Date.parse(iso);
|
|
15
|
+
return Number.isFinite(t) ? t : 0;
|
|
16
|
+
}
|
|
17
|
+
export class ServerState {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.queryPlans = new Map();
|
|
20
|
+
this.queryResults = new Map();
|
|
21
|
+
}
|
|
22
|
+
purgeExpiredQueryArtifacts(now) {
|
|
23
|
+
for (const [id, plan] of this.queryPlans) {
|
|
24
|
+
if (parseIsoMs(plan.createdAt) + QUERY_ARTIFACT_TTL_MS < now) {
|
|
25
|
+
this.queryPlans.delete(id);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
for (const [id, result] of this.queryResults) {
|
|
29
|
+
if (parseIsoMs(result.createdAt) + QUERY_ARTIFACT_TTL_MS < now) {
|
|
30
|
+
this.queryResults.delete(id);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
evictOldestByCreatedAt(map, maxEntries) {
|
|
35
|
+
if (map.size <= maxEntries) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const sorted = [...map.values()].sort((a, b) => parseIsoMs(a.createdAt) - parseIsoMs(b.createdAt));
|
|
39
|
+
while (map.size > maxEntries && sorted.length > 0) {
|
|
40
|
+
const oldest = sorted.shift();
|
|
41
|
+
if (oldest) {
|
|
42
|
+
map.delete(oldest.id);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
storeQueryPlan(databaseName, query, planXml) {
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
this.purgeExpiredQueryArtifacts(now);
|
|
49
|
+
const createdAt = new Date().toISOString();
|
|
50
|
+
const id = hashParts([databaseName, query, planXml]);
|
|
51
|
+
const entry = {
|
|
52
|
+
id,
|
|
53
|
+
databaseName: databaseName ?? null,
|
|
54
|
+
query,
|
|
55
|
+
planXml,
|
|
56
|
+
createdAt,
|
|
57
|
+
};
|
|
58
|
+
this.queryPlans.set(id, entry);
|
|
59
|
+
this.evictOldestByCreatedAt(this.queryPlans, DEFAULT_MAX_QUERY_PLANS);
|
|
60
|
+
return entry;
|
|
61
|
+
}
|
|
62
|
+
getQueryPlan(id) {
|
|
63
|
+
this.purgeExpiredQueryArtifacts(Date.now());
|
|
64
|
+
return this.queryPlans.get(id);
|
|
65
|
+
}
|
|
66
|
+
listQueryPlans() {
|
|
67
|
+
this.purgeExpiredQueryArtifacts(Date.now());
|
|
68
|
+
return [...this.queryPlans.values()].sort((a, b) => a.createdAt < b.createdAt ? 1 : -1);
|
|
69
|
+
}
|
|
70
|
+
storeQueryResult(databaseName, label, payload) {
|
|
71
|
+
const now = Date.now();
|
|
72
|
+
this.purgeExpiredQueryArtifacts(now);
|
|
73
|
+
const createdAt = new Date().toISOString();
|
|
74
|
+
const id = hashParts([
|
|
75
|
+
databaseName,
|
|
76
|
+
label,
|
|
77
|
+
JSON.stringify(payload, (_key, value) => value instanceof Date ? value.toISOString() : value),
|
|
78
|
+
]);
|
|
79
|
+
const entry = {
|
|
80
|
+
id,
|
|
81
|
+
databaseName: databaseName ?? null,
|
|
82
|
+
label,
|
|
83
|
+
payload,
|
|
84
|
+
createdAt,
|
|
85
|
+
};
|
|
86
|
+
this.queryResults.set(id, entry);
|
|
87
|
+
this.evictOldestByCreatedAt(this.queryResults, DEFAULT_MAX_QUERY_RESULTS);
|
|
88
|
+
return entry;
|
|
89
|
+
}
|
|
90
|
+
getQueryResult(id) {
|
|
91
|
+
this.purgeExpiredQueryArtifacts(Date.now());
|
|
92
|
+
return this.queryResults.get(id);
|
|
93
|
+
}
|
|
94
|
+
listQueryResults() {
|
|
95
|
+
this.purgeExpiredQueryArtifacts(Date.now());
|
|
96
|
+
return [...this.queryResults.values()].sort((a, b) => a.createdAt < b.createdAt ? 1 : -1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=serverState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverState.js","sourceRoot":"","sources":["../src/serverState.ts"],"names":[],"mappings":"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"}
|
package/dist/sql.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function isSafeSqlIdentifier(value: string): boolean;
|
|
2
|
+
export declare function assertSafeSqlIdentifier(value: string, label?: string): void;
|
|
3
|
+
export declare function quoteIdentifier(value: string): string;
|
|
4
|
+
export declare function buildQualifiedName(objectName: string, schemaName?: string): string;
|
|
5
|
+
export declare function getFriendlyObjectType(typeCode: string): string;
|
|
6
|
+
export declare function getObjectTypeCodes(objectTypes?: string[]): string[];
|
|
7
|
+
//# sourceMappingURL=sql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../src/sql.ts"],"names":[],"mappings":"AAWA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAM1D;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EACb,KAAK,SAAe,GACnB,IAAI,CAIN;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAQR;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmB9D;AAED,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA0BnE"}
|
package/dist/sql.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
function containsControlCharacters(value) {
|
|
2
|
+
for (const character of value) {
|
|
3
|
+
const codePoint = character.charCodeAt(0);
|
|
4
|
+
if (codePoint < 32 || codePoint === 127) {
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
export function isSafeSqlIdentifier(value) {
|
|
11
|
+
return (typeof value === "string" &&
|
|
12
|
+
value.trim().length > 0 &&
|
|
13
|
+
!containsControlCharacters(value));
|
|
14
|
+
}
|
|
15
|
+
export function assertSafeSqlIdentifier(value, label = "identifier") {
|
|
16
|
+
if (!isSafeSqlIdentifier(value)) {
|
|
17
|
+
throw new Error(`Invalid ${label}.`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function quoteIdentifier(value) {
|
|
21
|
+
assertSafeSqlIdentifier(value);
|
|
22
|
+
return `[${value.replace(/\]/g, "]]")}]`;
|
|
23
|
+
}
|
|
24
|
+
export function buildQualifiedName(objectName, schemaName) {
|
|
25
|
+
assertSafeSqlIdentifier(objectName, "object name");
|
|
26
|
+
if (!schemaName) {
|
|
27
|
+
return quoteIdentifier(objectName);
|
|
28
|
+
}
|
|
29
|
+
assertSafeSqlIdentifier(schemaName, "schema name");
|
|
30
|
+
return `${quoteIdentifier(schemaName)}.${quoteIdentifier(objectName)}`;
|
|
31
|
+
}
|
|
32
|
+
export function getFriendlyObjectType(typeCode) {
|
|
33
|
+
switch (typeCode) {
|
|
34
|
+
case "U":
|
|
35
|
+
return "table";
|
|
36
|
+
case "V":
|
|
37
|
+
return "view";
|
|
38
|
+
case "P":
|
|
39
|
+
return "procedure";
|
|
40
|
+
case "FN":
|
|
41
|
+
case "IF":
|
|
42
|
+
case "TF":
|
|
43
|
+
case "FS":
|
|
44
|
+
case "FT":
|
|
45
|
+
return "function";
|
|
46
|
+
case "TR":
|
|
47
|
+
return "trigger";
|
|
48
|
+
default:
|
|
49
|
+
return "object";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function getObjectTypeCodes(objectTypes) {
|
|
53
|
+
if (!objectTypes || objectTypes.length === 0) {
|
|
54
|
+
return ["U", "V", "P", "FN", "IF", "TF", "FS", "FT", "TR"];
|
|
55
|
+
}
|
|
56
|
+
const typeMap = {
|
|
57
|
+
table: ["U"],
|
|
58
|
+
view: ["V"],
|
|
59
|
+
procedure: ["P"],
|
|
60
|
+
function: ["FN", "IF", "TF", "FS", "FT"],
|
|
61
|
+
trigger: ["TR"],
|
|
62
|
+
};
|
|
63
|
+
const resolvedCodes = objectTypes.flatMap((objectType) => {
|
|
64
|
+
const normalized = objectType.trim().toLowerCase();
|
|
65
|
+
const codes = typeMap[normalized];
|
|
66
|
+
if (!codes) {
|
|
67
|
+
throw new Error(`Unsupported object type '${objectType}'. Expected one of: ${Object.keys(typeMap).join(", ")}.`);
|
|
68
|
+
}
|
|
69
|
+
return codes;
|
|
70
|
+
});
|
|
71
|
+
return [...new Set(resolvedCodes)];
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=sql.js.map
|
package/dist/sql.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.js","sourceRoot":"","sources":["../src/sql.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export interface RunnableTool {
|
|
4
|
+
name: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
run(params: unknown): Promise<unknown>;
|
|
7
|
+
}
|
|
8
|
+
export interface ToolDefinition {
|
|
9
|
+
tool: RunnableTool;
|
|
10
|
+
inputSchema: z.ZodType;
|
|
11
|
+
outputSchema: z.ZodRawShape;
|
|
12
|
+
annotations: ToolAnnotations;
|
|
13
|
+
readOnly: boolean;
|
|
14
|
+
requiresConfirmation?: boolean;
|
|
15
|
+
requiresDdl?: boolean;
|
|
16
|
+
writePreviewTool?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const toolDefinitions: ToolDefinition[];
|
|
19
|
+
export declare function getAvailableTools(isReadOnly: boolean): ToolDefinition[];
|
|
20
|
+
//# sourceMappingURL=toolRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolRegistry.d.ts","sourceRoot":"","sources":["../src/toolRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE1E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAyBxB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC;IACvB,YAAY,EAAE,CAAC,CAAC,WAAW,CAAC;IAC5B,WAAW,EAAE,eAAe,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAoHD,eAAO,MAAM,eAAe,EAAE,cAAc,EAwd3C,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,OAAO,GAAG,cAAc,EAAE,CAIvE"}
|