feat(frontend): add /api/stations.json and /api/stations/:id/cover

This commit is contained in:
devilreef 2026-04-30 09:33:37 +06:00
parent a7256bc13c
commit d16bc80ac8
Signed by: devilreef
SSH key fingerprint: SHA256:UZisRr4iuXx+IhkbZnR655L2RWAT6o2rgbGv5F/6m3Y
2 changed files with 54 additions and 0 deletions

View file

@ -0,0 +1,17 @@
import type { APIRoute } from 'astro';
import { listStations } from '@lib/stations';
export const prerender = false;
export const GET: APIRoute = async () => {
const root = process.env.LIBRARY_ROOT ?? '/library';
const stations = await listStations(root);
return new Response(JSON.stringify(stations), {
status: 200,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Cache-Control': 'max-age=30, public',
'Access-Control-Allow-Origin': '*',
},
});
};

View file

@ -0,0 +1,37 @@
import type { APIRoute } from 'astro';
import { access, readFile } from 'node:fs/promises';
import path from 'node:path';
export const prerender = false;
const ID_RE = /^[a-z0-9-]+$/;
const CANDIDATES: Array<[string, string]> = [
['cover.jpg', 'image/jpeg'],
['cover.png', 'image/png'],
['cover.webp', 'image/webp'],
];
export const GET: APIRoute = async ({ params }) => {
const id = params.id ?? '';
if (!ID_RE.test(id)) {
return new Response('not found', { status: 404 });
}
const root = process.env.LIBRARY_ROOT ?? '/library';
for (const [name, mime] of CANDIDATES) {
const p = path.join(root, id, name);
try {
await access(p);
const buf = await readFile(p);
return new Response(new Uint8Array(buf), {
status: 200,
headers: {
'Content-Type': mime,
'Cache-Control': 'max-age=300, public',
},
});
} catch {
// try next
}
}
return new Response('not found', { status: 404 });
};