40 lines
1006 B
TypeScript
40 lines
1006 B
TypeScript
#!/usr/bin/env bun
|
|
/**
|
|
* Fetches top stories from Hacker News API and prints title + URL + score.
|
|
* Usage: bun run scripts/hn_top.ts [limit]
|
|
*/
|
|
|
|
const limit = Number(Bun.argv[2] ?? 10);
|
|
|
|
interface HNItem {
|
|
id: number;
|
|
title?: string;
|
|
url?: string;
|
|
score?: number;
|
|
by?: string;
|
|
type?: string;
|
|
}
|
|
|
|
const BASE = "https://hacker-news.firebaseio.com/v0";
|
|
|
|
async function fetchJSON<T>(url: string): Promise<T> {
|
|
const res = await fetch(url);
|
|
if (!res.ok) throw new Error(`HTTP ${res.status} for ${url}`);
|
|
return res.json() as Promise<T>;
|
|
}
|
|
|
|
const ids = await fetchJSON<number[]>(`${BASE}/topstories.json`);
|
|
const top = ids.slice(0, limit);
|
|
|
|
const items = await Promise.all(
|
|
top.map((id) => fetchJSON<HNItem>(`${BASE}/item/${id}.json`)),
|
|
);
|
|
|
|
for (const item of items) {
|
|
if (item.type !== "story" || !item.title) continue;
|
|
const score = item.score ?? 0;
|
|
const url = item.url ?? "(no url)";
|
|
console.log(`[${score}↑] ${item.title}`);
|
|
console.log(` ${url}`);
|
|
console.log();
|
|
} |