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,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate Command
|
|
3
|
+
* Validates generated context against database
|
|
4
|
+
*/
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { logger, readFileSafe } from '../../core/index.js';
|
|
7
|
+
import { createExtractor, UnifiedSchemaConverter, } from '../extractors/index.js';
|
|
8
|
+
import * as fs from 'fs'; // Keep fs for existsSync checks
|
|
9
|
+
export async function validate(options) {
|
|
10
|
+
logger.info('Validating database context...');
|
|
11
|
+
if (options.strict) {
|
|
12
|
+
logger.info('Strict mode: enabled');
|
|
13
|
+
}
|
|
14
|
+
const outputDir = '.devmind'; // In future use config
|
|
15
|
+
const configPath = path.join(outputDir, 'devmind.config.json');
|
|
16
|
+
// Fallback to legacy
|
|
17
|
+
const legacyConfigPath = '.ai/cohere-config.json';
|
|
18
|
+
let config;
|
|
19
|
+
// Check if context exists
|
|
20
|
+
if (fs.existsSync(configPath)) {
|
|
21
|
+
try {
|
|
22
|
+
config = JSON.parse(await readFileSafe(configPath));
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
logger.error('Failed to parse devmind.config.json');
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else if (fs.existsSync('cohere-config.json')) {
|
|
30
|
+
try {
|
|
31
|
+
config = JSON.parse(await readFileSafe('cohere-config.json'));
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
logger.error('Failed to parse cohere-config.json');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else if (fs.existsSync(legacyConfigPath)) {
|
|
39
|
+
try {
|
|
40
|
+
config = JSON.parse(await readFileSafe(legacyConfigPath));
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
logger.error('Failed to parse legacy config');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
logger.error('No configuration found.');
|
|
49
|
+
logger.info('Run: devmind init --url "your-database-url"');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const result = {
|
|
53
|
+
valid: true,
|
|
54
|
+
errors: [],
|
|
55
|
+
warnings: [],
|
|
56
|
+
};
|
|
57
|
+
try {
|
|
58
|
+
let extractorType = 'postgresql';
|
|
59
|
+
let connectionString = config.databaseUrl || process.env.DATABASE_URL;
|
|
60
|
+
let schemaPath;
|
|
61
|
+
// Auto-detect extractor type
|
|
62
|
+
if (fs.existsSync('prisma/schema.prisma')) {
|
|
63
|
+
extractorType = 'prisma';
|
|
64
|
+
schemaPath = 'prisma/schema.prisma';
|
|
65
|
+
logger.info('Detected: Prisma');
|
|
66
|
+
}
|
|
67
|
+
else if (fs.existsSync('src/db/schema.ts')) {
|
|
68
|
+
extractorType = 'drizzle';
|
|
69
|
+
schemaPath = 'src/db/schema.ts';
|
|
70
|
+
logger.info('Detected: Drizzle');
|
|
71
|
+
}
|
|
72
|
+
else if (connectionString &&
|
|
73
|
+
(connectionString.startsWith('mongodb://') || connectionString.startsWith('mongodb+srv://'))) {
|
|
74
|
+
extractorType = 'mongodb';
|
|
75
|
+
logger.info('Detected: MongoDB');
|
|
76
|
+
}
|
|
77
|
+
else if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
|
|
78
|
+
extractorType = 'firebase';
|
|
79
|
+
logger.info('Detected: Firebase');
|
|
80
|
+
}
|
|
81
|
+
else if (connectionString) {
|
|
82
|
+
if (connectionString.startsWith('mysql')) {
|
|
83
|
+
extractorType = 'mysql';
|
|
84
|
+
logger.info('Detected: MySQL');
|
|
85
|
+
}
|
|
86
|
+
else if (connectionString.includes('.db') || connectionString.includes('.sqlite')) {
|
|
87
|
+
extractorType = 'sqlite';
|
|
88
|
+
logger.info('Detected: SQLite');
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
logger.info('Detected: PostgreSQL');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (!connectionString && !schemaPath) {
|
|
95
|
+
logger.error('No database connection or schema file found.');
|
|
96
|
+
logger.info('Run: devmind generate');
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// Extract current schema
|
|
100
|
+
logger.info('Extracting current schema...');
|
|
101
|
+
// We need to handle the dummy connection string case if schemaPath is present
|
|
102
|
+
const extractor = await createExtractor(extractorType, connectionString || 'dummy', {
|
|
103
|
+
schemaPath,
|
|
104
|
+
projectId: config.firebaseProject,
|
|
105
|
+
serviceAccountPath: config.firebaseKey,
|
|
106
|
+
});
|
|
107
|
+
let currentSchema;
|
|
108
|
+
try {
|
|
109
|
+
const rawSchema = await extractor.extract();
|
|
110
|
+
currentSchema = UnifiedSchemaConverter.convert(rawSchema);
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
if (extractor.close) {
|
|
114
|
+
await extractor.close();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
logger.info(` Tables found: ${currentSchema.tables.length}`);
|
|
118
|
+
// Check if generated context files exist
|
|
119
|
+
const claudeFile = path.join(config.outputDir || outputDir, 'CLAUDE.md');
|
|
120
|
+
const agentsFile = path.join(config.outputDir || outputDir, 'AGENTS.md');
|
|
121
|
+
if (!fs.existsSync(claudeFile) && !fs.existsSync(agentsFile)) {
|
|
122
|
+
result.valid = false;
|
|
123
|
+
result.errors.push('Generated context files not found');
|
|
124
|
+
logger.error('No generated context files found in output directory');
|
|
125
|
+
logger.info('Run: devmind generate');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
// Parse generated context to extract table names
|
|
129
|
+
logger.info('Parsing generated context...');
|
|
130
|
+
const generatedTables = new Set();
|
|
131
|
+
if (fs.existsSync(claudeFile)) {
|
|
132
|
+
const content = await readFileSafe(claudeFile);
|
|
133
|
+
// Extract table names from markdown (looking for ### TableName pattern)
|
|
134
|
+
const tableMatches = content.matchAll(/###\s+([a-zA-Z_][a-zA-Z0-9_]*)/g);
|
|
135
|
+
for (const match of tableMatches) {
|
|
136
|
+
generatedTables.add(match[1]);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
logger.info(` Tables documented: ${generatedTables.size}`);
|
|
140
|
+
// Validate tables
|
|
141
|
+
logger.info('Validating tables...');
|
|
142
|
+
const currentTableNames = new Set(currentSchema.tables.map((t) => t.name));
|
|
143
|
+
// Check for missing tables in generated context
|
|
144
|
+
for (const table of currentSchema.tables) {
|
|
145
|
+
if (!generatedTables.has(table.name)) {
|
|
146
|
+
result.warnings.push(`Table '${table.name}' exists in schema but not in generated context`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Check for extra tables in generated context
|
|
150
|
+
for (const tableName of generatedTables) {
|
|
151
|
+
if (!currentTableNames.has(tableName)) {
|
|
152
|
+
result.warnings.push(`Table '${tableName}' in generated context but not in current schema`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Validate column counts
|
|
156
|
+
for (const table of currentSchema.tables) {
|
|
157
|
+
if (generatedTables.has(table.name)) {
|
|
158
|
+
const columnCount = table.columns.length;
|
|
159
|
+
if (columnCount === 0) {
|
|
160
|
+
result.warnings.push(`Table '${table.name}' has no columns`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Display results
|
|
165
|
+
if (result.errors.length === 0 && result.warnings.length === 0) {
|
|
166
|
+
logger.success('Validation passed!');
|
|
167
|
+
logger.info(' All tables match between schema and generated context.');
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
if (result.errors.length > 0) {
|
|
171
|
+
logger.error('Validation errors:');
|
|
172
|
+
result.errors.forEach((err) => logger.error(` - ${err}`));
|
|
173
|
+
}
|
|
174
|
+
if (result.warnings.length > 0) {
|
|
175
|
+
logger.warn('Validation warnings:');
|
|
176
|
+
result.warnings.forEach((warn) => logger.warn(` - ${warn}`));
|
|
177
|
+
}
|
|
178
|
+
if (result.warnings.length > 0 && result.errors.length === 0) {
|
|
179
|
+
logger.info('Recommendation: Run "devmind generate" to update context');
|
|
180
|
+
}
|
|
181
|
+
if (options.strict && (result.errors.length > 0 || result.warnings.length > 0)) {
|
|
182
|
+
logger.error('Validation failed in strict mode');
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Summary
|
|
187
|
+
logger.info('Summary:');
|
|
188
|
+
logger.info(` Current tables: ${currentSchema.tables.length}`);
|
|
189
|
+
logger.info(` Documented tables: ${generatedTables.size}`);
|
|
190
|
+
logger.info(` Errors: ${result.errors.length}`);
|
|
191
|
+
logger.info(` Warnings: ${result.warnings.length}`);
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
logger.error('Validation failed:', error);
|
|
195
|
+
if (options.strict) {
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/database/commands/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Watch Command
|
|
3
|
+
* Watch for schema changes and regenerate context
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import { generate } from './generate.js';
|
|
7
|
+
import { logger } from '../../core/index.js';
|
|
8
|
+
export async function watch(options) {
|
|
9
|
+
const debounce = parseInt(options.debounce || '2000', 10);
|
|
10
|
+
logger.info('Watch mode enabled...');
|
|
11
|
+
logger.info(` Debounce: ${debounce}ms`);
|
|
12
|
+
// Detect schema files to watch
|
|
13
|
+
const watchPaths = [];
|
|
14
|
+
if (fs.existsSync('prisma/schema.prisma')) {
|
|
15
|
+
watchPaths.push('prisma/schema.prisma');
|
|
16
|
+
logger.info(' Watching: prisma/schema.prisma');
|
|
17
|
+
}
|
|
18
|
+
if (fs.existsSync('src/db/schema.ts')) {
|
|
19
|
+
watchPaths.push('src/db/schema.ts');
|
|
20
|
+
logger.info(' Watching: src/db/schema.ts');
|
|
21
|
+
}
|
|
22
|
+
if (fs.existsSync('drizzle.config.ts')) {
|
|
23
|
+
watchPaths.push('drizzle.config.ts');
|
|
24
|
+
logger.info(' Watching: drizzle.config.ts');
|
|
25
|
+
}
|
|
26
|
+
if (watchPaths.length === 0) {
|
|
27
|
+
logger.warn('No schema files detected.');
|
|
28
|
+
logger.info(' Looking for:');
|
|
29
|
+
logger.info(' - prisma/schema.prisma');
|
|
30
|
+
logger.info(' - src/db/schema.ts');
|
|
31
|
+
logger.info(' - drizzle.config.ts');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
logger.info('');
|
|
35
|
+
logger.info('Watching for changes... (Press Ctrl+C to stop)');
|
|
36
|
+
let debounceTimer = null;
|
|
37
|
+
let generating = false;
|
|
38
|
+
const regenerate = async () => {
|
|
39
|
+
if (generating)
|
|
40
|
+
return;
|
|
41
|
+
generating = true;
|
|
42
|
+
logger.info(`Schema change detected, regenerating...`);
|
|
43
|
+
try {
|
|
44
|
+
await generate({});
|
|
45
|
+
logger.success('Regeneration complete');
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
logger.error('Regeneration failed:', error);
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
generating = false;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const handleChange = (filename) => {
|
|
55
|
+
logger.info(`Change detected: ${filename}`);
|
|
56
|
+
if (debounceTimer) {
|
|
57
|
+
clearTimeout(debounceTimer);
|
|
58
|
+
}
|
|
59
|
+
debounceTimer = setTimeout(regenerate, debounce);
|
|
60
|
+
};
|
|
61
|
+
// Watch each file
|
|
62
|
+
const watchers = watchPaths.map((filePath) => {
|
|
63
|
+
return fs.watch(filePath, (eventType, filename) => {
|
|
64
|
+
if (eventType === 'change') {
|
|
65
|
+
handleChange(filePath);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
// Keep process alive
|
|
70
|
+
process.on('SIGINT', () => {
|
|
71
|
+
logger.info('');
|
|
72
|
+
logger.info('Stopping watch mode...');
|
|
73
|
+
watchers.forEach((watcher) => watcher.close());
|
|
74
|
+
process.exit(0);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=watch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../../src/database/commands/watch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drizzle Schema Parser
|
|
3
|
+
* Extracts schema information from Drizzle schema.ts files
|
|
4
|
+
*/
|
|
5
|
+
export interface DrizzleColumnInfo {
|
|
6
|
+
name: string;
|
|
7
|
+
type: string;
|
|
8
|
+
isList: boolean;
|
|
9
|
+
isOptional: boolean;
|
|
10
|
+
isUnique: boolean;
|
|
11
|
+
isPrimaryKey: boolean;
|
|
12
|
+
isDefault: boolean;
|
|
13
|
+
defaultValue: string | null;
|
|
14
|
+
isRelation: boolean;
|
|
15
|
+
relationName: string | null;
|
|
16
|
+
onDelete: string | null;
|
|
17
|
+
}
|
|
18
|
+
export interface DrizzleIndexInfo {
|
|
19
|
+
name: string;
|
|
20
|
+
columns: string[];
|
|
21
|
+
unique: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface DrizzleRelationInfo {
|
|
24
|
+
name: string;
|
|
25
|
+
fromTable: string;
|
|
26
|
+
fromColumns: string[];
|
|
27
|
+
toTable: string;
|
|
28
|
+
toColumns: string[];
|
|
29
|
+
type: 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many';
|
|
30
|
+
onDelete: string | null;
|
|
31
|
+
}
|
|
32
|
+
export interface DrizzleTableInfo {
|
|
33
|
+
name: string;
|
|
34
|
+
description: string | null;
|
|
35
|
+
schema: string | null;
|
|
36
|
+
columns: DrizzleColumnInfo[];
|
|
37
|
+
indexes: DrizzleIndexInfo[];
|
|
38
|
+
relations: DrizzleRelationInfo[];
|
|
39
|
+
primaryKey: string[];
|
|
40
|
+
uniqueConstraints: string[][];
|
|
41
|
+
}
|
|
42
|
+
export interface DrizzleSchemaInfo {
|
|
43
|
+
tables: DrizzleTableInfo[];
|
|
44
|
+
dialect: 'postgresql' | 'mysql' | 'sqlite';
|
|
45
|
+
}
|
|
46
|
+
export declare class DrizzleExtractor {
|
|
47
|
+
private schemaPath;
|
|
48
|
+
private schemaContent;
|
|
49
|
+
constructor(schemaPath: string);
|
|
50
|
+
extract(): Promise<DrizzleSchemaInfo>;
|
|
51
|
+
private detectDialect;
|
|
52
|
+
private parseTables;
|
|
53
|
+
private parseTableDefinition;
|
|
54
|
+
private splitByComma;
|
|
55
|
+
private parseColumn;
|
|
56
|
+
private parseRelations;
|
|
57
|
+
close(): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
export declare const DRIZZLE_TYPE_MAPPINGS: {
|
|
60
|
+
drizzleType: string;
|
|
61
|
+
tsType: string;
|
|
62
|
+
}[];
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drizzle Schema Parser
|
|
3
|
+
* Extracts schema information from Drizzle schema.ts files
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
export class DrizzleExtractor {
|
|
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(`Drizzle schema not found at: ${this.schemaPath}`);
|
|
16
|
+
}
|
|
17
|
+
this.schemaContent = fs.readFileSync(this.schemaPath, 'utf-8');
|
|
18
|
+
const dialect = this.detectDialect();
|
|
19
|
+
const tables = this.parseTables();
|
|
20
|
+
this.parseRelations(tables);
|
|
21
|
+
return {
|
|
22
|
+
tables,
|
|
23
|
+
dialect,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
detectDialect() {
|
|
27
|
+
if (this.schemaContent.includes('pgTable') || this.schemaContent.includes('pgEnum')) {
|
|
28
|
+
return 'postgresql';
|
|
29
|
+
}
|
|
30
|
+
if (this.schemaContent.includes('mysqlTable') || this.schemaContent.includes('mysqlEnum')) {
|
|
31
|
+
return 'mysql';
|
|
32
|
+
}
|
|
33
|
+
if (this.schemaContent.includes('sqliteTable')) {
|
|
34
|
+
return 'sqlite';
|
|
35
|
+
}
|
|
36
|
+
return 'postgresql'; // Default
|
|
37
|
+
}
|
|
38
|
+
parseTables() {
|
|
39
|
+
const tables = [];
|
|
40
|
+
// Match table definitions with schema name
|
|
41
|
+
const tableRegex = /(?:export\s+)?(?:const|export)\s+(\w+)\s*=\s*(?:pgTable|mysqlTable|sqliteTable)\s*\(\s*["']([^"']+)["']\s*,\s*\{([^}]+)\}\s*(?:,\s*(\w+))?\s*\)/g;
|
|
42
|
+
let match;
|
|
43
|
+
while ((match = tableRegex.exec(this.schemaContent)) !== null) {
|
|
44
|
+
const tableName = match[1];
|
|
45
|
+
const tableSqlName = match[2];
|
|
46
|
+
const columnsBody = match[3];
|
|
47
|
+
const relationsExport = match[4];
|
|
48
|
+
const table = this.parseTableDefinition(tableName, tableSqlName, columnsBody);
|
|
49
|
+
tables.push(table);
|
|
50
|
+
}
|
|
51
|
+
return tables;
|
|
52
|
+
}
|
|
53
|
+
parseTableDefinition(name, sqlName, columnsBody) {
|
|
54
|
+
const columns = [];
|
|
55
|
+
const indexes = [];
|
|
56
|
+
let primaryKey = [];
|
|
57
|
+
const uniqueConstraints = [];
|
|
58
|
+
// Split by comma, but handle nested objects
|
|
59
|
+
const lines = this.splitByComma(columnsBody);
|
|
60
|
+
for (const line of lines) {
|
|
61
|
+
const trimmed = line.trim();
|
|
62
|
+
if (!trimmed)
|
|
63
|
+
continue;
|
|
64
|
+
// Parse column definition
|
|
65
|
+
const colMatch = trimmed.match(/^(\w+):\s*(.+)$/s);
|
|
66
|
+
if (colMatch) {
|
|
67
|
+
const [_, colName, colDef] = colMatch;
|
|
68
|
+
const column = this.parseColumn(colName, colDef);
|
|
69
|
+
columns.push(column);
|
|
70
|
+
if (column.isPrimaryKey) {
|
|
71
|
+
primaryKey.push(colName);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
name,
|
|
77
|
+
description: null,
|
|
78
|
+
schema: sqlName,
|
|
79
|
+
columns,
|
|
80
|
+
indexes,
|
|
81
|
+
relations: [],
|
|
82
|
+
primaryKey,
|
|
83
|
+
uniqueConstraints,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
splitByComma(str) {
|
|
87
|
+
const result = [];
|
|
88
|
+
let current = '';
|
|
89
|
+
let depth = 0;
|
|
90
|
+
for (let i = 0; i < str.length; i++) {
|
|
91
|
+
const char = str[i];
|
|
92
|
+
if (char === '{' || char === '[')
|
|
93
|
+
depth++;
|
|
94
|
+
if (char === '}' || char === ']')
|
|
95
|
+
depth--;
|
|
96
|
+
if (char === ',' && depth === 0) {
|
|
97
|
+
result.push(current);
|
|
98
|
+
current = '';
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
current += char;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (current.trim()) {
|
|
105
|
+
result.push(current);
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
parseColumn(name, def) {
|
|
110
|
+
let type = '';
|
|
111
|
+
let isOptional = false;
|
|
112
|
+
let isUnique = false;
|
|
113
|
+
let isPrimaryKey = false;
|
|
114
|
+
let isDefault = false;
|
|
115
|
+
let defaultValue = null;
|
|
116
|
+
let isRelation = false;
|
|
117
|
+
let relationName = null;
|
|
118
|
+
let onDelete = null;
|
|
119
|
+
// Extract type and options
|
|
120
|
+
const typeMatch = def.match(/^([\w.]+)/);
|
|
121
|
+
if (typeMatch) {
|
|
122
|
+
type = typeMatch[1];
|
|
123
|
+
}
|
|
124
|
+
const optionsStr = def.substring(type.length);
|
|
125
|
+
// Parse options
|
|
126
|
+
const optionalMatch = optionsStr.match(/\.optional\(\)/);
|
|
127
|
+
if (optionalMatch) {
|
|
128
|
+
isOptional = true;
|
|
129
|
+
}
|
|
130
|
+
const primaryKeyMatch = optionsStr.match(/\.primaryKey\(\)/);
|
|
131
|
+
if (primaryKeyMatch) {
|
|
132
|
+
isPrimaryKey = true;
|
|
133
|
+
}
|
|
134
|
+
const uniqueMatch = optionsStr.match(/\.unique\(\)/);
|
|
135
|
+
if (uniqueMatch) {
|
|
136
|
+
isUnique = true;
|
|
137
|
+
}
|
|
138
|
+
const defaultMatch = optionsStr.match(/\.default\(([^)]+)\)/);
|
|
139
|
+
if (defaultMatch) {
|
|
140
|
+
isDefault = true;
|
|
141
|
+
defaultValue = defaultMatch[1].trim();
|
|
142
|
+
}
|
|
143
|
+
// Check for references
|
|
144
|
+
const referencesMatch = optionsStr.match(/\.references?\s*\(\s*\(\)\s*=>\s*(\w+)\.(\w+)\)/);
|
|
145
|
+
if (referencesMatch) {
|
|
146
|
+
isRelation = true;
|
|
147
|
+
relationName = referencesMatch[1];
|
|
148
|
+
}
|
|
149
|
+
// Check for onDelete
|
|
150
|
+
const onDeleteMatch = optionsStr.match(/onDelete:\s*['"]?(\w+)['"]?/);
|
|
151
|
+
if (onDeleteMatch) {
|
|
152
|
+
onDelete = onDeleteMatch[1].toUpperCase();
|
|
153
|
+
}
|
|
154
|
+
// Check for serial/autoIncrement
|
|
155
|
+
if (optionsStr.includes('.serial()') || optionsStr.includes('.autoincrement()')) {
|
|
156
|
+
type = type === 'integer' ? 'serial' : type;
|
|
157
|
+
}
|
|
158
|
+
// Normalize type names
|
|
159
|
+
if (optionsStr.includes('.text()'))
|
|
160
|
+
type = 'text';
|
|
161
|
+
if (optionsStr.includes('.varchar()'))
|
|
162
|
+
type = 'varchar';
|
|
163
|
+
if (optionsStr.includes('.integer()'))
|
|
164
|
+
type = 'integer';
|
|
165
|
+
if (optionsStr.includes('.boolean()'))
|
|
166
|
+
type = 'boolean';
|
|
167
|
+
if (optionsStr.includes('.timestamp()'))
|
|
168
|
+
type = 'timestamp';
|
|
169
|
+
if (optionsStr.includes('.json()'))
|
|
170
|
+
type = 'json';
|
|
171
|
+
if (optionsStr.includes('.uuid()'))
|
|
172
|
+
type = 'uuid';
|
|
173
|
+
return {
|
|
174
|
+
name,
|
|
175
|
+
type,
|
|
176
|
+
isList: false,
|
|
177
|
+
isOptional,
|
|
178
|
+
isUnique,
|
|
179
|
+
isPrimaryKey,
|
|
180
|
+
isDefault,
|
|
181
|
+
defaultValue,
|
|
182
|
+
isRelation,
|
|
183
|
+
relationName,
|
|
184
|
+
onDelete,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
parseRelations(tables) {
|
|
188
|
+
const tableMap = new Map(tables.map((t) => [t.name, t]));
|
|
189
|
+
// Parse relation definitions
|
|
190
|
+
const relationsRegex = /export\s+const\s+(\w+)\s*=\s*relations?\s*\(\s*(\w+)\s*,\s*\(\{\s*([\s\S]*?)\}\s*\)\s*=>\s*\{([^}]*)\}\s*\)/g;
|
|
191
|
+
let match;
|
|
192
|
+
while ((match = relationsRegex.exec(this.schemaContent)) !== null) {
|
|
193
|
+
const relationName = match[1];
|
|
194
|
+
const tableName = match[2];
|
|
195
|
+
const fieldsSection = match[3];
|
|
196
|
+
const refsSection = match[4];
|
|
197
|
+
const table = tableMap.get(tableName);
|
|
198
|
+
if (!table)
|
|
199
|
+
continue;
|
|
200
|
+
// Parse many-to-many relations
|
|
201
|
+
const manyToManyMatch = refsSection.match(/many\s*:\s*\[([^\]]+)\]/);
|
|
202
|
+
if (manyToManyMatch) {
|
|
203
|
+
const relatedTables = manyToManyMatch[1].split(',').map((s) => s.trim());
|
|
204
|
+
for (const relatedName of relatedTables) {
|
|
205
|
+
const relation = {
|
|
206
|
+
name: relationName,
|
|
207
|
+
fromTable: tableName,
|
|
208
|
+
fromColumns: [],
|
|
209
|
+
toTable: relatedName,
|
|
210
|
+
toColumns: [],
|
|
211
|
+
type: 'many-to-many',
|
|
212
|
+
onDelete: null,
|
|
213
|
+
};
|
|
214
|
+
table.relations.push(relation);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// Parse one-to-many
|
|
218
|
+
const oneToManyMatch = refsSection.match(/one\s*:\s*\[([^\]]+)\]/);
|
|
219
|
+
if (oneToManyMatch) {
|
|
220
|
+
const relatedTables = oneToManyMatch[1].split(',').map((s) => s.trim());
|
|
221
|
+
for (const relatedName of relatedTables) {
|
|
222
|
+
const relation = {
|
|
223
|
+
name: relationName,
|
|
224
|
+
fromTable: tableName,
|
|
225
|
+
fromColumns: [],
|
|
226
|
+
toTable: relatedName,
|
|
227
|
+
toColumns: [],
|
|
228
|
+
type: 'one-to-many',
|
|
229
|
+
onDelete: null,
|
|
230
|
+
};
|
|
231
|
+
table.relations.push(relation);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
async close() { }
|
|
237
|
+
}
|
|
238
|
+
// Drizzle to TypeScript type mappings
|
|
239
|
+
export const DRIZZLE_TYPE_MAPPINGS = [
|
|
240
|
+
{ drizzleType: 'text', tsType: 'string' },
|
|
241
|
+
{ drizzleType: 'varchar', tsType: 'string' },
|
|
242
|
+
{ drizzleType: 'integer', tsType: 'number' },
|
|
243
|
+
{ drizzleType: 'serial', tsType: 'number' },
|
|
244
|
+
{ drizzleType: 'bigint', tsType: 'bigint' },
|
|
245
|
+
{ drizzleType: 'boolean', tsType: 'boolean' },
|
|
246
|
+
{ drizzleType: 'timestamp', tsType: 'Date' },
|
|
247
|
+
{ drizzleType: 'date', tsType: 'Date' },
|
|
248
|
+
{ drizzleType: 'json', tsType: 'Record<string, unknown>' },
|
|
249
|
+
{ drizzleType: 'uuid', tsType: 'string' },
|
|
250
|
+
];
|
|
251
|
+
//# sourceMappingURL=drizzle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle.js","sourceRoot":"","sources":["../../../src/database/extractors/drizzle.ts"],"names":[],"mappings":"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"}
|