244 lines
5.7 KiB
TypeScript
244 lines
5.7 KiB
TypeScript
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000/api';
|
|
|
|
// Tipos para relaciones del juego
|
|
export interface Artwork {
|
|
id: string;
|
|
type: string;
|
|
sourceUrl: string;
|
|
localPath?: string;
|
|
width?: number;
|
|
height?: number;
|
|
fetchedAt: string;
|
|
}
|
|
|
|
export interface Purchase {
|
|
id: string;
|
|
priceCents: number;
|
|
currency: string;
|
|
store?: string;
|
|
date: string;
|
|
receiptPath?: string;
|
|
}
|
|
|
|
export interface GamePlatform {
|
|
id: string;
|
|
platform: {
|
|
id: string;
|
|
name: string;
|
|
slug: string;
|
|
generation?: number;
|
|
};
|
|
}
|
|
|
|
export interface Tag {
|
|
id: string;
|
|
name: string;
|
|
}
|
|
|
|
// Tipos para metadatos de búsqueda
|
|
export interface MetadataGame {
|
|
id?: number;
|
|
name: string;
|
|
slug?: string;
|
|
releaseDate?: string;
|
|
genres?: string[];
|
|
platforms?: PlatformInfo[];
|
|
coverUrl?: string;
|
|
source?: string;
|
|
}
|
|
|
|
export interface PlatformInfo {
|
|
id?: number;
|
|
name?: string;
|
|
abbreviation?: string;
|
|
slug?: string;
|
|
}
|
|
|
|
export interface Game {
|
|
id: string;
|
|
title: string;
|
|
slug: string;
|
|
description?: string;
|
|
releaseDate?: string;
|
|
genre?: string;
|
|
platform?: string;
|
|
year?: number;
|
|
cover?: string;
|
|
source: string;
|
|
sourceId?: string;
|
|
// Campos específicos de ROM (si source = "rom")
|
|
romPath?: string;
|
|
romFilename?: string;
|
|
romSize?: number;
|
|
romChecksum?: string;
|
|
romFormat?: string;
|
|
romHashes?: string;
|
|
// IDs de integraciones externas
|
|
igdbId?: number;
|
|
rawgId?: number;
|
|
thegamesdbId?: number;
|
|
// Metadatos adicionales
|
|
metadata?: string;
|
|
// Timestamps
|
|
addedAt?: string;
|
|
lastSeenAt?: string;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
// Relaciones
|
|
artworks?: Artwork[];
|
|
purchases?: Purchase[];
|
|
gamePlatforms?: GamePlatform[];
|
|
tags?: Tag[];
|
|
}
|
|
|
|
export interface CreateGameInput {
|
|
title: string;
|
|
slug?: string;
|
|
description?: string;
|
|
releaseDate?: string;
|
|
genre?: string;
|
|
platform?: string;
|
|
year?: number;
|
|
cover?: string;
|
|
source?: string;
|
|
sourceId?: string;
|
|
platformId?: string;
|
|
priceCents?: number;
|
|
currency?: string;
|
|
store?: string;
|
|
date?: string;
|
|
condition?: 'Loose' | 'CIB' | 'New';
|
|
}
|
|
|
|
export interface UpdateGameInput {
|
|
title?: string;
|
|
slug?: string;
|
|
description?: string;
|
|
releaseDate?: string;
|
|
genre?: string;
|
|
platform?: string;
|
|
year?: number;
|
|
cover?: string;
|
|
source?: string;
|
|
sourceId?: string;
|
|
platformId?: string;
|
|
priceCents?: number;
|
|
currency?: string;
|
|
store?: string;
|
|
date?: string;
|
|
condition?: 'Loose' | 'CIB' | 'New';
|
|
}
|
|
|
|
export interface ImportRequest {
|
|
directory: string;
|
|
recursive?: boolean;
|
|
}
|
|
|
|
export interface ImportResult {
|
|
success: boolean;
|
|
message: string;
|
|
imported: number;
|
|
errors: string[];
|
|
}
|
|
|
|
export const gamesApi = {
|
|
getAll: async (): Promise<Game[]> => {
|
|
const response = await fetch(`${API_BASE}/games`);
|
|
if (!response.ok) {
|
|
throw new Error(`Error fetching games: ${response.statusText}`);
|
|
}
|
|
return response.json();
|
|
},
|
|
|
|
getById: async (id: string): Promise<Game> => {
|
|
const response = await fetch(`${API_BASE}/games/${id}`);
|
|
if (!response.ok) {
|
|
throw new Error(`Error fetching game: ${response.statusText}`);
|
|
}
|
|
return response.json();
|
|
},
|
|
|
|
getBySource: async (source: string): Promise<Game[]> => {
|
|
const response = await fetch(`${API_BASE}/games/source/${source}`);
|
|
if (!response.ok) {
|
|
throw new Error(`Error fetching games by source: ${response.statusText}`);
|
|
}
|
|
return response.json();
|
|
},
|
|
|
|
create: async (data: CreateGameInput): Promise<Game> => {
|
|
const response = await fetch(`${API_BASE}/games`, {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`Error creating game: ${response.statusText}`);
|
|
}
|
|
return response.json();
|
|
},
|
|
|
|
update: async (id: string, data: UpdateGameInput): Promise<Game> => {
|
|
const response = await fetch(`${API_BASE}/games/${id}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(data),
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`Error updating game: ${response.statusText}`);
|
|
}
|
|
return response.json();
|
|
},
|
|
|
|
delete: async (id: string): Promise<void> => {
|
|
const response = await fetch(`${API_BASE}/games/${id}`, {
|
|
method: 'DELETE',
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`Error deleting game: ${response.statusText}`);
|
|
}
|
|
},
|
|
};
|
|
|
|
export const importApi = {
|
|
start: async (data: ImportRequest): Promise<ImportResult> => {
|
|
const response = await fetch(`${API_BASE}/import`, {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`Error starting import: ${response.statusText}`);
|
|
}
|
|
return response.json();
|
|
},
|
|
};
|
|
|
|
export const metadataApi = {
|
|
searchIGDB: async (query: string): Promise<MetadataGame[]> => {
|
|
const response = await fetch(`${API_BASE}/metadata/igdb/search?q=${encodeURIComponent(query)}`);
|
|
if (!response.ok) {
|
|
throw new Error(`Error searching IGDB: ${response.statusText}`);
|
|
}
|
|
return response.json();
|
|
},
|
|
|
|
searchRAWG: async (query: string): Promise<MetadataGame[]> => {
|
|
const response = await fetch(`${API_BASE}/metadata/rawg/search?q=${encodeURIComponent(query)}`);
|
|
if (!response.ok) {
|
|
throw new Error(`Error searching RAWG: ${response.statusText}`);
|
|
}
|
|
return response.json();
|
|
},
|
|
|
|
searchTheGamesDB: async (query: string): Promise<MetadataGame[]> => {
|
|
const response = await fetch(
|
|
`${API_BASE}/metadata/thegamesdb/search?q=${encodeURIComponent(query)}`
|
|
);
|
|
if (!response.ok) {
|
|
throw new Error(`Error searching TheGamesDB: ${response.statusText}`);
|
|
}
|
|
return response.json();
|
|
},
|
|
};
|