gitnexus 1.5.2 → 1.6.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/README.md +10 -0
- package/dist/_shared/graph/types.d.ts +1 -1
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/index.d.ts +1 -0
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/language-detection.d.ts.map +1 -1
- package/dist/_shared/language-detection.js +2 -0
- package/dist/_shared/language-detection.js.map +1 -1
- package/dist/_shared/languages.d.ts +1 -0
- package/dist/_shared/languages.d.ts.map +1 -1
- package/dist/_shared/languages.js +1 -0
- package/dist/_shared/languages.js.map +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +3 -1
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/mro-strategy.d.ts +19 -0
- package/dist/_shared/mro-strategy.d.ts.map +1 -0
- package/dist/_shared/mro-strategy.js +2 -0
- package/dist/_shared/mro-strategy.js.map +1 -0
- package/dist/cli/ai-context.d.ts +1 -0
- package/dist/cli/ai-context.js +28 -4
- package/dist/cli/analyze.d.ts +2 -0
- package/dist/cli/analyze.js +2 -1
- package/dist/cli/group.d.ts +2 -0
- package/dist/cli/group.js +233 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/serve.js +4 -1
- package/dist/cli/setup.js +34 -3
- package/dist/cli/wiki.js +15 -44
- package/dist/config/ignore-service.js +8 -3
- package/dist/core/augmentation/engine.js +1 -1
- package/dist/core/git-staleness.d.ts +13 -0
- package/dist/core/git-staleness.js +29 -0
- package/dist/core/group/bridge-db.d.ts +82 -0
- package/dist/core/group/bridge-db.js +460 -0
- package/dist/core/group/bridge-schema.d.ts +27 -0
- package/dist/core/group/bridge-schema.js +55 -0
- package/dist/core/group/config-parser.d.ts +3 -0
- package/dist/core/group/config-parser.js +83 -0
- package/dist/core/group/contract-extractor.d.ts +7 -0
- package/dist/core/group/contract-extractor.js +1 -0
- package/dist/core/group/extractors/grpc-extractor.d.ts +16 -0
- package/dist/core/group/extractors/grpc-extractor.js +264 -0
- package/dist/core/group/extractors/http-route-extractor.d.ts +24 -0
- package/dist/core/group/extractors/http-route-extractor.js +428 -0
- package/dist/core/group/extractors/topic-extractor.d.ts +9 -0
- package/dist/core/group/extractors/topic-extractor.js +234 -0
- package/dist/core/group/matching.d.ts +13 -0
- package/dist/core/group/matching.js +198 -0
- package/dist/core/group/normalization.d.ts +3 -0
- package/dist/core/group/normalization.js +115 -0
- package/dist/core/group/service-boundary-detector.d.ts +8 -0
- package/dist/core/group/service-boundary-detector.js +155 -0
- package/dist/core/group/service.d.ts +46 -0
- package/dist/core/group/service.js +160 -0
- package/dist/core/group/storage.d.ts +9 -0
- package/dist/core/group/storage.js +91 -0
- package/dist/core/group/sync.d.ts +21 -0
- package/dist/core/group/sync.js +148 -0
- package/dist/core/group/types.d.ts +130 -0
- package/dist/core/group/types.js +1 -0
- package/dist/core/ingestion/binding-accumulator.d.ts +207 -0
- package/dist/core/ingestion/binding-accumulator.js +332 -0
- package/dist/core/ingestion/call-processor.d.ts +155 -24
- package/dist/core/ingestion/call-processor.js +1129 -247
- package/dist/core/ingestion/class-extractors/generic.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/generic.js +135 -0
- package/dist/core/ingestion/class-types.d.ts +34 -0
- package/dist/core/ingestion/class-types.js +1 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +1 -0
- package/dist/core/ingestion/entry-point-scoring.js +1 -0
- package/dist/core/ingestion/field-extractors/configs/helpers.d.ts +5 -1
- package/dist/core/ingestion/field-extractors/configs/helpers.js +13 -3
- package/dist/core/ingestion/field-types.d.ts +2 -2
- package/dist/core/ingestion/filesystem-walker.js +8 -0
- package/dist/core/ingestion/framework-detection.d.ts +1 -0
- package/dist/core/ingestion/framework-detection.js +1 -0
- package/dist/core/ingestion/heritage-processor.d.ts +8 -15
- package/dist/core/ingestion/heritage-processor.js +15 -28
- package/dist/core/ingestion/import-processor.d.ts +1 -11
- package/dist/core/ingestion/import-processor.js +0 -12
- package/dist/core/ingestion/import-resolvers/utils.js +1 -0
- package/dist/core/ingestion/import-resolvers/vue.d.ts +8 -0
- package/dist/core/ingestion/import-resolvers/vue.js +9 -0
- package/dist/core/ingestion/language-provider.d.ts +6 -3
- package/dist/core/ingestion/languages/c-cpp.js +168 -1
- package/dist/core/ingestion/languages/csharp.js +20 -0
- package/dist/core/ingestion/languages/dart.js +26 -4
- package/dist/core/ingestion/languages/go.js +22 -0
- package/dist/core/ingestion/languages/index.d.ts +1 -0
- package/dist/core/ingestion/languages/index.js +2 -0
- package/dist/core/ingestion/languages/java.js +17 -0
- package/dist/core/ingestion/languages/kotlin.js +24 -1
- package/dist/core/ingestion/languages/php.js +23 -11
- package/dist/core/ingestion/languages/python.js +9 -0
- package/dist/core/ingestion/languages/ruby.js +28 -0
- package/dist/core/ingestion/languages/rust.js +38 -0
- package/dist/core/ingestion/languages/swift.js +31 -0
- package/dist/core/ingestion/languages/typescript.d.ts +1 -0
- package/dist/core/ingestion/languages/typescript.js +54 -1
- package/dist/core/ingestion/languages/vue.d.ts +13 -0
- package/dist/core/ingestion/languages/vue.js +81 -0
- package/dist/core/ingestion/method-extractors/configs/c-cpp.d.ts +3 -0
- package/dist/core/ingestion/method-extractors/configs/c-cpp.js +387 -0
- package/dist/core/ingestion/method-extractors/configs/csharp.js +5 -1
- package/dist/core/ingestion/method-extractors/configs/dart.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/dart.js +376 -0
- package/dist/core/ingestion/method-extractors/configs/go.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/go.js +176 -0
- package/dist/core/ingestion/method-extractors/configs/jvm.js +13 -4
- package/dist/core/ingestion/method-extractors/configs/php.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/php.js +304 -0
- package/dist/core/ingestion/method-extractors/configs/python.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/python.js +309 -0
- package/dist/core/ingestion/method-extractors/configs/ruby.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/ruby.js +285 -0
- package/dist/core/ingestion/method-extractors/configs/rust.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/rust.js +195 -0
- package/dist/core/ingestion/method-extractors/configs/swift.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/swift.js +277 -0
- package/dist/core/ingestion/method-extractors/configs/typescript-javascript.d.ts +3 -0
- package/dist/core/ingestion/method-extractors/configs/typescript-javascript.js +338 -0
- package/dist/core/ingestion/method-extractors/generic.js +38 -15
- package/dist/core/ingestion/method-types.d.ts +25 -0
- package/dist/core/ingestion/model/field-registry.d.ts +18 -0
- package/dist/core/ingestion/model/field-registry.js +22 -0
- package/dist/core/ingestion/model/heritage-map.d.ts +70 -0
- package/dist/core/ingestion/model/heritage-map.js +159 -0
- package/dist/core/ingestion/model/index.d.ts +20 -0
- package/dist/core/ingestion/model/index.js +41 -0
- package/dist/core/ingestion/model/method-registry.d.ts +62 -0
- package/dist/core/ingestion/model/method-registry.js +130 -0
- package/dist/core/ingestion/model/registration-table.d.ts +139 -0
- package/dist/core/ingestion/model/registration-table.js +224 -0
- package/dist/core/ingestion/model/resolution-context.d.ts +93 -0
- package/dist/core/ingestion/model/resolution-context.js +337 -0
- package/dist/core/ingestion/model/resolve.d.ts +56 -0
- package/dist/core/ingestion/model/resolve.js +242 -0
- package/dist/core/ingestion/model/semantic-model.d.ts +86 -0
- package/dist/core/ingestion/model/semantic-model.js +120 -0
- package/dist/core/ingestion/model/symbol-table.d.ts +222 -0
- package/dist/core/ingestion/model/symbol-table.js +206 -0
- package/dist/core/ingestion/model/type-registry.d.ts +39 -0
- package/dist/core/ingestion/model/type-registry.js +62 -0
- package/dist/core/ingestion/mro-processor.d.ts +4 -3
- package/dist/core/ingestion/mro-processor.js +310 -106
- package/dist/core/ingestion/parsing-processor.d.ts +5 -4
- package/dist/core/ingestion/parsing-processor.js +210 -85
- package/dist/core/ingestion/pipeline.d.ts +2 -0
- package/dist/core/ingestion/pipeline.js +192 -68
- package/dist/core/ingestion/tree-sitter-queries.d.ts +6 -6
- package/dist/core/ingestion/tree-sitter-queries.js +37 -0
- package/dist/core/ingestion/type-env.d.ts +15 -2
- package/dist/core/ingestion/type-env.js +163 -102
- package/dist/core/ingestion/type-extractors/csharp.js +17 -0
- package/dist/core/ingestion/type-extractors/jvm.js +11 -0
- package/dist/core/ingestion/type-extractors/php.js +0 -55
- package/dist/core/ingestion/type-extractors/ruby.js +0 -32
- package/dist/core/ingestion/type-extractors/swift.js +13 -0
- package/dist/core/ingestion/type-extractors/types.d.ts +8 -8
- package/dist/core/ingestion/type-extractors/typescript.js +66 -69
- package/dist/core/ingestion/utils/ast-helpers.d.ts +33 -43
- package/dist/core/ingestion/utils/ast-helpers.js +129 -565
- package/dist/core/ingestion/utils/method-props.d.ts +32 -0
- package/dist/core/ingestion/utils/method-props.js +147 -0
- package/dist/core/ingestion/vue-sfc-extractor.d.ts +44 -0
- package/dist/core/ingestion/vue-sfc-extractor.js +94 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +31 -19
- package/dist/core/ingestion/workers/parse-worker.js +463 -198
- package/dist/core/lbug/lbug-adapter.d.ts +6 -0
- package/dist/core/lbug/lbug-adapter.js +68 -3
- package/dist/core/lbug/pool-adapter.d.ts +76 -0
- package/dist/core/lbug/pool-adapter.js +522 -0
- package/dist/core/run-analyze.d.ts +2 -0
- package/dist/core/run-analyze.js +1 -1
- package/dist/core/search/bm25-index.js +1 -1
- package/dist/core/tree-sitter/parser-loader.js +1 -0
- package/dist/core/wiki/graph-queries.js +1 -1
- package/dist/core/wiki/html-viewer.js +6 -4
- package/dist/core/wiki/llm-client.js +4 -6
- package/dist/mcp/core/embedder.js +6 -5
- package/dist/mcp/core/lbug-adapter.d.ts +3 -63
- package/dist/mcp/core/lbug-adapter.js +3 -484
- package/dist/mcp/local/local-backend.d.ts +31 -2
- package/dist/mcp/local/local-backend.js +255 -46
- package/dist/mcp/resources.js +5 -4
- package/dist/mcp/staleness.d.ts +3 -13
- package/dist/mcp/staleness.js +2 -31
- package/dist/mcp/tools.js +80 -4
- package/dist/server/analyze-job.d.ts +2 -0
- package/dist/server/analyze-job.js +4 -0
- package/dist/server/api.d.ts +20 -1
- package/dist/server/api.js +306 -71
- package/dist/server/git-clone.d.ts +2 -1
- package/dist/server/git-clone.js +98 -5
- package/dist/storage/git.d.ts +13 -0
- package/dist/storage/git.js +25 -0
- package/dist/storage/repo-manager.js +1 -1
- package/package.json +8 -2
- package/scripts/patch-tree-sitter-swift.cjs +78 -0
- package/dist/core/ingestion/named-binding-processor.d.ts +0 -18
- package/dist/core/ingestion/named-binding-processor.js +0 -42
- package/dist/core/ingestion/resolution-context.d.ts +0 -58
- package/dist/core/ingestion/resolution-context.js +0 -135
- package/dist/core/ingestion/symbol-table.d.ts +0 -79
- package/dist/core/ingestion/symbol-table.js +0 -115
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { glob } from 'glob';
|
|
4
|
+
function readSafe(repoPath, rel) {
|
|
5
|
+
const abs = path.resolve(repoPath, rel);
|
|
6
|
+
const base = path.resolve(repoPath);
|
|
7
|
+
const relToBase = path.relative(base, abs);
|
|
8
|
+
if (relToBase.startsWith('..') || path.isAbsolute(relToBase))
|
|
9
|
+
return null;
|
|
10
|
+
try {
|
|
11
|
+
return fs.readFileSync(abs, 'utf-8');
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function contractId(pkg, service, method) {
|
|
18
|
+
const prefix = pkg ? `${pkg}.${service}` : service;
|
|
19
|
+
return `grpc::${prefix}/${method}`;
|
|
20
|
+
}
|
|
21
|
+
function serviceOnlyContractId(serviceName) {
|
|
22
|
+
return `grpc::${serviceName}/*`;
|
|
23
|
+
}
|
|
24
|
+
function extractServiceBlocks(content) {
|
|
25
|
+
const results = [];
|
|
26
|
+
// v1: brace-depth only — braces inside comments or string literals are not filtered (see spec Fix 2)
|
|
27
|
+
const headerRe = /service\s+(\w+)\s*\{/g;
|
|
28
|
+
let headerMatch;
|
|
29
|
+
while ((headerMatch = headerRe.exec(content)) !== null) {
|
|
30
|
+
const serviceName = headerMatch[1];
|
|
31
|
+
const bodyStart = headerMatch.index + headerMatch[0].length;
|
|
32
|
+
let depth = 1;
|
|
33
|
+
let pos = bodyStart;
|
|
34
|
+
while (pos < content.length && depth > 0) {
|
|
35
|
+
const ch = content[pos];
|
|
36
|
+
if (ch === '{')
|
|
37
|
+
depth++;
|
|
38
|
+
else if (ch === '}')
|
|
39
|
+
depth--;
|
|
40
|
+
pos++;
|
|
41
|
+
}
|
|
42
|
+
// If EOF before depth returns to 0, skip incomplete service
|
|
43
|
+
if (depth !== 0)
|
|
44
|
+
continue;
|
|
45
|
+
// body is between opening { (consumed by regex) and closing } (pos is one past it)
|
|
46
|
+
const body = content.slice(bodyStart, pos - 1);
|
|
47
|
+
results.push({ name: serviceName, body });
|
|
48
|
+
}
|
|
49
|
+
return results;
|
|
50
|
+
}
|
|
51
|
+
function makeContract(cid, role, filePath, symbolName, confidence, meta) {
|
|
52
|
+
return {
|
|
53
|
+
contractId: cid,
|
|
54
|
+
type: 'grpc',
|
|
55
|
+
role,
|
|
56
|
+
symbolUid: '',
|
|
57
|
+
symbolRef: { filePath: filePath.replace(/\\/g, '/'), name: symbolName },
|
|
58
|
+
symbolName,
|
|
59
|
+
confidence,
|
|
60
|
+
meta: { ...meta, extractionStrategy: 'source_scan' },
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export class GrpcExtractor {
|
|
64
|
+
type = 'grpc';
|
|
65
|
+
async canExtract(_repo) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
async extract(_dbExecutor, repoPath, _repo) {
|
|
69
|
+
const out = [];
|
|
70
|
+
// Proto files — definitive provider source
|
|
71
|
+
const protoFiles = await glob('**/*.proto', {
|
|
72
|
+
cwd: repoPath,
|
|
73
|
+
ignore: ['**/node_modules/**', '**/.git/**', '**/vendor/**'],
|
|
74
|
+
nodir: true,
|
|
75
|
+
});
|
|
76
|
+
for (const rel of protoFiles) {
|
|
77
|
+
const content = readSafe(repoPath, rel);
|
|
78
|
+
if (content)
|
|
79
|
+
out.push(...this.parseProtoFile(content, rel));
|
|
80
|
+
}
|
|
81
|
+
// Source files — server/client detection
|
|
82
|
+
const sourceFiles = await glob('**/*.{go,java,py,ts,tsx,js,jsx}', {
|
|
83
|
+
cwd: repoPath,
|
|
84
|
+
ignore: ['**/node_modules/**', '**/.git/**', '**/vendor/**', '**/dist/**', '**/build/**'],
|
|
85
|
+
nodir: true,
|
|
86
|
+
});
|
|
87
|
+
for (const rel of sourceFiles) {
|
|
88
|
+
const content = readSafe(repoPath, rel);
|
|
89
|
+
if (!content)
|
|
90
|
+
continue;
|
|
91
|
+
const ext = path.extname(rel).toLowerCase();
|
|
92
|
+
if (ext === '.go') {
|
|
93
|
+
out.push(...this.scanGoProviders(content, rel));
|
|
94
|
+
out.push(...this.scanGoConsumers(content, rel));
|
|
95
|
+
}
|
|
96
|
+
else if (ext === '.java') {
|
|
97
|
+
out.push(...this.scanJavaProviders(content, rel));
|
|
98
|
+
out.push(...this.scanJavaConsumers(content, rel));
|
|
99
|
+
}
|
|
100
|
+
else if (ext === '.py') {
|
|
101
|
+
out.push(...this.scanPythonProviders(content, rel));
|
|
102
|
+
out.push(...this.scanPythonConsumers(content, rel));
|
|
103
|
+
}
|
|
104
|
+
else if (['.ts', '.tsx', '.js', '.jsx'].includes(ext)) {
|
|
105
|
+
out.push(...this.scanTsProviders(content, rel));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return this.dedupe(out);
|
|
109
|
+
}
|
|
110
|
+
parseProtoFile(content, filePath) {
|
|
111
|
+
const out = [];
|
|
112
|
+
const pkgMatch = content.match(/^package\s+([\w.]+)\s*;/m);
|
|
113
|
+
const pkg = pkgMatch ? pkgMatch[1] : '';
|
|
114
|
+
for (const { name: serviceName, body } of extractServiceBlocks(content)) {
|
|
115
|
+
const rpcRe = /rpc\s+(\w+)\s*\(/g;
|
|
116
|
+
let rpcMatch;
|
|
117
|
+
while ((rpcMatch = rpcRe.exec(body)) !== null) {
|
|
118
|
+
const methodName = rpcMatch[1];
|
|
119
|
+
const cid = contractId(pkg, serviceName, methodName);
|
|
120
|
+
out.push(makeContract(cid, 'provider', filePath, `${serviceName}.${methodName}`, 0.85, {
|
|
121
|
+
package: pkg,
|
|
122
|
+
service: serviceName,
|
|
123
|
+
method: methodName,
|
|
124
|
+
source: 'proto',
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
scanGoProviders(content, filePath) {
|
|
131
|
+
const out = [];
|
|
132
|
+
// pb.RegisterXxxServer(
|
|
133
|
+
const registerRe = /\w+\.Register(\w+)Server\s*\(/g;
|
|
134
|
+
let m;
|
|
135
|
+
while ((m = registerRe.exec(content)) !== null) {
|
|
136
|
+
const serviceName = m[1];
|
|
137
|
+
out.push(makeContract(serviceOnlyContractId(serviceName), 'provider', filePath, `Register${serviceName}Server`, 0.8, { service: serviceName, source: 'go_register' }));
|
|
138
|
+
}
|
|
139
|
+
// pb.UnimplementedXxxServer
|
|
140
|
+
const unimplRe = /\w+\.Unimplemented(\w+)Server\b/g;
|
|
141
|
+
while ((m = unimplRe.exec(content)) !== null) {
|
|
142
|
+
const serviceName = m[1];
|
|
143
|
+
out.push(makeContract(serviceOnlyContractId(serviceName), 'provider', filePath, `Unimplemented${serviceName}Server`, 0.8, { service: serviceName, source: 'go_unimplemented' }));
|
|
144
|
+
}
|
|
145
|
+
return out;
|
|
146
|
+
}
|
|
147
|
+
scanGoConsumers(content, filePath) {
|
|
148
|
+
const out = [];
|
|
149
|
+
const re = /\w+\.New(\w+)Client\s*\(/g;
|
|
150
|
+
let m;
|
|
151
|
+
while ((m = re.exec(content)) !== null) {
|
|
152
|
+
const serviceName = m[1];
|
|
153
|
+
out.push(makeContract(serviceOnlyContractId(serviceName), 'consumer', filePath, `New${serviceName}Client`, 0.7, { service: serviceName, source: 'go_client' }));
|
|
154
|
+
}
|
|
155
|
+
return out;
|
|
156
|
+
}
|
|
157
|
+
scanJavaProviders(content, filePath) {
|
|
158
|
+
const out = [];
|
|
159
|
+
// @GrpcService
|
|
160
|
+
if (content.includes('@GrpcService')) {
|
|
161
|
+
const implBaseRe = /extends\s+(\w+)Grpc\.(\w+)ImplBase/;
|
|
162
|
+
const m = content.match(implBaseRe);
|
|
163
|
+
if (m) {
|
|
164
|
+
out.push(makeContract(serviceOnlyContractId(m[1]), 'provider', filePath, m[2], 0.8, {
|
|
165
|
+
service: m[1],
|
|
166
|
+
source: 'java_grpc_service',
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
// Try extracting service name from class name
|
|
171
|
+
const classRe = /class\s+(\w*?)(?:Grpc)?(?:Service)?\s+extends\s+(\w+)(?:Grpc\.(\w+))?ImplBase/;
|
|
172
|
+
const cm = content.match(classRe);
|
|
173
|
+
if (cm) {
|
|
174
|
+
const svcName = cm[2].replace(/Grpc$/, '');
|
|
175
|
+
out.push(makeContract(serviceOnlyContractId(svcName), 'provider', filePath, cm[1], 0.8, {
|
|
176
|
+
service: svcName,
|
|
177
|
+
source: 'java_grpc_service',
|
|
178
|
+
}));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// extends XxxImplBase (without @GrpcService)
|
|
183
|
+
if (!content.includes('@GrpcService')) {
|
|
184
|
+
const implRe = /extends\s+(\w+?)(?:Grpc\.(\w+))?ImplBase/;
|
|
185
|
+
const m = content.match(implRe);
|
|
186
|
+
if (m) {
|
|
187
|
+
const svcName = m[2] || m[1].replace(/Grpc$/, '');
|
|
188
|
+
out.push(makeContract(serviceOnlyContractId(svcName), 'provider', filePath, svcName, 0.8, {
|
|
189
|
+
service: svcName,
|
|
190
|
+
source: 'java_impl_base',
|
|
191
|
+
}));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return out;
|
|
195
|
+
}
|
|
196
|
+
scanJavaConsumers(content, filePath) {
|
|
197
|
+
const out = [];
|
|
198
|
+
// XxxGrpc.newBlockingStub( or XxxGrpc.newStub(
|
|
199
|
+
const re = /(\w+)Grpc\.new(?:Blocking)?Stub\s*\(/g;
|
|
200
|
+
let m;
|
|
201
|
+
while ((m = re.exec(content)) !== null) {
|
|
202
|
+
const serviceName = m[1];
|
|
203
|
+
out.push(makeContract(serviceOnlyContractId(serviceName), 'consumer', filePath, `${serviceName}Stub`, 0.7, { service: serviceName, source: 'java_stub' }));
|
|
204
|
+
}
|
|
205
|
+
return out;
|
|
206
|
+
}
|
|
207
|
+
scanPythonProviders(content, filePath) {
|
|
208
|
+
const out = [];
|
|
209
|
+
// add_XxxServicer_to_server(
|
|
210
|
+
const re = /add_(\w+?)Servicer_to_server\s*\(/g;
|
|
211
|
+
let m;
|
|
212
|
+
while ((m = re.exec(content)) !== null) {
|
|
213
|
+
const serviceName = m[1];
|
|
214
|
+
out.push(makeContract(serviceOnlyContractId(serviceName), 'provider', filePath, `add_${serviceName}Servicer_to_server`, 0.8, { service: serviceName, source: 'python_servicer' }));
|
|
215
|
+
}
|
|
216
|
+
return out;
|
|
217
|
+
}
|
|
218
|
+
scanPythonConsumers(content, filePath) {
|
|
219
|
+
const out = [];
|
|
220
|
+
// XxxStub(
|
|
221
|
+
const re = /(\w+)Stub\s*\(/g;
|
|
222
|
+
let m;
|
|
223
|
+
while ((m = re.exec(content)) !== null) {
|
|
224
|
+
const name = m[1];
|
|
225
|
+
// Filter out common false positives
|
|
226
|
+
if (['Mock', 'Test', 'Fake', 'Stub'].includes(name))
|
|
227
|
+
continue;
|
|
228
|
+
out.push(makeContract(serviceOnlyContractId(name), 'consumer', filePath, `${name}Stub`, 0.7, {
|
|
229
|
+
service: name,
|
|
230
|
+
source: 'python_stub',
|
|
231
|
+
}));
|
|
232
|
+
}
|
|
233
|
+
return out;
|
|
234
|
+
}
|
|
235
|
+
scanTsProviders(content, filePath) {
|
|
236
|
+
const out = [];
|
|
237
|
+
// @GrpcMethod('ServiceName', 'MethodName')
|
|
238
|
+
const re = /@GrpcMethod\s*\(\s*['"](\w+)['"]\s*,\s*['"](\w+)['"]\s*\)/g;
|
|
239
|
+
let m;
|
|
240
|
+
while ((m = re.exec(content)) !== null) {
|
|
241
|
+
const serviceName = m[1];
|
|
242
|
+
const methodName = m[2];
|
|
243
|
+
const cid = contractId('', serviceName, methodName);
|
|
244
|
+
out.push(makeContract(cid, 'provider', filePath, `${serviceName}.${methodName}`, 0.8, {
|
|
245
|
+
service: serviceName,
|
|
246
|
+
method: methodName,
|
|
247
|
+
source: 'ts_grpc_method',
|
|
248
|
+
}));
|
|
249
|
+
}
|
|
250
|
+
return out;
|
|
251
|
+
}
|
|
252
|
+
dedupe(items) {
|
|
253
|
+
const seen = new Set();
|
|
254
|
+
const out = [];
|
|
255
|
+
for (const c of items) {
|
|
256
|
+
const k = `${c.contractId}|${c.role}|${c.symbolRef.filePath}`;
|
|
257
|
+
if (seen.has(k))
|
|
258
|
+
continue;
|
|
259
|
+
seen.add(k);
|
|
260
|
+
out.push(c);
|
|
261
|
+
}
|
|
262
|
+
return out;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ContractExtractor, CypherExecutor } from '../contract-extractor.js';
|
|
2
|
+
import type { ExtractedContract, RepoHandle } from '../types.js';
|
|
3
|
+
export declare function normalizeHttpPath(p: string): string;
|
|
4
|
+
export declare class HttpRouteExtractor implements ContractExtractor {
|
|
5
|
+
type: "http";
|
|
6
|
+
canExtract(_repo: RepoHandle): Promise<boolean>;
|
|
7
|
+
extract(dbExecutor: CypherExecutor | null, repoPath: string, repo: RepoHandle): Promise<ExtractedContract[]>;
|
|
8
|
+
private extractProvidersGraph;
|
|
9
|
+
private inferMethodFromFileScan;
|
|
10
|
+
private extractProvidersSourceScan;
|
|
11
|
+
private dedupeContracts;
|
|
12
|
+
private scanSpringProviders;
|
|
13
|
+
private scanExpressProviders;
|
|
14
|
+
private scanLaravelProviders;
|
|
15
|
+
private scanFastApiProviders;
|
|
16
|
+
private makeProvider;
|
|
17
|
+
private extractConsumersGraph;
|
|
18
|
+
private inferFetchMethod;
|
|
19
|
+
private extractConsumersSourceScan;
|
|
20
|
+
private scanFetchConsumers;
|
|
21
|
+
private templateToPattern;
|
|
22
|
+
private scanAxiosConsumers;
|
|
23
|
+
private makeConsumer;
|
|
24
|
+
}
|