From 93e68fbfed5021bb368d7451f43b8b2743be1e2c Mon Sep 17 00:00:00 2001 From: Justintime50 <39606064+Justintime50@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:48:19 -0600 Subject: [PATCH] TSM-10: convert Group E services to TypeScript --- ...{api_key_service.js => api_key_service.ts} | 26 +++--- ..._service.js => customer_portal_service.ts} | 2 +- ...dable_service.js => embeddable_service.ts} | 2 +- ...pper_service.js => end_shipper_service.ts} | 10 ++- ...rvice.js => fedex_registration_service.ts} | 37 +++++--- .../{luma_service.js => luma_service.ts} | 4 +- ...ervice.js => referral_customer_service.ts} | 88 +++++++++++++------ .../{user_service.js => user_service.ts} | 48 +++++++--- 8 files changed, 150 insertions(+), 67 deletions(-) rename src/services/{api_key_service.js => api_key_service.ts} (85%) rename src/services/{customer_portal_service.js => customer_portal_service.ts} (90%) rename src/services/{embeddable_service.js => embeddable_service.ts} (90%) rename src/services/{end_shipper_service.js => end_shipper_service.ts} (88%) rename src/services/{fedex_registration_service.js => fedex_registration_service.ts} (81%) rename src/services/{luma_service.js => luma_service.ts} (89%) rename src/services/{referral_customer_service.js => referral_customer_service.ts} (76%) rename src/services/{user_service.js => user_service.ts} (78%) diff --git a/src/services/api_key_service.js b/src/services/api_key_service.ts similarity index 85% rename from src/services/api_key_service.js rename to src/services/api_key_service.ts index 20f1d1b63..c661426e8 100644 --- a/src/services/api_key_service.js +++ b/src/services/api_key_service.ts @@ -4,6 +4,12 @@ import Constants from '../constants'; import FilteringError from '../errors/general/filtering_error'; import baseService from './base_service'; +type ApiKeyUser = Record & { + id?: string; + keys?: unknown[]; + children?: Array & { id?: string; keys?: unknown[] }>; +}; + export default (easypostClient) => /** * The ApiKeyService class provides methods for interacting with EasyPost {@link ApiKey} objects. @@ -17,20 +23,20 @@ export default (easypostClient) => * @returns {Array} - List of associated API Keys. * @throws {FilteringError} If user or API Keys are not found. */ - static async retrieveApiKeysForUser(id) { + static async retrieveApiKeysForUser(id: string): Promise { const url = `api_keys`; try { const response = await easypostClient._get(url); - const user = this._convertToEasyPostObject(response.body); + const user = this._convertToEasyPostObject(response.body) as ApiKeyUser; if (user.id == id) { - return user.keys; + return user.keys ?? []; } - user.children.forEach((child) => { + user.children?.forEach((child) => { if (child.id == id) { - return child.keys; + return child.keys ?? []; } }); } catch (e) { @@ -45,7 +51,7 @@ export default (easypostClient) => * See {@link https://docs.easypost.com/docs/api-keys#retrieve-an-api-key EasyPost API Documentation} for more information. * @returns {Object} - An object containing the API keys associated with the current authenticated user and its child users. */ - static async all(params = {}) { + static async all(params: Record = {}): Promise { const url = 'api_keys'; return this._all(url, params); @@ -57,7 +63,7 @@ export default (easypostClient) => * @param {string} mode - The mode for the API key (either "production" or "test"). * @returns {ApiKey} - The created API key. */ - static async create(mode) { + static async create(mode: string): Promise { const url = 'api_keys'; const params = { mode }; @@ -70,7 +76,7 @@ export default (easypostClient) => * @param {string} id - The ID of the API key to delete. * @returns {Promise|Promise} - A promise that resolves if the API key was successfully deleted. */ - static async delete(id) { + static async delete(id: string): Promise { const url = `api_keys/${id}`; try { @@ -88,7 +94,7 @@ export default (easypostClient) => * @param {string} id - The ID of the API key to enable. * @returns {ApiKey} - The enabled API key. */ - static async enable(id) { + static async enable(id: string): Promise { const url = `api_keys/${id}/enable`; try { @@ -106,7 +112,7 @@ export default (easypostClient) => * @param {string} id - The ID of the API key to disable. * @returns {ApiKey} - The disabled API key. */ - static async disable(id) { + static async disable(id: string): Promise { const url = `api_keys/${id}/disable`; try { diff --git a/src/services/customer_portal_service.js b/src/services/customer_portal_service.ts similarity index 90% rename from src/services/customer_portal_service.js rename to src/services/customer_portal_service.ts index c58a3f8c8..9642d6a5e 100644 --- a/src/services/customer_portal_service.js +++ b/src/services/customer_portal_service.ts @@ -11,7 +11,7 @@ export default (easypostClient) => * @param {Object} [params] - The parameters to create a session from. * @returns {Object} - An object containing the created session. */ - static async createAccountLink(params = {}) { + static async createAccountLink(params: Record = {}): Promise { const url = 'customer_portal/account_link'; try { diff --git a/src/services/embeddable_service.js b/src/services/embeddable_service.ts similarity index 90% rename from src/services/embeddable_service.js rename to src/services/embeddable_service.ts index d27f056e1..df90a3347 100644 --- a/src/services/embeddable_service.js +++ b/src/services/embeddable_service.ts @@ -11,7 +11,7 @@ export default (easypostClient) => * @param {Object} [params] - The parameters to create a session from. * @returns {Object} - An object containing the created session. */ - static async createSession(params = {}) { + static async createSession(params: Record = {}): Promise { const url = 'embeddables/session'; try { diff --git a/src/services/end_shipper_service.js b/src/services/end_shipper_service.ts similarity index 88% rename from src/services/end_shipper_service.js rename to src/services/end_shipper_service.ts index 7c2515422..ad5b59b6f 100644 --- a/src/services/end_shipper_service.js +++ b/src/services/end_shipper_service.ts @@ -1,5 +1,7 @@ import baseService from './base_service'; +type EndShipperParams = Record; + export default (easypostClient) => /** * The EndShipperService class provides methods for interacting with EasyPost {@link EndShipper} objects. @@ -12,7 +14,7 @@ export default (easypostClient) => * @param {Object} params - Parameters for the end shipper to be created. * @returns {EndShipper} - The created end shipper. */ - static async create(params) { + static async create(params: EndShipperParams): Promise { const url = 'end_shippers'; const wrappedParams = { address: params }; @@ -26,7 +28,7 @@ export default (easypostClient) => * @param {Object} params - Parameters for the end shipper to be updated. * @returns {EndShipper} - The updated end shipper. */ - static async update(id, params) { + static async update(id: string, params: EndShipperParams): Promise { const url = `end_shippers/${id}`; const wrappedParams = { address: params }; @@ -45,7 +47,7 @@ export default (easypostClient) => * @param {string} id - The ID of the end shipper to retrieve. * @returns {EndShipper} - The retrieved end shipper. */ - static async retrieve(id) { + static async retrieve(id: string): Promise { const url = `end_shippers/${id}`; return this._retrieve(url); @@ -57,7 +59,7 @@ export default (easypostClient) => * @param {Object} [params] - Parameters to filter the list of end shippers. * @returns {Object} - An object containing a list of {@link EndShipper end shippers} and pagination information. */ - static async all(params = {}) { + static async all(params: Record = {}): Promise { const url = 'end_shippers'; return this._all(url, params); diff --git a/src/services/fedex_registration_service.js b/src/services/fedex_registration_service.ts similarity index 81% rename from src/services/fedex_registration_service.js rename to src/services/fedex_registration_service.ts index 2f11f901d..659377815 100644 --- a/src/services/fedex_registration_service.js +++ b/src/services/fedex_registration_service.ts @@ -2,6 +2,14 @@ import { v4 as uuid } from 'uuid'; import baseService from './base_service'; +type FedExValidationMap = Record & { name?: string | null }; +type FedExParams = Record & { + address_validation?: FedExValidationMap; + pin_validation?: FedExValidationMap; + invoice_validation?: FedExValidationMap; + easypost_details?: Record; +}; + export default (easypostClient) => /** * The FedExRegistrationService class provides methods for registering FedEx carrier accounts with MFA. @@ -14,7 +22,10 @@ export default (easypostClient) => * @param {Object} params - Map of parameters. * @returns {Object} */ - static async registerAddress(fedexAccountNumber, params) { + static async registerAddress( + fedexAccountNumber: string, + params: FedExParams, + ): Promise { const wrappedParams = this._wrapAddressValidation(params); const endpoint = `fedex_registrations/${fedexAccountNumber}/address`; @@ -33,7 +44,11 @@ export default (easypostClient) => * @param {Object} params - Map of parameters. * @returns {Object} */ - static async requestPin(fedexAccountNumber, pinMethodOption, params) { + static async requestPin( + fedexAccountNumber: string, + pinMethodOption: string, + params: FedExParams, + ): Promise { const wrappedParams = this._wrapPinValidation(params); wrappedParams.pin_method = { option: pinMethodOption, @@ -54,7 +69,7 @@ export default (easypostClient) => * @param {Object} params - Map of parameters. * @returns {Object} */ - static async validatePin(fedexAccountNumber, params) { + static async validatePin(fedexAccountNumber: string, params: FedExParams): Promise { const wrappedParams = this._wrapPinValidation(params); const endpoint = `fedex_registrations/${fedexAccountNumber}/pin/validate`; @@ -72,7 +87,7 @@ export default (easypostClient) => * @param {Object} params - Map of parameters. * @returns {Object} */ - static async submitInvoice(fedexAccountNumber, params) { + static async submitInvoice(fedexAccountNumber: string, params: FedExParams): Promise { const wrappedParams = this._wrapInvoiceValidation(params); const endpoint = `fedex_registrations/${fedexAccountNumber}/invoice`; @@ -91,8 +106,8 @@ export default (easypostClient) => * @param {Object} params - The original parameters map. * @returns {Object} - A new map with properly wrapped address_validation and easypost_details. */ - static _wrapAddressValidation(params) { - const wrappedParams = {}; + static _wrapAddressValidation(params: FedExParams): Record { + const wrappedParams: Record = {}; if (params.address_validation) { const addressValidation = { ...params.address_validation }; @@ -114,8 +129,8 @@ export default (easypostClient) => * @param {Object} params - The original parameters map. * @returns {Object} - A new map with properly wrapped pin_validation and easypost_details. */ - static _wrapPinValidation(params) { - const wrappedParams = {}; + static _wrapPinValidation(params: FedExParams): Record { + const wrappedParams: Record = {}; if (params.pin_validation) { const pinValidation = { ...params.pin_validation }; @@ -137,8 +152,8 @@ export default (easypostClient) => * @param {Object} params - The original parameters map. * @returns {Object} - A new map with properly wrapped invoice_validation and easypost_details. */ - static _wrapInvoiceValidation(params) { - const wrappedParams = {}; + static _wrapInvoiceValidation(params: FedExParams): Record { + const wrappedParams: Record = {}; if (params.invoice_validation) { const invoiceValidation = { ...params.invoice_validation }; @@ -160,7 +175,7 @@ export default (easypostClient) => * @private * @param {Object} map - The map to ensure the "name" field in. */ - static _ensureNameField(map) { + static _ensureNameField(map: FedExValidationMap): void { if (!map.name || map.name === null) { const uuidValue = uuid().replace(/-/g, ''); map.name = uuidValue; diff --git a/src/services/luma_service.js b/src/services/luma_service.ts similarity index 89% rename from src/services/luma_service.js rename to src/services/luma_service.ts index 3947a5421..79db1c314 100644 --- a/src/services/luma_service.js +++ b/src/services/luma_service.ts @@ -1,5 +1,7 @@ import baseService from './base_service'; +type LumaParams = Record; + export default (easypostClient) => /** * The LumaService class provides methods for interacting with EasyPost Luma objects. @@ -11,7 +13,7 @@ export default (easypostClient) => * @param {Object} params - The parameters to get a Luma promise with. * @returns {Object} - An object containing the Luma promise. */ - static async getPromise(params) { + static async getPromise(params: LumaParams): Promise { const url = `luma/promise`; const wrappedParams = { diff --git a/src/services/referral_customer_service.js b/src/services/referral_customer_service.ts similarity index 76% rename from src/services/referral_customer_service.js rename to src/services/referral_customer_service.ts index 70cbe1f8b..de716b06d 100644 --- a/src/services/referral_customer_service.js +++ b/src/services/referral_customer_service.ts @@ -5,6 +5,20 @@ import EasyPostClient from '../easypost'; import ExternalApiError from '../errors/api/external_api_error'; import baseService from './base_service'; +type ReferralCustomerParams = Record; +type MandateData = Record; +/* eslint-disable no-unused-vars */ +type ReferralScopedClient = { + _post: ( + ...args: [string, Record?] + ) => Promise<{ body: Record }>; +}; +type EasyPostHttpClient = { + _get: (...args: [string, Record?]) => Promise<{ body: Record }>; + _put: (...args: [string, Record?]) => Promise; +}; +/* eslint-enable no-unused-vars */ + /** * Get an instance of the EasyPostClient using the referral user's API key. * @private @@ -12,7 +26,7 @@ import baseService from './base_service'; * @param {string} referralApiKey - The referral user's API key. * @returns {EasyPostClient} - An instance of the EasyPostClient. */ -function _getReferralClient(client, referralApiKey) { +function _getReferralClient(client: EasyPostClient, referralApiKey: string): EasyPostClient { return EasyPostClient.copyClient(client, { apiKey: referralApiKey, }); @@ -24,12 +38,13 @@ function _getReferralClient(client, referralApiKey) { * @param {EasyPostClient} easypostClient - The EasyPostClient to use. * @returns {string} - The Stripe API key. */ -async function _getEasyPostStripeKey(easypostClient) { +async function _getEasyPostStripeKey(easypostClient: EasyPostHttpClient): Promise { const url = 'partners/stripe_public_key'; const response = await easypostClient._get(url); - return response.body.public_key; + const body = response.body as Record; + return body.public_key as string; } /** @@ -42,7 +57,13 @@ async function _getEasyPostStripeKey(easypostClient) { * @param {string} cvc - Credit card CVC. * @returns {Promise} - Stripe credit card token. */ -async function _sendCardDetailsToStripe(stripeKey, number, expirationMonth, expirationYear, cvc) { +async function _sendCardDetailsToStripe( + stripeKey: string, + number: string, + expirationMonth: string, + expirationYear: string, + cvc: string, +): Promise { const searchParams = new URLSearchParams({ 'card[number]': number, 'card[exp_month]': expirationMonth, @@ -66,10 +87,13 @@ async function _sendCardDetailsToStripe(stripeKey, number, expirationMonth, expi const body = await response.json(); - return body.id; + return body.id as string; } catch (error) { throw new ExternalApiError({ message: util.format(Constants.EXTERNAL_API_CALL_FAILED, 'Stripe'), + code: undefined, + statusCode: undefined, + errors: undefined, }); } } @@ -83,12 +107,17 @@ async function _sendCardDetailsToStripe(stripeKey, number, expirationMonth, expi * @param {string} priority - Whether to add the card as the 'primary' or 'secondary' card. * @returns {Object} - Response body (EasyPost payment method object). */ -async function _sendCardDetailsToEasyPost(client, referralApiKey, stripeCreditCardToken, priority) { +async function _sendCardDetailsToEasyPost( + client: EasyPostClient, + referralApiKey: string, + stripeCreditCardToken: string, + priority: string, +): Promise> { const _client = _getReferralClient(client, referralApiKey); const url = 'credit_cards'; const params = { credit_card: { stripe_object_id: stripeCreditCardToken, priority } }; - const response = await _client._post(url, params); + const response = await (_client as ReferralScopedClient)._post(url, params); return response.body; } @@ -105,7 +134,7 @@ export default (easypostClient) => * @param {Object} params - The referral customer's information. * @returns {User} - The newly created referral customer. */ - static async create(params) { + static async create(params: ReferralCustomerParams): Promise { const url = 'referral_customers'; const wrappedParams = { @@ -122,7 +151,7 @@ export default (easypostClient) => * @param {string} email - The new email address. * @returns {boolean} - Returns true if the referral was updated successfully, false otherwise. */ - static async updateEmail(referralUserId, email) { + static async updateEmail(referralUserId: string, email: string): Promise { const url = `referral_customers/${referralUserId}`; const wrappedParams = { user: { email } }; @@ -143,13 +172,13 @@ export default (easypostClient) => * @returns {Object} - An object representing the newly-added credit card. */ static async addCreditCard( - referralApiKey, - number, - expirationMonth, - expirationYear, - cvc, - priority = 'primary', - ) { + referralApiKey: string, + number: string, + expirationMonth: string, + expirationYear: string, + cvc: string, + priority: string = 'primary', + ): Promise> { const stripeKey = await _getEasyPostStripeKey(easypostClient); // will throw if there's an error const stripeCreditCardId = await _sendCardDetailsToStripe( @@ -175,7 +204,11 @@ export default (easypostClient) => * This function requires the ReferralCustomer User's API key. * @returns {object} - A JSON object representing the credit card. */ - static async addCreditCardFromStripe(referralApiKey, paymentMethodId, priority = 'primary') { + static async addCreditCardFromStripe( + referralApiKey: string, + paymentMethodId: string, + priority: string = 'primary', + ): Promise { const _client = _getReferralClient(easypostClient, referralApiKey); const params = { credit_card: { @@ -185,7 +218,7 @@ export default (easypostClient) => }; const url = 'credit_cards'; - const response = await _client._post(url, params); + const response = await (_client as ReferralScopedClient)._post(url, params); return this._convertToEasyPostObject(response.body, params); } @@ -196,11 +229,11 @@ export default (easypostClient) => * @returns {object} - A JSON object representing the bank account. */ static async addBankAccountFromStripe( - referralApiKey, - financialConnectionsId, - mandateData, - priority = 'primary', - ) { + referralApiKey: string, + financialConnectionsId: string, + mandateData: MandateData, + priority: string = 'primary', + ): Promise { const _client = _getReferralClient(easypostClient, referralApiKey); const params = { financial_connections_id: financialConnectionsId, @@ -210,7 +243,7 @@ export default (easypostClient) => const url = 'bank_accounts'; - const response = await _client._post(url, params); + const response = await (_client as ReferralScopedClient)._post(url, params); return this._convertToEasyPostObject(response.body, params); } @@ -221,7 +254,7 @@ export default (easypostClient) => * @param {Object} [params] - Parameters to filter the referral customers by. * @returns {Object} - An object containing a list of {@link User referral customers} and pagination information. */ - static async all(params = {}) { + static async all(params: Record = {}): Promise { const url = 'referral_customers'; return this._all(url, params); @@ -233,7 +266,10 @@ export default (easypostClient) => * @param {Number} pageSize The number of records to return on each page * @returns {EasyPostObject|Promise} The retrieved {@link EasyPostObject}-based class instance, or a `Promise` that rejects with an error. */ - static async getNextPage(referralCustomers, pageSize = null) { + static async getNextPage( + referralCustomers: Record, + pageSize: number | null = null, + ): Promise { const url = 'referral_customers'; return this._getNextPage(url, 'referral_customers', referralCustomers, pageSize); } diff --git a/src/services/user_service.js b/src/services/user_service.ts similarity index 78% rename from src/services/user_service.js rename to src/services/user_service.ts index 7bfc6e382..d91abada1 100644 --- a/src/services/user_service.js +++ b/src/services/user_service.ts @@ -1,6 +1,13 @@ import EndOfPaginationError from '../errors/general/end_of_pagination_error'; import baseService from './base_service'; +type UserParams = Record; +type BrandParams = Record; +type UserCollection = Record & { + has_more?: boolean; + _params?: Record; +}; + export default (easypostClient) => /** * The UserService class provides methods for interacting with EasyPost {@link User} objects. @@ -13,7 +20,7 @@ export default (easypostClient) => * @param {Object} params - The parameters to create a child user with. * @returns {User} - The created child user. */ - static async create(params) { + static async create(params: UserParams): Promise { const url = 'users'; const wrappedParams = { @@ -30,7 +37,7 @@ export default (easypostClient) => * @param {Object} params - The parameters to update the user with. * @returns {User} - The updated user. */ - static async update(id, params) { + static async update(id: string, params: UserParams): Promise { const url = `users/${id}`; const wrappedParams = { user: params, @@ -51,7 +58,7 @@ export default (easypostClient) => * @param {string} id - The ID of the child user to retrieve. * @returns {User} - The retrieved child user. */ - static async retrieve(id) { + static async retrieve(id: string): Promise { const url = `users/${id}`; try { @@ -68,7 +75,7 @@ export default (easypostClient) => * See {@link https://docs.easypost.com/docs/users#retrieve-a-user EasyPost API Documentation} for more information. * @returns {User} - The retrieved user. */ - static async retrieveMe() { + static async retrieveMe(): Promise { const url = 'users'; try { @@ -86,7 +93,7 @@ export default (easypostClient) => * @param {string} id - The ID of the child user to delete. * @returns {Promise|Promise} - A promise that resolves when the child user is deleted successfully. */ - static async delete(id) { + static async delete(id: string): Promise { const url = `users/${id}`; try { @@ -105,7 +112,7 @@ export default (easypostClient) => * @param {Object} params - The parameters to update the brand with. * @returns {Brand} - The updated brand. */ - static async updateBrand(id, params) { + static async updateBrand(id: string, params: BrandParams): Promise { const url = `users/${id}/brand`; const wrappedParams = { brand: params }; @@ -124,7 +131,7 @@ export default (easypostClient) => * @param {Object} params - Parameters to filter the list of children users. * @returns {Object} - An object containing a list of {@link Children User} and pagination information. */ - static async allChildren(params) { + static async allChildren(params: Record): Promise { const url = 'users/children'; try { @@ -142,18 +149,28 @@ export default (easypostClient) => * @param {Number} pageSize The number of records to return on each page * @returns {EasyPostObject|Promise} The retrieved {@link EasyPostObject}-based class instance, or a `Promise` that rejects with an error. */ - static async getNextPage(children, pageSize = null) { + static async getNextPage( + children: UserCollection, + pageSize: number | null = null, + ): Promise { const url = 'users/children'; return this._getNextPage(url, 'children', children, pageSize); } - static async _getNextPage(url, key, collection, pageSize = null) { - const collectionArray = collection[key]; + static async _getNextPage( + url: string, + key: string, + collection: UserCollection, + pageSize: number | null = null, + ): Promise { + const collectionArray = collection[key] as Array> | undefined; if (collectionArray == undefined || collectionArray.length == 0 || !collection.has_more) { throw new EndOfPaginationError(); } - const defaultParams = collection._params ?? collectionArray[0]._params ?? {}; + const firstObjectParams = + (collectionArray[0]?._params as Record | undefined) ?? {}; + const defaultParams = collection._params ?? firstObjectParams; const params = { ...defaultParams, @@ -161,8 +178,13 @@ export default (easypostClient) => after_id: collectionArray[collectionArray.length - 1].id, }; - const response = await this._all(url, params); - if (response == undefined || response[key].length == 0) { + const response = (await this._all(url, params)) as Record; + const responseCollection = response[key] as Array> | undefined; + if ( + response == undefined || + responseCollection == undefined || + responseCollection.length == 0 + ) { throw new EndOfPaginationError(); }