@thisisagile/easy
Version:
Straightforward library for building domain-driven microservice architectures
170 lines (131 loc) • 4.52 kB
text/typescript
import { asString, capitalize, replaceAll, Text } from './Text';
import { toName } from './Constructor';
import { Optional } from './Types';
import { Get, ofGet } from './Get';
import { isEmpty, isNotEmpty } from './Is';
import { List, toList } from './List';
import { JsonValue } from './Json';
import { template } from './Template';
export class ToText implements Text {
constructor(readonly subject: string) {}
get cap(): ToText {
return this.map(s => capitalize(s?.toLowerCase()));
}
get capFirst(): ToText {
return this.map(s => capitalize(s));
}
get title(): ToText {
return this.map(s =>
s
.split(' ')
.map(w => text(w).cap)
.join(' ')
);
}
get pascal(): ToText {
return this.title.replace(' ', '');
}
get lower(): ToText {
return this.map(s => s.toLowerCase());
}
get upper(): ToText {
return this.map(s => s.toUpperCase());
}
get camel(): ToText {
return this.title.trim.map(s => `${s.charAt(0).toLowerCase()}${s.slice(1)}`);
}
get kebab(): ToText {
return this.lower.replace(' ', '-');
}
get strictKebab(): ToText {
return this.map(s => s.replace(/[^a-z\d]+/gi, ' ').trim()).kebab;
}
get slug(): ToText {
return this.map(s =>
s
.replace(/ß/g, 'ss')
.normalize('NFKD')
.replace(/[\u0300-\u036F]/g, '')
.toLowerCase()
.replace(/[^a-z\d]+/g, '-')
.replace(/(^-)|(-$)/g, '')
);
}
get snake(): ToText {
return this.upper.replace(' ', '_');
}
get plural(): ToText {
return this.ifLike('') ?? this.add('s');
}
get space(): ToText {
return this.map(s => s.replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/[_-]/g, ' '));
}
get sentence(): ToText {
return this.isEmpty ? this : this.map(s => `${s.charAt(0).toUpperCase()}${s.slice(1)}.`);
}
get initials(): ToText {
return this.map(s =>
s
.split(' ')
.map(w => w[0])
.join('')
);
}
get trim(): ToText {
return this.map(s => s.replace(/[- ,_#]/g, ''));
}
get trimSentence(): ToText {
return this.map(s =>
s
.replace(/[\u200B-\u200D\uFEFF]/g, '')
.replace(/[\s\u00A0]+/g, ' ')
.replace(/\s+([.,;:!?])/g, '$1')
.trim()
);
}
get isEmpty(): boolean {
return isEmpty(this.toString());
}
parse = (subject: unknown, options = {}): ToText => text(template(this.subject, subject, { typeof: toName(subject), ...options }));
is = (...others: unknown[]): boolean => others.some(o => this.toString() === text(o).toString());
equals = this.is;
like = (...others: unknown[]): boolean => others.some(o => this.trim.lower.toString().includes(text(o).trim.lower.toString()));
isLike = (...others: unknown[]): boolean => others.some(o => this.trim.lower.is(text(o).trim.lower));
ifLike = (...others: unknown[]): Optional<this> => (this.isLike(...others) ? this : undefined);
endsWith = (end?: unknown): boolean => this.subject.endsWith(asString(end));
startsWith = (end?: unknown): boolean => this.subject.startsWith(asString(end));
first = (n: number): ToText => this.map(s => s.substring(0, n));
last = (n: number): ToText => this.map(s => s.substring(s.length - n));
map = (func: Get<string, string>): ToText => text(ofGet(func, this.subject));
replace = (search: Text, replace: Text): ToText => this.map(s => replaceAll(s, search, replace));
add = (add?: unknown, separator = ''): ToText => this.map(s => (isNotEmpty(add) ? `${s}${separator}${text(add)}` : s));
with = (separator: string, ...other: unknown[]): ToText =>
this.map(s =>
toList(s)
.add(...other.map(u => text(u).toString()))
.filter(s => isNotEmpty(s))
.join(separator)
);
split = (separator: string = ' '): List<string> => toList(this.subject.split(separator));
toString(): string {
return this.subject;
}
toJSON(): JsonValue {
return this.subject;
}
}
export function text(subject?: unknown, alt = ''): ToText {
const sub = subject ? asString(subject) : alt;
return new ToText(sub !== '[object Object]' ? sub : '');
}
export function textValue(subject: any, prop: string): string {
const p = prop.split('.');
const root = subject?.[p[0]];
const initial = typeof root === 'object' && root !== null ? root : text(root);
return (
p
.splice(1)
.reduce((t, s) => (typeof t === 'object' && t !== null ? t : text(t))?.[s], initial)
?.toString() ?? ''
);
}