Create parseJson() to debug Infos more easily

This commit is contained in:
Taevas 2025-04-16 15:58:02 +02:00
parent 98f4e9057d
commit f8987cdcdb
Signed by: Taevas
SSH key fingerprint: SHA256:Y5Hv18xwPvUKSlgkx1sPnRO3L2mc03ehC7BzrnZVEyY
12 changed files with 37 additions and 33 deletions

View file

@ -27,6 +27,14 @@ const info_routes: Record<string, Handler[]> = {
export type Handler = (req: URLSearchParams) => Promise<Response>;
export async function parseJson(response: Response) {
try {
return await response.json();
} catch {
throw new Error(`Failed to parse JSON for\n${response.url}\n(OK: ${response.ok}) ${response.status} ${response.statusText}`);
}
}
export async function api(pathname: string, parameters: URLSearchParams) {
if (pathname === "/api/infos/token") {
return await token(parameters);

View file

@ -1,11 +1,11 @@
import { type KitsudevInfo } from "#Infos/Coding/KitsuDev.tsx";
import type { Handler } from "../..";
import { parseJson, type Handler } from "../..";
const username = "Taevas";
export const kitsudev: Handler = async () => {
/** https://kitsunes.dev/api/swagger#/user/userListActivityFeeds */
const kitsudev = await (await fetch(`https://kitsunes.dev/api/v1/users/${username}/activities/feeds?limit=1`)).json() as [{
const kitsudev = await parseJson(await fetch(`https://kitsunes.dev/api/v1/users/${username}/activities/feeds?limit=1`)) as [{
repo: {
full_name: string
html_url: string

View file

@ -1,11 +1,11 @@
import { type KitsuclubInfo } from "#Infos/Fediverse/KitsuClub.tsx";
import type { Handler } from "../..";
import { parseJson, type Handler } from "../..";
const user_id = "a2hgd7delf";
export const kitsuclub: Handler = async () => {
/** https://kitsunes.club/api-doc#tag/users/POST/users/notes */
const kitsuclub = await (await fetch("https://kitsunes.club/api/users/notes", {
const kitsuclub = await parseJson(await fetch("https://kitsunes.club/api/users/notes", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env["API_KITSUCLUB"]}`,
@ -24,7 +24,7 @@ export const kitsuclub: Handler = async () => {
"withFiles": false,
"allowPartial": false,
})
})).json() as {
})) as {
id: string
user: {
name: string

View file

@ -1,11 +1,11 @@
import type { AlakajamInfo } from "#Infos/GameDev/Alakajam.tsx";
import type { Handler } from "../..";
import { parseJson, type Handler } from "../..";
const username = "Taevas";
export const alakajam: Handler = async () => {
/** https://alakajam.com/api */
const response = await (await fetch(`https://alakajam.com/api/user/${username}/latestEntry`)).json() as {
const response = await parseJson(await fetch(`https://alakajam.com/api/user/${username}/latestEntry`)) as {
name: string
latest_entry: {
event_name: string

View file

@ -1,9 +1,9 @@
import type { ItchioInfo } from "#Infos/GameDev/Itchio.tsx";
import type { Handler } from "../..";
import { parseJson, type Handler } from "../..";
export const itchio: Handler = async () => {
/** https://itch.io/docs/api/serverside#reference/profilegames-httpsitchioapi1keymy-games */
const response = await (await fetch(`https://itch.io/api/1/${process.env["API_ITCHIO"]}/my-games`)).json() as {
const response = await parseJson(await fetch(`https://itch.io/api/1/${process.env["API_ITCHIO"]}/my-games`)) as {
games: {
published_at?: string
title: string

View file

@ -1,5 +1,5 @@
import {type SpeedruncomInfo} from "#Infos/Gaming/Speedruncom.tsx";
import type { Handler } from "../..";
import { parseJson, type Handler } from "../..";
const user_id = "j03v45mj";
@ -47,7 +47,7 @@ export const speedruncom: Handler = async () => {
// using the API's embedding would be stupid here, as that'd create lag due to irrelevant runs
/** https://github.com/speedruncomorg/api/blob/master/version1/users.md#get-usersidpersonal-bests */
const speedruncom = await (await fetch(`https://www.speedrun.com/api/v1/users/${user_id}/personal-bests`)).json() as Runs;
const speedruncom = await parseJson(await fetch(`https://www.speedrun.com/api/v1/users/${user_id}/personal-bests`)) as Runs;
const data = speedruncom.data.at(0);
if (!data) {
@ -61,7 +61,7 @@ export const speedruncom: Handler = async () => {
/** https://github.com/speedruncomorg/api/blob/master/version1/categories.md */
if (data.run.category) {urlsToRequest.push(`https://www.speedrun.com/api/v1/categories/${data.run.category}`);}
const toRequest = urlsToRequest.map((url) => new Promise(async (resolve) => resolve(await (await fetch(url)).json())));
const toRequest = urlsToRequest.map((url) => new Promise(async (resolve) => resolve(await parseJson(await fetch(url)))));
const responses = await Promise.all(toRequest) as [Game, Level?, Level?];
const game = responses[0];
const details = [responses[1]].concat(responses[2]).filter((d) => d !== undefined);

View file

@ -1,11 +1,11 @@
import {type HacktheboxInfo} from "#Infos/Hacking/Hackthebox.tsx";
import type { Handler } from "../..";
import { parseJson, type Handler } from "../..";
const user_id = 1063999;
export const hackthebox: Handler = async () => {
/** https://documenter.getpostman.com/view/13129365/TVeqbmeq#1b0b22fc-2e45-456a-9a8f-42888375d1a9 */
const hackthebox = await (await fetch(`https://www.hackthebox.com/api/v4/profile/activity/${user_id}`)).json() as {
const hackthebox = await parseJson(await fetch(`https://www.hackthebox.com/api/v4/profile/activity/${user_id}`)) as {
profile: {
activity: HacktheboxInfo[];
};

View file

@ -1,6 +1,6 @@
import {type WanikaniInfo} from "#Infos/Japanese/Wanikani.tsx";
import type { WKLevelProgression, WKResetCollection, WKSummary } from "@bachmacintosh/wanikani-api-types";
import type { Handler } from "../..";
import { parseJson, type Handler } from "../..";
interface Subject {
id: number;
@ -59,7 +59,7 @@ export const wanikani: Handler = async () => {
"Authorization": `Bearer ${process.env["API_WANIKANI"]}`,
"Content-Type": "application/json",
}});
resolve(await response.json());
resolve(await parseJson(response));
}));
const data = await Promise.all(toRequest);
@ -91,10 +91,10 @@ export const wanikani: Handler = async () => {
const moreThingsToReviewAt = nextReviews.at(0)?.available_at ?? summary.data.next_reviews_at;
const subjectIdsAll = subjectIdsLessons.concat(subjectIdsReviews);
const subjects = await (await fetch(`https://api.wanikani.com/v2/subjects?ids=${subjectIdsAll.toString()}`, {headers: {
const subjects = await parseJson(await fetch(`https://api.wanikani.com/v2/subjects?ids=${subjectIdsAll.toString()}`, {headers: {
"Authorization": `Bearer ${process.env["API_WANIKANI"]}`,
"Content-Type": "application/json",
}})).json() as {data: Subject[]};
}})) as {data: Subject[]};
const lessons = addStuffToLearn(subjectIdsLessons, summary.data.lessons, subjects.data);
const reviews = addStuffToLearn(subjectIdsReviews, summary.data.reviews, subjects.data);

View file

@ -1,5 +1,5 @@
import {type AnilistInfo} from "#Infos/Media/Anilist.tsx";
import type { Handler } from "../..";
import { parseJson, type Handler } from "../..";
const username = "Taevas";
@ -47,7 +47,7 @@ export const anilist: Handler = async () => {
}),
});
const json = (await anilist.json()).data.MediaList;
const json = (await parseJson(anilist)).data.MediaList;
const anime: AnilistInfo = {
title: json.media.title.romaji,
episodes: {

View file

@ -1,11 +1,11 @@
import {type LastfmInfo} from "#Infos/Media/Lastfm.tsx";
import type { Handler } from "../..";
import { parseJson, type Handler } from "../..";
const username = "TTTaevas";
export const lastfm: Handler = async () => {
/** https://www.last.fm/api/show/user.getRecentTracks */
const lastfm = await (await fetch(`https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${username}&api_key=${process.env["API_LASTFM"]}&format=json&limit=1`)).json() as {
const lastfm = await parseJson(await fetch(`https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${username}&api_key=${process.env["API_LASTFM"]}&format=json&limit=1`)) as {
recenttracks: {
track: {
artist: {

View file

@ -1,12 +1,12 @@
import { type KitsudevInfo } from "#Infos/Website/KitsuDev.tsx";
import type { Handler } from "../..";
import { parseJson, type Handler } from "../..";
const username = "Taevas";
const repository = "taevas.xyz";
export const kitsudev: Handler = async () => {
/** https://kitsunes.dev/api/swagger#/repository/repoGetAllCommits */
const kitsudev = await (await fetch(`https://kitsunes.dev/api/v1/repos/${username}/${repository}/commits?limit=1`)).json() as [{
const kitsudev = await parseJson(await fetch(`https://kitsunes.dev/api/v1/repos/${username}/${repository}/commits?limit=1`)) as [{
html_url: string
commit: {
author: {

View file

@ -1,4 +1,4 @@
import type { Handler } from "../..";
import { parseJson, type Handler } from "../..";
import type { UmamiInfo } from "#Infos/Website/Umami.tsx";
import { db, getToken } from "../../../database.ts";
@ -9,18 +9,14 @@ export const umami: Handler = async () => {
const now = new Date();
const sevendaysago = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
const response = await fetch(`${api_server}/websites/${website_id}/stats?startAt=${Number(sevendaysago)}&endAt=${Number(now)}`, {
// Not using the package directly because of serious issues I consider it to have
const umami = await parseJson(await fetch(`${api_server}/websites/${website_id}/stats?startAt=${Number(sevendaysago)}&endAt=${Number(now)}`, {
headers: {
"Accept": "application/json",
"Authorization": `Bearer ${token?.access_token}`
},
});
// Not using the package directly because of serious issues I consider it to have
const umami = await response.json() as UmamiInfo;
if (!umami) {
return new Response("Not Found", {status: 404});
}
})) as UmamiInfo;
return Response.json(umami, {status: 200});
};