diff --git a/README.md b/README.md index 5422901..55e4300 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, format, search query, device, type, storage and common utilities +- πŸ› οΈ **Comprehensive**: String, object, cookie, number, validation, format, search query, device, type, storage, easter egg 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 @@ -36,6 +36,7 @@ import { searchQueryUtil, typeUtil, deviceUtil, + easterEggUtil, } from "kr-corekit"; // String utilities @@ -109,6 +110,10 @@ const isNotPlain = typeUtil.isPlainObject(new Date()); // false // Device utilities const device = deviceUtil.getDevice(); // { isMobile: false, isTablet: false, isDesktop: true, isIOS: false, isAndroid: false } +// Easter Egg utilities - Encouraging messages for developers +easterEggUtil.generateHappy(); // [5:28:35 AM] Progress, not perfection. πŸš€ +easterEggUtil.generateHappy("Custom message! πŸŽ‰"); // [5:28:35 AM] Custom message! πŸŽ‰ + // Cookie utilities cookieUtil.setCookie("theme", "dark"); const theme = cookieUtil.getCookie("theme"); @@ -125,12 +130,14 @@ For optimal bundle size, import only the functions you need: import { escapeHtml, unescapeHtml } from "kr-corekit"; import { sum, multiply } from "kr-corekit"; import { clearNullProperties, deepFreeze } from "kr-corekit"; +import { generateHappy } from "kr-corekit"; // Option 2: Import from specific utility modules (good tree-shaking) import { escapeHtml } from "kr-corekit/stringUtil"; import { sum } from "kr-corekit/numberUtil"; import { clearNullProperties } from "kr-corekit/objectUtil"; import { storage } from "kr-corekit/commonUtil"; +import { generateHappy } from "kr-corekit/easterEggUtil"; // Usage remains the same const escaped = escapeHtml("
Hello
"); @@ -228,6 +235,10 @@ storage.set("data", { key: "value" }); - `getDevice(): DeviceInfo` - Detects the user's device environment. Returns information about device type (mobile/tablet/desktop) and operating system (iOS/Android). Uses navigator.userAgent for detection and provides safe fallback for SSR environments. +### EasterEggUtil + +- `generateHappy(message?: string): string` - Displays encouraging messages to developers in the console with colorful styling and timestamps. Randomly selects from 10 motivational default messages or displays a custom message if provided. Returns the message text. Perfect for adding positivity to development workflows, celebrating test success, or boosting morale during debugging sessions. + ### CookieUtil - `setCookie(name: string, value: string, options?: object): void` - Sets a cookie diff --git a/package.json b/package.json index c2e4dbe..3f1f9e8 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,11 @@ "types": "./dist/types/deviceUtil/index.d.ts", "require": "./dist/types/deviceUtil/index.js", "import": "./dist/types/deviceUtil/index.js" + }, + "./easterEggUtil": { + "types": "./dist/types/easterEggUtil/index.d.ts", + "require": "./dist/types/easterEggUtil/index.js", + "import": "./dist/types/easterEggUtil/index.js" } }, "scripts": { diff --git a/package/easterEggUtil/generateHappy/README.md b/package/easterEggUtil/generateHappy/README.md new file mode 100644 index 0000000..f70b3ec --- /dev/null +++ b/package/easterEggUtil/generateHappy/README.md @@ -0,0 +1,134 @@ +# generateHappy() + +Display encouraging messages to developers in the console with colorful styling and timestamps. + +## Features + +- 🎨 **Styled Console Output**: Colorful messages with pink timestamps +- 🎲 **Random Messages**: 10 motivational default messages +- πŸ’¬ **Custom Messages**: Support for user-defined messages +- ⏰ **Timestamps**: Automatic timestamp on each message +- πŸŽ‰ **Developer Friendly**: Spread positivity while coding! + +## Usage + +### Basic Usage (Random Message) + +```typescript +import { generateHappy } from "kr-corekit"; + +// Displays a random encouraging message +generateHappy(); +// Console output: [5:28:35 AM] Progress, not perfection. πŸš€ +``` + +### Custom Message + +```typescript +import { generateHappy } from "kr-corekit"; + +// Display your own encouraging message +const message = generateHappy("Great job on completing the feature! πŸŽ‰"); +console.log(message); // Returns: "Great job on completing the feature! πŸŽ‰" +``` + +### Tree-Shaking Import + +```typescript +// Import from specific module for better tree-shaking +import { generateHappy } from "kr-corekit/easterEggUtil"; + +generateHappy("Keep coding! πŸ’»"); +``` + +## Default Messages + +The function randomly selects from these 10 encouraging messages: + +- "Keep going β€” you're doing great! πŸ’ͺ" +- "Small steps lead to big changes. 🌱" +- "Today is a good day to smile. 😊" +- "You're closer than you think. 🌈" +- "Stay curious, stay kind. ✨" +- "Progress, not perfection. πŸš€" +- "You make the code better. πŸ’»β€οΈ" +- "Breathe. You're doing your best. 🌀️" +- "Trust the process, enjoy the journey. πŸ›€οΈ" +- "Every bug fixed is a victory. πŸžπŸ†" + +## API + +### Parameters + +- `message?: string` - Optional custom message to display. If not provided, a random default message is used. + +### Returns + +- `string` - The message that was displayed in the console + +## Examples + +### In Development Scripts + +Add encouraging messages to your build or development scripts: + +```typescript +import { generateHappy } from "kr-corekit"; + +console.log("Starting development server..."); +generateHappy(); + +// Your server startup code... +``` + +### After Test Success + +Celebrate successful tests: + +```typescript +import { generateHappy } from "kr-corekit"; + +describe("My Tests", () => { + afterAll(() => { + generateHappy("All tests passed! 🎊"); + }); +}); +``` + +### During Debugging + +Add morale boosters during long debugging sessions: + +```typescript +import { generateHappy } from "kr-corekit"; + +function complexDebugFunction() { + // ... debugging code ... + + if (bugFixed) { + generateHappy("Bug squashed! πŸ›βœ¨"); + } +} +``` + +## Console Output + +The function outputs styled messages to the console with: +- **Pink timestamp** (`#ff69b4`) with bold font +- **Dark gray message** (`#333`) with 14px font size + +Example output: +``` +[5:28:35 AM] Progress, not perfection. πŸš€ +``` + +## Notes + +- This is a fun utility to add positivity to your development workflow +- The function uses `console.log` with CSS styling (works in modern browsers) +- Safe to use in development and can be easily removed for production if needed +- The timestamp format depends on the user's locale settings + +## License + +MIT diff --git a/package/easterEggUtil/generateHappy/index.test.ts b/package/easterEggUtil/generateHappy/index.test.ts new file mode 100644 index 0000000..7d1e1f8 --- /dev/null +++ b/package/easterEggUtil/generateHappy/index.test.ts @@ -0,0 +1,68 @@ +import { describe, test, expect, vi, beforeEach, afterEach } from "vitest"; +import generateHappy from "."; + +describe("generateHappy", () => { + let consoleLogSpy: ReturnType; + + beforeEach(() => { + // console.logλ₯Ό spy둜 λŒ€μ²΄ν•˜μ—¬ 호좜 μ—¬λΆ€λ₯Ό μΆ”μ ν•©λ‹ˆλ‹€. + consoleLogSpy = vi.spyOn(console, "log").mockImplementation(() => {}); + }); + + afterEach(() => { + // 각 ν…ŒμŠ€νŠΈ ν›„ spyλ₯Ό λ³΅μ›ν•©λ‹ˆλ‹€. + consoleLogSpy.mockRestore(); + }); + + test("μ‚¬μš©μž μ •μ˜ λ©”μ‹œμ§€κ°€ 없을 λ•Œ κΈ°λ³Έ λ©”μ‹œμ§€ 쀑 ν•˜λ‚˜λ₯Ό λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€", () => { + const result = generateHappy(); + + // κΈ°λ³Έ λ©”μ‹œμ§€ 쀑 ν•˜λ‚˜κ°€ λ°˜ν™˜λ˜λŠ”μ§€ 확인 (ꡬ체적인 λ©”μ‹œμ§€ 배열을 ν•˜λ“œμ½”λ”©ν•˜μ§€ μ•ŠμŒ) + expect(typeof result).toBe("string"); + expect(result.length).toBeGreaterThan(0); + }); + + test("μ‚¬μš©μž μ •μ˜ λ©”μ‹œμ§€λ₯Ό μ „λ‹¬ν•˜λ©΄ ν•΄λ‹Ή λ©”μ‹œμ§€λ₯Ό λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€", () => { + const customMessage = "Custom happy message!"; + const result = generateHappy(customMessage); + + expect(result).toBe(customMessage); + }); + + test("console.logκ°€ ν˜ΈμΆœλ˜μ–΄μ•Ό ν•œλ‹€", () => { + generateHappy("Test message"); + + expect(consoleLogSpy).toHaveBeenCalledTimes(1); + }); + + test("console.log에 νƒ€μž„μŠ€νƒ¬ν”„μ™€ λ©”μ‹œμ§€κ°€ ν¬ν•¨λ˜μ–΄μ•Ό ν•œλ‹€", () => { + const testMessage = "Test message"; + generateHappy(testMessage); + + expect(consoleLogSpy).toHaveBeenCalled(); + const [firstArg] = consoleLogSpy.mock.calls[0]; + + // 첫 번째 μΈμžμ— νƒ€μž„μŠ€νƒ¬ν”„μ™€ λ©”μ‹œμ§€κ°€ ν¬ν•¨λ˜μ–΄ μžˆλŠ”μ§€ 확인 + expect(firstArg).toContain(testMessage); + expect(firstArg).toMatch(/\[\d{1,2}:\d{2}:\d{2}.*\]/); // νƒ€μž„μŠ€νƒ¬ν”„ ν˜•μ‹ 확인 + }); + + test("console.log에 μ˜¬λ°”λ₯Έ μŠ€νƒ€μΌμ΄ μ μš©λ˜μ–΄μ•Ό ν•œλ‹€", () => { + generateHappy("Test message"); + + expect(consoleLogSpy).toHaveBeenCalled(); + const args = consoleLogSpy.mock.calls[0]; + + // μŠ€νƒ€μΌ μΈμžλ“€μ΄ μ˜¬λ°”λ₯΄κ²Œ μ „λ‹¬λ˜μ—ˆλŠ”μ§€ 확인 + expect(args[1]).toBe('color: #ff69b4; font-weight: bold;'); + expect(args[2]).toBe('color: #333; font-size: 14px;'); + }); + + test("μ—¬λŸ¬ 번 ν˜ΈμΆœν•΄λ„ μ •μƒμ μœΌλ‘œ λ™μž‘ν•΄μ•Ό ν•œλ‹€", () => { + generateHappy("Message 1"); + generateHappy("Message 2"); + generateHappy(); + + expect(consoleLogSpy).toHaveBeenCalledTimes(3); + }); +}); diff --git a/package/easterEggUtil/generateHappy/index.ts b/package/easterEggUtil/generateHappy/index.ts new file mode 100644 index 0000000..bee6ffb --- /dev/null +++ b/package/easterEggUtil/generateHappy/index.ts @@ -0,0 +1,27 @@ +export default function generateHappy(message?: string) { + const defaultMessages = [ + "Keep going β€” you're doing great! πŸ’ͺ", + "Small steps lead to big changes. 🌱", + "Today is a good day to smile. 😊", + "You're closer than you think. 🌈", + "Stay curious, stay kind. ✨", + "Progress, not perfection. πŸš€", + "You make the code better. πŸ’»β€οΈ", + "Breathe. You're doing your best. 🌀️", + "Trust the process, enjoy the journey. πŸ›€οΈ", + "Every bug fixed is a victory. πŸžπŸ†", + ]; + + const text = + message ?? + defaultMessages[Math.floor(Math.random() * defaultMessages.length)]; + const timestamp = new Date().toLocaleTimeString(); + + console.log( + `%c[${timestamp}] %c${text}`, + 'color: #ff69b4; font-weight: bold;', + 'color: #333; font-size: 14px;' + ); + + return text; +} diff --git a/package/easterEggUtil/index.ts b/package/easterEggUtil/index.ts new file mode 100644 index 0000000..adba2e9 --- /dev/null +++ b/package/easterEggUtil/index.ts @@ -0,0 +1 @@ +export { default as generateHappy } from "./generateHappy"; diff --git a/package/index.ts b/package/index.ts index 40a1131..f1d66de 100644 --- a/package/index.ts +++ b/package/index.ts @@ -9,6 +9,7 @@ export * as searchQueryUtil from "./searchQueryUtil"; export * as typeUtil from "./typeUtil"; export * as formatUtil from "./formatUtil"; export * as deviceUtil from "./deviceUtil"; +export * as easterEggUtil from "./easterEggUtil"; // κ°œλ³„ ν•¨μˆ˜μ— λŒ€ν•œ 읡슀포트 μ§„ν–‰ export * from "./stringUtil"; @@ -21,3 +22,4 @@ export * from "./searchQueryUtil"; export * from "./typeUtil"; export * from "./formatUtil"; export * from "./deviceUtil"; +export * from "./easterEggUtil";