import type { ScanConfigSchema } from '@ones-open/cli-utils' import fse from 'fs-extra' import { resolve } from 'path' export const traverse = async ( dir: string, callback: (filePath: string) => void | Promise, options: ScanConfigSchema & { ext?: string[] }, ) => { const { exclude = [], ext = ['js', 'jsx', 'ts', 'tsx'] } = options || {} const subPaths = await fse.readdir(dir) const subPathPromises: Array> = [] for (const subPath of subPaths) { const fullSubPath = resolve(dir, subPath) const isExcluded = exclude.some((item) => { if (typeof item === 'string') { return fullSubPath === item } else if (item) { return item.test(fullSubPath) } }) if (!isExcluded) { const stat = await fse.stat(fullSubPath) if (stat.isDirectory()) { subPathPromises.push(traverse(fullSubPath, callback, options)) } else if (stat.isFile() && ext.some((item) => fullSubPath.endsWith(item))) { subPathPromises.push(Promise.resolve(callback(fullSubPath))) } } } await Promise.all(subPathPromises) }