UNPKG

feats

Version:

A comprehensive TypeScript utility library featuring fluent text building, type-safe switching, duration utilities, React hooks, and extended array/object prototypes for modern JavaScript development.

392 lines (388 loc) 11.3 kB
'use strict'; /** * The underlying class for the `text()` factory function. 🧱 * It provides a fluent API for building strings step-by-step. * * It's recommended to use the `text()` factory function to create new instances. */ class TextBuilder { constructor() { this.text = ""; } /** * Returns the final built string. 🚀 * This is the recommended way to get the result. * * @returns The final string. * * @example * ```ts * const builder = text(); * const result = builder.add("Done building!").done(); * // result will be "Done building!" * ``` */ done() { return this.text; } /** * An alias for the `done()` method. 📝 * It returns the current state of the built string. * * @returns The final string. * * @example * ```ts * const builder = text().add("Here's the string.").toString(); * // result will be "Here's the string." * ``` */ toString() { return this.text; } /** * Adds one or more new lines to the string. ✍️ * * @param count The number of new lines to add. Defaults to 1. * @returns The `TextBuilder` instance for chaining. * * @example * ```ts * const myString = text().add("First line.").newLine(2).add("Third line.").done(); * // myString will be "First line.\n\nThird line." * ``` */ newLine(count = 1) { this.text += "\n".repeat(count); return this; } /** * Adds a string to the builder. ➕ * * @param text The string to add. * @returns The `TextBuilder` instance for chaining. * * @example * ```ts * const myString = text().add("Hello").add("World").done(); * // myString will be "HelloWorld" * ``` */ add(text) { this.text += text; return this; } /** * Adds a single space to the string. ➡️ * * @returns The `TextBuilder` instance for chaining. * * @example * ```ts * const myString = text().add("Hello").space().add("World").done(); * // myString will be "Hello World" * ``` */ space() { this.text += " "; return this; } /** * Adds a string followed by a new line. ➡️✍️ * This is a convenient shortcut for `add(text).newLine()`. * * @param text The string to add before the new line. * @returns The `TextBuilder` instance for chaining. * * @example * ```ts * const myString = text().line("Line 1").line("Line 2").done(); * // myString will be "Line 1\nLine 2\n" * ``` */ line(text) { this.text += text; return this.newLine(); } /** * Conditionally adds a string or executes a function. 🚦 * This method has two overloads for flexibility: one with an object parameter and one with positional arguments. * * @param params An object containing the `condition`, `then` value, and an optional `else` value. * @param condition The boolean condition to check. * @param then The string or function to execute if the condition is `true`. * @param otherwise An optional string or function to execute if the condition is `false`. * @returns The `TextBuilder` instance for chaining. * * @example * // Using the object syntax * ```ts * const userIsAdmin = true; * const myString = text() * .if({ * condition: userIsAdmin, * then: (b) => b.add("Admin Panel").newLine(), * else: "Guest Access" * }) * .done(); * // myString will be "Admin Panel\n" * ``` * * @example * // Using the positional argument syntax * ```ts * const isLoggedIn = false; * const myString = text() * .if( * isLoggedIn, * "Welcome back!", * (b) => b.add("Please log in.") * ) * .done(); * // myString will be "Please log in." * ``` */ if(condition, then, otherwise) { let cond; let onThen; let onElse; if (typeof condition === "object") { cond = condition.condition; onThen = condition.then; onElse = condition.else; } else { cond = condition; onThen = then; onElse = otherwise; } if (cond) { typeof onThen === "function" ? onThen(this) : this.add(onThen); } else if (onElse !== undefined) { typeof onElse === "function" ? onElse(this) : this.add(onElse); } return this; } /** * Trims whitespace from the beginning and end of each line in the string. ✂️ * * @returns The `TextBuilder` instance for chaining. * * @example * ```ts * const myString = text().add(" Hello ").newLine().add(" World ").trimLines().done(); * // The final string will be "Hello\nWorld" * ``` */ trimLines() { this.text = this.text .split("\n") .map((line) => line.trim()) .join("\n"); return this; } /** * Gets an array of the current string's lines. 📚 * * @returns An array of strings, where each element is a line. * * @example * ```ts * const builder = text().line("First").line("Second"); * const myLines = builder.lines; * // myLines is ["First", "Second", ""] * ``` */ get lines() { return this.text.split("\n"); } /** * Checks if the built string is empty or contains only whitespace. 🕵️ * * @returns `true` if the trimmed string is empty, otherwise `false`. * * @example * ```ts * const builder1 = text(); * console.log(builder1.isEmpty); // true * * const builder2 = text().add("Hello"); * console.log(builder2.isEmpty); // false * ``` */ get isEmpty() { return this.text.trim() === ""; } /** * Gets the total length of the built string. 📏 * * @returns The number of characters in the string. * * @example * ```ts * const builder = text().add("test"); * console.log(builder.length); // 4 * ``` */ get length() { return this.text.length; } } /** * A factory function to create a new `TextBuilder` instance. 🏭 * This is the preferred way to start building a new string, providing a clean, fluent API. * * @returns A new `TextBuilder` instance. * * @example * // A basic example of building a string * ```ts * const myString = text() * .add("Hello") * .space() * .add("World!") * .newLine() * .add("This is a new line.") * .done(); * * // myString is now "Hello World!\nThis is a new line." * ``` * * @example * // Using conditional logic * ```ts * const user = { name: "Alice", isAdmin: true }; * * const welcomeMessage = text() * .add(`Welcome, ${user.name}!`) * .if(user.isAdmin, (builder) => { * builder.newLine().add("You have admin access."); * }) * .done(); * * // welcomeMessage is now "Welcome, Alice!\nYou have admin access." * ``` */ function text() { return new TextBuilder(); } /** * The underlying class for the `switcher` factory function. 🛠️ * It provides a powerful, type-safe, and fluent API for handling conditional logic, acting as a robust alternative to traditional switch statements. * * It's recommended to use the `switcher()` factory function to create new instances. */ class Switcher { /** * Constructs a new `Switcher` instance. * * You should typically use the `switcher()` factory function instead of calling this constructor directly. * * @param value The value to be matched against. * @param options Optional configuration for the switcher, like a custom `equalityCheck`. */ constructor(value, options = {}) { this.returnedValue = undefined; const { equalityCheck } = options; this.value = value; this.equalityCheck = equalityCheck !== null && equalityCheck !== void 0 ? equalityCheck : ((v1, v2) => v1 === v2); } case(condition, then) { if (this.returnedValue === undefined) { const conditions = Array.isArray(condition) ? condition : [condition]; for (const cond of conditions) { if (this.equalityCheck(this.value, cond)) { this.returnedValue = then; break; } } } return this; } /** * Finalizes the switcher and returns the result. 🎉 * * If a `.case()` matched, it returns the corresponding value. * If no `.case()` matched and no `.default()` was called, it returns `undefined`. * * @returns The matched value or `undefined`. The return type is inferred by the TypeScript compiler. * * @example * ```ts * const status = "error"; * const message = switcher(status) * .case("success", "Operation successful") * .case("pending", "Operation is pending") * .done(); * * // message is now undefined * ``` */ done() { return this.returnedValue; } /** * Specifies a default value to be returned if no `.case()` condition matches. 🎁 * This method should be called at the end of your `Switcher` chain. * * @param value The default value to return. * @returns The value from the first matching `.case()` or the provided `default` value. * * @example * ```ts * const role = "guest"; * const accessLevel = switcher(role) * .case("admin", "full") * .case("user", "limited") * .default("read-only"); * * // accessLevel is now "read-only" * ``` */ default(value) { var _a; (_a = this.returnedValue) !== null && _a !== void 0 ? _a : (this.returnedValue = value); return this.returnedValue; } } /** * A powerful factory function that creates a type-safe `Switcher` instance. 🚀 * This is the recommended way to start a new switcher chain, providing a fluent, readable replacement for traditional `switch` statements. * * @param args The arguments to pass to the `Switcher` constructor. * @returns A new `Switcher` instance. * * @example * // Basic usage with strings * ```ts * const day = "Monday"; * const greeting = switcher(day) * .case("Monday", "Hello, Monday!") * .case("Tuesday", "Happy Tuesday!") * .default("Have a great day!"); * * // greeting will be "Hello, Monday!" * ``` * * @example * // Using a custom equality check for objects * ```ts * const user = { id: 1, name: "Alice" }; * const allUsers = [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }]; * * const selectedUser = switcher(user, { equalityCheck: (v1, v2) => v1.id === v2.id }) * .case(allUsers[0], "It's Alice") * .case(allUsers[1], "It's Bob") * .done(); * * // selectedUser will be "It's Alice" * ``` */ function switcher(...args) { return new Switcher(...args); } exports.Switcher = Switcher; exports.TextBuilder = TextBuilder; exports.switcher = switcher; exports.text = text; //# sourceMappingURL=internals-BSwTxaM2.js.map