UNPKG

xcoobee-sdk

Version:

The XcooBee SDK is a facility to abstract lower level calls and implement standard behaviors. The XcooBee team is providing this to improve the speed of implementation and show the best practices while interacting with XcooBee.

254 lines (233 loc) 9.38 kB
const ApiUtils = require('../api/ApiUtils'); const BeesApi = require('../api/BeesApi'); const DirectiveApi = require('../api/DirectiveApi'); const UploadPolicyIntents = require('../api/UploadPolicyIntents'); const ErrorResponse = require('./ErrorResponse'); const FileUtils = require('./FileUtils'); const SdkUtils = require('./SdkUtils'); const SuccessResponse = require('./SuccessResponse'); /** * The Bees SDK service. * * Instances are not created directly. An {@link Sdk} instance will have a * reference to a `Bees` SDK instance through the {@link Sdk#bees bees} property. * * ```js * const XcooBee = require('xcoobee-sdk'); * * const sdk = new XcooBee.Sdk(...); * sdk.bees.listBees(...).then(...); * ``` * * @param {Config} config * @param {ApiAccessTokenCache} apiAccessTokenCache * @param {UsersCache} usersCache */ class Bees { /* eslint-disable-next-line valid-jsdoc */ /** * Constructs a Bees SDK service instance. */ constructor(config, apiAccessTokenCache, usersCache) { this._ = { apiAccessTokenCache, config: config || null, usersCache, }; } /** * @protected * @param {Config} config */ set config(config) { this._.config = config; } /** * @protected */ _assertValidState() { if (!this._.config) { throw TypeError('Illegal State: Default config has not been set yet.'); } } /** * Returns a page of bees in the system that your account is able to hire that * match the specified search text. * * ```js * let socialBees = []; * * function collectSocialBees(pagingResponse) { * const { result } = pagingResponse; * const pageOfBees = result.data; * socialBees = socialBees.concat(pageOfBees); * if (pagingResponse.hasNextPage()) { * pagingResponse.getNextPage().then(collectSocialBees); * } else { * socialBees.forEach(bee => { * const { bee_system_name, description, bee_icon, ...etc } = bee; * // DO something with this data. * }); * } * } * * sdk.bees.listBees('social') * .then(collectSocialBees) * .catch(res => { * const { error } = res; * console.error(error); * }); * ``` * * @async * @param {string} searchText - The search text. It is a string of keywords to * search for in the bee system name or label in the language of your account. * @param {Config} [config] - If specified, the configuration to use instead of the * default. * * @returns {Promise<PagingResponse | ErrorResponse>} - The response. * @property {number} code - The response status code. * @property {Error} [error] - The response error if status is not successful. * @property {string} [error.message] - The error message. * @property {string} request_id - The ID of the request generated by the XcooBee * system. * @property {Object} [result] - The result of the response if status is successful. * @property {Bee[]} result.data - Bees for this page. * @property {Object} [result.page_info] - The page information. * @property {boolean} result.page_info.has_next_page - Flag indicating whether there is * another page of data to may be fetched. * @property {string} result.page_info.end_cursor - The end cursor. * * @throws {XcooBeeError} */ async listBees(searchText = null, config = null) { this._assertValidState(); const fetchPage = async (apiCfg, params) => { const { apiKey, apiSecret, apiUrlRoot } = apiCfg; const { after, limit, searchText: search } = params; const apiAccessToken = await this._.apiAccessTokenCache.get(apiUrlRoot, apiKey, apiSecret); const beesPage = await BeesApi.bees(apiUrlRoot, apiAccessToken, search, after, limit); return beesPage; }; const apiCfg = SdkUtils.resolveApiCfg(config, this._.config); const params = { searchText }; return SdkUtils.startPaging(fetchPage, apiCfg, params); } /** * * @async * @param {Array<Object<string, Object>>} bees - A mapping of bee names to bee parameters. * @param {string} bees[].key - The bee name. A 'transfer' bee will be ignored. * @param {Object} bees[].value - The bee parameters. * @param {Object} options - The bee take off options. * @param {Object} options.process - * @param {Object} [options.custom] - custom properties * @param {Array<email|XcooBeeId>} [options.process.destinations] - * @param {string[]} options.process.fileNames - * @param {string} [options.process.userReference] - * @param {TransactionSubscriptions} [subscriptions] * @param {Config} [config] - If specified, the configuration to use instead of the * default. * * @returns {Promise<SuccessResponse | ErrorResponse>} - The response. * @property {number} code - The response status code. * @property {Error} [error] - The response error if status is not successful. * @property {string} [error.message] - The error message. * @property {string} request_id - The ID of the request generated by the XcooBee * system. * @property {Object} [result] - The result of the response if status is successful. * @property {string} [result.ref_id] - A reference ID generated by the XcooBee * system. * * @throws {XcooBeeError} */ async takeOff(bees, options, subscriptions, config = null) { this._assertValidState(); const apiCfg = SdkUtils.resolveApiCfg(config, this._.config); const { apiKey, apiSecret, apiUrlRoot } = apiCfg; const directiveInput = { filenames: options.process.fileNames, user_reference: options.process.userReference || null, }; if (subscriptions) { // TODO: validate subscriptions directiveInput.subscriptions = subscriptions; } if (options.custom && typeof options.custom === 'object') { directiveInput.custom = Object .keys(options.custom) .map((name) => ({ name, value: options.custom[name] })); } if ( Array.isArray(options.process.destinations) && options.process.destinations.length > 0 ) { directiveInput.destinations = options.process.destinations.map( (destination) => { if (ApiUtils.appearsToBeAnEmailAddress(destination)) { return { email: destination }; } return { xcoobee_id: destination }; } ); } directiveInput.bees = Object .keys(bees) .map((beeName) => { if (beeName !== 'transfer') { return { bee_name: beeName, params: JSON.stringify(bees[beeName]) }; } return null; }) .filter(Boolean); try { const apiAccessToken = await this._.apiAccessTokenCache.get(apiUrlRoot, apiKey, apiSecret); const ref_id = await DirectiveApi.addDirective(apiUrlRoot, apiAccessToken, directiveInput); const response = new SuccessResponse({ ref_id }); return response; } catch (err) { throw new ErrorResponse(400, err); } } /** * Uploads specified files to XcooBee. * * @async * @param {string[]|File[]} files - File paths of the files on the local file system * to be uploaded. For example, 'C:\Temp\MyPic.jpg' or '~/MyPic.jpg`. Or an array * of 'File' objects as is available in a modern browser. * TODO: Test what file paths actually work and make sure the documentation is * adequate. Be sure to show examples of various path types. * @param {string} endpoint - Endpoint type * @param {Config} [config] - If specified, the configuration to use instead of the * default. * * @returns {Promise<SuccessResponse | ErrorResponse>} * @property {number} code - The response status code. * @property {Error} [error] - The response error if status is not successful. * @property {string} [error.message] - The error message. * @property {string} request_id - The ID of the request generated by the XcooBee * system. * @property {Object[]} [result] - The result of the response if status is * successful. Is an array of sub-results. One for each file uploaded. Each * sub-result has a string `file` property and a boolean `success` property * indicating whether the file was successfully uploaded. If `success` is `false`, * then an error `error` property will also exist. */ async uploadFiles(files, endpoint = UploadPolicyIntents.OUTBOX, config = null) { this._assertValidState(); const apiCfg = SdkUtils.resolveApiCfg(config, this._.config); const { apiKey, apiSecret, apiUrlRoot } = apiCfg; try { const apiAccessToken = await this._.apiAccessTokenCache.get(apiUrlRoot, apiKey, apiSecret); const user = await this._.usersCache.get(apiUrlRoot, apiKey, apiSecret); const userCursor = user.cursor; const result = await FileUtils.upload(apiUrlRoot, apiAccessToken, userCursor, endpoint, files); const response = new SuccessResponse(result); return response; } catch (err) { throw new ErrorResponse(400, err); } } }// eo class Bees module.exports = Bees;