UNPKG

node-hue-api

Version:
99 lines (98 loc) 4.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Transport = void 0; const ApiError_1 = require("../../ApiError"); const util_1 = require("../../util"); const HueError_1 = require("../../HueError"); const HueRateLimiter_1 = require("../HueRateLimiter"); class Transport { constructor(client, rateLimiterConfig, username) { this._username = username; this._client = client; this._limiter = new HueRateLimiter_1.HueRateLimiter('', 'transport', rateLimiterConfig); } get limiter() { return this._limiter; } /** * Executes an API Endpoint Request. * @param api The Api endpoint to perform a request against. * @param parameters Any parameters specific to the request. * @returns {Promise<any>} The promise for making the specified API request. */ execute(api, parameters) { let self = this, limiter = this.limiter, client = self._client, requestParameters = Object.assign({ username: self._username }, parameters), promise; if (!api) { throw new Error('An API must be provided'); } // @ts-ignore promise = limiter.schedule(() => { return client.request(api.getRequest(requestParameters)); }) .catch((err) => { // @ts-ignore throw extractError(err, err.response); }) .then((res) => { // Errors can be contained in the object payload from a successful response code. const errors = (0, util_1.parseErrors)(res.data); if (errors) { throw new ApiError_1.ApiError(errors[0]); } return res.data; }); if (api.getErrorHandler()) { // @ts-ignore promise = promise.catch(api.getErrorHandler()); } const postProcessing = api.getPostProcessing(); if (postProcessing) { // Inject the request parameters into the post processing function promise = promise.then((result) => { return postProcessing(result, requestParameters); }); } return promise; } refreshAuthorizationHeader(token) { // Update the default common authorization header with the new bearer token this._client.refreshAuthorizationHeader(`Bearer ${token}`); } } exports.Transport = Transport; /** * Extracts an appropriate error from the provided details. * * @param {Error} err The captured Error. * @param {Object} response The underlying transport HTTP response object. * @returns {ApiError | HueError} The error extracted from the data provided */ function extractError(err, response) { var _a, _b; if (!response) { //TODO fetch leaks the API key in the URL, need to redact it const error = new ApiError_1.ApiError(err.message); // Set the original stack trace here as the one for the error created is pretty much useless and obscures the real problem error.stack = err.stack; throw error; } const headers = response.headers, authenticateHeader = headers ? headers['www-authenticate'] : null; let hueError; if (authenticateHeader) { const errorMatch = /error="(.*?)"/.exec(authenticateHeader), errorDescriptionMatch = /error_description="(.*?)"/.exec(authenticateHeader); hueError = new HueError_1.HueError({ type: response.status, message: (errorMatch ? errorMatch[1] : response.data) || 'Error', description: errorDescriptionMatch ? errorDescriptionMatch[1] : undefined, address: (_a = response.config) === null || _a === void 0 ? void 0 : _a.url, }); } else { hueError = new HueError_1.HueError({ type: response.status, message: response.data || 'Error', address: (_b = response.config) === null || _b === void 0 ? void 0 : _b.url, }); } return new ApiError_1.ApiError(hueError); }