feature/api-development #1
|
|
@ -1,6 +1,7 @@
|
||||||
import express, { Application } from 'express';
|
import express, { Application } from 'express';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import { config } from 'dotenv';
|
import { config } from 'dotenv';
|
||||||
|
import { randomUUID } from 'crypto';
|
||||||
import { Config } from './types/api';
|
import { Config } from './types/api';
|
||||||
import { textToImageRouter } from './routes/textToImage';
|
import { textToImageRouter } from './routes/textToImage';
|
||||||
import { imagesRouter } from './routes/images';
|
import { imagesRouter } from './routes/images';
|
||||||
|
|
@ -43,7 +44,7 @@ export const createApp = (): Application => {
|
||||||
|
|
||||||
// Request ID middleware for logging
|
// Request ID middleware for logging
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
req.requestId = Math.random().toString(36).substr(2, 9);
|
req.requestId = randomUUID();
|
||||||
res.setHeader('X-Request-ID', req.requestId);
|
res.setHeader('X-Request-ID', req.requestId);
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ export class ImageGenService {
|
||||||
filename: uploadResult.filename,
|
filename: uploadResult.filename,
|
||||||
filepath: uploadResult.path,
|
filepath: uploadResult.path,
|
||||||
url: uploadResult.url,
|
url: uploadResult.url,
|
||||||
|
size: uploadResult.size,
|
||||||
model: this.primaryModel,
|
model: this.primaryModel,
|
||||||
geminiParams,
|
geminiParams,
|
||||||
...(generatedData.description && {
|
...(generatedData.description && {
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ export class GenerationService {
|
||||||
storageKey,
|
storageKey,
|
||||||
storageUrl: genResult.url!,
|
storageUrl: genResult.url!,
|
||||||
mimeType: 'image/jpeg',
|
mimeType: 'image/jpeg',
|
||||||
fileSize: 0, // TODO: Get actual file size from storage
|
fileSize: genResult.size || 0,
|
||||||
fileHash,
|
fileHash,
|
||||||
source: 'generated',
|
source: 'generated',
|
||||||
alias: params.assignAlias || null,
|
alias: params.assignAlias || null,
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,7 @@ export interface ImageGenerationResult {
|
||||||
filename?: string;
|
filename?: string;
|
||||||
filepath?: string;
|
filepath?: string;
|
||||||
url?: string; // API URL for accessing the image
|
url?: string; // API URL for accessing the image
|
||||||
|
size?: number; // File size in bytes
|
||||||
description?: string;
|
description?: string;
|
||||||
model: string;
|
model: string;
|
||||||
geminiParams?: GeminiParams; // Gemini SDK parameters used for generation
|
geminiParams?: GeminiParams; // Gemini SDK parameters used for generation
|
||||||
|
|
|
||||||
|
|
@ -22,39 +22,39 @@ async function main() {
|
||||||
description: 'Test logo image',
|
description: 'Test logo image',
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.image || !response.image.id) {
|
if (!response || !response.id) {
|
||||||
throw new Error('No image returned');
|
throw new Error('No image returned');
|
||||||
}
|
}
|
||||||
|
|
||||||
testContext.uploadedImageId = response.image.id;
|
testContext.uploadedImageId = response.id;
|
||||||
log.detail('Image ID', response.image.id);
|
log.detail('Image ID', response.id);
|
||||||
log.detail('Storage Key', response.image.storageKey);
|
log.detail('Storage Key', response.storageKey);
|
||||||
log.detail('Alias', response.image.alias);
|
log.detail('Alias', response.alias);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test 2: List images
|
// Test 2: List images
|
||||||
await runTest('List images', async () => {
|
await runTest('List images', async () => {
|
||||||
const result = await api(endpoints.images);
|
const result = await api(endpoints.images);
|
||||||
|
|
||||||
if (!result.data.images || !Array.isArray(result.data.images)) {
|
if (!result.data.data || !Array.isArray(result.data.data)) {
|
||||||
throw new Error('No images array returned');
|
throw new Error('No images array returned');
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Total images', result.data.images.length);
|
log.detail('Total images', result.data.data.length);
|
||||||
log.detail('Has uploaded', result.data.images.some((img: any) => img.source === 'uploaded'));
|
log.detail('Has uploaded', result.data.data.some((img: any) => img.source === 'uploaded'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test 3: Get image by ID
|
// Test 3: Get image by ID
|
||||||
await runTest('Get image by ID', async () => {
|
await runTest('Get image by ID', async () => {
|
||||||
const result = await api(`${endpoints.images}/${testContext.uploadedImageId}`);
|
const result = await api(`${endpoints.images}/${testContext.uploadedImageId}`);
|
||||||
|
|
||||||
if (!result.data.image) {
|
if (!result.data.data) {
|
||||||
throw new Error('Image not found');
|
throw new Error('Image not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Image ID', result.data.image.id);
|
log.detail('Image ID', result.data.data.id);
|
||||||
log.detail('Source', result.data.image.source);
|
log.detail('Source', result.data.data.source);
|
||||||
log.detail('File size', `${result.data.image.fileSize} bytes`);
|
log.detail('File size', `${result.data.data.fileSize} bytes`);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test 4: Generate image without references
|
// Test 4: Generate image without references
|
||||||
|
|
@ -68,14 +68,14 @@ async function main() {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result.data.generation) {
|
if (!result.data.data) {
|
||||||
throw new Error('No generation returned');
|
throw new Error('No generation returned');
|
||||||
}
|
}
|
||||||
|
|
||||||
testContext.generationId = result.data.generation.id;
|
testContext.generationId = result.data.data.id;
|
||||||
log.detail('Generation ID', result.data.generation.id);
|
log.detail('Generation ID', result.data.data.id);
|
||||||
log.detail('Status', result.data.generation.status);
|
log.detail('Status', result.data.data.status);
|
||||||
log.detail('Prompt', result.data.generation.originalPrompt);
|
log.detail('Prompt', result.data.data.originalPrompt);
|
||||||
|
|
||||||
// Wait for completion
|
// Wait for completion
|
||||||
log.info('Waiting for generation to complete...');
|
log.info('Waiting for generation to complete...');
|
||||||
|
|
@ -93,7 +93,7 @@ async function main() {
|
||||||
const imageResult = await api(`${endpoints.images}/${generation.outputImageId}`);
|
const imageResult = await api(`${endpoints.images}/${generation.outputImageId}`);
|
||||||
|
|
||||||
// Download image
|
// Download image
|
||||||
const imageUrl = imageResult.data.image.storageUrl;
|
const imageUrl = imageResult.data.data.storageUrl;
|
||||||
const imageResponse = await fetch(imageUrl);
|
const imageResponse = await fetch(imageUrl);
|
||||||
const imageBuffer = await imageResponse.arrayBuffer();
|
const imageBuffer = await imageResponse.arrayBuffer();
|
||||||
|
|
||||||
|
|
@ -114,16 +114,16 @@ async function main() {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result.data.generation) {
|
if (!result.data.data) {
|
||||||
throw new Error('No generation returned');
|
throw new Error('No generation returned');
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Generation ID', result.data.generation.id);
|
log.detail('Generation ID', result.data.data.id);
|
||||||
log.detail('Referenced images', result.data.generation.referencedImages?.length || 0);
|
log.detail('Referenced images', result.data.data.referencedImages?.length || 0);
|
||||||
|
|
||||||
// Wait for completion
|
// Wait for completion
|
||||||
log.info('Waiting for generation to complete...');
|
log.info('Waiting for generation to complete...');
|
||||||
const generation = await waitForGeneration(result.data.generation.id);
|
const generation = await waitForGeneration(result.data.data.id);
|
||||||
|
|
||||||
if (generation.status !== 'success') {
|
if (generation.status !== 'success') {
|
||||||
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
||||||
|
|
@ -132,7 +132,7 @@ async function main() {
|
||||||
// Save generated image
|
// Save generated image
|
||||||
if (generation.outputImageId) {
|
if (generation.outputImageId) {
|
||||||
const imageResult = await api(`${endpoints.images}/${generation.outputImageId}`);
|
const imageResult = await api(`${endpoints.images}/${generation.outputImageId}`);
|
||||||
const imageUrl = imageResult.data.image.storageUrl;
|
const imageUrl = imageResult.data.data.storageUrl;
|
||||||
const imageResponse = await fetch(imageUrl);
|
const imageResponse = await fetch(imageUrl);
|
||||||
const imageBuffer = await imageResponse.arrayBuffer();
|
const imageBuffer = await imageResponse.arrayBuffer();
|
||||||
|
|
||||||
|
|
@ -144,12 +144,12 @@ async function main() {
|
||||||
await runTest('List generations', async () => {
|
await runTest('List generations', async () => {
|
||||||
const result = await api(endpoints.generations);
|
const result = await api(endpoints.generations);
|
||||||
|
|
||||||
if (!result.data.generations || !Array.isArray(result.data.generations)) {
|
if (!result.data.data || !Array.isArray(result.data.data)) {
|
||||||
throw new Error('No generations array returned');
|
throw new Error('No generations array returned');
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Total generations', result.data.generations.length);
|
log.detail('Total generations', result.data.data.length);
|
||||||
log.detail('Successful', result.data.generations.filter((g: any) => g.status === 'success').length);
|
log.detail('Successful', result.data.data.filter((g: any) => g.status === 'success').length);
|
||||||
log.detail('Has pagination', !!result.data.pagination);
|
log.detail('Has pagination', !!result.data.pagination);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -157,14 +157,14 @@ async function main() {
|
||||||
await runTest('Get generation details', async () => {
|
await runTest('Get generation details', async () => {
|
||||||
const result = await api(`${endpoints.generations}/${testContext.generationId}`);
|
const result = await api(`${endpoints.generations}/${testContext.generationId}`);
|
||||||
|
|
||||||
if (!result.data.generation) {
|
if (!result.data.data) {
|
||||||
throw new Error('Generation not found');
|
throw new Error('Generation not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Generation ID', result.data.generation.id);
|
log.detail('Generation ID', result.data.data.id);
|
||||||
log.detail('Status', result.data.generation.status);
|
log.detail('Status', result.data.data.status);
|
||||||
log.detail('Has image', !!result.data.image);
|
log.detail('Has output image', !!result.data.data.outputImage);
|
||||||
log.detail('Referenced images', result.data.referencedImages?.length || 0);
|
log.detail('Referenced images', result.data.data.referencedImages?.length || 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
log.section('BASIC TESTS COMPLETED');
|
log.section('BASIC TESTS COMPLETED');
|
||||||
|
|
|
||||||
|
|
@ -22,24 +22,24 @@ async function main() {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result.data.flow || !result.data.flow.id) {
|
if (!result.data.data || !result.data.data.id) {
|
||||||
throw new Error('No flow returned');
|
throw new Error('No flow returned');
|
||||||
}
|
}
|
||||||
|
|
||||||
testContext.flowId = result.data.flow.id;
|
testContext.flowId = result.data.data.id;
|
||||||
log.detail('Flow ID', result.data.flow.id);
|
log.detail('Flow ID', result.data.data.id);
|
||||||
log.detail('Aliases', JSON.stringify(result.data.flow.aliases));
|
log.detail('Aliases', JSON.stringify(result.data.data.aliases));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test 2: List flows
|
// Test 2: List flows
|
||||||
await runTest('List flows', async () => {
|
await runTest('List flows', async () => {
|
||||||
const result = await api(endpoints.flows);
|
const result = await api(endpoints.flows);
|
||||||
|
|
||||||
if (!result.data.flows || !Array.isArray(result.data.flows)) {
|
if (!result.data.data || !Array.isArray(result.data.data)) {
|
||||||
throw new Error('No flows array returned');
|
throw new Error('No flows array returned');
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Total flows', result.data.flows.length);
|
log.detail('Total flows', result.data.data.length);
|
||||||
log.detail('Has pagination', !!result.data.pagination);
|
log.detail('Has pagination', !!result.data.pagination);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -55,16 +55,16 @@ async function main() {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result.data.generation) {
|
if (!result.data.data) {
|
||||||
throw new Error('No generation returned');
|
throw new Error('No generation returned');
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Generation ID', result.data.generation.id);
|
log.detail('Generation ID', result.data.data.id);
|
||||||
log.detail('Flow ID', result.data.generation.flowId);
|
log.detail('Flow ID', result.data.data.flowId);
|
||||||
|
|
||||||
// Wait for completion
|
// Wait for completion
|
||||||
log.info('Waiting for generation to complete...');
|
log.info('Waiting for generation to complete...');
|
||||||
const generation = await waitForGeneration(result.data.generation.id);
|
const generation = await waitForGeneration(result.data.data.id);
|
||||||
|
|
||||||
if (generation.status !== 'success') {
|
if (generation.status !== 'success') {
|
||||||
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
||||||
|
|
@ -96,16 +96,16 @@ async function main() {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result.data.generation) {
|
if (!result.data.data) {
|
||||||
throw new Error('No generation returned');
|
throw new Error('No generation returned');
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Generation ID', result.data.generation.id);
|
log.detail('Generation ID', result.data.data.id);
|
||||||
log.detail('Referenced @last', result.data.generation.referencedImages?.some((r: any) => r.alias === '@last'));
|
log.detail('Referenced @last', result.data.data.referencedImages?.some((r: any) => r.alias === '@last'));
|
||||||
|
|
||||||
// Wait for completion
|
// Wait for completion
|
||||||
log.info('Waiting for generation to complete...');
|
log.info('Waiting for generation to complete...');
|
||||||
const generation = await waitForGeneration(result.data.generation.id);
|
const generation = await waitForGeneration(result.data.data.id);
|
||||||
|
|
||||||
if (generation.status !== 'success') {
|
if (generation.status !== 'success') {
|
||||||
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
||||||
|
|
@ -126,13 +126,13 @@ async function main() {
|
||||||
await runTest('Get flow details', async () => {
|
await runTest('Get flow details', async () => {
|
||||||
const result = await api(`${endpoints.flows}/${testContext.flowId}`);
|
const result = await api(`${endpoints.flows}/${testContext.flowId}`);
|
||||||
|
|
||||||
if (!result.data.flow) {
|
if (!result.data.data) {
|
||||||
throw new Error('Flow not found');
|
throw new Error('Flow not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Flow ID', result.data.flow.id);
|
log.detail('Flow ID', result.data.data.id);
|
||||||
log.detail('Generations count', result.data.generations?.length || 0);
|
log.detail('Generations count', result.data.datas?.length || 0);
|
||||||
log.detail('Images count', result.data.images?.length || 0);
|
log.detail('Images count', result.data.data?.length || 0);
|
||||||
log.detail('Resolved aliases', Object.keys(result.data.resolvedAliases || {}).length);
|
log.detail('Resolved aliases', Object.keys(result.data.resolvedAliases || {}).length);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -157,11 +157,11 @@ async function main() {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result.data.flow) {
|
if (!result.data.data) {
|
||||||
throw new Error('Flow not returned');
|
throw new Error('Flow not returned');
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Updated aliases', JSON.stringify(result.data.flow.aliases));
|
log.detail('Updated aliases', JSON.stringify(result.data.data.aliases));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test 7: Generate with flow-scoped alias
|
// Test 7: Generate with flow-scoped alias
|
||||||
|
|
@ -177,16 +177,16 @@ async function main() {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result.data.generation) {
|
if (!result.data.data) {
|
||||||
throw new Error('No generation returned');
|
throw new Error('No generation returned');
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Generation ID', result.data.generation.id);
|
log.detail('Generation ID', result.data.data.id);
|
||||||
log.detail('Referenced @hero', result.data.generation.referencedImages?.some((r: any) => r.alias === '@hero'));
|
log.detail('Referenced @hero', result.data.data.referencedImages?.some((r: any) => r.alias === '@hero'));
|
||||||
|
|
||||||
// Wait for completion
|
// Wait for completion
|
||||||
log.info('Waiting for generation to complete...');
|
log.info('Waiting for generation to complete...');
|
||||||
const generation = await waitForGeneration(result.data.generation.id);
|
const generation = await waitForGeneration(result.data.data.id);
|
||||||
|
|
||||||
if (generation.status !== 'success') {
|
if (generation.status !== 'success') {
|
||||||
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
||||||
|
|
@ -211,13 +211,13 @@ async function main() {
|
||||||
|
|
||||||
// Verify it's deleted
|
// Verify it's deleted
|
||||||
const result = await api(`${endpoints.flows}/${testContext.flowId}`);
|
const result = await api(`${endpoints.flows}/${testContext.flowId}`);
|
||||||
const hasFeatureAlias = '@featured' in result.data.flow.aliases;
|
const hasFeatureAlias = '@featured' in result.data.data.aliases;
|
||||||
|
|
||||||
if (hasFeatureAlias) {
|
if (hasFeatureAlias) {
|
||||||
throw new Error('Alias was not deleted');
|
throw new Error('Alias was not deleted');
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Remaining aliases', JSON.stringify(result.data.flow.aliases));
|
log.detail('Remaining aliases', JSON.stringify(result.data.data.aliases));
|
||||||
});
|
});
|
||||||
|
|
||||||
log.section('FLOW TESTS COMPLETED');
|
log.section('FLOW TESTS COMPLETED');
|
||||||
|
|
|
||||||
|
|
@ -78,50 +78,50 @@ async function main() {
|
||||||
await runTest('Resolve project alias', async () => {
|
await runTest('Resolve project alias', async () => {
|
||||||
const result = await api(`${endpoints.images}/resolve/@brand-logo`);
|
const result = await api(`${endpoints.images}/resolve/@brand-logo`);
|
||||||
|
|
||||||
if (!result.data.image) {
|
if (!result.data.data) {
|
||||||
throw new Error('Image not resolved');
|
throw new Error('Image not resolved');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.data.scope !== 'project') {
|
if (result.data.data.scope !== 'project') {
|
||||||
throw new Error(`Wrong scope: ${result.data.scope}`);
|
throw new Error(`Wrong scope: ${result.data.data.scope}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Image ID', result.data.image.id);
|
log.detail('Image ID', result.data.data.id);
|
||||||
log.detail('Scope', result.data.scope);
|
log.detail('Scope', result.data.data.scope);
|
||||||
log.detail('Alias', result.data.image.alias);
|
log.detail('Alias', result.data.data.alias);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test 5: Resolve flow-scoped alias
|
// Test 5: Resolve flow-scoped alias
|
||||||
await runTest('Resolve flow alias', async () => {
|
await runTest('Resolve flow alias', async () => {
|
||||||
const result = await api(`${endpoints.images}/resolve/@temp-logo?flowId=${testContext.flowId}`);
|
const result = await api(`${endpoints.images}/resolve/@temp-logo?flowId=${testContext.flowId}`);
|
||||||
|
|
||||||
if (!result.data.image) {
|
if (!result.data.data) {
|
||||||
throw new Error('Image not resolved');
|
throw new Error('Image not resolved');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.data.scope !== 'flow') {
|
if (result.data.data.scope !== 'flow') {
|
||||||
throw new Error(`Wrong scope: ${result.data.scope}`);
|
throw new Error(`Wrong scope: ${result.data.data.scope}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Image ID', result.data.image.id);
|
log.detail('Image ID', result.data.data.id);
|
||||||
log.detail('Scope', result.data.scope);
|
log.detail('Scope', result.data.data.scope);
|
||||||
log.detail('Flow ID', result.data.flow?.id);
|
log.detail('Flow ID', result.data.data?.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test 6: Resolve @last technical alias
|
// Test 6: Resolve @last technical alias
|
||||||
await runTest('Resolve @last technical alias', async () => {
|
await runTest('Resolve @last technical alias', async () => {
|
||||||
const result = await api(`${endpoints.images}/resolve/@last?flowId=${testContext.flowId}`);
|
const result = await api(`${endpoints.images}/resolve/@last?flowId=${testContext.flowId}`);
|
||||||
|
|
||||||
if (!result.data.image) {
|
if (!result.data.data) {
|
||||||
throw new Error('Image not resolved');
|
throw new Error('Image not resolved');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.data.scope !== 'technical') {
|
if (result.data.data.scope !== 'technical') {
|
||||||
throw new Error(`Wrong scope: ${result.data.scope}`);
|
throw new Error(`Wrong scope: ${result.data.data.scope}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Image ID', result.data.image.id);
|
log.detail('Image ID', result.data.data.id);
|
||||||
log.detail('Scope', result.data.scope);
|
log.detail('Scope', result.data.data.scope);
|
||||||
log.detail('Technical alias', '@last');
|
log.detail('Technical alias', '@last');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -129,33 +129,33 @@ async function main() {
|
||||||
await runTest('Resolve @first technical alias', async () => {
|
await runTest('Resolve @first technical alias', async () => {
|
||||||
const result = await api(`${endpoints.images}/resolve/@first?flowId=${testContext.flowId}`);
|
const result = await api(`${endpoints.images}/resolve/@first?flowId=${testContext.flowId}`);
|
||||||
|
|
||||||
if (!result.data.image) {
|
if (!result.data.data) {
|
||||||
throw new Error('Image not resolved');
|
throw new Error('Image not resolved');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.data.scope !== 'technical') {
|
if (result.data.data.scope !== 'technical') {
|
||||||
throw new Error(`Wrong scope: ${result.data.scope}`);
|
throw new Error(`Wrong scope: ${result.data.data.scope}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Image ID', result.data.image.id);
|
log.detail('Image ID', result.data.data.id);
|
||||||
log.detail('Scope', result.data.scope);
|
log.detail('Scope', result.data.data.scope);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test 8: Resolve @upload technical alias
|
// Test 8: Resolve @upload technical alias
|
||||||
await runTest('Resolve @upload technical alias', async () => {
|
await runTest('Resolve @upload technical alias', async () => {
|
||||||
const result = await api(`${endpoints.images}/resolve/@upload?flowId=${testContext.flowId}`);
|
const result = await api(`${endpoints.images}/resolve/@upload?flowId=${testContext.flowId}`);
|
||||||
|
|
||||||
if (!result.data.image) {
|
if (!result.data.data) {
|
||||||
throw new Error('Image not resolved');
|
throw new Error('Image not resolved');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.data.scope !== 'technical') {
|
if (result.data.data.scope !== 'technical') {
|
||||||
throw new Error(`Wrong scope: ${result.data.scope}`);
|
throw new Error(`Wrong scope: ${result.data.data.scope}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.detail('Image ID', result.data.image.id);
|
log.detail('Image ID', result.data.data.id);
|
||||||
log.detail('Scope', result.data.scope);
|
log.detail('Scope', result.data.data.scope);
|
||||||
log.detail('Source', result.data.image.source);
|
log.detail('Source', result.data.data.source);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test 9: Generate with assignAlias (project-scoped)
|
// Test 9: Generate with assignAlias (project-scoped)
|
||||||
|
|
@ -171,7 +171,7 @@ async function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
log.info('Waiting for generation to complete...');
|
log.info('Waiting for generation to complete...');
|
||||||
const generation = await waitForGeneration(result.data.generation.id);
|
const generation = await waitForGeneration(result.data.data.id);
|
||||||
|
|
||||||
if (generation.status !== 'success') {
|
if (generation.status !== 'success') {
|
||||||
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
||||||
|
|
@ -208,7 +208,7 @@ async function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
log.info('Waiting for generation to complete...');
|
log.info('Waiting for generation to complete...');
|
||||||
const generation = await waitForGeneration(result.data.generation.id);
|
const generation = await waitForGeneration(result.data.data.id);
|
||||||
|
|
||||||
if (generation.status !== 'success') {
|
if (generation.status !== 'success') {
|
||||||
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ export const config = {
|
||||||
|
|
||||||
// Paths
|
// Paths
|
||||||
resultsDir: '../../results',
|
resultsDir: '../../results',
|
||||||
fixturesDir: './fixtures',
|
fixturesDir: './fixture',
|
||||||
|
|
||||||
// Timeouts
|
// Timeouts
|
||||||
requestTimeout: 30000,
|
requestTimeout: 30000,
|
||||||
|
|
|
||||||
|
After Width: | Height: | Size: 1.5 MiB |
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import { writeFile, mkdir } from 'fs/promises';
|
import { writeFile, mkdir } from 'fs/promises';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { config } from './config';
|
import { config, endpoints } from './config';
|
||||||
|
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
|
|
@ -150,7 +150,7 @@ export async function uploadFile(
|
||||||
formData.append(key, value);
|
formData.append(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await api(config.endpoints.images + '/upload', {
|
const result = await api(endpoints.images + '/upload', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: formData,
|
body: formData,
|
||||||
headers: {
|
headers: {
|
||||||
|
|
@ -158,7 +158,7 @@ export async function uploadFile(
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return result.data;
|
return result.data.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait helper
|
// Wait helper
|
||||||
|
|
@ -172,8 +172,8 @@ export async function waitForGeneration(
|
||||||
maxAttempts = 20
|
maxAttempts = 20
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
for (let i = 0; i < maxAttempts; i++) {
|
for (let i = 0; i < maxAttempts; i++) {
|
||||||
const result = await api(`${config.endpoints.generations}/${generationId}`);
|
const result = await api(`${endpoints.generations}/${generationId}`);
|
||||||
const generation = result.data.generation;
|
const generation = result.data.data;
|
||||||
|
|
||||||
if (generation.status === 'success' || generation.status === 'failed') {
|
if (generation.status === 'success' || generation.status === 'failed') {
|
||||||
return generation;
|
return generation;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue