gitnexus 1.6.0 → 1.6.1
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/cli/analyze.js +28 -3
- package/dist/core/group/extractors/fs-utils.d.ts +10 -0
- package/dist/core/group/extractors/fs-utils.js +24 -0
- package/dist/core/group/extractors/grpc-extractor.d.ts +17 -8
- package/dist/core/group/extractors/grpc-extractor.js +313 -191
- package/dist/core/group/extractors/grpc-patterns/go.d.ts +2 -0
- package/dist/core/group/extractors/grpc-patterns/go.js +97 -0
- package/dist/core/group/extractors/grpc-patterns/index.d.ts +19 -0
- package/dist/core/group/extractors/grpc-patterns/index.js +46 -0
- package/dist/core/group/extractors/grpc-patterns/java.d.ts +2 -0
- package/dist/core/group/extractors/grpc-patterns/java.js +173 -0
- package/dist/core/group/extractors/grpc-patterns/node.d.ts +4 -0
- package/dist/core/group/extractors/grpc-patterns/node.js +290 -0
- package/dist/core/group/extractors/grpc-patterns/proto.d.ts +9 -0
- package/dist/core/group/extractors/grpc-patterns/proto.js +134 -0
- package/dist/core/group/extractors/grpc-patterns/python.d.ts +2 -0
- package/dist/core/group/extractors/grpc-patterns/python.js +67 -0
- package/dist/core/group/extractors/grpc-patterns/types.d.ts +50 -0
- package/dist/core/group/extractors/grpc-patterns/types.js +1 -0
- package/dist/core/group/extractors/http-patterns/go.d.ts +2 -0
- package/dist/core/group/extractors/http-patterns/go.js +215 -0
- package/dist/core/group/extractors/http-patterns/index.d.ts +17 -0
- package/dist/core/group/extractors/http-patterns/index.js +44 -0
- package/dist/core/group/extractors/http-patterns/java.d.ts +2 -0
- package/dist/core/group/extractors/http-patterns/java.js +253 -0
- package/dist/core/group/extractors/http-patterns/node.d.ts +4 -0
- package/dist/core/group/extractors/http-patterns/node.js +354 -0
- package/dist/core/group/extractors/http-patterns/php.d.ts +2 -0
- package/dist/core/group/extractors/http-patterns/php.js +70 -0
- package/dist/core/group/extractors/http-patterns/python.d.ts +2 -0
- package/dist/core/group/extractors/http-patterns/python.js +133 -0
- package/dist/core/group/extractors/http-patterns/types.d.ts +61 -0
- package/dist/core/group/extractors/http-patterns/types.js +1 -0
- package/dist/core/group/extractors/http-route-extractor.d.ts +10 -13
- package/dist/core/group/extractors/http-route-extractor.js +201 -238
- package/dist/core/group/extractors/manifest-extractor.d.ts +54 -0
- package/dist/core/group/extractors/manifest-extractor.js +235 -0
- package/dist/core/group/extractors/topic-extractor.d.ts +0 -1
- package/dist/core/group/extractors/topic-extractor.js +55 -192
- package/dist/core/group/extractors/topic-patterns/go.d.ts +2 -0
- package/dist/core/group/extractors/topic-patterns/go.js +120 -0
- package/dist/core/group/extractors/topic-patterns/index.d.ts +14 -0
- package/dist/core/group/extractors/topic-patterns/index.js +38 -0
- package/dist/core/group/extractors/topic-patterns/java.d.ts +2 -0
- package/dist/core/group/extractors/topic-patterns/java.js +80 -0
- package/dist/core/group/extractors/topic-patterns/node.d.ts +4 -0
- package/dist/core/group/extractors/topic-patterns/node.js +155 -0
- package/dist/core/group/extractors/topic-patterns/python.d.ts +2 -0
- package/dist/core/group/extractors/topic-patterns/python.js +116 -0
- package/dist/core/group/extractors/topic-patterns/types.d.ts +25 -0
- package/dist/core/group/extractors/topic-patterns/types.js +10 -0
- package/dist/core/group/extractors/tree-sitter-scanner.d.ts +113 -0
- package/dist/core/group/extractors/tree-sitter-scanner.js +94 -0
- package/dist/core/ingestion/binding-accumulator.d.ts +22 -17
- package/dist/core/ingestion/binding-accumulator.js +29 -25
- package/dist/core/ingestion/cobol-processor.d.ts +1 -1
- package/dist/core/ingestion/import-processor.js +1 -1
- package/dist/core/ingestion/language-config.js +1 -1
- package/dist/core/ingestion/language-provider.d.ts +8 -0
- package/dist/core/ingestion/languages/ruby.js +15 -0
- package/dist/core/ingestion/markdown-processor.d.ts +1 -1
- package/dist/core/ingestion/method-extractors/configs/jvm.js +1 -0
- package/dist/core/ingestion/method-extractors/configs/ruby.js +1 -0
- package/dist/core/ingestion/method-extractors/generic.d.ts +6 -0
- package/dist/core/ingestion/method-extractors/generic.js +48 -4
- package/dist/core/ingestion/method-types.d.ts +4 -0
- package/dist/core/ingestion/model/resolve.js +103 -48
- package/dist/core/ingestion/model/semantic-model.d.ts +1 -1
- package/dist/core/ingestion/model/semantic-model.js +1 -1
- package/dist/core/ingestion/model/symbol-table.d.ts +7 -7
- package/dist/core/ingestion/model/symbol-table.js +7 -7
- package/dist/core/ingestion/mro-processor.d.ts +1 -1
- package/dist/core/ingestion/mro-processor.js +1 -1
- package/dist/core/ingestion/parsing-processor.js +54 -42
- package/dist/core/ingestion/pipeline-phases/cobol.d.ts +16 -0
- package/dist/core/ingestion/pipeline-phases/cobol.js +45 -0
- package/dist/core/ingestion/pipeline-phases/communities.d.ts +16 -0
- package/dist/core/ingestion/pipeline-phases/communities.js +62 -0
- package/dist/core/ingestion/pipeline-phases/cross-file-impl.d.ts +17 -0
- package/dist/core/ingestion/pipeline-phases/cross-file-impl.js +156 -0
- package/dist/core/ingestion/pipeline-phases/cross-file.d.ts +37 -0
- package/dist/core/ingestion/pipeline-phases/cross-file.js +63 -0
- package/dist/core/ingestion/pipeline-phases/index.d.ts +21 -0
- package/dist/core/ingestion/pipeline-phases/index.js +22 -0
- package/dist/core/ingestion/pipeline-phases/markdown.d.ts +17 -0
- package/dist/core/ingestion/pipeline-phases/markdown.js +33 -0
- package/dist/core/ingestion/pipeline-phases/mro.d.ts +18 -0
- package/dist/core/ingestion/pipeline-phases/mro.js +36 -0
- package/dist/core/ingestion/pipeline-phases/orm-extraction.d.ts +22 -0
- package/dist/core/ingestion/pipeline-phases/orm-extraction.js +92 -0
- package/dist/core/ingestion/pipeline-phases/orm.d.ts +15 -0
- package/dist/core/ingestion/pipeline-phases/orm.js +74 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +47 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +437 -0
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +49 -0
- package/dist/core/ingestion/pipeline-phases/parse.js +33 -0
- package/dist/core/ingestion/pipeline-phases/processes.d.ts +16 -0
- package/dist/core/ingestion/pipeline-phases/processes.js +143 -0
- package/dist/core/ingestion/pipeline-phases/routes.d.ts +21 -0
- package/dist/core/ingestion/pipeline-phases/routes.js +243 -0
- package/dist/core/ingestion/pipeline-phases/runner.d.ts +22 -0
- package/dist/core/ingestion/pipeline-phases/runner.js +203 -0
- package/dist/core/ingestion/pipeline-phases/scan.d.ts +21 -0
- package/dist/core/ingestion/pipeline-phases/scan.js +46 -0
- package/dist/core/ingestion/pipeline-phases/structure.d.ts +27 -0
- package/dist/core/ingestion/pipeline-phases/structure.js +35 -0
- package/dist/core/ingestion/pipeline-phases/tools.d.ts +20 -0
- package/dist/core/ingestion/pipeline-phases/tools.js +79 -0
- package/dist/core/ingestion/pipeline-phases/types.d.ts +79 -0
- package/dist/core/ingestion/pipeline-phases/types.js +37 -0
- package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.d.ts +35 -0
- package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.js +174 -0
- package/dist/core/ingestion/pipeline.d.ts +16 -10
- package/dist/core/ingestion/pipeline.js +66 -1534
- package/dist/core/ingestion/process-processor.js +1 -1
- package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
- package/dist/core/ingestion/tree-sitter-queries.js +69 -0
- package/dist/core/ingestion/utils/ast-helpers.d.ts +1 -3
- package/dist/core/ingestion/utils/ast-helpers.js +48 -21
- package/dist/core/ingestion/utils/env.d.ts +10 -0
- package/dist/core/ingestion/utils/env.js +10 -0
- package/dist/core/ingestion/utils/graph-sort.d.ts +58 -0
- package/dist/core/ingestion/utils/graph-sort.js +100 -0
- package/dist/core/ingestion/workers/parse-worker.js +12 -8
- package/dist/core/lbug/lbug-adapter.js +66 -24
- package/package.json +3 -3
- package/vendor/tree-sitter-proto/binding.gyp +30 -0
- package/vendor/tree-sitter-proto/bindings/node/binding.cc +20 -0
- package/vendor/tree-sitter-proto/bindings/node/index.d.ts +28 -0
- package/vendor/tree-sitter-proto/bindings/node/index.js +7 -0
- package/vendor/tree-sitter-proto/package.json +18 -0
- package/vendor/tree-sitter-proto/src/node-types.json +1145 -0
- package/vendor/tree-sitter-proto/src/parser.c +10149 -0
- package/vendor/tree-sitter-proto/src/tree_sitter/alloc.h +54 -0
- package/vendor/tree-sitter-proto/src/tree_sitter/array.h +291 -0
- package/vendor/tree-sitter-proto/src/tree_sitter/parser.h +266 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase: markdown
|
|
3
|
+
*
|
|
4
|
+
* Processes Markdown/MDX files to extract headings and cross-links.
|
|
5
|
+
*
|
|
6
|
+
* @deps structure
|
|
7
|
+
* @reads scannedFiles, allPaths (from structure phase)
|
|
8
|
+
* @writes graph (Markdown section nodes + cross-link edges)
|
|
9
|
+
*/
|
|
10
|
+
import { getPhaseOutput } from './types.js';
|
|
11
|
+
import { processMarkdown } from '../markdown-processor.js';
|
|
12
|
+
import { readFileContents } from '../filesystem-walker.js';
|
|
13
|
+
import { isDev } from '../utils/env.js';
|
|
14
|
+
export const markdownPhase = {
|
|
15
|
+
name: 'markdown',
|
|
16
|
+
deps: ['structure'],
|
|
17
|
+
async execute(ctx, deps) {
|
|
18
|
+
const { scannedFiles, allPathSet } = getPhaseOutput(deps, 'structure');
|
|
19
|
+
const mdScanned = scannedFiles.filter((f) => f.path.endsWith('.md') || f.path.endsWith('.mdx'));
|
|
20
|
+
if (mdScanned.length === 0) {
|
|
21
|
+
return { sections: 0, links: 0 };
|
|
22
|
+
}
|
|
23
|
+
const mdContents = await readFileContents(ctx.repoPath, mdScanned.map((f) => f.path));
|
|
24
|
+
const mdFiles = mdScanned
|
|
25
|
+
.filter((f) => mdContents.has(f.path))
|
|
26
|
+
.map((f) => ({ path: f.path, content: mdContents.get(f.path) }));
|
|
27
|
+
const mdResult = processMarkdown(ctx.graph, mdFiles, allPathSet);
|
|
28
|
+
if (isDev) {
|
|
29
|
+
console.log(` Markdown: ${mdResult.sections} sections, ${mdResult.links} cross-links from ${mdFiles.length} files`);
|
|
30
|
+
}
|
|
31
|
+
return { sections: mdResult.sections, links: mdResult.links };
|
|
32
|
+
},
|
|
33
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase: mro
|
|
3
|
+
*
|
|
4
|
+
* Computes Method Resolution Order (MRO) and creates METHOD_OVERRIDES
|
|
5
|
+
* and METHOD_IMPLEMENTS edges.
|
|
6
|
+
*
|
|
7
|
+
* @deps crossFile
|
|
8
|
+
* @reads graph (all nodes and relationships)
|
|
9
|
+
* @writes graph (METHOD_OVERRIDES, METHOD_IMPLEMENTS edges)
|
|
10
|
+
*/
|
|
11
|
+
import type { PipelinePhase } from './types.js';
|
|
12
|
+
export interface MROOutput {
|
|
13
|
+
entries: number;
|
|
14
|
+
ambiguityCount: number;
|
|
15
|
+
overrideEdges: number;
|
|
16
|
+
methodImplementsEdges: number;
|
|
17
|
+
}
|
|
18
|
+
export declare const mroPhase: PipelinePhase<MROOutput>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase: mro
|
|
3
|
+
*
|
|
4
|
+
* Computes Method Resolution Order (MRO) and creates METHOD_OVERRIDES
|
|
5
|
+
* and METHOD_IMPLEMENTS edges.
|
|
6
|
+
*
|
|
7
|
+
* @deps crossFile
|
|
8
|
+
* @reads graph (all nodes and relationships)
|
|
9
|
+
* @writes graph (METHOD_OVERRIDES, METHOD_IMPLEMENTS edges)
|
|
10
|
+
*/
|
|
11
|
+
import { getPhaseOutput } from './types.js';
|
|
12
|
+
import { computeMRO } from '../mro-processor.js';
|
|
13
|
+
import { isDev } from '../utils/env.js';
|
|
14
|
+
export const mroPhase = {
|
|
15
|
+
name: 'mro',
|
|
16
|
+
deps: ['crossFile', 'structure'],
|
|
17
|
+
async execute(ctx, deps) {
|
|
18
|
+
const { totalFiles } = getPhaseOutput(deps, 'structure');
|
|
19
|
+
ctx.onProgress({
|
|
20
|
+
phase: 'enriching',
|
|
21
|
+
percent: 83,
|
|
22
|
+
message: 'Computing method resolution order...',
|
|
23
|
+
stats: { filesProcessed: totalFiles, totalFiles, nodesCreated: ctx.graph.nodeCount },
|
|
24
|
+
});
|
|
25
|
+
const mroResult = computeMRO(ctx.graph);
|
|
26
|
+
if (isDev && mroResult.entries.length > 0) {
|
|
27
|
+
console.log(`🔀 MRO: ${mroResult.entries.length} classes analyzed, ${mroResult.ambiguityCount} ambiguities, ${mroResult.overrideEdges} METHOD_OVERRIDES, ${mroResult.methodImplementsEdges} METHOD_IMPLEMENTS`);
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
entries: mroResult.entries.length,
|
|
31
|
+
ambiguityCount: mroResult.ambiguityCount,
|
|
32
|
+
overrideEdges: mroResult.overrideEdges,
|
|
33
|
+
methodImplementsEdges: mroResult.methodImplementsEdges,
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline ORM query extraction (sequential fallback path).
|
|
3
|
+
*
|
|
4
|
+
* Extracts Prisma and Supabase query calls from source content using
|
|
5
|
+
* regex patterns. Used by the sequential parse path when workers are
|
|
6
|
+
* not available — the worker path extracts ORM queries via tree-sitter
|
|
7
|
+
* queries instead.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import type { ExtractedORMQuery } from '../workers/parse-worker.js';
|
|
12
|
+
/**
|
|
13
|
+
* Extract ORM query calls from file content using regex.
|
|
14
|
+
*
|
|
15
|
+
* Fast-path: skips files that don't contain `prisma.` or `supabase.from`.
|
|
16
|
+
* Results are appended to the `out` array (push pattern avoids allocation).
|
|
17
|
+
*
|
|
18
|
+
* @param filePath Relative path of the source file
|
|
19
|
+
* @param content File content string
|
|
20
|
+
* @param out Output array to append extracted queries to
|
|
21
|
+
*/
|
|
22
|
+
export declare function extractORMQueriesInline(filePath: string, content: string, out: ExtractedORMQuery[]): void;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline ORM query extraction (sequential fallback path).
|
|
3
|
+
*
|
|
4
|
+
* Extracts Prisma and Supabase query calls from source content using
|
|
5
|
+
* regex patterns. Used by the sequential parse path when workers are
|
|
6
|
+
* not available — the worker path extracts ORM queries via tree-sitter
|
|
7
|
+
* queries instead.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
// ── Regex patterns ─────────────────────────────────────────────────────────
|
|
12
|
+
/** Matches Prisma client method calls: `prisma.user.findMany(...)` */
|
|
13
|
+
const PRISMA_QUERY_RE = /\bprisma\.(\w+)\.(findMany|findFirst|findUnique|findUniqueOrThrow|findFirstOrThrow|create|createMany|update|updateMany|delete|deleteMany|upsert|count|aggregate|groupBy)\s*\(/g;
|
|
14
|
+
/** Matches Supabase client method calls: `supabase.from('users').select(...)` */
|
|
15
|
+
const SUPABASE_QUERY_RE = /\bsupabase\.from\s*\(\s*['"](\w+)['"]\s*\)\s*\.(select|insert|update|delete|upsert)\s*\(/g;
|
|
16
|
+
// ── Extraction function ───────────────────────────────────────────────────
|
|
17
|
+
/**
|
|
18
|
+
* Extract ORM query calls from file content using regex.
|
|
19
|
+
*
|
|
20
|
+
* Fast-path: skips files that don't contain `prisma.` or `supabase.from`.
|
|
21
|
+
* Results are appended to the `out` array (push pattern avoids allocation).
|
|
22
|
+
*
|
|
23
|
+
* @param filePath Relative path of the source file
|
|
24
|
+
* @param content File content string
|
|
25
|
+
* @param out Output array to append extracted queries to
|
|
26
|
+
*/
|
|
27
|
+
export function extractORMQueriesInline(filePath, content, out) {
|
|
28
|
+
const hasPrisma = content.includes('prisma.');
|
|
29
|
+
const hasSupabase = content.includes('supabase.from');
|
|
30
|
+
if (!hasPrisma && !hasSupabase)
|
|
31
|
+
return;
|
|
32
|
+
// Pre-compute line number offsets to avoid O(n²) substring+split per match
|
|
33
|
+
const lineOffsets = buildLineOffsets(content);
|
|
34
|
+
if (hasPrisma) {
|
|
35
|
+
PRISMA_QUERY_RE.lastIndex = 0;
|
|
36
|
+
let m;
|
|
37
|
+
while ((m = PRISMA_QUERY_RE.exec(content)) !== null) {
|
|
38
|
+
const model = m[1];
|
|
39
|
+
if (model.startsWith('$'))
|
|
40
|
+
continue;
|
|
41
|
+
out.push({
|
|
42
|
+
filePath,
|
|
43
|
+
orm: 'prisma',
|
|
44
|
+
model,
|
|
45
|
+
method: m[2],
|
|
46
|
+
lineNumber: lineNumberAtOffset(lineOffsets, m.index),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (hasSupabase) {
|
|
51
|
+
SUPABASE_QUERY_RE.lastIndex = 0;
|
|
52
|
+
let m;
|
|
53
|
+
while ((m = SUPABASE_QUERY_RE.exec(content)) !== null) {
|
|
54
|
+
out.push({
|
|
55
|
+
filePath,
|
|
56
|
+
orm: 'supabase',
|
|
57
|
+
model: m[1],
|
|
58
|
+
method: m[2],
|
|
59
|
+
lineNumber: lineNumberAtOffset(lineOffsets, m.index),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// ── Line offset helpers ───────────────────────────────────────────────────
|
|
65
|
+
/** Build an array of byte offsets where each newline occurs (O(n) once). */
|
|
66
|
+
function buildLineOffsets(content) {
|
|
67
|
+
const offsets = [];
|
|
68
|
+
for (let i = 0; i < content.length; i++) {
|
|
69
|
+
if (content[i] === '\n')
|
|
70
|
+
offsets.push(i);
|
|
71
|
+
}
|
|
72
|
+
return offsets;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Binary search for 0-based line number at a given character offset.
|
|
76
|
+
*
|
|
77
|
+
* Returns the number of newlines that occur before `offset` in the content,
|
|
78
|
+
* which is the 0-based line number. When `offset` is beyond the last newline,
|
|
79
|
+
* returns `lineOffsets.length` (i.e., the last line index).
|
|
80
|
+
*/
|
|
81
|
+
function lineNumberAtOffset(lineOffsets, offset) {
|
|
82
|
+
let lo = 0;
|
|
83
|
+
let hi = lineOffsets.length;
|
|
84
|
+
while (lo < hi) {
|
|
85
|
+
const mid = (lo + hi) >>> 1;
|
|
86
|
+
if (lineOffsets[mid] < offset)
|
|
87
|
+
lo = mid + 1;
|
|
88
|
+
else
|
|
89
|
+
hi = mid;
|
|
90
|
+
}
|
|
91
|
+
return lo;
|
|
92
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase: orm
|
|
3
|
+
*
|
|
4
|
+
* Processes ORM queries (Prisma + Supabase) and creates QUERIES edges.
|
|
5
|
+
*
|
|
6
|
+
* @deps parse
|
|
7
|
+
* @reads allORMQueries (from parse)
|
|
8
|
+
* @writes graph (CodeElement nodes, QUERIES edges)
|
|
9
|
+
*/
|
|
10
|
+
import type { PipelinePhase } from './types.js';
|
|
11
|
+
export interface ORMOutput {
|
|
12
|
+
edgesCreated: number;
|
|
13
|
+
modelCount: number;
|
|
14
|
+
}
|
|
15
|
+
export declare const ormPhase: PipelinePhase<ORMOutput>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase: orm
|
|
3
|
+
*
|
|
4
|
+
* Processes ORM queries (Prisma + Supabase) and creates QUERIES edges.
|
|
5
|
+
*
|
|
6
|
+
* @deps parse
|
|
7
|
+
* @reads allORMQueries (from parse)
|
|
8
|
+
* @writes graph (CodeElement nodes, QUERIES edges)
|
|
9
|
+
*/
|
|
10
|
+
import { getPhaseOutput } from './types.js';
|
|
11
|
+
import { generateId } from '../../../lib/utils.js';
|
|
12
|
+
import { isDev } from '../utils/env.js';
|
|
13
|
+
export const ormPhase = {
|
|
14
|
+
name: 'orm',
|
|
15
|
+
deps: ['parse'],
|
|
16
|
+
async execute(ctx, deps) {
|
|
17
|
+
const { allORMQueries } = getPhaseOutput(deps, 'parse');
|
|
18
|
+
if (allORMQueries.length === 0) {
|
|
19
|
+
return { edgesCreated: 0, modelCount: 0 };
|
|
20
|
+
}
|
|
21
|
+
return processORMQueries(ctx.graph, allORMQueries);
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
function processORMQueries(graph, queries) {
|
|
25
|
+
const modelNodes = new Map();
|
|
26
|
+
const seenEdges = new Set();
|
|
27
|
+
let edgesCreated = 0;
|
|
28
|
+
for (const q of queries) {
|
|
29
|
+
const modelKey = `${q.orm}:${q.model}`;
|
|
30
|
+
let modelNodeId = modelNodes.get(modelKey);
|
|
31
|
+
if (!modelNodeId) {
|
|
32
|
+
const candidateIds = [
|
|
33
|
+
generateId('Class', `${q.model}`),
|
|
34
|
+
generateId('Interface', `${q.model}`),
|
|
35
|
+
generateId('CodeElement', `${q.model}`),
|
|
36
|
+
];
|
|
37
|
+
const existing = candidateIds.find((id) => graph.getNode(id));
|
|
38
|
+
if (existing) {
|
|
39
|
+
modelNodeId = existing;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
modelNodeId = generateId('CodeElement', `${q.orm}:${q.model}`);
|
|
43
|
+
graph.addNode({
|
|
44
|
+
id: modelNodeId,
|
|
45
|
+
label: 'CodeElement',
|
|
46
|
+
properties: {
|
|
47
|
+
name: q.model,
|
|
48
|
+
filePath: '',
|
|
49
|
+
description: `${q.orm} model/table: ${q.model}`,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
modelNodes.set(modelKey, modelNodeId);
|
|
54
|
+
}
|
|
55
|
+
const fileId = generateId('File', q.filePath);
|
|
56
|
+
const edgeKey = `${fileId}->${modelNodeId}:${q.method}`;
|
|
57
|
+
if (seenEdges.has(edgeKey))
|
|
58
|
+
continue;
|
|
59
|
+
seenEdges.add(edgeKey);
|
|
60
|
+
graph.addRelationship({
|
|
61
|
+
id: generateId('QUERIES', edgeKey),
|
|
62
|
+
sourceId: fileId,
|
|
63
|
+
targetId: modelNodeId,
|
|
64
|
+
type: 'QUERIES',
|
|
65
|
+
confidence: 0.9,
|
|
66
|
+
reason: `${q.orm}-${q.method}`,
|
|
67
|
+
});
|
|
68
|
+
edgesCreated++;
|
|
69
|
+
}
|
|
70
|
+
if (isDev) {
|
|
71
|
+
console.log(`ORM dataflow: ${edgesCreated} QUERIES edges, ${modelNodes.size} models (${queries.length} total calls)`);
|
|
72
|
+
}
|
|
73
|
+
return { edgesCreated, modelCount: modelNodes.size };
|
|
74
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse implementation — chunked parse + resolve loop.
|
|
3
|
+
*
|
|
4
|
+
* This is the core parsing engine of the ingestion pipeline. It reads
|
|
5
|
+
* source files in byte-budget chunks (~20MB each), parses via worker
|
|
6
|
+
* pool (or sequential fallback), resolves imports/calls/heritage per
|
|
7
|
+
* chunk, and synthesizes wildcard import bindings.
|
|
8
|
+
*
|
|
9
|
+
* Consumed by the parse phase (`parse.ts`) — the phase file handles
|
|
10
|
+
* dependency wiring while the heavy implementation lives here.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
import { BindingAccumulator } from '../binding-accumulator.js';
|
|
15
|
+
import { type ExportedTypeMap } from '../call-processor.js';
|
|
16
|
+
import { createResolutionContext } from '../model/resolution-context.js';
|
|
17
|
+
import { type PipelineProgress } from '../../../_shared/index.js';
|
|
18
|
+
import type { ExtractedDecoratorRoute, ExtractedFetchCall, ExtractedORMQuery, ExtractedRoute, ExtractedToolDef } from '../workers/parse-worker.js';
|
|
19
|
+
import type { KnowledgeGraph } from '../../graph/types.js';
|
|
20
|
+
import type { PipelineOptions } from '../pipeline.js';
|
|
21
|
+
type ScannedFile = {
|
|
22
|
+
path: string;
|
|
23
|
+
size: number;
|
|
24
|
+
};
|
|
25
|
+
type ProgressFn = (progress: PipelineProgress) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Chunked parse + resolve loop.
|
|
28
|
+
*
|
|
29
|
+
* Reads source in byte-budget chunks (~20MB each). For each chunk:
|
|
30
|
+
* 1. Parse via worker pool (or sequential fallback)
|
|
31
|
+
* 2. Resolve imports from extracted data
|
|
32
|
+
* 3. Synthesize wildcard import bindings (Go/Ruby/C++/Swift/Python)
|
|
33
|
+
* 4. Resolve heritage + routes per chunk; defer worker CALLS until all chunks
|
|
34
|
+
* have contributed heritage so interface-dispatch implementor map is complete
|
|
35
|
+
* 5. Collect TypeEnv bindings for cross-file propagation
|
|
36
|
+
*/
|
|
37
|
+
export declare function runChunkedParseAndResolve(graph: KnowledgeGraph, scannedFiles: ScannedFile[], allPaths: string[], totalFiles: number, repoPath: string, pipelineStart: number, onProgress: ProgressFn, options?: PipelineOptions): Promise<{
|
|
38
|
+
exportedTypeMap: ExportedTypeMap;
|
|
39
|
+
allFetchCalls: ExtractedFetchCall[];
|
|
40
|
+
allExtractedRoutes: ExtractedRoute[];
|
|
41
|
+
allDecoratorRoutes: ExtractedDecoratorRoute[];
|
|
42
|
+
allToolDefs: ExtractedToolDef[];
|
|
43
|
+
allORMQueries: ExtractedORMQuery[];
|
|
44
|
+
bindingAccumulator: BindingAccumulator;
|
|
45
|
+
resolutionContext: ReturnType<typeof createResolutionContext>;
|
|
46
|
+
}>;
|
|
47
|
+
export {};
|