Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

string-ts

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

string-ts - npm Package Compare versions

Comparing version
2.2.1
to
2.3.0-experimental.0
+366
dist/index.cjs
'use strict';
// src/native/char-at.ts
function charAt(str, index) {
return str.charAt(index);
}
// src/native/join.ts
function join(tuple, delimiter = "") {
return tuple.join(delimiter);
}
// src/native/concat.ts
function concat(...strings) {
return join(strings);
}
// src/native/ends-with.ts
function endsWith(text, search, position = text.length) {
return text.endsWith(search, position);
}
// src/native/includes.ts
function includes(text, search, position = 0) {
return text.includes(search, position);
}
// src/native/length.ts
function length(str) {
return str.length;
}
// src/native/pad-end.ts
function padEnd(str, length2 = 0, pad = " ") {
return str.padEnd(length2, pad);
}
// src/native/pad-start.ts
function padStart(str, length2 = 0, pad = " ") {
return str.padStart(length2, pad);
}
// src/native/repeat.ts
function repeat(str, times = 0) {
return str.repeat(times);
}
// src/native/replace.ts
function replace(sentence, lookup, replacement = "") {
return sentence.replace(lookup, replacement);
}
// src/native/replace-all.ts
function replaceAll(sentence, lookup, replacement = "") {
if (typeof sentence.replaceAll === "function") {
return sentence.replaceAll(lookup, replacement);
}
const regex = new RegExp(lookup, "g");
return sentence.replace(regex, replacement);
}
// src/native/slice.ts
function slice(str, start = 0, end = void 0) {
return str.slice(start, end);
}
// src/native/split.ts
function split(str, delimiter = "") {
return str.split(delimiter);
}
// src/native/starts-with.ts
function startsWith(text, search, position = 0) {
return text.startsWith(search, position);
}
// src/native/trim-start.ts
function trimStart(str) {
return str.trimStart();
}
// src/native/trim-end.ts
function trimEnd(str) {
return str.trimEnd();
}
// src/native/trim.ts
function trim(str) {
return str.trim();
}
// src/native/to-lower-case.ts
function toLowerCase(str) {
return str.toLowerCase();
}
// src/native/to-upper-case.ts
function toUpperCase(str) {
return str.toUpperCase();
}
// src/utils/reverse.ts
function reverse(str) {
return str.split("").reverse().join("");
}
// src/utils/truncate.ts
function truncate(sentence, length2, omission = "...") {
if (length2 < 0) return omission;
if (sentence.length <= length2) return sentence;
return join([
sentence.slice(0, length2 - omission.length),
omission
]);
}
// src/utils/characters/separators.ts
var UNESCAPED_SEPARATORS = [
"[",
"]",
"{",
"}",
"(",
")",
"|",
"/",
"-",
"\\"
];
var SEPARATORS = [...UNESCAPED_SEPARATORS, " ", "_", "."];
function escapeChar(char) {
return UNESCAPED_SEPARATORS.includes(char) ? `\\${char}` : char;
}
var SEPARATOR_REGEX = new RegExp(
`[${SEPARATORS.map(escapeChar).join("")}]`,
"g"
);
// src/utils/words.ts
function words(sentence) {
return sentence.replace(SEPARATOR_REGEX, " ").replace(/([a-zA-Z])([0-9])/g, "$1 $2").replace(/([0-9])([a-zA-Z])/g, "$1 $2").replace(/([a-zA-Z0-9_\-./])([^a-zA-Z0-9_\-./'])/g, "$1 $2").replace(/([^a-zA-Z0-9_\-./'])([a-zA-Z0-9_\-./])/g, "$1 $2").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z])([A-Z][a-z])/g, "$1 $2").trim().split(/\s+/g);
}
// src/utils/characters/apostrophe.ts
function removeApostrophe(str) {
return replaceAll(str, "'", "");
}
// src/utils/word-case/capitalize.ts
function capitalize(str) {
return join([
toUpperCase(charAt(str, 0) ?? ""),
slice(str, 1)
]);
}
// src/internal/internals.ts
function typeOf(t) {
return Object.prototype.toString.call(t).replace(/^\[object (.+)\]$/, "$1").toLowerCase();
}
function pascalCaseAll(words2) {
return words2.map((v) => capitalize(toLowerCase(v)));
}
// src/utils/word-case/pascal-case.ts
function pascalCase(str) {
return join(pascalCaseAll(words(removeApostrophe(str))));
}
var toPascalCase = pascalCase;
// src/utils/word-case/uncapitalize.ts
function uncapitalize(str) {
return join([
toLowerCase(charAt(str, 0) ?? ""),
slice(str, 1)
]);
}
// src/utils/word-case/camel-case.ts
function camelCase(str) {
return uncapitalize(pascalCase(removeApostrophe(str)));
}
var toCamelCase = camelCase;
// src/utils/word-case/delimiter-case.ts
function delimiterCase(str, delimiter) {
return join(words(removeApostrophe(str)), delimiter);
}
var toDelimiterCase = delimiterCase;
// src/utils/word-case/constant-case.ts
function constantCase(str) {
return toUpperCase(delimiterCase(removeApostrophe(str), "_"));
}
var toConstantCase = constantCase;
// src/utils/word-case/kebab-case.ts
function kebabCase(str) {
return toLowerCase(delimiterCase(removeApostrophe(str), "-"));
}
var toKebabCase = kebabCase;
// src/utils/word-case/snake-case.ts
function snakeCase(str) {
return toLowerCase(delimiterCase(removeApostrophe(str), "_"));
}
var toSnakeCase = snakeCase;
// src/utils/word-case/title-case.ts
function titleCase(str) {
return delimiterCase(pascalCase(str), " ");
}
var toTitleCase = titleCase;
// src/utils/word-case/lower-case.ts
function lowerCase(str) {
return toLowerCase(delimiterCase(str, " "));
}
// src/utils/word-case/upper-case.ts
function upperCase(str) {
return toUpperCase(delimiterCase(str, " "));
}
// src/utils/object-keys/transform-keys.ts
function transformKeys(obj, transform) {
if (typeOf(obj) !== "object") return obj;
const res = {};
for (const key in obj) {
res[transform(key)] = obj[key];
}
return res;
}
// src/utils/object-keys/camel-keys.ts
function camelKeys(obj) {
return transformKeys(obj, camelCase);
}
// src/utils/object-keys/constant-keys.ts
function constantKeys(obj) {
return transformKeys(obj, constantCase);
}
// src/utils/object-keys/delimiter-keys.ts
function delimiterKeys(obj, delimiter) {
return transformKeys(obj, (str) => delimiterCase(str, delimiter));
}
// src/utils/object-keys/kebab-keys.ts
function kebabKeys(obj) {
return transformKeys(obj, kebabCase);
}
// src/utils/object-keys/pascal-keys.ts
function pascalKeys(obj) {
return transformKeys(obj, pascalCase);
}
// src/utils/object-keys/snake-keys.ts
function snakeKeys(obj) {
return transformKeys(obj, snakeCase);
}
// src/utils/object-keys/replace-keys.ts
function replaceKeys(obj, lookup, replacement = "") {
return transformKeys(obj, (s) => replace(s, lookup, replacement));
}
// src/utils/object-keys/deep-transform-keys.ts
function deepTransformKeys(obj, transform) {
if (!["object", "array"].includes(typeOf(obj))) return obj;
if (Array.isArray(obj)) {
return obj.map((x) => deepTransformKeys(x, transform));
}
const res = {};
for (const key in obj) {
res[transform(key)] = deepTransformKeys(obj[key], transform);
}
return res;
}
// src/utils/object-keys/deep-camel-keys.ts
function deepCamelKeys(obj) {
return deepTransformKeys(obj, camelCase);
}
// src/utils/object-keys/deep-constant-keys.ts
function deepConstantKeys(obj) {
return deepTransformKeys(obj, constantCase);
}
// src/utils/object-keys/deep-delimiter-keys.ts
function deepDelimiterKeys(obj, delimiter) {
return deepTransformKeys(obj, (str) => delimiterCase(str, delimiter));
}
// src/utils/object-keys/deep-kebab-keys.ts
function deepKebabKeys(obj) {
return deepTransformKeys(obj, kebabCase);
}
// src/utils/object-keys/deep-pascal-keys.ts
function deepPascalKeys(obj) {
return deepTransformKeys(obj, pascalCase);
}
// src/utils/object-keys/deep-snake-keys.ts
function deepSnakeKeys(obj) {
return deepTransformKeys(obj, snakeCase);
}
exports.camelCase = camelCase;
exports.camelKeys = camelKeys;
exports.capitalize = capitalize;
exports.charAt = charAt;
exports.concat = concat;
exports.constantCase = constantCase;
exports.constantKeys = constantKeys;
exports.deepCamelKeys = deepCamelKeys;
exports.deepConstantKeys = deepConstantKeys;
exports.deepDelimiterKeys = deepDelimiterKeys;
exports.deepKebabKeys = deepKebabKeys;
exports.deepPascalKeys = deepPascalKeys;
exports.deepSnakeKeys = deepSnakeKeys;
exports.deepTransformKeys = deepTransformKeys;
exports.delimiterCase = delimiterCase;
exports.delimiterKeys = delimiterKeys;
exports.endsWith = endsWith;
exports.includes = includes;
exports.join = join;
exports.kebabCase = kebabCase;
exports.kebabKeys = kebabKeys;
exports.length = length;
exports.lowerCase = lowerCase;
exports.padEnd = padEnd;
exports.padStart = padStart;
exports.pascalCase = pascalCase;
exports.pascalKeys = pascalKeys;
exports.repeat = repeat;
exports.replace = replace;
exports.replaceAll = replaceAll;
exports.replaceKeys = replaceKeys;
exports.reverse = reverse;
exports.slice = slice;
exports.snakeCase = snakeCase;
exports.snakeKeys = snakeKeys;
exports.split = split;
exports.startsWith = startsWith;
exports.titleCase = titleCase;
exports.toCamelCase = toCamelCase;
exports.toConstantCase = toConstantCase;
exports.toDelimiterCase = toDelimiterCase;
exports.toKebabCase = toKebabCase;
exports.toLowerCase = toLowerCase;
exports.toPascalCase = toPascalCase;
exports.toSnakeCase = toSnakeCase;
exports.toTitleCase = toTitleCase;
exports.toUpperCase = toUpperCase;
exports.trim = trim;
exports.trimEnd = trimEnd;
exports.trimStart = trimStart;
exports.truncate = truncate;
exports.uncapitalize = uncapitalize;
exports.upperCase = upperCase;
exports.words = words;
/**
* Returns true if input number type is a literal
*/
type IsNumberLiteral<T extends number> = [T] extends [number] ? [number] extends [T] ? false : true : false;
type IsBooleanLiteral<T extends boolean> = [T] extends [boolean] ? [boolean] extends [T] ? false : true : false;
/**
* Returns true if any elements in boolean array are the literal true (not false or boolean)
*/
type Any<Arr extends boolean[]> = Arr extends [
infer Head extends boolean,
...infer Rest extends boolean[]
] ? IsBooleanLiteral<Head> extends true ? Head extends true ? true : Any<Rest> : Any<Rest> : false;
/**
* Returns true if every element in boolean array is the literal true (not false or boolean)
*/
type All<Arr extends boolean[]> = IsBooleanLiteral<Arr[number]> extends true ? Arr extends [infer Head extends boolean, ...infer Rest extends boolean[]] ? Head extends true ? Any<Rest> : false : true : false;
/**
* Returns true if string input type is a literal
*/
type IsStringLiteral<T extends string> = [T] extends [string] ? [string] extends [T] ? false : Uppercase<T> extends Uppercase<Lowercase<T>> ? Lowercase<T> extends Lowercase<Uppercase<T>> ? true : false : false : false;
type IsStringLiteralArray<Arr extends string[] | readonly string[]> = IsStringLiteral<Arr[number]> extends true ? true : false;
/**
* Splits a string into an array of substrings.
* T: The string to split.
* delimiter: The delimiter.
*/
type Split<T extends string, delimiter extends string = ''> = IsStringLiteral<T | delimiter> extends true ? T extends `${infer first}${delimiter}${infer rest}` ? [first, ...Split<rest, delimiter>] : T extends '' ? [] : [T] : string[];
/**
* A strongly-typed version of `String.prototype.split`.
* @param str the string to split.
* @param delimiter the delimiter.
* @returns the splitted string in both type level and runtime.
* @example split('hello world', ' ') // ['hello', 'world']
*/
declare function split<T extends string, D extends string = ''>(str: T, delimiter?: D): Split<T, D>;
/**
* Gets the character at the given index.
* T: The string to get the character from.
* index: The index of the character.
*/
type CharAt<T extends string, index extends number> = All<[
IsStringLiteral<T>,
IsNumberLiteral<index>
]> extends true ? Split<T>[index] : string;
/**
* A strongly-typed version of `String.prototype.charAt`.
* @param str the string to get the character from.
* @param index the index of the character.
* @returns the character in both type level and runtime.
* @example charAt('hello world', 6) // 'w'
*/
declare function charAt<T extends string, I extends number>(str: T, index: I): CharAt<T, I>;
/**
* Joins a tuple of strings with the given delimiter.
* T: The tuple of strings to join.
* delimiter: The delimiter.
*/
type Join<T extends readonly string[], delimiter extends string = ''> = All<[IsStringLiteralArray<T>, IsStringLiteral<delimiter>]> extends true ? T extends readonly [
infer first extends string,
...infer rest extends string[]
] ? rest extends [] ? first : `${first}${delimiter}${Join<rest, delimiter>}` : '' : string;
/**
* A strongly-typed version of `Array.prototype.join`.
* @param tuple the tuple of strings to join.
* @param delimiter the delimiter.
* @returns the joined string in both type level and runtime.
* @example join(['hello', 'world'], '-') // 'hello-world'
*/
declare function join<const T extends readonly string[], D extends string = ''>(tuple: T, delimiter?: D): Join<T, D>;
/**
* Concatenates a tuple of strings.
* T: The tuple of strings to concatenate.
*/
type Concat<T extends string[]> = Join<T>;
/**
* A strongly-typed version of `String.prototype.concat`.
* @param strings the tuple of strings to concatenate.
* @returns the concatenated string in both type level and runtime.
* @example concat('a', 'bc', 'def') // 'abcdef'
*/
declare function concat<T extends string[]>(...strings: T): Concat<T>;
/**
* Gets the length of a string.
*/
type Length<T extends string> = IsStringLiteral<T> extends true ? Split<T>['length'] : number;
/**
* A strongly-typed version of `String.prototype.length`.
* @param str the string to get the length from.
* @returns the length of the string in both type level and runtime.
* @example length('hello world') // 11
*/
declare function length<T extends string>(str: T): Length<T>;
/**
* PascalCases all the words in a tuple of strings
*/
type PascalCaseAll<T extends string[]> = T extends [
infer head extends string,
...infer rest extends string[]
] ? [Capitalize<Lowercase<head>>, ...PascalCaseAll<rest>] : T;
/**
* Removes all the elements matching the given condition from a tuple.
*/
type Reject<tuple, cond, output extends any[] = []> = tuple extends [
infer first,
...infer rest
] ? Reject<rest, cond, first extends cond ? output : [...output, first]> : output;
/**
* Removes the given suffix from a sentence.
*/
type DropSuffix<sentence extends string, suffix extends string> = string extends sentence | suffix ? string : sentence extends `${infer rest}${suffix}` ? rest : sentence;
/**
* Returns a tuple of the given length with the given type.
*/
type TupleOf<L extends number, T = unknown, result extends any[] = []> = result['length'] extends L ? result : TupleOf<L, T, [...result, T]>;
declare namespace Math {
type Subtract<A extends number, B extends number> = number extends A | B ? number : TupleOf<A> extends [...infer U, ...TupleOf<B>] ? U['length'] : 0;
type IsNegative<T extends number> = number extends T ? boolean : `${T}` extends `-${number}` ? true : false;
type Abs<T extends number> = `${T}` extends `-${infer U extends number}` ? U : T;
type GetPositiveIndex<T extends string, I extends number> = IsNegative<I> extends false ? I : Subtract<Length<T>, Abs<I>>;
}
/**
* Reverses a string.
* - `T` The string to reverse.
*/
type Reverse<T extends string, _acc extends string = ''> = T extends `${infer Head}${infer Tail}` ? Reverse<Tail, `${Head}${_acc}`> : _acc extends '' ? T : `${T}${_acc}`;
/**
* A strongly-typed function to reverse a string.
* @param str the string to reverse.
* @returns the reversed string in both type level and runtime.
* @example reverse('hello world') // 'dlrow olleh'
*/
declare function reverse<T extends string>(str: T): Reverse<T>;
/**
* Slices a string from a startIndex to an endIndex.
* T: The string to slice.
* startIndex: The start index.
* endIndex: The end index.
*/
type Slice<T extends string, startIndex extends number = 0, endIndex extends number | undefined = undefined> = endIndex extends number ? _Slice<T, startIndex, endIndex> : _SliceStart<T, startIndex>;
/** Slice with startIndex and endIndex */
type _Slice<T extends string, startIndex extends number, endIndex extends number, _result extends string = ''> = IsNumberLiteral<startIndex | endIndex> extends true ? T extends `${infer head}${infer rest}` ? IsStringLiteral<head> extends true ? startIndex extends 0 ? endIndex extends 0 ? _result : _Slice<rest, 0, Math.Subtract<Math.GetPositiveIndex<T, endIndex>, 1>, `${_result}${head}`> : _Slice<rest, Math.Subtract<Math.GetPositiveIndex<T, startIndex>, 1>, Math.Subtract<Math.GetPositiveIndex<T, endIndex>, 1>, _result> : startIndex | endIndex extends 0 ? _result : string : IsStringLiteral<T> extends true ? _result : startIndex | endIndex extends 0 ? _result : string : string;
/** Slice with startIndex only */
type _SliceStart<T extends string, startIndex extends number, _result extends string = ''> = IsNumberLiteral<startIndex> extends true ? T extends `${infer head}${infer rest}` ? IsStringLiteral<head> extends true ? startIndex extends 0 ? T : _SliceStart<rest, Math.Subtract<Math.GetPositiveIndex<T, startIndex>, 1>, _result> : string : IsStringLiteral<T> extends true ? _result : startIndex extends 0 ? _result : string : string;
/**
* A strongly-typed version of `String.prototype.slice`.
* @param str the string to slice.
* @param start the start index.
* @param end the end index.
* @returns the sliced string in both type level and runtime.
* @example slice('hello world', 6) // 'world'
*/
declare function slice<T extends string, S extends number = 0, E extends number | undefined = undefined>(str: T, start?: S, end?: E): Slice<T, S, E>;
/**
* Checks if a string starts with another string.
* T: The string to check.
* S: The string to check against.
* P: The position to start the search.
*/
type StartsWith<T extends string, S extends string, P extends number = 0> = All<[IsStringLiteral<S>, IsNumberLiteral<P>]> extends true ? Math.IsNegative<P> extends false ? P extends 0 ? S extends `${infer SHead}${infer SRest}` ? T extends `${infer THead}${infer TRest}` ? IsStringLiteral<THead | SHead> extends true ? THead extends SHead ? StartsWith<TRest, SRest> : false : boolean : IsStringLiteral<T> extends true ? false : boolean : true : StartsWith<Slice<T, P>, S, 0> : StartsWith<T, S, 0> : boolean;
/**
* A strongly-typed version of `String.prototype.startsWith`.
* @param text the string to search.
* @param search the string to search with.
* @param position the index to start search at.
* @returns boolean, whether or not the text string starts with the search string.
* @example startsWith('abc', 'a') // true
*/
declare function startsWith<T extends string, S extends string, P extends number = 0>(text: T, search: S, position?: P): StartsWith<T, S, P>;
/**
* Checks if a string ends with another string.
* T: The string to check.
* S: The string to check against.
* P: The position the search should end.
*/
type EndsWith<T extends string, S extends string, P extends number | undefined = undefined> = P extends number ? _EndsWith<T, S, P> : _EndsWithNoPosition<T, S>;
type _EndsWith<T extends string, S extends string, P extends number> = All<[
IsStringLiteral<S>,
IsNumberLiteral<P>
]> extends true ? Math.IsNegative<P> extends false ? P extends Length<T> ? IsStringLiteral<T> extends true ? S extends Slice<T, Math.Subtract<Length<T>, Length<S>>, Length<T>> ? true : false : _EndsWithNoPosition<Slice<T, 0, P>, S> : _EndsWithNoPosition<Slice<T, 0, P>, S> : false : boolean;
/** Overload of EndsWith without P */
type _EndsWithNoPosition<T extends string, S extends string> = StartsWith<Reverse<T>, Reverse<S>>;
/**
* A strongly-typed version of `String.prototype.endsWith`.
* @param text the string to search.
* @param search the string to search with.
* @param position the index the search should end at.
* @returns boolean, whether or not the text string ends with the search string.
* @example endsWith('abc', 'c') // true
*/
declare function endsWith<T extends string, S extends string, P extends number = Length<T>>(text: T, search: S, position?: P): EndsWith<T, S, P>;
/**
* Checks if a string includes another string.
* T: The string to check.
* S: The string to check against.
* P: The position to start the search.
*/
type Includes<T extends string, S extends string, P extends number = 0> = string extends T | S ? boolean : Math.IsNegative<P> extends false ? P extends 0 ? T extends `${string}${S}${string}` ? true : false : Includes<Slice<T, P>, S, 0> : Includes<T, S, 0>;
/**
* A strongly-typed version of `String.prototype.includes`.
* @param text the string to search
* @param search the string to search with
* @param position the index to start search at
* @returns boolean, whether or not the text contains the search string.
* @example includes('abcde', 'bcd') // true
*/
declare function includes<T extends string, S extends string, P extends number = 0>(text: T, search: S, position?: P): Includes<T, S, P>;
/**
* Repeats a string N times.
* T: The string to repeat.
* N: The number of times to repeat.
*/
type Repeat<T extends string, times extends number = 0> = All<[
IsStringLiteral<T>,
IsNumberLiteral<times>
]> extends true ? times extends 0 ? '' : Math.IsNegative<times> extends false ? Join<TupleOf<times, T>> : never : string;
/**
* A strongly-typed version of `String.prototype.repeat`.
* @param str the string to repeat.
* @param times the number of times to repeat.
* @returns the repeated string in both type level and runtime.
* @example repeat('hello', 3) // 'hellohellohello'
*/
declare function repeat<T extends string, N extends number = 0>(str: T, times?: N): Repeat<T, N>;
/**
* Pads a string at the end with another string.
* T: The string to pad.
* times: The number of times to pad.
* pad: The string to pad with.
*/
type PadEnd<T extends string, times extends number = 0, pad extends string = ' '> = All<[IsStringLiteral<T | pad>, IsNumberLiteral<times>]> extends true ? Math.IsNegative<times> extends false ? Math.Subtract<times, Length<T>> extends infer missing extends number ? `${T}${Slice<Repeat<pad, missing>, 0, missing>}` : never : T : string;
/**
* A strongly-typed version of `String.prototype.padEnd`.
* @param str the string to pad.
* @param length the length to pad.
* @param pad the string to pad with.
* @returns the padded string in both type level and runtime.
* @example padEnd('hello', 10, '=') // 'hello====='
*/
declare function padEnd<T extends string, N extends number = 0, U extends string = ' '>(str: T, length?: N, pad?: U): PadEnd<T, N, U>;
/**
* Pads a string at the start with another string.
* T: The string to pad.
* times: The number of times to pad.
* pad: The string to pad with.
*/
type PadStart<T extends string, times extends number = 0, pad extends string = ' '> = All<[IsStringLiteral<T | pad>, IsNumberLiteral<times>]> extends true ? Math.IsNegative<times> extends false ? Math.Subtract<times, Length<T>> extends infer missing extends number ? `${Slice<Repeat<pad, missing>, 0, missing>}${T}` : never : T : string;
/**
* A strongly-typed version of `String.prototype.padStart`.
* @param str the string to pad.
* @param length the length to pad.
* @param pad the string to pad with.
* @returns the padded string in both type level and runtime.
* @example padStart('hello', 10, '=') // '=====hello'
*/
declare function padStart<T extends string, N extends number = 0, U extends string = ' '>(str: T, length?: N, pad?: U): PadStart<T, N, U>;
/**
* Replaces the first occurrence of a string with another string.
* sentence: The sentence to replace.
* lookup: The lookup string to be replaced.
* replacement: The replacement string.
*/
type Replace<sentence extends string, lookup extends string | RegExp, replacement extends string = ''> = lookup extends string ? IsStringLiteral<lookup | sentence | replacement> extends true ? sentence extends `${infer rest}${lookup}${infer rest2}` ? `${rest}${replacement}${rest2}` : sentence : string : string;
/**
* A strongly-typed version of `String.prototype.replace`.
* @param sentence the sentence to replace.
* @param lookup the lookup string to be replaced.
* @param replacement the replacement string.
* @returns the replaced string in both type level and runtime.
* @example replace('hello world', 'l', '1') // 'he1lo world'
*/
declare function replace<T extends string, S extends string | RegExp, R extends string = ''>(sentence: T, lookup: S, replacement?: R): Replace<T, S, R>;
/**
* Replaces all the occurrences of a string with another string.
* sentence: The sentence to replace.
* lookup: The lookup string to be replaced.
* replacement: The replacement string.
*/
type ReplaceAll<sentence extends string, lookup extends string | RegExp, replacement extends string = ''> = lookup extends string ? IsStringLiteral<lookup | sentence | replacement> extends true ? sentence extends `${infer rest}${lookup}${infer rest2}` ? `${rest}${replacement}${ReplaceAll<rest2, lookup, replacement>}` : sentence : string : string;
/**
* A strongly-typed version of `String.prototype.replaceAll`.
* @param sentence the sentence to replace.
* @param lookup the lookup string to be replaced.
* @param replacement the replacement string.
* @returns the replaced string in both type level and runtime.
* @example replaceAll('hello world', 'l', '1') // 'he11o wor1d'
*/
declare function replaceAll<T extends string, S extends string | RegExp, R extends string = ''>(sentence: T, lookup: S, replacement?: R): ReplaceAll<T, S, R>;
/**
* Trims all whitespaces at the start of a string.
* T: The string to trim.
*/
type TrimStart<T extends string> = T extends ` ${infer rest}` ? TrimStart<rest> : T;
/**
* A strongly-typed version of `String.prototype.trimStart`.
* @param str the string to trim.
* @returns the trimmed string in both type level and runtime.
* @example trimStart(' hello world ') // 'hello world '
*/
declare function trimStart<T extends string>(str: T): TrimStart<T>;
/**
* Trims all whitespaces at the end of a string.
* T: The string to trim.
*/
type TrimEnd<T extends string> = T extends `${infer rest} ` ? TrimEnd<rest> : T;
/**
* A strongly-typed version of `String.prototype.trimEnd`.
* @param str the string to trim.
* @returns the trimmed string in both type level and runtime.
* @example trimEnd(' hello world ') // ' hello world'
*/
declare function trimEnd<T extends string>(str: T): TrimEnd<T>;
/**
* Trims all whitespaces at the start and end of a string.
* T: The string to trim.
*/
type Trim<T extends string> = TrimEnd<TrimStart<T>>;
/**
* A strongly-typed version of `String.prototype.trim`.
* @param str the string to trim.
* @returns the trimmed string in both type level and runtime.
* @example trim(' hello world ') // 'hello world'
*/
declare function trim<T extends string>(str: T): Trim<T>;
/**
* This function is a strongly-typed counterpart of String.prototype.toLowerCase.
* @param str the string to make lowercase.
* @returns the lowercased string.
* @example toLowerCase('HELLO WORLD') // 'hello world'
*/
declare function toLowerCase<T extends string>(str: T): Lowercase<T>;
/**
* This function is a strongly-typed counterpart of String.prototype.toUpperCase.
* @param str the string to make uppercase.
* @returns the uppercased string.
* @example toUpperCase('hello world') // 'HELLO WORLD'
*/
declare function toUpperCase<T extends string>(str: T): Uppercase<T>;
/**
* Truncate a string if it's longer than the given maximum length.
* The last characters of the truncated string are replaced with the omission string which defaults to "...".
*/
type Truncate<T extends string, Size extends number, Omission extends string = '...'> = All<[IsStringLiteral<T | Omission>, IsNumberLiteral<Size>]> extends true ? Math.IsNegative<Size> extends true ? Omission : Math.Subtract<Length<T>, Size> extends 0 ? T : Join<[Slice<T, 0, Math.Subtract<Size, Length<Omission>>>, Omission]> : string;
/**
* A strongly typed function to truncate a string if it's longer than the given maximum string length.
* The last characters of the truncated string are replaced with the omission string which defaults to "...".
* @param sentence the sentence to extract the words from.
* @param length the maximum length of the string.
* @param omission the string to append to the end of the truncated string.
* @returns the truncated string
* @example truncate('Hello, World', 8) // 'Hello...'
*/
declare function truncate<T extends string, S extends number, P extends string = '...'>(sentence: T, length: S, omission?: P): Truncate<T, S, P>;
type UpperChars = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
type LowerChars = Lowercase<UpperChars>;
/**
* Checks if the given character is an upper case letter.
*/
type IsUpper<T extends string> = IsStringLiteral<T> extends true ? T extends UpperChars ? true : false : boolean;
/**
* Checks if the given character is a lower case letter.
*/
type IsLower<T extends string> = IsStringLiteral<T> extends true ? T extends LowerChars ? true : false : boolean;
/**
* Checks if the given character is a letter.
*/
type IsLetter<T extends string> = IsStringLiteral<T> extends true ? T extends LowerChars | UpperChars ? true : false : boolean;
type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
/**
* Checks if the given character is a number.
*/
type IsDigit<T extends string> = IsStringLiteral<T> extends true ? T extends Digit ? true : false : boolean;
declare const SEPARATORS: readonly ["[", "]", "{", "}", "(", ")", "|", "/", "-", "\\", " ", "_", "."];
type Separator = (typeof SEPARATORS)[number];
/**
* Checks if the given character is a separator.
* E.g. space, underscore, dash, dot, slash.
*/
type IsSeparator<T extends string> = IsStringLiteral<T> extends true ? T extends Separator ? true : false : boolean;
type Apostrophe = "'";
/**
* Checks if the given character is an apostrophe
*/
type IsApostrophe<T extends string> = IsStringLiteral<T> extends true ? T extends Apostrophe ? true : false : boolean;
type RemoveApostrophe<T extends string> = ReplaceAll<T, "'", ''>;
/**
* Checks if the given character is a special character.
* E.g. not a letter, number, or separator.
*/
type IsSpecial<T extends string> = IsStringLiteral<T> extends true ? IsLetter<T> extends true ? false : IsDigit<T> extends true ? false : IsSeparator<T> extends true ? false : IsApostrophe<T> extends true ? false : true : boolean;
/**
* Splits a string into words.
* sentence: The current string to split.
* word: The current word.
* prev: The previous character.
*/
type Words<sentence extends string, word extends string = '', prev extends string = ''> = IsStringLiteral<sentence | word | prev> extends true ? sentence extends `${infer curr}${infer rest}` ? IsSeparator<curr> extends true ? Reject<[word, ...Words<rest>], ''> : prev extends '' ? Reject<Words<rest, curr, curr>, ''> : [false, true] extends [IsDigit<prev>, IsDigit<curr>] ? [
word,
...Words<rest, curr, curr>
] : [true, false] extends [IsDigit<prev>, IsDigit<curr>] ? [
word,
...Words<rest, curr, curr>
] : [false, true] extends [IsSpecial<prev>, IsSpecial<curr>] ? [
word,
...Words<rest, curr, curr>
] : [true, false] extends [IsSpecial<prev>, IsSpecial<curr>] ? [
word,
...Words<rest, curr, curr>
] : [true, true] extends [IsDigit<prev>, IsDigit<curr>] ? Reject<Words<rest, `${word}${curr}`, curr>, ''> : [true, true] extends [IsLower<prev>, IsUpper<curr>] ? [
word,
...Words<rest, curr, curr>
] : [true, true] extends [IsUpper<prev>, IsLower<curr>] ? [
DropSuffix<word, prev>,
...Words<rest, `${prev}${curr}`, curr>
] : Reject<Words<rest, `${word}${curr}`, curr>, ''> : Reject<[word], ''> : string[];
/**
* A strongly-typed function to extract the words from a sentence.
* @param sentence the sentence to extract the words from.
* @returns an array of words in both type level and runtime.
* @example words('helloWorld') // ['hello', 'World']
*/
declare function words<T extends string>(sentence: T): Words<T>;
/**
* Transforms a string to PascalCase.
*/
type PascalCase<T extends string> = Join<PascalCaseAll<Words<RemoveApostrophe<T>>>>;
/**
* A strongly typed version of `pascalCase` that works in both runtime and type level.
* @param str the string to convert to pascal case.
* @returns the pascal cased string.
* @example pascalCase('hello world') // 'HelloWorld'
*/
declare function pascalCase<T extends string>(str: T): PascalCase<T>;
/**
* @deprecated
* Use `pascalCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toPascalCase: typeof pascalCase;
/**
* Transforms a string to camelCase.
*/
type CamelCase<T extends string> = Uncapitalize<PascalCase<RemoveApostrophe<T>>>;
/**
* A strongly typed version of `camelCase` that works in both runtime and type level.
* @param str the string to convert to camel case.
* @returns the camel cased string.
* @example camelCase('hello world') // 'helloWorld'
*/
declare function camelCase<T extends string>(str: T): CamelCase<T>;
/**
* @deprecated
* Use `camelCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toCamelCase: typeof camelCase;
/**
* Transforms a string with the specified separator (delimiter).
*/
type DelimiterCase<T extends string, D extends string> = Join<Words<RemoveApostrophe<T>>, D>;
/**
* A function that transforms a string by splitting it into words and joining them with the specified delimiter.
* @param str the string to transform.
* @param delimiter the delimiter to use.
* @returns the transformed string.
* @example delimiterCase('hello world', '.') // 'hello.world'
*/
declare function delimiterCase<T extends string, D extends string>(str: T, delimiter: D): DelimiterCase<T, D>;
/**
* @deprecated
* Use `delimiterCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toDelimiterCase: typeof delimiterCase;
/**
* Transforms a string to CONSTANT_CASE.
*/
type ConstantCase<T extends string> = Uppercase<DelimiterCase<RemoveApostrophe<T>, '_'>>;
/**
* A strongly typed version of `constantCase` that works in both runtime and type level.
* @param str the string to convert to constant case.
* @returns the constant cased string.
* @example constantCase('hello world') // 'HELLO_WORLD'
*/
declare function constantCase<T extends string>(str: T): ConstantCase<T>;
/**
* @deprecated
* Use `constantCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toConstantCase: typeof constantCase;
/**
* Transforms a string to kebab-case.
*/
type KebabCase<T extends string> = Lowercase<DelimiterCase<RemoveApostrophe<T>, '-'>>;
/**
* A strongly typed version of `kebabCase` that works in both runtime and type level.
* @param str the string to convert to kebab case.
* @returns the kebab cased string.
* @example kebabCase('hello world') // 'hello-world'
*/
declare function kebabCase<T extends string>(str: T): KebabCase<T>;
/**
* @deprecated
* Use `kebabCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toKebabCase: typeof kebabCase;
/**
* Transforms a string to snake_case.
*/
type SnakeCase<T extends string> = Lowercase<DelimiterCase<RemoveApostrophe<T>, '_'>>;
/**
* A strongly typed version of `snakeCase` that works in both runtime and type level.
* @param str the string to convert to snake case.
* @returns the snake cased string.
* @example snakeCase('hello world') // 'hello_world'
*/
declare function snakeCase<T extends string>(str: T): SnakeCase<T>;
/**
* @deprecated
* Use `snakeCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toSnakeCase: typeof snakeCase;
/**
* Transforms a string to "Title Case".
*/
type TitleCase<T extends string> = DelimiterCase<PascalCase<T>, ' '>;
/**
* A strongly typed version of `titleCase` that works in both runtime and type level.
* @param str the string to convert to title case.
* @returns the title cased string.
* @example titleCase('hello world') // 'Hello World'
*/
declare function titleCase<T extends string>(str: T): TitleCase<T>;
/**
* @deprecated
* Use `titleCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toTitleCase: typeof titleCase;
/**
* Capitalizes the first letter of a string. This is a runtime counterpart of `Capitalize<T>` from `src/types.d.ts`.
* @param str the string to capitalize.
* @returns the capitalized string.
* @example capitalize('hello world') // 'Hello world'
*/
declare function capitalize<T extends string>(str: T): Capitalize<T>;
/**
* A strongly-typed version of `lowerCase` that works in both runtime and type level.
* @param str the string to convert to lower case.
* @returns the lowercased string.
* @example lowerCase('HELLO-WORLD') // 'hello world'
*/
declare function lowerCase<T extends string>(str: T): Lowercase<DelimiterCase<T, ' '>>;
/**
* Uncapitalizes the first letter of a string. This is a runtime counterpart of `Uncapitalize<T>` from `src/types.d.ts`.
* @param str the string to uncapitalize.
* @returns the uncapitalized string.
* @example uncapitalize('Hello world') // 'hello world'
*/
declare function uncapitalize<T extends string>(str: T): Uncapitalize<T>;
/**
* A strongly-typed version of `upperCase` that works in both runtime and type level.
* @param str the string to convert to upper case.
* @returns the uppercased string.
* @example upperCase('hello-world') // 'HELLO WORLD'
*/
declare function upperCase<T extends string>(str: T): Uppercase<DelimiterCase<T, ' '>>;
/**
* Shallowly transforms the keys of a Record to camelCase.
* T: the type of the Record to transform.
*/
type CamelKeys<T> = T extends [] ? T : {
[K in keyof T as CamelCase<Extract<K, string>>]: T[K];
};
/**
* A strongly typed function that shallowly transforms the keys of an object to camelCase. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example camelKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { fooBar: { 'fizz-buz': true } }
*/
declare function camelKeys<T>(obj: T): CamelKeys<T>;
/**
* Shallowly transforms the keys of a Record to CONSTANT_CASE.
* T: the type of the Record to transform.
*/
type ConstantKeys<T> = T extends [] ? T : {
[K in keyof T as ConstantCase<Extract<K, string>>]: T[K];
};
/**
* A strongly typed function that shallowly transforms the keys of an object to CONSTANT_CASE. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example constantKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { FOO_BAR: { 'fizz-buzz': true } }
*/
declare function constantKeys<T>(obj: T): ConstantKeys<T>;
/**
* Shallowly transforms the keys of a Record to a custom delimiter case.
* T: the type of the Record to transform.
* D: the delimiter to use.
*/
type DelimiterKeys<T, D extends string> = T extends [] ? T : {
[K in keyof T as DelimiterCase<Extract<K, string>, D>]: T[K];
};
/**
* A strongly typed function that shallowly transforms the keys of an object to a custom delimiter case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @param delimiter the delimiter to use.
* @returns the transformed object.
* @example delimiterKeys({ 'foo-bar': { 'fizz-buzz': true } }, '.') // { 'foo.bar': { 'fizz.buzz': true } }
*/
declare function delimiterKeys<T, D extends string>(obj: T, delimiter: D): DelimiterKeys<T, D>;
/**
* Shallowly transforms the keys of a Record to kebab-case.
* T: the type of the Record to transform.
*/
type KebabKeys<T> = T extends [] ? T : {
[K in keyof T as KebabCase<Extract<K, string>>]: T[K];
};
/**
* A strongly typed function that shallowly transforms the keys of an object to kebab-case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example kebabKeys({ fooBar: { fizzBuzz: true } }) // { 'foo-bar': { fizzBuzz: true } }
*/
declare function kebabKeys<T>(obj: T): KebabKeys<T>;
/**
* Shallowly transforms the keys of a Record to PascalCase.
* T: the type of the Record to transform.
*/
type PascalKeys<T> = T extends [] ? T : {
[K in keyof T as PascalCase<Extract<K, string>>]: T[K];
};
/**
* A strongly typed function that shallowly transforms the keys of an object to pascal case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example pascalKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { FooBar: { 'fizz-buzz': true } }
*/
declare function pascalKeys<T>(obj: T): PascalKeys<T>;
/**
* Shallowly transforms the keys of a Record to snake_case.
* T: the type of the Record to transform.
*/
type SnakeKeys<T> = T extends [] ? T : {
[K in keyof T as SnakeCase<Extract<K, string>>]: T[K];
};
/**
* A strongly typed function that shallowly the keys of an object to snake_case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example snakeKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { 'foo_bar': { 'fizz-buzz': true } }
*/
declare function snakeKeys<T>(obj: T): SnakeKeys<T>;
/**
* Shallowly transforms the keys of a Record with `replace`.
* T: the type of the Record to transform.
*/
type ReplaceKeys<T, lookup extends string | RegExp, replacement extends string = ''> = T extends [] ? T : {
[K in keyof T as Replace<Extract<K, string>, lookup, replacement>]: T[K];
};
/**
* A strongly typed function that shallowly transforms the keys of an object by running the `replace` method in every key. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @param lookup the lookup string to be replaced.
* @param replacement the replacement string.
* @returns the transformed object.
* @example replaceKeys({ 'foo-bar': { 'fizz-buzz': true } }, 'f', 'b') // { booBar: { 'fizz-buz': true } }
*/
declare function replaceKeys<T, S extends string | RegExp, R extends string = ''>(obj: T, lookup: S, replacement?: R): ReplaceKeys<T, S, R>;
/**
* Recursively transforms the keys of a Record to camelCase.
* T: the type of the Record to transform.
*/
type DeepCamelKeys<T> = T extends [any, ...any] ? {
[I in keyof T]: DeepCamelKeys<T[I]>;
} : T extends (infer V)[] ? DeepCamelKeys<V>[] : {
[K in keyof T as CamelCase<Extract<K, string>>]: DeepCamelKeys<T[K]>;
};
/**
* A strongly typed function that recursively transforms the keys of an object to camelCase. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example deepCamelKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { fooBar: { fizzBuzz: true } }
*/
declare function deepCamelKeys<T>(obj: T): DeepCamelKeys<T>;
/**
* Recursively transforms the keys of a Record to CONSTANT_CASE.
* T: the type of the Record to transform.
*/
type DeepConstantKeys<T> = T extends [any, ...any] ? {
[I in keyof T]: DeepConstantKeys<T[I]>;
} : T extends (infer V)[] ? DeepConstantKeys<V>[] : {
[K in keyof T as ConstantCase<Extract<K, string>>]: DeepConstantKeys<T[K]>;
};
/**
* A strongly typed function that recursively transforms the keys of an object to CONSTANT_CASE. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example deepConstantKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { FOO_BAR: { FIZZ_BUZZ: true } }
*/
declare function deepConstantKeys<T>(obj: T): DeepConstantKeys<T>;
/**
* Recursively transforms the keys of a Record to a custom delimiter case.
* T: the type of the Record to transform.
* D: the delimiter to use.
*/
type DeepDelimiterKeys<T, D extends string> = T extends [any, ...any] ? {
[I in keyof T]: DeepDelimiterKeys<T[I], D>;
} : T extends (infer V)[] ? DeepDelimiterKeys<V, D>[] : {
[K in keyof T as DelimiterCase<Extract<K, string>, D>]: DeepDelimiterKeys<T[K], D>;
};
/**
* A strongly typed function that recursively transforms the keys of an object to a custom delimiter case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @param delimiter the delimiter to use.
* @returns the transformed object.
* @example deepDelimiterKeys({ 'foo-bar': { 'fizz-buzz': true } }, '.') // { 'foo.bar': { 'fizz.buzz': true } }
*/
declare function deepDelimiterKeys<T, D extends string>(obj: T, delimiter: D): DeepDelimiterKeys<T, D>;
/**
* Recursively transforms the keys of a Record to kebab-case.
* T: the type of the Record to transform.
*/
type DeepKebabKeys<T> = T extends [any, ...any] ? {
[I in keyof T]: DeepKebabKeys<T[I]>;
} : T extends (infer V)[] ? DeepKebabKeys<V>[] : {
[K in keyof T as KebabCase<Extract<K, string>>]: DeepKebabKeys<T[K]>;
};
/**
* A strongly typed function that recursively transforms the keys of an object to kebab-case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example deepKebabKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { 'foo-bar': { 'fizz-buzz': true } }
*/
declare function deepKebabKeys<T>(obj: T): DeepKebabKeys<T>;
/**
* Recursively transforms the keys of a Record to PascalCase.
* T: the type of the Record to transform.
*/
type DeepPascalKeys<T> = T extends [any, ...any] ? {
[I in keyof T]: DeepPascalKeys<T[I]>;
} : T extends (infer V)[] ? DeepPascalKeys<V>[] : {
[K in keyof T as PascalCase<Extract<K, string>>]: DeepPascalKeys<T[K]>;
};
/**
* A strongly typed function that recursively transforms the keys of an object to pascal case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example deepPascalKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { FooBar: { FizzBuzz: true } }
*/
declare function deepPascalKeys<T>(obj: T): DeepPascalKeys<T>;
/**
* Recursively transforms the keys of a Record to snake_case.
* T: the type of the Record to transform.
*/
type DeepSnakeKeys<T> = T extends [any, ...any] ? {
[I in keyof T]: DeepSnakeKeys<T[I]>;
} : T extends (infer V)[] ? DeepSnakeKeys<V>[] : {
[K in keyof T as SnakeCase<Extract<K, string>>]: DeepSnakeKeys<T[K]>;
};
/**
* A strongly typed function that recursively transforms the keys of an object to snake_case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example deepSnakeKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { 'foo_bar': { 'fizz_buzz': true } }
*/
declare function deepSnakeKeys<T>(obj: T): DeepSnakeKeys<T>;
/**
* This function is used to transform the keys of an object deeply.
* It will only be transformed at runtime, so it's not type safe.
* @param obj the object to transform.
* @param transform the function to transform the keys from string to string.
* @returns the transformed object.
* @example deepTransformKeys({ 'foo-bar': { 'fizz-buzz': true } }, camelCase)
* // { fooBar: { fizzBuzz: true } }
*/
declare function deepTransformKeys<T>(obj: T, transform: (s: string) => string): T;
export { type CamelCase, type CamelKeys, type CharAt, type Concat, type ConstantCase, type ConstantKeys, type DeepCamelKeys, type DeepConstantKeys, type DeepDelimiterKeys, type DeepKebabKeys, type DeepPascalKeys, type DeepSnakeKeys, type DelimiterCase, type DelimiterKeys, type EndsWith, type Includes, type IsDigit, type IsLetter, type IsLower, type IsSeparator, type IsSpecial, type IsUpper, type Join, type KebabCase, type KebabKeys, type Length, type PadEnd, type PadStart, type PascalCase, type PascalKeys, type Repeat, type Replace, type ReplaceAll, type ReplaceKeys, type Reverse, type Slice, type SnakeCase, type SnakeKeys, type Split, type StartsWith, type TitleCase, type Trim, type TrimEnd, type TrimStart, type Truncate, type Words, camelCase, camelKeys, capitalize, charAt, concat, constantCase, constantKeys, deepCamelKeys, deepConstantKeys, deepDelimiterKeys, deepKebabKeys, deepPascalKeys, deepSnakeKeys, deepTransformKeys, delimiterCase, delimiterKeys, endsWith, includes, join, kebabCase, kebabKeys, length, lowerCase, padEnd, padStart, pascalCase, pascalKeys, repeat, replace, replaceAll, replaceKeys, reverse, slice, snakeCase, snakeKeys, split, startsWith, titleCase, toCamelCase, toConstantCase, toDelimiterCase, toKebabCase, toLowerCase, toPascalCase, toSnakeCase, toTitleCase, toUpperCase, trim, trimEnd, trimStart, truncate, uncapitalize, upperCase, words };
import type {
CharAt,
Concat,
EndsWith,
Includes,
Join,
PadEnd,
PadStart,
Repeat,
ReplaceAll,
Replace,
Slice,
Split,
StartsWith,
TrimEnd,
TrimStart,
Trim,
} from '..'
// biome-ignore lint/complexity/noUselessEmptyExport: <explanation>
export {}
declare global {
interface ReadonlyArray<T> {
join<const A extends readonly string[], D extends string = ''>(
this: A,
separator?: D
): Join<A, D>
}
interface String {
charAt<const S extends string, I extends number>(
this: S,
index: I
): CharAt<S, I>
concat<const S extends string, const T extends readonly string[]>(
this: S,
...args: T
): Concat<[S, ...T]>
endsWith<
const S extends string,
const T extends string,
P extends number | undefined = undefined,
>(this: S, searchString: T, index?: P): EndsWith<S, T, P>
includes<
const S extends string,
const T extends string,
P extends number = 0,
>(this: S, searchString: T, position?: P): Includes<S, T, P>
padEnd<
const S extends string,
const T extends number,
const U extends string = ' ',
>(this: S, maxLength: T, fillString?: U): PadEnd<S, T, U>
padStart<
const S extends string,
const T extends number,
const U extends string = ' ',
>(this: S, maxLength: T, fillString?: U): PadStart<S, T, U>
repeat<const S extends string, const T extends number>(
this: S,
count: T
): Repeat<S, T>
replace<
const S extends string,
const T extends string,
const U extends string,
>(this: S, searchValue: T, replaceValue: U): Replace<S, T, U>
replaceAll<
const S extends string,
const T extends string,
const U extends string,
>(this: S, searchValue: T, replaceValue: U): ReplaceAll<S, T, U>
slice<const S extends string>(this: S): Slice<S>
slice<const S extends string, const T extends number>(
this: S,
start?: T
): Slice<S, T>
slice<
const S extends string,
const T extends number,
const U extends number,
>(this: S, start?: T, end?: U): Slice<S, T, U>
split<const S extends string, D extends string>(
this: S,
delimiter: D
): Split<S, D>
startsWith<
const S extends string,
const T extends string,
P extends number = 0,
>(this: S, searchString: T, position?: P): StartsWith<S, T, P>
toLowerCase<const S extends string>(this: S): Lowercase<S>
toUpperCase<const S extends string>(this: S): Uppercase<S>
trim<const S extends string>(this: S): Trim<S>
trimEnd<const S extends string>(this: S): TrimEnd<S>
trimStart<const S extends string>(this: S): TrimStart<S>
}
}
+21
-21

@@ -130,2 +130,15 @@ /**

/**
* Reverses a string.
* - `T` The string to reverse.
*/
type Reverse<T extends string, _acc extends string = ''> = T extends `${infer Head}${infer Tail}` ? Reverse<Tail, `${Head}${_acc}`> : _acc extends '' ? T : `${T}${_acc}`;
/**
* A strongly-typed function to reverse a string.
* @param str the string to reverse.
* @returns the reversed string in both type level and runtime.
* @example reverse('hello world') // 'dlrow olleh'
*/
declare function reverse<T extends string>(str: T): Reverse<T>;
/**
* Slices a string from a startIndex to an endIndex.

@@ -169,15 +182,2 @@ * T: The string to slice.

/**
* Reverses a string.
* - `T` The string to reverse.
*/
type Reverse<T extends string, _acc extends string = ''> = T extends `${infer Head}${infer Tail}` ? Reverse<Tail, `${Head}${_acc}`> : _acc extends '' ? T : `${T}${_acc}`;
/**
* A strongly-typed function to reverse a string.
* @param str the string to reverse.
* @returns the reversed string in both type level and runtime.
* @example reverse('hello world') // 'dlrow olleh'
*/
declare function reverse<T extends string>(str: T): Reverse<T>;
/**
* Checks if a string ends with another string.

@@ -379,10 +379,2 @@ * T: The string to check.

declare const SEPARATORS: readonly ["[", "]", "{", "}", "(", ")", "|", "/", "-", "\\", " ", "_", "."];
type Separator = (typeof SEPARATORS)[number];
/**
* Checks if the given character is a separator.
* E.g. space, underscore, dash, dot, slash.
*/
type IsSeparator<T extends string> = IsStringLiteral<T> extends true ? T extends Separator ? true : false : boolean;
type UpperChars = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';

@@ -409,2 +401,10 @@ type LowerChars = Lowercase<UpperChars>;

declare const SEPARATORS: readonly ["[", "]", "{", "}", "(", ")", "|", "/", "-", "\\", " ", "_", "."];
type Separator = (typeof SEPARATORS)[number];
/**
* Checks if the given character is a separator.
* E.g. space, underscore, dash, dot, slash.
*/
type IsSeparator<T extends string> = IsStringLiteral<T> extends true ? T extends Separator ? true : false : boolean;
type Apostrophe = "'";

@@ -411,0 +411,0 @@ /**

@@ -1,3 +0,1 @@

'use strict';
// src/native/char-at.ts

@@ -63,3 +61,3 @@ function charAt(str, index) {

// src/native/slice.ts
function slice(str, start = 0, end = undefined) {
function slice(str, start = 0, end = void 0) {
return str.slice(start, end);

@@ -145,2 +143,7 @@ }

// src/utils/characters/apostrophe.ts
function removeApostrophe(str) {
return replaceAll(str, "'", "");
}
// src/utils/word-case/capitalize.ts

@@ -162,7 +165,2 @@ function capitalize(str) {

// src/utils/characters/apostrophe.ts
function removeApostrophe(str) {
return replaceAll(str, "'", "");
}
// src/utils/word-case/pascal-case.ts

@@ -316,55 +314,2 @@ function pascalCase(str) {

exports.camelCase = camelCase;
exports.camelKeys = camelKeys;
exports.capitalize = capitalize;
exports.charAt = charAt;
exports.concat = concat;
exports.constantCase = constantCase;
exports.constantKeys = constantKeys;
exports.deepCamelKeys = deepCamelKeys;
exports.deepConstantKeys = deepConstantKeys;
exports.deepDelimiterKeys = deepDelimiterKeys;
exports.deepKebabKeys = deepKebabKeys;
exports.deepPascalKeys = deepPascalKeys;
exports.deepSnakeKeys = deepSnakeKeys;
exports.deepTransformKeys = deepTransformKeys;
exports.delimiterCase = delimiterCase;
exports.delimiterKeys = delimiterKeys;
exports.endsWith = endsWith;
exports.includes = includes;
exports.join = join;
exports.kebabCase = kebabCase;
exports.kebabKeys = kebabKeys;
exports.length = length;
exports.lowerCase = lowerCase;
exports.padEnd = padEnd;
exports.padStart = padStart;
exports.pascalCase = pascalCase;
exports.pascalKeys = pascalKeys;
exports.repeat = repeat;
exports.replace = replace;
exports.replaceAll = replaceAll;
exports.replaceKeys = replaceKeys;
exports.reverse = reverse;
exports.slice = slice;
exports.snakeCase = snakeCase;
exports.snakeKeys = snakeKeys;
exports.split = split;
exports.startsWith = startsWith;
exports.titleCase = titleCase;
exports.toCamelCase = toCamelCase;
exports.toConstantCase = toConstantCase;
exports.toDelimiterCase = toDelimiterCase;
exports.toKebabCase = toKebabCase;
exports.toLowerCase = toLowerCase;
exports.toPascalCase = toPascalCase;
exports.toSnakeCase = toSnakeCase;
exports.toTitleCase = toTitleCase;
exports.toUpperCase = toUpperCase;
exports.trim = trim;
exports.trimEnd = trimEnd;
exports.trimStart = trimStart;
exports.truncate = truncate;
exports.uncapitalize = uncapitalize;
exports.upperCase = upperCase;
exports.words = words;
export { camelCase, camelKeys, capitalize, charAt, concat, constantCase, constantKeys, deepCamelKeys, deepConstantKeys, deepDelimiterKeys, deepKebabKeys, deepPascalKeys, deepSnakeKeys, deepTransformKeys, delimiterCase, delimiterKeys, endsWith, includes, join, kebabCase, kebabKeys, length, lowerCase, padEnd, padStart, pascalCase, pascalKeys, repeat, replace, replaceAll, replaceKeys, reverse, slice, snakeCase, snakeKeys, split, startsWith, titleCase, toCamelCase, toConstantCase, toDelimiterCase, toKebabCase, toLowerCase, toPascalCase, toSnakeCase, toTitleCase, toUpperCase, trim, trimEnd, trimStart, truncate, uncapitalize, upperCase, words };
{
"name": "string-ts",
"version": "2.2.1",
"version": "2.3.0-experimental.0",
"description": "Strongly-typed string functions.",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"author": "Gustavo Guichard <@gugaguichard>",
"license": "MIT",
"type": "module",
"scripts": {
"build": "tsup ./src/index.ts --format esm,cjs --dts --treeshake",
"build": "tsup ./src/index.ts --format esm,cjs --dts --treeshake && tsx scripts/generate-entrypoints.ts",
"dev": "tsup ./src/index.ts --format esm,cjs --watch --dts",
"lint": "eslint *.ts*",
"lint": "node_modules/.bin/biome check --write --error-on-warnings",
"tsc": "tsc --noEmit",

@@ -18,15 +16,29 @@ "tsc:dist": "tsc --project tsconfig.dist.json",

},
"exports": {
".": {
"require": "./dist/index.js",
"import": "./dist/index.mjs"
},
"./native": {
"default": "./dist/native.js"
}
},
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"typesVersions": {
"*": {
"native": ["dist/native.d.ts"]
}
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "latest",
"@biomejs/biome": "^1.9.4",
"@types/node": "^22.15.3",
"@vitest/coverage-v8": "^3.0.5",
"eslint": "latest",
"prettier": "latest",
"tsup": "latest",
"tsx": "^4.19.4",
"typescript": "^5.7.3",
"vitest": "latest"
},
"files": [
"README.md",
"./dist/*"
],
"files": ["README.md", "./dist/*"],
"repository": {

@@ -39,3 +51,6 @@ "type": "git",

},
"sideEfects": false
"sideEffects": false,
"pnpm": {
"onlyBuiltDependencies": ["@biomejs/biome", "esbuild"]
}
}

@@ -958,3 +958,2 @@ <p align="center">

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->

@@ -976,3 +975,2 @@ <table>

<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->

@@ -979,0 +977,0 @@ <!-- ALL-CONTRIBUTORS-LIST:END -->

/**
* Returns true if input number type is a literal
*/
type IsNumberLiteral<T extends number> = [T] extends [number] ? [number] extends [T] ? false : true : false;
type IsBooleanLiteral<T extends boolean> = [T] extends [boolean] ? [boolean] extends [T] ? false : true : false;
/**
* Returns true if any elements in boolean array are the literal true (not false or boolean)
*/
type Any<Arr extends boolean[]> = Arr extends [
infer Head extends boolean,
...infer Rest extends boolean[]
] ? IsBooleanLiteral<Head> extends true ? Head extends true ? true : Any<Rest> : Any<Rest> : false;
/**
* Returns true if every element in boolean array is the literal true (not false or boolean)
*/
type All<Arr extends boolean[]> = IsBooleanLiteral<Arr[number]> extends true ? Arr extends [infer Head extends boolean, ...infer Rest extends boolean[]] ? Head extends true ? Any<Rest> : false : true : false;
/**
* Returns true if string input type is a literal
*/
type IsStringLiteral<T extends string> = [T] extends [string] ? [string] extends [T] ? false : Uppercase<T> extends Uppercase<Lowercase<T>> ? Lowercase<T> extends Lowercase<Uppercase<T>> ? true : false : false : false;
type IsStringLiteralArray<Arr extends string[] | readonly string[]> = IsStringLiteral<Arr[number]> extends true ? true : false;
/**
* Splits a string into an array of substrings.
* T: The string to split.
* delimiter: The delimiter.
*/
type Split<T extends string, delimiter extends string = ''> = IsStringLiteral<T | delimiter> extends true ? T extends `${infer first}${delimiter}${infer rest}` ? [first, ...Split<rest, delimiter>] : T extends '' ? [] : [T] : string[];
/**
* A strongly-typed version of `String.prototype.split`.
* @param str the string to split.
* @param delimiter the delimiter.
* @returns the splitted string in both type level and runtime.
* @example split('hello world', ' ') // ['hello', 'world']
*/
declare function split<T extends string, D extends string = ''>(str: T, delimiter?: D): Split<T, D>;
/**
* Gets the character at the given index.
* T: The string to get the character from.
* index: The index of the character.
*/
type CharAt<T extends string, index extends number> = All<[
IsStringLiteral<T>,
IsNumberLiteral<index>
]> extends true ? Split<T>[index] : string;
/**
* A strongly-typed version of `String.prototype.charAt`.
* @param str the string to get the character from.
* @param index the index of the character.
* @returns the character in both type level and runtime.
* @example charAt('hello world', 6) // 'w'
*/
declare function charAt<T extends string, I extends number>(str: T, index: I): CharAt<T, I>;
/**
* Joins a tuple of strings with the given delimiter.
* T: The tuple of strings to join.
* delimiter: The delimiter.
*/
type Join<T extends readonly string[], delimiter extends string = ''> = All<[IsStringLiteralArray<T>, IsStringLiteral<delimiter>]> extends true ? T extends readonly [
infer first extends string,
...infer rest extends string[]
] ? rest extends [] ? first : `${first}${delimiter}${Join<rest, delimiter>}` : '' : string;
/**
* A strongly-typed version of `Array.prototype.join`.
* @param tuple the tuple of strings to join.
* @param delimiter the delimiter.
* @returns the joined string in both type level and runtime.
* @example join(['hello', 'world'], '-') // 'hello-world'
*/
declare function join<const T extends readonly string[], D extends string = ''>(tuple: T, delimiter?: D): Join<T, D>;
/**
* Concatenates a tuple of strings.
* T: The tuple of strings to concatenate.
*/
type Concat<T extends string[]> = Join<T>;
/**
* A strongly-typed version of `String.prototype.concat`.
* @param strings the tuple of strings to concatenate.
* @returns the concatenated string in both type level and runtime.
* @example concat('a', 'bc', 'def') // 'abcdef'
*/
declare function concat<T extends string[]>(...strings: T): Concat<T>;
/**
* Gets the length of a string.
*/
type Length<T extends string> = IsStringLiteral<T> extends true ? Split<T>['length'] : number;
/**
* A strongly-typed version of `String.prototype.length`.
* @param str the string to get the length from.
* @returns the length of the string in both type level and runtime.
* @example length('hello world') // 11
*/
declare function length<T extends string>(str: T): Length<T>;
/**
* PascalCases all the words in a tuple of strings
*/
type PascalCaseAll<T extends string[]> = T extends [
infer head extends string,
...infer rest extends string[]
] ? [Capitalize<Lowercase<head>>, ...PascalCaseAll<rest>] : T;
/**
* Removes all the elements matching the given condition from a tuple.
*/
type Reject<tuple, cond, output extends any[] = []> = tuple extends [
infer first,
...infer rest
] ? Reject<rest, cond, first extends cond ? output : [...output, first]> : output;
/**
* Removes the given suffix from a sentence.
*/
type DropSuffix<sentence extends string, suffix extends string> = string extends sentence | suffix ? string : sentence extends `${infer rest}${suffix}` ? rest : sentence;
/**
* Returns a tuple of the given length with the given type.
*/
type TupleOf<L extends number, T = unknown, result extends any[] = []> = result['length'] extends L ? result : TupleOf<L, T, [...result, T]>;
declare namespace Math {
type Subtract<A extends number, B extends number> = number extends A | B ? number : TupleOf<A> extends [...infer U, ...TupleOf<B>] ? U['length'] : 0;
type IsNegative<T extends number> = number extends T ? boolean : `${T}` extends `-${number}` ? true : false;
type Abs<T extends number> = `${T}` extends `-${infer U extends number}` ? U : T;
type GetPositiveIndex<T extends string, I extends number> = IsNegative<I> extends false ? I : Subtract<Length<T>, Abs<I>>;
}
/**
* Slices a string from a startIndex to an endIndex.
* T: The string to slice.
* startIndex: The start index.
* endIndex: The end index.
*/
type Slice<T extends string, startIndex extends number = 0, endIndex extends number | undefined = undefined> = endIndex extends number ? _Slice<T, startIndex, endIndex> : _SliceStart<T, startIndex>;
/** Slice with startIndex and endIndex */
type _Slice<T extends string, startIndex extends number, endIndex extends number, _result extends string = ''> = IsNumberLiteral<startIndex | endIndex> extends true ? T extends `${infer head}${infer rest}` ? IsStringLiteral<head> extends true ? startIndex extends 0 ? endIndex extends 0 ? _result : _Slice<rest, 0, Math.Subtract<Math.GetPositiveIndex<T, endIndex>, 1>, `${_result}${head}`> : _Slice<rest, Math.Subtract<Math.GetPositiveIndex<T, startIndex>, 1>, Math.Subtract<Math.GetPositiveIndex<T, endIndex>, 1>, _result> : startIndex | endIndex extends 0 ? _result : string : IsStringLiteral<T> extends true ? _result : startIndex | endIndex extends 0 ? _result : string : string;
/** Slice with startIndex only */
type _SliceStart<T extends string, startIndex extends number, _result extends string = ''> = IsNumberLiteral<startIndex> extends true ? T extends `${infer head}${infer rest}` ? IsStringLiteral<head> extends true ? startIndex extends 0 ? T : _SliceStart<rest, Math.Subtract<Math.GetPositiveIndex<T, startIndex>, 1>, _result> : string : IsStringLiteral<T> extends true ? _result : startIndex extends 0 ? _result : string : string;
/**
* A strongly-typed version of `String.prototype.slice`.
* @param str the string to slice.
* @param start the start index.
* @param end the end index.
* @returns the sliced string in both type level and runtime.
* @example slice('hello world', 6) // 'world'
*/
declare function slice<T extends string, S extends number = 0, E extends number | undefined = undefined>(str: T, start?: S, end?: E): Slice<T, S, E>;
/**
* Checks if a string starts with another string.
* T: The string to check.
* S: The string to check against.
* P: The position to start the search.
*/
type StartsWith<T extends string, S extends string, P extends number = 0> = All<[IsStringLiteral<S>, IsNumberLiteral<P>]> extends true ? Math.IsNegative<P> extends false ? P extends 0 ? S extends `${infer SHead}${infer SRest}` ? T extends `${infer THead}${infer TRest}` ? IsStringLiteral<THead | SHead> extends true ? THead extends SHead ? StartsWith<TRest, SRest> : false : boolean : IsStringLiteral<T> extends true ? false : boolean : true : StartsWith<Slice<T, P>, S, 0> : StartsWith<T, S, 0> : boolean;
/**
* A strongly-typed version of `String.prototype.startsWith`.
* @param text the string to search.
* @param search the string to search with.
* @param position the index to start search at.
* @returns boolean, whether or not the text string starts with the search string.
* @example startsWith('abc', 'a') // true
*/
declare function startsWith<T extends string, S extends string, P extends number = 0>(text: T, search: S, position?: P): StartsWith<T, S, P>;
/**
* Reverses a string.
* - `T` The string to reverse.
*/
type Reverse<T extends string, _acc extends string = ''> = T extends `${infer Head}${infer Tail}` ? Reverse<Tail, `${Head}${_acc}`> : _acc extends '' ? T : `${T}${_acc}`;
/**
* A strongly-typed function to reverse a string.
* @param str the string to reverse.
* @returns the reversed string in both type level and runtime.
* @example reverse('hello world') // 'dlrow olleh'
*/
declare function reverse<T extends string>(str: T): Reverse<T>;
/**
* Checks if a string ends with another string.
* T: The string to check.
* S: The string to check against.
* P: The position the search should end.
*/
type EndsWith<T extends string, S extends string, P extends number | undefined = undefined> = P extends number ? _EndsWith<T, S, P> : _EndsWithNoPosition<T, S>;
type _EndsWith<T extends string, S extends string, P extends number> = All<[
IsStringLiteral<S>,
IsNumberLiteral<P>
]> extends true ? Math.IsNegative<P> extends false ? P extends Length<T> ? IsStringLiteral<T> extends true ? S extends Slice<T, Math.Subtract<Length<T>, Length<S>>, Length<T>> ? true : false : _EndsWithNoPosition<Slice<T, 0, P>, S> : _EndsWithNoPosition<Slice<T, 0, P>, S> : false : boolean;
/** Overload of EndsWith without P */
type _EndsWithNoPosition<T extends string, S extends string> = StartsWith<Reverse<T>, Reverse<S>>;
/**
* A strongly-typed version of `String.prototype.endsWith`.
* @param text the string to search.
* @param search the string to search with.
* @param position the index the search should end at.
* @returns boolean, whether or not the text string ends with the search string.
* @example endsWith('abc', 'c') // true
*/
declare function endsWith<T extends string, S extends string, P extends number = Length<T>>(text: T, search: S, position?: P): EndsWith<T, S, P>;
/**
* Checks if a string includes another string.
* T: The string to check.
* S: The string to check against.
* P: The position to start the search.
*/
type Includes<T extends string, S extends string, P extends number = 0> = string extends T | S ? boolean : Math.IsNegative<P> extends false ? P extends 0 ? T extends `${string}${S}${string}` ? true : false : Includes<Slice<T, P>, S, 0> : Includes<T, S, 0>;
/**
* A strongly-typed version of `String.prototype.includes`.
* @param text the string to search
* @param search the string to search with
* @param position the index to start search at
* @returns boolean, whether or not the text contains the search string.
* @example includes('abcde', 'bcd') // true
*/
declare function includes<T extends string, S extends string, P extends number = 0>(text: T, search: S, position?: P): Includes<T, S, P>;
/**
* Repeats a string N times.
* T: The string to repeat.
* N: The number of times to repeat.
*/
type Repeat<T extends string, times extends number = 0> = All<[
IsStringLiteral<T>,
IsNumberLiteral<times>
]> extends true ? times extends 0 ? '' : Math.IsNegative<times> extends false ? Join<TupleOf<times, T>> : never : string;
/**
* A strongly-typed version of `String.prototype.repeat`.
* @param str the string to repeat.
* @param times the number of times to repeat.
* @returns the repeated string in both type level and runtime.
* @example repeat('hello', 3) // 'hellohellohello'
*/
declare function repeat<T extends string, N extends number = 0>(str: T, times?: N): Repeat<T, N>;
/**
* Pads a string at the end with another string.
* T: The string to pad.
* times: The number of times to pad.
* pad: The string to pad with.
*/
type PadEnd<T extends string, times extends number = 0, pad extends string = ' '> = All<[IsStringLiteral<T | pad>, IsNumberLiteral<times>]> extends true ? Math.IsNegative<times> extends false ? Math.Subtract<times, Length<T>> extends infer missing extends number ? `${T}${Slice<Repeat<pad, missing>, 0, missing>}` : never : T : string;
/**
* A strongly-typed version of `String.prototype.padEnd`.
* @param str the string to pad.
* @param length the length to pad.
* @param pad the string to pad with.
* @returns the padded string in both type level and runtime.
* @example padEnd('hello', 10, '=') // 'hello====='
*/
declare function padEnd<T extends string, N extends number = 0, U extends string = ' '>(str: T, length?: N, pad?: U): PadEnd<T, N, U>;
/**
* Pads a string at the start with another string.
* T: The string to pad.
* times: The number of times to pad.
* pad: The string to pad with.
*/
type PadStart<T extends string, times extends number = 0, pad extends string = ' '> = All<[IsStringLiteral<T | pad>, IsNumberLiteral<times>]> extends true ? Math.IsNegative<times> extends false ? Math.Subtract<times, Length<T>> extends infer missing extends number ? `${Slice<Repeat<pad, missing>, 0, missing>}${T}` : never : T : string;
/**
* A strongly-typed version of `String.prototype.padStart`.
* @param str the string to pad.
* @param length the length to pad.
* @param pad the string to pad with.
* @returns the padded string in both type level and runtime.
* @example padStart('hello', 10, '=') // '=====hello'
*/
declare function padStart<T extends string, N extends number = 0, U extends string = ' '>(str: T, length?: N, pad?: U): PadStart<T, N, U>;
/**
* Replaces the first occurrence of a string with another string.
* sentence: The sentence to replace.
* lookup: The lookup string to be replaced.
* replacement: The replacement string.
*/
type Replace<sentence extends string, lookup extends string | RegExp, replacement extends string = ''> = lookup extends string ? IsStringLiteral<lookup | sentence | replacement> extends true ? sentence extends `${infer rest}${lookup}${infer rest2}` ? `${rest}${replacement}${rest2}` : sentence : string : string;
/**
* A strongly-typed version of `String.prototype.replace`.
* @param sentence the sentence to replace.
* @param lookup the lookup string to be replaced.
* @param replacement the replacement string.
* @returns the replaced string in both type level and runtime.
* @example replace('hello world', 'l', '1') // 'he1lo world'
*/
declare function replace<T extends string, S extends string | RegExp, R extends string = ''>(sentence: T, lookup: S, replacement?: R): Replace<T, S, R>;
/**
* Replaces all the occurrences of a string with another string.
* sentence: The sentence to replace.
* lookup: The lookup string to be replaced.
* replacement: The replacement string.
*/
type ReplaceAll<sentence extends string, lookup extends string | RegExp, replacement extends string = ''> = lookup extends string ? IsStringLiteral<lookup | sentence | replacement> extends true ? sentence extends `${infer rest}${lookup}${infer rest2}` ? `${rest}${replacement}${ReplaceAll<rest2, lookup, replacement>}` : sentence : string : string;
/**
* A strongly-typed version of `String.prototype.replaceAll`.
* @param sentence the sentence to replace.
* @param lookup the lookup string to be replaced.
* @param replacement the replacement string.
* @returns the replaced string in both type level and runtime.
* @example replaceAll('hello world', 'l', '1') // 'he11o wor1d'
*/
declare function replaceAll<T extends string, S extends string | RegExp, R extends string = ''>(sentence: T, lookup: S, replacement?: R): ReplaceAll<T, S, R>;
/**
* Trims all whitespaces at the start of a string.
* T: The string to trim.
*/
type TrimStart<T extends string> = T extends ` ${infer rest}` ? TrimStart<rest> : T;
/**
* A strongly-typed version of `String.prototype.trimStart`.
* @param str the string to trim.
* @returns the trimmed string in both type level and runtime.
* @example trimStart(' hello world ') // 'hello world '
*/
declare function trimStart<T extends string>(str: T): TrimStart<T>;
/**
* Trims all whitespaces at the end of a string.
* T: The string to trim.
*/
type TrimEnd<T extends string> = T extends `${infer rest} ` ? TrimEnd<rest> : T;
/**
* A strongly-typed version of `String.prototype.trimEnd`.
* @param str the string to trim.
* @returns the trimmed string in both type level and runtime.
* @example trimEnd(' hello world ') // ' hello world'
*/
declare function trimEnd<T extends string>(str: T): TrimEnd<T>;
/**
* Trims all whitespaces at the start and end of a string.
* T: The string to trim.
*/
type Trim<T extends string> = TrimEnd<TrimStart<T>>;
/**
* A strongly-typed version of `String.prototype.trim`.
* @param str the string to trim.
* @returns the trimmed string in both type level and runtime.
* @example trim(' hello world ') // 'hello world'
*/
declare function trim<T extends string>(str: T): Trim<T>;
/**
* This function is a strongly-typed counterpart of String.prototype.toLowerCase.
* @param str the string to make lowercase.
* @returns the lowercased string.
* @example toLowerCase('HELLO WORLD') // 'hello world'
*/
declare function toLowerCase<T extends string>(str: T): Lowercase<T>;
/**
* This function is a strongly-typed counterpart of String.prototype.toUpperCase.
* @param str the string to make uppercase.
* @returns the uppercased string.
* @example toUpperCase('hello world') // 'HELLO WORLD'
*/
declare function toUpperCase<T extends string>(str: T): Uppercase<T>;
/**
* Truncate a string if it's longer than the given maximum length.
* The last characters of the truncated string are replaced with the omission string which defaults to "...".
*/
type Truncate<T extends string, Size extends number, Omission extends string = '...'> = All<[IsStringLiteral<T | Omission>, IsNumberLiteral<Size>]> extends true ? Math.IsNegative<Size> extends true ? Omission : Math.Subtract<Length<T>, Size> extends 0 ? T : Join<[Slice<T, 0, Math.Subtract<Size, Length<Omission>>>, Omission]> : string;
/**
* A strongly typed function to truncate a string if it's longer than the given maximum string length.
* The last characters of the truncated string are replaced with the omission string which defaults to "...".
* @param sentence the sentence to extract the words from.
* @param length the maximum length of the string.
* @param omission the string to append to the end of the truncated string.
* @returns the truncated string
* @example truncate('Hello, World', 8) // 'Hello...'
*/
declare function truncate<T extends string, S extends number, P extends string = '...'>(sentence: T, length: S, omission?: P): Truncate<T, S, P>;
declare const SEPARATORS: readonly ["[", "]", "{", "}", "(", ")", "|", "/", "-", "\\", " ", "_", "."];
type Separator = (typeof SEPARATORS)[number];
/**
* Checks if the given character is a separator.
* E.g. space, underscore, dash, dot, slash.
*/
type IsSeparator<T extends string> = IsStringLiteral<T> extends true ? T extends Separator ? true : false : boolean;
type UpperChars = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
type LowerChars = Lowercase<UpperChars>;
/**
* Checks if the given character is an upper case letter.
*/
type IsUpper<T extends string> = IsStringLiteral<T> extends true ? T extends UpperChars ? true : false : boolean;
/**
* Checks if the given character is a lower case letter.
*/
type IsLower<T extends string> = IsStringLiteral<T> extends true ? T extends LowerChars ? true : false : boolean;
/**
* Checks if the given character is a letter.
*/
type IsLetter<T extends string> = IsStringLiteral<T> extends true ? T extends LowerChars | UpperChars ? true : false : boolean;
type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
/**
* Checks if the given character is a number.
*/
type IsDigit<T extends string> = IsStringLiteral<T> extends true ? T extends Digit ? true : false : boolean;
type Apostrophe = "'";
/**
* Checks if the given character is an apostrophe
*/
type IsApostrophe<T extends string> = IsStringLiteral<T> extends true ? T extends Apostrophe ? true : false : boolean;
type RemoveApostrophe<T extends string> = ReplaceAll<T, "'", ''>;
/**
* Checks if the given character is a special character.
* E.g. not a letter, number, or separator.
*/
type IsSpecial<T extends string> = IsStringLiteral<T> extends true ? IsLetter<T> extends true ? false : IsDigit<T> extends true ? false : IsSeparator<T> extends true ? false : IsApostrophe<T> extends true ? false : true : boolean;
/**
* Splits a string into words.
* sentence: The current string to split.
* word: The current word.
* prev: The previous character.
*/
type Words<sentence extends string, word extends string = '', prev extends string = ''> = IsStringLiteral<sentence | word | prev> extends true ? sentence extends `${infer curr}${infer rest}` ? IsSeparator<curr> extends true ? Reject<[word, ...Words<rest>], ''> : prev extends '' ? Reject<Words<rest, curr, curr>, ''> : [false, true] extends [IsDigit<prev>, IsDigit<curr>] ? [
word,
...Words<rest, curr, curr>
] : [true, false] extends [IsDigit<prev>, IsDigit<curr>] ? [
word,
...Words<rest, curr, curr>
] : [false, true] extends [IsSpecial<prev>, IsSpecial<curr>] ? [
word,
...Words<rest, curr, curr>
] : [true, false] extends [IsSpecial<prev>, IsSpecial<curr>] ? [
word,
...Words<rest, curr, curr>
] : [true, true] extends [IsDigit<prev>, IsDigit<curr>] ? Reject<Words<rest, `${word}${curr}`, curr>, ''> : [true, true] extends [IsLower<prev>, IsUpper<curr>] ? [
word,
...Words<rest, curr, curr>
] : [true, true] extends [IsUpper<prev>, IsLower<curr>] ? [
DropSuffix<word, prev>,
...Words<rest, `${prev}${curr}`, curr>
] : Reject<Words<rest, `${word}${curr}`, curr>, ''> : Reject<[word], ''> : string[];
/**
* A strongly-typed function to extract the words from a sentence.
* @param sentence the sentence to extract the words from.
* @returns an array of words in both type level and runtime.
* @example words('helloWorld') // ['hello', 'World']
*/
declare function words<T extends string>(sentence: T): Words<T>;
/**
* Transforms a string to PascalCase.
*/
type PascalCase<T extends string> = Join<PascalCaseAll<Words<RemoveApostrophe<T>>>>;
/**
* A strongly typed version of `pascalCase` that works in both runtime and type level.
* @param str the string to convert to pascal case.
* @returns the pascal cased string.
* @example pascalCase('hello world') // 'HelloWorld'
*/
declare function pascalCase<T extends string>(str: T): PascalCase<T>;
/**
* @deprecated
* Use `pascalCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toPascalCase: typeof pascalCase;
/**
* Transforms a string to camelCase.
*/
type CamelCase<T extends string> = Uncapitalize<PascalCase<RemoveApostrophe<T>>>;
/**
* A strongly typed version of `camelCase` that works in both runtime and type level.
* @param str the string to convert to camel case.
* @returns the camel cased string.
* @example camelCase('hello world') // 'helloWorld'
*/
declare function camelCase<T extends string>(str: T): CamelCase<T>;
/**
* @deprecated
* Use `camelCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toCamelCase: typeof camelCase;
/**
* Transforms a string with the specified separator (delimiter).
*/
type DelimiterCase<T extends string, D extends string> = Join<Words<RemoveApostrophe<T>>, D>;
/**
* A function that transforms a string by splitting it into words and joining them with the specified delimiter.
* @param str the string to transform.
* @param delimiter the delimiter to use.
* @returns the transformed string.
* @example delimiterCase('hello world', '.') // 'hello.world'
*/
declare function delimiterCase<T extends string, D extends string>(str: T, delimiter: D): DelimiterCase<T, D>;
/**
* @deprecated
* Use `delimiterCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toDelimiterCase: typeof delimiterCase;
/**
* Transforms a string to CONSTANT_CASE.
*/
type ConstantCase<T extends string> = Uppercase<DelimiterCase<RemoveApostrophe<T>, '_'>>;
/**
* A strongly typed version of `constantCase` that works in both runtime and type level.
* @param str the string to convert to constant case.
* @returns the constant cased string.
* @example constantCase('hello world') // 'HELLO_WORLD'
*/
declare function constantCase<T extends string>(str: T): ConstantCase<T>;
/**
* @deprecated
* Use `constantCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toConstantCase: typeof constantCase;
/**
* Transforms a string to kebab-case.
*/
type KebabCase<T extends string> = Lowercase<DelimiterCase<RemoveApostrophe<T>, '-'>>;
/**
* A strongly typed version of `kebabCase` that works in both runtime and type level.
* @param str the string to convert to kebab case.
* @returns the kebab cased string.
* @example kebabCase('hello world') // 'hello-world'
*/
declare function kebabCase<T extends string>(str: T): KebabCase<T>;
/**
* @deprecated
* Use `kebabCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toKebabCase: typeof kebabCase;
/**
* Transforms a string to snake_case.
*/
type SnakeCase<T extends string> = Lowercase<DelimiterCase<RemoveApostrophe<T>, '_'>>;
/**
* A strongly typed version of `snakeCase` that works in both runtime and type level.
* @param str the string to convert to snake case.
* @returns the snake cased string.
* @example snakeCase('hello world') // 'hello_world'
*/
declare function snakeCase<T extends string>(str: T): SnakeCase<T>;
/**
* @deprecated
* Use `snakeCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toSnakeCase: typeof snakeCase;
/**
* Transforms a string to "Title Case".
*/
type TitleCase<T extends string> = DelimiterCase<PascalCase<T>, ' '>;
/**
* A strongly typed version of `titleCase` that works in both runtime and type level.
* @param str the string to convert to title case.
* @returns the title cased string.
* @example titleCase('hello world') // 'Hello World'
*/
declare function titleCase<T extends string>(str: T): TitleCase<T>;
/**
* @deprecated
* Use `titleCase` instead.
* Read more about the deprecation [here](https://github.com/gustavoguichard/string-ts/issues/44).
*/
declare const toTitleCase: typeof titleCase;
/**
* Capitalizes the first letter of a string. This is a runtime counterpart of `Capitalize<T>` from `src/types.d.ts`.
* @param str the string to capitalize.
* @returns the capitalized string.
* @example capitalize('hello world') // 'Hello world'
*/
declare function capitalize<T extends string>(str: T): Capitalize<T>;
/**
* A strongly-typed version of `lowerCase` that works in both runtime and type level.
* @param str the string to convert to lower case.
* @returns the lowercased string.
* @example lowerCase('HELLO-WORLD') // 'hello world'
*/
declare function lowerCase<T extends string>(str: T): Lowercase<DelimiterCase<T, ' '>>;
/**
* Uncapitalizes the first letter of a string. This is a runtime counterpart of `Uncapitalize<T>` from `src/types.d.ts`.
* @param str the string to uncapitalize.
* @returns the uncapitalized string.
* @example uncapitalize('Hello world') // 'hello world'
*/
declare function uncapitalize<T extends string>(str: T): Uncapitalize<T>;
/**
* A strongly-typed version of `upperCase` that works in both runtime and type level.
* @param str the string to convert to upper case.
* @returns the uppercased string.
* @example upperCase('hello-world') // 'HELLO WORLD'
*/
declare function upperCase<T extends string>(str: T): Uppercase<DelimiterCase<T, ' '>>;
/**
* Shallowly transforms the keys of a Record to camelCase.
* T: the type of the Record to transform.
*/
type CamelKeys<T> = T extends [] ? T : {
[K in keyof T as CamelCase<Extract<K, string>>]: T[K];
};
/**
* A strongly typed function that shallowly transforms the keys of an object to camelCase. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example camelKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { fooBar: { 'fizz-buz': true } }
*/
declare function camelKeys<T>(obj: T): CamelKeys<T>;
/**
* Shallowly transforms the keys of a Record to CONSTANT_CASE.
* T: the type of the Record to transform.
*/
type ConstantKeys<T> = T extends [] ? T : {
[K in keyof T as ConstantCase<Extract<K, string>>]: T[K];
};
/**
* A strongly typed function that shallowly transforms the keys of an object to CONSTANT_CASE. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example constantKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { FOO_BAR: { 'fizz-buzz': true } }
*/
declare function constantKeys<T>(obj: T): ConstantKeys<T>;
/**
* Shallowly transforms the keys of a Record to a custom delimiter case.
* T: the type of the Record to transform.
* D: the delimiter to use.
*/
type DelimiterKeys<T, D extends string> = T extends [] ? T : {
[K in keyof T as DelimiterCase<Extract<K, string>, D>]: T[K];
};
/**
* A strongly typed function that shallowly transforms the keys of an object to a custom delimiter case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @param delimiter the delimiter to use.
* @returns the transformed object.
* @example delimiterKeys({ 'foo-bar': { 'fizz-buzz': true } }, '.') // { 'foo.bar': { 'fizz.buzz': true } }
*/
declare function delimiterKeys<T, D extends string>(obj: T, delimiter: D): DelimiterKeys<T, D>;
/**
* Shallowly transforms the keys of a Record to kebab-case.
* T: the type of the Record to transform.
*/
type KebabKeys<T> = T extends [] ? T : {
[K in keyof T as KebabCase<Extract<K, string>>]: T[K];
};
/**
* A strongly typed function that shallowly transforms the keys of an object to kebab-case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example kebabKeys({ fooBar: { fizzBuzz: true } }) // { 'foo-bar': { fizzBuzz: true } }
*/
declare function kebabKeys<T>(obj: T): KebabKeys<T>;
/**
* Shallowly transforms the keys of a Record to PascalCase.
* T: the type of the Record to transform.
*/
type PascalKeys<T> = T extends [] ? T : {
[K in keyof T as PascalCase<Extract<K, string>>]: T[K];
};
/**
* A strongly typed function that shallowly transforms the keys of an object to pascal case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example pascalKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { FooBar: { 'fizz-buzz': true } }
*/
declare function pascalKeys<T>(obj: T): PascalKeys<T>;
/**
* Shallowly transforms the keys of a Record to snake_case.
* T: the type of the Record to transform.
*/
type SnakeKeys<T> = T extends [] ? T : {
[K in keyof T as SnakeCase<Extract<K, string>>]: T[K];
};
/**
* A strongly typed function that shallowly the keys of an object to snake_case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example snakeKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { 'foo_bar': { 'fizz-buzz': true } }
*/
declare function snakeKeys<T>(obj: T): SnakeKeys<T>;
/**
* Shallowly transforms the keys of a Record with `replace`.
* T: the type of the Record to transform.
*/
type ReplaceKeys<T, lookup extends string | RegExp, replacement extends string = ''> = T extends [] ? T : {
[K in keyof T as Replace<Extract<K, string>, lookup, replacement>]: T[K];
};
/**
* A strongly typed function that shallowly transforms the keys of an object by running the `replace` method in every key. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @param lookup the lookup string to be replaced.
* @param replacement the replacement string.
* @returns the transformed object.
* @example replaceKeys({ 'foo-bar': { 'fizz-buzz': true } }, 'f', 'b') // { booBar: { 'fizz-buz': true } }
*/
declare function replaceKeys<T, S extends string | RegExp, R extends string = ''>(obj: T, lookup: S, replacement?: R): ReplaceKeys<T, S, R>;
/**
* Recursively transforms the keys of a Record to camelCase.
* T: the type of the Record to transform.
*/
type DeepCamelKeys<T> = T extends [any, ...any] ? {
[I in keyof T]: DeepCamelKeys<T[I]>;
} : T extends (infer V)[] ? DeepCamelKeys<V>[] : {
[K in keyof T as CamelCase<Extract<K, string>>]: DeepCamelKeys<T[K]>;
};
/**
* A strongly typed function that recursively transforms the keys of an object to camelCase. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example deepCamelKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { fooBar: { fizzBuzz: true } }
*/
declare function deepCamelKeys<T>(obj: T): DeepCamelKeys<T>;
/**
* Recursively transforms the keys of a Record to CONSTANT_CASE.
* T: the type of the Record to transform.
*/
type DeepConstantKeys<T> = T extends [any, ...any] ? {
[I in keyof T]: DeepConstantKeys<T[I]>;
} : T extends (infer V)[] ? DeepConstantKeys<V>[] : {
[K in keyof T as ConstantCase<Extract<K, string>>]: DeepConstantKeys<T[K]>;
};
/**
* A strongly typed function that recursively transforms the keys of an object to CONSTANT_CASE. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example deepConstantKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { FOO_BAR: { FIZZ_BUZZ: true } }
*/
declare function deepConstantKeys<T>(obj: T): DeepConstantKeys<T>;
/**
* Recursively transforms the keys of a Record to a custom delimiter case.
* T: the type of the Record to transform.
* D: the delimiter to use.
*/
type DeepDelimiterKeys<T, D extends string> = T extends [any, ...any] ? {
[I in keyof T]: DeepDelimiterKeys<T[I], D>;
} : T extends (infer V)[] ? DeepDelimiterKeys<V, D>[] : {
[K in keyof T as DelimiterCase<Extract<K, string>, D>]: DeepDelimiterKeys<T[K], D>;
};
/**
* A strongly typed function that recursively transforms the keys of an object to a custom delimiter case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @param delimiter the delimiter to use.
* @returns the transformed object.
* @example deepDelimiterKeys({ 'foo-bar': { 'fizz-buzz': true } }, '.') // { 'foo.bar': { 'fizz.buzz': true } }
*/
declare function deepDelimiterKeys<T, D extends string>(obj: T, delimiter: D): DeepDelimiterKeys<T, D>;
/**
* Recursively transforms the keys of a Record to kebab-case.
* T: the type of the Record to transform.
*/
type DeepKebabKeys<T> = T extends [any, ...any] ? {
[I in keyof T]: DeepKebabKeys<T[I]>;
} : T extends (infer V)[] ? DeepKebabKeys<V>[] : {
[K in keyof T as KebabCase<Extract<K, string>>]: DeepKebabKeys<T[K]>;
};
/**
* A strongly typed function that recursively transforms the keys of an object to kebab-case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example deepKebabKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { 'foo-bar': { 'fizz-buzz': true } }
*/
declare function deepKebabKeys<T>(obj: T): DeepKebabKeys<T>;
/**
* Recursively transforms the keys of a Record to PascalCase.
* T: the type of the Record to transform.
*/
type DeepPascalKeys<T> = T extends [any, ...any] ? {
[I in keyof T]: DeepPascalKeys<T[I]>;
} : T extends (infer V)[] ? DeepPascalKeys<V>[] : {
[K in keyof T as PascalCase<Extract<K, string>>]: DeepPascalKeys<T[K]>;
};
/**
* A strongly typed function that recursively transforms the keys of an object to pascal case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example deepPascalKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { FooBar: { FizzBuzz: true } }
*/
declare function deepPascalKeys<T>(obj: T): DeepPascalKeys<T>;
/**
* Recursively transforms the keys of a Record to snake_case.
* T: the type of the Record to transform.
*/
type DeepSnakeKeys<T> = T extends [any, ...any] ? {
[I in keyof T]: DeepSnakeKeys<T[I]>;
} : T extends (infer V)[] ? DeepSnakeKeys<V>[] : {
[K in keyof T as SnakeCase<Extract<K, string>>]: DeepSnakeKeys<T[K]>;
};
/**
* A strongly typed function that recursively transforms the keys of an object to snake_case. The transformation is done both at runtime and type level.
* @param obj the object to transform.
* @returns the transformed object.
* @example deepSnakeKeys({ 'foo-bar': { 'fizz-buzz': true } }) // { 'foo_bar': { 'fizz_buzz': true } }
*/
declare function deepSnakeKeys<T>(obj: T): DeepSnakeKeys<T>;
/**
* This function is used to transform the keys of an object deeply.
* It will only be transformed at runtime, so it's not type safe.
* @param obj the object to transform.
* @param transform the function to transform the keys from string to string.
* @returns the transformed object.
* @example deepTransformKeys({ 'foo-bar': { 'fizz-buzz': true } }, camelCase)
* // { fooBar: { fizzBuzz: true } }
*/
declare function deepTransformKeys<T>(obj: T, transform: (s: string) => string): T;
export { type CamelCase, type CamelKeys, type CharAt, type Concat, type ConstantCase, type ConstantKeys, type DeepCamelKeys, type DeepConstantKeys, type DeepDelimiterKeys, type DeepKebabKeys, type DeepPascalKeys, type DeepSnakeKeys, type DelimiterCase, type DelimiterKeys, type EndsWith, type Includes, type IsDigit, type IsLetter, type IsLower, type IsSeparator, type IsSpecial, type IsUpper, type Join, type KebabCase, type KebabKeys, type Length, type PadEnd, type PadStart, type PascalCase, type PascalKeys, type Repeat, type Replace, type ReplaceAll, type ReplaceKeys, type Reverse, type Slice, type SnakeCase, type SnakeKeys, type Split, type StartsWith, type TitleCase, type Trim, type TrimEnd, type TrimStart, type Truncate, type Words, camelCase, camelKeys, capitalize, charAt, concat, constantCase, constantKeys, deepCamelKeys, deepConstantKeys, deepDelimiterKeys, deepKebabKeys, deepPascalKeys, deepSnakeKeys, deepTransformKeys, delimiterCase, delimiterKeys, endsWith, includes, join, kebabCase, kebabKeys, length, lowerCase, padEnd, padStart, pascalCase, pascalKeys, repeat, replace, replaceAll, replaceKeys, reverse, slice, snakeCase, snakeKeys, split, startsWith, titleCase, toCamelCase, toConstantCase, toDelimiterCase, toKebabCase, toLowerCase, toPascalCase, toSnakeCase, toTitleCase, toUpperCase, trim, trimEnd, trimStart, truncate, uncapitalize, upperCase, words };
// src/native/char-at.ts
function charAt(str, index) {
return str.charAt(index);
}
// src/native/join.ts
function join(tuple, delimiter = "") {
return tuple.join(delimiter);
}
// src/native/concat.ts
function concat(...strings) {
return join(strings);
}
// src/native/ends-with.ts
function endsWith(text, search, position = text.length) {
return text.endsWith(search, position);
}
// src/native/includes.ts
function includes(text, search, position = 0) {
return text.includes(search, position);
}
// src/native/length.ts
function length(str) {
return str.length;
}
// src/native/pad-end.ts
function padEnd(str, length2 = 0, pad = " ") {
return str.padEnd(length2, pad);
}
// src/native/pad-start.ts
function padStart(str, length2 = 0, pad = " ") {
return str.padStart(length2, pad);
}
// src/native/repeat.ts
function repeat(str, times = 0) {
return str.repeat(times);
}
// src/native/replace.ts
function replace(sentence, lookup, replacement = "") {
return sentence.replace(lookup, replacement);
}
// src/native/replace-all.ts
function replaceAll(sentence, lookup, replacement = "") {
if (typeof sentence.replaceAll === "function") {
return sentence.replaceAll(lookup, replacement);
}
const regex = new RegExp(lookup, "g");
return sentence.replace(regex, replacement);
}
// src/native/slice.ts
function slice(str, start = 0, end = undefined) {
return str.slice(start, end);
}
// src/native/split.ts
function split(str, delimiter = "") {
return str.split(delimiter);
}
// src/native/starts-with.ts
function startsWith(text, search, position = 0) {
return text.startsWith(search, position);
}
// src/native/trim-start.ts
function trimStart(str) {
return str.trimStart();
}
// src/native/trim-end.ts
function trimEnd(str) {
return str.trimEnd();
}
// src/native/trim.ts
function trim(str) {
return str.trim();
}
// src/native/to-lower-case.ts
function toLowerCase(str) {
return str.toLowerCase();
}
// src/native/to-upper-case.ts
function toUpperCase(str) {
return str.toUpperCase();
}
// src/utils/reverse.ts
function reverse(str) {
return str.split("").reverse().join("");
}
// src/utils/truncate.ts
function truncate(sentence, length2, omission = "...") {
if (length2 < 0) return omission;
if (sentence.length <= length2) return sentence;
return join([
sentence.slice(0, length2 - omission.length),
omission
]);
}
// src/utils/characters/separators.ts
var UNESCAPED_SEPARATORS = [
"[",
"]",
"{",
"}",
"(",
")",
"|",
"/",
"-",
"\\"
];
var SEPARATORS = [...UNESCAPED_SEPARATORS, " ", "_", "."];
function escapeChar(char) {
return UNESCAPED_SEPARATORS.includes(char) ? `\\${char}` : char;
}
var SEPARATOR_REGEX = new RegExp(
`[${SEPARATORS.map(escapeChar).join("")}]`,
"g"
);
// src/utils/words.ts
function words(sentence) {
return sentence.replace(SEPARATOR_REGEX, " ").replace(/([a-zA-Z])([0-9])/g, "$1 $2").replace(/([0-9])([a-zA-Z])/g, "$1 $2").replace(/([a-zA-Z0-9_\-./])([^a-zA-Z0-9_\-./'])/g, "$1 $2").replace(/([^a-zA-Z0-9_\-./'])([a-zA-Z0-9_\-./])/g, "$1 $2").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z])([A-Z][a-z])/g, "$1 $2").trim().split(/\s+/g);
}
// src/utils/word-case/capitalize.ts
function capitalize(str) {
return join([
toUpperCase(charAt(str, 0) ?? ""),
slice(str, 1)
]);
}
// src/internal/internals.ts
function typeOf(t) {
return Object.prototype.toString.call(t).replace(/^\[object (.+)\]$/, "$1").toLowerCase();
}
function pascalCaseAll(words2) {
return words2.map((v) => capitalize(toLowerCase(v)));
}
// src/utils/characters/apostrophe.ts
function removeApostrophe(str) {
return replaceAll(str, "'", "");
}
// src/utils/word-case/pascal-case.ts
function pascalCase(str) {
return join(pascalCaseAll(words(removeApostrophe(str))));
}
var toPascalCase = pascalCase;
// src/utils/word-case/uncapitalize.ts
function uncapitalize(str) {
return join([
toLowerCase(charAt(str, 0) ?? ""),
slice(str, 1)
]);
}
// src/utils/word-case/camel-case.ts
function camelCase(str) {
return uncapitalize(pascalCase(removeApostrophe(str)));
}
var toCamelCase = camelCase;
// src/utils/word-case/delimiter-case.ts
function delimiterCase(str, delimiter) {
return join(words(removeApostrophe(str)), delimiter);
}
var toDelimiterCase = delimiterCase;
// src/utils/word-case/constant-case.ts
function constantCase(str) {
return toUpperCase(delimiterCase(removeApostrophe(str), "_"));
}
var toConstantCase = constantCase;
// src/utils/word-case/kebab-case.ts
function kebabCase(str) {
return toLowerCase(delimiterCase(removeApostrophe(str), "-"));
}
var toKebabCase = kebabCase;
// src/utils/word-case/snake-case.ts
function snakeCase(str) {
return toLowerCase(delimiterCase(removeApostrophe(str), "_"));
}
var toSnakeCase = snakeCase;
// src/utils/word-case/title-case.ts
function titleCase(str) {
return delimiterCase(pascalCase(str), " ");
}
var toTitleCase = titleCase;
// src/utils/word-case/lower-case.ts
function lowerCase(str) {
return toLowerCase(delimiterCase(str, " "));
}
// src/utils/word-case/upper-case.ts
function upperCase(str) {
return toUpperCase(delimiterCase(str, " "));
}
// src/utils/object-keys/transform-keys.ts
function transformKeys(obj, transform) {
if (typeOf(obj) !== "object") return obj;
const res = {};
for (const key in obj) {
res[transform(key)] = obj[key];
}
return res;
}
// src/utils/object-keys/camel-keys.ts
function camelKeys(obj) {
return transformKeys(obj, camelCase);
}
// src/utils/object-keys/constant-keys.ts
function constantKeys(obj) {
return transformKeys(obj, constantCase);
}
// src/utils/object-keys/delimiter-keys.ts
function delimiterKeys(obj, delimiter) {
return transformKeys(obj, (str) => delimiterCase(str, delimiter));
}
// src/utils/object-keys/kebab-keys.ts
function kebabKeys(obj) {
return transformKeys(obj, kebabCase);
}
// src/utils/object-keys/pascal-keys.ts
function pascalKeys(obj) {
return transformKeys(obj, pascalCase);
}
// src/utils/object-keys/snake-keys.ts
function snakeKeys(obj) {
return transformKeys(obj, snakeCase);
}
// src/utils/object-keys/replace-keys.ts
function replaceKeys(obj, lookup, replacement = "") {
return transformKeys(obj, (s) => replace(s, lookup, replacement));
}
// src/utils/object-keys/deep-transform-keys.ts
function deepTransformKeys(obj, transform) {
if (!["object", "array"].includes(typeOf(obj))) return obj;
if (Array.isArray(obj)) {
return obj.map((x) => deepTransformKeys(x, transform));
}
const res = {};
for (const key in obj) {
res[transform(key)] = deepTransformKeys(obj[key], transform);
}
return res;
}
// src/utils/object-keys/deep-camel-keys.ts
function deepCamelKeys(obj) {
return deepTransformKeys(obj, camelCase);
}
// src/utils/object-keys/deep-constant-keys.ts
function deepConstantKeys(obj) {
return deepTransformKeys(obj, constantCase);
}
// src/utils/object-keys/deep-delimiter-keys.ts
function deepDelimiterKeys(obj, delimiter) {
return deepTransformKeys(obj, (str) => delimiterCase(str, delimiter));
}
// src/utils/object-keys/deep-kebab-keys.ts
function deepKebabKeys(obj) {
return deepTransformKeys(obj, kebabCase);
}
// src/utils/object-keys/deep-pascal-keys.ts
function deepPascalKeys(obj) {
return deepTransformKeys(obj, pascalCase);
}
// src/utils/object-keys/deep-snake-keys.ts
function deepSnakeKeys(obj) {
return deepTransformKeys(obj, snakeCase);
}
export { camelCase, camelKeys, capitalize, charAt, concat, constantCase, constantKeys, deepCamelKeys, deepConstantKeys, deepDelimiterKeys, deepKebabKeys, deepPascalKeys, deepSnakeKeys, deepTransformKeys, delimiterCase, delimiterKeys, endsWith, includes, join, kebabCase, kebabKeys, length, lowerCase, padEnd, padStart, pascalCase, pascalKeys, repeat, replace, replaceAll, replaceKeys, reverse, slice, snakeCase, snakeKeys, split, startsWith, titleCase, toCamelCase, toConstantCase, toDelimiterCase, toKebabCase, toLowerCase, toPascalCase, toSnakeCase, toTitleCase, toUpperCase, trim, trimEnd, trimStart, truncate, uncapitalize, upperCase, words };