fix(core): Switch to SmartRequest fluent API and improve Cloudflare API request handling
This commit is contained in:
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@apiclient.xyz/cloudflare',
|
||||
version: '6.4.1',
|
||||
version: '6.4.2',
|
||||
description: 'A TypeScript client for managing Cloudflare accounts, zones, DNS records, and workers with ease.'
|
||||
}
|
||||
|
||||
@@ -42,56 +42,77 @@ export class CloudflareAccount implements plugins.tsclass.network.IConvenientDns
|
||||
customHeaders?: Record<string, string>,
|
||||
): Promise<T> {
|
||||
try {
|
||||
const options: plugins.smartrequest.ISmartRequestOptions = {
|
||||
method,
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.authToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
...customHeaders,
|
||||
},
|
||||
};
|
||||
logger.log('debug', `Making ${method} request to ${endpoint}`);
|
||||
|
||||
// Build the request using fluent API
|
||||
let requestBuilder = plugins.SmartRequest.create()
|
||||
.url(`https://api.cloudflare.com/client/v4${endpoint}`)
|
||||
.header('Authorization', `Bearer ${this.authToken}`);
|
||||
|
||||
// Add custom headers
|
||||
if (customHeaders) {
|
||||
for (const [key, value] of Object.entries(customHeaders)) {
|
||||
requestBuilder = requestBuilder.header(key, value);
|
||||
}
|
||||
} else {
|
||||
// Default to JSON content type if no custom headers
|
||||
requestBuilder = requestBuilder.header('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
// Add request body if provided
|
||||
if (data) {
|
||||
if (customHeaders && customHeaders['Content-Type']?.includes('multipart/form-data')) {
|
||||
// For multipart form data, use the data directly as the request body
|
||||
options.requestBody = data;
|
||||
// For multipart form data, use formData method
|
||||
requestBuilder = requestBuilder.formData(data);
|
||||
} else {
|
||||
// For JSON requests, stringify the data
|
||||
options.requestBody = JSON.stringify(data);
|
||||
// For JSON requests, use json method
|
||||
requestBuilder = requestBuilder.json(data);
|
||||
}
|
||||
}
|
||||
|
||||
logger.log('debug', `Making ${method} request to ${endpoint}`);
|
||||
const response = await plugins.smartrequest.request(
|
||||
`https://api.cloudflare.com/client/v4${endpoint}`,
|
||||
options,
|
||||
);
|
||||
|
||||
// Check if response is already an object (might happen with newer smartrequest versions)
|
||||
if (typeof response.body === 'object' && response.body !== null) {
|
||||
return response.body;
|
||||
// Execute the request with the appropriate method
|
||||
let response: plugins.CoreResponse;
|
||||
switch (method) {
|
||||
case 'GET':
|
||||
response = await requestBuilder.get();
|
||||
break;
|
||||
case 'POST':
|
||||
response = await requestBuilder.post();
|
||||
break;
|
||||
case 'PUT':
|
||||
response = await requestBuilder.put();
|
||||
break;
|
||||
case 'DELETE':
|
||||
response = await requestBuilder.delete();
|
||||
break;
|
||||
case 'PATCH':
|
||||
response = await requestBuilder.patch();
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unsupported HTTP method: ${method}`);
|
||||
}
|
||||
|
||||
// Otherwise try to parse as JSON
|
||||
// Check response status
|
||||
if (!response.ok) {
|
||||
const errorBody = await response.text();
|
||||
logger.log('error', `HTTP ${response.status}: ${errorBody}`);
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
// Parse the response body
|
||||
try {
|
||||
if (typeof response.body === 'string' && response.body.trim()) {
|
||||
return JSON.parse(response.body);
|
||||
} else {
|
||||
// If body is empty or not a string, return an empty result
|
||||
logger.log('warn', `Empty or invalid response body: ${typeof response.body}`);
|
||||
return { result: [] } as T;
|
||||
}
|
||||
return await response.json<T>();
|
||||
} catch (parseError) {
|
||||
logger.log('warn', `Failed to parse response as JSON: ${parseError.message}`);
|
||||
|
||||
// Create a fake response object to maintain expected structure
|
||||
// Try to get as text and create a fallback response
|
||||
const textBody = await response.text().catch(() => '');
|
||||
|
||||
return {
|
||||
result: [],
|
||||
success: true,
|
||||
errors: [],
|
||||
messages: [
|
||||
`Failed to parse: ${typeof response.body === 'string' ? response.body?.substring(0, 50) : typeof response.body}...`,
|
||||
],
|
||||
messages: [`Failed to parse: ${textBody.substring(0, 50)}...`],
|
||||
} as T;
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import * as smartlog from '@push.rocks/smartlog';
|
||||
import * as smartpromise from '@push.rocks/smartpromise';
|
||||
import * as smartdelay from '@push.rocks/smartdelay';
|
||||
import * as smartrequest from '@push.rocks/smartrequest';
|
||||
import { SmartRequest, CoreResponse } from '@push.rocks/smartrequest';
|
||||
import * as smartstring from '@push.rocks/smartstring';
|
||||
import * as tsclass from '@tsclass/tsclass';
|
||||
|
||||
export { smartlog, smartpromise, smartdelay, smartrequest, smartstring, tsclass };
|
||||
export { smartlog, smartpromise, smartdelay, SmartRequest, CoreResponse, smartstring, tsclass };
|
||||
|
||||
// third party
|
||||
import * as cloudflare from 'cloudflare';
|
||||
|
||||
Reference in New Issue
Block a user