feat: upgrade to SvelteKit 3 and adapter-bun
Some checks failed
Test and deploy staging / staging (push) Failing after 43s
Some checks failed
Test and deploy staging / staging (push) Failing after 43s
Run the sveltekit-3 migration and finish its manual tasks:
- Move kit config into the sveltekit() Vite plugin; drop svelte.config.js
- Replace $lib with #lib subpath imports
- Declare env vars in src/env.ts and import them from $app/env/{private,public}
- Consolidate param matchers into src/params.ts
- Use error(status, message), Response.json, refreshAll and goto reset/shallow
- Fall back to a full page load when goto rejects a login return path
Switch from adapter-node to adapter-bun: the build script runs Vite under
Bun (the adapter requires it) and the image starts with `bun ./build`.
Runtime env names (PORT, BODY_SIZE_LIMIT, ADDRESS_HEADER, ...) are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { asc, eq } from 'drizzle-orm';
|
||||
import { db } from '$lib/server/db';
|
||||
import { db } from '#lib/server/db/index.js';
|
||||
import {
|
||||
trackerGames,
|
||||
trackerItems,
|
||||
@@ -9,12 +9,12 @@ import {
|
||||
trackerChallenges,
|
||||
trackerChallengeProgress,
|
||||
osuEntries
|
||||
} from '$lib/server/db/schema';
|
||||
import { loadPokemonProgress } from '$lib/server/tracker-progress';
|
||||
import { challengeProgress, combinedProgress, sumProgress } from '$lib/game-tracker/progress';
|
||||
import { gameRanksProgress, hasReachedMaxLevel } from '$lib/game-tracker/rank-progress';
|
||||
import { summarizeGame } from '$lib/game-tracker/mastery';
|
||||
import { chronologicalPokemon, pokemonRelease } from '$lib/game-tracker/game-art';
|
||||
} from '#lib/server/db/schema/index.js';
|
||||
import { loadPokemonProgress } from '#lib/server/tracker-progress.js';
|
||||
import { challengeProgress, combinedProgress, sumProgress } from '#lib/game-tracker/progress.js';
|
||||
import { gameRanksProgress, hasReachedMaxLevel } from '#lib/game-tracker/rank-progress.js';
|
||||
import { summarizeGame } from '#lib/game-tracker/mastery.js';
|
||||
import { chronologicalPokemon, pokemonRelease } from '#lib/game-tracker/game-art.js';
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
async function pokemonSummary(userId: string | undefined) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import GameLogo from '$lib/game-tracker/GameLogo.svelte';
|
||||
import ProgressMeter from '$lib/game-tracker/ProgressMeter.svelte';
|
||||
import GameLogo from '#lib/game-tracker/GameLogo.svelte';
|
||||
import ProgressMeter from '#lib/game-tracker/ProgressMeter.svelte';
|
||||
import type { PageProps } from './$types';
|
||||
let { data }: PageProps = $props();
|
||||
</script>
|
||||
@@ -14,10 +14,10 @@
|
||||
</div>
|
||||
{#if !data.user}<a
|
||||
class="text-sm text-muted-foreground underline"
|
||||
href={resolve('/login?returnTo=/projects/game-tracker')}>Sign in to save progress</a
|
||||
href={resolve('login?returnTo=/projects/game-tracker')}>Sign in to save progress</a
|
||||
>{:else}<a
|
||||
class="text-xs text-muted-foreground underline"
|
||||
href={resolve('/projects/game-tracker/credits')}>Artwork credits</a
|
||||
href={resolve('projects/game-tracker/credits')}>Artwork credits</a
|
||||
>{/if}
|
||||
</div>
|
||||
<div
|
||||
@@ -55,7 +55,7 @@
|
||||
aria-labelledby="pokemon-series"
|
||||
>
|
||||
<a
|
||||
href={resolve('/projects/game-tracker/pokemon')}
|
||||
href={resolve('projects/game-tracker/pokemon')}
|
||||
class="series-heading mb-3 flex items-center gap-3 rounded-xl bg-amber-500/10 p-3 transition-colors hover:bg-amber-500/20"
|
||||
>
|
||||
<GameLogo slug="pokemon" name="Pokémon" class="h-12 w-24" />
|
||||
@@ -87,7 +87,7 @@
|
||||
{#each data.pokemon.games as game (game.id)}
|
||||
<a
|
||||
class="game-row flex min-h-0 min-w-0 items-center gap-2 rounded-lg border px-2 py-1.5 transition-colors hover:border-amber-500/50 hover:bg-amber-500/5"
|
||||
href={resolve(`/projects/game-tracker/pokemon?game=${game.slug ?? game.id}`)}
|
||||
href={resolve(`projects/game-tracker/pokemon?game=${game.slug ?? game.id}`)}
|
||||
title={`${game.name} · ${game.releaseYear}`}
|
||||
>
|
||||
<GameLogo
|
||||
@@ -112,7 +112,7 @@
|
||||
</div>
|
||||
{:else}<a
|
||||
class="rounded-xl border border-dashed p-5 text-sm text-muted-foreground hover:text-foreground"
|
||||
href={resolve('/projects/game-tracker/pokemon')}
|
||||
href={resolve('projects/game-tracker/pokemon')}
|
||||
>Choose your games in “set rules” to build your collection here.</a
|
||||
>{/if}
|
||||
</section>
|
||||
@@ -135,7 +135,7 @@
|
||||
<div class="cod-rows grid min-h-0 gap-1.5">
|
||||
{#each data.callOfDuty as game (game.slug)}
|
||||
<a
|
||||
href={resolve(`/projects/game-tracker/call-of-duty/${game.slug}`)}
|
||||
href={resolve(`projects/game-tracker/call-of-duty/${game.slug}`)}
|
||||
class="game-row flex min-h-0 items-center gap-3 rounded-lg border p-2 transition-colors hover:border-primary/40 hover:bg-muted/50"
|
||||
>
|
||||
<GameLogo slug={`cod/${game.slug}`} name={game.name} class="h-11 w-24" />
|
||||
@@ -169,7 +169,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
href={resolve('/projects/game-tracker/osu')}
|
||||
href={resolve('projects/game-tracker/osu')}
|
||||
class="rounded-xl border p-4 transition-colors hover:border-pink-500/50 hover:bg-pink-500/5"
|
||||
><div class="flex items-center gap-3">
|
||||
<GameLogo slug="osu" name="osu!" class="h-14 w-14" />
|
||||
|
||||
@@ -3,7 +3,7 @@ import achievementArt from '../../../../../../data/cod-achievement-art.json';
|
||||
const achievementImages: Record<string, string> = achievementArt;
|
||||
import { and, asc, eq, sql } from 'drizzle-orm';
|
||||
import type { AnyPgColumn } from 'drizzle-orm/pg-core';
|
||||
import { db } from '$lib/server/db';
|
||||
import { db } from '#lib/server/db/index.js';
|
||||
import {
|
||||
trackerGames,
|
||||
trackerItems,
|
||||
@@ -12,11 +12,15 @@ import {
|
||||
trackerWeaponRanks,
|
||||
trackerChallenges,
|
||||
trackerChallengeProgress
|
||||
} from '$lib/server/db/schema';
|
||||
import { boundedInteger } from '$lib/game-tracker/journal';
|
||||
import { appliesTo } from '$lib/game-tracker/mastery';
|
||||
import { playerRankLimits, weaponRankLimits, type RankLimits } from '$lib/game-tracker/rank-limits';
|
||||
import { maxUncappedLevel, stepRank } from '$lib/game-tracker/rank-progress';
|
||||
} from '#lib/server/db/schema/index.js';
|
||||
import { boundedInteger } from '#lib/game-tracker/journal.js';
|
||||
import { appliesTo } from '#lib/game-tracker/mastery.js';
|
||||
import {
|
||||
playerRankLimits,
|
||||
weaponRankLimits,
|
||||
type RankLimits
|
||||
} from '#lib/game-tracker/rank-limits.js';
|
||||
import { maxUncappedLevel, stepRank } from '#lib/game-tracker/rank-progress.js';
|
||||
import type { Actions, PageServerLoad } from './$types';
|
||||
|
||||
async function findGame(slug: string) {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script lang="ts">
|
||||
import RankStepper from '$lib/game-tracker/RankStepper.svelte';
|
||||
import WeaponArtwork from '$lib/game-tracker/WeaponArtwork.svelte';
|
||||
import * as Dialog from '$lib/components/ui/dialog/index.js';
|
||||
import { Button } from '$lib/components/ui/button/index.js';
|
||||
import { Input } from '$lib/components/ui/input/index.js';
|
||||
import { Checkbox } from '$lib/components/ui/checkbox/index.js';
|
||||
import { NativeSelect } from '$lib/components/ui/native-select/index.js';
|
||||
import RankStepper from '#lib/game-tracker/RankStepper.svelte';
|
||||
import WeaponArtwork from '#lib/game-tracker/WeaponArtwork.svelte';
|
||||
import * as Dialog from '#lib/components/ui/dialog/index.js';
|
||||
import { Button } from '#lib/components/ui/button/index.js';
|
||||
import { Input } from '#lib/components/ui/input/index.js';
|
||||
import { Checkbox } from '#lib/components/ui/checkbox/index.js';
|
||||
import { NativeSelect } from '#lib/components/ui/native-select/index.js';
|
||||
import Crosshair from 'lucide-svelte/icons/crosshair';
|
||||
import Trophy from 'lucide-svelte/icons/trophy';
|
||||
import Target from 'lucide-svelte/icons/target';
|
||||
@@ -13,19 +13,19 @@
|
||||
import ChevronDown from 'lucide-svelte/icons/chevron-down';
|
||||
import EyeOff from 'lucide-svelte/icons/eye-off';
|
||||
import ChartNoAxesCombined from 'lucide-svelte/icons/chart-no-axes-combined';
|
||||
import PlayerRankBadge from '$lib/game-tracker/PlayerRankBadge.svelte';
|
||||
import PlayerRankBadge from '#lib/game-tracker/PlayerRankBadge.svelte';
|
||||
import {
|
||||
gameRanksProgress,
|
||||
rankProgress as countRank,
|
||||
weaponLevelsProgress,
|
||||
weaponFinished,
|
||||
hasReachedMaxLevel
|
||||
} from '$lib/game-tracker/rank-progress';
|
||||
import { fraction } from '$lib/game-tracker/progress';
|
||||
import GameLogo from '$lib/game-tracker/GameLogo.svelte';
|
||||
import ProgressMeter from '$lib/game-tracker/ProgressMeter.svelte';
|
||||
import { combinedProgress, sumProgress, challengeProgress } from '$lib/game-tracker/progress';
|
||||
import { playerRankLimits, weaponRankLimits } from '$lib/game-tracker/rank-limits';
|
||||
} from '#lib/game-tracker/rank-progress.js';
|
||||
import { fraction } from '#lib/game-tracker/progress.js';
|
||||
import GameLogo from '#lib/game-tracker/GameLogo.svelte';
|
||||
import ProgressMeter from '#lib/game-tracker/ProgressMeter.svelte';
|
||||
import { combinedProgress, sumProgress, challengeProgress } from '#lib/game-tracker/progress.js';
|
||||
import { playerRankLimits, weaponRankLimits } from '#lib/game-tracker/rank-limits.js';
|
||||
let rankOpen = $state(false);
|
||||
let rankWeapon = $state<number | null>(null);
|
||||
let challengeSearch = $state('');
|
||||
@@ -40,8 +40,8 @@
|
||||
import { resolve } from '$app/paths';
|
||||
import { deserialize, enhance } from '$app/forms';
|
||||
import { SvelteSet, SvelteMap } from 'svelte/reactivity';
|
||||
import * as Tabs from '$lib/components/ui/tabs/index.js';
|
||||
import { appliesTo, summarizeGame } from '$lib/game-tracker/mastery';
|
||||
import * as Tabs from '#lib/components/ui/tabs/index.js';
|
||||
import { appliesTo, summarizeGame } from '#lib/game-tracker/mastery.js';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
let { data, form }: PageProps = $props();
|
||||
@@ -239,7 +239,7 @@
|
||||
|
||||
<div class="cod-companion">
|
||||
<div class="companion-header">
|
||||
<a href={resolve('/projects/game-tracker')} class="back-link">← game tracker</a>
|
||||
<a href={resolve('projects/game-tracker')} class="back-link">← game tracker</a>
|
||||
<GameLogo
|
||||
slug={`cod/${data.game.slug}`}
|
||||
name={data.game.shortName}
|
||||
@@ -268,7 +268,7 @@
|
||||
onupdate={(r) => (playerRank = { level: r.level, prestige: r.prestige })}
|
||||
/>{:else}<Button
|
||||
variant="outline"
|
||||
href={resolve(`/login?returnTo=/projects/game-tracker/call-of-duty/${data.game.slug}`)}
|
||||
href={resolve(`login?returnTo=/projects/game-tracker/call-of-duty/${data.game.slug}`)}
|
||||
>Sign in to save</Button
|
||||
>{/if}
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<!-- Download manifest links point to reviewed external image sources. -->
|
||||
<!-- eslint-disable svelte/no-navigation-without-resolve -->
|
||||
<div class="mx-auto max-w-4xl px-4 py-10 sm:px-6">
|
||||
<a href={resolve('/projects/game-tracker')} class="text-sm text-muted-foreground hover:underline"
|
||||
<a href={resolve('projects/game-tracker')} class="text-sm text-muted-foreground hover:underline"
|
||||
>← Game tracker</a
|
||||
>
|
||||
<h1 class="mt-6 text-3xl font-semibold">Artwork credits</h1>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { and, desc, eq } from 'drizzle-orm';
|
||||
import { fail } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/db';
|
||||
import { osuEntries } from '$lib/server/db/schema';
|
||||
import { allowedOsuUrl, boundedInteger, validDate } from '$lib/game-tracker/journal';
|
||||
import { db } from '#lib/server/db/index.js';
|
||||
import { osuEntries } from '#lib/server/db/schema/index.js';
|
||||
import { allowedOsuUrl, boundedInteger, validDate } from '#lib/game-tracker/journal.js';
|
||||
import type { Actions, PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async ({ locals }) => ({
|
||||
|
||||
@@ -6,18 +6,18 @@
|
||||
});
|
||||
import { resolve } from '$app/paths';
|
||||
import { enhance } from '$app/forms';
|
||||
import * as Dialog from '$lib/components/ui/dialog/index.js';
|
||||
import * as AlertDialog from '$lib/components/ui/alert-dialog/index.js';
|
||||
import * as Tabs from '$lib/components/ui/tabs/index.js';
|
||||
import * as Table from '$lib/components/ui/table/index.js';
|
||||
import { Button } from '$lib/components/ui/button/index.js';
|
||||
import { Input } from '$lib/components/ui/input/index.js';
|
||||
import { Textarea } from '$lib/components/ui/textarea/index.js';
|
||||
import { NativeSelect } from '$lib/components/ui/native-select/index.js';
|
||||
import { Checkbox } from '$lib/components/ui/checkbox/index.js';
|
||||
import { Badge } from '$lib/components/ui/badge/index.js';
|
||||
import GameLogo from '$lib/game-tracker/GameLogo.svelte';
|
||||
import ProgressMeter from '$lib/game-tracker/ProgressMeter.svelte';
|
||||
import * as Dialog from '#lib/components/ui/dialog/index.js';
|
||||
import * as AlertDialog from '#lib/components/ui/alert-dialog/index.js';
|
||||
import * as Tabs from '#lib/components/ui/tabs/index.js';
|
||||
import * as Table from '#lib/components/ui/table/index.js';
|
||||
import { Button } from '#lib/components/ui/button/index.js';
|
||||
import { Input } from '#lib/components/ui/input/index.js';
|
||||
import { Textarea } from '#lib/components/ui/textarea/index.js';
|
||||
import { NativeSelect } from '#lib/components/ui/native-select/index.js';
|
||||
import { Checkbox } from '#lib/components/ui/checkbox/index.js';
|
||||
import { Badge } from '#lib/components/ui/badge/index.js';
|
||||
import GameLogo from '#lib/game-tracker/GameLogo.svelte';
|
||||
import ProgressMeter from '#lib/game-tracker/ProgressMeter.svelte';
|
||||
import type { PageProps } from './$types';
|
||||
let { data, form }: PageProps = $props();
|
||||
type Entry = (typeof data.entries)[number];
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
<div class="mx-auto max-w-6xl px-3 py-4 sm:px-5">
|
||||
<a
|
||||
href={resolve('/projects/game-tracker')}
|
||||
href={resolve('projects/game-tracker')}
|
||||
class="text-sm text-muted-foreground hover:text-foreground">← game tracker</a
|
||||
>
|
||||
<div class="mt-3 flex flex-wrap items-center gap-3">
|
||||
@@ -95,7 +95,7 @@
|
||||
>
|
||||
</div>
|
||||
{#if !data.user}<p class="mt-6">
|
||||
<a class="underline" href={resolve('/login?returnTo=/projects/game-tracker/osu')}>Sign in</a> to
|
||||
<a class="underline" href={resolve('login?returnTo=/projects/game-tracker/osu')}>Sign in</a> to
|
||||
start your training journal.
|
||||
</p>{/if}
|
||||
{#if form?.message && !open && !deleteOpen}<p class="mt-4 text-destructive" role="alert">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { pokemonJournalActions, catchesFor } from '$lib/server/pokemon-journal';
|
||||
import { loadPokemonProgress } from '$lib/server/tracker-progress';
|
||||
import { pokemonJournalActions, catchesFor } from '#lib/server/pokemon-journal.js';
|
||||
import { loadPokemonProgress } from '#lib/server/tracker-progress.js';
|
||||
import {
|
||||
pokemonCatches,
|
||||
pokemonDexNumbers,
|
||||
@@ -9,9 +9,9 @@ import {
|
||||
pokemonLocations,
|
||||
pokemonEncounters,
|
||||
pokemonSeen
|
||||
} from '$lib/server/db/schema';
|
||||
} from '#lib/server/db/schema/index.js';
|
||||
import { sql } from 'drizzle-orm';
|
||||
import { db } from '$lib/server/db';
|
||||
import { db } from '#lib/server/db/index.js';
|
||||
import {
|
||||
games,
|
||||
pokemon as pokemonTable,
|
||||
@@ -19,11 +19,15 @@ import {
|
||||
userEntries,
|
||||
userGames,
|
||||
catchEmAllSettings
|
||||
} from '$lib/server/db/schema';
|
||||
} from '#lib/server/db/schema/index.js';
|
||||
import { and, asc, eq, inArray } from 'drizzle-orm';
|
||||
import type { Actions, PageServerLoad } from './$types';
|
||||
import { availabilityValues, obtainableAvailability, type Availability } from '$lib/availability';
|
||||
import { requireAdmin } from '$lib/server/authorization';
|
||||
import {
|
||||
availabilityValues,
|
||||
obtainableAvailability,
|
||||
type Availability
|
||||
} from '#lib/availability.js';
|
||||
import { requireAdmin } from '#lib/server/authorization.js';
|
||||
import { fail } from '@sveltejs/kit';
|
||||
export type WireEntry = [id: number, gameId: number, availability: number, note?: string];
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
import { goto } from '$app/navigation';
|
||||
import { enhance } from '$app/forms';
|
||||
import { SvelteSet } from 'svelte/reactivity';
|
||||
import * as Dialog from '$lib/components/ui/dialog/index.js';
|
||||
import { Button } from '$lib/components/ui/button/index.js';
|
||||
import { Checkbox } from '$lib/components/ui/checkbox/index.js';
|
||||
import { chronologicalPokemon } from '$lib/game-tracker/game-art';
|
||||
import GameLogo from '$lib/game-tracker/GameLogo.svelte';
|
||||
import PokemonJournal from '$lib/game-tracker/PokemonJournal.svelte';
|
||||
import * as Dialog from '#lib/components/ui/dialog/index.js';
|
||||
import { Button } from '#lib/components/ui/button/index.js';
|
||||
import { Checkbox } from '#lib/components/ui/checkbox/index.js';
|
||||
import { chronologicalPokemon } from '#lib/game-tracker/game-art.js';
|
||||
import GameLogo from '#lib/game-tracker/GameLogo.svelte';
|
||||
import PokemonJournal from '#lib/game-tracker/PokemonJournal.svelte';
|
||||
import type { PageProps } from './$types';
|
||||
let { data, form }: PageProps = $props();
|
||||
let rulesOpen = $state(false);
|
||||
@@ -49,7 +49,7 @@
|
||||
/>{/if}
|
||||
<div>
|
||||
<a
|
||||
href={resolve('/projects/game-tracker')}
|
||||
href={resolve('projects/game-tracker')}
|
||||
class="text-xs text-muted-foreground hover:underline">← Game tracker</a
|
||||
>
|
||||
<h1 class="text-xl font-semibold">
|
||||
@@ -79,9 +79,8 @@
|
||||
title={game.name}
|
||||
class={`game-cover-button h-12 min-w-0 rounded-md border p-1 ${data.activeGame?.id === game.id ? 'border-amber-500 bg-amber-500/15 ring-1 ring-amber-500' : 'border-transparent opacity-65 hover:opacity-100'}`}
|
||||
onclick={() =>
|
||||
goto(resolve(`/projects/game-tracker/pokemon?game=${game.slug ?? game.id}`), {
|
||||
noScroll: true,
|
||||
keepFocus: true
|
||||
goto(resolve(`projects/game-tracker/pokemon?game=${game.slug ?? game.id}`), {
|
||||
reset: false
|
||||
})}
|
||||
>
|
||||
<GameLogo slug={`pokemon/${game.slug}`} name={game.name} class="h-10 w-full" />
|
||||
@@ -99,7 +98,7 @@
|
||||
</div>
|
||||
|
||||
{#if !data.user}<p class="mt-4 text-sm">
|
||||
<a href={resolve('/login?returnTo=/projects/game-tracker/pokemon')} class="underline"
|
||||
<a href={resolve('login?returnTo=/projects/game-tracker/pokemon')} class="underline"
|
||||
>Sign in</a
|
||||
> to save catches, teams and adventures.
|
||||
</p>{/if}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { error, json } from '@sveltejs/kit';
|
||||
import { pokemonDetail } from '$lib/server/pokemon-detail';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { pokemonDetail } from '#lib/server/pokemon-detail.js';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
export const GET: RequestHandler = async ({ params, url }) => {
|
||||
@@ -7,5 +7,5 @@ export const GET: RequestHandler = async ({ params, url }) => {
|
||||
const gameId = Number.isSafeInteger(game) && game > 0 && game <= 2147483647 ? game : null;
|
||||
const number = Number(params.number);
|
||||
if (number > 100000) error(404, 'Unknown Pokémon');
|
||||
return json(await pokemonDetail(number, gameId));
|
||||
return Response.json(await pokemonDetail(number, gameId));
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { json, error } from '@sveltejs/kit';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { and, asc, eq } from 'drizzle-orm';
|
||||
import { db } from '$lib/server/db';
|
||||
import { pokemon, pokemonEncounters } from '$lib/server/db/schema';
|
||||
import { db } from '#lib/server/db/index.js';
|
||||
import { pokemon, pokemonEncounters } from '#lib/server/db/schema/index.js';
|
||||
|
||||
export async function GET({ url }) {
|
||||
const gameId = Number(url.searchParams.get('game'));
|
||||
@@ -28,5 +28,5 @@ export async function GET({ url }) {
|
||||
.innerJoin(pokemon, eq(pokemon.id, pokemonEncounters.pokemonId))
|
||||
.where(and(eq(pokemonEncounters.gameId, gameId), eq(pokemonEncounters.locationId, locationId)))
|
||||
.orderBy(asc(pokemon.number), asc(pokemonEncounters.method), asc(pokemonEncounters.minLevel));
|
||||
return json(rows, { headers: { 'Cache-Control': 'public, max-age=3600' } });
|
||||
return Response.json(rows, { headers: { 'Cache-Control': 'public, max-age=3600' } });
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { asc, countDistinct, eq, sql } from 'drizzle-orm';
|
||||
import { db } from '$lib/server/db';
|
||||
import { pokemonEncounters, pokemonLocations } from '$lib/server/db/schema';
|
||||
import { db } from '#lib/server/db/index.js';
|
||||
import { pokemonEncounters, pokemonLocations } from '#lib/server/db/schema/index.js';
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async () => ({
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { NativeSelect } from '$lib/components/ui/native-select/index.js';
|
||||
import { NativeSelect } from '#lib/components/ui/native-select/index.js';
|
||||
import { resolve } from '$app/paths';
|
||||
import { Input } from '$lib/components/ui/input/index.js';
|
||||
import * as Card from '$lib/components/ui/card/index.js';
|
||||
import { Input } from '#lib/components/ui/input/index.js';
|
||||
import * as Card from '#lib/components/ui/card/index.js';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
let { data }: PageProps = $props();
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
<div class="mx-auto max-w-6xl px-4 py-10 sm:px-6 sm:py-14">
|
||||
<a
|
||||
href={resolve('/projects/game-tracker/pokemon')}
|
||||
href={resolve('projects/game-tracker/pokemon')}
|
||||
class="text-[var(--site-muted)] hover:text-[var(--site-text)]">← catchemall</a
|
||||
>
|
||||
<h1 class="mt-3 text-4xl font-semibold tracking-tight sm:text-5xl">locations</h1>
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { error, fail } from '@sveltejs/kit';
|
||||
import { asc, eq } from 'drizzle-orm';
|
||||
import { db } from '$lib/server/db';
|
||||
import { games, pokemon, pokemonEncounters, pokemonLocations } from '$lib/server/db/schema';
|
||||
import { requireAdmin } from '$lib/server/authorization';
|
||||
import { deleteObject, locationImageUrl, uploadImage } from '$lib/server/r2';
|
||||
import { db } from '#lib/server/db/index.js';
|
||||
import {
|
||||
games,
|
||||
pokemon,
|
||||
pokemonEncounters,
|
||||
pokemonLocations
|
||||
} from '#lib/server/db/schema/index.js';
|
||||
import { requireAdmin } from '#lib/server/authorization.js';
|
||||
import { deleteObject, locationImageUrl, uploadImage } from '#lib/server/r2.js';
|
||||
import type { Actions, PageServerLoad } from './$types';
|
||||
|
||||
const PICTURE_TYPES = ['image/jpeg', 'image/png', 'image/webp'];
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { pokemonImage } from '$lib/game-tracker/game-art';
|
||||
import { NativeSelect } from '$lib/components/ui/native-select/index.js';
|
||||
import { pokemonImage } from '#lib/game-tracker/game-art.js';
|
||||
import { NativeSelect } from '#lib/components/ui/native-select/index.js';
|
||||
import { resolve } from '$app/paths';
|
||||
import { enhance } from '$app/forms';
|
||||
import { page } from '$app/state';
|
||||
import { Button } from '$lib/components/ui/button/index.js';
|
||||
import { Input } from '$lib/components/ui/input/index.js';
|
||||
import { Textarea } from '$lib/components/ui/textarea/index.js';
|
||||
import { Button } from '#lib/components/ui/button/index.js';
|
||||
import { Input } from '#lib/components/ui/input/index.js';
|
||||
import { Textarea } from '#lib/components/ui/textarea/index.js';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
let { data, form }: PageProps = $props();
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<div class="mx-auto max-w-6xl px-4 py-10 sm:px-6 sm:py-14">
|
||||
<a
|
||||
href={resolve('/projects/game-tracker/pokemon/locations')}
|
||||
href={resolve('projects/game-tracker/pokemon/locations')}
|
||||
class="text-[var(--site-muted)] hover:text-[var(--site-text)]">← locations</a
|
||||
>
|
||||
<h1 class="mt-3 text-4xl font-semibold tracking-tight sm:text-5xl">{data.location.name}</h1>
|
||||
|
||||
Reference in New Issue
Block a user