repowiki-core 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/analyzer/api-analyzer.d.ts +22 -0
- package/dist/analyzer/api-analyzer.d.ts.map +1 -0
- package/dist/analyzer/api-analyzer.js +272 -0
- package/dist/analyzer/api-analyzer.js.map +1 -0
- package/dist/analyzer/config-analyzer.d.ts +18 -0
- package/dist/analyzer/config-analyzer.d.ts.map +1 -0
- package/dist/analyzer/config-analyzer.js +200 -0
- package/dist/analyzer/config-analyzer.js.map +1 -0
- package/dist/analyzer/database-analyzer.d.ts +24 -0
- package/dist/analyzer/database-analyzer.d.ts.map +1 -0
- package/dist/analyzer/database-analyzer.js +391 -0
- package/dist/analyzer/database-analyzer.js.map +1 -0
- package/dist/analyzer/index.d.ts +10 -0
- package/dist/analyzer/index.d.ts.map +1 -0
- package/dist/analyzer/index.js +10 -0
- package/dist/analyzer/index.js.map +1 -0
- package/dist/analyzer/module-analyzer.d.ts +20 -0
- package/dist/analyzer/module-analyzer.d.ts.map +1 -0
- package/dist/analyzer/module-analyzer.js +252 -0
- package/dist/analyzer/module-analyzer.js.map +1 -0
- package/dist/analyzer/workflow-analyzer.d.ts +19 -0
- package/dist/analyzer/workflow-analyzer.d.ts.map +1 -0
- package/dist/analyzer/workflow-analyzer.js +165 -0
- package/dist/analyzer/workflow-analyzer.js.map +1 -0
- package/dist/detector/dependency-detector.d.ts +50 -0
- package/dist/detector/dependency-detector.d.ts.map +1 -0
- package/dist/detector/dependency-detector.js +326 -0
- package/dist/detector/dependency-detector.js.map +1 -0
- package/dist/detector/entrypoint-detector.d.ts +30 -0
- package/dist/detector/entrypoint-detector.d.ts.map +1 -0
- package/dist/detector/entrypoint-detector.js +240 -0
- package/dist/detector/entrypoint-detector.js.map +1 -0
- package/dist/detector/index.d.ts +10 -0
- package/dist/detector/index.d.ts.map +1 -0
- package/dist/detector/index.js +10 -0
- package/dist/detector/index.js.map +1 -0
- package/dist/detector/tech-stack-detector.d.ts +41 -0
- package/dist/detector/tech-stack-detector.d.ts.map +1 -0
- package/dist/detector/tech-stack-detector.js +300 -0
- package/dist/detector/tech-stack-detector.js.map +1 -0
- package/dist/generator/index.d.ts +9 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +9 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/markdown-generator.d.ts +71 -0
- package/dist/generator/markdown-generator.d.ts.map +1 -0
- package/dist/generator/markdown-generator.js +235 -0
- package/dist/generator/markdown-generator.js.map +1 -0
- package/dist/generator/mermaid-generator.d.ts +30 -0
- package/dist/generator/mermaid-generator.d.ts.map +1 -0
- package/dist/generator/mermaid-generator.js +297 -0
- package/dist/generator/mermaid-generator.js.map +1 -0
- package/dist/generator/sidebar-generator.d.ts +10 -0
- package/dist/generator/sidebar-generator.d.ts.map +1 -0
- package/dist/generator/sidebar-generator.js +120 -0
- package/dist/generator/sidebar-generator.js.map +1 -0
- package/dist/generator/wiki-generator.d.ts +45 -0
- package/dist/generator/wiki-generator.d.ts.map +1 -0
- package/dist/generator/wiki-generator.js +217 -0
- package/dist/generator/wiki-generator.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/auth-manager.d.ts +50 -0
- package/dist/llm/auth-manager.d.ts.map +1 -0
- package/dist/llm/auth-manager.js +172 -0
- package/dist/llm/auth-manager.js.map +1 -0
- package/dist/llm/index.d.ts +10 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +9 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/llm-client.d.ts +132 -0
- package/dist/llm/llm-client.d.ts.map +1 -0
- package/dist/llm/llm-client.js +308 -0
- package/dist/llm/llm-client.js.map +1 -0
- package/dist/llm/prompt-manager.d.ts +67 -0
- package/dist/llm/prompt-manager.d.ts.map +1 -0
- package/dist/llm/prompt-manager.js +283 -0
- package/dist/llm/prompt-manager.js.map +1 -0
- package/dist/models/analysis-result.d.ts +425 -0
- package/dist/models/analysis-result.d.ts.map +1 -0
- package/dist/models/analysis-result.js +34 -0
- package/dist/models/analysis-result.js.map +1 -0
- package/dist/models/analysis-types.d.ts +223 -0
- package/dist/models/analysis-types.d.ts.map +1 -0
- package/dist/models/analysis-types.js +95 -0
- package/dist/models/analysis-types.js.map +1 -0
- package/dist/models/file-reference.d.ts +62 -0
- package/dist/models/file-reference.d.ts.map +1 -0
- package/dist/models/file-reference.js +34 -0
- package/dist/models/file-reference.js.map +1 -0
- package/dist/models/index.d.ts +10 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +10 -0
- package/dist/models/index.js.map +1 -0
- package/dist/models/project-profile.d.ts +48 -0
- package/dist/models/project-profile.d.ts.map +1 -0
- package/dist/models/project-profile.js +26 -0
- package/dist/models/project-profile.js.map +1 -0
- package/dist/models/wiki-page.d.ts +57 -0
- package/dist/models/wiki-page.d.ts.map +1 -0
- package/dist/models/wiki-page.js +19 -0
- package/dist/models/wiki-page.js.map +1 -0
- package/dist/pipeline.d.ts +30 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +159 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/scanner/file-scanner.d.ts +27 -0
- package/dist/scanner/file-scanner.d.ts.map +1 -0
- package/dist/scanner/file-scanner.js +149 -0
- package/dist/scanner/file-scanner.js.map +1 -0
- package/dist/scanner/ignore-rules.d.ts +31 -0
- package/dist/scanner/ignore-rules.d.ts.map +1 -0
- package/dist/scanner/ignore-rules.js +98 -0
- package/dist/scanner/ignore-rules.js.map +1 -0
- package/dist/scanner/index.d.ts +8 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +8 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/tree-builder.d.ts +20 -0
- package/dist/scanner/tree-builder.d.ts.map +1 -0
- package/dist/scanner/tree-builder.js +118 -0
- package/dist/scanner/tree-builder.js.map +1 -0
- package/package.json +34 -0
- package/src/analyzer/api-analyzer.ts +324 -0
- package/src/analyzer/config-analyzer.ts +209 -0
- package/src/analyzer/database-analyzer.ts +468 -0
- package/src/analyzer/index.ts +26 -0
- package/src/analyzer/module-analyzer.ts +308 -0
- package/src/analyzer/workflow-analyzer.ts +190 -0
- package/src/detector/dependency-detector.ts +390 -0
- package/src/detector/entrypoint-detector.ts +270 -0
- package/src/detector/index.ts +21 -0
- package/src/detector/tech-stack-detector.ts +377 -0
- package/src/generator/index.ts +36 -0
- package/src/generator/markdown-generator.ts +277 -0
- package/src/generator/mermaid-generator.ts +340 -0
- package/src/generator/sidebar-generator.ts +134 -0
- package/src/generator/wiki-generator.ts +281 -0
- package/src/index.ts +12 -0
- package/src/llm/auth-manager.ts +207 -0
- package/src/llm/index.ts +21 -0
- package/src/llm/llm-client.ts +417 -0
- package/src/llm/prompt-manager.ts +325 -0
- package/src/models/analysis-result.ts +44 -0
- package/src/models/analysis-types.ts +121 -0
- package/src/models/file-reference.ts +41 -0
- package/src/models/index.ts +44 -0
- package/src/models/project-profile.ts +29 -0
- package/src/models/wiki-page.ts +23 -0
- package/src/pipeline.ts +225 -0
- package/src/scanner/file-scanner.ts +192 -0
- package/src/scanner/ignore-rules.ts +112 -0
- package/src/scanner/index.ts +19 -0
- package/src/scanner/tree-builder.ts +156 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 数据库模型分析器
|
|
3
|
+
* 通过正则表达式从 ORM 定义文件中提取数据模型、字段和关系信息。
|
|
4
|
+
* 支持 SQLAlchemy、Prisma、TypeORM、Mongoose 四种 ORM。
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'node:fs/promises';
|
|
7
|
+
import * as path from 'node:path';
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// 模型文件过滤
|
|
10
|
+
// ============================================================================
|
|
11
|
+
/** 路径中包含这些关键词的文件可能定义数据模型 */
|
|
12
|
+
const MODEL_PATH_KEYWORDS = ['model', 'entity', 'schema', 'entities'];
|
|
13
|
+
/** 特定文件名(精确匹配)*/
|
|
14
|
+
const MODEL_FILE_NAMES = ['schema.prisma'];
|
|
15
|
+
/**
|
|
16
|
+
* 判断文件是否可能包含数据模型定义
|
|
17
|
+
* @param relativePath - 文件相对路径
|
|
18
|
+
* @returns 是否为候选模型文件
|
|
19
|
+
*/
|
|
20
|
+
function isModelCandidateFile(relativePath) {
|
|
21
|
+
const normalized = relativePath.replace(/\\/g, '/').toLowerCase();
|
|
22
|
+
const basename = path.basename(normalized);
|
|
23
|
+
if (MODEL_FILE_NAMES.includes(basename)) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
return MODEL_PATH_KEYWORDS.some((kw) => normalized.includes(kw));
|
|
27
|
+
}
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// SQLAlchemy 解析器
|
|
30
|
+
// ============================================================================
|
|
31
|
+
/** SQLAlchemy 类定义:class User(Base) 或 class User(db.Model) */
|
|
32
|
+
const SQLALCHEMY_CLASS_PATTERN = /class\s+(\w+)\s*\([^)]*(?:Base|Model)[^)]*\)/g;
|
|
33
|
+
/** SQLAlchemy Column 定义:name = Column(String, ...) */
|
|
34
|
+
const SQLALCHEMY_COLUMN_PATTERN = /(\w+)\s*=\s*Column\(\s*(\w+)/g;
|
|
35
|
+
/** SQLAlchemy relationship:children = relationship("Child") */
|
|
36
|
+
const SQLALCHEMY_RELATIONSHIP_PATTERN = /(\w+)\s*=\s*relationship\(\s*['"]?(\w+)/g;
|
|
37
|
+
/**
|
|
38
|
+
* 从 SQLAlchemy 文件内容中提取模型
|
|
39
|
+
* @param content - 文件内容
|
|
40
|
+
* @param filePath - 文件相对路径
|
|
41
|
+
* @returns 提取到的数据库模型数组
|
|
42
|
+
*/
|
|
43
|
+
function extractSQLAlchemyModels(content, filePath) {
|
|
44
|
+
const models = [];
|
|
45
|
+
SQLALCHEMY_CLASS_PATTERN.lastIndex = 0;
|
|
46
|
+
let classMatch;
|
|
47
|
+
while ((classMatch = SQLALCHEMY_CLASS_PATTERN.exec(content)) !== null) {
|
|
48
|
+
const modelName = classMatch[1];
|
|
49
|
+
const classStartIndex = classMatch.index;
|
|
50
|
+
// 查找此类的大致范围(到下一个 class 或文件末尾)
|
|
51
|
+
const nextClassIndex = content.indexOf('\nclass ', classStartIndex + 1);
|
|
52
|
+
const classBody = nextClassIndex !== -1
|
|
53
|
+
? content.slice(classStartIndex, nextClassIndex)
|
|
54
|
+
: content.slice(classStartIndex);
|
|
55
|
+
// 提取字段
|
|
56
|
+
const fields = [];
|
|
57
|
+
SQLALCHEMY_COLUMN_PATTERN.lastIndex = 0;
|
|
58
|
+
let colMatch;
|
|
59
|
+
while ((colMatch = SQLALCHEMY_COLUMN_PATTERN.exec(classBody)) !== null) {
|
|
60
|
+
fields.push({
|
|
61
|
+
name: colMatch[1],
|
|
62
|
+
type: colMatch[2],
|
|
63
|
+
nullable: classBody.includes(`${colMatch[1]}`) && classBody.includes('nullable=True'),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
// 提取关系
|
|
67
|
+
const relations = [];
|
|
68
|
+
SQLALCHEMY_RELATIONSHIP_PATTERN.lastIndex = 0;
|
|
69
|
+
let relMatch;
|
|
70
|
+
while ((relMatch = SQLALCHEMY_RELATIONSHIP_PATTERN.exec(classBody)) !== null) {
|
|
71
|
+
relations.push({
|
|
72
|
+
fieldName: relMatch[1],
|
|
73
|
+
relatedModel: relMatch[2],
|
|
74
|
+
relationType: 'relationship',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
models.push({
|
|
78
|
+
name: modelName,
|
|
79
|
+
filePath,
|
|
80
|
+
orm: 'sqlalchemy',
|
|
81
|
+
fields,
|
|
82
|
+
relations,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return models;
|
|
86
|
+
}
|
|
87
|
+
// ============================================================================
|
|
88
|
+
// Prisma 解析器
|
|
89
|
+
// ============================================================================
|
|
90
|
+
/** Prisma model 块:model User { ... } */
|
|
91
|
+
const PRISMA_MODEL_PATTERN = /model\s+(\w+)\s*\{([^}]*)\}/g;
|
|
92
|
+
/** Prisma 字段行:name Type? @... */
|
|
93
|
+
const PRISMA_FIELD_PATTERN = /^\s+(\w+)\s+(\w+)(\??)/gm;
|
|
94
|
+
/**
|
|
95
|
+
* 从 Prisma schema 文件中提取模型
|
|
96
|
+
* @param content - 文件内容
|
|
97
|
+
* @param filePath - 文件相对路径
|
|
98
|
+
* @returns 提取到的数据库模型数组
|
|
99
|
+
*/
|
|
100
|
+
function extractPrismaModels(content, filePath) {
|
|
101
|
+
const models = [];
|
|
102
|
+
// 先收集所有模型名称用于关系推断
|
|
103
|
+
const allModelNames = new Set();
|
|
104
|
+
PRISMA_MODEL_PATTERN.lastIndex = 0;
|
|
105
|
+
let nameMatch;
|
|
106
|
+
while ((nameMatch = PRISMA_MODEL_PATTERN.exec(content)) !== null) {
|
|
107
|
+
allModelNames.add(nameMatch[1]);
|
|
108
|
+
}
|
|
109
|
+
PRISMA_MODEL_PATTERN.lastIndex = 0;
|
|
110
|
+
let modelMatch;
|
|
111
|
+
while ((modelMatch = PRISMA_MODEL_PATTERN.exec(content)) !== null) {
|
|
112
|
+
const modelName = modelMatch[1];
|
|
113
|
+
const modelBody = modelMatch[2];
|
|
114
|
+
const fields = [];
|
|
115
|
+
const relations = [];
|
|
116
|
+
// 逐行解析模型体
|
|
117
|
+
const bodyLines = modelBody.split('\n');
|
|
118
|
+
for (const line of bodyLines) {
|
|
119
|
+
const trimmed = line.trim();
|
|
120
|
+
if (!trimmed || trimmed.startsWith('//') || trimmed.startsWith('@@')) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
// 匹配字段:fieldName FieldType? @...
|
|
124
|
+
const fieldMatch = /^(\w+)\s+(\w+)(\??)(\[\])?/.exec(trimmed);
|
|
125
|
+
if (fieldMatch) {
|
|
126
|
+
const fieldName = fieldMatch[1];
|
|
127
|
+
const fieldType = fieldMatch[2];
|
|
128
|
+
const isNullable = fieldMatch[3] === '?';
|
|
129
|
+
const isArray = fieldMatch[4] === '[]';
|
|
130
|
+
// 如果类型是另一个模型名称,则为关系字段
|
|
131
|
+
if (allModelNames.has(fieldType)) {
|
|
132
|
+
relations.push({
|
|
133
|
+
fieldName,
|
|
134
|
+
relatedModel: fieldType,
|
|
135
|
+
relationType: isArray ? 'OneToMany' : 'ManyToOne',
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
fields.push({
|
|
140
|
+
name: fieldName,
|
|
141
|
+
type: fieldType,
|
|
142
|
+
nullable: isNullable,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
models.push({
|
|
148
|
+
name: modelName,
|
|
149
|
+
filePath,
|
|
150
|
+
orm: 'prisma',
|
|
151
|
+
fields,
|
|
152
|
+
relations,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return models;
|
|
156
|
+
}
|
|
157
|
+
// ============================================================================
|
|
158
|
+
// TypeORM 解析器
|
|
159
|
+
// ============================================================================
|
|
160
|
+
/** TypeORM @Entity() 装饰器后的类名 */
|
|
161
|
+
const TYPEORM_ENTITY_PATTERN = /@Entity\(\s*\)\s*(?:export\s+)?class\s+(\w+)/g;
|
|
162
|
+
/** TypeORM @Column 装饰器后的属性 */
|
|
163
|
+
const TYPEORM_COLUMN_PATTERN = /@Column\([^)]*\)\s*(\w+)\s*[!?]?\s*:\s*(\w+)/g;
|
|
164
|
+
/** TypeORM 关系装饰器 */
|
|
165
|
+
const TYPEORM_RELATION_PATTERN = /@(ManyToOne|OneToMany|ManyToMany|OneToOne)\([^)]*\)\s*(\w+)\s*[!?]?\s*:/g;
|
|
166
|
+
/**
|
|
167
|
+
* 从 TypeORM 文件中提取模型
|
|
168
|
+
* @param content - 文件内容
|
|
169
|
+
* @param filePath - 文件相对路径
|
|
170
|
+
* @returns 提取到的数据库模型数组
|
|
171
|
+
*/
|
|
172
|
+
function extractTypeORMModels(content, filePath) {
|
|
173
|
+
const models = [];
|
|
174
|
+
// 检测所有 Entity 定义的位置
|
|
175
|
+
const entityPositions = [];
|
|
176
|
+
TYPEORM_ENTITY_PATTERN.lastIndex = 0;
|
|
177
|
+
let entityMatch;
|
|
178
|
+
while ((entityMatch = TYPEORM_ENTITY_PATTERN.exec(content)) !== null) {
|
|
179
|
+
entityPositions.push({ name: entityMatch[1], startIndex: entityMatch.index });
|
|
180
|
+
}
|
|
181
|
+
for (let i = 0; i < entityPositions.length; i++) {
|
|
182
|
+
const entity = entityPositions[i];
|
|
183
|
+
const nextStart = i + 1 < entityPositions.length ? entityPositions[i + 1].startIndex : content.length;
|
|
184
|
+
const classBody = content.slice(entity.startIndex, nextStart);
|
|
185
|
+
// 提取字段
|
|
186
|
+
const fields = [];
|
|
187
|
+
TYPEORM_COLUMN_PATTERN.lastIndex = 0;
|
|
188
|
+
let colMatch;
|
|
189
|
+
while ((colMatch = TYPEORM_COLUMN_PATTERN.exec(classBody)) !== null) {
|
|
190
|
+
fields.push({
|
|
191
|
+
name: colMatch[1],
|
|
192
|
+
type: colMatch[2],
|
|
193
|
+
nullable: classBody.includes('nullable: true'),
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
// 提取关系
|
|
197
|
+
const relations = [];
|
|
198
|
+
TYPEORM_RELATION_PATTERN.lastIndex = 0;
|
|
199
|
+
let relMatch;
|
|
200
|
+
while ((relMatch = TYPEORM_RELATION_PATTERN.exec(classBody)) !== null) {
|
|
201
|
+
// 尝试从装饰器参数中提取关联模型
|
|
202
|
+
const afterDecorator = classBody.slice(relMatch.index);
|
|
203
|
+
const modelRef = /\(\s*\(\)\s*=>\s*(\w+)/.exec(afterDecorator);
|
|
204
|
+
relations.push({
|
|
205
|
+
fieldName: relMatch[2],
|
|
206
|
+
relatedModel: modelRef ? modelRef[1] : '',
|
|
207
|
+
relationType: relMatch[1],
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
models.push({
|
|
211
|
+
name: entity.name,
|
|
212
|
+
filePath,
|
|
213
|
+
orm: 'typeorm',
|
|
214
|
+
fields,
|
|
215
|
+
relations,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return models;
|
|
219
|
+
}
|
|
220
|
+
// ============================================================================
|
|
221
|
+
// Mongoose 解析器
|
|
222
|
+
// ============================================================================
|
|
223
|
+
/** Mongoose Schema 构造 */
|
|
224
|
+
const MONGOOSE_SCHEMA_PATTERN = /(?:new\s+(?:mongoose\.)?Schema|mongoose\.Schema)\s*\(/g;
|
|
225
|
+
/** 变量名赋值形式:const userSchema = new Schema( */
|
|
226
|
+
const MONGOOSE_SCHEMA_VAR_PATTERN = /(?:const|let|var)\s+(\w+)\s*=\s*new\s+(?:mongoose\.)?Schema\s*\(/g;
|
|
227
|
+
/**
|
|
228
|
+
* 从 Mongoose 文件中提取模型
|
|
229
|
+
* @param content - 文件内容
|
|
230
|
+
* @param filePath - 文件相对路径
|
|
231
|
+
* @returns 提取到的数据库模型数组
|
|
232
|
+
*/
|
|
233
|
+
function extractMongooseModels(content, filePath) {
|
|
234
|
+
const models = [];
|
|
235
|
+
// 尝试从 mongoose.model("Name", schema) 中提取模型名
|
|
236
|
+
const modelNamePattern = /mongoose\.model\s*\(\s*['"](\w+)['"]/g;
|
|
237
|
+
const modelNames = [];
|
|
238
|
+
let nameMatch;
|
|
239
|
+
while ((nameMatch = modelNamePattern.exec(content)) !== null) {
|
|
240
|
+
modelNames.push(nameMatch[1]);
|
|
241
|
+
}
|
|
242
|
+
// 同时尝试从变量名推断
|
|
243
|
+
MONGOOSE_SCHEMA_VAR_PATTERN.lastIndex = 0;
|
|
244
|
+
let varMatch;
|
|
245
|
+
while ((varMatch = MONGOOSE_SCHEMA_VAR_PATTERN.exec(content)) !== null) {
|
|
246
|
+
const varName = varMatch[1];
|
|
247
|
+
// 将 userSchema 转换为 User
|
|
248
|
+
const inferred = varName
|
|
249
|
+
.replace(/Schema$/i, '')
|
|
250
|
+
.replace(/^./, (c) => c.toUpperCase());
|
|
251
|
+
if (inferred && !modelNames.includes(inferred)) {
|
|
252
|
+
modelNames.push(inferred);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// 检查文件是否确实包含 Schema 构造
|
|
256
|
+
MONGOOSE_SCHEMA_PATTERN.lastIndex = 0;
|
|
257
|
+
if (!MONGOOSE_SCHEMA_PATTERN.test(content)) {
|
|
258
|
+
return models;
|
|
259
|
+
}
|
|
260
|
+
// 提取 Schema 对象中的属性定义
|
|
261
|
+
// 简单匹配 key: { type: Type } 或 key: Type 模式
|
|
262
|
+
const fields = [];
|
|
263
|
+
const schemaFieldPattern = /(\w+)\s*:\s*\{?\s*type\s*:\s*(\w+)/g;
|
|
264
|
+
const simpleFieldPattern = /(\w+)\s*:\s*(String|Number|Boolean|Date|ObjectId|Buffer|Map)/g;
|
|
265
|
+
let fieldMatch;
|
|
266
|
+
schemaFieldPattern.lastIndex = 0;
|
|
267
|
+
while ((fieldMatch = schemaFieldPattern.exec(content)) !== null) {
|
|
268
|
+
if (!fields.some((f) => f.name === fieldMatch[1])) {
|
|
269
|
+
fields.push({
|
|
270
|
+
name: fieldMatch[1],
|
|
271
|
+
type: fieldMatch[2],
|
|
272
|
+
nullable: false,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
simpleFieldPattern.lastIndex = 0;
|
|
277
|
+
while ((fieldMatch = simpleFieldPattern.exec(content)) !== null) {
|
|
278
|
+
if (!fields.some((f) => f.name === fieldMatch[1])) {
|
|
279
|
+
fields.push({
|
|
280
|
+
name: fieldMatch[1],
|
|
281
|
+
type: fieldMatch[2],
|
|
282
|
+
nullable: false,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// 检测关系(ObjectId + ref)
|
|
287
|
+
const relations = [];
|
|
288
|
+
const refPattern = /(\w+)\s*:.*ref\s*:\s*['"](\w+)['"]/g;
|
|
289
|
+
let refMatch;
|
|
290
|
+
while ((refMatch = refPattern.exec(content)) !== null) {
|
|
291
|
+
relations.push({
|
|
292
|
+
fieldName: refMatch[1],
|
|
293
|
+
relatedModel: refMatch[2],
|
|
294
|
+
relationType: 'ref',
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
// 为每个检测到的模型名创建记录
|
|
298
|
+
const effectiveNames = modelNames.length > 0 ? modelNames : [guessModelNameFromPath(filePath)];
|
|
299
|
+
for (const name of effectiveNames) {
|
|
300
|
+
models.push({
|
|
301
|
+
name,
|
|
302
|
+
filePath,
|
|
303
|
+
orm: 'mongoose',
|
|
304
|
+
fields: [...fields],
|
|
305
|
+
relations: [...relations],
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
return models;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* 从文件路径中猜测模型名
|
|
312
|
+
* @param filePath - 文件相对路径
|
|
313
|
+
* @returns 猜测的模型名
|
|
314
|
+
*/
|
|
315
|
+
function guessModelNameFromPath(filePath) {
|
|
316
|
+
const basename = path.basename(filePath, path.extname(filePath));
|
|
317
|
+
// 移除常见后缀
|
|
318
|
+
const cleaned = basename.replace(/[.\-_]?(model|entity|schema)$/i, '');
|
|
319
|
+
return cleaned.replace(/^./, (c) => c.toUpperCase());
|
|
320
|
+
}
|
|
321
|
+
// ============================================================================
|
|
322
|
+
// ORM 检测与分发
|
|
323
|
+
// ============================================================================
|
|
324
|
+
/**
|
|
325
|
+
* 检测文件中使用的 ORM 并提取模型
|
|
326
|
+
* @param content - 文件内容
|
|
327
|
+
* @param filePath - 文件相对路径
|
|
328
|
+
* @returns 提取到的数据库模型数组
|
|
329
|
+
*/
|
|
330
|
+
function extractModelsFromContent(content, filePath) {
|
|
331
|
+
const allModels = [];
|
|
332
|
+
// Prisma(根据文件扩展名和内容特征判断)
|
|
333
|
+
if (filePath.endsWith('.prisma') || /^model\s+\w+\s*\{/m.test(content)) {
|
|
334
|
+
allModels.push(...extractPrismaModels(content, filePath));
|
|
335
|
+
}
|
|
336
|
+
// SQLAlchemy(Python 风格 + Base/Model 继承)
|
|
337
|
+
if (/class\s+\w+\s*\([^)]*(?:Base|Model)/.test(content) && /Column\(/.test(content)) {
|
|
338
|
+
allModels.push(...extractSQLAlchemyModels(content, filePath));
|
|
339
|
+
}
|
|
340
|
+
// TypeORM(@Entity 装饰器)
|
|
341
|
+
if (/@Entity\s*\(/.test(content)) {
|
|
342
|
+
allModels.push(...extractTypeORMModels(content, filePath));
|
|
343
|
+
}
|
|
344
|
+
// Mongoose(new Schema 或 mongoose.Schema)
|
|
345
|
+
if (/(?:new\s+(?:mongoose\.)?Schema|mongoose\.Schema)\s*\(/.test(content)) {
|
|
346
|
+
allModels.push(...extractMongooseModels(content, filePath));
|
|
347
|
+
}
|
|
348
|
+
return allModels;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* 分析项目中的数据库模型定义
|
|
352
|
+
*
|
|
353
|
+
* 从扫描到的文件列表中筛选可能包含 ORM 模型定义的文件,
|
|
354
|
+
* 读取其内容并通过正则提取模型名、字段和关系信息。
|
|
355
|
+
*
|
|
356
|
+
* 支持的 ORM:
|
|
357
|
+
* - SQLAlchemy(Python,Column + relationship 解析)
|
|
358
|
+
* - Prisma(schema.prisma 文件解析)
|
|
359
|
+
* - TypeORM(TypeScript @Entity 装饰器解析)
|
|
360
|
+
* - Mongoose(TypeScript/JavaScript Schema 解析)
|
|
361
|
+
*
|
|
362
|
+
* @param rootPath - 项目根目录的绝对路径
|
|
363
|
+
* @param files - 扫描到的 FileNode 列表
|
|
364
|
+
* @returns 排序后的 DatabaseModel 数组
|
|
365
|
+
*/
|
|
366
|
+
export async function analyzeDatabaseModels(rootPath, files) {
|
|
367
|
+
const allModels = [];
|
|
368
|
+
// 筛选候选文件
|
|
369
|
+
const candidates = files.filter((f) => f.nodeType === 'file' && isModelCandidateFile(f.relativePath));
|
|
370
|
+
for (const candidate of candidates) {
|
|
371
|
+
try {
|
|
372
|
+
const absolutePath = path.resolve(rootPath, candidate.relativePath);
|
|
373
|
+
const content = await fs.readFile(absolutePath, 'utf-8');
|
|
374
|
+
const models = extractModelsFromContent(content, candidate.relativePath);
|
|
375
|
+
allModels.push(...models);
|
|
376
|
+
}
|
|
377
|
+
catch {
|
|
378
|
+
// 无法读取的文件直接跳过
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// 按文件路径和模型名排序
|
|
383
|
+
allModels.sort((a, b) => {
|
|
384
|
+
const fileCmp = a.filePath.localeCompare(b.filePath);
|
|
385
|
+
if (fileCmp !== 0)
|
|
386
|
+
return fileCmp;
|
|
387
|
+
return a.name.localeCompare(b.name);
|
|
388
|
+
});
|
|
389
|
+
return allModels;
|
|
390
|
+
}
|
|
391
|
+
//# sourceMappingURL=database-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-analyzer.js","sourceRoot":"","sources":["../../src/analyzer/database-analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* analyzer 模块入口
|
|
3
|
+
* 包含模块聚类、API 路由提取、数据库模型分析、配置与工作流识别等核心静态分析能力。
|
|
4
|
+
*/
|
|
5
|
+
export { analyzeModules, } from './module-analyzer.js';
|
|
6
|
+
export { analyzeApiRoutes, } from './api-analyzer.js';
|
|
7
|
+
export { analyzeDatabaseModels, } from './database-analyzer.js';
|
|
8
|
+
export { analyzeConfigs, type ConfigInfo, } from './config-analyzer.js';
|
|
9
|
+
export { analyzeWorkflows, type WorkflowInfo, } from './workflow-analyzer.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,cAAc,GACjB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACH,gBAAgB,GACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACH,qBAAqB,GACxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACH,cAAc,EACd,KAAK,UAAU,GAClB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACH,gBAAgB,EAChB,KAAK,YAAY,GACpB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* analyzer 模块入口
|
|
3
|
+
* 包含模块聚类、API 路由提取、数据库模型分析、配置与工作流识别等核心静态分析能力。
|
|
4
|
+
*/
|
|
5
|
+
export { analyzeModules, } from './module-analyzer.js';
|
|
6
|
+
export { analyzeApiRoutes, } from './api-analyzer.js';
|
|
7
|
+
export { analyzeDatabaseModels, } from './database-analyzer.js';
|
|
8
|
+
export { analyzeConfigs, } from './config-analyzer.js';
|
|
9
|
+
export { analyzeWorkflows, } from './workflow-analyzer.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,cAAc,GACjB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACH,gBAAgB,GACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACH,qBAAqB,GACxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACH,cAAc,GAEjB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACH,gBAAgB,GAEnB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 模块聚类分析器
|
|
3
|
+
* 将扫描到的文件按目录结构聚类为逻辑模块,并可选通过 LLM 生成模块描述。
|
|
4
|
+
*/
|
|
5
|
+
import type { FileNode, ModuleInfo } from '../models/index.js';
|
|
6
|
+
import type { LLMClient } from '../llm/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* 将文件聚类为逻辑模块并生成描述
|
|
9
|
+
*
|
|
10
|
+
* 将扫描到的全部文件按顶级和次级目录分组,每个分组视为一个逻辑模块。
|
|
11
|
+
* 若提供 LLM 客户端,则通过 LLM 为每个模块生成专业描述;
|
|
12
|
+
* 否则基于文件结构启发式推断。
|
|
13
|
+
*
|
|
14
|
+
* @param rootPath - 项目根目录的绝对路径
|
|
15
|
+
* @param files - 扫描到的 FileNode 列表
|
|
16
|
+
* @param llmClient - 可选的 LLM 客户端实例
|
|
17
|
+
* @returns 分析得到的 ModuleInfo 数组
|
|
18
|
+
*/
|
|
19
|
+
export declare function analyzeModules(rootPath: string, files: FileNode[], llmClient?: LLMClient | null): Promise<ModuleInfo[]>;
|
|
20
|
+
//# sourceMappingURL=module-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/module-analyzer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAiB,MAAM,oBAAoB,CAAC;AAC9E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAwMjD;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,QAAQ,EAAE,EACjB,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,GAC7B,OAAO,CAAC,UAAU,EAAE,CAAC,CAoFvB"}
|