@bryanochoa/custom-fetch-api 1.0.3 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -6
- package/dist/index.d.mts +42 -1
- package/dist/index.mjs +105 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@ Este proyecto utiliza la funcionalidad nativa del FETCH API para realizar solici
|
|
|
4
4
|
|
|
5
5
|
Cabe aclarar que este proyecto no es un reemplazo completo del FETCH API, sino una capa adicional que facilita su uso en ciertos escenarios. El proyecto sigue en construcción y esta sujeto a cambios y mejoras continuas. De momento, se encuentra en una fase inicial de desarrollo y se espera que evolucione con el tiempo.
|
|
6
6
|
|
|
7
|
+
Recientemente he agregado una version alterna dentro del mismo paquete, cuya funcionalidad asemeja como trabaja axios, si bien no funcionan y no integra todo lo que ofrece axios, resulta una alternativa a mi parecer mucho mas funcional que la primera version que lance. Esta nueva versión resuelve un par de detalles como lo son el manejo de la url de la api y la persistencia del token en caso de ser enviado en la peticion. A continuación te muestro la nueva forma de trabajar con este paquete, no obstante puedes continuar trabajando en la primera version que igual continuare dando soporte y agregando funcionalidades hasta donde la logica y el fetch me lo permitan.
|
|
8
|
+
|
|
7
9
|
### Instalación
|
|
8
10
|
|
|
9
11
|
```bash
|
|
@@ -23,25 +25,121 @@ pnpm add @bryanochoa/custom-fetch-api
|
|
|
23
25
|
```bash
|
|
24
26
|
yarn add @bryanochoa/custom-fetch-api
|
|
25
27
|
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Versión 2 implementación mediante clase CustomFetchAPI
|
|
32
|
+
|
|
33
|
+
Para esta nueva versión el enfoque se hace mediante una clase cuya instancia maneja las peticiones http más comunes(GET,POST,PUT,PATCH,DELETE), cada verbo contiene su metodo respectivo en la instancia.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
**Ejemplo de uso**
|
|
38
|
+
|
|
39
|
+
- Peticion GET:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
import {CustomFetchAPI} from "@bryanochoa/custom-fetch-api"
|
|
43
|
+
|
|
44
|
+
const fetcher = new CustomFetchAPI({
|
|
45
|
+
baseUrl: "https://api.example.com",
|
|
46
|
+
});
|
|
47
|
+
const data = await fetcher.get("/data");
|
|
48
|
+
console.log(data, "DATA");
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
- Petición POST:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
import {CustomFetchAPI} from "@bryanochoa/custom-fetch-api"
|
|
55
|
+
|
|
56
|
+
const fetcher = new CustomFetchAPI({
|
|
57
|
+
baseUrl: "https://api.example.com",
|
|
58
|
+
});
|
|
59
|
+
const data = await fetcher.post("/data",{
|
|
60
|
+
body:{}
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- Petición PUT:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
import {CustomFetchAPI} from "@bryanochoa/custom-fetch-api"
|
|
68
|
+
|
|
69
|
+
const fetcher = new CustomFetchAPI({
|
|
70
|
+
baseUrl: "https://api.example.com",
|
|
71
|
+
});
|
|
72
|
+
const data = await fetcher.put("/data/1",{
|
|
73
|
+
body:{}
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- Petición DELETE:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
import {CustomFetchAPI} from "@bryanochoa/custom-fetch-api"
|
|
81
|
+
|
|
82
|
+
const fetcher = new CustomFetchAPI({
|
|
83
|
+
baseUrl: "https://api.example.com",
|
|
84
|
+
});
|
|
85
|
+
const data = await fetcher.delete("data/1");
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Manejo del token
|
|
89
|
+
|
|
90
|
+
En este nuevo enfoque al ser una instancia de una clase, cuenta con metodos para colocar o remover el token en la peticion http se configura de la siguiente forma. Puedes configurar la persistencia del token en localStorage o sessionStorage desde la instancia de la clase y asi no tener que colocarlo en cada peticion donde tengas que colocar el token, esta configuracion es opcional,si no la configuras en este punto puedes hacerlo desde el metodo de la instancia setToken() su segundo parametro es un objeto de configuracion que te permite configurar la persistencia del token en localStorage o sessionStorage, si no lo configuras el token se colocara en la peticion pero no se guardara en ningun lado y tendras que colocarlo en cada peticion donde sea necesario.
|
|
91
|
+
|
|
26
92
|
```
|
|
93
|
+
import {CustomFetchAPI} from "@bryanochoa/custom-fetch-api"
|
|
94
|
+
|
|
95
|
+
const fetcher = new CustomFetchAPI({
|
|
96
|
+
baseUrl: "https://api.example.com",
|
|
97
|
+
// safeTokenOn:{
|
|
98
|
+
// keyname:"token",
|
|
99
|
+
// storage:"sessionStorage | localStorage "
|
|
100
|
+
// }
|
|
101
|
+
});
|
|
102
|
+
//agregar token a localStorage/sessionStorage
|
|
103
|
+
fetcher.setToken("token_here",{
|
|
104
|
+
storage:"localStorage",
|
|
105
|
+
keyname:"token"
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
//eliminar token
|
|
109
|
+
fetcher.removeToken()
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
En esta nueva implementación del manejo del token, te permite configurar la persistencia del token ya sea en local storage o en session storage una vez colocado el token intento emular el comportamiento de axios con los interceptores, al mandar el token si existe en todas las peticiones mediante el header de Authorization todo eso lo hace automaticamente ya que es el caso mas común de enviar el token en una api.
|
|
114
|
+
|
|
115
|
+
En conclusión, esta nueva versión de la librería ofrece una forma más estructurada y flexible de realizar solicitudes HTTP, con un manejo más eficiente del token de autenticación y una interfaz más clara para interactuar con APIs externas.
|
|
116
|
+
|
|
117
|
+
## ¿Y entonces, que enfoque deberia elegir?
|
|
118
|
+
|
|
119
|
+
Ten encuenta que la primera versión esta enfocada en realizar peticiones HTTP ya sea desde el frontend o el backend (en versiones de nodejs que ya soporten el fetch api) y en esta nueva implementación el enfoque incluye la persistencia del token mediante localStorage o sessionStorage, por lo que si tu proyecto requiere de esta funcionalidad te recomiendo utilizar la segunda versión, en caso contrario puedes seguir utilizando la primera versión que igual seguirá recibiendo soporte y mejoras hasta donde la logica y el fetch api nativo me lo permita.
|
|
120
|
+
|
|
121
|
+
## Versión 1 función makeApiRequest()
|
|
27
122
|
|
|
28
123
|
- Ejemplo de uso
|
|
29
124
|
|
|
30
125
|
Petición GET:
|
|
31
126
|
|
|
32
127
|
```
|
|
128
|
+
|
|
33
129
|
const data = await makeApiRequest('https://api.example.com/data');
|
|
130
|
+
|
|
34
131
|
```
|
|
35
132
|
|
|
36
133
|
Petición POST:
|
|
37
134
|
|
|
38
135
|
```
|
|
136
|
+
|
|
39
137
|
const data = await makeApiRequest('https://api.example.com/data', {
|
|
40
|
-
|
|
138
|
+
method: 'POST',
|
|
41
139
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
140
|
+
body: {
|
|
141
|
+
key: 'value'
|
|
142
|
+
}
|
|
45
143
|
});
|
|
46
144
|
|
|
47
145
|
```
|
|
@@ -49,6 +147,7 @@ const data = await makeApiRequest('https://api.example.com/data', {
|
|
|
49
147
|
Petición PUT:
|
|
50
148
|
|
|
51
149
|
```
|
|
150
|
+
|
|
52
151
|
const data = await makeApiRequest('https://api.example.com/data', {
|
|
53
152
|
method: 'PUT',
|
|
54
153
|
body: {
|
|
@@ -61,9 +160,10 @@ key: 'value'
|
|
|
61
160
|
Si tu peticion maneja tokens de autenticación, puedes incluirlos en el objeto de configuración:
|
|
62
161
|
|
|
63
162
|
```
|
|
163
|
+
|
|
64
164
|
const data = await makeApiRequest('https://api.example.com/data', {
|
|
65
165
|
method: 'GET',
|
|
66
|
-
token:"
|
|
166
|
+
token:"your_token_here"
|
|
67
167
|
});
|
|
68
168
|
|
|
69
169
|
```
|
|
@@ -94,12 +194,12 @@ interface ApiResponse {
|
|
|
94
194
|
id: number;
|
|
95
195
|
name: string;}
|
|
96
196
|
|
|
97
|
-
|
|
98
197
|
```
|
|
99
198
|
|
|
100
199
|
Petición GET:
|
|
101
200
|
|
|
102
201
|
```
|
|
202
|
+
|
|
103
203
|
const data = await makeApiRequest<ApiResponse>('https://api.example.com/data');
|
|
104
204
|
|
|
105
205
|
console.log(data.id);
|
|
@@ -115,3 +215,7 @@ Por ultimo, se puede cambiar el content-type de la solicitud HTTP, por defecto s
|
|
|
115
215
|
No lo mencione en ejemplos anteriores pero por defecto, las peticiones de tipo POST,PUT,PATCH la propiedad body se convierte automáticamente a JSON por ende es obligatorio que para esta propiedad se pase un objeto, de lo contrario la petición fallara.
|
|
116
216
|
|
|
117
217
|
El proyecto se encuentra en constante desarrollo y se espera que se agreguen más funcionalidades y mejoras en el futuro.
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
```
|
package/dist/index.d.mts
CHANGED
|
@@ -9,4 +9,45 @@ interface RequestOptions {
|
|
|
9
9
|
}
|
|
10
10
|
declare function makeApiRequest<T>(url: string, options?: RequestOptions): Promise<T>;
|
|
11
11
|
//#endregion
|
|
12
|
-
|
|
12
|
+
//#region src/fetchByClass.d.ts
|
|
13
|
+
interface CustomFetchSearchParams {
|
|
14
|
+
searchParams?: Record<string, any>;
|
|
15
|
+
}
|
|
16
|
+
type ContentType = "application/json" | "FormData";
|
|
17
|
+
interface CustomFetchOptions extends CustomFetchSearchParams {
|
|
18
|
+
body?: any;
|
|
19
|
+
contentType?: ContentType;
|
|
20
|
+
}
|
|
21
|
+
interface BaseOptions {
|
|
22
|
+
baseUrl?: string;
|
|
23
|
+
safeTokenOn?: SafeTokenOn;
|
|
24
|
+
}
|
|
25
|
+
type SafeTokenOn = LocalStorageOptionsConfig | SessionStorageOptionsConfig;
|
|
26
|
+
type LocalStorageOptionsConfig = {
|
|
27
|
+
storage?: "localStorage";
|
|
28
|
+
keyname: string;
|
|
29
|
+
};
|
|
30
|
+
type SessionStorageOptionsConfig = {
|
|
31
|
+
storage?: "sessionStorage";
|
|
32
|
+
keyname: string;
|
|
33
|
+
};
|
|
34
|
+
declare class CustomFetchAPI {
|
|
35
|
+
private baseUrl?;
|
|
36
|
+
private token?;
|
|
37
|
+
private headers;
|
|
38
|
+
private optionRequest;
|
|
39
|
+
private safeTokenOn?;
|
|
40
|
+
constructor(options?: BaseOptions);
|
|
41
|
+
get<T>(url: string, searchParams?: CustomFetchSearchParams): Promise<T>;
|
|
42
|
+
post<T>(url: string, { searchParams, body, contentType }: CustomFetchOptions): Promise<T>;
|
|
43
|
+
put<T>(url: string, { searchParams, body, contentType }: CustomFetchOptions): Promise<T>;
|
|
44
|
+
patch<T>(url: string, { searchParams, body, contentType }: CustomFetchOptions): Promise<T>;
|
|
45
|
+
delete<T>(url: string): Promise<T>;
|
|
46
|
+
private setBody;
|
|
47
|
+
private setParams;
|
|
48
|
+
private verifyTokenWereSet;
|
|
49
|
+
setToken(token: string, safeTokenOn?: SafeTokenOn): void;
|
|
50
|
+
removeToken(): void;
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { BaseOptions, CustomFetchAPI, CustomFetchOptions, makeApiRequest };
|
package/dist/index.mjs
CHANGED
|
@@ -21,4 +21,108 @@ async function makeApiRequest(url, options) {
|
|
|
21
21
|
return await (await fetch(finalUrl, optionRequest)).json();
|
|
22
22
|
}
|
|
23
23
|
//#endregion
|
|
24
|
-
|
|
24
|
+
//#region src/fetchByClass.ts
|
|
25
|
+
var CustomFetchAPI = class {
|
|
26
|
+
baseUrl;
|
|
27
|
+
token;
|
|
28
|
+
headers;
|
|
29
|
+
optionRequest;
|
|
30
|
+
safeTokenOn;
|
|
31
|
+
constructor(options) {
|
|
32
|
+
const headers = new Headers();
|
|
33
|
+
if (options?.baseUrl) this.baseUrl = options.baseUrl;
|
|
34
|
+
this.headers = headers;
|
|
35
|
+
this.optionRequest = { headers: this.headers };
|
|
36
|
+
if (options?.safeTokenOn) this.safeTokenOn = options.safeTokenOn;
|
|
37
|
+
}
|
|
38
|
+
async get(url, searchParams) {
|
|
39
|
+
this.verifyTokenWereSet();
|
|
40
|
+
const finalUrl = this.setParams(url, { searchParams });
|
|
41
|
+
return await (await fetch(finalUrl, this.optionRequest)).json();
|
|
42
|
+
}
|
|
43
|
+
async post(url, { searchParams, body, contentType }) {
|
|
44
|
+
this.verifyTokenWereSet();
|
|
45
|
+
this.optionRequest.method = "POST";
|
|
46
|
+
this.setBody(body, contentType);
|
|
47
|
+
const finalUrl = this.setParams(url, searchParams);
|
|
48
|
+
return await (await fetch(finalUrl, this.optionRequest)).json();
|
|
49
|
+
}
|
|
50
|
+
async put(url, { searchParams, body, contentType }) {
|
|
51
|
+
this.verifyTokenWereSet();
|
|
52
|
+
this.optionRequest.method = "PUT";
|
|
53
|
+
this.setBody(body, contentType);
|
|
54
|
+
const finalUrl = this.setParams(url, searchParams);
|
|
55
|
+
return await (await fetch(finalUrl, this.optionRequest)).json();
|
|
56
|
+
}
|
|
57
|
+
async patch(url, { searchParams, body, contentType }) {
|
|
58
|
+
this.verifyTokenWereSet();
|
|
59
|
+
this.optionRequest.method = "PATCH";
|
|
60
|
+
this.setBody(body, contentType);
|
|
61
|
+
const finalUrl = this.setParams(url, searchParams);
|
|
62
|
+
return await (await fetch(finalUrl, this.optionRequest)).json();
|
|
63
|
+
}
|
|
64
|
+
async delete(url) {
|
|
65
|
+
this.verifyTokenWereSet();
|
|
66
|
+
this.optionRequest.method = "DELETE";
|
|
67
|
+
const uri = this.baseUrl ? `${this.baseUrl}${url}` : url;
|
|
68
|
+
return await (await fetch(uri, this.optionRequest)).json();
|
|
69
|
+
}
|
|
70
|
+
setBody(body, contentType) {
|
|
71
|
+
if (contentType == "application/json") this.headers.append("Content-Type", "application/json");
|
|
72
|
+
if (body && contentType == "application/json") this.optionRequest.body = JSON.stringify(body);
|
|
73
|
+
}
|
|
74
|
+
setParams(url, { searchParams }) {
|
|
75
|
+
let partialUrl = "";
|
|
76
|
+
if (searchParams) {
|
|
77
|
+
const urlWithSearchParams = new URLSearchParams();
|
|
78
|
+
for (const [key, value] of Object.entries(searchParams)) urlWithSearchParams.append(key, value.toString());
|
|
79
|
+
partialUrl = urlWithSearchParams.toString();
|
|
80
|
+
}
|
|
81
|
+
const uri = this.baseUrl ? `${this.baseUrl}${url}` : url;
|
|
82
|
+
return partialUrl != "" ? uri.concat("?", partialUrl) : uri;
|
|
83
|
+
}
|
|
84
|
+
verifyTokenWereSet() {
|
|
85
|
+
if (this.safeTokenOn) this.token = this.safeTokenOn.storage == "localStorage" ? LocalStorage.getItem(this.safeTokenOn.keyname) : SessionStorage.getItem(this.safeTokenOn.keyname);
|
|
86
|
+
if (this.token != null && !this.headers.has("Authorization")) this.headers.append("Authorization", `Bearer ${this.token}`);
|
|
87
|
+
}
|
|
88
|
+
setToken(token, safeTokenOn) {
|
|
89
|
+
if (token) {
|
|
90
|
+
this.token = token;
|
|
91
|
+
this.headers.append("Authorization", `Bearer ${token}`);
|
|
92
|
+
if (this.safeTokenOn) this.safeTokenOn.storage == "localStorage" ? LocalStorage.setItem(this.safeTokenOn.keyname, token) : SessionStorage.setItem(this.safeTokenOn.keyname, token);
|
|
93
|
+
if (safeTokenOn) {
|
|
94
|
+
this.safeTokenOn = safeTokenOn;
|
|
95
|
+
this.safeTokenOn.storage == "localStorage" ? LocalStorage.setItem(this.safeTokenOn.keyname, token) : SessionStorage.setItem(this.safeTokenOn.keyname, token);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
removeToken() {
|
|
100
|
+
this.token = "";
|
|
101
|
+
this.headers.delete("Authorization");
|
|
102
|
+
if (this.safeTokenOn) this.safeTokenOn.storage == "localStorage" ? LocalStorage.removeItem(this.safeTokenOn.keyname) : SessionStorage.removeItem(this.safeTokenOn.keyname);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
var LocalStorage = class {
|
|
106
|
+
static getItem(key) {
|
|
107
|
+
return localStorage.getItem(key);
|
|
108
|
+
}
|
|
109
|
+
static setItem(key, value) {
|
|
110
|
+
localStorage.setItem(key, value);
|
|
111
|
+
}
|
|
112
|
+
static removeItem(key) {
|
|
113
|
+
localStorage.removeItem(key);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
var SessionStorage = class {
|
|
117
|
+
static getItem(key) {
|
|
118
|
+
return sessionStorage.getItem(key);
|
|
119
|
+
}
|
|
120
|
+
static setItem(key, value) {
|
|
121
|
+
sessionStorage.setItem(key, value);
|
|
122
|
+
}
|
|
123
|
+
static removeItem(key) {
|
|
124
|
+
sessionStorage.removeItem(key);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
//#endregion
|
|
128
|
+
export { CustomFetchAPI, makeApiRequest };
|
package/package.json
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bryanochoa/custom-fetch-api",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.1",
|
|
5
5
|
"description": "fetch API personalizado",
|
|
6
6
|
"author": "Bryan Ochoa <bryanjm96@gmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"homepage": "https://github.com/bryanmsombra27/custom-fetch-api#readme",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"fetch",
|
|
11
|
+
"api",
|
|
12
|
+
"node"
|
|
13
|
+
],
|
|
9
14
|
"repository": {
|
|
10
15
|
"type": "git",
|
|
11
16
|
"url": "https://github.com/bryanmsombra27/custom-fetch-api.git"
|