this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 55 lines 1.5 kB view raw
1import { file } from "astro/loaders"; 2import { z } from "astro/zod"; 3import { defineCollection } from "astro:content"; 4import { getSecret } from "astro:env/server"; 5import { differenceInMonths } from "date-fns"; 6import { mkdir, readFile, writeFile } from "node:fs/promises"; 7import path from "node:path"; 8 9export async function wakatimeCollection( 10 cachepath: string, 11 subkey: "languages" | "projects", 12) { 13 await refreshWakatimeCache(cachepath); 14 15 return defineCollection({ 16 schema: z.object({ 17 name: z.string(), 18 total_seconds: z.number(), 19 }), 20 loader: file(cachepath, { 21 parser: (text) => 22 JSON.parse(text).data[subkey].map((l) => ({ 23 id: l.name.toLowerCase(), 24 ...l, 25 })), 26 }), 27 }); 28} 29 30export async function refreshWakatimeCache(cachepath: string) { 31 try { 32 const cachedResponse = JSON.parse((await readFile(cachepath)).toString()); 33 // cache is fresh enough 34 if ( 35 differenceInMonths(new Date(), new Date(cachedResponse.writtenAt)) < 2 36 ) { 37 return cachedResponse; 38 } 39 } catch {} 40 41 const response = await fetch( 42 `https://wakatime.com/api/v1/users/current/stats/all_time`, 43 { 44 headers: { 45 Authorization: `Basic ${getSecret("WAKATIME_API_KEY")}`, 46 }, 47 }, 48 ).then((response) => response.json()); 49 50 await mkdir(path.dirname(cachepath), { recursive: true }); 51 await writeFile( 52 cachepath, 53 JSON.stringify({ ...response, writtenAt: new Date().toISOString() }), 54 ); 55}