40 lines
1.4 KiB
TypeScript
40 lines
1.4 KiB
TypeScript
/**
|
|
* Serves the Bandcamp release the native player plays, resolved from its page
|
|
* when playback starts. On any failure the player falls back to the embed.
|
|
*
|
|
* - `GET /api/bandcamp/tracks?url=&force=` — public. Answers the page's
|
|
* tracks and their stream URLs; `force=1` skips the server's cache.
|
|
*
|
|
* @module
|
|
*/
|
|
|
|
import { Router } from "@oak/oak";
|
|
import type { APIResponse } from "../../shared/api.ts";
|
|
import { resolveBandcamp } from "../remote/bandcamp-streams.ts";
|
|
import type { Tralbum } from "../../shared/player.ts";
|
|
|
|
/**
|
|
* Mounted by `api/main.ts` behind the error, Open Graph and CORS middleware.
|
|
* An `APIException` thrown by a handler becomes the JSON error response there.
|
|
*/
|
|
const bandcampRouter: Router = new Router();
|
|
|
|
// Public: it reads a public page and answers the URLs that page gives any
|
|
// visitor.
|
|
bandcampRouter.get("/api/bandcamp/tracks", async (ctx) => {
|
|
const url = ctx.request.url.searchParams.get("url") ?? "";
|
|
const force = ctx.request.url.searchParams.get("force") === "1";
|
|
|
|
const responseBody: APIResponse<Tralbum> = {
|
|
success: true,
|
|
data: await resolveBandcamp(url, { force }),
|
|
};
|
|
|
|
// Not in a shared cache: the signed URLs belong to one page fetch. An hour
|
|
// is well inside their 24 hours.
|
|
ctx.response.headers.set("Cache-Control", "private, max-age=3600");
|
|
ctx.response.body = responseBody;
|
|
});
|
|
|
|
export default bandcampRouter;
|