fix(core): Switch to SmartRequest fluent API and improve Cloudflare API request handling

This commit is contained in:
2025-11-17 23:10:24 +00:00
parent 1c0a20ac99
commit 038f56b0ce
8 changed files with 10467 additions and 4727 deletions

View File

@@ -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.'
}

View File

@@ -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) {

View File

@@ -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';