@apiclient.xyz/cloudflare
An elegant, class-based TypeScript client for the Cloudflare API that makes managing your Cloudflare resources simple and type-safe.
Features
- Comprehensive coverage of the Cloudflare API including zones, DNS records, and Workers
- Clean manager-based architecture with intuitive methods for all Cloudflare operations
- Strong TypeScript typing for excellent IDE autocompletion and type safety
- Fully integrated with the official Cloudflare client using modern async iterators
- IConvenientDnsProvider compatibility for seamless integration with third-party modules
- Promise-based API for easy async/await usage
- ESM compatible for modern JavaScript projects
- Comprehensive error handling for robust applications
Installation
# Using npm
npm install @apiclient.xyz/cloudflare
# Using yarn
yarn add @apiclient.xyz/cloudflare
# Using pnpm
pnpm add @apiclient.xyz/cloudflare
Quick Start
import * as cflare from '@apiclient.xyz/cloudflare';
// Initialize with your API token
const cfAccount = new cflare.CloudflareAccount('your-cloudflare-api-token');
// Use the clean manager-based API
await cfAccount.recordManager.createRecord('subdomain.example.com', 'A', '192.0.2.1', 3600);
await cfAccount.zoneManager.purgeZone('example.com');
// Or use the IConvenientDnsProvider interface for third-party modules
const dnsProvider = cfAccount.getConvenientDnsProvider();
await dnsProvider.createRecord('subdomain.example.com', 'A', '192.0.2.1');
Usage Guide
Account Management
Initialize your Cloudflare account with your API token:
import * as cflare from '@apiclient.xyz/cloudflare';
const cfAccount = new cflare.CloudflareAccount('your-cloudflare-api-token');
// If you have multiple accounts, you can preselect one
await cfAccount.preselectAccountByName('My Company Account');
// List all accounts you have access to
const myAccounts = await cfAccount.listAccounts();
Zone Management
Zones represent your domains in Cloudflare.
// List all zones in your account
const allZones = await cfAccount.zoneManager.listZones();
// Get a specific zone by domain name
const myZone = await cfAccount.zoneManager.getZoneByName('example.com');
// Get zone ID directly
const zoneId = await cfAccount.zoneManager.getZoneId('example.com');
// Create a new zone
const newZone = await cfAccount.zoneManager.createZone('newdomain.com');
// Purge cache for an entire zone
await cfAccount.zoneManager.purgeZone('example.com');
// Or using the zone object
await myZone.purgeCache();
// Purge specific URLs
await myZone.purgeUrls(['https://example.com/css/styles.css', 'https://example.com/js/app.js']);
// Enable/disable development mode
await myZone.enableDevelopmentMode(); // Enables dev mode for 3 hours
await myZone.disableDevelopmentMode();
// Check zone status
const isActive = await myZone.isActive();
const usingCfNameservers = await myZone.isUsingCloudflareNameservers();
DNS Record Management
Manage DNS records for your domains with ease using the RecordManager.
// List all DNS records for a domain
const allRecords = await cfAccount.recordManager.listRecords('example.com');
// Create a new DNS record
await cfAccount.recordManager.createRecord('api.example.com', 'A', '192.0.2.1', 3600);
// Create a CNAME record
await cfAccount.recordManager.createRecord('www.example.com', 'CNAME', 'example.com', 3600);
// Get a specific DNS record
const record = await cfAccount.recordManager.getRecord('api.example.com', 'A');
// Update a DNS record (automatically creates it if it doesn't exist)
await cfAccount.recordManager.updateRecord('api.example.com', 'A', '192.0.2.2', 3600);
// Delete a specific DNS record
await cfAccount.recordManager.deleteRecord('api.example.com', 'A');
// Clean (remove) all records of a specific type for a domain
await cfAccount.recordManager.cleanRecords('example.com', 'TXT');
// For third-party modules requiring IConvenientDnsProvider interface
const dnsProvider = cfAccount.getConvenientDnsProvider();
await dnsProvider.createRecord('api.example.com', 'A', '192.0.2.1');
// Support for ACME DNS challenges (for certificate issuance)
await dnsProvider.acmeSetDnsChallenge({
hostName: '_acme-challenge.example.com',
challenge: 'token-validation-string',
});
await dnsProvider.acmeRemoveDnsChallenge({
hostName: '_acme-challenge.example.com',
challenge: 'token-validation-string',
});
Workers Management
Create and manage Cloudflare Workers with full TypeScript support.
// Create or update a worker
const workerScript = `
addEventListener('fetch', event => {
event.respondWith(new Response('Hello from Cloudflare Workers!'))
})`;
const worker = await cfAccount.workerManager.createWorker('my-worker', workerScript);
// List all workers
const allWorkers = await cfAccount.workerManager.listWorkers();
// Get an existing worker
const existingWorker = await cfAccount.workerManager.getWorker('my-worker');
// Set routes for a worker
await worker.setRoutes([
{
zoneName: 'example.com',
pattern: 'https://api.example.com/*',
},
{
zoneName: 'example.com',
pattern: 'https://app.example.com/api/*',
},
]);
// List all routes for a worker
const routes = await worker.listRoutes();
// Update a worker's script
await worker.updateScript(`
addEventListener('fetch', event => {
event.respondWith(new Response('Updated worker content!'))
})`);
// Delete a worker
await worker.delete();
// Or using the worker manager
await cfAccount.workerManager.deleteWorker('my-worker');
Complete Example
Here's a complete example showing how to manage multiple aspects of your Cloudflare account:
import * as cflare from '@apiclient.xyz/cloudflare';
async function manageCloudflare() {
try {
// Initialize with API token from environment variable
const cfAccount = new cflare.CloudflareAccount(process.env.CLOUDFLARE_API_TOKEN);
// Preselect account if needed
await cfAccount.preselectAccountByName('My Company');
// Get zone and check status
const myZone = await cfAccount.zoneManager.getZoneByName('example.com');
console.log(`Zone active: ${await myZone.isActive()}`);
console.log(`Using CF nameservers: ${await myZone.isUsingCloudflareNameservers()}`);
// Configure DNS using RecordManager
await cfAccount.recordManager.createRecord('api.example.com', 'A', '192.0.2.1');
await cfAccount.recordManager.createRecord('www.example.com', 'CNAME', 'example.com');
// Create a worker and set up routes
const workerCode = `
addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.pathname.startsWith('/api/')) {
event.respondWith(new Response(JSON.stringify({ status: 'ok' }), {
headers: { 'Content-Type': 'application/json' }
}));
} else {
event.respondWith(fetch(event.request));
}
})`;
const worker = await cfAccount.workerManager.createWorker('api-handler', workerCode);
await worker.setRoutes([{ zoneName: 'example.com', pattern: 'https://api.example.com/*' }]);
// Purge cache for specific URLs
await myZone.purgeUrls(['https://example.com/css/styles.css']);
console.log('Configuration completed successfully');
} catch (error) {
console.error('Error managing Cloudflare:', error);
}
}
manageCloudflare();
API Documentation
CloudflareAccount
The main entry point for all Cloudflare operations.
class CloudflareAccount {
constructor(apiToken: string);
// Account management
async listAccounts(): Promise<Array<ICloudflareTypes['Account']>>;
async preselectAccountByName(accountName: string): Promise<void>;
// Managers - Clean, logical API
readonly zoneManager: ZoneManager;
readonly workerManager: WorkerManager;
readonly recordManager: RecordManager;
// Get IConvenientDnsProvider adapter for third-party modules
getConvenientDnsProvider(): ConvenientDnsProvider;
// Official Cloudflare client
readonly apiAccount: cloudflare.Cloudflare;
// ⚠️ Deprecated: convenience namespace (kept for backward compatibility)
// Use the managers instead: recordManager, zoneManager, workerManager
readonly convenience: { /* deprecated methods */ };
}
RecordManager
Clean DNS record management (recommended over deprecated convenience methods).
class RecordManager {
async listRecords(domainName: string): Promise<CloudflareRecord[]>;
async getRecord(domainName: string, recordType: string): Promise<CloudflareRecord | undefined>;
async createRecord(domainName: string, recordType: string, content: string, ttl?: number): Promise<CloudflareRecord>;
async updateRecord(domainName: string, recordType: string, content: string, ttl?: number): Promise<CloudflareRecord>;
async deleteRecord(domainName: string, recordType: string): Promise<void>;
async cleanRecords(domainName: string, recordType: string): Promise<void>;
}
ZoneManager
class ZoneManager {
async listZones(zoneName?: string): Promise<CloudflareZone[]>;
async getZoneById(zoneId: string): Promise<CloudflareZone | undefined>;
async getZoneByName(zoneName: string): Promise<CloudflareZone | undefined>;
async getZoneId(domainName: string): Promise<string>;
async createZone(zoneName: string): Promise<CloudflareZone | undefined>;
async deleteZone(zoneId: string): Promise<boolean>;
async purgeZone(domainName: string): Promise<void>;
}
WorkerManager
class WorkerManager {
async listWorkers(): Promise<Array<ICloudflareTypes['Script']>>;
async getWorker(workerName: string): Promise<CloudflareWorker | undefined>;
async createWorker(workerName: string, workerScript: string): Promise<CloudflareWorker>;
async deleteWorker(workerName: string): Promise<boolean>;
}
ConvenientDnsProvider
Adapter for third-party modules requiring IConvenientDnsProvider interface.
class ConvenientDnsProvider implements IConvenientDnsProvider {
async createRecord(domainName: string, recordType: string, content: string, ttl?: number): Promise<any>;
async updateRecord(domainName: string, recordType: string, content: string, ttl?: number): Promise<any>;
async removeRecord(domainName: string, recordType: string): Promise<any>;
async getRecord(domainName: string, recordType: string): Promise<any | undefined>;
async listRecords(domainName: string): Promise<any[]>;
async cleanRecord(domainName: string, recordType: string): Promise<void>;
async isDomainSupported(domainName: string): Promise<boolean>;
async acmeSetDnsChallenge(dnsChallenge: IDnsChallenge): Promise<void>;
async acmeRemoveDnsChallenge(dnsChallenge: IDnsChallenge): Promise<void>;
}
CloudflareZone
Represents a Cloudflare zone (domain).
class CloudflareZone {
// Properties
readonly id: string;
readonly name: string;
readonly status: string;
readonly paused: boolean;
readonly type: string;
readonly nameServers: string[];
// Methods
async purgeCache(): Promise<any>;
async purgeUrls(urls: string[]): Promise<any>;
async isActive(): Promise<boolean>;
async isUsingCloudflareNameservers(): Promise<boolean>;
async isDevelopmentModeActive(): Promise<boolean>;
async enableDevelopmentMode(): Promise<any>;
async disableDevelopmentMode(): Promise<any>;
}
CloudflareRecord
Represents a DNS record.
class CloudflareRecord {
// Properties
readonly id: string;
readonly type: string;
readonly name: string;
readonly content: string;
readonly ttl: number;
readonly proxied: boolean;
// Methods
async update(content: string, ttl?: number): Promise<any>;
async delete(): Promise<any>;
}
CloudflareWorker
Represents a Cloudflare Worker.
class CloudflareWorker {
// Properties
readonly id: string;
readonly script: string;
readonly routes: IWorkerRoute[];
// Methods
async listRoutes(): Promise<void>; // Populates the routes property
async setRoutes(routes: Array<IWorkerRouteDefinition>): Promise<void>;
async updateScript(scriptContent: string): Promise<CloudflareWorker>;
async delete(): Promise<boolean>;
}
interface IWorkerRouteDefinition {
zoneName: string;
pattern: string;
}
Utility Functions
The library includes helpful utility functions:
// Validate a domain name
CloudflareUtils.isValidDomain('example.com'); // true
// Extract zone name from a domain
CloudflareUtils.getZoneName('subdomain.example.com'); // 'example.com'
// Validate a record type
CloudflareUtils.isValidRecordType('A'); // true
// Format URL for cache purging
CloudflareUtils.formatUrlForPurge('example.com/page'); // 'https://example.com/page'
// Format TTL value
CloudflareUtils.formatTtl(3600); // '1 hour'
What's New in 7.0.0
- 🎨 Clean Manager-Based Architecture: New RecordManager, improved ZoneManager and WorkerManager with consistent naming
- 🔌 IConvenientDnsProvider Compatibility: New ConvenientDnsProvider adapter for seamless third-party module integration
- 📝 Consistent Method Naming:
listZones(),listWorkers(),listRecords()- consistent list* patterndeleteRecord()instead ofremoveRecord()- clearer semanticslistRoutes()instead ofgetRoutes()- consistent with other list methods
- ⚠️ Deprecated convenience Namespace: Old methods still work but are deprecated - use managers instead
- ✅ Backward Compatible: All existing code continues to work with deprecation warnings
Migration Guide (6.x → 7.0)
DNS Record Operations
// Old (deprecated):
await cfAccount.convenience.createRecord('example.com', 'A', '1.2.3.4');
await cfAccount.convenience.listRecords('example.com');
await cfAccount.convenience.removeRecord('example.com', 'A');
// New (recommended):
await cfAccount.recordManager.createRecord('example.com', 'A', '1.2.3.4');
await cfAccount.recordManager.listRecords('example.com');
await cfAccount.recordManager.deleteRecord('example.com', 'A');
// For third-party modules:
const dnsProvider = cfAccount.getConvenientDnsProvider();
await dnsProvider.createRecord('example.com', 'A', '1.2.3.4');
Zone Operations
// Old (deprecated):
await cfAccount.convenience.listZones();
await cfAccount.convenience.purgeZone('example.com');
// New (recommended):
await cfAccount.zoneManager.listZones();
await cfAccount.zoneManager.purgeZone('example.com');
Worker Operations
// Old:
await cfAccount.workerManager.listWorkerScripts();
await worker.getRoutes();
// New:
await cfAccount.workerManager.listWorkers();
await worker.listRoutes();
Development & Testing
To build the project:
npm run build
# or
pnpm run build
To run tests:
npm test
# or
pnpm run test
License
MIT © Lossless GmbH