UNPKG

google-api-fetch

Version:

A lightweight Google API client using fetch for edge environments

193 lines (169 loc) 5.32 kB
import AuthClient from './auth/AuthClient.js'; import DriveClient_v3 from './services/drive/DriveClient_v3.js'; import DocsClient_v1 from './services/docs/DocsClient_v1.js'; import SheetsClient_v4 from './services/sheets/SheetsClient_v4.js'; import RateLimiter from './utils/RateLimiter.js'; export default class GoogleApiFactory { /** * Create a new GoogleApi client * @param {Object} credentials - Service account credentials * @param {string} credentials.client_email - Client email from credentials * @param {string} credentials.private_key - Private key from credentials */ constructor(credentials, options = {}) { if (!credentials) { throw new Error('Credentials required'); } this.options = { enableRateLimiting: true, maxConcurrentRequests: 5, requestIntervalMs: 500, ...options }; if (this.options.enableRateLimiting) { this.rateLimiter = new RateLimiter( this.options.maxConcurrentRequests, this.options.requestIntervalMs ); } this.credentials = credentials; this._authClient = new AuthClient(credentials); } async _rateLimitedRequest(fn) { if (this.options.enableRateLimiting && this.rateLimiter) { return this.rateLimiter.execute(fn); } return fn(); } _wrapWithRateLimiter(client) { if (!client || typeof client !== 'object') { return client; } const wrapped = {}; for(const [key, value] of Object.entries(client)) { if (typeof value === 'function') { wrapped[key] = async (...args) => { return this._rateLimitedRequest(() => value(...args)); }; } else if (typeof value === 'object' && value !== null) { wrapped[key] = this._wrapWithRateLimiter(value); } else { wrapped[key] = value; } } return wrapped; } /** * Access Google Auth services * @returns {Object} Google Auth API */ get auth() { return { GoogleAuth: class GoogleAuth { constructor(options) { this.credentials = options.credentials; this.scopes = options.scopes; this._client = new AuthClient(this.credentials); } async getClient() { return this._client; } getAccessToken() { return this._client.getAccessToken(); } } }; } /** * Access Google Drive services * @param {Object} options - Drive API options * @param {string} options.version - API version (default: 'v3') * @param {Object} options.auth - Auth client (optional) * @returns {Object} Drive API client */ drive({ version = 'v3', auth } = {}) { let client; switch(version) { case 'v3': client = new DriveClient_v3(auth || this._authClient); break; default: throw new Error(`Unsupported Drive API version: ${version}`); } const iface = client.getInterface(); if (!this.options.enableRateLimiting) { return iface; } return this._wrapWithRateLimiter(iface); } /** * Access Google Docs services * @param {Object} options - Docs API options * @param {string} options.version - API version (default: 'v1') * @param {Object} options.auth - Auth client (optional) * @returns {Object} Docs API client */ docs({ version = 'v1', auth } = {}) { let client; switch(version) { case 'v1': client = new DocsClient_v1(auth || this._authClient); break; default: throw new Error(`Unsupported Docs API version: ${version}`); } return client.getInterface(); } /** * Access Google Sheets services * @param {Object} options - Sheets API options * @param {string} options.version - API version (default: 'v4') * @param {Object} options.auth - Auth client (optional) * @returns {Object} Sheets API client */ sheets({ version = 'v4', auth } = {}) { let client; switch(version) { case 'v4': client = new SheetsClient_v4(auth || this._authClient); break; default: throw new Error(`Unsupported Sheets API version: ${version}`); } return client.getInterface(); } /** * Download a file using an existing access token * @param {string} fileId - The ID of the file to download * @param {string} accessToken - A valid Google API access token * @param {Object} options - Additional options * @returns {Promise<Buffer>} - The file content as a Buffer */ static async downloadFile(fileId, accessToken, options = {}) { const response = await fetch( `https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`, { headers: { Authorization: `Bearer ${accessToken}`, ...(options.headers || {}) } } ); if (!response.ok) { throw new Error(`Failed to download file: ${response.statusText}`); } return Buffer.from(await response.arrayBuffer()); } async downloadFile(fileId, options = {}) { return this._rateLimitedRequest(async () => { const accessToken = await this._authClient.getAccessToken(); return GoogleApiFactory.downloadFile(fileId, accessToken, options); }); } } export { AuthClient, DriveClient_v3, DocsClient_v1, SheetsClient_v4 };