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/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
@@ -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
@@ -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
@@ -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"}
@@ -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
@@ -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
@@ -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"}