1/******************************************************************** 2 * 3 * RestFul v1.0 4 * An open source manager for REST API Calls 5 * 6 * Copyright (c) 2024 Enfoque[S.I.] 7 * Contact us at soporte@enfoque-sicom 8 * 9 * Licensed under The GNU General Public License 10 * https://www.gnu.org/licenses/gpl-3.0.txt 11 * 12 ********************************************************************/ 13 14/******************************************************************** 15 * Configuration: 16 * 17 * RestFul.config = { 18 * debug: [true|false], 19 * baseURL: [true|false], 20 * handleResponse:[function|false], 21 * handleError:[function|false], 22 * } 23 * 24 * Call: 25 * RestFul.[post|get|put|patch|delete](url-endpoint, [text|form-fields], [json-with-additional-headers|null], [handle-response-function|null], [handle-error-function|null]); 26 * 27 * Examples: 28 * RestFul.post('http://domain.com/api/endpoint', 'payload', {'Accept-Language': lang}, function(data){...}); 29 * RestFul.get('/api/endpoint?param=1', ''); 30 * 31********************************************************************/ 32 33class RestFul { 34 35 static config = { 36 debug: false, 37 baseURL: false, 38 handleResponse: false, 39 handleError: false, 40 }; 41 42 static #consoleDebug(message, data) { 43 if (this.config.debug) { 44 console.log(message, data); 45 } 46 } 47 48 static async #request(endpoint, method = 'GET', body = null, headers = {}, handleResponse = false, handleError = false) { 49 50 // Construir el endpoint para la solicitud 51 if (!endpoint.startsWith('http') && this.config.baseURL && this.config.baseURL.startsWith('http')) { 52 endpoint = this.config.baseURL.replace(/[\/]*$/,'') + '/' + endpoint.replace(/^[\/]*/,''); 53 } 54 55 const options = { 56 method, 57 headers: { 58 ...headers 59 } 60 }; 61 62 if (body) { 63 if (body instanceof FormData) { 64 // Si es FormData, no configuramos 'Content-Type' ya que el navegador lo hace automáticamente 65 options.body = body; 66 } else { 67 options.headers['Content-Type'] = 'application/json'; 68 options.body = JSON.stringify(body); 69 } 70 } 71 this.#consoleDebug('f #request:', { endpoint, options }); 72 73 // Realizar la petición 74 try { 75 const response = await fetch(endpoint, options); 76 this.#consoleDebug('f #request :: response:', response); 77 78 // Verificar que la respuesta sea exitosa 79 if (!response.ok) { 80 const errorText = await response.text(); 81 throw new Error(`HTTP error! status: ${response.status}, details: ${errorText}`); 82 } 83 84 // Detectar el tipo de contenido de la respuesta 85 const contentType = response.headers.get('Content-Type').replace(/;.*$/, ''); 86 this.#consoleDebug('f #request :: response content type:', contentType ? contentType : 'No Content-Type'); 87 88 let data; 89 if (response.status > 200) { 90 data = null; 91 } else if (contentType.includes('application/json')) { 92 data = await response.json(); 93 } else if (contentType.includes('text/')) { 94 data = await response.text(); 95 } else { 96 data = await response.blob(); 97 } 98 this.#consoleDebug('f #request :: response data:', data); 99 100 if (typeof handleResponse === "function") { 101 handleResponse(data, contentType); 102 } else if (typeof this.config.handleResponse === "function") { 103 this.config.handleResponse(data, contentType); 104 } else { 105 this.#handleResponse(data, contentType); 106 } 107 108 } catch (error) { 109 if (typeof handleError === "function") { 110 handleError(error); 111 } else if (typeof this.config.handleError === "function") { 112 this.config.handleError(error); 113 } else { 114 this.#handleError(error); 115 } 116 } 117 } 118 119 static async options(endpoint, headers = {}) { 120 return this.#request(endpoint, 'OPTIONS', null, headers); 121 } 122 123 static async head(endpoint, headers = {}) { 124 return this.#request(endpoint, 'HEAD', null, headers); 125 } 126 127 static async get(endpoint, headers = {}) { 128 return this.#request(endpoint, 'GET', null, headers); 129 } 130 131 static async delete(endpoint, headers = {}) {
132 return this.#request(endpoint, 'DELETE', null, headers); 133 } 134 135 static async post(endpoint, body, headers = {}, handleResponse = false, handleError = false) { 136 return this.#request(endpoint, 'POST', body, headers, handleResponse, handleError); 137 } 138 139 static async put(endpoint, body, headers = {}) { 140 return this.#request(endpoint, 'PUT', body, headers); 141 } 142 143 static async patch(endpoint, body, headers = {}) { 144 return this.#request(endpoint, 'PATCH', body, headers); 145 } 146 147 static async upload(endpoint, file, additionalFields = {}, headers = {}) { 148 /* 149 const formData = new FormData(); 150 formData.append('file', file); 151 // Agregar campos adicionales al FormData si existen 152 for (const key in additionalFields) { 153 formData.append(key, additionalFields[key]); 154 } 155 */ 156 const formData = this.json2FormData(additionalFields); 157 formData.append('file', file); 158 return this.#request(endpoint, 'POST', formData, headers); 159 } 160 161 // Función para manejar la respuesta según su tipo 162 static #handleResponse(data, contentType = '') { 163 this.#consoleDebug('f handleResponse: ', data, contentType); 164 /* 165 // Si es un blob, podrÃas crear un enlace de descarga 166 const url = URL.createObjectURL(data); 167 const a = document.createElement('a'); 168 a.href = url; 169 a.download = 'file'; 170 document.body.appendChild(a); 171 a.click(); 172 URL.revokeObjectURL(url); 173 document.body.removeChild(a); 174 */ 175 } 176 177 static #handleError(error) { 178 this.#consoleDebug('f handleError:', error); 179 throw error; 180 } 181 182 static json2FormData(json) { 183 const formData = new FormData(); 184 for (const key in json) { 185 formData.append(key, json[key]); 186 } 187 return formData; 188 } 189}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.