devmind 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/LICENSE +191 -0
- package/README.md +148 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +232 -0
- package/dist/cli.js.map +1 -0
- package/dist/codebase/generators/architecture.d.ts +4 -0
- package/dist/codebase/generators/architecture.js +33 -0
- package/dist/codebase/generators/architecture.js.map +1 -0
- package/dist/codebase/generators/modules.d.ts +9 -0
- package/dist/codebase/generators/modules.js +46 -0
- package/dist/codebase/generators/modules.js.map +1 -0
- package/dist/codebase/generators/overview.d.ts +5 -0
- package/dist/codebase/generators/overview.js +34 -0
- package/dist/codebase/generators/overview.js.map +1 -0
- package/dist/codebase/generators/skeleton.d.ts +8 -0
- package/dist/codebase/generators/skeleton.js +57 -0
- package/dist/codebase/generators/skeleton.js.map +1 -0
- package/dist/codebase/index.d.ts +24 -0
- package/dist/codebase/index.js +50 -0
- package/dist/codebase/index.js.map +1 -0
- package/dist/codebase/parsers/typescript.d.ts +14 -0
- package/dist/codebase/parsers/typescript.js +145 -0
- package/dist/codebase/parsers/typescript.js.map +1 -0
- package/dist/codebase/scanners/filesystem.d.ts +17 -0
- package/dist/codebase/scanners/filesystem.js +152 -0
- package/dist/codebase/scanners/filesystem.js.map +1 -0
- package/dist/codebase/utils/hashing.d.ts +15 -0
- package/dist/codebase/utils/hashing.js +50 -0
- package/dist/codebase/utils/hashing.js.map +1 -0
- package/dist/codebase/utils/stats.d.ts +12 -0
- package/dist/codebase/utils/stats.js +55 -0
- package/dist/codebase/utils/stats.js.map +1 -0
- package/dist/codebase/utils/tree.d.ts +10 -0
- package/dist/codebase/utils/tree.js +22 -0
- package/dist/codebase/utils/tree.js.map +1 -0
- package/dist/commands/analyze.d.ts +6 -0
- package/dist/commands/analyze.js +97 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/context.d.ts +4 -0
- package/dist/commands/context.js +54 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/core/config.d.ts +20 -0
- package/dist/core/config.js +40 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/errors.d.ts +18 -0
- package/dist/core/errors.js +53 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/fileio.d.ts +10 -0
- package/dist/core/fileio.js +57 -0
- package/dist/core/fileio.js.map +1 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +15 -0
- package/dist/core/logger.js +40 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/types.d.ts +106 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/database/cli.d.ts +7 -0
- package/dist/database/cli.js +132 -0
- package/dist/database/cli.js.map +1 -0
- package/dist/database/commands/checkpoint.d.ts +13 -0
- package/dist/database/commands/checkpoint.js +136 -0
- package/dist/database/commands/checkpoint.js.map +1 -0
- package/dist/database/commands/generate.d.ts +21 -0
- package/dist/database/commands/generate.js +269 -0
- package/dist/database/commands/generate.js.map +1 -0
- package/dist/database/commands/handoff.d.ts +15 -0
- package/dist/database/commands/handoff.js +332 -0
- package/dist/database/commands/handoff.js.map +1 -0
- package/dist/database/commands/history.d.ts +13 -0
- package/dist/database/commands/history.js +148 -0
- package/dist/database/commands/history.js.map +1 -0
- package/dist/database/commands/init.d.ts +10 -0
- package/dist/database/commands/init.js +28 -0
- package/dist/database/commands/init.js.map +1 -0
- package/dist/database/commands/learn.d.ts +12 -0
- package/dist/database/commands/learn.js +93 -0
- package/dist/database/commands/learn.js.map +1 -0
- package/dist/database/commands/memory.d.ts +90 -0
- package/dist/database/commands/memory.js +353 -0
- package/dist/database/commands/memory.js.map +1 -0
- package/dist/database/commands/show.d.ts +9 -0
- package/dist/database/commands/show.js +136 -0
- package/dist/database/commands/show.js.map +1 -0
- package/dist/database/commands/validate.d.ts +9 -0
- package/dist/database/commands/validate.js +200 -0
- package/dist/database/commands/validate.js.map +1 -0
- package/dist/database/commands/watch.d.ts +9 -0
- package/dist/database/commands/watch.js +77 -0
- package/dist/database/commands/watch.js.map +1 -0
- package/dist/database/extractors/drizzle.d.ts +62 -0
- package/dist/database/extractors/drizzle.js +251 -0
- package/dist/database/extractors/drizzle.js.map +1 -0
- package/dist/database/extractors/firebase.d.ts +39 -0
- package/dist/database/extractors/firebase.js +192 -0
- package/dist/database/extractors/firebase.js.map +1 -0
- package/dist/database/extractors/index.d.ts +69 -0
- package/dist/database/extractors/index.js +345 -0
- package/dist/database/extractors/index.js.map +1 -0
- package/dist/database/extractors/mongodb.d.ts +44 -0
- package/dist/database/extractors/mongodb.js +198 -0
- package/dist/database/extractors/mongodb.js.map +1 -0
- package/dist/database/extractors/mysql.d.ts +61 -0
- package/dist/database/extractors/mysql.js +173 -0
- package/dist/database/extractors/mysql.js.map +1 -0
- package/dist/database/extractors/postgres.d.ts +47 -0
- package/dist/database/extractors/postgres.js +141 -0
- package/dist/database/extractors/postgres.js.map +1 -0
- package/dist/database/extractors/prisma.d.ts +71 -0
- package/dist/database/extractors/prisma.js +270 -0
- package/dist/database/extractors/prisma.js.map +1 -0
- package/dist/database/extractors/sqlite.d.ts +50 -0
- package/dist/database/extractors/sqlite.js +148 -0
- package/dist/database/extractors/sqlite.js.map +1 -0
- package/dist/database/generators/learning-generator.d.ts +48 -0
- package/dist/database/generators/learning-generator.js +221 -0
- package/dist/database/generators/learning-generator.js.map +1 -0
- package/dist/database/generators/templates.d.ts +103 -0
- package/dist/database/generators/templates.js +1557 -0
- package/dist/database/generators/templates.js.map +1 -0
- package/dist/database/index.d.ts +15 -0
- package/dist/database/index.js +16 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/utils/json-output.d.ts +26 -0
- package/dist/database/utils/json-output.js +37 -0
- package/dist/database/utils/json-output.js.map +1 -0
- package/dist/generators/unified.d.ts +1 -0
- package/dist/generators/unified.js +173 -0
- package/dist/generators/unified.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/config-detector.d.ts +1 -0
- package/dist/utils/config-detector.js +40 -0
- package/dist/utils/config-detector.js.map +1 -0
- package/dist/utils/config-loader.d.ts +16 -0
- package/dist/utils/config-loader.js +20 -0
- package/dist/utils/config-loader.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL Schema Extractor
|
|
3
|
+
* Extracts database schema information from PostgreSQL databases
|
|
4
|
+
*/
|
|
5
|
+
import { Pool } from 'pg';
|
|
6
|
+
export class PostgresExtractor {
|
|
7
|
+
pool;
|
|
8
|
+
constructor(connectionString) {
|
|
9
|
+
this.pool = new Pool({
|
|
10
|
+
connectionString,
|
|
11
|
+
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
async extract(schemaName = 'public') {
|
|
15
|
+
const client = await this.pool.connect();
|
|
16
|
+
try {
|
|
17
|
+
const tables = await this.extractTables(client, schemaName);
|
|
18
|
+
const tablesWithDetails = await Promise.all(tables.map(async (table) => {
|
|
19
|
+
const tableName = table.name || '';
|
|
20
|
+
const columns = await this.extractColumns(client, schemaName, tableName);
|
|
21
|
+
const indexes = await this.extractIndexes(client, schemaName, tableName);
|
|
22
|
+
const foreignKeys = await this.extractForeignKeys(client, schemaName, tableName);
|
|
23
|
+
const primaryKey = indexes.filter((i) => i.isPrimaryKey).flatMap((i) => i.columns);
|
|
24
|
+
return {
|
|
25
|
+
name: tableName,
|
|
26
|
+
description: table.description || null,
|
|
27
|
+
columns,
|
|
28
|
+
indexes,
|
|
29
|
+
foreignKeys,
|
|
30
|
+
primaryKey,
|
|
31
|
+
};
|
|
32
|
+
}));
|
|
33
|
+
return {
|
|
34
|
+
tables: tablesWithDetails,
|
|
35
|
+
databaseType: 'postgresql',
|
|
36
|
+
schemaName,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
client.release();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async extractTables(client, schemaName) {
|
|
44
|
+
const query = `
|
|
45
|
+
SELECT t.table_name, obj_description(c.oid, 'pg_class') as description
|
|
46
|
+
FROM information_schema.tables t
|
|
47
|
+
LEFT JOIN pg_class c ON c.relname = t.table_name
|
|
48
|
+
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
49
|
+
WHERE t.table_schema = $1
|
|
50
|
+
AND t.table_type = 'BASE TABLE'
|
|
51
|
+
ORDER BY t.table_name
|
|
52
|
+
`;
|
|
53
|
+
const result = await client.query(query, [schemaName]);
|
|
54
|
+
return result.rows.map((row) => ({
|
|
55
|
+
name: row.table_name,
|
|
56
|
+
description: row.description,
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
59
|
+
async extractColumns(client, schemaName, tableName) {
|
|
60
|
+
const query = `
|
|
61
|
+
SELECT
|
|
62
|
+
c.column_name,
|
|
63
|
+
c.data_type,
|
|
64
|
+
c.is_nullable = 'YES' as is_nullable,
|
|
65
|
+
c.column_default,
|
|
66
|
+
pg_catalog.col_description(
|
|
67
|
+
(SELECT c.oid FROM pg_class WHERE relname = $2)::regclass::oid,
|
|
68
|
+
c.ordinal_position
|
|
69
|
+
) as description
|
|
70
|
+
FROM information_schema.columns c
|
|
71
|
+
WHERE c.table_schema = $1 AND c.table_name = $2
|
|
72
|
+
ORDER BY c.ordinal_position
|
|
73
|
+
`;
|
|
74
|
+
const result = await client.query(query, [schemaName, tableName]);
|
|
75
|
+
return result.rows.map((row) => ({
|
|
76
|
+
name: row.column_name,
|
|
77
|
+
type: row.data_type,
|
|
78
|
+
nullable: row.is_nullable,
|
|
79
|
+
default: row.column_default,
|
|
80
|
+
description: row.description,
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
async extractIndexes(client, schemaName, tableName) {
|
|
84
|
+
const query = `
|
|
85
|
+
SELECT
|
|
86
|
+
i.relname as index_name,
|
|
87
|
+
array_agg(a.attname ORDER BY ix.indkey::integer[]) as columns,
|
|
88
|
+
ix.indisunique as is_unique,
|
|
89
|
+
ix.indisprimary as is_primary_key
|
|
90
|
+
FROM pg_class t
|
|
91
|
+
JOIN pg_index ix ON t.oid = ix.indrelid
|
|
92
|
+
JOIN pg_class i ON i.oid = ix.indexrelid
|
|
93
|
+
JOIN pg_namespace n ON n.oid = t.relnamespace
|
|
94
|
+
LEFT JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey::integer[])
|
|
95
|
+
WHERE t.relname = $1 AND n.nspname = $2
|
|
96
|
+
GROUP BY i.relname, ix.indisunique, ix.indisprimary
|
|
97
|
+
`;
|
|
98
|
+
const result = await client.query(query, [tableName, schemaName]);
|
|
99
|
+
return result.rows.map((row) => ({
|
|
100
|
+
name: row.index_name,
|
|
101
|
+
columns: row.columns.filter(Boolean),
|
|
102
|
+
unique: row.is_unique,
|
|
103
|
+
isPrimaryKey: row.is_primary_key,
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
async extractForeignKeys(client, schemaName, tableName) {
|
|
107
|
+
const query = `
|
|
108
|
+
SELECT
|
|
109
|
+
kcu.column_name,
|
|
110
|
+
ccu.table_name AS references_table,
|
|
111
|
+
ccu.column_name AS references_column,
|
|
112
|
+
rc.delete_rule AS on_delete,
|
|
113
|
+
rc.update_rule AS on_update
|
|
114
|
+
FROM information_schema.table_constraints AS tc
|
|
115
|
+
JOIN information_schema.key_column_usage AS kcu
|
|
116
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
117
|
+
AND tc.table_schema = kcu.table_schema
|
|
118
|
+
JOIN information_schema.constraint_column_usage AS ccu
|
|
119
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
120
|
+
AND ccu.table_schema = tc.table_schema
|
|
121
|
+
JOIN information_schema.referential_constraints AS rc
|
|
122
|
+
ON tc.constraint_name = rc.constraint_name
|
|
123
|
+
AND tc.table_schema = rc.constraint_schema
|
|
124
|
+
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
125
|
+
AND tc.table_schema = $1
|
|
126
|
+
AND tc.table_name = $2
|
|
127
|
+
`;
|
|
128
|
+
const result = await client.query(query, [schemaName, tableName]);
|
|
129
|
+
return result.rows.map((row) => ({
|
|
130
|
+
column: row.column_name,
|
|
131
|
+
referencesTable: row.references_table,
|
|
132
|
+
referencesColumn: row.references_column,
|
|
133
|
+
onDelete: row.on_delete,
|
|
134
|
+
onUpdate: row.on_update,
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
async close() {
|
|
138
|
+
await this.pool.end();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=postgres.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../../src/database/extractors/postgres.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prisma Schema Parser
|
|
3
|
+
* Extracts schema information from Prisma schema.prisma files
|
|
4
|
+
*/
|
|
5
|
+
export interface PrismaColumnInfo {
|
|
6
|
+
name: string;
|
|
7
|
+
type: string;
|
|
8
|
+
isList: boolean;
|
|
9
|
+
isOptional: boolean;
|
|
10
|
+
isUnique: boolean;
|
|
11
|
+
isId: boolean;
|
|
12
|
+
isDefault: boolean;
|
|
13
|
+
defaultValue: string | null;
|
|
14
|
+
isRelation: boolean;
|
|
15
|
+
relationName: string | null;
|
|
16
|
+
relationFields: string[];
|
|
17
|
+
relationReferences: string[];
|
|
18
|
+
onDelete: string | null;
|
|
19
|
+
}
|
|
20
|
+
export interface PrismaIndexInfo {
|
|
21
|
+
name: string;
|
|
22
|
+
columns: string[];
|
|
23
|
+
unique: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface PrismaRelationInfo {
|
|
26
|
+
name: string;
|
|
27
|
+
fromTable: string;
|
|
28
|
+
fromFields: string[];
|
|
29
|
+
toTable: string;
|
|
30
|
+
toFields: string[];
|
|
31
|
+
type: 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many';
|
|
32
|
+
onDelete: string | null;
|
|
33
|
+
}
|
|
34
|
+
export interface PrismaTableInfo {
|
|
35
|
+
name: string;
|
|
36
|
+
description: string | null;
|
|
37
|
+
columns: PrismaColumnInfo[];
|
|
38
|
+
indexes: PrismaIndexInfo[];
|
|
39
|
+
relations: PrismaRelationInfo[];
|
|
40
|
+
primaryKey: string[];
|
|
41
|
+
uniqueConstraints: string[][];
|
|
42
|
+
}
|
|
43
|
+
export interface PrismaSchemaInfo {
|
|
44
|
+
tables: PrismaTableInfo[];
|
|
45
|
+
datasource: {
|
|
46
|
+
provider: string;
|
|
47
|
+
url: string;
|
|
48
|
+
};
|
|
49
|
+
generator: {
|
|
50
|
+
provider: string;
|
|
51
|
+
output: string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export declare class PrismaExtractor {
|
|
55
|
+
private schemaPath;
|
|
56
|
+
private schemaContent;
|
|
57
|
+
constructor(schemaPath: string);
|
|
58
|
+
extract(): Promise<PrismaSchemaInfo>;
|
|
59
|
+
private parseDatasource;
|
|
60
|
+
private parseGenerator;
|
|
61
|
+
private parseModels;
|
|
62
|
+
private parseModel;
|
|
63
|
+
private parseField;
|
|
64
|
+
private parseRelations;
|
|
65
|
+
close(): Promise<void>;
|
|
66
|
+
private parsePrismaList;
|
|
67
|
+
}
|
|
68
|
+
export declare const PRISMA_TYPE_MAPPINGS: {
|
|
69
|
+
prismaType: string;
|
|
70
|
+
tsType: string;
|
|
71
|
+
}[];
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prisma Schema Parser
|
|
3
|
+
* Extracts schema information from Prisma schema.prisma files
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
export class PrismaExtractor {
|
|
7
|
+
schemaPath;
|
|
8
|
+
schemaContent;
|
|
9
|
+
constructor(schemaPath) {
|
|
10
|
+
this.schemaPath = schemaPath;
|
|
11
|
+
this.schemaContent = '';
|
|
12
|
+
}
|
|
13
|
+
async extract() {
|
|
14
|
+
if (!fs.existsSync(this.schemaPath)) {
|
|
15
|
+
throw new Error(`Prisma schema not found at: ${this.schemaPath}`);
|
|
16
|
+
}
|
|
17
|
+
this.schemaContent = fs.readFileSync(this.schemaPath, 'utf-8');
|
|
18
|
+
const datasource = this.parseDatasource();
|
|
19
|
+
const generator = this.parseGenerator();
|
|
20
|
+
const tables = this.parseModels();
|
|
21
|
+
return {
|
|
22
|
+
tables,
|
|
23
|
+
datasource,
|
|
24
|
+
generator,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
parseDatasource() {
|
|
28
|
+
const datasourceMatch = this.schemaContent.match(/datasource\s+db\s*\{[^}]*url\s*=\s*env\(["']?([^"']+)["']?\)/s);
|
|
29
|
+
const providerMatch = this.schemaContent.match(/datasource\s+db\s*\{[^}]*provider\s*=\s*["']?([^"'\n]+)["']?/s);
|
|
30
|
+
return {
|
|
31
|
+
url: datasourceMatch ? process.env[datasourceMatch[1]] || datasourceMatch[1] : '',
|
|
32
|
+
provider: providerMatch ? providerMatch[1].trim() : 'postgresql',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
parseGenerator() {
|
|
36
|
+
const providerMatch = this.schemaContent.match(/generator\s+client\s*\{[^}]*provider\s*=\s*["']?([^"'\n]+)["']?/s);
|
|
37
|
+
const outputMatch = this.schemaContent.match(/generator\s+client\s*\{[^}]*output\s*=\s*["']?([^"'\n]+)["']?/s);
|
|
38
|
+
return {
|
|
39
|
+
provider: providerMatch ? providerMatch[1].trim() : 'prisma-client-js',
|
|
40
|
+
output: outputMatch ? outputMatch[1].trim() : './node_modules/.prisma/client',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
parseModels() {
|
|
44
|
+
const models = [];
|
|
45
|
+
const modelRegex = /model\s+(\w+)\s*\{([^}]+)\}/g;
|
|
46
|
+
let match;
|
|
47
|
+
while ((match = modelRegex.exec(this.schemaContent)) !== null) {
|
|
48
|
+
const modelName = match[1];
|
|
49
|
+
const modelBody = match[2];
|
|
50
|
+
const table = this.parseModel(modelName, modelBody);
|
|
51
|
+
models.push(table);
|
|
52
|
+
}
|
|
53
|
+
// Parse relations after all models are extracted
|
|
54
|
+
this.parseRelations(models);
|
|
55
|
+
return models;
|
|
56
|
+
}
|
|
57
|
+
parseModel(name, body) {
|
|
58
|
+
const lines = body.split('\n').filter((l) => l.trim());
|
|
59
|
+
const columns = [];
|
|
60
|
+
const indexes = [];
|
|
61
|
+
let primaryKey = [];
|
|
62
|
+
let uniqueConstraints = [];
|
|
63
|
+
for (const line of lines) {
|
|
64
|
+
const trimmed = line.trim();
|
|
65
|
+
// Skip empty lines and comments
|
|
66
|
+
if (!trimmed || trimmed.startsWith('//'))
|
|
67
|
+
continue;
|
|
68
|
+
// Parse @@id (composite primary key)
|
|
69
|
+
const idMatch = trimmed.match(/@@id\s*\(\s*\[([^\]]+)\]\s*\)/);
|
|
70
|
+
if (idMatch) {
|
|
71
|
+
primaryKey = idMatch[1].split(',').map((s) => s.trim());
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
// Parse @@unique
|
|
75
|
+
const uniqueMatch = trimmed.match(/@@unique\s*\(\s*\[([^\]]+)\]\s*\)/);
|
|
76
|
+
if (uniqueMatch) {
|
|
77
|
+
uniqueConstraints.push(uniqueMatch[1].split(',').map((s) => s.trim()));
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
// Parse @@index
|
|
81
|
+
const indexMatch = trimmed.match(/@@index\s*\(\s*\[([^\]]+)\]\s*\)/);
|
|
82
|
+
if (indexMatch) {
|
|
83
|
+
indexes.push({
|
|
84
|
+
name: `idx_${name}_${indexMatch[1].split(',')[0].trim()}`,
|
|
85
|
+
columns: indexMatch[1].split(',').map((s) => s.trim()),
|
|
86
|
+
unique: false,
|
|
87
|
+
});
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
// Parse field
|
|
91
|
+
const fieldMatch = trimmed.match(/^(\w+)\s+(.+)$/);
|
|
92
|
+
if (fieldMatch) {
|
|
93
|
+
const [_, fieldName, fieldDef] = fieldMatch;
|
|
94
|
+
const column = this.parseField(fieldName, fieldDef);
|
|
95
|
+
columns.push(column);
|
|
96
|
+
if (column.isId && !column.isRelation) {
|
|
97
|
+
primaryKey = [fieldName];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
name,
|
|
103
|
+
description: null,
|
|
104
|
+
columns,
|
|
105
|
+
indexes,
|
|
106
|
+
relations: [],
|
|
107
|
+
primaryKey,
|
|
108
|
+
uniqueConstraints,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
parseField(name, def) {
|
|
112
|
+
const trimmed = def.trim();
|
|
113
|
+
const typeMatch = trimmed.match(/^([^\s\[\?]+)(\[\])?(\?)?/);
|
|
114
|
+
let type = typeMatch?.[1] || '';
|
|
115
|
+
const isList = Boolean(typeMatch?.[2]);
|
|
116
|
+
const isOptional = Boolean(typeMatch?.[3]);
|
|
117
|
+
const remainder = trimmed.slice(typeMatch?.[0]?.length || 0).trim();
|
|
118
|
+
let isUnique = false;
|
|
119
|
+
let isId = false;
|
|
120
|
+
let isDefault = false;
|
|
121
|
+
let defaultValue = null;
|
|
122
|
+
let isRelation = false;
|
|
123
|
+
let relationName = null;
|
|
124
|
+
const relationFields = [];
|
|
125
|
+
const relationReferences = [];
|
|
126
|
+
let onDelete = null;
|
|
127
|
+
const builtInTypes = [
|
|
128
|
+
'String',
|
|
129
|
+
'Int',
|
|
130
|
+
'Float',
|
|
131
|
+
'Boolean',
|
|
132
|
+
'DateTime',
|
|
133
|
+
'Json',
|
|
134
|
+
'Bytes',
|
|
135
|
+
'BigInt',
|
|
136
|
+
'Decimal',
|
|
137
|
+
];
|
|
138
|
+
const attrRegex = /@(\w+)(\(([^)]*)\))?/g;
|
|
139
|
+
let match;
|
|
140
|
+
while ((match = attrRegex.exec(remainder)) !== null) {
|
|
141
|
+
const [, attr, , body] = match;
|
|
142
|
+
switch (attr) {
|
|
143
|
+
case 'id':
|
|
144
|
+
isId = true;
|
|
145
|
+
break;
|
|
146
|
+
case 'unique':
|
|
147
|
+
isUnique = true;
|
|
148
|
+
break;
|
|
149
|
+
case 'default':
|
|
150
|
+
isDefault = true;
|
|
151
|
+
defaultValue = body?.trim() || null;
|
|
152
|
+
break;
|
|
153
|
+
case 'relation':
|
|
154
|
+
isRelation = true;
|
|
155
|
+
if (body) {
|
|
156
|
+
const nameMatch = body.match(/name:\s*["']([^"']+)["']/);
|
|
157
|
+
if (nameMatch) {
|
|
158
|
+
relationName = nameMatch[1];
|
|
159
|
+
}
|
|
160
|
+
const fieldsMatch = body.match(/fields:\s*\[([^\]]+)\]/);
|
|
161
|
+
if (fieldsMatch) {
|
|
162
|
+
relationFields.push(...this.parsePrismaList(fieldsMatch[1]));
|
|
163
|
+
}
|
|
164
|
+
const referencesMatch = body.match(/references:\s*\[([^\]]+)\]/);
|
|
165
|
+
if (referencesMatch) {
|
|
166
|
+
relationReferences.push(...this.parsePrismaList(referencesMatch[1]));
|
|
167
|
+
}
|
|
168
|
+
const onDeleteMatch = body.match(/onDelete:\s*([A-Za-z_]+)/);
|
|
169
|
+
if (onDeleteMatch) {
|
|
170
|
+
onDelete = onDeleteMatch[1].toUpperCase();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const isBuiltIn = builtInTypes.includes(type);
|
|
177
|
+
if (!isBuiltIn) {
|
|
178
|
+
isRelation = true;
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
name,
|
|
182
|
+
type,
|
|
183
|
+
isList,
|
|
184
|
+
isOptional,
|
|
185
|
+
isUnique,
|
|
186
|
+
isId,
|
|
187
|
+
isDefault,
|
|
188
|
+
defaultValue,
|
|
189
|
+
isRelation,
|
|
190
|
+
relationName,
|
|
191
|
+
relationFields,
|
|
192
|
+
relationReferences,
|
|
193
|
+
onDelete,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
parseRelations(models) {
|
|
197
|
+
const modelMap = new Map(models.map((m) => [m.name, m]));
|
|
198
|
+
// Find all relation fields and update them
|
|
199
|
+
for (const model of models) {
|
|
200
|
+
for (const column of model.columns) {
|
|
201
|
+
if (column.isRelation && !column.relationName) {
|
|
202
|
+
// Try to find the related model
|
|
203
|
+
const relatedModel = modelMap.get(column.type);
|
|
204
|
+
if (relatedModel) {
|
|
205
|
+
// Find corresponding relation field in related model
|
|
206
|
+
for (const relatedCol of relatedModel.columns) {
|
|
207
|
+
if (relatedCol.isRelation && relatedCol.type === model.name) {
|
|
208
|
+
// This is a bidirectional relation
|
|
209
|
+
column.relationFields = [column.name];
|
|
210
|
+
column.relationReferences = [relatedCol.name];
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Build relation info
|
|
219
|
+
for (const model of models) {
|
|
220
|
+
for (const column of model.columns) {
|
|
221
|
+
if (column.isRelation) {
|
|
222
|
+
const relatedModel = modelMap.get(column.type);
|
|
223
|
+
if (relatedModel) {
|
|
224
|
+
const relation = {
|
|
225
|
+
name: column.relationName || `${model.name}_${column.name}`,
|
|
226
|
+
fromTable: model.name,
|
|
227
|
+
fromFields: [column.name],
|
|
228
|
+
toTable: relatedModel.name,
|
|
229
|
+
toFields: relatedModel.primaryKey,
|
|
230
|
+
type: column.isList ? 'one-to-many' : 'one-to-one',
|
|
231
|
+
onDelete: column.onDelete,
|
|
232
|
+
};
|
|
233
|
+
// Check for many-to-many (both sides have list relations)
|
|
234
|
+
for (const relatedCol of relatedModel.columns) {
|
|
235
|
+
if (relatedCol.isRelation && relatedCol.type === model.name && relatedCol.isList) {
|
|
236
|
+
relation.type = 'many-to-many';
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// Check for many-to-one (current side is optional/list)
|
|
241
|
+
if (column.isOptional || column.isList) {
|
|
242
|
+
relation.type = column.isList ? 'one-to-many' : 'many-to-one';
|
|
243
|
+
}
|
|
244
|
+
model.relations.push(relation);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
async close() { }
|
|
251
|
+
parsePrismaList(value) {
|
|
252
|
+
return value
|
|
253
|
+
.split(',')
|
|
254
|
+
.map((item) => item.trim().replace(/^["']|["']$/g, ''))
|
|
255
|
+
.filter(Boolean);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// Prisma to TypeScript type mappings
|
|
259
|
+
export const PRISMA_TYPE_MAPPINGS = [
|
|
260
|
+
{ prismaType: 'String', tsType: 'string' },
|
|
261
|
+
{ prismaType: 'Int', tsType: 'number' },
|
|
262
|
+
{ prismaType: 'Float', tsType: 'number' },
|
|
263
|
+
{ prismaType: 'Boolean', tsType: 'boolean' },
|
|
264
|
+
{ prismaType: 'DateTime', tsType: 'Date' },
|
|
265
|
+
{ prismaType: 'Json', tsType: 'Record<string, unknown>' },
|
|
266
|
+
{ prismaType: 'Bytes', tsType: 'Buffer' },
|
|
267
|
+
{ prismaType: 'BigInt', tsType: 'bigint' },
|
|
268
|
+
{ prismaType: 'Decimal', tsType: 'number' },
|
|
269
|
+
];
|
|
270
|
+
//# sourceMappingURL=prisma.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prisma.js","sourceRoot":"","sources":["../../../src/database/extractors/prisma.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Schema Extractor
|
|
3
|
+
* Extracts database schema information from SQLite databases
|
|
4
|
+
*/
|
|
5
|
+
export interface SQLiteColumnInfo {
|
|
6
|
+
name: string;
|
|
7
|
+
type: string;
|
|
8
|
+
nullable: boolean;
|
|
9
|
+
default: string | null;
|
|
10
|
+
primaryKey: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface SQLiteIndexInfo {
|
|
13
|
+
name: string;
|
|
14
|
+
table: string;
|
|
15
|
+
columns: string[];
|
|
16
|
+
unique: boolean;
|
|
17
|
+
isPrimaryKey: boolean;
|
|
18
|
+
isAutoIncrement: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface SQLiteForeignKeyInfo {
|
|
21
|
+
id: number;
|
|
22
|
+
seq: number;
|
|
23
|
+
table: string;
|
|
24
|
+
from: string;
|
|
25
|
+
to: string;
|
|
26
|
+
onUpdate: string;
|
|
27
|
+
onDelete: string;
|
|
28
|
+
match: string;
|
|
29
|
+
}
|
|
30
|
+
export interface SQLiteTableInfo {
|
|
31
|
+
name: string;
|
|
32
|
+
columns: SQLiteColumnInfo[];
|
|
33
|
+
indexes: SQLiteIndexInfo[];
|
|
34
|
+
foreignKeys: SQLiteForeignKeyInfo[];
|
|
35
|
+
primaryKey: string[];
|
|
36
|
+
withoutRowId: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface SQLiteSchemaInfo {
|
|
39
|
+
tables: SQLiteTableInfo[];
|
|
40
|
+
databaseType: 'sqlite';
|
|
41
|
+
databasePath: string;
|
|
42
|
+
}
|
|
43
|
+
export declare class SQLiteExtractor {
|
|
44
|
+
private dbPath;
|
|
45
|
+
constructor(dbPath: string);
|
|
46
|
+
extract(): Promise<SQLiteSchemaInfo>;
|
|
47
|
+
private extractTables;
|
|
48
|
+
private enrichTable;
|
|
49
|
+
close(): Promise<void>;
|
|
50
|
+
}
|