Skip to content

Commit 853b0b4

Browse files
committed
refactor: reduce code complexity
1 parent 136a2b5 commit 853b0b4

File tree

4 files changed

+130
-116
lines changed

4 files changed

+130
-116
lines changed

packages/cloudflare-worker/src/sanitize.ts

+65-60
Original file line numberDiff line numberDiff line change
@@ -10,73 +10,81 @@ import {
1010
} from "leetcode-card";
1111
import { booleanize, normalize } from "./utils";
1212

13-
export function sanitize(config: Record<string, string>): Config {
14-
const sanitized: Config = {
15-
username: "jacoblincool",
16-
site: "us",
17-
width: 500,
18-
height: 200,
19-
css: [],
20-
extensions: [FontExtension, AnimationExtension, ThemeExtension],
21-
font: "baloo_2",
22-
animation: true,
23-
theme: { light: "light", dark: "dark" },
24-
cache: 60,
25-
};
13+
// Helper functions to reduce complexity
14+
function handleExtension(config: Record<string, string>): Config["extensions"] {
15+
const extensions = [FontExtension, AnimationExtension, ThemeExtension];
16+
17+
const extName = config.ext || config.extension;
18+
if (extName === "activity") {
19+
extensions.push(ActivityExtension);
20+
} else if (extName === "contest") {
21+
extensions.push(ContestExtension);
22+
} else if (extName === "heatmap") {
23+
extensions.push(HeatmapExtension);
24+
}
2625

27-
if (!config.username?.trim()) {
28-
throw new Error("Missing username");
26+
if (config.sheets) {
27+
extensions.push(RemoteStyleExtension);
2928
}
30-
sanitized.username = config.username.trim();
3129

32-
// #region backward compatibility
30+
return extensions;
31+
}
32+
33+
function handleCssRules(config: Record<string, string>): string[] {
34+
const css: string[] = [];
35+
36+
// Handle border radius (backward compatibility)
3337
if (config.border_radius) {
34-
const size = parseFloat(config.border_radius) ?? 1;
35-
sanitized.css.push(`#background{rx:${size}px}`);
38+
css.push(`#background{rx:${parseFloat(config.border_radius) ?? 1}px}`);
3639
}
3740

41+
// Handle show_rank (backward compatibility)
3842
if (config.show_rank && booleanize(config.show_rank) === false) {
39-
sanitized.css.push(`#ranking{display:none}`);
43+
css.push(`#ranking{display:none}`);
4044
}
41-
// #endregion
4245

43-
if (config.site?.trim().toLowerCase() === "cn") {
44-
sanitized.site = "cn";
45-
}
46-
47-
if (config.width?.trim()) {
48-
sanitized.width = parseInt(config.width.trim()) ?? 500;
46+
// Handle radius
47+
if (config.radius) {
48+
css.push(`#background{rx:${parseFloat(config.radius) ?? 4}px}`);
4949
}
5050

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

55-
if (config.theme?.trim()) {
56-
const themes = config.theme.trim().split(",");
57-
if (themes.length === 1 || themes[1] === "") {
58-
sanitized.theme = themes[0].trim();
59-
} else {
60-
sanitized.theme = { light: themes[0].trim(), dark: themes[1].trim() };
61-
}
62-
}
57+
return css;
58+
}
6359

64-
if (config.font?.trim()) {
65-
sanitized.font = normalize(config.font.trim());
60+
export function sanitize(config: Record<string, string>): Config {
61+
if (!config.username?.trim()) {
62+
throw new Error("Missing username");
6663
}
6764

68-
if (config.animation?.trim()) {
69-
sanitized.animation = booleanize(config.animation.trim());
70-
}
65+
const sanitized: Config = {
66+
username: config.username.trim(),
67+
site: config.site?.trim().toLowerCase() === "cn" ? "cn" : "us",
68+
width: parseInt(config.width?.trim()) || 500,
69+
height: parseInt(config.height?.trim()) || 200,
70+
css: [],
71+
extensions: handleExtension(config),
72+
font: normalize(config.font?.trim()) || "baloo_2",
73+
animation: config.animation ? booleanize(config.animation.trim()) : true,
74+
theme: { light: "light", dark: "dark" },
75+
cache: 60,
76+
};
7177

72-
if (config.ext === "activity" || config.extension === "activity") {
73-
sanitized.extensions.push(ActivityExtension);
74-
} else if (config.ext === "contest" || config.extension === "contest") {
75-
sanitized.extensions.push(ContestExtension);
76-
} else if (config.ext === "heatmap" || config.extension === "heatmap") {
77-
sanitized.extensions.push(HeatmapExtension);
78+
// Handle theme
79+
if (config.theme?.trim()) {
80+
const themes = config.theme.trim().split(",");
81+
sanitized.theme =
82+
themes.length === 1 || themes[1] === ""
83+
? themes[0].trim()
84+
: { light: themes[0].trim(), dark: themes[1].trim() };
7885
}
7986

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

91-
if (config.radius) {
92-
const size = parseFloat(config.radius) ?? 4;
93-
sanitized.css.push(`#background{rx:${size}px}`);
94-
}
95-
96-
if (config.hide) {
97-
const targets = config.hide.split(",").map((x) => x.trim());
98-
sanitized.css.push(...targets.map((x) => `#${x}{display:none}`));
99-
}
99+
// Handle CSS rules
100+
sanitized.css = handleCssRules(config);
100101

102+
// Handle remote style sheets
101103
if (config.sheets) {
102104
sanitized.sheets = config.sheets.split(",").map((x) => x.trim());
103-
sanitized.extensions.push(RemoteStyleExtension);
104105
}
105106

106-
if (config.cache && parseInt(config.cache) >= 0 && parseInt(config.cache) <= 60 * 60 * 24 * 7) {
107-
sanitized.cache = parseInt(config.cache);
107+
// Handle cache
108+
if (config.cache) {
109+
const cacheValue = parseInt(config.cache);
110+
if (cacheValue >= 0 && cacheValue <= 60 * 60 * 24 * 7) {
111+
sanitized.cache = cacheValue;
112+
}
108113
}
109114

110115
return sanitized;

packages/core/src/exts/contest.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Generator } from "../card";
33
import { Item } from "../item";
44
import { Extension } from "../types";
55

6-
export function ContestExtension(generator: Generator): Extension {
6+
export async function ContestExtension(generator: Generator): Promise<Extension> {
77
const pre_result = new Promise<null | { ranking: ContestRanking; history: ContestInfo[] }>(
88
(resolve) => {
99
const lc = new LeetCode();

packages/core/src/exts/remote-style.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Generator } from "../card";
22
import { Extension } from "../types";
33

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

77
const externals: Promise<string>[] = [];

packages/core/src/query.ts

+63-54
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,41 @@ import { LeetCode, LeetCodeCN } from "leetcode-query";
33
import { CN_LANGS_MAP, CN_RESULTS_MAP } from "./constants";
44
import { FetchedData } from "./types";
55

6+
interface ProblemCount {
7+
difficulty: string;
8+
count: number;
9+
}
10+
11+
interface DifficultyStats {
12+
solved: number;
13+
total: number;
14+
}
15+
16+
function getProblemStats(
17+
difficulty: string,
18+
acCounts: ProblemCount[],
19+
totalCounts: ProblemCount[],
20+
): DifficultyStats {
21+
return {
22+
solved: acCounts.find((x) => x.difficulty === difficulty)?.count || 0,
23+
total: totalCounts.find((x) => x.difficulty === difficulty)?.count || 0,
24+
};
25+
}
26+
27+
function getCNProblemStats(
28+
difficulty: string,
29+
progress: Record<string, ProblemCount[]>,
30+
): DifficultyStats {
31+
return {
32+
solved: progress.ac.find((x) => x.difficulty === difficulty.toUpperCase())?.count || 0,
33+
total: (Object.values(progress) as ProblemCount[][]).reduce(
34+
(acc, arr) =>
35+
acc + (arr.find((x) => x.difficulty === difficulty.toUpperCase())?.count || 0),
36+
0,
37+
),
38+
};
39+
}
40+
641
export class Query {
742
async us(username: string, headers?: Record<string, string>): Promise<FetchedData> {
843
const lc = new LeetCode();
@@ -62,35 +97,20 @@ export class Query {
6297
country: data.user.profile.country,
6398
},
6499
problem: {
65-
easy: {
66-
solved:
67-
data.user.submits.ac.find((x: any) => x.difficulty === "Easy")?.count || 0,
68-
total: data.problems.find((x: any) => x.difficulty === "Easy")?.count || 0,
69-
},
70-
medium: {
71-
solved:
72-
data.user.submits.ac.find((x: any) => x.difficulty === "Medium")?.count ||
73-
0,
74-
total: data.problems.find((x: any) => x.difficulty === "Medium")?.count || 0,
75-
},
76-
hard: {
77-
solved:
78-
data.user.submits.ac.find((x: any) => x.difficulty === "Hard")?.count || 0,
79-
total: data.problems.find((x: any) => x.difficulty === "Hard")?.count || 0,
80-
},
100+
easy: getProblemStats("Easy", data.user.submits.ac, data.problems),
101+
medium: getProblemStats("Medium", data.user.submits.ac, data.problems),
102+
hard: getProblemStats("Hard", data.user.submits.ac, data.problems),
81103
ranking: data.user.profile.ranking,
82104
},
83-
submissions: data.submissions.map((x: any) => ({
105+
submissions: data.submissions.map((x: { time: string }) => ({
84106
...x,
85107
time: parseInt(x.time) * 1000,
86108
})),
87-
contest: data.contest
88-
? {
89-
rating: data.contest.rating,
90-
ranking: data.contest.ranking,
91-
badge: data.contest.badge?.name || "",
92-
}
93-
: undefined,
109+
contest: data.contest && {
110+
rating: data.contest.rating,
111+
ranking: data.contest.ranking,
112+
badge: data.contest.badge?.name || "",
113+
},
94114
};
95115

96116
return result;
@@ -147,38 +167,27 @@ export class Query {
147167
country: data.user.profile.country,
148168
},
149169
problem: {
150-
easy: {
151-
solved: data.progress.ac.find((x: any) => x.difficulty === "EASY")?.count || 0,
152-
total: (Object.values(data.progress) as any[]).reduce(
153-
(acc, arr) => acc + arr.find((x: any) => x.difficulty === "EASY").count,
154-
0,
155-
),
156-
},
157-
medium: {
158-
solved:
159-
data.progress.ac.find((x: any) => x.difficulty === "MEDIUM")?.count || 0,
160-
total: (Object.values(data.progress) as any[]).reduce(
161-
(acc, arr) => acc + arr.find((x: any) => x.difficulty === "MEDIUM").count,
162-
0,
163-
),
164-
},
165-
hard: {
166-
solved: data.progress.ac.find((x: any) => x.difficulty === "HARD")?.count || 0,
167-
total: (Object.values(data.progress) as any[]).reduce(
168-
(acc, arr) => acc + arr.find((x: any) => x.difficulty === "HARD").count,
169-
0,
170-
),
171-
},
170+
easy: getCNProblemStats("EASY", data.progress),
171+
medium: getCNProblemStats("MEDIUM", data.progress),
172+
hard: getCNProblemStats("HARD", data.progress),
172173
ranking: data.user.ranking,
173174
},
174-
submissions: data.submissions.map((x: any) => ({
175-
title: x.question.title,
176-
time: x.time * 1000,
177-
status: CN_RESULTS_MAP[x.status] || "",
178-
lang: CN_LANGS_MAP[x.lang] || "",
179-
slug: x.question.slug,
180-
id: x.id,
181-
})),
175+
submissions: data.submissions.map(
176+
(x: {
177+
question: { title: any; slug: any };
178+
time: number;
179+
status: string | number;
180+
lang: string | number;
181+
id: any;
182+
}) => ({
183+
title: x.question.title,
184+
time: x.time * 1000,
185+
status: CN_RESULTS_MAP[x.status] || "",
186+
lang: CN_LANGS_MAP[x.lang] || "",
187+
slug: x.question.slug,
188+
id: x.id,
189+
}),
190+
),
182191
};
183192

184193
return result;

0 commit comments

Comments
 (0)