UNPKG

semanticpen

Version:

AI Article Writer & SEO Blog Generator SDK - Professional TypeScript/JavaScript library for automated content creation, AI-powered article generation, and SEO blog writing with SemanticPen

116 lines 4.72 kB
import { ErrorFactory, NetworkError, TimeoutError } from '../errors'; export class BaseClient { constructor(config) { this.config = { ...config }; this.baseUrl = config.baseUrl || 'https://www.semanticpen.com'; this.timeout = config.timeout || 30000; this.debug = config.debug || false; this.validateConfig(); } validateConfig() { if (!this.config.apiKey || typeof this.config.apiKey !== 'string') { throw new Error('API key is required and must be a string'); } if (this.config.apiKey.length < 10) { throw new Error('API key appears to be invalid (too short)'); } if (this.timeout < 1000 || this.timeout > 300000) { throw new Error('Timeout must be between 1000ms and 300000ms'); } } getDefaultHeaders() { return { 'Authorization': `Bearer ${this.config.apiKey}`, 'Content-Type': 'application/json', 'Accept': 'application/json', 'User-Agent': 'SemanticPen-SDK/1.0.0' }; } buildUrl(endpoint) { const cleanEndpoint = endpoint.startsWith('/') ? endpoint.slice(1) : endpoint; const cleanBaseUrl = this.baseUrl.endsWith('/') ? this.baseUrl.slice(0, -1) : this.baseUrl; return `${cleanBaseUrl}/${cleanEndpoint}`; } async request(endpoint, options = { method: 'GET' }) { const url = this.buildUrl(endpoint); const requestTimeout = options.timeout || this.timeout; if (this.debug) { console.log(`[SemanticPen SDK] ${options.method} ${url}`); if (options.body) { console.log('[SemanticPen SDK] Request body:', options.body); } } const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), requestTimeout); try { const headers = { ...this.getDefaultHeaders(), ...options.headers }; const fetchOptions = { method: options.method, headers, signal: controller.signal }; if (options.body && options.method !== 'GET') { fetchOptions.body = typeof options.body === 'string' ? options.body : JSON.stringify(options.body); } const response = await fetch(url, fetchOptions); clearTimeout(timeoutId); if (this.debug) { console.log(`[SemanticPen SDK] Response status: ${response.status}`); } let responseData; const contentType = response.headers.get('content-type'); if (!contentType || contentType.includes('application/json') || contentType.includes('text/plain')) { try { responseData = await response.json(); } catch (parseError) { responseData = await response.text(); } } else { responseData = await response.text(); } if (this.debug && responseData) { console.log('[SemanticPen SDK] Response data:', responseData); } if (!response.ok) { throw ErrorFactory.fromHttpResponse(response, endpoint, responseData); } return responseData; } catch (error) { clearTimeout(timeoutId); if (error.name === 'AbortError') { throw new TimeoutError(`Request timed out after ${requestTimeout}ms`, requestTimeout, `${options.method} ${endpoint}`); } if (error instanceof TypeError && error.message.includes('fetch')) { throw new NetworkError('Network error: Unable to reach SemanticPen API', undefined, endpoint, { originalError: error }); } if (error.type) { throw error; } throw ErrorFactory.fromError(error, `${options.method} ${endpoint}`); } } async get(endpoint, headers) { return this.request(endpoint, { method: 'GET', headers }); } async post(endpoint, body, headers) { return this.request(endpoint, { method: 'POST', body, headers }); } async put(endpoint, body, headers) { return this.request(endpoint, { method: 'PUT', body, headers }); } async delete(endpoint, headers) { return this.request(endpoint, { method: 'DELETE', headers }); } getConfig() { return Object.freeze({ ...this.config }); } } //# sourceMappingURL=BaseClient.js.map