readdirp
Advanced tools
Comparing version 3.1.3 to 3.2.0
97
index.js
'use strict'; | ||
const fs = require('fs'); | ||
const {Readable} = require('stream'); | ||
const { Readable } = require('stream'); | ||
const sysPath = require('path'); | ||
const picomatch = require('picomatch'); | ||
const {promisify} = require('util'); | ||
const { promisify } = require('util'); | ||
const [readdir, stat, lstat] = [promisify(fs.readdir), promisify(fs.stat), promisify(fs.lstat)]; | ||
@@ -33,5 +33,7 @@ const supportsDirent = 'Dirent' in fs; | ||
const isNormalFlowError = (errorCode) => NORMAL_FLOW_ERRORS.has(errorCode); | ||
const isNormalFlowError = errorCode => NORMAL_FLOW_ERRORS.has(errorCode); | ||
const normalizeFilter = (filter) => { | ||
const checkBasename = f => f(entry.basename); | ||
const normalizeFilter = filter => { | ||
if (filter === undefined) return; | ||
@@ -42,3 +44,3 @@ if (typeof filter === 'function') return filter; | ||
const glob = picomatch(filter.trim()); | ||
return (entry) => glob(entry.basename); | ||
return entry => glob(entry.basename); | ||
} | ||
@@ -60,9 +62,9 @@ | ||
if (positive.length > 0) { | ||
return (entry) => positive.some(f => f(entry.basename)) && | ||
!negative.some(f => f(entry.basename)); | ||
return entry => | ||
positive.some(f => f(entry.basename)) && !negative.some(f => f(entry.basename)); | ||
} else { | ||
return (entry) => !negative.some(f => f(entry.basename)); | ||
return entry => !negative.some(f => f(entry.basename)); | ||
} | ||
} else { | ||
return (entry) => positive.some(f => f(entry.basename)); | ||
return entry => positive.some(f => f(entry.basename)); | ||
} | ||
@@ -83,4 +85,4 @@ } | ||
root: '.', | ||
fileFilter: (path) => true, | ||
directoryFilter: (path) => true, | ||
fileFilter: path => true, | ||
directoryFilter: path => true, | ||
type: 'files', | ||
@@ -90,9 +92,9 @@ lstat: false, | ||
alwaysStat: false | ||
} | ||
}; | ||
} | ||
constructor(options = {}) { | ||
super({objectMode: true, highWaterMark: 1}); | ||
super({ objectMode: true, highWaterMark: 1, autoDestroy: true }); | ||
const opts = Object.assign({}, ReaddirpStream.defaultOptions, options); | ||
const {root} = opts; | ||
const { root } = opts; | ||
@@ -102,9 +104,9 @@ this._fileFilter = normalizeFilter(opts.fileFilter); | ||
this._statMethod = opts.lstat ? lstat : stat; | ||
this._statOpts = {bigint: isWindows}; | ||
this._statOpts = { bigint: isWindows }; | ||
this._maxDepth = opts.depth; | ||
this._entryType = opts.type | ||
this._root = root; | ||
this._entryType = opts.type; | ||
this._root = sysPath.resolve(root); | ||
this._isDirent = !opts.alwaysStat && supportsDirent; | ||
this._statsProp = this._isDirent ? 'dirent' : 'stats'; | ||
this._readdir_options = {encoding: 'utf8', withFileTypes: this._isDirent}; | ||
this._readdir_options = { encoding: 'utf8', withFileTypes: this._isDirent }; | ||
@@ -118,6 +120,6 @@ // Launch stream with one parent, the root dir. | ||
async _read() { | ||
// If the stream was destroyed, we must not proceed. | ||
if (!this.readable) return; | ||
do { | ||
// If the stream was destroyed, we must not proceed. | ||
if (this.destroyed) return; | ||
do { | ||
const parent = this.parents.pop(); | ||
@@ -131,3 +133,3 @@ if (!parent) { | ||
await this._exploreDirectory(parent); | ||
} while(!this.isPaused() && !this._isQueueEmpty()); | ||
} while (!this.isPaused() && !this._isQueueEmpty()); | ||
@@ -155,9 +157,9 @@ this._endStreamIfQueueIsEmpty(); | ||
// If the stream was destroyed, after readdir is completed | ||
if (!this.readable) return; | ||
if (this.destroyed) return; | ||
this.filesToRead += files.length; | ||
const entries = await Promise.all(files.map(dirent => this._formatEntry(dirent, parent))); | ||
const entries = await Promise.all(files.map(dirent => this._formatEntry(dirent, parent))); | ||
if (!this.readable) return; | ||
if (this.destroyed) return; | ||
@@ -180,3 +182,3 @@ for (let i = 0; i < entries.length; i++) { | ||
_isStatOptionsSupported() { | ||
return this._statMethod.length === STAT_OPTIONS_SUPPORT_LENGTH; | ||
return this._statMethod.length === STAT_OPTIONS_SUPPORT_LENGTH; | ||
} | ||
@@ -193,4 +195,4 @@ | ||
async _formatEntry(dirent, parent) { | ||
const relativePath = this._isDirent ? dirent.name : dirent; | ||
const fullPath = sysPath.resolve(sysPath.join(parent.path, relativePath)); | ||
const basename = this._isDirent ? dirent.name : dirent; | ||
const fullPath = sysPath.resolve(sysPath.join(parent.path, basename)); | ||
@@ -213,6 +215,5 @@ let stats; | ||
const path = sysPath.relative(this._root, fullPath); | ||
const basename = sysPath.basename(path); | ||
/** @type {EntryInfo} */ | ||
const entry = {path, fullPath, basename, [this._statsProp]: stats}; | ||
const entry = { path, fullPath, basename, [this._statsProp]: stats }; | ||
@@ -235,3 +236,3 @@ return entry; | ||
this.parents.push(new ExploringDir(parentPath, depth)); | ||
return true | ||
return true; | ||
} else { | ||
@@ -248,6 +249,5 @@ return false; | ||
const stats = entry[this._statsProp]; | ||
const isFileType = ( | ||
const isFileType = | ||
(this._entryType === EVERYTHING_TYPE && !stats.isDirectory()) || | ||
(stats.isFile() || stats.isSymbolicLink()) | ||
); | ||
(stats.isFile() || stats.isSymbolicLink()); | ||
return isFileType && this._fileFilter(entry); | ||
@@ -259,3 +259,5 @@ } | ||
// TODO: Understand why this happens. | ||
const fn = () => {this._push(entry)}; | ||
const fn = () => { | ||
this.push(entry); | ||
}; | ||
if (this._isDirent) setImmediate(fn); | ||
@@ -268,8 +270,2 @@ else fn(); | ||
if (FILE_TYPES.has(this._entryType)) { | ||
this._push(entry); | ||
} | ||
} | ||
_push(entry) { | ||
if (this.readable) { | ||
this.push(entry); | ||
@@ -280,19 +276,10 @@ } | ||
_handleError(error) { | ||
if (!this.readable) { | ||
return; | ||
if (!this.destroyed) { | ||
this.emit('warn', error); | ||
} | ||
this.emit('warn', error); | ||
} | ||
_handleFatalError(error) { | ||
if (!this.readable) { | ||
return; | ||
} | ||
this.emit('error', error); | ||
this.destroy(); | ||
this.destroy(error); | ||
} | ||
destroy() { | ||
this.emit('close'); | ||
} | ||
} | ||
@@ -336,5 +323,5 @@ | ||
readdirp(root, options) | ||
.on('data', (entry) => files.push(entry)) | ||
.on('data', entry => files.push(entry)) | ||
.on('end', () => resolve(files)) | ||
.on('error', (error) => reject(error)); | ||
.on('error', error => reject(error)); | ||
}); | ||
@@ -341,0 +328,0 @@ }; |
{ | ||
"name": "readdirp", | ||
"description": "Recursive version of fs.readdir with streaming api.", | ||
"version": "3.1.3", | ||
"version": "3.2.0", | ||
"homepage": "https://github.com/paulmillr/readdirp", | ||
@@ -6,0 +6,0 @@ "repository": { |
18844
306