mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 06:12:03 +00:00
feat: enhance auto mode service and UI components for branch handling and verification
- Added a new function to retrieve the current branch name in the auto mode service, improving branch management. - Updated the `getRunningCountForWorktree` method to utilize the current branch name for accurate feature counting. - Modified UI components to include a toggle for skipping verification in auto mode, enhancing user control. - Refactored various hooks and components to ensure consistent handling of branch names across the application. - Introduced a new utility file for string operations, providing common functions for text manipulation.
This commit is contained in:
178
libs/utils/src/string-utils.ts
Normal file
178
libs/utils/src/string-utils.ts
Normal file
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* String utility functions for common text operations
|
||||
*/
|
||||
|
||||
/**
|
||||
* Truncate a string to a maximum length, adding an ellipsis if truncated
|
||||
* @param str - The string to truncate
|
||||
* @param maxLength - Maximum length of the result (including ellipsis)
|
||||
* @param ellipsis - The ellipsis string to use (default: '...')
|
||||
* @returns The truncated string
|
||||
*/
|
||||
export function truncate(str: string, maxLength: number, ellipsis: string = '...'): string {
|
||||
if (maxLength < ellipsis.length) {
|
||||
throw new Error(
|
||||
`maxLength (${maxLength}) must be at least the length of ellipsis (${ellipsis.length})`
|
||||
);
|
||||
}
|
||||
|
||||
if (str.length <= maxLength) {
|
||||
return str;
|
||||
}
|
||||
|
||||
return str.slice(0, maxLength - ellipsis.length) + ellipsis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string to kebab-case (e.g., "Hello World" -> "hello-world")
|
||||
* @param str - The string to convert
|
||||
* @returns The kebab-case string
|
||||
*/
|
||||
export function toKebabCase(str: string): string {
|
||||
return str
|
||||
.replace(/([a-z])([A-Z])/g, '$1-$2') // camelCase -> camel-Case
|
||||
.replace(/[\s_]+/g, '-') // spaces and underscores -> hyphens
|
||||
.replace(/[^a-zA-Z0-9-]/g, '') // remove non-alphanumeric (except hyphens)
|
||||
.replace(/-+/g, '-') // collapse multiple hyphens
|
||||
.replace(/^-|-$/g, '') // remove leading/trailing hyphens
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string to camelCase (e.g., "hello-world" -> "helloWorld")
|
||||
* @param str - The string to convert
|
||||
* @returns The camelCase string
|
||||
*/
|
||||
export function toCamelCase(str: string): string {
|
||||
return str
|
||||
.replace(/[^a-zA-Z0-9\s_-]/g, '') // remove special characters
|
||||
.replace(/[-_\s]+(.)?/g, (_, char) => (char ? char.toUpperCase() : ''))
|
||||
.replace(/^[A-Z]/, (char) => char.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string to PascalCase (e.g., "hello-world" -> "HelloWorld")
|
||||
* @param str - The string to convert
|
||||
* @returns The PascalCase string
|
||||
*/
|
||||
export function toPascalCase(str: string): string {
|
||||
const camel = toCamelCase(str);
|
||||
return camel.charAt(0).toUpperCase() + camel.slice(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Capitalize the first letter of a string
|
||||
* @param str - The string to capitalize
|
||||
* @returns The string with first letter capitalized
|
||||
*/
|
||||
export function capitalize(str: string): string {
|
||||
if (str.length === 0) {
|
||||
return str;
|
||||
}
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove duplicate whitespace from a string, preserving single spaces
|
||||
* @param str - The string to clean
|
||||
* @returns The string with duplicate whitespace removed
|
||||
*/
|
||||
export function collapseWhitespace(str: string): string {
|
||||
return str.replace(/\s+/g, ' ').trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a string is empty or contains only whitespace
|
||||
* @param str - The string to check
|
||||
* @returns True if the string is blank
|
||||
*/
|
||||
export function isBlank(str: string | null | undefined): boolean {
|
||||
return str === null || str === undefined || str.trim().length === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a string is not empty and contains non-whitespace characters
|
||||
* @param str - The string to check
|
||||
* @returns True if the string is not blank
|
||||
*/
|
||||
export function isNotBlank(str: string | null | undefined): boolean {
|
||||
return !isBlank(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely parse a string to an integer, returning a default value on failure
|
||||
* @param str - The string to parse
|
||||
* @param defaultValue - The default value if parsing fails (default: 0)
|
||||
* @returns The parsed integer or the default value
|
||||
*/
|
||||
export function safeParseInt(str: string | null | undefined, defaultValue: number = 0): number {
|
||||
if (isBlank(str)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
const parsed = parseInt(str!, 10);
|
||||
return isNaN(parsed) ? defaultValue : parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a slug from a string (URL-friendly identifier)
|
||||
* @param str - The string to convert to a slug
|
||||
* @param maxLength - Optional maximum length for the slug
|
||||
* @returns The slugified string
|
||||
*/
|
||||
export function slugify(str: string, maxLength?: number): string {
|
||||
let slug = str
|
||||
.toLowerCase()
|
||||
.normalize('NFD') // Normalize unicode characters
|
||||
.replace(/[\u0300-\u036f]/g, '') // Remove diacritics
|
||||
.replace(/[^a-z0-9\s-]/g, '') // Remove non-alphanumeric
|
||||
.replace(/\s+/g, '-') // Replace spaces with hyphens
|
||||
.replace(/-+/g, '-') // Collapse multiple hyphens
|
||||
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
|
||||
|
||||
if (maxLength !== undefined && slug.length > maxLength) {
|
||||
// Truncate at word boundary if possible
|
||||
slug = slug.slice(0, maxLength);
|
||||
const lastHyphen = slug.lastIndexOf('-');
|
||||
if (lastHyphen > maxLength * 0.5) {
|
||||
slug = slug.slice(0, lastHyphen);
|
||||
}
|
||||
slug = slug.replace(/-$/g, ''); // Remove trailing hyphen after truncation
|
||||
}
|
||||
|
||||
return slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape special regex characters in a string
|
||||
* @param str - The string to escape
|
||||
* @returns The escaped string safe for use in a RegExp
|
||||
*/
|
||||
export function escapeRegex(str: string): string {
|
||||
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
|
||||
/**
|
||||
* Pluralize a word based on count
|
||||
* @param word - The singular form of the word
|
||||
* @param count - The count to base pluralization on
|
||||
* @param pluralForm - Optional custom plural form (default: word + 's')
|
||||
* @returns The word in singular or plural form
|
||||
*/
|
||||
export function pluralize(word: string, count: number, pluralForm?: string): string {
|
||||
if (count === 1) {
|
||||
return word;
|
||||
}
|
||||
return pluralForm || `${word}s`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a count with its associated word (e.g., "1 item", "3 items")
|
||||
* @param count - The count
|
||||
* @param singular - The singular form of the word
|
||||
* @param plural - Optional custom plural form
|
||||
* @returns Formatted string with count and word
|
||||
*/
|
||||
export function formatCount(count: number, singular: string, plural?: string): string {
|
||||
return `${count} ${pluralize(singular, count, plural)}`;
|
||||
}
|
||||
Reference in New Issue
Block a user