String
The String module provides curried, pipe-friendly functions for working with strings. Every function is pure — the original string is never modified.
import * as Str from "@oofp/core/string";Manipulation
Section titled “Manipulation”trim / trimStart / trimEnd
Section titled “trim / trimStart / trimEnd”Remove whitespace from both sides, the start, or the end.
import { pipe } from "@oofp/core/pipe";import * as Str from "@oofp/core/string";
pipe(" hello ", Str.trim); // "hello"pipe(" hello ", Str.trimStart); // "hello "pipe(" hello ", Str.trimEnd); // " hello"padStart / padEnd
Section titled “padStart / padEnd”Pads a string to a target length from the start or end.
pipe("42", Str.padStart(5, "0")); // "00042"pipe("42", Str.padEnd(5, ".")); // "42..."pipe("hello", Str.padStart(5)); // "hello" — already long enoughrepeat
Section titled “repeat”Repeats a string a given number of times.
pipe("ha", Str.repeat(3)); // "hahaha"pipe("-", Str.repeat(10)); // "----------"replace / replaceAll
Section titled “replace / replaceAll”Replace the first occurrence, or all occurrences, of a pattern.
pipe("hello world", Str.replace("world", "there"));// "hello there"
pipe("aabaa", Str.replaceAll("a", "x"));// "xxbxx"
// Also works with RegExp:pipe("hello 123 world 456", Str.replaceAll(/\d+/g, "#"));// "hello # world #"slice / substring
Section titled “slice / substring”Extract portions of a string by index.
pipe("hello world", Str.slice(0, 5)); // "hello"pipe("hello world", Str.substring(6)); // "world"pipe("hello world", Str.slice(-5)); // "world"Splits a string into an array by a separator.
pipe("a,b,c", Str.split(","));// ["a", "b", "c"]
pipe("hello world", Str.split(" "));// ["hello", "world"]
// With limit:pipe("a-b-c-d", Str.split("-", 2));// ["a", "b"]concat
Section titled “concat”Concatenates additional strings onto the piped string.
pipe("hello", Str.concat(" ", "world", "!"));// "hello world!"reverse
Section titled “reverse”Reverses a string.
pipe("hello", Str.reverse); // "olleh"pipe("abcde", Str.reverse); // "edcba"truncate
Section titled “truncate”Truncates a string to a maximum length, appending a suffix (default "...").
pipe("This is a long string", Str.truncate(10));// "This is..."
pipe("This is a long string", Str.truncate(10, "~"));// "This is a~"
pipe("Short", Str.truncate(10));// "Short" — not truncatedinsert
Section titled “insert”Inserts a substring at a given index.
pipe("hello", Str.insert(2, "XX"));// "heXXllo"remove
Section titled “remove”Removes characters from a given start position and length.
pipe("hello", Str.remove(1, 2));// "hlo"takeLeft / takeRight
Section titled “takeLeft / takeRight”Takes characters from the left or right.
pipe("hello", Str.takeLeft(3)); // "hel"pipe("hello", Str.takeRight(3)); // "llo"dropLeft / dropRight
Section titled “dropLeft / dropRight”Drops characters from the left or right.
pipe("hello", Str.dropLeft(2)); // "llo"pipe("hello", Str.dropRight(2)); // "hel"Case Conversion
Section titled “Case Conversion”toUpperCase / toLowerCase
Section titled “toUpperCase / toLowerCase”pipe("Hello World", Str.toUpperCase); // "HELLO WORLD"pipe("Hello World", Str.toLowerCase); // "hello world"capitalize / uncapitalize
Section titled “capitalize / uncapitalize”Capitalize or uncapitalize the first character.
pipe("hello world", Str.capitalize); // "Hello world"pipe("Hello World", Str.uncapitalize); // "hello World"camelCase
Section titled “camelCase”Converts to camelCase from any separator (spaces, hyphens, underscores).
pipe("hello world", Str.camelCase); // "helloWorld"pipe("hello-world", Str.camelCase); // "helloWorld"pipe("hello_world", Str.camelCase); // "helloWorld"pipe("HelloWorld", Str.camelCase); // "helloWorld"pascalCase
Section titled “pascalCase”Converts to PascalCase.
pipe("hello world", Str.pascalCase); // "HelloWorld"pipe("hello-world", Str.pascalCase); // "HelloWorld"kebabCase
Section titled “kebabCase”Converts to kebab-case.
pipe("HelloWorld", Str.kebabCase); // "hello-world"pipe("hello world", Str.kebabCase); // "hello-world"pipe("hello_world", Str.kebabCase); // "hello-world"snakeCase
Section titled “snakeCase”Converts to snake_case.
pipe("HelloWorld", Str.snakeCase); // "hello_world"pipe("hello world", Str.snakeCase); // "hello_world"pipe("hello-world", Str.snakeCase); // "hello_world"slugify
Section titled “slugify”Creates a URL-friendly slug: removes accents, lowercases, replaces non-alphanumeric characters with hyphens.
pipe("Hello, World! Cafe", Str.slugify);// "hello-world-cafe"
pipe("Functional Programming 101", Str.slugify);// "functional-programming-101"Validation
Section titled “Validation”startsWith / endsWith / includes
Section titled “startsWith / endsWith / includes”Check if a string starts with, ends with, or contains a substring.
pipe("hello world", Str.startsWith("hello")); // truepipe("hello world", Str.endsWith("world")); // truepipe("hello world", Str.includes("lo wo")); // truematch / matchAll
Section titled “match / matchAll”Pattern matching with regular expressions.
pipe("hello 123", Str.match(/\d+/));// RegExpMatchArray: ["123"]
pipe("a1 b2 c3", Str.matchAll(/[a-z]\d/g));// IterableIterator of matchesisEmpty / isBlank
Section titled “isEmpty / isBlank”Str.isEmpty(""); // trueStr.isEmpty("hello"); // false
Str.isBlank(""); // trueStr.isBlank(" "); // trueStr.isBlank("hello"); // falseisAlpha / isAlphaNumeric / isNumeric
Section titled “isAlpha / isAlphaNumeric / isNumeric”Str.isAlpha("hello"); // trueStr.isAlpha("hello123"); // false
Str.isAlphaNumeric("hello123"); // trueStr.isAlphaNumeric("hello-123"); // false
Str.isNumeric("12345"); // trueStr.isNumeric("123abc"); // falseisEmail
Section titled “isEmail”Basic email format validation.
Str.isEmail("user@example.com"); // trueStr.isEmail("invalid-email"); // falseValidates a URL using the URL constructor.
Str.isUrl("https://example.com"); // trueStr.isUrl("not-a-url"); // falseescapeHtml / unescapeHtml
Section titled “escapeHtml / unescapeHtml”Escape and unescape HTML special characters (&, <, >, ", ').
pipe("<div>Hello & goodbye</div>", Str.escapeHtml);// "<div>Hello & goodbye</div>"
pipe("<div>Hello & goodbye</div>", Str.unescapeHtml);// "<div>Hello & goodbye</div>"Character & Index Operations
Section titled “Character & Index Operations”length
Section titled “length”Returns the length of a string.
Str.length("hello"); // 5Str.length(""); // 0charAt / charCodeAt
Section titled “charAt / charCodeAt”Access individual characters or their codes.
pipe("hello", Str.charAt(1)); // "e"pipe("hello", Str.charCodeAt(0)); // 104indexOf / lastIndexOf
Section titled “indexOf / lastIndexOf”Find the position of a substring.
pipe("hello world", Str.indexOf("o")); // 4pipe("hello world", Str.lastIndexOf("o")); // 7pipe("hello world", Str.indexOf("xyz")); // -1Splitting & Joining
Section titled “Splitting & Joining”Extracts words (sequences of word characters) from a string.
Str.words("hello world test");// ["hello", "world", "test"]
Str.words("camelCase is-fun");// ["camelCase", "is", "fun"]Splits a string by line breaks (\n, \r, \r\n).
Str.lines("line1\nline2\rline3\r\nline4");// ["line1", "line2", "line3", "line4"]unlines
Section titled “unlines”Joins an array of strings with newline characters.
Str.unlines(["line1", "line2", "line3"]);// "line1\nline2\nline3"Functional Operations
Section titled “Functional Operations”Transforms each character of a string.
pipe("hello", Str.map((char) => char.toUpperCase()));// "HELLO"Executes a side effect on the string without modifying it.
pipe( "hello", Str.tap((s) => console.log(`Processing: ${s}`)), Str.toUpperCase,);// Logs: "Processing: hello"// Result: "HELLO"filter
Section titled “filter”Keeps only characters that satisfy a predicate.
pipe("hello123", Str.filter((c) => Str.isAlpha(c)));// "hello"
pipe("h-e-l-l-o", Str.filter((c) => c !== "-"));// "hello"Returns the first character that satisfies a predicate, or undefined.
pipe("hello", Str.find((c) => c === "l")); // "l"pipe("hello", Str.find((c) => c === "z")); // undefinedevery / some
Section titled “every / some”Check if all or any characters satisfy a predicate.
pipe("aaa", Str.every((c) => c === "a")); // truepipe("abc", Str.every((c) => c === "a")); // false
pipe("abc", Str.some((c) => c === "b")); // truepipe("abc", Str.some((c) => c === "z")); // falseComparison
Section titled “Comparison”equals / equalsIgnoreCase
Section titled “equals / equalsIgnoreCase”Str.equals("hello")("hello"); // trueStr.equals("hello")("Hello"); // false
Str.equalsIgnoreCase("hello")("Hello"); // trueStr.equalsIgnoreCase("hello")("world"); // falseOther Utilities
Section titled “Other Utilities”Counts occurrences of a substring.
pipe("hello world hello", Str.count("hello")); // 2pipe("aaa", Str.count("aa")); // 1removeAccents
Section titled “removeAccents”Removes diacritical marks (accents) from characters.
Str.removeAccents("cafe"); // "cafe"Str.removeAccents("resume"); // "resume"search
Section titled “search”Returns the index of the first match for a regex, or -1.
pipe("hello 123", Str.search(/\d+/)); // 6pipe("hello world", Str.search(/\d+/)); // -1ellipsis
Section titled “ellipsis”Shortcut for truncate with the "..." suffix.
pipe("This is a long string", Str.ellipsis(10));// "This is..."Practical Examples
Section titled “Practical Examples”Input sanitization pipeline
Section titled “Input sanitization pipeline”import { pipe } from "@oofp/core/pipe";import * as Str from "@oofp/core/string";
const sanitizeInput = (input: string) => pipe( input, Str.trim, Str.replaceAll(/\s+/g, " "), Str.escapeHtml, Str.truncate(200), );
sanitizeInput(" <script>alert('xss')</script> Hello World ");// "<script>alert('xss')</script> Hello World"Generating URL slugs
Section titled “Generating URL slugs”import { pipe } from "@oofp/core/pipe";import * as Str from "@oofp/core/string";
const createSlug = (title: string) => pipe(title, Str.slugify);
createSlug("Functional Programming in TypeScript!");// "functional-programming-in-typescript"CSV parsing
Section titled “CSV parsing”import { pipe } from "@oofp/core/pipe";import * as Str from "@oofp/core/string";import * as L from "@oofp/core/list";
const parseCSV = (csv: string) => pipe( csv, Str.lines, L.map(Str.split(",")), L.map(L.map(Str.trim)), );
parseCSV("name, age\nAlice, 30\nBob, 25");// [["name", "age"], ["Alice", "30"], ["Bob", "25"]]Case conversion pipeline
Section titled “Case conversion pipeline”import { pipe } from "@oofp/core/pipe";import * as Str from "@oofp/core/string";
// Database column → TypeScript propertyconst toProperty = (column: string) => pipe(column, Str.camelCase);
toProperty("user_name"); // "userName"toProperty("created_at"); // "createdAt"
// TypeScript property → Database columnconst toColumn = (prop: string) => pipe(prop, Str.snakeCase);
toColumn("userName"); // "user_name"toColumn("createdAt"); // "created_at"Validation with pipe
Section titled “Validation with pipe”import { pipe } from "@oofp/core/pipe";import * as Str from "@oofp/core/string";import * as E from "@oofp/core/either";
const validateUsername = (input: string) => pipe( input, Str.trim, (s) => Str.isEmpty(s) ? E.left("Username is required") : E.right(s), E.chain((s) => Str.isAlphaNumeric(s) ? E.right(s) : E.left("Username must be alphanumeric"), ), E.chain((s) => Str.length(s) >= 3 ? E.right(s) : E.left("Username must be at least 3 characters"), ), );
validateUsername("alice123"); // Right("alice123")validateUsername("al"); // Left("Username must be at least 3 characters")validateUsername("al!ce"); // Left("Username must be alphanumeric")