UNPKG

timekit-sdk

Version:

JavaScript SDK for the Timekit API (timekit.io)

338 lines (296 loc) 7.7 kB
'use strict'; /*! * Timekit JavaScript SDK * http://timekit.io * * Copyright 2015 Timekit, Inc. * The Timekit JavaScript SDK is freely distributable under the MIT license. * */ var axios = require('axios'); var humps = require('humps'); var merge = require('deepmerge'); var utils = require('./utils'); var endpoints = require('./endpoints'); var deprecatedEndpoints = require('./deprecated_endpoints'); function Timekit() { /** * Auth variables for login gated API methods * @type {String} */ var includes = []; var headers = {}; var nextPayload = {}; /** * Default config * @type {Object} */ var config = { app: '', apiVersion: 'v2', apiBaseUrl: 'https://api.timekit.io/', convertResponseToCamelcase: false, convertRequestToSnakecase: true, autoFlattenResponse: true, resourceEmail: null, resourceKey: null, appKey: null, }; /** * Root Object that holds methods to expose for API consumption * @type {Object} */ var TK = {}; /** * Prepare and make HTTP request to API * @type {Object} * @return {Promise} */ TK.makeRequest = function (args) { // Handle chained payload data if applicable args = utils.mergeNextPayload(args, nextPayload); nextPayload = {}; // construct URL with base, version and endpoint args.url = utils.buildUrl(args.url, config); // add http headers if applicable args.headers = args.headers || headers || {}; if (config.headers) { args.headers = merge(config.headers, args.headers); } if (!args.headers['Timekit-App'] && config.app) { args.headers['Timekit-App'] = config.app; } if (config.inputTimestampFormat) { args.headers['Timekit-InputTimestampFormat'] = config.inputTimestampFormat; } if (config.outputTimestampFormat) { args.headers['Timekit-OutputTimestampFormat'] = config.outputTimestampFormat; } if (config.timezone) { args.headers['Timekit-Timezone'] = config.timezone; } // add auth headers (personal token) if not being overwritten by request/asUser if ( !args.headers['Authorization'] && config.resourceEmail && config.resourceKey ) { args.headers['Authorization'] = 'Basic ' + utils.encodeAuthHeader(config.resourceEmail, config.resourceKey); } // add auth headers (app token) if (!args.headers['Authorization'] && config.appKey) { args.headers['Authorization'] = 'Basic ' + utils.encodeAuthHeader('', config.appKey); } // reset headers if (Object.keys(headers).length > 0) { headers = {}; } // add dynamic includes if applicable if (includes && includes.length > 0) { if (args.params === undefined) { args.params = {}; } args.params.include = includes.join(); includes = []; } // decamelize keys in data objects if (args.data && config.convertRequestToSnakecase) { args.data = humps.decamelizeKeys(args.data); } // register response interceptor for data manipulation var interceptor = axios.interceptors.response.use( function (response) { if (response.data && response.data.data) { if (config.autoFlattenResponse) { response = utils.copyResponseMetaData(response); } if (config.convertResponseToCamelcase) { response.data = humps.camelizeKeys(response.data); } } return response; }, function (error) { if (error.response) { return Promise.reject(error.response); } else if (error.request) { return Promise.reject(error.request); } return Promise.reject(error); } ); // execute request! var request = axios(args); // deregister response interceptor axios.interceptors.response.eject(interceptor); return request; }; /** * Overwrite default config with supplied settings * @type {Function} * @return {Object} */ TK.configure = function (custom) { for (var attr in custom) { config[attr] = custom[attr]; } return config; }; /** * Returns the current config * @type {Function} * @return {Object} */ TK.getConfig = function () { return config; }; /** * Set the active user manually (happens automatically on timekit.auth()) * @type {Function} */ TK.setUser = function (email, apiKey) { config.resourceEmail = email; config.resourceKey = apiKey; }; /** * Returns the current active user * @type {Function} * @return {Object} */ TK.getUser = function () { return { email: config.resourceEmail, apiToken: config.resourceKey, }; }; /** * Set app token (happens automatically on timekit.auth()) * @type {Function} */ TK.setAppKey = function (apiKey) { config.appKey = apiKey; }; /** * Returns the app token * @type {Function} * @return {Object} */ TK.getAppKey = function () { return config.appKey; }; /** * Set the active user temporarily for the next request (fluent/chainable return) * @type {Function} */ TK.asUser = function (email, apiKey) { headers['Authorization'] = 'Basic ' + utils.encodeAuthHeader(email, apiKey); return this; }; /** * Set the timekit app slug temporarily for the next request (fluent/chainable return) * @type {Function} */ TK.asApp = function (slug) { headers['Timekit-App'] = slug; return this; }; /** * Add supplied dynamic includes to the next request (fluent/chainable return) * @type {Function} * @return {Object} */ TK.include = function (arg) { if (Array.isArray(arg)) includes = arg; else includes = Array.prototype.slice.call(arguments); return this; }; /** * Add supplied headers to the next request (fluent/chainable return) * @type {Function} * @return {Object} */ TK.headers = function (data) { headers = merge(headers, data); return this; }; /** * Add supplied payload to the next request only * @type {Function} * @return {Object} */ TK.carry = function (data) { nextPayload = merge(nextPayload, data); return this; }; /** * Return a new instance of the SDK * @type {Function} * @return {Object} */ TK.newInstance = function () { return new Timekit(); }; /** * Redirect to the Google signup/login page * Kept this in this file (not endpoints.js) because of internal dependencies to headers, config etc. * @type {Function} * @return {String} */ TK.accountGoogleSignup = function (data, shouldAutoRedirect) { var app = config.app; // If app header exists (using .asApp() function), use that if (headers['Timekit-App']) { app = headers['Timekit-App']; } var baseUrl = utils.buildUrl('/accounts/google/signup', config); var finalUrl = baseUrl + '?Timekit-App=' + app + (data && data.callback ? '&callback=' + data.callback : ''); if (shouldAutoRedirect && window) { window.location.href = finalUrl; } else { return finalUrl; } }; /** * Redirect to the Microsoft signup/login page * Kept this in this file (not endpoints.js) because of internal dependencies to headers, config etc. * @type {Function} * @return {String} */ TK.accountMicrosoftSignup = function (data, shouldAutoRedirect) { var app = config.app; // If app header exists (using .asApp() function), use that if (headers['Timekit-App']) { app = headers['Timekit-App']; } var baseUrl = utils.buildUrl('/accounts/microsoft/signup', config); var finalUrl = baseUrl + '?Timekit-App=' + app + (data && data.callback ? '&callback=' + data.callback : ''); if (shouldAutoRedirect && window) { window.location.href = finalUrl; } else { return finalUrl; } }; /** * Import endpoint defintions */ TK = endpoints(TK); /** * Import deprecated endpoint defintions */ TK = deprecatedEndpoints(TK); return TK; } module.exports = new Timekit();