string-extn 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +367 -0
- package/dist/case.d.ts +49 -0
- package/dist/case.d.ts.map +1 -0
- package/dist/case.js +92 -0
- package/dist/case.js.map +1 -0
- package/dist/core.d.ts +79 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +94 -0
- package/dist/core.js.map +1 -0
- package/dist/diff.d.ts +16 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +23 -0
- package/dist/diff.js.map +1 -0
- package/dist/fp.d.ts +60 -0
- package/dist/fp.d.ts.map +1 -0
- package/dist/fp.js +68 -0
- package/dist/fp.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/mask.d.ts +33 -0
- package/dist/mask.d.ts.map +1 -0
- package/dist/mask.js +57 -0
- package/dist/mask.js.map +1 -0
- package/dist/similarity.d.ts +18 -0
- package/dist/similarity.d.ts.map +1 -0
- package/dist/similarity.js +50 -0
- package/dist/similarity.js.map +1 -0
- package/dist/slug.d.ts +32 -0
- package/dist/slug.d.ts.map +1 -0
- package/dist/slug.js +44 -0
- package/dist/slug.js.map +1 -0
- package/dist/unicode.d.ts +54 -0
- package/dist/unicode.d.ts.map +1 -0
- package/dist/unicode.js +63 -0
- package/dist/unicode.js.map +1 -0
- package/dist/validate.d.ts +264 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +326 -0
- package/dist/validate.js.map +1 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Balaji Katta Venkatarathnam
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
# string-extn
|
|
2
|
+
|
|
3
|
+
A lightweight, TypeScript-first library for **safe and functional string manipulation**. It provides **core string utilities, functional programming helpers, and Unicode-safe operations**, designed for **Node.js and browser environments**.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Features](#features)
|
|
10
|
+
- [Installation](#installation)
|
|
11
|
+
- [Quick Start](#quick-start)
|
|
12
|
+
- [API Reference](#api-reference)
|
|
13
|
+
- [Core Functions](#core-functions)
|
|
14
|
+
- [Functional Programming](#functional-programming)
|
|
15
|
+
- [Case Conversion](#case-conversion)
|
|
16
|
+
- [String Comparison & Similarity](#string-comparison--similarity)
|
|
17
|
+
- [String Masking & Redaction](#string-masking--redaction)
|
|
18
|
+
- [URL & Filename Safe Conversion](#url--filename-safe-conversion)
|
|
19
|
+
- [String Validation](#string-validation)
|
|
20
|
+
- [Unicode Operations](#unicode-operations)
|
|
21
|
+
- [Examples](#examples)
|
|
22
|
+
- [Testing](#testing)
|
|
23
|
+
- [License](#license)
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
### ✨ Core String Operations
|
|
30
|
+
- **trim** - Remove leading/trailing whitespace
|
|
31
|
+
- **pad** - Pad strings to a fixed length with custom characters
|
|
32
|
+
- **slice** - Extract string substrings with flexible indexing
|
|
33
|
+
- **repeat** - Repeat strings multiple times
|
|
34
|
+
- **truncate** - Truncate strings with ellipsis
|
|
35
|
+
- **reverse** - Reverse string character order
|
|
36
|
+
|
|
37
|
+
### 🔧 Functional Programming Helpers
|
|
38
|
+
- **map** - Transform each character with a function
|
|
39
|
+
- **filter** - Keep only characters matching a predicate
|
|
40
|
+
- **reduce** - Accumulate values by processing characters
|
|
41
|
+
- **compose** - Chain multiple functions for complex transformations
|
|
42
|
+
|
|
43
|
+
### 🔤 Case Conversion
|
|
44
|
+
- **toCamelCase** - Convert to camelCase from kebab-case, snake_case, or spaces
|
|
45
|
+
- **toKebabCase** - Convert to kebab-case from camelCase, snake_case, or spaces
|
|
46
|
+
- **toSnakeCase** - Convert to snake_case from camelCase, kebab-case, or spaces
|
|
47
|
+
- **toPascalCase** - Convert to PascalCase from any format
|
|
48
|
+
|
|
49
|
+
### 🔍 String Comparison & Similarity
|
|
50
|
+
- **diff** - Find character differences between two strings
|
|
51
|
+
- **similarity** - Calculate similarity score (0-1) using Levenshtein distance
|
|
52
|
+
|
|
53
|
+
### 🎭 String Masking & Redaction
|
|
54
|
+
- **mask** - Mask sensitive information keeping only last N characters visible
|
|
55
|
+
- **redact** - Redact portions matching regex patterns
|
|
56
|
+
|
|
57
|
+
### 🌐 URL & Filename Safe Conversion
|
|
58
|
+
- **slugify** - Convert to URL-friendly slug format
|
|
59
|
+
- **filenameSafe** - Remove invalid filesystem characters
|
|
60
|
+
|
|
61
|
+
### ✔️ String Validation (20 validators)
|
|
62
|
+
- Email, UUID, Numeric, URL, Hex Color, Phone Number, Date
|
|
63
|
+
- Strong Password, JSON, Base64, Alphabetic, Alphanumeric
|
|
64
|
+
- Case validators, Whitespace, Palindrome, Hexadecimal, Roman Numeral
|
|
65
|
+
- IPv4, IPv6 validation
|
|
66
|
+
|
|
67
|
+
### 🌍 Unicode-Safe Operations
|
|
68
|
+
- **lengthUnicode** - Count Unicode grapheme clusters (handles emoji with modifiers)
|
|
69
|
+
- **unicodeSlice** - Slice strings while respecting grapheme boundaries
|
|
70
|
+
- **reverseUnicode** - Reverse strings with proper emoji and combining mark support
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Installation
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npm install string-extn
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Or with Yarn:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
yarn add string-extn
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Quick Start
|
|
89
|
+
|
|
90
|
+
### Core Functions
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { trim, pad, slice, repeat, truncate, reverse } from 'string-extn';
|
|
94
|
+
|
|
95
|
+
trim(' hello world '); // "hello world"
|
|
96
|
+
pad('abc', 5, '-'); // "abc--"
|
|
97
|
+
slice('hello', 1, 4); // "ell"
|
|
98
|
+
repeat('ha', 3); // "hahaha"
|
|
99
|
+
truncate('This is a long string', 10, '...'); // "This is a ..."
|
|
100
|
+
reverse('hello'); // "olleh"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Functional Programming
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import { map, filter, reduce, compose } from 'string-extn';
|
|
107
|
+
|
|
108
|
+
map('abc', c => c.toUpperCase()); // "ABC"
|
|
109
|
+
filter('abcdef', c => 'aeiou'.includes(c)); // "ae"
|
|
110
|
+
reduce('abc', (acc, c) => acc + c.charCodeAt(0), 0); // 294
|
|
111
|
+
|
|
112
|
+
const shout = compose(s => s + '!', s => s.toUpperCase());
|
|
113
|
+
shout('hello'); // "HELLO!"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Unicode-Safe Operations
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import { lengthUnicode, unicodeSlice, reverseUnicode } from 'string-extn';
|
|
120
|
+
|
|
121
|
+
const emojiStr = '👍🏽👍';
|
|
122
|
+
lengthUnicode(emojiStr); // 2 (counts emoji with skin tone as 1)
|
|
123
|
+
unicodeSlice(emojiStr, 0, 1); // "👍🏽"
|
|
124
|
+
reverseUnicode(emojiStr); // "👍👍🏽"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## API Reference
|
|
130
|
+
|
|
131
|
+
### Core Functions
|
|
132
|
+
|
|
133
|
+
| Function | Signature | Description |
|
|
134
|
+
|----------|-----------|-------------|
|
|
135
|
+
| `trim` | `trim(str: string): string` | Removes leading/trailing whitespace |
|
|
136
|
+
| `pad` | `pad(str: string, length: number, char?: string): string` | Pads string to fixed length |
|
|
137
|
+
| `slice` | `slice(str: string, start: number, end?: number): string` | Returns substring |
|
|
138
|
+
| `repeat` | `repeat(str: string, times: number): string` | Repeats string N times |
|
|
139
|
+
| `truncate` | `truncate(str: string, max: number): string` | Truncates with ellipsis (...) |
|
|
140
|
+
| `reverse` | `reverse(str: string): string` | Reverses string characters |
|
|
141
|
+
|
|
142
|
+
### Functional Programming
|
|
143
|
+
|
|
144
|
+
| Function | Signature | Description |
|
|
145
|
+
|----------|-----------|-------------|
|
|
146
|
+
| `map` | `map(str: string, fn: (c: string) => string): string` | Transforms each character |
|
|
147
|
+
| `filter` | `filter(str: string, fn: (c: string) => boolean): string` | Filters characters by predicate |
|
|
148
|
+
| `reduce` | `reduce<T>(str: string, fn: (acc: T, c: string) => T, initial: T): T` | Reduces string to accumulator value |
|
|
149
|
+
| `compose` | `compose(...fns: Function[]): (value: any) => any` | Composes functions right-to-left |
|
|
150
|
+
|
|
151
|
+
### Case Conversion
|
|
152
|
+
|
|
153
|
+
| Function | Signature | Description |
|
|
154
|
+
|----------|-----------|-------------|
|
|
155
|
+
| `toCamelCase` | `toCamelCase(input: string): string` | Converts to camelCase |
|
|
156
|
+
| `toKebabCase` | `toKebabCase(input: string): string` | Converts to kebab-case |
|
|
157
|
+
| `toSnakeCase` | `toSnakeCase(input: string): string` | Converts to snake_case |
|
|
158
|
+
| `toPascalCase` | `toPascalCase(input: string): string` | Converts to PascalCase |
|
|
159
|
+
|
|
160
|
+
### String Comparison & Similarity
|
|
161
|
+
|
|
162
|
+
| Function | Signature | Description |
|
|
163
|
+
|----------|-----------|-------------|
|
|
164
|
+
| `diff` | `diff(a: string, b: string): string[]` | Returns character differences between two strings |
|
|
165
|
+
| `similarity` | `similarity(a: string, b: string): number` | Returns similarity score (0-1) using Levenshtein distance |
|
|
166
|
+
|
|
167
|
+
### String Masking & Redaction
|
|
168
|
+
|
|
169
|
+
| Function | Signature | Description |
|
|
170
|
+
|----------|-----------|-------------|
|
|
171
|
+
| `mask` | `mask(input: string, visible?: number, maskChar?: string): string` | Masks string keeping last N characters visible |
|
|
172
|
+
| `redact` | `redact(input: string, patterns: RegExp[]): string` | Redacts portions matching regex patterns |
|
|
173
|
+
|
|
174
|
+
### URL & Filename Safe Conversion
|
|
175
|
+
|
|
176
|
+
| Function | Signature | Description |
|
|
177
|
+
|----------|-----------|-------------|
|
|
178
|
+
| `slugify` | `slugify(input: string): string` | Converts to URL-friendly slug format |
|
|
179
|
+
| `filenameSafe` | `filenameSafe(input: string): string` | Removes invalid filesystem characters |
|
|
180
|
+
|
|
181
|
+
### String Validation
|
|
182
|
+
|
|
183
|
+
| Function | Input | Returns | Purpose |
|
|
184
|
+
|----------|-------|---------|---------|
|
|
185
|
+
| `isEmail` | string | boolean | Validates email address format |
|
|
186
|
+
| `isUUID` | string | boolean | Validates UUID format (v1-v5) |
|
|
187
|
+
| `isNumeric` | string | boolean | Validates numeric strings |
|
|
188
|
+
| `isURL` | string | boolean | Validates URL format |
|
|
189
|
+
| `isHexColor` | string | boolean | Validates hex color codes |
|
|
190
|
+
| `isPhoneNumber` | string | boolean | Validates E.164 phone numbers |
|
|
191
|
+
| `isDate` | string | boolean | Validates date strings |
|
|
192
|
+
| `isStrongPassword` | string | boolean | Validates strong password criteria |
|
|
193
|
+
| `isJSON` | string | boolean | Validates JSON format |
|
|
194
|
+
| `isBase64` | string | boolean | Validates Base64 encoding |
|
|
195
|
+
| `isAlphabetic` | string | boolean | Validates alphabetic strings only |
|
|
196
|
+
| `isAlphanumeric` | string | boolean | Validates alphanumeric strings |
|
|
197
|
+
| `isLowerCase` | string | boolean | Validates lowercase strings |
|
|
198
|
+
| `isUpperCase` | string | boolean | Validates uppercase strings |
|
|
199
|
+
| `isWhitespace` | string | boolean | Validates whitespace-only strings |
|
|
200
|
+
| `isPalindrome` | string | boolean | Validates palindrome strings |
|
|
201
|
+
| `isHexadecimal` | string | boolean | Validates hexadecimal format |
|
|
202
|
+
| `isRomanNumeral` | string | boolean | Validates Roman numeral format |
|
|
203
|
+
| `isIPv4` | string | boolean | Validates IPv4 addresses |
|
|
204
|
+
| `isIPv6` | string | boolean | Validates IPv6 addresses |
|
|
205
|
+
|
|
206
|
+
### Unicode Operations
|
|
207
|
+
|
|
208
|
+
| Function | Signature | Description |
|
|
209
|
+
|----------|-----------|-------------|
|
|
210
|
+
| `lengthUnicode` | `lengthUnicode(str: string): number` | Counts Unicode grapheme clusters |
|
|
211
|
+
| `unicodeSlice` | `unicodeSlice(str: string, start: number, end?: number): string` | Slices by grapheme boundaries |
|
|
212
|
+
| `reverseUnicode` | `reverseUnicode(str: string): string` | Reverses with emoji/modifier support |
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Examples
|
|
217
|
+
|
|
218
|
+
### Example 1: Text Processing Pipeline
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
import { trim, map, filter } from 'string-extn';
|
|
222
|
+
|
|
223
|
+
const input = ' HELLO WORLD ';
|
|
224
|
+
const result = trim(input)
|
|
225
|
+
.toLowerCase()
|
|
226
|
+
.split(' ')
|
|
227
|
+
.map(word => filter(word, c => 'aeiou'.includes(c)))
|
|
228
|
+
.join(',');
|
|
229
|
+
|
|
230
|
+
console.log(result); // "e,o"
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Example 2: Case Conversion
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import { toCamelCase, toKebabCase, toSnakeCase, toPascalCase } from 'string-extn';
|
|
237
|
+
|
|
238
|
+
const text = 'hello-world-example';
|
|
239
|
+
|
|
240
|
+
console.log(toCamelCase(text)); // "helloWorldExample"
|
|
241
|
+
console.log(toKebabCase('helloWorld')); // "hello-world"
|
|
242
|
+
console.log(toSnakeCase('helloWorld')); // "hello_world"
|
|
243
|
+
console.log(toPascalCase(text)); // "HelloWorldExample"
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Example 3: String Similarity & Diff
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
import { similarity, diff } from 'string-extn';
|
|
250
|
+
|
|
251
|
+
const str1 = 'hello';
|
|
252
|
+
const str2 = 'hallo';
|
|
253
|
+
|
|
254
|
+
console.log(similarity(str1, str2)); // 0.8 (80% similar - one character different)
|
|
255
|
+
console.log(diff('abc', 'bcd')); // ["-a", "+d"]
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Example 4: Masking Sensitive Data
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
import { mask, redact } from 'string-extn';
|
|
262
|
+
|
|
263
|
+
// Mask credit card
|
|
264
|
+
const cardNumber = '4532111111111111';
|
|
265
|
+
console.log(mask(cardNumber, 4)); // "············1111"
|
|
266
|
+
|
|
267
|
+
// Redact email patterns
|
|
268
|
+
const text = 'Contact john@example.com or jane@test.org';
|
|
269
|
+
console.log(redact(text, [/@\w+\.\w+/g])); // "Contact [REDACTED] or [REDACTED]"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Example 5: URL & Filename Safe Conversion
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
import { slugify, filenameSafe } from 'string-extn';
|
|
276
|
+
|
|
277
|
+
console.log(slugify('Hello World! Welcome')); // "hello-world-welcome"
|
|
278
|
+
console.log(slugify('Café au Lait')); // "cafe-au-lait"
|
|
279
|
+
console.log(filenameSafe('File<>Name?.txt')); // "FileName.txt"
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Example 6: String Validation
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
import {
|
|
286
|
+
isEmail, isURL, isStrongPassword, isIPv4,
|
|
287
|
+
isPalindrome, isJSON
|
|
288
|
+
} from 'string-extn';
|
|
289
|
+
|
|
290
|
+
console.log(isEmail('user@example.com')); // true
|
|
291
|
+
console.log(isURL('https://example.com')); // true
|
|
292
|
+
console.log(isStrongPassword('MyPass@123')); // true
|
|
293
|
+
console.log(isIPv4('192.168.1.1')); // true
|
|
294
|
+
console.log(isPalindrome('A man a plan a canal Panama')); // true
|
|
295
|
+
console.log(isJSON('{"key":"value"}')); // true
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Example 7: Emoji Handling with Unicode
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
import { lengthUnicode, unicodeSlice, reverseUnicode } from 'string-extn';
|
|
302
|
+
|
|
303
|
+
const message = 'Hello 👨👩👧👦 World 🇺🇸';
|
|
304
|
+
|
|
305
|
+
console.log(lengthUnicode(message)); // Correctly counts family emoji as 1
|
|
306
|
+
console.log(unicodeSlice(message, 6, 8)); // "👨👩👧👦 "
|
|
307
|
+
console.log(reverseUnicode(message)); // Preserves emoji integrity
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Example 3: Function Composition
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
import { compose } from 'string-extn';
|
|
314
|
+
|
|
315
|
+
const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
316
|
+
const addPrefix = (s: string) => 'Hello, ' + s;
|
|
317
|
+
const addExclamation = (s: string) => s + '!';
|
|
318
|
+
|
|
319
|
+
const greet = compose(addExclamation, addPrefix, capitalize);
|
|
320
|
+
console.log(greet('world')); // "Hello, World!"
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## Testing
|
|
326
|
+
|
|
327
|
+
### Run the Test Suite
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
npm test
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Build the Library
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
npm run build
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
This generates compiled JavaScript in the `dist/` folder.
|
|
340
|
+
|
|
341
|
+
### Link Locally for Testing
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
# In the string-extn folder
|
|
345
|
+
npm link
|
|
346
|
+
|
|
347
|
+
# In your test project folder
|
|
348
|
+
npm link string-extn
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
### Development Commands
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
npm install # Install dependencies
|
|
357
|
+
npm run build # Build the library
|
|
358
|
+
npm test # Run tests
|
|
359
|
+
npm link # Link for local testing
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## License
|
|
365
|
+
|
|
366
|
+
MIT © Balaji Katta Venkatarathnam
|
|
367
|
+
|
package/dist/case.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a string to camelCase format.
|
|
3
|
+
*
|
|
4
|
+
* @param input - The input string to convert (can be kebab-case, snake_case, or space-separated)
|
|
5
|
+
* @returns The string converted to camelCase (first letter lowercase, subsequent words capitalized)
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* toCamelCase("hello-world") // returns "helloWorld"
|
|
9
|
+
* toCamelCase("hello_world") // returns "helloWorld"
|
|
10
|
+
* toCamelCase("hello world") // returns "helloWorld"
|
|
11
|
+
*/
|
|
12
|
+
export declare function toCamelCase(input: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Converts a string to kebab-case format.
|
|
15
|
+
*
|
|
16
|
+
* @param input - The input string to convert (can be camelCase, snake_case, or space-separated)
|
|
17
|
+
* @returns The string converted to kebab-case (lowercase with hyphens between words)
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* toKebabCase("helloWorld") // returns "hello-world"
|
|
21
|
+
* toKebabCase("hello_world") // returns "hello-world"
|
|
22
|
+
* toKebabCase("hello world") // returns "hello-world"
|
|
23
|
+
*/
|
|
24
|
+
export declare function toKebabCase(input: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Converts a string to snake_case format.
|
|
27
|
+
*
|
|
28
|
+
* @param input - The input string to convert (can be camelCase, kebab-case, or space-separated)
|
|
29
|
+
* @returns The string converted to snake_case (lowercase with underscores between words)
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* toSnakeCase("helloWorld") // returns "hello_world"
|
|
33
|
+
* toSnakeCase("hello-world") // returns "hello_world"
|
|
34
|
+
* toSnakeCase("hello world") // returns "hello_world"
|
|
35
|
+
*/
|
|
36
|
+
export declare function toSnakeCase(input: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Converts a string to Title Case format.
|
|
39
|
+
*
|
|
40
|
+
* @param input - The input string to convert
|
|
41
|
+
* @returns The string converted to Title Case (first letter of each word capitalized, rest lowercase)
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* toTitleCase("hello world") // returns "Hello World"
|
|
45
|
+
* toTitleCase("helloWorld") // returns "HelloWorld"
|
|
46
|
+
* toTitleCase("hello-world") // returns "Hello-World"
|
|
47
|
+
*/
|
|
48
|
+
export declare function toTitleCase(input: string): string;
|
|
49
|
+
//# sourceMappingURL=case.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"case.d.ts","sourceRoot":"","sources":["../src/case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAajD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWjD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAajD"}
|
package/dist/case.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a string to camelCase format.
|
|
3
|
+
*
|
|
4
|
+
* @param input - The input string to convert (can be kebab-case, snake_case, or space-separated)
|
|
5
|
+
* @returns The string converted to camelCase (first letter lowercase, subsequent words capitalized)
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* toCamelCase("hello-world") // returns "helloWorld"
|
|
9
|
+
* toCamelCase("hello_world") // returns "helloWorld"
|
|
10
|
+
* toCamelCase("hello world") // returns "helloWorld"
|
|
11
|
+
*/
|
|
12
|
+
export function toCamelCase(input) {
|
|
13
|
+
return input
|
|
14
|
+
.toLowerCase()
|
|
15
|
+
.replace(/[-_\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ""))
|
|
16
|
+
.replace(/^(.)/, (m) => m.toLowerCase());
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Converts a string to kebab-case format.
|
|
20
|
+
*
|
|
21
|
+
* @param input - The input string to convert (can be camelCase, snake_case, or space-separated)
|
|
22
|
+
* @returns The string converted to kebab-case (lowercase with hyphens between words)
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* toKebabCase("helloWorld") // returns "hello-world"
|
|
26
|
+
* toKebabCase("hello_world") // returns "hello-world"
|
|
27
|
+
* toKebabCase("hello world") // returns "hello-world"
|
|
28
|
+
*/
|
|
29
|
+
export function toKebabCase(input) {
|
|
30
|
+
// If the input is all uppercase (acronym style), just lowercase it
|
|
31
|
+
const compact = input.replace(/[_\s-]+/g, "");
|
|
32
|
+
if (compact && compact === compact.toUpperCase()) {
|
|
33
|
+
return input.replace(/[_\s]+/g, "-").toLowerCase();
|
|
34
|
+
}
|
|
35
|
+
// insert hyphen before every uppercase letter, treat underscores/spaces as separators
|
|
36
|
+
return input
|
|
37
|
+
.replace(/([A-Z])/g, "-$1")
|
|
38
|
+
.replace(/[_\s]+/g, "-")
|
|
39
|
+
.replace(/-+/g, "-")
|
|
40
|
+
.replace(/^-|-$|^-/g, "")
|
|
41
|
+
.toLowerCase();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Converts a string to snake_case format.
|
|
45
|
+
*
|
|
46
|
+
* @param input - The input string to convert (can be camelCase, kebab-case, or space-separated)
|
|
47
|
+
* @returns The string converted to snake_case (lowercase with underscores between words)
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* toSnakeCase("helloWorld") // returns "hello_world"
|
|
51
|
+
* toSnakeCase("hello-world") // returns "hello_world"
|
|
52
|
+
* toSnakeCase("hello world") // returns "hello_world"
|
|
53
|
+
*/
|
|
54
|
+
export function toSnakeCase(input) {
|
|
55
|
+
const compact = input.replace(/[-\s_]+/g, "");
|
|
56
|
+
if (compact && compact === compact.toUpperCase()) {
|
|
57
|
+
return input.replace(/[-\s]+/g, "_").toLowerCase();
|
|
58
|
+
}
|
|
59
|
+
return input
|
|
60
|
+
.replace(/([A-Z])/g, "_$1")
|
|
61
|
+
.replace(/[-\s]+/g, "_")
|
|
62
|
+
.replace(/_+/g, "_")
|
|
63
|
+
.replace(/^_|_$/g, "")
|
|
64
|
+
.toLowerCase();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Converts a string to Title Case format.
|
|
68
|
+
*
|
|
69
|
+
* @param input - The input string to convert
|
|
70
|
+
* @returns The string converted to Title Case (first letter of each word capitalized, rest lowercase)
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* toTitleCase("hello world") // returns "Hello World"
|
|
74
|
+
* toTitleCase("helloWorld") // returns "HelloWorld"
|
|
75
|
+
* toTitleCase("hello-world") // returns "Hello-World"
|
|
76
|
+
*/
|
|
77
|
+
export function toTitleCase(input) {
|
|
78
|
+
// Preserve separators and multiple spaces; capitalize first char of each word
|
|
79
|
+
const parts = input.split(/([^A-Za-z0-9]+)/);
|
|
80
|
+
return parts
|
|
81
|
+
.map((tok) => {
|
|
82
|
+
if (/^[A-Za-z0-9_]+$/.test(tok)) {
|
|
83
|
+
// if token is all uppercase, downcase then capitalize
|
|
84
|
+
if (tok === tok.toUpperCase())
|
|
85
|
+
tok = tok.toLowerCase();
|
|
86
|
+
return tok.charAt(0).toUpperCase() + tok.slice(1);
|
|
87
|
+
}
|
|
88
|
+
return tok;
|
|
89
|
+
})
|
|
90
|
+
.join("");
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=case.js.map
|
package/dist/case.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"case.js","sourceRoot":"","sources":["../src/case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,KAAK;SACT,WAAW,EAAE;SACb,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SAC7D,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,mEAAmE;IACnE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC9C,IAAI,OAAO,IAAI,OAAO,KAAK,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QACjD,OAAO,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IACrD,CAAC;IACD,sFAAsF;IACtF,OAAO,KAAK;SACT,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC;SAC1B,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;SACxB,WAAW,EAAE,CAAC;AACnB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC9C,IAAI,OAAO,IAAI,OAAO,KAAK,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QACjD,OAAO,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IACrD,CAAC;IACD,OAAO,KAAK;SACT,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC;SAC1B,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,WAAW,EAAE,CAAC;AACnB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,8EAA8E;IAC9E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC7C,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACX,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,sDAAsD;YACtD,IAAI,GAAG,KAAK,GAAG,CAAC,WAAW,EAAE;gBAAE,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YACvD,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC"}
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Removes leading and trailing whitespace from a string.
|
|
3
|
+
*
|
|
4
|
+
* @param str - The string to trim.
|
|
5
|
+
* @returns A new string with whitespace removed from both ends.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* trim(' hello world ') // => 'hello world'
|
|
9
|
+
*/
|
|
10
|
+
export declare function trim(str: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Pads a string to a specified length by appending characters to the end.
|
|
13
|
+
*
|
|
14
|
+
* @param str - The string to pad.
|
|
15
|
+
* @param length - The target length for the padded string.
|
|
16
|
+
* @param char - The character to pad with. Defaults to a space (' ').
|
|
17
|
+
* @returns A new string padded to the specified length, or the original string if already longer.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* pad('hello', 10, '-') // => 'hello-----'
|
|
21
|
+
* pad('hello', 8) // => 'hello '
|
|
22
|
+
*/
|
|
23
|
+
export declare function pad(str: string, length: number, char?: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Extracts a section of a string.
|
|
26
|
+
*
|
|
27
|
+
* @param str - The string to slice.
|
|
28
|
+
* @param start - The starting index (inclusive). Negative indices count from the end.
|
|
29
|
+
* @param end - The ending index (exclusive). Negative indices count from the end. Optional.
|
|
30
|
+
* @returns A new string containing the extracted section.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* slice('hello', 1, 4) // => 'ell'
|
|
34
|
+
* slice('hello', 2) // => 'llo'
|
|
35
|
+
* slice('hello', -3) // => 'llo'
|
|
36
|
+
*/
|
|
37
|
+
export declare function slice(str: string, start: number, end?: number): string;
|
|
38
|
+
/**
|
|
39
|
+
* Repeats a string a specified number of times.
|
|
40
|
+
*
|
|
41
|
+
* @param str - The string to repeat.
|
|
42
|
+
* @param times - The number of times to repeat the string. Must be a non-negative integer.
|
|
43
|
+
* @returns A new string with the original string repeated.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* repeat('ab', 3) // => 'ababab'
|
|
47
|
+
* repeat('x', 5) // => 'xxxxx'
|
|
48
|
+
*/
|
|
49
|
+
export declare function repeat(str: string, times: number): string;
|
|
50
|
+
/**
|
|
51
|
+
* Truncates a string to a maximum length and appends a suffix if truncated.
|
|
52
|
+
*
|
|
53
|
+
* @param input - The string to truncate.
|
|
54
|
+
* @param maxLength - The maximum length of the string (not including the suffix).
|
|
55
|
+
* @param suffix - The suffix to append if truncated. Defaults to '…'.
|
|
56
|
+
* @returns The original string if its length is <= maxLength, or the truncated string with suffix appended.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* truncate('hello world', 5) // => 'hello…'
|
|
60
|
+
* truncate('hi', 10) // => 'hi'
|
|
61
|
+
* truncate('hello world', 5, '...') // => 'he...'
|
|
62
|
+
*/
|
|
63
|
+
export declare function truncate(input: string, maxLength: number, suffix?: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Reverses the order of characters in a string.
|
|
66
|
+
*
|
|
67
|
+
* @param str - The string to reverse.
|
|
68
|
+
* @returns A new string with characters in reverse order.
|
|
69
|
+
*
|
|
70
|
+
* @note This function splits the string into individual characters and reverses them.
|
|
71
|
+
* For Unicode-aware reversal that handles complex grapheme clusters (like emojis with modifiers),
|
|
72
|
+
* use {@link reverseUnicode} from the unicode module instead.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* reverse('hello') // => 'olleh'
|
|
76
|
+
* reverse('12345') // => '54321'
|
|
77
|
+
*/
|
|
78
|
+
export declare function reverse(str: string): string;
|
|
79
|
+
//# sourceMappingURL=core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,SAAM,GAAG,MAAM,CAEnE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,MAAM,SAAQ,GACb,MAAM,CAIR;AAGD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C"}
|