UNPKG

@applicvision/js-toolbox

Version:

A collection of tools for modern JavaScript development

60 lines (52 loc) 1.87 kB
import fs from 'node:fs/promises' import path from 'node:path' import { pathToFileURL } from 'node:url' async function readGitignore() { try { const gitIgnore = `${await fs.readFile('.gitignore')}` return gitIgnore.split('\n').filter(file => file) } catch (e) { if (e.code !== 'ENOENT') { throw e } return [] } } /** * @template {boolean} [T = false] * @param {string} directory * @param {Set<string>} ignoreSet * @param {(filename: string) => boolean} fileMatcher * @param {T} useFileUrls * @returns {Promise<T extends true ? URL[] : string[]>} */ async function scanDirectory(directory, ignoreSet, fileMatcher, useFileUrls) { const entries = await fs.readdir(directory, { withFileTypes: true }) const filtered = entries .filter(entry => !entry.name.startsWith('.')) .filter(entry => !ignoreSet.has(entry.name)) const found = await Promise.all(filtered.map(async entry => { if (entry.isDirectory()) { const directoryPath = path.join(directory, entry.name) return ignoreSet.has(directoryPath) ? [] : scanDirectory(directoryPath, ignoreSet, fileMatcher, useFileUrls) } if (fileMatcher(entry.name)) { const filePath = path.join(directory, entry.name) return useFileUrls ? pathToFileURL(filePath) : filePath } return [] })) // @ts-ignore return found.flat() } /** * @template {boolean} [T=false] * @param {string} directory * @param {{ignoreSet?: Set<string>, fileMatcher?: (filename: string) => boolean, useFileUrls?: T}} options * @returns {Promise<T extends true ? URL[] : string[]>} */ export async function findFiles(directory = '.', { ignoreSet = new Set(), fileMatcher = () => true, useFileUrls } = {}) { const gitIgnoreEntries = await readGitignore() gitIgnoreEntries.forEach(ignoreEntry => ignoreSet.add(ignoreEntry)) return scanDirectory(directory, ignoreSet, fileMatcher, useFileUrls) }