返回 CodeWhale
types.ts
根目录 / web / lib / types.ts
1 export type FeedKind = "issue" | "pull" | "release" | "discussion";
2
3 export interface FeedItem {
4 kind: FeedKind;
5 /** Issue / pull number. Releases have none and carry `0` — read `tag`. */
6 number: number;
7 title: string;
8 url: string;
9 state: "open" | "closed" | "merged" | "draft" | "published";
10 author: string;
11 authorAvatar: string;
12 createdAt: string; // ISO
13 updatedAt: string; // ISO
14 comments: number;
15 labels: { name: string; color: string }[];
16 body?: string;
17
18 /** Release tag (`kind: "release"` only), e.g. "v0.9.4". */
19 tag?: string;
20
21 /**
22 * When the item entered the state it is in — `merged_at`, `closed_at`,
23 * `published_at`, or `created_at`. `updatedAt` still orders the feed, but a
24 * surface that prints a verb ("merged", "opened") must date that verb, not
25 * the last comment on the thread: an issue opened in March and commented on
26 * today is not "opened, just now".
27 */
28 eventAt?: string;
29
30 /**
31 * GitHub's own `author_association === "FIRST_TIME_CONTRIBUTOR"` verdict,
32 * copied verbatim from the list payload — never inferred by us, and never
33 * derived from the size of the window we happened to fetch. GitHub
34 * recomputes the association as the author gains commits, so this marks a
35 * newcomer's contribution while it is still new, and stops on its own.
36 */
37 firstTimeContributor?: boolean;
38 }
39
40 export interface RepoStats {
41 stars: number;
42 forks: number;
43 openIssues: number;
44 openPulls: number;
45 contributors: number;
46 latestRelease?: { tag: string; publishedAt: string; url: string };
47 fetchedAt: string;
48 }
49
50 export interface CuratedDispatch {
51 generatedAt: string;
52 /** English — always present (backward compat). */
53 headline: string;
54 summary: string;
55 highlights: { title: string; href: string; tag: string; blurb: string }[];
56 movers: { number: number; title: string; href: string; reason: string }[];
57 /** zh-CN — populated by cron curate since ~May 2026. Falls back to English fields when absent. */
58 headlineZh?: string;
59 summaryZh?: string;
60 highlightsZh?: { title: string; href: string; tag: string; blurb: string }[];
61 moversZh?: { number: number; title: string; href: string; reason: string }[];
62 }
63
63 lines TYPESCRIPT