// strings export const str = { join: (arr: string[], sep: string = ',') => arr.join(sep), split: (str: string, sep: string = ',') => str.split(sep), 'to-upper': (str: string) => str.toUpperCase(), 'to-lower': (str: string) => str.toLowerCase(), trim: (str: string) => str.trim(), // predicates 'starts-with?': (str: string, prefix: string) => str.startsWith(prefix), 'ends-with?': (str: string, suffix: string) => str.endsWith(suffix), 'contains?': (str: string, substr: string) => str.includes(substr), 'empty?': (str: string) => str.length === 0, // inspection 'index-of': (str: string, search: string) => str.indexOf(search), 'last-index-of': (str: string, search: string) => str.lastIndexOf(search), // transformations replace: (str: string, search: string, replacement: string) => str.replace(search, replacement), 'replace-all': (str: string, search: string, replacement: string) => str.replaceAll(search, replacement), slice: (str: string, start: number, end?: number | null) => str.slice(start, end ?? undefined), substring: (str: string, start: number, end?: number | null) => str.substring(start, end ?? undefined), repeat: (str: string, count: number) => { if (count < 0) throw new Error(`repeat: count must be non-negative, got ${count}`) if (!Number.isInteger(count)) throw new Error(`repeat: count must be an integer, got ${count}`) return str.repeat(count) }, 'pad-start': (str: string, length: number, pad: string = ' ') => str.padStart(length, pad), 'pad-end': (str: string, length: number, pad: string = ' ') => str.padEnd(length, pad), lines: (str: string) => str.split('\n'), chars: (str: string) => str.split(''), // regex match: (str: string, regex: RegExp) => str.match(regex), 'test?': (str: string, regex: RegExp) => regex.test(str), }