UNPKG

magically-sdk

Version:

Official SDK for Magically - Build mobile apps with AI

111 lines (110 loc) 4.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.APIClient = void 0; const Logger_1 = require("./Logger"); class APIClient { constructor(config, loggerPrefix = 'MagicallyAPI') { this.apiKey = null; this.config = config; this.logger = new Logger_1.Logger(config.debug || false, loggerPrefix); this.baseUrl = config.apiUrl || 'https://trymagically.com'; // Check for API key in environment (for edge functions) if (typeof globalThis !== 'undefined' && 'MAGICALLY_API_KEY' in globalThis) { this.apiKey = globalThis.MAGICALLY_API_KEY; this.logger.info('API key detected in environment - using API key authentication'); } } /** * Make an authenticated API request with automatic logging */ async request(endpoint, options, token) { const startTime = Date.now(); let requestId = ''; const url = `${this.baseUrl}${endpoint}`; const headers = { 'Content-Type': 'application/json', ...options.headers, }; // Use API key if available (edge environment), otherwise use provided token if (this.apiKey) { headers['Authorization'] = `Bearer ${this.apiKey}`; this.logger.debug('Using API key authentication for request'); } else if (token) { headers['Authorization'] = `Bearer ${token}`; } const requestConfig = { method: options.method, headers, body: options.body ? JSON.stringify(options.body) : undefined, }; // Log the request requestId = this.logger.networkRequest(options.method, url, { headers, body: options.body, operation: options.operation }); try { const response = await fetch(url, requestConfig); const responseData = await response.json(); const duration = Date.now() - startTime; if (!response.ok) { // Log error response this.logger.networkError(requestId, responseData, { duration, operation: options.operation }); // Throw structured error this.handleAPIError(responseData, `${options.operation || 'Request'} failed`); } // Log successful response this.logger.networkResponse(requestId, { status: response.status, statusText: response.statusText, duration, data: this.sanitizeResponseData(responseData, options.operation), operation: options.operation }); return responseData; } catch (error) { // Log network errors if (requestId) { this.logger.networkError(requestId, error, { duration: Date.now() - startTime, operation: options.operation }); } throw error; } } /** * Check if running in edge environment (has API key) */ isEdgeEnvironment() { return this.apiKey !== null; } /** * Sanitize response data for logging (avoid logging large arrays) */ sanitizeResponseData(data, operation) { if (operation === 'query' && data.data && Array.isArray(data.data)) { return { ...data, dataCount: data.data.length, data: '[Array of items]' }; } return data; } /** * Handle API errors with structured error information */ handleAPIError(errorData, fallbackMessage) { // Create an error with the response data attached for the Logger const error = new Error(errorData.error || errorData.message || fallbackMessage); error.responseData = errorData; // Preserve the original error response for Logger throw error; } } exports.APIClient = APIClient;