Juergen Kunz 18afafd3b3
Some checks failed
Default (tags) / security (push) Failing after 1m35s
Default (tags) / test (push) Failing after 41s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
v7.0.0
2025-11-18 20:39:08 +00:00
2022-09-27 19:24:52 +02:00
2024-06-15 19:56:32 +02:00
2024-06-15 19:55:48 +02:00
2025-11-18 20:39:08 +00:00
2020-02-19 16:58:46 +00:00
2024-06-15 19:55:48 +02:00

@apiclient.xyz/cloudflare

An elegant, class-based TypeScript client for the Cloudflare API that makes managing your Cloudflare resources simple and type-safe.

npm version License: MIT

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* pattern
    • deleteRecord() instead of removeRecord() - clearer semantics
    • listRoutes() instead of getRoutes() - 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

Description
An elegant, class-based TypeScript client for the Cloudflare API that makes managing your Cloudflare resources simple and type-safe.
Readme 1,015 KiB
Languages
TypeScript 100%