Files
sim/packages/utils/src/string.ts
T
Waleed 0673e3c0f7 refactor(sim): consolidate record guards + pure utils into @sim/utils (#5061)
* feat(utils): add record guards and pure helpers to @sim/utils

Add isRecordLike (loose, non-prototype-checked record guard) and
sortObjectKeysDeep; relocate isPlainRecord (strict) and normalizeEmail
into @sim/utils so they are reusable across apps and packages. Unit tests
cover the loose-vs-strict distinction, deep key sorting, and email
normalization.

* refactor(sim): consolidate record guards and normalize helpers onto @sim/utils

Replace ~55 re-implemented loose record guards with the canonical
@sim/utils isRecordLike (and one strict site with isPlainRecord), and
dedupe three normalize clusters: sortObjectKeysDeep (sanitization +
copilot builders), normalizeToken (salesforce + servicenow triggers),
and normalizeEmail. Array-allowing guards and domain-specific normalizers
are intentionally left untouched. Pure refactor — identical predicates
and transforms, no behavior change.
2026-06-15 12:32:19 -07:00

48 lines
1.6 KiB
TypeScript

/**
* Truncates `str` if it exceeds `sliceLength` characters, appending `suffix`.
* The total output length when truncated is `sliceLength + suffix.length`.
* Defaults suffix to `'...'`.
*
* @example
* truncate('hello world', 8) // 'hello wo...' (11 chars)
* truncate('hello world', 8, ' …') // 'hello wo …'
* truncate('hi', 10) // 'hi'
*/
export function truncate(str: string, sliceLength: number, suffix = '...'): string {
return str.length > sliceLength ? str.slice(0, sliceLength) + suffix : str
}
/**
* Strips a trailing `_vN` version suffix from `value`, yielding the base type.
* Only the single trailing suffix is removed; leading occurrences are left intact.
*
* @example
* stripVersionSuffix('notion_search_v2') // 'notion_search'
* stripVersionSuffix('x') // 'x'
* stripVersionSuffix('a_v2_v3') // 'a_v2'
*/
export function stripVersionSuffix(value: string): string {
return value.replace(/_v\d+$/, '')
}
/**
* Tests whether `value` ends with a `_vN` version suffix.
* Only a trailing suffix counts; a leading or embedded `_vN` does not match.
*
* @example
* isVersionedType('notion_search_v2') // true
* isVersionedType('plain') // false
* isVersionedType('a_version') // false
*/
export function isVersionedType(value: string): boolean {
return /_v\d+$/.test(value)
}
/**
* Normalizes an email address for comparison and storage by trimming
* surrounding whitespace and lowercasing.
*/
export function normalizeEmail(email: string): string {
return email.trim().toLowerCase()
}