@tmlmobilidade/utils 20260526.2143.45 → 20260527.1749.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/dist/http/fetch-data.d.ts +23 -0
- package/dist/http/fetch-data.js +77 -0
- package/dist/http/http.d.ts +17 -0
- package/dist/http/http.js +18 -0
- package/dist/http/index.d.ts +5 -0
- package/dist/http/index.js +5 -0
- package/dist/http/multipart.d.ts +26 -0
- package/dist/http/multipart.js +59 -0
- package/dist/http/response.d.ts +11 -0
- package/dist/http/response.js +13 -0
- package/dist/http/swr.d.ts +28 -0
- package/dist/http/swr.js +47 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/http.d.ts +0 -95
- package/dist/http.js +0 -195
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { HttpResponse } from './response.js';
|
|
2
|
+
/**
|
|
3
|
+
* Fetches data from a URL with configurable HTTP method, body, headers, and options.
|
|
4
|
+
* @param url - The URL to fetch from
|
|
5
|
+
* @param method - The HTTP method to use (DELETE, GET, POST, PUT). Defaults to GET.
|
|
6
|
+
* @param body - Optional request body data
|
|
7
|
+
* @param headers - Optional request headers
|
|
8
|
+
* @param options - Optional fetch options (excluding body, headers, method)
|
|
9
|
+
* @returns Promise resolving to HttpResponse containing data, error and status
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* // GET request
|
|
13
|
+
* const response = await fetchData<User>('/api/users/123');
|
|
14
|
+
*
|
|
15
|
+
* // POST request with body
|
|
16
|
+
* const response = await fetchData<User>(
|
|
17
|
+
* '/api/users',
|
|
18
|
+
* 'POST',
|
|
19
|
+
* { name: 'John', email: 'john@example.com' }
|
|
20
|
+
* );
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function fetchData<T>(url: string, method?: 'DELETE' | 'GET' | 'POST' | 'PUT', body?: unknown, headers?: Record<string, string>, options?: Omit<RequestInit, 'body' | 'headers' | 'method'>, retries?: number): Promise<HttpResponse<T>>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
import { HttpResponse } from './response.js';
|
|
3
|
+
/**
|
|
4
|
+
* Fetches data from a URL with configurable HTTP method, body, headers, and options.
|
|
5
|
+
* @param url - The URL to fetch from
|
|
6
|
+
* @param method - The HTTP method to use (DELETE, GET, POST, PUT). Defaults to GET.
|
|
7
|
+
* @param body - Optional request body data
|
|
8
|
+
* @param headers - Optional request headers
|
|
9
|
+
* @param options - Optional fetch options (excluding body, headers, method)
|
|
10
|
+
* @returns Promise resolving to HttpResponse containing data, error and status
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // GET request
|
|
14
|
+
* const response = await fetchData<User>('/api/users/123');
|
|
15
|
+
*
|
|
16
|
+
* // POST request with body
|
|
17
|
+
* const response = await fetchData<User>(
|
|
18
|
+
* '/api/users',
|
|
19
|
+
* 'POST',
|
|
20
|
+
* { name: 'John', email: 'john@example.com' }
|
|
21
|
+
* );
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export async function fetchData(url, method = 'GET', body, headers = {}, options = {}, retries = 3) {
|
|
25
|
+
let attempt = 0;
|
|
26
|
+
let lastError;
|
|
27
|
+
while (attempt <= retries) {
|
|
28
|
+
try {
|
|
29
|
+
const response = await fetch(url, {
|
|
30
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
31
|
+
credentials: 'include',
|
|
32
|
+
headers: {
|
|
33
|
+
...(method === 'GET' || method === 'DELETE' || 'Content-Type' in headers
|
|
34
|
+
? {}
|
|
35
|
+
: { 'Content-Type': 'application/json' }),
|
|
36
|
+
...headers,
|
|
37
|
+
},
|
|
38
|
+
method,
|
|
39
|
+
...options,
|
|
40
|
+
});
|
|
41
|
+
const data = (await response.json());
|
|
42
|
+
if (!response.ok || data.error) {
|
|
43
|
+
// Don't retry for 4xx (client) errors
|
|
44
|
+
if (response.status >= 400 && response.status < 500) {
|
|
45
|
+
return new HttpResponse({
|
|
46
|
+
data: null,
|
|
47
|
+
error: data.error,
|
|
48
|
+
statusCode: response.status,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
throw new Error(`HTTP ${response.status} - ${data.error ?? 'Unknown error'}`);
|
|
52
|
+
}
|
|
53
|
+
return new HttpResponse({
|
|
54
|
+
data: data.data,
|
|
55
|
+
error: null,
|
|
56
|
+
statusCode: response.status,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
lastError = error;
|
|
61
|
+
attempt++;
|
|
62
|
+
// Stop retrying if we've reached the limit
|
|
63
|
+
if (attempt > retries)
|
|
64
|
+
break;
|
|
65
|
+
// Wait before retrying (exponential backoff: 0.5s, 1s, 2s, etc.)
|
|
66
|
+
const delay = 500 * Math.pow(2, attempt - 1);
|
|
67
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return new HttpResponse({
|
|
71
|
+
data: null,
|
|
72
|
+
error: lastError instanceof Error
|
|
73
|
+
? `${lastError.message} - ${lastError.cause ?? ''}`
|
|
74
|
+
: 'Network error',
|
|
75
|
+
statusCode: 500,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type WithPagination<T> = T & {
|
|
2
|
+
pagination: {
|
|
3
|
+
limit: number;
|
|
4
|
+
page: number;
|
|
5
|
+
total: number;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Fetches data from a URL using the SWR fetcher function without authentication.
|
|
10
|
+
* @param url - The URL to fetch from
|
|
11
|
+
* @returns Promise resolving to the fetched data
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const data = await standardSwrFetcher('/api/users/123');
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare const standardSwrFetcher: <T>(url: string) => Promise<T>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
import { HttpException } from '@tmlmobilidade/consts';
|
|
3
|
+
/**
|
|
4
|
+
* Fetches data from a URL using the SWR fetcher function without authentication.
|
|
5
|
+
* @param url - The URL to fetch from
|
|
6
|
+
* @returns Promise resolving to the fetched data
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const data = await standardSwrFetcher('/api/users/123');
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export const standardSwrFetcher = async (url) => {
|
|
13
|
+
const res = await fetch(url, { credentials: 'omit' });
|
|
14
|
+
if (!res.ok) {
|
|
15
|
+
throw new HttpException(res.status, res.statusText);
|
|
16
|
+
}
|
|
17
|
+
return res.json();
|
|
18
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { HttpResponse } from './response.js';
|
|
2
|
+
/**
|
|
3
|
+
* Sends a multipart form data request to a URL.
|
|
4
|
+
* @param url - The URL to send the request to
|
|
5
|
+
* @param formData - The FormData object containing the multipart form data
|
|
6
|
+
* @returns Promise resolving to HttpResponse containing data, error and status
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const formData = new FormData();
|
|
10
|
+
* formData.append('file', fileBlob);
|
|
11
|
+
* formData.append('name', 'profile.jpg');
|
|
12
|
+
* const response = await multipartFetch('/api/upload', formData);
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare function multipartFetch<T>(url: string, formData: FormData): Promise<HttpResponse<T>>;
|
|
16
|
+
/**
|
|
17
|
+
* Uploads a file to a URL using multipart form data.
|
|
18
|
+
* @param url - The URL to send the request to
|
|
19
|
+
* @param file - The file to upload
|
|
20
|
+
* @returns Promise resolving to HttpResponse containing data, error and status
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const response = await uploadFile('/api/upload', file);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function uploadFile<T>(url: string, file: File): Promise<HttpResponse<T>>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
import { HttpResponse } from './response.js';
|
|
3
|
+
/**
|
|
4
|
+
* Sends a multipart form data request to a URL.
|
|
5
|
+
* @param url - The URL to send the request to
|
|
6
|
+
* @param formData - The FormData object containing the multipart form data
|
|
7
|
+
* @returns Promise resolving to HttpResponse containing data, error and status
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const formData = new FormData();
|
|
11
|
+
* formData.append('file', fileBlob);
|
|
12
|
+
* formData.append('name', 'profile.jpg');
|
|
13
|
+
* const response = await multipartFetch('/api/upload', formData);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export async function multipartFetch(url, formData) {
|
|
17
|
+
try {
|
|
18
|
+
const response = await fetch(url, {
|
|
19
|
+
body: formData,
|
|
20
|
+
credentials: 'include',
|
|
21
|
+
method: 'POST',
|
|
22
|
+
});
|
|
23
|
+
const data = await response.json();
|
|
24
|
+
if (!response.ok || data.error) {
|
|
25
|
+
return new HttpResponse({
|
|
26
|
+
data: null,
|
|
27
|
+
error: data.error,
|
|
28
|
+
statusCode: response.status,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return new HttpResponse({
|
|
32
|
+
data: data.data,
|
|
33
|
+
error: null,
|
|
34
|
+
statusCode: response.status,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
return new HttpResponse({
|
|
39
|
+
data: null,
|
|
40
|
+
error: error instanceof Error ? error.message : 'Network error',
|
|
41
|
+
statusCode: 500,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Uploads a file to a URL using multipart form data.
|
|
47
|
+
* @param url - The URL to send the request to
|
|
48
|
+
* @param file - The file to upload
|
|
49
|
+
* @returns Promise resolving to HttpResponse containing data, error and status
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* const response = await uploadFile('/api/upload', file);
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export async function uploadFile(url, file) {
|
|
56
|
+
const formData = new FormData();
|
|
57
|
+
formData.append('file', file, file.name);
|
|
58
|
+
return await multipartFetch(url, formData);
|
|
59
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class HttpResponse<T> {
|
|
2
|
+
readonly data: null | T;
|
|
3
|
+
readonly error: null | string;
|
|
4
|
+
readonly isOk?: () => boolean;
|
|
5
|
+
readonly statusCode: number;
|
|
6
|
+
constructor({ data, error, statusCode }: {
|
|
7
|
+
data: null | T;
|
|
8
|
+
error: null | string;
|
|
9
|
+
statusCode: number;
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
export class HttpResponse {
|
|
3
|
+
data;
|
|
4
|
+
error;
|
|
5
|
+
isOk;
|
|
6
|
+
statusCode;
|
|
7
|
+
constructor({ data, error, statusCode }) {
|
|
8
|
+
this.data = data;
|
|
9
|
+
this.error = error;
|
|
10
|
+
this.statusCode = statusCode;
|
|
11
|
+
this.isOk = () => statusCode >= 200 && statusCode < 300;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface SwrFetcherOptions {
|
|
2
|
+
credentials?: RequestInit['credentials'];
|
|
3
|
+
url: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Fetches data from a URL using the SWR fetcher function.
|
|
7
|
+
* @param urlOrOptions The URL to fetch from or the options object.
|
|
8
|
+
* @returns Promise resolving to the fetched data
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // Fetch data from a URL
|
|
12
|
+
* const data = await swrFetcher('/api/users/123');
|
|
13
|
+
*
|
|
14
|
+
* // Fetch data from a URL with options
|
|
15
|
+
* const data = await swrFetcher({ url: '/api/users/123', credentials: 'omit' });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function swrFetcher<T>(urlOrOptions: string | SwrFetcherOptions): Promise<T>;
|
|
19
|
+
/**
|
|
20
|
+
* Fetches data from a URL using the SWR fetcher function.
|
|
21
|
+
* @param urlOrOptions The URL to fetch from or the options object.
|
|
22
|
+
* @returns Promise resolving to the fetched data
|
|
23
|
+
* @deprecated Use `swrFetcher` with an options object instead.
|
|
24
|
+
* ```ts
|
|
25
|
+
* const data = await swrFetcher({ url: '/api/users/123', credentials: 'omit' });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function unauthenticatedSwrFetcher<T>(url: string): Promise<T>;
|
package/dist/http/swr.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
import { HttpException } from '@tmlmobilidade/consts';
|
|
3
|
+
/**
|
|
4
|
+
* Fetches data from a URL using the SWR fetcher function.
|
|
5
|
+
* @param urlOrOptions The URL to fetch from or the options object.
|
|
6
|
+
* @returns Promise resolving to the fetched data
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* // Fetch data from a URL
|
|
10
|
+
* const data = await swrFetcher('/api/users/123');
|
|
11
|
+
*
|
|
12
|
+
* // Fetch data from a URL with options
|
|
13
|
+
* const data = await swrFetcher({ url: '/api/users/123', credentials: 'omit' });
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export async function swrFetcher(urlOrOptions) {
|
|
17
|
+
//
|
|
18
|
+
//
|
|
19
|
+
// Extract the URL either from the string directly
|
|
20
|
+
// or from the options object
|
|
21
|
+
const urlValue = typeof urlOrOptions === 'string' ? urlOrOptions : urlOrOptions.url;
|
|
22
|
+
//
|
|
23
|
+
// Extract the credentials option from the options object
|
|
24
|
+
// or use the default value. By default, it uses 'include' credentials.
|
|
25
|
+
const credentialsValue = typeof urlOrOptions === 'string' ? 'include' : urlOrOptions.credentials ?? 'include';
|
|
26
|
+
//
|
|
27
|
+
// Perform the fetch operation
|
|
28
|
+
const res = await fetch(urlValue, { credentials: credentialsValue });
|
|
29
|
+
const data = await res.json();
|
|
30
|
+
if (!res.ok) {
|
|
31
|
+
throw new HttpException(res.status, data.error ?? 'An error occurred');
|
|
32
|
+
}
|
|
33
|
+
return data.data;
|
|
34
|
+
}
|
|
35
|
+
;
|
|
36
|
+
/**
|
|
37
|
+
* Fetches data from a URL using the SWR fetcher function.
|
|
38
|
+
* @param urlOrOptions The URL to fetch from or the options object.
|
|
39
|
+
* @returns Promise resolving to the fetched data
|
|
40
|
+
* @deprecated Use `swrFetcher` with an options object instead.
|
|
41
|
+
* ```ts
|
|
42
|
+
* const data = await swrFetcher({ url: '/api/users/123', credentials: 'omit' });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export async function unauthenticatedSwrFetcher(url) {
|
|
46
|
+
return swrFetcher({ credentials: 'omit', url: url });
|
|
47
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export * from './batching/index.js';
|
|
|
2
2
|
export * from './caching/index.js';
|
|
3
3
|
export * from './generic/index.js';
|
|
4
4
|
export * from './get-public-trip-id.js';
|
|
5
|
-
export * from './http.js';
|
|
5
|
+
export * from './http/index.js';
|
|
6
6
|
export * from './numbers/index.js';
|
|
7
7
|
export * from './objects/index.js';
|
|
8
8
|
export * from './permissions.js';
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ export * from './batching/index.js';
|
|
|
2
2
|
export * from './caching/index.js';
|
|
3
3
|
export * from './generic/index.js';
|
|
4
4
|
export * from './get-public-trip-id.js';
|
|
5
|
-
export * from './http.js';
|
|
5
|
+
export * from './http/index.js';
|
|
6
6
|
export * from './numbers/index.js';
|
|
7
7
|
export * from './objects/index.js';
|
|
8
8
|
export * from './permissions.js';
|
package/package.json
CHANGED
package/dist/http.d.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
export declare class HttpResponse<T> {
|
|
2
|
-
readonly data: null | T;
|
|
3
|
-
readonly error: null | string;
|
|
4
|
-
readonly isOk?: () => boolean;
|
|
5
|
-
readonly statusCode: number;
|
|
6
|
-
constructor({ data, error, statusCode }: {
|
|
7
|
-
data: null | T;
|
|
8
|
-
error: null | string;
|
|
9
|
-
statusCode: number;
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
export type WithPagination<T> = T & {
|
|
13
|
-
pagination: {
|
|
14
|
-
limit: number;
|
|
15
|
-
page: number;
|
|
16
|
-
total: number;
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
|
-
/**
|
|
20
|
-
* Fetches data from a URL with configurable HTTP method, body, headers, and options.
|
|
21
|
-
* @param url - The URL to fetch from
|
|
22
|
-
* @param method - The HTTP method to use (DELETE, GET, POST, PUT). Defaults to GET.
|
|
23
|
-
* @param body - Optional request body data
|
|
24
|
-
* @param headers - Optional request headers
|
|
25
|
-
* @param options - Optional fetch options (excluding body, headers, method)
|
|
26
|
-
* @returns Promise resolving to HttpResponse containing data, error and status
|
|
27
|
-
* @example
|
|
28
|
-
* ```ts
|
|
29
|
-
* // GET request
|
|
30
|
-
* const response = await fetchData<User>('/api/users/123');
|
|
31
|
-
*
|
|
32
|
-
* // POST request with body
|
|
33
|
-
* const response = await fetchData<User>(
|
|
34
|
-
* '/api/users',
|
|
35
|
-
* 'POST',
|
|
36
|
-
* { name: 'John', email: 'john@example.com' }
|
|
37
|
-
* );
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
export declare function fetchData<T>(url: string, method?: 'DELETE' | 'GET' | 'POST' | 'PUT', body?: unknown, headers?: Record<string, string>, options?: Omit<RequestInit, 'body' | 'headers' | 'method'>, retries?: number): Promise<HttpResponse<T>>;
|
|
41
|
-
/**
|
|
42
|
-
* Sends a multipart form data request to a URL.
|
|
43
|
-
* @param url - The URL to send the request to
|
|
44
|
-
* @param formData - The FormData object containing the multipart form data
|
|
45
|
-
* @returns Promise resolving to HttpResponse containing data, error and status
|
|
46
|
-
* @example
|
|
47
|
-
* ```ts
|
|
48
|
-
* const formData = new FormData();
|
|
49
|
-
* formData.append('file', fileBlob);
|
|
50
|
-
* formData.append('name', 'profile.jpg');
|
|
51
|
-
* const response = await multipartFetch('/api/upload', formData);
|
|
52
|
-
* ```
|
|
53
|
-
*/
|
|
54
|
-
export declare function multipartFetch<T>(url: string, formData: FormData): Promise<HttpResponse<T>>;
|
|
55
|
-
/**
|
|
56
|
-
* Uploads a file to a URL using multipart form data.
|
|
57
|
-
* @param url - The URL to send the request to
|
|
58
|
-
* @param file - The file to upload
|
|
59
|
-
* @returns Promise resolving to HttpResponse containing data, error and status
|
|
60
|
-
* @example
|
|
61
|
-
* ```ts
|
|
62
|
-
* const response = await uploadFile('/api/upload', file);
|
|
63
|
-
* ```
|
|
64
|
-
*/
|
|
65
|
-
export declare function uploadFile<T>(url: string, file: File): Promise<HttpResponse<T>>;
|
|
66
|
-
/**
|
|
67
|
-
* Fetches data from a URL using the SWR fetcher function.
|
|
68
|
-
* @param url - The URL to fetch from
|
|
69
|
-
* @returns Promise resolving to the fetched data
|
|
70
|
-
* @example
|
|
71
|
-
* ```ts
|
|
72
|
-
* const data = await swrFetcher('/api/users/123');
|
|
73
|
-
* ```
|
|
74
|
-
*/
|
|
75
|
-
export declare const swrFetcher: <T>(url: string) => Promise<T>;
|
|
76
|
-
/**
|
|
77
|
-
* Fetches data from a URL using the SWR fetcher function.
|
|
78
|
-
* @param url - The URL to fetch from
|
|
79
|
-
* @returns Promise resolving to the fetched data
|
|
80
|
-
* @example
|
|
81
|
-
* ```ts
|
|
82
|
-
* const data = await swrFetcher('/api/users/123');
|
|
83
|
-
* ```
|
|
84
|
-
*/
|
|
85
|
-
export declare const unauthenticatedSwrFetcher: <T>(url: string) => Promise<T>;
|
|
86
|
-
/**
|
|
87
|
-
* Fetches data from a URL using the SWR fetcher function without authentication.
|
|
88
|
-
* @param url - The URL to fetch from
|
|
89
|
-
* @returns Promise resolving to the fetched data
|
|
90
|
-
* @example
|
|
91
|
-
* ```ts
|
|
92
|
-
* const data = await standardSwrFetcher('/api/users/123');
|
|
93
|
-
* ```
|
|
94
|
-
*/
|
|
95
|
-
export declare const standardSwrFetcher: <T>(url: string) => Promise<T>;
|
package/dist/http.js
DELETED
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import { HttpException } from '@tmlmobilidade/consts';
|
|
2
|
-
export class HttpResponse {
|
|
3
|
-
data;
|
|
4
|
-
error;
|
|
5
|
-
isOk;
|
|
6
|
-
statusCode;
|
|
7
|
-
constructor({ data, error, statusCode }) {
|
|
8
|
-
this.data = data;
|
|
9
|
-
this.error = error;
|
|
10
|
-
this.statusCode = statusCode;
|
|
11
|
-
this.isOk = () => statusCode >= 200 && statusCode < 300;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Fetches data from a URL with configurable HTTP method, body, headers, and options.
|
|
16
|
-
* @param url - The URL to fetch from
|
|
17
|
-
* @param method - The HTTP method to use (DELETE, GET, POST, PUT). Defaults to GET.
|
|
18
|
-
* @param body - Optional request body data
|
|
19
|
-
* @param headers - Optional request headers
|
|
20
|
-
* @param options - Optional fetch options (excluding body, headers, method)
|
|
21
|
-
* @returns Promise resolving to HttpResponse containing data, error and status
|
|
22
|
-
* @example
|
|
23
|
-
* ```ts
|
|
24
|
-
* // GET request
|
|
25
|
-
* const response = await fetchData<User>('/api/users/123');
|
|
26
|
-
*
|
|
27
|
-
* // POST request with body
|
|
28
|
-
* const response = await fetchData<User>(
|
|
29
|
-
* '/api/users',
|
|
30
|
-
* 'POST',
|
|
31
|
-
* { name: 'John', email: 'john@example.com' }
|
|
32
|
-
* );
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
export async function fetchData(url, method = 'GET', body, headers = {}, options = {}, retries = 3) {
|
|
36
|
-
let attempt = 0;
|
|
37
|
-
let lastError;
|
|
38
|
-
while (attempt <= retries) {
|
|
39
|
-
try {
|
|
40
|
-
const response = await fetch(url, {
|
|
41
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
42
|
-
credentials: 'include',
|
|
43
|
-
headers: {
|
|
44
|
-
...(method === 'GET' || method === 'DELETE' || 'Content-Type' in headers
|
|
45
|
-
? {}
|
|
46
|
-
: { 'Content-Type': 'application/json' }),
|
|
47
|
-
...headers,
|
|
48
|
-
},
|
|
49
|
-
method,
|
|
50
|
-
...options,
|
|
51
|
-
});
|
|
52
|
-
const data = (await response.json());
|
|
53
|
-
if (!response.ok || data.error) {
|
|
54
|
-
// Don't retry for 4xx (client) errors
|
|
55
|
-
if (response.status >= 400 && response.status < 500) {
|
|
56
|
-
return new HttpResponse({
|
|
57
|
-
data: null,
|
|
58
|
-
error: data.error,
|
|
59
|
-
statusCode: response.status,
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
throw new Error(`HTTP ${response.status} - ${data.error ?? 'Unknown error'}`);
|
|
63
|
-
}
|
|
64
|
-
return new HttpResponse({
|
|
65
|
-
data: data.data,
|
|
66
|
-
error: null,
|
|
67
|
-
statusCode: response.status,
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
catch (error) {
|
|
71
|
-
lastError = error;
|
|
72
|
-
attempt++;
|
|
73
|
-
// Stop retrying if we've reached the limit
|
|
74
|
-
if (attempt > retries)
|
|
75
|
-
break;
|
|
76
|
-
// Wait before retrying (exponential backoff: 0.5s, 1s, 2s, etc.)
|
|
77
|
-
const delay = 500 * Math.pow(2, attempt - 1);
|
|
78
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return new HttpResponse({
|
|
82
|
-
data: null,
|
|
83
|
-
error: lastError instanceof Error
|
|
84
|
-
? `${lastError.message} - ${lastError.cause ?? ''}`
|
|
85
|
-
: 'Network error',
|
|
86
|
-
statusCode: 500,
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Sends a multipart form data request to a URL.
|
|
91
|
-
* @param url - The URL to send the request to
|
|
92
|
-
* @param formData - The FormData object containing the multipart form data
|
|
93
|
-
* @returns Promise resolving to HttpResponse containing data, error and status
|
|
94
|
-
* @example
|
|
95
|
-
* ```ts
|
|
96
|
-
* const formData = new FormData();
|
|
97
|
-
* formData.append('file', fileBlob);
|
|
98
|
-
* formData.append('name', 'profile.jpg');
|
|
99
|
-
* const response = await multipartFetch('/api/upload', formData);
|
|
100
|
-
* ```
|
|
101
|
-
*/
|
|
102
|
-
export async function multipartFetch(url, formData) {
|
|
103
|
-
try {
|
|
104
|
-
const response = await fetch(url, {
|
|
105
|
-
body: formData,
|
|
106
|
-
credentials: 'include',
|
|
107
|
-
method: 'POST',
|
|
108
|
-
});
|
|
109
|
-
const data = await response.json();
|
|
110
|
-
if (!response.ok || data.error) {
|
|
111
|
-
return new HttpResponse({
|
|
112
|
-
data: null,
|
|
113
|
-
error: data.error,
|
|
114
|
-
statusCode: response.status,
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
return new HttpResponse({
|
|
118
|
-
data: data.data,
|
|
119
|
-
error: null,
|
|
120
|
-
statusCode: response.status,
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
catch (error) {
|
|
124
|
-
return new HttpResponse({
|
|
125
|
-
data: null,
|
|
126
|
-
error: error instanceof Error ? error.message : 'Network error',
|
|
127
|
-
statusCode: 500,
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Uploads a file to a URL using multipart form data.
|
|
133
|
-
* @param url - The URL to send the request to
|
|
134
|
-
* @param file - The file to upload
|
|
135
|
-
* @returns Promise resolving to HttpResponse containing data, error and status
|
|
136
|
-
* @example
|
|
137
|
-
* ```ts
|
|
138
|
-
* const response = await uploadFile('/api/upload', file);
|
|
139
|
-
* ```
|
|
140
|
-
*/
|
|
141
|
-
export async function uploadFile(url, file) {
|
|
142
|
-
const formData = new FormData();
|
|
143
|
-
formData.append('file', file, file.name);
|
|
144
|
-
return await multipartFetch(url, formData);
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Fetches data from a URL using the SWR fetcher function.
|
|
148
|
-
* @param url - The URL to fetch from
|
|
149
|
-
* @returns Promise resolving to the fetched data
|
|
150
|
-
* @example
|
|
151
|
-
* ```ts
|
|
152
|
-
* const data = await swrFetcher('/api/users/123');
|
|
153
|
-
* ```
|
|
154
|
-
*/
|
|
155
|
-
export const swrFetcher = async (url) => {
|
|
156
|
-
const res = await fetch(url, { credentials: 'include' });
|
|
157
|
-
const data = await res.json();
|
|
158
|
-
if (!res.ok) {
|
|
159
|
-
throw new HttpException(res.status, data.error ?? 'An error occurred');
|
|
160
|
-
}
|
|
161
|
-
return data.data;
|
|
162
|
-
};
|
|
163
|
-
/**
|
|
164
|
-
* Fetches data from a URL using the SWR fetcher function.
|
|
165
|
-
* @param url - The URL to fetch from
|
|
166
|
-
* @returns Promise resolving to the fetched data
|
|
167
|
-
* @example
|
|
168
|
-
* ```ts
|
|
169
|
-
* const data = await swrFetcher('/api/users/123');
|
|
170
|
-
* ```
|
|
171
|
-
*/
|
|
172
|
-
export const unauthenticatedSwrFetcher = async (url) => {
|
|
173
|
-
const res = await fetch(url, { credentials: 'omit' });
|
|
174
|
-
const data = await res.json();
|
|
175
|
-
if (!res.ok) {
|
|
176
|
-
throw new HttpException(res.status, data.error ?? 'An error occurred');
|
|
177
|
-
}
|
|
178
|
-
return data.data;
|
|
179
|
-
};
|
|
180
|
-
/**
|
|
181
|
-
* Fetches data from a URL using the SWR fetcher function without authentication.
|
|
182
|
-
* @param url - The URL to fetch from
|
|
183
|
-
* @returns Promise resolving to the fetched data
|
|
184
|
-
* @example
|
|
185
|
-
* ```ts
|
|
186
|
-
* const data = await standardSwrFetcher('/api/users/123');
|
|
187
|
-
* ```
|
|
188
|
-
*/
|
|
189
|
-
export const standardSwrFetcher = async (url) => {
|
|
190
|
-
const res = await fetch(url, { credentials: 'omit' });
|
|
191
|
-
if (!res.ok) {
|
|
192
|
-
throw new HttpException(res.status, res.statusText);
|
|
193
|
-
}
|
|
194
|
-
return res.json();
|
|
195
|
-
};
|