refactor(utils): replace MONTH_NAMES array, drop @uiw/color-convert, use z.enum for localeSchema

Finding 1: Replace hand-rolled MONTH_NAMES[12] array with Intl.DateTimeFormat("en-US", {month:"long"}).
Finding 2: Drop @uiw/color-convert fallback — parseColorString already rejects the same inputs, return "#000000" instead. Remove dep from utils and server package.json.
Finding 3: Replace 56 z.literal calls in z.union with z.enum([...]); identical parse behavior and inferred type.

Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
This commit is contained in:
Amruth Pillai
2026-07-04 20:53:51 +02:00
parent 5226f04e86
commit a5935dee0f
7 changed files with 70 additions and 86 deletions
-1
View File
@@ -45,7 +45,6 @@
"@reactive-resume/utils": "workspace:*", "@reactive-resume/utils": "workspace:*",
"@sindresorhus/slugify": "^3.0.0", "@sindresorhus/slugify": "^3.0.0",
"@t3-oss/env-core": "^0.13.11", "@t3-oss/env-core": "^0.13.11",
"@uiw/color-convert": "^2.10.3",
"ai": "^7.0.15", "ai": "^7.0.15",
"bcrypt": "^6.0.0", "bcrypt": "^6.0.0",
"better-auth": "1.6.23", "better-auth": "1.6.23",
-1
View File
@@ -28,7 +28,6 @@
"@orpc/experimental-ratelimit", "@orpc/experimental-ratelimit",
"@sindresorhus/slugify", "@sindresorhus/slugify",
"@t3-oss/env-core", "@t3-oss/env-core",
"@uiw/color-convert",
"ai", "ai",
"bcrypt", "bcrypt",
"cjk-regex", "cjk-regex",
-1
View File
@@ -27,7 +27,6 @@
}, },
"dependencies": { "dependencies": {
"@sindresorhus/slugify": "^3.0.0", "@sindresorhus/slugify": "^3.0.0",
"@uiw/color-convert": "^2.10.3",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"tailwind-merge": "^3.6.0", "tailwind-merge": "^3.6.0",
"unique-names-generator": "^4.7.1", "unique-names-generator": "^4.7.1",
+4 -6
View File
@@ -1,19 +1,17 @@
import type { ColorResult } from "@uiw/color-convert"; type ParsedColor = { r: number; g: number; b: number; a: number };
import { hsvaToHex, rgbaStringToHsva } from "@uiw/color-convert";
export function rgbaStringToHex(rgba: string): string { export function rgbaStringToHex(rgba: string): string {
const color = parseColorString(rgba); const color = parseColorString(rgba);
if (color) return `#${toHexComponent(color.r)}${toHexComponent(color.g)}${toHexComponent(color.b)}`; if (color) return `#${toHexComponent(color.r)}${toHexComponent(color.g)}${toHexComponent(color.b)}`;
// ponytail: unrecognized format → black; same result the prior @uiw/color-convert fallback produced
const hsva = rgbaStringToHsva(rgba); return "#000000";
return hsvaToHex(hsva);
} }
function toHexComponent(value: number): string { function toHexComponent(value: number): string {
return Math.max(0, Math.min(255, value)).toString(16).padStart(2, "0"); return Math.max(0, Math.min(255, value)).toString(16).padStart(2, "0");
} }
export function parseColorString(value: string): ColorResult["rgba"] | null { export function parseColorString(value: string): ParsedColor | null {
const trimmed = value.trim(); const trimmed = value.trim();
// Parse rgb/rgba colors // Parse rgb/rgba colors
+9 -15
View File
@@ -1,17 +1,11 @@
const MONTH_NAMES = [ // ponytail: Intl replaces the 12-line MONTH_NAMES array; pinned to en-US so output is stable
"January", const fmt = new Intl.DateTimeFormat("en-US", { month: "long" });
"February",
"March", function getMonthName(month: string | undefined): string {
"April", const index = Number.parseInt(month ?? "1", 10) - 1;
"May", if (index < 0 || index > 11) return "undefined";
"June", return fmt.format(new Date(2000, index, 1));
"July", }
"August",
"September",
"October",
"November",
"December",
];
/** /**
* Formats a partial ISO 8601 date string (YYYY, YYYY-MM, or YYYY-MM-DD) * Formats a partial ISO 8601 date string (YYYY, YYYY-MM, or YYYY-MM-DD)
@@ -22,7 +16,7 @@ export function formatDate(date: string, includeDay = false): string {
if (parts.length >= 2) { if (parts.length >= 2) {
const [year, month] = parts; const [year, month] = parts;
const monthName = MONTH_NAMES[Number.parseInt(month ?? "1", 10) - 1]; const monthName = getMonthName(month);
if (parts.length === 3 && includeDay) { if (parts.length === 3 && includeDay) {
return `${monthName} ${parts[2]}, ${year}`; return `${monthName} ${parts[2]}, ${year}`;
+57 -56
View File
@@ -1,61 +1,62 @@
import z from "zod"; import z from "zod";
export const localeSchema = z.union([ // ponytail: z.enum([...]) over 56 z.literal calls; same parse behavior, same inferred union type
z.literal("af-ZA"), export const localeSchema = z.enum([
z.literal("am-ET"), "af-ZA",
z.literal("ar-SA"), "am-ET",
z.literal("az-AZ"), "ar-SA",
z.literal("bg-BG"), "az-AZ",
z.literal("bn-BD"), "bg-BG",
z.literal("ca-ES"), "bn-BD",
z.literal("cs-CZ"), "ca-ES",
z.literal("da-DK"), "cs-CZ",
z.literal("de-DE"), "da-DK",
z.literal("el-GR"), "de-DE",
z.literal("en-US"), "el-GR",
z.literal("en-GB"), "en-US",
z.literal("es-ES"), "en-GB",
z.literal("fa-IR"), "es-ES",
z.literal("fi-FI"), "fa-IR",
z.literal("fr-FR"), "fi-FI",
z.literal("he-IL"), "fr-FR",
z.literal("hi-IN"), "he-IL",
z.literal("hu-HU"), "hi-IN",
z.literal("id-ID"), "hu-HU",
z.literal("it-IT"), "id-ID",
z.literal("ja-JP"), "it-IT",
z.literal("km-KH"), "ja-JP",
z.literal("kn-IN"), "km-KH",
z.literal("ko-KR"), "kn-IN",
z.literal("lt-LT"), "ko-KR",
z.literal("lv-LV"), "lt-LT",
z.literal("ml-IN"), "lv-LV",
z.literal("mr-IN"), "ml-IN",
z.literal("ms-MY"), "mr-IN",
z.literal("ne-NP"), "ms-MY",
z.literal("nl-NL"), "ne-NP",
z.literal("no-NO"), "nl-NL",
z.literal("or-IN"), "no-NO",
z.literal("pl-PL"), "or-IN",
z.literal("pt-BR"), "pl-PL",
z.literal("pt-PT"), "pt-BR",
z.literal("ro-RO"), "pt-PT",
z.literal("ru-RU"), "ro-RO",
z.literal("sk-SK"), "ru-RU",
z.literal("sl-SI"), "sk-SK",
z.literal("sq-AL"), "sl-SI",
z.literal("sr-SP"), "sq-AL",
z.literal("sv-SE"), "sr-SP",
z.literal("ta-IN"), "sv-SE",
z.literal("te-IN"), "ta-IN",
z.literal("th-TH"), "te-IN",
z.literal("tr-TR"), "th-TH",
z.literal("uk-UA"), "tr-TR",
z.literal("uz-UZ"), "uk-UA",
z.literal("vi-VN"), "uz-UZ",
z.literal("zh-CN"), "vi-VN",
z.literal("zh-TW"), "zh-CN",
z.literal("zu-ZA"), "zh-TW",
"zu-ZA",
]); ]);
export type Locale = z.infer<typeof localeSchema>; export type Locale = z.infer<typeof localeSchema>;
-6
View File
@@ -165,9 +165,6 @@ importers:
'@t3-oss/env-core': '@t3-oss/env-core':
specifier: ^0.13.11 specifier: ^0.13.11
version: 0.13.11(typescript@6.0.3)(zod@4.4.3) version: 0.13.11(typescript@6.0.3)(zod@4.4.3)
'@uiw/color-convert':
specifier: ^2.10.3
version: 2.10.3(@babel/runtime@7.29.7)
ai: ai:
specifier: ^7.0.15 specifier: ^7.0.15
version: 7.0.15(zod@4.4.3) version: 7.0.15(zod@4.4.3)
@@ -1092,9 +1089,6 @@ importers:
'@sindresorhus/slugify': '@sindresorhus/slugify':
specifier: ^3.0.0 specifier: ^3.0.0
version: 3.0.0 version: 3.0.0
'@uiw/color-convert':
specifier: ^2.10.3
version: 2.10.3(@babel/runtime@7.29.7)
clsx: clsx:
specifier: ^2.1.1 specifier: ^2.1.1
version: 2.1.1 version: 2.1.1