@sigma4life/mysql-mcp-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +35 -0
- package/.github/workflows/ci.yml +18 -0
- package/AUTHENTICATION.md +24 -0
- package/CLAUDE.md +37 -0
- package/CONTRIBUTING.md +19 -0
- package/LICENSE +21 -0
- package/QUERY_ACCESS_SETUP.md +65 -0
- package/README.md +144 -0
- package/SECURITY.md +10 -0
- package/TESTING.md +54 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +197 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/cache.d.ts +11 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +30 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/config.d.ts +24 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +63 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/database-url.d.ts +11 -0
- package/dist/core/database-url.d.ts.map +1 -0
- package/dist/core/database-url.js +37 -0
- package/dist/core/database-url.js.map +1 -0
- package/dist/core/database-url.test.d.ts +2 -0
- package/dist/core/database-url.test.d.ts.map +1 -0
- package/dist/core/database-url.test.js +22 -0
- package/dist/core/database-url.test.js.map +1 -0
- package/dist/core/logger.d.ts +3 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +17 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/mcp.d.ts +14 -0
- package/dist/core/mcp.d.ts.map +1 -0
- package/dist/core/mcp.js +23 -0
- package/dist/core/mcp.js.map +1 -0
- package/dist/core/query-safety.d.ts +10 -0
- package/dist/core/query-safety.d.ts.map +1 -0
- package/dist/core/query-safety.js +50 -0
- package/dist/core/query-safety.js.map +1 -0
- package/dist/core/query-safety.test.d.ts +2 -0
- package/dist/core/query-safety.test.d.ts.map +1 -0
- package/dist/core/query-safety.test.js +30 -0
- package/dist/core/query-safety.test.js.map +1 -0
- package/dist/core/schema-types.d.ts +53 -0
- package/dist/core/schema-types.d.ts.map +1 -0
- package/dist/core/schema-types.js +2 -0
- package/dist/core/schema-types.js.map +1 -0
- package/dist/core/security/access-control.d.ts +32 -0
- package/dist/core/security/access-control.d.ts.map +1 -0
- package/dist/core/security/access-control.js +244 -0
- package/dist/core/security/access-control.js.map +1 -0
- package/dist/core/security/config-loader.d.ts +20 -0
- package/dist/core/security/config-loader.d.ts.map +1 -0
- package/dist/core/security/config-loader.js +227 -0
- package/dist/core/security/config-loader.js.map +1 -0
- package/dist/core/security/types.d.ts +64 -0
- package/dist/core/security/types.d.ts.map +1 -0
- package/dist/core/security/types.js +28 -0
- package/dist/core/security/types.js.map +1 -0
- package/dist/core/sql-parser.d.ts +23 -0
- package/dist/core/sql-parser.d.ts.map +1 -0
- package/dist/core/sql-parser.js +460 -0
- package/dist/core/sql-parser.js.map +1 -0
- package/dist/core/sql-parser.test.d.ts +2 -0
- package/dist/core/sql-parser.test.d.ts.map +1 -0
- package/dist/core/sql-parser.test.js +21 -0
- package/dist/core/sql-parser.test.js.map +1 -0
- package/dist/handlers/accessible-schema.d.ts +53 -0
- package/dist/handlers/accessible-schema.d.ts.map +1 -0
- package/dist/handlers/accessible-schema.js +192 -0
- package/dist/handlers/accessible-schema.js.map +1 -0
- package/dist/handlers/data.d.ts +17 -0
- package/dist/handlers/data.d.ts.map +1 -0
- package/dist/handlers/data.js +30 -0
- package/dist/handlers/data.js.map +1 -0
- package/dist/handlers/relationships.d.ts +14 -0
- package/dist/handlers/relationships.d.ts.map +1 -0
- package/dist/handlers/relationships.js +77 -0
- package/dist/handlers/relationships.js.map +1 -0
- package/dist/handlers/schema.d.ts +14 -0
- package/dist/handlers/schema.d.ts.map +1 -0
- package/dist/handlers/schema.js +104 -0
- package/dist/handlers/schema.js.map +1 -0
- package/dist/handlers/search.d.ts +14 -0
- package/dist/handlers/search.d.ts.map +1 -0
- package/dist/handlers/search.js +18 -0
- package/dist/handlers/search.js.map +1 -0
- package/dist/handlers/validation.d.ts +32 -0
- package/dist/handlers/validation.d.ts.map +1 -0
- package/dist/handlers/validation.js +116 -0
- package/dist/handlers/validation.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +294 -0
- package/dist/index.js.map +1 -0
- package/dist/mysql/connection.d.ts +15 -0
- package/dist/mysql/connection.d.ts.map +1 -0
- package/dist/mysql/connection.js +57 -0
- package/dist/mysql/connection.js.map +1 -0
- package/dist/mysql/identifiers.d.ts +3 -0
- package/dist/mysql/identifiers.d.ts.map +1 -0
- package/dist/mysql/identifiers.js +10 -0
- package/dist/mysql/identifiers.js.map +1 -0
- package/dist/mysql/identifiers.test.d.ts +2 -0
- package/dist/mysql/identifiers.test.d.ts.map +1 -0
- package/dist/mysql/identifiers.test.js +11 -0
- package/dist/mysql/identifiers.test.js.map +1 -0
- package/dist/mysql/queries.d.ts +49 -0
- package/dist/mysql/queries.d.ts.map +1 -0
- package/dist/mysql/queries.js +206 -0
- package/dist/mysql/queries.js.map +1 -0
- package/docs/clients/claude-code.md +28 -0
- package/docs/clients/claude-desktop.md +35 -0
- package/docs/clients/codex.md +28 -0
- package/docs/clients/cursor.md +26 -0
- package/docs/clients/opencode.md +35 -0
- package/docs/clients/vscode.md +25 -0
- package/package.json +49 -0
- package/query-access.example.json +21 -0
- package/src/cli.ts +221 -0
- package/src/core/cache.ts +41 -0
- package/src/core/config.ts +97 -0
- package/src/core/database-url.test.ts +28 -0
- package/src/core/database-url.ts +47 -0
- package/src/core/logger.ts +24 -0
- package/src/core/mcp.ts +23 -0
- package/src/core/query-safety.test.ts +36 -0
- package/src/core/query-safety.ts +63 -0
- package/src/core/schema-types.ts +58 -0
- package/src/core/security/access-control.ts +321 -0
- package/src/core/security/config-loader.ts +315 -0
- package/src/core/security/types.ts +114 -0
- package/src/core/sql-parser.test.ts +37 -0
- package/src/core/sql-parser.ts +572 -0
- package/src/handlers/accessible-schema.ts +314 -0
- package/src/handlers/data.ts +66 -0
- package/src/handlers/relationships.ts +114 -0
- package/src/handlers/schema.ts +154 -0
- package/src/handlers/search.ts +34 -0
- package/src/handlers/validation.ts +165 -0
- package/src/index.ts +337 -0
- package/src/mysql/connection.ts +68 -0
- package/src/mysql/identifiers.test.ts +12 -0
- package/src/mysql/identifiers.ts +10 -0
- package/src/mysql/queries.ts +285 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { appConfig } from '../core/config.js';
|
|
2
|
+
import {
|
|
3
|
+
ColumnMetadata,
|
|
4
|
+
ForeignKeyMetadata,
|
|
5
|
+
IndexMetadata,
|
|
6
|
+
PrimaryKeyMetadata,
|
|
7
|
+
StatisticsMetadata,
|
|
8
|
+
} from '../core/schema-types.js';
|
|
9
|
+
import { db } from './connection.js';
|
|
10
|
+
import { likePattern } from './identifiers.js';
|
|
11
|
+
|
|
12
|
+
interface TableRow {
|
|
13
|
+
schemaName: string;
|
|
14
|
+
tableName: string;
|
|
15
|
+
tableType: 'BASE TABLE' | 'VIEW';
|
|
16
|
+
createDate: Date | null;
|
|
17
|
+
rowCount: number | null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface TableSearchResult {
|
|
21
|
+
schemaName: string;
|
|
22
|
+
tableName: string;
|
|
23
|
+
rowCount?: number;
|
|
24
|
+
createDate?: Date | null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ObjectSearchResult {
|
|
28
|
+
schemaName: string;
|
|
29
|
+
tableName?: string;
|
|
30
|
+
columnName?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface Relationship {
|
|
34
|
+
fromSchema: string;
|
|
35
|
+
fromTable: string;
|
|
36
|
+
fromColumn: string;
|
|
37
|
+
toSchema: string;
|
|
38
|
+
toTable: string;
|
|
39
|
+
toColumn: string;
|
|
40
|
+
constraintName: string;
|
|
41
|
+
deleteAction: string;
|
|
42
|
+
updateAction: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function listTables(tableNames?: string[]): Promise<TableRow[]> {
|
|
46
|
+
const tableFilter = tableNames?.length
|
|
47
|
+
? 'AND t.TABLE_NAME IN (:tableNames)'
|
|
48
|
+
: '';
|
|
49
|
+
return db.query<TableRow & any>(
|
|
50
|
+
`
|
|
51
|
+
SELECT
|
|
52
|
+
t.TABLE_SCHEMA AS schemaName,
|
|
53
|
+
t.TABLE_NAME AS tableName,
|
|
54
|
+
t.TABLE_TYPE AS tableType,
|
|
55
|
+
t.CREATE_TIME AS createDate,
|
|
56
|
+
t.TABLE_ROWS AS rowCount
|
|
57
|
+
FROM information_schema.TABLES t
|
|
58
|
+
WHERE t.TABLE_SCHEMA = :database
|
|
59
|
+
AND t.TABLE_TYPE IN ('BASE TABLE', 'VIEW')
|
|
60
|
+
${tableFilter}
|
|
61
|
+
ORDER BY t.TABLE_NAME
|
|
62
|
+
`,
|
|
63
|
+
{ database: appConfig.db.name, tableNames },
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export async function getColumns(tableNames?: string[]): Promise<ColumnMetadata[]> {
|
|
68
|
+
const tableFilter = tableNames?.length
|
|
69
|
+
? 'AND c.TABLE_NAME IN (:tableNames)'
|
|
70
|
+
: '';
|
|
71
|
+
return db.query<ColumnMetadata & any>(
|
|
72
|
+
`
|
|
73
|
+
SELECT
|
|
74
|
+
c.COLUMN_NAME AS name,
|
|
75
|
+
c.ORDINAL_POSITION AS ordinal,
|
|
76
|
+
c.COLUMN_TYPE AS dataType,
|
|
77
|
+
CASE WHEN c.IS_NULLABLE = 'YES' THEN true ELSE false END AS nullable,
|
|
78
|
+
CASE WHEN c.EXTRA LIKE '%auto_increment%' THEN true ELSE false END AS isIdentity,
|
|
79
|
+
CASE WHEN c.EXTRA LIKE '%VIRTUAL GENERATED%' OR c.EXTRA LIKE '%STORED GENERATED%' THEN true ELSE false END AS isComputed,
|
|
80
|
+
c.COLUMN_DEFAULT AS defaultValue,
|
|
81
|
+
c.COLUMN_COMMENT AS description,
|
|
82
|
+
CASE WHEN kcu.CONSTRAINT_NAME = 'PRIMARY' THEN true ELSE false END AS isPrimaryKey,
|
|
83
|
+
CASE WHEN fk.CONSTRAINT_NAME IS NOT NULL THEN true ELSE false END AS isForeignKey,
|
|
84
|
+
c.TABLE_SCHEMA AS \`schema\`,
|
|
85
|
+
c.TABLE_NAME AS tableName
|
|
86
|
+
FROM information_schema.COLUMNS c
|
|
87
|
+
LEFT JOIN information_schema.KEY_COLUMN_USAGE kcu
|
|
88
|
+
ON kcu.TABLE_SCHEMA = c.TABLE_SCHEMA
|
|
89
|
+
AND kcu.TABLE_NAME = c.TABLE_NAME
|
|
90
|
+
AND kcu.COLUMN_NAME = c.COLUMN_NAME
|
|
91
|
+
AND kcu.CONSTRAINT_NAME = 'PRIMARY'
|
|
92
|
+
LEFT JOIN information_schema.KEY_COLUMN_USAGE fk
|
|
93
|
+
ON fk.TABLE_SCHEMA = c.TABLE_SCHEMA
|
|
94
|
+
AND fk.TABLE_NAME = c.TABLE_NAME
|
|
95
|
+
AND fk.COLUMN_NAME = c.COLUMN_NAME
|
|
96
|
+
AND fk.REFERENCED_TABLE_NAME IS NOT NULL
|
|
97
|
+
WHERE c.TABLE_SCHEMA = :database
|
|
98
|
+
${tableFilter}
|
|
99
|
+
ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION
|
|
100
|
+
`,
|
|
101
|
+
{ database: appConfig.db.name, tableNames },
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export async function getPrimaryKeys(tableNames?: string[]): Promise<(PrimaryKeyMetadata & { tableName: string })[]> {
|
|
106
|
+
const tableFilter = tableNames?.length
|
|
107
|
+
? 'AND kcu.TABLE_NAME IN (:tableNames)'
|
|
108
|
+
: '';
|
|
109
|
+
return db.query<PrimaryKeyMetadata & { tableName: string } & any>(
|
|
110
|
+
`
|
|
111
|
+
SELECT
|
|
112
|
+
kcu.TABLE_NAME AS tableName,
|
|
113
|
+
kcu.CONSTRAINT_NAME AS constraintName,
|
|
114
|
+
GROUP_CONCAT(kcu.COLUMN_NAME ORDER BY kcu.ORDINAL_POSITION SEPARATOR ',') AS columns
|
|
115
|
+
FROM information_schema.KEY_COLUMN_USAGE kcu
|
|
116
|
+
WHERE kcu.TABLE_SCHEMA = :database
|
|
117
|
+
AND kcu.CONSTRAINT_NAME = 'PRIMARY'
|
|
118
|
+
${tableFilter}
|
|
119
|
+
GROUP BY kcu.TABLE_NAME, kcu.CONSTRAINT_NAME
|
|
120
|
+
`,
|
|
121
|
+
{ database: appConfig.db.name, tableNames },
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export async function getForeignKeys(tableNames?: string[]): Promise<(ForeignKeyMetadata & { tableName: string })[]> {
|
|
126
|
+
const tableFilter = tableNames?.length
|
|
127
|
+
? 'AND kcu.TABLE_NAME IN (:tableNames)'
|
|
128
|
+
: '';
|
|
129
|
+
return db.query<ForeignKeyMetadata & { tableName: string } & any>(
|
|
130
|
+
`
|
|
131
|
+
SELECT
|
|
132
|
+
kcu.TABLE_NAME AS tableName,
|
|
133
|
+
kcu.CONSTRAINT_NAME AS constraintName,
|
|
134
|
+
kcu.TABLE_SCHEMA AS fromSchema,
|
|
135
|
+
kcu.TABLE_NAME AS fromTable,
|
|
136
|
+
GROUP_CONCAT(kcu.COLUMN_NAME ORDER BY kcu.ORDINAL_POSITION SEPARATOR ',') AS fromColumns,
|
|
137
|
+
kcu.REFERENCED_TABLE_SCHEMA AS toSchema,
|
|
138
|
+
kcu.REFERENCED_TABLE_NAME AS toTable,
|
|
139
|
+
GROUP_CONCAT(kcu.REFERENCED_COLUMN_NAME ORDER BY kcu.ORDINAL_POSITION SEPARATOR ',') AS toColumns,
|
|
140
|
+
rc.DELETE_RULE AS onDelete,
|
|
141
|
+
rc.UPDATE_RULE AS onUpdate
|
|
142
|
+
FROM information_schema.KEY_COLUMN_USAGE kcu
|
|
143
|
+
JOIN information_schema.REFERENTIAL_CONSTRAINTS rc
|
|
144
|
+
ON rc.CONSTRAINT_SCHEMA = kcu.CONSTRAINT_SCHEMA
|
|
145
|
+
AND rc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
|
|
146
|
+
WHERE kcu.TABLE_SCHEMA = :database
|
|
147
|
+
AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
|
|
148
|
+
${tableFilter}
|
|
149
|
+
GROUP BY
|
|
150
|
+
kcu.TABLE_NAME,
|
|
151
|
+
kcu.CONSTRAINT_NAME,
|
|
152
|
+
kcu.TABLE_SCHEMA,
|
|
153
|
+
kcu.REFERENCED_TABLE_SCHEMA,
|
|
154
|
+
kcu.REFERENCED_TABLE_NAME,
|
|
155
|
+
rc.DELETE_RULE,
|
|
156
|
+
rc.UPDATE_RULE
|
|
157
|
+
`,
|
|
158
|
+
{ database: appConfig.db.name, tableNames },
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export async function getIndexes(tableNames?: string[]): Promise<(IndexMetadata & { tableName: string })[]> {
|
|
163
|
+
const tableFilter = tableNames?.length
|
|
164
|
+
? 'AND s.TABLE_NAME IN (:tableNames)'
|
|
165
|
+
: '';
|
|
166
|
+
return db.query<IndexMetadata & { tableName: string } & any>(
|
|
167
|
+
`
|
|
168
|
+
SELECT
|
|
169
|
+
s.TABLE_NAME AS tableName,
|
|
170
|
+
s.INDEX_NAME AS name,
|
|
171
|
+
s.INDEX_TYPE AS type,
|
|
172
|
+
CASE WHEN s.NON_UNIQUE = 0 THEN true ELSE false END AS isUnique,
|
|
173
|
+
CASE WHEN s.INDEX_NAME = 'PRIMARY' THEN true ELSE false END AS isPrimaryKey,
|
|
174
|
+
GROUP_CONCAT(s.COLUMN_NAME ORDER BY s.SEQ_IN_INDEX SEPARATOR ',') AS columns
|
|
175
|
+
FROM information_schema.STATISTICS s
|
|
176
|
+
WHERE s.TABLE_SCHEMA = :database
|
|
177
|
+
${tableFilter}
|
|
178
|
+
GROUP BY s.TABLE_NAME, s.INDEX_NAME, s.INDEX_TYPE, s.NON_UNIQUE
|
|
179
|
+
`,
|
|
180
|
+
{ database: appConfig.db.name, tableNames },
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export async function getStatistics(tableNames?: string[]): Promise<(StatisticsMetadata & { tableName: string })[]> {
|
|
185
|
+
const tableFilter = tableNames?.length
|
|
186
|
+
? 'AND t.TABLE_NAME IN (:tableNames)'
|
|
187
|
+
: '';
|
|
188
|
+
return db.query<StatisticsMetadata & { tableName: string } & any>(
|
|
189
|
+
`
|
|
190
|
+
SELECT
|
|
191
|
+
t.TABLE_NAME AS tableName,
|
|
192
|
+
t.TABLE_ROWS AS rowCount,
|
|
193
|
+
ROUND(((t.DATA_LENGTH + t.INDEX_LENGTH) / 1024), 0) AS totalSizeKB,
|
|
194
|
+
ROUND((t.DATA_LENGTH / 1024), 0) AS usedSizeKB
|
|
195
|
+
FROM information_schema.TABLES t
|
|
196
|
+
WHERE t.TABLE_SCHEMA = :database
|
|
197
|
+
${tableFilter}
|
|
198
|
+
`,
|
|
199
|
+
{ database: appConfig.db.name, tableNames },
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export async function findTables(pattern?: string, hasColumn?: string): Promise<TableSearchResult[]> {
|
|
204
|
+
const params = {
|
|
205
|
+
database: appConfig.db.name,
|
|
206
|
+
pattern: likePattern(pattern),
|
|
207
|
+
hasColumn: likePattern(hasColumn),
|
|
208
|
+
};
|
|
209
|
+
return db.query<TableSearchResult & any>(
|
|
210
|
+
`
|
|
211
|
+
SELECT DISTINCT
|
|
212
|
+
t.TABLE_SCHEMA AS schemaName,
|
|
213
|
+
t.TABLE_NAME AS tableName,
|
|
214
|
+
t.TABLE_ROWS AS rowCount,
|
|
215
|
+
t.CREATE_TIME AS createDate
|
|
216
|
+
FROM information_schema.TABLES t
|
|
217
|
+
${hasColumn ? `JOIN information_schema.COLUMNS c
|
|
218
|
+
ON c.TABLE_SCHEMA = t.TABLE_SCHEMA AND c.TABLE_NAME = t.TABLE_NAME` : ''}
|
|
219
|
+
WHERE t.TABLE_SCHEMA = :database
|
|
220
|
+
AND t.TABLE_TYPE IN ('BASE TABLE', 'VIEW')
|
|
221
|
+
${pattern ? 'AND t.TABLE_NAME LIKE :pattern' : ''}
|
|
222
|
+
${hasColumn ? 'AND c.COLUMN_NAME LIKE :hasColumn' : ''}
|
|
223
|
+
ORDER BY t.TABLE_NAME
|
|
224
|
+
LIMIT 100
|
|
225
|
+
`,
|
|
226
|
+
params,
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export async function searchObjects(search: string, type?: string): Promise<ObjectSearchResult[]> {
|
|
231
|
+
const pattern = likePattern(search) || `%${search}%`;
|
|
232
|
+
const includeTables = !type || type === 'table';
|
|
233
|
+
const includeColumns = !type || type === 'column';
|
|
234
|
+
const parts: string[] = [];
|
|
235
|
+
|
|
236
|
+
if (includeTables) {
|
|
237
|
+
parts.push(`
|
|
238
|
+
SELECT t.TABLE_SCHEMA AS schemaName, t.TABLE_NAME AS tableName, NULL AS columnName
|
|
239
|
+
FROM information_schema.TABLES t
|
|
240
|
+
WHERE t.TABLE_SCHEMA = :database
|
|
241
|
+
AND t.TABLE_NAME LIKE :pattern`);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (includeColumns) {
|
|
245
|
+
parts.push(`
|
|
246
|
+
SELECT c.TABLE_SCHEMA AS schemaName, c.TABLE_NAME AS tableName, c.COLUMN_NAME AS columnName
|
|
247
|
+
FROM information_schema.COLUMNS c
|
|
248
|
+
WHERE c.TABLE_SCHEMA = :database
|
|
249
|
+
AND c.COLUMN_NAME LIKE :pattern`);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (parts.length === 0) {
|
|
253
|
+
return [];
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return db.query<ObjectSearchResult & any>(
|
|
257
|
+
`${parts.join('\nUNION ALL\n')}\nORDER BY tableName, columnName\nLIMIT 100`,
|
|
258
|
+
{ database: appConfig.db.name, pattern },
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export async function getRelationships(): Promise<Relationship[]> {
|
|
263
|
+
return db.query<Relationship & any>(
|
|
264
|
+
`
|
|
265
|
+
SELECT
|
|
266
|
+
kcu.TABLE_SCHEMA AS fromSchema,
|
|
267
|
+
kcu.TABLE_NAME AS fromTable,
|
|
268
|
+
kcu.COLUMN_NAME AS fromColumn,
|
|
269
|
+
kcu.REFERENCED_TABLE_SCHEMA AS toSchema,
|
|
270
|
+
kcu.REFERENCED_TABLE_NAME AS toTable,
|
|
271
|
+
kcu.REFERENCED_COLUMN_NAME AS toColumn,
|
|
272
|
+
kcu.CONSTRAINT_NAME AS constraintName,
|
|
273
|
+
rc.DELETE_RULE AS deleteAction,
|
|
274
|
+
rc.UPDATE_RULE AS updateAction
|
|
275
|
+
FROM information_schema.KEY_COLUMN_USAGE kcu
|
|
276
|
+
JOIN information_schema.REFERENTIAL_CONSTRAINTS rc
|
|
277
|
+
ON rc.CONSTRAINT_SCHEMA = kcu.CONSTRAINT_SCHEMA
|
|
278
|
+
AND rc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
|
|
279
|
+
WHERE kcu.TABLE_SCHEMA = :database
|
|
280
|
+
AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
|
|
281
|
+
ORDER BY kcu.TABLE_NAME, kcu.ORDINAL_POSITION
|
|
282
|
+
`,
|
|
283
|
+
{ database: appConfig.db.name },
|
|
284
|
+
);
|
|
285
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ES2022",
|
|
5
|
+
"lib": ["ES2022"],
|
|
6
|
+
"moduleResolution": "node",
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"declarationMap": true,
|
|
16
|
+
"sourceMap": true,
|
|
17
|
+
"noUnusedLocals": true,
|
|
18
|
+
"noUnusedParameters": true,
|
|
19
|
+
"noImplicitReturns": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true
|
|
21
|
+
},
|
|
22
|
+
"include": ["src/**/*"],
|
|
23
|
+
"exclude": ["node_modules", "dist"]
|
|
24
|
+
}
|