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:
Amruth Pillai
2026-07-03 20:03:50 +02:00
parent 2a80e6a1df
commit a4999c04af
107 changed files with 1222 additions and 3894 deletions
+3 -5
View File
@@ -5,11 +5,9 @@
"private": true,
"exports": {
"./browser": "./src/browser.tsx",
"./context": "./src/context.tsx",
"./document": "./src/document.tsx",
"./section-title": "./src/section-title.ts",
"./server": "./src/server.tsx",
"./templates": "./src/templates/index.ts"
"./server": "./src/server.tsx"
},
"imports": {
"#react-pdf-renderer": "@react-pdf/renderer"
@@ -27,7 +25,7 @@
"@reactive-resume/schema": "workspace:*",
"@reactive-resume/utils": "workspace:*",
"cjk-regex": "^3.4.0",
"node-html-parser": "^8.0.3",
"node-html-parser": "^8.0.4",
"phosphor-icons-react-pdf": "^0.1.3",
"react": "^19.2.7",
"react-pdf-html": "^2.1.5",
@@ -37,7 +35,7 @@
"@react-pdf/types": "^2.11.1",
"@reactive-resume/config": "workspace:*",
"@types/react": "^19.2.17",
"@typescript/native-preview": "7.0.0-dev.20260628.1",
"@typescript/native-preview": "7.0.0-dev.20260703.1",
"typescript": "^6.0.3"
}
}
+1 -1
View File
@@ -2,8 +2,8 @@ import type { ResumeData } from "@reactive-resume/schema/resume/data";
import type { Template } from "@reactive-resume/schema/templates";
import type { SectionTitleResolver } from "./section-title";
import { createElement } from "react";
import { pdf } from "#react-pdf-renderer";
import { ResumeDocument } from "./document";
import { pdf } from "./renderer";
type CreateResumePdfBlobOptions = {
data: ResumeData;
+1 -1
View File
@@ -11,7 +11,7 @@ type RenderContextValue = ResumeData & {
const RenderContext = createContext<RenderContextValue | null>(null);
export type RenderProviderProps = {
type RenderProviderProps = {
data: ResumeData;
resolveSectionTitle?: SectionTitleResolver | undefined;
children: ReactNode;
+2 -2
View File
@@ -4,9 +4,9 @@ import type { Locale } from "@reactive-resume/utils/locale";
import type { ComponentType } from "react";
import type { SectionTitleResolver } from "./section-title";
import { useMemo } from "react";
import { Document } from "#react-pdf-renderer";
import { RenderProvider } from "./context";
import { registerFonts, resumeContentContainsCJK, resumeContentScripts } from "./hooks/use-register-fonts";
import { Document } from "./renderer";
import { getTemplatePage } from "./templates";
export type TemplatePageProps = {
@@ -16,7 +16,7 @@ export type TemplatePageProps = {
export type TemplatePage = ComponentType<TemplatePageProps>;
export type ResumeDocumentProps = {
type ResumeDocumentProps = {
data: ResumeData;
template: Template;
resolveSectionTitle?: SectionTitleResolver | undefined;
@@ -2,7 +2,7 @@ import type { ResumeData, Typography } from "@reactive-resume/schema/resume/data
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { getWebFontSource } from "@reactive-resume/fonts";
import { defaultResumeData } from "@reactive-resume/schema/resume/default";
import { Font } from "../renderer";
import { Font } from "#react-pdf-renderer";
const typography = {
body: {
+2 -2
View File
@@ -11,7 +11,7 @@ import {
sortFontWeights,
} from "@reactive-resume/fonts";
import { isCJKLocale } from "@reactive-resume/utils/locale";
import { Font } from "../renderer";
import { Font } from "#react-pdf-renderer";
type FontWeightRange = {
lowest: number;
@@ -26,7 +26,7 @@ const preferredFallbackFontWeights = ["400", "700", "600", "500"] satisfies Font
// `fontFamily` is widened to `string | string[]` so react-pdf can do
// glyph-level font fallback for CJK characters (#2986).
export type PdfTypography = Omit<Typography, "body" | "heading"> & {
type PdfTypography = Omit<Typography, "body" | "heading"> & {
body: Omit<Typography["body"], "fontFamily"> & { fontFamily: string | string[] };
heading: Omit<Typography["heading"], "fontFamily"> & { fontFamily: string | string[] };
};
-12
View File
@@ -1,12 +0,0 @@
export {
Document,
Font,
Image,
Link,
Page,
pdf,
renderToBuffer,
StyleSheet,
Text,
View,
} from "#react-pdf-renderer";
+1 -1
View File
@@ -1,6 +1,6 @@
import type { ResumeData, SectionType } from "@reactive-resume/schema/resume/data";
export type SectionTitleResolverInput = {
type SectionTitleResolverInput = {
sectionId: string;
locale: string;
sectionKind: "summary" | "builtin" | "custom";
+1 -1
View File
@@ -2,8 +2,8 @@ import type { ResumeData } from "@reactive-resume/schema/resume/data";
import type { Template } from "@reactive-resume/schema/templates";
import type { SectionTitleResolver } from "./section-title";
import { createElement } from "react";
import { renderToBuffer } from "#react-pdf-renderer";
import { ResumeDocument } from "./document";
import { renderToBuffer } from "./renderer";
type CreateResumePdfFileOptions = {
data: ResumeData;
@@ -9,8 +9,8 @@ import type {
} from "../shared/types";
import { Fragment, useMemo } from "react";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { filterSections } from "../shared/filtering";
@@ -3,8 +3,8 @@ import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateStyleSlots } from "../shared/types";
import { useMemo } from "react";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { filterSections } from "../shared/filtering";
@@ -3,8 +3,8 @@ import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateStyleContext, TemplateStyleSlots } from "../shared/types";
import { Fragment, useMemo } from "react";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { filterSections } from "../shared/filtering";
@@ -2,9 +2,10 @@ import type { Style } from "@react-pdf/types";
import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateFeatures, TemplateStyleContext, TemplateStyleSlots } from "../shared/types";
import { useMemo } from "react";
import { parseColorString, rgbaStringToHex } from "@reactive-resume/utils/color";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { getPrimaryTint } from "../shared/color-helpers";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { getFeaturedSummaryLayout } from "../shared/featured-summary";
@@ -161,16 +162,6 @@ const Header = ({ styles, colors }: DitgarHeaderProps) => {
);
};
const getPrimaryTint = (primaryColor: string, opacity: number): string => {
const primary = parseColorString(primaryColor);
if (!primary) return rgbaStringToHex(primaryColor);
const alpha = Math.max(0, Math.min(1, primary.a * opacity));
return `rgba(${primary.r}, ${primary.g}, ${primary.b}, ${alpha})`;
};
const useDitgarTemplate = (): DitgarTemplate => {
const { picture, metadata, rtl } = useRender();
@@ -3,8 +3,8 @@ import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateStyleContext, TemplateStyleSlots } from "../shared/types";
import { Fragment, useMemo } from "react";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { filterSections } from "../shared/filtering";
@@ -2,9 +2,10 @@ import type { Style } from "@react-pdf/types";
import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateStyleContext, TemplateStyleSlots } from "../shared/types";
import { Fragment, useMemo } from "react";
import { parseColorString, rgbaStringToHex } from "@reactive-resume/utils/color";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { getPrimaryTint } from "../shared/color-helpers";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { getFeaturedSummaryLayout } from "../shared/featured-summary";
@@ -158,16 +159,6 @@ const Header = ({ styles, colors }: GengarHeaderProps) => {
);
};
const getPrimaryTint = (primaryColor: string, opacity: number): string => {
const primary = parseColorString(primaryColor);
if (!primary) return rgbaStringToHex(primaryColor);
const alpha = Math.max(0, Math.min(1, primary.a * opacity));
return `rgba(${primary.r}, ${primary.g}, ${primary.b}, ${alpha})`;
};
const useGengarTemplate = (): GengarTemplate => {
const { picture, metadata, rtl } = useRender();
@@ -2,9 +2,10 @@ import type { Style } from "@react-pdf/types";
import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateFeatures, TemplateStyleContext, TemplateStyleSlots } from "../shared/types";
import { useMemo } from "react";
import { parseColorString, rgbaStringToHex } from "@reactive-resume/utils/color";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { getPrimaryTint } from "../shared/color-helpers";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { filterSections } from "../shared/filtering";
@@ -138,16 +139,6 @@ const Header = ({ styles }: GlalieHeaderProps) => {
);
};
const getPrimaryTint = (primaryColor: string, opacity: number): string => {
const primary = parseColorString(primaryColor);
if (!primary) return rgbaStringToHex(primaryColor);
const alpha = Math.max(0, Math.min(1, primary.a * opacity));
return `rgba(${primary.r}, ${primary.g}, ${primary.b}, ${alpha})`;
};
const useGlalieTemplate = (): GlalieTemplate => {
const { picture, metadata, rtl } = useRender();
+1 -19
View File
@@ -34,24 +34,6 @@ export const templatePages: Partial<Record<Template, TemplatePage>> = {
scizor: ScizorPage,
};
export const defaultTemplatePage = AzurillPage;
const defaultTemplatePage = AzurillPage;
export const getTemplatePage = (template: Template): TemplatePage => templatePages[template] ?? defaultTemplatePage;
export {
AzurillPage,
BronzorPage,
ChikoritaPage,
DitgarPage,
DittoPage,
GengarPage,
GlaliePage,
KakunaPage,
LaprasPage,
LeafishPage,
MeowthPage,
OnyxPage,
PikachuPage,
RhyhornPage,
ScizorPage,
};
@@ -3,8 +3,8 @@ import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateStyleContext, TemplateStyleSlots } from "../shared/types";
import { useMemo } from "react";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { filterSections } from "../shared/filtering";
@@ -3,8 +3,8 @@ import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateStyleContext, TemplateStyleSlots } from "../shared/types";
import { useMemo } from "react";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { filterSections } from "../shared/filtering";
@@ -2,9 +2,10 @@ import type { Style } from "@react-pdf/types";
import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateStyleContext, TemplateStyleSlots } from "../shared/types";
import { useMemo } from "react";
import { parseColorString, rgbaStringToHex } from "@reactive-resume/utils/color";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { getPrimaryTint as getPrimaryAlpha } from "../shared/color-helpers";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { filterSections } from "../shared/filtering";
@@ -134,16 +135,6 @@ const Header = ({ styles }: LeafishHeaderProps) => {
);
};
const getPrimaryAlpha = (primaryColor: string, opacity: number): string => {
const primary = parseColorString(primaryColor);
if (!primary) return rgbaStringToHex(primaryColor);
const alpha = Math.max(0, Math.min(1, primary.a * opacity));
return `rgba(${primary.r}, ${primary.g}, ${primary.b}, ${alpha})`;
};
const useLeafishTemplate = (): LeafishTemplate => {
const { picture, metadata, rtl } = useRender();
@@ -3,8 +3,8 @@ import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateFeatures, TemplateStyleContext, TemplateStyleSlots } from "../shared/types";
import { useMemo } from "react";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { filterSections } from "../shared/filtering";
+1 -1
View File
@@ -3,8 +3,8 @@ import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateStyleContext, TemplateStyleSlots } from "../shared/types";
import { useMemo } from "react";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { filterSections } from "../shared/filtering";
@@ -3,8 +3,8 @@ import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateFeatures, TemplateStyleContext, TemplateStyleSlots } from "../shared/types";
import { useMemo } from "react";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { filterSections } from "../shared/filtering";
@@ -4,8 +4,8 @@ import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateStyleContext, TemplateStyleSlots } from "../shared/types";
import { useMemo } from "react";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { filterSections } from "../shared/filtering";
@@ -3,8 +3,8 @@ import type { TemplatePageProps } from "../../document";
import type { TemplateColorRoles, TemplateStyleContext, TemplateStyleSlots } from "../shared/types";
import { useMemo } from "react";
import { rgbaStringToHex } from "@reactive-resume/utils/color";
import { Image, Page, StyleSheet, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Image, Page, StyleSheet, View } from "../../renderer";
import { CustomFieldContactItem, WebsiteContactItem } from "../shared/contact-item";
import { TemplateProvider } from "../shared/context";
import { filterSections } from "../shared/filtering";
@@ -0,0 +1,12 @@
import { parseColorString, rgbaStringToHex } from "@reactive-resume/utils/color";
/** Returns the primary color as an `rgba()` string at the given opacity, falling back to a hex color. */
export const getPrimaryTint = (primaryColor: string, opacity: number): string => {
const primary = parseColorString(primaryColor);
if (!primary) return rgbaStringToHex(primaryColor);
const alpha = Math.max(0, Math.min(1, primary.a * opacity));
return `rgba(${primary.r}, ${primary.g}, ${primary.b}, ${alpha})`;
};
+1 -1
View File
@@ -16,7 +16,7 @@ type SectionTimelineInput = {
columns: unknown;
};
export type SectionItemsLayout = {
type SectionItemsLayout = {
columns: number;
containerStyle: Style;
rowStyle: Style | undefined;
@@ -1,7 +1,7 @@
import type { Style } from "@react-pdf/types";
import type { CustomField } from "@reactive-resume/schema/resume/data";
import type { IconName } from "phosphor-icons-react-pdf/dynamic";
import { View } from "../../renderer";
import { View } from "#react-pdf-renderer";
import { getCustomFieldLinkUrl, getWebsiteDisplayText } from "./contact";
import { Icon, Link, Text } from "./primitives";
@@ -1,8 +1,8 @@
import type { Style } from "@react-pdf/types";
import type { IconName } from "phosphor-icons-react-pdf/dynamic";
import { resolveLevelDisplaySizes } from "@reactive-resume/schema/resume/level-display-sizes";
import { View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { View } from "../../renderer";
import { useSectionStyleRule, useTemplateIconSlot, useTemplateStyle } from "./context";
import { resolveStyleFontSize } from "./icon-size";
import { getTemplateMetrics } from "./metrics";
+1 -1
View File
@@ -2,7 +2,7 @@ import type { ResumeData } from "@reactive-resume/schema/resume/data";
type PageMetricsInput = Pick<ResumeData["metadata"]["page"], "gapX" | "gapY" | "marginX" | "marginY">;
export type TemplateMetrics = {
type TemplateMetrics = {
page: {
paddingHorizontal: number;
paddingVertical: number;
@@ -2,8 +2,8 @@ import type { Style } from "@react-pdf/types";
import type { ComponentProps } from "react";
import type { StyleInput } from "./styles";
import { Icon as PhosphorIcon } from "phosphor-icons-react-pdf/dynamic";
import { Link as PdfLink, Text as PdfText, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Link as PdfLink, Text as PdfText, View } from "../../renderer";
import { useSectionStyleRule, useTemplateIconSlot, useTemplateStyle } from "./context";
import { resolveIconSize } from "./icon-size";
import { safeTextStyle } from "./safe-text-style";
@@ -1,7 +1,7 @@
import type { ReactElement } from "react";
import { describe, expect, it } from "vitest";
import { renderHtml } from "react-pdf-html";
import { Text as PdfText } from "../../renderer";
import { Text as PdfText } from "#react-pdf-renderer";
import { convertPseudoBulletParagraphs, normalizeRichTextHtml, richTextMarkClassName } from "./rich-text-html";
type PdfElement = ReactElement<{ children?: unknown; element?: { tag: string } }>;
@@ -1,7 +1,7 @@
import type { Style } from "@react-pdf/types";
import type { ReactNode } from "react";
import { createElement } from "react";
import { Text as PdfText } from "../../renderer";
import { Text as PdfText } from "#react-pdf-renderer";
import {
getRichTextEdgeTrimStyle,
isRichTextElementInsideListItem,
@@ -2,8 +2,8 @@ import type { Style } from "@react-pdf/types";
import type { ReactElement, ReactNode } from "react";
import { cloneElement, isValidElement } from "react";
import { Html } from "react-pdf-html";
import { Text as PdfText, View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { Text as PdfText, View } from "../../renderer";
import { useSectionStyleRule, useTemplateStyle } from "./context";
import { convertPseudoBulletParagraphs, normalizeRichTextHtml } from "./rich-text-html";
import { renderRichTextParagraph, toRichTextStyleArray } from "./rich-text-renderers";
+1 -1
View File
@@ -1,6 +1,6 @@
import type { Style } from "@react-pdf/types";
export type RtlStyleHelpers = {
type RtlStyleHelpers = {
rtl: boolean;
pageDirection: "ltr" | "rtl";
row: "row" | "row-reverse";
@@ -21,8 +21,8 @@ import type { StyleInput, TemplatePlacement } from "./styles";
import type { CustomItemSection, ItemSection } from "./types";
import { Children, createContext, isValidElement, use } from "react";
import { match } from "ts-pattern";
import { View } from "#react-pdf-renderer";
import { useRender } from "../../context";
import { View } from "../../renderer";
import { getResumeSectionIcon } from "../../section-icon";
import { getResumeSectionTitle } from "../../section-title";
import { getSectionItemRows, getSectionItemsLayout, shouldUseSectionTimeline } from "./columns";
+1 -1
View File
@@ -33,7 +33,7 @@ export const mergeLinkStyles = (options: LinkStyleOptions = {}, ...styles: Style
export const headerNameLineHeight = 1.3;
export type ResolvePlacementColorOptions = {
type ResolvePlacementColorOptions = {
placement: TemplatePlacement;
defaultForeground: string;
sidebarForeground?: string | undefined;