233 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			233 lines
		
	
	
		
			6.9 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;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |