@@ -14,7 +14,8 @@ if (!GITHUB_TOKEN || !REPO) {
1414
1515const METRICS_FILE = 'metrics.json' ;
1616
17- async function getVisitorCount ( ) {
17+ // Fetch the last 14 days of traffic data (GitHub API returns up to 14 days)
18+ async function getLast14DaysTraffic ( ) {
1819 const res = await fetch ( `https://api.github.com/repos/${ REPO } /traffic/views` , {
1920 headers : {
2021 'Accept' : 'application/vnd.github+json' ,
@@ -29,20 +30,55 @@ async function getVisitorCount() {
2930 }
3031
3132 const data = await res . json ( ) ;
32- return data . count || 0 ;
33+ // Each entry contains: timestamp, count, uniques
34+ return data . views . map ( item => ( {
35+ date : item . timestamp . slice ( 0 , 10 ) , // Keep only YYYY-MM-DD
36+ count : item . count ,
37+ uniques : item . uniques
38+ } ) ) ;
3339}
3440
35- function updateMetricsFile ( total_views ) {
36- const lastUpdated = new Date ( ) . toISOString ( ) ;
37- const metrics = { total_views, lastUpdated } ;
41+ // Read metrics.json as an array of daily entries (if exists)
42+ function readMetrics ( ) {
43+ if ( fs . existsSync ( METRICS_FILE ) ) {
44+ const raw = fs . readFileSync ( METRICS_FILE , 'utf-8' ) ;
45+ try {
46+ const arr = JSON . parse ( raw ) ;
47+ if ( Array . isArray ( arr ) ) return arr ;
48+ } catch ( e ) {
49+ console . error ( 'metrics.json is not valid JSON. Starting fresh.' ) ;
50+ }
51+ }
52+ return [ ] ;
53+ }
54+
55+ // Write the updated metrics array back to metrics.json
56+ function writeMetrics ( metrics ) {
3857 fs . writeFileSync ( METRICS_FILE , JSON . stringify ( metrics , null , 2 ) ) ;
39- console . log ( `metrics.json updated with ${ total_views } views ` ) ;
58+ console . log ( `metrics.json updated with ${ metrics . length } days ` ) ;
4059}
4160
61+ // Merge existing and new metrics, using the date as the unique key
62+ function mergeMetrics ( existing , fetched ) {
63+ // Use an object for fast deduplication by date
64+ const byDate = { } ;
65+ existing . forEach ( entry => { byDate [ entry . date ] = entry ; } ) ;
66+ fetched . forEach ( entry => { byDate [ entry . date ] = entry ; } ) ;
67+ // Convert back to array and sort by date ascending
68+ return Object . values ( byDate ) . sort ( ( a , b ) => a . date . localeCompare ( b . date ) ) ;
69+ }
70+
71+ // Calculate the sum of all view counts (historical total)
72+ function calculateTotalViews ( metrics ) {
73+ return metrics . reduce ( ( sum , entry ) => sum + entry . count , 0 ) ;
74+ }
75+
76+ // Find and update the badge block in all Markdown files (recursive)
4277function updateMarkdownBadges ( total_views ) {
4378 const refreshDate = new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] ;
4479 const badgeRegex = / < ! - - S T A R T B A D G E - - > [ \s \S ] * ?< ! - - E N D B A D G E - - > / g;
4580
81+ // This is your existing badge schema, preserved as requested
4682 const badgeBlock = `<!-- START BADGE -->
4783<div align="center">
4884 <img src="https://img.shields.io/badge/Total%20views-${ total_views } -limegreen" alt="Total views">
@@ -63,6 +99,7 @@ function updateMarkdownBadges(total_views) {
6399 } ) ;
64100}
65101
102+ // Recursively find all Markdown files in a directory
66103function findMarkdownFiles ( dir ) {
67104 let results = [ ] ;
68105 const list = fs . readdirSync ( dir ) ;
@@ -78,17 +115,29 @@ function findMarkdownFiles(dir) {
78115 return results ;
79116}
80117
118+ // Optionally delete node_modules after running
81119function deleteNodeModules ( ) {
82120 if ( fs . existsSync ( 'node_modules' ) ) {
83121 execSync ( 'rm -rf node_modules' , { stdio : 'inherit' } ) ;
84122 console . log ( 'node_modules folder deleted.' ) ;
85123 }
86124}
87125
126+ // Main async function to orchestrate update
88127( async ( ) => {
89128 try {
90- const total_views = await getVisitorCount ( ) ;
91- updateMetricsFile ( total_views ) ;
129+ // Fetch latest 14 days of traffic data
130+ const fetched = await getLast14DaysTraffic ( ) ;
131+ // Load existing metrics.json (if present)
132+ const existing = readMetrics ( ) ;
133+ // Merge and deduplicate daily metrics
134+ const merged = mergeMetrics ( existing , fetched ) ;
135+ // Save the updated metrics array
136+ writeMetrics ( merged ) ;
137+
138+ // Calculate historical total views for badge
139+ const total_views = calculateTotalViews ( merged ) ;
140+ // Update the badge in Markdown files
92141 updateMarkdownBadges ( total_views ) ;
93142 } catch ( err ) {
94143 console . error ( err ) ;
0 commit comments