206 lines
No EOL
4.8 KiB
TypeScript
206 lines
No EOL
4.8 KiB
TypeScript
export interface ImageGenerationRequest {
|
|
prompt: string;
|
|
model?: string;
|
|
resolution?: string;
|
|
ratio?: string;
|
|
quality?: string;
|
|
}
|
|
|
|
export interface VideoGenerationRequest {
|
|
prompt: string;
|
|
model?: string;
|
|
duration?: number;
|
|
resolution?: string;
|
|
ratio?: string;
|
|
quality?: string;
|
|
}
|
|
|
|
export interface TaskStatus {
|
|
task_id: string;
|
|
status: string;
|
|
tasks?: Array<{
|
|
task_id: string;
|
|
status: string;
|
|
result?: {
|
|
url?: string;
|
|
};
|
|
}>;
|
|
}
|
|
|
|
export interface ModelInfo {
|
|
model: string;
|
|
name: string;
|
|
type: string;
|
|
resolution_options: string[];
|
|
duration_options: number[];
|
|
ratios_options: string[];
|
|
quality_options: string[];
|
|
}
|
|
|
|
const BASE_URL = 'https://api.34ai.net/api/v1';
|
|
|
|
export async function generateImage(
|
|
apiKey: string,
|
|
request: ImageGenerationRequest
|
|
): Promise<{ task_id: string }> {
|
|
const response = await fetch(`${BASE_URL}/generate-image`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'x-api-key': apiKey,
|
|
},
|
|
body: JSON.stringify({
|
|
prompt: request.prompt,
|
|
model: request.model || 'banana_pro_2',
|
|
resolution: request.resolution || '1K',
|
|
ratio: request.ratio || '1:1',
|
|
quality: request.quality,
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const error = await response.json().catch(() => ({}));
|
|
throw new Error(error.message || `Image generation failed: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
if (!data.success) {
|
|
throw new Error(data.message || 'Image generation failed');
|
|
}
|
|
|
|
return { task_id: data.data.tasks[0].task_id };
|
|
}
|
|
|
|
export async function generateVideo(
|
|
apiKey: string,
|
|
request: VideoGenerationRequest
|
|
): Promise<{ task_id: string }> {
|
|
const response = await fetch(`${BASE_URL}/generate-video`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'x-api-key': apiKey,
|
|
},
|
|
body: JSON.stringify({
|
|
prompt: request.prompt,
|
|
model: request.model || 'veo3.1',
|
|
duration: request.duration || 4,
|
|
resolution: request.resolution || '720p',
|
|
ratio: request.ratio || '16:9',
|
|
quality: request.quality || 'fast',
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const error = await response.json().catch(() => ({}));
|
|
throw new Error(error.message || `Video generation failed: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
if (!data.success) {
|
|
throw new Error(data.message || 'Video generation failed');
|
|
}
|
|
|
|
return { task_id: data.data.tasks[0].task_id };
|
|
}
|
|
|
|
export async function checkTask(
|
|
apiKey: string,
|
|
taskId: string
|
|
): Promise<TaskStatus> {
|
|
const response = await fetch(`${BASE_URL}/check-task`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'x-api-key': apiKey,
|
|
},
|
|
body: JSON.stringify({ task_id: taskId }),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Check task failed: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
if (!data.success) {
|
|
throw new Error(data.message || 'Check task failed');
|
|
}
|
|
|
|
const taskData = data.data;
|
|
const innerTask = taskData.tasks?.[0];
|
|
|
|
return {
|
|
task_id: taskId,
|
|
status: taskData.status,
|
|
tasks: taskData.tasks,
|
|
};
|
|
}
|
|
|
|
export async function getModels(apiKey: string): Promise<ModelInfo[]> {
|
|
const response = await fetch(`${BASE_URL}/models`, {
|
|
method: 'GET',
|
|
headers: {
|
|
'x-api-key': apiKey,
|
|
},
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Get models failed: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
if (!data.success) {
|
|
throw new Error(data.message || 'Get models failed');
|
|
}
|
|
|
|
return data.data.models.map((m: any) => ({
|
|
model: m.model,
|
|
name: m.name,
|
|
type: m.type,
|
|
resolution_options: m.resolution_options || [],
|
|
duration_options: m.duration_options || [],
|
|
ratios_options: m.ratios_options || [],
|
|
quality_options: m.quality_options || [],
|
|
}));
|
|
}
|
|
|
|
export async function testConnection(apiKey: string): Promise<boolean> {
|
|
try {
|
|
const response = await fetch(`${BASE_URL}/models`, {
|
|
method: 'GET',
|
|
headers: {
|
|
'x-api-key': apiKey,
|
|
},
|
|
});
|
|
return response.ok;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export async function waitForTaskCompletion(
|
|
apiKey: string,
|
|
taskId: string,
|
|
maxAttempts: number = 60,
|
|
intervalMs: number = 3000
|
|
): Promise<string> {
|
|
for (let i = 0; i < maxAttempts; i++) {
|
|
const status = await checkTask(apiKey, taskId);
|
|
|
|
if (status.status === 'completed') {
|
|
const result = status.tasks?.[0]?.result;
|
|
if (result?.url) {
|
|
return result.url;
|
|
}
|
|
throw new Error('Task completed but no URL in result');
|
|
}
|
|
|
|
if (status.status === 'failed') {
|
|
throw new Error('Task failed');
|
|
}
|
|
|
|
await new Promise(resolve => setTimeout(resolve, intervalMs));
|
|
}
|
|
|
|
throw new Error('Task timeout');
|
|
} |