Files
memory-infrastructure-palace/code/websites/pokedex.online/src/utilities/gamemaster-client.js

193 lines
4.9 KiB
JavaScript

/**
* Gamemaster Client Utility
* Use this in any app on the site to access gamemaster data
*
* Usage:
* import { GamemasterClient } from './gamemaster-client.js';
* const gm = new GamemasterClient('/api/gamemaster');
*
* // Get filtered pokemon
* const pokemon = await gm.getPokemon();
*
* // Get all forms with costumes
* const allForms = await gm.getAllForms();
*
* // Get moves
* const moves = await gm.getMoves();
*
* // Get raw unmodified data
* const raw = await gm.getRaw();
*
* // Check what's available
* const status = await gm.getStatus();
*/
export class GamemasterClient {
constructor(baseUrl = '/api/gamemaster') {
this.baseUrl = baseUrl;
this.cache = new Map();
}
/**
* Make a request to the gamemaster API
* @private
* @param {string} endpoint
* @param {Object} options
* @returns {Promise<Object|Array>}
*/
async request(endpoint, options = {}) {
const url = `${this.baseUrl}${endpoint}`;
try {
const response = await fetch(url, {
method: 'GET',
...options
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.error || `HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
console.error(`Gamemaster API Error [${endpoint}]:`, error.message);
throw error;
}
}
/**
* Get status of available files
* @returns {Promise<Object>}
*/
async getStatus() {
return this.request('/status');
}
/**
* Get filtered pokemon data (base forms + regional variants)
* @param {Object} options
* @param {boolean} options.useCache - Use cached data if available
* @returns {Promise<Array>}
*/
async getPokemon(options = {}) {
if (options.useCache && this.cache.has('pokemon')) {
return this.cache.get('pokemon');
}
const data = await this.request('/pokemon');
this.cache.set('pokemon', data);
return data;
}
/**
* Get all pokemon forms including costumes, shadows, events, etc.
* @param {Object} options
* @param {boolean} options.useCache - Use cached data if available
* @returns {Promise<Array>}
*/
async getAllForms(options = {}) {
if (options.useCache && this.cache.has('allForms')) {
return this.cache.get('allForms');
}
const data = await this.request('/pokemon/allForms');
this.cache.set('allForms', data);
return data;
}
/**
* Get all pokemon moves
* @param {Object} options
* @param {boolean} options.useCache - Use cached data if available
* @returns {Promise<Array>}
*/
async getMoves(options = {}) {
if (options.useCache && this.cache.has('moves')) {
return this.cache.get('moves');
}
const data = await this.request('/moves');
this.cache.set('moves', data);
return data;
}
/**
* Get raw unmodified gamemaster data
* @param {Object} options
* @param {boolean} options.useCache - Use cached data if available
* @returns {Promise<Array>}
*/
async getRaw(options = {}) {
if (options.useCache && this.cache.has('raw')) {
return this.cache.get('raw');
}
const data = await this.request('/raw');
this.cache.set('raw', data);
return data;
}
/**
* Download a file directly
* @param {string} filename - One of: pokemon.json, pokemon-allFormsCostumes.json, pokemon-moves.json, latest-raw.json
* @returns {Promise<void>}
*/
async downloadFile(filename) {
const url = `${this.baseUrl}/download/${filename}`;
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to download ${filename}`);
}
const blob = await response.blob();
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
}
/**
* Clear cached data
* @param {string} key - Optional specific key to clear, or clears all if not provided
*/
clearCache(key = null) {
if (key) {
this.cache.delete(key);
} else {
this.cache.clear();
}
}
/**
* Get a specific pokemon from the filtered dataset
* @param {string} pokemonId
* @returns {Promise<Object|null>}
*/
async getPokemonById(pokemonId) {
const pokemon = await this.getPokemon({ useCache: true });
return (
pokemon.find(p => p.data?.pokemonSettings?.pokemonId === pokemonId) ||
null
);
}
/**
* Get a specific move
* @param {string} moveId
* @returns {Promise<Object|null>}
*/
async getMoveById(moveId) {
const moves = await this.getMoves({ useCache: true });
return moves.find(m => m.data?.moveSettings?.movementId === moveId) || null;
}
}
/**
* Singleton instance - use this for most cases
*/
export const gamemasterClient = new GamemasterClient();