SPB Git forge

spb/countryatlas

Public
20commits 1branches 0releases
268.3 MBsize
maindefault branch
12 days agolast push
TypeScript 57% Python 38.6% JavaScript 3.6% CSS 0.6%
4.3 KB · 77 lines typescript
Raw Blame History
1import 'server-only';2import { request } from './api';3import { finderQuery, type FinderFilterInput } from './finder-query';4import type {5  CountryQualityResponse,6  DistributionResponse,7  ExtremesResponse,8  ExtremesWindow,9  FinderResponse,10  FramesResponse,11  IndicatorQualityResponse,12  MoverCategory,13  MoverKindFilter,14  MoverWindow,15  MoversResponse,16  PeersResponse,17  PulseResponse,18  RaceResponse,19  RegionCompareResponse,20  RelatedResponse,21  ScatterResponse,22  StoryResponse,23  TrajectoryResponse,24  UpdatesResponse,25} from './types-analytics';2627/**28 * Server-side endpoints of the analytics API (API 1.1 — docs/API.md § Analytics). Same conventions as29 * `lib/api.ts` (`request<T>` → ApiError, ISR 900 s). Browser code uses `lib/client-api-analytics.ts`.30 */31export type { FinderFilterInput } from './finder-query';3233export const apiAnalytics = {34  pulse: () => request<PulseResponse>('/pulse'),3536  movers: (q: { window?: MoverWindow; category?: MoverCategory; kind?: MoverKindFilter; limit?: number; min_population?: number | null } = {}) =>37    request<MoversResponse>('/movers', { window: q.window, category: q.category, kind: q.kind, limit: q.limit, min_population: q.min_population ?? undefined }),3839  extremes: (q: { window?: ExtremesWindow | string; topic?: string | null; min_population?: number | null } = {}) =>40    request<ExtremesResponse>('/extremes', { window: q.window, topic: q.topic ?? undefined, min_population: q.min_population ?? undefined }),4142  scatter: (q: { x: string; y: string; size?: string | null; year?: number | null; group?: string | null; log_x?: string | boolean | null; log_y?: string | boolean | null }) =>43    request<ScatterResponse>('/scatter', { x: q.x, y: q.y, size: q.size ?? undefined, year: q.year ?? undefined, group: q.group ?? undefined, log_x: q.log_x ?? undefined, log_y: q.log_y ?? undefined }),4445  trajectory: (q: { x?: string; y?: string; size?: string | null; from?: number | null; to?: number | null; group?: string | null } = {}) =>46    request<TrajectoryResponse>('/trajectory', { x: q.x, y: q.y, size: q.size ?? undefined, from: q.from ?? undefined, to: q.to ?? undefined, group: q.group ?? undefined }),4748  finder: (filters: FinderFilterInput[], q: { mode?: 'and' | 'or'; region?: string | null; income?: string | null; sort?: string | null; limit?: number } = {}) =>49    request<FinderResponse>(`/finder${finderQuery(filters, q)}`),5051  peers: (q: { y?: string; x?: string; year?: number | null; method?: 'theil-sen' | 'ols'; log_x?: string | boolean | null } = {}) =>52    request<PeersResponse>('/peers', { y: q.y, x: q.x, year: q.year ?? undefined, method: q.method, log_x: q.log_x ?? undefined }),5354  indicatorRelated: (slug: string, q: { limit?: number; min_n?: number } = {}) => request<RelatedResponse>(`/indicators/${encodeURIComponent(slug)}/related`, q),5556  indicatorDistribution: (slug: string, q: { year?: number | null; highlight?: string | null; bins?: number } = {}) =>57    request<DistributionResponse>(`/indicators/${encodeURIComponent(slug)}/distribution`, { year: q.year ?? undefined, highlight: q.highlight ?? undefined, bins: q.bins }),5859  indicatorFrames: (slug: string, q: { from?: number | null; to?: number | null; step?: number; group?: string | null } = {}) =>60    request<FramesResponse>(`/indicators/${encodeURIComponent(slug)}/frames`, { from: q.from ?? undefined, to: q.to ?? undefined, step: q.step, group: q.group ?? undefined }),6162  indicatorQuality: (slug: string) => request<IndicatorQualityResponse>(`/indicators/${encodeURIComponent(slug)}/quality`),6364  race: (indicator: string, q: { from?: number | null; to?: number | null; top?: number; group?: string | null } = {}) =>65    request<RaceResponse>(`/rankings/${encodeURIComponent(indicator)}/race`, { from: q.from ?? undefined, to: q.to ?? undefined, top: q.top, group: q.group ?? undefined }),6667  regionsCompare: (a: string, b: string, indicators?: string[]) => request<RegionCompareResponse>('/regions/compare', { a, b, indicators: indicators?.length ? indicators.join(',') : undefined }),6869  countryStory: (id: string) => request<StoryResponse>(`/countries/${encodeURIComponent(id)}/story`),7071  countryQuality: (id: string) => request<CountryQualityResponse>(`/countries/${encodeURIComponent(id)}/quality`),7273  updates: () => request<UpdatesResponse>('/updates', undefined, { revalidate: 300 }),74};7576export type ApiAnalytics = typeof apiAnalytics;77