UNPKG

cimpress-fulfiller-identity

Version:
204 lines (174 loc) 8.12 kB
const axios = require('axios'); const axiosRetry = require('axios-retry'); const FulfillerNotFoundError = require("./errors/fulfiller_not_found_error"); const ForbiddenError = require("./errors/forbidden_error"); const XRayProxy = require("./xray_proxy"); const Fulfiller = require("./fulfiller"); const FulfillerContact = require("./fulfillerContact"); const AWSXRayMock = require('./aws_xray_mock'); /** * The main class exposing client methods. */ class FulfillerIdentityClient { constructor(authorization, clientOptions) { const options = clientOptions || {}; const awsXRay = options.AWSXRay ? options.AWSXRay : AWSXRayMock; const retries = parseInt(options.retries, 10); const retryDelayInMs = parseInt(options.retryDelayInMs, 10); const retryOnTimeouts = options.retryOnTimeouts || false; if (typeof authorization === "undefined") { this.authorizer = { getAuthorization: () => Promise.resolve("") }; } else if (typeof authorization === "string") { this.authorizer = { getAuthorization: () => Promise.resolve(authorization.startsWith('Bearer ') ? authorization : 'Bearer ' + authorization) }; } else if (typeof authorization === "function") { this.authorizer = { getAuthorization: () => Promise.resolve(authorization()) }; } else { throw new Error("The authorization should be either a string, a function that returns a string, or a function that returns a Promise"); } this.timeout = options.timeout ? options.timeout : 3000; this.baseUrl = options.url ? options.url : "https://fulfilleridentity.trdlnk.cimpress.io"; this.xrayPRoxy = new XRayProxy(this.authorizer, awsXRay); const retryCondition = retryOnTimeouts ? err => err.code === 'ECONNABORTED' || axiosRetry.isNetworkOrIdempotentRequestError(err) : axiosRetry.isNetworkOrIdempotentRequestError; axiosRetry(axios, { retries: retries >= 0 ? retries : 3, retryDelay: retryCount => retryDelayInMs >= 0 ? retryDelayInMs : 1000, shouldResetTimeout: true, retryCondition: retryCondition }); } getUrl() { return this.baseUrl; } /** * Returns an array of fulfiller objects that meet the criteria expesses in options * @param options Criteria for the query * { * showArchived: boolean * fulfillerName: string * noCache: boolean * } */ getFulfillers(options) { return this.xrayPRoxy .capturePromise('FulfillerIdentity.getFulfillers', this._getFulfillers.bind(this), [], options); } _getFulfillers(authorization, subsegment, options) { let queryParameters = []; if (options && options.showArchived) queryParameters.push(`showArchived=${options.showArchived}`); if (options && options.fulfillerName) queryParameters.push(`fulfillerName=${options.fulfillerName}`); if (options && options.noCache) queryParameters.push(`noCache=${Math.random()}`); const url = `${this.baseUrl}/v1/fulfillers${queryParameters.length ? "?" + queryParameters.join('&') : ""}`; return this.makeRequest(authorization, 'GET', url) .then(res => { subsegment.addMetadata("response", res.data); return res.data; }) .then(parsedBody => parsedBody.map(f => new Fulfiller(f.fulfillerId, f.internalFulfillerId, f.name, f.email, f.phone, f.language, f.links, f.archived))) .catch((err) => Promise.reject(new Error("Unable to get fulfillers: " + err.message))); } /** * Returns an array of fulfiller objects that meet the criteria expesses in options * @param fulfillerId Id of the fulfiller to retrieve * @param options Criteria for the query * { * noCache: boolean * } */ getFulfiller(fulfillerId, options) { return this.xrayPRoxy .capturePromise('FulfillerIdentity.getFulfillerById', this._getFulfiller.bind(this), [], fulfillerId, options); } _getFulfiller(authorization, subsegment, fulfillerId, options) { let queryParameters = []; if (options && options.noCache) queryParameters.push(`noCache=${Math.random()}`); const url = `${this.baseUrl}/v1/fulfillers/${fulfillerId}${options && options.noCache ? `?noCache=${Math.random()}` : ""}`; subsegment.addAnnotation("FulfillerId", fulfillerId); return this.makeRequest(authorization, 'GET', url) .then(res => { subsegment.addMetadata("response", res.data); return res.data; }) .then(f => new Fulfiller(f.fulfillerId, f.internalFulfillerId, f.name, f.email, f.phone, f.language, f.links, f.archived)) .catch((err) => { if (err.response && err.response.status === 403) { return Promise.reject(new ForbiddenError(`You are forbidden from reading the details of fulfiller ${fulfillerId}`)); } else if (err.response && err.response.status === 404) { return Promise.reject(new FulfillerNotFoundError(`Fulfiller ${fulfillerId} does not exist`)); } return Promise.reject(new Error("Unable to get fulfiller: " + err.message)); }); } /** * Returns an array of fulfiller objects that meet the criteria expesses in options * @param fulfillerId Id of the fulfiller to retrieve * @param options Criteria for the query * { * noCache: boolean * } */ getFulfillerContacts(fulfillerId, options) { return this.xrayPRoxy .capturePromise('FulfillerIdentity.getFulfillerContacts', this._getFulfillerContacts.bind(this), [], fulfillerId, options); } _getFulfillerContacts(authorization, subsegment, fulfillerId, options) { const url = `${this.baseUrl}/v1/fulfillers/${fulfillerId}/contacts${options && options.noCache ? `?noCache=${Math.random()}` : ""}`; subsegment.addAnnotation("FulfillerId", fulfillerId); return this.makeRequest(authorization, 'GET', url) .then(res => { subsegment.addMetadata("response", res.data); return res.data; }) .then(parsedBody => parsedBody.map(f => new FulfillerContact(f.id, f.createdAt, f.createdBy, f.defaultContact, f.email, f.language, f.name, f.phone, f.technicalContact, f.businessContact, f.operationalSupportContact, f.links))) .catch((err) => { if (err.response && err.response.status === 403) { return Promise.reject(new ForbiddenError(`You are forbidden from reading the details of fulfiller ${fulfillerId}`)); } else if (err.response && err.response.status === 404) { return Promise.reject(new FulfillerNotFoundError(`Fulfiller ${fulfillerId} does not exist`)); } return Promise.reject(new Error("Unable to get fulfiller contacts: " + err.message)); }); } /** * Saves changes made to a fulfiller object. * @param fulfiller Fufiller object, either retrieved via getFulfiller or getFulfillers or using new Fulfiller statement */ saveFulfiller(fulfiller) { return this.xrayPRoxy .capturePromise('FulfillerIdentity.saveFulfiller', this._saveFulfiller.bind(this), [], fulfiller); } _saveFulfiller(authorization, subsegment, fulfiller) { const fulfillerId = fulfiller.fulfillerId || fulfiller.internalFulfillerId; if (fulfillerId) { subsegment.addAnnotation("FulfillerId", fulfillerId); return this.makeRequest(authorization, 'PUT', `${this.baseUrl}/v1/fulfillers/${fulfillerId}`, fulfiller) .then((f) => Promise.resolve()) .catch((err) => Promise.reject(new Error("Unable to update fulfiller: " + err.message))); } else { return this.makeRequest(authorization, 'POST', `${this.baseUrl}/v1/fulfillers`, fulfiller) .then((f) => Promise.resolve()) .catch((err) => Promise.reject(new Error("Unable to create fulfiller: " + err.message))); } } makeRequest(authorization, method, url, body) { let params = { timeout: this.timeout, method, url, headers: { 'Content-Type': 'application/json' } }; if (authorization) { params.headers.Authorization = authorization; } if (body) { params.data = body; } return axios(params); } } module.exports = FulfillerIdentityClient;