UNPKG

als-file-list

Version:

Generates filtered and sorted list of all file paths in a directory and its subdirectories.

89 lines (76 loc) 3.2 kB
const fs = require('fs'); function checkWhere(where, relativePath, stats, isDir, errors) { if (where) { try { if (where(relativePath, stats, isDir) === false) return false } catch (error) { addError(error, { relativePath, where: where.name }, errors) } } return true } function sortAndSelect(sort,result,skip,limit,select) { if(sort) { sortBy(sort,result) result = sliceArray(result,skip,limit) } if(result.length === 0) return result else return result.map(({relativePath,stats}) => checkSelect(relativePath,stats,select)) } function addError(error, details, errors) { error.details = details errors.push(error) } function notExistsSync() { if(fs.existsSync(dirPath)) return false addError(new Error(`${dirPath} not exists`),{dirPath},errors) return true } async function notExists(dirPath,errors) { try {await fs.promises.access(dirPath)} catch (error) { addError(new Error(`${dirPath} not exists`),{dirPath},errors) return true } return false } function checkSelect(relativePath,stats,select) { if(select === undefined) return relativePath if(select.length === 0) return relativePath const obj = { relativePath } select.forEach(key => { if (stats[key]) obj[key] = stats[key] }); return obj } function sortBy(property, array) { if (array.length === 0) return; array.sort((a, b) => { let valueA = (property === 'relativePath') ? a.relativePath : a.stats[property]; let valueB = (property === 'relativePath') ? b.relativePath : b.stats[property]; if (typeof valueA === 'string' && typeof valueB === 'string') valueA.localeCompare(valueB) else return valueA - valueB; }); } function validate(obj,type,required,allowed = []) { const [key,value] = Object.entries(obj)[0] if(required && (obj === undefined || obj === null)) throw new Error(`${key} is required`) if(!value) return if(type === 'number' && value < 0) throw new Error(`${key} has to be >= 0`) if(typeof value !== type) throw new Error(`${key} has to be type of ${type}`) if(allowed.length && !allowed.includes(value)) throw new Error(`The value can be only one of ${allowed.join()}`) } function validateOptions(dirPath,{ level = Infinity, where, select,limit=Infinity,skip=0,sort }) { validate({dirPath},'string',true) validate({level},'number',true) validate({limit},'number',true) validate({where},'function',false) validate({select},'string',false) validate({skip},'number',false) validate({sort},'string',false) return { level, where, select,limit,skip,sort} } function sliceArray(arr, skip = 0, limit = Infinity) { // Корректировка skip и limit в соответствии с длиной массива skip = Math.min(skip, arr.length); limit = Math.min(limit, arr.length - skip); return arr.slice(skip, skip + limit); // Возвращаем подмассив, начиная с skip и ограниченный limit } module.exports = {checkWhere,validateOptions,addError,notExists,sortAndSelect,notExistsSync}