@bryanochoa/custom-fetch-api 1.0.1 → 2.0.0

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 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,117 @@ 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
+
26
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
+ :
92
+ const fetcher = new CustomFetchAPI({
93
+ baseUrl: "https://api.example.com",
94
+ // safeTokenOn:{
95
+ // keyname:"token",
96
+ // storage:"sessionStorage | localStorage "
97
+ // }
98
+ });
99
+ //agregar token a localStorage/sessionStorage
100
+ fetcher.setToken("token_here",{
101
+ storage:"localStorage",
102
+ keyname:"token"
103
+ })
104
+
105
+ //eliminar token
106
+ fetcher.removeToken()
107
+
108
+ ```
109
+ 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.
110
+
111
+ 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.
112
+
113
+ ## ¿Y entonces, que enfoque deberia elegir?
114
+
115
+ 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.
116
+
117
+ ## Versión 1 función makeApiRequest()
27
118
 
28
119
  - Ejemplo de uso
29
120
 
30
121
  Petición GET:
31
122
 
32
123
  ```
124
+
33
125
  const data = await makeApiRequest('https://api.example.com/data');
126
+
34
127
  ```
35
128
 
36
129
  Petición POST:
37
130
 
38
131
  ```
132
+
39
133
  const data = await makeApiRequest('https://api.example.com/data', {
40
- method: 'POST',
134
+ method: 'POST',
41
135
 
42
- body: {
43
- key: 'value'
44
- }
136
+ body: {
137
+ key: 'value'
138
+ }
45
139
  });
46
140
 
47
141
  ```
@@ -49,6 +143,7 @@ const data = await makeApiRequest('https://api.example.com/data', {
49
143
  Petición PUT:
50
144
 
51
145
  ```
146
+
52
147
  const data = await makeApiRequest('https://api.example.com/data', {
53
148
  method: 'PUT',
54
149
  body: {
@@ -61,9 +156,10 @@ key: 'value'
61
156
  Si tu peticion maneja tokens de autenticación, puedes incluirlos en el objeto de configuración:
62
157
 
63
158
  ```
159
+
64
160
  const data = await makeApiRequest('https://api.example.com/data', {
65
161
  method: 'GET',
66
- token:"Bearer your_token_here"
162
+ token:"your_token_here"
67
163
  });
68
164
 
69
165
  ```
@@ -94,12 +190,12 @@ interface ApiResponse {
94
190
  id: number;
95
191
  name: string;}
96
192
 
97
-
98
193
  ```
99
194
 
100
195
  Petición GET:
101
196
 
102
197
  ```
198
+
103
199
  const data = await makeApiRequest<ApiResponse>('https://api.example.com/data');
104
200
 
105
201
  console.log(data.id);
@@ -115,3 +211,4 @@ Por ultimo, se puede cambiar el content-type de la solicitud HTTP, por defecto s
115
211
  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
212
 
117
213
  El proyecto se encuentra en constante desarrollo y se espera que se agreguen más funcionalidades y mejoras en el futuro.
214
+ ```
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
- export { makeApiRequest };
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
- export { makeApiRequest };
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,17 +1,22 @@
1
1
  {
2
2
  "name": "@bryanochoa/custom-fetch-api",
3
3
  "type": "module",
4
- "version": "1.0.1",
4
+ "version": "2.0.0",
5
5
  "description": "fetch API personalizado",
6
6
  "author": "Bryan Ochoa <bryanjm96@gmail.com>",
7
7
  "license": "MIT",
8
- "homepage": "https://github.com/author/library#readme",
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
- "url": "git+https://github.com/author/library.git"
16
+ "url": "https://github.com/bryanmsombra27/custom-fetch-api.git"
12
17
  },
13
18
  "bugs": {
14
- "url": "https://github.com/author/library/issues"
19
+ "url": "https://github.com/bryanmsombra27/custom-fetch-api/issues"
15
20
  },
16
21
  "exports": {
17
22
  ".": "./dist/index.mjs",