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:
Josh Creek
2026-09-13 17:38:35 +01:00
parent 676490b800
commit 08c5e3271c
12 changed files with 219 additions and 211 deletions
+8
View File
@@ -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
+2 -2
View File
@@ -1,6 +1,6 @@
export default { export default {
plugins: { plugins: {
tailwindcss: {}, tailwindcss: {},
autoprefixer: {}, autoprefixer: {}
},
} }
};
+2 -2
View File
@@ -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';
+31 -17
View File
@@ -18,10 +18,10 @@ const __dirname = path.dirname(__filename);
*/ */
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) => {
@@ -64,14 +64,27 @@ function generateMigration(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,
Unova: 5,
Kalos: 6,
Alola: 7,
Galar: 8,
Hisui: 8,
Paldea: 9
}; };
const gen = regionToGen[region] || 1; 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(
__dirname,
'..',
'data',
'pokemon',
`gen${gen}-${region.toLowerCase()}.csv`
);
const gamesPath = path.join(__dirname, '..', 'data', 'pokemon', 'games.csv'); const gamesPath = path.join(__dirname, '..', 'data', 'pokemon', 'games.csv');
if (!fs.existsSync(pokemonPath)) { if (!fs.existsSync(pokemonPath)) {
@@ -83,7 +96,7 @@ function generateMigration(region) {
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`);
@@ -97,7 +110,7 @@ function generateMigration(region) {
// 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)
@@ -111,13 +124,13 @@ function generateMigration(region) {
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})`;
}); });
@@ -129,11 +142,9 @@ function generateMigration(region) {
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})`;
}); });
@@ -155,10 +166,13 @@ function generateMigration(region) {
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()
.toISOString()
.replace(/[-:T.]/g, '')
.slice(0, 14);
const filename = `${timestamp}_seed_${region.toLowerCase()}.sql`; const filename = `${timestamp}_seed_${region.toLowerCase()}.sql`;
const outputPath = path.join(__dirname, '..', 'supabase', 'migrations', filename); const outputPath = path.join(__dirname, '..', 'supabase', 'migrations', filename);
@@ -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,8 +160,7 @@
<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} {:else if gameList.length > 0}
{#if gameList.length > 0}
{#each gameList as game} {#each gameList as game}
<option value={game.displayName}>{game.displayName}</option> <option value={game.displayName}>{game.displayName}</option>
{/each} {/each}
@@ -172,7 +169,6 @@
<option value={game}>{game}</option> <option value={game}>{game}</option>
{/each} {/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();
+1 -3
View File
@@ -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 }[];
+51 -51
View File
@@ -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);
} }
+1 -5
View File
@@ -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}