mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-09-16 02:22:17 +00:00
style: format tracked files and ignore generated data exports
`prettier --check .` failed on 22 files, so gating CI on `npm run lint` was never going to pass. These changes are whitespace only. Adds the two remaining generated data exports to .prettierignore so this class of churn cannot recur, along with machine-local settings files.
This commit is contained in:
@@ -2,3 +2,11 @@
|
|||||||
pnpm-lock.yaml
|
pnpm-lock.yaml
|
||||||
package-lock.json
|
package-lock.json
|
||||||
yarn.lock
|
yarn.lock
|
||||||
|
|
||||||
|
# Generated data exports. Nobody hand-edits these, and reformatting them buries real data
|
||||||
|
# changes under tens of thousands of lines of churn.
|
||||||
|
src/lib/helpers/pokeapi-pokemon.json
|
||||||
|
static/sprites/pokemon.json
|
||||||
|
|
||||||
|
# Machine-local editor and tool settings.
|
||||||
|
**/*.local.json
|
||||||
|
|||||||
+5
-5
@@ -1,6 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
plugins: {
|
plugins: {
|
||||||
tailwindcss: {},
|
tailwindcss: {},
|
||||||
autoprefixer: {},
|
autoprefixer: {}
|
||||||
},
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import process from 'node:process'
|
import process from 'node:process';
|
||||||
|
|
||||||
export const generateSW = process.env.GENERATE_SW === 'true'
|
export const generateSW = process.env.GENERATE_SW === 'true';
|
||||||
|
|||||||
+133
-119
@@ -17,167 +17,181 @@ const __dirname = path.dirname(__filename);
|
|||||||
* Parse CSV file into array of objects
|
* Parse CSV file into array of objects
|
||||||
*/
|
*/
|
||||||
function parseCSV(filePath) {
|
function parseCSV(filePath) {
|
||||||
const content = fs.readFileSync(filePath, 'utf-8');
|
const content = fs.readFileSync(filePath, 'utf-8');
|
||||||
const lines = content.split('\n').filter(line => line.trim());
|
const lines = content.split('\n').filter((line) => line.trim());
|
||||||
const headers = lines[0].split(',');
|
const headers = lines[0].split(',');
|
||||||
|
|
||||||
return lines.slice(1).map(line => {
|
return lines.slice(1).map((line) => {
|
||||||
const values = parseCSVLine(line);
|
const values = parseCSVLine(line);
|
||||||
const obj = {};
|
const obj = {};
|
||||||
headers.forEach((header, i) => {
|
headers.forEach((header, i) => {
|
||||||
obj[header] = values[i] || null;
|
obj[header] = values[i] || null;
|
||||||
});
|
});
|
||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a single CSV line, handling quoted values
|
* Parse a single CSV line, handling quoted values
|
||||||
*/
|
*/
|
||||||
function parseCSVLine(line) {
|
function parseCSVLine(line) {
|
||||||
const values = [];
|
const values = [];
|
||||||
let current = '';
|
let current = '';
|
||||||
let inQuotes = false;
|
let inQuotes = false;
|
||||||
|
|
||||||
for (let i = 0; i < line.length; i++) {
|
for (let i = 0; i < line.length; i++) {
|
||||||
const char = line[i];
|
const char = line[i];
|
||||||
|
|
||||||
if (char === '"') {
|
if (char === '"') {
|
||||||
inQuotes = !inQuotes;
|
inQuotes = !inQuotes;
|
||||||
} else if (char === ',' && !inQuotes) {
|
} else if (char === ',' && !inQuotes) {
|
||||||
values.push(current);
|
values.push(current);
|
||||||
current = '';
|
current = '';
|
||||||
} else {
|
} else {
|
||||||
current += char;
|
current += char;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
values.push(current);
|
values.push(current);
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate migration SQL from CSV data
|
* Generate migration SQL from CSV data
|
||||||
*/
|
*/
|
||||||
function generateMigration(region) {
|
function generateMigration(region) {
|
||||||
console.log(`\nGenerating migration for ${region}...`);
|
console.log(`\nGenerating migration for ${region}...`);
|
||||||
|
|
||||||
// Determine generation number from region
|
// Determine generation number from region
|
||||||
const regionToGen = {
|
const regionToGen = {
|
||||||
'Kanto': 1, 'Johto': 2, 'Hoenn': 3, 'Sinnoh': 4,
|
Kanto: 1,
|
||||||
'Unova': 5, 'Kalos': 6, 'Alola': 7, 'Galar': 8,
|
Johto: 2,
|
||||||
'Hisui': 8, 'Paldea': 9
|
Hoenn: 3,
|
||||||
};
|
Sinnoh: 4,
|
||||||
const gen = regionToGen[region] || 1;
|
Unova: 5,
|
||||||
|
Kalos: 6,
|
||||||
|
Alola: 7,
|
||||||
|
Galar: 8,
|
||||||
|
Hisui: 8,
|
||||||
|
Paldea: 9
|
||||||
|
};
|
||||||
|
const gen = regionToGen[region] || 1;
|
||||||
|
|
||||||
// 1. Load CSV files
|
// 1. Load CSV files
|
||||||
const pokemonPath = path.join(__dirname, '..', 'data', 'pokemon', `gen${gen}-${region.toLowerCase()}.csv`);
|
const pokemonPath = path.join(
|
||||||
const gamesPath = path.join(__dirname, '..', 'data', 'pokemon', 'games.csv');
|
__dirname,
|
||||||
|
'..',
|
||||||
|
'data',
|
||||||
|
'pokemon',
|
||||||
|
`gen${gen}-${region.toLowerCase()}.csv`
|
||||||
|
);
|
||||||
|
const gamesPath = path.join(__dirname, '..', 'data', 'pokemon', 'games.csv');
|
||||||
|
|
||||||
if (!fs.existsSync(pokemonPath)) {
|
if (!fs.existsSync(pokemonPath)) {
|
||||||
console.error(`Error: Pokemon CSV not found at ${pokemonPath}`);
|
console.error(`Error: Pokemon CSV not found at ${pokemonPath}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const pokemon = parseCSV(pokemonPath);
|
const pokemon = parseCSV(pokemonPath);
|
||||||
const games = parseCSV(gamesPath);
|
const games = parseCSV(gamesPath);
|
||||||
|
|
||||||
// 2. Filter for this region
|
// 2. Filter for this region
|
||||||
const regionGames = games.filter(g => g.region === region);
|
const regionGames = games.filter((g) => g.region === region);
|
||||||
|
|
||||||
if (regionGames.length === 0) {
|
if (regionGames.length === 0) {
|
||||||
console.error(`Error: No games found for region ${region} in games.csv`);
|
console.error(`Error: No games found for region ${region} in games.csv`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Generate SQL
|
// 3. Generate SQL
|
||||||
let sql = `-- Seed ${region} region Pokémon (Gen ${gen})\n`;
|
let sql = `-- Seed ${region} region Pokémon (Gen ${gen})\n`;
|
||||||
sql += `-- Auto-generated from CSV files\n\n`;
|
sql += `-- Auto-generated from CSV files\n\n`;
|
||||||
|
|
||||||
// Region-game mappings
|
// Region-game mappings
|
||||||
sql += `-- Insert ${region} region-game mappings\n`;
|
sql += `-- Insert ${region} region-game mappings\n`;
|
||||||
sql += `INSERT INTO region_game_mappings (region, game) VALUES\n`;
|
sql += `INSERT INTO region_game_mappings (region, game) VALUES\n`;
|
||||||
sql += regionGames.map(g => ` ('${region}', '${g.displayName}')`).join(',\n');
|
sql += regionGames.map((g) => ` ('${region}', '${g.displayName}')`).join(',\n');
|
||||||
sql += `\nON CONFLICT (region, game) DO NOTHING;\n\n`;
|
sql += `\nON CONFLICT (region, game) DO NOTHING;\n\n`;
|
||||||
|
|
||||||
// Pokemon entries (without regional dex number)
|
// Pokemon entries (without regional dex number)
|
||||||
sql += `-- Insert ${region} Pokémon entries\n`;
|
sql += `-- Insert ${region} Pokémon entries\n`;
|
||||||
sql += `INSERT INTO pokedex_entries (\n`;
|
sql += `INSERT INTO pokedex_entries (\n`;
|
||||||
sql += ` "pokedexNumber",\n`;
|
sql += ` "pokedexNumber",\n`;
|
||||||
sql += ` pokemon,\n`;
|
sql += ` pokemon,\n`;
|
||||||
sql += ` form,\n`;
|
sql += ` form,\n`;
|
||||||
sql += ` "canGigantamax",\n`;
|
sql += ` "canGigantamax",\n`;
|
||||||
sql += ` "regionToCatchIn",\n`;
|
sql += ` "regionToCatchIn",\n`;
|
||||||
sql += ` "gamesToCatchIn"\n`;
|
sql += ` "gamesToCatchIn"\n`;
|
||||||
sql += `) VALUES\n`;
|
sql += `) VALUES\n`;
|
||||||
|
|
||||||
const rows = pokemon.map(p => {
|
const rows = pokemon.map((p) => {
|
||||||
const form = p.form ? `'${p.form}'` : 'NULL';
|
const form = p.form ? `'${p.form}'` : 'NULL';
|
||||||
// Use regionalDexGames for the database (regional dex availability)
|
// Use regionalDexGames for the database (regional dex availability)
|
||||||
// originGames column is for future origin dex feature
|
// originGames column is for future origin dex feature
|
||||||
const gamesField = p.regionalDexGames || p.games; // Fallback to old 'games' column for compatibility
|
const gamesField = p.regionalDexGames || p.games; // Fallback to old 'games' column for compatibility
|
||||||
const gamesList = gamesField.split('|');
|
const gamesList = gamesField.split('|');
|
||||||
const gamesArray = `ARRAY[${gamesList.map(g => `'${g}'`).join(', ')}]`;
|
const gamesArray = `ARRAY[${gamesList.map((g) => `'${g}'`).join(', ')}]`;
|
||||||
|
|
||||||
return `(${p.pokedexNumber}, '${p.name}', ${form}, false, '${region}', ${gamesArray})`;
|
return `(${p.pokedexNumber}, '${p.name}', ${form}, false, '${region}', ${gamesArray})`;
|
||||||
});
|
});
|
||||||
|
|
||||||
sql += rows.join(',\n');
|
sql += rows.join(',\n');
|
||||||
sql += '\nON CONFLICT ON CONSTRAINT unique_pokemon_form DO NOTHING;\n\n';
|
sql += '\nON CONFLICT ON CONSTRAINT unique_pokemon_form DO NOTHING;\n\n';
|
||||||
|
|
||||||
// Regional dex numbers (separate table)
|
// Regional dex numbers (separate table)
|
||||||
sql += `-- Insert ${region} regional dex numbers\n`;
|
sql += `-- Insert ${region} regional dex numbers\n`;
|
||||||
|
|
||||||
const dexRows = pokemon
|
const dexRows = pokemon
|
||||||
.filter(p => p.regionalNumber) // Only entries with regional dex numbers
|
.filter((p) => p.regionalNumber) // Only entries with regional dex numbers
|
||||||
.map(p => {
|
.map((p) => {
|
||||||
const formCondition = p.form
|
const formCondition = p.form ? `form = '${p.form}'` : `form IS NULL`;
|
||||||
? `form = '${p.form}'`
|
|
||||||
: `form IS NULL`;
|
|
||||||
|
|
||||||
return ` ((SELECT id FROM pokedex_entries WHERE "pokedexNumber" = ${p.pokedexNumber} AND ${formCondition}), '${region}', ${p.regionalNumber})`;
|
return ` ((SELECT id FROM pokedex_entries WHERE "pokedexNumber" = ${p.pokedexNumber} AND ${formCondition}), '${region}', ${p.regionalNumber})`;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (dexRows.length > 0) {
|
if (dexRows.length > 0) {
|
||||||
sql += `INSERT INTO regional_dex_numbers (\n`;
|
sql += `INSERT INTO regional_dex_numbers (\n`;
|
||||||
sql += ` pokedex_entry_id,\n`;
|
sql += ` pokedex_entry_id,\n`;
|
||||||
sql += ` region,\n`;
|
sql += ` region,\n`;
|
||||||
sql += ` dex_number\n`;
|
sql += ` dex_number\n`;
|
||||||
sql += `) VALUES\n`;
|
sql += `) VALUES\n`;
|
||||||
sql += dexRows.join(',\n');
|
sql += dexRows.join(',\n');
|
||||||
sql += ';\n\n';
|
sql += ';\n\n';
|
||||||
} else {
|
} else {
|
||||||
sql += '-- No regional dex numbers for this region\n\n';
|
sql += '-- No regional dex numbers for this region\n\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add metadata
|
// Add metadata
|
||||||
sql += `-- Add metadata\n`;
|
sql += `-- Add metadata\n`;
|
||||||
sql += `INSERT INTO metadata (key, value) VALUES\n`;
|
sql += `INSERT INTO metadata (key, value) VALUES\n`;
|
||||||
sql += ` ('${region.toLowerCase()}_seeded', 'true'),\n`;
|
sql += ` ('${region.toLowerCase()}_seeded', 'true'),\n`;
|
||||||
sql += ` ('${region.toLowerCase()}_seed_date', NOW()::TEXT),\n`;
|
sql += ` ('${region.toLowerCase()}_seed_date', NOW()::TEXT),\n`;
|
||||||
sql += ` ('${region.toLowerCase()}_pokemon_count', '${pokemon.filter(p => !p.form).length}');\n`;
|
sql += ` ('${region.toLowerCase()}_pokemon_count', '${pokemon.filter((p) => !p.form).length}');\n`;
|
||||||
|
|
||||||
// 4. Write file
|
// 4. Write file
|
||||||
const timestamp = new Date().toISOString().replace(/[-:T.]/g, '').slice(0, 14);
|
const timestamp = new Date()
|
||||||
const filename = `${timestamp}_seed_${region.toLowerCase()}.sql`;
|
.toISOString()
|
||||||
const outputPath = path.join(__dirname, '..', 'supabase', 'migrations', filename);
|
.replace(/[-:T.]/g, '')
|
||||||
|
.slice(0, 14);
|
||||||
|
const filename = `${timestamp}_seed_${region.toLowerCase()}.sql`;
|
||||||
|
const outputPath = path.join(__dirname, '..', 'supabase', 'migrations', filename);
|
||||||
|
|
||||||
fs.writeFileSync(outputPath, sql);
|
fs.writeFileSync(outputPath, sql);
|
||||||
|
|
||||||
console.log(`✓ Generated ${filename}`);
|
console.log(`✓ Generated ${filename}`);
|
||||||
console.log(` - ${pokemon.length} Pokemon entries`);
|
console.log(` - ${pokemon.length} Pokemon entries`);
|
||||||
console.log(` - ${dexRows.length} regional dex numbers`);
|
console.log(` - ${dexRows.length} regional dex numbers`);
|
||||||
console.log(` - ${regionGames.length} games\n`);
|
console.log(` - ${regionGames.length} games\n`);
|
||||||
|
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run
|
// Run
|
||||||
const region = process.argv[2];
|
const region = process.argv[2];
|
||||||
if (!region) {
|
if (!region) {
|
||||||
console.error('Usage: node csv-to-migration.js <Region>');
|
console.error('Usage: node csv-to-migration.js <Region>');
|
||||||
console.error('Example: node csv-to-migration.js Kanto');
|
console.error('Example: node csv-to-migration.js Kanto');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
generateMigration(region);
|
generateMigration(region);
|
||||||
|
|||||||
@@ -56,7 +56,6 @@
|
|||||||
}
|
}
|
||||||
updateCatchRecord('toggle');
|
updateCatchRecord('toggle');
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -59,10 +59,8 @@
|
|||||||
// Validation
|
// Validation
|
||||||
$: hasAtLeastOneType =
|
$: hasAtLeastOneType =
|
||||||
pokedex.isLivingDex || pokedex.isShinyDex || pokedex.isOriginDex || pokedex.isFormDex;
|
pokedex.isLivingDex || pokedex.isShinyDex || pokedex.isOriginDex || pokedex.isFormDex;
|
||||||
$: hasDexScope =
|
$: hasDexScope = !pokedex.gameScope || (pokedex.dexScopes && pokedex.dexScopes.length > 0);
|
||||||
!pokedex.gameScope || (pokedex.dexScopes && pokedex.dexScopes.length > 0);
|
$: canSubmit = pokedex.name && pokedex.name.trim() !== '' && hasAtLeastOneType && hasDexScope;
|
||||||
$: canSubmit =
|
|
||||||
pokedex.name && pokedex.name.trim() !== '' && hasAtLeastOneType && hasDexScope;
|
|
||||||
|
|
||||||
$: if (pokedex.gameScope !== lastGameScope) {
|
$: if (pokedex.gameScope !== lastGameScope) {
|
||||||
const shouldResetDexes = mode === 'create' || hasSeenGameScope;
|
const shouldResetDexes = mode === 'create' || hasSeenGameScope;
|
||||||
@@ -162,16 +160,14 @@
|
|||||||
<option value={null}>All Games</option>
|
<option value={null}>All Games</option>
|
||||||
{#if loadingDexes}
|
{#if loadingDexes}
|
||||||
<option disabled>Loading games...</option>
|
<option disabled>Loading games...</option>
|
||||||
|
{:else if gameList.length > 0}
|
||||||
|
{#each gameList as game}
|
||||||
|
<option value={game.displayName}>{game.displayName}</option>
|
||||||
|
{/each}
|
||||||
{:else}
|
{:else}
|
||||||
{#if gameList.length > 0}
|
{#each gameOrder.length > 0 ? gameOrder : Object.keys(gameDexes) as game}
|
||||||
{#each gameList as game}
|
<option value={game}>{game}</option>
|
||||||
<option value={game.displayName}>{game.displayName}</option>
|
{/each}
|
||||||
{/each}
|
|
||||||
{:else}
|
|
||||||
{#each gameOrder.length > 0 ? gameOrder : Object.keys(gameDexes) as game}
|
|
||||||
<option value={game}>{game}</option>
|
|
||||||
{/each}
|
|
||||||
{/if}
|
|
||||||
{/if}
|
{/if}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@@ -181,7 +177,9 @@
|
|||||||
<fieldset class="w-full">
|
<fieldset class="w-full">
|
||||||
<legend class="label">
|
<legend class="label">
|
||||||
<span class="label-text">Dex Scope</span>
|
<span class="label-text">Dex Scope</span>
|
||||||
<span class="label-text-alt text-error">{!hasDexScope ? 'Select at least one dex' : ''}</span>
|
<span class="label-text-alt text-error"
|
||||||
|
>{!hasDexScope ? 'Select at least one dex' : ''}</span
|
||||||
|
>
|
||||||
</legend>
|
</legend>
|
||||||
{#if availableDexes.length === 0}
|
{#if availableDexes.length === 0}
|
||||||
<p class="text-sm text-error">No dexes found for this game.</p>
|
<p class="text-sm text-error">No dexes found for this game.</p>
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ import type { SupabaseClient } from '@supabase/supabase-js';
|
|||||||
class PokedexEntryRepository {
|
class PokedexEntryRepository {
|
||||||
constructor(private supabase: SupabaseClient) {}
|
constructor(private supabase: SupabaseClient) {}
|
||||||
|
|
||||||
private parseCatchInformation(
|
private parseCatchInformation(values: string[] | null): Array<string | CatchInformationItem> {
|
||||||
values: string[] | null
|
|
||||||
): Array<string | CatchInformationItem> {
|
|
||||||
if (!values) return [];
|
if (!values) return [];
|
||||||
return values.map((value) => {
|
return values.map((value) => {
|
||||||
const trimmed = value.trim();
|
const trimmed = value.trim();
|
||||||
|
|||||||
@@ -84,9 +84,7 @@ export async function setPokedexDexScopes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function listGameDexes(
|
export async function listGameDexes(supabase: SupabaseClient): Promise<{
|
||||||
supabase: SupabaseClient
|
|
||||||
): Promise<{
|
|
||||||
gameDexes: Record<string, GameDexRow[]>;
|
gameDexes: Record<string, GameDexRow[]>;
|
||||||
gameOrder: string[];
|
gameOrder: string[];
|
||||||
games: { displayName: string; releaseYear: number }[];
|
games: { displayName: string; releaseYear: number }[];
|
||||||
|
|||||||
@@ -24,62 +24,62 @@ type RegionalDexKey =
|
|||||||
|
|
||||||
const gameToRegionalDexMap: Record<string, RegionalDexKey> = {
|
const gameToRegionalDexMap: Record<string, RegionalDexKey> = {
|
||||||
// Kanto region
|
// Kanto region
|
||||||
'Red': 'kanto',
|
Red: 'kanto',
|
||||||
'Blue': 'kanto',
|
Blue: 'kanto',
|
||||||
'Yellow': 'kanto',
|
Yellow: 'kanto',
|
||||||
'FireRed': 'kanto',
|
FireRed: 'kanto',
|
||||||
'LeafGreen': 'kanto',
|
LeafGreen: 'kanto',
|
||||||
'LG: Pikachu': 'kanto',
|
'LG: Pikachu': 'kanto',
|
||||||
'LG: Eevee': 'kanto',
|
'LG: Eevee': 'kanto',
|
||||||
|
|
||||||
// Johto region
|
// Johto region
|
||||||
'Gold': 'johto',
|
Gold: 'johto',
|
||||||
'Silver': 'johto',
|
Silver: 'johto',
|
||||||
'Crystal': 'johto',
|
Crystal: 'johto',
|
||||||
'HeartGold': 'johto',
|
HeartGold: 'johto',
|
||||||
'SoulSilver': 'johto',
|
SoulSilver: 'johto',
|
||||||
|
|
||||||
// Hoenn region
|
// Hoenn region
|
||||||
'Ruby': 'hoenn',
|
Ruby: 'hoenn',
|
||||||
'Sapphire': 'hoenn',
|
Sapphire: 'hoenn',
|
||||||
'Emerald': 'hoenn',
|
Emerald: 'hoenn',
|
||||||
'OmegaRuby': 'hoenn',
|
OmegaRuby: 'hoenn',
|
||||||
'AlphaSapphire': 'hoenn',
|
AlphaSapphire: 'hoenn',
|
||||||
|
|
||||||
// Sinnoh region
|
// Sinnoh region
|
||||||
'Diamond': 'sinnoh',
|
Diamond: 'sinnoh',
|
||||||
'Pearl': 'sinnoh',
|
Pearl: 'sinnoh',
|
||||||
'Platinum': 'sinnoh',
|
Platinum: 'sinnoh',
|
||||||
'BrilliantDiamond': 'sinnoh',
|
BrilliantDiamond: 'sinnoh',
|
||||||
'ShiningPearl': 'sinnoh',
|
ShiningPearl: 'sinnoh',
|
||||||
|
|
||||||
// Unova region
|
// Unova region
|
||||||
'Black': 'unova_bw',
|
Black: 'unova_bw',
|
||||||
'White': 'unova_bw',
|
White: 'unova_bw',
|
||||||
'Black2': 'unova_b2w2',
|
Black2: 'unova_b2w2',
|
||||||
'White2': 'unova_b2w2',
|
White2: 'unova_b2w2',
|
||||||
|
|
||||||
// Kalos region - Note: All XY use all three sub-dexes
|
// Kalos region - Note: All XY use all three sub-dexes
|
||||||
// We default to Central for simplicity
|
// We default to Central for simplicity
|
||||||
'X': 'kalos_central',
|
X: 'kalos_central',
|
||||||
'Y': 'kalos_central',
|
Y: 'kalos_central',
|
||||||
|
|
||||||
// Alola region
|
// Alola region
|
||||||
'Sun': 'alola_sm',
|
Sun: 'alola_sm',
|
||||||
'Moon': 'alola_sm',
|
Moon: 'alola_sm',
|
||||||
'UltraSun': 'alola_usum',
|
UltraSun: 'alola_usum',
|
||||||
'UltraMoon': 'alola_usum',
|
UltraMoon: 'alola_usum',
|
||||||
|
|
||||||
// Galar region
|
// Galar region
|
||||||
'Sword': 'galar',
|
Sword: 'galar',
|
||||||
'Shield': 'galar',
|
Shield: 'galar',
|
||||||
|
|
||||||
// Hisui region
|
// Hisui region
|
||||||
'LegendsArceus': 'hisui',
|
LegendsArceus: 'hisui',
|
||||||
|
|
||||||
// Paldea region
|
// Paldea region
|
||||||
'Scarlet': 'paldea',
|
Scarlet: 'paldea',
|
||||||
'Violet': 'paldea'
|
Violet: 'paldea'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -119,22 +119,22 @@ export function getRegionalDexFieldName(gameName: string): string | undefined {
|
|||||||
|
|
||||||
// Map regional key to actual PokedexEntry field name (camelCase)
|
// Map regional key to actual PokedexEntry field name (camelCase)
|
||||||
const fieldMap: Record<string, string> = {
|
const fieldMap: Record<string, string> = {
|
||||||
'kanto': 'kantoDexNumber',
|
kanto: 'kantoDexNumber',
|
||||||
'johto': 'johtoDexNumber',
|
johto: 'johtoDexNumber',
|
||||||
'hoenn': 'hoennDexNumber',
|
hoenn: 'hoennDexNumber',
|
||||||
'sinnoh': 'sinnohDexNumber',
|
sinnoh: 'sinnohDexNumber',
|
||||||
'unova_bw': 'unovaBwDexNumber',
|
unova_bw: 'unovaBwDexNumber',
|
||||||
'unova_b2w2': 'unovaB2w2DexNumber',
|
unova_b2w2: 'unovaB2w2DexNumber',
|
||||||
'kalos_central': 'kalosCentralDexNumber',
|
kalos_central: 'kalosCentralDexNumber',
|
||||||
'kalos_coastal': 'kalosCoastalDexNumber',
|
kalos_coastal: 'kalosCoastalDexNumber',
|
||||||
'kalos_mountain': 'kalosMountainDexNumber',
|
kalos_mountain: 'kalosMountainDexNumber',
|
||||||
'alola_sm': 'alolaSmDexNumber',
|
alola_sm: 'alolaSmDexNumber',
|
||||||
'alola_usum': 'alolaUsumDexNumber',
|
alola_usum: 'alolaUsumDexNumber',
|
||||||
'galar': 'galarDexNumber',
|
galar: 'galarDexNumber',
|
||||||
'galar_isle_of_armor': 'galarIsleOfArmorDexNumber',
|
galar_isle_of_armor: 'galarIsleOfArmorDexNumber',
|
||||||
'galar_crown_tundra': 'galarCrownTundraDexNumber',
|
galar_crown_tundra: 'galarCrownTundraDexNumber',
|
||||||
'hisui': 'hisuiDexNumber',
|
hisui: 'hisuiDexNumber',
|
||||||
'paldea': 'paldeaDexNumber'
|
paldea: 'paldeaDexNumber'
|
||||||
};
|
};
|
||||||
|
|
||||||
return fieldMap[regionalKey];
|
return fieldMap[regionalKey];
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ export const PUT = async (event: RequestEvent) => {
|
|||||||
.eq('userId', userId)
|
.eq('userId', userId)
|
||||||
.is('pokedexId', null)
|
.is('pokedexId', null)
|
||||||
.eq('provider', provider)
|
.eq('provider', provider)
|
||||||
.select('id, provider, enabled, fileName, folderId, path, metadata, lastExportedAt, lastError')
|
.select(
|
||||||
|
'id, provider, enabled, fileName, folderId, path, metadata, lastExportedAt, lastError'
|
||||||
|
)
|
||||||
.maybeSingle();
|
.maybeSingle();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|||||||
@@ -31,9 +31,7 @@ export const GET = async (event: RequestEvent) => {
|
|||||||
|
|
||||||
const repo = new CatchRecordRepository(event.locals.supabase, userId, pokedexId);
|
const repo = new CatchRecordRepository(event.locals.supabase, userId, pokedexId);
|
||||||
const catchData = await repo.findAll();
|
const catchData = await repo.findAll();
|
||||||
const sortedData = catchData.sort(
|
const sortedData = catchData.sort((a, b) => Number(a.pokemonId) - Number(b.pokemonId));
|
||||||
(a, b) => Number(a.pokemonId) - Number(b.pokemonId)
|
|
||||||
);
|
|
||||||
return json(sortedData);
|
return json(sortedData);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
@@ -159,10 +157,7 @@ export const POST = async (event: RequestEvent) => {
|
|||||||
try {
|
try {
|
||||||
await exportPokedexIfConfigured(event.locals.supabase, userId, pokedexId);
|
await exportPokedexIfConfigured(event.locals.supabase, userId, pokedexId);
|
||||||
} catch (exportError) {
|
} catch (exportError) {
|
||||||
console.error(
|
console.error('Failed to export pokedex after per-record catch updates:', exportError);
|
||||||
'Failed to export pokedex after per-record catch updates:',
|
|
||||||
exportError
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return json(insertedRecords);
|
return json(insertedRecords);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,11 +204,7 @@
|
|||||||
</h3>
|
</h3>
|
||||||
<PokedexForm bind:pokedex={formData} {mode} onSubmit={handleSubmit} onCancel={closeModal} />
|
<PokedexForm bind:pokedex={formData} {mode} onSubmit={handleSubmit} onCancel={closeModal} />
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button type="button" class="modal-backdrop" aria-label="Close modal" on:click={closeModal}
|
||||||
type="button"
|
|
||||||
class="modal-backdrop"
|
|
||||||
aria-label="Close modal"
|
|
||||||
on:click={closeModal}
|
|
||||||
></button>
|
></button>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
Reference in New Issue
Block a user