nodejs read directory recursively, get files paths, then use paths to copy files to another directory

i use recursive-readdir to read a directory and its subdirectories like this:

const fse = require('fs-extra')
const recursive = require('recursive-readdir');

const inputFolder = './input';

const files =  await recursive(inputFolder)

then i filter the fetched files like this:

const fileteredFiles = files.filter((f) => f.includes('.gif'));

i console.log(filteredFiles) and this is the output:

[ 'input/background/black.gif',
  'input/background/grey.gif',]

now i want to copy black.gif and grey.gif to another directory, i tried this:

fse.copyFileSync(fileteredFiles, 'outputDir')

i get this error:

TypeError [ERR_INVALID_ARG_TYPE]: The "src" argument must be one of type string, Buffer, or URL. Received type object
    at Object.copyFileSync (fs.js:1719:3)

so please point me to the right way of grabbing filteredFiles and copying then to another directory.

any help would be much appreciated.

Answer

You are not using fs.copyFileSync correctly in two separate ways:

  1. The first argument to fs.copyFileSync() must be the source file path. You are trying to pass an array of file paths. That is not how it works. You must call fs.copyFileSync() for ONE individual file.

  2. The second argument to fs.copyFileSync() must be the destination file path, NOT a directory path.

Note that even if you try to use the fs-extra version named fs.copySync(), it says this:

if src is a file, dest cannot be a directory

So, to fix your use of fs.copyFileSync(), you must call it for each file you want to copy and you must build the appropriate target file path (and not pass just the destination directory).

Note: Added to node v16 is an experimental interface for copying multiple files from one location to another with either fs.cpSync(), fs.cp() or fs.promises.cp(). You could also try out that new interface as it will do a recursive copy for you and it offers a filter function so you could restrict it to just GIF files if you want.