GitHub

@@ -1,10 +1,5 @@

11

type GithubCommitResponse = {

22

html_url: string;

3-

commit: {

4-

author: {

5-

date: string;

6-

};

7-

};

83

stats?: {

94

additions: number;

105

deletions: number;

@@ -13,12 +8,31 @@ type GithubCommitResponse = {

138149

export type GithubCommitMetadata = {

1510

url: string;

16-

date: string;

1711

additions: number | null;

1812

deletions: number | null;

1913

};

201421-

export async function getGithubCommitMetadata(

15+

const commitMetadataCache = new Map<

16+

string,

17+

Promise<GithubCommitMetadata | null>

18+

>();

19+20+

export function getGithubCommitMetadata(

21+

repo: string,

22+

sha: string,

23+

): Promise<GithubCommitMetadata | null> {

24+

const cacheKey = `${repo}:${sha}`;

25+

const cached = commitMetadataCache.get(cacheKey);

26+27+

if (cached) return cached;

28+29+

const request = fetchGithubCommitMetadata(repo, sha);

30+

commitMetadataCache.set(cacheKey, request);

31+32+

return request;

33+

}

34+35+

async function fetchGithubCommitMetadata(

2236

repo: string,

2337

sha: string,

2438

): Promise<GithubCommitMetadata | null> {

@@ -45,7 +59,6 @@ export async function getGithubCommitMetadata(

45594660

return {

4761

url: data.html_url,

48-

date: data.commit.author.date,

4962

additions: data.stats.additions,

5063

deletions: data.stats.deletions,

5164

};

@@ -64,10 +77,6 @@ async function getGithubCommitMetadataFromPatch(

6477

if (!res.ok) return null;

65786679

const patch = await res.text();

67-

const date = patch.match(/^Date: (.+)$/m)?.[1];

68-69-

if (!date) return null;

70-7180

const additions = patch

7281

.split("\n")

7382

.filter((line) => line.startsWith("+") && !line.startsWith("+++")).length;

@@ -77,32 +86,10 @@ async function getGithubCommitMetadataFromPatch(

77867887

return {

7988

url: `https://github.com/${repo}/commit/${sha}`,

80-

date,

8189

additions,

8290

deletions,

8391

};

8492

} catch {

8593

return null;

8694

}

8795

}

88-89-

export function formatRelativeTime(date: string): string {

90-

const elapsedSeconds = (Date.now() - new Date(date).getTime()) / 1000;

91-

const units = [

92-

["year", 60 * 60 * 24 * 365],

93-

["month", 60 * 60 * 24 * 30],

94-

["week", 60 * 60 * 24 * 7],

95-

["day", 60 * 60 * 24],

96-

["hour", 60 * 60],

97-

["minute", 60],

98-

] as const;

99-100-

const [unit, seconds] = units.find(

101-

([, seconds]) => elapsedSeconds >= seconds,

102-

) ?? ["second", 1];

103-104-

return new Intl.RelativeTimeFormat("en", { numeric: "always" }).format(

105-

-Math.floor(elapsedSeconds / seconds),

106-

unit,

107-

);

108-

}

Read the original on github.com ↗