'use strict';
const _ = require('lodash'),
async = require('async'),
RestClient = require('node-rest-client').Client,
functionUtils = require('./function-utils');
function query(path, args, cb) {
args.headers = {
'x-agent-info': 'github.com/zbentley/classeur-api-client'
};
let req = this.RestClient.get(this.root + path, args, function(data, response) {
if ( response.statusCode == 200 ) {
cb(null, JSON.parse(data));
} else {
cb(`Got an error (${response.statusCode}): ${response.statusMessage}`, null);
}
});
req.on('requestTimeout',function(req){
req.abort();
cb('request expired', null);
});
req.on('responseTimeout', _.partial(cb, 'request timed out', null));
req.on('error', _.partialRight(cb, null));
}
function multiQuery(type, wantArray, Array, cb) {
const self = this;
async.map(
Array,
function(item, cb) {
_.bind(query, self, type + item, {}, cb)();
},
functionUtils.scrubArrayCallback(cb, wantArray)
);
}
function metadataQuery(field, wantArray, ids, cb) {
_.bind(query, this)(
'metadata/' + field,
{
parameters: {
id: ids.join(','),
}
},
functionUtils.scrubArrayCallback(cb, wantArray)
);
}
/**
* Constructs a new API client.
* @classdesc Object-oriented interface to the Classeur REST API.
* @class ClasseurClient
* @example
* const ClasseurClient = require('classeur-api-client'),
* client = new ClasseurClient('my user id', 'my api key');
* @param {string} userId - Classeur user ID string.
* @param {string} apiKey - API Key string. Keep this secret.
* @param {string} [host=app.classeur.io] - Fully qualified hostname to connect to. Can be prefixed with `http://` or `https://`.
* @returns {Object} Returns a ClasseurClient instance.
*/
module.exports = class {
constructor(userId, apiKey, host) {
host = host || 'app.classeur.io';
this.RestClient = new RestClient({
user: userId,
password: apiKey,
});
host.replace(/\Ahttps?:[/][/]/g, '');
this.root = `https://${host}/api/v1/`;
}
};
Object.assign(
module.exports.prototype,
// Has to lend the prototype, otherwise the methods show up as static.
/** @lends ClasseurClient.prototype */
{
/**
* Retrieve one or more files.
* @method
* @param {String[]} ids - Array of Classeur file IDs to retrieve.
* @param {ClasseurClient~scrubbedCallback(?(Error))} callback - Called with `(error, result)`.
* - `result` will be an Array of {@link ClasseurClient~File} objects, or `null` on error.
*//**
* Retrieve one or more files.
* Like {@link ClasseurClient#getFiles}, but with spread: accepts a variable number of file IDs in the arguments, instead of an Array.
* @method
* @variation 2
* @param {...String} ids - Classeur file IDs to retrieve.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be an Array of {@link ClasseurClient~File} objects, or `null` on error.
*/
getFiles: _.partial(functionUtils.restOrArrayAndCallback(multiQuery), 'files/', true),
/**
* Retrieve a single file.
* @method
* @param {String} id - Classeur file ID to retrieve.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be a {@link ClasseurClient~File} object, or `null` on error.
*/
getFile: _.partial(functionUtils.singleElementAndCallback(multiQuery), 'files/', false),
/**
* Retrieve one or more folders.
* @method
* @param {String[]} ids - Array of Classeur folder IDs to retrieve.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be an Array of {@link ClasseurClient~Folder} objects, or `null` on error.
*//**
* Like {@link ClasseurClient#getFolders}, but with spread: accepts a variable number of folder IDs in the arguments, instead of an Array.
* @method
* @variation 2
* @param {...String} ids - Classeur folder IDs to retrieve.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be an Array of {@link ClasseurClient~Folder} objects, or `null` on error.
*/
getFolders: _.partial(functionUtils.restOrArrayAndCallback(multiQuery), 'folders/', true),
/**
* Retrieve a single folder.
* @method
* @param {String} id - Classeur folder ID to retrieve.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be a {@link ClasseurClient~Folder} object, or `null` on error.
*/
getFolder: _.partial(functionUtils.singleElementAndCallback(multiQuery), 'folders/', false),
/**
* Retrieve all users on the Classeur account to which the ClasseurClient is connected.
* @method
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be an Array of {@link ClasseurClient~User} objects, or `null` on error.
*/
getUsers: _.partial(functionUtils.singleElementAndCallback(multiQuery), 'users', true, ''),
/**
* Retrieve metadata for one or more users.
* @method
* @param {String[]} ids - Array of Classeur user IDs for which to retrieve metadata.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be an Array of {@link ClasseurClient~UserMetadata} objects, or `null` on error.
*//**
* Like {@link ClasseurClient#getUsersMetadata}, but with spread: accepts a variable number of folder IDs in the arguments, instead of an Array.
* @method
* @variation 2
* @param {...String} ids - Classeur user IDs for which to retrieve metadata.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be an Array of {@link ClasseurClient~UserMetadata} objects, or `null` on error.
*/
getUsersMetadata: _.partial(functionUtils.restOrArrayAndCallback(metadataQuery), 'users', true),
/**
* Retrieve metadata for one or more folders.
* @method
* @param {String[]} ids - Array of Classeur folder IDs for which to retrieve metadata.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be an Array of {@link ClasseurClient~FolderMetadata} objects, or `null` on error.
*//**
* Like {@link ClasseurClient#getUsersMetadata}, but with spread: accepts a variable number of folder IDs in the arguments, instead of an Array.
* @method
* @variation 2
* @param {...String} ids - Classeur folder IDs for which to retrieve metadata.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be an Array of {@link ClasseurClient~FolderMetadata} objects, or `null` on error.
*/
getFoldersMetadata: _.partial(functionUtils.restOrArrayAndCallback(metadataQuery), 'files', true),
/**
* Retrieve metadata for one or more files.
* @method
* @param {String[]} ids - Array of Classeur file IDs for which to retrieve metadata.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be an Array of {@link ClasseurClient~FileMetadata} objects, or `null` on error.
*//**
* Like {@link ClasseurClient#getUsersMetadata}, but with spread: accepts a variable number of folder IDs in the arguments, instead of an Array.
* @method
* @variation 2
* @param {...String} ids - Classeur file IDs for which to retrieve metadata.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be an Array of {@link ClasseurClient~FileMetadata} objects, or `null` on error.
*/
getFilesMetadata: _.partial(functionUtils.restOrArrayAndCallback(metadataQuery), 'folders', true),
/**
* Retrieve metadata for a user.
* @method
* @param {String} id - The Classeur user ID for which to retrieve metadata.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be a {@link ClasseurClient~UserMetadata} object, or `null` on error.
*/
getUserMetadata: _.partial(functionUtils.singleElementAndCallback(metadataQuery), 'users', false),
/**
* Retrieve metadata for a file.
* @method
* @param {String} id - The Classeur file ID for which to retrieve metadata.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be a {@link ClasseurClient~FileMetadata} object, or `null` on error.
*/
getFileMetadata: _.partial(functionUtils.singleElementAndCallback(metadataQuery), 'files', false),
/**
* Retrieve metadata for a folder.
* @method
* @param {String} id - The Classeur folder ID for which to retrieve metadata.
* @param {ClasseurClient~scrubbedCallback} callback - Called with `(error, result)`.
* - `result` will be a {@link ClasseurClient~FolderMetadata} object, or `null` on error.
*/
getFolderMetadata: _.partial(functionUtils.singleElementAndCallback(metadataQuery), 'folders', false)
}
);