quillshield 1.0.1 → 1.0.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAWA,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED,eAAO,MAAM,YAAY,GACvB,YAAY,MAAM,EAClB,SAAS,YAAY,kBAwMtB,CAAC"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAWA,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED,eAAO,MAAM,YAAY,GACvB,YAAY,MAAM,EAClB,SAAS,YAAY,kBAgNtB,CAAC"}
@@ -43,6 +43,8 @@ const auditCommand = async (targetPath, options) => {
43
43
  compilerVersion: '0.8.20',
44
44
  remappings: [],
45
45
  configFile: undefined,
46
+ sourceDirs: ['.'],
47
+ depDirs: [],
46
48
  };
47
49
  // Try to detect compiler version from the file's pragma
48
50
  const content = files[0].content;
@@ -54,7 +56,7 @@ const auditCommand = async (targetPath, options) => {
54
56
  console.log(chalk_1.default.gray(` Compiler version: ${projectInfo.compilerVersion}`));
55
57
  }
56
58
  else if (isDirectory) {
57
- // Directory audit (existing behavior)
59
+ // Directory audit
58
60
  const spinner = (0, ora_1.default)('Detecting project type...').start();
59
61
  const detectedType = (0, projectDetector_1.detectProjectType)(absolutePath);
60
62
  projectType = detectedType;
@@ -65,8 +67,14 @@ const auditCommand = async (targetPath, options) => {
65
67
  if (projectInfo.remappings.length > 0) {
66
68
  console.log(chalk_1.default.gray(` Found ${projectInfo.remappings.length} remapping(s)`));
67
69
  }
68
- spinner.start('Collecting Solidity files...');
69
- files = await (0, fileCollector_1.collectSolidityFiles)(absolutePath, detectedType);
70
+ if (projectInfo.sourceDirs.length > 0) {
71
+ console.log(chalk_1.default.gray(` Source dirs: ${projectInfo.sourceDirs.join(', ')}`));
72
+ }
73
+ if (projectInfo.depDirs.length > 0) {
74
+ console.log(chalk_1.default.gray(` Dependency dirs: ${projectInfo.depDirs.join(', ')}`));
75
+ }
76
+ spinner.start('Collecting Solidity files & resolving dependencies...');
77
+ files = await (0, fileCollector_1.collectSolidityFiles)(absolutePath, detectedType, projectInfo);
70
78
  if (files.length === 0) {
71
79
  spinner.fail('No Solidity files found');
72
80
  process.exit(1);
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { ProjectType } from './projectDetector';
1
+ import { ProjectType, ProjectInfo } from './projectDetector';
2
2
  export interface SolidityFile {
3
3
  name: string;
4
4
  path: string;
@@ -6,15 +6,18 @@ export interface SolidityFile {
6
6
  dependency: boolean;
7
7
  }
8
8
  /**
9
- * Collect a single Solidity file for auditing
9
+ * Collect a single Solidity file for auditing.
10
10
  */
11
11
  export declare const collectSingleFile: (filePath: string) => SolidityFile;
12
12
  /**
13
- * Collect all Solidity files from a project
13
+ * Collect all Solidity files from a project.
14
+ *
15
+ * Uses the enriched `ProjectInfo` (sourceDirs/depDirs) when available.
16
+ * Falls back to project-type–specific defaults when called with just a type.
14
17
  */
15
- export declare const collectSolidityFiles: (projectPath: string, projectType: ProjectType) => Promise<SolidityFile[]>;
18
+ export declare const collectSolidityFiles: (projectPath: string, projectType: ProjectType, projectInfo?: ProjectInfo) => Promise<SolidityFile[]>;
16
19
  /**
17
- * Get statistics about collected files
20
+ * Get statistics about collected files.
18
21
  */
19
22
  export declare const getFileStats: (files: SolidityFile[]) => {
20
23
  total: number;
@@ -1 +1 @@
1
- {"version":3,"file":"fileCollector.d.ts","sourceRoot":"","sources":["../../src/utils/fileCollector.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,MAAM,KAAG,YAQpD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAC/B,aAAa,MAAM,EACnB,aAAa,WAAW,KACvB,OAAO,CAAC,YAAY,EAAE,CAsBxB,CAAC;AA2JF;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,YAAY,EAAE;;;;;CAcjD,CAAC"}
1
+ {"version":3,"file":"fileCollector.d.ts","sourceRoot":"","sources":["../../src/utils/fileCollector.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAM7D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;CACrB;AA2BD;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,MAAM,KAAG,YAQpD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,aAAa,MAAM,EACnB,aAAa,WAAW,EACxB,cAAc,WAAW,KACxB,OAAO,CAAC,YAAY,EAAE,CA0CxB,CAAC;AA4ZF;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,YAAY,EAAE;;;;;CAcjD,CAAC"}
@@ -7,8 +7,28 @@ exports.getFileStats = exports.collectSolidityFiles = exports.collectSingleFile
7
7
  const fs_extra_1 = __importDefault(require("fs-extra"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const glob_1 = require("glob");
10
+ // ---------------------------------------------------------------------------
11
+ // Patterns to skip (test / mock / script files that should not be audited)
12
+ // ---------------------------------------------------------------------------
13
+ const TEST_PATH_PATTERNS = [
14
+ /[/\\]test[/\\]/i,
15
+ /[/\\]tests[/\\]/i,
16
+ /[/\\]mock[s]?[/\\]/i,
17
+ /[/\\]script[s]?[/\\]/i,
18
+ /[/\\]examples?[/\\]/i,
19
+ /[/\\]sample[s]?[/\\]/i,
20
+ /\.t\.sol$/i,
21
+ /\.test\.sol$/i,
22
+ /\.spec\.sol$/i,
23
+ /Mock\w*\.sol$/i,
24
+ /Test\w*\.sol$/i,
25
+ ];
26
+ const isTestFile = (filePath) => TEST_PATH_PATTERNS.some((re) => re.test(filePath));
27
+ // ---------------------------------------------------------------------------
28
+ // Public API
29
+ // ---------------------------------------------------------------------------
10
30
  /**
11
- * Collect a single Solidity file for auditing
31
+ * Collect a single Solidity file for auditing.
12
32
  */
13
33
  const collectSingleFile = (filePath) => {
14
34
  const content = fs_extra_1.default.readFileSync(filePath, 'utf-8');
@@ -21,10 +41,21 @@ const collectSingleFile = (filePath) => {
21
41
  };
22
42
  exports.collectSingleFile = collectSingleFile;
23
43
  /**
24
- * Collect all Solidity files from a project
44
+ * Collect all Solidity files from a project.
45
+ *
46
+ * Uses the enriched `ProjectInfo` (sourceDirs/depDirs) when available.
47
+ * Falls back to project-type–specific defaults when called with just a type.
25
48
  */
26
- const collectSolidityFiles = async (projectPath, projectType) => {
49
+ const collectSolidityFiles = async (projectPath, projectType, projectInfo) => {
27
50
  const files = [];
51
+ // If we have rich project info, use the universal collector
52
+ if (projectInfo && projectInfo.sourceDirs.length > 0) {
53
+ await collectFromDirs(projectPath, projectInfo.sourceDirs, projectInfo.depDirs, files);
54
+ // Additionally, discover dynamic dependencies from imports
55
+ await collectDynamicDependencies(projectPath, files, projectInfo.depDirs);
56
+ return dedup(files);
57
+ }
58
+ // Legacy: fall back to project-type switches
28
59
  switch (projectType) {
29
60
  case 'foundry':
30
61
  await collectFoundryFiles(projectPath, files);
@@ -33,87 +64,117 @@ const collectSolidityFiles = async (projectPath, projectType) => {
33
64
  await collectHardhatFiles(projectPath, files);
34
65
  break;
35
66
  case 'truffle':
36
- await collectTruffleFiles(projectPath, files);
67
+ case 'brownie':
68
+ case 'ape':
69
+ await collectContractsDirFiles(projectPath, files);
70
+ break;
71
+ case 'dapptools':
72
+ await collectDappToolsFiles(projectPath, files);
37
73
  break;
38
74
  case 'raw':
39
75
  await collectRawFiles(projectPath, files);
40
76
  break;
41
77
  }
42
- return files;
78
+ // For all project types, discover and add dynamic dependencies
79
+ const depDirs = detectDepDirs(projectPath);
80
+ await collectDynamicDependencies(projectPath, files, depDirs);
81
+ return dedup(files);
43
82
  };
44
83
  exports.collectSolidityFiles = collectSolidityFiles;
84
+ // ---------------------------------------------------------------------------
85
+ // Universal directory-based collector
86
+ // ---------------------------------------------------------------------------
45
87
  /**
46
- * Collect files from Foundry project
88
+ * Collect .sol files from given source and dependency directories.
47
89
  */
48
- const collectFoundryFiles = async (projectPath, files) => {
49
- // Collect source files
50
- const srcPattern = path_1.default.join(projectPath, 'src/**/*.sol');
51
- const srcFiles = await (0, glob_1.glob)(srcPattern, { nodir: true });
52
- for (const filePath of srcFiles) {
53
- const relativePath = path_1.default.relative(projectPath, filePath);
54
- const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
55
- files.push({
56
- name: path_1.default.basename(filePath),
57
- path: relativePath,
58
- content,
59
- dependency: false,
60
- });
90
+ async function collectFromDirs(projectPath, sourceDirs, depDirs, files) {
91
+ // Source files
92
+ for (const dir of sourceDirs) {
93
+ // When source dir is '.', collect recursively but exclude dependency
94
+ // directories (node_modules, lib, etc.) and build artifacts.
95
+ const pattern = dir === '.'
96
+ ? path_1.default.join(projectPath, '**/*.sol')
97
+ : path_1.default.join(projectPath, dir, '**/*.sol');
98
+ const ignorePatterns = dir === '.'
99
+ ? [
100
+ ...depDirs.map((d) => `**/${d}/**`),
101
+ '**/build/**',
102
+ '**/artifacts/**',
103
+ '**/cache/**',
104
+ '**/out/**',
105
+ '**/typechain/**',
106
+ '**/typechain-types/**',
107
+ ]
108
+ : [];
109
+ const matches = await (0, glob_1.glob)(pattern, { nodir: true, ignore: ignorePatterns });
110
+ for (const filePath of matches) {
111
+ if (isTestFile(filePath))
112
+ continue;
113
+ const relativePath = path_1.default.relative(projectPath, filePath);
114
+ const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
115
+ files.push({
116
+ name: path_1.default.basename(filePath),
117
+ path: relativePath,
118
+ content,
119
+ dependency: false,
120
+ });
121
+ }
61
122
  }
62
- // Collect library files
63
- const libPattern = path_1.default.join(projectPath, 'lib/**/*.sol');
64
- const libFiles = await (0, glob_1.glob)(libPattern, { nodir: true });
65
- for (const filePath of libFiles) {
66
- // Skip test files
67
- if (filePath.includes('.t.sol') || filePath.includes('test')) {
123
+ // Dependency files
124
+ for (const dir of depDirs) {
125
+ const fullDir = path_1.default.join(projectPath, dir);
126
+ if (!fs_extra_1.default.existsSync(fullDir))
68
127
  continue;
128
+ const pattern = path_1.default.join(fullDir, '**/*.sol');
129
+ const matches = await (0, glob_1.glob)(pattern, { nodir: true });
130
+ for (const filePath of matches) {
131
+ if (isDepTestFile(filePath))
132
+ continue;
133
+ const relativePath = path_1.default.relative(projectPath, filePath);
134
+ const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
135
+ files.push({
136
+ name: path_1.default.basename(filePath),
137
+ path: relativePath,
138
+ content,
139
+ dependency: true,
140
+ });
69
141
  }
70
- const relativePath = path_1.default.relative(projectPath, filePath);
71
- const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
72
- files.push({
73
- name: path_1.default.basename(filePath),
74
- path: relativePath,
75
- content,
76
- dependency: true,
77
- });
78
142
  }
79
- };
143
+ }
144
+ // ---------------------------------------------------------------------------
145
+ // Dynamic dependency discovery
146
+ // ---------------------------------------------------------------------------
80
147
  /**
81
- * Collect files from Hardhat project
148
+ * Scan import statements in all collected source files to discover
149
+ * dependency files that haven't been collected yet.
150
+ * This handles ANY package in node_modules/lib/etc., not just hardcoded ones.
82
151
  */
83
- const collectHardhatFiles = async (projectPath, files) => {
84
- // Collect contract files
85
- const contractPattern = path_1.default.join(projectPath, 'contracts/**/*.sol');
86
- const contractFiles = await (0, glob_1.glob)(contractPattern, { nodir: true });
87
- for (const filePath of contractFiles) {
88
- const relativePath = path_1.default.relative(projectPath, filePath);
89
- const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
90
- files.push({
91
- name: path_1.default.basename(filePath),
92
- path: relativePath,
93
- content,
94
- dependency: false,
95
- });
152
+ async function collectDynamicDependencies(projectPath, files, depDirs) {
153
+ if (depDirs.length === 0)
154
+ return;
155
+ const collectedPaths = new Set(files.map((f) => f.path));
156
+ const importedPackages = new Set();
157
+ // Step 1: Extract all non-relative imports from source files
158
+ for (const file of files) {
159
+ if (file.dependency)
160
+ continue;
161
+ extractPackageNames(file.content, importedPackages);
96
162
  }
97
- // Collect node_modules dependencies (common libraries)
98
- const nodeModulesPath = path_1.default.join(projectPath, 'node_modules');
99
- if (fs_extra_1.default.existsSync(nodeModulesPath)) {
100
- const libraries = [
101
- '@openzeppelin/contracts',
102
- '@chainlink/contracts',
103
- '@uniswap/v3-core',
104
- '@uniswap/v2-core',
105
- ];
106
- for (const lib of libraries) {
107
- const libPath = path_1.default.join(nodeModulesPath, lib);
108
- if (fs_extra_1.default.existsSync(libPath)) {
109
- const libPattern = path_1.default.join(libPath, '**/*.sol');
110
- const libFiles = await (0, glob_1.glob)(libPattern, { nodir: true });
111
- for (const filePath of libFiles) {
112
- // Skip test and mock files
113
- if (filePath.includes('test') || filePath.includes('mock')) {
114
- continue;
115
- }
163
+ // Step 2: For each discovered package, collect all .sol files from dep dirs
164
+ for (const pkg of importedPackages) {
165
+ for (const depDir of depDirs) {
166
+ const pkgPath = path_1.default.join(projectPath, depDir, pkg);
167
+ if (!fs_extra_1.default.existsSync(pkgPath))
168
+ continue;
169
+ const pattern = path_1.default.join(pkgPath, '**/*.sol');
170
+ try {
171
+ const matches = await (0, glob_1.glob)(pattern, { nodir: true });
172
+ for (const filePath of matches) {
116
173
  const relativePath = path_1.default.relative(projectPath, filePath);
174
+ if (collectedPaths.has(relativePath))
175
+ continue;
176
+ if (isDepTestFile(filePath))
177
+ continue;
117
178
  const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
118
179
  files.push({
119
180
  name: path_1.default.basename(filePath),
@@ -121,34 +182,175 @@ const collectHardhatFiles = async (projectPath, files) => {
121
182
  content,
122
183
  dependency: true,
123
184
  });
185
+ collectedPaths.add(relativePath);
124
186
  }
125
187
  }
188
+ catch {
189
+ // skip
190
+ }
126
191
  }
127
192
  }
128
- };
193
+ // Step 3: Recursively resolve transitive dependencies
194
+ // (dependency files may import other packages)
195
+ const newDeps = files.filter((f) => f.dependency && !collectedPaths.has('__visited__' + f.path));
196
+ if (newDeps.length > 0) {
197
+ await resolveTransitiveDeps(projectPath, files, depDirs, collectedPaths, 0);
198
+ }
199
+ }
129
200
  /**
130
- * Collect files from Truffle project
201
+ * Resolve transitive dependencies (dependencies that import other dependencies).
202
+ * Limited to a max depth to avoid infinite loops.
131
203
  */
132
- const collectTruffleFiles = async (projectPath, files) => {
133
- const contractPattern = path_1.default.join(projectPath, 'contracts/**/*.sol');
134
- const contractFiles = await (0, glob_1.glob)(contractPattern, { nodir: true });
135
- for (const filePath of contractFiles) {
136
- const relativePath = path_1.default.relative(projectPath, filePath);
137
- const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
138
- files.push({
139
- name: path_1.default.basename(filePath),
140
- path: relativePath,
141
- content,
142
- dependency: false,
143
- });
204
+ async function resolveTransitiveDeps(projectPath, files, depDirs, collectedPaths, depth) {
205
+ if (depth >= 5)
206
+ return; // max recursion depth
207
+ const newImports = new Set();
208
+ // Check recently added dependency files for their imports
209
+ for (const file of files) {
210
+ if (!file.dependency)
211
+ continue;
212
+ extractPackageNames(file.content, newImports);
213
+ }
214
+ let addedAny = false;
215
+ for (const pkg of newImports) {
216
+ for (const depDir of depDirs) {
217
+ const pkgPath = path_1.default.join(projectPath, depDir, pkg);
218
+ if (!fs_extra_1.default.existsSync(pkgPath))
219
+ continue;
220
+ const pattern = path_1.default.join(pkgPath, '**/*.sol');
221
+ try {
222
+ const matches = await (0, glob_1.glob)(pattern, { nodir: true });
223
+ for (const filePath of matches) {
224
+ const relativePath = path_1.default.relative(projectPath, filePath);
225
+ if (collectedPaths.has(relativePath))
226
+ continue;
227
+ if (isDepTestFile(filePath))
228
+ continue;
229
+ const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
230
+ files.push({
231
+ name: path_1.default.basename(filePath),
232
+ path: relativePath,
233
+ content,
234
+ dependency: true,
235
+ });
236
+ collectedPaths.add(relativePath);
237
+ addedAny = true;
238
+ }
239
+ }
240
+ catch {
241
+ // skip
242
+ }
243
+ }
244
+ }
245
+ if (addedAny) {
246
+ await resolveTransitiveDeps(projectPath, files, depDirs, collectedPaths, depth + 1);
247
+ }
248
+ }
249
+ // ---------------------------------------------------------------------------
250
+ // Project-type–specific collectors (legacy fallback)
251
+ // ---------------------------------------------------------------------------
252
+ const collectFoundryFiles = async (projectPath, files) => {
253
+ // Source files
254
+ const srcDir = path_1.default.join(projectPath, 'src');
255
+ if (fs_extra_1.default.existsSync(srcDir)) {
256
+ const srcPattern = path_1.default.join(srcDir, '**/*.sol');
257
+ const srcFiles = await (0, glob_1.glob)(srcPattern, { nodir: true });
258
+ for (const filePath of srcFiles) {
259
+ if (isTestFile(filePath))
260
+ continue;
261
+ const relativePath = path_1.default.relative(projectPath, filePath);
262
+ const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
263
+ files.push({ name: path_1.default.basename(filePath), path: relativePath, content, dependency: false });
264
+ }
265
+ }
266
+ // Lib dependency files
267
+ const libDir = path_1.default.join(projectPath, 'lib');
268
+ if (fs_extra_1.default.existsSync(libDir)) {
269
+ const libPattern = path_1.default.join(libDir, '**/*.sol');
270
+ const libFiles = await (0, glob_1.glob)(libPattern, { nodir: true });
271
+ for (const filePath of libFiles) {
272
+ if (isDepTestFile(filePath))
273
+ continue;
274
+ const relativePath = path_1.default.relative(projectPath, filePath);
275
+ const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
276
+ files.push({ name: path_1.default.basename(filePath), path: relativePath, content, dependency: true });
277
+ }
278
+ }
279
+ };
280
+ const collectHardhatFiles = async (projectPath, files) => {
281
+ // Source contracts
282
+ const contractsDir = path_1.default.join(projectPath, 'contracts');
283
+ if (fs_extra_1.default.existsSync(contractsDir)) {
284
+ const pattern = path_1.default.join(contractsDir, '**/*.sol');
285
+ const contractFiles = await (0, glob_1.glob)(pattern, { nodir: true });
286
+ for (const filePath of contractFiles) {
287
+ if (isTestFile(filePath))
288
+ continue;
289
+ const relativePath = path_1.default.relative(projectPath, filePath);
290
+ const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
291
+ files.push({ name: path_1.default.basename(filePath), path: relativePath, content, dependency: false });
292
+ }
144
293
  }
294
+ // Dynamic dependency collection happens in collectDynamicDependencies()
145
295
  };
146
296
  /**
147
- * Collect files from raw Solidity project
297
+ * Collect from contracts/ directory (Truffle, Brownie, Ape).
148
298
  */
299
+ const collectContractsDirFiles = async (projectPath, files) => {
300
+ const contractsDir = path_1.default.join(projectPath, 'contracts');
301
+ if (fs_extra_1.default.existsSync(contractsDir)) {
302
+ const pattern = path_1.default.join(contractsDir, '**/*.sol');
303
+ const contractFiles = await (0, glob_1.glob)(pattern, { nodir: true });
304
+ for (const filePath of contractFiles) {
305
+ if (isTestFile(filePath))
306
+ continue;
307
+ const relativePath = path_1.default.relative(projectPath, filePath);
308
+ const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
309
+ files.push({ name: path_1.default.basename(filePath), path: relativePath, content, dependency: false });
310
+ }
311
+ }
312
+ };
313
+ const collectDappToolsFiles = async (projectPath, files) => {
314
+ // Source files in src/
315
+ const srcDir = path_1.default.join(projectPath, 'src');
316
+ if (fs_extra_1.default.existsSync(srcDir)) {
317
+ const pattern = path_1.default.join(srcDir, '**/*.sol');
318
+ const srcFiles = await (0, glob_1.glob)(pattern, { nodir: true });
319
+ for (const filePath of srcFiles) {
320
+ if (isTestFile(filePath))
321
+ continue;
322
+ const relativePath = path_1.default.relative(projectPath, filePath);
323
+ const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
324
+ files.push({ name: path_1.default.basename(filePath), path: relativePath, content, dependency: false });
325
+ }
326
+ }
327
+ // Lib dependencies
328
+ const libDir = path_1.default.join(projectPath, 'lib');
329
+ if (fs_extra_1.default.existsSync(libDir)) {
330
+ const pattern = path_1.default.join(libDir, '**/*.sol');
331
+ const libFiles = await (0, glob_1.glob)(pattern, { nodir: true });
332
+ for (const filePath of libFiles) {
333
+ if (isDepTestFile(filePath))
334
+ continue;
335
+ const relativePath = path_1.default.relative(projectPath, filePath);
336
+ const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
337
+ files.push({ name: path_1.default.basename(filePath), path: relativePath, content, dependency: true });
338
+ }
339
+ }
340
+ };
149
341
  const collectRawFiles = async (projectPath, files) => {
150
342
  const pattern = path_1.default.join(projectPath, '**/*.sol');
151
- const solFiles = await (0, glob_1.glob)(pattern, { nodir: true });
343
+ const solFiles = await (0, glob_1.glob)(pattern, {
344
+ nodir: true,
345
+ ignore: [
346
+ '**/node_modules/**',
347
+ '**/lib/**',
348
+ '**/build/**',
349
+ '**/artifacts/**',
350
+ '**/cache/**',
351
+ '**/out/**',
352
+ ],
353
+ });
152
354
  for (const filePath of solFiles) {
153
355
  const relativePath = path_1.default.relative(projectPath, filePath);
154
356
  const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
@@ -160,12 +362,90 @@ const collectRawFiles = async (projectPath, files) => {
160
362
  });
161
363
  }
162
364
  };
365
+ // ---------------------------------------------------------------------------
366
+ // Helpers
367
+ // ---------------------------------------------------------------------------
368
+ // ---- Solidity import regex covering ALL import forms ----
369
+ // 1. import "path";
370
+ // 2. import "path" as Alias;
371
+ // 3. import * as Alias from "path";
372
+ // 4. import {Foo, Bar} from "path";
373
+ const SOLIDITY_IMPORT_REGEX = /import\s+(?:(?:\{[^}]*\}|\*\s+as\s+\w+)\s+from\s+)?["']([^"']+)["']/g;
374
+ /**
375
+ * Extract non-relative import package names from Solidity source content.
376
+ */
377
+ function extractPackageNames(content, packages) {
378
+ const regex = new RegExp(SOLIDITY_IMPORT_REGEX.source, 'g');
379
+ let match;
380
+ while ((match = regex.exec(content)) !== null) {
381
+ const importPath = match[1];
382
+ if (!importPath.startsWith('.') && !importPath.startsWith('/')) {
383
+ const parts = importPath.split('/');
384
+ let pkgName;
385
+ if (parts[0].startsWith('@') && parts.length >= 2) {
386
+ pkgName = parts[0] + '/' + parts[1];
387
+ }
388
+ else {
389
+ pkgName = parts[0];
390
+ }
391
+ packages.add(pkgName);
392
+ }
393
+ }
394
+ }
395
+ /**
396
+ * Check if a dependency file is a test/mock/example that should be skipped.
397
+ * More lenient than source-file test detection since we want to include
398
+ * the actual library code but skip their tests.
399
+ */
400
+ function isDepTestFile(filePath) {
401
+ const lower = filePath.toLowerCase();
402
+ return (lower.includes('/test/') ||
403
+ lower.includes('/tests/') ||
404
+ lower.includes('/mock/') ||
405
+ lower.includes('/mocks/') ||
406
+ lower.includes('/examples/') ||
407
+ lower.includes('/scripts/') ||
408
+ lower.endsWith('.t.sol') ||
409
+ lower.endsWith('.test.sol'));
410
+ }
411
+ /**
412
+ * Detect potential dependency directories for a project.
413
+ */
414
+ function detectDepDirs(projectPath) {
415
+ const candidates = ['node_modules', 'lib', 'dependencies', 'packages'];
416
+ return candidates.filter((d) => {
417
+ const full = path_1.default.join(projectPath, d);
418
+ try {
419
+ return fs_extra_1.default.existsSync(full) && fs_extra_1.default.statSync(full).isDirectory();
420
+ }
421
+ catch {
422
+ return false;
423
+ }
424
+ });
425
+ }
426
+ /**
427
+ * Deduplicate files by path.
428
+ */
429
+ function dedup(files) {
430
+ const seen = new Set();
431
+ const result = [];
432
+ for (const file of files) {
433
+ if (seen.has(file.path))
434
+ continue;
435
+ seen.add(file.path);
436
+ result.push(file);
437
+ }
438
+ return result;
439
+ }
440
+ // ---------------------------------------------------------------------------
441
+ // Statistics
442
+ // ---------------------------------------------------------------------------
163
443
  /**
164
- * Get statistics about collected files
444
+ * Get statistics about collected files.
165
445
  */
166
446
  const getFileStats = (files) => {
167
- const sourceFiles = files.filter(f => !f.dependency);
168
- const dependencyFiles = files.filter(f => f.dependency);
447
+ const sourceFiles = files.filter((f) => !f.dependency);
448
+ const dependencyFiles = files.filter((f) => f.dependency);
169
449
  const totalLines = files.reduce((sum, file) => {
170
450
  return sum + file.content.split('\n').length;
171
451
  }, 0);