@thinkdata/cli 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/dist/bin/thinkdata.d.ts +3 -0
- package/dist/bin/thinkdata.d.ts.map +1 -0
- package/dist/bin/thinkdata.js +43 -0
- package/dist/bin/thinkdata.js.map +1 -0
- package/dist/commands/compare.d.ts +41 -0
- package/dist/commands/compare.d.ts.map +1 -0
- package/dist/commands/compare.js +264 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/extract.d.ts +16 -0
- package/dist/commands/extract.d.ts.map +1 -0
- package/dist/commands/extract.js +255 -0
- package/dist/commands/extract.js.map +1 -0
- package/dist/converter/schemaToERD.d.ts +56 -0
- package/dist/converter/schemaToERD.d.ts.map +1 -0
- package/dist/converter/schemaToERD.js +80 -0
- package/dist/converter/schemaToERD.js.map +1 -0
- package/dist/extractors/index.d.ts +20 -0
- package/dist/extractors/index.d.ts.map +1 -0
- package/dist/extractors/index.js +81 -0
- package/dist/extractors/index.js.map +1 -0
- package/dist/extractors/mysql.d.ts +14 -0
- package/dist/extractors/mysql.d.ts.map +1 -0
- package/dist/extractors/mysql.js +198 -0
- package/dist/extractors/mysql.js.map +1 -0
- package/dist/extractors/postgres.d.ts +22 -0
- package/dist/extractors/postgres.d.ts.map +1 -0
- package/dist/extractors/postgres.js +259 -0
- package/dist/extractors/postgres.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +114 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL 스키마 추출기
|
|
3
|
+
*
|
|
4
|
+
* information_schema + pg_catalog에서 테이블, 컬럼, PK, FK, 인덱스를 추출합니다.
|
|
5
|
+
* 비밀번호는 메모리에서만 사용되며 추출 완료 후 연결이 즉시 종료됩니다.
|
|
6
|
+
*/
|
|
7
|
+
import pg from 'pg';
|
|
8
|
+
export class PostgresExtractor {
|
|
9
|
+
/**
|
|
10
|
+
* 연결 테스트 — PostgreSQL 버전 반환
|
|
11
|
+
*/
|
|
12
|
+
async testConnection(config) {
|
|
13
|
+
const client = this.createClient(config);
|
|
14
|
+
try {
|
|
15
|
+
await client.connect();
|
|
16
|
+
const result = await client.query('SELECT version()');
|
|
17
|
+
return result.rows[0].version;
|
|
18
|
+
}
|
|
19
|
+
finally {
|
|
20
|
+
await client.end();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 스키마 추출 — 테이블, 컬럼, PK, FK, 인덱스를 한 번에 추출
|
|
25
|
+
*/
|
|
26
|
+
async extract(config) {
|
|
27
|
+
const client = this.createClient(config);
|
|
28
|
+
const schema = config.schema || 'public';
|
|
29
|
+
try {
|
|
30
|
+
await client.connect();
|
|
31
|
+
// 병렬 추출
|
|
32
|
+
const [version, tables, pks, fks, indexes] = await Promise.all([
|
|
33
|
+
this.getVersion(client),
|
|
34
|
+
this.getTables(client, schema),
|
|
35
|
+
this.getPrimaryKeys(client, schema),
|
|
36
|
+
this.getForeignKeys(client, schema),
|
|
37
|
+
this.getIndexes(client, schema),
|
|
38
|
+
]);
|
|
39
|
+
// PK 정보를 컬럼에 매핑
|
|
40
|
+
const pkMap = this.buildPKMap(pks);
|
|
41
|
+
// 인덱스를 테이블별로 그룹핑
|
|
42
|
+
const indexMap = this.buildIndexMap(indexes);
|
|
43
|
+
// 테이블 조합
|
|
44
|
+
const extractedTables = tables.map((t) => ({
|
|
45
|
+
name: t.table_name,
|
|
46
|
+
schema: t.table_schema,
|
|
47
|
+
comment: t.table_comment || undefined,
|
|
48
|
+
columns: t.columns.map((c) => ({
|
|
49
|
+
name: c.column_name,
|
|
50
|
+
type: this.formatType(c),
|
|
51
|
+
nullable: c.is_nullable === 'YES',
|
|
52
|
+
isPK: pkMap.get(`${t.table_schema}.${t.table_name}`)?.has(c.column_name) ?? false,
|
|
53
|
+
defaultValue: c.column_default || undefined,
|
|
54
|
+
comment: c.column_comment || undefined,
|
|
55
|
+
ordinalPosition: c.ordinal_position,
|
|
56
|
+
maxLength: c.character_maximum_length || undefined,
|
|
57
|
+
numericPrecision: c.numeric_precision || undefined,
|
|
58
|
+
numericScale: c.numeric_scale || undefined,
|
|
59
|
+
})),
|
|
60
|
+
indexes: indexMap.get(`${t.table_schema}.${t.table_name}`) || [],
|
|
61
|
+
}));
|
|
62
|
+
return {
|
|
63
|
+
dbmsType: 'postgres',
|
|
64
|
+
dbmsVersion: version,
|
|
65
|
+
extractedAt: new Date().toISOString(),
|
|
66
|
+
schemaName: schema,
|
|
67
|
+
tables: extractedTables,
|
|
68
|
+
foreignKeys: fks,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
// 비밀번호 불필요 — 즉시 연결 종료
|
|
73
|
+
await client.end();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// ─── Private Helpers ─────────────────────────────────────────
|
|
77
|
+
createClient(config) {
|
|
78
|
+
return new pg.Client({
|
|
79
|
+
host: config.host,
|
|
80
|
+
port: config.port,
|
|
81
|
+
database: config.database,
|
|
82
|
+
user: config.user,
|
|
83
|
+
password: config.password,
|
|
84
|
+
ssl: config.ssl ? { rejectUnauthorized: false } : undefined,
|
|
85
|
+
connectionTimeoutMillis: 10000, // 10초 타임아웃
|
|
86
|
+
statement_timeout: 30000, // 30초 쿼리 타임아웃
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async getVersion(client) {
|
|
90
|
+
const result = await client.query('SHOW server_version');
|
|
91
|
+
return result.rows[0].server_version;
|
|
92
|
+
}
|
|
93
|
+
async getTables(client, schema) {
|
|
94
|
+
// 테이블 + 컬럼을 한 번에 조회하고, 테이블 코멘트도 JOIN
|
|
95
|
+
const result = await client.query(`
|
|
96
|
+
SELECT
|
|
97
|
+
c.table_schema,
|
|
98
|
+
c.table_name,
|
|
99
|
+
c.column_name,
|
|
100
|
+
c.ordinal_position,
|
|
101
|
+
c.data_type,
|
|
102
|
+
c.udt_name,
|
|
103
|
+
c.is_nullable,
|
|
104
|
+
c.column_default,
|
|
105
|
+
c.character_maximum_length,
|
|
106
|
+
c.numeric_precision,
|
|
107
|
+
c.numeric_scale,
|
|
108
|
+
pgd_col.description AS column_comment,
|
|
109
|
+
pgd_tbl.description AS table_comment
|
|
110
|
+
FROM information_schema.columns c
|
|
111
|
+
LEFT JOIN pg_catalog.pg_statio_all_tables st
|
|
112
|
+
ON st.schemaname = c.table_schema AND st.relname = c.table_name
|
|
113
|
+
LEFT JOIN pg_catalog.pg_description pgd_col
|
|
114
|
+
ON pgd_col.objoid = st.relid AND pgd_col.objsubid = c.ordinal_position
|
|
115
|
+
LEFT JOIN pg_catalog.pg_description pgd_tbl
|
|
116
|
+
ON pgd_tbl.objoid = st.relid AND pgd_tbl.objsubid = 0
|
|
117
|
+
WHERE c.table_schema = $1
|
|
118
|
+
AND c.table_name NOT LIKE 'pg_%'
|
|
119
|
+
AND c.table_name NOT LIKE '_prisma_%'
|
|
120
|
+
ORDER BY c.table_name, c.ordinal_position
|
|
121
|
+
`, [schema]);
|
|
122
|
+
// 테이블별로 그룹핑
|
|
123
|
+
const tableMap = new Map();
|
|
124
|
+
for (const row of result.rows) {
|
|
125
|
+
const key = `${row.table_schema}.${row.table_name}`;
|
|
126
|
+
if (!tableMap.has(key)) {
|
|
127
|
+
tableMap.set(key, {
|
|
128
|
+
table_schema: row.table_schema,
|
|
129
|
+
table_name: row.table_name,
|
|
130
|
+
table_comment: row.table_comment,
|
|
131
|
+
columns: [],
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
tableMap.get(key).columns.push(row);
|
|
135
|
+
}
|
|
136
|
+
return Array.from(tableMap.values());
|
|
137
|
+
}
|
|
138
|
+
async getPrimaryKeys(client, schema) {
|
|
139
|
+
const result = await client.query(`
|
|
140
|
+
SELECT
|
|
141
|
+
tc.table_schema,
|
|
142
|
+
tc.table_name,
|
|
143
|
+
kcu.column_name
|
|
144
|
+
FROM information_schema.table_constraints tc
|
|
145
|
+
JOIN information_schema.key_column_usage kcu
|
|
146
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
147
|
+
AND tc.table_schema = kcu.table_schema
|
|
148
|
+
WHERE tc.constraint_type = 'PRIMARY KEY'
|
|
149
|
+
AND tc.table_schema = $1
|
|
150
|
+
ORDER BY tc.table_name, kcu.ordinal_position
|
|
151
|
+
`, [schema]);
|
|
152
|
+
return result.rows;
|
|
153
|
+
}
|
|
154
|
+
async getForeignKeys(client, schema) {
|
|
155
|
+
const result = await client.query(`
|
|
156
|
+
SELECT
|
|
157
|
+
tc.constraint_name,
|
|
158
|
+
kcu.table_schema AS source_schema,
|
|
159
|
+
kcu.table_name AS source_table,
|
|
160
|
+
kcu.column_name AS source_column,
|
|
161
|
+
ccu.table_schema AS target_schema,
|
|
162
|
+
ccu.table_name AS target_table,
|
|
163
|
+
ccu.column_name AS target_column,
|
|
164
|
+
rc.delete_rule,
|
|
165
|
+
rc.update_rule
|
|
166
|
+
FROM information_schema.table_constraints tc
|
|
167
|
+
JOIN information_schema.key_column_usage kcu
|
|
168
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
169
|
+
AND tc.table_schema = kcu.table_schema
|
|
170
|
+
JOIN information_schema.constraint_column_usage ccu
|
|
171
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
172
|
+
AND ccu.table_schema = tc.table_schema
|
|
173
|
+
JOIN information_schema.referential_constraints rc
|
|
174
|
+
ON rc.constraint_name = tc.constraint_name
|
|
175
|
+
AND rc.constraint_schema = tc.table_schema
|
|
176
|
+
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
177
|
+
AND tc.table_schema = $1
|
|
178
|
+
ORDER BY tc.table_name, kcu.ordinal_position
|
|
179
|
+
`, [schema]);
|
|
180
|
+
return result.rows.map((r) => ({
|
|
181
|
+
name: r.constraint_name,
|
|
182
|
+
sourceTable: r.source_table,
|
|
183
|
+
sourceSchema: r.source_schema,
|
|
184
|
+
sourceColumn: r.source_column,
|
|
185
|
+
targetTable: r.target_table,
|
|
186
|
+
targetSchema: r.target_schema,
|
|
187
|
+
targetColumn: r.target_column,
|
|
188
|
+
onDelete: r.delete_rule !== 'NO ACTION' ? r.delete_rule : undefined,
|
|
189
|
+
onUpdate: r.update_rule !== 'NO ACTION' ? r.update_rule : undefined,
|
|
190
|
+
}));
|
|
191
|
+
}
|
|
192
|
+
async getIndexes(client, schema) {
|
|
193
|
+
const result = await client.query(`
|
|
194
|
+
SELECT
|
|
195
|
+
schemaname AS table_schema,
|
|
196
|
+
tablename AS table_name,
|
|
197
|
+
indexname AS index_name,
|
|
198
|
+
indexdef
|
|
199
|
+
FROM pg_indexes
|
|
200
|
+
WHERE schemaname = $1
|
|
201
|
+
AND indexname NOT LIKE '%_pkey'
|
|
202
|
+
ORDER BY tablename, indexname
|
|
203
|
+
`, [schema]);
|
|
204
|
+
return result.rows.map((r) => ({
|
|
205
|
+
tableSchema: r.table_schema,
|
|
206
|
+
tableName: r.table_name,
|
|
207
|
+
indexName: r.index_name,
|
|
208
|
+
unique: r.indexdef.includes('UNIQUE'),
|
|
209
|
+
columns: this.parseIndexColumns(r.indexdef),
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
parseIndexColumns(indexDef) {
|
|
213
|
+
// "CREATE INDEX idx_name ON table USING btree (col1, col2)"
|
|
214
|
+
const match = indexDef.match(/\(([^)]+)\)/);
|
|
215
|
+
if (!match)
|
|
216
|
+
return [];
|
|
217
|
+
return match[1].split(',').map((s) => s.trim().replace(/"/g, ''));
|
|
218
|
+
}
|
|
219
|
+
buildPKMap(pks) {
|
|
220
|
+
const map = new Map();
|
|
221
|
+
for (const pk of pks) {
|
|
222
|
+
const key = `${pk.table_schema}.${pk.table_name}`;
|
|
223
|
+
if (!map.has(key))
|
|
224
|
+
map.set(key, new Set());
|
|
225
|
+
map.get(key).add(pk.column_name);
|
|
226
|
+
}
|
|
227
|
+
return map;
|
|
228
|
+
}
|
|
229
|
+
buildIndexMap(indexes) {
|
|
230
|
+
const map = new Map();
|
|
231
|
+
for (const idx of indexes) {
|
|
232
|
+
const key = `${idx.tableSchema}.${idx.tableName}`;
|
|
233
|
+
if (!map.has(key))
|
|
234
|
+
map.set(key, []);
|
|
235
|
+
map.get(key).push({
|
|
236
|
+
name: idx.indexName,
|
|
237
|
+
columns: idx.columns,
|
|
238
|
+
unique: idx.unique,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
return map;
|
|
242
|
+
}
|
|
243
|
+
formatType(col) {
|
|
244
|
+
// udt_name은 실제 PostgreSQL 내부 타입 (int4, varchar, timestamptz 등)
|
|
245
|
+
const udt = col.udt_name;
|
|
246
|
+
// 길이/정밀도가 있는 타입
|
|
247
|
+
if (col.character_maximum_length) {
|
|
248
|
+
return `${udt}(${col.character_maximum_length})`;
|
|
249
|
+
}
|
|
250
|
+
if (col.numeric_precision && udt === 'numeric') {
|
|
251
|
+
if (col.numeric_scale) {
|
|
252
|
+
return `numeric(${col.numeric_precision},${col.numeric_scale})`;
|
|
253
|
+
}
|
|
254
|
+
return `numeric(${col.numeric_precision})`;
|
|
255
|
+
}
|
|
256
|
+
return udt;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=postgres.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/extractors/postgres.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @thinkdata/cli — 공개 API
|
|
3
|
+
*
|
|
4
|
+
* @thinkdata/probe 등 외부 패키지에서 사용할 수 있는 엔트리포인트.
|
|
5
|
+
*/
|
|
6
|
+
export type { ExtractedSchema, ExtractedTable, ExtractedColumn, ExtractedIndex, ExtractedForeignKey, ConnectionConfig, SchemaExtractor, } from './types.js';
|
|
7
|
+
export { createExtractor, parseConnectionString } from './extractors/index.js';
|
|
8
|
+
export { PostgresExtractor } from './extractors/postgres.js';
|
|
9
|
+
export { MySQLExtractor } from './extractors/mysql.js';
|
|
10
|
+
export { convertToERD } from './converter/schemaToERD.js';
|
|
11
|
+
export type { ERDEntity, ERDColumn, ERDRelationship, ConversionResult } from './converter/schemaToERD.js';
|
|
12
|
+
export { compareSchemas } from './commands/compare.js';
|
|
13
|
+
export type { SchemaDiff, TableDiff, ColumnDiff, FKDiff } from './commands/compare.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,YAAY,EACR,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC1G,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createExtractor, parseConnectionString } from './extractors/index.js';
|
|
2
|
+
export { PostgresExtractor } from './extractors/postgres.js';
|
|
3
|
+
export { MySQLExtractor } from './extractors/mysql.js';
|
|
4
|
+
export { convertToERD } from './converter/schemaToERD.js';
|
|
5
|
+
export { compareSchemas } from './commands/compare.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @thinkdata/cli — 추출된 스키마 타입 정의
|
|
3
|
+
*
|
|
4
|
+
* 모든 DBMS 추출기가 공통으로 반환하는 스키마 구조.
|
|
5
|
+
* @thinkdata/probe (TUI)에서도 이 타입을 공유합니다.
|
|
6
|
+
*/
|
|
7
|
+
/** 추출된 스키마 전체 구조 */
|
|
8
|
+
export interface ExtractedSchema {
|
|
9
|
+
/** DBMS 종류 (postgres, mysql, oracle, mssql, sqlite) */
|
|
10
|
+
dbmsType: string;
|
|
11
|
+
/** DBMS 버전 문자열 */
|
|
12
|
+
dbmsVersion: string;
|
|
13
|
+
/** 추출 시각 (ISO 8601) */
|
|
14
|
+
extractedAt: string;
|
|
15
|
+
/** 추출된 스키마 이름 */
|
|
16
|
+
schemaName: string;
|
|
17
|
+
/** 테이블 목록 */
|
|
18
|
+
tables: ExtractedTable[];
|
|
19
|
+
/** 외래 키 목록 */
|
|
20
|
+
foreignKeys: ExtractedForeignKey[];
|
|
21
|
+
}
|
|
22
|
+
/** 추출된 테이블 */
|
|
23
|
+
export interface ExtractedTable {
|
|
24
|
+
/** 테이블 이름 */
|
|
25
|
+
name: string;
|
|
26
|
+
/** 스키마 이름 (예: public) */
|
|
27
|
+
schema: string;
|
|
28
|
+
/** 테이블 코멘트 */
|
|
29
|
+
comment?: string;
|
|
30
|
+
/** 컬럼 목록 */
|
|
31
|
+
columns: ExtractedColumn[];
|
|
32
|
+
/** 인덱스 목록 */
|
|
33
|
+
indexes: ExtractedIndex[];
|
|
34
|
+
}
|
|
35
|
+
/** 추출된 컬럼 */
|
|
36
|
+
export interface ExtractedColumn {
|
|
37
|
+
/** 컬럼 이름 */
|
|
38
|
+
name: string;
|
|
39
|
+
/** 데이터 타입 (원본 DBMS 타입) */
|
|
40
|
+
type: string;
|
|
41
|
+
/** NULL 허용 여부 */
|
|
42
|
+
nullable: boolean;
|
|
43
|
+
/** PK 여부 */
|
|
44
|
+
isPK: boolean;
|
|
45
|
+
/** 기본값 */
|
|
46
|
+
defaultValue?: string;
|
|
47
|
+
/** 컬럼 코멘트 */
|
|
48
|
+
comment?: string;
|
|
49
|
+
/** 정렬 순서 (ordinal_position) */
|
|
50
|
+
ordinalPosition: number;
|
|
51
|
+
/** 문자열 최대 길이 */
|
|
52
|
+
maxLength?: number;
|
|
53
|
+
/** 숫자 정밀도 */
|
|
54
|
+
numericPrecision?: number;
|
|
55
|
+
/** 숫자 스케일 */
|
|
56
|
+
numericScale?: number;
|
|
57
|
+
}
|
|
58
|
+
/** 추출된 인덱스 */
|
|
59
|
+
export interface ExtractedIndex {
|
|
60
|
+
/** 인덱스 이름 */
|
|
61
|
+
name: string;
|
|
62
|
+
/** 포함 컬럼 목록 */
|
|
63
|
+
columns: string[];
|
|
64
|
+
/** UNIQUE 여부 */
|
|
65
|
+
unique: boolean;
|
|
66
|
+
}
|
|
67
|
+
/** 추출된 외래 키 */
|
|
68
|
+
export interface ExtractedForeignKey {
|
|
69
|
+
/** FK 제약조건 이름 */
|
|
70
|
+
name: string;
|
|
71
|
+
/** 소스 테이블 */
|
|
72
|
+
sourceTable: string;
|
|
73
|
+
/** 소스 스키마 */
|
|
74
|
+
sourceSchema: string;
|
|
75
|
+
/** 소스 컬럼 */
|
|
76
|
+
sourceColumn: string;
|
|
77
|
+
/** 대상 테이블 */
|
|
78
|
+
targetTable: string;
|
|
79
|
+
/** 대상 스키마 */
|
|
80
|
+
targetSchema: string;
|
|
81
|
+
/** 대상 컬럼 */
|
|
82
|
+
targetColumn: string;
|
|
83
|
+
/** ON DELETE 액션 */
|
|
84
|
+
onDelete?: string;
|
|
85
|
+
/** ON UPDATE 액션 */
|
|
86
|
+
onUpdate?: string;
|
|
87
|
+
}
|
|
88
|
+
/** 연결 설정 */
|
|
89
|
+
export interface ConnectionConfig {
|
|
90
|
+
/** DBMS 타입 */
|
|
91
|
+
type: 'postgres' | 'mysql' | 'oracle' | 'mssql' | 'sqlite';
|
|
92
|
+
/** 호스트 */
|
|
93
|
+
host: string;
|
|
94
|
+
/** 포트 */
|
|
95
|
+
port: number;
|
|
96
|
+
/** 데이터베이스 이름 */
|
|
97
|
+
database: string;
|
|
98
|
+
/** 사용자 */
|
|
99
|
+
user: string;
|
|
100
|
+
/** 비밀번호 (메모리 전용, 전송/저장 안 함) */
|
|
101
|
+
password: string;
|
|
102
|
+
/** 대상 스키마 (기본: public/dbo 등) */
|
|
103
|
+
schema?: string;
|
|
104
|
+
/** SSL 사용 여부 */
|
|
105
|
+
ssl?: boolean;
|
|
106
|
+
}
|
|
107
|
+
/** 스키마 추출기 인터페이스 */
|
|
108
|
+
export interface SchemaExtractor {
|
|
109
|
+
/** DBMS에 연결하여 스키마 메타데이터를 추출 */
|
|
110
|
+
extract(config: ConnectionConfig): Promise<ExtractedSchema>;
|
|
111
|
+
/** 연결 테스트 (버전 문자열 반환) */
|
|
112
|
+
testConnection(config: ConnectionConfig): Promise<string>;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@thinkdata/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "ThinkERD CLI — Database schema extraction and comparison tool",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": ["dist", "README.md"],
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"thinkdata": "./dist/bin/thinkdata.js"
|
|
12
|
+
},
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": "./dist/index.js",
|
|
17
|
+
"./extractors": "./dist/extractors/index.js",
|
|
18
|
+
"./converter": "./dist/converter/schemaToERD.js"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"dev": "tsx watch src/bin/thinkdata.ts",
|
|
23
|
+
"start": "tsx src/bin/thinkdata.ts",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest"
|
|
26
|
+
},
|
|
27
|
+
"keywords": ["erd", "schema", "database", "reverse-engineering", "thinkerd"],
|
|
28
|
+
"author": "ThinkData <hello@thinkdata.dev>",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/Thinkdata-dev/thinkdata"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://thinkdata.dev",
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"commander": "^13.1.0",
|
|
37
|
+
"@clack/prompts": "^0.10.0",
|
|
38
|
+
"picocolors": "^1.1.1",
|
|
39
|
+
"pg": "^8.16.0",
|
|
40
|
+
"mysql2": "^3.14.0",
|
|
41
|
+
"undici": "^7.8.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^22.15.0",
|
|
45
|
+
"@types/pg": "^8.11.11",
|
|
46
|
+
"tsx": "^4.19.4",
|
|
47
|
+
"typescript": "^5.8.3",
|
|
48
|
+
"vitest": "^3.2.1"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=18.0.0"
|
|
52
|
+
}
|
|
53
|
+
}
|