fuf.js
function fuf(target, source, options = {}) {
  return new Promise((resolve, reject) => {

    if (!target) {
      return reject(new Error('the target path is required'))
    }
  
    if (!source) {
      return reject(new Error('the source path is required'))
    }

    if (options && MATCHES.indexOf(options.match) === -1) {
      return reject(new Error(`options.match should be one of the following values: ${MATCHES.join(', ')}.`))
    }

    options = { ...defaults, ...options }

    Promise.all([
      pglob(target, { nodir: true, ignore: source }),
      findSourceFiles(source),
    ]).then(([targetFiles, sourceFiles]) => {
      // By default all source files are considered unused.
      const unused = sourceFiles.map(file => ({ ...file }))

      // We loop through all files looking for unused files matches, when we
      // found a match we removed it from the unused bag.
      const results = targetFiles.map(file => {
        return fs.readFile(file)
          .then(data => {
            const matches = findMatches(data.toString(), unused.map(u => u[options.match]))
            matches.forEach(match => {
              // Remove match from unused.
              unused.splice(unused.findIndex(u => u[options.match] === match.needle), 1)
              // Remove match from source files.
              sourceFiles.splice(sourceFiles.findIndex(f => f[options.match] === match.needle), 1)
            })
          })
      })

      Promise
        .all(results)
        .then(() => {
          resolve({ unused })
        })
    }).catch(reject)
  })
}
function fuf(target, source, options = {}) {
  return new Promise((resolve, reject) => {

    if (!target) {
      return reject(new Error('the target path is required'))
    }
  
    if (!source) {
      return reject(new Error('the source path is required'))
    }

    if (options && MATCHES.indexOf(options.match) === -1) {
      return reject(new Error(`options.match should be one of the following values: ${MATCHES.join(', ')}.`))
    }

    options = { ...defaults, ...options }

    Promise.all([
      pglob(target, { nodir: true, ignore: source }),
      findSourceFiles(source),
    ]).then(([targetFiles, sourceFiles]) => {
      // By default all source files are considered unused.
      const unused = sourceFiles.map(file => ({ ...file }))

      // We loop through all files looking for unused files matches, when we
      // found a match we removed it from the unused bag.
      const results = targetFiles.map(file => {
        return fs.readFile(file)
          .then(data => {
            const matches = findMatches(data.toString(), unused.map(u => u[options.match]))
            matches.forEach(match => {
              // Remove match from unused.
              unused.splice(unused.findIndex(u => u[options.match] === match.needle), 1)
              // Remove match from source files.
              sourceFiles.splice(sourceFiles.findIndex(f => f[options.match] === match.needle), 1)
            })
          })
      })

      Promise
        .all(results)
        .then(() => {
          resolve({ unused })
        })
    }).catch(reject)
  })
}
function fuf ( target , source , options = { } ) { return new Promise ( ( resolve , reject ) => { if ( ! target ) { return reject ( new Error ( 'the target path is required' ) ) } if ( ! source ) { return reject ( new Error ( 'the source path is required' ) ) } if ( options && MATCHES . indexOf ( options . match ) === - 1 ) { return reject ( new Error ( ` ${ MATCHES . join ( ', ' ) } ` ) ) } options = { ... defaults , ... options } Promise . all ( [ pglob ( target , { nodir : true , ignore : source } ) , findSourceFiles ( source ) , ] ) . then ( ( [ targetFiles , sourceFiles ] ) => { // By default all source files are considered unused. const unused = sourceFiles . map ( file => ( { ... file } ) ) // We loop through all files looking for unused files matches, when we // found a match we removed it from the unused bag. const results = targetFiles . map ( file => { return fs . readFile ( file ) . then ( data => { const matches = findMatches ( data . toString ( ) , unused . map ( u => u [ options . match ] ) ) matches . forEach ( match => { // Remove match from unused. unused . splice ( unused . findIndex ( u => u [ options . match ] === match . needle ) , 1 ) // Remove match from source files. sourceFiles . splice ( sourceFiles . findIndex ( f => f [ options . match ] === match . needle ) , 1 ) } ) } ) } ) Promise . all ( results ) . then ( ( ) => { resolve ( { unused } ) } ) } ) . catch ( reject ) } ) }
Find unused files.

@param {string} target The target directory containing files that will be used to look for usage.
@param {string} source The source directory containing files that will be determined if unused.
@param {FufOptions} options The options.

@return {Promise<FindSourceFilesResult[]> Error>}
Find unused files .