├── .gitignore ├── README.md ├── index.js ├── package.json └── tests.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # node-zip-folder 2 | 3 | > zips a folder and calls your callback when it's done 4 | > AKA: something that maybe already exists in npmjs.org, but that I couldn't find. 5 | 6 | ## Usage 7 | 8 | ```javascript 9 | var zipFolder = require('zip-folder'); 10 | 11 | zipFolder('/path/to/the/folder', '/path/to/archive.zip', function(err) { 12 | if(err) { 13 | console.log('oh no!', err); 14 | } else { 15 | console.log('EXCELLENT'); 16 | } 17 | }); 18 | ``` 19 | 20 | ## Tests 21 | 22 | Tests are in `tests.js` and built with nodeunit. Run `npm test` to run the tests. 23 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var archiver = require('archiver'); 3 | 4 | function zipFolder(srcFolder, zipFilePath, callback) { 5 | var output = fs.createWriteStream(zipFilePath); 6 | var zipArchive = archiver('zip'); 7 | 8 | output.on('close', function() { 9 | callback(); 10 | }); 11 | 12 | zipArchive.pipe(output); 13 | 14 | zipArchive.bulk([ 15 | { cwd: srcFolder, src: ['**/*'], expand: true } 16 | ]); 17 | 18 | zipArchive.finalize(function(err, bytes) { 19 | if(err) { 20 | callback(err); 21 | } 22 | }); 23 | } 24 | 25 | module.exports = zipFolder; 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zip-folder", 3 | "version": "1.0.0", 4 | "description": "zips a folder and calls your callback when it's done", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "nodeunit tests.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/sole/node-zip-folder" 12 | }, 13 | "keywords": [ 14 | "zip", 15 | "folder" 16 | ], 17 | "author": "sole", 18 | "license": "Apache 2", 19 | "bugs": { 20 | "url": "https://github.com/sole/node-zip-folder/issues" 21 | }, 22 | "homepage": "https://github.com/sole/node-zip-folder", 23 | "dependencies": { 24 | "archiver": "^0.11.0" 25 | }, 26 | "devDependencies": { 27 | "nodeunit": "^0.9.0", 28 | "temporary": "0.0.8", 29 | "unzip": "^0.1.11" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests.js: -------------------------------------------------------------------------------- 1 | var tmp = require('temporary'); 2 | var fs = require('fs'); 3 | var path = require('path'); 4 | var unzip = require('unzip'); 5 | var zipFolder = require('./index'); 6 | 7 | var txtFileName = 'file.txt'; 8 | var txtFileContents = 'this is a text file'; 9 | var zipFileName = 'archive.zip'; 10 | 11 | function emptyDirectory(dirName) { 12 | var dirFiles = fs.readdirSync(dirName); 13 | dirFiles.forEach(function(f) { 14 | var entryPath = path.join(dirName, f); 15 | var fileStats = fs.statSync(entryPath); 16 | if(fileStats.isFile()) { 17 | fs.unlink(entryPath); 18 | } else { 19 | emptyDirectory(entryPath); 20 | } 21 | }); 22 | } 23 | 24 | module.exports = { 25 | setUp: function(callback) { 26 | this.tmpSrcDir = new tmp.Dir(); 27 | 28 | var writePath = this.tmpSrcDir.path; 29 | 30 | fs.writeFileSync(path.join(writePath, txtFileName), txtFileContents); 31 | this.txtFileName = txtFileName; 32 | this.txtFileContents = txtFileContents; 33 | 34 | this.tmpZipFile = new tmp.File(); 35 | this.tmpZipExtractionDir = new tmp.Dir(); 36 | 37 | zipFolder(writePath, this.tmpZipFile.path, function() { 38 | 39 | callback(); 40 | 41 | }); 42 | 43 | }, 44 | 45 | tearDown: function(callback) { 46 | 47 | emptyDirectory(this.tmpSrcDir.path); 48 | this.tmpSrcDir.rmdir(); 49 | 50 | emptyDirectory(this.tmpZipExtractionDir.path); 51 | this.tmpZipExtractionDir.rmdir(); 52 | 53 | this.tmpZipFile.unlink(); 54 | 55 | callback(); 56 | }, 57 | 58 | // Ensure the zip has been created 59 | itCreatesTheZipFile: function(test) { 60 | test.ok(fs.existsSync(this.tmpZipFile.path), 'zip exists'); 61 | test.done(); 62 | }, 63 | 64 | // Assume the zip is valid if it can be unzipped 65 | // and the unzipped contents are not empty 66 | theZipFileIsValid: function(test) { 67 | 68 | test.expect(1); 69 | 70 | var dstPath = this.tmpZipExtractionDir.path; 71 | 72 | fs.createReadStream(this.tmpZipFile.path) 73 | .pipe(unzip.Extract({ path: dstPath })) 74 | .on('close', function() { 75 | var dirList = fs.readdirSync(dstPath); 76 | test.ok(dirList.length > 0, 'the zip contains files'); 77 | test.done(); 78 | }); 79 | 80 | }, 81 | 82 | theZipFileContainsTheRightFiles: function(test) { 83 | 84 | var dstPath = this.tmpZipExtractionDir.path; 85 | var txtFileName = this.txtFileName; 86 | var txtFilePath = path.join(dstPath, txtFileName); 87 | var txtFileContents = this.txtFileContents; 88 | 89 | fs.createReadStream(this.tmpZipFile.path) 90 | .pipe(unzip.Extract({ path: dstPath })) 91 | .on('close', function() { 92 | 93 | test.ok(fs.existsSync(txtFilePath), 'txt file exists'); 94 | test.equals(fs.readFileSync(txtFilePath), txtFileContents, 'contents are the same we put in'); 95 | test.done(); 96 | }); 97 | 98 | } 99 | }; 100 | --------------------------------------------------------------------------------