diff --git a/package-lock.json b/package-lock.json index 0c505a9ac..04289bf70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -801,9 +801,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -851,9 +851,9 @@ } }, "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -2691,9 +2691,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.3.tgz", - "integrity": "sha512-DRdx5neNsG/QXbniLFWi2YmC/68oeOOmKz6zOjVk6ZS1ZLXgLIKqVEc6hWsmkjBbgii0SwaBTcJ5XKj5gzY/4A==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "dev": true, "license": "MIT", "dependencies": { @@ -3826,9 +3826,9 @@ } }, "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -4068,9 +4068,9 @@ } }, "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -4125,9 +4125,9 @@ } }, "node_modules/eslint-plugin-react/node_modules/brace-expansion": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -4226,9 +4226,9 @@ } }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -4486,9 +4486,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", - "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.6.tgz", + "integrity": "sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==", "dev": true, "funding": [ { @@ -4867,9 +4867,9 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -5766,9 +5766,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", - "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", "dev": true, "funding": [ { @@ -6462,9 +6462,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.16", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", - "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", "dev": true, "funding": [ { diff --git a/src/constants.js b/src/constants.ts similarity index 100% rename from src/constants.js rename to src/constants.ts diff --git a/src/easypost.js b/src/easypost.ts similarity index 80% rename from src/easypost.js rename to src/easypost.ts index b86082806..43bad4796 100644 --- a/src/easypost.js +++ b/src/easypost.ts @@ -1,7 +1,6 @@ import util from 'util'; import { v4 as uuid } from 'uuid'; -import pkg from '../package.json'; import Constants from './constants'; import ErrorHandler from './errors/error_handler'; import MissingParameterError from './errors/general/missing_parameter_error'; @@ -39,6 +38,56 @@ import UserService from './services/user_service'; import WebhookService from './services/webhook_service'; import Utils from './utils/util'; +const pkgVersion = process.env.npm_package_version ?? 'unknown'; + +/* eslint-disable no-unused-vars */ +type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete'; +type RequestHeaders = Record; +type HttpClient = typeof fetch; + +interface CompatibilityRequest { + method: string; + url: string; + _data: unknown; + set(headersToSet?: RequestHeaders): CompatibilityRequest; + auth(key: string): CompatibilityRequest; + query(queryParams?: Record): CompatibilityRequest; + send(body?: unknown): CompatibilityRequest; +} + +interface HttpMiddleware { + (httpClient: HttpClient): HttpClient; +} + +interface RequestMiddleware { + (request: CompatibilityRequest): CompatibilityRequest | undefined; +} +/* eslint-enable no-unused-vars */ + +type ClientOptions = { + apiKey?: string; + useProxy?: boolean; + timeout?: number; + baseUrl?: string; + httpMiddleware?: HttpMiddleware; + requestMiddleware?: RequestMiddleware; + httpClient?: HttpClient; +}; + +type HookValue = { + method: string; + path: string; + requestBody: unknown; + headers: RequestHeaders; + requestTimestamp: number; + requestUUID: string; + httpStatus?: number; + responseBody?: unknown; + responseTimestamp?: number; +}; + +type HookHandler = any; + /** * The client used to access services of the EasyPost API. * This client is configured to use the latest production version of the EasyPost API. @@ -46,7 +95,25 @@ import Utils from './utils/util'; * @param {Object} [options] Additional options to use for the underlying HTTP client (e.g. middleware, proxy configuration). */ export default class EasyPostClient { - constructor(key, options = {}) { + static MS_SECOND: number; + static DEFAULT_TIMEOUT: number; + static DEFAULT_BASE_URL: string; + static DEFAULT_HEADERS: RequestHeaders; + static METHODS: Record<'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', HttpMethod>; + static SERVICES: Record; + + [key: string]: any; + key?: string; + useProxy?: boolean; + timeout: number; + baseUrl: string; + httpClient: HttpClient; + requestMiddleware?: RequestMiddleware; + requestHooks: HookHandler[]; + responseHooks: HookHandler[]; + Utils: Utils; + + constructor(key?: string, options: ClientOptions = {}) { const { useProxy, timeout, baseUrl, httpMiddleware, requestMiddleware, httpClient } = options; if (!key && !useProxy) { @@ -59,7 +126,13 @@ export default class EasyPostClient { this.timeout = timeout || EasyPostClient.DEFAULT_TIMEOUT; this.baseUrl = baseUrl || EasyPostClient.DEFAULT_BASE_URL; this.httpClient = - httpClient || (typeof fetch === 'function' ? (...args) => fetch(...args) : undefined); + httpClient || + (typeof fetch === 'function' + ? (input: RequestInfo | URL, init?: RequestInit) => fetch(input, init) + : ((async () => { + throw new Error('No global fetch implementation found. Node 18+ is required.'); + }) as HttpClient)); + this.useProxy = useProxy; this.requestMiddleware = requestMiddleware; this.requestHooks = []; this.responseHooks = []; @@ -80,20 +153,20 @@ export default class EasyPostClient { * Add a request hook function. * @param {(config: object) => void} hook */ - addRequestHook(hook) { + addRequestHook(hook: HookHandler): void { this.requestHooks = [...this.requestHooks, hook]; } /** * Remove a request hook function. * @param {(config: object) => void} hook */ - removeRequestHook(hook) { + removeRequestHook(hook: HookHandler): void { this.requestHooks = this.requestHooks.filter((h) => h !== hook); } /** * Clear all request hooks. */ - clearRequestHooks() { + clearRequestHooks(): void { this.requestHooks = []; } @@ -101,20 +174,20 @@ export default class EasyPostClient { * Add a response hook function. * @param {(config: object) => void} hook */ - addResponseHook(hook) { + addResponseHook(hook: HookHandler): void { this.responseHooks = [...this.responseHooks, hook]; } /** * Remove a response hook function. * @param {(config: object) => void} hook */ - removeResponseHook(hook) { + removeResponseHook(hook: HookHandler): void { this.responseHooks = this.responseHooks.filter((h) => h !== hook); } /** * Clear all response hooks. */ - clearResponseHooks() { + clearResponseHooks(): void { this.responseHooks = []; } @@ -129,7 +202,11 @@ export default class EasyPostClient { * @param {Object} [params] - The parameters to send with the request. * @returns {Promise} The response from the API call. */ - async makeApiCall(method, endpoint, params = {}) { + async makeApiCall( + method: string, + endpoint: string, + params: Record = {}, + ): Promise { const response = await this._request(endpoint, method, params); return response.body; @@ -141,7 +218,7 @@ export default class EasyPostClient { * @param {Object} [options] The options to override. * @returns {EasyPostClient} A new `EasyPostClient` instance. */ - static copyClient(client, options = {}) { + static copyClient(client: EasyPostClient, options: ClientOptions = {}): EasyPostClient { const { apiKey, useProxy, timeout, baseUrl, httpMiddleware, requestMiddleware, httpClient } = options; const nextHttpClient = @@ -161,7 +238,7 @@ export default class EasyPostClient { * @param {string} method - The method passed in by callers. * @returns {string} lowercase method suitable for fetch. */ - static _normalizeMethod(method = EasyPostClient.METHODS.GET) { + static _normalizeMethod(method: string = EasyPostClient.METHODS.GET): string { return method.toLowerCase(); } @@ -169,7 +246,7 @@ export default class EasyPostClient { * Executes a fetch request with timeout support. * @private */ - async _fetchWithTimeout(url, init) { + async _fetchWithTimeout(url: string, init: RequestInit): Promise { if (typeof AbortSignal !== 'undefined' && typeof AbortSignal.timeout === 'function') { return this.httpClient(url, { ...init, @@ -194,7 +271,7 @@ export default class EasyPostClient { * Parse an HTTP response body. * @private */ - async _parseResponseBody(response) { + async _parseResponseBody(response: Response): Promise { const text = await response.text(); if (!text) { return {}; @@ -211,7 +288,7 @@ export default class EasyPostClient { * Encodes a string to base64 in both Node and edge runtimes. * @private */ - static _toBase64(value) { + static _toBase64(value: string): string { if (typeof Buffer !== 'undefined') { return Buffer.from(value).toString('base64'); } @@ -224,7 +301,7 @@ export default class EasyPostClient { * @param {Object} [additionalHeaders] Additional headers to combine or override with the default headers. * @returns {Object} The headers to use for the request. */ - static _buildHeaders(additionalHeaders = {}) { + static _buildHeaders(additionalHeaders: RequestHeaders = {}): RequestHeaders { return { ...EasyPostClient.DEFAULT_HEADERS, 'User-Agent': EasyPostClient._buildUserAgent(), @@ -237,7 +314,7 @@ export default class EasyPostClient { * do not expose Node globals/modules. * @returns {string} The default User-Agent header value. */ - static _buildUserAgent() { + static _buildUserAgent(): string { let nodeVersion = 'unknown'; let osName = 'unknown'; let osVersion = 'unknown'; @@ -252,14 +329,14 @@ export default class EasyPostClient { osVersion; } - return `EasyPost/v2 NodejsClient/${pkg.version} Nodejs/${nodeVersion} OS/${osName} OSVersion/${osVersion} OSArch/${osArch}`; + return `EasyPost/v2 NodejsClient/${pkgVersion} Nodejs/${nodeVersion} OS/${osName} OSVersion/${osVersion} OSArch/${osArch}`; } /** * Attach services to an {@link EasyPostClient} instance. * @param {Map} services - A map of {@link BaseService}-based service classes to construct and attach to the client. */ - _attachServices(services) { + _attachServices(services: Record): void { Object.keys(services).forEach((s) => { this[s] = services[s](this); }); @@ -270,7 +347,7 @@ export default class EasyPostClient { * @param {string} path - The path to build. * @returns {string} The full path to use for the HTTP request. */ - _buildPath(path = '') { + _buildPath(path = ''): string { if (path.indexOf('http') === 0) { return path; } @@ -290,7 +367,7 @@ export default class EasyPostClient { * @param {Object} response - the response from the HTTP request * @returns {Object} - the value to be passed to the responseHooks */ - _createResponseHooksValue(baseHooksValue, response) { + _createResponseHooksValue(baseHooksValue: HookValue, response: any): HookValue { return { ...baseHooksValue, httpStatus: response.status, @@ -309,7 +386,12 @@ export default class EasyPostClient { * @returns {*} The response from the HTTP request. * @throws {ApiError} If the request fails. */ - async _request(path = '', method = EasyPostClient.METHODS.GET, params = {}, headers = {}) { + async _request( + path = '', + method: string = EasyPostClient.METHODS.GET, + params: Record = {}, + headers: RequestHeaders = {}, + ): Promise { const urlPath = this._buildPath(path); const normalizedMethod = EasyPostClient._normalizeMethod(method); const requestHeaders = EasyPostClient._buildHeaders(headers); @@ -322,7 +404,7 @@ export default class EasyPostClient { if (params !== undefined) { if (isQueryMethod) { Object.entries(params).forEach(([key, value]) => { - url.searchParams.append(key, value); + url.searchParams.append(key, String(value)); }); } else { requestBody = params; @@ -343,7 +425,7 @@ export default class EasyPostClient { }, query: (queryParams = {}) => { Object.entries(queryParams).forEach(([key, value]) => { - url.searchParams.append(key, value); + url.searchParams.append(key, String(value)); }); compatibilityRequest.url = url.toString(); return compatibilityRequest; @@ -386,7 +468,7 @@ export default class EasyPostClient { middlewareResponse = middlewareRequest.send(params); } - const baseHooksValue = { + const baseHooksValue: HookValue = { method, path: middlewareRequest.url || url.toString(), requestBody: middlewareRequest._data, @@ -446,16 +528,21 @@ export default class EasyPostClient { return response; } catch (error) { - if (error.statusCode && error.body) { - const responseHooksValue = this._createResponseHooksValue(baseHooksValue, error); + const handledError = error as any; + + if (handledError.statusCode && handledError.body) { + const responseHooksValue = this._createResponseHooksValue(baseHooksValue, handledError); this.responseHooks.forEach((fn) => fn(responseHooksValue)); - throw ErrorHandler.handleApiError(error); - } else if (error.response && error.response.body) { - const responseHooksValue = this._createResponseHooksValue(baseHooksValue, error.response); + throw ErrorHandler.handleApiError(handledError); + } else if (handledError.response && handledError.response.body) { + const responseHooksValue = this._createResponseHooksValue( + baseHooksValue, + handledError.response, + ); this.responseHooks.forEach((fn) => fn(responseHooksValue)); - throw ErrorHandler.handleApiError(error.response); + throw ErrorHandler.handleApiError(handledError.response); } else { - throw error; + throw handledError; } } } @@ -467,7 +554,11 @@ export default class EasyPostClient { * @param {Object} [headers] - Additional headers to send with the request. * @returns {*} The response from the HTTP request. */ - _get(path, params = {}, headers = {}) { + _get( + path: string, + params: Record = {}, + headers: RequestHeaders = {}, + ): Promise { return this._request(path, EasyPostClient.METHODS.GET, params, headers); } @@ -478,7 +569,11 @@ export default class EasyPostClient { * @param {Object} [headers] - Additional headers to send with the request. * @returns {*} The response from the HTTP request. */ - _post(path, params = {}, headers = {}) { + _post( + path: string, + params: Record = {}, + headers: RequestHeaders = {}, + ): Promise { return this._request(path, EasyPostClient.METHODS.POST, params, headers); } @@ -489,7 +584,11 @@ export default class EasyPostClient { * @param {Object} [headers] - Additional headers to send with the request. * @returns {*} The response from the HTTP request. */ - _put(path, params = {}, headers = {}) { + _put( + path: string, + params: Record = {}, + headers: RequestHeaders = {}, + ): Promise { return this._request(path, EasyPostClient.METHODS.PUT, params, headers); } @@ -500,7 +599,11 @@ export default class EasyPostClient { * @param {Object} [headers] - Additional headers to send with the request. * @returns {*} The response from the HTTP request. */ - _patch(path, params = {}, headers = {}) { + _patch( + path: string, + params: Record = {}, + headers: RequestHeaders = {}, + ): Promise { return this._request(path, EasyPostClient.METHODS.PATCH, params, headers); } @@ -511,7 +614,11 @@ export default class EasyPostClient { * @param {Object} [headers] - Additional headers to send with the request. * @returns {*} The response from the HTTP request. */ - _delete(path, params = {}, headers = {}) { + _delete( + path: string, + params: Record = {}, + headers: RequestHeaders = {}, + ): Promise { return this._request(path, EasyPostClient.METHODS.DELETE, params, headers); } } diff --git a/src/utils/internal_util.js b/src/utils/internal_util.ts similarity index 100% rename from src/utils/internal_util.js rename to src/utils/internal_util.ts diff --git a/src/utils/util.js b/src/utils/util.ts similarity index 87% rename from src/utils/util.js rename to src/utils/util.ts index ab26d7804..c355313cc 100644 --- a/src/utils/util.js +++ b/src/utils/util.ts @@ -6,6 +6,17 @@ import FilteringError from '../errors/general/filtering_error'; import InvalidParameterError from '../errors/general/invalid_parameter_error'; import SignatureVerificationError from '../errors/general/signature_verification_error'; +type SmartRate = { + rate: string; + time_in_transit: Record; +}; + +type Rate = { + rate: string; + carrier: string; + service: string; +}; + /** * Utility class of various publicly-available helper functions. * @public @@ -22,7 +33,11 @@ export default class Utils { * @throws {FilteringError} - If no applicable rates are found * @throws {InvalidParameterError} - If the deliveryAccuracy value is invalid */ - getLowestSmartRate(smartrates, deliveryDays, deliveryAccuracy) { + getLowestSmartRate( + smartrates: SmartRate[], + deliveryDays: number | string, + deliveryAccuracy: string, + ): SmartRate { const validDeliveryAccuracyValues = new Set([ 'percentile_50', 'percentile_75', @@ -32,13 +47,13 @@ export default class Utils { 'percentile_97', 'percentile_99', ]); - let lowestSmartRate = null; + let lowestSmartRate: SmartRate | null = null; const lowercaseDeliveryAccuracy = deliveryAccuracy.toLowerCase(); if (!validDeliveryAccuracyValues.has(lowercaseDeliveryAccuracy)) { throw new InvalidParameterError({ - message: `Invalid deliveryAccuracy value, must be one of: ${new Array( - ...validDeliveryAccuracyValues, + message: `Invalid deliveryAccuracy value, must be one of: ${Array.from( + validDeliveryAccuracyValues, ).join(', ')}`, }); } @@ -46,7 +61,7 @@ export default class Utils { for (let i = 0; i < smartrates.length; i += 1) { const rate = smartrates[i]; - if (rate.time_in_transit[lowercaseDeliveryAccuracy] > parseInt(deliveryDays, 10)) { + if (rate.time_in_transit[lowercaseDeliveryAccuracy] > parseInt(String(deliveryDays), 10)) { // eslint-disable-next-line no-continue continue; } else if ( @@ -73,7 +88,11 @@ export default class Utils { * @returns {Rate} - The lowest rate * @throws {FilteringError} - If no applicable rates are found */ - getLowestRate(rates, carriers = null, services = null) { + getLowestRate( + rates: Rate[], + carriers: string[] | null = null, + services: string[] | null = null, + ): Rate { if (carriers) { const carriersLower = carriers.map((carrier) => carrier.toLowerCase()); // eslint-disable-next-line no-param-reassign @@ -111,8 +130,12 @@ export default class Utils { * @returns {object} - The JSON-parsed webhook event body if the signature could be verified * @throws {SignatureVerificationError} - If the signature could not be verified */ - validateWebhook(eventBody, headers, webhookSecret) { - let webhook = {}; + validateWebhook( + eventBody: Buffer | string, + headers: Record, + webhookSecret: string, + ): Record { + let webhook: Record = {}; const easypostHmacSignature = headers['X-Hmac-Signature'] ?? headers['x-hmac-signature'] ?? null; diff --git a/tsconfig.build.json b/tsconfig.build.json index e301a68b4..f4bfc21ac 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -3,6 +3,7 @@ "compilerOptions": { "allowJs": true, "checkJs": false, + "noImplicitAny": false, "declaration": true, "noEmit": true }, diff --git a/vite.config.js b/vite.config.js index 901662487..653e064df 100644 --- a/vite.config.js +++ b/vite.config.js @@ -10,7 +10,7 @@ export default defineConfig({ // drop node 12 support in the future, change this to the next min version target: 'node12', lib: { - entry: path.resolve(__dirname, 'src/easypost.js'), + entry: path.resolve(__dirname, 'src/easypost.ts'), fileName: 'easypost', }, sourcemap: isDev, @@ -32,7 +32,7 @@ export default defineConfig({ }, resolve: { - extensions: ['.js'], + extensions: ['.ts', '.js'], alias: { '@': path.resolve(__dirname, 'src'), },