SPB Git forge

spb/market-atlas

Public
12commits 1branches 0releases
1.1 MBsize
maindefault branch
10 days agolast push
TypeScript 96.7% SQL 1.6% CSS 0.8% JavaScript 0.5%
2.6 KB · 47 lines typescript
Raw Blame History
1import type { MetadataRoute } from "next";2import { API_URL } from "@/lib/api";3import { SITE_URL } from "@/lib/site";45/**6 * Segmented sitemap: static pages, exchanges, countries, then quoted instruments per asset class7 * (thin pages without a canonical quote are not listed).8 */9export async function generateSitemaps() {10  return [{ id: "static" }, { id: "exchanges" }, { id: "countries" }, { id: "stocks" }, { id: "etfs" }, { id: "indices" }, { id: "crypto" }, { id: "forex" }, { id: "rates" }, { id: "commodities" }];11}1213const CLASS: Record<string, string[]> = { stocks: ["EQUITY"], etfs: ["ETF", "ETN"], indices: ["INDEX"], crypto: ["CRYPTO"], forex: ["FOREX"], rates: ["TREASURY", "BOND", "INTEREST_RATE"], commodities: ["COMMODITY", "FUTURE"] };1415async function get<T>(path: string): Promise<T | null> {16  try {17    const r = await fetch(`${API_URL}${path}`, { cache: "no-store" });18    if (!r.ok) return null;19    return ((await r.json()) as { data: T }).data;20  } catch {21    return null;22  }23}2425export default async function sitemap({ id: rawId }: { id: string | Promise<string> }): Promise<MetadataRoute.Sitemap> {26  const id = String(await rawId); // Next 16 passes the segment param as a promise27  const now = new Date();28  if (id === "static") {29    return ["", "/markets", "/live", "/stocks", "/etfs", "/indices", "/crypto", "/forex", "/rates", "/commodities", "/exchanges", "/countries", "/events", "/halts", "/filings", "/sources", "/coverage", "/connectors", "/data-health", "/status", "/compare", "/methodology", "/developers", "/licensing"].map((p) => ({ url: `${SITE_URL}${p}`, lastModified: now, changeFrequency: p === "" || p === "/live" ? "always" : "hourly", priority: p === "" ? 1 : 0.7 }));30  }31  if (id === "exchanges") {32    const xs = (await get<Array<{ id: string }>>("/v1/exchanges")) ?? [];33    return xs.map((x) => ({ url: `${SITE_URL}/exchanges/${x.id}`, lastModified: now, changeFrequency: "hourly", priority: 0.6 }));34  }35  if (id === "countries") {36    const cs = (await get<Array<{ code: string }>>("/v1/countries")) ?? [];37    return cs.map((c) => ({ url: `${SITE_URL}/countries/${c.code}`, lastModified: now, changeFrequency: "daily", priority: 0.5 }));38  }39  const classes = CLASS[id] ?? [];40  const out: MetadataRoute.Sitemap = [];41  for (const c of classes) {42    const rows = (await get<Array<{ id: string }>>(`/v1/instruments?asset_class=${c}&quoted=1&limit=500`)) ?? [];43    out.push(...rows.map((r) => ({ url: `${SITE_URL}/instruments/${encodeURIComponent(r.id)}`, lastModified: now, changeFrequency: "hourly" as const, priority: 0.6 })));44  }45  return out;46}47