Skip to content

Commit

Permalink
refactor: reduce code complexity
Browse files Browse the repository at this point in the history
  • Loading branch information
JacobLinCool committed Dec 14, 2024
1 parent 136a2b5 commit 853b0b4
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 116 deletions.
125 changes: 65 additions & 60 deletions packages/cloudflare-worker/src/sanitize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,73 +10,81 @@ import {
} from "leetcode-card";
import { booleanize, normalize } from "./utils";

export function sanitize(config: Record<string, string>): Config {
const sanitized: Config = {
username: "jacoblincool",
site: "us",
width: 500,
height: 200,
css: [],
extensions: [FontExtension, AnimationExtension, ThemeExtension],
font: "baloo_2",
animation: true,
theme: { light: "light", dark: "dark" },
cache: 60,
};
// Helper functions to reduce complexity
function handleExtension(config: Record<string, string>): Config["extensions"] {
const extensions = [FontExtension, AnimationExtension, ThemeExtension];

const extName = config.ext || config.extension;
if (extName === "activity") {
extensions.push(ActivityExtension);
} else if (extName === "contest") {
extensions.push(ContestExtension);
} else if (extName === "heatmap") {
extensions.push(HeatmapExtension);
}

if (!config.username?.trim()) {
throw new Error("Missing username");
if (config.sheets) {
extensions.push(RemoteStyleExtension);
}
sanitized.username = config.username.trim();

// #region backward compatibility
return extensions;
}

function handleCssRules(config: Record<string, string>): string[] {
const css: string[] = [];

// Handle border radius (backward compatibility)
if (config.border_radius) {
const size = parseFloat(config.border_radius) ?? 1;
sanitized.css.push(`#background{rx:${size}px}`);
css.push(`#background{rx:${parseFloat(config.border_radius) ?? 1}px}`);
}

// Handle show_rank (backward compatibility)
if (config.show_rank && booleanize(config.show_rank) === false) {
sanitized.css.push(`#ranking{display:none}`);
css.push(`#ranking{display:none}`);
}
// #endregion

if (config.site?.trim().toLowerCase() === "cn") {
sanitized.site = "cn";
}

if (config.width?.trim()) {
sanitized.width = parseInt(config.width.trim()) ?? 500;
// Handle radius
if (config.radius) {
css.push(`#background{rx:${parseFloat(config.radius) ?? 4}px}`);
}

if (config.height?.trim()) {
sanitized.height = parseInt(config.height.trim()) ?? 200;
// Handle hide elements
if (config.hide) {
const targets = config.hide.split(",").map((x) => x.trim());
css.push(...targets.map((x) => `#${x}{display:none}`));
}

if (config.theme?.trim()) {
const themes = config.theme.trim().split(",");
if (themes.length === 1 || themes[1] === "") {
sanitized.theme = themes[0].trim();
} else {
sanitized.theme = { light: themes[0].trim(), dark: themes[1].trim() };
}
}
return css;
}

if (config.font?.trim()) {
sanitized.font = normalize(config.font.trim());
export function sanitize(config: Record<string, string>): Config {
if (!config.username?.trim()) {
throw new Error("Missing username");
}

if (config.animation?.trim()) {
sanitized.animation = booleanize(config.animation.trim());
}
const sanitized: Config = {
username: config.username.trim(),
site: config.site?.trim().toLowerCase() === "cn" ? "cn" : "us",
width: parseInt(config.width?.trim()) || 500,
height: parseInt(config.height?.trim()) || 200,
css: [],
extensions: handleExtension(config),
font: normalize(config.font?.trim()) || "baloo_2",
animation: config.animation ? booleanize(config.animation.trim()) : true,
theme: { light: "light", dark: "dark" },
cache: 60,
};

if (config.ext === "activity" || config.extension === "activity") {
sanitized.extensions.push(ActivityExtension);
} else if (config.ext === "contest" || config.extension === "contest") {
sanitized.extensions.push(ContestExtension);
} else if (config.ext === "heatmap" || config.extension === "heatmap") {
sanitized.extensions.push(HeatmapExtension);
// Handle theme
if (config.theme?.trim()) {
const themes = config.theme.trim().split(",");
sanitized.theme =
themes.length === 1 || themes[1] === ""
? themes[0].trim()
: { light: themes[0].trim(), dark: themes[1].trim() };
}

// Handle border
if (config.border) {
const size = parseFloat(config.border) ?? 1;
sanitized.extensions.push(() => (generator, data, body, styles) => {
Expand All @@ -88,23 +96,20 @@ export function sanitize(config: Record<string, string>): Config {
});
}

if (config.radius) {
const size = parseFloat(config.radius) ?? 4;
sanitized.css.push(`#background{rx:${size}px}`);
}

if (config.hide) {
const targets = config.hide.split(",").map((x) => x.trim());
sanitized.css.push(...targets.map((x) => `#${x}{display:none}`));
}
// Handle CSS rules
sanitized.css = handleCssRules(config);

// Handle remote style sheets
if (config.sheets) {
sanitized.sheets = config.sheets.split(",").map((x) => x.trim());
sanitized.extensions.push(RemoteStyleExtension);
}

if (config.cache && parseInt(config.cache) >= 0 && parseInt(config.cache) <= 60 * 60 * 24 * 7) {
sanitized.cache = parseInt(config.cache);
// Handle cache
if (config.cache) {
const cacheValue = parseInt(config.cache);
if (cacheValue >= 0 && cacheValue <= 60 * 60 * 24 * 7) {
sanitized.cache = cacheValue;
}
}

return sanitized;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/exts/contest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Generator } from "../card";
import { Item } from "../item";
import { Extension } from "../types";

export function ContestExtension(generator: Generator): Extension {
export async function ContestExtension(generator: Generator): Promise<Extension> {
const pre_result = new Promise<null | { ranking: ContestRanking; history: ContestInfo[] }>(
(resolve) => {
const lc = new LeetCode();
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/exts/remote-style.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Generator } from "../card";
import { Extension } from "../types";

export function RemoteStyleExtension(generator: Generator): Extension {
export async function RemoteStyleExtension(generator: Generator): Promise<Extension> {
const urls = generator.config.sheets;

const externals: Promise<string>[] = [];
Expand Down
117 changes: 63 additions & 54 deletions packages/core/src/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,41 @@ import { LeetCode, LeetCodeCN } from "leetcode-query";
import { CN_LANGS_MAP, CN_RESULTS_MAP } from "./constants";
import { FetchedData } from "./types";

interface ProblemCount {
difficulty: string;
count: number;
}

interface DifficultyStats {
solved: number;
total: number;
}

function getProblemStats(
difficulty: string,
acCounts: ProblemCount[],
totalCounts: ProblemCount[],
): DifficultyStats {
return {
solved: acCounts.find((x) => x.difficulty === difficulty)?.count || 0,
total: totalCounts.find((x) => x.difficulty === difficulty)?.count || 0,
};
}

function getCNProblemStats(
difficulty: string,
progress: Record<string, ProblemCount[]>,
): DifficultyStats {
return {
solved: progress.ac.find((x) => x.difficulty === difficulty.toUpperCase())?.count || 0,
total: (Object.values(progress) as ProblemCount[][]).reduce(
(acc, arr) =>
acc + (arr.find((x) => x.difficulty === difficulty.toUpperCase())?.count || 0),
0,
),
};
}

export class Query {
async us(username: string, headers?: Record<string, string>): Promise<FetchedData> {
const lc = new LeetCode();
Expand Down Expand Up @@ -62,35 +97,20 @@ export class Query {
country: data.user.profile.country,
},
problem: {
easy: {
solved:
data.user.submits.ac.find((x: any) => x.difficulty === "Easy")?.count || 0,
total: data.problems.find((x: any) => x.difficulty === "Easy")?.count || 0,
},
medium: {
solved:
data.user.submits.ac.find((x: any) => x.difficulty === "Medium")?.count ||
0,
total: data.problems.find((x: any) => x.difficulty === "Medium")?.count || 0,
},
hard: {
solved:
data.user.submits.ac.find((x: any) => x.difficulty === "Hard")?.count || 0,
total: data.problems.find((x: any) => x.difficulty === "Hard")?.count || 0,
},
easy: getProblemStats("Easy", data.user.submits.ac, data.problems),
medium: getProblemStats("Medium", data.user.submits.ac, data.problems),
hard: getProblemStats("Hard", data.user.submits.ac, data.problems),
ranking: data.user.profile.ranking,
},
submissions: data.submissions.map((x: any) => ({
submissions: data.submissions.map((x: { time: string }) => ({
...x,
time: parseInt(x.time) * 1000,
})),
contest: data.contest
? {
rating: data.contest.rating,
ranking: data.contest.ranking,
badge: data.contest.badge?.name || "",
}
: undefined,
contest: data.contest && {
rating: data.contest.rating,
ranking: data.contest.ranking,
badge: data.contest.badge?.name || "",
},
};

return result;
Expand Down Expand Up @@ -147,38 +167,27 @@ export class Query {
country: data.user.profile.country,
},
problem: {
easy: {
solved: data.progress.ac.find((x: any) => x.difficulty === "EASY")?.count || 0,
total: (Object.values(data.progress) as any[]).reduce(
(acc, arr) => acc + arr.find((x: any) => x.difficulty === "EASY").count,
0,
),
},
medium: {
solved:
data.progress.ac.find((x: any) => x.difficulty === "MEDIUM")?.count || 0,
total: (Object.values(data.progress) as any[]).reduce(
(acc, arr) => acc + arr.find((x: any) => x.difficulty === "MEDIUM").count,
0,
),
},
hard: {
solved: data.progress.ac.find((x: any) => x.difficulty === "HARD")?.count || 0,
total: (Object.values(data.progress) as any[]).reduce(
(acc, arr) => acc + arr.find((x: any) => x.difficulty === "HARD").count,
0,
),
},
easy: getCNProblemStats("EASY", data.progress),
medium: getCNProblemStats("MEDIUM", data.progress),
hard: getCNProblemStats("HARD", data.progress),
ranking: data.user.ranking,
},
submissions: data.submissions.map((x: any) => ({
title: x.question.title,
time: x.time * 1000,
status: CN_RESULTS_MAP[x.status] || "",
lang: CN_LANGS_MAP[x.lang] || "",
slug: x.question.slug,
id: x.id,
})),
submissions: data.submissions.map(
(x: {
question: { title: any; slug: any };
time: number;
status: string | number;
lang: string | number;
id: any;
}) => ({
title: x.question.title,
time: x.time * 1000,
status: CN_RESULTS_MAP[x.status] || "",
lang: CN_LANGS_MAP[x.lang] || "",
slug: x.question.slug,
id: x.id,
}),
),
};

return result;
Expand Down

0 comments on commit 853b0b4

Please sign in to comment.