commit
fed898b1c5
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"extends": "loopback",
|
||||||
|
"rules": {
|
||||||
|
"max-len": ["error", 90, 4, {
|
||||||
|
"ignoreComments": true,
|
||||||
|
"ignoreUrls": true,
|
||||||
|
"ignorePattern": "^\\s*var\\s.+=\\s*(require\\s*\\()|(/)"
|
||||||
|
}],
|
||||||
|
// NOTE we should eventually remove this override
|
||||||
|
// and fix all of those 100+ violations
|
||||||
|
"one-var": "off",
|
||||||
|
"no-unused-expressions": "off"
|
||||||
|
}
|
||||||
|
}
|
1
index.js
1
index.js
|
@ -2,6 +2,7 @@
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
'use strict';
|
||||||
|
|
||||||
var SG = require('strong-globalize');
|
var SG = require('strong-globalize');
|
||||||
SG.SetRootDir(__dirname);
|
SG.SetRootDir(__dirname);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
'use strict';
|
||||||
|
|
||||||
var pkgcloud = require('pkgcloud');
|
var pkgcloud = require('pkgcloud');
|
||||||
|
|
||||||
|
@ -13,9 +14,9 @@ function patchBaseClass(cls) {
|
||||||
var proto = cls.prototype;
|
var proto = cls.prototype;
|
||||||
var found = false;
|
var found = false;
|
||||||
// Find the prototype that owns the _setProperties method
|
// Find the prototype that owns the _setProperties method
|
||||||
while (proto
|
while (proto &&
|
||||||
&& proto.constructor !== pkgcloud.storage.Container
|
proto.constructor !== pkgcloud.storage.Container &&
|
||||||
&& proto.constructor !== pkgcloud.storage.File) {
|
proto.constructor !== pkgcloud.storage.File) {
|
||||||
if (proto.hasOwnProperty('_setProperties')) {
|
if (proto.hasOwnProperty('_setProperties')) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
@ -27,13 +28,13 @@ function patchBaseClass(cls) {
|
||||||
proto = cls.prototype;
|
proto = cls.prototype;
|
||||||
}
|
}
|
||||||
var m1 = proto._setProperties;
|
var m1 = proto._setProperties;
|
||||||
proto._setProperties = function (details) {
|
proto._setProperties = function(details) {
|
||||||
// Use an empty object to receive the calculated properties from details
|
// Use an empty object to receive the calculated properties from details
|
||||||
var receiver = {};
|
var receiver = {};
|
||||||
// Pass in some context as non-enumerable properties
|
// Pass in some context as non-enumerable properties
|
||||||
Object.defineProperties(receiver, {
|
Object.defineProperties(receiver, {
|
||||||
client: {value: this.client},
|
client: {value: this.client},
|
||||||
files: {value: this.files}
|
files: {value: this.files},
|
||||||
});
|
});
|
||||||
m1.call(receiver, details);
|
m1.call(receiver, details);
|
||||||
// Apply the calculated properties to this
|
// Apply the calculated properties to this
|
||||||
|
@ -43,20 +44,19 @@ function patchBaseClass(cls) {
|
||||||
// Keep references to raw and the calculated properties
|
// Keep references to raw and the calculated properties
|
||||||
this._rawMetadata = details;
|
this._rawMetadata = details;
|
||||||
this._metadata = receiver; // Use _metadata to avoid conflicts
|
this._metadata = receiver; // Use _metadata to avoid conflicts
|
||||||
}
|
};
|
||||||
|
|
||||||
proto.toJSON = function () {
|
proto.toJSON = function() {
|
||||||
return this._metadata;
|
return this._metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.getMetadata = function () {
|
proto.getMetadata = function() {
|
||||||
return this._metadata;
|
return this._metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.getRawMetadata = function () {
|
proto.getRawMetadata = function() {
|
||||||
return this._rawMetadata;
|
return this._rawMetadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
/*!
|
/*!
|
||||||
* Patch the pkgcloud Container/File classes so that the metadata are separately
|
* Patch the pkgcloud Container/File classes so that the metadata are separately
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
'use strict';
|
||||||
|
|
||||||
var base = require('pkgcloud').storage;
|
var base = require('pkgcloud').storage;
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
@ -14,7 +15,7 @@ function Container(client, details) {
|
||||||
|
|
||||||
util.inherits(Container, base.Container);
|
util.inherits(Container, base.Container);
|
||||||
|
|
||||||
Container.prototype._setProperties = function (details) {
|
Container.prototype._setProperties = function(details) {
|
||||||
for (var k in details) {
|
for (var k in details) {
|
||||||
if (typeof details[k] !== 'function') {
|
if (typeof details[k] !== 'function') {
|
||||||
this[k] = details[k];
|
this[k] = details[k];
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
'use strict';
|
||||||
|
|
||||||
var base = require('pkgcloud').storage;
|
var base = require('pkgcloud').storage;
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
@ -14,7 +15,7 @@ function File(client, details) {
|
||||||
|
|
||||||
util.inherits(File, base.File);
|
util.inherits(File, base.File);
|
||||||
|
|
||||||
File.prototype._setProperties = function (details) {
|
File.prototype._setProperties = function(details) {
|
||||||
for (var k in details) {
|
for (var k in details) {
|
||||||
if (typeof details[k] !== 'function') {
|
if (typeof details[k] !== 'function') {
|
||||||
this[k] = details[k];
|
this[k] = details[k];
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
|
// Turning on strict for this file breaks;
|
||||||
|
// disabling strict for this file
|
||||||
|
/* eslint-disable strict */
|
||||||
|
|
||||||
// Globalization
|
// Globalization
|
||||||
var g = require('strong-globalize')();
|
var g = require('strong-globalize')();
|
||||||
|
|
||||||
|
@ -21,7 +25,7 @@ module.exports.storage = module.exports; // To make it consistent with pkgcloud
|
||||||
module.exports.File = File;
|
module.exports.File = File;
|
||||||
module.exports.Container = Container;
|
module.exports.Container = Container;
|
||||||
module.exports.Client = FileSystemProvider;
|
module.exports.Client = FileSystemProvider;
|
||||||
module.exports.createClient = function (options) {
|
module.exports.createClient = function(options) {
|
||||||
return new FileSystemProvider(options);
|
return new FileSystemProvider(options);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,19 +83,19 @@ function populateMetadata(stat, props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystemProvider.prototype.getContainers = function (cb) {
|
FileSystemProvider.prototype.getContainers = function(cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
fs.readdir(self.root, function (err, files) {
|
fs.readdir(self.root, function(err, files) {
|
||||||
var containers = [];
|
var containers = [];
|
||||||
var tasks = [];
|
var tasks = [];
|
||||||
files.forEach(function (f) {
|
files.forEach(function(f) {
|
||||||
tasks.push(fs.stat.bind(fs, path.join(self.root, f)));
|
tasks.push(fs.stat.bind(fs, path.join(self.root, f)));
|
||||||
});
|
});
|
||||||
async.parallel(tasks, function (err, stats) {
|
async.parallel(tasks, function(err, stats) {
|
||||||
if (err) {
|
if (err) {
|
||||||
cb && cb(err);
|
cb && cb(err);
|
||||||
} else {
|
} else {
|
||||||
stats.forEach(function (stat, index) {
|
stats.forEach(function(stat, index) {
|
||||||
if (stat.isDirectory()) {
|
if (stat.isDirectory()) {
|
||||||
var name = files[index];
|
var name = files[index];
|
||||||
var props = {name: name};
|
var props = {name: name};
|
||||||
|
@ -106,15 +110,15 @@ FileSystemProvider.prototype.getContainers = function (cb) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.createContainer = function (options, cb) {
|
FileSystemProvider.prototype.createContainer = function(options, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var name = options.name;
|
var name = options.name;
|
||||||
var dir = path.join(this.root, name);
|
var dir = path.join(this.root, name);
|
||||||
validateName(name, cb) && fs.mkdir(dir, options, function (err) {
|
validateName(name, cb) && fs.mkdir(dir, options, function(err) {
|
||||||
if(err) {
|
if (err) {
|
||||||
return cb && cb(err);
|
return cb && cb(err);
|
||||||
}
|
}
|
||||||
fs.stat(dir, function (err, stat) {
|
fs.stat(dir, function(err, stat) {
|
||||||
var container = null;
|
var container = null;
|
||||||
if (!err) {
|
if (!err) {
|
||||||
var props = {name: name};
|
var props = {name: name};
|
||||||
|
@ -126,18 +130,18 @@ FileSystemProvider.prototype.createContainer = function (options, cb) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.destroyContainer = function (containerName, cb) {
|
FileSystemProvider.prototype.destroyContainer = function(containerName, cb) {
|
||||||
if (!validateName(containerName, cb)) return;
|
if (!validateName(containerName, cb)) return;
|
||||||
|
|
||||||
var dir = path.join(this.root, containerName);
|
var dir = path.join(this.root, containerName);
|
||||||
fs.readdir(dir, function (err, files) {
|
fs.readdir(dir, function(err, files) {
|
||||||
files = files || [];
|
files = files || [];
|
||||||
|
|
||||||
var tasks = [];
|
var tasks = [];
|
||||||
files.forEach(function (f) {
|
files.forEach(function(f) {
|
||||||
tasks.push(fs.unlink.bind(fs, path.join(dir, f)));
|
tasks.push(fs.unlink.bind(fs, path.join(dir, f)));
|
||||||
});
|
});
|
||||||
async.parallel(tasks, function (err) {
|
async.parallel(tasks, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
cb && cb(err);
|
cb && cb(err);
|
||||||
} else {
|
} else {
|
||||||
|
@ -147,11 +151,11 @@ FileSystemProvider.prototype.destroyContainer = function (containerName, cb) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.getContainer = function (containerName, cb) {
|
FileSystemProvider.prototype.getContainer = function(containerName, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!validateName(containerName, cb)) return;
|
if (!validateName(containerName, cb)) return;
|
||||||
var dir = path.join(this.root, containerName);
|
var dir = path.join(this.root, containerName);
|
||||||
fs.stat(dir, function (err, stat) {
|
fs.stat(dir, function(err, stat) {
|
||||||
var container = null;
|
var container = null;
|
||||||
if (!err) {
|
if (!err) {
|
||||||
var props = {name: containerName};
|
var props = {name: containerName};
|
||||||
|
@ -163,7 +167,7 @@ FileSystemProvider.prototype.getContainer = function (containerName, cb) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// File related functions
|
// File related functions
|
||||||
FileSystemProvider.prototype.upload = function (options, cb) {
|
FileSystemProvider.prototype.upload = function(options, cb) {
|
||||||
var container = options.container;
|
var container = options.container;
|
||||||
if (!validateName(container, cb)) return;
|
if (!validateName(container, cb)) return;
|
||||||
var file = options.remote;
|
var file = options.remote;
|
||||||
|
@ -172,7 +176,7 @@ FileSystemProvider.prototype.upload = function (options, cb) {
|
||||||
|
|
||||||
var fileOpts = {flags: options.flags || 'w+',
|
var fileOpts = {flags: options.flags || 'w+',
|
||||||
encoding: options.encoding || null,
|
encoding: options.encoding || null,
|
||||||
mode: options.mode || 0666
|
mode: options.mode || 0666,
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -180,7 +184,7 @@ FileSystemProvider.prototype.upload = function (options, cb) {
|
||||||
//fixes: https://github.com/strongloop/loopback-component-storage/issues/58
|
//fixes: https://github.com/strongloop/loopback-component-storage/issues/58
|
||||||
// & #23 & #67
|
// & #23 & #67
|
||||||
var stream = fs.createWriteStream(filePath, fileOpts);
|
var stream = fs.createWriteStream(filePath, fileOpts);
|
||||||
stream.on('finish', function(){
|
stream.on('finish', function() {
|
||||||
stream.emit('success');
|
stream.emit('success');
|
||||||
});
|
});
|
||||||
return stream;
|
return stream;
|
||||||
|
@ -189,7 +193,7 @@ FileSystemProvider.prototype.upload = function (options, cb) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.download = function (options, cb) {
|
FileSystemProvider.prototype.download = function(options, cb) {
|
||||||
var container = options.container;
|
var container = options.container;
|
||||||
if (!validateName(container, cb)) return;
|
if (!validateName(container, cb)) return;
|
||||||
var file = options.remote;
|
var file = options.remote;
|
||||||
|
@ -198,11 +202,11 @@ FileSystemProvider.prototype.download = function (options, cb) {
|
||||||
var filePath = path.join(this.root, container, file);
|
var filePath = path.join(this.root, container, file);
|
||||||
|
|
||||||
var fileOpts = {flags: 'r',
|
var fileOpts = {flags: 'r',
|
||||||
autoClose: true };
|
autoClose: true};
|
||||||
|
|
||||||
if (options.start) {
|
if (options.start) {
|
||||||
fileOpts.start = options.start
|
fileOpts.start = options.start;
|
||||||
fileOpts.end = options.end
|
fileOpts.end = options.end;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -212,7 +216,7 @@ FileSystemProvider.prototype.download = function (options, cb) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.getFiles = function (container, options, cb) {
|
FileSystemProvider.prototype.getFiles = function(container, options, cb) {
|
||||||
if (typeof options === 'function' && !(options instanceof RegExp)) {
|
if (typeof options === 'function' && !(options instanceof RegExp)) {
|
||||||
cb = options;
|
cb = options;
|
||||||
options = false;
|
options = false;
|
||||||
|
@ -220,18 +224,18 @@ FileSystemProvider.prototype.getFiles = function (container, options, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!validateName(container, cb)) return;
|
if (!validateName(container, cb)) return;
|
||||||
var dir = path.join(this.root, container);
|
var dir = path.join(this.root, container);
|
||||||
fs.readdir(dir, function (err, entries) {
|
fs.readdir(dir, function(err, entries) {
|
||||||
entries = entries || [];
|
entries = entries || [];
|
||||||
var files = [];
|
var files = [];
|
||||||
var tasks = [];
|
var tasks = [];
|
||||||
entries.forEach(function (f) {
|
entries.forEach(function(f) {
|
||||||
tasks.push(fs.stat.bind(fs, path.join(dir, f)));
|
tasks.push(fs.stat.bind(fs, path.join(dir, f)));
|
||||||
});
|
});
|
||||||
async.parallel(tasks, function (err, stats) {
|
async.parallel(tasks, function(err, stats) {
|
||||||
if (err) {
|
if (err) {
|
||||||
cb && cb(err);
|
cb && cb(err);
|
||||||
} else {
|
} else {
|
||||||
stats.forEach(function (stat, index) {
|
stats.forEach(function(stat, index) {
|
||||||
if (stat.isFile()) {
|
if (stat.isFile()) {
|
||||||
var props = {container: container, name: entries[index]};
|
var props = {container: container, name: entries[index]};
|
||||||
populateMetadata(stat, props);
|
populateMetadata(stat, props);
|
||||||
|
@ -245,12 +249,12 @@ FileSystemProvider.prototype.getFiles = function (container, options, cb) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.getFile = function (container, file, cb) {
|
FileSystemProvider.prototype.getFile = function(container, file, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!validateName(container, cb)) return;
|
if (!validateName(container, cb)) return;
|
||||||
if (!validateName(file, cb)) return;
|
if (!validateName(file, cb)) return;
|
||||||
var filePath = path.join(this.root, container, file);
|
var filePath = path.join(this.root, container, file);
|
||||||
fs.stat(filePath, function (err, stat) {
|
fs.stat(filePath, function(err, stat) {
|
||||||
var f = null;
|
var f = null;
|
||||||
if (!err) {
|
if (!err) {
|
||||||
var props = {container: container, name: file};
|
var props = {container: container, name: file};
|
||||||
|
@ -261,13 +265,13 @@ FileSystemProvider.prototype.getFile = function (container, file, cb) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.getUrl = function (options) {
|
FileSystemProvider.prototype.getUrl = function(options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var filePath = path.join(this.root, options.container, options.path);
|
var filePath = path.join(this.root, options.container, options.path);
|
||||||
return filePath;
|
return filePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.removeFile = function (container, file, cb) {
|
FileSystemProvider.prototype.removeFile = function(container, file, cb) {
|
||||||
if (!validateName(container, cb)) return;
|
if (!validateName(container, cb)) return;
|
||||||
if (!validateName(file, cb)) return;
|
if (!validateName(file, cb)) return;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
'use strict';
|
||||||
|
|
||||||
var StorageService = require('./storage-service');
|
var StorageService = require('./storage-service');
|
||||||
/**
|
/**
|
||||||
|
@ -11,14 +12,14 @@ var StorageService = require('./storage-service');
|
||||||
* @callback {Function} callback Callback function
|
* @callback {Function} callback Callback function
|
||||||
* @param {String|Object} err Error string or object
|
* @param {String|Object} err Error string or object
|
||||||
*/
|
*/
|
||||||
exports.initialize = function (dataSource, callback) {
|
exports.initialize = function(dataSource, callback) {
|
||||||
var settings = dataSource.settings || {};
|
var settings = dataSource.settings || {};
|
||||||
|
|
||||||
var connector = new StorageService(settings);
|
var connector = new StorageService(settings);
|
||||||
dataSource.connector = connector;
|
dataSource.connector = connector;
|
||||||
dataSource.connector.dataSource = dataSource;
|
dataSource.connector.dataSource = dataSource;
|
||||||
|
|
||||||
connector.DataAccessObject = function () {
|
connector.DataAccessObject = function() {
|
||||||
};
|
};
|
||||||
for (var m in StorageService.prototype) {
|
for (var m in StorageService.prototype) {
|
||||||
var method = StorageService.prototype[m];
|
var method = StorageService.prototype[m];
|
||||||
|
@ -30,6 +31,6 @@ exports.initialize = function (dataSource, callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connector.define = function (model, properties, settings) {
|
connector.define = function(model, properties, settings) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
'use strict';
|
||||||
|
|
||||||
// Globalization
|
// Globalization
|
||||||
var g = require('strong-globalize')();
|
var g = require('strong-globalize')();
|
||||||
|
@ -11,7 +12,7 @@ var StringDecoder = require('string_decoder').StringDecoder;
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
var defaultOptions = {
|
var defaultOptions = {
|
||||||
maxFileSize: 10 * 1024 * 1024 // 10 MB
|
maxFileSize: 10 * 1024 * 1024, // 10 MB
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,18 +36,22 @@ exports.upload = function(provider, req, res, options, cb) {
|
||||||
|
|
||||||
var form = new IncomingForm(options);
|
var form = new IncomingForm(options);
|
||||||
var container = options.container || req.params.container;
|
var container = options.container || req.params.container;
|
||||||
var fields = {}, files = {};
|
var fields = {};
|
||||||
|
var files = {};
|
||||||
form.handlePart = function(part) {
|
form.handlePart = function(part) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (part.filename === undefined) {
|
if (part.filename === undefined) {
|
||||||
var value = ''
|
var value = '';
|
||||||
, decoder = new StringDecoder(this.encoding);
|
var decoder = new StringDecoder(this.encoding);
|
||||||
|
|
||||||
part.on('data', function(buffer) {
|
part.on('data', function(buffer) {
|
||||||
self._fieldsSize += buffer.length;
|
self._fieldsSize += buffer.length;
|
||||||
if (self._fieldsSize > self.maxFieldsSize) {
|
if (self._fieldsSize > self.maxFieldsSize) {
|
||||||
self._error(new Error(g.f('{{maxFieldsSize}} exceeded, received %s bytes of field data', self._fieldsSize)));
|
self._error(new Error(
|
||||||
|
g.f('{{maxFieldsSize}} exceeded, received %s bytes of field data',
|
||||||
|
self._fieldsSize
|
||||||
|
)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
value += decoder.write(buffer);
|
value += decoder.write(buffer);
|
||||||
|
@ -70,7 +75,7 @@ exports.upload = function(provider, req, res, options, cb) {
|
||||||
var file = {
|
var file = {
|
||||||
container: container,
|
container: container,
|
||||||
name: part.filename,
|
name: part.filename,
|
||||||
type: part.mime
|
type: part.mime,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Options for this file
|
// Options for this file
|
||||||
|
@ -91,7 +96,11 @@ exports.upload = function(provider, req, res, options, cb) {
|
||||||
}
|
}
|
||||||
if (Array.isArray(allowedContentTypes) && allowedContentTypes.length !== 0) {
|
if (Array.isArray(allowedContentTypes) && allowedContentTypes.length !== 0) {
|
||||||
if (allowedContentTypes.indexOf(file.type) === -1) {
|
if (allowedContentTypes.indexOf(file.type) === -1) {
|
||||||
self._error(new Error(g.f('{{contentType}} "%s" is not allowed (Must be in [%s])', file.type, allowedContentTypes.join(', '))));
|
self._error(new Error(
|
||||||
|
g.f('{{contentType}} "%s" is not allowed (Must be in [%s])',
|
||||||
|
file.type,
|
||||||
|
allowedContentTypes.join(', ')
|
||||||
|
)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,7 +130,7 @@ exports.upload = function(provider, req, res, options, cb) {
|
||||||
var uploadParams = {
|
var uploadParams = {
|
||||||
container: container,
|
container: container,
|
||||||
remote: file.name,
|
remote: file.name,
|
||||||
contentType: file.type
|
contentType: file.type,
|
||||||
};
|
};
|
||||||
if (file.acl) {
|
if (file.acl) {
|
||||||
uploadParams.acl = file.acl;
|
uploadParams.acl = file.acl;
|
||||||
|
@ -161,13 +170,17 @@ exports.upload = function(provider, req, res, options, cb) {
|
||||||
// We are missing some way to tell the provider to cancel upload/multipart upload of the current file.
|
// We are missing some way to tell the provider to cancel upload/multipart upload of the current file.
|
||||||
// - s3-upload-stream doesn't provide a way to do this in it's public interface
|
// - s3-upload-stream doesn't provide a way to do this in it's public interface
|
||||||
// - We could call provider.delete file but it would not delete multipart data
|
// - We could call provider.delete file but it would not delete multipart data
|
||||||
self._error(new Error(g.f('{{maxFileSize}} exceeded, received %s bytes of field data (max is %s)', fileSize, maxFileSize)));
|
self._error(new Error(
|
||||||
|
g.f('{{maxFileSize}} exceeded, received %s bytes of field data (max is %s)',
|
||||||
|
fileSize,
|
||||||
|
maxFileSize
|
||||||
|
)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
part.on("end", function() {
|
part.on('end', function() {
|
||||||
writer.end();
|
writer.end();
|
||||||
});
|
});
|
||||||
part.pipe(writer, {end: false});
|
part.pipe(writer, {end: false});
|
||||||
|
@ -177,6 +190,7 @@ exports.upload = function(provider, req, res, options, cb) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line no-unused-expressions
|
||||||
cb && cb(err, {files: files, fields: fields});
|
cb && cb(err, {files: files, fields: fields});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -191,7 +205,6 @@ function handleError(res, err) {
|
||||||
res.status(500).send({error: err});
|
res.status(500).send({error: err});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle download from a container/file.
|
* Handle download from a container/file.
|
||||||
* @param {Object} provider The storage service provider
|
* @param {Object} provider The storage service provider
|
||||||
|
@ -203,42 +216,39 @@ function handleError(res, err) {
|
||||||
* @header storageService.download(provider, req, res, container, file, cb)
|
* @header storageService.download(provider, req, res, container, file, cb)
|
||||||
*/
|
*/
|
||||||
exports.download = function(provider, req, res, container, file, cb) {
|
exports.download = function(provider, req, res, container, file, cb) {
|
||||||
|
|
||||||
var fileName = path.basename(file);
|
var fileName = path.basename(file);
|
||||||
var params = {
|
var params = {
|
||||||
container: container || req && req.params.container,
|
container: container || req && req.params.container,
|
||||||
remote: file || req && req.params.file
|
remote: file || req && req.params.file,
|
||||||
};
|
};
|
||||||
|
|
||||||
var range = null;
|
var range = null;
|
||||||
|
|
||||||
if (req) {
|
if (req) {
|
||||||
|
|
||||||
if (req.headers) {
|
if (req.headers) {
|
||||||
range = req.headers.range || '';
|
range = req.headers.range || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (range) {
|
if (range) {
|
||||||
provider.getFile(params.container, params.remote, function(err, stats) {
|
provider.getFile(params.container, params.remote, function(err, stats) {
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
handleError(res, err);
|
handleError(res, err);
|
||||||
} else {
|
} else {
|
||||||
var total = stats.size;
|
var total = stats.size;
|
||||||
|
|
||||||
var parts = range.replace(/bytes=/, "").split("-")
|
var parts = range.replace(/bytes=/, '').split('-');
|
||||||
var partialstart = parts[0]
|
var partialstart = parts[0];
|
||||||
var partialend = parts[1]
|
var partialend = parts[1];
|
||||||
|
|
||||||
params.start = parseInt(partialstart, 10)
|
params.start = parseInt(partialstart, 10);
|
||||||
params.end = partialend ? parseInt(partialend, 10) : total - 1
|
params.end = partialend ? parseInt(partialend, 10) : total - 1;
|
||||||
|
|
||||||
var chunksize = (params.end - params.start) + 1
|
var chunksize = (params.end - params.start) + 1;
|
||||||
|
|
||||||
res.status(206)
|
res.status(206);
|
||||||
res.set("Content-Range", "bytes " + params.start + "-" + params.end + "/" + total);
|
res.set('Content-Range', 'bytes ' + params.start + '-' + params.end + '/' + total);
|
||||||
res.set("Accept-Ranges", "bytes");
|
res.set('Accept-Ranges', 'bytes');
|
||||||
res.set("Content-Length", chunksize);
|
res.set('Content-Length', chunksize);
|
||||||
|
|
||||||
var reader = provider.download(params);
|
var reader = provider.download(params);
|
||||||
|
|
||||||
|
@ -253,9 +263,7 @@ exports.download = function(provider, req, res, container, file, cb) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
var reader = provider.download(params);
|
var reader = provider.download(params);
|
||||||
|
|
||||||
res.type(fileName);
|
res.type(fileName);
|
||||||
|
@ -271,6 +279,3 @@ exports.download = function(provider, req, res, container, file, cb) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
'use strict';
|
||||||
|
|
||||||
var factory = require('./factory');
|
var factory = require('./factory');
|
||||||
var handler = require('./storage-handler');
|
var handler = require('./storage-handler');
|
||||||
|
@ -45,7 +46,6 @@ function StorageService(options) {
|
||||||
if (options.maxFileSize) {
|
if (options.maxFileSize) {
|
||||||
this.maxFileSize = options.maxFileSize;
|
this.maxFileSize = options.maxFileSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function map(obj) {
|
function map(obj) {
|
||||||
|
@ -58,12 +58,12 @@ function map(obj) {
|
||||||
* @param {Object|String} err Error string or object
|
* @param {Object|String} err Error string or object
|
||||||
* @param {Object[]} containers An array of container metadata objects
|
* @param {Object[]} containers An array of container metadata objects
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.getContainers = function (cb) {
|
StorageService.prototype.getContainers = function(cb) {
|
||||||
this.client.getContainers(function (err, containers) {
|
this.client.getContainers(function(err, containers) {
|
||||||
if (err) {
|
if (err) {
|
||||||
cb(err, containers);
|
cb(err, containers);
|
||||||
} else {
|
} else {
|
||||||
cb(err, containers.map(function (c) {
|
cb(err, containers.map(function(c) {
|
||||||
return map(c);
|
return map(c);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -80,14 +80,14 @@ StorageService.prototype.getContainers = function (cb) {
|
||||||
* @param {Object} container Container metadata object
|
* @param {Object} container Container metadata object
|
||||||
*/
|
*/
|
||||||
|
|
||||||
StorageService.prototype.createContainer = function (options, cb) {
|
StorageService.prototype.createContainer = function(options, cb) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
if ('object' === typeof options && !(options instanceof storage.Container)) {
|
if ('object' === typeof options && !(options instanceof storage.Container)) {
|
||||||
options.Name = options.name; // Amazon expects Name
|
options.Name = options.name; // Amazon expects Name
|
||||||
var Container = factory.getProvider(this.provider).storage.Container;
|
var Container = factory.getProvider(this.provider).storage.Container;
|
||||||
options = new Container(this.client, options);
|
options = new Container(this.client, options);
|
||||||
}
|
}
|
||||||
return this.client.createContainer(options, function (err, container) {
|
return this.client.createContainer(options, function(err, container) {
|
||||||
return cb(err, map(container));
|
return cb(err, map(container));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -98,7 +98,7 @@ StorageService.prototype.createContainer = function (options, cb) {
|
||||||
* @callback {Function} callback Callback function.
|
* @callback {Function} callback Callback function.
|
||||||
* @param {Object|String} err Error string or object
|
* @param {Object|String} err Error string or object
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.destroyContainer = function (container, cb) {
|
StorageService.prototype.destroyContainer = function(container, cb) {
|
||||||
return this.client.destroyContainer(container, cb);
|
return this.client.destroyContainer(container, cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,8 +109,8 @@ StorageService.prototype.destroyContainer = function (container, cb) {
|
||||||
* @param {Object|String} err Error string or object
|
* @param {Object|String} err Error string or object
|
||||||
* @param {Object} container Container metadata object
|
* @param {Object} container Container metadata object
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.getContainer = function (container, cb) {
|
StorageService.prototype.getContainer = function(container, cb) {
|
||||||
return this.client.getContainer(container, function (err, container) {
|
return this.client.getContainer(container, function(err, container) {
|
||||||
if (err && err.code === 'ENOENT') {
|
if (err && err.code === 'ENOENT') {
|
||||||
err.statusCode = err.status = 404;
|
err.statusCode = err.status = 404;
|
||||||
return cb(err);
|
return cb(err);
|
||||||
|
@ -128,7 +128,7 @@ StorageService.prototype.getContainer = function (container, cb) {
|
||||||
* @param {String|Object} err Error string or object
|
* @param {String|Object} err Error string or object
|
||||||
* @returns {Stream} Stream for uploading
|
* @returns {Stream} Stream for uploading
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.uploadStream = function (container, file, options) {
|
StorageService.prototype.uploadStream = function(container, file, options) {
|
||||||
if (typeof options === 'function') {
|
if (typeof options === 'function') {
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ StorageService.prototype.uploadStream = function (container, file, options) {
|
||||||
* @param {String|Object} err Error string or object
|
* @param {String|Object} err Error string or object
|
||||||
* @returns {Stream} Stream for downloading
|
* @returns {Stream} Stream for downloading
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.downloadStream = function (container, file, options) {
|
StorageService.prototype.downloadStream = function(container, file, options) {
|
||||||
if (typeof options === 'function') {
|
if (typeof options === 'function') {
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
@ -175,17 +175,17 @@ StorageService.prototype.downloadStream = function (container, file, options) {
|
||||||
* @param {Object|String} err Error string or object
|
* @param {Object|String} err Error string or object
|
||||||
* @param {Object[]} files An array of file metadata objects
|
* @param {Object[]} files An array of file metadata objects
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.getFiles = function (container, options, cb) {
|
StorageService.prototype.getFiles = function(container, options, cb) {
|
||||||
if(typeof options === 'function' && !cb) {
|
if (typeof options === 'function' && !cb) {
|
||||||
// options argument is not present
|
// options argument is not present
|
||||||
cb = options;
|
cb = options;
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
return this.client.getFiles(container, options, function (err, files) {
|
return this.client.getFiles(container, options, function(err, files) {
|
||||||
if (err) {
|
if (err) {
|
||||||
cb(err, files);
|
cb(err, files);
|
||||||
} else {
|
} else {
|
||||||
cb(err, files.map(function (f) {
|
cb(err, files.map(function(f) {
|
||||||
return map(f);
|
return map(f);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -200,8 +200,8 @@ StorageService.prototype.getFiles = function (container, options, cb) {
|
||||||
* @param {Object|String} err Error string or object
|
* @param {Object|String} err Error string or object
|
||||||
* @param {Object} file File metadata object
|
* @param {Object} file File metadata object
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.getFile = function (container, file, cb) {
|
StorageService.prototype.getFile = function(container, file, cb) {
|
||||||
return this.client.getFile(container, file, function (err, f) {
|
return this.client.getFile(container, file, function(err, f) {
|
||||||
return cb(err, map(f));
|
return cb(err, map(f));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -213,7 +213,7 @@ StorageService.prototype.getFile = function (container, file, cb) {
|
||||||
* @callback {Function} cb Callback function
|
* @callback {Function} cb Callback function
|
||||||
* @param {Object|String} err Error string or object
|
* @param {Object|String} err Error string or object
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.removeFile = function (container, file, cb) {
|
StorageService.prototype.removeFile = function(container, file, cb) {
|
||||||
return this.client.removeFile(container, file, cb);
|
return this.client.removeFile(container, file, cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ StorageService.prototype.upload = function(req, res, options, cb) {
|
||||||
* @param {Response} res HTTP response
|
* @param {Response} res HTTP response
|
||||||
* @param {Function} cb Callback function
|
* @param {Function} cb Callback function
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.download = function (container, file, req, res, cb) {
|
StorageService.prototype.download = function(container, file, req, res, cb) {
|
||||||
return handler.download(this.client, req, res, container, file, cb);
|
return handler.download(this.client, req, res, container, file, cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -260,29 +260,39 @@ StorageService.modelName = 'storage';
|
||||||
|
|
||||||
StorageService.prototype.getContainers.shared = true;
|
StorageService.prototype.getContainers.shared = true;
|
||||||
StorageService.prototype.getContainers.accepts = [];
|
StorageService.prototype.getContainers.accepts = [];
|
||||||
StorageService.prototype.getContainers.returns = {arg: 'containers', type: 'array', root: true};
|
StorageService.prototype.getContainers.returns = {
|
||||||
|
arg: 'containers',
|
||||||
|
type: 'array',
|
||||||
|
root: true,
|
||||||
|
};
|
||||||
StorageService.prototype.getContainers.http =
|
StorageService.prototype.getContainers.http =
|
||||||
{verb: 'get', path: '/'};
|
{verb: 'get', path: '/'};
|
||||||
|
|
||||||
StorageService.prototype.getContainer.shared = true;
|
StorageService.prototype.getContainer.shared = true;
|
||||||
StorageService.prototype.getContainer.accepts = [
|
StorageService.prototype.getContainer.accepts = [
|
||||||
{arg: 'container', type: 'string'}
|
{arg: 'container', type: 'string'},
|
||||||
];
|
];
|
||||||
StorageService.prototype.getContainer.returns = {arg: 'container', type: 'object', root: true};
|
StorageService.prototype.getContainer.returns = {
|
||||||
|
arg: 'container',
|
||||||
|
type: 'object', root: true,
|
||||||
|
};
|
||||||
StorageService.prototype.getContainer.http =
|
StorageService.prototype.getContainer.http =
|
||||||
{verb: 'get', path: '/:container'};
|
{verb: 'get', path: '/:container'};
|
||||||
|
|
||||||
StorageService.prototype.createContainer.shared = true;
|
StorageService.prototype.createContainer.shared = true;
|
||||||
StorageService.prototype.createContainer.accepts = [
|
StorageService.prototype.createContainer.accepts = [
|
||||||
{arg: 'options', type: 'object', http: {source: 'body'}}
|
{arg: 'options', type: 'object', http: {source: 'body'}},
|
||||||
];
|
];
|
||||||
StorageService.prototype.createContainer.returns = {arg: 'container', type: 'object', root: true};
|
StorageService.prototype.createContainer.returns = {
|
||||||
|
arg: 'container',
|
||||||
|
type: 'object', root: true,
|
||||||
|
};
|
||||||
StorageService.prototype.createContainer.http =
|
StorageService.prototype.createContainer.http =
|
||||||
{verb: 'post', path: '/'};
|
{verb: 'post', path: '/'};
|
||||||
|
|
||||||
StorageService.prototype.destroyContainer.shared = true;
|
StorageService.prototype.destroyContainer.shared = true;
|
||||||
StorageService.prototype.destroyContainer.accepts = [
|
StorageService.prototype.destroyContainer.accepts = [
|
||||||
{arg: 'container', type: 'string'}
|
{arg: 'container', type: 'string'},
|
||||||
];
|
];
|
||||||
StorageService.prototype.destroyContainer.returns = {};
|
StorageService.prototype.destroyContainer.returns = {};
|
||||||
StorageService.prototype.destroyContainer.http =
|
StorageService.prototype.destroyContainer.http =
|
||||||
|
@ -290,7 +300,7 @@ StorageService.prototype.destroyContainer.http =
|
||||||
|
|
||||||
StorageService.prototype.getFiles.shared = true;
|
StorageService.prototype.getFiles.shared = true;
|
||||||
StorageService.prototype.getFiles.accepts = [
|
StorageService.prototype.getFiles.accepts = [
|
||||||
{arg: 'container', type: 'string'}
|
{arg: 'container', type: 'string'},
|
||||||
];
|
];
|
||||||
StorageService.prototype.getFiles.returns = {arg: 'files', type: 'array', root: true};
|
StorageService.prototype.getFiles.returns = {arg: 'files', type: 'array', root: true};
|
||||||
StorageService.prototype.getFiles.http =
|
StorageService.prototype.getFiles.http =
|
||||||
|
@ -299,7 +309,7 @@ StorageService.prototype.getFiles.http =
|
||||||
StorageService.prototype.getFile.shared = true;
|
StorageService.prototype.getFile.shared = true;
|
||||||
StorageService.prototype.getFile.accepts = [
|
StorageService.prototype.getFile.accepts = [
|
||||||
{arg: 'container', type: 'string'},
|
{arg: 'container', type: 'string'},
|
||||||
{arg: 'file', type: 'string'}
|
{arg: 'file', type: 'string'},
|
||||||
];
|
];
|
||||||
StorageService.prototype.getFile.returns = {arg: 'file', type: 'object', root: true};
|
StorageService.prototype.getFile.returns = {arg: 'file', type: 'object', root: true};
|
||||||
StorageService.prototype.getFile.http =
|
StorageService.prototype.getFile.http =
|
||||||
|
@ -308,7 +318,7 @@ StorageService.prototype.getFile.http =
|
||||||
StorageService.prototype.removeFile.shared = true;
|
StorageService.prototype.removeFile.shared = true;
|
||||||
StorageService.prototype.removeFile.accepts = [
|
StorageService.prototype.removeFile.accepts = [
|
||||||
{arg: 'container', type: 'string'},
|
{arg: 'container', type: 'string'},
|
||||||
{arg: 'file', type: 'string'}
|
{arg: 'file', type: 'string'},
|
||||||
];
|
];
|
||||||
StorageService.prototype.removeFile.returns = {};
|
StorageService.prototype.removeFile.returns = {};
|
||||||
StorageService.prototype.removeFile.http =
|
StorageService.prototype.removeFile.http =
|
||||||
|
@ -317,7 +327,7 @@ StorageService.prototype.removeFile.http =
|
||||||
StorageService.prototype.upload.shared = true;
|
StorageService.prototype.upload.shared = true;
|
||||||
StorageService.prototype.upload.accepts = [
|
StorageService.prototype.upload.accepts = [
|
||||||
{arg: 'req', type: 'object', 'http': {source: 'req'}},
|
{arg: 'req', type: 'object', 'http': {source: 'req'}},
|
||||||
{arg: 'res', type: 'object', 'http': {source: 'res'}}
|
{arg: 'res', type: 'object', 'http': {source: 'res'}},
|
||||||
];
|
];
|
||||||
StorageService.prototype.upload.returns = {arg: 'result', type: 'object'};
|
StorageService.prototype.upload.returns = {arg: 'result', type: 'object'};
|
||||||
StorageService.prototype.upload.http =
|
StorageService.prototype.upload.http =
|
||||||
|
@ -328,7 +338,7 @@ StorageService.prototype.download.accepts = [
|
||||||
{arg: 'container', type: 'string', 'http': {source: 'path'}},
|
{arg: 'container', type: 'string', 'http': {source: 'path'}},
|
||||||
{arg: 'file', type: 'string', 'http': {source: 'path'}},
|
{arg: 'file', type: 'string', 'http': {source: 'path'}},
|
||||||
{arg: 'req', type: 'object', 'http': {source: 'req'}},
|
{arg: 'req', type: 'object', 'http': {source: 'req'}},
|
||||||
{arg: 'res', type: 'object', 'http': {source: 'res'}}
|
{arg: 'res', type: 'object', 'http': {source: 'res'}},
|
||||||
];
|
];
|
||||||
StorageService.prototype.download.http =
|
StorageService.prototype.download.http =
|
||||||
{verb: 'get', path: '/:container/download/:file'};
|
{verb: 'get', path: '/:container/download/:file'};
|
||||||
|
|
10
package.json
10
package.json
|
@ -4,7 +4,9 @@
|
||||||
"version": "1.9.2",
|
"version": "1.9.2",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "./node_modules/.bin/mocha --timeout 30000 test/*test.js"
|
"lint": "eslint .",
|
||||||
|
"test": "./node_modules/.bin/mocha --timeout 30000 test/*test.js",
|
||||||
|
"posttest": "npm run lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"async": "^0.9.0",
|
"async": "^0.9.0",
|
||||||
|
@ -13,11 +15,13 @@
|
||||||
"strong-globalize": "^2.6.2"
|
"strong-globalize": "^2.6.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"eslint": "^2.13.1",
|
||||||
|
"eslint-config-loopback": "^4.0.0",
|
||||||
"express": "^4.11.0",
|
"express": "^4.11.0",
|
||||||
"loopback": "^2.10.0",
|
"loopback": "^2.10.0",
|
||||||
|
"mkdirp": "^0.5.0",
|
||||||
"mocha": "^2.1.0",
|
"mocha": "^2.1.0",
|
||||||
"supertest": "^0.15.0",
|
"supertest": "^0.15.0"
|
||||||
"mkdirp": "^0.5.0"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
'use strict';
|
||||||
|
|
||||||
var loopback = require('loopback')
|
var loopback = require('loopback');
|
||||||
, app = module.exports = loopback();
|
var app = module.exports = loopback();
|
||||||
|
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
|
@ -18,7 +19,7 @@ app.set('port', process.env.PORT || 3000);
|
||||||
var ds = loopback.createDataSource({
|
var ds = loopback.createDataSource({
|
||||||
connector: require('../index'),
|
connector: require('../index'),
|
||||||
provider: 'filesystem',
|
provider: 'filesystem',
|
||||||
root: path.join(__dirname, 'storage')
|
root: path.join(__dirname, 'storage'),
|
||||||
});
|
});
|
||||||
|
|
||||||
var container = ds.createModel('container');
|
var container = ds.createModel('container');
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
'use strict';
|
||||||
|
|
||||||
var FileSystemProvider = require('../lib/providers/filesystem/index.js').Client;
|
var FileSystemProvider = require('../lib/providers/filesystem/index.js').Client;
|
||||||
|
|
||||||
|
@ -19,16 +20,15 @@ function verifyMetadata(fileOrContainer, name) {
|
||||||
assert.equal(typeof fileOrContainer.getMetadata().size, 'number');
|
assert.equal(typeof fileOrContainer.getMetadata().size, 'number');
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('FileSystem based storage provider', function () {
|
describe('FileSystem based storage provider', function() {
|
||||||
|
describe('container apis', function() {
|
||||||
describe('container apis', function () {
|
|
||||||
var client = null;
|
var client = null;
|
||||||
it('should require an existing directory as the root', function (done) {
|
it('should require an existing directory as the root', function(done) {
|
||||||
client = new FileSystemProvider({root: path.join(__dirname, 'storage')});
|
client = new FileSystemProvider({root: path.join(__dirname, 'storage')});
|
||||||
process.nextTick(done);
|
process.nextTick(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should complain if the root directory doesn\'t exist', function (done) {
|
it('should complain if the root directory doesn\'t exist', function(done) {
|
||||||
try {
|
try {
|
||||||
client = new FileSystemProvider({root: path.join(__dirname, '_storage')});
|
client = new FileSystemProvider({root: path.join(__dirname, '_storage')});
|
||||||
process.nextTick(done.bind(null, 'Error'));
|
process.nextTick(done.bind(null, 'Error'));
|
||||||
|
@ -38,98 +38,98 @@ describe('FileSystem based storage provider', function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return an empty list of containers', function (done) {
|
it('should return an empty list of containers', function(done) {
|
||||||
client.getContainers(function (err, containers) {
|
client.getContainers(function(err, containers) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(0, containers.length);
|
assert.equal(0, containers.length);
|
||||||
done(err, containers);
|
done(err, containers);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a new container', function (done) {
|
it('should create a new container', function(done) {
|
||||||
client.createContainer({name: 'c1'}, function (err, container) {
|
client.createContainer({name: 'c1'}, function(err, container) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
verifyMetadata(container, 'c1');
|
verifyMetadata(container, 'c1');
|
||||||
done(err, container);
|
done(err, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get a container c1', function (done) {
|
it('should get a container c1', function(done) {
|
||||||
client.getContainer('c1', function (err, container) {
|
client.getContainer('c1', function(err, container) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
verifyMetadata(container, 'c1');
|
verifyMetadata(container, 'c1');
|
||||||
done(err, container);
|
done(err, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not get a container c2', function (done) {
|
it('should not get a container c2', function(done) {
|
||||||
client.getContainer('c2', function (err, container) {
|
client.getContainer('c2', function(err, container) {
|
||||||
assert(err);
|
assert(err);
|
||||||
done(null, container);
|
done(null, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return one container', function (done) {
|
it('should return one container', function(done) {
|
||||||
client.getContainers(function (err, containers) {
|
client.getContainers(function(err, containers) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(1, containers.length);
|
assert.equal(1, containers.length);
|
||||||
done(err, containers);
|
done(err, containers);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should destroy a container c1', function (done) {
|
it('should destroy a container c1', function(done) {
|
||||||
client.destroyContainer('c1', function (err, container) {
|
client.destroyContainer('c1', function(err, container) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
done(err, container);
|
done(err, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not get a container c1 after destroy', function (done) {
|
it('should not get a container c1 after destroy', function(done) {
|
||||||
client.getContainer('c1', function (err, container) {
|
client.getContainer('c1', function(err, container) {
|
||||||
assert(err);
|
assert(err);
|
||||||
done(null, container);
|
done(null, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('file apis', function () {
|
describe('file apis', function() {
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var client = new FileSystemProvider({root: path.join(__dirname, 'storage')});
|
var client = new FileSystemProvider({root: path.join(__dirname, 'storage')});
|
||||||
|
|
||||||
it('should create a new container', function (done) {
|
it('should create a new container', function(done) {
|
||||||
client.createContainer({name: 'c1'}, function (err, container) {
|
client.createContainer({name: 'c1'}, function(err, container) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
done(err, container);
|
done(err, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should upload a file', function (done) {
|
it('should upload a file', function(done) {
|
||||||
var writer = client.upload({container: 'c1', remote: 'f1.txt'});
|
var writer = client.upload({container: 'c1', remote: 'f1.txt'});
|
||||||
fs.createReadStream(path.join(__dirname, 'files/f1.txt')).pipe(writer);
|
fs.createReadStream(path.join(__dirname, 'files/f1.txt')).pipe(writer);
|
||||||
writer.on('finish', done);
|
writer.on('finish', done);
|
||||||
writer.on('error', done);
|
writer.on('error', done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should download a file', function (done) {
|
it('should download a file', function(done) {
|
||||||
var reader = client.download({
|
var reader = client.download({
|
||||||
container: 'c1',
|
container: 'c1',
|
||||||
remote: 'f1.txt'
|
remote: 'f1.txt',
|
||||||
});
|
});
|
||||||
reader.pipe(fs.createWriteStream(path.join(__dirname, 'files/f1_downloaded.txt')));
|
reader.pipe(fs.createWriteStream(path.join(__dirname, 'files/f1_downloaded.txt')));
|
||||||
reader.on('end', done);
|
reader.on('end', done);
|
||||||
reader.on('error', done);
|
reader.on('error', done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get files for a container', function (done) {
|
it('should get files for a container', function(done) {
|
||||||
client.getFiles('c1', function (err, files) {
|
client.getFiles('c1', function(err, files) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(1, files.length);
|
assert.equal(1, files.length);
|
||||||
done(err, files);
|
done(err, files);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get a file', function (done) {
|
it('should get a file', function(done) {
|
||||||
client.getFile('c1', 'f1.txt', function (err, f) {
|
client.getFile('c1', 'f1.txt', function(err, f) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.ok(f);
|
assert.ok(f);
|
||||||
verifyMetadata(f, 'f1.txt');
|
verifyMetadata(f, 'f1.txt');
|
||||||
|
@ -137,30 +137,28 @@ describe('FileSystem based storage provider', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove a file', function (done) {
|
it('should remove a file', function(done) {
|
||||||
client.removeFile('c1', 'f1.txt', function (err) {
|
client.removeFile('c1', 'f1.txt', function(err) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get no files from a container', function (done) {
|
it('should get no files from a container', function(done) {
|
||||||
client.getFiles('c1', function (err, files) {
|
client.getFiles('c1', function(err, files) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(0, files.length);
|
assert.equal(0, files.length);
|
||||||
done(err, files);
|
done(err, files);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should destroy a container c1', function (done) {
|
it('should destroy a container c1', function(done) {
|
||||||
client.destroyContainer('c1', function (err, container) {
|
client.destroyContainer('c1', function(err, container) {
|
||||||
// console.error(err);
|
// console.error(err);
|
||||||
assert(!err);
|
assert(!err);
|
||||||
done(err, container);
|
done(err, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,113 +2,115 @@
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
'use strict';
|
||||||
|
|
||||||
var StorageService = require('../lib/storage-service.js');
|
var StorageService = require('../lib/storage-service.js');
|
||||||
|
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
var storageService = new StorageService({root: path.join(__dirname, 'storage'), provider: 'filesystem'});
|
var storageService = new StorageService({
|
||||||
|
root: path.join(__dirname, 'storage'),
|
||||||
|
provider: 'filesystem',
|
||||||
|
});
|
||||||
|
|
||||||
describe('Storage service', function () {
|
describe('Storage service', function() {
|
||||||
|
describe('container apis', function() {
|
||||||
describe('container apis', function () {
|
it('should return an empty list of containers', function(done) {
|
||||||
|
storageService.getContainers(function(err, containers) {
|
||||||
it('should return an empty list of containers', function (done) {
|
|
||||||
storageService.getContainers(function (err, containers) {
|
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(0, containers.length);
|
assert.equal(0, containers.length);
|
||||||
done(err, containers);
|
done(err, containers);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a new container', function (done) {
|
it('should create a new container', function(done) {
|
||||||
storageService.createContainer({name: 'c1'}, function (err, container) {
|
storageService.createContainer({name: 'c1'}, function(err, container) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert(container.getMetadata());
|
assert(container.getMetadata());
|
||||||
done(err, container);
|
done(err, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get a container c1', function (done) {
|
it('should get a container c1', function(done) {
|
||||||
storageService.getContainer('c1', function (err, container) {
|
storageService.getContainer('c1', function(err, container) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert(container.getMetadata());
|
assert(container.getMetadata());
|
||||||
done(err, container);
|
done(err, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not get a container c2', function (done) {
|
it('should not get a container c2', function(done) {
|
||||||
storageService.getContainer('c2', function (err, container) {
|
storageService.getContainer('c2', function(err, container) {
|
||||||
assert(err);
|
assert(err);
|
||||||
done(null, container);
|
done(null, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return one container', function (done) {
|
it('should return one container', function(done) {
|
||||||
storageService.getContainers(function (err, containers) {
|
storageService.getContainers(function(err, containers) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(1, containers.length);
|
assert.equal(1, containers.length);
|
||||||
done(err, containers);
|
done(err, containers);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should destroy a container c1', function (done) {
|
it('should destroy a container c1', function(done) {
|
||||||
storageService.destroyContainer('c1', function (err, container) {
|
storageService.destroyContainer('c1', function(err, container) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
done(err, container);
|
done(err, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not get a container c1 after destroy', function (done) {
|
it('should not get a container c1 after destroy', function(done) {
|
||||||
storageService.getContainer('c1', function (err, container) {
|
storageService.getContainer('c1', function(err, container) {
|
||||||
assert(err);
|
assert(err);
|
||||||
done(null, container);
|
done(null, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('file apis', function () {
|
describe('file apis', function() {
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
it('should create a new container', function (done) {
|
it('should create a new container', function(done) {
|
||||||
storageService.createContainer({name: 'c1'}, function (err, container) {
|
storageService.createContainer({name: 'c1'}, function(err, container) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
done(err, container);
|
done(err, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should upload a file', function (done) {
|
it('should upload a file', function(done) {
|
||||||
var writer = storageService.uploadStream('c1', 'f1.txt');
|
var writer = storageService.uploadStream('c1', 'f1.txt');
|
||||||
fs.createReadStream(path.join(__dirname, 'files/f1.txt')).pipe(writer);
|
fs.createReadStream(path.join(__dirname, 'files/f1.txt')).pipe(writer);
|
||||||
writer.on('finish', done);
|
writer.on('finish', done);
|
||||||
writer.on('error', done);
|
writer.on('error', done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should emit success event', function (done) {
|
it('should emit success event', function(done) {
|
||||||
var writer = storageService.uploadStream('c1', 'f1.txt');
|
var writer = storageService.uploadStream('c1', 'f1.txt');
|
||||||
fs.createReadStream(path.join(__dirname, 'files/f1.txt')).pipe(writer);
|
fs.createReadStream(path.join(__dirname, 'files/f1.txt')).pipe(writer);
|
||||||
writer.on('success', done);
|
writer.on('success', done);
|
||||||
writer.on('error', done);
|
writer.on('error', done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should download a file', function (done) {
|
it('should download a file', function(done) {
|
||||||
var reader = storageService.downloadStream('c1', 'f1.txt');
|
var reader = storageService.downloadStream('c1', 'f1.txt');
|
||||||
reader.pipe(fs.createWriteStream(path.join(__dirname, 'files/f1_downloaded.txt')));
|
reader.pipe(fs.createWriteStream(path.join(__dirname, 'files/f1_downloaded.txt')));
|
||||||
reader.on('end', done);
|
reader.on('end', done);
|
||||||
reader.on('error', done);
|
reader.on('error', done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get files for a container', function (done) {
|
it('should get files for a container', function(done) {
|
||||||
storageService.getFiles('c1', function (err, files) {
|
storageService.getFiles('c1', function(err, files) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(1, files.length);
|
assert.equal(1, files.length);
|
||||||
done(err, files);
|
done(err, files);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get a file', function (done) {
|
it('should get a file', function(done) {
|
||||||
storageService.getFile('c1', 'f1.txt', function (err, f) {
|
storageService.getFile('c1', 'f1.txt', function(err, f) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.ok(f);
|
assert.ok(f);
|
||||||
assert(f.getMetadata());
|
assert(f.getMetadata());
|
||||||
|
@ -116,30 +118,28 @@ describe('Storage service', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove a file', function (done) {
|
it('should remove a file', function(done) {
|
||||||
storageService.removeFile('c1', 'f1.txt', function (err) {
|
storageService.removeFile('c1', 'f1.txt', function(err) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get no files from a container', function (done) {
|
it('should get no files from a container', function(done) {
|
||||||
storageService.getFiles('c1', function (err, files) {
|
storageService.getFiles('c1', function(err, files) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(0, files.length);
|
assert.equal(0, files.length);
|
||||||
done(err, files);
|
done(err, files);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should destroy a container c1', function (done) {
|
it('should destroy a container c1', function(done) {
|
||||||
storageService.destroyContainer('c1', function (err, container) {
|
storageService.destroyContainer('c1', function(err, container) {
|
||||||
// console.error(err);
|
// console.error(err);
|
||||||
assert(!err);
|
assert(!err);
|
||||||
done(err, container);
|
done(err, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
'use strict';
|
||||||
|
|
||||||
var request = require('supertest');
|
var request = require('supertest');
|
||||||
var loopback = require('loopback');
|
var loopback = require('loopback');
|
||||||
|
@ -23,7 +24,7 @@ var dsImage = loopback.createDataSource({
|
||||||
},
|
},
|
||||||
acl: 'public-read',
|
acl: 'public-read',
|
||||||
allowedContentTypes: ['image/png', 'image/jpeg'],
|
allowedContentTypes: ['image/png', 'image/jpeg'],
|
||||||
maxFileSize: 5 * 1024 * 1024
|
maxFileSize: 5 * 1024 * 1024,
|
||||||
});
|
});
|
||||||
|
|
||||||
var ImageContainer = dsImage.createModel('imageContainer');
|
var ImageContainer = dsImage.createModel('imageContainer');
|
||||||
|
@ -32,7 +33,7 @@ app.model(ImageContainer);
|
||||||
var ds = loopback.createDataSource({
|
var ds = loopback.createDataSource({
|
||||||
connector: require('../lib/storage-connector'),
|
connector: require('../lib/storage-connector'),
|
||||||
provider: 'filesystem',
|
provider: 'filesystem',
|
||||||
root: path.join(__dirname, 'images')
|
root: path.join(__dirname, 'images'),
|
||||||
});
|
});
|
||||||
|
|
||||||
var Container = ds.createModel('container', {}, {base: 'Model'});
|
var Container = ds.createModel('container', {}, {base: 'Model'});
|
||||||
|
@ -66,51 +67,48 @@ function verifyMetadata(containerOrFile, name) {
|
||||||
assert.equal(typeof containerOrFile.size, 'number');
|
assert.equal(typeof containerOrFile.size, 'number');
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('storage service', function () {
|
describe('storage service', function() {
|
||||||
var server = null;
|
var server = null;
|
||||||
before(function (done) {
|
before(function(done) {
|
||||||
server = app.listen(0, function () {
|
server = app.listen(0, function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function () {
|
after(function() {
|
||||||
server.close();
|
server.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a container', function (done) {
|
it('should create a container', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.post('/containers')
|
.post('/containers')
|
||||||
.send({name: 'test-container'})
|
.send({name: 'test-container'})
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.set('Content-Type', 'application/json')
|
.set('Content-Type', 'application/json')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200, function (err, res) {
|
.expect(200, function(err, res) {
|
||||||
verifyMetadata(res.body, 'test-container');
|
verifyMetadata(res.body, 'test-container');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get a container', function (done) {
|
it('should get a container', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.get('/containers/test-container')
|
.get('/containers/test-container')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200, function (err, res) {
|
.expect(200, function(err, res) {
|
||||||
verifyMetadata(res.body, 'test-container');
|
verifyMetadata(res.body, 'test-container');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should list containers', function (done) {
|
it('should list containers', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.get('/containers')
|
.get('/containers')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200, function (err, res) {
|
.expect(200, function(err, res) {
|
||||||
assert(Array.isArray(res.body));
|
assert(Array.isArray(res.body));
|
||||||
assert.equal(res.body.length, 2);
|
assert.equal(res.body.length, 2);
|
||||||
res.body.forEach(function(c) {
|
res.body.forEach(function(c) {
|
||||||
|
@ -120,37 +118,34 @@ describe('storage service', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should delete a container', function (done) {
|
it('should delete a container', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.del('/containers/test-container')
|
.del('/containers/test-container')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200, function (err, res) {
|
.expect(200, function(err, res) {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should list containers after delete', function (done) {
|
it('should list containers after delete', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.get('/containers')
|
.get('/containers')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200, function (err, res) {
|
.expect(200, function(err, res) {
|
||||||
assert(Array.isArray(res.body));
|
assert(Array.isArray(res.body));
|
||||||
assert.equal(res.body.length, 1);
|
assert.equal(res.body.length, 1);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should list files', function (done) {
|
it('should list files', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.get('/containers/album1/files')
|
.get('/containers/album1/files')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200, function (err, res) {
|
.expect(200, function(err, res) {
|
||||||
assert(Array.isArray(res.body));
|
assert(Array.isArray(res.body));
|
||||||
res.body.forEach(function(f) {
|
res.body.forEach(function(f) {
|
||||||
verifyMetadata(f);
|
verifyMetadata(f);
|
||||||
|
@ -159,33 +154,31 @@ describe('storage service', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uploads files', function (done) {
|
it('uploads files', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.post('/containers/album1/upload')
|
.post('/containers/album1/upload')
|
||||||
.attach('image', path.join(__dirname, './fixtures/test.jpg'))
|
.attach('image', path.join(__dirname, './fixtures/test.jpg'))
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200, function (err, res) {
|
.expect(200, function(err, res) {
|
||||||
assert.deepEqual(res.body, {"result": {"files": {"image": [
|
assert.deepEqual(res.body, {'result': {'files': {'image': [
|
||||||
{"container": "album1", "name": "test.jpg", "type": "image/jpeg",
|
{'container': 'album1', 'name': 'test.jpg', 'type': 'image/jpeg',
|
||||||
"size": 60475}
|
'size': 60475},
|
||||||
]}, "fields": {}}});
|
]}, 'fields': {}}});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uploads files with renamer', function (done) {
|
it('uploads files with renamer', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.post('/imageContainers/album1/upload')
|
.post('/imageContainers/album1/upload')
|
||||||
.attach('image', path.join(__dirname, './fixtures/test.jpg'))
|
.attach('image', path.join(__dirname, './fixtures/test.jpg'))
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200, function (err, res) {
|
.expect(200, function(err, res) {
|
||||||
assert.deepEqual(res.body, {"result": {"files": {"image": [
|
assert.deepEqual(res.body, {'result': {'files': {'image': [
|
||||||
{"container": "album1", "name": "image-test.jpg", "originalFilename":"test.jpg", "type": "image/jpeg", "acl":"public-read", "size": 60475}
|
{'container': 'album1', 'name': 'image-test.jpg', 'originalFilename': 'test.jpg', 'type': 'image/jpeg', 'acl': 'public-read', 'size': 60475},
|
||||||
]}, "fields": {}}});
|
]}, 'fields': {}}});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -203,51 +196,47 @@ describe('storage service', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uploads file too large', function (done) {
|
it('uploads file too large', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.post('/imageContainers/album1/upload')
|
.post('/imageContainers/album1/upload')
|
||||||
.attach('image', path.join(__dirname, './fixtures/largeImage.jpg'))
|
.attach('image', path.join(__dirname, './fixtures/largeImage.jpg'))
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.set('Connection', 'keep-alive')
|
.set('Connection', 'keep-alive')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200, function (err, res) {
|
.expect(200, function(err, res) {
|
||||||
assert(err);
|
assert(err);
|
||||||
assert(res.body.error.message.indexOf('maxFileSize exceeded') !== -1);
|
assert(res.body.error.message.indexOf('maxFileSize exceeded') !== -1);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get file by name', function (done) {
|
it('should get file by name', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.get('/containers/album1/files/test.jpg')
|
.get('/containers/album1/files/test.jpg')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200, function (err, res) {
|
.expect(200, function(err, res) {
|
||||||
verifyMetadata(res.body, 'test.jpg');
|
verifyMetadata(res.body, 'test.jpg');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get file by renamed file name', function (done) {
|
it('should get file by renamed file name', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.get('/imageContainers/album1/files/image-test.jpg')
|
.get('/imageContainers/album1/files/image-test.jpg')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200, function (err, res) {
|
.expect(200, function(err, res) {
|
||||||
verifyMetadata(res.body, 'image-test.jpg');
|
verifyMetadata(res.body, 'image-test.jpg');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('downloads files', function (done) {
|
it('downloads files', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.get('/containers/album1/download/test.jpg')
|
.get('/containers/album1/download/test.jpg')
|
||||||
.expect('Content-Type', 'image/jpeg')
|
.expect('Content-Type', 'image/jpeg')
|
||||||
.expect(200, function (err, res) {
|
.expect(200, function(err, res) {
|
||||||
if (err) done(err);
|
if (err) done(err);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -293,23 +282,21 @@ describe('storage service', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should delete a file', function (done) {
|
it('should delete a file', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.del('/containers/album1/files/test.jpg')
|
.del('/containers/album1/files/test.jpg')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200, function (err, res) {
|
.expect(200, function(err, res) {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('reports errors if it fails to find the file to download', function (done) {
|
it('reports errors if it fails to find the file to download', function(done) {
|
||||||
|
|
||||||
request('http://localhost:' + app.get('port'))
|
request('http://localhost:' + app.get('port'))
|
||||||
.get('/containers/album1/download/test_not_exist.jpg')
|
.get('/containers/album1/download/test_not_exist.jpg')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(500, function (err, res) {
|
.expect(500, function(err, res) {
|
||||||
assert(res.body.error);
|
assert(res.body.error);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue