lib/components/source.js
function processStackItem(out, stack, rootPath, userFilter, readMode) {
  // Initialize a new file object.
  const initFile = (dirPath) => {
    return (fileName, callback) => {
      const filePath = path.join(dirPath, fileName);
      fs.stat(filePath, (error, stats) => {
        async.nextTick(callback, error, {
          path: path.relative(rootPath, filePath),
          stats,
        });
      });
    };
  };

  // Filter supported files.
  const filterSupported = () => {
    return (file, callback) => {
      const keep = file.stats.isFile() || file.stats.isDirectory();
      async.nextTick(callback, null, keep);
    };
  };

  // Filter output files.
  const filterOutput = () => {
    return (file, callback) => {
      const keep = file.stats.isFile() && userFilter(file);
      async.nextTick(callback, null, keep);
    };
  };

  // Read a file's data.
  const readData = () => {
    return (file, callback) => {
      const filePath = path.join(rootPath, file.path);
      read(filePath, readMode, (error, data) => {
        async.nextTick(callback, error, Object.assign({}, file, { data }));
      });
    };
  };

  return (callback) => {
    const dirPath = stack.shift();
    async.waterfall([
      cb => fs.readdir(dirPath, cb),
      (fileNames, cb) => async.map(fileNames, initFile(dirPath), cb),
      (files, cb) => async.filter(files, filterSupported(), cb),
      (files, cb) => populateStack(stack, rootPath, files, cb),
      (files, cb) => async.filter(files, filterOutput(), cb),
      (files, cb) => async.map(files, readData(), cb),
    ], (error, result) => {
      if (error) {
        async.nextTick(callback, error);
        return;
      }

      out.push(...result);
      async.nextTick(callback, null);
    });
  };
}
function processStackItem(out, stack, rootPath, userFilter, readMode) {
  // Initialize a new file object.
  const initFile = (dirPath) => {
    return (fileName, callback) => {
      const filePath = path.join(dirPath, fileName);
      fs.stat(filePath, (error, stats) => {
        async.nextTick(callback, error, {
          path: path.relative(rootPath, filePath),
          stats,
        });
      });
    };
  };

  // Filter supported files.
  const filterSupported = () => {
    return (file, callback) => {
      const keep = file.stats.isFile() || file.stats.isDirectory();
      async.nextTick(callback, null, keep);
    };
  };

  // Filter output files.
  const filterOutput = () => {
    return (file, callback) => {
      const keep = file.stats.isFile() && userFilter(file);
      async.nextTick(callback, null, keep);
    };
  };

  // Read a file's data.
  const readData = () => {
    return (file, callback) => {
      const filePath = path.join(rootPath, file.path);
      read(filePath, readMode, (error, data) => {
        async.nextTick(callback, error, Object.assign({}, file, { data }));
      });
    };
  };

  return (callback) => {
    const dirPath = stack.shift();
    async.waterfall([
      cb => fs.readdir(dirPath, cb),
      (fileNames, cb) => async.map(fileNames, initFile(dirPath), cb),
      (files, cb) => async.filter(files, filterSupported(), cb),
      (files, cb) => populateStack(stack, rootPath, files, cb),
      (files, cb) => async.filter(files, filterOutput(), cb),
      (files, cb) => async.map(files, readData(), cb),
    ], (error, result) => {
      if (error) {
        async.nextTick(callback, error);
        return;
      }

      out.push(...result);
      async.nextTick(callback, null);
    });
  };
}
function processStackItem ( out , stack , rootPath , userFilter , readMode ) { // Initialize a new file object. const initFile = ( dirPath ) => { return ( fileName , callback ) => { const filePath = path . join ( dirPath , fileName ) ; fs . stat ( filePath , ( error , stats ) => { async . nextTick ( callback , error , { path : path . relative ( rootPath , filePath ) , stats , } ) ; } ) ; } ; } ; // Filter supported files. const filterSupported = ( ) => { return ( file , callback ) => { const keep = file . stats . isFile ( ) || file . stats . isDirectory ( ) ; async . nextTick ( callback , null , keep ) ; } ; } ; // Filter output files. const filterOutput = ( ) => { return ( file , callback ) => { const keep = file . stats . isFile ( ) && userFilter ( file ) ; async . nextTick ( callback , null , keep ) ; } ; } ; // Read a file's data. const readData = ( ) => { return ( file , callback ) => { const filePath = path . join ( rootPath , file . path ) ; read ( filePath , readMode , ( error , data ) => { async . nextTick ( callback , error , Object . assign ( { } , file , { data } ) ) ; } ) ; } ; } ; return ( callback ) => { const dirPath = stack . shift ( ) ; async . waterfall ( [ cb => fs . readdir ( dirPath , cb ) , ( fileNames , cb ) => async . map ( fileNames , initFile ( dirPath ) , cb ) , ( files , cb ) => async . filter ( files , filterSupported ( ) , cb ) , ( files , cb ) => populateStack ( stack , rootPath , files , cb ) , ( files , cb ) => async . filter ( files , filterOutput ( ) , cb ) , ( files , cb ) => async . map ( files , readData ( ) , cb ) , ] , ( error , result ) => { if ( error ) { async . nextTick ( callback , error ) ; return ; } out . push ( ... result ) ; async . nextTick ( callback , null ) ; } ) ; } ; }
Process a single stack item.
Process a single stack item .