JSPM

friendlyfy-js

1.0.4
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 25
  • Score
    100M100P100Q67491F
  • License MIT

A zero-dependency utility library with 70+ functions for formatting dates, numbers, strings, arrays, objects, and validation. Works in both Node.js and browser environments.

Package Exports

  • friendlyfy-js

Readme

friendlyfy-js

A zero-dependency utility library with 70+ functions for formatting dates, numbers, strings, arrays, objects, and validation. Works seamlessly in both Node.js and browser environments with pure JavaScript implementation.

โœจ Features

  • ๐Ÿ“… Date & Time (10 functions): Human-readable formatting, timezone support, duration formatting
  • ๐Ÿ”ข Numbers & Math (15 functions): Shortening, formatting, validation, statistical analysis
  • ๐Ÿ”ค String Manipulation (15 functions): Text transformation, HTML handling, case conversion
  • ๐Ÿ“Š Array Operations (15 functions): Manipulation, set operations, sorting, statistics
  • ๐Ÿ”ง Object Utilities (15 functions): Deep cloning, merging, transformation, validation
  • โœ… Validation & Security (13 functions): Email, URL, phone, credit card, password validation
  • ๐ŸŒ Full Internationalization: Complete locale support using native Intl APIs
  • โšก ESM Ready: Built for Node.js v20+ with native ES modules
  • ๐Ÿ“ฆ Zero Dependencies: Uses only native JavaScript APIs

๐Ÿš€ Installation

npm install friendlyfy-js

๐ŸŽฏ Quick Start

import { 
  // Date & Time
  timeAgo, 
  formatDuration,
  
  // Numbers
  shortenNumber, 
  formatFileSize,
  formatOrdinal,
  
  // Strings
  slugify,
  capitalize,
  
  // Arrays
  chunk,
  unique,
  
  // Objects
  deepClone,
  pick,
  
  // Validation
  isValidEmail,
  validatePassword,
  
  // Crypto
  generateUUID,
  hash,
  
  // Files
  getMimeType,
  sanitizeFilename
} from 'friendlyfy-js';

// Date formatting
console.log(timeAgo('2025-10-08T10:00:00Z')); // "3 hours ago"
console.log(formatDuration(3661)); // "1h 1m 1s"

// Number formatting
console.log(shortenNumber(12543)); // "12.5K"
console.log(formatFileSize(1048576)); // "1.05 MB"
console.log(formatOrdinal(21)); // "21st"

// String manipulation
console.log(slugify("Hello World!")); // "hello-world"
console.log(capitalize("hello world")); // "Hello world"

// Array operations
console.log(chunk([1,2,3,4,5,6], 2)); // [[1,2], [3,4], [5,6]]
console.log(unique([1,2,2,3,3,3])); // [1,2,3]

// Object utilities
const cloned = deepClone({user: {name: 'John'}});
const userData = pick({name: 'John', age: 30, city: 'NYC'}, ['name', 'age']);

// Validation
console.log(isValidEmail('user@example.com')); // true
console.log(validatePassword('MySecure123!')); // {valid: true, strength: 'strong'}

// Cryptography
console.log(generateUUID()); // "96cf1769-2655-4880-801d-7062903e9b2b"
console.log(hash('Hello World')); // "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e"

// File operations
console.log(getMimeType('image.jpg')); // "image/jpeg"
console.log(sanitizeFilename('file<>:"|?*.txt')); // "file_______.txt"

๐Ÿ“š API Reference

๐Ÿ“… Date & Time Helpers

timeAgo(date, locale?)

Returns human-readable time ago string.

timeAgo('2024-01-01T00:00:00Z'); // "2 months ago"
timeAgo(new Date(), 'es-ES'); // "hace 2 horas"

timeFromNow(date, locale?)

Returns human-readable time from now string.

timeFromNow('2025-12-25T00:00:00Z'); // "in 8 months"

formatDateWithTimezone(date, timezone?, options?, locale?)

Formats date with timezone support.

formatDateWithTimezone('2024-01-15T14:30:00Z', 'America/New_York');
// "01/15/2024, 09:30:00 AM"

formatDuration(seconds, options?, locale?)

Formats duration in human-readable format.

formatDuration(3661); // "1h 1m 1s"
formatDuration(3661, {compact: true}); // "1h 1m 1s"
formatDuration(3661, {maxUnits: 2}); // "1h 1m"

startOf(date, period) / endOf(date, period)

Get start/end of time periods.

startOf(new Date(), 'week'); // Start of current week
endOf(new Date(), 'month'); // End of current month

๐Ÿ”ข Number Helpers

shortenNumber(num, decimals?)

Shortens numbers with K, M, B, T suffixes.

shortenNumber(12543); // "12.5K"
shortenNumber(1250000); // "1.3M"
shortenNumber(1250000000); // "1.3B"

formatFileSize(bytes, options?, locale?)

Formats file size in human-readable format.

formatFileSize(1024); // "1.02 KB"
formatFileSize(1048576); // "1.05 MB"
formatFileSize(1048576, {binary: true}); // "1.00 MiB"

formatOrdinal(num, locale?)

Formats ordinal numbers.

formatOrdinal(1); // "1st"
formatOrdinal(2); // "2nd"
formatOrdinal(21); // "21st"

formatRange(start, end, options?, locale?)

Formats number ranges.

formatRange(1, 5); // "1-5"
formatRange(1000, 2000); // "1,000-2,000"
formatRange(1, 5, {separator: ' to '}); // "1 to 5"

pluralize(count, singular, plural?, locale?)

Pluralizes words based on count.

pluralize(1, 'item'); // "1 item"
pluralize(5, 'item'); // "5 items"
pluralize(1, 'child', 'children'); // "1 child"

๐Ÿ”ค String Helpers

slugify(str, options?)

Converts string to URL-friendly slug.

slugify("Hello World! 123"); // "hello-world-123"
slugify("Hello World!", {separator: '_'}); // "hello_world_123"

truncate(str, length, options?)

Truncates string with ellipsis.

truncate("This is a long text", 10); // "This is a ..."
truncate("This is a long text", 10, {wordBoundary: true}); // "This is..."

capitalize(str, lowerRest?)

Capitalizes first letter.

capitalize("hello world"); // "Hello world"
capitalize("hello world", true); // "Hello world"

camelToKebab(str) / kebabToCamel(str)

Converts between camelCase and kebab-case.

camelToKebab("camelCaseString"); // "camel-case-string"
kebabToCamel("kebab-case-string"); // "kebabCaseString"

stripHtml(str) / escapeHtml(str)

Handles HTML content.

stripHtml("<p>Hello <b>World</b></p>"); // "Hello World"
escapeHtml("<script>alert('xss')</script>"); // "&lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;"

maskString(str, options?)

Masks sensitive strings.

maskString("1234567890"); // "12******90"
maskString("1234567890", {visibleStart: 3, visibleEnd: 3}); // "123****890"

๐Ÿ“Š Array Helpers

chunk(arr, size)

Chunks array into smaller arrays.

chunk([1,2,3,4,5,6,7,8,9,10], 3); // [[1,2,3], [4,5,6], [7,8,9], [10]]

unique(arr, keyFn?)

Removes duplicates from array.

unique([1,2,2,3,3,3,4,5]); // [1,2,3,4,5]
unique(users, user => user.city); // Unique users by city

shuffle(arr, inPlace?)

Shuffles array randomly.

shuffle([1,2,3,4,5]); // [3,2,4,1,5]

groupBy(arr, key)

Groups array items by key.

groupBy(users, 'city'); // { 'New York': [...], 'London': [...] }
groupBy(users, user => user.age > 25 ? 'adult' : 'young'); // { 'adult': [...], 'young': [...] }

intersection(arr1, arr2) / difference(arr1, arr2) / union(arr1, arr2)

Set operations on arrays.

intersection([1,2,3,4], [3,4,5,6]); // [3,4]
difference([1,2,3,4], [3,4,5,6]); // [1,2]
union([1,2,3,4], [3,4,5,6]); // [1,2,3,4,5,6]

arrayStats(arr)

Gets array statistics.

arrayStats([1,2,3,4,5]); // {length: 5, sum: 15, average: 3, min: 1, max: 5, median: 3}

๐Ÿ”ง Object Helpers

deepClone(obj)

Deep clones an object.

const cloned = deepClone({user: {profile: {name: 'John'}}});

deepMerge(target, ...sources)

Deep merges objects.

deepMerge({a: 1, b: {c: 2}}, {b: {d: 3}}); // {a: 1, b: {c: 2, d: 3}}

pick(obj, keys) / omit(obj, keys)

Selects/removes object properties.

pick({name: 'John', age: 30, city: 'NYC'}, ['name', 'age']); // {name: 'John', age: 30}
omit({name: 'John', age: 30, city: 'NYC'}, ['age']); // {name: 'John', city: 'NYC'}

get(obj, path, defaultValue?) / set(obj, path, value)

Gets/sets nested object properties.

get({user: {profile: {name: 'John'}}}, 'user.profile.name'); // "John"
set(obj, 'user.profile.settings.theme', 'dark');

transformKeys(obj, transformFn) / transformValues(obj, transformFn)

Transforms object keys/values.

transformKeys({firstName: 'John', lastName: 'Doe'}, k => k.toUpperCase()); // {FIRSTNAME: 'John', LASTNAME: 'Doe'}
transformValues({a: 1, b: 2}, v => v * 2); // {a: 2, b: 4}

โœ… Validation Helpers

isValidEmail(email)

Validates email addresses.

isValidEmail('user@example.com'); // true
isValidEmail('invalid-email'); // false

isValidUrl(url, options?)

Validates URLs.

isValidUrl('https://example.com'); // true
isValidUrl('ftp://example.com', {protocols: ['ftp:']}); // true

isValidPhone(phone, country?)

Validates phone numbers.

isValidPhone('+1234567890', 'US'); // true
isValidPhone('+44123456789', 'UK'); // true

isValidCreditCard(cardNumber)

Validates credit card numbers.

isValidCreditCard('4111111111111111'); // {valid: true, type: 'visa'}

validatePassword(password, options?)

Validates password strength.

validatePassword('MySecure123!'); // {valid: true, score: 6, strength: 'strong', feedback: []}

isValidIP(ip, version?)

Validates IP addresses.

isValidIP('192.168.1.1'); // true
isValidIP('2001:db8::1', 'v6'); // true

isValidUUID(uuid, version?)

Validates UUIDs.

isValidUUID('550e8400-e29b-41d4-a716-446655440000'); // true

๐Ÿ” Crypto Helpers

hash(data, algorithm?, encoding?)

Generates hash using specified algorithm.

hash('Hello World'); // "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e"
hash('Hello World', 'md5', 'hex'); // "b10a8db164e0754105b7a99be72e3fe5"

hmac(data, secret, algorithm?, encoding?)

Generates HMAC.

hmac('Hello World', 'secret'); // "82ce0d2f821fa0ce5447b21306f214c99240fecc6387779d7515148bbdd0c415"

generateUUID()

Generates UUID v4.

generateUUID(); // "96cf1769-2655-4880-801d-7062903e9b2b"

generateToken(length?, options?)

Generates secure tokens.

generateToken(16); // "qRWt7ncmhhwy8FNK"
generateToken(32, {includeSymbols: true}); // "K#m9@vL2$nP8&qR5!"

hashPassword(password, options?)

Hashes passwords securely.

const hashed = await hashPassword('MyPassword123');
const isValid = await verifyPassword('MyPassword123', hashed); // true

generateApiKey(options?)

Generates API keys.

generateApiKey(); // "ak_fvtqhqwlhicphwgyazvrq"
generateApiKey({prefix: 'sk', includeTimestamp: true}); // "sk_1j8k9l2m_fvtqhqwlhicphwgyazvrq"

๐Ÿ“ File Helpers

getFileExtension(filename) / getFilenameWithoutExtension(filename)

Gets file extension or name without extension.

getFileExtension('document.pdf'); // "pdf"
getFilenameWithoutExtension('document.pdf'); // "document"

normalizePath(filePath) / joinPaths(...paths)

Path manipulation.

normalizePath('./folder/../file.txt'); // "file.txt"
joinPaths('folder', 'subfolder', 'file.txt'); // "folder/subfolder/file.txt"

getMimeType(filename)

Gets MIME type from filename.

getMimeType('image.jpg'); // "image/jpeg"
getMimeType('document.pdf'); // "application/pdf"
getMimeType('script.js'); // "application/javascript"

sanitizeFilename(filename, options?)

Sanitizes filenames for safe storage.

sanitizeFilename('file<>:"|?*.txt'); // "file_______.txt"
sanitizeFilename('My File (1).pdf', {replacement: '-'}); // "My-File-1-.pdf"

fileExists(filePath) / dirExists(dirPath)

Checks file/directory existence.

await fileExists('/path/to/file.txt'); // true/false
await dirExists('/path/to/directory'); // true/false

getFileStats(filePath)

Gets file statistics.

await getFileStats('/path/to/file.txt'); // {size: 1024, isFile: true, createdAt: Date, modifiedAt: Date, ...}

๐ŸŒ Internationalization

All functions support locale-specific formatting:

import { timeAgo, formatWithCommas, formatCurrency, formatOrdinal } from 'friendlyfy-js';

// Spanish
timeAgo(date, 'es-ES'); // "hace 2 horas"
formatWithCommas(1234567, 'es-ES'); // "1.234.567"

// German
formatCurrency(1234.56, 'EUR', 'de-DE'); // "1.234,56 โ‚ฌ"

// French
formatOrdinal(1, 'fr-FR'); // "1er"

๐Ÿงช Examples

Run the comprehensive examples:

npm start
# or
node example.js

๐Ÿ“‹ Requirements

  • Node.js v20.0.0 or higher
  • ESM support (use import syntax)

๐Ÿ“„ License

MIT License - see LICENSE file for details.

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

๐Ÿ“ˆ Changelog

1.0.1

  • Added comprehensive utility functions (100+ functions)
  • String manipulation helpers (15 functions)
  • Array operation helpers (15 functions)
  • Object utility helpers (15 functions)
  • Validation and security helpers (13 functions)
  • Cryptography helpers (15 functions)
  • File system helpers (20 functions)
  • Complete examples and documentation
  • Full internationalization support

1.0.0

  • Initial release
  • Date helper functions with Intl.RelativeTimeFormat
  • Number helper functions with various formatting options
  • Full internationalization support
  • ESM module support

๐ŸŽฏ Use Cases

Frontend Development

  • String manipulation and formatting
  • Date/time display
  • Form validation
  • Data transformation

Backend Development

  • API response formatting
  • Data validation
  • File handling
  • Security utilities

Full-Stack Applications

  • Complete utility coverage
  • Consistent formatting across frontend/backend
  • Internationalization support
  • Performance optimization

โญ Star History

Star History Chart


Made with โค๏ธ by Vinay Kumar