162 lines
5.6 KiB
TypeScript
162 lines
5.6 KiB
TypeScript
import * as plugins from './cloudflare.plugins.js';
|
|
import { CloudflareAccount } from './cloudflare.classes.account.js';
|
|
import { CloudflareWorker } from './cloudflare.classes.worker.js';
|
|
import { logger } from './cloudflare.logger.js';
|
|
|
|
export class WorkerManager {
|
|
public cfAccount: CloudflareAccount;
|
|
|
|
constructor(cfAccountArg: CloudflareAccount) {
|
|
this.cfAccount = cfAccountArg;
|
|
}
|
|
|
|
/**
|
|
* Creates a new worker or updates an existing one
|
|
* @param workerName Name of the worker
|
|
* @param workerScript JavaScript content of the worker
|
|
* @returns CloudflareWorker instance for the created/updated worker
|
|
*/
|
|
public async createWorker(workerName: string, workerScript: string): Promise<CloudflareWorker> {
|
|
if (!this.cfAccount.preselectedAccountId) {
|
|
throw new Error('No account selected. Please select it first on the account.');
|
|
}
|
|
|
|
try {
|
|
// Use the official client to create/update the worker (upload script content)
|
|
await this.cfAccount.apiAccount.workers.scripts.content.update(workerName, {
|
|
account_id: this.cfAccount.preselectedAccountId,
|
|
// name the multipart part for the script code
|
|
metadata: { body_part: 'script' },
|
|
/* header to indicate which part contains the script */
|
|
'CF-WORKER-BODY-PART': 'script',
|
|
// include the actual script as a form part named 'script'
|
|
script: workerScript,
|
|
});
|
|
|
|
// Create a new worker instance
|
|
const worker = new CloudflareWorker(this);
|
|
worker.id = workerName;
|
|
worker.script = workerScript;
|
|
|
|
// Initialize the worker and get its routes
|
|
try {
|
|
await worker.getRoutes();
|
|
} catch (routeError) {
|
|
logger.log('warn', `Failed to get routes for worker ${workerName}: ${routeError.message}`);
|
|
// Continue anyway since the worker was created
|
|
}
|
|
|
|
return worker;
|
|
} catch (error) {
|
|
logger.log('error', `Failed to create worker ${workerName}: ${error.message}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a worker by name
|
|
* @param workerName Name of the worker to retrieve
|
|
* @returns CloudflareWorker instance or undefined if not found
|
|
*/
|
|
public async getWorker(workerName: string): Promise<CloudflareWorker | undefined> {
|
|
if (!this.cfAccount.preselectedAccountId) {
|
|
throw new Error('No account selected. Please select it first on the account.');
|
|
}
|
|
|
|
try {
|
|
// Get the worker script using the official client
|
|
const workerScript = await this.cfAccount.apiAccount.workers.scripts.get(workerName, {
|
|
account_id: this.cfAccount.preselectedAccountId
|
|
});
|
|
|
|
// Create a new worker instance
|
|
const worker = new CloudflareWorker(this);
|
|
worker.id = workerName;
|
|
|
|
// Save script content if available
|
|
if (workerScript && typeof workerScript === 'object') {
|
|
Object.assign(worker, workerScript);
|
|
}
|
|
|
|
// Initialize the worker and get its routes
|
|
try {
|
|
await worker.getRoutes();
|
|
} catch (routeError) {
|
|
logger.log('warn', `Failed to get routes for worker ${workerName}: ${routeError.message}`);
|
|
// Continue anyway since we found the worker
|
|
}
|
|
|
|
return worker;
|
|
} catch (error) {
|
|
logger.log('warn', `Worker '${workerName}' not found: ${error.message}`);
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Lists all worker scripts
|
|
* @returns Array of worker scripts
|
|
*/
|
|
public async listWorkerScripts() {
|
|
if (!this.cfAccount.preselectedAccountId) {
|
|
throw new Error('No account selected. Please select it first on the account.');
|
|
}
|
|
|
|
try {
|
|
// Collect all scripts using the new client's async iterator
|
|
const workerScripts: plugins.ICloudflareTypes['Script'][] = [];
|
|
|
|
try {
|
|
for await (const script of this.cfAccount.apiAccount.workers.scripts.list({
|
|
account_id: this.cfAccount.preselectedAccountId,
|
|
})) {
|
|
workerScripts.push(script);
|
|
}
|
|
|
|
logger.log('info', `Found ${workerScripts.length} worker scripts`);
|
|
return workerScripts;
|
|
} catch (error) {
|
|
logger.log('warn', `Error while listing workers with async iterator: ${error.message}`);
|
|
|
|
// Try alternative approach if the async iterator fails
|
|
const result = await this.cfAccount.apiAccount.workers.scripts.list({
|
|
account_id: this.cfAccount.preselectedAccountId,
|
|
}) as any;
|
|
|
|
// Check if the result has a 'result' property (older API response format)
|
|
if (result && result.result && Array.isArray(result.result)) {
|
|
logger.log('info', `Found ${result.result.length} worker scripts using direct result`);
|
|
return result.result;
|
|
}
|
|
}
|
|
|
|
logger.log('warn', 'Could not retrieve worker scripts');
|
|
return [];
|
|
} catch (error) {
|
|
logger.log('error', `Failed to list worker scripts: ${error.message}`);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Deletes a worker script
|
|
* @param workerName Name of the worker to delete
|
|
* @returns True if deletion was successful
|
|
*/
|
|
public async deleteWorker(workerName: string): Promise<boolean> {
|
|
if (!this.cfAccount.preselectedAccountId) {
|
|
throw new Error('No account selected. Please select it first on the account.');
|
|
}
|
|
|
|
try {
|
|
await this.cfAccount.apiAccount.workers.scripts.delete(workerName, {
|
|
account_id: this.cfAccount.preselectedAccountId
|
|
});
|
|
logger.log('info', `Worker '${workerName}' deleted successfully`);
|
|
return true;
|
|
} catch (error) {
|
|
logger.log('error', `Failed to delete worker '${workerName}': ${error.message}`);
|
|
return false;
|
|
}
|
|
}
|
|
} |