Comparing version 0.0.6 to 0.0.9
@@ -6,3 +6,7 @@ // fileserver | ||
var mime = require('mime'); | ||
var path = require('path'); | ||
/* used to modify format out output of data; | ||
input of function is full filepath | ||
*/ | ||
var modifyOut = null; | ||
var fileserver = function(app) { | ||
@@ -14,4 +18,4 @@ if (!app) { | ||
app.use(bodyParser()); | ||
app.get("/*/", getDir); | ||
app.get("/*", getFile); | ||
app.get(/^\/.+\/$/, getDir); | ||
app.get(/^\/.+[^\/]$/, getFile); | ||
app.post("/*", postFileOrDir); | ||
@@ -24,2 +28,11 @@ app.put("/*", putFileOrDir); | ||
}); | ||
app.setModifyOut = function(func) { | ||
if (typeof func !== 'function') { | ||
throw new Error('should be function'); | ||
} | ||
modifyOut = func; | ||
}; | ||
app.unsetModifyOut = function(func) { | ||
modifyOut = null; | ||
}; | ||
return app; | ||
@@ -59,5 +72,11 @@ }; | ||
return; | ||
} else if (err.code === 'ENOENT') { | ||
return res.send(404); | ||
} else { | ||
return next(err); | ||
} | ||
return next(err); | ||
} | ||
for (var i = files.length - 1; i >= 0; i--) { | ||
files[i] = formatOutData(files[i]); | ||
} | ||
res.json(files); | ||
@@ -98,5 +117,7 @@ }; | ||
return; | ||
} else if (err.code === 'ENOENT') { | ||
return res.send(404); | ||
} else { | ||
return next(err); | ||
} | ||
next(err); | ||
return; | ||
} | ||
@@ -138,3 +159,3 @@ | ||
fileDriver.move(dirPath, req.body.newPath, options, | ||
sendCode(200, req, res, next, formatOutData(dirPath, isDir))); | ||
sendCode(200, req, res, next, formatOutData(dirPath))); | ||
return; | ||
@@ -146,3 +167,3 @@ } | ||
fileDriver.mkdir(dirPath, mode, | ||
sendCode(201, req, res, next, formatOutData(dirPath, isDir))); | ||
sendCode(201, req, res, next, formatOutData(dirPath))); | ||
} else { | ||
@@ -153,3 +174,3 @@ options.encoding = req.body.encoding || 'utf8'; | ||
fileDriver.writeFile(dirPath, data, options, | ||
sendCode(201, req, res, next, formatOutData(dirPath, isDir))); | ||
sendCode(201, req, res, next, formatOutData(dirPath))); | ||
} | ||
@@ -181,3 +202,3 @@ }; | ||
fileDriver.mkdir(dirPath, mode, | ||
sendCode(201, req, res, next, formatOutData(dirPath, true))); | ||
sendCode(201, req, res, next, formatOutData(dirPath))); | ||
} else { | ||
@@ -188,3 +209,3 @@ options.encoding = req.body.encoding || 'utf8'; | ||
fileDriver.writeFile(dirPath, data, options, | ||
sendCode(201, req, res, next, formatOutData(dirPath, false))); | ||
sendCode(201, req, res, next, formatOutData(dirPath))); | ||
} | ||
@@ -195,3 +216,5 @@ }; | ||
/path/to/dir/ | ||
deletes file | ||
deletes dir | ||
*optional* | ||
body.clobber = will remove non-empty dir (defaut: false) | ||
@@ -203,3 +226,14 @@ return: | ||
var dirPath = decodeURI(url.parse(req.url).pathname); | ||
fileDriver.rmdir(dirPath, sendCode(200, req, res, next, formatOutData())); | ||
var clobber = req.body.clobber || false; | ||
fileDriver.rmdir(dirPath, clobber, function (err) { | ||
if (err && err.code === 'ENOENT') { | ||
sendCode(404, req, res, next, formatOutData(dirPath))(null); | ||
} else if (err && err.code === 'EPERM') { | ||
sendCode(403, req, res, next, formatOutData(dirPath))(null); | ||
} else if (err && err.code === 'ENOTDIR') { | ||
sendCode(404, req, res, next, formatOutData(dirPath))(null); | ||
} else { | ||
sendCode(200, req, res, next, formatOutData(dirPath))(err); | ||
} | ||
}); | ||
}; | ||
@@ -216,16 +250,24 @@ | ||
var dirPath = decodeURI(url.parse(req.url).pathname); | ||
fileDriver.unlink(dirPath, sendCode(200, req, res, next, formatOutData())); | ||
fileDriver.unlink(dirPath, function (err) { | ||
if (err && err.code === 'ENOENT') { | ||
sendCode(404, req, res, next, formatOutData(dirPath))(null); | ||
} else if (err && err.code === 'EPERM') { | ||
sendCode(403, req, res, next, formatOutData(dirPath))(null); | ||
} else if (err && err.code === 'EISDIR') { | ||
sendCode(404, req, res, next, formatOutData(dirPath))(null); | ||
} else { | ||
sendCode(200, req, res, next, formatOutData(dirPath))(err); | ||
} | ||
}); | ||
}; | ||
// Helpers | ||
var formatOutData = function (filepath, isDir) { | ||
if (!filepath) return {}; | ||
var parts = filepath.split("/"); | ||
var filename = parts[parts.length - 1]; | ||
var path = filepath.substr(0, filepath.length - filename.length); | ||
return { | ||
"name" : filename, | ||
"path" : path, | ||
"dir" : isDir | ||
}; | ||
// formats out data based on client spec. | ||
var formatOutData = function (filepath) { | ||
var out = filepath; | ||
if (modifyOut) { | ||
out = modifyOut(out); | ||
} | ||
return out; | ||
}; | ||
@@ -238,6 +280,6 @@ | ||
} | ||
res.json(code, out); | ||
res.send(code, out); | ||
}; | ||
}; | ||
module.exports = fileserver; | ||
module.exports = fileserver; |
@@ -9,13 +9,4 @@ // fsDriver | ||
// returns array of files and dir. trailing slash determines type. | ||
var listAll = function(reqDir, onlyDir, cb) { | ||
/* returns array of files and dir in format : | ||
[ | ||
{ | ||
name: base, | ||
path: path.dirname(file), | ||
dir: false | ||
}, | ||
... | ||
] | ||
*/ | ||
var finder = findit(reqDir); | ||
@@ -25,7 +16,3 @@ var files = []; | ||
finder.on('directory', function (dir, stat, stop) { | ||
files.push({ | ||
name: path.basename(dir), | ||
path: path.dirname(dir), | ||
dir: true | ||
}); | ||
files.push(path.join(dir, '/')); | ||
}); | ||
@@ -35,7 +22,3 @@ | ||
finder.on('file', function (file, stat) { | ||
files.push({ | ||
name: path.basename(file), | ||
path: path.dirname(file), | ||
dir: false | ||
}); | ||
files.push(file); | ||
}); | ||
@@ -49,13 +32,4 @@ } | ||
// returns array of files and dir. trailing slash determines type. | ||
var list = function(reqDir, cb) { | ||
/* returns array of files and dir in format : | ||
[ | ||
{ | ||
name: base, // file or dir name | ||
path: path.dirname(file), // path to file | ||
dir: false | ||
}, | ||
... | ||
] | ||
*/ | ||
var filesList = []; | ||
@@ -75,7 +49,4 @@ var cnt = 0; | ||
} | ||
filesList.push({ | ||
name: files[index], | ||
path: reqDir, | ||
isDir: stat.isDirectory() | ||
}); | ||
var file = path.join(reqDir, files[index], stat.isDirectory() ? '/' : ''); | ||
filesList.push(file); | ||
cnt++; | ||
@@ -96,3 +67,3 @@ if (cnt === files.length) { | ||
*/ | ||
var readFile = function(filePath, encoding, cb) { | ||
var readFile = function(filePath, encoding, cb) { | ||
fs.readFile(filePath, encoding, cb); | ||
@@ -111,4 +82,7 @@ }; | ||
*/ | ||
var rmdir = function(dirPath, cb) { | ||
fs.rmdir(dirPath, cb); | ||
var rmdir = function(dirPath, clobber, cb) { | ||
if (clobber) { | ||
return rm(dirPath, cb); | ||
} | ||
return fs.rmdir(dirPath, cb); | ||
}; | ||
@@ -145,6 +119,6 @@ | ||
fs.stat(oldPath, function(err, stats) { | ||
if(err) { | ||
if (err) { | ||
return cb(err); | ||
} | ||
if (stats.isDirectory() && | ||
else if (stats.isDirectory() && | ||
~newPath.indexOf(oldPath) && | ||
@@ -155,10 +129,6 @@ newPath.split("/").length > oldPath.split("/").length) { | ||
return cb(err); | ||
} | ||
// also work around bug for clobber in dir | ||
if (opts.clobber) { | ||
} else if (opts.clobber) { | ||
// also work around bug for clobber in dir | ||
rm(newPath, function(err) { | ||
if (err) { | ||
return cb(err); | ||
} | ||
if (err) { return cb(err); } | ||
return mv(oldPath, newPath, opts, cb); | ||
@@ -165,0 +135,0 @@ }); |
{ | ||
"name": "rest-fs", | ||
"version": "0.0.6", | ||
"version": "0.0.9", | ||
"description": "restful fileserver", | ||
@@ -10,3 +10,3 @@ "main": "fileserver.js", | ||
"scripts": { | ||
"test": "lab -v -c -t 97", | ||
"test": "lab -v -c -t 96", | ||
"start": "node index.js" | ||
@@ -40,4 +40,5 @@ }, | ||
"walkdir": "0.0.7", | ||
"lab": "^3.1.1" | ||
"lab": "^3.1.1", | ||
"lodash": "^2.4.1" | ||
} | ||
} |
@@ -12,2 +12,4 @@ var Lab = require('lab'); | ||
var walk = require('walkdir'); | ||
var _ = require('lodash'); | ||
// attach the .compare method to Array's prototype to call it on any array | ||
@@ -181,5 +183,3 @@ Array.prototype.compare = function (array) { | ||
/* | ||
START TEST | ||
START TEST | ||
*/ | ||
@@ -210,3 +210,3 @@ | ||
Lab.experiment('basic delete tests', function () { | ||
Lab.experiment('delete tests', function () { | ||
Lab.beforeEach(function (done) { | ||
@@ -243,6 +243,6 @@ cleanBase(done); | ||
Lab.test('delete nonexiting dir', function (done) { | ||
var dirpath = baseDir+'/dir2/fake'; | ||
var dirpath = baseDir+'/dir2/fake/'; | ||
supertest(server) | ||
.del(dirpath) | ||
.expect(500) | ||
.expect(404) | ||
.end(function(err, res){ | ||
@@ -259,3 +259,3 @@ if (err) { | ||
} else { | ||
return done(new Error('dir did not get deleted')); | ||
return done(new Error('remove returned unexpected error')); | ||
} | ||
@@ -266,3 +266,3 @@ }); | ||
Lab.test('attempt to delete file', function (done) { | ||
Lab.test('attempt to delete file with trailing slash', function (done) { | ||
var filePath = baseDir+'/file'; | ||
@@ -273,2 +273,43 @@ createFile(filePath, "test", function (err) { | ||
.del(filePath+'/') | ||
.expect(404) | ||
.end(done); | ||
}); | ||
}); | ||
Lab.test('attempt to a folder with files and folders in it without clobber', function (done) { | ||
var dir1 = baseDir+'/dir1/'; | ||
var file1 = dir1+'/file1'; | ||
var file2 = dir1+'/file2'; | ||
var dir1_dir1 = dir1+'/dir1/'; | ||
var dir1_file1 = dir1_dir1+'/file1'; | ||
var dir1_file2 = dir1_dir1+'/file2'; | ||
var fileContent = "testing one two three and I am stopping now"; | ||
async.series([ | ||
function(cb) { | ||
cleanBase(cb); | ||
}, | ||
function(cb) { | ||
createDir(dir1, cb); | ||
}, | ||
function(cb) { | ||
createDir(dir1_dir1, cb); | ||
}, | ||
function(cb) { | ||
createFile(file1, fileContent, cb); | ||
}, | ||
function(cb) { | ||
createFile(file2, fileContent, cb); | ||
}, | ||
function(cb) { | ||
createFile(dir1_file1, fileContent, cb); | ||
}, | ||
function(cb) { | ||
createFile(dir1_file2, fileContent, cb); | ||
} | ||
], function (err) { | ||
if (err) { | ||
return done(err); | ||
} | ||
supertest(server) | ||
.del(dir1) | ||
.expect(500) | ||
@@ -278,7 +319,13 @@ .end(function(err, res){ | ||
return done(err); | ||
} else if (res.body.code === 'ENOTDIR') { | ||
return done(); | ||
} else { | ||
return done(new Error('file was deleted')); | ||
} | ||
if (res.body.code !== 'ENOTEMPTY') { | ||
return done(new Error('should have returned ENOTEMPTY')); | ||
} | ||
fs.stat(dir1, function (err, stats) { | ||
if (err) { | ||
return done(new Error('dir got deleted')); | ||
} else { | ||
return done(); | ||
} | ||
}); | ||
}); | ||
@@ -288,2 +335,56 @@ }); | ||
Lab.test('attempt to a folder with files and folders in it with clobber', function (done) { | ||
var dir1 = baseDir+'/dir1/'; | ||
var file1 = dir1+'/file1'; | ||
var file2 = dir1+'/file2'; | ||
var dir1_dir1 = dir1+'/dir1/'; | ||
var dir1_file1 = dir1_dir1+'/file1'; | ||
var dir1_file2 = dir1_dir1+'/file2'; | ||
var fileContent = "testing one two three and I am stopping now"; | ||
async.series([ | ||
function(cb) { | ||
cleanBase(cb); | ||
}, | ||
function(cb) { | ||
createDir(dir1, cb); | ||
}, | ||
function(cb) { | ||
createDir(dir1_dir1, cb); | ||
}, | ||
function(cb) { | ||
createFile(file1, fileContent, cb); | ||
}, | ||
function(cb) { | ||
createFile(file2, fileContent, cb); | ||
}, | ||
function(cb) { | ||
createFile(dir1_file1, fileContent, cb); | ||
}, | ||
function(cb) { | ||
createFile(dir1_file2, fileContent, cb); | ||
} | ||
], function (err) { | ||
if (err) { | ||
return done(err); | ||
} | ||
supertest(server) | ||
.del(dir1) | ||
.send({clobber: true}) | ||
.expect(200) | ||
.end(function(err, res){ | ||
if (err) { | ||
return done(err); | ||
} | ||
fs.stat(dir1, function (err, stats) { | ||
if (err) { | ||
if (err.code === 'ENOENT') { | ||
return done(); | ||
} | ||
return done(err); | ||
} | ||
return done(new Error('dir did not get deleted')); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
@@ -293,8 +394,8 @@ | ||
Lab.experiment('read tests', function () { | ||
var testdirR = baseDir+'/dir2'; | ||
var testdir = testdirR+'/'; | ||
var emptydirR = baseDir+'/dir1'; | ||
var emptydir = emptydirR+'/'; | ||
var file1Path = baseDir+'/test_file1.txt'; | ||
var file2Path = testdir+'test_file2.txt'; | ||
var dir2R = baseDir+'/dir2'; | ||
var dir2 = dir2R+'/'; | ||
var dir1D = baseDir+'/dir1'; | ||
var dir1 = dir1D+'/'; | ||
var file1 = baseDir+'/file1.txt'; | ||
var dir1_file1 = dir2+'file2.txt'; | ||
var fileContent = "test"; | ||
@@ -308,12 +409,12 @@ | ||
function(cb) { | ||
createDir(testdir, {mode: 0}, cb); | ||
createDir(dir2, cb); | ||
}, | ||
function(cb) { | ||
createDir(emptydir, {mode: 0}, cb); | ||
createDir(dir1, cb); | ||
}, | ||
function(cb) { | ||
createFile(file1Path, fileContent, cb); | ||
createFile(file1, fileContent, cb); | ||
}, | ||
function(cb) { | ||
createFile(file2Path, fileContent, cb); | ||
createFile(dir1_file1, fileContent, cb); | ||
} | ||
@@ -325,3 +426,3 @@ ], done); | ||
supertest(server) | ||
.get(testdir) | ||
.get(dir2) | ||
.expect(200) | ||
@@ -331,3 +432,3 @@ .end(function(err, res){ | ||
return done(err); | ||
} else if (!~file2Path.indexOf(res.body[0].path+res.body[0].name)) { | ||
} if (res.body.length !== 1 || (_.difference(res.body, [ dir1_file1 ])).length) { | ||
return done(new Error('file list incorrect')); | ||
@@ -339,2 +440,21 @@ } | ||
Lab.test('test setModifyOut', function (done) { | ||
server.setModifyOut(function (file) { | ||
return 'anand'; | ||
}); | ||
supertest(server) | ||
.get(dir2) | ||
.expect(200) | ||
.end(function(err, res){ | ||
server.unsetModifyOut(); | ||
if (err) { | ||
return done(err); | ||
} if (res.body.length !== 1 || (_.difference(res.body, ['anand'])).length) { | ||
return done(new Error('file list incorrect')); | ||
} | ||
return done(); | ||
}); | ||
}); | ||
Lab.test('get filled dir ls', function (done) { | ||
@@ -347,3 +467,3 @@ supertest(server) | ||
return done(err); | ||
} else if (res.body.length != 3) { | ||
} else if (res.body.length !== 3 || (_.difference(res.body, [ dir1, dir2, file1 ])).length) { | ||
return done(new Error('file list incorrect')); | ||
@@ -363,3 +483,3 @@ } | ||
return done(err); | ||
} else if (res.body.length != 5) { | ||
} else if (res.body.length != 5 || (_.difference(res.body, [ baseDir+'/', dir1, dir2, file1, dir1_file1 ])).length) { | ||
return done(new Error('file list incorrect')); | ||
@@ -373,3 +493,3 @@ } | ||
supertest(server) | ||
.get(emptydir) | ||
.get(dir1) | ||
.expect(200) | ||
@@ -388,3 +508,3 @@ .end(function(err, res){ | ||
supertest(server) | ||
.get(testdirR) | ||
.get(dir2R) | ||
.expect(303) | ||
@@ -394,3 +514,3 @@ .end(function(err, res){ | ||
return done(err); | ||
} else if (!~res.text.indexOf('Redirecting to '+testdir)) { | ||
} else if (!~res.text.indexOf('Redirecting to '+dir2)) { | ||
return done(new Error('not redirecting')); | ||
@@ -404,3 +524,3 @@ } | ||
supertest(server) | ||
.get(emptydirR) | ||
.get(dir1D) | ||
.expect(303) | ||
@@ -410,3 +530,3 @@ .end(function(err, res){ | ||
return done(err); | ||
} else if (!~res.text.indexOf('Redirecting to '+emptydir)) { | ||
} else if (!~res.text.indexOf('Redirecting to '+dir1)) { | ||
return done(new Error('not redirecting')); | ||
@@ -420,16 +540,8 @@ } | ||
supertest(server) | ||
.get(emptydirR+"/fake") | ||
.expect(500) | ||
.end(function(err, res){ | ||
if (err) { | ||
return done(err); | ||
} else if (res.body.code !== 'ENOENT') { | ||
return done(new Error('file should not exist')); | ||
} | ||
return done(); | ||
}); | ||
.get(dir1D+"/fake/") | ||
.expect(404) | ||
.end(done); | ||
}); | ||
}); | ||
Lab.experiment('move tests', function () { | ||
@@ -554,3 +666,2 @@ var dir1 = baseDir+'/dir1/'; | ||
if (err.code === 'EINVAL') { | ||
console.log(err); | ||
return done(); | ||
@@ -568,3 +679,2 @@ } | ||
if (err.code === 'EINVAL') { | ||
console.log(err); | ||
return done(); | ||
@@ -712,2 +822,2 @@ } | ||
}); | ||
}); |
@@ -246,3 +246,3 @@ var Lab = require('lab'); | ||
} else if (200 !== res.statusCode) { | ||
return cb(res.body); | ||
return cb(err, res); | ||
} | ||
@@ -276,11 +276,23 @@ fs.stat(path, function (err, stats) { | ||
Lab.test('delete file with trailing slash', function (done) { | ||
var filepath = baseFolder+'/test_file.txt'; | ||
createFile(filepath, function(err) { | ||
if (err) { | ||
return done(err); | ||
} | ||
rmFile(filepath + '/', function (err, res) { | ||
if (err) { return done(err); } | ||
Lab.expect(res.statusCode).to.equal(404); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
Lab.test('delete file that does not exist', function (done) { | ||
rmFile(baseFolder+'/fake.txt', function(err){ | ||
if(err) { | ||
if(err.code === 'ENOENT') { | ||
return done(); | ||
} | ||
rmFile(baseFolder+'/fake.txt', function (err, res) { | ||
if (err) { | ||
return done(err); | ||
} | ||
return done(new Error('file should not exist')); | ||
Lab.expect(res.statusCode).to.equal(404); | ||
return done(); | ||
}); | ||
@@ -290,10 +302,8 @@ }); | ||
Lab.test('try to delete folder', function (done) { | ||
rmFile(baseFolder, function(err){ | ||
if(err) { | ||
if(err.code === 'EPERM' || err.code === 'EISDIR') { | ||
return done(); | ||
} | ||
rmFile(baseFolder, function (err, res) { | ||
if (err) { | ||
return done(err); | ||
} | ||
return done(new Error('folder should not be removed')); | ||
Lab.expect(res.statusCode).to.equal(403); | ||
return done(); | ||
}); | ||
@@ -400,8 +410,6 @@ }); | ||
.get(file1path+'.fake.txt') | ||
.expect(500) | ||
.expect(404) | ||
.end(function(err, res){ | ||
if (err) { | ||
return done(err); | ||
} else if (res.body.code !== 'ENOENT') { | ||
return done(new Error('file should not exist')); | ||
} | ||
@@ -499,2 +507,2 @@ return done(); | ||
}); | ||
}); | ||
}); |
var Lab = require('lab'); | ||
var restfs = require('../fileserver.js'); | ||
var express = require('express'); | ||
var server = express(); | ||
restfs(server); | ||
@@ -15,2 +18,9 @@ Lab.experiment('create tests', function () { | ||
}); | ||
Lab.test('test invalid setModifyOut', function (done) { | ||
try { | ||
server.setModifyOut("fake"); | ||
} catch (err) { | ||
done(); | ||
} | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
56874
1601
5