This commit is contained in:
117
src/utils/fileFinder.ts
Normal file
117
src/utils/fileFinder.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import * as glob from 'glob';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
export interface FileFinderOptions {
|
||||
includePatterns: string[];
|
||||
excludePatterns: string[];
|
||||
maxDepth?: number;
|
||||
}
|
||||
|
||||
export interface FoundFile {
|
||||
filePath: string;
|
||||
relativePath: string;
|
||||
extension: string;
|
||||
size: number;
|
||||
modifiedAt: Date;
|
||||
}
|
||||
|
||||
export class FileFinder {
|
||||
private options: FileFinderOptions;
|
||||
|
||||
constructor(options: Partial<FileFinderOptions> = {}) {
|
||||
this.options = {
|
||||
includePatterns: options.includePatterns || ['**/*.ts', '**/*.tsx'],
|
||||
excludePatterns: options.excludePatterns || ['node_modules', 'dist', '*.d.ts'],
|
||||
maxDepth: options.maxDepth || 10
|
||||
};
|
||||
}
|
||||
|
||||
find(baseDirectory: string): FoundFile[] {
|
||||
const files: FoundFile[] = [];
|
||||
|
||||
for (const pattern of this.options.includePatterns) {
|
||||
const matches = glob.sync(pattern, {
|
||||
cwd: baseDirectory,
|
||||
ignore: this.options.excludePatterns,
|
||||
nodir: true,
|
||||
maxDepth: this.options.maxDepth
|
||||
});
|
||||
|
||||
for (const match of matches) {
|
||||
const filePath = path.resolve(baseDirectory, match);
|
||||
const stats = fs.statSync(filePath);
|
||||
|
||||
if (stats.isFile()) {
|
||||
files.push({
|
||||
filePath,
|
||||
relativePath: match,
|
||||
extension: path.extname(filePath),
|
||||
size: stats.size,
|
||||
modifiedAt: stats.mtime
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return files.sort((a, b) => a.filePath.localeCompare(b.filePath));
|
||||
}
|
||||
|
||||
findSync(baseDirectory: string): FoundFile[] {
|
||||
return this.find(baseDirectory);
|
||||
}
|
||||
|
||||
async findAsync(baseDirectory: string): Promise<FoundFile[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const results: FoundFile[] = [];
|
||||
|
||||
const processPattern = (pattern: string): Promise<void> => {
|
||||
return new Promise((res, rej) => {
|
||||
glob(pattern, {
|
||||
cwd: baseDirectory,
|
||||
ignore: this.options.excludePatterns,
|
||||
nodir: true,
|
||||
maxDepth: this.options.maxDepth
|
||||
}, (err: Error | null, matches: string[]) => {
|
||||
if (err) {
|
||||
rej(err);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const match of matches) {
|
||||
const filePath = path.resolve(baseDirectory, match);
|
||||
try {
|
||||
const stats = fs.statSync(filePath);
|
||||
if (stats.isFile()) {
|
||||
results.push({
|
||||
filePath,
|
||||
relativePath: match,
|
||||
extension: path.extname(filePath),
|
||||
size: stats.size,
|
||||
modifiedAt: stats.mtime
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
res();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Promise.all(this.options.includePatterns.map(processPattern))
|
||||
.then(() => {
|
||||
resolve(results.sort((a, b) => a.filePath.localeCompare(b.filePath)));
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function findTypeScriptFiles(
|
||||
directory: string,
|
||||
options?: Partial<FileFinderOptions>
|
||||
): FoundFile[] {
|
||||
const finder = new FileFinder(options);
|
||||
return finder.find(directory);
|
||||
}
|
||||
Reference in New Issue
Block a user