In this article, we’ll explore a practical use case involving JSON parsing and file operations in Node.js and TypeScript. Specifically, we’ll write a script to read a JSON configuration file, extract files and directories specified therein, and zip them into a single file.
Prerequisites
Before we get started, make sure you have Node.js and TypeScript installed on your system. Also, you will need the fs, path and archiver libraries. If you haven’t installed the archiver library yet, you can add it to your project using npm:
import*asfsfrom'fs';import*aspathfrom'path';import*asarchiverfrom'archiver';functiongetAllFiles(dirPath: string,arrayOfFiles: string[]=[]){constfiles=fs.readdirSync(dirPath)files.forEach(function(file){if(fs.statSync(dirPath+"/"+file).isDirectory()){arrayOfFiles=getAllFiles(dirPath+"/"+file,arrayOfFiles)}else{arrayOfFiles.push(path.join(dirPath,"/",file))}})returnarrayOfFiles}asyncfunctionmain() {constrawData=fs.readFileSync('input.json');constjsonData=JSON.parse(rawData.toString());if(!jsonData.configuration){console.log('No configuration object found in JSON');return;}constoutput=fs.createWriteStream('output.zip');constarchive=archiver('zip',{zlib:{level: 9}// Sets the compression level.
});output.on('close',()=>console.log(archive.pointer()+' total bytes'));archive.on('error',(err: any)=>{throwerr;});archive.pipe(output);for(constkeyinjsonData.configuration){for(constfileOrFolderofjsonData.configuration[key]){constisDirectory=fs.lstatSync(fileOrFolder).isDirectory();if(isDirectory){constfiles=getAllFiles(fileOrFolder);for(constfileoffiles){constfilePath=path.resolve(file);constfileDirName=path.dirname(file);archive.append(fs.createReadStream(filePath),{name: path.join(fileDirName,path.basename(file))});}}else{archive.append(fs.createReadStream(fileOrFolder),{name: fileOrFolder});}}}awaitarchive.finalize();}main().catch(console.error);
How it works
The script begins by reading a JSON file, parsing its contents, and checking for a configuration property.
1
2
3
4
5
6
7
constrawData=fs.readFileSync('input.json');constjsonData=JSON.parse(rawData.toString());if(!jsonData.configuration){console.log('No configuration object found in JSON');return;}
It then creates a write stream for the output zip file and sets up the archiver to zip files.
1
2
3
4
5
6
7
8
9
10
constoutput=fs.createWriteStream('output.zip');constarchive=archiver('zip',{zlib:{level: 9}// Sets the compression level.
});output.on('close',()=>console.log(archive.pointer()+' total bytes'));archive.on('error',(err: any)=>{throwerr;});archive.pipe(output);
Next, the script loops over the keys in the configuration object. For each file or folder path, it checks if the path points to a directory. If it does, it retrieves all files under the directory recursively using the getAllFiles function.
Once all files have been processed, it finalizes the archive, effectively creating the zip file.
1
awaitarchive.finalize();
And that’s it! With this script, you can easily generate zip files based on configurations in a JSON file.
Conclusion
Node.js and TypeScript offer a powerful platform for handling file operations and processing JSON. The ability to read directories, read and write files, and even create zip archives opens up a world of possibilities for data processing and manipulation. With these tools in your toolkit, you can automate many manual tasks and streamline your data workflows.
Remember to handle file and directory paths carefully and ensure that your script has appropriate permissions to read and write where necessary.