@visulima/string 2.0.6 → 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 +157 -0
  2. package/LICENSE.md +429 -1
  3. package/README.md +105 -24
  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 +8 -16
  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 +3 -3
  82. package/dist/packem_shared/closestN-BREy4E7C.js +0 -19
  83. package/dist/packem_shared/lru-cache-B_t27XwI.d.ts +0 -14
@@ -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 };
@@ -1,17 +1,14 @@
1
- import { L as LocaleOptions, i as SplitByCase } 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, i as SplitByCase } 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 SplitOptions extends LocaleOptions {
6
- handleAnsi?: boolean;
7
- handleEmoji?: boolean;
8
- knownAcronyms?: ReadonlyArray<string>;
9
- normalize?: boolean;
10
- separators?: ReadonlyArray<string> | RegExp;
11
- stripAnsi?: boolean;
12
- stripEmoji?: boolean;
5
+ handleAnsi?: boolean;
6
+ handleEmoji?: boolean;
7
+ knownAcronyms?: ReadonlyArray<string>;
8
+ normalize?: boolean;
9
+ separators?: ReadonlyArray<string> | RegExp;
10
+ stripAnsi?: boolean;
11
+ stripEmoji?: boolean;
13
12
  }
14
13
  declare const splitByCase: <T extends string = string>(input: T, options?: SplitOptions) => SplitByCase<T>;
15
-
16
- export { splitByCase };
17
- export type { SplitOptions };
14
+ export { SplitOptions, splitByCase };
@@ -20,16 +20,17 @@ const __cjs_getBuiltinModule = (module) => {
20
20
  const {
21
21
  stripVTControlCharacters
22
22
  } = __cjs_getBuiltinModule("node:util");
23
- import { j as RE_EMOJI, s as stripEmoji, k as RE_SEPARATORS, R as RE_FAST_ANSI, l as RE_CYRILLIC, m as RE_LATIN, n as RE_GREEK, o as RE_GREEK_LATIN_SPLIT, p as RE_UZBEK_LATIN_MODIFIER, q as RE_KATAKANA, r as RE_KANJI, t as RE_HIRAGANA, u as RE_HANGUL, v as RE_HEBREW, w as RE_ARABIC, x as RE_DEVANAGARI, y as RE_BENGALI, z as RE_GUJARATI, A as RE_GURMUKHI, B as RE_KANNADA, C as RE_TAMIL, D as RE_TELUGU, E as RE_MALAYALAM, F as RE_SINHALA, G as RE_THAI, H as RE_LAO, I as RE_TIBETAN, J as RE_MYANMAR, K as RE_ETHIOPIC, L as RE_KHMER, M as RE_ORIYA } from '../packem_shared/constants-CTzC6Gjg.js';
23
+ import { i as RE_EMOJI, s as stripEmoji, R as RE_FAST_ANSI, l as RE_CYRILLIC, m as RE_LATIN, n as RE_GREEK, o as RE_GREEK_LATIN_SPLIT, p as RE_UZBEK_LATIN_MODIFIER, q as RE_KATAKANA, r as RE_KANJI, t as RE_HIRAGANA, u as RE_HANGUL, v as RE_HEBREW, w as RE_ARABIC, x as RE_SEPARATORS, y as RE_DEVANAGARI, z as RE_BENGALI, A as RE_GUJARATI, B as RE_GURMUKHI, C as RE_KANNADA, D as RE_TAMIL, E as RE_TELUGU, F as RE_MALAYALAM, G as RE_SINHALA, H as RE_THAI, I as RE_LAO, J as RE_TIBETAN, K as RE_MYANMAR, L as RE_ETHIOPIC, M as RE_KHMER, N as RE_ORIYA } from '../packem_shared/constants-BsZS5f0z.js';
24
24
  import LRUCache from '../packem_shared/LRUCache-3r3SovvR.js';
25
25
 
26
26
  const regexCache = new LRUCache(1e3);
27
+ const RE_ESCAPE_SPECIAL = /[.*+?^${}()|[\]\\]/g;
27
28
  const getSeparatorsRegex = (separators) => {
28
29
  const key = separators.join("");
29
30
  if (regexCache.has(key)) {
30
31
  return regexCache.get(key);
31
32
  }
32
- const pattern = separators.map((s) => s.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`)).join("|");
33
+ const pattern = separators.map((s) => s.replaceAll(RE_ESCAPE_SPECIAL, String.raw`\$&`)).join("|");
33
34
  const regex = new RegExp(pattern, "g");
34
35
  regexCache.set(key, regex);
35
36
  return regex;
@@ -53,6 +54,7 @@ const splitByEmoji = (text) => {
53
54
  return segments.filter(Boolean);
54
55
  };
55
56
 
57
+ const RE_SLOVENIAN_SPECIAL = /[ČŠŽĐ]/i;
56
58
  const isUpperCode = new Uint8Array(128);
57
59
  const isLowerCode = new Uint8Array(128);
58
60
  const isDigitCode = new Uint8Array(128);
@@ -69,8 +71,9 @@ const handleScriptTransitions = (s, scriptDetectors, caseSensitive, locale, cust
69
71
  return [];
70
72
  }
71
73
  let hasDetectedScript = false;
72
- for (const detector of Object.values(scriptDetectors)) {
73
- if (detector(s[0])) {
74
+ const detectorValues = Object.values(scriptDetectors);
75
+ for (const detectorValue of detectorValues) {
76
+ if (detectorValue(s[0])) {
74
77
  hasDetectedScript = true;
75
78
  break;
76
79
  }
@@ -82,7 +85,9 @@ const handleScriptTransitions = (s, scriptDetectors, caseSensitive, locale, cust
82
85
  const result = [];
83
86
  let currentSegment = chars[0];
84
87
  let previousType = "other";
85
- for (const [type, detector] of Object.entries(scriptDetectors)) {
88
+ const scriptEntries = Object.entries(scriptDetectors);
89
+ for (const scriptEntry of scriptEntries) {
90
+ const [type, detector] = scriptEntry;
86
91
  if (detector(chars[0])) {
87
92
  previousType = type;
88
93
  break;
@@ -92,7 +97,8 @@ const handleScriptTransitions = (s, scriptDetectors, caseSensitive, locale, cust
92
97
  for (let index = 1; index < chars.length; index++) {
93
98
  const char = chars[index];
94
99
  let currentType = "other";
95
- for (const [type, detector] of Object.entries(scriptDetectors)) {
100
+ for (const scriptEntry of scriptEntries) {
101
+ const [type, detector] = scriptEntry;
96
102
  if (detector(char)) {
97
103
  currentType = type;
98
104
  break;
@@ -126,6 +132,18 @@ const handleScriptTransitions = (s, scriptDetectors, caseSensitive, locale, cust
126
132
  }
127
133
  return result.length > 0 ? result : [s];
128
134
  };
135
+ const detectAndProcessAcronym = (s, start, knownAcronyms, tokens) => {
136
+ if (knownAcronyms.size === 0) {
137
+ return start;
138
+ }
139
+ for (const acronym of knownAcronyms) {
140
+ if (s.startsWith(acronym, start)) {
141
+ tokens.push(acronym);
142
+ return start + acronym.length;
143
+ }
144
+ }
145
+ return start;
146
+ };
129
147
  const splitCamelCaseFast = (s, knownAcronyms = /* @__PURE__ */ new Set()) => {
130
148
  if (s.length === 0) {
131
149
  return [];
@@ -137,21 +155,14 @@ const splitCamelCaseFast = (s, knownAcronyms = /* @__PURE__ */ new Set()) => {
137
155
  const tokens = [];
138
156
  const width = s.length;
139
157
  for (let index = 1; index < width; index++) {
158
+ const newStart = detectAndProcessAcronym(s, start, knownAcronyms, tokens);
159
+ if (newStart !== start) {
160
+ start = newStart;
161
+ index = start - 1;
162
+ continue;
163
+ }
140
164
  const previousCode = s.codePointAt(index - 1);
141
165
  const currentCode = s.codePointAt(index);
142
- if (knownAcronyms.size > 0) {
143
- for (const acronym of knownAcronyms) {
144
- if (s.startsWith(acronym, start)) {
145
- tokens.push(acronym);
146
- start += acronym.length;
147
- index = start - 1;
148
- break;
149
- }
150
- }
151
- if (index < start) {
152
- continue;
153
- }
154
- }
155
166
  const previousIsUpper = previousCode && previousCode < 128 && isUpper(previousCode);
156
167
  const currentIsUpper = currentCode && currentCode < 128 && isUpper(currentCode);
157
168
  const previousIsLower = previousCode && previousCode < 128 && isLower(previousCode);
@@ -255,11 +266,26 @@ const splitCamelCaseLocale = (s, locale, knownAcronyms) => {
255
266
  const width_2 = chars2.length;
256
267
  const result2 = [];
257
268
  let currentSegment2 = chars2[0];
258
- let previousType = RE_CYRILLIC.test(chars2[0]) ? 1 : RE_LATIN.test(chars2[0]) ? 2 : 0;
259
- let previousIsUpper2 = chars2[0] === chars2[0].toLocaleUpperCase(locale);
269
+ const firstChar = chars2[0];
270
+ let previousType;
271
+ if (RE_CYRILLIC.test(firstChar)) {
272
+ previousType = 1;
273
+ } else if (RE_LATIN.test(firstChar)) {
274
+ previousType = 2;
275
+ } else {
276
+ previousType = 0;
277
+ }
278
+ let previousIsUpper2 = firstChar === firstChar.toLocaleUpperCase(locale);
260
279
  for (let index = 1; index < width_2; index++) {
261
280
  const char = chars2[index];
262
- const currentType = RE_CYRILLIC.test(char) ? 1 : RE_LATIN.test(char) ? 2 : 0;
281
+ let currentType;
282
+ if (RE_CYRILLIC.test(char)) {
283
+ currentType = 1;
284
+ } else if (RE_LATIN.test(char)) {
285
+ currentType = 2;
286
+ } else {
287
+ currentType = 0;
288
+ }
263
289
  const isUpperCaseChar = char === char.toLocaleUpperCase(locale);
264
290
  if (previousType !== currentType && (previousType === 1 || previousType === 2) && (currentType === 1 || currentType === 2) || currentType === previousType && !previousIsUpper2 && isUpperCaseChar) {
265
291
  result2.push(currentSegment2);
@@ -288,28 +314,36 @@ const splitCamelCaseLocale = (s, locale, knownAcronyms) => {
288
314
  if (!RE_GREEK.test(s) && !RE_LATIN.test(s)) {
289
315
  return [s];
290
316
  }
291
- const parts = s.match(RE_GREEK_LATIN_SPLIT) ?? [s];
317
+ const parts = [];
318
+ RE_GREEK_LATIN_SPLIT.lastIndex = 0;
319
+ let greekExecMatch;
320
+ while ((greekExecMatch = RE_GREEK_LATIN_SPLIT.exec(s)) !== null) {
321
+ parts.push(greekExecMatch[0]);
322
+ }
323
+ if (parts.length === 0) {
324
+ parts.push(s);
325
+ }
292
326
  const result2 = [];
293
327
  const width = parts.length;
294
328
  if (width === 1) {
295
329
  const part = parts[0];
296
330
  if (!part || !RE_GREEK.test(part[0]) || part.length === 1) {
297
- return [part || s];
331
+ return [part ?? s];
298
332
  }
299
333
  }
300
- for (const part of parts) {
301
- if (!part) {
334
+ for (const greekPart of parts) {
335
+ if (!greekPart) {
302
336
  continue;
303
337
  }
304
- if (!RE_GREEK.test(part[0]) || part.length === 1) {
305
- result2.push(part);
338
+ if (!RE_GREEK.test(greekPart[0]) || greekPart.length === 1) {
339
+ result2.push(greekPart);
306
340
  continue;
307
341
  }
308
- const partLength = part.length;
309
- let word = part[0];
310
- let previousIsUpper2 = part[0] === part[0].toLocaleUpperCase(locale);
342
+ const partLength = greekPart.length;
343
+ let word = greekPart[0];
344
+ let previousIsUpper2 = greekPart[0] === greekPart[0].toLocaleUpperCase(locale);
311
345
  for (let index = 1; index < partLength; index++) {
312
- const char = part[index];
346
+ const char = greekPart[index];
313
347
  const isUpperCaseChar = char === char.toLocaleUpperCase(locale);
314
348
  if (!previousIsUpper2 && isUpperCaseChar) {
315
349
  result2.push(word);
@@ -347,9 +381,10 @@ const splitCamelCaseLocale = (s, locale, knownAcronyms) => {
347
381
  // latin -> japanese
348
382
  );
349
383
  const result2 = [];
350
- for (const segment of baseSegments) {
384
+ for (const baseSegment of baseSegments) {
385
+ const segment = baseSegment;
351
386
  if (segment.length === 1 && particles.has(segment) && result2.length > 0) {
352
- result2[result2.length - 1] += segment;
387
+ result2[result2.length - 1] = result2.at(-1) + segment;
353
388
  } else {
354
389
  result2.push(segment);
355
390
  }
@@ -374,7 +409,7 @@ const splitCamelCaseLocale = (s, locale, knownAcronyms) => {
374
409
  for (let index = 1; index < width_2; index++) {
375
410
  const char = chars2[index];
376
411
  const isUpperCaseChar = char === char.toLocaleUpperCase(locale);
377
- const isSpecialChar = /[ČŠŽĐ]/i.test(char);
412
+ const isSpecialChar = RE_SLOVENIAN_SPECIAL.test(char);
378
413
  const nextIsUpper = index < width_2 - 1 && chars2[index + 1] === chars2[index + 1].toLocaleUpperCase(locale);
379
414
  if (!previousIsUpper2 && isUpperCaseChar || isSpecialChar && nextIsUpper) {
380
415
  result2.push(currentSegment2);
@@ -540,17 +575,21 @@ const splitCamelCaseLocale = (s, locale, knownAcronyms) => {
540
575
  for (let index = 1; index < width_; index++) {
541
576
  const char = chars[index];
542
577
  const isUpperCaseChar = char === char.toLocaleUpperCase(locale);
543
- let isAcronym = false;
578
+ let acronymLength = 0;
544
579
  for (const acronym of knownAcronyms) {
545
580
  if (s.startsWith(acronym, index)) {
546
581
  result.push(currentSegment, acronym);
547
- index += acronym.length - 1;
582
+ acronymLength = acronym.length;
548
583
  currentSegment = "";
549
- isAcronym = true;
584
+ const lastAcronymChar = acronym.at(-1);
585
+ if (lastAcronymChar) {
586
+ previousIsUpper = lastAcronymChar === lastAcronymChar.toLocaleUpperCase(locale);
587
+ }
550
588
  break;
551
589
  }
552
590
  }
553
- if (isAcronym) {
591
+ if (acronymLength > 0) {
592
+ index += acronymLength - 1;
554
593
  continue;
555
594
  }
556
595
  if (!previousIsUpper && isUpperCaseChar) {
@@ -569,20 +608,21 @@ const splitCamelCaseLocale = (s, locale, knownAcronyms) => {
569
608
  const processTextWithAnsiEmoji = (text, locale, knownAcronyms) => {
570
609
  const result = [];
571
610
  const segments = RE_FAST_ANSI.test(text) ? text.split(RE_FAST_ANSI).filter(Boolean) : [text];
572
- for (const seg of segments) {
611
+ for (const segment of segments) {
612
+ const seg = segment;
573
613
  if (RE_FAST_ANSI.test(seg)) {
574
614
  result.push(seg);
575
615
  } else {
576
616
  const subs = RE_EMOJI.test(seg) ? splitByEmoji(seg).filter(Boolean) : [seg];
577
- for (const sub of subs) {
578
- if (RE_EMOJI.test(sub)) {
579
- result.push(sub);
617
+ for (const emojiSub of subs) {
618
+ if (RE_EMOJI.test(emojiSub)) {
619
+ result.push(emojiSub);
580
620
  } else {
581
621
  if (locale) {
582
622
  const normalizedLocale = locale.toLowerCase().split("-")[0];
583
- result.push(...splitCamelCaseLocale(sub, normalizedLocale, knownAcronyms));
623
+ result.push(...splitCamelCaseLocale(emojiSub, normalizedLocale, knownAcronyms));
584
624
  } else {
585
- result.push(...splitCamelCaseFast(sub, knownAcronyms));
625
+ result.push(...splitCamelCaseFast(emojiSub, knownAcronyms));
586
626
  }
587
627
  }
588
628
  }
@@ -604,7 +644,7 @@ const splitByCase = (input, options = {}) => {
604
644
  stripAnsi: stripAnsiOption = false,
605
645
  stripEmoji: stripEmojiOption = false
606
646
  } = options;
607
- const acronymSet = new Set([...knownAcronyms].sort((a, b) => b.length - a.length));
647
+ const acronymSet = new Set([...knownAcronyms].toSorted((a, b) => b.length - a.length));
608
648
  let cleanedInput = input;
609
649
  if (stripAnsiOption) {
610
650
  cleanedInput = stripVTControlCharacters(cleanedInput);
@@ -612,16 +652,95 @@ const splitByCase = (input, options = {}) => {
612
652
  if (stripEmojiOption) {
613
653
  cleanedInput = stripEmoji(cleanedInput);
614
654
  }
615
- const separatorRegex = Array.isArray(separators) ? getSeparatorsRegex(separators) : separators instanceof RegExp ? separators : RE_SEPARATORS;
616
- const parts = cleanedInput.split(separatorRegex).filter(Boolean);
655
+ let separatorRegex;
656
+ if (Array.isArray(separators)) {
657
+ separatorRegex = getSeparatorsRegex(separators);
658
+ } else if (separators instanceof RegExp) {
659
+ separatorRegex = separators;
660
+ } else {
661
+ separatorRegex = RE_SEPARATORS;
662
+ }
663
+ const parts = [];
664
+ let workingInput = cleanedInput;
665
+ const regex = separatorRegex.flags.includes("g") ? separatorRegex : new RegExp(separatorRegex.source, `${separatorRegex.flags}g`);
666
+ while (workingInput.length > 0) {
667
+ const match = regex.exec(workingInput);
668
+ if (!match) {
669
+ if (workingInput === "..") {
670
+ parts.push("..");
671
+ } else if (workingInput === ".") {
672
+ parts.push(".");
673
+ } else if (workingInput.length > 0) {
674
+ parts.push(workingInput);
675
+ }
676
+ break;
677
+ }
678
+ const matchIndex = match.index;
679
+ const matchText = match[0];
680
+ const matchLength = matchText.length;
681
+ const beforeMatch = workingInput.slice(0, matchIndex);
682
+ const afterMatch = workingInput.slice(matchIndex + matchLength);
683
+ if (matchText.startsWith("../")) {
684
+ parts.push("..");
685
+ workingInput = workingInput.slice(matchIndex + 3);
686
+ } else if (matchText.startsWith("./")) {
687
+ parts.push(".");
688
+ workingInput = workingInput.slice(matchIndex + 2);
689
+ } else if (matchIndex === 0 && matchText === "..") {
690
+ parts.push("..");
691
+ workingInput = workingInput.slice(2);
692
+ } else if (matchIndex === 0 && matchText === ".") {
693
+ parts.push(".");
694
+ workingInput = workingInput.slice(1);
695
+ } else {
696
+ if (beforeMatch.length > 0) {
697
+ parts.push(beforeMatch);
698
+ }
699
+ let pos = 0;
700
+ while ((pos = matchText.indexOf("../", pos)) !== -1) {
701
+ parts.push("..");
702
+ pos += 3;
703
+ }
704
+ pos = 0;
705
+ while ((pos = matchText.indexOf("./", pos)) !== -1) {
706
+ if (pos === 0 || matchText[pos - 1] !== ".") {
707
+ parts.push(".");
708
+ }
709
+ pos += 2;
710
+ }
711
+ let remainingAfterMatch = afterMatch;
712
+ while (remainingAfterMatch.startsWith("../")) {
713
+ parts.push("..");
714
+ remainingAfterMatch = remainingAfterMatch.slice(3);
715
+ }
716
+ while (remainingAfterMatch.startsWith("./")) {
717
+ parts.push(".");
718
+ remainingAfterMatch = remainingAfterMatch.slice(2);
719
+ }
720
+ if (remainingAfterMatch === "..") {
721
+ parts.push("..");
722
+ break;
723
+ } else if (remainingAfterMatch === ".") {
724
+ parts.push(".");
725
+ break;
726
+ } else {
727
+ workingInput = remainingAfterMatch;
728
+ }
729
+ }
730
+ regex.lastIndex = 0;
731
+ }
732
+ if (parts.length === 0) {
733
+ const standardParts = cleanedInput.split(separatorRegex).filter(Boolean);
734
+ parts.push(...standardParts);
735
+ }
617
736
  let tokens = [];
618
- for (const part of parts) {
737
+ for (const splitPart of parts) {
619
738
  if (handleAnsi || handleEmoji) {
620
- tokens.push(...processTextWithAnsiEmoji(part, locale, acronymSet));
739
+ tokens.push(...processTextWithAnsiEmoji(splitPart, locale, acronymSet));
621
740
  } else if (locale) {
622
- tokens.push(...splitCamelCaseLocale(part, locale, acronymSet));
741
+ tokens.push(...splitCamelCaseLocale(splitPart, locale, acronymSet));
623
742
  } else {
624
- tokens.push(...splitCamelCaseFast(part, acronymSet));
743
+ tokens.push(...splitCamelCaseFast(splitPart, acronymSet));
625
744
  }
626
745
  }
627
746
  if (normalize) {
@@ -1,7 +1,5 @@
1
- import { C as CaseOptions, T as TitleCase } 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, T as TitleCase } 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 function titleCase<T extends string = string>(value?: T, options?: CaseOptions): TitleCase<T>;
6
-
7
5
  export { titleCase as default };
@@ -2,7 +2,7 @@ import LRUCache from '../packem_shared/LRUCache-3r3SovvR.js';
2
2
  import { splitByCase } from './split-by-case.js';
3
3
  import upperFirst from './upper-first.js';
4
4
  import { g as generateCacheKey } from '../packem_shared/generate-cache-key-DdayDfjV.js';
5
- import { n as normalizeGermanEszett } from '../packem_shared/normalize-german-eszett-DEB8-ZPT.js';
5
+ import { n as normalizeGermanEszett } from '../packem_shared/normalize-german-eszett-4p3yKEzn.js';
6
6
 
7
7
  const defaultCacheStore = new LRUCache(1e3);
8
8
  function titleCase(value, options) {
@@ -28,10 +28,8 @@ function titleCase(value, options) {
28
28
  stripAnsi: options?.stripAnsi,
29
29
  stripEmoji: options?.stripEmoji
30
30
  }).map((word) => {
31
- if (options?.locale?.startsWith("de")) {
32
- word = normalizeGermanEszett(word);
33
- }
34
- return upperFirst(options?.locale ? word.toLocaleLowerCase(options.locale) : word.toLowerCase(), { locale: options?.locale });
31
+ const normalized = options?.locale?.startsWith("de") ? normalizeGermanEszett(word) : word;
32
+ return upperFirst(options?.locale ? normalized.toLocaleLowerCase(options.locale) : normalized.toLowerCase(), { locale: options?.locale });
35
33
  }).join(" ");
36
34
  if (shouldCache && cacheKey) {
37
35
  cacheStore.set(cacheKey, result);
@@ -1,7 +1,5 @@
1
- import { C as CaseOptions, j as TrainCase } 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, j as TrainCase } 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 trainCase: <T extends string = string>(value?: T, options?: CaseOptions) => TrainCase<T>;
6
-
7
5
  export { trainCase as default };
@@ -2,7 +2,7 @@ import LRUCache from '../packem_shared/LRUCache-3r3SovvR.js';
2
2
  import { splitByCase } from './split-by-case.js';
3
3
  import upperFirst from './upper-first.js';
4
4
  import { g as generateCacheKey } from '../packem_shared/generate-cache-key-DdayDfjV.js';
5
- import joinSegments from '../packem_shared/joinSegments-CuU8RGpP.js';
5
+ import joinSegments from '../packem_shared/joinSegments-CvxSgKz0.js';
6
6
 
7
7
  const defaultCacheStore = new LRUCache(1e3);
8
8
  const trainCase = (value, options) => {
@@ -1,7 +1,5 @@
1
- import { L as LocaleOptions, U as UpperFirst } 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, U as UpperFirst } 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 upperFirst: <T extends string = string>(value?: T, options?: LocaleOptions) => UpperFirst<T>;
6
-
7
5
  export { upperFirst as default };
@@ -1,8 +1,6 @@
1
1
  interface ClosestStringOptions {
2
- caseSensitive?: boolean;
3
- compareFn?: (a: string, b: string) => number;
2
+ caseSensitive?: boolean;
3
+ compareFn?: (a: string, b: string) => number;
4
4
  }
5
5
  declare const closestString: (givenWord: string, possibleWords: ReadonlyArray<string>, options?: ClosestStringOptions) => string | undefined;
6
-
7
- export { closestString };
8
- export type { ClosestStringOptions };
6
+ export { ClosestStringOptions, closestString };
@@ -2,18 +2,15 @@ import { distance } from './packem_shared/closest-IHuSvnSn.js';
2
2
 
3
3
  const closestString = (givenWord, possibleWords, options) => {
4
4
  if (possibleWords.length === 0) {
5
- throw new TypeError(
6
- "When using closestString(), the possibleWords array must contain at least one word"
7
- );
5
+ throw new TypeError("When using closestString(), the possibleWords array must contain at least one word");
8
6
  }
9
7
  const { caseSensitive, compareFn: compareFunction = distance } = { ...options };
10
- if (!caseSensitive) {
11
- givenWord = givenWord.toLowerCase();
12
- }
8
+ const normalizedGivenWord = caseSensitive ? givenWord : givenWord.toLowerCase();
13
9
  let nearestWord = possibleWords[0] ?? void 0;
14
10
  let closestStringDistance = Infinity;
15
- for (const each of possibleWords) {
16
- const distance = caseSensitive ? compareFunction(givenWord, each) : compareFunction(givenWord, each.toLowerCase());
11
+ for (const possibleWord of possibleWords) {
12
+ const each = possibleWord;
13
+ const distance = caseSensitive ? compareFunction(normalizedGivenWord, each) : compareFunction(normalizedGivenWord, each.toLowerCase());
17
14
  if (distance < closestStringDistance) {
18
15
  nearestWord = each;
19
16
  closestStringDistance = distance;
@@ -1,8 +1,6 @@
1
1
  interface CompareSimilarityOptions {
2
- caseSensitive?: boolean;
3
- compareFn?: (a: string, b: string) => number;
2
+ caseSensitive?: boolean;
3
+ compareFn?: (a: string, b: string) => number;
4
4
  }
5
5
  declare const compareSimilarity: (givenWord: string, options?: CompareSimilarityOptions) => (a: string, b: string) => number;
6
-
7
- export { compareSimilarity };
8
- export type { CompareSimilarityOptions };
6
+ export { CompareSimilarityOptions, compareSimilarity };
@@ -5,8 +5,8 @@ const compareSimilarity = (givenWord, options) => {
5
5
  if (options?.caseSensitive) {
6
6
  return (a, b) => compareFunction(givenWord, a) - compareFunction(givenWord, b);
7
7
  }
8
- givenWord = givenWord.toLowerCase();
9
- return (a, b) => compareFunction(givenWord, a.toLowerCase()) - compareFunction(givenWord, b.toLowerCase());
8
+ const normalizedGivenWord = givenWord.toLowerCase();
9
+ return (a, b) => compareFunction(normalizedGivenWord, a.toLowerCase()) - compareFunction(normalizedGivenWord, b.toLowerCase());
10
10
  };
11
11
 
12
12
  export { compareSimilarity };
@@ -1,25 +1,23 @@
1
1
  interface StringTruncatedWidthOptions {
2
- ambiguousIsNarrow?: boolean;
3
- ansiWidth?: number;
4
- controlWidth?: number;
5
- countAnsiEscapeCodes?: boolean;
6
- ellipsis?: string;
7
- ellipsisWidth?: number;
8
- emojiWidth?: number;
9
- fullWidth?: number;
10
- halfWidth?: number;
11
- limit?: number;
12
- regularWidth?: number;
13
- tabWidth?: number;
14
- wideWidth?: number;
2
+ ambiguousIsNarrow?: boolean;
3
+ ansiWidth?: number;
4
+ controlWidth?: number;
5
+ countAnsiEscapeCodes?: boolean;
6
+ ellipsis?: string;
7
+ ellipsisWidth?: number;
8
+ emojiWidth?: number;
9
+ fullWidth?: number;
10
+ halfWidth?: number;
11
+ limit?: number;
12
+ regularWidth?: number;
13
+ tabWidth?: number;
14
+ wideWidth?: number;
15
15
  }
16
16
  interface StringTruncatedWidthResult {
17
- ellipsed: boolean;
18
- index: number;
19
- truncated: boolean;
20
- width: number;
17
+ ellipsed: boolean;
18
+ index: number;
19
+ truncated: boolean;
20
+ width: number;
21
21
  }
22
22
  declare const getStringTruncatedWidth: (input: string, options?: StringTruncatedWidthOptions) => StringTruncatedWidthResult;
23
-
24
- export { getStringTruncatedWidth };
25
- export type { StringTruncatedWidthOptions, StringTruncatedWidthResult };
23
+ export { StringTruncatedWidthOptions, StringTruncatedWidthResult, getStringTruncatedWidth };