box-view-api
Version:
Box View API, node.js client library
206 lines (166 loc) • 8.3 kB
JavaScript
// Core node module dependencies
//
var fs = require('fs');
// 3rd party library dependencies
//
var _ = require('underscore');
// Internal dependencies
//
var BoxViewError = require('./error');
var fsUtils = require('./fsUtils');
// aliasing for brevity
var ErrorTypes = BoxViewError.errors;
var getPathStats = fsUtils.getPathStats;
var isFile = fsUtils.isFile;
var isReadable = fsUtils.isReadable;
var BoxViewAPI = require('./boxView');
var DocumentAPI = module.exports = BoxViewAPI.extend({
constructor: function DocumentAPI() {
BoxViewAPI.apply(this, arguments);
_.bindAll(this, /*'uploadFile',*/ 'uploadUrl', 'list', 'changeName', 'download', 'remove', 'poll');
},
/*
* Not sure if this is supported by the Box View API, so commenting out for now.
uploadFile: function(filepath, callback) {
var readStream;
// Validate params
if (typeof filepath !== 'string') {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name+'.uploadFile was not passed a string filepath: '+(typeof filepath));
}
if (!isFile(filepath)) {
throw new BoxViewError(ErrorTypes.FILE_ERROR, this.constructor.name+'.uploadFile, file does not exist or is not a file: "'+filepath+'"');
}
if (!isReadable(filepath)) {
throw new BoxViewError(ErrorTypes.FILE_ERROR, this.constructor.name+'.uploadFile, file is not readable: "'+filepath+'"');
}
readStream = fs.createReadStream(filepath);
return this.post(DocumentAPI.resource, {query: {file: readStream}, encodingOptions: {multipart: true, chunked: false}}, callback);
},
*/
uploadUrl: function (fileurl, filename, cb) {
// Validate params
if (arguments.length !== 3) {
throw new BoxViewError(ErrorTypes.INVALID_USE, 'Incorrect number of arguments passed to ' + __filename + '.uploadUrl(): ' + arguments.length);
}
if (typeof fileurl !== 'string' || fileurl.length <= 0) {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name + '.uploadUrl() was not passed a valid url string: ' + (typeof fileurl));
}
if (typeof filename !== 'string' || filename.length <= 0) {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name + '.uploadUrl() was not passed a valid filename string: ' + (typeof filename));
}
if (typeof cb !== 'function') {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name + '.uploadUrl() was not passed a valid callback function: ' + (typeof cb));
}
return this.post(DocumentAPI.resource, {json: {url: fileurl, name: filename}}, cb);
},
list: function() {
if (arguments.length < 1 || arguments.length > 2) {
throw new BoxViewError(ErrorTypes.INVALID_USE, 'Incorrect number of arguments passed to ' + __filename + '.list(): ' + arguments.length);
}
var options = (arguments.length === 2) ? arguments[0] : null;
var cb = arguments[arguments.length - 1];
if (options && typeof options !== 'object') {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name + '.list() was not passed a valid options object: ' + (typeof options));
}
if (typeof cb !== 'function') {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name + '.list() was not passed a valid callback function: ' + (typeof cb));
}
return this.get(DocumentAPI.resource, {query: options}, cb);
},
info: function(uuid) {
// Validate params
if (arguments.length < 2 || arguments.length > 3) {
throw new BoxViewError(ErrorTypes.INVALID_USE, 'Incorrect number of arguments passed to ' + __filename + '.info(): ' + arguments.length);
}
if (typeof uuid !== 'string' || uuid.length <= 0 ) {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name+'.info() was not passed a non-blank string document id: '+(typeof uuid));
}
var fields = (arguments.length === 3) ? arguments[1] : null;
var cb = arguments[arguments.length -1];
var sanitisedFields = [];
if (_.isArray(fields)) {
_.each(fields, function(value) {
if (typeof value === 'string' && DocumentAPI.documentFields.indexOf(value) >= 0) {
sanitisedFields.push(value);
}
});
fields = sanitisedFields.join(',');
}
if (fields && typeof fields !== 'string') {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name + '.info() was not passed a valid list of fields: '+ arguments[1]);
}
if (typeof cb !== 'function') {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name + '.info() was not passed a valid function callback: ' + (typeof cb));
}
return this.get(DocumentAPI.resource+'/'+uuid, {query: {fields: fields}}, cb);
},
changeName: function(uuid, name, cb) {
if (arguments.length !== 3) {
throw new BoxViewError(ErrorTypes.INVALID_USE, 'Incorrect number of arguments passed to ' + __filename + '.changeName(): ' + arguments.length);
}
if (typeof uuid !== 'string' || uuid.length <= 0) {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name + '.changeName was not passed a non-blank string document id: ' + (typeof uuid));
}
if (typeof name !== 'string' || name.length <= 0) {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name + '.changeName was not passed a non-blank string filename: ' + (typeof name));
}
return this.put(DocumentAPI.resource + '/' + uuid, {json: {name: name}}, cb);
},
download: function(uuid, type, stream, cb) {
// Validate params
if (arguments.length !== 4) {
throw new BoxViewError(ErrorTypes.INVALID_USE, 'Incorrect number of arguments passed to ' + this.constructor.name + '.download(): ' + arguments.length);
}
if (typeof uuid !== 'string' || uuid.length <= 0) {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name + '.download() was not passed a non-blank string document id: ' + (typeof uuid));
}
if (typeof type !== 'string' || !DocumentAPI.downloadTypes[type]) {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name + '.download() was not passed a valid type parameter: ' + (typeof type) + ': ' + type);
}
if (!stream || !fsUtils.isWriteStream(stream)) {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name + '.download() was not passed a valid writeStream parameter: ' + (typeof stream));
}
return this.get(DocumentAPI.resource + '/' + uuid + '/content.'+type, {successStream: stream, headers: { accept: 'application/'+type}}, cb);
},
remove: function(uuid, callback) {
// Validate params
if (arguments.length !== 2) {
throw new BoxViewError(ErrorTypes.INVALID_USE, 'Incorrect number of arguments passed to ' + __filename + '.remove(): ' + arguments.length);
}
if (typeof uuid !== 'string' || uuid.length <= 0) {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name+'.remove was not passed a valid uuid string: '+ (typeof uuid));
}
return this.del(DocumentAPI.resource + '/' + uuid, callback);
},
// This is not part of the API, but merely a helper
//
poll: function(id, callback) {
if (arguments.length !== 2) {
throw new BoxViewError(ErrorTypes.INVALID_USE, 'Incorrect number of arguments passed to '+this.constructor.name+'.poll(): ' + arguments.length);
}
if (typeof id !== 'string' || id.length <= 0) {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name+'.poll was not passed a valid uuid string: '+ (typeof id));
}
if (typeof callback !== 'function') {
throw new BoxViewError(ErrorTypes.INVALID_TYPE, this.constructor.name+'.poll was not passed a valid callback: '+ (typeof callback));
}
var self = this;
this.info(id, function (e, r, b) {
var body = b;
var status = (body.status || 'unknown').toLowerCase();
if (e || body.error || status === 'error' || status === 'done') {
callback(e, r, body);
}
else {
setTimeout(function() {self.poll(id, callback);}, 2000);
}
});
}
}, {
documentFields: ['status', 'name', 'created_at', 'modified_at'],
downloadTypes: {
pdf: 'pdf',
zip: 'zip'
},
resource: 'documents'
});