driftdetect-core 0.9.26 → 0.9.28

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 (104) hide show
  1. package/dist/boundaries/boundary-scanner.d.ts.map +1 -1
  2. package/dist/boundaries/boundary-scanner.js +151 -9
  3. package/dist/boundaries/boundary-scanner.js.map +1 -1
  4. package/dist/boundaries/field-extractors/diesel-extractor.d.ts +26 -0
  5. package/dist/boundaries/field-extractors/diesel-extractor.d.ts.map +1 -0
  6. package/dist/boundaries/field-extractors/diesel-extractor.js +166 -0
  7. package/dist/boundaries/field-extractors/diesel-extractor.js.map +1 -0
  8. package/dist/boundaries/field-extractors/django-extractor.d.ts +27 -0
  9. package/dist/boundaries/field-extractors/django-extractor.d.ts.map +1 -0
  10. package/dist/boundaries/field-extractors/django-extractor.js +226 -0
  11. package/dist/boundaries/field-extractors/django-extractor.js.map +1 -0
  12. package/dist/boundaries/field-extractors/gorm-extractor.d.ts +27 -0
  13. package/dist/boundaries/field-extractors/gorm-extractor.d.ts.map +1 -0
  14. package/dist/boundaries/field-extractors/gorm-extractor.js +197 -0
  15. package/dist/boundaries/field-extractors/gorm-extractor.js.map +1 -0
  16. package/dist/boundaries/field-extractors/index.d.ts +32 -0
  17. package/dist/boundaries/field-extractors/index.d.ts.map +1 -0
  18. package/dist/boundaries/field-extractors/index.js +115 -0
  19. package/dist/boundaries/field-extractors/index.js.map +1 -0
  20. package/dist/boundaries/field-extractors/prisma-extractor.d.ts +24 -0
  21. package/dist/boundaries/field-extractors/prisma-extractor.d.ts.map +1 -0
  22. package/dist/boundaries/field-extractors/prisma-extractor.js +156 -0
  23. package/dist/boundaries/field-extractors/prisma-extractor.js.map +1 -0
  24. package/dist/boundaries/field-extractors/raw-sql-extractor.d.ts +52 -0
  25. package/dist/boundaries/field-extractors/raw-sql-extractor.d.ts.map +1 -0
  26. package/dist/boundaries/field-extractors/raw-sql-extractor.js +234 -0
  27. package/dist/boundaries/field-extractors/raw-sql-extractor.js.map +1 -0
  28. package/dist/boundaries/field-extractors/sqlalchemy-extractor.d.ts +25 -0
  29. package/dist/boundaries/field-extractors/sqlalchemy-extractor.d.ts.map +1 -0
  30. package/dist/boundaries/field-extractors/sqlalchemy-extractor.js +201 -0
  31. package/dist/boundaries/field-extractors/sqlalchemy-extractor.js.map +1 -0
  32. package/dist/boundaries/field-extractors/supabase-extractor.d.ts +25 -0
  33. package/dist/boundaries/field-extractors/supabase-extractor.d.ts.map +1 -0
  34. package/dist/boundaries/field-extractors/supabase-extractor.js +131 -0
  35. package/dist/boundaries/field-extractors/supabase-extractor.js.map +1 -0
  36. package/dist/boundaries/field-extractors/types.d.ts +116 -0
  37. package/dist/boundaries/field-extractors/types.d.ts.map +1 -0
  38. package/dist/boundaries/field-extractors/types.js +59 -0
  39. package/dist/boundaries/field-extractors/types.js.map +1 -0
  40. package/dist/boundaries/index.d.ts +1 -0
  41. package/dist/boundaries/index.d.ts.map +1 -1
  42. package/dist/boundaries/index.js +6 -0
  43. package/dist/boundaries/index.js.map +1 -1
  44. package/dist/call-graph/store/call-graph-store.js +2 -2
  45. package/dist/call-graph/store/call-graph-store.js.map +1 -1
  46. package/dist/call-graph/streaming-builder.d.ts +18 -1
  47. package/dist/call-graph/streaming-builder.d.ts.map +1 -1
  48. package/dist/call-graph/streaming-builder.js +112 -5
  49. package/dist/call-graph/streaming-builder.js.map +1 -1
  50. package/dist/call-graph/unified-provider.d.ts.map +1 -1
  51. package/dist/call-graph/unified-provider.js +11 -3
  52. package/dist/call-graph/unified-provider.js.map +1 -1
  53. package/dist/dna/dna-analyzer.d.ts +11 -1
  54. package/dist/dna/dna-analyzer.d.ts.map +1 -1
  55. package/dist/dna/dna-analyzer.js +153 -23
  56. package/dist/dna/dna-analyzer.js.map +1 -1
  57. package/dist/dna/gene-extractors/api-response-format.d.ts +22 -0
  58. package/dist/dna/gene-extractors/api-response-format.d.ts.map +1 -0
  59. package/dist/dna/gene-extractors/api-response-format.js +137 -0
  60. package/dist/dna/gene-extractors/api-response-format.js.map +1 -0
  61. package/dist/dna/gene-extractors/config-pattern.d.ts +21 -0
  62. package/dist/dna/gene-extractors/config-pattern.d.ts.map +1 -0
  63. package/dist/dna/gene-extractors/config-pattern.js +137 -0
  64. package/dist/dna/gene-extractors/config-pattern.js.map +1 -0
  65. package/dist/dna/gene-extractors/error-response-format.d.ts +21 -0
  66. package/dist/dna/gene-extractors/error-response-format.d.ts.map +1 -0
  67. package/dist/dna/gene-extractors/error-response-format.js +135 -0
  68. package/dist/dna/gene-extractors/error-response-format.js.map +1 -0
  69. package/dist/dna/gene-extractors/index.d.ts +6 -0
  70. package/dist/dna/gene-extractors/index.d.ts.map +1 -1
  71. package/dist/dna/gene-extractors/index.js +40 -0
  72. package/dist/dna/gene-extractors/index.js.map +1 -1
  73. package/dist/dna/gene-extractors/logging-format.d.ts +21 -0
  74. package/dist/dna/gene-extractors/logging-format.d.ts.map +1 -0
  75. package/dist/dna/gene-extractors/logging-format.js +130 -0
  76. package/dist/dna/gene-extractors/logging-format.js.map +1 -0
  77. package/dist/dna/index.d.ts +5 -1
  78. package/dist/dna/index.d.ts.map +1 -1
  79. package/dist/dna/index.js +8 -1
  80. package/dist/dna/index.js.map +1 -1
  81. package/dist/dna/types.d.ts +8 -1
  82. package/dist/dna/types.d.ts.map +1 -1
  83. package/dist/dna/types.js +4 -2
  84. package/dist/dna/types.js.map +1 -1
  85. package/dist/index.d.ts +2 -0
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +2 -0
  88. package/dist/index.js.map +1 -1
  89. package/dist/lake/callgraph-shard-store.d.ts +3 -0
  90. package/dist/lake/callgraph-shard-store.d.ts.map +1 -1
  91. package/dist/lake/callgraph-shard-store.js +23 -3
  92. package/dist/lake/callgraph-shard-store.js.map +1 -1
  93. package/dist/lake/pattern-shard-store.d.ts.map +1 -1
  94. package/dist/lake/pattern-shard-store.js +1 -0
  95. package/dist/lake/pattern-shard-store.js.map +1 -1
  96. package/dist/lake/query-engine.js +1 -1
  97. package/dist/lake/query-engine.js.map +1 -1
  98. package/dist/lake/types.d.ts +18 -1
  99. package/dist/lake/types.d.ts.map +1 -1
  100. package/dist/lake/types.js.map +1 -1
  101. package/dist/module-coupling/coupling-analyzer.d.ts.map +1 -1
  102. package/dist/module-coupling/coupling-analyzer.js +33 -1
  103. package/dist/module-coupling/coupling-analyzer.js.map +1 -1
  104. package/package.json +13 -13
@@ -0,0 +1,201 @@
1
+ /**
2
+ * SQLAlchemy Field Extractor
3
+ *
4
+ * Extracts fields from SQLAlchemy query patterns:
5
+ * - session.query(User.id, User.email)
6
+ * - session.query(User).with_entities(User.email)
7
+ * - session.query(User).filter(User.email == 'test')
8
+ * - session.query(User).filter_by(email='test')
9
+ *
10
+ * Also extracts from SQLAlchemy model definitions.
11
+ */
12
+ import { BaseFieldExtractor, } from './types.js';
13
+ export class SQLAlchemyFieldExtractor extends BaseFieldExtractor {
14
+ name = 'sqlalchemy';
15
+ framework = 'sqlalchemy';
16
+ languages = ['python'];
17
+ matches(content, language) {
18
+ if (language !== 'python')
19
+ return false;
20
+ return (content.includes('session.query') ||
21
+ content.includes('declarative_base') ||
22
+ content.includes('from sqlalchemy') ||
23
+ content.includes('Column('));
24
+ }
25
+ extractFromLine(line, _context, lineNumber) {
26
+ if (this.isComment(line)) {
27
+ return { fields: [] };
28
+ }
29
+ const fields = [];
30
+ let table;
31
+ // Extract table from session.query(Model) or session.query(Model.field)
32
+ const queryMatch = line.match(/\.query\s*\(\s*([A-Z][a-zA-Z0-9]*)/);
33
+ if (queryMatch?.[1]) {
34
+ table = queryMatch[1].toLowerCase() + 's';
35
+ }
36
+ // Extract fields from session.query(Model.field1, Model.field2)
37
+ const queryFieldsMatch = line.match(/\.query\s*\(([^)]+)\)/);
38
+ if (queryFieldsMatch?.[1]) {
39
+ const fieldMatches = queryFieldsMatch[1].matchAll(/[A-Z]\w*\.(\w+)/g);
40
+ for (const fm of fieldMatches) {
41
+ if (fm[1]) {
42
+ fields.push(this.createField(fm[1], 'query', 0.95, { line: lineNumber }));
43
+ }
44
+ }
45
+ }
46
+ // Extract fields from .with_entities(Model.field1, Model.field2)
47
+ const entitiesMatch = line.match(/\.with_entities\s*\(([^)]+)\)/);
48
+ if (entitiesMatch?.[1]) {
49
+ const fieldMatches = entitiesMatch[1].matchAll(/[A-Z]\w*\.(\w+)/g);
50
+ for (const fm of fieldMatches) {
51
+ if (fm[1]) {
52
+ fields.push(this.createField(fm[1], 'query', 0.95, { line: lineNumber }));
53
+ }
54
+ }
55
+ }
56
+ // Extract fields from .filter(Model.field == value)
57
+ const filterMatch = line.match(/\.filter\s*\(([^)]+)\)/);
58
+ if (filterMatch?.[1]) {
59
+ const fieldMatches = filterMatch[1].matchAll(/[A-Z]\w*\.(\w+)/g);
60
+ for (const fm of fieldMatches) {
61
+ if (fm[1]) {
62
+ fields.push(this.createField(fm[1], 'filter', 0.9, { line: lineNumber }));
63
+ }
64
+ }
65
+ }
66
+ // Extract fields from .filter_by(field=value)
67
+ const filterByMatch = line.match(/\.filter_by\s*\(([^)]+)\)/);
68
+ if (filterByMatch?.[1]) {
69
+ const fieldMatches = filterByMatch[1].matchAll(/(\w+)\s*=/g);
70
+ for (const fm of fieldMatches) {
71
+ if (fm[1]) {
72
+ fields.push(this.createField(fm[1], 'filter', 0.9, { line: lineNumber }));
73
+ }
74
+ }
75
+ }
76
+ // Extract fields from .order_by(Model.field)
77
+ const orderMatch = line.match(/\.order_by\s*\(([^)]+)\)/);
78
+ if (orderMatch?.[1]) {
79
+ const fieldMatches = orderMatch[1].matchAll(/[A-Z]\w*\.(\w+)/g);
80
+ for (const fm of fieldMatches) {
81
+ if (fm[1]) {
82
+ fields.push(this.createField(fm[1], 'query', 0.85, { line: lineNumber }));
83
+ }
84
+ }
85
+ }
86
+ // Extract fields from .group_by(Model.field)
87
+ const groupMatch = line.match(/\.group_by\s*\(([^)]+)\)/);
88
+ if (groupMatch?.[1]) {
89
+ const fieldMatches = groupMatch[1].matchAll(/[A-Z]\w*\.(\w+)/g);
90
+ for (const fm of fieldMatches) {
91
+ if (fm[1]) {
92
+ fields.push(this.createField(fm[1], 'query', 0.85, { line: lineNumber }));
93
+ }
94
+ }
95
+ }
96
+ // Deduplicate
97
+ const uniqueFields = this.deduplicateFields(fields);
98
+ return this.buildResult(uniqueFields, table, this.framework);
99
+ }
100
+ extractFromModels(content) {
101
+ const results = [];
102
+ // Parse SQLAlchemy model class definitions
103
+ const modelPattern = /class\s+(\w+)\s*\([^)]*(?:Base|DeclarativeBase)[^)]*\)\s*:/g;
104
+ let match;
105
+ while ((match = modelPattern.exec(content)) !== null) {
106
+ const modelName = match[1];
107
+ if (!modelName)
108
+ continue;
109
+ const startLine = content.substring(0, match.index).split('\n').length;
110
+ // Find the model body
111
+ const afterClass = content.substring(match.index + match[0].length);
112
+ const lines = afterClass.split('\n');
113
+ const fields = [];
114
+ let endLine = startLine;
115
+ let tableName;
116
+ for (let i = 0; i < lines.length; i++) {
117
+ const line = lines[i];
118
+ if (line === undefined)
119
+ continue;
120
+ // Check if we've exited the class
121
+ if (i > 0 && line.length > 0 && !line.startsWith(' ') && !line.startsWith('\t')) {
122
+ break;
123
+ }
124
+ endLine = startLine + i + 1;
125
+ // Check for __tablename__
126
+ const tableNameMatch = line.match(/__tablename__\s*=\s*["'](\w+)["']/);
127
+ if (tableNameMatch?.[1]) {
128
+ tableName = tableNameMatch[1];
129
+ }
130
+ // Parse field definitions: field_name = Column(Type, ...)
131
+ const fieldMatch = line.match(/^\s+(\w+)\s*=\s*Column\s*\(\s*(\w+)/);
132
+ if (fieldMatch?.[1] && fieldMatch[2]) {
133
+ const fieldName = fieldMatch[1];
134
+ const fieldType = fieldMatch[2];
135
+ fields.push(this.createField(fieldName, 'model', 0.98, {
136
+ type: this.mapSQLAlchemyType(fieldType),
137
+ line: startLine + i + 1,
138
+ }));
139
+ }
140
+ // Parse relationship definitions
141
+ const relMatch = line.match(/^\s+(\w+)\s*=\s*relationship\s*\(\s*["'](\w+)["']/);
142
+ if (relMatch?.[1] && relMatch[2]) {
143
+ fields.push(this.createField(relMatch[1], 'model', 0.95, {
144
+ type: 'relation',
145
+ line: startLine + i + 1,
146
+ isRelation: true,
147
+ relatedTable: relMatch[2].toLowerCase() + 's',
148
+ }));
149
+ }
150
+ }
151
+ if (fields.length > 0) {
152
+ results.push({
153
+ modelName,
154
+ tableName: tableName ?? modelName.toLowerCase() + 's',
155
+ fields,
156
+ framework: this.framework,
157
+ startLine,
158
+ endLine,
159
+ });
160
+ }
161
+ }
162
+ return results;
163
+ }
164
+ mapSQLAlchemyType(saType) {
165
+ const typeMap = {
166
+ 'String': 'string',
167
+ 'Text': 'string',
168
+ 'Unicode': 'string',
169
+ 'UnicodeText': 'string',
170
+ 'Integer': 'int',
171
+ 'SmallInteger': 'int',
172
+ 'BigInteger': 'bigint',
173
+ 'Float': 'float',
174
+ 'Numeric': 'decimal',
175
+ 'Boolean': 'boolean',
176
+ 'Date': 'date',
177
+ 'DateTime': 'datetime',
178
+ 'Time': 'time',
179
+ 'LargeBinary': 'bytes',
180
+ 'PickleType': 'bytes',
181
+ 'Enum': 'enum',
182
+ 'JSON': 'json',
183
+ 'ARRAY': 'array',
184
+ };
185
+ return typeMap[saType] ?? 'unknown';
186
+ }
187
+ deduplicateFields(fields) {
188
+ const seen = new Map();
189
+ for (const field of fields) {
190
+ const existing = seen.get(field.name);
191
+ if (!existing || field.confidence > existing.confidence) {
192
+ seen.set(field.name, field);
193
+ }
194
+ }
195
+ return Array.from(seen.values());
196
+ }
197
+ }
198
+ export function createSQLAlchemyExtractor() {
199
+ return new SQLAlchemyFieldExtractor();
200
+ }
201
+ //# sourceMappingURL=sqlalchemy-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlalchemy-extractor.js","sourceRoot":"","sources":["../../../src/boundaries/field-extractors/sqlalchemy-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Supabase Field Extractor
3
+ *
4
+ * Extracts fields from Supabase query patterns:
5
+ * - .select('field1, field2')
6
+ * - .eq('field', value)
7
+ * - .neq('field', value)
8
+ * - .in('field', [values])
9
+ * - .insert({ field: value })
10
+ * - .update({ field: value })
11
+ * - .order('field')
12
+ */
13
+ import type { ORMFramework } from '../types.js';
14
+ import { BaseFieldExtractor, type LineExtractionResult, type ModelExtractionResult } from './types.js';
15
+ export declare class SupabaseFieldExtractor extends BaseFieldExtractor {
16
+ readonly name = "supabase";
17
+ readonly framework: ORMFramework;
18
+ readonly languages: string[];
19
+ matches(content: string, language: string): boolean;
20
+ extractFromLine(line: string, _context: string[], lineNumber: number): LineExtractionResult;
21
+ extractFromModels(_content: string): ModelExtractionResult[];
22
+ private deduplicateFields;
23
+ }
24
+ export declare function createSupabaseExtractor(): SupabaseFieldExtractor;
25
+ //# sourceMappingURL=supabase-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-extractor.d.ts","sourceRoot":"","sources":["../../../src/boundaries/field-extractors/supabase-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAE3B,MAAM,YAAY,CAAC;AAEpB,qBAAa,sBAAuB,SAAQ,kBAAkB;IAC5D,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAc;IAC9C,QAAQ,CAAC,SAAS,WAAgC;IAElD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IASnD,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,oBAAoB;IA+F3F,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,qBAAqB,EAAE;IAM5D,OAAO,CAAC,iBAAiB;CAU1B;AAED,wBAAgB,uBAAuB,IAAI,sBAAsB,CAEhE"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Supabase Field Extractor
3
+ *
4
+ * Extracts fields from Supabase query patterns:
5
+ * - .select('field1, field2')
6
+ * - .eq('field', value)
7
+ * - .neq('field', value)
8
+ * - .in('field', [values])
9
+ * - .insert({ field: value })
10
+ * - .update({ field: value })
11
+ * - .order('field')
12
+ */
13
+ import { BaseFieldExtractor, } from './types.js';
14
+ export class SupabaseFieldExtractor extends BaseFieldExtractor {
15
+ name = 'supabase';
16
+ framework = 'supabase';
17
+ languages = ['typescript', 'javascript'];
18
+ matches(content, language) {
19
+ if (!this.languages.includes(language))
20
+ return false;
21
+ return (content.includes('supabase') ||
22
+ content.includes('@supabase/supabase-js') ||
23
+ /\.from\s*\(\s*["'`]/.test(content));
24
+ }
25
+ extractFromLine(line, _context, lineNumber) {
26
+ if (this.isComment(line)) {
27
+ return { fields: [] };
28
+ }
29
+ const fields = [];
30
+ let table;
31
+ // Extract table from .from('table_name')
32
+ const fromMatch = line.match(/\.from\s*\(\s*["'`]([a-zA-Z_][a-zA-Z0-9_]*)["'`]/);
33
+ if (fromMatch?.[1]) {
34
+ table = fromMatch[1];
35
+ }
36
+ // Extract fields from .select('field1, field2, field3')
37
+ const selectMatch = line.match(/\.select\s*\(\s*["'`]([^"'`]+)["'`]/);
38
+ if (selectMatch?.[1]) {
39
+ const fieldNames = this.parseFieldList(selectMatch[1]);
40
+ for (const name of fieldNames) {
41
+ // Handle nested selects like 'id, profiles(name, avatar)'
42
+ if (name.includes('(')) {
43
+ const [fieldName] = name.split('(');
44
+ if (fieldName) {
45
+ fields.push(this.createField(fieldName.trim(), 'query', 0.95, {
46
+ line: lineNumber,
47
+ isRelation: true,
48
+ }));
49
+ }
50
+ }
51
+ else {
52
+ fields.push(this.createField(name, 'query', 0.95, { line: lineNumber }));
53
+ }
54
+ }
55
+ }
56
+ // Extract fields from filter methods: .eq('field', value), .neq(), .gt(), .lt(), etc.
57
+ const filterPatterns = [
58
+ /\.eq\s*\(\s*["'](\w+)["']/g,
59
+ /\.neq\s*\(\s*["'](\w+)["']/g,
60
+ /\.gt\s*\(\s*["'](\w+)["']/g,
61
+ /\.gte\s*\(\s*["'](\w+)["']/g,
62
+ /\.lt\s*\(\s*["'](\w+)["']/g,
63
+ /\.lte\s*\(\s*["'](\w+)["']/g,
64
+ /\.like\s*\(\s*["'](\w+)["']/g,
65
+ /\.ilike\s*\(\s*["'](\w+)["']/g,
66
+ /\.is\s*\(\s*["'](\w+)["']/g,
67
+ /\.in\s*\(\s*["'](\w+)["']/g,
68
+ /\.contains\s*\(\s*["'](\w+)["']/g,
69
+ /\.containedBy\s*\(\s*["'](\w+)["']/g,
70
+ /\.range\s*\(\s*["'](\w+)["']/g,
71
+ /\.match\s*\(\s*\{([^}]+)\}/g,
72
+ ];
73
+ for (const pattern of filterPatterns) {
74
+ const matches = line.matchAll(pattern);
75
+ for (const match of matches) {
76
+ if (match[1]) {
77
+ // For .match({ field: value }), extract object keys
78
+ if (pattern.source.includes('match')) {
79
+ const keyMatches = match[1].matchAll(/(\w+)\s*:/g);
80
+ for (const km of keyMatches) {
81
+ if (km[1]) {
82
+ fields.push(this.createField(km[1], 'filter', 0.9, { line: lineNumber }));
83
+ }
84
+ }
85
+ }
86
+ else {
87
+ fields.push(this.createField(match[1], 'filter', 0.9, { line: lineNumber }));
88
+ }
89
+ }
90
+ }
91
+ }
92
+ // Extract fields from .order('field')
93
+ const orderMatch = line.match(/\.order\s*\(\s*["'](\w+)["']/);
94
+ if (orderMatch?.[1]) {
95
+ fields.push(this.createField(orderMatch[1], 'query', 0.85, { line: lineNumber }));
96
+ }
97
+ // Extract fields from .insert({ field: value }) or .update({ field: value })
98
+ const mutationMatch = line.match(/\.(?:insert|update|upsert)\s*\(\s*\{([^}]+)\}/);
99
+ if (mutationMatch?.[1]) {
100
+ const keyMatches = mutationMatch[1].matchAll(/(\w+)\s*:/g);
101
+ for (const km of keyMatches) {
102
+ if (km[1]) {
103
+ const source = line.includes('.insert') ? 'insert' : 'update';
104
+ fields.push(this.createField(km[1], source, 0.9, { line: lineNumber }));
105
+ }
106
+ }
107
+ }
108
+ // Deduplicate fields by name
109
+ const uniqueFields = this.deduplicateFields(fields);
110
+ return this.buildResult(uniqueFields, table, this.framework);
111
+ }
112
+ extractFromModels(_content) {
113
+ // Supabase doesn't have model definitions in code
114
+ // Models are defined in the database schema
115
+ return [];
116
+ }
117
+ deduplicateFields(fields) {
118
+ const seen = new Map();
119
+ for (const field of fields) {
120
+ const existing = seen.get(field.name);
121
+ if (!existing || field.confidence > existing.confidence) {
122
+ seen.set(field.name, field);
123
+ }
124
+ }
125
+ return Array.from(seen.values());
126
+ }
127
+ }
128
+ export function createSupabaseExtractor() {
129
+ return new SupabaseFieldExtractor();
130
+ }
131
+ //# sourceMappingURL=supabase-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-extractor.js","sourceRoot":"","sources":["../../../src/boundaries/field-extractors/supabase-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Field Extractor Types
3
+ *
4
+ * Defines the interface for framework-specific field extractors.
5
+ * Each ORM/framework has its own extractor that knows how to parse
6
+ * field access patterns from that framework's syntax.
7
+ */
8
+ import type { ORMFramework } from '../types.js';
9
+ /**
10
+ * Source of field extraction
11
+ */
12
+ export type FieldSource = 'query' | 'model' | 'filter' | 'insert' | 'update' | 'inferred';
13
+ /**
14
+ * An extracted field with metadata
15
+ */
16
+ export interface ExtractedField {
17
+ /** Field/column name */
18
+ name: string;
19
+ /** Field type if detectable (e.g., 'string', 'int', 'boolean') */
20
+ type?: string;
21
+ /** Extraction confidence (0-1) */
22
+ confidence: number;
23
+ /** How the field was extracted */
24
+ source: FieldSource;
25
+ /** Line number where field was found */
26
+ line?: number;
27
+ /** Whether this is a relationship/foreign key */
28
+ isRelation?: boolean;
29
+ /** Related table for foreign keys */
30
+ relatedTable?: string;
31
+ }
32
+ /**
33
+ * Result of field extraction from a line
34
+ */
35
+ export interface LineExtractionResult {
36
+ /** Extracted fields */
37
+ fields: ExtractedField[];
38
+ /** Table name if detected */
39
+ table?: string;
40
+ /** Framework that matched */
41
+ framework?: ORMFramework;
42
+ }
43
+ /**
44
+ * Result of field extraction from a model definition
45
+ */
46
+ export interface ModelExtractionResult {
47
+ /** Model/class name */
48
+ modelName: string;
49
+ /** Mapped table name */
50
+ tableName?: string;
51
+ /** All fields in the model */
52
+ fields: ExtractedField[];
53
+ /** Framework that matched */
54
+ framework: ORMFramework;
55
+ /** Start line of model definition */
56
+ startLine: number;
57
+ /** End line of model definition */
58
+ endLine: number;
59
+ }
60
+ /**
61
+ * Interface for framework-specific field extractors
62
+ */
63
+ export interface FieldExtractor {
64
+ /** Extractor name for debugging */
65
+ readonly name: string;
66
+ /** ORM framework this extractor handles */
67
+ readonly framework: ORMFramework;
68
+ /** Languages this extractor supports */
69
+ readonly languages: string[];
70
+ /**
71
+ * Check if this extractor can handle the given content
72
+ * @param content File content
73
+ * @param language Detected language
74
+ */
75
+ matches(content: string, language: string): boolean;
76
+ /**
77
+ * Extract fields from a single line of code
78
+ * @param line The line to analyze
79
+ * @param context Surrounding lines for context
80
+ * @param lineNumber Line number in file
81
+ */
82
+ extractFromLine(line: string, context: string[], lineNumber: number): LineExtractionResult;
83
+ /**
84
+ * Extract fields from model/entity definitions in the content
85
+ * @param content Full file content
86
+ */
87
+ extractFromModels(content: string): ModelExtractionResult[];
88
+ }
89
+ /**
90
+ * Base class for field extractors with common utilities
91
+ */
92
+ export declare abstract class BaseFieldExtractor implements FieldExtractor {
93
+ abstract readonly name: string;
94
+ abstract readonly framework: ORMFramework;
95
+ abstract readonly languages: string[];
96
+ abstract matches(content: string, language: string): boolean;
97
+ abstract extractFromLine(line: string, context: string[], lineNumber: number): LineExtractionResult;
98
+ abstract extractFromModels(content: string): ModelExtractionResult[];
99
+ /**
100
+ * Helper to create an extracted field with defaults
101
+ */
102
+ protected createField(name: string, source: FieldSource, confidence: number, options?: Partial<ExtractedField>): ExtractedField;
103
+ /**
104
+ * Helper to extract fields from comma-separated string
105
+ */
106
+ protected parseFieldList(fieldStr: string): string[];
107
+ /**
108
+ * Helper to check if line is a comment
109
+ */
110
+ protected isComment(line: string): boolean;
111
+ /**
112
+ * Helper to build LineExtractionResult without undefined values
113
+ */
114
+ protected buildResult(fields: ExtractedField[], table?: string, framework?: ORMFramework): LineExtractionResult;
115
+ }
116
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/boundaries/field-extractors/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,UAAU,CAAC;AAEf;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,MAAM,EAAE,WAAW,CAAC;IACpB,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qCAAqC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,uBAAuB;IACvB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,SAAS,CAAC,EAAE,YAAY,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,6BAA6B;IAC7B,SAAS,EAAE,YAAY,CAAC;IACxB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;CACjB;AAGD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,2CAA2C;IAC3C,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IAEjC,wCAAwC;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAE7B;;;;OAIG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAEpD;;;;;OAKG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,oBAAoB,CAAC;IAE3F;;;OAGG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,EAAE,CAAC;CAC7D;AAED;;GAEG;AACH,8BAAsB,kBAAmB,YAAW,cAAc;IAChE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAEtC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAC5D,QAAQ,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,oBAAoB;IACnG,QAAQ,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,EAAE;IAEpE;;OAEG;IACH,SAAS,CAAC,WAAW,CACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAChC,cAAc;IASjB;;OAEG;IACH,SAAS,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAOpD;;OAEG;IACH,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAa1C;;OAEG;IACH,SAAS,CAAC,WAAW,CACnB,MAAM,EAAE,cAAc,EAAE,EACxB,KAAK,CAAC,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,YAAY,GACvB,oBAAoB;CAUxB"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Field Extractor Types
3
+ *
4
+ * Defines the interface for framework-specific field extractors.
5
+ * Each ORM/framework has its own extractor that knows how to parse
6
+ * field access patterns from that framework's syntax.
7
+ */
8
+ /**
9
+ * Base class for field extractors with common utilities
10
+ */
11
+ export class BaseFieldExtractor {
12
+ /**
13
+ * Helper to create an extracted field with defaults
14
+ */
15
+ createField(name, source, confidence, options) {
16
+ return {
17
+ name,
18
+ source,
19
+ confidence,
20
+ ...options,
21
+ };
22
+ }
23
+ /**
24
+ * Helper to extract fields from comma-separated string
25
+ */
26
+ parseFieldList(fieldStr) {
27
+ return fieldStr
28
+ .split(/\s*,\s*/)
29
+ .map(f => f.trim())
30
+ .filter(f => f && f !== '*');
31
+ }
32
+ /**
33
+ * Helper to check if line is a comment
34
+ */
35
+ isComment(line) {
36
+ const trimmed = line.trim();
37
+ return (trimmed.startsWith('//') ||
38
+ trimmed.startsWith('#') ||
39
+ trimmed.startsWith('*') ||
40
+ trimmed.startsWith('/*') ||
41
+ trimmed.startsWith('--') ||
42
+ trimmed.startsWith('"""') ||
43
+ trimmed.startsWith("'''"));
44
+ }
45
+ /**
46
+ * Helper to build LineExtractionResult without undefined values
47
+ */
48
+ buildResult(fields, table, framework) {
49
+ const result = { fields };
50
+ if (table) {
51
+ result.table = table;
52
+ }
53
+ if (framework) {
54
+ result.framework = framework;
55
+ }
56
+ return result;
57
+ }
58
+ }
59
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/boundaries/field-extractors/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAqGH;;GAEG;AACH,MAAM,OAAgB,kBAAkB;IAStC;;OAEG;IACO,WAAW,CACnB,IAAY,EACZ,MAAmB,EACnB,UAAkB,EAClB,OAAiC;QAEjC,OAAO;YACL,IAAI;YACJ,MAAM;YACN,UAAU;YACV,GAAG,OAAO;SACX,CAAC;IACJ,CAAC;IAED;;OAEG;IACO,cAAc,CAAC,QAAgB;QACvC,OAAO,QAAQ;aACZ,KAAK,CAAC,SAAS,CAAC;aAChB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACO,SAAS,CAAC,IAAY;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,OAAO,CACL,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YACxB,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YACvB,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YACvB,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YACxB,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YACxB,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC;YACzB,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAC1B,CAAC;IACJ,CAAC;IAED;;OAEG;IACO,WAAW,CACnB,MAAwB,EACxB,KAAc,EACd,SAAwB;QAExB,MAAM,MAAM,GAAyB,EAAE,MAAM,EAAE,CAAC;QAChD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;QACvB,CAAC;QACD,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;QAC/B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
@@ -11,4 +11,5 @@ export { DataAccessLearner, createDataAccessLearner } from './data-access-learne
11
11
  export type { LearnedDataAccessPattern, LearnedDataAccessConventions, DataAccessLearningConfig, } from './data-access-learner.js';
12
12
  export { SecurityPrioritizer, createSecurityPrioritizer } from './security-prioritizer.js';
13
13
  export type { SecurityClassification, PrioritizedAccessPoint, SecuritySummary, PrioritizedScanResult, } from './security-prioritizer.js';
14
+ export { type FieldExtractor, type ExtractedField, type FieldSource, type LineExtractionResult, type ModelExtractionResult, BaseFieldExtractor, SupabaseFieldExtractor, createSupabaseExtractor, PrismaFieldExtractor, createPrismaExtractor, DjangoFieldExtractor, createDjangoExtractor, SQLAlchemyFieldExtractor, createSQLAlchemyExtractor, RawSQLFieldExtractor, createRawSQLExtractor, GORMFieldExtractor, createGORMExtractor, DieselFieldExtractor, createDieselExtractor, getMatchingExtractors, getAllExtractors, extractFieldsFromLine, extractModelsFromContent, } from './field-extractors/index.js';
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/boundaries/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,aAAa,EACb,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,eAAe,EACf,eAAe,EACf,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAGzE,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGrF,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACtF,YAAY,EACV,wBAAwB,EACxB,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC3F,YAAY,EACV,sBAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,GACtB,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/boundaries/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,aAAa,EACb,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,eAAe,EACf,eAAe,EACf,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAGzE,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGrF,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACtF,YAAY,EACV,wBAAwB,EACxB,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC3F,YAAY,EACV,sBAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,kBAAkB,EAElB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EAErB,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,6BAA6B,CAAC"}
@@ -11,4 +11,10 @@ export { BoundaryScanner, createBoundaryScanner } from './boundary-scanner.js';
11
11
  export { DataAccessLearner, createDataAccessLearner } from './data-access-learner.js';
12
12
  // Security Prioritizer
13
13
  export { SecurityPrioritizer, createSecurityPrioritizer } from './security-prioritizer.js';
14
+ // Field Extractors
15
+ export { BaseFieldExtractor,
16
+ // Extractors
17
+ SupabaseFieldExtractor, createSupabaseExtractor, PrismaFieldExtractor, createPrismaExtractor, DjangoFieldExtractor, createDjangoExtractor, SQLAlchemyFieldExtractor, createSQLAlchemyExtractor, RawSQLFieldExtractor, createRawSQLExtractor, GORMFieldExtractor, createGORMExtractor, DieselFieldExtractor, createDieselExtractor,
18
+ // Factory functions
19
+ getMatchingExtractors, getAllExtractors, extractFieldsFromLine, extractModelsFromContent, } from './field-extractors/index.js';
14
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/boundaries/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsBH,QAAQ;AACR,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAEzE,0BAA0B;AAC1B,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAG/E,sBAAsB;AACtB,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAOtF,uBAAuB;AACvB,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/boundaries/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsBH,QAAQ;AACR,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAEzE,0BAA0B;AAC1B,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAG/E,sBAAsB;AACtB,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAOtF,uBAAuB;AACvB,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAQ3F,mBAAmB;AACnB,OAAO,EAOL,kBAAkB;AAClB,aAAa;AACb,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB;AACrB,oBAAoB;AACpB,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,6BAA6B,CAAC"}
@@ -194,8 +194,8 @@ export class CallGraphStore {
194
194
  stats: {
195
195
  totalFunctions: index.summary?.totalFunctions ?? functions.size,
196
196
  totalCallSites: index.summary?.totalCalls ?? 0,
197
- resolvedCallSites: 0,
198
- unresolvedCallSites: 0,
197
+ resolvedCallSites: index.summary?.resolvedCalls ?? 0,
198
+ unresolvedCallSites: index.summary?.unresolvedCalls ?? 0,
199
199
  totalDataAccessors: index.summary?.dataAccessors ?? dataAccessors.length,
200
200
  byLanguage: {
201
201
  python: 0,