diff --git a/README.md b/README.md index be28112..191f406 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A comprehensive collection of TypeScript utility functions for modern web develo ## Features -- ๐Ÿ› ๏ธ **Comprehensive**: String, object, cookie, number, validation, and common utilities +- ๐Ÿ› ๏ธ **Comprehensive**: String, object, cookie, number, validation, format, and common utilities - ๐Ÿ“ฆ **Tree-shakable**: Import only what you need - ๐Ÿ”’ **Type-safe**: Full TypeScript support with type definitions - โšก **Lightweight**: Minimal dependencies and optimized for performance @@ -30,6 +30,7 @@ import { numberUtil, validationUtil, commonUtil, + formatUtil, } from "kr-corekit"; // String utilities @@ -69,6 +70,8 @@ await commonUtil.sleep(1000); // Pauses execution for 1 second // Cookie utilities cookieUtil.setCookie("theme", "dark"); const theme = cookieUtil.getCookie("theme"); +// Format utilities +const formattedPhone = formatUtil.formatPhoneNumber("01012345678"); // "010-1234-5678" ``` ## API Reference @@ -90,6 +93,10 @@ const theme = cookieUtil.getCookie("theme"); - `subtract(...numbers: number[]): number` - Calculates subtraction of numbers - `multiply(...numbers: number[]): number` - Calculates multiplication of numbers +### FormatUtil + +- `formatPhoneNumber(phone: string): string` - Formats a phone number string to a standard format (e.g., "010-1234-5678") + ### ValidationUtil - `checkEmail(email: string): boolean` - Validates email format diff --git a/package/formatUtil/formatPhoneNumber/index.test.ts b/package/formatUtil/formatPhoneNumber/index.test.ts new file mode 100644 index 0000000..b7e7781 --- /dev/null +++ b/package/formatUtil/formatPhoneNumber/index.test.ts @@ -0,0 +1,71 @@ +import { describe, expect, test } from "vitest"; +import formatPhoneNumber from "."; + +describe("formatPhoneNumber", () => { + describe("ํœด๋Œ€ํฐ ๋ฒˆํ˜ธ", () => { + test("11์ž๋ฆฌ ํœด๋Œ€ํฐ ๋ฒˆํ˜ธ์— ํ•˜์ดํ”ˆ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€ํ•œ๋‹ค (010)", () => { + expect(formatPhoneNumber("01012345678")).toBe("010-1234-5678"); + }); + + test("11์ž๋ฆฌ ํœด๋Œ€ํฐ ๋ฒˆํ˜ธ์— ํ•˜์ดํ”ˆ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€ํ•œ๋‹ค (011)", () => { + expect(formatPhoneNumber("01198765432")).toBe("011-9876-5432"); + }); + + test("์ค‘๊ฐ„์— ๊ณต๋ฐฑ์ด๋‚˜ ํ•˜์ดํ”ˆ์ด ์žˆ์–ด๋„ ์ˆซ์ž๋ฅผ ์ œ์™ธํ•˜๊ณ  ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•œ๋‹ค", () => { + expect(formatPhoneNumber("010-1234 5678")).toBe("010-1234-5678"); + }); + }); + + describe("์ง€์—ญ๋ฒˆํ˜ธ", () => { + test("์„œ์šธ ์ง€์—ญ๋ฒˆํ˜ธ(02) 9์ž๋ฆฌ์— ํ•˜์ดํ”ˆ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€ํ•œ๋‹ค", () => { + expect(formatPhoneNumber("021234567")).toBe("02-123-4567"); + }); + + test("์„œ์šธ ์ง€์—ญ๋ฒˆํ˜ธ(02) 10์ž๋ฆฌ์— ํ•˜์ดํ”ˆ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€ํ•œ๋‹ค", () => { + expect(formatPhoneNumber("0212345678")).toBe("02-1234-5678"); + }); + + test("์„œ์šธ ์™ธ ์ง€์—ญ๋ฒˆํ˜ธ(031) 10์ž๋ฆฌ์— ํ•˜์ดํ”ˆ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€ํ•œ๋‹ค", () => { + expect(formatPhoneNumber("0311234567")).toBe("031-123-4567"); + }); + + test("์„œ์šธ ์™ธ ์ง€์—ญ๋ฒˆํ˜ธ(054) 10์ž๋ฆฌ์— ํ•˜์ดํ”ˆ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€ํ•œ๋‹ค", () => { + expect(formatPhoneNumber("0541234567")).toBe("054-123-4567"); + }); + }); + + describe("๋Œ€ํ‘œ๋ฒˆํ˜ธ", () => { + test("8์ž๋ฆฌ ๋Œ€ํ‘œ๋ฒˆํ˜ธ(1588)์— ํ•˜์ดํ”ˆ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€ํ•œ๋‹ค", () => { + expect(formatPhoneNumber("15881234")).toBe("1588-1234"); + }); + + test("8์ž๋ฆฌ ๋Œ€ํ‘œ๋ฒˆํ˜ธ(1670)์— ํ•˜์ดํ”ˆ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€ํ•œ๋‹ค", () => { + expect(formatPhoneNumber("16709876")).toBe("1670-9876"); + }); + }); + + describe("์˜ˆ์™ธ ์ผ€์ด์Šค", () => { + test("๋นˆ ๋ฌธ์ž์—ด์„ ์ž…๋ ฅํ•˜๋ฉด ๋นˆ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค", () => { + expect(formatPhoneNumber("")).toBe(""); + }); + + test("null ๋˜๋Š” undefined๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๋นˆ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค", () => { + // @ts-ignore + expect(formatPhoneNumber(null)).toBe(""); + // @ts-ignore + expect(formatPhoneNumber(undefined)).toBe(""); + }); + + test("์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๋ฌธ์ž๊ฐ€ ํฌํ•จ๋œ ๊ฒฝ์šฐ, ํ•ด๋‹น ๋ฌธ์ž๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ํฌ๋งทํŒ…ํ•œ๋‹ค", () => { + expect(formatPhoneNumber("010-abcd-1234-efg-5678")).toBe("010-1234-5678"); + }); + + test("์–ด๋–ค ํ˜•์‹์—๋„ ๋งž์ง€ ์•Š๋Š” ์งง์€ ๊ธธ์ด๋ผ๋ฉด ์ˆซ์ž๋งŒ ๋ฐ˜ํ™˜ํ•œ๋‹ค", () => { + expect(formatPhoneNumber("12345")).toBe("12345"); + }); + + test("์–ด๋–ค ํ˜•์‹์—๋„ ๋งž์ง€ ์•Š๋Š” ๊ธด ๊ธธ์ด๋ผ๋ฉด ์ˆซ์ž๋งŒ ๋ฐ˜ํ™˜ํ•œ๋‹ค", () => { + expect(formatPhoneNumber("0101234567890")).toBe("0101234567890"); + }); + }); +}); diff --git a/package/formatUtil/formatPhoneNumber/index.ts b/package/formatUtil/formatPhoneNumber/index.ts new file mode 100644 index 0000000..8f4d4ad --- /dev/null +++ b/package/formatUtil/formatPhoneNumber/index.ts @@ -0,0 +1,51 @@ +// ์ „ํ™”๋ฒˆํ˜ธ ํ˜•์‹ ๊ทœ์น™์„ ๋ฐ์ดํ„ฐ๋กœ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. +const formatRules = [ + // ์„œ์šธ ์ง€์—ญ๋ฒˆํ˜ธ (02) - 9์ž๋ฆฌ + { + prefix: "02", + length: 9, + format: /(\d{2})(\d{3})(\d{4})/, + replacement: "$1-$2-$3", + }, + // ์„œ์šธ ์ง€์—ญ๋ฒˆํ˜ธ (02) - 10์ž๋ฆฌ + { + prefix: "02", + length: 10, + format: /(\d{2})(\d{4})(\d{4})/, + replacement: "$1-$2-$3", + }, + // 8์ž๋ฆฌ ๋Œ€ํ‘œ๋ฒˆํ˜ธ (1588, 1670 ๋“ฑ) + { + length: 8, + format: /(\d{4})(\d{4})/, + replacement: "$1-$2", + }, + // ์ผ๋ฐ˜ ์ง€์—ญ๋ฒˆํ˜ธ (031, 054 ๋“ฑ) + { + length: 10, + format: /(\d{3})(\d{3})(\d{4})/, + replacement: "$1-$2-$3", + }, + // ํœด๋Œ€ํฐ ๋ฒˆํ˜ธ + { + length: 11, + format: /(\d{3})(\d{4})(\d{4})/, + replacement: "$1-$2-$3", + }, +]; + +export default function formatPhoneNumber(phoneNumber: string): string { + if (!phoneNumber) return ""; + + const digitsOnly = phoneNumber.replace(/\D/g, ""); + + const matched = formatRules.find( + (rule) => + (!rule.prefix || digitsOnly.startsWith(rule.prefix)) && + digitsOnly.length === rule.length + ); + + return matched + ? digitsOnly.replace(matched.format, matched.replacement) + : digitsOnly; +} diff --git a/package/formatUtil/index.ts b/package/formatUtil/index.ts new file mode 100644 index 0000000..df16a92 --- /dev/null +++ b/package/formatUtil/index.ts @@ -0,0 +1 @@ +export { default as formatPhoneNumber } from "./formatPhoneNumber"; diff --git a/vitest-report.xml b/vitest-report.xml index ef7f3f4..be02621 100644 --- a/vitest-report.xml +++ b/vitest-report.xml @@ -1,205 +1,235 @@ - - - + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + + + + + + + + + + + - - + + + + + + + + + + - + - + - + + + + + + + + + + + + + - - + + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - - + + - - + + - + + + - + - - - + - - + + - - + + - - + + - + - + - - + + - + - - + + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - +