UNPKG

box-chrome-sdk

Version:

A Chrome App SDK for the Box V2 API

340 lines (336 loc) 15.3 kB
/** * @fileoverview Box SDK public interface. * @author jmeadows */ var sdk = angular.module('box.sdk', ['rx', 'chrome.storage', 'box.auth', 'box.conf', 'box.http', 'box.objects', 'box.util']); sdk.factory('boxSdk', [ '$timeout', 'rx', 'boxHttp', 'apiUrl', 'authUrl', 'crypto', 'BoxCollaboration', 'BoxFile', 'BoxFolder', 'BoxTask', 'BoxUser', 'BoxGroup', 'getAll', 'clientId', 'clientSecret', 'chromeStorage', 'BoxComment', 'http', 'boxObjectBase', 'responseTranslator', 'BoxEvent', function( $timeout, rx, boxHttp, apiUrl, authUrl, crypto, BoxCollaboration, BoxFile, BoxFolder, BoxTask, BoxUser, BoxGroup, getAll, clientId, clientSecret, chromeStorage, BoxComment, http, boxObjectBase, responseTranslator, BoxEvent ) { function Sdk() { this.boxHttp = boxHttp; } Sdk.prototype = angular.extend(Object.create(boxObjectBase), { /** * Logs out from Box, revoking the current API auth and refresh tokens. * @returns {Observable} An observable containing the result of the API request. */ logout: function() { return chromeStorage.getLocal('refresh_token') .flatMap(function(data) { return chromeStorage.removeLocal('access_token') .concat(chromeStorage.removeLocal('refresh_token')) .concat(http.request( 'POST', authUrl + '/revoke', null, { /*eslint-disable camelcase*/ client_id: clientId, client_secret: clientSecret, /*eslint-enable camelcase*/ token: data.token } )); }) .takeLast(1); }, /** * Get the folder object with a given id. * @param {String} id The Box folder id identifying the requested folder * @returns {Observable} An observable containing the requested folder object. */ getFolder: function(id) { return this.boxHttp.get(apiUrl + '/folders/' + id).map(function(result) { return new BoxFolder(result); }); }, /** * Get the file object with a given id. * @param {String} id The Box file id identifying the requested file * @returns {Observable} An observable containing the requested file object. */ getFile: function(id) { return this.boxHttp.get(apiUrl + '/files/' + id).map(function(result) { return new BoxFile(result); }); }, /** * Get the folder object with a given id from the trash. * @param {String} id The Box folder id identifying the requested trashed folder * @returns {Observable} An observable containing the requested trashed folder object. */ getTrashedFolder: function(id) { return this.boxHttp.get(apiUrl + '/folders/' + id + '/trash').map(function(result) { return new BoxFolder(result); }); }, /** * Get the file object with a given id from the trash. * @param {String} id The Box file id identifying the requested trashed file * @returns {Observable} An observable containing the requested trashed file object. */ getTrashedFile: function(id) { return this.boxHttp.get(apiUrl + '/files/' + id + '/trash').map(function(result) { return new BoxFile(result); }); }, /** * Get a list of all items in the trash. * @param {String} fields A comma separated list of fields that should be returned for each trashed item * @returns {Observable} An observable sequence of files and/or folders that are in the trash. */ getTrashedItems: function(fields) { var boxHttp = this.boxHttp; return getAll( function(limit, offset) { return boxHttp.get(apiUrl + '/folders/trash/items', { fields: fields, limit: limit, offset: offset }); }, responseTranslator.translateResponse ); }, /** * Get a list of all pending collaborations. * @returns {Observable} An observable sequence of collaboration objects that are still pending. */ getPendingCollaborations: function() { return this.boxHttp.get(apiUrl + '/collaborations?pending').flatMap(function(result) { return rx.Observable.fromArray(result.entries.map(function(entry) { return new BoxCollaboration(entry); })); }); }, /** * Search Box for content. Read more here [http://developers.box.com/docs/#search]. * @param {String} query The string to search for * @param {Object} params Specifies how the query will be executed. * @returns {Observable} An observable sequence of files and folders. */ search: function(query, params) { var boxHttp = this.boxHttp; return getAll( function(limit, offset) { return boxHttp.get(apiUrl + '/search', { params: angular.extend(params || {}, {query: query, limit: limit, offset: offset}) }); }, responseTranslator.translateResponse ); }, /** * Create a new task. * @param {File|Object} item The file the task will be associated with. * @param {Object} params Can include message (string) and/or due_at (timestamp). * @returns {Observable} An observable containing the newly created Task. */ createTask: function(item, params) { return this.boxHttp.post(apiUrl + '/tasks', null, angular.extend(params, { item: { type: 'file', id: item.id }, action: 'review' }) ).map(function(result) { return new BoxTask(result); }); }, /** * Gets information about the logged-in user. * @returns {Observable} An observable containing the User object for the logged-in user. */ getUserInfo: function() { return this.boxHttp.get(apiUrl + '/users/me').map(function(result) { return new BoxUser(result); }); }, /** * Gets all users in the current user's enterprise if the current user is an enterprise admin. * @param {String} filter A string used to filter the results to only users starting with the filter in either the name or the login * @returns {Observable} An observable stream of user objects in the current enterprise. */ getUsers: function(filter) { var boxHttp = this.boxHttp; return getAll( function(limit, offset) { return boxHttp.get(apiUrl + '/users', { /*eslint-disable camelcase*/ params: { filter_term: filter, limit: limit, offset: offset} /*eslint-enable camelcase*/ }); }, function(result) { return new BoxUser(result); } ); }, /** * Creates a new enterprise user if the current user is an enterprise admin. * @param {Object} params A hash of properties for the user. Must contain at least login and name. * @returns {Observable} An observable containing the new user object. */ createUser: function(params) { return this.boxHttp.post(apiUrl + '/users', null, params) .map(function(result) { return new BoxUser(result); }); }, /** * Get all of the groups for the logged-in user. * @returns {Observable} An observable sequence of groups for the logged-in user. */ getGroups: function() { return this.boxHttp.get(apiUrl + '/groups').flatMap(function(result) { return rx.Observable.fromArray(result.entries.map(function(entry) { return new BoxGroup(entry); })); }); }, /** * Create a new group. * @param {String} name The name for the new group * @returns {Observable} An observable containing the newly created group. */ createGroup: function(name) { return this.boxHttp.post(apiUrl + '/groups', null, {name: name}) .map(function(result) { return new BoxGroup(result); }); }, /** * Subscribe to events for the current user. * @param {String} streamPosition The stream position from which to start streaming events. * @returns {Observable} An observable sequence of BoxEvent objects. Disposing of this sequence unsubscribes. */ subscribeToEvents: function(streamPosition) { var boxHttp = this.boxHttp; function subscribe(streamPosition) { return boxHttp.options(apiUrl + '/events') .flatMap(function(result) { return boxHttp.get(result.entries[0].url + '&stream_position=' + streamPosition) .flatMap(function(response) { if (response.message === 'new_change') { var chunk = -1; return rx.Observable.while( function() { return chunk !== 0; }, rx.Observable.defer(function() { return rx.Observable.return(streamPosition); }) .flatMap(function(position) { return boxHttp.get(apiUrl + '/events?stream_position=' + position) .do(function(result) { chunk = result.chunk_size; streamPosition = result.next_stream_position; }) .flatMap(function(result) { return rx.Observable.fromArray(result.entries) .map(function(entry) { return new BoxEvent(entry, result.next_stream_position); }); }); }) ); } else if (response.message === 'reconnect') { return rx.Observable.empty(); } else { return rx.Observable.empty(); } }) .timeout(result.entries[0].retry_timeout * 1000, rx.Observable.defer(function() { return rx.Observable.empty(); })) .map(function(result) { return { result: result, streamPosition: streamPosition }; }); }); } var obs = rx.Observable.return(streamPosition); if (!angular.isDefined(streamPosition)) { obs = boxHttp.get(apiUrl + '/events?stream_position=now') .map(function(result) { return result.next_stream_position; }); } var subject = new rx.ReplaySubject(); obs.subscribe(function(streamPosition) { var currentStreamPosition = streamPosition; function sub() { subscribe(currentStreamPosition) .do(function(result) { currentStreamPosition = result.streamPosition; }) .subscribe( function onNext(result) { subject.onNext(result.result); }, function onError(error) { subject.onError(error); }, function onCompleted() { $timeout(sub, 1); } ); } sub(); }); return subject.asObservable(); } }); return new Sdk(); }]); sdk.config(['boxApiAuthProvider', function(boxApiAuthProvider) { boxApiAuthProvider.setThrowError(function() { throw chrome.runtime.lastError; }); }]);