import fetch from 'node-fetch';
import type {
RendiConfig,
RunFFmpegCommandRequest,
RunChainedFFmpegCommandsRequest,
CommandSubmissionResponse,
PollCommandResponse
} from './types.js';
export class RendiClient {
private readonly baseUrl = 'https://api.rendi.dev/v1';
private readonly apiKey: string;
constructor(config: RendiConfig) {
this.apiKey = config.apiKey;
}
/**
* Run a single FFmpeg command
*/
async runFFmpegCommand(request: RunFFmpegCommandRequest): Promise<CommandSubmissionResponse> {
const response = await fetch(`${this.baseUrl}/run-ffmpeg-command`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': this.apiKey
},
body: JSON.stringify(request)
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Rendi API error (${response.status}): ${errorText}`);
}
return await response.json() as CommandSubmissionResponse;
}
/**
* Run chained FFmpeg commands
*/
async runChainedFFmpegCommands(request: RunChainedFFmpegCommandsRequest): Promise<CommandSubmissionResponse> {
const response = await fetch(`${this.baseUrl}/run-chained-ffmpeg-commands`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': this.apiKey
},
body: JSON.stringify(request)
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Rendi API error (${response.status}): ${errorText}`);
}
return await response.json() as CommandSubmissionResponse;
}
/**
* Poll the status of a command
*/
async pollCommand(commandId: string): Promise<PollCommandResponse> {
const response = await fetch(`${this.baseUrl}/commands/${commandId}`, {
method: 'GET',
headers: {
'X-API-KEY': this.apiKey
}
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Rendi API error (${response.status}): ${errorText}`);
}
return await response.json() as PollCommandResponse;
}
/**
* Delete all output files associated with a command
*/
async deleteCommandFiles(commandId: string): Promise<void> {
const response = await fetch(`${this.baseUrl}/commands/${commandId}/files`, {
method: 'DELETE',
headers: {
'X-API-KEY': this.apiKey
}
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Rendi API error (${response.status}): ${errorText}`);
}
// 204 No Content - successful deletion
}
/**
* Test the API connection
*/
async testConnection(): Promise<boolean> {
try {
// Try to list commands (this will validate the API key)
const response = await fetch(`${this.baseUrl}/commands`, {
method: 'GET',
headers: {
'X-API-KEY': this.apiKey
}
});
return response.ok;
} catch (error) {
return false;
}
}
}