Files
gridpilot.gg/apps/website/lib/adapters/MediaAdapter.ts
2026-01-26 17:56:11 +01:00

65 lines
1.7 KiB
TypeScript

/**
* MediaAdapter
*
* Handles HTTP operations for media assets.
* This is where external API calls belong.
*/
import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl';
import { Result } from '@/lib/contracts/Result';
import { DomainError } from '@/lib/contracts/services/Service';
import { MediaBinaryDTO } from '@/lib/types/MediaBinaryDTO';
// TODO why is this an adapter?
/**
* MediaAdapter
*
* Handles binary media fetching from the API.
* All HTTP calls are isolated here.
*/
export class MediaAdapter {
private baseUrl: string;
constructor() {
this.baseUrl = getWebsiteApiBaseUrl();
}
/**
* Fetch binary media from API
*
* @param mediaPath - API path to media resource
* @returns Result with MediaBinaryDTO on success, DomainError on failure
*/
async fetchMedia(mediaPath: string): Promise<Result<MediaBinaryDTO, DomainError>> {
try {
const response = await fetch(`${this.baseUrl}${mediaPath}`, {
method: 'GET',
});
if (!response.ok) {
if (response.status === 404) {
return Result.err({
type: 'notFound',
message: `Media not found: ${mediaPath}`
});
}
return Result.err({
type: 'serverError',
message: `HTTP ${response.status}: ${response.statusText}`
});
}
const buffer = await response.arrayBuffer();
const contentType = response.headers.get('content-type') || 'image/svg+xml';
return Result.ok({ buffer, contentType });
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
return Result.err({
type: 'networkError',
message: `Failed to fetch media: ${errorMessage}`
});
}
}
}