@synstack/str 1.2.14 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -101,10 +101,11 @@ var split = (text, separator, limit) => {
101
101
  return text.split(separator, limit);
102
102
  };
103
103
  var addLineNumbers = (text, separator = ":") => {
104
- return text.split("\n").map((line, index) => `${index}${separator}${line}`).join("\n");
104
+ const lines = text.split(/\r?\n/);
105
+ return lines.map((line, index) => `${index}${separator}${line}`).join("\n");
105
106
  };
106
107
  var indentation = (text) => {
107
- return text.split("\n").reduce((acc, line) => {
108
+ return text.split(/\r?\n/).reduce((acc, line) => {
108
109
  if (line.trim() === "") return acc;
109
110
  const indentation2 = leadingSpacesCount(line);
110
111
  if (acc === null) return indentation2;
@@ -114,13 +115,15 @@ var indentation = (text) => {
114
115
  var indent = (text, size, char = " ") => {
115
116
  if (size === 0) return text;
116
117
  const indentStr = char.repeat(size);
117
- return text.split("\n").map((line) => indentStr + line).join("\n");
118
+ const lines = text.split(/\r?\n/);
119
+ return lines.map((line) => indentStr + line).join("\n");
118
120
  };
119
121
  var dedent = (text, size) => {
120
122
  const _size = size ?? indentation(text);
121
123
  if (_size === 0) return text;
122
124
  const regex = new RegExp(`^\\s{1,${_size}}`);
123
- return text.split("\n").map((line) => line.replace(regex, "")).join("\n");
125
+ const lines = text.split(/\r?\n/);
126
+ return lines.map((line) => line.replace(regex, "")).join("\n");
124
127
  };
125
128
  var chopEnd = (text, count) => {
126
129
  if (count === 0) return text;
@@ -145,10 +148,10 @@ var takeEnd = (text, count) => {
145
148
  return text.slice(-count);
146
149
  };
147
150
  var lastLine = (text) => {
148
- return text.split("\n").at(-1) ?? "";
151
+ return text.split(/\r?\n/).at(-1) ?? "";
149
152
  };
150
153
  var firstLine = (text) => {
151
- return text.split("\n").at(0) ?? "";
154
+ return text.split(/\r?\n/).at(0) ?? "";
152
155
  };
153
156
  var leadingSpacesCount = (text) => {
154
157
  return text.match(/^\s+/)?.at(0)?.length ?? 0;
@@ -183,7 +186,7 @@ var Str = class _Str extends import_pipe.Pipeable {
183
186
  */
184
187
  constructor(text) {
185
188
  super();
186
- this.text = text;
189
+ this.text = text.replace(/\r\n/g, "\n");
187
190
  }
188
191
  /**
189
192
  * Get the underlying string value
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/str.index.ts","../src/str.chainable.ts","../src/str.lib.ts"],"sourcesContent":["export {\n camelCase,\n capitalCase,\n constantCase,\n dotCase,\n kebabCase,\n noCase,\n pascalCase,\n pascalSnakeCase,\n pathCase,\n sentenceCase,\n snakeCase,\n trainCase,\n} from \"change-case\";\nexport { Str, str } from \"./str.chainable.ts\";\nexport * from \"./str.lib.ts\";\n","import { Pipeable } from \"@synstack/pipe\";\nimport * as changeCase from \"change-case\";\nimport { type Stringable } from \"../../shared/src/ts.utils.ts\";\nimport * as lib from \"./str.lib.ts\";\n\n/**\n * A chainable string manipulation class that extends Pipeable\n * Provides a fluent interface for string operations with full TypeScript support\n *\n * @example\n * ```typescript\n * import { str } from '@synstack/str'\n *\n * // Basic chaining\n * const result = str('Hello World')\n * .trim()\n * .split(' ')\n * .at(0)\n * .$\n *\n * // Advanced chaining with Pipeable methods\n * const modified = str('hello-world')\n * ._((s) => s.camelCase())\n * ._$((value) => value.toUpperCase())\n * .$\n * ```\n */\nexport class Str extends Pipeable<Str, string> {\n private readonly text: string;\n\n /**\n * Create a new Str instance\n * @param text - The input string to wrap\n * @example\n * ```typescript\n * const s = new Str('Hello World')\n * // or use the convenience function\n * const s = str('Hello World')\n * ```\n */\n public constructor(text: string) {\n super();\n this.text = text;\n }\n\n /**\n * Get the underlying string value\n * @returns The wrapped string value\n */\n public valueOf(): string {\n return this.text;\n }\n\n /**\n * Convert the Str instance to a string\n * @returns The wrapped string value\n */\n public toString() {\n return this.text;\n }\n\n /**\n * Get the current Str instance\n * @returns The current Str instance\n * @internal Used by Pipeable\n */\n public instanceOf(): Str {\n return this;\n }\n\n /**\n * Remove empty lines at the start of the text\n * @returns A new Str instance with empty lines removed from the start\n * @example\n * ```typescript\n * str('\\n\\n Hello').chopEmptyLinesStart().$ // ' Hello'\n * ```\n */\n public chopEmptyLinesStart() {\n return new Str(lib.chopEmptyLinesStart(this.text));\n }\n\n /**\n * Remove empty lines at the end of the text\n * @returns A new Str instance with empty lines removed from the end\n * @example\n * ```typescript\n * str('Hello\\n\\n').chopEmptyLinesEnd().$ // 'Hello'\n * ```\n */\n public chopEmptyLinesEnd() {\n return new Str(lib.chopEmptyLinesEnd(this.text));\n }\n\n /**\n * Remove whitespace from empty lines\n * @returns A new Str instance with whitespace removed from empty lines\n * @example\n * ```typescript\n * str('Hello\\n \\nWorld').trimEmptyLines().$ // 'Hello\\n\\nWorld'\n * ```\n */\n public trimEmptyLines() {\n return new Str(lib.trimEmptyLines(this.text));\n }\n\n /**\n * Remove trailing spaces from all lines\n * @returns A new Str instance with trailing spaces removed from all lines\n * @example\n * ```typescript\n * str('Hello \\nWorld ').trimLinesTrailingSpaces().$ // 'Hello\\nWorld'\n * ```\n */\n public trimLinesTrailingSpaces() {\n return new Str(lib.trimLinesTrailingSpaces(this.text));\n }\n\n /**\n * Remove leading and trailing whitespace\n * @returns A new Str instance with whitespace removed from both ends\n * @example\n * ```typescript\n * str(' Hello ').trim().$ // 'Hello'\n * ```\n */\n public trim() {\n return new Str(lib.trim(this.text));\n }\n\n /**\n * Remove leading whitespace\n * @returns A new Str instance with leading whitespace removed\n * @example\n * ```typescript\n * str(' Hello ').trimStart().$ // 'Hello '\n * ```\n */\n public trimStart() {\n return new Str(lib.trimStart(this.text));\n }\n\n /**\n * Remove trailing whitespace\n * @returns A new Str instance with trailing whitespace removed\n * @example\n * ```typescript\n * str(' Hello ').trimEnd().$ // ' Hello'\n * ```\n */\n public trimEnd() {\n return new Str(lib.trimEnd(this.text));\n }\n\n /**\n * Split the string into an array of Str instances\n * @param separator - String or RegExp to split on\n * @param limit - Maximum number of splits to perform\n * @returns Array of Str instances\n * @example\n * ```typescript\n * str('a,b,c').split(',') // [Str('a'), Str('b'), Str('c')]\n * str('a b c').split(' ', 2) // [Str('a'), Str('b')]\n * ```\n */\n public split(separator: string | RegExp, limit?: number) {\n return lib.split(this.text, separator, limit).map((v) => new Str(v));\n }\n\n /**\n * Add line numbers to each line\n * @param separator - String to separate line numbers from content\n * @returns A new Str instance with line numbers added\n * @example\n * ```typescript\n * str('A\\nB').addLineNumbers().$ // '0:A\\n1:B'\n * str('A\\nB').addLineNumbers(' -> ').$ // '0 -> A\\n1 -> B'\n * ```\n */\n public addLineNumbers(separator: string = \":\") {\n return new Str(lib.addLineNumbers(this.text, separator));\n }\n\n /**\n * Get the character at a specific index\n * @param index - Zero-based position in the string\n * @returns The character at the index, or undefined if out of bounds\n * @example\n * ```typescript\n * str('Hello').at(0) // 'H'\n * str('Hello').at(-1) // 'o'\n * ```\n */\n public at(index: number) {\n return this.text.at(index);\n }\n\n /**\n * Get the length of the string\n * @returns The number of characters in the string\n * @example\n * ```typescript\n * str('Hello').length() // 5\n * str('').length() // 0\n * ```\n */\n public length() {\n return this.text.length;\n }\n\n /**\n * Indent each line by a specified number of spaces\n * @param size - Number of spaces to add\n * @param char - Character to use for indentation\n * @returns A new Str instance with added indentation\n * @example\n * ```typescript\n * str('Hello\\nWorld').indent(2).$ // ' Hello\\n World'\n * str('A\\nB').indent(2, '-').$ // '--A\\n--B'\n * ```\n */\n public indent(size: number, char: string = \" \") {\n return new Str(lib.indent(this.text, size, char));\n }\n\n /**\n * Remove indentation from each line\n * @param indentation - Optional number of spaces to remove\n * @returns A new Str instance with indentation removed\n * @example\n * ```typescript\n * str(' Hello\\n World').dedent().$ // 'Hello\\n World'\n * str(' A\\n B').dedent(2).$ // ' A\\nB'\n * ```\n */\n public dedent(indentation?: number) {\n return new Str(lib.dedent(this.text, indentation));\n }\n\n /**\n * Remove characters from the start of the string\n * @param count - Number of characters to remove\n * @returns A new Str instance with characters removed from the start\n * @example\n * ```typescript\n * str('Hello').chopStart(2).$ // 'llo'\n * ```\n */\n public chopStart(count: number) {\n return new Str(lib.chopStart(this.text, count));\n }\n\n /**\n * Remove characters from the end of the string\n * @param count - Number of characters to remove\n * @returns A new Str instance with characters removed from the end\n * @example\n * ```typescript\n * str('Hello').chopEnd(2).$ // 'Hel'\n * ```\n */\n public chopEnd(count: number) {\n if (count === 0) return this;\n return new Str(lib.chopEnd(this.text, count));\n }\n\n /**\n * Limit consecutive newlines to a maximum count\n * @param maxRepeat - Maximum number of consecutive newlines to allow\n * @returns A new Str instance with limited consecutive newlines\n * @example\n * ```typescript\n * str('A\\n\\n\\nB').chopRepeatNewlines(1).$ // 'A\\nB'\n * str('A\\n\\n\\nB').chopRepeatNewlines(2).$ // 'A\\n\\nB'\n * ```\n */\n public chopRepeatNewlines(maxRepeat: number) {\n if (maxRepeat === 0) return this;\n return new Str(lib.chopRepeatNewlines(this.text, maxRepeat));\n }\n\n /**\n * Take characters from the start of the string\n * @param count - Number of characters to take\n * @returns A new Str instance with the first n characters\n * @example\n * ```typescript\n * str('Hello').takeStart(2).$ // 'He'\n * ```\n */\n public takeStart(count: number) {\n return new Str(lib.takeStart(this.text, count));\n }\n\n /**\n * Take characters from the end of the string\n * @param count - Number of characters to take\n * @returns A new Str instance with the last n characters\n * @example\n * ```typescript\n * str('Hello').takeEnd(2).$ // 'lo'\n * ```\n */\n public takeEnd(count: number) {\n return new Str(lib.takeEnd(this.text, count));\n }\n\n /**\n * Get the last line of the string\n * @returns A new Str instance containing the last line\n * @example\n * ```typescript\n * str('Hello\\nWorld').lastLine().$ // 'World'\n * ```\n */\n public lastLine() {\n return new Str(lib.lastLine(this.text));\n }\n\n /**\n * Get the first line of the string\n * @returns A new Str instance containing the first line\n * @example\n * ```typescript\n * str('Hello\\nWorld').firstLine().$ // 'Hello'\n * ```\n */\n public firstLine() {\n return new Str(lib.firstLine(this.text));\n }\n\n /**\n * Count leading space characters\n * @returns The number of leading space characters\n * @example\n * ```typescript\n * str(' Hello').leadingSpacesCount() // 2\n * str('Hello').leadingSpacesCount() // 0\n * ```\n */\n public leadingSpacesCount() {\n return lib.leadingSpacesCount(this.text);\n }\n\n /**\n * Get the minimum indentation level of non-empty lines\n * @returns The number of spaces in the minimum indentation\n * @example\n * ```typescript\n * str(' Hello\\n World').indentation() // 2\n * str('Hello\\n World').indentation() // 0\n * ```\n */\n public indentation() {\n return lib.indentation(this.text);\n }\n\n /**\n * Check if the string is empty or contains only whitespace\n * @returns True if empty or whitespace-only, false otherwise\n * @example\n * ```typescript\n * str('').isEmpty() // true\n * str(' \\n').isEmpty() // true\n * str('Hello').isEmpty() // false\n * ```\n */\n public isEmpty() {\n return lib.isEmpty(this.text);\n }\n\n /**\n * Replace the first occurrence of a substring or pattern\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the match with\n * @returns A new Str instance with the first match replaced\n * @example\n * ```typescript\n * str('Hello World').replace('o', '0').$ // 'Hell0 World'\n * str('abc abc').replace(/[a-z]/, 'X').$ // 'Xbc abc'\n * ```\n */\n public replace(searchValue: string | RegExp, replaceValue: string) {\n return new Str(lib.replace(this.text, searchValue, replaceValue));\n }\n\n /**\n * Replace all occurrences of a substring or pattern\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the matches with\n * @returns A new Str instance with all matches replaced\n * @example\n * ```typescript\n * str('Hello World').replaceAll('o', '0').$ // 'Hell0 W0rld'\n * str('abc abc').replaceAll(/[a-z]/g, 'X').$ // 'XXX XXX'\n * ```\n */\n public replaceAll(searchValue: string | RegExp, replaceValue: string) {\n return new Str(lib.replaceAll(this.text, searchValue, replaceValue));\n }\n\n /**\n * Convert string to camelCase\n * @returns A new Str instance in camelCase\n * @example\n * ```typescript\n * str('hello-world').camelCase().$ // 'helloWorld'\n * ```\n */\n public camelCase() {\n return new Str(changeCase.camelCase(this.text));\n }\n\n /**\n * Convert string to Capital Case\n * @returns A new Str instance in Capital Case\n * @example\n * ```typescript\n * str('hello-world').capitalCase().$ // 'Hello World'\n * ```\n */\n public capitalCase() {\n return new Str(changeCase.capitalCase(this.text));\n }\n\n /**\n * Convert string to CONSTANT_CASE\n * @returns A new Str instance in CONSTANT_CASE\n * @example\n * ```typescript\n * str('hello-world').constantCase().$ // 'HELLO_WORLD'\n * ```\n */\n public constantCase() {\n return new Str(changeCase.constantCase(this.text));\n }\n\n /**\n * Convert string to dot.case\n * @returns A new Str instance in dot.case\n * @example\n * ```typescript\n * str('hello-world').dotCase().$ // 'hello.world'\n * ```\n */\n public dotCase() {\n return new Str(changeCase.dotCase(this.text));\n }\n\n /**\n * Convert string to kebab-case\n * @returns A new Str instance in kebab-case\n * @example\n * ```typescript\n * str('helloWorld').kebabCase().$ // 'hello-world'\n * ```\n */\n public kebabCase() {\n return new Str(changeCase.kebabCase(this.text));\n }\n\n /**\n * Convert string to no case\n * @returns A new Str instance with no case\n * @example\n * ```typescript\n * str('helloWorld').noCase().$ // 'hello world'\n * ```\n */\n public noCase() {\n return new Str(changeCase.noCase(this.text));\n }\n\n /**\n * Convert string to PascalCase\n * @returns A new Str instance in PascalCase\n * @example\n * ```typescript\n * str('hello-world').pascalCase().$ // 'HelloWorld'\n * ```\n */\n public pascalCase() {\n return new Str(changeCase.pascalCase(this.text));\n }\n\n /**\n * Convert string to Pascal_Snake_Case\n * @returns A new Str instance in Pascal_Snake_Case\n * @example\n * ```typescript\n * str('hello-world').pascalSnakeCase().$ // 'Hello_World'\n * ```\n */\n public pascalSnakeCase() {\n return new Str(changeCase.pascalSnakeCase(this.text));\n }\n\n /**\n * Convert string to path/case\n * @returns A new Str instance in path/case\n * @example\n * ```typescript\n * str('hello-world').pathCase().$ // 'hello/world'\n * ```\n */\n public pathCase() {\n return new Str(changeCase.pathCase(this.text));\n }\n\n /**\n * Convert string to Sentence case\n * @returns A new Str instance in Sentence case\n * @example\n * ```typescript\n * str('hello-world').sentenceCase().$ // 'Hello world'\n * ```\n */\n public sentenceCase() {\n return new Str(changeCase.sentenceCase(this.text));\n }\n\n /**\n * Convert string to snake_case\n * @returns A new Str instance in snake_case\n * @example\n * ```typescript\n * str('helloWorld').snakeCase().$ // 'hello_world'\n * ```\n */\n public snakeCase() {\n return new Str(changeCase.snakeCase(this.text));\n }\n\n /**\n * Convert string to Train-Case\n * @returns A new Str instance in Train-Case\n * @example\n * ```typescript\n * str('hello-world').trainCase().$ // 'Hello-World'\n * ```\n */\n public trainCase() {\n return new Str(changeCase.trainCase(this.text));\n }\n\n /**\n * Get the underlying string value\n * @returns The wrapped string value\n * @example\n * ```typescript\n * str('hello').str // 'hello'\n * ```\n */\n public get str() {\n return this.toString();\n }\n}\n\n/**\n * Create a new Str instance from any stringable value\n * @param text - Any value that can be converted to a string\n * @returns A new Str instance wrapping the string value\n * @example\n * ```typescript\n * str('hello') // from string\n * str(123) // from number\n * str({ toString() }) // from object with toString\n * ```\n */\nexport const str = (text: Stringable) => {\n return new Str(text.toString());\n};\n","/**\n * Remove empty lines at the start of the text but leave whitespace on the first line with content\n * @param text - The input string to process\n * @returns The string with empty lines removed from the start\n * @example\n * ```typescript\n * chopEmptyLinesStart(\"\\n\\n \\n Hello\") // \" Hello\"\n * chopEmptyLinesStart(\" Hello\") // \" Hello\"\n * ```\n */\nexport const chopEmptyLinesStart = (text: string) => {\n return text.replace(/^(\\s*\\n)+/, \"\");\n};\n\n/**\n * Remove empty lines at the end of the text but leave whitespace on the last line with content\n * @param text - The input string to process\n * @returns The string with empty lines removed from the end\n * @example\n * ```typescript\n * chopEmptyLinesEnd(\"Hello\\n\\n \\n\") // \"Hello\"\n * chopEmptyLinesEnd(\"Hello \") // \"Hello \"\n * ```\n */\nexport const chopEmptyLinesEnd = (text: string) => {\n return text.replace(/(\\n\\s*)+$/, \"\");\n};\n\n/**\n * Remove all space characters in lines that contain no content\n * @param text - The input string to process\n * @returns The string with whitespace removed from empty lines\n * @example\n * ```typescript\n * trimEmptyLines(\"Hello\\n \\nWorld\") // \"Hello\\n\\nWorld\"\n * trimEmptyLines(\" \\n \\n \") // \"\\n\\n\"\n * ```\n */\nexport const trimEmptyLines = (text: string) => {\n return text.replace(/(^|\\n)\\s+(\\n|$)/g, \"$1$2\");\n};\n\n/**\n * Remove all space characters at the end of each line\n * @param text - The input string to process\n * @returns The string with trailing spaces removed from all lines\n * @example\n * ```typescript\n * trimLinesTrailingSpaces(\"Hello \\nWorld \") // \"Hello\\nWorld\"\n * trimLinesTrailingSpaces(\"Hello \") // \"Hello\"\n * ```\n */\nexport const trimLinesTrailingSpaces = (text: string) => {\n return text.replace(/ +(\\n|$)/g, \"$1\");\n};\n\n/**\n * Remove leading and trailing whitespace and line terminator characters\n * @param text - The input string to process\n * @returns The trimmed string\n * @example\n * ```typescript\n * trim(\" Hello World \") // \"Hello World\"\n * trim(\"\\n Hello \\n\") // \"Hello\"\n * ```\n */\nexport const trim = (text: string) => {\n return text.trim();\n};\n\n/**\n * Remove leading whitespace and line terminator characters\n * @param text - The input string to process\n * @returns The string with leading whitespace removed\n * @example\n * ```typescript\n * trimStart(\" Hello World \") // \"Hello World \"\n * trimStart(\"\\n Hello\") // \"Hello\"\n * ```\n */\nexport const trimStart = (text: string) => {\n return text.trimStart();\n};\n\n/**\n * Remove trailing whitespace and line terminator characters\n * @param text - The input string to process\n * @returns The string with trailing whitespace removed\n * @example\n * ```typescript\n * trimEnd(\" Hello World \") // \" Hello World\"\n * trimEnd(\"Hello \\n\") // \"Hello\"\n * ```\n */\nexport const trimEnd = (text: string) => {\n return text.trimEnd();\n};\n\n/**\n * Split a string into substrings using the specified separator\n * @param text - The input string to split\n * @param separator - The string or regular expression to use for splitting\n * @param limit - Optional limit on the number of splits to perform\n * @returns An array of substrings\n * @example\n * ```typescript\n * split(\"Hello World\", \" \") // [\"Hello\", \"World\"]\n * split(\"a,b,c\", \",\", 2) // [\"a\", \"b\"]\n * split(\"a.b-c\", /[.-]/) // [\"a\", \"b\", \"c\"]\n * ```\n */\nexport const split = (\n text: string,\n separator: string | RegExp,\n limit?: number,\n) => {\n return text.split(separator, limit);\n};\n\n/**\n * Add line numbers to each line in a string\n * @param text - The string to add line numbers to\n * @param separator - The separator between line number and content (defaults to \":\")\n * @returns The string with line numbers added\n * @example\n * ```typescript\n * addLineNumbers(\"Hello\\nWorld\") // \"0:Hello\\n1:World\"\n * addLineNumbers(\"A\\nB\\nC\", \" -> \") // \"0 -> A\\n1 -> B\\n2 -> C\"\n * ```\n */\nexport const addLineNumbers = (text: string, separator: string = \":\") => {\n return text\n .split(\"\\n\")\n .map((line, index) => `${index}${separator}${line}`)\n .join(\"\\n\");\n};\n\n/**\n * Calculate the minimum indentation level of non-empty lines in the string\n * @param text - The input string to analyze\n * @returns The number of spaces in the minimum indentation level, or 0 if no indentation found\n * @example\n * ```typescript\n * indentation(\" Hello\\n World\") // 2\n * indentation(\"Hello\\n World\") // 0\n * indentation(\" \\n Hello\") // 4\n * ```\n */\nexport const indentation = (text: string) => {\n return (\n text.split(\"\\n\").reduce((acc: number | null, line) => {\n if (line.trim() === \"\") return acc;\n const indentation = leadingSpacesCount(line);\n if (acc === null) return indentation;\n return Math.min(acc, indentation);\n }, null) ?? 0\n );\n};\n\n/**\n * Indent each line of the string by a specified number of spaces\n * @param text - The input string to indent\n * @param size - The number of spaces to add at the start of each line\n * @param char - The character to use for indentation (defaults to space)\n * @returns The indented string\n * @example\n * ```typescript\n * indent(\"Hello\\nWorld\", 2) // \" Hello\\n World\"\n * indent(\"A\\nB\", 3, \"-\") // \"---A\\n---B\"\n * ```\n */\nexport const indent = (text: string, size: number, char: string = \" \") => {\n if (size === 0) return text;\n\n const indentStr = char.repeat(size);\n return text\n .split(\"\\n\")\n .map((line) => indentStr + line)\n .join(\"\\n\");\n};\n\n/**\n * Remove indentation from each line of the string\n * @param text - The input string to dedent\n * @param size - Optional number of spaces to remove. If not provided, removes the minimum common indentation\n * @returns The dedented string\n * @example\n * ```typescript\n * dedent(\" Hello\\n World\") // \"Hello\\n World\"\n * dedent(\" A\\n B\", 2) // \" A\\nB\"\n * ```\n */\nexport const dedent = (text: string, size?: number) => {\n const _size = size ?? indentation(text);\n if (_size === 0) return text;\n const regex = new RegExp(`^\\\\s{1,${_size}}`);\n return text\n .split(\"\\n\")\n .map((line) => line.replace(regex, \"\"))\n .join(\"\\n\");\n};\n\n/**\n * Remove a specified number of characters from the end of the string\n * @param text - The input string to process\n * @param count - The number of characters to remove\n * @returns The string with characters removed from the end\n * @example\n * ```typescript\n * chopEnd(\"Hello World\", 6) // \"Hello\"\n * chopEnd(\"Hello\", 0) // \"Hello\"\n * ```\n */\nexport const chopEnd = (text: string, count: number) => {\n if (count === 0) return text;\n return text.slice(0, -count);\n};\n\n/**\n * Remove a specified number of characters from the start of the string\n * @param text - The input string to process\n * @param count - The number of characters to remove\n * @returns The string with characters removed from the start\n * @example\n * ```typescript\n * chopStart(\"Hello World\", 6) // \"World\"\n * chopStart(\"Hello\", 0) // \"Hello\"\n * ```\n */\nexport const chopStart = (text: string, count: number) => {\n if (count === 0) return text;\n return text.slice(count);\n};\n\n/**\n * Limit the number of consecutive newlines in the string\n * @param text - The input string to process\n * @param maxRepeat - The maximum number of consecutive newlines to allow\n * @returns The string with consecutive newlines limited\n * @example\n * ```typescript\n * chopRepeatNewlines(\"A\\n\\n\\n\\nB\", 2) // \"A\\n\\nB\"\n * chopRepeatNewlines(\"A\\n\\nB\", 1) // \"A\\nB\"\n * ```\n */\nexport const chopRepeatNewlines = (text: string, maxRepeat: number) => {\n if (maxRepeat === 0) return text;\n return text.replace(\n new RegExp(`\\n{${maxRepeat + 1},}`, \"g\"),\n \"\\n\".repeat(maxRepeat),\n );\n};\n\n/**\n * Extract a specified number of characters from the start of the string\n * @param text - The input string to process\n * @param count - The number of characters to take\n * @returns The extracted substring from the start\n * @example\n * ```typescript\n * takeStart(\"Hello World\", 5) // \"Hello\"\n * takeStart(\"Hi\", 5) // \"Hi\"\n * ```\n */\nexport const takeStart = (text: string, count: number) => {\n return text.slice(0, count);\n};\n\n/**\n * Extract a specified number of characters from the end of the string\n * @param text - The input string to process\n * @param count - The number of characters to take\n * @returns The extracted substring from the end\n * @example\n * ```typescript\n * takeEnd(\"Hello World\", 5) // \"World\"\n * takeEnd(\"Hi\", 5) // \"Hi\"\n * ```\n */\nexport const takeEnd = (text: string, count: number) => {\n return text.slice(-count);\n};\n\n/**\n * Get the last line of a multi-line string\n * @param text - The input string to process\n * @returns The last line of the string, or empty string if input is empty\n * @example\n * ```typescript\n * lastLine(\"Hello\\nWorld\") // \"World\"\n * lastLine(\"Hello\") // \"Hello\"\n * lastLine(\"\") // \"\"\n * ```\n */\nexport const lastLine = (text: string) => {\n return text.split(\"\\n\").at(-1) ?? \"\";\n};\n\n/**\n * Get the first line of a multi-line string\n * @param text - The input string to process\n * @returns The first line of the string, or empty string if input is empty\n * @example\n * ```typescript\n * firstLine(\"Hello\\nWorld\") // \"Hello\"\n * firstLine(\"Hello\") // \"Hello\"\n * firstLine(\"\") // \"\"\n * ```\n */\nexport const firstLine = (text: string) => {\n return text.split(\"\\n\").at(0) ?? \"\";\n};\n\n/**\n * Count the number of leading space characters in a string\n * @param text - The input string to analyze\n * @returns The number of leading space characters\n * @example\n * ```typescript\n * leadingSpacesCount(\" Hello\") // 2\n * leadingSpacesCount(\"Hello\") // 0\n * ```\n */\nexport const leadingSpacesCount = (text: string) => {\n return text.match(/^\\s+/)?.at(0)?.length ?? 0;\n};\n\n/**\n * Check if a string is empty or contains only whitespace\n * @param text - The input string to check\n * @returns True if the string is empty or contains only whitespace, false otherwise\n * @example\n * ```typescript\n * isEmpty(\"\") // true\n * isEmpty(\" \\n \") // true\n * isEmpty(\"Hello\") // false\n * ```\n */\nexport const isEmpty = (text: string) => {\n return text.trim() === \"\";\n};\n\n/**\n * Replace the first occurrence of a substring or pattern in the string\n * @param text - The input string to process\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the match with\n * @returns The string with the first match replaced\n * @example\n * ```typescript\n * replace(\"Hello World\", \"o\", \"0\") // \"Hell0 World\"\n * replace(\"abc abc\", /[a-z]/, \"X\") // \"Xbc abc\"\n * ```\n */\nexport const replace = (\n text: string,\n searchValue: string | RegExp,\n replaceValue: string,\n) => {\n return text.replace(searchValue, replaceValue);\n};\n\n/**\n * Replace all occurrences of a substring or pattern in the string\n * @param text - The input string to process\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the matches with\n * @returns The string with all matches replaced\n * @example\n * ```typescript\n * replaceAll(\"Hello World\", \"o\", \"0\") // \"Hell0 W0rld\"\n * replaceAll(\"abc abc\", /[a-z]/g, \"X\") // \"XXX XXX\"\n * ```\n */\nexport const replaceAll = (\n text: string,\n searchValue: string | RegExp,\n replaceValue: string,\n) => {\n if (typeof searchValue === \"string\") {\n return text.replaceAll(searchValue, replaceValue);\n }\n // Ensure the RegExp has the global flag\n const flags = searchValue.flags.includes(\"g\")\n ? searchValue.flags\n : searchValue.flags + \"g\";\n const globalRegex = new RegExp(searchValue.source, flags);\n return text.replace(globalRegex, replaceValue);\n};\n"],"mappings":"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","names":["indentation","indentation"]}
1
+ {"version":3,"sources":["../src/str.index.ts","../src/str.chainable.ts","../src/str.lib.ts"],"sourcesContent":["export {\n camelCase,\n capitalCase,\n constantCase,\n dotCase,\n kebabCase,\n noCase,\n pascalCase,\n pascalSnakeCase,\n pathCase,\n sentenceCase,\n snakeCase,\n trainCase,\n} from \"change-case\";\nexport { Str, str } from \"./str.chainable.ts\";\nexport * from \"./str.lib.ts\";\n","import { Pipeable } from \"@synstack/pipe\";\nimport * as changeCase from \"change-case\";\nimport { type Stringable } from \"../../shared/src/ts.utils.ts\";\nimport * as lib from \"./str.lib.ts\";\n\n/**\n * A chainable string manipulation class that extends Pipeable\n * Provides a fluent interface for string operations with full TypeScript support\n *\n * @example\n * ```typescript\n * import { str } from '@synstack/str'\n *\n * // Basic chaining\n * const result = str('Hello World')\n * .trim()\n * .split(' ')\n * .at(0)\n * .$\n *\n * // Advanced chaining with Pipeable methods\n * const modified = str('hello-world')\n * ._((s) => s.camelCase())\n * ._$((value) => value.toUpperCase())\n * .$\n * ```\n */\nexport class Str extends Pipeable<Str, string> {\n private readonly text: string;\n\n /**\n * Create a new Str instance\n * @param text - The input string to wrap\n * @example\n * ```typescript\n * const s = new Str('Hello World')\n * // or use the convenience function\n * const s = str('Hello World')\n * ```\n */\n public constructor(text: string) {\n super();\n this.text = text.replace(/\\r\\n/g, \"\\n\");\n }\n\n /**\n * Get the underlying string value\n * @returns The wrapped string value\n */\n public valueOf(): string {\n return this.text;\n }\n\n /**\n * Convert the Str instance to a string\n * @returns The wrapped string value\n */\n public toString() {\n return this.text;\n }\n\n /**\n * Get the current Str instance\n * @returns The current Str instance\n * @internal Used by Pipeable\n */\n public instanceOf(): Str {\n return this;\n }\n\n /**\n * Remove empty lines at the start of the text\n * @returns A new Str instance with empty lines removed from the start\n * @example\n * ```typescript\n * str('\\n\\n Hello').chopEmptyLinesStart().$ // ' Hello'\n * ```\n */\n public chopEmptyLinesStart() {\n return new Str(lib.chopEmptyLinesStart(this.text));\n }\n\n /**\n * Remove empty lines at the end of the text\n * @returns A new Str instance with empty lines removed from the end\n * @example\n * ```typescript\n * str('Hello\\n\\n').chopEmptyLinesEnd().$ // 'Hello'\n * ```\n */\n public chopEmptyLinesEnd() {\n return new Str(lib.chopEmptyLinesEnd(this.text));\n }\n\n /**\n * Remove whitespace from empty lines\n * @returns A new Str instance with whitespace removed from empty lines\n * @example\n * ```typescript\n * str('Hello\\n \\nWorld').trimEmptyLines().$ // 'Hello\\n\\nWorld'\n * ```\n */\n public trimEmptyLines() {\n return new Str(lib.trimEmptyLines(this.text));\n }\n\n /**\n * Remove trailing spaces from all lines\n * @returns A new Str instance with trailing spaces removed from all lines\n * @example\n * ```typescript\n * str('Hello \\nWorld ').trimLinesTrailingSpaces().$ // 'Hello\\nWorld'\n * ```\n */\n public trimLinesTrailingSpaces() {\n return new Str(lib.trimLinesTrailingSpaces(this.text));\n }\n\n /**\n * Remove leading and trailing whitespace\n * @returns A new Str instance with whitespace removed from both ends\n * @example\n * ```typescript\n * str(' Hello ').trim().$ // 'Hello'\n * ```\n */\n public trim() {\n return new Str(lib.trim(this.text));\n }\n\n /**\n * Remove leading whitespace\n * @returns A new Str instance with leading whitespace removed\n * @example\n * ```typescript\n * str(' Hello ').trimStart().$ // 'Hello '\n * ```\n */\n public trimStart() {\n return new Str(lib.trimStart(this.text));\n }\n\n /**\n * Remove trailing whitespace\n * @returns A new Str instance with trailing whitespace removed\n * @example\n * ```typescript\n * str(' Hello ').trimEnd().$ // ' Hello'\n * ```\n */\n public trimEnd() {\n return new Str(lib.trimEnd(this.text));\n }\n\n /**\n * Split the string into an array of Str instances\n * @param separator - String or RegExp to split on\n * @param limit - Maximum number of splits to perform\n * @returns Array of Str instances\n * @example\n * ```typescript\n * str('a,b,c').split(',') // [Str('a'), Str('b'), Str('c')]\n * str('a b c').split(' ', 2) // [Str('a'), Str('b')]\n * ```\n */\n public split(separator: string | RegExp, limit?: number) {\n return lib.split(this.text, separator, limit).map((v) => new Str(v));\n }\n\n /**\n * Add line numbers to each line\n * @param separator - String to separate line numbers from content\n * @returns A new Str instance with line numbers added\n * @example\n * ```typescript\n * str('A\\nB').addLineNumbers().$ // '0:A\\n1:B'\n * str('A\\nB').addLineNumbers(' -> ').$ // '0 -> A\\n1 -> B'\n * ```\n */\n public addLineNumbers(separator: string = \":\") {\n return new Str(lib.addLineNumbers(this.text, separator));\n }\n\n /**\n * Get the character at a specific index\n * @param index - Zero-based position in the string\n * @returns The character at the index, or undefined if out of bounds\n * @example\n * ```typescript\n * str('Hello').at(0) // 'H'\n * str('Hello').at(-1) // 'o'\n * ```\n */\n public at(index: number) {\n return this.text.at(index);\n }\n\n /**\n * Get the length of the string\n * @returns The number of characters in the string\n * @example\n * ```typescript\n * str('Hello').length() // 5\n * str('').length() // 0\n * ```\n */\n public length() {\n return this.text.length;\n }\n\n /**\n * Indent each line by a specified number of spaces\n * @param size - Number of spaces to add\n * @param char - Character to use for indentation\n * @returns A new Str instance with added indentation\n * @example\n * ```typescript\n * str('Hello\\nWorld').indent(2).$ // ' Hello\\n World'\n * str('A\\nB').indent(2, '-').$ // '--A\\n--B'\n * ```\n */\n public indent(size: number, char: string = \" \") {\n return new Str(lib.indent(this.text, size, char));\n }\n\n /**\n * Remove indentation from each line\n * @param indentation - Optional number of spaces to remove\n * @returns A new Str instance with indentation removed\n * @example\n * ```typescript\n * str(' Hello\\n World').dedent().$ // 'Hello\\n World'\n * str(' A\\n B').dedent(2).$ // ' A\\nB'\n * ```\n */\n public dedent(indentation?: number) {\n return new Str(lib.dedent(this.text, indentation));\n }\n\n /**\n * Remove characters from the start of the string\n * @param count - Number of characters to remove\n * @returns A new Str instance with characters removed from the start\n * @example\n * ```typescript\n * str('Hello').chopStart(2).$ // 'llo'\n * ```\n */\n public chopStart(count: number) {\n return new Str(lib.chopStart(this.text, count));\n }\n\n /**\n * Remove characters from the end of the string\n * @param count - Number of characters to remove\n * @returns A new Str instance with characters removed from the end\n * @example\n * ```typescript\n * str('Hello').chopEnd(2).$ // 'Hel'\n * ```\n */\n public chopEnd(count: number) {\n if (count === 0) return this;\n return new Str(lib.chopEnd(this.text, count));\n }\n\n /**\n * Limit consecutive newlines to a maximum count\n * @param maxRepeat - Maximum number of consecutive newlines to allow\n * @returns A new Str instance with limited consecutive newlines\n * @example\n * ```typescript\n * str('A\\n\\n\\nB').chopRepeatNewlines(1).$ // 'A\\nB'\n * str('A\\n\\n\\nB').chopRepeatNewlines(2).$ // 'A\\n\\nB'\n * ```\n */\n public chopRepeatNewlines(maxRepeat: number) {\n if (maxRepeat === 0) return this;\n return new Str(lib.chopRepeatNewlines(this.text, maxRepeat));\n }\n\n /**\n * Take characters from the start of the string\n * @param count - Number of characters to take\n * @returns A new Str instance with the first n characters\n * @example\n * ```typescript\n * str('Hello').takeStart(2).$ // 'He'\n * ```\n */\n public takeStart(count: number) {\n return new Str(lib.takeStart(this.text, count));\n }\n\n /**\n * Take characters from the end of the string\n * @param count - Number of characters to take\n * @returns A new Str instance with the last n characters\n * @example\n * ```typescript\n * str('Hello').takeEnd(2).$ // 'lo'\n * ```\n */\n public takeEnd(count: number) {\n return new Str(lib.takeEnd(this.text, count));\n }\n\n /**\n * Get the last line of the string\n * @returns A new Str instance containing the last line\n * @example\n * ```typescript\n * str('Hello\\nWorld').lastLine().$ // 'World'\n * ```\n */\n public lastLine() {\n return new Str(lib.lastLine(this.text));\n }\n\n /**\n * Get the first line of the string\n * @returns A new Str instance containing the first line\n * @example\n * ```typescript\n * str('Hello\\nWorld').firstLine().$ // 'Hello'\n * ```\n */\n public firstLine() {\n return new Str(lib.firstLine(this.text));\n }\n\n /**\n * Count leading space characters\n * @returns The number of leading space characters\n * @example\n * ```typescript\n * str(' Hello').leadingSpacesCount() // 2\n * str('Hello').leadingSpacesCount() // 0\n * ```\n */\n public leadingSpacesCount() {\n return lib.leadingSpacesCount(this.text);\n }\n\n /**\n * Get the minimum indentation level of non-empty lines\n * @returns The number of spaces in the minimum indentation\n * @example\n * ```typescript\n * str(' Hello\\n World').indentation() // 2\n * str('Hello\\n World').indentation() // 0\n * ```\n */\n public indentation() {\n return lib.indentation(this.text);\n }\n\n /**\n * Check if the string is empty or contains only whitespace\n * @returns True if empty or whitespace-only, false otherwise\n * @example\n * ```typescript\n * str('').isEmpty() // true\n * str(' \\n').isEmpty() // true\n * str('Hello').isEmpty() // false\n * ```\n */\n public isEmpty() {\n return lib.isEmpty(this.text);\n }\n\n /**\n * Replace the first occurrence of a substring or pattern\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the match with\n * @returns A new Str instance with the first match replaced\n * @example\n * ```typescript\n * str('Hello World').replace('o', '0').$ // 'Hell0 World'\n * str('abc abc').replace(/[a-z]/, 'X').$ // 'Xbc abc'\n * ```\n */\n public replace(searchValue: string | RegExp, replaceValue: string) {\n return new Str(lib.replace(this.text, searchValue, replaceValue));\n }\n\n /**\n * Replace all occurrences of a substring or pattern\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the matches with\n * @returns A new Str instance with all matches replaced\n * @example\n * ```typescript\n * str('Hello World').replaceAll('o', '0').$ // 'Hell0 W0rld'\n * str('abc abc').replaceAll(/[a-z]/g, 'X').$ // 'XXX XXX'\n * ```\n */\n public replaceAll(searchValue: string | RegExp, replaceValue: string) {\n return new Str(lib.replaceAll(this.text, searchValue, replaceValue));\n }\n\n /**\n * Convert string to camelCase\n * @returns A new Str instance in camelCase\n * @example\n * ```typescript\n * str('hello-world').camelCase().$ // 'helloWorld'\n * ```\n */\n public camelCase() {\n return new Str(changeCase.camelCase(this.text));\n }\n\n /**\n * Convert string to Capital Case\n * @returns A new Str instance in Capital Case\n * @example\n * ```typescript\n * str('hello-world').capitalCase().$ // 'Hello World'\n * ```\n */\n public capitalCase() {\n return new Str(changeCase.capitalCase(this.text));\n }\n\n /**\n * Convert string to CONSTANT_CASE\n * @returns A new Str instance in CONSTANT_CASE\n * @example\n * ```typescript\n * str('hello-world').constantCase().$ // 'HELLO_WORLD'\n * ```\n */\n public constantCase() {\n return new Str(changeCase.constantCase(this.text));\n }\n\n /**\n * Convert string to dot.case\n * @returns A new Str instance in dot.case\n * @example\n * ```typescript\n * str('hello-world').dotCase().$ // 'hello.world'\n * ```\n */\n public dotCase() {\n return new Str(changeCase.dotCase(this.text));\n }\n\n /**\n * Convert string to kebab-case\n * @returns A new Str instance in kebab-case\n * @example\n * ```typescript\n * str('helloWorld').kebabCase().$ // 'hello-world'\n * ```\n */\n public kebabCase() {\n return new Str(changeCase.kebabCase(this.text));\n }\n\n /**\n * Convert string to no case\n * @returns A new Str instance with no case\n * @example\n * ```typescript\n * str('helloWorld').noCase().$ // 'hello world'\n * ```\n */\n public noCase() {\n return new Str(changeCase.noCase(this.text));\n }\n\n /**\n * Convert string to PascalCase\n * @returns A new Str instance in PascalCase\n * @example\n * ```typescript\n * str('hello-world').pascalCase().$ // 'HelloWorld'\n * ```\n */\n public pascalCase() {\n return new Str(changeCase.pascalCase(this.text));\n }\n\n /**\n * Convert string to Pascal_Snake_Case\n * @returns A new Str instance in Pascal_Snake_Case\n * @example\n * ```typescript\n * str('hello-world').pascalSnakeCase().$ // 'Hello_World'\n * ```\n */\n public pascalSnakeCase() {\n return new Str(changeCase.pascalSnakeCase(this.text));\n }\n\n /**\n * Convert string to path/case\n * @returns A new Str instance in path/case\n * @example\n * ```typescript\n * str('hello-world').pathCase().$ // 'hello/world'\n * ```\n */\n public pathCase() {\n return new Str(changeCase.pathCase(this.text));\n }\n\n /**\n * Convert string to Sentence case\n * @returns A new Str instance in Sentence case\n * @example\n * ```typescript\n * str('hello-world').sentenceCase().$ // 'Hello world'\n * ```\n */\n public sentenceCase() {\n return new Str(changeCase.sentenceCase(this.text));\n }\n\n /**\n * Convert string to snake_case\n * @returns A new Str instance in snake_case\n * @example\n * ```typescript\n * str('helloWorld').snakeCase().$ // 'hello_world'\n * ```\n */\n public snakeCase() {\n return new Str(changeCase.snakeCase(this.text));\n }\n\n /**\n * Convert string to Train-Case\n * @returns A new Str instance in Train-Case\n * @example\n * ```typescript\n * str('hello-world').trainCase().$ // 'Hello-World'\n * ```\n */\n public trainCase() {\n return new Str(changeCase.trainCase(this.text));\n }\n\n /**\n * Get the underlying string value\n * @returns The wrapped string value\n * @example\n * ```typescript\n * str('hello').str // 'hello'\n * ```\n */\n public get str() {\n return this.toString();\n }\n}\n\n/**\n * Create a new Str instance from any stringable value\n * @param text - Any value that can be converted to a string\n * @returns A new Str instance wrapping the string value\n * @example\n * ```typescript\n * str('hello') // from string\n * str(123) // from number\n * str({ toString() }) // from object with toString\n * ```\n */\nexport const str = (text: Stringable) => {\n return new Str(text.toString());\n};\n","/**\n * Remove empty lines at the start of the text but leave whitespace on the first line with content\n * @param text - The input string to process\n * @returns The string with empty lines removed from the start\n * @example\n * ```typescript\n * chopEmptyLinesStart(\"\\n\\n \\n Hello\") // \" Hello\"\n * chopEmptyLinesStart(\" Hello\") // \" Hello\"\n * ```\n */\nexport const chopEmptyLinesStart = (text: string) => {\n return text.replace(/^(\\s*\\n)+/, \"\");\n};\n\n/**\n * Remove empty lines at the end of the text but leave whitespace on the last line with content\n * @param text - The input string to process\n * @returns The string with empty lines removed from the end\n * @example\n * ```typescript\n * chopEmptyLinesEnd(\"Hello\\n\\n \\n\") // \"Hello\"\n * chopEmptyLinesEnd(\"Hello \") // \"Hello \"\n * ```\n */\nexport const chopEmptyLinesEnd = (text: string) => {\n return text.replace(/(\\n\\s*)+$/, \"\");\n};\n\n/**\n * Remove all space characters in lines that contain no content\n * @param text - The input string to process\n * @returns The string with whitespace removed from empty lines\n * @example\n * ```typescript\n * trimEmptyLines(\"Hello\\n \\nWorld\") // \"Hello\\n\\nWorld\"\n * trimEmptyLines(\" \\n \\n \") // \"\\n\\n\"\n * ```\n */\nexport const trimEmptyLines = (text: string) => {\n return text.replace(/(^|\\n)\\s+(\\n|$)/g, \"$1$2\");\n};\n\n/**\n * Remove all space characters at the end of each line\n * @param text - The input string to process\n * @returns The string with trailing spaces removed from all lines\n * @example\n * ```typescript\n * trimLinesTrailingSpaces(\"Hello \\nWorld \") // \"Hello\\nWorld\"\n * trimLinesTrailingSpaces(\"Hello \") // \"Hello\"\n * ```\n */\nexport const trimLinesTrailingSpaces = (text: string) => {\n return text.replace(/ +(\\n|$)/g, \"$1\");\n};\n\n/**\n * Remove leading and trailing whitespace and line terminator characters\n * @param text - The input string to process\n * @returns The trimmed string\n * @example\n * ```typescript\n * trim(\" Hello World \") // \"Hello World\"\n * trim(\"\\n Hello \\n\") // \"Hello\"\n * ```\n */\nexport const trim = (text: string) => {\n return text.trim();\n};\n\n/**\n * Remove leading whitespace and line terminator characters\n * @param text - The input string to process\n * @returns The string with leading whitespace removed\n * @example\n * ```typescript\n * trimStart(\" Hello World \") // \"Hello World \"\n * trimStart(\"\\n Hello\") // \"Hello\"\n * ```\n */\nexport const trimStart = (text: string) => {\n return text.trimStart();\n};\n\n/**\n * Remove trailing whitespace and line terminator characters\n * @param text - The input string to process\n * @returns The string with trailing whitespace removed\n * @example\n * ```typescript\n * trimEnd(\" Hello World \") // \" Hello World\"\n * trimEnd(\"Hello \\n\") // \"Hello\"\n * ```\n */\nexport const trimEnd = (text: string) => {\n return text.trimEnd();\n};\n\n/**\n * Split a string into substrings using the specified separator\n * @param text - The input string to split\n * @param separator - The string or regular expression to use for splitting\n * @param limit - Optional limit on the number of splits to perform\n * @returns An array of substrings\n * @example\n * ```typescript\n * split(\"Hello World\", \" \") // [\"Hello\", \"World\"]\n * split(\"a,b,c\", \",\", 2) // [\"a\", \"b\"]\n * split(\"a.b-c\", /[.-]/) // [\"a\", \"b\", \"c\"]\n * ```\n */\nexport const split = (\n text: string,\n separator: string | RegExp,\n limit?: number,\n) => {\n return text.split(separator, limit);\n};\n\n/**\n * Add line numbers to each line in a string\n * @param text - The string to add line numbers to\n * @param separator - The separator between line number and content (defaults to \":\")\n * @returns The string with line numbers added\n * @example\n * ```typescript\n * addLineNumbers(\"Hello\\nWorld\") // \"0:Hello\\n1:World\"\n * addLineNumbers(\"A\\nB\\nC\", \" -> \") // \"0 -> A\\n1 -> B\\n2 -> C\"\n * ```\n */\nexport const addLineNumbers = (text: string, separator: string = \":\") => {\n const lines = text.split(/\\r?\\n/);\n return lines\n .map((line, index) => `${index}${separator}${line}`)\n .join(\"\\n\");\n};\n\n/**\n * Calculate the minimum indentation level of non-empty lines in the string\n * @param text - The input string to analyze\n * @returns The number of spaces in the minimum indentation level, or 0 if no indentation found\n * @example\n * ```typescript\n * indentation(\" Hello\\n World\") // 2\n * indentation(\"Hello\\n World\") // 0\n * indentation(\" \\n Hello\") // 4\n * ```\n */\nexport const indentation = (text: string) => {\n return (\n text.split(/\\r?\\n/).reduce((acc: number | null, line) => {\n if (line.trim() === \"\") return acc;\n const indentation = leadingSpacesCount(line);\n if (acc === null) return indentation;\n return Math.min(acc, indentation);\n }, null) ?? 0\n );\n};\n\n/**\n * Indent each line of the string by a specified number of spaces\n * @param text - The input string to indent\n * @param size - The number of spaces to add at the start of each line\n * @param char - The character to use for indentation (defaults to space)\n * @returns The indented string\n * @example\n * ```typescript\n * indent(\"Hello\\nWorld\", 2) // \" Hello\\n World\"\n * indent(\"A\\nB\", 3, \"-\") // \"---A\\n---B\"\n * ```\n */\nexport const indent = (text: string, size: number, char: string = \" \") => {\n if (size === 0) return text;\n\n const indentStr = char.repeat(size);\n const lines = text.split(/\\r?\\n/);\n return lines\n .map((line) => indentStr + line)\n .join(\"\\n\");\n};\n\n/**\n * Remove indentation from each line of the string\n * @param text - The input string to dedent\n * @param size - Optional number of spaces to remove. If not provided, removes the minimum common indentation\n * @returns The dedented string\n * @example\n * ```typescript\n * dedent(\" Hello\\n World\") // \"Hello\\n World\"\n * dedent(\" A\\n B\", 2) // \" A\\nB\"\n * ```\n */\nexport const dedent = (text: string, size?: number) => {\n const _size = size ?? indentation(text);\n if (_size === 0) return text;\n const regex = new RegExp(`^\\\\s{1,${_size}}`);\n const lines = text.split(/\\r?\\n/);\n return lines\n .map((line) => line.replace(regex, \"\"))\n .join(\"\\n\");\n};\n\n/**\n * Remove a specified number of characters from the end of the string\n * @param text - The input string to process\n * @param count - The number of characters to remove\n * @returns The string with characters removed from the end\n * @example\n * ```typescript\n * chopEnd(\"Hello World\", 6) // \"Hello\"\n * chopEnd(\"Hello\", 0) // \"Hello\"\n * ```\n */\nexport const chopEnd = (text: string, count: number) => {\n if (count === 0) return text;\n return text.slice(0, -count);\n};\n\n/**\n * Remove a specified number of characters from the start of the string\n * @param text - The input string to process\n * @param count - The number of characters to remove\n * @returns The string with characters removed from the start\n * @example\n * ```typescript\n * chopStart(\"Hello World\", 6) // \"World\"\n * chopStart(\"Hello\", 0) // \"Hello\"\n * ```\n */\nexport const chopStart = (text: string, count: number) => {\n if (count === 0) return text;\n return text.slice(count);\n};\n\n/**\n * Limit the number of consecutive newlines in the string\n * @param text - The input string to process\n * @param maxRepeat - The maximum number of consecutive newlines to allow\n * @returns The string with consecutive newlines limited\n * @example\n * ```typescript\n * chopRepeatNewlines(\"A\\n\\n\\n\\nB\", 2) // \"A\\n\\nB\"\n * chopRepeatNewlines(\"A\\n\\nB\", 1) // \"A\\nB\"\n * ```\n */\nexport const chopRepeatNewlines = (text: string, maxRepeat: number) => {\n if (maxRepeat === 0) return text;\n return text.replace(\n new RegExp(`\\n{${maxRepeat + 1},}`, \"g\"),\n \"\\n\".repeat(maxRepeat),\n );\n};\n\n/**\n * Extract a specified number of characters from the start of the string\n * @param text - The input string to process\n * @param count - The number of characters to take\n * @returns The extracted substring from the start\n * @example\n * ```typescript\n * takeStart(\"Hello World\", 5) // \"Hello\"\n * takeStart(\"Hi\", 5) // \"Hi\"\n * ```\n */\nexport const takeStart = (text: string, count: number) => {\n return text.slice(0, count);\n};\n\n/**\n * Extract a specified number of characters from the end of the string\n * @param text - The input string to process\n * @param count - The number of characters to take\n * @returns The extracted substring from the end\n * @example\n * ```typescript\n * takeEnd(\"Hello World\", 5) // \"World\"\n * takeEnd(\"Hi\", 5) // \"Hi\"\n * ```\n */\nexport const takeEnd = (text: string, count: number) => {\n return text.slice(-count);\n};\n\n/**\n * Get the last line of a multi-line string\n * @param text - The input string to process\n * @returns The last line of the string, or empty string if input is empty\n * @example\n * ```typescript\n * lastLine(\"Hello\\nWorld\") // \"World\"\n * lastLine(\"Hello\") // \"Hello\"\n * lastLine(\"\") // \"\"\n * ```\n */\nexport const lastLine = (text: string) => {\n return text.split(/\\r?\\n/).at(-1) ?? \"\";\n};\n\n/**\n * Get the first line of a multi-line string\n * @param text - The input string to process\n * @returns The first line of the string, or empty string if input is empty\n * @example\n * ```typescript\n * firstLine(\"Hello\\nWorld\") // \"Hello\"\n * firstLine(\"Hello\") // \"Hello\"\n * firstLine(\"\") // \"\"\n * ```\n */\nexport const firstLine = (text: string) => {\n return text.split(/\\r?\\n/).at(0) ?? \"\";\n};\n\n/**\n * Count the number of leading space characters in a string\n * @param text - The input string to analyze\n * @returns The number of leading space characters\n * @example\n * ```typescript\n * leadingSpacesCount(\" Hello\") // 2\n * leadingSpacesCount(\"Hello\") // 0\n * ```\n */\nexport const leadingSpacesCount = (text: string) => {\n return text.match(/^\\s+/)?.at(0)?.length ?? 0;\n};\n\n/**\n * Check if a string is empty or contains only whitespace\n * @param text - The input string to check\n * @returns True if the string is empty or contains only whitespace, false otherwise\n * @example\n * ```typescript\n * isEmpty(\"\") // true\n * isEmpty(\" \\n \") // true\n * isEmpty(\"Hello\") // false\n * ```\n */\nexport const isEmpty = (text: string) => {\n return text.trim() === \"\";\n};\n\n/**\n * Replace the first occurrence of a substring or pattern in the string\n * @param text - The input string to process\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the match with\n * @returns The string with the first match replaced\n * @example\n * ```typescript\n * replace(\"Hello World\", \"o\", \"0\") // \"Hell0 World\"\n * replace(\"abc abc\", /[a-z]/, \"X\") // \"Xbc abc\"\n * ```\n */\nexport const replace = (\n text: string,\n searchValue: string | RegExp,\n replaceValue: string,\n) => {\n return text.replace(searchValue, replaceValue);\n};\n\n/**\n * Replace all occurrences of a substring or pattern in the string\n * @param text - The input string to process\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the matches with\n * @returns The string with all matches replaced\n * @example\n * ```typescript\n * replaceAll(\"Hello World\", \"o\", \"0\") // \"Hell0 W0rld\"\n * replaceAll(\"abc abc\", /[a-z]/g, \"X\") // \"XXX XXX\"\n * ```\n */\nexport const replaceAll = (\n text: string,\n searchValue: string | RegExp,\n replaceValue: string,\n) => {\n if (typeof searchValue === \"string\") {\n return text.replaceAll(searchValue, replaceValue);\n }\n // Ensure the RegExp has the global flag\n const flags = searchValue.flags.includes(\"g\")\n ? searchValue.flags\n : searchValue.flags + \"g\";\n const globalRegex = new RegExp(searchValue.source, flags);\n return text.replace(globalRegex, replaceValue);\n};\n"],"mappings":"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","names":["indentation","indentation"]}
package/dist/str.index.js CHANGED
@@ -44,10 +44,11 @@ var split = (text, separator, limit) => {
44
44
  return text.split(separator, limit);
45
45
  };
46
46
  var addLineNumbers = (text, separator = ":") => {
47
- return text.split("\n").map((line, index) => `${index}${separator}${line}`).join("\n");
47
+ const lines = text.split(/\r?\n/);
48
+ return lines.map((line, index) => `${index}${separator}${line}`).join("\n");
48
49
  };
49
50
  var indentation = (text) => {
50
- return text.split("\n").reduce((acc, line) => {
51
+ return text.split(/\r?\n/).reduce((acc, line) => {
51
52
  if (line.trim() === "") return acc;
52
53
  const indentation2 = leadingSpacesCount(line);
53
54
  if (acc === null) return indentation2;
@@ -57,13 +58,15 @@ var indentation = (text) => {
57
58
  var indent = (text, size, char = " ") => {
58
59
  if (size === 0) return text;
59
60
  const indentStr = char.repeat(size);
60
- return text.split("\n").map((line) => indentStr + line).join("\n");
61
+ const lines = text.split(/\r?\n/);
62
+ return lines.map((line) => indentStr + line).join("\n");
61
63
  };
62
64
  var dedent = (text, size) => {
63
65
  const _size = size ?? indentation(text);
64
66
  if (_size === 0) return text;
65
67
  const regex = new RegExp(`^\\s{1,${_size}}`);
66
- return text.split("\n").map((line) => line.replace(regex, "")).join("\n");
68
+ const lines = text.split(/\r?\n/);
69
+ return lines.map((line) => line.replace(regex, "")).join("\n");
67
70
  };
68
71
  var chopEnd = (text, count) => {
69
72
  if (count === 0) return text;
@@ -88,10 +91,10 @@ var takeEnd = (text, count) => {
88
91
  return text.slice(-count);
89
92
  };
90
93
  var lastLine = (text) => {
91
- return text.split("\n").at(-1) ?? "";
94
+ return text.split(/\r?\n/).at(-1) ?? "";
92
95
  };
93
96
  var firstLine = (text) => {
94
- return text.split("\n").at(0) ?? "";
97
+ return text.split(/\r?\n/).at(0) ?? "";
95
98
  };
96
99
  var leadingSpacesCount = (text) => {
97
100
  return text.match(/^\s+/)?.at(0)?.length ?? 0;
@@ -126,7 +129,7 @@ var Str = class _Str extends Pipeable {
126
129
  */
127
130
  constructor(text) {
128
131
  super();
129
- this.text = text;
132
+ this.text = text.replace(/\r\n/g, "\n");
130
133
  }
131
134
  /**
132
135
  * Get the underlying string value
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/str.index.ts","../src/str.chainable.ts","../src/str.lib.ts"],"sourcesContent":["export {\n camelCase,\n capitalCase,\n constantCase,\n dotCase,\n kebabCase,\n noCase,\n pascalCase,\n pascalSnakeCase,\n pathCase,\n sentenceCase,\n snakeCase,\n trainCase,\n} from \"change-case\";\nexport { Str, str } from \"./str.chainable.ts\";\nexport * from \"./str.lib.ts\";\n","import { Pipeable } from \"@synstack/pipe\";\nimport * as changeCase from \"change-case\";\nimport { type Stringable } from \"../../shared/src/ts.utils.ts\";\nimport * as lib from \"./str.lib.ts\";\n\n/**\n * A chainable string manipulation class that extends Pipeable\n * Provides a fluent interface for string operations with full TypeScript support\n *\n * @example\n * ```typescript\n * import { str } from '@synstack/str'\n *\n * // Basic chaining\n * const result = str('Hello World')\n * .trim()\n * .split(' ')\n * .at(0)\n * .$\n *\n * // Advanced chaining with Pipeable methods\n * const modified = str('hello-world')\n * ._((s) => s.camelCase())\n * ._$((value) => value.toUpperCase())\n * .$\n * ```\n */\nexport class Str extends Pipeable<Str, string> {\n private readonly text: string;\n\n /**\n * Create a new Str instance\n * @param text - The input string to wrap\n * @example\n * ```typescript\n * const s = new Str('Hello World')\n * // or use the convenience function\n * const s = str('Hello World')\n * ```\n */\n public constructor(text: string) {\n super();\n this.text = text;\n }\n\n /**\n * Get the underlying string value\n * @returns The wrapped string value\n */\n public valueOf(): string {\n return this.text;\n }\n\n /**\n * Convert the Str instance to a string\n * @returns The wrapped string value\n */\n public toString() {\n return this.text;\n }\n\n /**\n * Get the current Str instance\n * @returns The current Str instance\n * @internal Used by Pipeable\n */\n public instanceOf(): Str {\n return this;\n }\n\n /**\n * Remove empty lines at the start of the text\n * @returns A new Str instance with empty lines removed from the start\n * @example\n * ```typescript\n * str('\\n\\n Hello').chopEmptyLinesStart().$ // ' Hello'\n * ```\n */\n public chopEmptyLinesStart() {\n return new Str(lib.chopEmptyLinesStart(this.text));\n }\n\n /**\n * Remove empty lines at the end of the text\n * @returns A new Str instance with empty lines removed from the end\n * @example\n * ```typescript\n * str('Hello\\n\\n').chopEmptyLinesEnd().$ // 'Hello'\n * ```\n */\n public chopEmptyLinesEnd() {\n return new Str(lib.chopEmptyLinesEnd(this.text));\n }\n\n /**\n * Remove whitespace from empty lines\n * @returns A new Str instance with whitespace removed from empty lines\n * @example\n * ```typescript\n * str('Hello\\n \\nWorld').trimEmptyLines().$ // 'Hello\\n\\nWorld'\n * ```\n */\n public trimEmptyLines() {\n return new Str(lib.trimEmptyLines(this.text));\n }\n\n /**\n * Remove trailing spaces from all lines\n * @returns A new Str instance with trailing spaces removed from all lines\n * @example\n * ```typescript\n * str('Hello \\nWorld ').trimLinesTrailingSpaces().$ // 'Hello\\nWorld'\n * ```\n */\n public trimLinesTrailingSpaces() {\n return new Str(lib.trimLinesTrailingSpaces(this.text));\n }\n\n /**\n * Remove leading and trailing whitespace\n * @returns A new Str instance with whitespace removed from both ends\n * @example\n * ```typescript\n * str(' Hello ').trim().$ // 'Hello'\n * ```\n */\n public trim() {\n return new Str(lib.trim(this.text));\n }\n\n /**\n * Remove leading whitespace\n * @returns A new Str instance with leading whitespace removed\n * @example\n * ```typescript\n * str(' Hello ').trimStart().$ // 'Hello '\n * ```\n */\n public trimStart() {\n return new Str(lib.trimStart(this.text));\n }\n\n /**\n * Remove trailing whitespace\n * @returns A new Str instance with trailing whitespace removed\n * @example\n * ```typescript\n * str(' Hello ').trimEnd().$ // ' Hello'\n * ```\n */\n public trimEnd() {\n return new Str(lib.trimEnd(this.text));\n }\n\n /**\n * Split the string into an array of Str instances\n * @param separator - String or RegExp to split on\n * @param limit - Maximum number of splits to perform\n * @returns Array of Str instances\n * @example\n * ```typescript\n * str('a,b,c').split(',') // [Str('a'), Str('b'), Str('c')]\n * str('a b c').split(' ', 2) // [Str('a'), Str('b')]\n * ```\n */\n public split(separator: string | RegExp, limit?: number) {\n return lib.split(this.text, separator, limit).map((v) => new Str(v));\n }\n\n /**\n * Add line numbers to each line\n * @param separator - String to separate line numbers from content\n * @returns A new Str instance with line numbers added\n * @example\n * ```typescript\n * str('A\\nB').addLineNumbers().$ // '0:A\\n1:B'\n * str('A\\nB').addLineNumbers(' -> ').$ // '0 -> A\\n1 -> B'\n * ```\n */\n public addLineNumbers(separator: string = \":\") {\n return new Str(lib.addLineNumbers(this.text, separator));\n }\n\n /**\n * Get the character at a specific index\n * @param index - Zero-based position in the string\n * @returns The character at the index, or undefined if out of bounds\n * @example\n * ```typescript\n * str('Hello').at(0) // 'H'\n * str('Hello').at(-1) // 'o'\n * ```\n */\n public at(index: number) {\n return this.text.at(index);\n }\n\n /**\n * Get the length of the string\n * @returns The number of characters in the string\n * @example\n * ```typescript\n * str('Hello').length() // 5\n * str('').length() // 0\n * ```\n */\n public length() {\n return this.text.length;\n }\n\n /**\n * Indent each line by a specified number of spaces\n * @param size - Number of spaces to add\n * @param char - Character to use for indentation\n * @returns A new Str instance with added indentation\n * @example\n * ```typescript\n * str('Hello\\nWorld').indent(2).$ // ' Hello\\n World'\n * str('A\\nB').indent(2, '-').$ // '--A\\n--B'\n * ```\n */\n public indent(size: number, char: string = \" \") {\n return new Str(lib.indent(this.text, size, char));\n }\n\n /**\n * Remove indentation from each line\n * @param indentation - Optional number of spaces to remove\n * @returns A new Str instance with indentation removed\n * @example\n * ```typescript\n * str(' Hello\\n World').dedent().$ // 'Hello\\n World'\n * str(' A\\n B').dedent(2).$ // ' A\\nB'\n * ```\n */\n public dedent(indentation?: number) {\n return new Str(lib.dedent(this.text, indentation));\n }\n\n /**\n * Remove characters from the start of the string\n * @param count - Number of characters to remove\n * @returns A new Str instance with characters removed from the start\n * @example\n * ```typescript\n * str('Hello').chopStart(2).$ // 'llo'\n * ```\n */\n public chopStart(count: number) {\n return new Str(lib.chopStart(this.text, count));\n }\n\n /**\n * Remove characters from the end of the string\n * @param count - Number of characters to remove\n * @returns A new Str instance with characters removed from the end\n * @example\n * ```typescript\n * str('Hello').chopEnd(2).$ // 'Hel'\n * ```\n */\n public chopEnd(count: number) {\n if (count === 0) return this;\n return new Str(lib.chopEnd(this.text, count));\n }\n\n /**\n * Limit consecutive newlines to a maximum count\n * @param maxRepeat - Maximum number of consecutive newlines to allow\n * @returns A new Str instance with limited consecutive newlines\n * @example\n * ```typescript\n * str('A\\n\\n\\nB').chopRepeatNewlines(1).$ // 'A\\nB'\n * str('A\\n\\n\\nB').chopRepeatNewlines(2).$ // 'A\\n\\nB'\n * ```\n */\n public chopRepeatNewlines(maxRepeat: number) {\n if (maxRepeat === 0) return this;\n return new Str(lib.chopRepeatNewlines(this.text, maxRepeat));\n }\n\n /**\n * Take characters from the start of the string\n * @param count - Number of characters to take\n * @returns A new Str instance with the first n characters\n * @example\n * ```typescript\n * str('Hello').takeStart(2).$ // 'He'\n * ```\n */\n public takeStart(count: number) {\n return new Str(lib.takeStart(this.text, count));\n }\n\n /**\n * Take characters from the end of the string\n * @param count - Number of characters to take\n * @returns A new Str instance with the last n characters\n * @example\n * ```typescript\n * str('Hello').takeEnd(2).$ // 'lo'\n * ```\n */\n public takeEnd(count: number) {\n return new Str(lib.takeEnd(this.text, count));\n }\n\n /**\n * Get the last line of the string\n * @returns A new Str instance containing the last line\n * @example\n * ```typescript\n * str('Hello\\nWorld').lastLine().$ // 'World'\n * ```\n */\n public lastLine() {\n return new Str(lib.lastLine(this.text));\n }\n\n /**\n * Get the first line of the string\n * @returns A new Str instance containing the first line\n * @example\n * ```typescript\n * str('Hello\\nWorld').firstLine().$ // 'Hello'\n * ```\n */\n public firstLine() {\n return new Str(lib.firstLine(this.text));\n }\n\n /**\n * Count leading space characters\n * @returns The number of leading space characters\n * @example\n * ```typescript\n * str(' Hello').leadingSpacesCount() // 2\n * str('Hello').leadingSpacesCount() // 0\n * ```\n */\n public leadingSpacesCount() {\n return lib.leadingSpacesCount(this.text);\n }\n\n /**\n * Get the minimum indentation level of non-empty lines\n * @returns The number of spaces in the minimum indentation\n * @example\n * ```typescript\n * str(' Hello\\n World').indentation() // 2\n * str('Hello\\n World').indentation() // 0\n * ```\n */\n public indentation() {\n return lib.indentation(this.text);\n }\n\n /**\n * Check if the string is empty or contains only whitespace\n * @returns True if empty or whitespace-only, false otherwise\n * @example\n * ```typescript\n * str('').isEmpty() // true\n * str(' \\n').isEmpty() // true\n * str('Hello').isEmpty() // false\n * ```\n */\n public isEmpty() {\n return lib.isEmpty(this.text);\n }\n\n /**\n * Replace the first occurrence of a substring or pattern\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the match with\n * @returns A new Str instance with the first match replaced\n * @example\n * ```typescript\n * str('Hello World').replace('o', '0').$ // 'Hell0 World'\n * str('abc abc').replace(/[a-z]/, 'X').$ // 'Xbc abc'\n * ```\n */\n public replace(searchValue: string | RegExp, replaceValue: string) {\n return new Str(lib.replace(this.text, searchValue, replaceValue));\n }\n\n /**\n * Replace all occurrences of a substring or pattern\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the matches with\n * @returns A new Str instance with all matches replaced\n * @example\n * ```typescript\n * str('Hello World').replaceAll('o', '0').$ // 'Hell0 W0rld'\n * str('abc abc').replaceAll(/[a-z]/g, 'X').$ // 'XXX XXX'\n * ```\n */\n public replaceAll(searchValue: string | RegExp, replaceValue: string) {\n return new Str(lib.replaceAll(this.text, searchValue, replaceValue));\n }\n\n /**\n * Convert string to camelCase\n * @returns A new Str instance in camelCase\n * @example\n * ```typescript\n * str('hello-world').camelCase().$ // 'helloWorld'\n * ```\n */\n public camelCase() {\n return new Str(changeCase.camelCase(this.text));\n }\n\n /**\n * Convert string to Capital Case\n * @returns A new Str instance in Capital Case\n * @example\n * ```typescript\n * str('hello-world').capitalCase().$ // 'Hello World'\n * ```\n */\n public capitalCase() {\n return new Str(changeCase.capitalCase(this.text));\n }\n\n /**\n * Convert string to CONSTANT_CASE\n * @returns A new Str instance in CONSTANT_CASE\n * @example\n * ```typescript\n * str('hello-world').constantCase().$ // 'HELLO_WORLD'\n * ```\n */\n public constantCase() {\n return new Str(changeCase.constantCase(this.text));\n }\n\n /**\n * Convert string to dot.case\n * @returns A new Str instance in dot.case\n * @example\n * ```typescript\n * str('hello-world').dotCase().$ // 'hello.world'\n * ```\n */\n public dotCase() {\n return new Str(changeCase.dotCase(this.text));\n }\n\n /**\n * Convert string to kebab-case\n * @returns A new Str instance in kebab-case\n * @example\n * ```typescript\n * str('helloWorld').kebabCase().$ // 'hello-world'\n * ```\n */\n public kebabCase() {\n return new Str(changeCase.kebabCase(this.text));\n }\n\n /**\n * Convert string to no case\n * @returns A new Str instance with no case\n * @example\n * ```typescript\n * str('helloWorld').noCase().$ // 'hello world'\n * ```\n */\n public noCase() {\n return new Str(changeCase.noCase(this.text));\n }\n\n /**\n * Convert string to PascalCase\n * @returns A new Str instance in PascalCase\n * @example\n * ```typescript\n * str('hello-world').pascalCase().$ // 'HelloWorld'\n * ```\n */\n public pascalCase() {\n return new Str(changeCase.pascalCase(this.text));\n }\n\n /**\n * Convert string to Pascal_Snake_Case\n * @returns A new Str instance in Pascal_Snake_Case\n * @example\n * ```typescript\n * str('hello-world').pascalSnakeCase().$ // 'Hello_World'\n * ```\n */\n public pascalSnakeCase() {\n return new Str(changeCase.pascalSnakeCase(this.text));\n }\n\n /**\n * Convert string to path/case\n * @returns A new Str instance in path/case\n * @example\n * ```typescript\n * str('hello-world').pathCase().$ // 'hello/world'\n * ```\n */\n public pathCase() {\n return new Str(changeCase.pathCase(this.text));\n }\n\n /**\n * Convert string to Sentence case\n * @returns A new Str instance in Sentence case\n * @example\n * ```typescript\n * str('hello-world').sentenceCase().$ // 'Hello world'\n * ```\n */\n public sentenceCase() {\n return new Str(changeCase.sentenceCase(this.text));\n }\n\n /**\n * Convert string to snake_case\n * @returns A new Str instance in snake_case\n * @example\n * ```typescript\n * str('helloWorld').snakeCase().$ // 'hello_world'\n * ```\n */\n public snakeCase() {\n return new Str(changeCase.snakeCase(this.text));\n }\n\n /**\n * Convert string to Train-Case\n * @returns A new Str instance in Train-Case\n * @example\n * ```typescript\n * str('hello-world').trainCase().$ // 'Hello-World'\n * ```\n */\n public trainCase() {\n return new Str(changeCase.trainCase(this.text));\n }\n\n /**\n * Get the underlying string value\n * @returns The wrapped string value\n * @example\n * ```typescript\n * str('hello').str // 'hello'\n * ```\n */\n public get str() {\n return this.toString();\n }\n}\n\n/**\n * Create a new Str instance from any stringable value\n * @param text - Any value that can be converted to a string\n * @returns A new Str instance wrapping the string value\n * @example\n * ```typescript\n * str('hello') // from string\n * str(123) // from number\n * str({ toString() }) // from object with toString\n * ```\n */\nexport const str = (text: Stringable) => {\n return new Str(text.toString());\n};\n","/**\n * Remove empty lines at the start of the text but leave whitespace on the first line with content\n * @param text - The input string to process\n * @returns The string with empty lines removed from the start\n * @example\n * ```typescript\n * chopEmptyLinesStart(\"\\n\\n \\n Hello\") // \" Hello\"\n * chopEmptyLinesStart(\" Hello\") // \" Hello\"\n * ```\n */\nexport const chopEmptyLinesStart = (text: string) => {\n return text.replace(/^(\\s*\\n)+/, \"\");\n};\n\n/**\n * Remove empty lines at the end of the text but leave whitespace on the last line with content\n * @param text - The input string to process\n * @returns The string with empty lines removed from the end\n * @example\n * ```typescript\n * chopEmptyLinesEnd(\"Hello\\n\\n \\n\") // \"Hello\"\n * chopEmptyLinesEnd(\"Hello \") // \"Hello \"\n * ```\n */\nexport const chopEmptyLinesEnd = (text: string) => {\n return text.replace(/(\\n\\s*)+$/, \"\");\n};\n\n/**\n * Remove all space characters in lines that contain no content\n * @param text - The input string to process\n * @returns The string with whitespace removed from empty lines\n * @example\n * ```typescript\n * trimEmptyLines(\"Hello\\n \\nWorld\") // \"Hello\\n\\nWorld\"\n * trimEmptyLines(\" \\n \\n \") // \"\\n\\n\"\n * ```\n */\nexport const trimEmptyLines = (text: string) => {\n return text.replace(/(^|\\n)\\s+(\\n|$)/g, \"$1$2\");\n};\n\n/**\n * Remove all space characters at the end of each line\n * @param text - The input string to process\n * @returns The string with trailing spaces removed from all lines\n * @example\n * ```typescript\n * trimLinesTrailingSpaces(\"Hello \\nWorld \") // \"Hello\\nWorld\"\n * trimLinesTrailingSpaces(\"Hello \") // \"Hello\"\n * ```\n */\nexport const trimLinesTrailingSpaces = (text: string) => {\n return text.replace(/ +(\\n|$)/g, \"$1\");\n};\n\n/**\n * Remove leading and trailing whitespace and line terminator characters\n * @param text - The input string to process\n * @returns The trimmed string\n * @example\n * ```typescript\n * trim(\" Hello World \") // \"Hello World\"\n * trim(\"\\n Hello \\n\") // \"Hello\"\n * ```\n */\nexport const trim = (text: string) => {\n return text.trim();\n};\n\n/**\n * Remove leading whitespace and line terminator characters\n * @param text - The input string to process\n * @returns The string with leading whitespace removed\n * @example\n * ```typescript\n * trimStart(\" Hello World \") // \"Hello World \"\n * trimStart(\"\\n Hello\") // \"Hello\"\n * ```\n */\nexport const trimStart = (text: string) => {\n return text.trimStart();\n};\n\n/**\n * Remove trailing whitespace and line terminator characters\n * @param text - The input string to process\n * @returns The string with trailing whitespace removed\n * @example\n * ```typescript\n * trimEnd(\" Hello World \") // \" Hello World\"\n * trimEnd(\"Hello \\n\") // \"Hello\"\n * ```\n */\nexport const trimEnd = (text: string) => {\n return text.trimEnd();\n};\n\n/**\n * Split a string into substrings using the specified separator\n * @param text - The input string to split\n * @param separator - The string or regular expression to use for splitting\n * @param limit - Optional limit on the number of splits to perform\n * @returns An array of substrings\n * @example\n * ```typescript\n * split(\"Hello World\", \" \") // [\"Hello\", \"World\"]\n * split(\"a,b,c\", \",\", 2) // [\"a\", \"b\"]\n * split(\"a.b-c\", /[.-]/) // [\"a\", \"b\", \"c\"]\n * ```\n */\nexport const split = (\n text: string,\n separator: string | RegExp,\n limit?: number,\n) => {\n return text.split(separator, limit);\n};\n\n/**\n * Add line numbers to each line in a string\n * @param text - The string to add line numbers to\n * @param separator - The separator between line number and content (defaults to \":\")\n * @returns The string with line numbers added\n * @example\n * ```typescript\n * addLineNumbers(\"Hello\\nWorld\") // \"0:Hello\\n1:World\"\n * addLineNumbers(\"A\\nB\\nC\", \" -> \") // \"0 -> A\\n1 -> B\\n2 -> C\"\n * ```\n */\nexport const addLineNumbers = (text: string, separator: string = \":\") => {\n return text\n .split(\"\\n\")\n .map((line, index) => `${index}${separator}${line}`)\n .join(\"\\n\");\n};\n\n/**\n * Calculate the minimum indentation level of non-empty lines in the string\n * @param text - The input string to analyze\n * @returns The number of spaces in the minimum indentation level, or 0 if no indentation found\n * @example\n * ```typescript\n * indentation(\" Hello\\n World\") // 2\n * indentation(\"Hello\\n World\") // 0\n * indentation(\" \\n Hello\") // 4\n * ```\n */\nexport const indentation = (text: string) => {\n return (\n text.split(\"\\n\").reduce((acc: number | null, line) => {\n if (line.trim() === \"\") return acc;\n const indentation = leadingSpacesCount(line);\n if (acc === null) return indentation;\n return Math.min(acc, indentation);\n }, null) ?? 0\n );\n};\n\n/**\n * Indent each line of the string by a specified number of spaces\n * @param text - The input string to indent\n * @param size - The number of spaces to add at the start of each line\n * @param char - The character to use for indentation (defaults to space)\n * @returns The indented string\n * @example\n * ```typescript\n * indent(\"Hello\\nWorld\", 2) // \" Hello\\n World\"\n * indent(\"A\\nB\", 3, \"-\") // \"---A\\n---B\"\n * ```\n */\nexport const indent = (text: string, size: number, char: string = \" \") => {\n if (size === 0) return text;\n\n const indentStr = char.repeat(size);\n return text\n .split(\"\\n\")\n .map((line) => indentStr + line)\n .join(\"\\n\");\n};\n\n/**\n * Remove indentation from each line of the string\n * @param text - The input string to dedent\n * @param size - Optional number of spaces to remove. If not provided, removes the minimum common indentation\n * @returns The dedented string\n * @example\n * ```typescript\n * dedent(\" Hello\\n World\") // \"Hello\\n World\"\n * dedent(\" A\\n B\", 2) // \" A\\nB\"\n * ```\n */\nexport const dedent = (text: string, size?: number) => {\n const _size = size ?? indentation(text);\n if (_size === 0) return text;\n const regex = new RegExp(`^\\\\s{1,${_size}}`);\n return text\n .split(\"\\n\")\n .map((line) => line.replace(regex, \"\"))\n .join(\"\\n\");\n};\n\n/**\n * Remove a specified number of characters from the end of the string\n * @param text - The input string to process\n * @param count - The number of characters to remove\n * @returns The string with characters removed from the end\n * @example\n * ```typescript\n * chopEnd(\"Hello World\", 6) // \"Hello\"\n * chopEnd(\"Hello\", 0) // \"Hello\"\n * ```\n */\nexport const chopEnd = (text: string, count: number) => {\n if (count === 0) return text;\n return text.slice(0, -count);\n};\n\n/**\n * Remove a specified number of characters from the start of the string\n * @param text - The input string to process\n * @param count - The number of characters to remove\n * @returns The string with characters removed from the start\n * @example\n * ```typescript\n * chopStart(\"Hello World\", 6) // \"World\"\n * chopStart(\"Hello\", 0) // \"Hello\"\n * ```\n */\nexport const chopStart = (text: string, count: number) => {\n if (count === 0) return text;\n return text.slice(count);\n};\n\n/**\n * Limit the number of consecutive newlines in the string\n * @param text - The input string to process\n * @param maxRepeat - The maximum number of consecutive newlines to allow\n * @returns The string with consecutive newlines limited\n * @example\n * ```typescript\n * chopRepeatNewlines(\"A\\n\\n\\n\\nB\", 2) // \"A\\n\\nB\"\n * chopRepeatNewlines(\"A\\n\\nB\", 1) // \"A\\nB\"\n * ```\n */\nexport const chopRepeatNewlines = (text: string, maxRepeat: number) => {\n if (maxRepeat === 0) return text;\n return text.replace(\n new RegExp(`\\n{${maxRepeat + 1},}`, \"g\"),\n \"\\n\".repeat(maxRepeat),\n );\n};\n\n/**\n * Extract a specified number of characters from the start of the string\n * @param text - The input string to process\n * @param count - The number of characters to take\n * @returns The extracted substring from the start\n * @example\n * ```typescript\n * takeStart(\"Hello World\", 5) // \"Hello\"\n * takeStart(\"Hi\", 5) // \"Hi\"\n * ```\n */\nexport const takeStart = (text: string, count: number) => {\n return text.slice(0, count);\n};\n\n/**\n * Extract a specified number of characters from the end of the string\n * @param text - The input string to process\n * @param count - The number of characters to take\n * @returns The extracted substring from the end\n * @example\n * ```typescript\n * takeEnd(\"Hello World\", 5) // \"World\"\n * takeEnd(\"Hi\", 5) // \"Hi\"\n * ```\n */\nexport const takeEnd = (text: string, count: number) => {\n return text.slice(-count);\n};\n\n/**\n * Get the last line of a multi-line string\n * @param text - The input string to process\n * @returns The last line of the string, or empty string if input is empty\n * @example\n * ```typescript\n * lastLine(\"Hello\\nWorld\") // \"World\"\n * lastLine(\"Hello\") // \"Hello\"\n * lastLine(\"\") // \"\"\n * ```\n */\nexport const lastLine = (text: string) => {\n return text.split(\"\\n\").at(-1) ?? \"\";\n};\n\n/**\n * Get the first line of a multi-line string\n * @param text - The input string to process\n * @returns The first line of the string, or empty string if input is empty\n * @example\n * ```typescript\n * firstLine(\"Hello\\nWorld\") // \"Hello\"\n * firstLine(\"Hello\") // \"Hello\"\n * firstLine(\"\") // \"\"\n * ```\n */\nexport const firstLine = (text: string) => {\n return text.split(\"\\n\").at(0) ?? \"\";\n};\n\n/**\n * Count the number of leading space characters in a string\n * @param text - The input string to analyze\n * @returns The number of leading space characters\n * @example\n * ```typescript\n * leadingSpacesCount(\" Hello\") // 2\n * leadingSpacesCount(\"Hello\") // 0\n * ```\n */\nexport const leadingSpacesCount = (text: string) => {\n return text.match(/^\\s+/)?.at(0)?.length ?? 0;\n};\n\n/**\n * Check if a string is empty or contains only whitespace\n * @param text - The input string to check\n * @returns True if the string is empty or contains only whitespace, false otherwise\n * @example\n * ```typescript\n * isEmpty(\"\") // true\n * isEmpty(\" \\n \") // true\n * isEmpty(\"Hello\") // false\n * ```\n */\nexport const isEmpty = (text: string) => {\n return text.trim() === \"\";\n};\n\n/**\n * Replace the first occurrence of a substring or pattern in the string\n * @param text - The input string to process\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the match with\n * @returns The string with the first match replaced\n * @example\n * ```typescript\n * replace(\"Hello World\", \"o\", \"0\") // \"Hell0 World\"\n * replace(\"abc abc\", /[a-z]/, \"X\") // \"Xbc abc\"\n * ```\n */\nexport const replace = (\n text: string,\n searchValue: string | RegExp,\n replaceValue: string,\n) => {\n return text.replace(searchValue, replaceValue);\n};\n\n/**\n * Replace all occurrences of a substring or pattern in the string\n * @param text - The input string to process\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the matches with\n * @returns The string with all matches replaced\n * @example\n * ```typescript\n * replaceAll(\"Hello World\", \"o\", \"0\") // \"Hell0 W0rld\"\n * replaceAll(\"abc abc\", /[a-z]/g, \"X\") // \"XXX XXX\"\n * ```\n */\nexport const replaceAll = (\n text: string,\n searchValue: string | RegExp,\n replaceValue: string,\n) => {\n if (typeof searchValue === \"string\") {\n return text.replaceAll(searchValue, replaceValue);\n }\n // Ensure the RegExp has the global flag\n const flags = searchValue.flags.includes(\"g\")\n ? searchValue.flags\n : searchValue.flags + \"g\";\n const globalRegex = new RegExp(searchValue.source, flags);\n return text.replace(globalRegex, replaceValue);\n};\n"],"mappings":"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","names":["camelCase","capitalCase","constantCase","dotCase","kebabCase","noCase","pascalCase","pascalSnakeCase","pathCase","sentenceCase","snakeCase","trainCase","indentation","indentation"]}
1
+ {"version":3,"sources":["../src/str.index.ts","../src/str.chainable.ts","../src/str.lib.ts"],"sourcesContent":["export {\n camelCase,\n capitalCase,\n constantCase,\n dotCase,\n kebabCase,\n noCase,\n pascalCase,\n pascalSnakeCase,\n pathCase,\n sentenceCase,\n snakeCase,\n trainCase,\n} from \"change-case\";\nexport { Str, str } from \"./str.chainable.ts\";\nexport * from \"./str.lib.ts\";\n","import { Pipeable } from \"@synstack/pipe\";\nimport * as changeCase from \"change-case\";\nimport { type Stringable } from \"../../shared/src/ts.utils.ts\";\nimport * as lib from \"./str.lib.ts\";\n\n/**\n * A chainable string manipulation class that extends Pipeable\n * Provides a fluent interface for string operations with full TypeScript support\n *\n * @example\n * ```typescript\n * import { str } from '@synstack/str'\n *\n * // Basic chaining\n * const result = str('Hello World')\n * .trim()\n * .split(' ')\n * .at(0)\n * .$\n *\n * // Advanced chaining with Pipeable methods\n * const modified = str('hello-world')\n * ._((s) => s.camelCase())\n * ._$((value) => value.toUpperCase())\n * .$\n * ```\n */\nexport class Str extends Pipeable<Str, string> {\n private readonly text: string;\n\n /**\n * Create a new Str instance\n * @param text - The input string to wrap\n * @example\n * ```typescript\n * const s = new Str('Hello World')\n * // or use the convenience function\n * const s = str('Hello World')\n * ```\n */\n public constructor(text: string) {\n super();\n this.text = text.replace(/\\r\\n/g, \"\\n\");\n }\n\n /**\n * Get the underlying string value\n * @returns The wrapped string value\n */\n public valueOf(): string {\n return this.text;\n }\n\n /**\n * Convert the Str instance to a string\n * @returns The wrapped string value\n */\n public toString() {\n return this.text;\n }\n\n /**\n * Get the current Str instance\n * @returns The current Str instance\n * @internal Used by Pipeable\n */\n public instanceOf(): Str {\n return this;\n }\n\n /**\n * Remove empty lines at the start of the text\n * @returns A new Str instance with empty lines removed from the start\n * @example\n * ```typescript\n * str('\\n\\n Hello').chopEmptyLinesStart().$ // ' Hello'\n * ```\n */\n public chopEmptyLinesStart() {\n return new Str(lib.chopEmptyLinesStart(this.text));\n }\n\n /**\n * Remove empty lines at the end of the text\n * @returns A new Str instance with empty lines removed from the end\n * @example\n * ```typescript\n * str('Hello\\n\\n').chopEmptyLinesEnd().$ // 'Hello'\n * ```\n */\n public chopEmptyLinesEnd() {\n return new Str(lib.chopEmptyLinesEnd(this.text));\n }\n\n /**\n * Remove whitespace from empty lines\n * @returns A new Str instance with whitespace removed from empty lines\n * @example\n * ```typescript\n * str('Hello\\n \\nWorld').trimEmptyLines().$ // 'Hello\\n\\nWorld'\n * ```\n */\n public trimEmptyLines() {\n return new Str(lib.trimEmptyLines(this.text));\n }\n\n /**\n * Remove trailing spaces from all lines\n * @returns A new Str instance with trailing spaces removed from all lines\n * @example\n * ```typescript\n * str('Hello \\nWorld ').trimLinesTrailingSpaces().$ // 'Hello\\nWorld'\n * ```\n */\n public trimLinesTrailingSpaces() {\n return new Str(lib.trimLinesTrailingSpaces(this.text));\n }\n\n /**\n * Remove leading and trailing whitespace\n * @returns A new Str instance with whitespace removed from both ends\n * @example\n * ```typescript\n * str(' Hello ').trim().$ // 'Hello'\n * ```\n */\n public trim() {\n return new Str(lib.trim(this.text));\n }\n\n /**\n * Remove leading whitespace\n * @returns A new Str instance with leading whitespace removed\n * @example\n * ```typescript\n * str(' Hello ').trimStart().$ // 'Hello '\n * ```\n */\n public trimStart() {\n return new Str(lib.trimStart(this.text));\n }\n\n /**\n * Remove trailing whitespace\n * @returns A new Str instance with trailing whitespace removed\n * @example\n * ```typescript\n * str(' Hello ').trimEnd().$ // ' Hello'\n * ```\n */\n public trimEnd() {\n return new Str(lib.trimEnd(this.text));\n }\n\n /**\n * Split the string into an array of Str instances\n * @param separator - String or RegExp to split on\n * @param limit - Maximum number of splits to perform\n * @returns Array of Str instances\n * @example\n * ```typescript\n * str('a,b,c').split(',') // [Str('a'), Str('b'), Str('c')]\n * str('a b c').split(' ', 2) // [Str('a'), Str('b')]\n * ```\n */\n public split(separator: string | RegExp, limit?: number) {\n return lib.split(this.text, separator, limit).map((v) => new Str(v));\n }\n\n /**\n * Add line numbers to each line\n * @param separator - String to separate line numbers from content\n * @returns A new Str instance with line numbers added\n * @example\n * ```typescript\n * str('A\\nB').addLineNumbers().$ // '0:A\\n1:B'\n * str('A\\nB').addLineNumbers(' -> ').$ // '0 -> A\\n1 -> B'\n * ```\n */\n public addLineNumbers(separator: string = \":\") {\n return new Str(lib.addLineNumbers(this.text, separator));\n }\n\n /**\n * Get the character at a specific index\n * @param index - Zero-based position in the string\n * @returns The character at the index, or undefined if out of bounds\n * @example\n * ```typescript\n * str('Hello').at(0) // 'H'\n * str('Hello').at(-1) // 'o'\n * ```\n */\n public at(index: number) {\n return this.text.at(index);\n }\n\n /**\n * Get the length of the string\n * @returns The number of characters in the string\n * @example\n * ```typescript\n * str('Hello').length() // 5\n * str('').length() // 0\n * ```\n */\n public length() {\n return this.text.length;\n }\n\n /**\n * Indent each line by a specified number of spaces\n * @param size - Number of spaces to add\n * @param char - Character to use for indentation\n * @returns A new Str instance with added indentation\n * @example\n * ```typescript\n * str('Hello\\nWorld').indent(2).$ // ' Hello\\n World'\n * str('A\\nB').indent(2, '-').$ // '--A\\n--B'\n * ```\n */\n public indent(size: number, char: string = \" \") {\n return new Str(lib.indent(this.text, size, char));\n }\n\n /**\n * Remove indentation from each line\n * @param indentation - Optional number of spaces to remove\n * @returns A new Str instance with indentation removed\n * @example\n * ```typescript\n * str(' Hello\\n World').dedent().$ // 'Hello\\n World'\n * str(' A\\n B').dedent(2).$ // ' A\\nB'\n * ```\n */\n public dedent(indentation?: number) {\n return new Str(lib.dedent(this.text, indentation));\n }\n\n /**\n * Remove characters from the start of the string\n * @param count - Number of characters to remove\n * @returns A new Str instance with characters removed from the start\n * @example\n * ```typescript\n * str('Hello').chopStart(2).$ // 'llo'\n * ```\n */\n public chopStart(count: number) {\n return new Str(lib.chopStart(this.text, count));\n }\n\n /**\n * Remove characters from the end of the string\n * @param count - Number of characters to remove\n * @returns A new Str instance with characters removed from the end\n * @example\n * ```typescript\n * str('Hello').chopEnd(2).$ // 'Hel'\n * ```\n */\n public chopEnd(count: number) {\n if (count === 0) return this;\n return new Str(lib.chopEnd(this.text, count));\n }\n\n /**\n * Limit consecutive newlines to a maximum count\n * @param maxRepeat - Maximum number of consecutive newlines to allow\n * @returns A new Str instance with limited consecutive newlines\n * @example\n * ```typescript\n * str('A\\n\\n\\nB').chopRepeatNewlines(1).$ // 'A\\nB'\n * str('A\\n\\n\\nB').chopRepeatNewlines(2).$ // 'A\\n\\nB'\n * ```\n */\n public chopRepeatNewlines(maxRepeat: number) {\n if (maxRepeat === 0) return this;\n return new Str(lib.chopRepeatNewlines(this.text, maxRepeat));\n }\n\n /**\n * Take characters from the start of the string\n * @param count - Number of characters to take\n * @returns A new Str instance with the first n characters\n * @example\n * ```typescript\n * str('Hello').takeStart(2).$ // 'He'\n * ```\n */\n public takeStart(count: number) {\n return new Str(lib.takeStart(this.text, count));\n }\n\n /**\n * Take characters from the end of the string\n * @param count - Number of characters to take\n * @returns A new Str instance with the last n characters\n * @example\n * ```typescript\n * str('Hello').takeEnd(2).$ // 'lo'\n * ```\n */\n public takeEnd(count: number) {\n return new Str(lib.takeEnd(this.text, count));\n }\n\n /**\n * Get the last line of the string\n * @returns A new Str instance containing the last line\n * @example\n * ```typescript\n * str('Hello\\nWorld').lastLine().$ // 'World'\n * ```\n */\n public lastLine() {\n return new Str(lib.lastLine(this.text));\n }\n\n /**\n * Get the first line of the string\n * @returns A new Str instance containing the first line\n * @example\n * ```typescript\n * str('Hello\\nWorld').firstLine().$ // 'Hello'\n * ```\n */\n public firstLine() {\n return new Str(lib.firstLine(this.text));\n }\n\n /**\n * Count leading space characters\n * @returns The number of leading space characters\n * @example\n * ```typescript\n * str(' Hello').leadingSpacesCount() // 2\n * str('Hello').leadingSpacesCount() // 0\n * ```\n */\n public leadingSpacesCount() {\n return lib.leadingSpacesCount(this.text);\n }\n\n /**\n * Get the minimum indentation level of non-empty lines\n * @returns The number of spaces in the minimum indentation\n * @example\n * ```typescript\n * str(' Hello\\n World').indentation() // 2\n * str('Hello\\n World').indentation() // 0\n * ```\n */\n public indentation() {\n return lib.indentation(this.text);\n }\n\n /**\n * Check if the string is empty or contains only whitespace\n * @returns True if empty or whitespace-only, false otherwise\n * @example\n * ```typescript\n * str('').isEmpty() // true\n * str(' \\n').isEmpty() // true\n * str('Hello').isEmpty() // false\n * ```\n */\n public isEmpty() {\n return lib.isEmpty(this.text);\n }\n\n /**\n * Replace the first occurrence of a substring or pattern\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the match with\n * @returns A new Str instance with the first match replaced\n * @example\n * ```typescript\n * str('Hello World').replace('o', '0').$ // 'Hell0 World'\n * str('abc abc').replace(/[a-z]/, 'X').$ // 'Xbc abc'\n * ```\n */\n public replace(searchValue: string | RegExp, replaceValue: string) {\n return new Str(lib.replace(this.text, searchValue, replaceValue));\n }\n\n /**\n * Replace all occurrences of a substring or pattern\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the matches with\n * @returns A new Str instance with all matches replaced\n * @example\n * ```typescript\n * str('Hello World').replaceAll('o', '0').$ // 'Hell0 W0rld'\n * str('abc abc').replaceAll(/[a-z]/g, 'X').$ // 'XXX XXX'\n * ```\n */\n public replaceAll(searchValue: string | RegExp, replaceValue: string) {\n return new Str(lib.replaceAll(this.text, searchValue, replaceValue));\n }\n\n /**\n * Convert string to camelCase\n * @returns A new Str instance in camelCase\n * @example\n * ```typescript\n * str('hello-world').camelCase().$ // 'helloWorld'\n * ```\n */\n public camelCase() {\n return new Str(changeCase.camelCase(this.text));\n }\n\n /**\n * Convert string to Capital Case\n * @returns A new Str instance in Capital Case\n * @example\n * ```typescript\n * str('hello-world').capitalCase().$ // 'Hello World'\n * ```\n */\n public capitalCase() {\n return new Str(changeCase.capitalCase(this.text));\n }\n\n /**\n * Convert string to CONSTANT_CASE\n * @returns A new Str instance in CONSTANT_CASE\n * @example\n * ```typescript\n * str('hello-world').constantCase().$ // 'HELLO_WORLD'\n * ```\n */\n public constantCase() {\n return new Str(changeCase.constantCase(this.text));\n }\n\n /**\n * Convert string to dot.case\n * @returns A new Str instance in dot.case\n * @example\n * ```typescript\n * str('hello-world').dotCase().$ // 'hello.world'\n * ```\n */\n public dotCase() {\n return new Str(changeCase.dotCase(this.text));\n }\n\n /**\n * Convert string to kebab-case\n * @returns A new Str instance in kebab-case\n * @example\n * ```typescript\n * str('helloWorld').kebabCase().$ // 'hello-world'\n * ```\n */\n public kebabCase() {\n return new Str(changeCase.kebabCase(this.text));\n }\n\n /**\n * Convert string to no case\n * @returns A new Str instance with no case\n * @example\n * ```typescript\n * str('helloWorld').noCase().$ // 'hello world'\n * ```\n */\n public noCase() {\n return new Str(changeCase.noCase(this.text));\n }\n\n /**\n * Convert string to PascalCase\n * @returns A new Str instance in PascalCase\n * @example\n * ```typescript\n * str('hello-world').pascalCase().$ // 'HelloWorld'\n * ```\n */\n public pascalCase() {\n return new Str(changeCase.pascalCase(this.text));\n }\n\n /**\n * Convert string to Pascal_Snake_Case\n * @returns A new Str instance in Pascal_Snake_Case\n * @example\n * ```typescript\n * str('hello-world').pascalSnakeCase().$ // 'Hello_World'\n * ```\n */\n public pascalSnakeCase() {\n return new Str(changeCase.pascalSnakeCase(this.text));\n }\n\n /**\n * Convert string to path/case\n * @returns A new Str instance in path/case\n * @example\n * ```typescript\n * str('hello-world').pathCase().$ // 'hello/world'\n * ```\n */\n public pathCase() {\n return new Str(changeCase.pathCase(this.text));\n }\n\n /**\n * Convert string to Sentence case\n * @returns A new Str instance in Sentence case\n * @example\n * ```typescript\n * str('hello-world').sentenceCase().$ // 'Hello world'\n * ```\n */\n public sentenceCase() {\n return new Str(changeCase.sentenceCase(this.text));\n }\n\n /**\n * Convert string to snake_case\n * @returns A new Str instance in snake_case\n * @example\n * ```typescript\n * str('helloWorld').snakeCase().$ // 'hello_world'\n * ```\n */\n public snakeCase() {\n return new Str(changeCase.snakeCase(this.text));\n }\n\n /**\n * Convert string to Train-Case\n * @returns A new Str instance in Train-Case\n * @example\n * ```typescript\n * str('hello-world').trainCase().$ // 'Hello-World'\n * ```\n */\n public trainCase() {\n return new Str(changeCase.trainCase(this.text));\n }\n\n /**\n * Get the underlying string value\n * @returns The wrapped string value\n * @example\n * ```typescript\n * str('hello').str // 'hello'\n * ```\n */\n public get str() {\n return this.toString();\n }\n}\n\n/**\n * Create a new Str instance from any stringable value\n * @param text - Any value that can be converted to a string\n * @returns A new Str instance wrapping the string value\n * @example\n * ```typescript\n * str('hello') // from string\n * str(123) // from number\n * str({ toString() }) // from object with toString\n * ```\n */\nexport const str = (text: Stringable) => {\n return new Str(text.toString());\n};\n","/**\n * Remove empty lines at the start of the text but leave whitespace on the first line with content\n * @param text - The input string to process\n * @returns The string with empty lines removed from the start\n * @example\n * ```typescript\n * chopEmptyLinesStart(\"\\n\\n \\n Hello\") // \" Hello\"\n * chopEmptyLinesStart(\" Hello\") // \" Hello\"\n * ```\n */\nexport const chopEmptyLinesStart = (text: string) => {\n return text.replace(/^(\\s*\\n)+/, \"\");\n};\n\n/**\n * Remove empty lines at the end of the text but leave whitespace on the last line with content\n * @param text - The input string to process\n * @returns The string with empty lines removed from the end\n * @example\n * ```typescript\n * chopEmptyLinesEnd(\"Hello\\n\\n \\n\") // \"Hello\"\n * chopEmptyLinesEnd(\"Hello \") // \"Hello \"\n * ```\n */\nexport const chopEmptyLinesEnd = (text: string) => {\n return text.replace(/(\\n\\s*)+$/, \"\");\n};\n\n/**\n * Remove all space characters in lines that contain no content\n * @param text - The input string to process\n * @returns The string with whitespace removed from empty lines\n * @example\n * ```typescript\n * trimEmptyLines(\"Hello\\n \\nWorld\") // \"Hello\\n\\nWorld\"\n * trimEmptyLines(\" \\n \\n \") // \"\\n\\n\"\n * ```\n */\nexport const trimEmptyLines = (text: string) => {\n return text.replace(/(^|\\n)\\s+(\\n|$)/g, \"$1$2\");\n};\n\n/**\n * Remove all space characters at the end of each line\n * @param text - The input string to process\n * @returns The string with trailing spaces removed from all lines\n * @example\n * ```typescript\n * trimLinesTrailingSpaces(\"Hello \\nWorld \") // \"Hello\\nWorld\"\n * trimLinesTrailingSpaces(\"Hello \") // \"Hello\"\n * ```\n */\nexport const trimLinesTrailingSpaces = (text: string) => {\n return text.replace(/ +(\\n|$)/g, \"$1\");\n};\n\n/**\n * Remove leading and trailing whitespace and line terminator characters\n * @param text - The input string to process\n * @returns The trimmed string\n * @example\n * ```typescript\n * trim(\" Hello World \") // \"Hello World\"\n * trim(\"\\n Hello \\n\") // \"Hello\"\n * ```\n */\nexport const trim = (text: string) => {\n return text.trim();\n};\n\n/**\n * Remove leading whitespace and line terminator characters\n * @param text - The input string to process\n * @returns The string with leading whitespace removed\n * @example\n * ```typescript\n * trimStart(\" Hello World \") // \"Hello World \"\n * trimStart(\"\\n Hello\") // \"Hello\"\n * ```\n */\nexport const trimStart = (text: string) => {\n return text.trimStart();\n};\n\n/**\n * Remove trailing whitespace and line terminator characters\n * @param text - The input string to process\n * @returns The string with trailing whitespace removed\n * @example\n * ```typescript\n * trimEnd(\" Hello World \") // \" Hello World\"\n * trimEnd(\"Hello \\n\") // \"Hello\"\n * ```\n */\nexport const trimEnd = (text: string) => {\n return text.trimEnd();\n};\n\n/**\n * Split a string into substrings using the specified separator\n * @param text - The input string to split\n * @param separator - The string or regular expression to use for splitting\n * @param limit - Optional limit on the number of splits to perform\n * @returns An array of substrings\n * @example\n * ```typescript\n * split(\"Hello World\", \" \") // [\"Hello\", \"World\"]\n * split(\"a,b,c\", \",\", 2) // [\"a\", \"b\"]\n * split(\"a.b-c\", /[.-]/) // [\"a\", \"b\", \"c\"]\n * ```\n */\nexport const split = (\n text: string,\n separator: string | RegExp,\n limit?: number,\n) => {\n return text.split(separator, limit);\n};\n\n/**\n * Add line numbers to each line in a string\n * @param text - The string to add line numbers to\n * @param separator - The separator between line number and content (defaults to \":\")\n * @returns The string with line numbers added\n * @example\n * ```typescript\n * addLineNumbers(\"Hello\\nWorld\") // \"0:Hello\\n1:World\"\n * addLineNumbers(\"A\\nB\\nC\", \" -> \") // \"0 -> A\\n1 -> B\\n2 -> C\"\n * ```\n */\nexport const addLineNumbers = (text: string, separator: string = \":\") => {\n const lines = text.split(/\\r?\\n/);\n return lines\n .map((line, index) => `${index}${separator}${line}`)\n .join(\"\\n\");\n};\n\n/**\n * Calculate the minimum indentation level of non-empty lines in the string\n * @param text - The input string to analyze\n * @returns The number of spaces in the minimum indentation level, or 0 if no indentation found\n * @example\n * ```typescript\n * indentation(\" Hello\\n World\") // 2\n * indentation(\"Hello\\n World\") // 0\n * indentation(\" \\n Hello\") // 4\n * ```\n */\nexport const indentation = (text: string) => {\n return (\n text.split(/\\r?\\n/).reduce((acc: number | null, line) => {\n if (line.trim() === \"\") return acc;\n const indentation = leadingSpacesCount(line);\n if (acc === null) return indentation;\n return Math.min(acc, indentation);\n }, null) ?? 0\n );\n};\n\n/**\n * Indent each line of the string by a specified number of spaces\n * @param text - The input string to indent\n * @param size - The number of spaces to add at the start of each line\n * @param char - The character to use for indentation (defaults to space)\n * @returns The indented string\n * @example\n * ```typescript\n * indent(\"Hello\\nWorld\", 2) // \" Hello\\n World\"\n * indent(\"A\\nB\", 3, \"-\") // \"---A\\n---B\"\n * ```\n */\nexport const indent = (text: string, size: number, char: string = \" \") => {\n if (size === 0) return text;\n\n const indentStr = char.repeat(size);\n const lines = text.split(/\\r?\\n/);\n return lines\n .map((line) => indentStr + line)\n .join(\"\\n\");\n};\n\n/**\n * Remove indentation from each line of the string\n * @param text - The input string to dedent\n * @param size - Optional number of spaces to remove. If not provided, removes the minimum common indentation\n * @returns The dedented string\n * @example\n * ```typescript\n * dedent(\" Hello\\n World\") // \"Hello\\n World\"\n * dedent(\" A\\n B\", 2) // \" A\\nB\"\n * ```\n */\nexport const dedent = (text: string, size?: number) => {\n const _size = size ?? indentation(text);\n if (_size === 0) return text;\n const regex = new RegExp(`^\\\\s{1,${_size}}`);\n const lines = text.split(/\\r?\\n/);\n return lines\n .map((line) => line.replace(regex, \"\"))\n .join(\"\\n\");\n};\n\n/**\n * Remove a specified number of characters from the end of the string\n * @param text - The input string to process\n * @param count - The number of characters to remove\n * @returns The string with characters removed from the end\n * @example\n * ```typescript\n * chopEnd(\"Hello World\", 6) // \"Hello\"\n * chopEnd(\"Hello\", 0) // \"Hello\"\n * ```\n */\nexport const chopEnd = (text: string, count: number) => {\n if (count === 0) return text;\n return text.slice(0, -count);\n};\n\n/**\n * Remove a specified number of characters from the start of the string\n * @param text - The input string to process\n * @param count - The number of characters to remove\n * @returns The string with characters removed from the start\n * @example\n * ```typescript\n * chopStart(\"Hello World\", 6) // \"World\"\n * chopStart(\"Hello\", 0) // \"Hello\"\n * ```\n */\nexport const chopStart = (text: string, count: number) => {\n if (count === 0) return text;\n return text.slice(count);\n};\n\n/**\n * Limit the number of consecutive newlines in the string\n * @param text - The input string to process\n * @param maxRepeat - The maximum number of consecutive newlines to allow\n * @returns The string with consecutive newlines limited\n * @example\n * ```typescript\n * chopRepeatNewlines(\"A\\n\\n\\n\\nB\", 2) // \"A\\n\\nB\"\n * chopRepeatNewlines(\"A\\n\\nB\", 1) // \"A\\nB\"\n * ```\n */\nexport const chopRepeatNewlines = (text: string, maxRepeat: number) => {\n if (maxRepeat === 0) return text;\n return text.replace(\n new RegExp(`\\n{${maxRepeat + 1},}`, \"g\"),\n \"\\n\".repeat(maxRepeat),\n );\n};\n\n/**\n * Extract a specified number of characters from the start of the string\n * @param text - The input string to process\n * @param count - The number of characters to take\n * @returns The extracted substring from the start\n * @example\n * ```typescript\n * takeStart(\"Hello World\", 5) // \"Hello\"\n * takeStart(\"Hi\", 5) // \"Hi\"\n * ```\n */\nexport const takeStart = (text: string, count: number) => {\n return text.slice(0, count);\n};\n\n/**\n * Extract a specified number of characters from the end of the string\n * @param text - The input string to process\n * @param count - The number of characters to take\n * @returns The extracted substring from the end\n * @example\n * ```typescript\n * takeEnd(\"Hello World\", 5) // \"World\"\n * takeEnd(\"Hi\", 5) // \"Hi\"\n * ```\n */\nexport const takeEnd = (text: string, count: number) => {\n return text.slice(-count);\n};\n\n/**\n * Get the last line of a multi-line string\n * @param text - The input string to process\n * @returns The last line of the string, or empty string if input is empty\n * @example\n * ```typescript\n * lastLine(\"Hello\\nWorld\") // \"World\"\n * lastLine(\"Hello\") // \"Hello\"\n * lastLine(\"\") // \"\"\n * ```\n */\nexport const lastLine = (text: string) => {\n return text.split(/\\r?\\n/).at(-1) ?? \"\";\n};\n\n/**\n * Get the first line of a multi-line string\n * @param text - The input string to process\n * @returns The first line of the string, or empty string if input is empty\n * @example\n * ```typescript\n * firstLine(\"Hello\\nWorld\") // \"Hello\"\n * firstLine(\"Hello\") // \"Hello\"\n * firstLine(\"\") // \"\"\n * ```\n */\nexport const firstLine = (text: string) => {\n return text.split(/\\r?\\n/).at(0) ?? \"\";\n};\n\n/**\n * Count the number of leading space characters in a string\n * @param text - The input string to analyze\n * @returns The number of leading space characters\n * @example\n * ```typescript\n * leadingSpacesCount(\" Hello\") // 2\n * leadingSpacesCount(\"Hello\") // 0\n * ```\n */\nexport const leadingSpacesCount = (text: string) => {\n return text.match(/^\\s+/)?.at(0)?.length ?? 0;\n};\n\n/**\n * Check if a string is empty or contains only whitespace\n * @param text - The input string to check\n * @returns True if the string is empty or contains only whitespace, false otherwise\n * @example\n * ```typescript\n * isEmpty(\"\") // true\n * isEmpty(\" \\n \") // true\n * isEmpty(\"Hello\") // false\n * ```\n */\nexport const isEmpty = (text: string) => {\n return text.trim() === \"\";\n};\n\n/**\n * Replace the first occurrence of a substring or pattern in the string\n * @param text - The input string to process\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the match with\n * @returns The string with the first match replaced\n * @example\n * ```typescript\n * replace(\"Hello World\", \"o\", \"0\") // \"Hell0 World\"\n * replace(\"abc abc\", /[a-z]/, \"X\") // \"Xbc abc\"\n * ```\n */\nexport const replace = (\n text: string,\n searchValue: string | RegExp,\n replaceValue: string,\n) => {\n return text.replace(searchValue, replaceValue);\n};\n\n/**\n * Replace all occurrences of a substring or pattern in the string\n * @param text - The input string to process\n * @param searchValue - The string or pattern to search for\n * @param replaceValue - The string to replace the matches with\n * @returns The string with all matches replaced\n * @example\n * ```typescript\n * replaceAll(\"Hello World\", \"o\", \"0\") // \"Hell0 W0rld\"\n * replaceAll(\"abc abc\", /[a-z]/g, \"X\") // \"XXX XXX\"\n * ```\n */\nexport const replaceAll = (\n text: string,\n searchValue: string | RegExp,\n replaceValue: string,\n) => {\n if (typeof searchValue === \"string\") {\n return text.replaceAll(searchValue, replaceValue);\n }\n // Ensure the RegExp has the global flag\n const flags = searchValue.flags.includes(\"g\")\n ? searchValue.flags\n : searchValue.flags + \"g\";\n const globalRegex = new RegExp(searchValue.source, flags);\n return text.replace(globalRegex, replaceValue);\n};\n"],"mappings":";AAAA;AAAA,EACE,aAAAA;AAAA,EACA,eAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,cAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,aAAAC;AAAA,EACA,aAAAC;AAAA,OACK;;;ACbP,SAAS,gBAAgB;AACzB,YAAY,gBAAgB;;;ACSrB,IAAM,sBAAsB,CAAC,SAAiB;AACnD,SAAO,KAAK,QAAQ,aAAa,EAAE;AACrC;AAYO,IAAM,oBAAoB,CAAC,SAAiB;AACjD,SAAO,KAAK,QAAQ,aAAa,EAAE;AACrC;AAYO,IAAM,iBAAiB,CAAC,SAAiB;AAC9C,SAAO,KAAK,QAAQ,oBAAoB,MAAM;AAChD;AAYO,IAAM,0BAA0B,CAAC,SAAiB;AACvD,SAAO,KAAK,QAAQ,aAAa,IAAI;AACvC;AAYO,IAAM,OAAO,CAAC,SAAiB;AACpC,SAAO,KAAK,KAAK;AACnB;AAYO,IAAM,YAAY,CAAC,SAAiB;AACzC,SAAO,KAAK,UAAU;AACxB;AAYO,IAAM,UAAU,CAAC,SAAiB;AACvC,SAAO,KAAK,QAAQ;AACtB;AAeO,IAAM,QAAQ,CACnB,MACA,WACA,UACG;AACH,SAAO,KAAK,MAAM,WAAW,KAAK;AACpC;AAaO,IAAM,iBAAiB,CAAC,MAAc,YAAoB,QAAQ;AACvE,QAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,SAAO,MACJ,IAAI,CAAC,MAAM,UAAU,GAAG,KAAK,GAAG,SAAS,GAAG,IAAI,EAAE,EAClD,KAAK,IAAI;AACd;AAaO,IAAM,cAAc,CAAC,SAAiB;AAC3C,SACE,KAAK,MAAM,OAAO,EAAE,OAAO,CAAC,KAAoB,SAAS;AACvD,QAAI,KAAK,KAAK,MAAM,GAAI,QAAO;AAC/B,UAAMC,eAAc,mBAAmB,IAAI;AAC3C,QAAI,QAAQ,KAAM,QAAOA;AACzB,WAAO,KAAK,IAAI,KAAKA,YAAW;AAAA,EAClC,GAAG,IAAI,KAAK;AAEhB;AAcO,IAAM,SAAS,CAAC,MAAc,MAAc,OAAe,QAAQ;AACxE,MAAI,SAAS,EAAG,QAAO;AAEvB,QAAM,YAAY,KAAK,OAAO,IAAI;AAClC,QAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,SAAO,MACJ,IAAI,CAAC,SAAS,YAAY,IAAI,EAC9B,KAAK,IAAI;AACd;AAaO,IAAM,SAAS,CAAC,MAAc,SAAkB;AACrD,QAAM,QAAQ,QAAQ,YAAY,IAAI;AACtC,MAAI,UAAU,EAAG,QAAO;AACxB,QAAM,QAAQ,IAAI,OAAO,UAAU,KAAK,GAAG;AAC3C,QAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,SAAO,MACJ,IAAI,CAAC,SAAS,KAAK,QAAQ,OAAO,EAAE,CAAC,EACrC,KAAK,IAAI;AACd;AAaO,IAAM,UAAU,CAAC,MAAc,UAAkB;AACtD,MAAI,UAAU,EAAG,QAAO;AACxB,SAAO,KAAK,MAAM,GAAG,CAAC,KAAK;AAC7B;AAaO,IAAM,YAAY,CAAC,MAAc,UAAkB;AACxD,MAAI,UAAU,EAAG,QAAO;AACxB,SAAO,KAAK,MAAM,KAAK;AACzB;AAaO,IAAM,qBAAqB,CAAC,MAAc,cAAsB;AACrE,MAAI,cAAc,EAAG,QAAO;AAC5B,SAAO,KAAK;AAAA,IACV,IAAI,OAAO;AAAA,GAAM,YAAY,CAAC,MAAM,GAAG;AAAA,IACvC,KAAK,OAAO,SAAS;AAAA,EACvB;AACF;AAaO,IAAM,YAAY,CAAC,MAAc,UAAkB;AACxD,SAAO,KAAK,MAAM,GAAG,KAAK;AAC5B;AAaO,IAAM,UAAU,CAAC,MAAc,UAAkB;AACtD,SAAO,KAAK,MAAM,CAAC,KAAK;AAC1B;AAaO,IAAM,WAAW,CAAC,SAAiB;AACxC,SAAO,KAAK,MAAM,OAAO,EAAE,GAAG,EAAE,KAAK;AACvC;AAaO,IAAM,YAAY,CAAC,SAAiB;AACzC,SAAO,KAAK,MAAM,OAAO,EAAE,GAAG,CAAC,KAAK;AACtC;AAYO,IAAM,qBAAqB,CAAC,SAAiB;AAClD,SAAO,KAAK,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,UAAU;AAC9C;AAaO,IAAM,UAAU,CAAC,SAAiB;AACvC,SAAO,KAAK,KAAK,MAAM;AACzB;AAcO,IAAM,UAAU,CACrB,MACA,aACA,iBACG;AACH,SAAO,KAAK,QAAQ,aAAa,YAAY;AAC/C;AAcO,IAAM,aAAa,CACxB,MACA,aACA,iBACG;AACH,MAAI,OAAO,gBAAgB,UAAU;AACnC,WAAO,KAAK,WAAW,aAAa,YAAY;AAAA,EAClD;AAEA,QAAM,QAAQ,YAAY,MAAM,SAAS,GAAG,IACxC,YAAY,QACZ,YAAY,QAAQ;AACxB,QAAM,cAAc,IAAI,OAAO,YAAY,QAAQ,KAAK;AACxD,SAAO,KAAK,QAAQ,aAAa,YAAY;AAC/C;;;ADzWO,IAAM,MAAN,MAAM,aAAY,SAAsB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYV,YAAY,MAAc;AAC/B,UAAM;AACN,SAAK,OAAO,KAAK,QAAQ,SAAS,IAAI;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,UAAkB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,WAAW;AAChB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,aAAkB;AACvB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,sBAAsB;AAC3B,WAAO,IAAI,KAAQ,oBAAoB,KAAK,IAAI,CAAC;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,oBAAoB;AACzB,WAAO,IAAI,KAAQ,kBAAkB,KAAK,IAAI,CAAC;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,iBAAiB;AACtB,WAAO,IAAI,KAAQ,eAAe,KAAK,IAAI,CAAC;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,0BAA0B;AAC/B,WAAO,IAAI,KAAQ,wBAAwB,KAAK,IAAI,CAAC;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,OAAO;AACZ,WAAO,IAAI,KAAQ,KAAK,KAAK,IAAI,CAAC;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,YAAY;AACjB,WAAO,IAAI,KAAQ,UAAU,KAAK,IAAI,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,UAAU;AACf,WAAO,IAAI,KAAQ,QAAQ,KAAK,IAAI,CAAC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaO,MAAM,WAA4B,OAAgB;AACvD,WAAW,MAAM,KAAK,MAAM,WAAW,KAAK,EAAE,IAAI,CAAC,MAAM,IAAI,KAAI,CAAC,CAAC;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYO,eAAe,YAAoB,KAAK;AAC7C,WAAO,IAAI,KAAQ,eAAe,KAAK,MAAM,SAAS,CAAC;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYO,GAAG,OAAe;AACvB,WAAO,KAAK,KAAK,GAAG,KAAK;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWO,SAAS;AACd,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaO,OAAO,MAAc,OAAe,KAAK;AAC9C,WAAO,IAAI,KAAQ,OAAO,KAAK,MAAM,MAAM,IAAI,CAAC;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYO,OAAOC,cAAsB;AAClC,WAAO,IAAI,KAAQ,OAAO,KAAK,MAAMA,YAAW,CAAC;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWO,UAAU,OAAe;AAC9B,WAAO,IAAI,KAAQ,UAAU,KAAK,MAAM,KAAK,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWO,QAAQ,OAAe;AAC5B,QAAI,UAAU,EAAG,QAAO;AACxB,WAAO,IAAI,KAAQ,QAAQ,KAAK,MAAM,KAAK,CAAC;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYO,mBAAmB,WAAmB;AAC3C,QAAI,cAAc,EAAG,QAAO;AAC5B,WAAO,IAAI,KAAQ,mBAAmB,KAAK,MAAM,SAAS,CAAC;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWO,UAAU,OAAe;AAC9B,WAAO,IAAI,KAAQ,UAAU,KAAK,MAAM,KAAK,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWO,QAAQ,OAAe;AAC5B,WAAO,IAAI,KAAQ,QAAQ,KAAK,MAAM,KAAK,CAAC;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,WAAW;AAChB,WAAO,IAAI,KAAQ,SAAS,KAAK,IAAI,CAAC;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,YAAY;AACjB,WAAO,IAAI,KAAQ,UAAU,KAAK,IAAI,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWO,qBAAqB;AAC1B,WAAW,mBAAmB,KAAK,IAAI;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWO,cAAc;AACnB,WAAW,YAAY,KAAK,IAAI;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYO,UAAU;AACf,WAAW,QAAQ,KAAK,IAAI;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaO,QAAQ,aAA8B,cAAsB;AACjE,WAAO,IAAI,KAAQ,QAAQ,KAAK,MAAM,aAAa,YAAY,CAAC;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaO,WAAW,aAA8B,cAAsB;AACpE,WAAO,IAAI,KAAQ,WAAW,KAAK,MAAM,aAAa,YAAY,CAAC;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,YAAY;AACjB,WAAO,IAAI,KAAe,qBAAU,KAAK,IAAI,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,cAAc;AACnB,WAAO,IAAI,KAAe,uBAAY,KAAK,IAAI,CAAC;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,eAAe;AACpB,WAAO,IAAI,KAAe,wBAAa,KAAK,IAAI,CAAC;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,UAAU;AACf,WAAO,IAAI,KAAe,mBAAQ,KAAK,IAAI,CAAC;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,YAAY;AACjB,WAAO,IAAI,KAAe,qBAAU,KAAK,IAAI,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,SAAS;AACd,WAAO,IAAI,KAAe,kBAAO,KAAK,IAAI,CAAC;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,aAAa;AAClB,WAAO,IAAI,KAAe,sBAAW,KAAK,IAAI,CAAC;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,kBAAkB;AACvB,WAAO,IAAI,KAAe,2BAAgB,KAAK,IAAI,CAAC;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,WAAW;AAChB,WAAO,IAAI,KAAe,oBAAS,KAAK,IAAI,CAAC;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,eAAe;AACpB,WAAO,IAAI,KAAe,wBAAa,KAAK,IAAI,CAAC;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,YAAY;AACjB,WAAO,IAAI,KAAe,qBAAU,KAAK,IAAI,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,YAAY;AACjB,WAAO,IAAI,KAAe,qBAAU,KAAK,IAAI,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,IAAW,MAAM;AACf,WAAO,KAAK,SAAS;AAAA,EACvB;AACF;AAaO,IAAM,MAAM,CAAC,SAAqB;AACvC,SAAO,IAAI,IAAI,KAAK,SAAS,CAAC;AAChC;","names":["camelCase","capitalCase","constantCase","dotCase","kebabCase","noCase","pascalCase","pascalSnakeCase","pathCase","sentenceCase","snakeCase","trainCase","indentation","indentation"]}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "1.2.14",
7
+ "version": "1.3.0",
8
8
  "description": "Advanced chainable string manipulation",
9
9
  "keywords": [
10
10
  "string",
@@ -46,7 +46,7 @@
46
46
  }
47
47
  },
48
48
  "dependencies": {
49
- "@synstack/pipe": "^1.1.16",
49
+ "@synstack/pipe": "^1.1.17",
50
50
  "change-case": "^5.4.4"
51
51
  },
52
52
  "devDependencies": {
@@ -59,5 +59,5 @@
59
59
  "!src/**/*.test.ts",
60
60
  "dist/**/*"
61
61
  ],
62
- "gitHead": "4512f978a98c40c3a17595de5fa15176a105d9c9"
62
+ "gitHead": "285fd0d79bf51776af22872fb3b2e2c7e9ac3b95"
63
63
  }
@@ -40,7 +40,7 @@ export class Str extends Pipeable<Str, string> {
40
40
  */
41
41
  public constructor(text: string) {
42
42
  super();
43
- this.text = text;
43
+ this.text = text.replace(/\r\n/g, "\n");
44
44
  }
45
45
 
46
46
  /**
package/src/str.lib.ts CHANGED
@@ -129,8 +129,8 @@ export const split = (
129
129
  * ```
130
130
  */
131
131
  export const addLineNumbers = (text: string, separator: string = ":") => {
132
- return text
133
- .split("\n")
132
+ const lines = text.split(/\r?\n/);
133
+ return lines
134
134
  .map((line, index) => `${index}${separator}${line}`)
135
135
  .join("\n");
136
136
  };
@@ -148,7 +148,7 @@ export const addLineNumbers = (text: string, separator: string = ":") => {
148
148
  */
149
149
  export const indentation = (text: string) => {
150
150
  return (
151
- text.split("\n").reduce((acc: number | null, line) => {
151
+ text.split(/\r?\n/).reduce((acc: number | null, line) => {
152
152
  if (line.trim() === "") return acc;
153
153
  const indentation = leadingSpacesCount(line);
154
154
  if (acc === null) return indentation;
@@ -173,8 +173,8 @@ export const indent = (text: string, size: number, char: string = " ") => {
173
173
  if (size === 0) return text;
174
174
 
175
175
  const indentStr = char.repeat(size);
176
- return text
177
- .split("\n")
176
+ const lines = text.split(/\r?\n/);
177
+ return lines
178
178
  .map((line) => indentStr + line)
179
179
  .join("\n");
180
180
  };
@@ -194,8 +194,8 @@ export const dedent = (text: string, size?: number) => {
194
194
  const _size = size ?? indentation(text);
195
195
  if (_size === 0) return text;
196
196
  const regex = new RegExp(`^\\s{1,${_size}}`);
197
- return text
198
- .split("\n")
197
+ const lines = text.split(/\r?\n/);
198
+ return lines
199
199
  .map((line) => line.replace(regex, ""))
200
200
  .join("\n");
201
201
  };
@@ -293,7 +293,7 @@ export const takeEnd = (text: string, count: number) => {
293
293
  * ```
294
294
  */
295
295
  export const lastLine = (text: string) => {
296
- return text.split("\n").at(-1) ?? "";
296
+ return text.split(/\r?\n/).at(-1) ?? "";
297
297
  };
298
298
 
299
299
  /**
@@ -308,7 +308,7 @@ export const lastLine = (text: string) => {
308
308
  * ```
309
309
  */
310
310
  export const firstLine = (text: string) => {
311
- return text.split("\n").at(0) ?? "";
311
+ return text.split(/\r?\n/).at(0) ?? "";
312
312
  };
313
313
 
314
314
  /**