|
1 | 1 | import fs from 'node:fs/promises' |
2 | 2 | import path from 'node:path' |
3 | 3 | import { fileURLToPath } from 'node:url' |
| 4 | +import { fetchRepositoryStats } from './repository-stats.mjs' |
4 | 5 |
|
5 | 6 | const root = path.dirname(path.dirname(fileURLToPath(import.meta.url))) |
6 | 7 | const themesDir = path.join(root, 'src/content/themes') |
7 | | -const githubToken = process.env.GITHUB_TOKEN |
8 | | -const gitlabToken = process.env.GITLAB_TOKEN |
9 | | -const codebergToken = process.env.CODEBERG_TOKEN |
10 | | - |
11 | | -async function requestJson(url, headers = {}) { |
12 | | - const response = await fetch(url, { headers }) |
13 | | - |
14 | | - if (!response.ok) { |
15 | | - throw new Error(`${response.status} ${response.statusText}`) |
16 | | - } |
17 | | - |
18 | | - return response.json() |
19 | | -} |
20 | | - |
21 | | -function parseRepo(repository) { |
22 | | - const url = new URL(repository) |
23 | | - const [owner, name] = url.pathname.replace(/^\/|\/$/g, '').split('/') |
24 | | - |
25 | | - if (!owner || !name) { |
26 | | - throw new Error(`Unsupported repository path: ${repository}`) |
27 | | - } |
28 | | - |
29 | | - return { host: url.hostname.replace(/^www\./, ''), owner, name } |
30 | | -} |
31 | | - |
32 | | -async function readGithub({ owner, name }) { |
33 | | - const headers = githubToken ? { Authorization: `Bearer ${githubToken}` } : {} |
34 | | - const data = await requestJson(`https://api.github.com/repos/${owner}/${name}`, headers) |
35 | | - |
36 | | - return { |
37 | | - stars: data.stargazers_count ?? 0, |
38 | | - updatedAt: data.pushed_at ?? data.updated_at ?? null, |
39 | | - ownerAvatar: data.owner?.avatar_url ?? null, |
40 | | - accessible: true |
41 | | - } |
42 | | -} |
43 | | - |
44 | | -async function readGitlab({ owner, name }) { |
45 | | - const headers = gitlabToken ? { Authorization: `Bearer ${gitlabToken}` } : {} |
46 | | - const encoded = encodeURIComponent(`${owner}/${name}`) |
47 | | - const data = await requestJson(`https://gitlab.com/api/v4/projects/${encoded}`, headers) |
48 | | - |
49 | | - const avatar = data.namespace?.avatar_url ?? null |
50 | | - |
51 | | - return { |
52 | | - stars: data.star_count ?? 0, |
53 | | - updatedAt: data.last_activity_at ?? null, |
54 | | - ownerAvatar: avatar?.startsWith('/') ? `https://gitlab.com${avatar}` : avatar, |
55 | | - accessible: true |
56 | | - } |
57 | | -} |
58 | | - |
59 | | -async function readCodeberg({ owner, name }) { |
60 | | - const headers = codebergToken ? { Authorization: `token ${codebergToken}` } : {} |
61 | | - const data = await requestJson(`https://codeberg.org/api/v1/repos/${owner}/${name}`, headers) |
62 | | - |
63 | | - return { |
64 | | - stars: data.stars_count ?? 0, |
65 | | - updatedAt: data.updated_at ?? null, |
66 | | - ownerAvatar: data.owner?.avatar_url ?? null, |
67 | | - accessible: true |
68 | | - } |
69 | | -} |
70 | 8 |
|
71 | 9 | async function refreshTheme(file) { |
72 | 10 | const filePath = path.join(themesDir, file) |
73 | 11 | const theme = JSON.parse(await fs.readFile(filePath, 'utf8')) |
74 | | - const repo = parseRepo(theme.repository) |
75 | | - |
76 | | - let stats |
77 | | - if (repo.host === 'github.com') { |
78 | | - stats = await readGithub(repo) |
79 | | - } else if (repo.host === 'gitlab.com') { |
80 | | - stats = await readGitlab(repo) |
81 | | - } else if (repo.host === 'codeberg.org') { |
82 | | - stats = await readCodeberg(repo) |
83 | | - } else { |
84 | | - stats = { ...theme.stats, accessible: true } |
85 | | - } |
86 | | - |
87 | | - theme.stats = { ...theme.stats, ...stats } |
| 12 | + theme.stats = { ...theme.stats, ...await fetchRepositoryStats(theme.repository, theme.stats) } |
88 | 13 | await fs.writeFile(filePath, `${JSON.stringify(theme, null, 2)}\n`) |
89 | 14 | console.log(`Refreshed ${theme.slug}`) |
90 | 15 | } |
|
0 commit comments