Files
personal-website/src/lib/game-tracker/journal.ts
Stan Runge c2ba8febb4
Some checks failed
Test and deploy staging / staging (push) Failing after 5m29s
Expand website and game trackers
2026-09-25 22:43:04 +00:00

68 lines
1.9 KiB
TypeScript

export const stages = [
{
value: 'story',
label: 'The adventure',
description: 'Catch as you go, earn badges and become Champion.'
},
{
value: 'postgame',
label: 'Beyond the credits',
description: 'Explore the postgame and finish what you can in this game.'
},
{
value: 'collection',
label: 'Complete the collection',
description: 'Trades, transfers and event Pokémon.'
}
] as const;
export type Stage = (typeof stages)[number]['value'];
export const obtainedMethods = [
'caught',
'starter',
'gift',
'evolved',
'bred',
'trade',
'transfer',
'event'
] as const;
export const isStage = (value: string): value is Stage => stages.some((s) => s.value === value);
export function boundedInteger(value: FormDataEntryValue | null, min: number, max: number) {
if (typeof value !== 'string' || !/^\d+$/.test(value)) return null;
const number = Number(value);
return Number.isSafeInteger(number) && number >= min && number <= max ? number : null;
}
export function validDate(value: string) {
return (
/^\d{4}-\d{2}-\d{2}$/.test(value) &&
Number(value.slice(0, 4)) > 0 &&
!Number.isNaN(Date.parse(value)) &&
new Date(value).toISOString().slice(0, 10) === value
);
}
export function firstCatches<T extends { id: number; pokemonId: number }>(catches: T[]) {
const first = new Map<number, T>();
for (const caught of [...catches].sort((a, b) => a.id - b.id))
if (!first.has(caught.pokemonId)) first.set(caught.pokemonId, caught);
return first;
}
export function allowedOsuUrl(value: string, kind: 'beatmap' | 'score') {
if (!value) return true;
try {
const url = new URL(value);
return (
url.protocol === 'https:' &&
url.hostname === 'osu.ppy.sh' &&
!url.username &&
!url.password &&
!url.port &&
(kind === 'beatmap'
? /^\/(beatmaps|b|beatmapsets)\/\d+\/?$/.test(url.pathname)
: /^\/scores\/(?:osu\/|taiko\/|fruits\/|mania\/)?\d+\/?$/.test(url.pathname))
);
} catch {
return false;
}
}