esp/assets/js/apiClient.js

126 lines
3.4 KiB
JavaScript

// Cliente API moderno con fetch nativo (Vanilla JS)
(function(global){
'use strict';
// Helper para construir query string desde objeto
function buildQueryString(params) {
if (!params || Object.keys(params).length === 0) return '';
const query = Object.keys(params)
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
.join('&');
return '?' + query;
}
// Helper para manejar respuestas fetch
async function handleResponse(response) {
// Redirección automática al login en 401
if (response.status === 401) {
if (location.pathname.indexOf('login.php') === -1) {
window.location.href = '/login.php';
}
throw new Error('No autorizado');
}
// Parsear JSON o texto según content-type
const contentType = response.headers.get('content-type');
let data;
if (contentType && contentType.includes('application/json')) {
try {
data = await response.json();
} catch (err) {
const error = new Error('La API devolvió JSON inválido');
error.response = response;
throw error;
}
} else {
const text = await response.text();
data = text;
if (!response.ok || /^\s*</.test(text)) {
const error = new Error('La API devolvió HTML en lugar de JSON');
error.response = response;
error.data = text;
throw error;
}
}
if (!response.ok) {
const error = new Error(data.message || 'Error en la petición');
error.response = response;
error.data = data;
throw error;
}
return data;
}
// API pública
const api = {
// GET request
get: function(url, params) {
const queryString = buildQueryString(params);
return fetch(url + queryString, {
method: 'GET',
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
}
}).then(handleResponse);
},
// GET JSON (alias de get para compatibilidad)
getJSON: function(url, params) {
return this.get(url, params);
},
// POST JSON
postJSON: function(url, body, options) {
const opts = options || {};
const headers = Object.assign({
'Content-Type': 'application/json',
'Accept': 'application/json',
}, opts.headers || {});
return fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: headers,
body: JSON.stringify(body || {})
}).then(handleResponse);
},
// PUT JSON
putJSON: function(url, body, options) {
const opts = options || {};
const headers = Object.assign({
'Content-Type': 'application/json',
'Accept': 'application/json',
}, opts.headers || {});
return fetch(url, {
method: 'PUT',
credentials: 'same-origin',
headers: headers,
body: JSON.stringify(body || {})
}).then(handleResponse);
},
// DELETE request
delete: function(url, params) {
const queryString = buildQueryString(params);
return fetch(url + queryString, {
method: 'DELETE',
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
}
}).then(handleResponse);
}
};
// Exportar globalmente
global.api = api;
// Log de inicialización
try { console.log('[API Client] Inicializado (Vanilla JS)'); } catch {}
})(window);