feat(core): switch to native fetch API for all HTTP requests
This commit is contained in:
@@ -27,7 +27,7 @@ export class BunqHttpClient {
|
||||
* Make an API request to bunq
|
||||
*/
|
||||
public async request<T = any>(options: IBunqRequestOptions): Promise<T> {
|
||||
const url = `${this.context.baseUrl}${options.endpoint}`;
|
||||
let url = `${this.context.baseUrl}${options.endpoint}`;
|
||||
|
||||
// Prepare headers
|
||||
const headers = this.prepareHeaders(options);
|
||||
@@ -45,47 +45,45 @@ export class BunqHttpClient {
|
||||
);
|
||||
}
|
||||
|
||||
// Make the request
|
||||
const requestOptions: any = {
|
||||
method: options.method === 'LIST' ? 'GET' : options.method,
|
||||
headers: headers,
|
||||
requestBody: body
|
||||
};
|
||||
|
||||
// Handle query parameters
|
||||
if (options.params) {
|
||||
const queryParams: { [key: string]: string } = {};
|
||||
const queryParams = new URLSearchParams();
|
||||
Object.entries(options.params).forEach(([key, value]) => {
|
||||
if (value !== undefined && value !== null) {
|
||||
queryParams[key] = String(value);
|
||||
queryParams.append(key, String(value));
|
||||
}
|
||||
});
|
||||
requestOptions.queryParams = queryParams;
|
||||
const queryString = queryParams.toString();
|
||||
if (queryString) {
|
||||
url += '?' + queryString;
|
||||
}
|
||||
}
|
||||
|
||||
// Make the request using native fetch
|
||||
const fetchOptions: RequestInit = {
|
||||
method: options.method === 'LIST' ? 'GET' : options.method,
|
||||
headers: headers,
|
||||
body: body
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await plugins.smartrequest.request(url, requestOptions);
|
||||
const response = await fetch(url, fetchOptions);
|
||||
|
||||
// Get response body as text
|
||||
const responseText = await response.text();
|
||||
|
||||
// Verify response signature if we have server public key
|
||||
if (this.context.serverPublicKey) {
|
||||
// Convert headers to string-only format
|
||||
const stringHeaders: { [key: string]: string } = {};
|
||||
for (const [key, value] of Object.entries(response.headers)) {
|
||||
if (typeof value === 'string') {
|
||||
stringHeaders[key] = value;
|
||||
} else if (Array.isArray(value)) {
|
||||
stringHeaders[key] = value.join(', ');
|
||||
}
|
||||
}
|
||||
|
||||
// Convert body to string if needed for signature verification
|
||||
const bodyString = typeof response.body === 'string'
|
||||
? response.body
|
||||
: JSON.stringify(response.body);
|
||||
response.headers.forEach((value, key) => {
|
||||
stringHeaders[key] = value;
|
||||
});
|
||||
|
||||
const isValid = this.crypto.verifyResponseSignature(
|
||||
response.statusCode,
|
||||
response.status,
|
||||
stringHeaders,
|
||||
bodyString,
|
||||
responseText,
|
||||
this.context.serverPublicKey
|
||||
);
|
||||
|
||||
@@ -99,17 +97,21 @@ export class BunqHttpClient {
|
||||
}
|
||||
}
|
||||
|
||||
// Parse response - smartrequest may already parse JSON automatically
|
||||
// Parse response
|
||||
let responseData;
|
||||
if (typeof response.body === 'string') {
|
||||
if (responseText) {
|
||||
try {
|
||||
responseData = JSON.parse(response.body);
|
||||
responseData = JSON.parse(responseText);
|
||||
} catch (parseError) {
|
||||
// If parsing fails and it's not a 2xx response, throw an HTTP error
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
throw new Error(`Failed to parse JSON response: ${parseError.message}`);
|
||||
}
|
||||
} else {
|
||||
// Response is already parsed
|
||||
responseData = response.body;
|
||||
// Empty response body
|
||||
responseData = {};
|
||||
}
|
||||
|
||||
// Check for errors
|
||||
@@ -117,6 +119,11 @@ export class BunqHttpClient {
|
||||
throw new BunqApiError(responseData.Error);
|
||||
}
|
||||
|
||||
// Check HTTP status
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
return responseData;
|
||||
} catch (error) {
|
||||
if (error instanceof BunqApiError) {
|
||||
|
Reference in New Issue
Block a user