From 0dddade717e48741b3ffdaca3ee9694594048121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Ch=C3=A1nh=20=C4=90=E1=BA=A1i?= Date: Mon, 2 Jun 2025 14:38:13 +0700 Subject: [PATCH 1/2] feat(web): add example.env file for environment variable configuration Add example.env to guide users in setting up environment variables, including APP_URL and GITHUB_API_TOKEN for API authentication. feat(api): create stargazers_count API route to fetch GitHub stargazers Introduce a new API route to fetch the stargazers count from GitHub using the GITHUB_API_TOKEN for authentication. This allows for centralized data fetching and caching. refactor(stars-count): update StarsCount component to use new API route Modify the StarsCount component to use the new /api/stargazers_count route instead of directly fetching from GitHub. This improves maintainability and leverages server-side caching. Add a check for negative stargazers_count to handle potential errors gracefully. --- apps/web/example.env | 4 ++++ apps/web/src/app/api/stargazers_count/route.ts | 17 +++++++++++++++++ apps/web/src/components/stars-count.tsx | 12 ++++++------ 3 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 apps/web/example.env create mode 100644 apps/web/src/app/api/stargazers_count/route.ts diff --git a/apps/web/example.env b/apps/web/example.env new file mode 100644 index 0000000..0f8d9d9 --- /dev/null +++ b/apps/web/example.env @@ -0,0 +1,4 @@ +APP_URL=https://react-wheel-picker.chanhdai.com + +# https://github.com/settings/tokens +GITHUB_API_TOKEN= diff --git a/apps/web/src/app/api/stargazers_count/route.ts b/apps/web/src/app/api/stargazers_count/route.ts new file mode 100644 index 0000000..4e16780 --- /dev/null +++ b/apps/web/src/app/api/stargazers_count/route.ts @@ -0,0 +1,17 @@ +export async function GET() { + const data = await fetch( + "https://api.github.com/repos/ncdai/react-wheel-picker", + { + headers: { + Accept: "application/vnd.github+json", + Authorization: `Bearer ${process.env.GITHUB_API_TOKEN}`, + "X-GitHub-Api-Version": "2022-11-28", + }, + next: { revalidate: 86400 }, // Cache for 1 day (86400 seconds) + }, + ); + const json = await data.json(); + return Response.json({ + stargazers_count: json?.stargazers_count ?? -1, + }); +} diff --git a/apps/web/src/components/stars-count.tsx b/apps/web/src/components/stars-count.tsx index 3f4c073..ef18996 100644 --- a/apps/web/src/components/stars-count.tsx +++ b/apps/web/src/components/stars-count.tsx @@ -3,23 +3,23 @@ import React from "react"; import useSWR from "swr"; -const fetcher = (url: string) => - fetch(url, { next: { revalidate: 86400 } }).then((r) => r.json()); // Cache for 1 day (86400 seconds) +const fetcher = (url: string) => fetch(url).then((r) => r.json()); type StarsCountResponse = { stargazers_count: number; }; export function StarsCount() { - const { data } = useSWR( - `https://api.github.com/repos/ncdai/react-wheel-picker`, - fetcher, - ); + const { data } = useSWR(`/api/stargazers_count`, fetcher); if (!data) { return ; } + if (data.stargazers_count < 0) { + return ; + } + return ( {data.stargazers_count.toLocaleString()} From ddf1327d986185cc0a63cf687cc3c6c616ae9895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Ch=C3=A1nh=20=C4=90=E1=BA=A1i?= Date: Mon, 2 Jun 2025 14:38:51 +0700 Subject: [PATCH 2/2] chore(package.json): update turbo devDependency from version 2.5.3 to 2.5.4 to include latest fixes and improvements --- package.json | 2 +- pnpm-lock.yaml | 64 +++++++++++++++++++++++++------------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 7705afc..d826570 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "devDependencies": { "@changesets/cli": "^2.29.4", "prettier": "3.5.3", - "turbo": "^2.5.3", + "turbo": "^2.5.4", "typescript": "^5.8.3" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0870eba..88b7815 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,8 +15,8 @@ importers: specifier: 3.5.3 version: 3.5.3 turbo: - specifier: ^2.5.3 - version: 2.5.3 + specifier: ^2.5.4 + version: 2.5.4 typescript: specifier: ^5.8.3 version: 5.8.3 @@ -200,7 +200,7 @@ importers: version: 12.1.1(eslint@9.27.0(jiti@2.4.2)) eslint-plugin-turbo: specifier: ^2.5.3 - version: 2.5.3(eslint@9.27.0(jiti@2.4.2))(turbo@2.5.3) + version: 2.5.3(eslint@9.27.0(jiti@2.4.2))(turbo@2.5.4) globals: specifier: 16.1.0 version: 16.1.0 @@ -4629,38 +4629,38 @@ packages: engines: {node: '>=18.0.0'} hasBin: true - turbo-darwin-64@2.5.3: - resolution: {integrity: sha512-YSItEVBUIvAGPUDpAB9etEmSqZI3T6BHrkBkeSErvICXn3dfqXUfeLx35LfptLDEbrzFUdwYFNmt8QXOwe9yaw==} + turbo-darwin-64@2.5.4: + resolution: {integrity: sha512-ah6YnH2dErojhFooxEzmvsoZQTMImaruZhFPfMKPBq8sb+hALRdvBNLqfc8NWlZq576FkfRZ/MSi4SHvVFT9PQ==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.5.3: - resolution: {integrity: sha512-5PefrwHd42UiZX7YA9m1LPW6x9YJBDErXmsegCkVp+GjmWrADfEOxpFrGQNonH3ZMj77WZB2PVE5Aw3gA+IOhg==} + turbo-darwin-arm64@2.5.4: + resolution: {integrity: sha512-2+Nx6LAyuXw2MdXb7pxqle3MYignLvS7OwtsP9SgtSBaMlnNlxl9BovzqdYAgkUW3AsYiQMJ/wBRb7d+xemM5A==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.5.3: - resolution: {integrity: sha512-M9xigFgawn5ofTmRzvjjLj3Lqc05O8VHKuOlWNUlnHPUltFquyEeSkpQNkE/vpPdOR14AzxqHbhhxtfS4qvb1w==} + turbo-linux-64@2.5.4: + resolution: {integrity: sha512-5May2kjWbc8w4XxswGAl74GZ5eM4Gr6IiroqdLhXeXyfvWEdm2mFYCSWOzz0/z5cAgqyGidF1jt1qzUR8hTmOA==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.5.3: - resolution: {integrity: sha512-auJRbYZ8SGJVqvzTikpg1bsRAsiI9Tk0/SDkA5Xgg0GdiHDH/BOzv1ZjDE2mjmlrO/obr19Dw+39OlMhwLffrw==} + turbo-linux-arm64@2.5.4: + resolution: {integrity: sha512-/2yqFaS3TbfxV3P5yG2JUI79P7OUQKOUvAnx4MV9Bdz6jqHsHwc9WZPpO4QseQm+NvmgY6ICORnoVPODxGUiJg==} cpu: [arm64] os: [linux] - turbo-windows-64@2.5.3: - resolution: {integrity: sha512-arLQYohuHtIEKkmQSCU9vtrKUg+/1TTstWB9VYRSsz+khvg81eX6LYHtXJfH/dK7Ho6ck+JaEh5G+QrE1jEmCQ==} + turbo-windows-64@2.5.4: + resolution: {integrity: sha512-EQUO4SmaCDhO6zYohxIjJpOKRN3wlfU7jMAj3CgcyTPvQR/UFLEKAYHqJOnJtymbQmiiM/ihX6c6W6Uq0yC7mA==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.5.3: - resolution: {integrity: sha512-3JPn66HAynJ0gtr6H+hjY4VHpu1RPKcEwGATvGUTmLmYSYBQieVlnGDRMMoYN066YfyPqnNGCfhYbXfH92Cm0g==} + turbo-windows-arm64@2.5.4: + resolution: {integrity: sha512-oQ8RrK1VS8lrxkLriotFq+PiF7iiGgkZtfLKF4DDKsmdbPo0O9R2mQxm7jHLuXraRCuIQDWMIw6dpcr7Iykf4A==} cpu: [arm64] os: [win32] - turbo@2.5.3: - resolution: {integrity: sha512-iHuaNcq5GZZnr3XDZNuu2LSyCzAOPwDuo5Qt+q64DfsTP1i3T2bKfxJhni2ZQxsvAoxRbuUK5QetJki4qc5aYA==} + turbo@2.5.4: + resolution: {integrity: sha512-kc8ZibdRcuWUG1pbYSBFWqmIjynlD8Lp7IB6U3vIzvOv9VG+6Sp8bzyeBWE3Oi8XV5KsQrznyRTBPvrf99E4mA==} hasBin: true tw-animate-css@1.2.9: @@ -7490,11 +7490,11 @@ snapshots: dependencies: eslint: 9.27.0(jiti@2.4.2) - eslint-plugin-turbo@2.5.3(eslint@9.27.0(jiti@2.4.2))(turbo@2.5.3): + eslint-plugin-turbo@2.5.3(eslint@9.27.0(jiti@2.4.2))(turbo@2.5.4): dependencies: dotenv: 16.0.3 eslint: 9.27.0(jiti@2.4.2) - turbo: 2.5.3 + turbo: 2.5.4 eslint-scope@8.3.0: dependencies: @@ -9960,32 +9960,32 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - turbo-darwin-64@2.5.3: + turbo-darwin-64@2.5.4: optional: true - turbo-darwin-arm64@2.5.3: + turbo-darwin-arm64@2.5.4: optional: true - turbo-linux-64@2.5.3: + turbo-linux-64@2.5.4: optional: true - turbo-linux-arm64@2.5.3: + turbo-linux-arm64@2.5.4: optional: true - turbo-windows-64@2.5.3: + turbo-windows-64@2.5.4: optional: true - turbo-windows-arm64@2.5.3: + turbo-windows-arm64@2.5.4: optional: true - turbo@2.5.3: + turbo@2.5.4: optionalDependencies: - turbo-darwin-64: 2.5.3 - turbo-darwin-arm64: 2.5.3 - turbo-linux-64: 2.5.3 - turbo-linux-arm64: 2.5.3 - turbo-windows-64: 2.5.3 - turbo-windows-arm64: 2.5.3 + turbo-darwin-64: 2.5.4 + turbo-darwin-arm64: 2.5.4 + turbo-linux-64: 2.5.4 + turbo-linux-arm64: 2.5.4 + turbo-windows-64: 2.5.4 + turbo-windows-arm64: 2.5.4 tw-animate-css@1.2.9: {}