lex-module
v1.3.2
Published
A comprehensive JavaScript string manipulation library with fluent API
Maintainers
Readme
lex-module
A lightweight, chainable JavaScript string manipulation library with comprehensive text processing capabilities.
Features
- Chainable API: Fluent method chaining for elegant string operations
- Comprehensive Methods: 54+ string manipulation utilities
- Input Validation: Built-in validation for robust error handling
- Zero Dependencies: Pure JavaScript implementation
- Well Tested: Comprehensive test suite with Mocha (529+ tests)
- HTML-Safe Truncation: Smart text truncation that preserves HTML structure
- Smart Truncation: Word boundary truncation for better readability
- Comprehensive Validation: Email, IP, phone number, and date validation
- Modular Architecture: Well-organized source code in 15 functional modules
Project Structure
The library has been refactored into a modular architecture for better maintainability:
src/
core/ # Core string operations (length, split, toString, duplicate, inverse, trim)
case/ # Case manipulation (uppercase, lowercase, ucFirst, capitalize)
search/ # Search and truncation (startsWith, endsWith, contains, truncate, truncateRight, truncateWithTags, smartTruncate)
words/ # Word operations (words, wordsCount, wordsFreq, firstWord, lastWord, randomWord, randomizeWords, acronym)
comparison/ # String comparison (compareByChar, compareByWord)
replace/ # Replacement (replace, replaceFirst, compile)
html/ # HTML handling (stripTags, isHtml, highlight)
url/ # URL parsing (isUrl, urlScheme, urlDomain, urlRoute, queryParams, slug)
path/ # File path operations (baseFileName, pathToFile, toFileNameWithExtension, fileExtension)
validation/ # Validation (isNumeric, isInt, isJSON, validEmail, validIP, validPhoneNumber, validDate)
random/ # Random generation (randomLetter, randomChars, insertTypo)
text/ # Text utilities (sentences, lines)
counting/ # Character counting (lettersCount, digitsCount, punctuationCount, emailsCount, ipCount, urlCount)
crypto/ # Cryptographic (hash, hashEquals)
distance/ # Distance calculation (levenstain)
StringObj.js # Main class that composes all modules
index.js # Entry point
test/ # Test files mirroring src/ structure (529+ tests)Key Design Principles
- Composability: The main
StringObjclass inherits fromStringCoreand mixes in methods from 14 functional modules - Backward Compatibility: All methods work exactly as before; the public API remains unchanged
- Testability: Each module has its own test file, enabling focused unit testing
Installation
npm install lex-moduleOr with yarn:
yarn add lex-moduleBundle Formats
The library is distributed in multiple formats for maximum compatibility:
- CommonJS (
dist/lex-module.cjs.js) - For Node.js and older bundlers - ES Modules (
dist/lex-module.mjs) - For modern bundlers (webpack, rollup, esbuild) - UMD (
dist/lex-module.umd.js) - For direct browser usage via CDN
Minified versions are also available:
dist/lex-module.cjs.min.js(~12 KB)dist/lex-module.mjs.min.js(~12 KB)dist/lex-module.umd.min.js(~13 KB)
75% size reduction from the original unminified version!
CDN Usage
You can use the library directly in browsers via CDN:
<!-- Using unpkg -->
<script src="https://unpkg.com/lex-module@latest/dist/lex-module.umd.min.js"></script>
<!-- Using jsDelivr -->
<script src="https://cdn.jsdelivr.net/npm/lex-module@latest/dist/lex-module.umd.min.js"></script>
<script>
const result = LexModule('hello world').uppercase().toString();
console.log(result); // "HELLO WORLD"
</script>Quick Start
const str = require('lex-module');
// Basic usage
const result = str('hello world')
.uppercase()
.replace('WORLD', 'Universe')
.toString();
console.log(result); // "HELLO UNIVERSE"
// Method chaining
const text = str(' the quick brown fox ')
.trim()
.capitalize()
.words();
// Returns: ['The', 'Quick', 'Brown', 'Fox']API Reference
String Transformation
uppercase()
Converts the entire string to uppercase.
str('hello world').uppercase(); // "HELLO WORLD"lowercase()
Converts the entire string to lowercase.
str('HELLO WORLD').lowercase(); // "hello world"ucFirst()
Capitalizes only the first character of the string.
str('hello world').ucFirst(); // "Hello world"capitalize()
Capitalizes the first character of each word.
str('hello world').capitalize(); // "Hello World"inverse()
Reverses the string character by character.
str('hello').inverse(); // "olleh"duplicate()
Duplicates the string content.
str('hello').duplicate(); // "hellohello"Search and Match
startsWith(needle)
Checks if the string starts with the specified substring.
str('hello world').startsWith('hello'); // true
str('hello world').startsWith('world'); // falseendsWith(needle)
Checks if the string ends with the specified substring.
str('hello world').endsWith('world'); // true
str('hello world').endsWith('hello'); // falsecontains(needle)
Checks if the string contains the specified substring.
str('hello world').contains('world'); // true
str('hello world').contains('foo'); // falseReplacement
replace(from, to)
Replaces all occurrences of a pattern or array of patterns. Supports both string and array parameters.
// Simple replacement
str('hello world').replace('world', 'universe'); // "hello universe"
// Array replacement
str('one two three').replace(['one', 'two'], ['1', '2']); // "1 2 three"
// Multiple replacements with arrays
str('The village was not so large')
.replace(['village', 'not '], ['town', '']); // "The town was so large"Throws: Error if from parameter is undefined/null or if to parameter is undefined.
replaceFirst(from, to)
Replaces only the first occurrence of a pattern or array of patterns.
str('one two one').replaceFirst('one', '1'); // "1 two one"
// Array replacement
str('The village was not so large. The village was small.')
.replaceFirst(['village', 'not '], ['town', '']); // "The town was so large. The village was small."Throws: Error if from parameter is undefined/null or if to parameter is undefined.
compile(params, template)
Replaces wildcards in the string with values from a params object.
// Default template {key}
str('Hello {name}, you are {age} years old')
.compile({ name: 'John', age: 30 }); // "Hello John, you are 30 years old"
// Custom template
str('Hello #{name}').compile({ name: 'World' }, /#\{(\w*)\}/g); // "Hello World"
// Handles missing params gracefully
str('Hello {name}').compile({}); // "Hello {name}"Parameters:
params(Object): Key-value pairs for replacementtemplate(RegExp, optional): Custom regex template (default:/\{(\w*)\}/g)
Throws: Error if params is null or not an object.
Text Analysis
words()
Extracts all words from the string as an array of lowercase strings.
str('Hello, World! This is a Test.').words();
// Returns: ['hello', 'world', 'this', 'is', 'a', 'test']wordsCount()
Returns the number of words in the string.
str('Hello world').wordsCount(); // 2wordsFreq()
Returns word frequency analysis as a two-element array: [words, frequencies].
str('hello world hello').wordsFreq();
// Returns: [['hello', 'world'], [2, 1]]sentences()
Splits the string into an array of sentences.
str('First sentence. Second one! What about third?').sentences();
// Returns: ['First sentence.', 'Second one!', 'What about third?']lines()
Splits the string into an array of lines using various line ending formats.
str('line1\nline2\nline3').lines(); // ['line1', 'line2', 'line3']
str('line1\r\nline2\r\nline3').lines(); // ['line1', 'line2', 'line3'] (Windows)
str('line1\rline2\rline3').lines(); // ['line1', 'line2', 'line3'] (old Mac)
str('line1\n\nline2').lines(); // ['line1', '', 'line2'] (empty lines preserved)Note: This is a getter method that returns an array directly (not this for chaining). Supports Unix (\n), Windows (\r\n), and old Mac (\r) line endings.
lettersCount()
Counts the number of letter characters (a-z, A-Z) in the string.
str('hello world').lettersCount(); // 10
str('ABC-123-XYZ').lettersCount(); // 6Note: Only ASCII letters are counted. International characters (accents, Cyrillic, etc.) are not included.
digitsCount()
Counts the number of digit characters (0-9) in the string.
str('hello123world').digitsCount(); // 3
str('ABC-123-XYZ').digitsCount(); // 3Note: Only ASCII digits are counted.
punctuationCount()
Counts the number of ASCII punctuation characters in the string.
str('Hello, World!').punctuationCount(); // 2
str('arr[i]++;').punctuationCount(); // 5Note: Counts ASCII punctuation: !"#$%&'()*+,-./:;<=>?@[]^_`{|}~
emailsCount()
Counts the number of email addresses in the string.
str('Contact us at [email protected]').emailsCount(); // 1
str('[email protected] and [email protected]').emailsCount(); // 2ipCount()
Counts the number of IP addresses (IPv4 and IPv6) in the string.
str('Server: 192.168.1.1').ipCount(); // 1
str('IPv4: 192.168.1.1, IPv6: ::1').ipCount(); // 2Note: Supports IPv4 (xxx.xxx.xxx.xxx) and IPv6 formats including mixed notation.
urlCount()
Counts the number of URLs (with http/https/www prefix) in the string.
str('Visit http://example.com').urlCount(); // 1
str('www.google.com and https://github.com').urlCount(); // 2Note: Only counts URLs with scheme (http://, https://) or www prefix.
length()
Returns the length of the string.
str('hello').length(); // 5acronym()
Creates an acronym by taking the first letter of each word.
str('Hello World').acronym(); // 'HW'
str('JavaScript Object Notation').acronym(); // 'JON'
str('Hyper Text Markup Language').acronym(); // 'HTML'
str('3D Studio Max').acronym(); // '3DSM' (numbers included)
str('C++ Programming').acronym(); // 'CP' (special chars skipped)Note: This is a getter method that returns a string directly (not this for chaining). Only ASCII alphanumeric characters are supported; international characters are skipped. The previous typo acronim() is kept as a backward-compatible alias.
isNumeric()
Checks if the string represents a numeric value (integer or float).
str('123').isNumeric(); // true
str('-123.45').isNumeric(); // true
str('123.').isNumeric(); // true (trailing decimal allowed)
str('.5').isNumeric(); // false (leading decimal not allowed)
str('1e10').isNumeric(); // false (scientific notation not supported)Throws: Error if input is null or undefined
isInt()
Checks if the string represents an integer value (no decimal points).
str('123').isInt(); // true
str('-123').isInt(); // true
str('123.45').isInt(); // false (has decimal point)
str('123.').isInt(); // false (trailing decimal not allowed)
str('0').isInt(); // true
str('-0').isInt(); // trueThrows: Error if input is null or undefined
Note: This validates the string format, not that the number is safely representable in JavaScript. Numbers exceeding Number.MAX_SAFE_INTEGER will return true but lose precision when parsed.
isJSON()
Checks if the string contains valid JSON data.
str('{"name":"John","age":30}').isJSON(); // true
str('[1,2,3]').isJSON(); // true
str('"hello"').isJSON(); // true (JSON string)
str('true').isJSON(); // true (JSON boolean)
str('null').isJSON(); // true (JSON null)
str('{name:"John"}').isJSON(); // false (missing quotes around keys)
str('').isJSON(); // false (empty string)Throws: Error if input is null or undefined
validEmail()
Validates if the string is a properly formatted email address.
str('[email protected]').validEmail(); // true
str('[email protected]').validEmail(); // true
str('[email protected]').validEmail(); // true (dots in local part)
str('[email protected]').validEmail(); // true (plus sign in local part)
str('[email protected]').validEmail(); // true (hyphen in local part)
str('[email protected]').validEmail(); // true (subdomains)
str('invalid-email').validEmail(); // false
str('user@').validEmail(); // false (missing domain)
str('@example.com').validEmail(); // false (missing local part)
str('[email protected]').validEmail(); // false (domain starts with dot)
str('user@domain').validEmail(); // false (missing TLD)
str('[email protected]').validEmail(); // false (double dots in domain)Throws: Error if input is null or undefined
Note: This validates email format, not that the email actually exists. The regex pattern is intentionally permissive to accommodate most valid email formats.
validIP()
Validates if the string is a valid IPv4 or IPv6 address.
// IPv4 addresses
str('192.168.1.1').validIP(); // true
str('10.0.0.1').validIP(); // true
str('0.0.0.0').validIP(); // true
str('255.255.255.255').validIP(); // true
str('8.8.8.8').validIP(); // true (Google DNS)
// IPv6 addresses
str('2001:0db8:85a3:0000:0000:8a2e:0370:7334').validIP(); // true (full format)
str('2001:db8:85a3:0:0:8a2e:370:7334').validIP(); // true (leading zeros omitted)
str('2001:db8:85a3::8a2e:370:7334').validIP(); // true (compressed)
str('::1').validIP(); // true (localhost)
str('::ffff:192.0.2.1').validIP(); // true (mixed IPv4/IPv6)
// Invalid addresses
str('256.1.2.3').validIP(); // false (octet > 255)
str('192.168.1').validIP(); // false (missing octet)
str('192.168.01.1').validIP(); // false (leading zero)
str('gggg::1').validIP(); // false (invalid hex)Throws: Error if input is null or undefined
Note:
- IPv4: Each octet must be 0-255, no leading zeros allowed (except '0' itself)
- IPv6: Supports full format, compressed (::), and mixed IPv4/IPv6 notation
validPhoneNumber()
Validates if the string is a valid international phone number. Permissive validation focusing on digit count (7-15 digits).
// US/Canada numbers
str('+1 (555) 123-4567').validPhoneNumber(); // true
str('1-555-123-4567').validPhoneNumber(); // true
str('(555) 123-4567').validPhoneNumber(); // true
str('555-123-4567').validPhoneNumber(); // true
// European numbers
str('+44 20 7123 4567').validPhoneNumber(); // true (UK)
str('+33 1 23 45 67 89').validPhoneNumber(); // true (France)
str('+49 30 12345678').validPhoneNumber(); // true (Germany)
// Asian numbers
str('+86 10 1234 5678').validPhoneNumber(); // true (China)
str('+81 3 1234 5678').validPhoneNumber(); // true (Japan)
// Invalid numbers
str('123').validPhoneNumber(); // false (too short)
str('abc-def-ghij').validPhoneNumber(); // false (contains letters)
str('111-111-1111').validPhoneNumber(); // false (all same digits)Throws: Error if input is null or undefined
Note: This is a basic permissive validator (7-15 digits). For production use with strict validation, consider using a dedicated library like libphonenumber-js or google-libphonenumber.
validDate()
Validates if the string is a valid date and checks for logical validity. Supports multiple date formats.
// ISO 8601 format (YYYY-MM-DD)
str('2024-01-15').validDate(); // true
str('2020-02-29').validDate(); // true (leap year)
str('2000-02-29').validDate(); // true (leap year divisible by 400)
// US format (MM/DD/YYYY)
str('01/15/2024').validDate(); // true
str('12/31/2024').validDate(); // true
str('02/29/2020').validDate(); // true (leap year)
// European format (DD/MM/YYYY)
str('15/01/2024').validDate(); // true
str('31/12/2024').validDate(); // true
str('29/02/2020').validDate(); // true (leap year)
// Short year formats
str('01/01/24').validDate(); // true (2024)
str('01/01/50').validDate(); // true (1950)
// Invalid dates - date rollover
str('2024-02-30').validDate(); // false (February never has 30 days)
str('2024-02-31').validDate(); // false (February never has 31 days)
str('2024-04-31').validDate(); // false (April has only 30 days)
// Invalid dates - non-leap year February 29
str('2023-02-29').validDate(); // false (2023 is not a leap year)
str('1900-02-29').validDate(); // false (1900 is not leap year)
// Invalid dates - impossible values
str('2024-13-01').validDate(); // false (month 13 doesn't exist)
str('2024-01-00').validDate(); // false (day 0 doesn't exist)
str('2024-01-32').validDate(); // false (day 32 doesn't exist)Throws: Error if input is null or undefined
Note: Supported formats include ISO 8601 (YYYY-MM-DD), US format (MM/DD/YYYY), European format (DD/MM/YYYY), and short year formats (YY/MM/DD, DD/MM/YY). Validates leap years, month boundaries, and days per month correctly.
Manipulation
truncate(length, start)
Truncates the string to specified length from an optional start position.
str('hello world').truncate(5); // "hello"
str('hello world').truncate(5, 6); // "world"
str('hello world').truncate(7, 3); // "lo worl"truncateRight(count)
Truncates the string by removing the specified number of characters from the right side.
str('hello world').truncateRight(5); // "hello "
str('filename.txt').truncateRight(4); // "filename"
str('document.pdf').truncateRight(4); // "document"
str('test').truncateRight(4); // "" (remove entire string)
str('test').truncateRight(0); // "test" (keep entire string)Parameters:
count(Number): The number of characters to remove from the right (must be >= 0)
Throws: Error if count is not provided or is invalid
smartTruncate(maxLength, append)
Truncates the string at word boundaries for better readability. Avoids cutting words in half.
str('Hello world test').smartTruncate(8); // "Hello..."
str('The quick brown fox').smartTruncate(10); // "The..."
str('Hello world test').smartTruncate(8, ' [more]'); // "Hello [more]"
str('Short').smartTruncate(10); // "Short" (no truncation needed)Parameters:
maxLength(Number): Maximum length of truncated string (excluding append string)append(String, optional): String to append when truncation occurs (default:'...')
Throws: Error if maxLength is not provided or is invalid
truncateWithTags(maxLength)
Truncates the string while preserving HTML/XML tag structure. Ensures all opened tags are properly closed.
str('<p>Hello world</p>').truncateWithTags(7); // "<p>Hello...</p>"
str('<div><span>Text</span></div>').truncateWithTags(4); // "<div><span>Text</span></div>"
str('<p><strong>Bold text</strong></p>').truncateWithTags(6); // "<p><strong>Bold...</strong></p>"
str('<p>Text<br/>more</p>').truncateWithTags(4); // "<p>Text...</p>"Parameters:
maxLength(Number): Maximum length of truncated string (excluding closing tags)
Throws: Error if maxLength is not provided or is invalid
Note: Does not sanitize HTML. Sanitize user-supplied content first to prevent XSS attacks.
split(delimiter)
Splits the string by the specified delimiter.
str('a,b,c').split(','); // ['a', 'b', 'c']randomizeWords()
Randomly shuffles the words in the string.
const result = str('hello world test').randomizeWords();
// Possible result: "test world hello"insertTypo()
Inserts a random typo into the string (useful for testing fuzzy search).
const result = str('hello').insertTypo();
// Possible result: "hlelo", "ehllo", "helo", etc.HTML Processing
stripTags()
Removes all HTML/XML tags from the string.
str('<p>Hello <b>world</b>!</p>').stripTags(); // "Hello world!"isHtml()
Checks if the string contains HTML tags.
str('<p>Hello</p>').isHtml(); // true
str('Hello world').isHtml(); // falsehighlight(words, template)
Highlights specified words in the string using a template.
// Default highlighting
str('hello world').highlight('world'); // "hello <mark>world</mark>"
// Custom template
str('hello world').highlight('world', '<span class="hl">$&</span>');
// "hello <span class="hl">world</span>"
// Multiple words
str('hello world test').highlight(['hello', 'test']);
// "<mark>hello</mark> world <mark>test</mark>"URL Processing
isUrl()
Checks if the string is a valid URL.
str('https://example.com').isUrl(); // true
str('example.com').isUrl(); // true
str('not a url').isUrl(); // falseurlScheme()
Extracts the URL scheme (http, https).
str('https://example.com').urlScheme(); // "https"
str('http://example.com').urlScheme(); // "http"
str('example.com').urlScheme(); // nullurlDomain()
Extracts the domain from the URL.
str('https://example.com').urlDomain(); // "example.com"
str('http://sub.example.com').urlDomain(); // "sub.example.com"urlRoute()
Extracts the route/path from the URL.
str('https://example.com/path/to/resource').urlRoute(); // "/path/to/resource"
str('http://example.com/').urlRoute(); // "/"queryParams()
Extracts query parameters from a URL string.
str('https://example.com?name=John&age=30').queryParams();
// Returns: { name: 'John', age: '30' }
// Handles arrays
str('https://example.com?name[]=John&name[]=Doe').queryParams();
// Returns: { name: ['John', 'Doe'] }
// Handles multiple same keys
str('https://example.com?name=John&name=Doe').queryParams();
// Returns: { name: ['John', 'Doe'] }
// Handles encoded characters
str('https://example.com?name=John%20Doe').queryParams();
// Returns: { name: 'John Doe' }File Operations
fileExtension()
Extracts the file extension from a filename or path.
str('example.txt').fileExtension(); // "txt"
str('archive.tar.gz').fileExtension(); // "gz"
str('path/to/file.js').fileExtension(); // "js"
str('image.png?width=200').fileExtension(); // "png"
str('noextension').fileExtension(); // nullNote: The previous typo fileExtention() is kept as a backward-compatible alias.
baseFileName()
Extracts the base filename from a file path, removing both the directory path and file extension.
str('/path/to/file.txt').baseFileName(); // "file"
str('C:\\Users\\John\\document.pdf').baseFileName(); // "document"
str('/path/to/.gitignore').baseFileName(); // ".gitignore"
str('archive.tar.gz').baseFileName(); // "archive"
str('/path/to/').baseFileName(); // "" (trailing slash, empty filename)Throws: Error if input is null or undefined
pathToFile()
Extracts the directory path from a file path, removing the filename and extension.
str('/path/to/file.txt').pathToFile(); // "/path/to"
str('C:\\Users\\John\\document.pdf').pathToFile(); // "C:\\Users\\John"
str('relative/path/to/image.png').pathToFile(); // "relative/path/to"
str('file.txt').pathToFile(); // "" (no directory path)
str('/').pathToFile(); // "/" (root directory)
str('https://example.com/path/to/file.txt').pathToFile(); // "https://example.com/path/to"Throws: Error if input is null or undefined
toFileNameWithExtension()
Converts strings to safe filenames with extensions, removing invalid characters.
str('My Document').toFileNameWithExtension().toString(); // 'My_Document'
str('report.pdf').toFileNameWithExtension().toString(); // 'report.pdf'
str('file:name*.txt').toFileNameWithExtension().toString(); // 'filename.txt'
str('path/to/file.txt').toFileNameWithExtension().toString(); // 'file.txt'
str('.env').toFileNameWithExtension().toString(); // '.env'
str('archive.tar.gz').toFileNameWithExtension().toString(); // 'archive.tar.gz'Note: This is a transformer method (returns this for chaining). Removes invalid characters (< > : " / \ | ? *), replaces whitespace with underscores, and preserves file extensions. Truncates to 255 characters max. The previous typo toFileNameWithExtention() is kept as a backward-compatible alias.
Limitations: Does not validate Windows reserved device names (CON, PRN, AUX, NUL, COM1-9, LPT1-9).
Text Formatting
slug()
Converts the string to a URL-friendly slug format.
str('Hello World').slug(); // "hello-world"
str('My Very Long Sentence!').slug(); // "my-very-long-sentence"
str('CAFÉ Résumé').slug(); // "cafe-resume"
str('Test @#$% String***').slug(); // "test-string"Throws: Error if input is null or undefined.
firstWord()
Extracts and returns the first word from the string.
str('Hello World').firstWord(); // "hello"
str('My very long sentence').firstWord(); // "my"
str('@#$% Test').firstWord(); // "test"Throws: Error if input is null or undefined.
lastWord()
Extracts and returns the last word from the string.
str('Hello World').lastWord(); // "world"
str('My very long sentence').lastWord(); // "sentence"
str('Test @#$%').lastWord(); // "test"Throws: Error if input is null or undefined.
Comparison
compareByChar(strToCompare)
Performs character-by-character comparison and returns an array of equal/diff objects.
str('abc').compareByChar('abc');
// Returns: [{ type: 'eq', content: 'abc' }]
str('abcxyz').compareByChar('abcpqr');
// Returns: [
// { type: 'eq', content: 'abc' },
// { type: 'diff', left: 'xyz', right: 'pqr' }
// ]Conversion
toString()
Returns the current string value (useful for ending chains).
str('hello').uppercase().toString(); // "HELLO"Chaining Examples
The library supports method chaining for complex operations:
const result = str(' the quick brown fox jumps over the lazy dog ')
.trim()
.capitalize()
.replace('fox', 'cat')
.truncate(20)
.toString();
// Result: "The Quick Brown Cat"// Complex URL processing
const url = str('https://EXAMPLE.com/path/To/Resource?name=John+Doe&age=30')
.lowercase()
.queryParams();
// Result: { name: 'john doe', age: '30' }// Smart truncation with HTML preservation
const html = '<p>This is a long paragraph with <strong>bold text</strong> that needs to be truncated.</p>';
const truncated = str(html).truncateWithTags(20);
// Result: "<p>This is a long...</p>"// Word boundary truncation
const text = 'The quick brown fox jumps over the lazy dog';
const smart = str(text).smartTruncate(15);
// Result: "The quick..."// Text processing pipeline
const text = str(' <p>Hello, WORLD!</p> This is a TEST. ')
.stripTags()
.trim()
.lowercase()
.capitalize()
.words();
// Result: ['Hello,', 'World', 'This', 'Is', 'A', 'Test.']Error Handling
Recent methods include comprehensive input validation:
// replace() validation
str('test').replace(undefined, 'x'); // Throws: Error
str('test').replace(null, 'x'); // Throws: Error
str('test').replace('x', undefined); // Throws: Error
// compile() validation
str('Hello {name}').compile(null); // Throws: Error
str('Hello {name}').compile(undefined); // Throws: Error
// slug() validation
str(null).slug(); // Throws: Error
str(undefined).slug(); // Throws: ErrorTesting
The library includes a comprehensive test suite. Run tests with:
npm testTests cover:
- Basic string operations
- Edge cases and error handling
- Method chaining
- Complex scenarios with multiple operations
Browser Support
The library uses modern JavaScript features and should work in all current browsers and Node.js versions.
License
MIT
Author
Alexey Afanasyev [email protected]
Version
Current version: 1.3.1
Changelog
v1.3.0 (January 2025)
- New Validation Functions: Added three comprehensive validation methods
validIP()- IPv4 and IPv6 address validation with full format supportvalidPhoneNumber()- International phone number validation (7-15 digits)validDate()- Multi-format date validation (ISO, US, European formats)
- Enhanced Testing: Added 64 new tests (total: 498 tests)
- Updated Documentation: Comprehensive API documentation for new validation functions
- Input Validation: All functions include null/undefined checks and type conversion
- Refactored Architecture: Split monolithic index.js into 15 modular source files for better maintainability
- Bug Fixes: Fixed duplicate
sentences()method and typos in method names:fileExtension()(corrected fromfileExtention)acronym()(corrected fromacronim)toFileNameWithExtension()(corrected fromtoFileNameWithExtention)
- Backward Compatibility: All corrected method names retain aliases for the old typos
v1.2.0 (January 2025)
- 🚀 Major Performance Improvement: Added minified builds (75% size reduction)
- 📦 Multiple Format Support: Now distributed in CommonJS, ES Modules, and UMD formats
- 🌐 CDN Support: Available via unpkg and jsDelivr
- ⚡ Tree-shakeable: Optimized for modern bundlers
- 🔧 Build Process: Automated build with Rollup
- ✅ 100% Backward Compatible: No breaking changes
v1.1.5
- Added comprehensive input validation
- Enhanced error messages
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Roadmap
The library has an extensive list of planned features (see commented TODO items in source code), including:
- Random character and word generation
- Hash functions and comparison
- Email, IP, and phone validation
- Levenshtein distance calculations
- Advanced text comparison methods
- Query string manipulation
- JSON validation
- And many more...
For a complete list of planned features, refer to the source code comments.
