diff --git a/src/main.ts b/src/main.ts index c3cbe0d..b221cff 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,8 @@ import express, { Application, Request, Response } from 'express'; import cors from 'cors'; -import { getGraph } from './utils'; +import { Utilities } from './utils'; +import { Fetcher } from './fetcher'; +import { invalidUserSvg } from './svgs'; const app: Application = express(); const port = process.env.PORT || 5100; @@ -13,7 +15,23 @@ app.get('/', (_req: Request, res: Response) => { }); //Get Graph -app.get('/graph', getGraph); +app.get('/graph', async (req: Request, res: Response) => { + try { + const utils = new Utilities(req.query); + + const fetcher = new Fetcher(utils.username); + const fetchCalendarData = await fetcher.fetchContributions(); + + const { finalGraph, header } = await utils.buildGraph(fetchCalendarData); + utils.setHttpHeader(res, header.maxAge); + + res.status(200).send(finalGraph); + } catch (error) { + res.setHeader('Cache-Control', 'no-store, max-age=0'); + res.set('Content-Type', 'image/svg+xml'); + res.send(invalidUserSvg('Something unexpected happened 💥')); + } +}); app.listen(port, (): void => { console.log(`Server is Running on Port ${port}`); diff --git a/src/utils.ts b/src/utils.ts index c1d6ee9..7f27397 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,65 +1,65 @@ -import { Request, Response } from 'express'; +import { Response } from 'express'; import { Card } from './GraphCards'; import { invalidUserSvg } from './svgs'; -import { Fetcher } from './fetcher'; import { selectColors } from './styles/themes'; -import { queryOption, ParsedQs } from './interfaces/interface'; +import { queryOption, ParsedQs, UserDetails } from './interfaces/interface'; -export const queryOptions = (queryString: ParsedQs): queryOption => { - let area = false; - const theme: string = queryString.theme || 'default'; - - if (String(queryString.area) === 'true') { - area = true; +export class Utilities { + username: string; + constructor(private readonly queryString: ParsedQs) { + this.username = String(this.queryString.username); } - // Custom options for user - const colors = { - areaColor: queryString.area_color - ? queryString.area_color - : selectColors(theme).areaColor, - bgColor: queryString.bg_color - ? queryString.bg_color - : selectColors(theme).bgColor, - borderColor: - String(queryString.hide_border) === 'true' - ? '0000' // transparent - : selectColors(theme).borderColor, - color: queryString.color ? queryString.color : selectColors(theme).color, - lineColor: queryString.line - ? queryString.line - : selectColors(theme).lineColor, - pointColor: queryString.point - ? queryString.point - : selectColors(theme).pointColor, - }; - - const options: queryOption = { - username: String(queryString.username), - hide_title: String(queryString.hide_title) === 'true' ? true : false, - colors: colors, - area: area, - }; + private getColors() { + const theme = this.queryString.theme || 'default'; + return { + areaColor: this.queryString.area_color + ? this.queryString.area_color + : selectColors(theme).areaColor, + bgColor: this.queryString.bg_color + ? this.queryString.bg_color + : selectColors(theme).bgColor, + borderColor: + String(this.queryString.hide_border) === 'true' + ? '0000' // transparent + : selectColors(theme).borderColor, + color: this.queryString.color + ? this.queryString.color + : selectColors(theme).color, + lineColor: this.queryString.line + ? this.queryString.line + : selectColors(theme).lineColor, + pointColor: this.queryString.point + ? this.queryString.point + : selectColors(theme).pointColor, + }; + } - if (queryString.custom_title) - options['custom_title'] = String(queryString.custom_title); + public queryOptions() { + let area = false; + if (String(this.queryString.area) === 'true') { + area = true; + } - return options; -}; + // Custom options for user + const colors = this.getColors(); -const setHttpHeader = (res: Response, directivesAndAge: string): void => { - res.setHeader('Cache-Control', `${directivesAndAge}`); - res.set('Content-Type', 'image/svg+xml'); -}; + const options: queryOption = { + username: this.username, + hide_title: String(this.queryString.hide_title) === 'true' ? true : false, + colors: colors, + area: area, + }; -export const getGraph = async (req: Request, res: Response) => { - try { - const options: queryOption = queryOptions(req.query); + if (this.queryString.custom_title) + options['custom_title'] = String(this.queryString.custom_title); - const fetcher = new Fetcher(options.username); - const fetchCalendarData = await fetcher.fetchContributions(); + return options; + } + public async buildGraph(fetchCalendarData: string | UserDetails) { if (typeof fetchCalendarData === 'object') { + const options = this.queryOptions(); let title = ''; if (!options.hide_title) { @@ -86,14 +86,22 @@ export const getGraph = async (req: Request, res: Response) => { fetchCalendarData.contributions ); - setHttpHeader(res, 'public, max-age=1800'); - res.status(200).send(getChart); + return { + finalGraph: getChart, + header: { + maxAge: 'public, max-age=1800', + }, + }; } else { - setHttpHeader(res, 'no-store, max-age=0'); - res.send(invalidUserSvg(fetchCalendarData)); + return { + finalGraph: invalidUserSvg(fetchCalendarData), + header: { maxAge: 'no-store, max-age=0' }, + }; } - } catch (error) { - setHttpHeader(res, 'no-store, max-age=0'); - res.send(invalidUserSvg('Something unexpected happened 💥')); } -}; + + public setHttpHeader(res: Response, directivesAndAge: string): void { + res.setHeader('Cache-Control', `${directivesAndAge}`); + res.set('Content-Type', 'image/svg+xml'); + } +}