@alba-cars/common-modules 1.10.3 → 1.10.4
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.
|
@@ -4,5 +4,53 @@ interface ApiRequestOptions extends RequestInit {
|
|
|
4
4
|
timeout?: number;
|
|
5
5
|
signal?: AbortSignal;
|
|
6
6
|
}
|
|
7
|
+
type RequestInterceptor = (config: RequestInit & {
|
|
8
|
+
url: string;
|
|
9
|
+
options: ApiRequestOptions;
|
|
10
|
+
}) => Promise<RequestInit & {
|
|
11
|
+
url: string;
|
|
12
|
+
options: ApiRequestOptions;
|
|
13
|
+
}> | (RequestInit & {
|
|
14
|
+
url: string;
|
|
15
|
+
options: ApiRequestOptions;
|
|
16
|
+
});
|
|
17
|
+
type ResponseInterceptor = (response: Response, requestConfig: RequestInit & {
|
|
18
|
+
url: string;
|
|
19
|
+
}) => Promise<Response> | Response;
|
|
20
|
+
type ResponseErrorInterceptor = (error: any, requestConfig: RequestInit & {
|
|
21
|
+
url: string;
|
|
22
|
+
}) => Promise<Response> | Response | Promise<any> | any;
|
|
23
|
+
declare class InterceptorManager {
|
|
24
|
+
private requestInterceptors;
|
|
25
|
+
private responseInterceptors;
|
|
26
|
+
private responseErrorInterceptors;
|
|
27
|
+
addRequestInterceptor(interceptor: RequestInterceptor): number;
|
|
28
|
+
addResponseInterceptor(interceptor: ResponseInterceptor): number;
|
|
29
|
+
addResponseErrorInterceptor(interceptor: ResponseErrorInterceptor): number;
|
|
30
|
+
removeRequestInterceptor(index: number): void;
|
|
31
|
+
removeResponseInterceptor(index: number): void;
|
|
32
|
+
removeResponseErrorInterceptor(index: number): void;
|
|
33
|
+
clearRequestInterceptors(): void;
|
|
34
|
+
clearResponseInterceptors(): void;
|
|
35
|
+
clearResponseErrorInterceptors(): void;
|
|
36
|
+
clearAllInterceptors(): void;
|
|
37
|
+
applyRequestInterceptors(config: RequestInit & {
|
|
38
|
+
url: string;
|
|
39
|
+
options: ApiRequestOptions;
|
|
40
|
+
}): Promise<RequestInit & {
|
|
41
|
+
url: string;
|
|
42
|
+
options: ApiRequestOptions;
|
|
43
|
+
}>;
|
|
44
|
+
applyResponseInterceptors(response: Response, requestConfig: RequestInit & {
|
|
45
|
+
url: string;
|
|
46
|
+
}): Promise<Response>;
|
|
47
|
+
applyResponseErrorInterceptors(error: any, requestConfig: RequestInit & {
|
|
48
|
+
url: string;
|
|
49
|
+
}): Promise<any>;
|
|
50
|
+
retryRequest<T>(config: RequestInit & {
|
|
51
|
+
url: string;
|
|
52
|
+
}): Promise<T>;
|
|
53
|
+
}
|
|
54
|
+
export declare const interceptors: InterceptorManager;
|
|
7
55
|
export declare function apiRequest<T>(endpoint: string, options?: ApiRequestOptions): Promise<T>;
|
|
8
56
|
export {};
|
|
@@ -3,12 +3,115 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.apiRequest = void 0;
|
|
6
|
+
exports.apiRequest = exports.interceptors = void 0;
|
|
7
7
|
const qs_1 = __importDefault(require("qs"));
|
|
8
8
|
const enums_1 = require("../enums");
|
|
9
9
|
const utils_1 = require("../utils");
|
|
10
10
|
const BASE_URL = process.env.NEXT_PUBLIC_API_URL;
|
|
11
11
|
const DEFAULT_TIMEOUT = (0, utils_1.timeAsMilliseconds)({ seconds: 30 });
|
|
12
|
+
// Interceptor manager
|
|
13
|
+
class InterceptorManager {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.requestInterceptors = [];
|
|
16
|
+
this.responseInterceptors = [];
|
|
17
|
+
this.responseErrorInterceptors = [];
|
|
18
|
+
}
|
|
19
|
+
addRequestInterceptor(interceptor) {
|
|
20
|
+
return this.requestInterceptors.push(interceptor) - 1;
|
|
21
|
+
}
|
|
22
|
+
addResponseInterceptor(interceptor) {
|
|
23
|
+
return this.responseInterceptors.push(interceptor) - 1;
|
|
24
|
+
}
|
|
25
|
+
addResponseErrorInterceptor(interceptor) {
|
|
26
|
+
return this.responseErrorInterceptors.push(interceptor) - 1;
|
|
27
|
+
}
|
|
28
|
+
removeRequestInterceptor(index) {
|
|
29
|
+
if (index >= 0) {
|
|
30
|
+
this.requestInterceptors.splice(index, 1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
removeResponseInterceptor(index) {
|
|
34
|
+
if (index >= 0) {
|
|
35
|
+
this.responseInterceptors.splice(index, 1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
removeResponseErrorInterceptor(index) {
|
|
39
|
+
if (index >= 0) {
|
|
40
|
+
this.responseErrorInterceptors.splice(index, 1);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
clearRequestInterceptors() {
|
|
44
|
+
this.requestInterceptors = [];
|
|
45
|
+
}
|
|
46
|
+
clearResponseInterceptors() {
|
|
47
|
+
this.responseInterceptors = [];
|
|
48
|
+
}
|
|
49
|
+
clearResponseErrorInterceptors() {
|
|
50
|
+
this.responseErrorInterceptors = [];
|
|
51
|
+
}
|
|
52
|
+
clearAllInterceptors() {
|
|
53
|
+
this.clearRequestInterceptors();
|
|
54
|
+
this.clearResponseInterceptors();
|
|
55
|
+
this.clearResponseErrorInterceptors();
|
|
56
|
+
}
|
|
57
|
+
async applyRequestInterceptors(config) {
|
|
58
|
+
let modifiedConfig = { ...config };
|
|
59
|
+
for (const interceptor of this.requestInterceptors) {
|
|
60
|
+
modifiedConfig = await interceptor(modifiedConfig);
|
|
61
|
+
}
|
|
62
|
+
return modifiedConfig;
|
|
63
|
+
}
|
|
64
|
+
async applyResponseInterceptors(response, requestConfig) {
|
|
65
|
+
let modifiedResponse = response;
|
|
66
|
+
for (const interceptor of this.responseInterceptors) {
|
|
67
|
+
modifiedResponse = await interceptor(modifiedResponse, requestConfig);
|
|
68
|
+
}
|
|
69
|
+
return modifiedResponse;
|
|
70
|
+
}
|
|
71
|
+
async applyResponseErrorInterceptors(error, requestConfig) {
|
|
72
|
+
let modifiedError = error;
|
|
73
|
+
for (const interceptor of this.responseErrorInterceptors) {
|
|
74
|
+
try {
|
|
75
|
+
// If an interceptor resolves the error, return the resolved value
|
|
76
|
+
const result = await interceptor(modifiedError, requestConfig);
|
|
77
|
+
if (result instanceof Response) {
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
modifiedError = result;
|
|
81
|
+
}
|
|
82
|
+
catch (newError) {
|
|
83
|
+
// If an interceptor rejects, continue with the new error
|
|
84
|
+
modifiedError = newError;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// If no interceptor handled the error, throw it
|
|
88
|
+
throw modifiedError;
|
|
89
|
+
}
|
|
90
|
+
async retryRequest(config) {
|
|
91
|
+
try {
|
|
92
|
+
// Make a new request with the updated config
|
|
93
|
+
const response = await fetch(config.url, config);
|
|
94
|
+
// Apply response interceptors
|
|
95
|
+
const interceptedResponse = await this.applyResponseInterceptors(response, config);
|
|
96
|
+
const contentType = interceptedResponse.headers.get("content-type");
|
|
97
|
+
const responseData = (contentType === null || contentType === void 0 ? void 0 : contentType.includes("application/json"))
|
|
98
|
+
? await interceptedResponse.json()
|
|
99
|
+
: await interceptedResponse.text();
|
|
100
|
+
if (interceptedResponse.ok) {
|
|
101
|
+
return responseData;
|
|
102
|
+
}
|
|
103
|
+
// Handle errors
|
|
104
|
+
const apiError = createApiError(interceptedResponse.status, responseData);
|
|
105
|
+
throw apiError;
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
// Apply response error interceptors
|
|
109
|
+
return this.applyResponseErrorInterceptors(error, config);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Create the interceptor manager instance
|
|
114
|
+
exports.interceptors = new InterceptorManager();
|
|
12
115
|
const buildUrl = (endpoint, query) => {
|
|
13
116
|
let url = `${BASE_URL}${endpoint}`;
|
|
14
117
|
if (query && Object.keys(query).length > 0) {
|
|
@@ -28,8 +131,8 @@ async function apiRequest(endpoint, options = {}) {
|
|
|
28
131
|
// If timeout is specified, create a timeout abort controller
|
|
29
132
|
if (options.timeout && controller) {
|
|
30
133
|
timeoutId = setTimeout(() => {
|
|
31
|
-
controller.abort(
|
|
32
|
-
}, options.timeout);
|
|
134
|
+
controller.abort("Request timeout");
|
|
135
|
+
}, options.timeout || DEFAULT_TIMEOUT);
|
|
33
136
|
}
|
|
34
137
|
// Use provided signal or timeout controller's signal
|
|
35
138
|
const signal = options.signal || (controller === null || controller === void 0 ? void 0 : controller.signal);
|
|
@@ -51,20 +154,46 @@ async function apiRequest(endpoint, options = {}) {
|
|
|
51
154
|
catch (error) {
|
|
52
155
|
return Promise.reject(error);
|
|
53
156
|
}
|
|
157
|
+
finally {
|
|
158
|
+
if (timeoutId) {
|
|
159
|
+
clearTimeout(timeoutId);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
54
162
|
}
|
|
55
163
|
exports.apiRequest = apiRequest;
|
|
56
164
|
async function makeRequest(endpoint, config, options = {}) {
|
|
57
165
|
const url = buildUrl(endpoint, options.query);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
166
|
+
// Apply request interceptors
|
|
167
|
+
let requestConfig = await exports.interceptors.applyRequestInterceptors({
|
|
168
|
+
...config,
|
|
169
|
+
url,
|
|
170
|
+
options,
|
|
171
|
+
});
|
|
172
|
+
// Extract the URL after interceptors may have modified it
|
|
173
|
+
const interceptedUrl = requestConfig.url;
|
|
174
|
+
try {
|
|
175
|
+
// Make the actual request
|
|
176
|
+
const response = await fetch(interceptedUrl, requestConfig);
|
|
177
|
+
// Apply response interceptors
|
|
178
|
+
const interceptedResponse = await exports.interceptors.applyResponseInterceptors(response, { ...requestConfig, url: interceptedUrl });
|
|
179
|
+
const contentType = interceptedResponse.headers.get("content-type");
|
|
180
|
+
const responseData = (contentType === null || contentType === void 0 ? void 0 : contentType.includes("application/json"))
|
|
181
|
+
? await interceptedResponse.json()
|
|
182
|
+
: await interceptedResponse.text();
|
|
183
|
+
if (interceptedResponse.ok) {
|
|
184
|
+
return responseData;
|
|
185
|
+
}
|
|
186
|
+
// Handle other errors
|
|
187
|
+
const apiError = createApiError(interceptedResponse.status, responseData);
|
|
188
|
+
throw apiError;
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
// Apply response error interceptors
|
|
192
|
+
return exports.interceptors.applyResponseErrorInterceptors(error, {
|
|
193
|
+
...requestConfig,
|
|
194
|
+
url: interceptedUrl,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
68
197
|
}
|
|
69
198
|
function createApiError(status, responseData) {
|
|
70
199
|
const error = new Error(typeof responseData === "object"
|
package/package.json
CHANGED