Skip to content

Commit 6c2c2e6

Browse files
authored
Phase 2 add utilities (#2)
1 parent 6f9c43f commit 6c2c2e6

16 files changed

+245
-0
lines changed

src/camelCase.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Converts a string to camelCase
3+
* @param str - The input string to convert
4+
* @returns A camelCase string
5+
* @example
6+
* camelCase('hello world') // 'helloWorld'
7+
* camelCase('hello-world') // 'helloWorld'
8+
* camelCase('hello_world') // 'helloWorld'
9+
*/
10+
export const camelCase = (str: string): string => {
11+
return str
12+
.replace(/[^a-zA-Z0-9]+(.)/g, (_, chr) => chr.toUpperCase())
13+
.replace(/^[A-Z]/, (chr) => chr.toLowerCase());
14+
};

src/capitalize.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Capitalizes the first letter of a string
3+
* @param str - The input string to capitalize
4+
* @returns A string with the first letter capitalized
5+
* @example
6+
* capitalize('hello world') // 'Hello world'
7+
* capitalize('HELLO') // 'HELLO'
8+
*/
9+
export const capitalize = (str: string): string => {
10+
if (!str) return str;
11+
return str.charAt(0).toUpperCase() + str.slice(1);
12+
};

src/escapeHtml.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Escapes HTML special characters in a string
3+
* @param str - The input string to escape
4+
* @returns A string with HTML entities escaped
5+
* @example
6+
* escapeHtml('<div>Hello & "World"</div>') // '&lt;div&gt;Hello &amp; &quot;World&quot;&lt;/div&gt;'
7+
* escapeHtml("It's <script>") // 'It&#39;s &lt;script&gt;'
8+
*/
9+
export const escapeHtml = (str: string): string => {
10+
const htmlEntities: Record<string, string> = {
11+
'&': '&amp;',
12+
'<': '&lt;',
13+
'>': '&gt;',
14+
'"': '&quot;',
15+
"'": '&#39;'
16+
};
17+
18+
return str.replace(/[&<>"']/g, (match) => htmlEntities[match] ?? match);
19+
};

src/hashString.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Generates a simple hash from a string (non-cryptographic)
3+
* @param str - The input string to hash
4+
* @returns A numeric hash value
5+
* @example
6+
* hashString('hello') // 99162322
7+
* hashString('world') // 113318802
8+
*/
9+
export const hashString = (str: string): number => {
10+
let hash = 0;
11+
12+
if (str.length === 0) return hash;
13+
14+
for (let i = 0; i < str.length; i++) {
15+
const char = str.charCodeAt(i);
16+
hash = ((hash << 5) - hash) + char;
17+
hash = hash & hash; // Convert to 32-bit integer
18+
}
19+
20+
return Math.abs(hash);
21+
};

src/index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export { slugify } from './slugify.js';
2+
export { truncate } from './truncate.js';
3+
export { capitalize } from './capitalize.js';
4+
export { camelCase } from './camelCase.js';
5+
export { snakeCase } from './snakeCase.js';
6+
export { kebabCase } from './kebabCase.js';
7+
export { stripHtml } from './stripHtml.js';
8+
export { escapeHtml } from './escapeHtml.js';
9+
export { randomString } from './randomString.js';
10+
export { hashString } from './hashString.js';
11+
export { pascalCase } from './pascalCase.js';
12+
export { reverse } from './reverse.js';
13+
export { isEmail } from './isEmail.js';
14+
export { isUrl } from './isUrl.js';
15+
export { wordCount } from './wordCount.js';

src/isEmail.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* Validates if a string is a valid email format
3+
* @param str - The input string to validate
4+
* @returns True if the string is a valid email format, false otherwise
5+
* @example
6+
* isEmail('[email protected]') // true
7+
* isEmail('invalid.email') // false
8+
* isEmail('[email protected]') // true
9+
*/
10+
export const isEmail = (str: string): boolean => {
11+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
12+
return emailRegex.test(str);
13+
};

src/isUrl.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Validates if a string is a valid URL format
3+
* @param str - The input string to validate
4+
* @returns True if the string is a valid URL format, false otherwise
5+
* @example
6+
* isUrl('https://example.com') // true
7+
* isUrl('http://localhost:3000') // true
8+
* isUrl('not a url') // false
9+
*/
10+
export const isUrl = (str: string): boolean => {
11+
try {
12+
new URL(str);
13+
return true;
14+
} catch {
15+
return false;
16+
}
17+
};

src/kebabCase.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Converts a string to kebab-case
3+
* @param str - The input string to convert
4+
* @returns A kebab-case string
5+
* @example
6+
* kebabCase('Hello World') // 'hello-world'
7+
* kebabCase('helloWorld') // 'hello-world'
8+
* kebabCase('hello_world') // 'hello-world'
9+
*/
10+
export const kebabCase = (str: string): string => {
11+
return str
12+
.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)
13+
.replace(/[^a-z0-9]+/gi, '-')
14+
.replace(/^-+|-+$/g, '')
15+
.replace(/-+/g, '-')
16+
.toLowerCase();
17+
};

src/pascalCase.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Converts a string to PascalCase
3+
* @param str - The input string to convert
4+
* @returns A PascalCase string
5+
* @example
6+
* pascalCase('hello world') // 'HelloWorld'
7+
* pascalCase('hello-world') // 'HelloWorld'
8+
* pascalCase('hello_world') // 'HelloWorld'
9+
*/
10+
export const pascalCase = (str: string): string => {
11+
return str
12+
.replace(/[^a-zA-Z0-9]+(.)/g, (_, chr) => chr.toUpperCase())
13+
.replace(/^[a-z]/, (chr) => chr.toUpperCase());
14+
};

src/randomString.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Generates a random alphanumeric string
3+
* @param length - The length of the random string
4+
* @param charset - Optional character set to use (default: alphanumeric)
5+
* @returns A random string of specified length
6+
* @example
7+
* randomString(10) // 'a3B9x2Kp1m'
8+
* randomString(5, 'abc123') // '3a1bc'
9+
*/
10+
export const randomString = (
11+
length: number,
12+
charset: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
13+
): string => {
14+
let result = '';
15+
const charsetLength = charset.length;
16+
17+
for (let i = 0; i < length; i++) {
18+
result += charset.charAt(Math.floor(Math.random() * charsetLength));
19+
}
20+
21+
return result;
22+
};

0 commit comments

Comments
 (0)