@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.
Files changed (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +47 -0
  3. package/dist/connectors/cache.d.ts +25 -0
  4. package/dist/connectors/cache.d.ts.map +1 -0
  5. package/dist/connectors/cache.js +73 -0
  6. package/dist/connectors/cache.js.map +1 -0
  7. package/dist/connectors/index.d.ts +12 -0
  8. package/dist/connectors/index.d.ts.map +1 -0
  9. package/dist/connectors/index.js +7 -0
  10. package/dist/connectors/index.js.map +1 -0
  11. package/dist/connectors/jira-connector.d.ts +26 -0
  12. package/dist/connectors/jira-connector.d.ts.map +1 -0
  13. package/dist/connectors/jira-connector.js +234 -0
  14. package/dist/connectors/jira-connector.js.map +1 -0
  15. package/dist/connectors/notion-connector.d.ts +24 -0
  16. package/dist/connectors/notion-connector.d.ts.map +1 -0
  17. package/dist/connectors/notion-connector.js +246 -0
  18. package/dist/connectors/notion-connector.js.map +1 -0
  19. package/dist/connectors/rate-limiter.d.ts +23 -0
  20. package/dist/connectors/rate-limiter.d.ts.map +1 -0
  21. package/dist/connectors/rate-limiter.js +54 -0
  22. package/dist/connectors/rate-limiter.js.map +1 -0
  23. package/dist/connectors/registry.d.ts +15 -0
  24. package/dist/connectors/registry.d.ts.map +1 -0
  25. package/dist/connectors/registry.js +72 -0
  26. package/dist/connectors/registry.js.map +1 -0
  27. package/dist/connectors/types.d.ts +142 -0
  28. package/dist/connectors/types.d.ts.map +1 -0
  29. package/dist/connectors/types.js +35 -0
  30. package/dist/connectors/types.js.map +1 -0
  31. package/dist/coverage/__tests__/fixtures/mixed-project/annotated.d.ts +9 -0
  32. package/dist/coverage/__tests__/fixtures/mixed-project/annotated.d.ts.map +1 -0
  33. package/dist/coverage/__tests__/fixtures/mixed-project/annotated.js +11 -0
  34. package/dist/coverage/__tests__/fixtures/mixed-project/annotated.js.map +1 -0
  35. package/dist/coverage/__tests__/fixtures/mixed-project/unannotated.d.ts +2 -0
  36. package/dist/coverage/__tests__/fixtures/mixed-project/unannotated.d.ts.map +1 -0
  37. package/dist/coverage/__tests__/fixtures/mixed-project/unannotated.js +4 -0
  38. package/dist/coverage/__tests__/fixtures/mixed-project/unannotated.js.map +1 -0
  39. package/dist/coverage/coverage-calculator.d.ts +3 -0
  40. package/dist/coverage/coverage-calculator.d.ts.map +1 -0
  41. package/dist/coverage/coverage-calculator.js +204 -0
  42. package/dist/coverage/coverage-calculator.js.map +1 -0
  43. package/dist/coverage/index.d.ts +3 -0
  44. package/dist/coverage/index.d.ts.map +1 -0
  45. package/dist/coverage/index.js +2 -0
  46. package/dist/coverage/index.js.map +1 -0
  47. package/dist/coverage/types.d.ts +38 -0
  48. package/dist/coverage/types.d.ts.map +1 -0
  49. package/dist/coverage/types.js +13 -0
  50. package/dist/coverage/types.js.map +1 -0
  51. package/dist/index.d.ts +17 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +16 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/indexer/database.d.ts +32 -0
  56. package/dist/indexer/database.d.ts.map +1 -0
  57. package/dist/indexer/database.js +242 -0
  58. package/dist/indexer/database.js.map +1 -0
  59. package/dist/indexer/index.d.ts +7 -0
  60. package/dist/indexer/index.d.ts.map +1 -0
  61. package/dist/indexer/index.js +4 -0
  62. package/dist/indexer/index.js.map +1 -0
  63. package/dist/indexer/indexer.d.ts +12 -0
  64. package/dist/indexer/indexer.d.ts.map +1 -0
  65. package/dist/indexer/indexer.js +145 -0
  66. package/dist/indexer/indexer.js.map +1 -0
  67. package/dist/indexer/schema.d.ts +21 -0
  68. package/dist/indexer/schema.d.ts.map +1 -0
  69. package/dist/indexer/schema.js +122 -0
  70. package/dist/indexer/schema.js.map +1 -0
  71. package/dist/indexer/types.d.ts +85 -0
  72. package/dist/indexer/types.d.ts.map +1 -0
  73. package/dist/indexer/types.js +2 -0
  74. package/dist/indexer/types.js.map +1 -0
  75. package/dist/parsers/generic-parser.d.ts +3 -0
  76. package/dist/parsers/generic-parser.d.ts.map +1 -0
  77. package/dist/parsers/generic-parser.js +150 -0
  78. package/dist/parsers/generic-parser.js.map +1 -0
  79. package/dist/parsers/go-parser.d.ts +3 -0
  80. package/dist/parsers/go-parser.d.ts.map +1 -0
  81. package/dist/parsers/go-parser.js +437 -0
  82. package/dist/parsers/go-parser.js.map +1 -0
  83. package/dist/parsers/index.d.ts +10 -0
  84. package/dist/parsers/index.d.ts.map +1 -0
  85. package/dist/parsers/index.js +8 -0
  86. package/dist/parsers/index.js.map +1 -0
  87. package/dist/parsers/java-parser.d.ts +3 -0
  88. package/dist/parsers/java-parser.d.ts.map +1 -0
  89. package/dist/parsers/java-parser.js +321 -0
  90. package/dist/parsers/java-parser.js.map +1 -0
  91. package/dist/parsers/metadata-extractor.d.ts +25 -0
  92. package/dist/parsers/metadata-extractor.d.ts.map +1 -0
  93. package/dist/parsers/metadata-extractor.js +137 -0
  94. package/dist/parsers/metadata-extractor.js.map +1 -0
  95. package/dist/parsers/python-parser.d.ts +3 -0
  96. package/dist/parsers/python-parser.d.ts.map +1 -0
  97. package/dist/parsers/python-parser.js +226 -0
  98. package/dist/parsers/python-parser.js.map +1 -0
  99. package/dist/parsers/registry.d.ts +3 -0
  100. package/dist/parsers/registry.d.ts.map +1 -0
  101. package/dist/parsers/registry.js +41 -0
  102. package/dist/parsers/registry.js.map +1 -0
  103. package/dist/parsers/types.d.ts +23 -0
  104. package/dist/parsers/types.d.ts.map +1 -0
  105. package/dist/parsers/types.js +2 -0
  106. package/dist/parsers/types.js.map +1 -0
  107. package/dist/parsers/typescript-parser.d.ts +3 -0
  108. package/dist/parsers/typescript-parser.d.ts.map +1 -0
  109. package/dist/parsers/typescript-parser.js +321 -0
  110. package/dist/parsers/typescript-parser.js.map +1 -0
  111. package/dist/query/index.d.ts +3 -0
  112. package/dist/query/index.d.ts.map +1 -0
  113. package/dist/query/index.js +2 -0
  114. package/dist/query/index.js.map +1 -0
  115. package/dist/query/query-engine.d.ts +40 -0
  116. package/dist/query/query-engine.d.ts.map +1 -0
  117. package/dist/query/query-engine.js +126 -0
  118. package/dist/query/query-engine.js.map +1 -0
  119. package/dist/suggest/index.d.ts +3 -0
  120. package/dist/suggest/index.d.ts.map +1 -0
  121. package/dist/suggest/index.js +2 -0
  122. package/dist/suggest/index.js.map +1 -0
  123. package/dist/suggest/suggestion-engine.d.ts +7 -0
  124. package/dist/suggest/suggestion-engine.d.ts.map +1 -0
  125. package/dist/suggest/suggestion-engine.js +239 -0
  126. package/dist/suggest/suggestion-engine.js.map +1 -0
  127. package/dist/suggest/types.d.ts +29 -0
  128. package/dist/suggest/types.d.ts.map +1 -0
  129. package/dist/suggest/types.js +13 -0
  130. package/dist/suggest/types.js.map +1 -0
  131. package/dist/types/entity.d.ts +336 -0
  132. package/dist/types/entity.d.ts.map +1 -0
  133. package/dist/types/entity.js +99 -0
  134. package/dist/types/entity.js.map +1 -0
  135. package/dist/types/index.d.ts +6 -0
  136. package/dist/types/index.d.ts.map +1 -0
  137. package/dist/types/index.js +3 -0
  138. package/dist/types/index.js.map +1 -0
  139. package/dist/types/manifest.d.ts +488 -0
  140. package/dist/types/manifest.d.ts.map +1 -0
  141. package/dist/types/manifest.js +66 -0
  142. package/dist/types/manifest.js.map +1 -0
  143. package/dist/types/parse-result.d.ts +25 -0
  144. package/dist/types/parse-result.d.ts.map +1 -0
  145. package/dist/types/parse-result.js +2 -0
  146. package/dist/types/parse-result.js.map +1 -0
  147. package/dist/validation/index.d.ts +5 -0
  148. package/dist/validation/index.d.ts.map +1 -0
  149. package/dist/validation/index.js +3 -0
  150. package/dist/validation/index.js.map +1 -0
  151. package/dist/validation/rules.d.ts +9 -0
  152. package/dist/validation/rules.d.ts.map +1 -0
  153. package/dist/validation/rules.js +119 -0
  154. package/dist/validation/rules.js.map +1 -0
  155. package/dist/validation/types.d.ts +34 -0
  156. package/dist/validation/types.d.ts.map +1 -0
  157. package/dist/validation/types.js +2 -0
  158. package/dist/validation/types.js.map +1 -0
  159. package/dist/validation/validator.d.ts +10 -0
  160. package/dist/validation/validator.d.ts.map +1 -0
  161. package/dist/validation/validator.js +111 -0
  162. package/dist/validation/validator.js.map +1 -0
  163. 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,3 @@
1
+ import type { ParserRegistry } from './types.js';
2
+ export declare function createDefaultRegistry(): ParserRegistry;
3
+ //# sourceMappingURL=registry.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/parsers/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { Parser } from './types.js';
2
+ export declare function createTypescriptParser(): Parser;
3
+ //# sourceMappingURL=typescript-parser.d.ts.map
@@ -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