232 lines
7.0 KiB
TypeScript
232 lines
7.0 KiB
TypeScript
import * as plugins from './cloudflare.plugins.js';
|
|
import { logger } from './cloudflare.logger.js';
|
|
import * as interfaces from './interfaces/index.js';
|
|
import type { CloudflareAccount } from './cloudflare.classes.account.js';
|
|
|
|
export class CloudflareZone {
|
|
// Zone properties
|
|
public id: string;
|
|
public name: string;
|
|
public status: interfaces.ICflareZone['status'];
|
|
public paused: boolean;
|
|
public type: interfaces.ICflareZone['type'];
|
|
public development_mode: number;
|
|
public name_servers: string[];
|
|
public original_name_servers: string[];
|
|
public original_registrar: string | null;
|
|
public original_dnshost: string | null;
|
|
public modified_on: string;
|
|
public created_on: string;
|
|
public activated_on: string;
|
|
public meta: interfaces.ICflareZone['meta'];
|
|
public owner: interfaces.ICflareZone['owner'];
|
|
public account: interfaces.ICflareZone['account'];
|
|
public permissions: string[];
|
|
public plan: interfaces.ICflareZone['plan'];
|
|
|
|
private cfAccount?: CloudflareAccount; // Will be set when created through a manager
|
|
|
|
/**
|
|
* Create a CloudflareZone instance from an API object
|
|
* @param apiObject Cloudflare Zone API object
|
|
* @param cfAccount Optional Cloudflare account instance
|
|
* @returns CloudflareZone instance
|
|
*/
|
|
public static createFromApiObject(
|
|
apiObject: plugins.ICloudflareTypes['Zone'],
|
|
cfAccount?: CloudflareAccount
|
|
): CloudflareZone {
|
|
const cloudflareZone = new CloudflareZone();
|
|
Object.assign(cloudflareZone, apiObject);
|
|
|
|
if (cfAccount) {
|
|
cloudflareZone.cfAccount = cfAccount;
|
|
}
|
|
|
|
return cloudflareZone;
|
|
}
|
|
|
|
/**
|
|
* Check if development mode is currently active
|
|
* @returns True if development mode is active
|
|
*/
|
|
public isDevelopmentModeActive(): boolean {
|
|
return this.development_mode > 0;
|
|
}
|
|
|
|
/**
|
|
* Enable development mode for the zone
|
|
* @param cfAccount Cloudflare account to use if not already set
|
|
* @param duration Duration in seconds (default: 3 hours)
|
|
* @returns Updated zone
|
|
*/
|
|
public async enableDevelopmentMode(
|
|
cfAccount?: CloudflareAccount,
|
|
duration: number = 10800
|
|
): Promise<CloudflareZone> {
|
|
const account = cfAccount || this.cfAccount;
|
|
if (!account) {
|
|
throw new Error('CloudflareAccount is required to enable development mode');
|
|
}
|
|
|
|
logger.log('info', `Enabling development mode for zone ${this.name}`);
|
|
|
|
try {
|
|
// The official client doesn't have a direct method for development mode
|
|
// We'll use the request method for this specific case
|
|
await account.request('PATCH', `/zones/${this.id}/settings/development_mode`, {
|
|
value: 'on',
|
|
time: duration
|
|
});
|
|
|
|
this.development_mode = duration;
|
|
return this;
|
|
} catch (error) {
|
|
logger.log('error', `Failed to enable development mode: ${error.message}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Disable development mode for the zone
|
|
* @param cfAccount Cloudflare account to use if not already set
|
|
* @returns Updated zone
|
|
*/
|
|
public async disableDevelopmentMode(cfAccount?: CloudflareAccount): Promise<CloudflareZone> {
|
|
const account = cfAccount || this.cfAccount;
|
|
if (!account) {
|
|
throw new Error('CloudflareAccount is required to disable development mode');
|
|
}
|
|
|
|
logger.log('info', `Disabling development mode for zone ${this.name}`);
|
|
|
|
try {
|
|
// The official client doesn't have a direct method for development mode
|
|
// We'll use the request method for this specific case
|
|
await account.request('PATCH', `/zones/${this.id}/settings/development_mode`, {
|
|
value: 'off'
|
|
});
|
|
|
|
this.development_mode = 0;
|
|
return this;
|
|
} catch (error) {
|
|
logger.log('error', `Failed to disable development mode: ${error.message}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Purge all cached content for this zone
|
|
* @param cfAccount Cloudflare account to use if not already set
|
|
* @returns True if successful
|
|
*/
|
|
public async purgeCache(cfAccount?: CloudflareAccount): Promise<boolean> {
|
|
const account = cfAccount || this.cfAccount;
|
|
if (!account) {
|
|
throw new Error('CloudflareAccount is required to purge cache');
|
|
}
|
|
|
|
logger.log('info', `Purging all cache for zone ${this.name}`);
|
|
|
|
try {
|
|
await account.apiAccount.cache.purge({
|
|
zone_id: this.id,
|
|
purge_everything: true
|
|
});
|
|
return true;
|
|
} catch (error) {
|
|
logger.log('error', `Failed to purge cache: ${error.message}`);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Purge specific URLs from the cache
|
|
* @param urls Array of URLs to purge
|
|
* @param cfAccount Cloudflare account to use if not already set
|
|
* @returns True if successful
|
|
*/
|
|
public async purgeUrls(urls: string[], cfAccount?: CloudflareAccount): Promise<boolean> {
|
|
const account = cfAccount || this.cfAccount;
|
|
if (!account) {
|
|
throw new Error('CloudflareAccount is required to purge URLs');
|
|
}
|
|
|
|
if (!urls.length) {
|
|
return true;
|
|
}
|
|
|
|
logger.log('info', `Purging ${urls.length} URLs from cache for zone ${this.name}`);
|
|
|
|
try {
|
|
await account.apiAccount.cache.purge({
|
|
zone_id: this.id,
|
|
files: urls
|
|
});
|
|
return true;
|
|
} catch (error) {
|
|
logger.log('error', `Failed to purge URLs: ${error.message}`);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if the zone is active
|
|
* @returns True if the zone is active
|
|
*/
|
|
public isActive(): boolean {
|
|
return this.status === 'active' && !this.paused;
|
|
}
|
|
|
|
/**
|
|
* Check if the zone is using Cloudflare nameservers
|
|
* @returns True if using Cloudflare nameservers
|
|
*/
|
|
public isUsingCloudflareNameservers(): boolean {
|
|
// Check if original nameservers match current nameservers
|
|
if (!this.original_name_servers || !this.name_servers) {
|
|
return false;
|
|
}
|
|
|
|
// If they're different, and current nameservers are Cloudflare's
|
|
return this.name_servers.some(ns => ns.includes('cloudflare'));
|
|
}
|
|
|
|
/**
|
|
* Update zone settings
|
|
* @param settings Settings to update
|
|
* @param cfAccount Cloudflare account to use if not already set
|
|
* @returns Updated zone
|
|
*/
|
|
public async updateSettings(
|
|
settings: Partial<{
|
|
paused: boolean;
|
|
plan: { id: string };
|
|
vanity_name_servers: string[];
|
|
type: 'full' | 'partial' | 'secondary';
|
|
}>,
|
|
cfAccount?: CloudflareAccount
|
|
): Promise<CloudflareZone> {
|
|
const account = cfAccount || this.cfAccount;
|
|
if (!account) {
|
|
throw new Error('CloudflareAccount is required to update zone settings');
|
|
}
|
|
|
|
logger.log('info', `Updating settings for zone ${this.name}`);
|
|
|
|
try {
|
|
// Use the request method instead of zones.edit to avoid type issues
|
|
const response: { result: interfaces.ICflareZone } = await account.request(
|
|
'PATCH',
|
|
`/zones/${this.id}`,
|
|
settings
|
|
);
|
|
|
|
Object.assign(this, response.result);
|
|
return this;
|
|
} catch (error) {
|
|
logger.log('error', `Failed to update zone settings: ${error.message}`);
|
|
throw error;
|
|
}
|
|
}
|
|
} |