@visulima/string 3.0.0-alpha.1 → 3.0.0-alpha.10

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.
Files changed (83) hide show
  1. package/CHANGELOG.md +140 -0
  2. package/LICENSE.md +429 -1
  3. package/README.md +72 -20
  4. package/dist/align-text.d.ts +7 -10
  5. package/dist/align-text.js +7 -5
  6. package/dist/case/camel-case.d.ts +3 -5
  7. package/dist/case/camel-case.js +7 -7
  8. package/dist/case/capital-case.d.ts +3 -5
  9. package/dist/case/capital-case.js +3 -3
  10. package/dist/case/constant-case.d.ts +3 -5
  11. package/dist/case/dot-case.d.ts +3 -5
  12. package/dist/case/flat-case.d.ts +3 -5
  13. package/dist/case/flip-case.d.ts +4 -7
  14. package/dist/case/flip-case.js +8 -2
  15. package/dist/case/identify-case.d.ts +3 -5
  16. package/dist/case/identify-case.js +2 -1
  17. package/dist/case/index.d.ts +23 -25
  18. package/dist/case/index.js +1 -1
  19. package/dist/case/kebab-case.d.ts +6 -9
  20. package/dist/case/kebab-case.js +3 -3
  21. package/dist/case/lower-first.d.ts +3 -5
  22. package/dist/case/no-case.d.ts +3 -5
  23. package/dist/case/pascal-case.d.ts +3 -5
  24. package/dist/case/pascal-case.js +3 -3
  25. package/dist/case/pascal-snake-case.d.ts +3 -5
  26. package/dist/case/path-case.d.ts +3 -5
  27. package/dist/case/sentence-case.d.ts +3 -5
  28. package/dist/case/sentence-case.js +7 -7
  29. package/dist/case/snake-case.d.ts +3 -5
  30. package/dist/case/split-by-case.d.ts +11 -14
  31. package/dist/case/split-by-case.js +171 -52
  32. package/dist/case/title-case.d.ts +3 -5
  33. package/dist/case/title-case.js +3 -5
  34. package/dist/case/train-case.d.ts +3 -5
  35. package/dist/case/train-case.js +1 -1
  36. package/dist/case/upper-first.d.ts +3 -5
  37. package/dist/closest-string.d.ts +3 -5
  38. package/dist/closest-string.js +5 -8
  39. package/dist/compare-similarity.d.ts +3 -5
  40. package/dist/compare-similarity.js +2 -2
  41. package/dist/get-string-truncated-width.d.ts +18 -20
  42. package/dist/get-string-truncated-width.js +2 -33
  43. package/dist/get-string-width.d.ts +2 -5
  44. package/dist/index.d.ts +49 -45
  45. package/dist/index.js +12 -4
  46. package/dist/native-string-types.d.ts +145 -128
  47. package/dist/outdent.d.ts +9 -11
  48. package/dist/outdent.js +7 -15
  49. package/dist/packem_shared/closestN-DUsjgiXb.js +25 -0
  50. package/dist/packem_shared/{constants-CTzC6Gjg.js → constants-BsZS5f0z.js} +1 -1
  51. package/dist/packem_shared/countOccurrences-CS9XprQN.js +22 -0
  52. package/dist/packem_shared/direction-C9gfWWTK.js +16 -0
  53. package/dist/packem_shared/eastAsianWidthType-SD3YniiT.js +20 -0
  54. package/dist/packem_shared/excerpt-COsVNttN.js +1502 -0
  55. package/dist/packem_shared/indent-D3DSCa6s.js +33 -0
  56. package/dist/packem_shared/isFullwidthCodePoint-IFXZxNjq.js +10 -0
  57. package/dist/packem_shared/{joinSegments-CuU8RGpP.js → joinSegments-CvxSgKz0.js} +1 -1
  58. package/dist/packem_shared/lookup-BE8lEqy4.js +104 -0
  59. package/dist/packem_shared/lru-cache.d-BsP6kbVJ.d.ts +13 -0
  60. package/dist/packem_shared/{normalize-german-eszett-DEB8-ZPT.js → normalize-german-eszett-4p3yKEzn.js} +2 -1
  61. package/dist/packem_shared/redent-DSb1IJWn.js +8 -0
  62. package/dist/packem_shared/{replaceString-vYvRBMfC.js → replaceString-Ce8X2ZQ-.js} +19 -17
  63. package/dist/packem_shared/stripIndent-D_TRjxZ_.js +20 -0
  64. package/dist/packem_shared/{transliterate-CYnKKT8f.js → transliterate-CKt9VK7D.js} +10 -12
  65. package/dist/packem_shared/{types-Daae0hGf.d.ts → types.d-BVNv675q.d.ts} +18 -21
  66. package/dist/packem_shared/{types-CfPsw9ix.d.ts → types.d-DfgbcNKh.d.ts} +19 -21
  67. package/dist/slice.d.ts +5 -8
  68. package/dist/slice.js +9 -7
  69. package/dist/slugify.d.ts +1 -3
  70. package/dist/slugify.js +1 -1
  71. package/dist/test/utils.d.ts +20 -22
  72. package/dist/test/utils.js +2 -2
  73. package/dist/test/vitest.d.ts +3 -6
  74. package/dist/truncate.d.ts +7 -10
  75. package/dist/truncate.js +49 -26
  76. package/dist/utilities.d.ts +2 -4
  77. package/dist/utilities.js +6 -8
  78. package/dist/word-similarity-sort.d.ts +3 -5
  79. package/dist/word-wrap.d.ts +9 -11
  80. package/dist/word-wrap.js +37 -35
  81. package/package.json +2 -2
  82. package/dist/packem_shared/closestN-BREy4E7C.js +0 -19
  83. package/dist/packem_shared/lru-cache-B_t27XwI.d.ts +0 -14
package/README.md CHANGED
@@ -55,13 +55,23 @@
55
55
  - Split by separators (foo-bar → ["foo", "bar"])
56
56
  - Preserve known acronyms (XMLHttpRequest → ["XML", "Http", "Request"])
57
57
  - **Text Indentation**:
58
- - `outdent`: Remove leading indentation while preserving relative indentation
59
- - Handles template literals and string inputs
58
+ - `indent`: Add indentation to each line in a string
59
+ - `stripIndent`: Strip common leading whitespace from all lines
60
+ - `dedent`: Strip indent and trim leading/trailing blank lines
61
+ - `redent`: Strip redundant indentation and re-indent
62
+ - `outdent`: Remove indentation from template literals
60
63
  - Normalizes newlines across platforms
61
64
  - Configurable trimming behavior
65
+ - **String Analysis**:
66
+ - `countOccurrences`: Count occurrences of a substring in a string
67
+ - `direction`: Detect text direction (left-to-right, right-to-left, or neutral)
68
+ - Unicode-aware and handles multi-byte characters
62
69
  - **String Width Calculation**:
63
70
  - `getStringWidth`: Calculate visual width of strings with Unicode support
64
71
  - `getStringTruncatedWidth`: Width calculation with smart truncation
72
+ - `isFullwidthCodePoint`: Check if a code point is fullwidth
73
+ - `eastAsianWidth`: Get character width (1 or 2) for a code point
74
+ - `eastAsianWidthType`: Get East Asian Width category for a code point
65
75
  - Handles CJK characters, emojis, ANSI codes, and more
66
76
  - Configurable character width settings
67
77
  - Support for zero-width and combining characters
@@ -133,6 +143,25 @@
133
143
 
134
144
  ---
135
145
 
146
+ ## Documentation
147
+
148
+ Comprehensive documentation is available in the [`docs/`](./docs/) directory. The documentation includes:
149
+
150
+ - **[Getting Started](./docs/index.mdx)** - Overview and quick start guide
151
+ - **[Installation](./docs/installation.mdx)** - Installation instructions and setup
152
+ - **[Case Conversion](./docs/case-conversion.mdx)** - Case conversion utilities (camelCase, PascalCase, etc.)
153
+ - **[String Manipulation](./docs/string-manipulation.mdx)** - Text formatting, truncation, wrapping, and alignment
154
+ - **[Slugification](./docs/slugification.mdx)** - URL slug generation and transliteration
155
+ - **[String Width](./docs/string-width.mdx)** - Visual width calculation for Unicode strings
156
+ - **[String Similarity](./docs/string-similarity.mdx)** - String comparison and similarity algorithms
157
+ - **[Testing](./docs/testing.mdx)** - Testing utilities for ANSI strings
158
+ - **[TypeScript](./docs/typescript.mdx)** - TypeScript support and type definitions
159
+ - **[API Reference](./docs/api.mdx)** - Complete API reference
160
+
161
+ The documentation follows the [fumadocs.dev](https://fumadocs.dev) markdown format and can be integrated into your documentation site.
162
+
163
+ ---
164
+
136
165
  ## Install
137
166
 
138
167
  ```sh
@@ -373,6 +402,42 @@ splitByCase("🎉HappyBirthday🎂", {
373
402
  // ['🎉', 'Happy', 'Birthday', '🎂']
374
403
  ```
375
404
 
405
+ ### String Analysis
406
+
407
+ The `countOccurrences` function counts how many times a substring appears in a string, with full Unicode support:
408
+
409
+ ```typescript
410
+ import { countOccurrences } from "@visulima/string";
411
+
412
+ // Basic counting
413
+ countOccurrences("foo", "o"); // 2
414
+ countOccurrences("fo fooo fo", "o"); // 5
415
+
416
+ // Unicode support
417
+ countOccurrences("a🤔b🤔c", "🤔"); // 2
418
+
419
+ // Empty string handling
420
+ countOccurrences("", "f"); // 0
421
+ ```
422
+
423
+ The `direction` function detects text direction for internationalization:
424
+
425
+ ```typescript
426
+ import { direction } from "@visulima/string";
427
+
428
+ // Left-to-right languages
429
+ direction("english"); // 'ltr'
430
+ direction("Hello World"); // 'ltr'
431
+
432
+ // Right-to-left languages
433
+ direction("الجملة"); // 'rtl' (Arabic)
434
+ direction("נ"); // 'rtl' (Hebrew)
435
+
436
+ // Neutral (numbers, symbols, empty)
437
+ direction("123"); // 'neutral'
438
+ direction(""); // 'neutral'
439
+ ```
440
+
376
441
  ### Case Conversion Functions
377
442
 
378
443
  #### camelCase
@@ -815,19 +880,16 @@ paddedStr.trimEnd<typeof paddedStr>(); // type: ' hello'
815
880
  These enhanced types provide several benefits:
816
881
 
817
882
  1. **Compile-Time Type Safety**:
818
-
819
883
  - Catch type errors before runtime
820
884
  - Get accurate type inference for method results
821
885
  - Validate string operations at compile time
822
886
 
823
887
  2. **Better IDE Support**:
824
-
825
888
  - Improved autocompletion
826
889
  - More accurate type hints
827
890
  - Better refactoring support
828
891
 
829
892
  3. **Type-Level String Manipulation**:
830
-
831
893
  - Perform string operations at the type level
832
894
  - Get literal type results for string operations
833
895
  - Chain operations with type safety
@@ -1072,7 +1134,7 @@ const alignedEmojiText = alignText(emojiText, {
1072
1134
  align: "center",
1073
1135
  split: "*",
1074
1136
  pad: "-",
1075
- stringWidthOptions: { emojiWidth: 2 } // Crucial for correct width calculation with emojis
1137
+ stringWidthOptions: { emojiWidth: 2 }, // Crucial for correct width calculation with emojis
1076
1138
  });
1077
1139
  // alignedEmojiText (string output, exact padding depends on calculated widths):
1078
1140
  // "--Line1😊---\nWiderLine😊😊"
@@ -1082,10 +1144,10 @@ const alignedEmojiText = alignText(emojiText, {
1082
1144
 
1083
1145
  The `alignText` function accepts an `options` object of type `AlignTextOptions` with the following properties:
1084
1146
 
1085
- - `align?: "center" | "left" | "right"`: Specifies the alignment direction. Defaults to `"center"`. Note: `left` alignment primarily ensures line splitting if `text` is a single string; it doesn't typically add padding on the left unless the string was not pre-split.
1086
- - `pad?: string`: The character or string to use for padding. Defaults to `" "`.
1087
- - `split?: string`: The character or string used to split the input `text` into multiple lines if it's provided as a single string. Defaults to `"\n"`.
1088
- - `stringWidthOptions?: StringWidthOptions`: Options passed to an internal string width calculation function (similar to `getStringWidth`) for determining the visual width of each line. This is important for accurately handling ANSI escape codes, CJK characters, emojis, etc. Refer to the `getStringWidth` documentation for details on `StringWidthOptions`.
1147
+ - `align?: "center" | "left" | "right"`: Specifies the alignment direction. Defaults to `"center"`. Note: `left` alignment primarily ensures line splitting if `text` is a single string; it doesn't typically add padding on the left unless the string was not pre-split.
1148
+ - `pad?: string`: The character or string to use for padding. Defaults to `" "`.
1149
+ - `split?: string`: The character or string used to split the input `text` into multiple lines if it's provided as a single string. Defaults to `"\n"`.
1150
+ - `stringWidthOptions?: StringWidthOptions`: Options passed to an internal string width calculation function (similar to `getStringWidth`) for determining the visual width of each line. This is important for accurately handling ANSI escape codes, CJK characters, emojis, etc. Refer to the `getStringWidth` documentation for details on `StringWidthOptions`.
1089
1151
 
1090
1152
  ## Related
1091
1153
 
@@ -1132,22 +1194,12 @@ The visulima string is open-sourced software licensed under the [MIT][license]
1132
1194
  <!-- badges -->
1133
1195
 
1134
1196
  [license-badge]: https://img.shields.io/npm/l/@visulima/string?style=for-the-badge
1135
-
1136
1197
  [license]: https://github.com/visulima/visulima/blob/main/LICENSE
1137
-
1138
1198
  [npm-downloads-badge]: https://img.shields.io/npm/dm/@visulima/string?style=for-the-badge
1139
-
1140
1199
  [npm-downloads]: https://www.npmjs.com/package/@visulima/string
1141
-
1142
1200
  [prs-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge
1143
-
1144
1201
  [prs-welcome]: https://github.com/visulima/visulima/blob/main/.github/CONTRIBUTING.md
1145
-
1146
1202
  [chat-badge]: https://img.shields.io/discord/932323359193186354.svg?style=for-the-badge
1147
-
1148
1203
  [chat]: https://discord.gg/TtFJY8xkFK
1149
-
1150
1204
  [typescript-badge]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
1151
-
1152
1205
  [typescript-url]: https://www.typescriptlang.org/
1153
-
@@ -1,13 +1,10 @@
1
- import { StringWidthOptions } from './get-string-width.js';
2
- import './get-string-truncated-width.js';
3
-
1
+ import { StringWidthOptions } from "./get-string-width.js";
2
+ import "./get-string-truncated-width.js";
4
3
  type AlignTextOptions = {
5
- align?: "center" | "left" | "right";
6
- pad?: string;
7
- split?: string;
8
- stringWidthOptions?: StringWidthOptions;
4
+ align?: "center" | "left" | "right";
5
+ pad?: string;
6
+ split?: string;
7
+ stringWidthOptions?: StringWidthOptions;
9
8
  };
10
9
  declare const alignText: (text: string[] | string, options?: AlignTextOptions) => string[] | string;
11
-
12
- export { alignText };
13
- export type { AlignTextOptions };
10
+ export { AlignTextOptions, alignText };
@@ -11,14 +11,16 @@ const alignText = (text, options = {}) => {
11
11
  const pad = options.pad ?? " ";
12
12
  const widthDiffFunction = align === "right" ? fullDiff : halfDiff;
13
13
  let returnString = false;
14
- if (!Array.isArray(text)) {
14
+ let lines;
15
+ if (Array.isArray(text)) {
16
+ lines = text;
17
+ } else {
15
18
  returnString = true;
16
- text = String(text).split(split);
19
+ lines = text.split(split);
17
20
  }
18
21
  let width;
19
22
  let maxWidth = 0;
20
- text = text.map((input) => {
21
- input = String(input);
23
+ const result = lines.map((input) => {
22
24
  width = getStringWidth(input, options.stringWidthOptions);
23
25
  maxWidth = Math.max(width, maxWidth);
24
26
  return {
@@ -26,7 +28,7 @@ const alignText = (text, options = {}) => {
26
28
  width
27
29
  };
28
30
  }).map((object) => Array.from({ length: widthDiffFunction(maxWidth, object.width) + 1 }).join(pad) + object.str);
29
- return returnString ? text.join(split) : text;
31
+ return returnString ? result.join(split) : result;
30
32
  };
31
33
 
32
34
  export { alignText };
@@ -1,7 +1,5 @@
1
- import { C as CaseOptions, a as CamelCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { C as CaseOptions, a as CamelCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  declare const camelCase: <T extends string = string>(value?: T, options?: CaseOptions) => CamelCase<T>;
6
-
7
5
  export { camelCase as default };
@@ -1,11 +1,11 @@
1
- import { R as RE_FAST_ANSI } from '../packem_shared/constants-CTzC6Gjg.js';
1
+ import { R as RE_FAST_ANSI } from '../packem_shared/constants-BsZS5f0z.js';
2
2
  import LRUCache from '../packem_shared/LRUCache-3r3SovvR.js';
3
3
  import lowerFirst from './lower-first.js';
4
4
  import { splitByCase } from './split-by-case.js';
5
5
  import upperFirst from './upper-first.js';
6
6
  import { g as generateCacheKey } from '../packem_shared/generate-cache-key-DdayDfjV.js';
7
- import joinSegments from '../packem_shared/joinSegments-CuU8RGpP.js';
8
- import { n as normalizeGermanEszett } from '../packem_shared/normalize-german-eszett-DEB8-ZPT.js';
7
+ import joinSegments from '../packem_shared/joinSegments-CvxSgKz0.js';
8
+ import { n as normalizeGermanEszett } from '../packem_shared/normalize-german-eszett-4p3yKEzn.js';
9
9
 
10
10
  const defaultCacheStore = new LRUCache(1e3);
11
11
  const camelCase = (value, options) => {
@@ -36,13 +36,13 @@ const camelCase = (value, options) => {
36
36
  if (options?.handleAnsi && RE_FAST_ANSI.test(word)) {
37
37
  return word;
38
38
  }
39
- word = options?.locale?.startsWith("de") ? normalizeGermanEszett(word) : word;
40
- word = options?.locale ? word.toLocaleLowerCase(options.locale) : word.toLowerCase();
39
+ const normalized = options?.locale?.startsWith("de") ? normalizeGermanEszett(word) : word;
40
+ const lowered = options?.locale ? normalized.toLocaleLowerCase(options.locale) : normalized.toLowerCase();
41
41
  if (firstWord) {
42
42
  firstWord = false;
43
- return lowerFirst(word, options);
43
+ return lowerFirst(lowered, options);
44
44
  }
45
- return upperFirst(word, options);
45
+ return upperFirst(lowered, options);
46
46
  }),
47
47
  ""
48
48
  );
@@ -1,7 +1,5 @@
1
- import { C as CaseOptions, b as CapitalCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { C as CaseOptions, b as CapitalCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  declare const capitalCase: <T extends string = string>(value?: T, options?: CaseOptions) => CapitalCase<T>;
6
-
7
5
  export { capitalCase as default };
@@ -1,10 +1,10 @@
1
- import { R as RE_FAST_ANSI } from '../packem_shared/constants-CTzC6Gjg.js';
1
+ import { R as RE_FAST_ANSI } from '../packem_shared/constants-BsZS5f0z.js';
2
2
  import LRUCache from '../packem_shared/LRUCache-3r3SovvR.js';
3
3
  import { splitByCase } from './split-by-case.js';
4
4
  import upperFirst from './upper-first.js';
5
5
  import { g as generateCacheKey } from '../packem_shared/generate-cache-key-DdayDfjV.js';
6
- import joinSegments from '../packem_shared/joinSegments-CuU8RGpP.js';
7
- import { n as normalizeGermanEszett } from '../packem_shared/normalize-german-eszett-DEB8-ZPT.js';
6
+ import joinSegments from '../packem_shared/joinSegments-CvxSgKz0.js';
7
+ import { n as normalizeGermanEszett } from '../packem_shared/normalize-german-eszett-4p3yKEzn.js';
8
8
 
9
9
  const defaultCacheStore = new LRUCache(1e3);
10
10
  const capitalCase = (value, options) => {
@@ -1,7 +1,5 @@
1
- import { C as CaseOptions, c as ConstantCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { C as CaseOptions, c as ConstantCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  declare const constantCase: <T extends string = string>(value?: T, options?: CaseOptions) => ConstantCase<T>;
6
-
7
5
  export { constantCase as default };
@@ -1,7 +1,5 @@
1
- import { C as CaseOptions, D as DotCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { C as CaseOptions, D as DotCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  declare const dotCase: <T extends string = string>(value?: T, options?: CaseOptions) => DotCase<T>;
6
-
7
5
  export { dotCase as default };
@@ -1,7 +1,5 @@
1
- import { C as CaseOptions, F as FlatCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { C as CaseOptions, F as FlatCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  declare const flatCase: <T extends string = string>(value?: T, options?: CaseOptions) => FlatCase<T>;
6
-
7
5
  export { flatCase as default };
@@ -1,9 +1,6 @@
1
- import { C as CaseOptions, d as FlipCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { C as CaseOptions, d as FlipCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  type FlipOptions = Omit<CaseOptions, "handleEmoji">;
6
5
  declare const flipCase: <T extends string = string>(value?: T, options?: FlipOptions) => FlipCase<T>;
7
-
8
- export { flipCase };
9
- export type { FlipOptions };
6
+ export { FlipOptions, flipCase };
@@ -20,7 +20,7 @@ const __cjs_getBuiltinModule = (module) => {
20
20
  const {
21
21
  stripVTControlCharacters
22
22
  } = __cjs_getBuiltinModule("node:util");
23
- import { s as stripEmoji } from '../packem_shared/constants-CTzC6Gjg.js';
23
+ import { s as stripEmoji } from '../packem_shared/constants-BsZS5f0z.js';
24
24
  import LRUCache from '../packem_shared/LRUCache-3r3SovvR.js';
25
25
  import { g as generateCacheKey } from '../packem_shared/generate-cache-key-DdayDfjV.js';
26
26
 
@@ -64,7 +64,13 @@ const flipCase = (value, options) => {
64
64
  }
65
65
  const char = processedValue[index];
66
66
  const lowerChar = options?.locale ? char.toLocaleLowerCase(options.locale) : char.toLowerCase();
67
- result += char === lowerChar ? options?.locale ? char.toLocaleUpperCase(options.locale) : char.toUpperCase() : lowerChar;
67
+ let flippedChar;
68
+ if (char === lowerChar) {
69
+ flippedChar = options?.locale ? char.toLocaleUpperCase(options.locale) : char.toUpperCase();
70
+ } else {
71
+ flippedChar = lowerChar;
72
+ }
73
+ result += flippedChar;
68
74
  index += 1;
69
75
  }
70
76
  if (shouldCache && cacheKey) {
@@ -1,7 +1,5 @@
1
- import { I as IdentifyCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { I as IdentifyCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  declare const identifyCase: <T extends string = string>(value?: T) => IdentifyCase<T>;
6
-
7
5
  export { identifyCase as default };
@@ -8,6 +8,7 @@ const IS_UPPERCASE = /^[A-Z][A-Z0-9]*$/;
8
8
  const WHITESPACE_REGEX = /\s+/;
9
9
  const IS_NUMERIC = /^\d+$/;
10
10
  const IS_CAMEL_CASE_LIKE = /^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)+$/;
11
+ const IS_LOWERCASE_START = /^[a-z]/;
11
12
  const CONTAINS_PUNCTUATION_MID_WORD = /[.!?;:,](?!\s|$)/;
12
13
  const identifyCase = (value) => {
13
14
  if (typeof value !== "string") {
@@ -47,7 +48,7 @@ const identifyCase = (value) => {
47
48
  if (words.length > 1 && IS_NUMERIC.test(words[0]) && IS_PASCAL_CASE.test(words[1])) {
48
49
  return "title";
49
50
  }
50
- if (words.length > 1 && IS_PASCAL_CASE.test(words[0]) && /^[a-z]/.test(words[1])) {
51
+ if (words.length > 1 && IS_PASCAL_CASE.test(words[0]) && IS_LOWERCASE_START.test(words[1])) {
51
52
  return "sentence";
52
53
  }
53
54
  if (IS_PASCAL_CASE.test(value)) {
@@ -1,26 +1,24 @@
1
- export { N as NodeLocale } from '../packem_shared/types-Daae0hGf.js';
2
- export { default as camelCase } from './camel-case.js';
3
- export { default as capitalCase } from './capital-case.js';
4
- export { default as constantCase } from './constant-case.js';
5
- export { default as dotCase } from './dot-case.js';
6
- export { default as flatCase } from './flat-case.js';
7
- export { FlipOptions, flipCase } from './flip-case.js';
8
- export { default as identifyCase } from './identify-case.js';
9
- export { KebabCaseOptions, kebabCase } from './kebab-case.js';
10
- export { default as lowerFirst } from './lower-first.js';
11
- export { default as noCase } from './no-case.js';
12
- export { default as pascalCase } from './pascal-case.js';
13
- export { default as pascalSnakeCase } from './pascal-snake-case.js';
14
- export { default as pathCase } from './path-case.js';
15
- export { default as sentenceCase } from './sentence-case.js';
16
- export { default as snakeCase } from './snake-case.js';
17
- export { SplitOptions, splitByCase } from './split-by-case.js';
18
- export { default as titleCase } from './title-case.js';
19
- export { default as trainCase } from './train-case.js';
20
- export { a as CamelCase, b as CapitalCase, C as CaseOptions, c as ConstantCase, D as DotCase, F as FlatCase, d as FlipCase, I as IdentifyCase, K as KebabCase, L as LocaleOptions, e as LowerFirst, N as NoCase, P as PascalCase, f as PascalSnakeCase, g as PathCase, S as SentenceCase, h as SnakeCase, i as SplitByCase, T as TitleCase, j as TrainCase, U as UpperFirst } from '../packem_shared/types-CfPsw9ix.js';
21
- export { default as upperFirst } from './upper-first.js';
22
- import '../packem_shared/lru-cache-B_t27XwI.js';
23
-
24
- declare const joinSegments: <T extends string = string>(segments: string[], joiner: string) => T;
25
-
1
+ export { type N as NodeLocale } from "../packem_shared/types.d-BVNv675q.js";
2
+ export { default as camelCase } from "./camel-case.js";
3
+ export { default as capitalCase } from "./capital-case.js";
4
+ export { default as constantCase } from "./constant-case.js";
5
+ export { default as dotCase } from "./dot-case.js";
6
+ export { default as flatCase } from "./flat-case.js";
7
+ export { type FlipOptions, flipCase } from "./flip-case.js";
8
+ export { default as identifyCase } from "./identify-case.js";
9
+ export { type KebabCaseOptions, kebabCase } from "./kebab-case.js";
10
+ export { default as lowerFirst } from "./lower-first.js";
11
+ export { default as noCase } from "./no-case.js";
12
+ export { default as pascalCase } from "./pascal-case.js";
13
+ export { default as pascalSnakeCase } from "./pascal-snake-case.js";
14
+ export { default as pathCase } from "./path-case.js";
15
+ export { default as sentenceCase } from "./sentence-case.js";
16
+ export { default as snakeCase } from "./snake-case.js";
17
+ export { type SplitOptions, splitByCase } from "./split-by-case.js";
18
+ export { default as titleCase } from "./title-case.js";
19
+ export { default as trainCase } from "./train-case.js";
20
+ export { type a as CamelCase, type b as CapitalCase, type C as CaseOptions, type c as ConstantCase, type D as DotCase, type F as FlatCase, type d as FlipCase, type I as IdentifyCase, type K as KebabCase, type L as LocaleOptions, type e as LowerFirst, type N as NoCase, type P as PascalCase, type f as PascalSnakeCase, type g as PathCase, type S as SentenceCase, type h as SnakeCase, type i as SplitByCase, type T as TitleCase, type j as TrainCase, type U as UpperFirst } from "../packem_shared/types.d-DfgbcNKh.js";
21
+ export { default as upperFirst } from "./upper-first.js";
22
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
23
+ declare const joinSegments: (segments: string[], joiner: string) => string;
26
24
  export { joinSegments };
@@ -17,4 +17,4 @@ export { splitByCase } from './split-by-case.js';
17
17
  export { default as titleCase } from './title-case.js';
18
18
  export { default as trainCase } from './train-case.js';
19
19
  export { default as upperFirst } from './upper-first.js';
20
- export { default as joinSegments } from '../packem_shared/joinSegments-CuU8RGpP.js';
20
+ export { default as joinSegments } from '../packem_shared/joinSegments-CvxSgKz0.js';
@@ -1,12 +1,9 @@
1
- import { C as CaseOptions, K as KebabCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { C as CaseOptions, K as KebabCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  interface KebabCaseOptions extends CaseOptions {
6
- joiner?: string;
7
- toUpperCase?: boolean;
5
+ joiner?: string;
6
+ toUpperCase?: boolean;
8
7
  }
9
8
  declare const kebabCase: <T extends string = string>(value?: T, options?: KebabCaseOptions) => KebabCase<T>;
10
-
11
- export { kebabCase };
12
- export type { KebabCaseOptions };
9
+ export { KebabCaseOptions, kebabCase };
@@ -1,9 +1,9 @@
1
- import { R as RE_FAST_ANSI } from '../packem_shared/constants-CTzC6Gjg.js';
1
+ import { R as RE_FAST_ANSI } from '../packem_shared/constants-BsZS5f0z.js';
2
2
  import LRUCache from '../packem_shared/LRUCache-3r3SovvR.js';
3
3
  import { splitByCase } from './split-by-case.js';
4
4
  import { g as generateCacheKey } from '../packem_shared/generate-cache-key-DdayDfjV.js';
5
- import joinSegments from '../packem_shared/joinSegments-CuU8RGpP.js';
6
- import { n as normalizeGermanEszett } from '../packem_shared/normalize-german-eszett-DEB8-ZPT.js';
5
+ import joinSegments from '../packem_shared/joinSegments-CvxSgKz0.js';
6
+ import { n as normalizeGermanEszett } from '../packem_shared/normalize-german-eszett-4p3yKEzn.js';
7
7
 
8
8
  const defaultCacheStore = new LRUCache(1e3);
9
9
  const kebabCase = (value, options) => {
@@ -1,7 +1,5 @@
1
- import { L as LocaleOptions, e as LowerFirst } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { L as LocaleOptions, e as LowerFirst } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  declare const lowerFirst: <T extends string = string>(value?: T, options?: LocaleOptions) => LowerFirst<T>;
6
-
7
5
  export { lowerFirst as default };
@@ -1,7 +1,5 @@
1
- import { C as CaseOptions, N as NoCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { C as CaseOptions, N as NoCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  declare const noCase: <T extends string = string>(value?: T, options?: CaseOptions) => NoCase<T>;
6
-
7
5
  export { noCase as default };
@@ -1,7 +1,5 @@
1
- import { C as CaseOptions, P as PascalCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { C as CaseOptions, P as PascalCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  declare const pascalCase: <T extends string = string>(value?: T, options?: CaseOptions) => PascalCase<T>;
6
-
7
5
  export { pascalCase as default };
@@ -1,10 +1,10 @@
1
- import { R as RE_FAST_ANSI } from '../packem_shared/constants-CTzC6Gjg.js';
1
+ import { R as RE_FAST_ANSI } from '../packem_shared/constants-BsZS5f0z.js';
2
2
  import LRUCache from '../packem_shared/LRUCache-3r3SovvR.js';
3
3
  import { splitByCase } from './split-by-case.js';
4
4
  import upperFirst from './upper-first.js';
5
5
  import { g as generateCacheKey } from '../packem_shared/generate-cache-key-DdayDfjV.js';
6
- import joinSegments from '../packem_shared/joinSegments-CuU8RGpP.js';
7
- import { n as normalizeGermanEszett } from '../packem_shared/normalize-german-eszett-DEB8-ZPT.js';
6
+ import joinSegments from '../packem_shared/joinSegments-CvxSgKz0.js';
7
+ import { n as normalizeGermanEszett } from '../packem_shared/normalize-german-eszett-4p3yKEzn.js';
8
8
 
9
9
  const defaultCacheStore = new LRUCache(1e3);
10
10
  const pascalCase = (value, options) => {
@@ -1,7 +1,5 @@
1
- import { C as CaseOptions, f as PascalSnakeCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { C as CaseOptions, f as PascalSnakeCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  declare const pascalSnakeCase: <T extends string = string>(value?: T, options?: CaseOptions) => PascalSnakeCase<T>;
6
-
7
5
  export { pascalSnakeCase as default };
@@ -1,7 +1,5 @@
1
- import { C as CaseOptions, g as PathCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { C as CaseOptions, g as PathCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  declare const pathCase: <T extends string = string>(value?: T, options?: CaseOptions) => PathCase<T>;
6
-
7
5
  export { pathCase as default };
@@ -1,7 +1,5 @@
1
- import { C as CaseOptions, S as SentenceCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { C as CaseOptions, S as SentenceCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  declare const sentenceCase: <T extends string = string>(value?: T, options?: CaseOptions) => SentenceCase<T>;
6
-
7
5
  export { sentenceCase as default };
@@ -1,10 +1,10 @@
1
- import { R as RE_FAST_ANSI } from '../packem_shared/constants-CTzC6Gjg.js';
1
+ import { R as RE_FAST_ANSI } from '../packem_shared/constants-BsZS5f0z.js';
2
2
  import LRUCache from '../packem_shared/LRUCache-3r3SovvR.js';
3
3
  import { splitByCase } from './split-by-case.js';
4
4
  import upperFirst from './upper-first.js';
5
5
  import { g as generateCacheKey } from '../packem_shared/generate-cache-key-DdayDfjV.js';
6
- import joinSegments from '../packem_shared/joinSegments-CuU8RGpP.js';
7
- import { n as normalizeGermanEszett } from '../packem_shared/normalize-german-eszett-DEB8-ZPT.js';
6
+ import joinSegments from '../packem_shared/joinSegments-CvxSgKz0.js';
7
+ import { n as normalizeGermanEszett } from '../packem_shared/normalize-german-eszett-4p3yKEzn.js';
8
8
 
9
9
  const defaultCacheStore = new LRUCache(1e3);
10
10
  const sentenceCase = (value, options) => {
@@ -35,13 +35,13 @@ const sentenceCase = (value, options) => {
35
35
  if (options?.handleAnsi && RE_FAST_ANSI.test(word)) {
36
36
  return word;
37
37
  }
38
- word = options?.locale?.startsWith("de") ? normalizeGermanEszett(word) : word;
39
- word = options?.locale ? word.toLocaleLowerCase(options.locale) : word.toLowerCase();
38
+ const normalized = options?.locale?.startsWith("de") ? normalizeGermanEszett(word) : word;
39
+ const lowered = options?.locale ? normalized.toLocaleLowerCase(options.locale) : normalized.toLowerCase();
40
40
  if (firstWord) {
41
41
  firstWord = false;
42
- return upperFirst(word, options);
42
+ return upperFirst(lowered, options);
43
43
  }
44
- return word;
44
+ return lowered;
45
45
  }),
46
46
  " "
47
47
  );
@@ -1,7 +1,5 @@
1
- import { C as CaseOptions, h as SnakeCase } from '../packem_shared/types-CfPsw9ix.js';
2
- import '../packem_shared/types-Daae0hGf.js';
3
- import '../packem_shared/lru-cache-B_t27XwI.js';
4
-
1
+ import { C as CaseOptions, h as SnakeCase } from "../packem_shared/types.d-DfgbcNKh.js";
2
+ import "../packem_shared/types.d-BVNv675q.js";
3
+ import "../packem_shared/lru-cache.d-BsP6kbVJ.js";
5
4
  declare const snakeCase: <T extends string = string>(value?: T, options?: CaseOptions) => SnakeCase<T>;
6
-
7
5
  export { snakeCase as default };