| 4 | import { Config, Extension, FetchedData } from "./types"; |
| 5 | |
| 6 | export class Generator { |
| 7 | public verbose = false; |
| 8 | public config: Config = { |
| 9 | username: "jacoblincool", |
| 10 | site: "us", |
| 11 | width: 500, |
| 12 | height: 200, |
| 13 | css: [], |
| 14 | extensions: [], |
| 15 | }; |
| 16 | public cache?: Cache; |
| 17 | public headers: Record<string, string>; |
| 18 | public fetches: Record<string, Promise<FetchedData>> = {}; |
| 19 | |
| 20 | constructor(cache?: Cache, headers?: Record<string, string>) { |
| 21 | this.cache = cache; |
| 22 | this.headers = headers ?? {}; |
| 23 | } |
| 24 | |
| 25 | async generate(config: Config): Promise<string> { |
| 26 | const start_time = Date.now(); |
| 27 | this.log("generating card for", config.username, config.site); |
| 28 | |
| 29 | this.config = config; |
| 30 | |
| 31 | const extensions = |
| 32 | this.config.extensions.map(async (init) => { |
| 33 | const start = Date.now(); |
| 34 | const ext = await init(this); |
| 35 | this.log(`extension "${ext.name}" initialized in ${Date.now() - start} ms`); |
| 36 | return ext; |
| 37 | }) ?? []; |
| 38 | const data = (async () => { |
| 39 | const start = Date.now(); |
| 40 | const data = await this.fetch(config.username, config.site, this.headers); |
| 41 | this.log(`user data fetched in ${Date.now() - start} ms`, data.profile); |
| 42 | return data; |
| 43 | })(); |
| 44 | const body = this.body(); |
| 45 | |
| 46 | const result = await this.hydrate(await data, body, await Promise.all(extensions)); |
| 47 | this.log(`card generated in ${Date.now() - start_time} ms`); |
| 48 | return result; |
| 49 | } |
| 50 | |
| 51 | protected async fetch( |
| 52 | username: string, |
| 53 | site: "us" | "cn", |
| 54 | headers: Record<string, string>, |
| 55 | ): Promise<FetchedData> { |
| 56 | this.log("fetching", username, site); |
| 57 | const cache_key = `https://leetcode-stats-card.local/data-${username.toLowerCase()}-${site}`; |
| 58 | console.log("cache_key", cache_key); |
| 59 | |
| 60 | if (cache_key in this.fetches) { |
| 61 | return this.fetches[cache_key]; |
| 62 | } |
| 63 | this.fetches[cache_key] = this._fetch(username, site, headers, cache_key); |
nothing calls this directly
no outgoing calls
no test coverage detected