fix(arch-scan): 修复 ts-scanner 误识别 Python 服务 + 扩展符号提取

- 新增 pyproject.toml 检测,跳过纯 Python 服务(ai/data-ana)和包(shared-py)

- 扩展符号提取:新增 TS_CONST_EXPORT_RE 匹配 camelCase/PascalCase 导出常量

- 新增 TS_TYPE_RE 匹配 export type alias

- 修复后 arch:scan 输出 22 模块 / 4715 符号 / 475 契约
This commit is contained in:
SpecialX
2026-07-14 21:24:22 +08:00
parent 0b858d9069
commit 594a4e65fe

View File

@@ -70,6 +70,11 @@ export function scanTypeScript(db: DBType, root: string): ScanStats {
const hasSrc = fs.existsSync(path.join(servicePath, "src"));
const hasPkg = fs.existsSync(path.join(servicePath, "package.json"));
if (!hasSrc && !hasPkg) continue;
// 跳过纯 Python 服务(有 pyproject.toml 且无 package.json
const hasPyproject = fs.existsSync(
path.join(servicePath, "pyproject.toml"),
);
if (hasPyproject && !hasPkg) continue;
const moduleName = serviceName;
insertModule.run(moduleName, servicePath, "ts", serviceName, "service");
@@ -97,6 +102,11 @@ export function scanTypeScript(db: DBType, root: string): ScanStats {
const hasPkg = fs.existsSync(path.join(pkgPath, "package.json"));
const hasProto = fs.existsSync(path.join(pkgPath, "proto"));
if (!hasSrc && !hasPkg && !hasProto) continue;
// 跳过纯 Python 包(有 pyproject.toml 且无 package.json
const hasPyprojectPkg = fs.existsSync(
path.join(pkgPath, "pyproject.toml"),
);
if (hasPyprojectPkg && !hasPkg) continue;
const moduleName = pkgName;
insertModule.run(moduleName, pkgPath, "ts", pkgName, "package");
const row = getModuleId.get(moduleName);
@@ -111,7 +121,12 @@ export function scanTypeScript(db: DBType, root: string): ScanStats {
const TS_FUNC_RE = /(?:export\s+)?(?:async\s+)?function\s+(\w+)\s*\(/g;
const TS_CLASS_RE = /(?:export\s+)?(?:abstract\s+)?class\s+(\w+)/g;
const TS_INTERFACE_RE = /(?:export\s+)?interface\s+(\w+)/g;
const TS_CONST_RE = /(?:export\s+)?const\s+([A-Z][A-Z0-9_]+)\s*=/g;
// 全大写常量(如 MAX_RETRY_COUNT
const TS_CONST_UPPER_RE = /(?:export\s+)?const\s+([A-Z][A-Z0-9_]+)\s*=/g;
// 导出的 camelCase / PascalCase 常量(如 colors、fontSizes
const TS_CONST_EXPORT_RE = /export\s+const\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=/g;
// 导出的 type alias如 ColorScheme
const TS_TYPE_RE = /export\s+type\s+(\w+)\s*=/g;
for (const mod of moduleList) {
const srcDir = path.join(mod.path, "src");
@@ -187,7 +202,7 @@ export function scanTypeScript(db: DBType, root: string): ScanStats {
}
// 常量UPPER_CASE
const constRe = new RegExp(TS_CONST_RE);
const constRe = new RegExp(TS_CONST_UPPER_RE);
while ((match = constRe.exec(content)) !== null) {
const name = match[1];
const lineNum = content.slice(0, match.index).split("\n").length;
@@ -204,6 +219,44 @@ export function scanTypeScript(db: DBType, root: string): ScanStats {
);
symbols++;
}
// 导出的 camelCase / PascalCase 常量(去重:已被 UPPER_CASE 匹配的跳过)
const constExportRe = new RegExp(TS_CONST_EXPORT_RE);
while ((match = constExportRe.exec(content)) !== null) {
const name = match[1];
// 跳过已被 UPPER_CASE 匹配的
if (/^[A-Z][A-Z0-9_]+$/.test(name)) continue;
const lineNum = content.slice(0, match.index).split("\n").length;
insertSymbol.run(
modRow.id,
name,
"const",
"ts",
filePath,
lineNum,
lineNum,
1,
);
symbols++;
}
// 导出的 type alias
const typeRe = new RegExp(TS_TYPE_RE);
while ((match = typeRe.exec(content)) !== null) {
const name = match[1];
const lineNum = content.slice(0, match.index).split("\n").length;
insertSymbol.run(
modRow.id,
name,
"type",
"ts",
filePath,
lineNum,
lineNum,
1,
);
symbols++;
}
}
}