/** * @fileoverview Billing operations for GitHub * @license Apache-2.0 * @version 3.0.0 * @author Michael Hay <michael.hay@mediumroast.io> * @copyright 2025 Mediumroast, Inc. All rights reserved. */ import ResponseFactory from './response.js'; /** * Manages GitHub billing operations */ class BillingManager { /** * @constructor * @param {Object} octokit - Octokit instance * @param {String} orgName - GitHub organization name */ constructor(octokit, orgName) { this.octokit = octokit; this.orgName = orgName; } /** * Gets GitHub Actions billing information for the organization * @returns {Promise<Array>} ResponseFactory result */ async getActionsBillings() { try { const response = await this.octokit.rest.billing.getGithubActionsBillingOrg({ org: this.orgName, }); return ResponseFactory.success( `Successfully retrieved Actions billing information for organization ${this.orgName}`, response.data ); } catch (err) { return ResponseFactory.error( `Failed to retrieve Actions billing information: ${err.message}`, err, err.status || 500 ); } } /** * Gets GitHub Packages storage billing information for the organization * @returns {Promise<Array>} ResponseFactory result */ async getStorageBillings() { try { const response = await this.octokit.rest.billing.getSharedStorageBillingOrg({ org: this.orgName, }); return ResponseFactory.success( `Successfully retrieved storage billing information for organization ${this.orgName}`, response.data ); } catch (err) { return ResponseFactory.error( `Failed to retrieve storage billing information: ${err.message}`, err, err.status || 500 ); } } /** * Gets GitHub Packages billing information for the organization * @returns {Promise<Array>} ResponseFactory result */ async getPackagesBillings() { try { const response = await this.octokit.rest.billing.getGithubPackagesBillingOrg({ org: this.orgName, }); return ResponseFactory.success( `Successfully retrieved Packages billing information for organization ${this.orgName}`, response.data ); } catch (err) { return ResponseFactory.error( `Failed to retrieve Packages billing information: ${err.message}`, err, err.status || 500 ); } } /** * Gets all billing information for the organization * @returns {Promise<Array>} ResponseFactory result with combined billing data */ async getAllBillings() { try { const [actionsResult, storageResult, packagesResult] = await Promise.all([ this.getActionsBillings(), this.getStorageBillings(), this.getPackagesBillings() ]); if (!actionsResult[0] || !storageResult[0] || !packagesResult[0]) { const failedRequests = []; if (!actionsResult[0]) failedRequests.push('Actions'); if (!storageResult[0]) failedRequests.push('Storage'); if (!packagesResult[0]) failedRequests.push('Packages'); return ResponseFactory.error( `Failed to retrieve some billing information: ${failedRequests.join(', ')}`, { actionsResult, storageResult, packagesResult }, 500 ); } const combinedData = { actions: actionsResult[2], storage: storageResult[2], packages: packagesResult[2] }; return ResponseFactory.success( `Successfully retrieved all billing information for organization ${this.orgName}`, combinedData ); } catch (err) { return ResponseFactory.error( `Failed to retrieve billing information: ${err.message}`, err ); } } } export default BillingManager;