UNPKG

cmc-api

Version:

CoinMarketCap RESTful API Wrapper

249 lines 12.9 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Client = void 0; const cmc_error_code_enum_1 = require("../enums/cmc-error-code.enum"); const cmc_apikey_disabled_error_1 = require("../errors/cmc-apikey-disabled.error"); const cmc_apikey_required_error_1 = require("../errors/cmc-apikey-required.error"); const cmc_invalid_error_1 = require("../errors/cmc-invalid.error"); const cmc_missing_error_1 = require("../errors/cmc-missing.error"); const cmc_payment_expired_error_1 = require("../errors/cmc-payment-expired.error"); const cmc_payment_required_error_1 = require("../errors/cmc-payment-required.error"); const cmc_plan_unauthorize_error_1 = require("../errors/cmc-plan-unauthorize.error"); const cmc_rate_limit_daily_error_1 = require("../errors/cmc-rate-limit-daily.error"); const cmc_rate_limit_ip_error_1 = require("../errors/cmc-rate-limit-ip.error"); const cmc_rate_limit_minute_error_1 = require("../errors/cmc-rate-limit-minute.error"); const cmc_rate_limit_monthly_error_1 = require("../errors/cmc-rate-limit-monthly.error"); const cmc_request_error_1 = require("../errors/cmc-request.error"); const decorators_util_1 = require("../utils/decorators.util"); /** * The `Client` class provides methods to interact with the CoinMarketCap API. * It allows sending HTTP GET requests, setting API keys, and handling errors. * * @remarks * This class includes methods for generating URIs with query parameters, * generating HTTP headers, and handling various error codes returned by the API. * * @example * ```typescript * import { CoinMarketCapApi } from ".."; * * const apikey = process.env.COINMARKETCAP_APIKEY; * const cmc = new CoinMarketCapApi(apikey); * * const data = await cmc.client.req('/v1/cryptocurrency/map'); * console.log(data); * ``` */ class Client { /** * Initializes a new instance of the `Client` class. * The constructor sets the base URL to the Pro API by default. */ constructor() { if (!this.baseURL) this.baseURL = Client.BaseURL.Pro; } /** * Send an HTTP GET request to the specified endpoint with optional query parameters and headers. * * @template TData - The expected type of the response data. * @template TQuery - The type of the query parameters, defaults to `Record<string, string | number | (string | number)[] | boolean>`. * @param {string} endpoint - The API endpoint to send the request to. * @param {TQuery} [query] - Optional query parameters to include in the request. * @param {Record<string, string>} [headers] - Optional headers to include in the request. * @returns {Promise<TData>} - A promise that resolves to the response data of type `TData`. * @throws {CmcErrorClass} Will throw an error if the response status indicates an error. */ async req(endpoint, query, headers) { var _a, _b; const uri = this.genUri(endpoint, query); const requestInit = { method: "GET", headers: this.genHeaders(headers) }; const request = await fetch(uri, requestInit); const result = await request.json(); const status = ((_a = result === null || result === void 0 ? void 0 : result.data) === null || _a === void 0 ? void 0 : _a.status) || (result === null || result === void 0 ? void 0 : result.status); const data = (((_b = result === null || result === void 0 ? void 0 : result.data) === null || _b === void 0 ? void 0 : _b.data) || (result === null || result === void 0 ? void 0 : result.data)); this.status = status; if (this.onError && (!status || (status === null || status === void 0 ? void 0 : status.error_code) > 0)) this.onError(uri, result); if ((status === null || status === void 0 ? void 0 : status.error_code) > 0) throw this.error(data); return (data !== null && data !== void 0 ? data : result); } /** * Set the API key for the client. * * @param apiKey - The API key to be set. * @returns The client instance with the API key set. * @example * ```typescript * const apikey = process.env.COINMARKETCAP_APIKEY; * const cmc = new CoinMarketCapApi(apikey); * cmc.client.setApiKey('dfa3195f-f1d4-f1c1-a1fa-83461b5f42eb'); * ``` */ setApiKey(apiKey) { this.apikey = apiKey; return this; } /** * Set the base URL for the client. * * @param {string} baseUrl - The base URL to be set. * @returns The client instance with the base URL set. * @example * ```typescript * const apikey = process.env.COINMARKETCAP_APIKEY; * const cmc = new CoinMarketCapApi(apikey); * cmc.client.setBaseUrl('https://sandbox-api.coinmarketcap.com'); * ``` */ setBaseUrl(baseUrl) { this.baseURL = baseUrl; return this; } /** * Converts an array of strings into a single comma-separated string. * If the input is already a string, it returns the input as is. * * @template TValue - The type of the input value, defaults to `string | number | (string | number)[]`. * @param {TValue} value - The input which can be either a string or an array of strings. * @returns A comma-separated string if the input is an array, otherwise the input string. */ commaSeparate(value) { return Array.isArray(value) ? value.join(",") : String(value); } /** * Set up the client to use the CoinMarketCap API sandbox environment. * This method sets the API key to the sandbox key and the base URL to the sandbox URL. * @returns The client instance with the sandbox environment set. */ sandbox() { this.apikey = Client.SandboxApikey; this.baseURL = Client.BaseURL.Sandbox; return this; } /** * Generates a complete URI with query parameters. * * @template TQuery - The type of the query parameters, defaults to `Record<string, string | number | (string | number)[] | boolean>`. * @param {string} endpoint - The endpoint to append to the base URL. * @param {TQuery} [query] - An optional object containing query parameters as key-value pairs. * @returns {URL} - The generated URL with the provided endpoint and query parameters. */ genUri(endpoint, query) { const uri = new URL(endpoint, this.baseURL); if (query) { for (const key of Object.keys(query)) if (query[key] && query[key] !== "undefined" && query[key] !== "null") { if (Array.isArray(query[key])) { uri.searchParams.append(key, this.commaSeparate(query[key])); } else { uri.searchParams.append(key, String(query === null || query === void 0 ? void 0 : query[key])); } } } return uri; } /** * Generates HTTP headers for the API request. * * @param additionHeaders - An object containing additional headers to be included in the request. * @returns A Headers object with the API key and any additional headers appended. * * @see {@link Headers} */ genHeaders(additionHeaders) { const headers = new Headers(); headers.append("X-CMC_PRO_API_KEY", this.apikey); if (additionHeaders) for (const key of Object.keys(additionHeaders)) headers.append(key, additionHeaders[key]); return headers; } /** * Handles errors based on the provided {@link CmcStatusResponse} and returns an appropriate {@link CmcErrorClass} instance. * * @param {CmcStatusResponse} status - The status object containing the error code and other relevant information. * @param {any} data - Optional additional data related to the error. * @returns An instance of a class extending {@link CmcErrorClass} that corresponds to the specific error code. * * The method maps the following error codes to their respective error classes: * - {@link CmcErrorCode.ApikeyInvalid} for {@link CmcInvalidError} * - {@link CmcErrorCode.ApikeyMissing} for {@link CmcMissingError} * - {@link CmcErrorCode.ApikeyPlanRequiresPayment} for {@link CmcPaymentRequiredError} * - {@link CmcErrorCode.ApikeyPlanPaymentExpired} for {@link CmcPaymentExpiredError} * - {@link CmcErrorCode.ApikeyRequired} for {@link CmcApikeyRequiredError} * - {@link CmcErrorCode.ApikeyPlanNotAuthorized} for {@link CmcPlanUnauthorizeError} * - {@link CmcErrorCode.ApikeyDisable} for {@link CmcApikeyDisabledError} * - {@link CmcErrorCode.ApikeyPlanMinuteRateLimitReached} for {@link CmcMinuteRateLimitError} * - {@link CmcErrorCode.ApikeyPlanDailyRateLimitReached} for {@link CmcDailyRateLimitError} * - {@link CmcErrorCode.ApikeyPlanMonthlyRateLimitReached} for {@link CmcMonthlyRateLimitError} * - {@link CmcErrorCode.IpRateLimitReached} for {@link CmcIpRateLimitError} * * If the error code does not match any of the above, a generic {@link CmcRequestError} is returned. */ error(data) { var _a; switch ((_a = this.status) === null || _a === void 0 ? void 0 : _a.error_code) { case cmc_error_code_enum_1.CmcErrorCode.ApikeyInvalid: return new cmc_invalid_error_1.CmcInvalidError(this.status, data); case cmc_error_code_enum_1.CmcErrorCode.ApikeyMissing: return new cmc_missing_error_1.CmcMissingError(this.status, data); case cmc_error_code_enum_1.CmcErrorCode.ApikeyPlanRequiresPayment: return new cmc_payment_required_error_1.CmcPaymentRequiredError(this.status, data); case cmc_error_code_enum_1.CmcErrorCode.ApikeyPlanPaymentExpired: return new cmc_payment_expired_error_1.CmcPaymentExpiredError(this.status, data); case cmc_error_code_enum_1.CmcErrorCode.ApikeyRequired: return new cmc_apikey_required_error_1.CmcApikeyRequiredError(this.status, data); case cmc_error_code_enum_1.CmcErrorCode.ApikeyPlanNotAuthorized: return new cmc_plan_unauthorize_error_1.CmcPlanUnauthorizeError(this.status, data); case cmc_error_code_enum_1.CmcErrorCode.ApikeyDisable: return new cmc_apikey_disabled_error_1.CmcApikeyDisabledError(this.status, data); case cmc_error_code_enum_1.CmcErrorCode.ApikeyPlanMinuteRateLimitReached: return new cmc_rate_limit_minute_error_1.CmcMinuteRateLimitError(this.status, data); case cmc_error_code_enum_1.CmcErrorCode.ApikeyPlanDailyRateLimitReached: return new cmc_rate_limit_daily_error_1.CmcDailyRateLimitError(this.status, data); case cmc_error_code_enum_1.CmcErrorCode.ApikeyPlanMonthlyRateLimitReached: return new cmc_rate_limit_monthly_error_1.CmcMonthlyRateLimitError(this.status, data); case cmc_error_code_enum_1.CmcErrorCode.IpRateLimitReached: return new cmc_rate_limit_ip_error_1.CmcIpRateLimitError(this.status, data); } return new cmc_request_error_1.CmcRequestError(this.status, data); } } exports.Client = Client; /** * The API key used for accessing the sandbox environment of the service. * This key is intended for testing purposes and should not be used in production. * @internal @private * @constant {string} */ Client.SandboxApikey = "b54bcf4d-1bca-4e8e-9a24-22ff2c3d462c"; /** * A collection of base URLs for the CoinMarketCap API. * @readonly @internal @private * @see {@link https://pro.coinmarketcap.com/api/v1#section/Quick-Start-Guide | Quick Start Guide} */ Client.BaseURL = { Sandbox: "https://sandbox-api.coinmarketcap.com", Pro: "https://pro-api.coinmarketcap.com", }; __decorate([ (0, decorators_util_1.Enumerable)(false), __metadata("design:type", String) ], Client.prototype, "baseURL", void 0); __decorate([ (0, decorators_util_1.Enumerable)(false), __metadata("design:type", String) ], Client.prototype, "apikey", void 0); //# sourceMappingURL=client.js.map