mal api route
This commit is contained in:
72
src/routes/api/mal/animelist/[username]/+server.ts
Normal file
72
src/routes/api/mal/animelist/[username]/+server.ts
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import { error } from "@sveltejs/kit";
|
||||||
|
import { env } from "$env/dynamic/private";
|
||||||
|
import type { RequestHandler } from "./$types";
|
||||||
|
|
||||||
|
const UPSTREAM_ORIGIN = "https://api.myanimelist.net/v2";
|
||||||
|
|
||||||
|
function pickForwardHeader(request: Request, headerName: string) {
|
||||||
|
const v = request.headers.get(headerName);
|
||||||
|
return v ?? undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const GET: RequestHandler = async ({ params, request, fetch, url }) => {
|
||||||
|
const username = params.username;
|
||||||
|
|
||||||
|
if (!username) {
|
||||||
|
throw error(400, "Missing username");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!env.MAL_CLIENT_ID) {
|
||||||
|
throw error(500, "MAL_CLIENT_ID is not configured");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward query params as-is (status/sort/limit/offset/etc).
|
||||||
|
// Note: url.searchParams is already decoded/encoded appropriately by URL.
|
||||||
|
const upstreamUrl = new URL(
|
||||||
|
`${UPSTREAM_ORIGIN}/users/${encodeURIComponent(username)}/animelist`,
|
||||||
|
);
|
||||||
|
|
||||||
|
upstreamUrl.search = url.search;
|
||||||
|
|
||||||
|
const ifNoneMatch = pickForwardHeader(request, "if-none-match");
|
||||||
|
const ifModifiedSince = pickForwardHeader(request, "if-modified-since");
|
||||||
|
|
||||||
|
const upstreamRes = await fetch(upstreamUrl, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"X-MAL-CLIENT-ID": env.MAL_CLIENT_ID,
|
||||||
|
...(ifNoneMatch ? { "if-none-match": ifNoneMatch } : {}),
|
||||||
|
...(ifModifiedSince ? { "if-modified-since": ifModifiedSince } : {}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Map common statuses cleanly
|
||||||
|
if (upstreamRes.status === 401 || upstreamRes.status === 403) {
|
||||||
|
throw error(upstreamRes.status, "MAL auth failed");
|
||||||
|
}
|
||||||
|
if (upstreamRes.status === 404) {
|
||||||
|
throw error(404, "User not found");
|
||||||
|
}
|
||||||
|
if (!upstreamRes.ok && upstreamRes.status !== 304) {
|
||||||
|
throw error(upstreamRes.status, `Upstream error (${upstreamRes.status})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass through caching/content headers that are useful and safe
|
||||||
|
const headers = new Headers();
|
||||||
|
|
||||||
|
const copy = (h: string) => {
|
||||||
|
const v = upstreamRes.headers.get(h);
|
||||||
|
if (v) headers.set(h, v);
|
||||||
|
};
|
||||||
|
|
||||||
|
copy("content-type");
|
||||||
|
copy("cache-control");
|
||||||
|
copy("etag");
|
||||||
|
copy("last-modified");
|
||||||
|
|
||||||
|
return new Response(upstreamRes.body, {
|
||||||
|
status: upstreamRes.status,
|
||||||
|
statusText: upstreamRes.statusText,
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user