Socket
Socket
Sign inDemoInstall

dispatch-node-sdk

Package Overview
Dependencies
Maintainers
4
Versions
148
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dispatch-node-sdk - npm Package Compare versions

Comparing version 3.8.1 to 3.9.0

3

dist/lib/analytics.js

@@ -113,5 +113,6 @@ 'use strict';

LITE_SKIP_SCHEDULE: 'schedule_date/time_skipped_lite', // 'Schedule date/time skipped on lite page'
RESET_TO_SCHEDULED: 'reset_to_scheduled_clicked_lite' }
RESET_TO_SCHEDULED: 'reset_to_scheduled_clicked_lite' // 'Tapped reset to scheduled button'
}
};
exports.default = Analytics;

@@ -21,4 +21,4 @@ 'use strict';

var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var accountId = offerData.accountId;
var data = offerData.data;
var accountId = offerData.accountId,
data = offerData.data;

@@ -25,0 +25,0 @@ var headers = _extends({}, options.headers, {

@@ -11,2 +11,26 @@ 'use strict';

var _map = require('lodash/map');
var _map2 = _interopRequireDefault(_map);
var _entries = require('lodash/entries');
var _entries2 = _interopRequireDefault(_entries);
var _uniq = require('lodash/uniq');
var _uniq2 = _interopRequireDefault(_uniq);
var _includes = require('lodash/includes');
var _includes2 = _interopRequireDefault(_includes);
var _omit = require('lodash/omit');
var _omit2 = _interopRequireDefault(_omit);
var _isEmpty = require('lodash/isEmpty');
var _isEmpty2 = _interopRequireDefault(_isEmpty);
var _endpoints = require('./endpoints');

@@ -20,6 +44,2 @@

var _underscore = require('underscore');
var _underscore2 = _interopRequireDefault(_underscore);
var _appointment = require('./entities/appointment');

@@ -101,6 +121,6 @@

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

@@ -608,3 +628,3 @@

var analytics = Object.assign({}, this.session, options.analytics);
var analyticsTags = _underscore2.default.map(_underscore2.default.pairs(analytics), function (param) {
var analyticsTags = (0, _map2.default)((0, _entries2.default)(analytics), function (param) {
return param.join(':');

@@ -739,6 +759,6 @@ }).join(',');

var organizationID = _ref.organizationID;
var query = _ref.query;
var filter = _ref.filter;
var maxResultsPerModel = _ref.maxResultsPerModel;
var organizationID = _ref.organizationID,
query = _ref.query,
filter = _ref.filter,
maxResultsPerModel = _ref.maxResultsPerModel;

@@ -766,3 +786,3 @@ var customers = void 0;

}, []);
list[field] = _underscore2.default.uniq(list[field]);
list[field] = (0, _uniq2.default)(list[field]);
} else {

@@ -789,3 +809,3 @@ list[field] = matches[field].matchedWords || [];

Object.getOwnPropertyNames(obj || {}).forEach(function (prop) {
if (Array.isArray(obj[prop]) && !_underscore2.default.contains(skipProps, prop)) {
if (Array.isArray(obj[prop]) && !(0, _includes2.default)(skipProps, prop)) {
obj[prop] = obj[prop].join('; ');

@@ -805,3 +825,3 @@ }

customers = customers.map(function (customer) {
var adjustedCustomer = _underscore2.default.omit(customer, '_highlightResult');
var adjustedCustomer = (0, _omit2.default)(customer, '_highlightResult');
arraysToStrings(adjustedCustomer, ['external_ids', 'phone_numbers']);

@@ -817,5 +837,5 @@

jobs = jobs.map(function (job) {
var appointment = job.next_scheduled_appointment && !_underscore2.default.isEmpty(job.next_scheduled_appointment) && getNextAppointmentTime(job.next_scheduled_appointment);
var appointment = job.next_scheduled_appointment && !(0, _isEmpty2.default)(job.next_scheduled_appointment) && getNextAppointmentTime(job.next_scheduled_appointment);
var adjustedJob = _underscore2.default.omit(job, '_highlightResult', 'next_scheduled_appointment');
var adjustedJob = (0, _omit2.default)(job, '_highlightResult', 'next_scheduled_appointment');
arraysToStrings(adjustedJob, ['labels']);

@@ -902,3 +922,3 @@

return new Promise(function (resolve, reject) {
_this9.entities.customers.update(id, _underscore2.default.omit(customerInfo, 'id')).then(function (customer) {
_this9.entities.customers.update(id, (0, _omit2.default)(customerInfo, 'id')).then(function (customer) {
resolveCustomer(resolve, customer);

@@ -905,0 +925,0 @@ }).catch(function (err) {

@@ -102,4 +102,4 @@ 'use strict';

return this.getWithMeta(_extends({}, query, { limit: 0 })).then(function (_ref) {
var _ref$meta = _ref.meta;
var meta = _ref$meta === undefined ? {} : _ref$meta;
var _ref$meta = _ref.meta,
meta = _ref$meta === undefined ? {} : _ref$meta;

@@ -106,0 +106,0 @@ return meta.total;

@@ -13,4 +13,4 @@ 'use strict';

getConversation: function getConversation(_ref) {
var organizationID = _ref.organizationID;
var customerUserID = _ref.customerUserID;
var organizationID = _ref.organizationID,
customerUserID = _ref.customerUserID;

@@ -17,0 +17,0 @@ if (!organizationID || !customerUserID) {

@@ -20,5 +20,5 @@ 'use strict';

pay: function pay(_ref) {
var amount = _ref.amount;
var cardToken = _ref.cardToken;
var paymentMethod = _ref.paymentMethod;
var amount = _ref.amount,
cardToken = _ref.cardToken,
paymentMethod = _ref.paymentMethod;

@@ -25,0 +25,0 @@ if (cardToken) {

@@ -11,5 +11,5 @@ 'use strict';

var _underscore = require('underscore');
var _isEmpty = require('lodash/isEmpty');
var _underscore2 = _interopRequireDefault(_underscore);
var _isEmpty2 = _interopRequireDefault(_isEmpty);

@@ -49,5 +49,5 @@ var _endpoints = require('../endpoints');

return client.entities.jobs.getOne(id).then(function (_ref) {
var organization_id = _ref.organization_id;
var _ref$customer = _ref.customer;
var customer = _ref$customer === undefined ? {} : _ref$customer;
var orgId = _ref.organization_id,
_ref$customer = _ref.customer,
customer = _ref$customer === undefined ? {} : _ref$customer;

@@ -60,3 +60,3 @@ return client.entities.billingDocuments.create({

job_id: id,
organization_id: organization_id
organization_id: orgId
});

@@ -80,3 +80,3 @@ });

if (action === 'accept') {
if (_underscore2.default.isEmpty(body)) {
if ((0, _isEmpty2.default)(body)) {
return client.doAuthenticatedRequest('POST', endpoints.WORK_ORDER_GOVERNANCE_SERVICE + '/' + id + '/accept', {}, options).then(function (response) {

@@ -83,0 +83,0 @@ return { status: response.new_job_status };

@@ -8,9 +8,9 @@ 'use strict';

exports.default = function () {
return _nodeUuid2.default.v4();
return (0, _v2.default)();
};
var _nodeUuid = require('node-uuid');
var _v = require('uuid/v4');
var _nodeUuid2 = _interopRequireDefault(_nodeUuid);
var _v2 = _interopRequireDefault(_v);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -6,8 +6,17 @@ 'use strict';

});
exports.generateSignature = generateSignature;
exports.default = getAuthHeaders;
var _crypto = require('crypto');
var _hmacSha = require('crypto-js/hmac-sha1');
var _crypto2 = _interopRequireDefault(_crypto);
var _hmacSha2 = _interopRequireDefault(_hmacSha);
var _encBase = require('crypto-js/enc-base64');
var _encBase2 = _interopRequireDefault(_encBase);
var _md = require('crypto-js/md5');
var _md2 = _interopRequireDefault(_md);
var _moment = require('moment');

@@ -19,2 +28,8 @@

function generateSignature(path, contentMD5, requestTime, secret) {
var components = ['application/json', contentMD5, path, requestTime];
var signature = (0, _hmacSha2.default)(components.join(','), secret);
return signature.toString(_encBase2.default);
}
/**

@@ -32,7 +47,7 @@ * Calculate the request headers for HMAC signature authentication

function getAuthHeaders(_ref) {
var path = _ref.path;
var body = _ref.body;
var userID = _ref.userID;
var userType = _ref.userType;
var secret = _ref.secret;
var path = _ref.path,
body = _ref.body,
userID = _ref.userID,
userType = _ref.userType,
secret = _ref.secret;

@@ -43,16 +58,8 @@ // Date must be formatted like this:

var signature = _crypto2.default.createHmac('sha1', secret);
var md5 = _crypto2.default.createHash('md5');
// NOTE: For now, this is an arbitrary "nonce" type of operation. So we just
// generate an md5 string from the body + the requestTime, and set it as
// Content-MD5. Eventually we might add MD5 content verification to the API.
md5.update(JSON.stringify(body) || '');
var md5 = (0, _md2.default)(JSON.stringify(body) || '');
var md5Value = md5.toString(_encBase2.default);
var md5Value = md5.digest('base64');
var components = ['application/json', md5Value, path, requestTime];
signature.update(components.join(','));
return {

@@ -62,4 +69,4 @@ 'Content-Type': 'application/json',

Date: requestTime,
Authorization: 'APIAuth ' + userType + '-' + userID + ':' + signature.digest('base64')
Authorization: 'APIAuth ' + userType + '-' + userID + ':' + generateSignature(path, md5Value, requestTime, secret)
};
}

@@ -10,4 +10,6 @@ 'use strict';

var _simplecheck = require('simplecheck');
var _includes = require('lodash/includes');
var _includes2 = _interopRequireDefault(_includes);
var _getAuthHeaders = require('./getAuthHeaders');

@@ -31,2 +33,4 @@

var validAuthModes = [AUTH_MODE_BEARER, AUTH_MODE_HMAC, AUTH_MODE_NONE];
/**

@@ -44,2 +48,3 @@ * Low-level client for interacting with the API.

*/
var RawClient = function () {

@@ -50,4 +55,7 @@ function RawClient(options) {

var authMode = options.authMode || AUTH_MODE_BEARER;
(0, _simplecheck.ensure)(authMode, (0, _simplecheck.oneOf)(AUTH_MODE_HMAC, AUTH_MODE_BEARER, AUTH_MODE_NONE));
if (!(0, _includes2.default)(validAuthModes, authMode)) {
throw new Error('Invalid auth mode `' + authMode + '`, expected one of ' + validAuthModes.join(', '));
}
this.authMode = authMode;

@@ -54,0 +62,0 @@

@@ -25,3 +25,3 @@ import expect from 'expect';

it('calculates duration with getDuration', () => {
appointments.forEach(appointment => {
appointments.forEach((appointment) => {
expect(AppointmentHelpers.getDuration(appointment.startTime, appointment.endTime)).toEqual(appointment.duration);

@@ -32,3 +32,3 @@ });

it('calculates endTime with getEndTime', () => {
appointments.forEach(appointment => {
appointments.forEach((appointment) => {
expect(AppointmentHelpers.getEndTime(appointment.startTime, appointment.duration)).toEqual(appointment.endTime);

@@ -39,3 +39,3 @@ });

it('calculates duration with getDuration and getEndTime', () => {
appointments.forEach(appointment => {
appointments.forEach((appointment) => {
const endTime = AppointmentHelpers.getEndTime(appointment.startTime, appointment.duration);

@@ -42,0 +42,0 @@ expect(AppointmentHelpers.getDuration(appointment.startTime, endTime)).toEqual(appointment.duration);

@@ -17,3 +17,3 @@ import expect from 'expect';

describe('getForEntity', () => {
it('should make correct API call', done => {
it('should make correct API call', (done) => {
const req = nock('https://api.dispatch.me').get('/config/foo/123?accountId=10').reply(200, {

@@ -24,3 +24,3 @@ foo: 'bar',

accountId: 10,
}).then(response => {
}).then((response) => {
expect(response).toEqual({ foo: 'bar' });

@@ -34,3 +34,3 @@ expect(req.isDone()).toEqual(true);

describe('setForEntity', () => {
it('should make correct API call', done => {
it('should make correct API call', (done) => {
const req = nock('https://api.dispatch.me').post('/config/foo/123', {

@@ -47,3 +47,3 @@ config: {

foo: 'bar',
}, false).then(response => {
}, false).then((response) => {
expect(response).toEqual({ foo: 'bar' });

@@ -57,7 +57,7 @@ expect(req.isDone()).toEqual(true);

describe('getDefault', () => {
it('should make correct API call', done => {
it('should make correct API call', (done) => {
const req = nock('https://api.dispatch.me').get('/config/default').reply(200, {
foo: 'bar',
});
client.configuration.getDefault().then(response => {
client.configuration.getDefault().then((response) => {
expect(response).toEqual({ foo: 'bar' });

@@ -71,3 +71,3 @@ expect(req.isDone()).toEqual(true);

describe('setDefaultForPrefix', () => {
it('should make correct API call', done => {
it('should make correct API call', (done) => {
const req = nock('https://api.dispatch.me').post('/config/default', {

@@ -84,3 +84,3 @@ config: {

foo: 'bar',
}).then(response => {
}).then((response) => {
expect(response).toEqual({ foo: 'bar' });

@@ -94,7 +94,7 @@ expect(req.isDone()).toEqual(true);

describe('schema', () => {
it('should make correct API call', done => {
it('should make correct API call', (done) => {
const req = nock('https://api.dispatch.me').get('/config/schema').reply(200, {
foo: 'bar',
});
client.configuration.schema().then(response => {
client.configuration.schema().then((response) => {
expect(response).toEqual({ foo: 'bar' });

@@ -108,5 +108,5 @@ expect(req.isDone()).toEqual(true);

describe('eventsList', () => {
it('should make correct API call', done => {
it('should make correct API call', (done) => {
const req = nock('https://api.dispatch.me').get('/config/events_list').reply(200, ['a', 'b']);
client.configuration.eventsList().then(response => {
client.configuration.eventsList().then((response) => {
expect(response).toEqual(['a', 'b']);

@@ -120,7 +120,7 @@ expect(req.isDone()).toEqual(true);

describe('report', () => {
it('should make correct API call', done => {
it('should make correct API call', (done) => {
const req = nock('https://api.dispatch.me').get('/config/report/app').reply(200, {
report: 'bar',
});
client.configuration.report('app').then(response => {
client.configuration.report('app').then((response) => {
expect(response).toEqual({ report: 'bar' });

@@ -127,0 +127,0 @@ expect(req.isDone()).toEqual(true);

@@ -0,4 +1,9 @@

import map from 'lodash/map';
import entries from 'lodash/entries';
import uniq from 'lodash/uniq';
import includes from 'lodash/includes';
import omit from 'lodash/omit';
import isEmpty from 'lodash/isEmpty';
import * as endpoints from './endpoints';
import * as queryString from './queryString';
import _ from 'underscore';
import appointmentMethods from './entities/appointment';

@@ -199,3 +204,3 @@ import attachmentMethods from './entities/attachment';

client_secret: this.clientSecret,
}).then(response => {
}).then((response) => {
this.appClient = new RawClient({

@@ -232,3 +237,3 @@ auditAction: this.auditAction,

this.onBearerTokenHooks.forEach(hook => {
this.onBearerTokenHooks.forEach((hook) => {
hook(this);

@@ -265,3 +270,3 @@ });

})
.then(response => this.handleBearerToken(response.access_token, response.refresh_token));
.then(response => this.handleBearerToken(response.access_token, response.refresh_token));
}

@@ -342,3 +347,3 @@

return this.getAppClient().then(client => client.get(`/v1/phone_numbers/${phoneNumber}/verification_codes/${verificationCode}`))
.then(response => this.handleBearerToken(response.access_token, response.refresh_token));
.then(response => this.handleBearerToken(response.access_token, response.refresh_token));
}

@@ -353,3 +358,3 @@

return this.doAuthenticatedRequest('GET', '/v1/me')
.then(response => response[Object.keys(response)[0]]);
.then(response => response[Object.keys(response)[0]]);
}

@@ -385,3 +390,3 @@

}
return this.doAuthenticatedRequest('GET', fullPath).then(response => {
return this.doAuthenticatedRequest('GET', fullPath).then((response) => {
if (opts.raw === true) {

@@ -403,6 +408,6 @@ return response;

getCollectionWithMeta(endpoint, filter = null) {
return this.getCollection(endpoint, filter, { raw: true }).then(response => {
return this.getCollection(endpoint, filter, { raw: true }).then((response) => {
let meta = {};
let data = Object.keys(response).length > 2 ? {} : [];
Object.keys(response).forEach(prop => {
Object.keys(response).forEach((prop) => {
if (prop === 'meta') {

@@ -427,3 +432,3 @@ meta = response[prop];

const analytics = Object.assign({}, this.session, options.analytics);
const analyticsTags = _.map(_.pairs(analytics), param => param.join(':')).join(',');
const analyticsTags = map(entries(analytics), param => param.join(':')).join(',');
const transactionId = options.transactionID || generateUUID();

@@ -463,3 +468,3 @@

.then(resolve)
.catch(err => {
.catch((err) => {
if (err instanceof UnauthorizedError) {

@@ -491,3 +496,3 @@ if (this.refreshToken) {

getModel(endpoint, id) {
return this.doAuthenticatedRequest('GET', `${endpoint}?filter[id_eq]=${id}`).then(response => {
return this.doAuthenticatedRequest('GET', `${endpoint}?filter[id_eq]=${id}`).then((response) => {
const model = response[Object.keys(response)[0]][0];

@@ -536,3 +541,5 @@ if (!model) {

*/
search({ organizationID, query, filter, maxResultsPerModel }) {
search({
organizationID, query, filter, maxResultsPerModel,
}) {
let customers;

@@ -550,3 +557,3 @@ let host;

const list = {};
Object.getOwnPropertyNames(matches).forEach(field => {
Object.getOwnPropertyNames(matches).forEach((field) => {
// Some like external_ids and notes are arrays

@@ -558,3 +565,3 @@ if (Array.isArray(matches[field])) {

}, []);
list[field] = _.uniq(list[field]);
list[field] = uniq(list[field]);
} else {

@@ -578,4 +585,4 @@ list[field] = matches[field].matchedWords || [];

function arraysToStrings(obj, skipProps = []) {
Object.getOwnPropertyNames(obj || {}).forEach(prop => {
if (Array.isArray(obj[prop]) && !_.contains(skipProps, prop)) {
Object.getOwnPropertyNames(obj || {}).forEach((prop) => {
if (Array.isArray(obj[prop]) && !includes(skipProps, prop)) {
obj[prop] = obj[prop].join('; ');

@@ -590,3 +597,3 @@ }

return this.getAuthClient().get(`${endpoints.SEARCH}?organization_id=${organizationID}&q=${query}${limitQuery}${filterQuery}`)
.then(response => {
.then((response) => {
host = this.determineAuxiliaryAPIHost('files-api');

@@ -596,4 +603,4 @@

customers = response.customer && response.customer.hits || [];
customers = customers.map(customer => {
const adjustedCustomer = _.omit(customer, '_highlightResult');
customers = customers.map((customer) => {
const adjustedCustomer = omit(customer, '_highlightResult');
arraysToStrings(adjustedCustomer, ['external_ids', 'phone_numbers']);

@@ -609,8 +616,8 @@

jobs = response.job && response.job.hits || [];
jobs = jobs.map(job => {
jobs = jobs.map((job) => {
const appointment = job.next_scheduled_appointment &&
!_.isEmpty(job.next_scheduled_appointment) &&
!isEmpty(job.next_scheduled_appointment) &&
getNextAppointmentTime(job.next_scheduled_appointment);
const adjustedJob = _.omit(job, '_highlightResult', 'next_scheduled_appointment');
const adjustedJob = omit(job, '_highlightResult', 'next_scheduled_appointment');
arraysToStrings(adjustedJob, ['labels']);

@@ -690,5 +697,5 @@

return new Promise((resolve, reject) => {
this.entities.customers.update(id, _.omit(customerInfo, 'id'))
.then(customer => { resolveCustomer(resolve, customer); })
.catch(err => { rejectCustomer(reject, err); });
this.entities.customers.update(id, omit(customerInfo, 'id'))
.then((customer) => { resolveCustomer(resolve, customer); })
.catch((err) => { rejectCustomer(reject, err); });
});

@@ -700,4 +707,4 @@ }

this.entities.customers.create(customerInfo)
.then(customer => { resolveCustomer(resolve, customer); })
.catch(err => { rejectCustomer(reject, err); });
.then((customer) => { resolveCustomer(resolve, customer); })
.catch((err) => { rejectCustomer(reject, err); });
});

@@ -709,3 +716,3 @@ };

this.entities.jobs.create(jobInfo)
.then(job => {
.then((job) => {
returnData.job = job;

@@ -717,3 +724,3 @@ if (appointmentInfo) {

})
.catch(err => {
.catch((err) => {
errorData.job = err;

@@ -733,7 +740,7 @@ reject(err);

this.entities.appointmentSeries.create(appointmentInfo)
.then(appointmentSeries => {
.then((appointmentSeries) => {
returnData.appointmentSeries = appointmentSeries;
resolve();
})
.catch(err => {
.catch((err) => {
errorData.appointmentSeries = err;

@@ -747,7 +754,7 @@ reject(err);

this.entities.appointments.create(appointmentInfo)
.then(appointment => {
.then((appointment) => {
returnData.appointment = appointment;
resolve();
})
.catch(err => {
.catch((err) => {
errorData.appointment = err;

@@ -754,0 +761,0 @@ reject(err);

@@ -38,3 +38,3 @@ import nock from 'nock';

client.authClient = 'foo';
client.loginEmailPassword(testEmail, testPassword).then(token => {
client.loginEmailPassword(testEmail, testPassword).then((token) => {
expect(token).toEqual(testBearerToken);

@@ -81,3 +81,3 @@ expect(client.bearerToken).toEqual(testBearerToken);

client.loginEmailPassword(testEmail, testPassword).then(token => {
client.loginEmailPassword(testEmail, testPassword).then((token) => {
expect(token).toEqual(testBearerToken);

@@ -90,3 +90,3 @@ expect(client.bearerToken).toEqual(testBearerToken);

client.doAuthenticatedRequest('GET', '/').then(response => {
client.doAuthenticatedRequest('GET', '/').then((response) => {
expect(response.foo).toEqual('bar');

@@ -117,3 +117,3 @@ expect(client.bearerToken).toEqual('new access token');

const client = new Dispatch(testClientID, testClientSecret);
client.requestVerificationCode(testPhoneNumber).then(response => {
client.requestVerificationCode(testPhoneNumber).then((response) => {
expect(response.message).toEqual('Verification code requested');

@@ -141,3 +141,3 @@ req.done();

const client = new Dispatch(testClientID, testClientSecret);
client.loginPhoneNumber(testPhoneNumber, testVerificationCode).then(token => {
client.loginPhoneNumber(testPhoneNumber, testVerificationCode).then((token) => {
expect(token).toEqual(testBearerToken);

@@ -151,3 +151,3 @@ expect(client.bearerToken).toEqual(testBearerToken);

it('should log in with auth token', done => {
it('should log in with auth token', (done) => {
const req = nock(dispatchUrl).post('/v1/auth_tokens/12345/exchange').reply(200, {

@@ -159,3 +159,3 @@ access_token: testBearerToken,

const client = new Dispatch(testClientID, testClientSecret);
client.loginAuthToken('12345').then(token => {
client.loginAuthToken('12345').then((token) => {
expect(token).toEqual(testBearerToken);

@@ -186,3 +186,3 @@ expect(client.bearerToken).toEqual(testBearerToken);

client.getCollection('/v1/jobs', null).then(collection => {
client.getCollection('/v1/jobs', null).then((collection) => {
expect(collection.length).toEqual(2);

@@ -195,3 +195,3 @@ expect(collection[0].status).toEqual('unscheduled');

it('should return meta data with getCollectionMeta', done => {
it('should return meta data with getCollectionMeta', (done) => {
const client = new Dispatch(testClientID, testClientSecret, devDispatchUrl);

@@ -221,3 +221,3 @@ const query = { limit: 1, offset: 0 };

});
client.getCollectionWithMeta('/v1/customers', query).then(response => {
client.getCollectionWithMeta('/v1/customers', query).then((response) => {
expect(response.data.length).toEqual(1);

@@ -233,3 +233,3 @@ expect(response.meta).toEqual({

it('should return meta data as an object (if !meta props are more than 1) with getCollectionMeta', done => {
it('should return meta data as an object (if !meta props are more than 1) with getCollectionMeta', (done) => {
const client = new Dispatch(testClientID, testClientSecret, devDispatchUrl);

@@ -273,3 +273,3 @@ const query = { limit: 1, offset: 0 };

});
client.getCollectionWithMeta('/v1/customers', query).then(response => {
client.getCollectionWithMeta('/v1/customers', query).then((response) => {
expect(Object.keys(response.data).length).toEqual(2);

@@ -301,3 +301,3 @@ expect(response.meta).toEqual({

client.getCollection('/v1/jobs', null, { raw: true }).then(response => {
client.getCollection('/v1/jobs', null, { raw: true }).then((response) => {
expect(response.jobs.length).toEqual(2);

@@ -321,3 +321,3 @@ done();

client.getModel('/v1/jobs', 1).then(model => {
client.getModel('/v1/jobs', 1).then((model) => {
expect(model.status).toEqual('unscheduled');

@@ -329,3 +329,3 @@ done();

describe('wrapped authenticated request', () => {
it('should try to refresh the bearer token when doing an authenticated request', done => {
it('should try to refresh the bearer token when doing an authenticated request', (done) => {
const client = new Dispatch(testClientID, testClientSecret);

@@ -349,3 +349,3 @@ nock(dispatchUrl).get('/').times(1).reply(401);

client.doAuthenticatedRequest('GET', '/').then(response => {
client.doAuthenticatedRequest('GET', '/').then((response) => {
expect(response.foo).toEqual('bar');

@@ -358,3 +358,3 @@ expect(client.bearerToken).toEqual('new access token');

it('should fail without a refresh token', done => {
it('should fail without a refresh token', (done) => {
const client = new Dispatch(testClientID, testClientSecret);

@@ -380,3 +380,3 @@ nock(dispatchUrl).get('/').times(1).reply(401);

done(new Error('Should not have worked'));
}).catch(err => {
}).catch((err) => {
expect(err instanceof UnauthorizedError).toEqual(true);

@@ -397,3 +397,3 @@ done();

it('should append a transaction ID to the headers of an authenticated request', done => {
it('should append a transaction ID to the headers of an authenticated request', (done) => {
const client = new Dispatch(testClientID, testClientSecret);

@@ -420,3 +420,3 @@ nock(dispatchUrl).get('/').times(1).reply(function reply() {

it('should append an analytics tags to the headers of an authenticated request', done => {
it('should append an analytics tags to the headers of an authenticated request', (done) => {
const client = new Dispatch(testClientID, testClientSecret);

@@ -443,3 +443,3 @@ nock(dispatchUrl).get('/').times(1).reply(function reply() {

it('should append session params to the analytics tags to the headers of an authenticated request', done => {
it('should append session params to the analytics tags to the headers of an authenticated request', (done) => {
const client = new Dispatch(testClientID, testClientSecret);

@@ -470,3 +470,3 @@ nock(dispatchUrl).get('/').times(1).reply(function reply() {

describe('search', () => {
it('parses query from api', done => {
it('parses query from api', (done) => {
const client = new Dispatch(testClientID, testClientSecret);

@@ -588,3 +588,3 @@ nock(dispatchUrl).get('/v2/search?organization_id=5&q=fix').times(1).reply(200, {

query: 'fix',
}).then(result => {
}).then((result) => {
expect(result).toEqual({

@@ -664,3 +664,3 @@ customers: [

it('should upload to correct URL, but blob on server is BS');
/**
/**
const client = new Dispatch(testClientID, testClientSecret);

@@ -678,3 +678,3 @@ nock('https://files-api.dispatch.me').post('/v1/datafiles').reply(201, {

}).catch(done);
**/
* */
});

@@ -693,3 +693,3 @@

describe('error handling', () => {
it('should fail and store the customer error correctly if the customer creation fails', done => {
it('should fail and store the customer error correctly if the customer creation fails', (done) => {
spyOn(client.entities.customers, 'create').andReturn(Promise.reject(new UnprocessableEntityError({})));

@@ -701,3 +701,3 @@

done(new Error('Should not have worked man'));
}).catch(err => {
}).catch((err) => {
expect(err instanceof MultiActionError).toEqual(true);

@@ -711,3 +711,3 @@ expect(err.data.customer instanceof UnprocessableEntityError).toEqual(true);

it('should fail and store the job error correctly if the job creation fails', done => {
it('should fail and store the job error correctly if the job creation fails', (done) => {
spyOn(client.entities.customers, 'create').andReturn(Promise.resolve({

@@ -725,3 +725,3 @@ id: 123,

done(new Error('Should not have worked man'));
}).catch(err => {
}).catch((err) => {
expect(err instanceof MultiActionError).toEqual(true);

@@ -735,3 +735,3 @@ expect(err.data.customer).toEqual(null);

it('should fail and store the appointment error correctly if the appointment creation fails', done => {
it('should fail and store the appointment error correctly if the appointment creation fails', (done) => {
spyOn(client.entities.customers, 'create').andReturn(Promise.resolve({

@@ -755,3 +755,3 @@ id: 123,

done(new Error('Should not have worked man'));
}).catch(err => {
}).catch((err) => {
expect(err instanceof MultiActionError).toEqual(true);

@@ -767,3 +767,3 @@ expect(err.data.customer).toEqual(null);

describe('success', () => {
it('should make post requests with all correct data with appointment', done => {
it('should make post requests with all correct data with appointment', (done) => {
spyOn(client.entities.customers, 'create').andReturn(Promise.resolve({

@@ -825,3 +825,3 @@ id: 123,

it('should make patch request if customer id exists', done => {
it('should make patch request if customer id exists', (done) => {
spyOn(client.entities.customers, 'create').andCallThrough();

@@ -839,3 +839,3 @@ spyOn(client.entities.customers, 'update').andReturn(Promise.resolve({

client.createAndScheduleJob({ title: 'Royale' }, { id: 123, full_name: 'Same Dude' })
.then(response => {
.then((response) => {
expect(response).toEqual({

@@ -862,3 +862,3 @@ job: {

it('should make post request if customer id does not exist', done => {
it('should make post request if customer id does not exist', (done) => {
spyOn(client.entities.customers, 'update').andCallThrough();

@@ -876,3 +876,3 @@ spyOn(client.entities.customers, 'create').andReturn(Promise.resolve({

client.createAndScheduleJob({ title: 'Royale' }, { full_name: 'Same Dude' })
.then(response => {
.then((response) => {
expect(response).toEqual({

@@ -934,3 +934,3 @@ job: {

name: 'Test Org',
}).then(response => {
}).then((response) => {
expect(response.message).toEqual('Thanks for signing up!');

@@ -951,3 +951,3 @@ req.done();

client.signUp({}, {}).then(response => {
client.signUp({}, {}).then((response) => {
expect(response.organization instanceof UnprocessableEntityError).toEqual(true);

@@ -954,0 +954,0 @@ expect(response.user).toEqual(null);

@@ -8,3 +8,3 @@ import * as endpoints from '../endpoints';

return client
.doAuthenticatedRequest('PATCH', `${endpoints.APPOINTMENTS}/${id}/notify`, appointmentProperties, headerOptions);
.doAuthenticatedRequest('PATCH', `${endpoints.APPOINTMENTS}/${id}/notify`, appointmentProperties, headerOptions);
},

@@ -15,5 +15,5 @@

return client
.doAuthenticatedRequest('PATCH', `${endpoints.APPOINTMENTS}/${id}/suggested_times/${uuid}`);
.doAuthenticatedRequest('PATCH', `${endpoints.APPOINTMENTS}/${id}/suggested_times/${uuid}`);
},
});
}

@@ -5,2 +5,3 @@ import expect from 'expect';

import * as endpoints from '../endpoints';
const testClientID = '12345';

@@ -7,0 +8,0 @@ const testClientSecret = '54321';

@@ -8,3 +8,3 @@ import { ATTACHMENTS } from '../endpoints';

description: text,
}, options).then(response => {
}, options).then((response) => {
return response.attachment;

@@ -16,9 +16,9 @@ });

return client.doAuthenticatedRequest('DELETE', `${ATTACHMENTS}/${id}`, null, options)
.then(() => {
.then(() => {
// endpoint returns no content on successful request
// return id of successfully deleted item b/c its useful for resolve callbacks
return id;
});
return id;
});
},
});
}

@@ -5,2 +5,3 @@ import expect from 'expect';

import * as endpoints from '../endpoints';
const testClientID = '12345';

@@ -36,3 +37,3 @@ const testClientSecret = '54321';

client.entities.attachment(456).delete()
.then(id => {
.then((id) => {
expect(id).toEqual(456);

@@ -39,0 +40,0 @@ expect(scope.isDone()).toEqual(true);

@@ -26,3 +26,3 @@ /**

create(data, options = {}) {
return this.client.doAuthenticatedRequest('POST', this.endpoint, data, options).then(response => {
return this.client.doAuthenticatedRequest('POST', this.endpoint, data, options).then((response) => {
if (options.raw === true) {

@@ -41,3 +41,3 @@ return response;

return this.client.doAuthenticatedRequest('PATCH', this.getSingleEndpoint(id), data, options)
.then(response => {
.then((response) => {
if (options.raw === true) {

@@ -44,0 +44,0 @@ return response;

@@ -76,3 +76,3 @@ import expect from 'expect';

foo: 'bar',
}).then(data => {
}).then((data) => {
expect(scope.isDone()).toEqual(true);

@@ -105,3 +105,3 @@ expect(data).toEqual({

raw: true,
}).then(data => {
}).then((data) => {
expect(scope.isDone()).toEqual(true);

@@ -136,3 +136,3 @@ expect(data).toEqual({

foo: 'bar',
}).then(data => {
}).then((data) => {
expect(scope.isDone()).toEqual(true);

@@ -165,3 +165,3 @@ expect(data).toEqual({

raw: true,
}).then(data => {
}).then((data) => {
expect(scope.isDone()).toEqual(true);

@@ -168,0 +168,0 @@ expect(data).toEqual({

@@ -5,2 +5,3 @@ import expect from 'expect';

import * as endpoints from '../endpoints';
const testClientID = '12345';

@@ -7,0 +8,0 @@ const testClientSecret = '54321';

@@ -5,2 +5,3 @@ import expect from 'expect';

import { PAYMENTS } from '../endpoints';
const testClientID = '12345';

@@ -7,0 +8,0 @@ const testClientSecret = '54321';

@@ -1,2 +0,2 @@

import _ from 'underscore';
import isEmpty from 'lodash/isEmpty';

@@ -29,3 +29,3 @@ import * as endpoints from '../endpoints';

function addBillingDocument(client, id, docType) {
return client.entities.jobs.getOne(id).then(({ organization_id, customer = {} }) => {
return client.entities.jobs.getOne(id).then(({ organization_id: orgId, customer = {} }) => {
return client.entities.billingDocuments.create({

@@ -38,3 +38,3 @@ customer: {

job_id: id,
organization_id,
organization_id: orgId,
});

@@ -55,3 +55,3 @@ });

if (action === 'accept') {
if (_.isEmpty(body)) {
if (isEmpty(body)) {
return client.doAuthenticatedRequest('POST', `${endpoints.WORK_ORDER_GOVERNANCE_SERVICE}/${id}/accept`, {}, options)

@@ -165,8 +165,8 @@ .then((response) => {

})
.then(appts => {
if (appts.length) {
return appts[0];
}
return null;
});
.then((appts) => {
if (appts.length) {
return appts[0];
}
return null;
});
},

@@ -173,0 +173,0 @@

@@ -5,2 +5,3 @@ import expect from 'expect';

import * as endpoints from '../endpoints';
const testClientID = '12345';

@@ -28,3 +29,3 @@ const testClientSecret = '54321';

it('should parse response correctly', done => {
it('should parse response correctly', (done) => {
const client = new Dispatch(testClientID, testClientSecret);

@@ -42,3 +43,3 @@ client.setBearerToken(testBearerToken, testRefreshToken);

});
client.entities.job(123).getNotes().then(notes => {
client.entities.job(123).getNotes().then((notes) => {
expect(notes.length).toEqual(1);

@@ -79,3 +80,3 @@ expect(scope.isDone()).toEqual(true);

it('should parse response correctly', done => {
it('should parse response correctly', (done) => {
const client = new Dispatch(testClientID, testClientSecret);

@@ -93,3 +94,3 @@ client.setBearerToken(testBearerToken, testRefreshToken);

});
client.entities.job(123).getPhotos().then(notes => {
client.entities.job(123).getPhotos().then((notes) => {
expect(notes.length).toEqual(1);

@@ -320,3 +321,3 @@ expect(scope.isDone()).toEqual(true);

client.entities.job(123).update(invalidJobProperties)
.catch(reason => {
.catch((reason) => {
expect(reason.name).toEqual('UnprocessableEntityError');

@@ -326,3 +327,3 @@ });

it('should append a transaction ID to the headers of an authenticated request', done => {
it('should append a transaction ID to the headers of an authenticated request', (done) => {
const transactionID = '12345';

@@ -353,3 +354,3 @@ const scope = nock(dispatchUrl)

client.entities.job(123).accept().then(response => {
client.entities.job(123).accept().then((response) => {
expect(postJobRequest.isDone()).toEqual(true);

@@ -370,3 +371,3 @@ expect(response.status).toEqual('unscheduled');

client.entities.job(123).accept(null, body).then(response => {
client.entities.job(123).accept(null, body).then((response) => {
expect(jobRequestWithAppointment.isDone()).toEqual(true);

@@ -384,3 +385,3 @@ expect(response.status).toEqual('scheduled');

client.entities.job(123).reject('uhh').then(response => {
client.entities.job(123).reject('uhh').then((response) => {
expect(rejectJobRequest.isDone()).toEqual(true);

@@ -387,0 +388,0 @@ expect(response.status).toEqual('scheduled');

@@ -12,6 +12,6 @@ import { CONVERSATIONS, CUSTOMERS } from '../endpoints';

},
dateIsInWorkHours: date => {
dateIsInWorkHours: (date) => {
if (!id || !date) throw new Error('Usage: organization(id).dateIsInWorkHours(date)');
return client.entities.organizations.getOne(id)
.then(organization => {
.then((organization) => {
if (organization.working_hours && typeof organization.working_hours === 'object' &&

@@ -18,0 +18,0 @@ Object.keys(organization.working_hours).length > 0 && organization.timezone) {

@@ -79,3 +79,3 @@ import expect, { spyOn, restoreSpies } from 'expect';

describe('dateIsInWorkHours', () => {
it('should work for an organization that has hours and timezone set', done => {
it('should work for an organization that has hours and timezone set', (done) => {
spyOn(client.entities.organizations, 'getOne').andReturn(Promise.resolve({

@@ -89,3 +89,3 @@ timezone: 'Pacific Time (US & Canada)',

client.entities.organization(5).dateIsInWorkHours(date).then(result => {
client.entities.organization(5).dateIsInWorkHours(date).then((result) => {
expect(result).toEqual(true);

@@ -97,3 +97,3 @@ expect(workHours.inWorkHours).toHaveBeenCalledWith(testWorkHours, 'Pacific Time (US & Canada)', date);

it('should return false for an organization that has no timezone set', done => {
it('should return false for an organization that has no timezone set', (done) => {
spyOn(client.entities.organizations, 'getOne').andReturn(Promise.resolve({

@@ -106,3 +106,3 @@ working_hours: testWorkHours,

client.entities.organization(5).dateIsInWorkHours(date).then(result => {
client.entities.organization(5).dateIsInWorkHours(date).then((result) => {
expect(result).toEqual(false);

@@ -114,3 +114,3 @@ expect(workHours.inWorkHours).toNotHaveBeenCalled();

it('should return false for an organization that has no working_hours set', done => {
it('should return false for an organization that has no working_hours set', (done) => {
spyOn(client.entities.organizations, 'getOne').andReturn(Promise.resolve({

@@ -123,3 +123,3 @@ timezone: 'Pacific Time (US & Canada)',

client.entities.organization(5).dateIsInWorkHours(date).then(result => {
client.entities.organization(5).dateIsInWorkHours(date).then((result) => {
expect(result).toEqual(false);

@@ -126,0 +126,0 @@ expect(workHours.inWorkHours).toNotHaveBeenCalled();

@@ -10,3 +10,3 @@ import { PUBLIC_SURVEY_RESPONSES } from '../endpoints';

export default function surveyMethods (client) {
return (uid) => ({
return uid => ({
update: (surveyProperties) => {

@@ -13,0 +13,0 @@ return client

@@ -5,2 +5,3 @@ import expect from 'expect';

import { PUBLIC_SURVEY_RESPONSES } from '../endpoints';
const testClientID = '12345';

@@ -7,0 +8,0 @@ const testClientSecret = '54321';

@@ -5,6 +5,6 @@ import { inWorkHours } from '../workHours';

return id => ({
dateIsInWorkHours: date => {
dateIsInWorkHours: (date) => {
if (!id || !date) throw new Error('Usage: user(id).dateIsInWorkHours(date)');
return client.entities.users.getOne(id)
.then(user => {
.then((user) => {
// If they have working hours, use those. Otherwise use the ones from their organization.

@@ -15,3 +15,3 @@ if (user.working_hours && typeof user.working_hours === 'object' && Object.keys(user.working_hours).length > 0) {

return client.entities.organizations.getOne(user.organization_id)
.then(organization => {
.then((organization) => {
if (!organization.timezone) {

@@ -18,0 +18,0 @@ console.warn('No timezone for technician nor organization. Cannot calculate work hours');

@@ -47,3 +47,3 @@ import expect, { spyOn, restoreSpies } from 'expect';

describe('dateIsInWorkHours', () => {
it('should work for a user who has hours and timezone set', done => {
it('should work for a user who has hours and timezone set', (done) => {
spyOn(client.entities.users, 'getOne').andReturn(Promise.resolve({

@@ -58,3 +58,3 @@ organization_id: 5,

client.entities.user(1).dateIsInWorkHours(date).then(result => {
client.entities.user(1).dateIsInWorkHours(date).then((result) => {
expect(result).toEqual(true);

@@ -66,3 +66,3 @@ expect(workHours.inWorkHours).toHaveBeenCalledWith(testWorkHours, 'Pacific Time (US & Canada)', date);

it('should fetch and use organization timezone for a user who has no timezone set', done => {
it('should fetch and use organization timezone for a user who has no timezone set', (done) => {
spyOn(client.entities.users, 'getOne').andReturn(Promise.resolve({

@@ -79,3 +79,3 @@ organization_id: 5,

client.entities.user(1).dateIsInWorkHours(date).then(result => {
client.entities.user(1).dateIsInWorkHours(date).then((result) => {
expect(result).toEqual(true);

@@ -87,3 +87,3 @@ expect(workHours.inWorkHours).toHaveBeenCalledWith(testWorkHours, 'Pacific Time (US & Canada)', date);

it('should return organization answer for a user who has no working_hours set', done => {
it('should return organization answer for a user who has no working_hours set', (done) => {
spyOn(client.entities.users, 'getOne').andReturn(Promise.resolve({

@@ -101,3 +101,3 @@ organization_id: 5,

client.entities.user(1).dateIsInWorkHours(date).then(result => {
client.entities.user(1).dateIsInWorkHours(date).then((result) => {
expect(result).toEqual(true);

@@ -109,3 +109,3 @@ expect(workHours.inWorkHours).toHaveBeenCalledWith(testWorkHours, 'Pacific Time (US & Canada)', date);

it('should return false if user has working hours but neither user nor organization have timezone set', done => {
it('should return false if user has working hours but neither user nor organization have timezone set', (done) => {
spyOn(client.entities.users, 'getOne').andReturn(Promise.resolve({

@@ -122,3 +122,3 @@ organization_id: 5,

client.entities.organization(5).dateIsInWorkHours(date).then(result => {
client.entities.organization(5).dateIsInWorkHours(date).then((result) => {
expect(result).toEqual(false);

@@ -125,0 +125,0 @@ expect(workHours.inWorkHours).toNotHaveBeenCalled();

@@ -1,5 +0,5 @@

import UUID from 'node-uuid';
import uuidv4 from 'uuid/v4';
export default function () {
return UUID.v4();
return uuidv4();
}

@@ -1,4 +0,12 @@

import crypto from 'crypto';
import SHA1 from 'crypto-js/hmac-sha1';
import EncBase64 from 'crypto-js/enc-base64';
import MD5 from 'crypto-js/md5';
import moment from 'moment';
export function generateSignature(path, contentMD5, requestTime, secret) {
const components = ['application/json', contentMD5, path, requestTime];
const signature = SHA1(components.join(','), secret);
return signature.toString(EncBase64);
}
/**

@@ -15,3 +23,5 @@ * Calculate the request headers for HMAC signature authentication

*/
export default function getAuthHeaders({ path, body, userID, userType, secret }) {
export default function getAuthHeaders({
path, body, userID, userType, secret,
}) {
// Date must be formatted like this:

@@ -21,16 +31,8 @@ // Thu, 01 Oct 2015 19:30:40 GMT

const signature = crypto.createHmac('sha1', secret);
const md5 = crypto.createHash('md5');
// NOTE: For now, this is an arbitrary "nonce" type of operation. So we just
// generate an md5 string from the body + the requestTime, and set it as
// Content-MD5. Eventually we might add MD5 content verification to the API.
md5.update(JSON.stringify(body) || '');
const md5 = MD5(JSON.stringify(body) || '');
const md5Value = md5.toString(EncBase64);
const md5Value = md5.digest('base64');
const components = ['application/json', md5Value, path, requestTime];
signature.update(components.join(','));
return {

@@ -40,4 +42,4 @@ 'Content-Type': 'application/json',

Date: requestTime,
Authorization: `APIAuth ${userType}-${userID}:${signature.digest('base64')}`,
Authorization: `APIAuth ${userType}-${userID}:${generateSignature(path, md5Value, requestTime, secret)}`,
};
}

@@ -16,3 +16,3 @@ import expect from 'expect';

describe('getForEntity', () => {
it('should make correct API call', done => {
it('should make correct API call', (done) => {
const req = nock('https://api.dispatch.me').get('/products/foo/123?accountId=10').reply(200, {

@@ -23,3 +23,3 @@ foo: 'bar',

client.products.getForEntity('foo', 123, { accountId: 10 })
.then(response => {
.then((response) => {
expect(response).toEqual({ foo: 'bar' });

@@ -26,0 +26,0 @@ expect(req.isDone()).toEqual(true);

function getNodesList(obj) {
const nodes = [];
Object.getOwnPropertyNames(obj).forEach(prop => {
Object.getOwnPropertyNames(obj).forEach((prop) => {
const val = obj[prop];
if ((typeof val) === 'object') {
if (Array.isArray(val)) {
val.forEach(v => {
val.forEach((v) => {
nodes.push([prop, '', v]);

@@ -13,3 +13,3 @@ });

const nestedNodes = getNodesList(obj[prop]);
nestedNodes.forEach(v => {
nestedNodes.forEach((v) => {
nodes.push([prop, ...v]);

@@ -27,3 +27,3 @@ });

function nodesListToQueryString(nodesList, encode) {
return nodesList.map(node => {
return nodesList.map((node) => {
const val = node.pop();

@@ -30,0 +30,0 @@ let key = node.shift();

@@ -1,7 +0,4 @@

import { ensure, oneOf } from 'simplecheck';
import includes from 'lodash/includes';
import getAuthHeaders from './getAuthHeaders';
import fetch from 'isomorphic-fetch';
export const AUTH_MODE_HMAC = 'dispatch/AUTH_MODE_HMAC';
export const AUTH_MODE_BEARER = 'dispatch/AUTH_MODE_BEARER';
export const AUTH_MODE_NONE = 'dispatch/AUTH_MODE_NONE';
import {

@@ -15,3 +12,9 @@ UnauthorizedError,

export const AUTH_MODE_HMAC = 'dispatch/AUTH_MODE_HMAC';
export const AUTH_MODE_BEARER = 'dispatch/AUTH_MODE_BEARER';
export const AUTH_MODE_NONE = 'dispatch/AUTH_MODE_NONE';
const validAuthModes = [AUTH_MODE_BEARER, AUTH_MODE_HMAC, AUTH_MODE_NONE];
/**

@@ -32,4 +35,7 @@ * Low-level client for interacting with the API.

const authMode = options.authMode || AUTH_MODE_BEARER;
ensure(authMode, oneOf(AUTH_MODE_HMAC, AUTH_MODE_BEARER, AUTH_MODE_NONE));
if (!includes(validAuthModes, authMode)) {
throw new Error(`Invalid auth mode \`${authMode}\`, expected one of ${validAuthModes.join(', ')}`);
}
this.authMode = authMode;

@@ -144,33 +150,33 @@

return fetch(url, params)
.then(response => {
.then((response) => {
// 204 returns no content. short circuit to prevent parse errors.
if (response.status === 204) {
return {};
}
if (response.status === 204) {
return {};
}
if (response.status >= 200 && response.status < 300) {
return response.json()
.then(json => {
if (options.transform) return options.transform(json);
return json;
});
}
if (response.status >= 200 && response.status < 300) {
return response.json()
.then((json) => {
if (options.transform) return options.transform(json);
return json;
});
}
// Emit a different error with different data based on the status code
switch (response.status) {
case 401:
return Promise.reject(new UnauthorizedError());
case 422:
// Emit a different error with different data based on the status code
switch (response.status) {
case 401:
return Promise.reject(new UnauthorizedError());
case 422:
// The API is pretty descriptive of the validation errors so we can process
// the response in the error constructor
return response.json().then(json => Promise.reject(new UnprocessableEntityError(json)));
case 404:
return Promise.reject(new NotFoundError());
case 403:
return Promise.reject(new ForbiddenError());
default:
return response.text().then(text => Promise.reject(new APIError(text, response.status)));
}
});
return response.json().then(json => Promise.reject(new UnprocessableEntityError(json)));
case 404:
return Promise.reject(new NotFoundError());
case 403:
return Promise.reject(new ForbiddenError());
default:
return response.text().then(text => Promise.reject(new APIError(text, response.status)));
}
});
}
}

@@ -41,3 +41,3 @@ import expect from 'expect';

done(new Error('Should not have worked'));
}).catch(err => {
}).catch((err) => {
expect(err instanceof APIError).toEqual(true);

@@ -56,3 +56,3 @@ expect(scope.isDone()).toEqual(true);

done(new Error('Should not have worked'));
}).catch(err => {
}).catch((err) => {
expect(err instanceof UnauthorizedError).toEqual(true);

@@ -71,3 +71,3 @@ expect(scope.isDone()).toEqual(true);

done(new Error('Should not have worked'));
}).catch(err => {
}).catch((err) => {
expect(err instanceof NotFoundError).toEqual(true);

@@ -86,3 +86,3 @@ expect(scope.isDone()).toEqual(true);

done(new Error('Should not have worked'));
}).catch(err => {
}).catch((err) => {
expect(err instanceof ForbiddenError).toEqual(true);

@@ -103,3 +103,3 @@ expect(scope.isDone()).toEqual(true);

done(new Error('Should not have worked'));
}).catch(err => {
}).catch((err) => {
expect(err instanceof UnprocessableEntityError).toEqual(true);

@@ -106,0 +106,0 @@ expect(err.errors).toEqual(['error #1', 'error #2']);

@@ -45,3 +45,3 @@ import expect from 'expect';

params.forEach(param => {
params.forEach((param) => {
it(`should parse ${param.block} accurately`, () => {

@@ -91,3 +91,3 @@ expect(translateWorkHourBlock(param.block)).toEqual(param.expect);

}];
params.forEach(param => {
params.forEach((param) => {
it(`should parse ${param.date} accurately`, () => {

@@ -94,0 +94,0 @@ expect(inWorkHours(testWorkHours, null, param.date)).toEqual(param.expect);

{
"name": "dispatch-node-sdk",
"version": "3.8.1",
"version": "3.9.0",
"description": "High- and low-level libraries for interacting with the Dispatch API",
"main": "dist/lib/index.js",
"scripts": {
"build": "rm -rf dist && node_modules/.bin/babel lib --out-dir dist/lib --ignore '*.tests.js'",
"jscs": "jscs .",
"jscs:fix": "npm run jscs -- --fix || true",
"build": "rm -rf dist && babel lib --out-dir dist/lib --ignore '*.tests.js'",
"lint": "eslint .",
"lint:fix": "npm run lint -- --fix || true",
"mocha": "mocha --compilers js:babel-core/register --recursive 'lib/**/*.tests.js'",
"prepublish": "npm run build",
"mocha": "mocha --require babel-core/register --recursive 'lib/**/*.tests.js'",
"prepublishOnly": "npm run test && npm run build",
"test": "npm run lint && npm run mocha",
"test:cover": "istanbul cover _mocha -- --compilers js:babel-core/register --recursive 'lib/**/*.tests.js'",
"test:cover": "nyc mocha --require babel-core/register --recursive 'lib/**/*.tests.js'",
"test:watch": "npm run mocha -- --watch"

@@ -21,29 +19,36 @@ },

"devDependencies": {
"babel-cli": "6.x.x",
"babel-core": "6.x.x",
"babel-eslint": "6.0.4",
"babel-jscs": "^2.0.5",
"babel-loader": "^6.2.1",
"babel-preset-es2015": "6.x.x",
"babel-preset-stage-0": "^6.5.0",
"babel-register": "^6.4.3",
"eslint": "2.10.2",
"eslint-config-airbnb": "9.0.1",
"eslint-plugin-import": "1.8.0",
"eslint-plugin-jsx-a11y": "^1.5.5",
"eslint-plugin-react": "^5.2.2",
"expect": "^1.18.0",
"mocha": "^2.4.5",
"nock": "^8.0.0",
"timekeeper": "0.0.5"
"babel-cli": "6.26.0",
"babel-core": "6.26.3",
"babel-eslint": "8.2.3",
"babel-loader": "7.1.4",
"babel-preset-env": "1.7.0",
"babel-preset-stage-0": "6.24.1",
"babel-register": "6.26.0",
"crypto-js": "^3.1.9-1",
"eslint": "4.19.1",
"eslint-config-airbnb": "16.1.0",
"eslint-plugin-import": "2.11.0",
"eslint-plugin-jsx-a11y": "6.0.3",
"eslint-plugin-react": "7.7.0",
"expect": "1.20.2",
"form-data": "2.3.2",
"isomorphic-fetch": "2.2.1",
"lodash": "4.17.10",
"mocha": "5.1.1",
"moment": "2.22.1",
"moment-timezone": "0.5.16",
"nock": "9.2.5",
"nyc": "^11.7.3",
"timekeeper": "2.1.1",
"uuid": "3.2.1"
},
"dependencies": {
"form-data": "^1.0.0-rc4",
"isomorphic-fetch": "^2.2.1",
"moment": "^2.13.0",
"moment-timezone": "^0.5.4",
"node-uuid": "^1.4.7",
"simplecheck": "^0.1.2",
"underscore": "^1.8.3"
"peerDependencies": {
"crypto-js": ">= 3.1.9-1",
"form-data": ">= 2.3.2",
"isomorphic-fetch": ">= 2.2.1",
"lodash": ">= 4.17.10",
"moment": ">= 2.22.1",
"moment-timezone": ">= 0.5.16",
"uuid": ">= 3.2.1"
}
}

@@ -27,2 +27,27 @@ Dispatch JavaScript SDK

#### Version 3.9+
These dependencies are now peer dependencies and must be installed manually:
- crypto-js (formerly used Node's built-in crypto library, this caused a huge overhead when bundling for a web app)
- form-data (upgraded to latest major version)
- isomorphic-fetch (upgraded to latest major version)
- lodash (formerly used underscore, now using only minor parts of lodash)
- moment
- moment-timezone
- uuid (formerly used node-uuid, which is now deprecated)
For example (you may need to install specific versions):
```sh
# using npm
npm install --save crypto-js form-data isomorphic-fetch lodash moment moment-timezone uuid
# or with yarn
yarn add crypto-js form-data isomorphic-fetch lodash moment moment-timezone uuid
```
The reason for this is to ensure you can more easily upgrade to minor and patch versions for these libraries.
Also removed the simplecheck library as it was only used in one place.
# Installation

@@ -297,3 +322,1 @@ ```

* `git push origin --tags`

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc