import * as plugins from './cloudflare.plugins.js'; import * as interfaces from './interfaces/index.js'; import { CloudflareAccount } from './cloudflare.classes.account.js'; import { CloudflareZone } from './cloudflare.classes.zone.js'; import { logger } from './cloudflare.logger.js'; export class ZoneManager { public cfAccount: CloudflareAccount; constructor(cfAccountArg: CloudflareAccount) { this.cfAccount = cfAccountArg; } /** * Get all zones, optionally filtered by name * @param zoneName Optional zone name to filter by * @returns Array of CloudflareZone instances */ public async getZones(zoneName?: string): Promise { try { const options: any = { per_page: 50 }; // May be optionally filtered by domain name if (zoneName) { options.name = zoneName; } const zones: plugins.ICloudflareTypes['Zone'][] = []; for await (const zone of this.cfAccount.apiAccount.zones.list(options)) { zones.push(zone); } return zones.map(zone => CloudflareZone.createFromApiObject(zone, this.cfAccount)); } catch (error) { logger.log('error', `Failed to fetch zones: ${error.message}`); return []; } } /** * Get a single zone by name * @param zoneName Zone name to find * @returns CloudflareZone instance or undefined if not found */ public async getZoneByName(zoneName: string): Promise { const zones = await this.getZones(zoneName); return zones.find(zone => zone.name === zoneName); } /** * Get a zone by its ID * @param zoneId Zone ID to find * @returns CloudflareZone instance or undefined if not found */ public async getZoneById(zoneId: string): Promise { try { // Use the request method instead of the zones.get method to avoid type issues const response: { result: interfaces.ICflareZone } = await this.cfAccount.request( 'GET', `/zones/${zoneId}` ); return CloudflareZone.createFromApiObject(response.result as any, this.cfAccount); } catch (error) { logger.log('error', `Failed to fetch zone with ID ${zoneId}: ${error.message}`); return undefined; } } /** * Create a new zone * @param zoneName Name of the zone to create * @param jumpStart Whether to automatically attempt to fetch existing DNS records * @param accountId Account ID to use (defaults to preselected account) * @returns The created zone */ public async createZone( zoneName: string, jumpStart: boolean = false, accountId?: string ): Promise { const useAccountId = accountId || this.cfAccount.preselectedAccountId; if (!useAccountId) { throw new Error('No account selected. Please select it first on the account.'); } try { logger.log('info', `Creating zone ${zoneName}`); // Use the request method for more direct control over the parameters const response: { result: interfaces.ICflareZone } = await this.cfAccount.request( 'POST', '/zones', { name: zoneName, jump_start: jumpStart, account: { id: useAccountId } } ); return CloudflareZone.createFromApiObject(response.result as any, this.cfAccount); } catch (error) { logger.log('error', `Failed to create zone ${zoneName}: ${error.message}`); return undefined; } } /** * Delete a zone * @param zoneId ID of the zone to delete * @returns True if successful */ public async deleteZone(zoneId: string): Promise { try { logger.log('info', `Deleting zone with ID ${zoneId}`); // Use the request method to avoid type issues await this.cfAccount.request('DELETE', `/zones/${zoneId}`); return true; } catch (error) { logger.log('error', `Failed to delete zone with ID ${zoneId}: ${error.message}`); return false; } } /** * Check if a zone exists * @param zoneName Name of the zone to check * @returns True if the zone exists */ public async zoneExists(zoneName: string): Promise { const zones = await this.getZones(zoneName); return zones.some(zone => zone.name === zoneName); } /** * Activate a zone (if it's in pending status) * @param zoneId ID of the zone to activate * @returns Updated zone or undefined if activation failed */ public async activateZone(zoneId: string): Promise { try { logger.log('info', `Activating zone with ID ${zoneId}`); // Use the request method for better control const response: { result: interfaces.ICflareZone } = await this.cfAccount.request( 'PATCH', `/zones/${zoneId}`, { status: 'active' } ); return CloudflareZone.createFromApiObject(response.result as any, this.cfAccount); } catch (error) { logger.log('error', `Failed to activate zone with ID ${zoneId}: ${error.message}`); return undefined; } } /** * Check the activation status of a zone * @param zoneId ID of the zone to check * @returns Updated zone or undefined if check failed */ public async checkZoneActivation(zoneId: string): Promise { try { logger.log('info', `Checking activation for zone with ID ${zoneId}`); // For this specific endpoint, we'll use the request method const response: { result: interfaces.ICflareZone } = await this.cfAccount.request( 'PUT', `/zones/${zoneId}/activation_check` ); return CloudflareZone.createFromApiObject(response.result as any, this.cfAccount); } catch (error) { logger.log('error', `Failed to check zone activation with ID ${zoneId}: ${error.message}`); return undefined; } } }