mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-07-20 15:05:48 +10:00
refactor: remove dead code, unused exports and redundant dependencies
- drop dotenv (Node 24 process.loadEnvFile) and dompurify (only used by dead code) - delete unused ui components/hooks (card, progress, checkbox, use-confirm, use-prompt) - delete dead sanitizeHtml/sanitizeCss, url-security helpers, patch-resume tool, schema/page, createResumePatches, patch-proposal preview builder, fonts fallback helpers - inline single-caller wrappers (flags service, auth getSession, pdf renderer passthrough) - deduplicate template color helpers into shared/color-helpers - unexport 50+ internal-only symbols, remove dead export-map entries - replace hand-rolled unique()/useIsMobile with Set spread and usehooks-ts
This commit is contained in:
@@ -1,13 +1,9 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
buildResumeFontFamily,
|
||||
fontList,
|
||||
getFallbackWebFontFamilies,
|
||||
getFont,
|
||||
getFontDisplayName,
|
||||
getFontSearchKeywords,
|
||||
getLoadableWebFontWeights,
|
||||
getPdfCjkFallbackFontFamily,
|
||||
getPdfFallbackFontFamilies,
|
||||
getWebFont,
|
||||
getWebFontSource,
|
||||
@@ -150,20 +146,6 @@ describe("getWebFontSource", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("getPdfCjkFallbackFontFamily", () => {
|
||||
it("returns Noto Sans SC for sans-serif/standard PDF fonts", () => {
|
||||
expect(getPdfCjkFallbackFontFamily("Helvetica")).toBe("Noto Sans SC");
|
||||
});
|
||||
|
||||
it("returns Noto Serif SC for serif fonts", () => {
|
||||
expect(getPdfCjkFallbackFontFamily("Times-Roman")).toBe("Noto Serif SC");
|
||||
});
|
||||
|
||||
it("returns null when family already is the CJK fallback", () => {
|
||||
expect(getPdfCjkFallbackFontFamily("Noto Sans SC")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("getPdfFallbackFontFamilies", () => {
|
||||
it("puts the Korean Noto font first for the ko-KR locale (Hangul needs KR, not SC)", () => {
|
||||
expect(getPdfFallbackFontFamilies("Times-Roman", { locale: "ko-KR" })).toEqual(["Noto Serif KR", "Noto Serif SC"]);
|
||||
@@ -234,102 +216,6 @@ describe("getPdfFallbackFontFamilies", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("getFallbackWebFontFamilies", () => {
|
||||
it("returns empty array for standard PDF fonts", () => {
|
||||
expect(getFallbackWebFontFamilies("Helvetica")).toEqual([]);
|
||||
expect(getFallbackWebFontFamilies("Courier")).toEqual([]);
|
||||
expect(getFallbackWebFontFamilies("Times-Roman")).toEqual([]);
|
||||
});
|
||||
|
||||
it("returns the primary CJK web font for non-standard, non-CJK families", () => {
|
||||
// e.g. Roboto (sans-serif) → Noto Sans SC fallback
|
||||
const roboto = getWebFont("Roboto");
|
||||
if (roboto) {
|
||||
expect(getFallbackWebFontFamilies("Roboto")).toEqual(["Noto Sans SC"]);
|
||||
}
|
||||
});
|
||||
|
||||
it("returns empty when family is already its primary CJK fallback", () => {
|
||||
expect(getFallbackWebFontFamilies("Noto Sans SC")).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getLoadableWebFontWeights", () => {
|
||||
it("returns empty array for unknown fonts", () => {
|
||||
expect(getLoadableWebFontWeights("definitely-not-a-font", ["400"])).toEqual([]);
|
||||
});
|
||||
|
||||
it("returns matching weights when preferred weights are available", () => {
|
||||
const roboto = getWebFont("Roboto");
|
||||
if (roboto) {
|
||||
const result = getLoadableWebFontWeights("Roboto", ["400", "700"]);
|
||||
for (const weight of result) {
|
||||
expect(roboto.weights).toContain(weight);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("falls back to default weights when no preferences match", () => {
|
||||
const roboto = getWebFont("Roboto");
|
||||
if (roboto) {
|
||||
const result = getLoadableWebFontWeights("Roboto", ["999"]);
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
}
|
||||
});
|
||||
|
||||
it("deduplicates preferred weights", () => {
|
||||
const roboto = getWebFont("Roboto");
|
||||
if (roboto?.weights.includes("400")) {
|
||||
const result = getLoadableWebFontWeights("Roboto", ["400", "400"]);
|
||||
expect(result).toEqual(["400"]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildResumeFontFamily", () => {
|
||||
it("wraps the primary family in single quotes", () => {
|
||||
const result = buildResumeFontFamily("Roboto");
|
||||
expect(result.startsWith("'Roboto',")).toBe(true);
|
||||
});
|
||||
|
||||
it("includes generic sans-serif fallback by default", () => {
|
||||
const result = buildResumeFontFamily("Roboto");
|
||||
expect(result.endsWith("sans-serif")).toBe(true);
|
||||
});
|
||||
|
||||
it("uses serif fallback for serif-category fonts", () => {
|
||||
expect(buildResumeFontFamily("Times-Roman").endsWith("serif")).toBe(true);
|
||||
});
|
||||
|
||||
it("includes system-ui and Segoe UI fallbacks", () => {
|
||||
const result = buildResumeFontFamily("Roboto");
|
||||
expect(result).toContain("system-ui");
|
||||
expect(result).toContain("Segoe UI");
|
||||
});
|
||||
|
||||
it("includes CJK fallbacks for sans-serif fonts", () => {
|
||||
const result = buildResumeFontFamily("Roboto");
|
||||
expect(result).toContain("Noto Sans SC");
|
||||
});
|
||||
|
||||
it("includes CJK serif fallbacks for serif fonts", () => {
|
||||
const result = buildResumeFontFamily("Times-Roman");
|
||||
expect(result).toContain("Noto Serif SC");
|
||||
});
|
||||
|
||||
it("does not duplicate primary family in fallback list", () => {
|
||||
const result = buildResumeFontFamily("Noto Sans SC");
|
||||
// Family should appear once
|
||||
const occurrences = result.split("Noto Sans SC").length - 1;
|
||||
expect(occurrences).toBe(1);
|
||||
});
|
||||
|
||||
it("escapes single quotes in family names", () => {
|
||||
const result = buildResumeFontFamily("Bob's Font");
|
||||
expect(result).toContain("Bob\\'s Font");
|
||||
});
|
||||
});
|
||||
|
||||
describe("legacy font compatibility (#2989)", () => {
|
||||
it.each([
|
||||
["Times New Roman", "Times-Roman"],
|
||||
|
||||
+4
-111
@@ -3,11 +3,11 @@ import { unique } from "@reactive-resume/utils/field";
|
||||
import { getLocaleScript, isCjkScript } from "@reactive-resume/utils/locale";
|
||||
import webFontListJSON from "./webfontlist.json";
|
||||
|
||||
export type FontCategory = "display" | "handwriting" | "monospace" | "serif" | "sans-serif";
|
||||
type FontCategory = "display" | "handwriting" | "monospace" | "serif" | "sans-serif";
|
||||
export type FontWeight = "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900";
|
||||
export type FontFileWeight = FontWeight | `${FontWeight}italic`;
|
||||
type FontFileWeight = FontWeight | `${FontWeight}italic`;
|
||||
|
||||
export type StandardFont = {
|
||||
type StandardFont = {
|
||||
type: "standard";
|
||||
category: FontCategory;
|
||||
family: string;
|
||||
@@ -23,7 +23,7 @@ export type WebFont = {
|
||||
files: Record<FontFileWeight, string>;
|
||||
};
|
||||
|
||||
export type FontRecord = StandardFont | WebFont;
|
||||
type FontRecord = StandardFont | WebFont;
|
||||
|
||||
const preferredChineseFontFamilies = [
|
||||
"Noto Sans SC",
|
||||
@@ -64,25 +64,6 @@ const fontDisplayNames: Partial<Record<string, string>> = {
|
||||
"ZCOOL QingKe HuangYou": "站酷庆科黄油体",
|
||||
};
|
||||
|
||||
const resumeCjkSansFontFallbacks = [
|
||||
"Noto Sans SC",
|
||||
"PingFang SC",
|
||||
"Hiragino Sans GB",
|
||||
"Microsoft YaHei",
|
||||
"SimHei",
|
||||
"Source Han Sans SC",
|
||||
"WenQuanYi Micro Hei",
|
||||
] as const;
|
||||
|
||||
const resumeCjkSerifFontFallbacks = [
|
||||
"Noto Serif SC",
|
||||
"Songti SC",
|
||||
"SimSun",
|
||||
"Source Han Serif SC",
|
||||
"KaiTi",
|
||||
"FangSong",
|
||||
] as const;
|
||||
|
||||
// Per-script Noto web font, split by serif/sans category. These match the
|
||||
// actual writing system: Hangul lives only in the KR fonts, Kana only in JP,
|
||||
// Arabic glyphs only in the Arabic fonts, etc. — so a Latin or Simplified-
|
||||
@@ -100,24 +81,6 @@ const scriptFonts: Record<Script, { serif: string; sansSerif: string }> = {
|
||||
thai: { serif: "Noto Sans Thai", sansSerif: "Noto Sans Thai" },
|
||||
};
|
||||
|
||||
const genericFontFamilies = new Set([
|
||||
"-apple-system",
|
||||
"BlinkMacSystemFont",
|
||||
"cursive",
|
||||
"emoji",
|
||||
"fantasy",
|
||||
"fangsong",
|
||||
"math",
|
||||
"monospace",
|
||||
"sans-serif",
|
||||
"serif",
|
||||
"system-ui",
|
||||
"ui-monospace",
|
||||
"ui-rounded",
|
||||
"ui-sans-serif",
|
||||
"ui-serif",
|
||||
]);
|
||||
|
||||
export const webFontList = webFontListJSON as WebFont[];
|
||||
export const webFontMap = new Map<string, WebFont>(webFontList.map((font) => [font.family, font]));
|
||||
export const standardFontList = standardPdfFontList.filter((font) => !webFontMap.has(font.family));
|
||||
@@ -131,11 +94,6 @@ function orderFonts(fonts: FontRecord[]) {
|
||||
});
|
||||
}
|
||||
|
||||
function toCSSFontFamilyToken(fontFamily: string) {
|
||||
if (genericFontFamilies.has(fontFamily)) return fontFamily;
|
||||
return `'${fontFamily.replaceAll("\\", "\\\\").replaceAll("'", "\\'")}'`;
|
||||
}
|
||||
|
||||
export const fontList = orderFonts([...standardFontList, ...webFontList]);
|
||||
|
||||
for (const font of fontList) {
|
||||
@@ -182,15 +140,6 @@ export function getFontSearchKeywords(family: string) {
|
||||
);
|
||||
}
|
||||
|
||||
function getCjkFallbacksByCategory(category: FontCategory | null) {
|
||||
return category === "serif" ? resumeCjkSerifFontFallbacks : resumeCjkSansFontFallbacks;
|
||||
}
|
||||
|
||||
function getPrimaryCjkWebFont(family: string) {
|
||||
const category = getFontCategory(family);
|
||||
return category === "serif" ? "Noto Serif SC" : "Noto Sans SC";
|
||||
}
|
||||
|
||||
function getScriptFont(script: Script, category: FontCategory | null) {
|
||||
const variants = scriptFonts[script];
|
||||
return category === "serif" ? variants.serif : variants.sansSerif;
|
||||
@@ -216,13 +165,6 @@ export function sortFontWeights<T extends string>(fontWeights: T[]): T[] {
|
||||
return [...fontWeights].sort((a, b) => Number(a) - Number(b));
|
||||
}
|
||||
|
||||
export function getFallbackWebFontFamilies(family: string) {
|
||||
if (isStandardPdfFontFamily(family)) return [];
|
||||
|
||||
const fallback = getPrimaryCjkWebFont(family);
|
||||
return fallback === family ? [] : [fallback];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ordered stack of Noto web fonts to register as glyph-level
|
||||
* fallbacks for PDF rendering. react-pdf resolves the font per-codepoint
|
||||
@@ -252,52 +194,3 @@ export function getPdfFallbackFontFamilies(
|
||||
.filter((candidate) => candidate !== family)
|
||||
.filter((candidate) => Boolean(getWebFont(candidate)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Back-compat single-font resolver kept for the public `@reactive-resume/fonts`
|
||||
* surface: returns the Simplified Chinese fallback (Noto Sans/Serif SC) for a
|
||||
* family, or `null` when the family already is that fallback.
|
||||
*/
|
||||
export function getPdfCjkFallbackFontFamily(family: string): string | null {
|
||||
const fallback = getPrimaryCjkWebFont(family);
|
||||
if (fallback === family) return null;
|
||||
if (!getWebFont(fallback)) return null;
|
||||
|
||||
return fallback;
|
||||
}
|
||||
|
||||
export function getLoadableWebFontWeights(family: string, preferredWeights: string[]) {
|
||||
const font = webFontMap.get(family);
|
||||
if (!font) return [];
|
||||
|
||||
const availableWeights = new Set<FontWeight>(font.weights);
|
||||
const matchingWeights = unique(preferredWeights).filter((weight): weight is FontWeight =>
|
||||
availableWeights.has(weight as FontWeight),
|
||||
);
|
||||
|
||||
if (matchingWeights.length > 0) return matchingWeights;
|
||||
|
||||
const defaultWeights = ["400", "500", "600", "700"].filter((weight): weight is FontWeight =>
|
||||
availableWeights.has(weight as FontWeight),
|
||||
);
|
||||
if (defaultWeights.length > 0) return defaultWeights.slice(0, 2);
|
||||
|
||||
return font.weights.slice(0, 2);
|
||||
}
|
||||
|
||||
export function buildResumeFontFamily(fontFamily: string) {
|
||||
const category = getFontCategory(fontFamily);
|
||||
const genericFallback = category === "serif" ? "serif" : "sans-serif";
|
||||
|
||||
return unique([
|
||||
fontFamily,
|
||||
...getCjkFallbacksByCategory(category),
|
||||
"system-ui",
|
||||
"-apple-system",
|
||||
"BlinkMacSystemFont",
|
||||
"Segoe UI",
|
||||
genericFallback,
|
||||
])
|
||||
.map(toCSSFontFamilyToken)
|
||||
.join(", ");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user