@know-graph/core 0.4.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 +21 -0
- package/README.md +47 -0
- package/dist/connectors/cache.d.ts +25 -0
- package/dist/connectors/cache.d.ts.map +1 -0
- package/dist/connectors/cache.js +73 -0
- package/dist/connectors/cache.js.map +1 -0
- package/dist/connectors/index.d.ts +12 -0
- package/dist/connectors/index.d.ts.map +1 -0
- package/dist/connectors/index.js +7 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors/jira-connector.d.ts +26 -0
- package/dist/connectors/jira-connector.d.ts.map +1 -0
- package/dist/connectors/jira-connector.js +234 -0
- package/dist/connectors/jira-connector.js.map +1 -0
- package/dist/connectors/notion-connector.d.ts +24 -0
- package/dist/connectors/notion-connector.d.ts.map +1 -0
- package/dist/connectors/notion-connector.js +246 -0
- package/dist/connectors/notion-connector.js.map +1 -0
- package/dist/connectors/rate-limiter.d.ts +23 -0
- package/dist/connectors/rate-limiter.d.ts.map +1 -0
- package/dist/connectors/rate-limiter.js +54 -0
- package/dist/connectors/rate-limiter.js.map +1 -0
- package/dist/connectors/registry.d.ts +15 -0
- package/dist/connectors/registry.d.ts.map +1 -0
- package/dist/connectors/registry.js +72 -0
- package/dist/connectors/registry.js.map +1 -0
- package/dist/connectors/types.d.ts +142 -0
- package/dist/connectors/types.d.ts.map +1 -0
- package/dist/connectors/types.js +35 -0
- package/dist/connectors/types.js.map +1 -0
- package/dist/coverage/__tests__/fixtures/mixed-project/annotated.d.ts +9 -0
- package/dist/coverage/__tests__/fixtures/mixed-project/annotated.d.ts.map +1 -0
- package/dist/coverage/__tests__/fixtures/mixed-project/annotated.js +11 -0
- package/dist/coverage/__tests__/fixtures/mixed-project/annotated.js.map +1 -0
- package/dist/coverage/__tests__/fixtures/mixed-project/unannotated.d.ts +2 -0
- package/dist/coverage/__tests__/fixtures/mixed-project/unannotated.d.ts.map +1 -0
- package/dist/coverage/__tests__/fixtures/mixed-project/unannotated.js +4 -0
- package/dist/coverage/__tests__/fixtures/mixed-project/unannotated.js.map +1 -0
- package/dist/coverage/coverage-calculator.d.ts +3 -0
- package/dist/coverage/coverage-calculator.d.ts.map +1 -0
- package/dist/coverage/coverage-calculator.js +204 -0
- package/dist/coverage/coverage-calculator.js.map +1 -0
- package/dist/coverage/index.d.ts +3 -0
- package/dist/coverage/index.d.ts.map +1 -0
- package/dist/coverage/index.js +2 -0
- package/dist/coverage/index.js.map +1 -0
- package/dist/coverage/types.d.ts +38 -0
- package/dist/coverage/types.d.ts.map +1 -0
- package/dist/coverage/types.js +13 -0
- package/dist/coverage/types.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/database.d.ts +32 -0
- package/dist/indexer/database.d.ts.map +1 -0
- package/dist/indexer/database.js +242 -0
- package/dist/indexer/database.js.map +1 -0
- package/dist/indexer/index.d.ts +7 -0
- package/dist/indexer/index.d.ts.map +1 -0
- package/dist/indexer/index.js +4 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/indexer.d.ts +12 -0
- package/dist/indexer/indexer.d.ts.map +1 -0
- package/dist/indexer/indexer.js +145 -0
- package/dist/indexer/indexer.js.map +1 -0
- package/dist/indexer/schema.d.ts +21 -0
- package/dist/indexer/schema.d.ts.map +1 -0
- package/dist/indexer/schema.js +122 -0
- package/dist/indexer/schema.js.map +1 -0
- package/dist/indexer/types.d.ts +85 -0
- package/dist/indexer/types.d.ts.map +1 -0
- package/dist/indexer/types.js +2 -0
- package/dist/indexer/types.js.map +1 -0
- package/dist/parsers/generic-parser.d.ts +3 -0
- package/dist/parsers/generic-parser.d.ts.map +1 -0
- package/dist/parsers/generic-parser.js +150 -0
- package/dist/parsers/generic-parser.js.map +1 -0
- package/dist/parsers/go-parser.d.ts +3 -0
- package/dist/parsers/go-parser.d.ts.map +1 -0
- package/dist/parsers/go-parser.js +437 -0
- package/dist/parsers/go-parser.js.map +1 -0
- package/dist/parsers/index.d.ts +10 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +8 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/java-parser.d.ts +3 -0
- package/dist/parsers/java-parser.d.ts.map +1 -0
- package/dist/parsers/java-parser.js +321 -0
- package/dist/parsers/java-parser.js.map +1 -0
- package/dist/parsers/metadata-extractor.d.ts +25 -0
- package/dist/parsers/metadata-extractor.d.ts.map +1 -0
- package/dist/parsers/metadata-extractor.js +137 -0
- package/dist/parsers/metadata-extractor.js.map +1 -0
- package/dist/parsers/python-parser.d.ts +3 -0
- package/dist/parsers/python-parser.d.ts.map +1 -0
- package/dist/parsers/python-parser.js +226 -0
- package/dist/parsers/python-parser.js.map +1 -0
- package/dist/parsers/registry.d.ts +3 -0
- package/dist/parsers/registry.d.ts.map +1 -0
- package/dist/parsers/registry.js +41 -0
- package/dist/parsers/registry.js.map +1 -0
- package/dist/parsers/types.d.ts +23 -0
- package/dist/parsers/types.d.ts.map +1 -0
- package/dist/parsers/types.js +2 -0
- package/dist/parsers/types.js.map +1 -0
- package/dist/parsers/typescript-parser.d.ts +3 -0
- package/dist/parsers/typescript-parser.d.ts.map +1 -0
- package/dist/parsers/typescript-parser.js +321 -0
- package/dist/parsers/typescript-parser.js.map +1 -0
- package/dist/query/index.d.ts +3 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +2 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/query-engine.d.ts +40 -0
- package/dist/query/query-engine.d.ts.map +1 -0
- package/dist/query/query-engine.js +126 -0
- package/dist/query/query-engine.js.map +1 -0
- package/dist/suggest/index.d.ts +3 -0
- package/dist/suggest/index.d.ts.map +1 -0
- package/dist/suggest/index.js +2 -0
- package/dist/suggest/index.js.map +1 -0
- package/dist/suggest/suggestion-engine.d.ts +7 -0
- package/dist/suggest/suggestion-engine.d.ts.map +1 -0
- package/dist/suggest/suggestion-engine.js +239 -0
- package/dist/suggest/suggestion-engine.js.map +1 -0
- package/dist/suggest/types.d.ts +29 -0
- package/dist/suggest/types.d.ts.map +1 -0
- package/dist/suggest/types.js +13 -0
- package/dist/suggest/types.js.map +1 -0
- package/dist/types/entity.d.ts +336 -0
- package/dist/types/entity.d.ts.map +1 -0
- package/dist/types/entity.js +99 -0
- package/dist/types/entity.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/manifest.d.ts +488 -0
- package/dist/types/manifest.d.ts.map +1 -0
- package/dist/types/manifest.js +66 -0
- package/dist/types/manifest.js.map +1 -0
- package/dist/types/parse-result.d.ts +25 -0
- package/dist/types/parse-result.d.ts.map +1 -0
- package/dist/types/parse-result.js +2 -0
- package/dist/types/parse-result.js.map +1 -0
- package/dist/validation/index.d.ts +5 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +3 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/rules.d.ts +9 -0
- package/dist/validation/rules.d.ts.map +1 -0
- package/dist/validation/rules.js +119 -0
- package/dist/validation/rules.js.map +1 -0
- package/dist/validation/types.d.ts +34 -0
- package/dist/validation/types.d.ts.map +1 -0
- package/dist/validation/types.js +2 -0
- package/dist/validation/types.js.map +1 -0
- package/dist/validation/validator.d.ts +10 -0
- package/dist/validation/validator.d.ts.map +1 -0
- package/dist/validation/validator.js +111 -0
- package/dist/validation/validator.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { extractMetadata } from './metadata-extractor.js';
|
|
2
|
+
const PYTHON_EXTENSIONS = ['.py', '.pyi'];
|
|
3
|
+
/**
|
|
4
|
+
* Regex to match Python triple-quoted docstrings.
|
|
5
|
+
* Captures the quote style and the content between quotes.
|
|
6
|
+
*/
|
|
7
|
+
const DOCSTRING_REGEX = /("""[\s\S]*?"""|'''[\s\S]*?''')/g;
|
|
8
|
+
/**
|
|
9
|
+
* Regex to match class definitions.
|
|
10
|
+
*/
|
|
11
|
+
const CLASS_DEF_REGEX = /^(\s*)class\s+(\w+)(?:\(([^)]*)\))?:/;
|
|
12
|
+
/**
|
|
13
|
+
* Regex to match function/method definitions.
|
|
14
|
+
*/
|
|
15
|
+
const FUNC_DEF_REGEX = /^(\s*)(?:async\s+)?def\s+(\w+)\(([^)]*)\)(?:\s*->\s*([^:]+))?:/;
|
|
16
|
+
/**
|
|
17
|
+
* Regex to match decorator lines.
|
|
18
|
+
*/
|
|
19
|
+
const DECORATOR_REGEX = /^\s*@(\S+)/;
|
|
20
|
+
function getLineNumber(source, charIndex) {
|
|
21
|
+
let line = 1;
|
|
22
|
+
for (let i = 0; i < charIndex && i < source.length; i++) {
|
|
23
|
+
if (source[i] === '\n') {
|
|
24
|
+
line++;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return line;
|
|
28
|
+
}
|
|
29
|
+
function stripDocstringQuotes(raw) {
|
|
30
|
+
const quoteChar = raw[0];
|
|
31
|
+
const tripleQuote = quoteChar.repeat(3);
|
|
32
|
+
if (raw.startsWith(tripleQuote) && raw.endsWith(tripleQuote)) {
|
|
33
|
+
return raw.slice(3, -3);
|
|
34
|
+
}
|
|
35
|
+
return raw;
|
|
36
|
+
}
|
|
37
|
+
function findAllDocstrings(content) {
|
|
38
|
+
const results = [];
|
|
39
|
+
let match;
|
|
40
|
+
const regex = new RegExp(DOCSTRING_REGEX.source, 'g');
|
|
41
|
+
while ((match = regex.exec(content)) !== null) {
|
|
42
|
+
const startLine = getLineNumber(content, match.index);
|
|
43
|
+
const endLine = getLineNumber(content, match.index + match[0].length - 1);
|
|
44
|
+
results.push({
|
|
45
|
+
content: stripDocstringQuotes(match[0]),
|
|
46
|
+
startLine,
|
|
47
|
+
endLine,
|
|
48
|
+
startIndex: match.index,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return results;
|
|
52
|
+
}
|
|
53
|
+
function getLineAt(content, lineNumber) {
|
|
54
|
+
const lines = content.split('\n');
|
|
55
|
+
return lines[lineNumber - 1] ?? '';
|
|
56
|
+
}
|
|
57
|
+
function collectDecorators(content, defLineNumber) {
|
|
58
|
+
const lines = content.split('\n');
|
|
59
|
+
const decorators = [];
|
|
60
|
+
let lineIdx = defLineNumber - 2; // 0-indexed, line before def
|
|
61
|
+
while (lineIdx >= 0) {
|
|
62
|
+
const line = lines[lineIdx];
|
|
63
|
+
if (line === undefined)
|
|
64
|
+
break;
|
|
65
|
+
const decoratorMatch = line.match(DECORATOR_REGEX);
|
|
66
|
+
if (decoratorMatch) {
|
|
67
|
+
decorators.unshift(decoratorMatch[1]);
|
|
68
|
+
lineIdx--;
|
|
69
|
+
}
|
|
70
|
+
else if (line.trim() === '' || line.trim().startsWith('#')) {
|
|
71
|
+
lineIdx--;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return decorators;
|
|
78
|
+
}
|
|
79
|
+
function findDefinitionBefore(content, docstringStartLine) {
|
|
80
|
+
const lineAbove = getLineAt(content, docstringStartLine - 1);
|
|
81
|
+
// Check if it's a function/method definition
|
|
82
|
+
const funcMatch = lineAbove.match(FUNC_DEF_REGEX);
|
|
83
|
+
if (funcMatch) {
|
|
84
|
+
const indent = funcMatch[1];
|
|
85
|
+
const name = funcMatch[2];
|
|
86
|
+
const params = funcMatch[3];
|
|
87
|
+
const returnType = funcMatch[4]?.trim();
|
|
88
|
+
const defLine = docstringStartLine - 1;
|
|
89
|
+
const decorators = collectDecorators(content, defLine);
|
|
90
|
+
const signatureParts = [`def ${name}(${params})`];
|
|
91
|
+
if (returnType) {
|
|
92
|
+
signatureParts.push(` -> ${returnType}`);
|
|
93
|
+
}
|
|
94
|
+
// Determine if method (has indentation and a class context)
|
|
95
|
+
const isMethod = (indent?.length ?? 0) > 0;
|
|
96
|
+
let parent;
|
|
97
|
+
if (isMethod) {
|
|
98
|
+
parent = findEnclosingClass(content, defLine);
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
name,
|
|
102
|
+
kind: isMethod && parent ? 'method' : 'function',
|
|
103
|
+
signature: signatureParts.join(''),
|
|
104
|
+
parent,
|
|
105
|
+
line: defLine,
|
|
106
|
+
decorators,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// Check if it's a class definition
|
|
110
|
+
const classMatch = lineAbove.match(CLASS_DEF_REGEX);
|
|
111
|
+
if (classMatch) {
|
|
112
|
+
const name = classMatch[2];
|
|
113
|
+
const defLine = docstringStartLine - 1;
|
|
114
|
+
const decorators = collectDecorators(content, defLine);
|
|
115
|
+
return {
|
|
116
|
+
name,
|
|
117
|
+
kind: 'class',
|
|
118
|
+
line: defLine,
|
|
119
|
+
decorators,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
function findEnclosingClass(content, lineNumber) {
|
|
125
|
+
const lines = content.split('\n');
|
|
126
|
+
const targetLine = lines[lineNumber - 1];
|
|
127
|
+
if (!targetLine)
|
|
128
|
+
return undefined;
|
|
129
|
+
const targetIndent = targetLine.search(/\S/);
|
|
130
|
+
for (let i = lineNumber - 2; i >= 0; i--) {
|
|
131
|
+
const line = lines[i];
|
|
132
|
+
if (line === undefined)
|
|
133
|
+
continue;
|
|
134
|
+
const currentIndent = line.search(/\S/);
|
|
135
|
+
if (currentIndent === -1)
|
|
136
|
+
continue; // blank line
|
|
137
|
+
if (currentIndent < targetIndent) {
|
|
138
|
+
const classMatch = line.match(CLASS_DEF_REGEX);
|
|
139
|
+
if (classMatch) {
|
|
140
|
+
return classMatch[2];
|
|
141
|
+
}
|
|
142
|
+
// If we hit a non-class at a lower indent, stop
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
function isModuleLevelDocstring(content, docstringStartLine) {
|
|
149
|
+
// A module-level docstring is at the beginning of the file,
|
|
150
|
+
// possibly preceded by comments, blank lines, or shebang
|
|
151
|
+
const lines = content.split('\n');
|
|
152
|
+
for (let i = 0; i < docstringStartLine - 1; i++) {
|
|
153
|
+
const line = lines[i]?.trim() ?? '';
|
|
154
|
+
if (line === '' || line.startsWith('#') || line.startsWith('!')) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
// Found a non-comment, non-blank line before the docstring
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
function getModuleName(filePath) {
|
|
163
|
+
const parts = filePath.split('/');
|
|
164
|
+
const fileName = parts[parts.length - 1] ?? '';
|
|
165
|
+
return fileName.replace(/\.(py|pyi)$/, '');
|
|
166
|
+
}
|
|
167
|
+
export function createPythonParser() {
|
|
168
|
+
return {
|
|
169
|
+
name: 'python',
|
|
170
|
+
supportedExtensions: PYTHON_EXTENSIONS,
|
|
171
|
+
parse(content, filePath) {
|
|
172
|
+
const docstrings = findAllDocstrings(content);
|
|
173
|
+
const results = [];
|
|
174
|
+
for (const docstring of docstrings) {
|
|
175
|
+
const extraction = extractMetadata(docstring.content, docstring.startLine);
|
|
176
|
+
if (!extraction.metadata) {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
const metadata = extraction.metadata;
|
|
180
|
+
// Determine context
|
|
181
|
+
const defContext = findDefinitionBefore(content, docstring.startLine);
|
|
182
|
+
if (defContext) {
|
|
183
|
+
results.push({
|
|
184
|
+
name: defContext.name,
|
|
185
|
+
filePath,
|
|
186
|
+
line: defContext.line,
|
|
187
|
+
column: 1,
|
|
188
|
+
language: 'python',
|
|
189
|
+
entityType: metadata.type,
|
|
190
|
+
metadata,
|
|
191
|
+
rawDocstring: docstring.content,
|
|
192
|
+
signature: defContext.signature,
|
|
193
|
+
parent: defContext.parent,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
else if (isModuleLevelDocstring(content, docstring.startLine)) {
|
|
197
|
+
results.push({
|
|
198
|
+
name: getModuleName(filePath),
|
|
199
|
+
filePath,
|
|
200
|
+
line: docstring.startLine,
|
|
201
|
+
column: 1,
|
|
202
|
+
language: 'python',
|
|
203
|
+
entityType: metadata.type,
|
|
204
|
+
metadata,
|
|
205
|
+
rawDocstring: docstring.content,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
// Standalone docstring not at module level - still include it
|
|
210
|
+
results.push({
|
|
211
|
+
name: 'unknown',
|
|
212
|
+
filePath,
|
|
213
|
+
line: docstring.startLine,
|
|
214
|
+
column: 1,
|
|
215
|
+
language: 'python',
|
|
216
|
+
entityType: metadata.type,
|
|
217
|
+
metadata,
|
|
218
|
+
rawDocstring: docstring.content,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return results;
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=python-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python-parser.js","sourceRoot":"","sources":["../../src/parsers/python-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/parsers/registry.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAU,cAAc,EAAE,MAAM,YAAY,CAAC;AAsCzD,wBAAgB,qBAAqB,IAAI,cAAc,CAOtD"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createPythonParser } from './python-parser.js';
|
|
2
|
+
import { createTypescriptParser } from './typescript-parser.js';
|
|
3
|
+
import { createGenericParser } from './generic-parser.js';
|
|
4
|
+
import { createGoParser } from './go-parser.js';
|
|
5
|
+
import { createJavaParser } from './java-parser.js';
|
|
6
|
+
function getExtension(filePath) {
|
|
7
|
+
const lastDot = filePath.lastIndexOf('.');
|
|
8
|
+
if (lastDot === -1)
|
|
9
|
+
return '';
|
|
10
|
+
return filePath.slice(lastDot);
|
|
11
|
+
}
|
|
12
|
+
function createRegistry() {
|
|
13
|
+
const parsers = [];
|
|
14
|
+
const genericParser = createGenericParser();
|
|
15
|
+
return {
|
|
16
|
+
register(parser) {
|
|
17
|
+
parsers.push(parser);
|
|
18
|
+
},
|
|
19
|
+
getParser(filePath) {
|
|
20
|
+
const ext = getExtension(filePath);
|
|
21
|
+
const specific = parsers.find((p) => p.supportedExtensions.includes(ext));
|
|
22
|
+
return specific ?? genericParser;
|
|
23
|
+
},
|
|
24
|
+
parseFile(content, filePath) {
|
|
25
|
+
const parser = this.getParser(filePath);
|
|
26
|
+
if (!parser) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
return parser.parse(content, filePath);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function createDefaultRegistry() {
|
|
34
|
+
const registry = createRegistry();
|
|
35
|
+
registry.register(createPythonParser());
|
|
36
|
+
registry.register(createTypescriptParser());
|
|
37
|
+
registry.register(createGoParser());
|
|
38
|
+
registry.register(createJavaParser());
|
|
39
|
+
return registry;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/parsers/registry.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,SAAS,YAAY,CAAC,QAAgB;IACpC,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,OAAO,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAC9B,OAAO,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,cAAc;IACrB,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,aAAa,GAAG,mBAAmB,EAAE,CAAC;IAE5C,OAAO;QACL,QAAQ,CAAC,MAAc;YACrB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QAED,SAAS,CAAC,QAAgB;YACxB,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;YACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1E,OAAO,QAAQ,IAAI,aAAa,CAAC;QACnC,CAAC;QAED,SAAS,CAAC,OAAe,EAAE,QAAgB;YACzC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACxC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,sBAAsB,EAAE,CAAC,CAAC;IAC5C,QAAQ,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAC;IACpC,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACtC,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @knowgraph
|
|
3
|
+
* type: interface
|
|
4
|
+
* description: Parser and ParserRegistry interfaces for the language parser system
|
|
5
|
+
* owner: knowgraph-core
|
|
6
|
+
* status: stable
|
|
7
|
+
* tags: [parser, types, interface, registry]
|
|
8
|
+
* context:
|
|
9
|
+
* business_goal: Define contracts for pluggable language parser implementations
|
|
10
|
+
* domain: parser-engine
|
|
11
|
+
*/
|
|
12
|
+
import type { ParseResult } from '../types/parse-result.js';
|
|
13
|
+
export interface Parser {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly supportedExtensions: readonly string[];
|
|
16
|
+
parse(content: string, filePath: string): readonly ParseResult[];
|
|
17
|
+
}
|
|
18
|
+
export interface ParserRegistry {
|
|
19
|
+
register(parser: Parser): void;
|
|
20
|
+
getParser(filePath: string): Parser | undefined;
|
|
21
|
+
parseFile(content: string, filePath: string): readonly ParseResult[];
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/parsers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,WAAW,EAAE,CAAC;CAClE;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAChD,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,WAAW,EAAE,CAAC;CACtE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/parsers/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescript-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/typescript-parser.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAyMzC,wBAAgB,sBAAsB,IAAI,MAAM,CAyL/C"}
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { extractMetadata } from './metadata-extractor.js';
|
|
2
|
+
const TS_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mts', '.cts'];
|
|
3
|
+
/**
|
|
4
|
+
* Regex to match JSDoc comment blocks: /** ... * /
|
|
5
|
+
*/
|
|
6
|
+
const JSDOC_REGEX = /\/\*\*[\s\S]*?\*\//g;
|
|
7
|
+
/**
|
|
8
|
+
* Regex to match class declarations after a JSDoc block.
|
|
9
|
+
*/
|
|
10
|
+
const CLASS_DECL_REGEX = /^(?:export\s+)?(?:abstract\s+)?class\s+(\w+)(?:<[^>]*>)?(?:\s+extends\s+\S+)?(?:\s+implements\s+[^{]+)?\s*\{/;
|
|
11
|
+
/**
|
|
12
|
+
* Regex to match function declarations after a JSDoc block.
|
|
13
|
+
*/
|
|
14
|
+
const FUNC_DECL_REGEX = /^(?:export\s+)?(?:async\s+)?function\s+(\w+)(?:<[^>]*>)?\s*\(([^)]*)\)(?:\s*:\s*([^{;]+))?/;
|
|
15
|
+
/**
|
|
16
|
+
* Regex to match arrow function / const assigned function.
|
|
17
|
+
*/
|
|
18
|
+
const ARROW_FUNC_REGEX = /^(?:export\s+)?(?:const|let|var)\s+(\w+)(?:\s*:\s*[^=]+)?\s*=\s*(?:async\s+)?(?:\([^)]*\)|[^=]+)\s*=>/;
|
|
19
|
+
/**
|
|
20
|
+
* Regex to match interface declarations.
|
|
21
|
+
*/
|
|
22
|
+
const INTERFACE_DECL_REGEX = /^(?:export\s+)?interface\s+(\w+)(?:<[^>]*>)?(?:\s+extends\s+[^{]+)?\s*\{/;
|
|
23
|
+
/**
|
|
24
|
+
* Regex to match type alias declarations.
|
|
25
|
+
*/
|
|
26
|
+
const TYPE_DECL_REGEX = /^(?:export\s+)?type\s+(\w+)(?:<[^>]*>)?\s*=/;
|
|
27
|
+
/**
|
|
28
|
+
* Regex to match method declarations inside a class.
|
|
29
|
+
*/
|
|
30
|
+
const METHOD_DECL_REGEX = /^\s+(?:(?:public|private|protected|static|async|readonly|override|abstract)\s+)*(\w+)(?:<[^>]*>)?\s*\(([^)]*)\)(?:\s*:\s*([^{;]+))?/;
|
|
31
|
+
/**
|
|
32
|
+
* Regex to match enum declarations.
|
|
33
|
+
*/
|
|
34
|
+
const ENUM_DECL_REGEX = /^(?:export\s+)?(?:const\s+)?enum\s+(\w+)\s*\{/;
|
|
35
|
+
function getLineNumber(source, charIndex) {
|
|
36
|
+
let line = 1;
|
|
37
|
+
for (let i = 0; i < charIndex && i < source.length; i++) {
|
|
38
|
+
if (source[i] === '\n') {
|
|
39
|
+
line++;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return line;
|
|
43
|
+
}
|
|
44
|
+
function stripJsdoc(raw) {
|
|
45
|
+
// Remove /** and */
|
|
46
|
+
const inner = raw.slice(3, -2);
|
|
47
|
+
// Remove leading * on each line
|
|
48
|
+
const lines = inner.split('\n').map((line) => line.replace(/^\s*\*\s?/, ''));
|
|
49
|
+
return lines.join('\n').trim();
|
|
50
|
+
}
|
|
51
|
+
function findAllJsdocBlocks(content) {
|
|
52
|
+
const results = [];
|
|
53
|
+
let match;
|
|
54
|
+
const regex = new RegExp(JSDOC_REGEX.source, 'g');
|
|
55
|
+
while ((match = regex.exec(content)) !== null) {
|
|
56
|
+
const startLine = getLineNumber(content, match.index);
|
|
57
|
+
const endIndex = match.index + match[0].length;
|
|
58
|
+
const endLine = getLineNumber(content, endIndex - 1);
|
|
59
|
+
results.push({
|
|
60
|
+
content: stripJsdoc(match[0]),
|
|
61
|
+
startLine,
|
|
62
|
+
endLine,
|
|
63
|
+
endIndex,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return results;
|
|
67
|
+
}
|
|
68
|
+
function getNextNonEmptyLine(content, afterIndex) {
|
|
69
|
+
const rest = content.slice(afterIndex);
|
|
70
|
+
const lines = rest.split('\n');
|
|
71
|
+
for (const line of lines) {
|
|
72
|
+
const trimmed = line.trim();
|
|
73
|
+
if (trimmed !== '') {
|
|
74
|
+
return trimmed;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return '';
|
|
78
|
+
}
|
|
79
|
+
function getNextNonEmptyLineRaw(content, afterIndex) {
|
|
80
|
+
const rest = content.slice(afterIndex);
|
|
81
|
+
const lines = rest.split('\n');
|
|
82
|
+
for (const line of lines) {
|
|
83
|
+
if (line.trim() !== '') {
|
|
84
|
+
return line;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return '';
|
|
88
|
+
}
|
|
89
|
+
function getNextNonEmptyLineNumber(content, afterIndex) {
|
|
90
|
+
const baseLine = getLineNumber(content, afterIndex);
|
|
91
|
+
const rest = content.slice(afterIndex);
|
|
92
|
+
const lines = rest.split('\n');
|
|
93
|
+
for (let i = 0; i < lines.length; i++) {
|
|
94
|
+
if (lines[i]?.trim() !== '') {
|
|
95
|
+
return baseLine + i;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return baseLine;
|
|
99
|
+
}
|
|
100
|
+
function isModuleLevelJsdoc(content, startLine) {
|
|
101
|
+
const lines = content.split('\n');
|
|
102
|
+
for (let i = 0; i < startLine - 1; i++) {
|
|
103
|
+
const line = lines[i]?.trim() ?? '';
|
|
104
|
+
if (line === '' ||
|
|
105
|
+
line.startsWith('//') ||
|
|
106
|
+
line.startsWith('/*') ||
|
|
107
|
+
line.startsWith('*')) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
// Check for imports/requires - those are fine before module-level jsdoc
|
|
111
|
+
if (line.startsWith('import ') ||
|
|
112
|
+
line.startsWith('require(') ||
|
|
113
|
+
line.startsWith("'use strict'") ||
|
|
114
|
+
line.startsWith('"use strict"')) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
function findEnclosingClassName(content, lineNumber) {
|
|
122
|
+
const lines = content.split('\n');
|
|
123
|
+
const targetLine = lines[lineNumber - 1];
|
|
124
|
+
if (!targetLine)
|
|
125
|
+
return undefined;
|
|
126
|
+
const targetIndent = targetLine.search(/\S/);
|
|
127
|
+
if (targetIndent <= 0)
|
|
128
|
+
return undefined;
|
|
129
|
+
for (let i = lineNumber - 2; i >= 0; i--) {
|
|
130
|
+
const line = lines[i];
|
|
131
|
+
if (line === undefined)
|
|
132
|
+
continue;
|
|
133
|
+
const currentIndent = line.search(/\S/);
|
|
134
|
+
if (currentIndent === -1)
|
|
135
|
+
continue;
|
|
136
|
+
if (currentIndent < targetIndent) {
|
|
137
|
+
const trimmed = line.trim();
|
|
138
|
+
const classMatch = trimmed.match(CLASS_DECL_REGEX);
|
|
139
|
+
if (classMatch) {
|
|
140
|
+
return classMatch[1];
|
|
141
|
+
}
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
function getModuleName(filePath) {
|
|
148
|
+
const parts = filePath.split('/');
|
|
149
|
+
const fileName = parts[parts.length - 1] ?? '';
|
|
150
|
+
return fileName.replace(/\.(ts|tsx|js|jsx|mts|cts)$/, '');
|
|
151
|
+
}
|
|
152
|
+
export function createTypescriptParser() {
|
|
153
|
+
return {
|
|
154
|
+
name: 'typescript',
|
|
155
|
+
supportedExtensions: TS_EXTENSIONS,
|
|
156
|
+
parse(content, filePath) {
|
|
157
|
+
const jsdocBlocks = findAllJsdocBlocks(content);
|
|
158
|
+
const results = [];
|
|
159
|
+
for (const jsdoc of jsdocBlocks) {
|
|
160
|
+
const extraction = extractMetadata(jsdoc.content, jsdoc.startLine);
|
|
161
|
+
if (!extraction.metadata) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
const metadata = extraction.metadata;
|
|
165
|
+
const nextLine = getNextNonEmptyLine(content, jsdoc.endIndex);
|
|
166
|
+
const nextLineRaw = getNextNonEmptyLineRaw(content, jsdoc.endIndex);
|
|
167
|
+
const nextLineNumber = getNextNonEmptyLineNumber(content, jsdoc.endIndex);
|
|
168
|
+
// Try to match class declaration
|
|
169
|
+
const classMatch = nextLine.match(CLASS_DECL_REGEX);
|
|
170
|
+
if (classMatch) {
|
|
171
|
+
results.push({
|
|
172
|
+
name: classMatch[1],
|
|
173
|
+
filePath,
|
|
174
|
+
line: nextLineNumber,
|
|
175
|
+
column: 1,
|
|
176
|
+
language: 'typescript',
|
|
177
|
+
entityType: metadata.type,
|
|
178
|
+
metadata,
|
|
179
|
+
rawDocstring: jsdoc.content,
|
|
180
|
+
});
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
// Try to match function declaration
|
|
184
|
+
const funcMatch = nextLine.match(FUNC_DECL_REGEX);
|
|
185
|
+
if (funcMatch) {
|
|
186
|
+
const name = funcMatch[1];
|
|
187
|
+
const params = funcMatch[2];
|
|
188
|
+
const returnType = funcMatch[3]?.trim();
|
|
189
|
+
const sigParts = [`function ${name}(${params})`];
|
|
190
|
+
if (returnType) {
|
|
191
|
+
sigParts.push(`: ${returnType}`);
|
|
192
|
+
}
|
|
193
|
+
results.push({
|
|
194
|
+
name,
|
|
195
|
+
filePath,
|
|
196
|
+
line: nextLineNumber,
|
|
197
|
+
column: 1,
|
|
198
|
+
language: 'typescript',
|
|
199
|
+
entityType: metadata.type,
|
|
200
|
+
metadata,
|
|
201
|
+
rawDocstring: jsdoc.content,
|
|
202
|
+
signature: sigParts.join(''),
|
|
203
|
+
});
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
// Try to match arrow function
|
|
207
|
+
const arrowMatch = nextLine.match(ARROW_FUNC_REGEX);
|
|
208
|
+
if (arrowMatch) {
|
|
209
|
+
results.push({
|
|
210
|
+
name: arrowMatch[1],
|
|
211
|
+
filePath,
|
|
212
|
+
line: nextLineNumber,
|
|
213
|
+
column: 1,
|
|
214
|
+
language: 'typescript',
|
|
215
|
+
entityType: metadata.type,
|
|
216
|
+
metadata,
|
|
217
|
+
rawDocstring: jsdoc.content,
|
|
218
|
+
});
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
// Try to match interface declaration
|
|
222
|
+
const ifaceMatch = nextLine.match(INTERFACE_DECL_REGEX);
|
|
223
|
+
if (ifaceMatch) {
|
|
224
|
+
results.push({
|
|
225
|
+
name: ifaceMatch[1],
|
|
226
|
+
filePath,
|
|
227
|
+
line: nextLineNumber,
|
|
228
|
+
column: 1,
|
|
229
|
+
language: 'typescript',
|
|
230
|
+
entityType: metadata.type,
|
|
231
|
+
metadata,
|
|
232
|
+
rawDocstring: jsdoc.content,
|
|
233
|
+
});
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
// Try to match type alias
|
|
237
|
+
const typeMatch = nextLine.match(TYPE_DECL_REGEX);
|
|
238
|
+
if (typeMatch) {
|
|
239
|
+
results.push({
|
|
240
|
+
name: typeMatch[1],
|
|
241
|
+
filePath,
|
|
242
|
+
line: nextLineNumber,
|
|
243
|
+
column: 1,
|
|
244
|
+
language: 'typescript',
|
|
245
|
+
entityType: metadata.type,
|
|
246
|
+
metadata,
|
|
247
|
+
rawDocstring: jsdoc.content,
|
|
248
|
+
});
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
// Try to match enum declaration
|
|
252
|
+
const enumMatch = nextLine.match(ENUM_DECL_REGEX);
|
|
253
|
+
if (enumMatch) {
|
|
254
|
+
results.push({
|
|
255
|
+
name: enumMatch[1],
|
|
256
|
+
filePath,
|
|
257
|
+
line: nextLineNumber,
|
|
258
|
+
column: 1,
|
|
259
|
+
language: 'typescript',
|
|
260
|
+
entityType: metadata.type,
|
|
261
|
+
metadata,
|
|
262
|
+
rawDocstring: jsdoc.content,
|
|
263
|
+
});
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
// Try to match method declaration (inside a class)
|
|
267
|
+
const methodMatch = nextLineRaw.match(METHOD_DECL_REGEX);
|
|
268
|
+
if (methodMatch) {
|
|
269
|
+
const name = methodMatch[1];
|
|
270
|
+
const params = methodMatch[2];
|
|
271
|
+
const returnType = methodMatch[3]?.trim();
|
|
272
|
+
const parent = findEnclosingClassName(content, nextLineNumber);
|
|
273
|
+
const sigParts = [`${name}(${params})`];
|
|
274
|
+
if (returnType) {
|
|
275
|
+
sigParts.push(`: ${returnType}`);
|
|
276
|
+
}
|
|
277
|
+
results.push({
|
|
278
|
+
name,
|
|
279
|
+
filePath,
|
|
280
|
+
line: nextLineNumber,
|
|
281
|
+
column: 1,
|
|
282
|
+
language: 'typescript',
|
|
283
|
+
entityType: metadata.type,
|
|
284
|
+
metadata,
|
|
285
|
+
rawDocstring: jsdoc.content,
|
|
286
|
+
signature: sigParts.join(''),
|
|
287
|
+
parent,
|
|
288
|
+
});
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
// Module-level JSDoc or unrecognized target
|
|
292
|
+
if (isModuleLevelJsdoc(content, jsdoc.startLine)) {
|
|
293
|
+
results.push({
|
|
294
|
+
name: getModuleName(filePath),
|
|
295
|
+
filePath,
|
|
296
|
+
line: jsdoc.startLine,
|
|
297
|
+
column: 1,
|
|
298
|
+
language: 'typescript',
|
|
299
|
+
entityType: metadata.type,
|
|
300
|
+
metadata,
|
|
301
|
+
rawDocstring: jsdoc.content,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
results.push({
|
|
306
|
+
name: 'unknown',
|
|
307
|
+
filePath,
|
|
308
|
+
line: jsdoc.startLine,
|
|
309
|
+
column: 1,
|
|
310
|
+
language: 'typescript',
|
|
311
|
+
entityType: metadata.type,
|
|
312
|
+
metadata,
|
|
313
|
+
rawDocstring: jsdoc.content,
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return results;
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
//# sourceMappingURL=typescript-parser.js.map
|