feat(core): Update dependencies, enhance documentation, and improve error handling with clearer API usage examples

This commit is contained in:
2025-03-19 11:31:50 +00:00
parent d1788dc626
commit 2b51df90e6
12 changed files with 6073 additions and 2111 deletions

555
readme.md
View File

@@ -1,250 +1,361 @@
# @apiclient.xyz/cloudflare
easy cloudflare management
## Install
To install the `@apiclient.xyz/cloudflare` package, you can use npm. Simply run the following command:
An elegant, class-based TypeScript client for the Cloudflare API that makes managing your Cloudflare resources simple and type-safe.
[![npm version](https://badge.fury.io/js/%40apiclient.xyz%2Fcloudflare.svg)](https://www.npmjs.com/package/@apiclient.xyz/cloudflare)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
## Features
- **Comprehensive coverage** of the Cloudflare API including zones, DNS records, and Workers
- **Class-based design** with intuitive methods for all Cloudflare operations
- **Strong TypeScript typing** for excellent IDE autocompletion and type safety
- **Built on the official Cloudflare client** but with a more developer-friendly interface
- **Convenience methods** for common operations to reduce boilerplate code
- **Promise-based API** for easy async/await usage
- **ESM and browser compatible** for maximum flexibility
## Installation
```bash
# Using npm
npm install @apiclient.xyz/cloudflare
# Using yarn
yarn add @apiclient.xyz/cloudflare
# Using pnpm
pnpm add @apiclient.xyz/cloudflare
```
Make sure to include it in your `dependencies` in `package.json`.
## Usage
### Initial Setup
First, let's start by importing the required modules and setting up an instance of `CloudflareAccount` with your API token. This instance will be used to interact with the Cloudflare API.
## Quick Start
```typescript
import * as cflare from '@apiclient.xyz/cloudflare';
// Initialize Cloudflare Account
const myCflareAccount = new cflare.CloudflareAccount('mySuperAwesomeAccountToken');
// Initialize with your API token
const cfAccount = new cflare.CloudflareAccount('your-cloudflare-api-token');
// Use convenience methods for quick operations
await cfAccount.convenience.createRecord('subdomain.example.com', 'A', '192.0.2.1', 3600);
// Or work with the powerful class-based API
const zone = await cfAccount.zoneManager.getZoneByName('example.com');
await zone.purgeCache();
```
### Managing Zones
## Usage Guide
#### List All Zones
### Account Management
To list all zones in your Cloudflare account, you can use the `listZones` method:
```typescript
const listAllZones = async () => {
const myZones = await myCflareAccount.convenience.listZones();
console.log(myZones);
};
```
#### Get Zone ID
To get the ID of a specific zone (domain), use the `getZoneId` method:
```typescript
const getZoneId = async (domainName: string) => {
try {
const zoneId = await myCflareAccount.convenience.getZoneId(domainName);
console.log(`Zone ID for ${domainName}:`, zoneId);
} catch (error) {
console.error('Error getting zone ID:', error);
}
};
```
#### Purge Cache for a Zone
To purge all cache for a specific zone:
```typescript
const purgeZoneCache = async (domainName: string) => {
await myCflareAccount.convenience.purgeZone(domainName);
console.log(`Purged cache for ${domainName}`);
};
```
### Managing DNS Records
#### List DNS Records
To list all DNS records for a specific zone:
```typescript
const listDnsRecords = async (domainName: string) => {
try {
const records = await myCflareAccount.convenience.listRecords(domainName);
console.log(`DNS Records for ${domainName}:`, records);
} catch (error) {
console.error('Error listing DNS records:', error);
}
};
```
#### Get a Specific Record
To get a specific DNS record by type (e.g., A, AAAA, CNAME, etc.):
```typescript
const getDnsRecord = async (domainName: string, recordType: string) => {
try {
const record = await myCflareAccount.convenience.getRecord(domainName, recordType);
console.log(`DNS Record (${recordType}) for ${domainName}:`, record);
} catch (error) {
console.error('Error getting DNS record:', error);
}
};
```
#### Create a DNS Record
To create a new DNS record:
```typescript
const createDnsRecord = async (domainName: string, recordType: string, content: string) => {
try {
const response = await myCflareAccount.convenience.createRecord(domainName, recordType, content, 120);
console.log(`Created DNS record (${recordType}) for ${domainName}:`, response);
} catch (error) {
console.error('Error creating DNS record:', error);
}
};
```
#### Remove a DNS Record
To remove a DNS record:
```typescript
const removeDnsRecord = async (domainName: string, recordType: string) => {
try {
await myCflareAccount.convenience.removeRecord(domainName, recordType);
console.log(`Removed DNS record (${recordType}) for ${domainName}`);
} catch (error) {
console.error('Error removing DNS record:', error);
}
};
```
#### Clean a DNS Record
To clean (remove) all records of a specific type for a domain:
```typescript
const cleanDnsRecord = async (domainName: string, recordType: string) => {
try {
await myCflareAccount.convenience.cleanRecord(domainName, recordType);
console.log(`Cleaned DNS records (${recordType}) for ${domainName}`);
} catch (error) {
console.error('Error cleaning DNS record:', error);
}
};
```
### Managing Workers
#### Create a Worker
To create a new Cloudflare Worker:
```typescript
const createWorker = async (workerName: string, workerScript: string) => {
try {
const worker = await myCflareAccount.workerManager.createWorker(workerName, workerScript);
console.log(`Created Worker (${workerName}):`, worker);
} catch (error) {
console.error('Error creating Worker:', error);
}
};
```
#### List Workers
To list all workers in your Cloudflare account:
```typescript
const listWorkers = async () => {
try {
const workers = await myCflareAccount.workerManager.listWorkers();
console.log('Workers:', workers);
} catch (error) {
console.error('Error listing workers:', error);
}
};
```
#### Set Worker Routes
To set routes for a Cloudflare Worker:
```typescript
import { CloudflareWorker } from '@apiclient.xyz/cloudflare';
const setWorkerRoutes = async (worker: CloudflareWorker, routes: Array<{ zoneName: string, pattern: string }>) => {
try {
await worker.setRoutes(routes);
console.log('Routes set successfully for Worker:', worker.id);
} catch (error) {
console.error('Error setting routes for Worker:', error);
}
};
```
#### Sample Complete Workflow
Below is a sample workflow that includes all the above features:
Initialize your Cloudflare account with your API token:
```typescript
import * as cflare from '@apiclient.xyz/cloudflare';
const myCflareAccount = new cflare.CloudflareAccount('mySuperAwesomeAccountToken');
const cfAccount = new cflare.CloudflareAccount('your-cloudflare-api-token');
const manageCloudflare = async () => {
// 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.
```typescript
// Get all zones in your account
const allZones = await cfAccount.convenience.listZones();
// Get a specific zone by domain name
const myZone = await cfAccount.zoneManager.getZoneByName('example.com');
// Get zone ID directly
const zoneId = await cfAccount.convenience.getZoneId('example.com');
// Create a new zone
const newZone = await cfAccount.zoneManager.createZone('newdomain.com');
// Purge cache for an entire zone
await cfAccount.convenience.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.
```typescript
// List all DNS records for a domain
const allRecords = await cfAccount.convenience.listRecords('example.com');
// Create a new DNS record
await cfAccount.convenience.createRecord('api.example.com', 'A', '192.0.2.1', 3600);
// Create a CNAME record
await cfAccount.convenience.createRecord('www.example.com', 'CNAME', 'example.com', 3600);
// Get a specific DNS record
const record = await cfAccount.convenience.getRecord('api.example.com', 'A');
// Update a DNS record (automatically creates it if it doesn't exist)
await cfAccount.convenience.updateRecord('api.example.com', 'A', '192.0.2.2', 3600);
// Remove a specific DNS record
await cfAccount.convenience.removeRecord('api.example.com', 'A');
// Clean (remove) all records of a specific type
await cfAccount.convenience.cleanRecord('example.com', 'TXT');
// Support for ACME DNS challenges (for certificate issuance)
await cfAccount.convenience.acmeSetDnsChallenge('example.com', 'challenge-token-here');
await cfAccount.convenience.acmeRemoveDnsChallenge('example.com');
```
### Workers Management
Create and manage Cloudflare Workers with full TypeScript support.
```typescript
// 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.listWorkerScripts();
// 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/*'
}
]);
// Get all routes for a worker
const routes = await worker.getRoutes();
// Delete a worker
await cfAccount.workerManager.deleteWorker('my-worker');
```
### Complete Example
Here's a complete example showing how to manage multiple aspects of your Cloudflare account:
```typescript
import * as cflare from '@apiclient.xyz/cloudflare';
async function manageCloudflare() {
try {
// List all zones
const myZones = await myCflareAccount.convenience.listZones();
console.log('Zones:', myZones);
// Get Zone ID for a specific domain
const myZoneId = await myCflareAccount.convenience.getZoneId('example.com');
console.log('Zone ID:', myZoneId);
// Purge cache for a zone
await myCflareAccount.convenience.purgeZone('example.com');
console.log('Cache purged for example.com');
// List DNS records for a domain
const myRecords = await myCflareAccount.convenience.listRecords('example.com');
console.log('DNS Records:', myRecords);
// Get a specific DNS record
const myRecord = await myCflareAccount.convenience.getRecord('sub.example.com', 'A');
console.log('Specific DNS Record:', myRecord);
// Create a DNS record
const createResponse = await myCflareAccount.convenience.createRecord('sub.example.com', 'A', '127.0.0.1');
console.log('Created DNS Record:', createResponse);
// Clean DNS records
await myCflareAccount.convenience.cleanRecord('sub.example.com', 'A');
console.log('Cleaned DNS Records for sub.example.com');
// Create a Cloudflare Worker
const myWorker = await myCflareAccount.workerManager.createWorker('myWorker', `addEventListener('fetch', event => { event.respondWith(fetch(event.request)) })`);
console.log('Created Worker:', myWorker);
// Set routes for the Worker
await myWorker.setRoutes([{ zoneName: 'example.com', pattern: 'https://*example.com/*' }]);
console.log('Routes set for Worker');
// List all Workers
const workers = await myCflareAccount.workerManager.listWorkers();
console.log('Workers:', workers);
// Initialize with API token
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
await cfAccount.convenience.createRecord('api.example.com', 'A', '192.0.2.1');
await cfAccount.convenience.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();
```
This complete guide covers initialization, managing Cloudflare zones, DNS records, and Cloudflare Workers comprehensively using TypeScript for enhanced type safety and intellisense. Always ensure to keep your API keys secure and avoid hardcoding them directly in your scripts.
undefined
## API Documentation
### CloudflareAccount
The main entry point for all Cloudflare operations.
```typescript
class CloudflareAccount {
constructor(apiToken: string);
// Account selection
async listAccounts(): Promise<any[]>;
async preselectAccountByName(accountName: string): Promise<void>;
// Managers
readonly zoneManager: ZoneManager;
readonly workerManager: WorkerManager;
// Direct API access
async request(endpoint: string, method?: string, data?: any): Promise<any>;
// Convenience namespace with helper methods
readonly convenience: {
// Zone operations
listZones(): Promise<CloudflareZone[]>;
getZoneId(domainName: string): Promise<string>;
purgeZone(domainName: string): Promise<void>;
// DNS operations
listRecords(domainName: string): Promise<CloudflareRecord[]>;
getRecord(domainName: string, recordType: string): Promise<CloudflareRecord>;
createRecord(domainName: string, recordType: string, content: string, ttl?: number): Promise<any>;
updateRecord(domainName: string, recordType: string, content: string, ttl?: number): Promise<any>;
removeRecord(domainName: string, recordType: string): Promise<any>;
cleanRecord(domainName: string, recordType: string): Promise<void>;
// ACME operations
acmeSetDnsChallenge(domainName: string, token: string): Promise<any>;
acmeRemoveDnsChallenge(domainName: string): Promise<any>;
};
}
```
### CloudflareZone
Represents a Cloudflare zone (domain).
```typescript
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.
```typescript
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.
```typescript
class CloudflareWorker {
// Properties
readonly id: string;
readonly name: string;
// Methods
async getRoutes(): Promise<any[]>;
async setRoutes(routes: Array<{ zoneName: string, pattern: string }>): Promise<any>;
}
```
## Utility Functions
The library includes helpful utility functions:
```typescript
// 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'
```
## Development & Testing
To build the project:
```bash
npm run build
```
To run tests:
```bash
npm test
```
## License
MIT © [Lossless GmbH](https://lossless.gmbh)