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/dist/core.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
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 function trim(str) {
|
|
11
|
+
return str.trim();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Pads a string to a specified length by appending characters to the end.
|
|
15
|
+
*
|
|
16
|
+
* @param str - The string to pad.
|
|
17
|
+
* @param length - The target length for the padded string.
|
|
18
|
+
* @param char - The character to pad with. Defaults to a space (' ').
|
|
19
|
+
* @returns A new string padded to the specified length, or the original string if already longer.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* pad('hello', 10, '-') // => 'hello-----'
|
|
23
|
+
* pad('hello', 8) // => 'hello '
|
|
24
|
+
*/
|
|
25
|
+
export function pad(str, length, char = ' ') {
|
|
26
|
+
return str.padEnd(length, char);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Extracts a section of a string.
|
|
30
|
+
*
|
|
31
|
+
* @param str - The string to slice.
|
|
32
|
+
* @param start - The starting index (inclusive). Negative indices count from the end.
|
|
33
|
+
* @param end - The ending index (exclusive). Negative indices count from the end. Optional.
|
|
34
|
+
* @returns A new string containing the extracted section.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* slice('hello', 1, 4) // => 'ell'
|
|
38
|
+
* slice('hello', 2) // => 'llo'
|
|
39
|
+
* slice('hello', -3) // => 'llo'
|
|
40
|
+
*/
|
|
41
|
+
export function slice(str, start, end) {
|
|
42
|
+
return str.slice(start, end);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Repeats a string a specified number of times.
|
|
46
|
+
*
|
|
47
|
+
* @param str - The string to repeat.
|
|
48
|
+
* @param times - The number of times to repeat the string. Must be a non-negative integer.
|
|
49
|
+
* @returns A new string with the original string repeated.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* repeat('ab', 3) // => 'ababab'
|
|
53
|
+
* repeat('x', 5) // => 'xxxxx'
|
|
54
|
+
*/
|
|
55
|
+
export function repeat(str, times) {
|
|
56
|
+
return str.repeat(times);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Truncates a string to a maximum length and appends a suffix if truncated.
|
|
60
|
+
*
|
|
61
|
+
* @param input - The string to truncate.
|
|
62
|
+
* @param maxLength - The maximum length of the string (not including the suffix).
|
|
63
|
+
* @param suffix - The suffix to append if truncated. Defaults to 'β¦'.
|
|
64
|
+
* @returns The original string if its length is <= maxLength, or the truncated string with suffix appended.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* truncate('hello world', 5) // => 'helloβ¦'
|
|
68
|
+
* truncate('hi', 10) // => 'hi'
|
|
69
|
+
* truncate('hello world', 5, '...') // => 'he...'
|
|
70
|
+
*/
|
|
71
|
+
export function truncate(input, maxLength, suffix = "...") {
|
|
72
|
+
if (input.length <= maxLength)
|
|
73
|
+
return input;
|
|
74
|
+
// slice first maxLength chars, then append suffix (tests expect suffix appended)
|
|
75
|
+
return input.slice(0, Math.max(0, maxLength)) + suffix;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Reverses the order of characters in a string.
|
|
79
|
+
*
|
|
80
|
+
* @param str - The string to reverse.
|
|
81
|
+
* @returns A new string with characters in reverse order.
|
|
82
|
+
*
|
|
83
|
+
* @note This function splits the string into individual characters and reverses them.
|
|
84
|
+
* For Unicode-aware reversal that handles complex grapheme clusters (like emojis with modifiers),
|
|
85
|
+
* use {@link reverseUnicode} from the unicode module instead.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* reverse('hello') // => 'olleh'
|
|
89
|
+
* reverse('12345') // => '54321'
|
|
90
|
+
*/
|
|
91
|
+
export function reverse(str) {
|
|
92
|
+
return str.split('').reverse().join('');
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,MAAc,EAAE,IAAI,GAAG,GAAG;IACzD,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,KAAK,CAAC,GAAW,EAAE,KAAa,EAAE,GAAY;IAC5D,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,MAAM,CAAC,GAAW,EAAE,KAAa;IAC/C,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAa,EACb,SAAiB,EACjB,MAAM,GAAG,KAAK;IAEd,IAAI,KAAK,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,KAAK,CAAC;IAC5C,iFAAiF;IACjF,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC;AACzD,CAAC;AAGD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,OAAO,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1C,CAAC"}
|
package/dist/diff.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compares two strings and returns the character differences between them.
|
|
3
|
+
*
|
|
4
|
+
* @param a - The first string to compare
|
|
5
|
+
* @param b - The second string to compare
|
|
6
|
+
* @returns An array of character differences, where characters prefixed with '-' are in string a but not in b,
|
|
7
|
+
* and characters prefixed with '+' are in string b but not in a
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* diff("abc", "bcd") // returns ["-a", "+d"]
|
|
11
|
+
* diff("hello", "hallo") // returns ["-e", "+a"]
|
|
12
|
+
*
|
|
13
|
+
* @note Duplicates are removed as the comparison uses sets of unique characters
|
|
14
|
+
*/
|
|
15
|
+
export declare function diff(a: string, b: string): string[];
|
|
16
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAQnD"}
|
package/dist/diff.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compares two strings and returns the character differences between them.
|
|
3
|
+
*
|
|
4
|
+
* @param a - The first string to compare
|
|
5
|
+
* @param b - The second string to compare
|
|
6
|
+
* @returns An array of character differences, where characters prefixed with '-' are in string a but not in b,
|
|
7
|
+
* and characters prefixed with '+' are in string b but not in a
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* diff("abc", "bcd") // returns ["-a", "+d"]
|
|
11
|
+
* diff("hello", "hallo") // returns ["-e", "+a"]
|
|
12
|
+
*
|
|
13
|
+
* @note Duplicates are removed as the comparison uses sets of unique characters
|
|
14
|
+
*/
|
|
15
|
+
export function diff(a, b) {
|
|
16
|
+
const aSet = new Set(a.split(""));
|
|
17
|
+
const bSet = new Set(b.split(""));
|
|
18
|
+
return [
|
|
19
|
+
...[...aSet].filter(x => !bSet.has(x)).map(x => `-${x}`),
|
|
20
|
+
...[...bSet].filter(x => !aSet.has(x)).map(x => `+${x}`)
|
|
21
|
+
];
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=diff.js.map
|
package/dist/diff.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,IAAI,CAAC,CAAS,EAAE,CAAS;IACvC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAElC,OAAO;QACL,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxD,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;KACzD,CAAC;AACJ,CAAC"}
|
package/dist/fp.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Applies a transformation function to each character in a string.
|
|
3
|
+
*
|
|
4
|
+
* @param str - The string to map over.
|
|
5
|
+
* @param fn - A function that takes a character and returns a transformed character.
|
|
6
|
+
* @returns A new string with the transformation applied to each character.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* map('hello', c => c.toUpperCase()) // => 'HELLO'
|
|
10
|
+
* map('abc', c => c + c) // => 'aabbcc'
|
|
11
|
+
*/
|
|
12
|
+
export declare function map(str: string, fn: (c: string) => string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Filters characters in a string based on a predicate function.
|
|
15
|
+
*
|
|
16
|
+
* @param str - The string to filter.
|
|
17
|
+
* @param fn - A predicate function that returns true for characters to keep, false to remove.
|
|
18
|
+
* @returns A new string containing only the characters that satisfy the predicate.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* filter('hello', c => 'aeiou'.includes(c)) // => 'eo'
|
|
22
|
+
* filter('a1b2c3', c => /\d/.test(c)) // => '123'
|
|
23
|
+
*/
|
|
24
|
+
export declare function filter(str: string, fn: (c: string) => boolean): string;
|
|
25
|
+
/**
|
|
26
|
+
* Reduces a string to a single value by applying an accumulator function to each character.
|
|
27
|
+
*
|
|
28
|
+
* @typeParam T - The type of the accumulated value.
|
|
29
|
+
* @param str - The string to reduce.
|
|
30
|
+
* @param fn - A reducer function that takes the accumulated value and a character, and returns the new accumulated value.
|
|
31
|
+
* @param initial - The initial value for the accumulator.
|
|
32
|
+
* @returns The final accumulated value after processing all characters.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* reduce('hello', (acc, c) => acc + 1, 0) // => 5 (character count)
|
|
36
|
+
* reduce('abc', (acc, c) => acc + c, '') // => 'abc' (concatenation)
|
|
37
|
+
* reduce('aabbcc', (acc, c) => ({ ...acc, [c]: (acc[c] || 0) + 1 }), {}) // => { a: 2, b: 2, c: 2 }
|
|
38
|
+
*/
|
|
39
|
+
export declare function reduce<T>(str: string, fn: (acc: T, c: string) => T, initial: T): T;
|
|
40
|
+
/**
|
|
41
|
+
* Composes multiple functions into a single function that applies them right-to-left.
|
|
42
|
+
*
|
|
43
|
+
* @param fns - Variable number of functions to compose.
|
|
44
|
+
* @returns A new function that applies the composed functions to its argument.
|
|
45
|
+
* Functions are applied right-to-left (the rightmost function is applied first).
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* const upper = (s: string) => s.toUpperCase();
|
|
49
|
+
* const exclaim = (s: string) => s + '!';
|
|
50
|
+
* const composed = compose(exclaim, upper);
|
|
51
|
+
* composed('hello') // => 'HELLO!' (upper applied first, then exclaim)
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* const add5 = (x: number) => x + 5;
|
|
55
|
+
* const mult2 = (x: number) => x * 2;
|
|
56
|
+
* const composed = compose(mult2, add5);
|
|
57
|
+
* composed(3) // => 16 (add5(3) = 8, then mult2(8) = 16)
|
|
58
|
+
*/
|
|
59
|
+
export declare function compose(...fns: Function[]): (value: any) => any;
|
|
60
|
+
//# sourceMappingURL=fp.d.ts.map
|
package/dist/fp.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fp.d.ts","sourceRoot":"","sources":["../src/fp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAElE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAEtE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,CAAC,EACtB,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC,EAC5B,OAAO,EAAE,CAAC,GACT,CAAC,CAEH;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,OAAO,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,IAChC,OAAO,GAAG,SACnB"}
|
package/dist/fp.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Applies a transformation function to each character in a string.
|
|
3
|
+
*
|
|
4
|
+
* @param str - The string to map over.
|
|
5
|
+
* @param fn - A function that takes a character and returns a transformed character.
|
|
6
|
+
* @returns A new string with the transformation applied to each character.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* map('hello', c => c.toUpperCase()) // => 'HELLO'
|
|
10
|
+
* map('abc', c => c + c) // => 'aabbcc'
|
|
11
|
+
*/
|
|
12
|
+
export function map(str, fn) {
|
|
13
|
+
return str.split('').map(fn).join('');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Filters characters in a string based on a predicate function.
|
|
17
|
+
*
|
|
18
|
+
* @param str - The string to filter.
|
|
19
|
+
* @param fn - A predicate function that returns true for characters to keep, false to remove.
|
|
20
|
+
* @returns A new string containing only the characters that satisfy the predicate.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* filter('hello', c => 'aeiou'.includes(c)) // => 'eo'
|
|
24
|
+
* filter('a1b2c3', c => /\d/.test(c)) // => '123'
|
|
25
|
+
*/
|
|
26
|
+
export function filter(str, fn) {
|
|
27
|
+
return str.split('').filter(fn).join('');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Reduces a string to a single value by applying an accumulator function to each character.
|
|
31
|
+
*
|
|
32
|
+
* @typeParam T - The type of the accumulated value.
|
|
33
|
+
* @param str - The string to reduce.
|
|
34
|
+
* @param fn - A reducer function that takes the accumulated value and a character, and returns the new accumulated value.
|
|
35
|
+
* @param initial - The initial value for the accumulator.
|
|
36
|
+
* @returns The final accumulated value after processing all characters.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* reduce('hello', (acc, c) => acc + 1, 0) // => 5 (character count)
|
|
40
|
+
* reduce('abc', (acc, c) => acc + c, '') // => 'abc' (concatenation)
|
|
41
|
+
* reduce('aabbcc', (acc, c) => ({ ...acc, [c]: (acc[c] || 0) + 1 }), {}) // => { a: 2, b: 2, c: 2 }
|
|
42
|
+
*/
|
|
43
|
+
export function reduce(str, fn, initial) {
|
|
44
|
+
return str.split('').reduce(fn, initial);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Composes multiple functions into a single function that applies them right-to-left.
|
|
48
|
+
*
|
|
49
|
+
* @param fns - Variable number of functions to compose.
|
|
50
|
+
* @returns A new function that applies the composed functions to its argument.
|
|
51
|
+
* Functions are applied right-to-left (the rightmost function is applied first).
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* const upper = (s: string) => s.toUpperCase();
|
|
55
|
+
* const exclaim = (s: string) => s + '!';
|
|
56
|
+
* const composed = compose(exclaim, upper);
|
|
57
|
+
* composed('hello') // => 'HELLO!' (upper applied first, then exclaim)
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* const add5 = (x: number) => x + 5;
|
|
61
|
+
* const mult2 = (x: number) => x * 2;
|
|
62
|
+
* const composed = compose(mult2, add5);
|
|
63
|
+
* composed(3) // => 16 (add5(3) = 8, then mult2(8) = 16)
|
|
64
|
+
*/
|
|
65
|
+
export function compose(...fns) {
|
|
66
|
+
return (value) => fns.reduceRight((acc, fn) => fn(acc), value);
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=fp.js.map
|
package/dist/fp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fp.js","sourceRoot":"","sources":["../src/fp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,EAAyB;IACxD,OAAO,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,MAAM,CAAC,GAAW,EAAE,EAA0B;IAC5D,OAAO,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,MAAM,CACpB,GAAW,EACX,EAA4B,EAC5B,OAAU;IAEV,OAAO,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,OAAO,CAAC,GAAG,GAAe;IACxC,OAAO,CAAC,KAAU,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;AACtE,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './core.js';
|
|
2
|
+
export * from './fp.js';
|
|
3
|
+
export * from './unicode.js';
|
|
4
|
+
export * from './case.js';
|
|
5
|
+
export * from './slug.js';
|
|
6
|
+
export * from './mask.js';
|
|
7
|
+
export * from './similarity.js';
|
|
8
|
+
export * from './diff.js';
|
|
9
|
+
export * from './validate.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './core.js';
|
|
2
|
+
export * from './fp.js';
|
|
3
|
+
export * from './unicode.js';
|
|
4
|
+
export * from './case.js';
|
|
5
|
+
export * from './slug.js';
|
|
6
|
+
export * from './mask.js';
|
|
7
|
+
export * from './similarity.js';
|
|
8
|
+
export * from './diff.js';
|
|
9
|
+
export * from './validate.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
|
package/dist/mask.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Masks a string by replacing characters with a mask character, keeping only the last visible characters.
|
|
3
|
+
*
|
|
4
|
+
* @param input - The string to mask
|
|
5
|
+
* @param visible - The number of characters to keep visible at the end (default: 4)
|
|
6
|
+
* @param maskChar - The character used for masking (default: '*')
|
|
7
|
+
* @returns The masked string with the last 'visible' characters shown and the rest replaced with maskChar
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* mask("1234567890") // returns "******7890"
|
|
11
|
+
* mask("1234567890", 6) // returns "****567890"
|
|
12
|
+
* mask("password", 2, '#') // returns "######rd"
|
|
13
|
+
* mask("abc", 4) // returns "***" (if input is shorter than visible, all chars are masked)
|
|
14
|
+
*
|
|
15
|
+
* @note Commonly used for masking sensitive information like credit card numbers, phone numbers, and passwords
|
|
16
|
+
*/
|
|
17
|
+
export declare function mask(input: string, visible?: number, maskChar?: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Redacts portions of a string that match the provided patterns.
|
|
20
|
+
*
|
|
21
|
+
* @param input - The string to redact
|
|
22
|
+
* @param patterns - An array of regular expressions to match against the input string
|
|
23
|
+
* @returns The string with matched patterns replaced with '[REDACTED]'
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* redact("Email: john@example.com", [/@\w+\.\w+/]) // returns "Email: john[REDACTED]"
|
|
27
|
+
* redact("Phone: 123-456-7890", [/\d{3}-\d{3}-\d{4}/]) // returns "Phone: [REDACTED]"
|
|
28
|
+
* redact("Name: Alice, ID: 12345", [/\d+/, /[A-Z][a-z]+/]) // returns "Name: [REDACTED], ID: [REDACTED]"
|
|
29
|
+
*
|
|
30
|
+
* @note All matches are replaced sequentially; patterns are applied in order
|
|
31
|
+
*/
|
|
32
|
+
export declare function redact(input: string, patterns: RegExp[]): string;
|
|
33
|
+
//# sourceMappingURL=mask.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mask.d.ts","sourceRoot":"","sources":["../src/mask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,IAAI,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,SAAI,EACX,QAAQ,SAAM,GACb,MAAM,CAaR;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CACpB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,CASR"}
|
package/dist/mask.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Masks a string by replacing characters with a mask character, keeping only the last visible characters.
|
|
3
|
+
*
|
|
4
|
+
* @param input - The string to mask
|
|
5
|
+
* @param visible - The number of characters to keep visible at the end (default: 4)
|
|
6
|
+
* @param maskChar - The character used for masking (default: '*')
|
|
7
|
+
* @returns The masked string with the last 'visible' characters shown and the rest replaced with maskChar
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* mask("1234567890") // returns "******7890"
|
|
11
|
+
* mask("1234567890", 6) // returns "****567890"
|
|
12
|
+
* mask("password", 2, '#') // returns "######rd"
|
|
13
|
+
* mask("abc", 4) // returns "***" (if input is shorter than visible, all chars are masked)
|
|
14
|
+
*
|
|
15
|
+
* @note Commonly used for masking sensitive information like credit card numbers, phone numbers, and passwords
|
|
16
|
+
*/
|
|
17
|
+
export function mask(input, visible = 4, maskChar = "*") {
|
|
18
|
+
const ch = maskChar ? maskChar.charAt(0) : "*";
|
|
19
|
+
if (visible <= 0)
|
|
20
|
+
return ch.repeat(input.length);
|
|
21
|
+
if (input.length === 0)
|
|
22
|
+
return "";
|
|
23
|
+
// If visible is greater than or equal to the string length, decide behavior:
|
|
24
|
+
// - For very short inputs (length < 4) we mask entirely
|
|
25
|
+
// - Otherwise we show the whole input
|
|
26
|
+
if (visible >= input.length) {
|
|
27
|
+
if (input.length < 4)
|
|
28
|
+
return ch.repeat(input.length);
|
|
29
|
+
return input;
|
|
30
|
+
}
|
|
31
|
+
return ch.repeat(input.length - visible) + input.slice(-visible);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Redacts portions of a string that match the provided patterns.
|
|
35
|
+
*
|
|
36
|
+
* @param input - The string to redact
|
|
37
|
+
* @param patterns - An array of regular expressions to match against the input string
|
|
38
|
+
* @returns The string with matched patterns replaced with '[REDACTED]'
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* redact("Email: john@example.com", [/@\w+\.\w+/]) // returns "Email: john[REDACTED]"
|
|
42
|
+
* redact("Phone: 123-456-7890", [/\d{3}-\d{3}-\d{4}/]) // returns "Phone: [REDACTED]"
|
|
43
|
+
* redact("Name: Alice, ID: 12345", [/\d+/, /[A-Z][a-z]+/]) // returns "Name: [REDACTED], ID: [REDACTED]"
|
|
44
|
+
*
|
|
45
|
+
* @note All matches are replaced sequentially; patterns are applied in order
|
|
46
|
+
*/
|
|
47
|
+
export function redact(input, patterns) {
|
|
48
|
+
let result = input;
|
|
49
|
+
for (const pattern of patterns) {
|
|
50
|
+
// ensure global replacement unless the pattern already has 'g'
|
|
51
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : pattern.flags + "g";
|
|
52
|
+
const re = new RegExp(pattern.source, flags);
|
|
53
|
+
result = result.replace(re, "[REDACTED]");
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=mask.js.map
|
package/dist/mask.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mask.js","sourceRoot":"","sources":["../src/mask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,IAAI,CAClB,KAAa,EACb,OAAO,GAAG,CAAC,EACX,QAAQ,GAAG,GAAG;IAEd,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC/C,IAAI,OAAO,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,6EAA6E;IAC7E,wDAAwD;IACxD,sCAAsC;IACtC,IAAI,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,MAAM,CACpB,KAAa,EACb,QAAkB;IAElB,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,+DAA+D;QAC/D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,GAAG,GAAG,CAAC;QAChF,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC7C,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculates the similarity between two strings using the Levenshtein distance algorithm.
|
|
3
|
+
*
|
|
4
|
+
* @param a - The first string to compare
|
|
5
|
+
* @param b - The second string to compare
|
|
6
|
+
* @returns A similarity score between 0 and 1, where 1 means the strings are identical and 0 means completely different
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* similarity("hello", "hello") // returns 1 (identical)
|
|
10
|
+
* similarity("hello", "hallo") // returns 0.8 (one character different)
|
|
11
|
+
* similarity("abc", "def") // returns 0 (completely different)
|
|
12
|
+
* similarity("", "") // returns 0 (one or both strings empty)
|
|
13
|
+
*
|
|
14
|
+
* @note Uses dynamic programming to compute the Levenshtein distance (edit distance) and converts it to a similarity score.
|
|
15
|
+
* The algorithm accounts for three operations: insertion, deletion, and substitution.
|
|
16
|
+
*/
|
|
17
|
+
export declare function similarity(a: string, b: string): number;
|
|
18
|
+
//# sourceMappingURL=similarity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"similarity.d.ts","sourceRoot":"","sources":["../src/similarity.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAsCvD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculates the similarity between two strings using the Levenshtein distance algorithm.
|
|
3
|
+
*
|
|
4
|
+
* @param a - The first string to compare
|
|
5
|
+
* @param b - The second string to compare
|
|
6
|
+
* @returns A similarity score between 0 and 1, where 1 means the strings are identical and 0 means completely different
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* similarity("hello", "hello") // returns 1 (identical)
|
|
10
|
+
* similarity("hello", "hallo") // returns 0.8 (one character different)
|
|
11
|
+
* similarity("abc", "def") // returns 0 (completely different)
|
|
12
|
+
* similarity("", "") // returns 0 (one or both strings empty)
|
|
13
|
+
*
|
|
14
|
+
* @note Uses dynamic programming to compute the Levenshtein distance (edit distance) and converts it to a similarity score.
|
|
15
|
+
* The algorithm accounts for three operations: insertion, deletion, and substitution.
|
|
16
|
+
*/
|
|
17
|
+
export function similarity(a, b) {
|
|
18
|
+
if (a === b)
|
|
19
|
+
return 1;
|
|
20
|
+
if (!a.length || !b.length)
|
|
21
|
+
return 0;
|
|
22
|
+
const rows = b.length + 1;
|
|
23
|
+
const cols = a.length + 1;
|
|
24
|
+
const matrix = [];
|
|
25
|
+
for (let i = 0; i < rows; i++) {
|
|
26
|
+
matrix.push(Array(cols).fill(0));
|
|
27
|
+
}
|
|
28
|
+
// Initialize matrix
|
|
29
|
+
for (let i = 0; i < rows; i++) {
|
|
30
|
+
matrix[i][0] = i;
|
|
31
|
+
}
|
|
32
|
+
for (let j = 0; j < cols; j++) {
|
|
33
|
+
matrix[0][j] = j;
|
|
34
|
+
}
|
|
35
|
+
// Compute distances
|
|
36
|
+
for (let i = 1; i < rows; i++) {
|
|
37
|
+
for (let j = 1; j < cols; j++) {
|
|
38
|
+
const cost = b[i - 1] === a[j - 1] ? 0 : 1;
|
|
39
|
+
const currentRow = matrix[i];
|
|
40
|
+
const prevRow = matrix[i - 1];
|
|
41
|
+
currentRow[j] = Math.min(prevRow[j] + 1, // deletion
|
|
42
|
+
currentRow[j - 1] + 1, // insertion
|
|
43
|
+
prevRow[j - 1] + cost // substitution
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const distance = matrix[b.length][a.length];
|
|
48
|
+
return 1 - distance / Math.max(a.length, b.length);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=similarity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"similarity.js","sourceRoot":"","sources":["../src/similarity.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,UAAU,CAAC,CAAS,EAAE,CAAS;IAC7C,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtB,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IAErC,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAE1B,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAa,CAAC,CAAC;IAC/C,CAAC;IAED,oBAAoB;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,CAAC,CAAC,CAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,CAAC,CAAC,CAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,oBAAoB;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAa,CAAC;YACzC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAa,CAAC;YAE1C,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CACtB,OAAO,CAAC,CAAC,CAAE,GAAG,CAAC,EAAM,WAAW;YAChC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,CAAC,EAAM,YAAY;YACxC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,IAAI,CAAC,eAAe;aACvC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAc,CAAC,CAAC,CAAC,MAAM,CAAE,CAAC;IAC3D,OAAO,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;AACrD,CAAC"}
|
package/dist/slug.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a string to a URL-friendly slug format.
|
|
3
|
+
*
|
|
4
|
+
* @param input - The string to convert to a slug
|
|
5
|
+
* @returns A slug-formatted string (lowercase, hyphen-separated, no special characters or accents)
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* slugify("Hello World") // returns "hello-world"
|
|
9
|
+
* slugify("CafΓ© au Lait") // returns "cafe-au-lait" (accents removed)
|
|
10
|
+
* slugify("Hello---World") // returns "hello-world" (multiple hyphens normalized)
|
|
11
|
+
* slugify("---Hello World---") // returns "hello-world" (leading/trailing hyphens removed)
|
|
12
|
+
*
|
|
13
|
+
* @note Removes diacritical marks and special characters, suitable for URLs and routing
|
|
14
|
+
*/
|
|
15
|
+
export declare function slugify(input: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Removes invalid filesystem characters from a string to make it a safe filename.
|
|
18
|
+
*
|
|
19
|
+
* @param input - The string to make filesystem-safe
|
|
20
|
+
* @returns A filename-safe string with invalid characters removed and whitespace trimmed
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* filenameSafe("My File.txt") // returns "My File.txt"
|
|
24
|
+
* filenameSafe("Document<>?.txt") // returns "Document.txt"
|
|
25
|
+
* filenameSafe("File:Name|Invalid.doc") // returns "FileNameInvalid.doc"
|
|
26
|
+
* filenameSafe(" spaces.txt ") // returns "spaces.txt" (trimmed)
|
|
27
|
+
*
|
|
28
|
+
* @note Removes characters: < > : " / \ | ? * and control characters (ASCII 0-31).
|
|
29
|
+
* Compatible with Windows, Mac, and Linux filesystems.
|
|
30
|
+
*/
|
|
31
|
+
export declare function filenameSafe(input: string): string;
|
|
32
|
+
//# sourceMappingURL=slug.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slug.d.ts","sourceRoot":"","sources":["../src/slug.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAU7C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD"}
|
package/dist/slug.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a string to a URL-friendly slug format.
|
|
3
|
+
*
|
|
4
|
+
* @param input - The string to convert to a slug
|
|
5
|
+
* @returns A slug-formatted string (lowercase, hyphen-separated, no special characters or accents)
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* slugify("Hello World") // returns "hello-world"
|
|
9
|
+
* slugify("CafΓ© au Lait") // returns "cafe-au-lait" (accents removed)
|
|
10
|
+
* slugify("Hello---World") // returns "hello-world" (multiple hyphens normalized)
|
|
11
|
+
* slugify("---Hello World---") // returns "hello-world" (leading/trailing hyphens removed)
|
|
12
|
+
*
|
|
13
|
+
* @note Removes diacritical marks and special characters, suitable for URLs and routing
|
|
14
|
+
*/
|
|
15
|
+
export function slugify(input) {
|
|
16
|
+
return input
|
|
17
|
+
.normalize("NFKD")
|
|
18
|
+
.replace(/[\u0300-\u036f]/g, "")
|
|
19
|
+
.toLowerCase()
|
|
20
|
+
// Remove punctuation except common separators (space, hyphen, underscore)
|
|
21
|
+
.replace(/[^a-z0-9\s_-]+/g, "")
|
|
22
|
+
// Normalize separators to single hyphen
|
|
23
|
+
.replace(/[\s_-]+/g, "-")
|
|
24
|
+
.replace(/(^-|-$)+/g, "");
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Removes invalid filesystem characters from a string to make it a safe filename.
|
|
28
|
+
*
|
|
29
|
+
* @param input - The string to make filesystem-safe
|
|
30
|
+
* @returns A filename-safe string with invalid characters removed and whitespace trimmed
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* filenameSafe("My File.txt") // returns "My File.txt"
|
|
34
|
+
* filenameSafe("Document<>?.txt") // returns "Document.txt"
|
|
35
|
+
* filenameSafe("File:Name|Invalid.doc") // returns "FileNameInvalid.doc"
|
|
36
|
+
* filenameSafe(" spaces.txt ") // returns "spaces.txt" (trimmed)
|
|
37
|
+
*
|
|
38
|
+
* @note Removes characters: < > : " / \ | ? * and control characters (ASCII 0-31).
|
|
39
|
+
* Compatible with Windows, Mac, and Linux filesystems.
|
|
40
|
+
*/
|
|
41
|
+
export function filenameSafe(input) {
|
|
42
|
+
return input.replace(/[<>:"/\\|?*\x00-\x1F]/g, "").trim();
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=slug.js.map
|
package/dist/slug.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slug.js","sourceRoot":"","sources":["../src/slug.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,KAAK;SACT,SAAS,CAAC,MAAM,CAAC;SACjB,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;SAC/B,WAAW,EAAE;QACd,0EAA0E;SACzE,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC/B,wCAAwC;SACvC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Counts the number of grapheme clusters (user-perceived characters) in a Unicode string.
|
|
3
|
+
*
|
|
4
|
+
* This function properly handles complex Unicode characters including:
|
|
5
|
+
* - Emoji with skin tone modifiers (e.g., ππ½)
|
|
6
|
+
* - Multi-codepoint emoji sequences (e.g., family emoji π¨βπ©βπ§βπ¦)
|
|
7
|
+
* - Flag emoji (e.g., πΊπΈ)
|
|
8
|
+
* - Accented characters and combining marks
|
|
9
|
+
*
|
|
10
|
+
* @param str - The Unicode string to count.
|
|
11
|
+
* @returns The number of grapheme clusters in the string.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* lengthUnicode('hello') // => 5
|
|
15
|
+
* lengthUnicode('ππ½π') // => 2 (skin tone modifier counted as part of first emoji)
|
|
16
|
+
* lengthUnicode('π¨βπ©βπ§βπ¦') // => 1 (complex emoji sequence counted as single grapheme)
|
|
17
|
+
*/
|
|
18
|
+
export declare function lengthUnicode(str: string): number;
|
|
19
|
+
/**
|
|
20
|
+
* Extracts a section of a Unicode string by grapheme cluster indices.
|
|
21
|
+
*
|
|
22
|
+
* This function correctly slices strings containing complex Unicode characters where
|
|
23
|
+
* multiple codepoints form a single user-perceived character. Use this instead of
|
|
24
|
+
* {@link slice} for proper Unicode-aware slicing.
|
|
25
|
+
*
|
|
26
|
+
* @param str - The Unicode string to slice.
|
|
27
|
+
* @param start - The starting grapheme cluster index (inclusive). Negative indices count from the end.
|
|
28
|
+
* @param end - The ending grapheme cluster index (exclusive). Negative indices count from the end. Optional.
|
|
29
|
+
* @returns A new string containing the extracted grapheme clusters.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* unicodeSlice('hello', 1, 4) // => 'ell'
|
|
33
|
+
* unicodeSlice('ππ½ππ', 0, 2) // => 'ππ½π' (correctly handles skin tone modifier)
|
|
34
|
+
* unicodeSlice('πππ', 1) // => 'ππ'
|
|
35
|
+
*/
|
|
36
|
+
export declare function unicodeSlice(str: string, start: number, end?: number): string;
|
|
37
|
+
/**
|
|
38
|
+
* Reverses the order of grapheme clusters in a Unicode string.
|
|
39
|
+
*
|
|
40
|
+
* This function properly reverses strings containing complex Unicode characters where
|
|
41
|
+
* multiple codepoints form a single user-perceived character. It maintains the integrity
|
|
42
|
+
* of multi-codepoint emoji and other complex grapheme clusters. Use this instead of
|
|
43
|
+
* {@link reverse} for Unicode-aware reversal.
|
|
44
|
+
*
|
|
45
|
+
* @param str - The Unicode string to reverse.
|
|
46
|
+
* @returns A new string with grapheme clusters in reverse order.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* reverseUnicode('hello') // => 'olleh'
|
|
50
|
+
* reverseUnicode('ππ½π') // => 'πππ½' (preserves emoji integrity)
|
|
51
|
+
* reverseUnicode('π¨βπ©βπ§βπ¦π') // => 'ππ¨βπ©βπ§βπ¦' (maintains complex emoji as single unit)
|
|
52
|
+
*/
|
|
53
|
+
export declare function reverseUnicode(str: string): string;
|
|
54
|
+
//# sourceMappingURL=unicode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unicode.d.ts","sourceRoot":"","sources":["../src/unicode.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAG7E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD"}
|