UNPKG

umay-render

Version:

Free, high-performance HTML to PDF and HTML to Image conversion SDK for both browser and Node.js

212 lines (211 loc) 11.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HttpClient = void 0; // src/http-client.ts const axios_1 = __importDefault(require("axios")); const errors_1 = require("./errors"); // ErrorCodes import edildi // ensureUint8Array fonksiyonu aynı kalır... function ensureUint8Array(data) { if (data instanceof Uint8Array) return data; if (data instanceof ArrayBuffer) return new Uint8Array(data); if (typeof data === "object" && data !== null && typeof data.byteLength === "number") { try { return new Uint8Array(data); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); throw new Error(`Cannot convert to Uint8Array: ${errorMessage}`); } } throw new Error(`Cannot convert to Uint8Array: Unsupported data type ${typeof data}`); } class HttpClient { constructor(config) { this.config = config; this.client = axios_1.default.create({ baseURL: config.API_URL, timeout: config.TIMEOUT, headers: { "Content-Type": "application/json", Accept: "application/json, image/*, application/pdf", // Accept başlığını doğru ayarla }, responseType: "arraybuffer", validateStatus: (status) => status < 500, // Sadece 5xx hataları AxiosError olarak fırlat }); } async request(endpoint, data) { try { // İstek loglaması (opsiyonel) // console.log(`Making POST ${endpoint} request with data:`, JSON.stringify(data)); // Axios isteği const response = await this.client.post(endpoint, data, { // responseType: 'arraybuffer' zaten instance seviyesinde ayarlı // headers Accept de instance seviyesinde ayarlı }); // Başarılı yanıt işleme (2xx) // console.log(`Received response from ${endpoint}: Status ${response.status}`); return this.processSuccessResponse(response); } catch (error) { // --- Hata İşleme --- console.error(`HTTP client error during request to ${endpoint}:`, error); // Axios Hatası mı? (Genellikle 5xx veya ağ/timeout hataları) if (axios_1.default.isAxiosError(error)) { const axiosError = error; // Tip belirlemesi // Timeout hatası mı? if (axiosError.code === "ECONNABORTED" || axiosError.message.includes("timeout")) { throw new errors_1.UmayError(errors_1.ErrorCodes.TIMEOUT, // Timeout kodu `Request timed out after ${this.config.TIMEOUT}ms`, axiosError.config // İlgili isteğin konfigürasyonunu detay olarak ekle ); } // Yanıt alındı mı? (Genellikle 5xx) if (axiosError.response) { // 5xx yanıtlarını işle (processResponse 4xx'leri işlemişti ama validateStatus ile bu değişti) return this.processErrorResponse(axiosError.response); } else if (axiosError.request) { // İstek yapıldı ama yanıt alınamadı (Ağ hatası) throw new errors_1.UmayError(errors_1.ErrorCodes.NETWORK_ERROR, `Network error: No response received from server. ${axiosError.message}`, { requestDetails: axiosError.request }); } else { // İstek ayarlanırken hata oluştu throw new errors_1.UmayError(errors_1.ErrorCodes.NETWORK_ERROR, // Veya daha spesifik bir kod? `Request setup error: ${axiosError.message}`, axiosError.config); } } // Axios olmayan beklenmedik hata throw new errors_1.UmayError(errors_1.ErrorCodes.NETWORK_ERROR, // Genel ağ/bilinmeyen hata kodu error instanceof Error ? error.message : "Unknown network or client error", error // Orijinal hatayı detay olarak sakla ); } } /** Başarılı (2xx) yanıtları işler */ processSuccessResponse(response) { const contentType = response.headers["content-type"]?.toLowerCase() || ""; const data = response.data; // Binary veri (PDF veya görseller) if (contentType.includes("application/pdf") || contentType.includes("image/")) { try { const uint8Array = ensureUint8Array(data); // console.log(`Processed binary response (${contentType}): ${uint8Array.length} bytes`); return uint8Array; // T'nin Uint8Array olacağını varsayıyoruz } catch (e) { console.error("Failed to process binary data:", e); // Bu durumda ne yapılmalı? Hata fırlatmak daha iyi olabilir. throw new errors_1.UmayError(errors_1.ErrorCodes.API_ERROR, "Failed to process binary response from API", e); } } // Diğer içerik tipleri (JSON beklenmiyor ama olabilir) if (contentType.includes("application/json")) { try { const text = new TextDecoder().decode(data); const jsonData = JSON.parse(text); // console.log("Processed JSON response:", jsonData); return jsonData; // T'nin JSON nesnesi olacağını varsayıyoruz } catch (e) { console.warn("Received JSON content-type but failed to parse response body."); // Belki de boş yanıt? Ya da text olarak dönelim? // Ya da hata fırlatmak daha güvenli. throw new errors_1.UmayError(errors_1.ErrorCodes.API_ERROR, "Failed to parse JSON response from API", { responseText: new TextDecoder().decode(data) }); } } // Beklenmedik içerik tipi veya boş yanıt console.warn(`Unexpected content type received: ${contentType}. Returning raw data.`); try { // Yine de Uint8Array'e çevirmeyi deneyelim, belki istemci işleyebilir const uint8Array = ensureUint8Array(data); return uint8Array; } catch (e) { // Başarısız olursa, ham veriyi dön (pek olası değil arraybuffer için) return data; } } /** Hatalı (4xx, 5xx) API yanıtlarını işler ve UmayError fırlatır */ processErrorResponse(response) { // Bu metodun aslında T dönmemesi, hata fırlatması lazım const status = response.status; let errorCode = errors_1.ErrorCodes.API_ERROR; // Varsayılan kod let errorMessage = `API request failed with status ${status}`; let errorDetails = null; let publicMessage = undefined; // Opsiyonel kullanıcı dostu mesaj try { if (response.data && response.data.byteLength > 0) { const text = new TextDecoder().decode(response.data); // console.log("Raw error response text:", text); // Hata ayıklama için try { const json = JSON.parse(text); // Backend'in hata yapısını varsayıyoruz: { error: { code: 'CODE', message: 'InternalMsg', publicMessage?: 'UserMsg' }, details?: any } // Veya { error: { code: 'CODE', message: 'PublicMsg', internal_message?: 'InternalMsg'}, ... } (errorHandler'a göre) // Backend'deki errorHandler yapısına göre ayarla: if (json.error && typeof json.error === "object") { const errObj = json.error; // --- Backend kodunu al --- const backendCode = errObj.code; if (backendCode && typeof backendCode === "string") { // Backend kodunu ErrorCodes içinde ara, varsa kullan, yoksa string olarak kullan errorCode = Object.prototype.hasOwnProperty.call(errors_1.ErrorCodes, backendCode) ? backendCode : backendCode; } // --- Mesajları al --- // Public message varsa önceliklendir publicMessage = typeof errObj.message === "string" ? errObj.message : undefined; // Hata mesajını public varsayalım // Internal message varsa geliştirici mesajı olarak kullan errorMessage = typeof errObj.internal_message === "string" ? errObj.internal_message : publicMessage || errorMessage; // İç mesaj yoksa dış mesajı kullan } else if (typeof json.error === "string") { // Eski yapı: { error: "Mesaj", details?: ... } publicMessage = json.error; // Ana mesajı public varsayalım errorMessage = json.error; } // Detayları al errorDetails = json.details || json.stack || json; // Stack veya tüm JSON detay olabilir } catch (parseError) { // JSON değilse, yanıtı text olarak kullan console.warn("API error response was not valid JSON:", text); errorMessage = `API Error (${status}): ${text || "No response body"}`; publicMessage = `An API error occurred (Status: ${status})`; // Genel mesaj errorDetails = { responseText: text }; } } else { // Boş yanıt gövdesi errorMessage = `API request failed with status ${status} and empty response body`; publicMessage = `An API error occurred (Status: ${status})`; // Genel mesaj } } catch (decodeError) { console.error("Error processing API error response data:", decodeError); errorMessage = `Failed to process error response (Status: ${status})`; publicMessage = `An error occurred while processing the API response (Status: ${status})`; errorDetails = decodeError; } // Hata fırlat, bu metodun bir değer dönmemesi gerekiyor. throw new errors_1.UmayError(errorCode, errorMessage, { // `details` içine publicMessage'ı da ekleyebiliriz status: status, responseDetails: errorDetails, publicMessage: publicMessage, // İstemci bu public mesajı kullanabilir }); } } exports.HttpClient = HttpClient;