diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3e93883137d..dcb7cdebaef 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,6 +5,14 @@ 3. Add your (or your organization's) name to the AUTHORS and CONTRIBUTORS files. 4. Send a pull request. +## Code quality + +To check code use: + +``` sh +$ npm run lint +``` + ## Testing ### Unit Tests diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 9f2214f8a9f..caff7905712 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -13,6 +13,8 @@ Burcu Dogan Johan Euphrosine +Maciej Chmielarski Patrick Costello Silvano Luciani Stephen Sawchuk + diff --git a/lib/storage/bucket.js b/lib/storage/bucket.js index 7e5c498fb72..8e467a89cd4 100644 --- a/lib/storage/bucket.js +++ b/lib/storage/bucket.js @@ -240,6 +240,28 @@ Bucket.prototype.file = function(name) { * bucket.getFiles({ * maxResults: 5 * }, function(err, files, nextQuery) {}); + * + * //- + * // Using delimiter and prefix parameter for results in + * // directory-like mode. In conjunction with the prefix filter, + * // the use of the delimiter parameter allows the list method to + * // operate like a directory listing, despite the object namespace + * // being flat. For example, if delimiter were set to "/", + * // then listing objects from a bucket that contains the objects + * // "a/b", "a/c", "d", "e", "e/f" would return objects "d" and "e", + * // and prefixes "a/" and "e/" + * //- + * var query = { delimiter: "/" }; + * bucket.getFiles(query, function(err, files, nextQuery, prefixes) { + * // files = ["d", "e"] + * // prefixes = ["a/", "e/"] + * + * query.prefix = "a/"; + * bucket.getFiles(query, function(err, files, nextQuery, prefixes) { + * // files = ["b", "c"] + * // prefixes = null; + * }); + * }); */ Bucket.prototype.getFiles = function(query, callback) { var that = this; @@ -252,16 +274,18 @@ Bucket.prototype.getFiles = function(query, callback) { callback(err); return; } + var files = (resp.items || []).map(function(item) { var file = that.file(item.name); file.metadata = item; return file; }); + var prefixes = resp.prefixes || null; var nextQuery = null; if (resp.nextPageToken) { nextQuery = extend({}, query, { pageToken: resp.nextPageToken }); } - callback(null, files, nextQuery); + callback(null, files, nextQuery, prefixes); }); }; diff --git a/regression/storage.js b/regression/storage.js index 322024096c3..10836470610 100644 --- a/regression/storage.js +++ b/regression/storage.js @@ -530,6 +530,65 @@ describe('storage', function() { }); }); + describe('prefixes', function() { + var filenames = ['a/b', 'a/c', 'd', 'e', 'e/f', 'e/f/g']; + + before(function(done) { + async.parallel( + filenames.map(function(filename) { + return function(callback) { + var file = bucket.file(filename); + var contents = 'test'; + + var writeStream = file.createWriteStream({ resumable: false }); + writeStream.on('error', function() { + callback(); + }); + writeStream.on('complete', function() { + callback(); + }); + writeStream.write(contents); + writeStream.end(); + }; + }), done); + }); + + after(function(done) { + async.parallel( + filenames.map(function(filename) { + return function(callback) { + bucket.file(filename).delete(callback); + }; + }), done); + }); + + it('should use delimiter', function(done) { + var query = { delimiter: '/' }; + bucket.getFiles(query, function(err, files, nextQuery, prefixes) { + assert.ifError(err); + assert.equal(files.length, 2); + ['a/', 'e/'].forEach(function(val) { + assert.equal((prefixes.indexOf(val) > -1), true); + }); + assert.equal(nextQuery, null); + done(); + }); + }); + + it('should use prefix & delimiter', function(done) { + var query = { delimiter: '/', prefix: 'e/' }; + bucket.getFiles(query, function(err, files, nextQuery, prefixes) { + assert.ifError(err); + assert.equal(files.length, 1); + ['e/f/'].forEach(function(val) { + assert.equal((prefixes.indexOf(val) > -1), true); + }); + assert.equal(nextQuery, null); + done(); + }); + }); + }); + describe('sign urls', function() { var localFile = fs.readFileSync(files.logo.path); var file; diff --git a/test/storage/bucket.js b/test/storage/bucket.js index 5718e196826..fc950ac1f58 100644 --- a/test/storage/bucket.js +++ b/test/storage/bucket.js @@ -200,6 +200,30 @@ describe('Bucket', function() { done(); }); }); + + it('should return prefixes', function(done) { + var fakePrefixes = ['fake-prefix-1']; + bucket.makeReq_ = function(method, path, query, body, callback) { + callback(null, { prefixes: fakePrefixes }); + }; + bucket.getFiles(function(err, files, nextQuery, prefixes) { + assert.ifError(err); + assert(prefixes, fakePrefixes); + done(); + }); + }); + + it('should return null if no prefixes', function(done) { + bucket.makeReq_ = function(method, path, query, body, callback) { + callback(null, {}); + }; + bucket.getFiles(function(err, files, nextQuery, prefixes) { + console.log(prefixes); + assert.ifError(err); + assert.strictEqual(nextQuery, null); + done(); + }); + }); }); describe('getMetadata', function() {