@visulima/string 1.0.4 โ 1.1.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.
- package/CHANGELOG.md +12 -0
- package/README.md +0 -1
- package/dist/case/identify-case.cjs +47 -8
- package/dist/case/identify-case.mjs +47 -8
- package/dist/get-string-truncated-width.cjs +3 -2
- package/dist/get-string-truncated-width.d.cts +0 -1
- package/dist/get-string-truncated-width.d.mts +0 -1
- package/dist/get-string-truncated-width.d.ts +0 -1
- package/dist/get-string-truncated-width.mjs +3 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## @visulima/string [1.1.0](https://github.com/visulima/visulima/compare/@visulima/string@1.0.5...@visulima/string@1.1.0) (2025-05-04)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* **string:** enhance identifyCase function to support additional cases ([#501](https://github.com/visulima/visulima/issues/501)) ([8f8ecee](https://github.com/visulima/visulima/commit/8f8eceefef3f4ce332eb702979291a4db010256c))
|
|
6
|
+
|
|
7
|
+
## @visulima/string [1.0.5](https://github.com/visulima/visulima/compare/@visulima/string@1.0.4...@visulima/string@1.0.5) (2025-05-02)
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **string:** update string width calculations for ellipsis and control characters, remove ambiguousWidth ([bf8a2de](https://github.com/visulima/visulima/commit/bf8a2de06429a229b5bdb17cadd8239243a55e0d))
|
|
12
|
+
|
|
1
13
|
## @visulima/string [1.0.4](https://github.com/visulima/visulima/compare/@visulima/string@1.0.3...@visulima/string@1.0.4) (2025-05-01)
|
|
2
14
|
|
|
3
15
|
### Bug Fixes
|
package/README.md
CHANGED
|
@@ -447,7 +447,6 @@ getStringWidth("๐จโ๐ฉโ๐งโ๐ฆ"); // => 2 (family emoji with ZWJ sequ
|
|
|
447
447
|
```typescript
|
|
448
448
|
interface StringWidthOptions {
|
|
449
449
|
ambiguousIsNarrow?: boolean; // Treat ambiguous-width characters as narrow
|
|
450
|
-
ambiguousWidth?: number; // Width of ambiguous-width characters (default: 1)
|
|
451
450
|
ansiWidth?: number; // Width of ANSI escape sequences (default: 0)
|
|
452
451
|
controlWidth?: number; // Width of control characters (default: 0)
|
|
453
452
|
countAnsiEscapeCodes?: boolean; // Include ANSI escape codes in width (default: false)
|
|
@@ -2,28 +2,67 @@
|
|
|
2
2
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
5
|
+
const IS_PASCAL_CASE = /^([A-Z][a-z]*)+$/;
|
|
6
|
+
const CONTAINS_LETTER_CASE_INSENSITIVE = /[a-z]/i;
|
|
7
|
+
const IS_UPPER_SNAKE_CASE = /^[A-Z0-9_]+$/;
|
|
8
|
+
const IS_LOWER_SNAKE_CASE = /^[a-z0-9_]+$/;
|
|
9
|
+
const IS_KEBAB_CASE = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
|
|
10
|
+
const IS_LOWERCASE_WITH_SPACE = /^[a-z ]+$/;
|
|
11
|
+
const IS_UPPERCASE = /^[A-Z][A-Z0-9]*$/;
|
|
12
|
+
const WHITESPACE_REGEX = /\s+/;
|
|
13
|
+
const IS_NUMERIC = /^\d+$/;
|
|
14
|
+
const IS_CAMEL_CASE_LIKE = /^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)+$/;
|
|
15
|
+
const CONTAINS_PUNCTUATION_MID_WORD = /[.!?;:,](?!\s|$)/;
|
|
5
16
|
const identifyCase = /* @__PURE__ */ __name((value) => {
|
|
6
|
-
if (typeof value !== "string"
|
|
7
|
-
|
|
17
|
+
if (typeof value !== "string") {
|
|
18
|
+
throw new TypeError("Expected input to be a string");
|
|
19
|
+
}
|
|
20
|
+
if (!value) {
|
|
21
|
+
return "unknown";
|
|
22
|
+
}
|
|
23
|
+
if (!CONTAINS_LETTER_CASE_INSENSITIVE.test(value)) {
|
|
24
|
+
return "unknown";
|
|
8
25
|
}
|
|
9
|
-
if (value
|
|
10
|
-
if (
|
|
26
|
+
if (value.includes("_")) {
|
|
27
|
+
if (IS_UPPER_SNAKE_CASE.test(value)) {
|
|
28
|
+
return "upper_snake";
|
|
29
|
+
}
|
|
30
|
+
if (IS_LOWER_SNAKE_CASE.test(value)) {
|
|
11
31
|
return "snake";
|
|
12
32
|
}
|
|
13
|
-
|
|
33
|
+
return "mixed";
|
|
34
|
+
}
|
|
35
|
+
if (value.includes("-")) {
|
|
36
|
+
if (IS_KEBAB_CASE.test(value)) {
|
|
14
37
|
return "kebab";
|
|
15
38
|
}
|
|
39
|
+
return "mixed";
|
|
40
|
+
}
|
|
41
|
+
if (IS_LOWERCASE_WITH_SPACE.test(value)) {
|
|
16
42
|
return "lower";
|
|
17
43
|
}
|
|
18
|
-
if (
|
|
44
|
+
if (IS_UPPERCASE.test(value)) {
|
|
19
45
|
return "upper";
|
|
20
46
|
}
|
|
21
|
-
|
|
47
|
+
const words = value.split(WHITESPACE_REGEX);
|
|
48
|
+
if (words.length > 1 && words.every((word) => IS_PASCAL_CASE.test(word))) {
|
|
49
|
+
return "title";
|
|
50
|
+
}
|
|
51
|
+
if (words.length > 1 && IS_NUMERIC.test(words[0]) && IS_PASCAL_CASE.test(words[1])) {
|
|
52
|
+
return "title";
|
|
53
|
+
}
|
|
54
|
+
if (words.length > 1 && IS_PASCAL_CASE.test(words[0]) && /^[a-z]/.test(words[1])) {
|
|
55
|
+
return "sentence";
|
|
56
|
+
}
|
|
57
|
+
if (IS_PASCAL_CASE.test(value)) {
|
|
22
58
|
return "pascal";
|
|
23
59
|
}
|
|
24
|
-
if (
|
|
60
|
+
if (IS_CAMEL_CASE_LIKE.test(value)) {
|
|
25
61
|
return "camel";
|
|
26
62
|
}
|
|
63
|
+
if (CONTAINS_PUNCTUATION_MID_WORD.test(value)) {
|
|
64
|
+
return "unknown";
|
|
65
|
+
}
|
|
27
66
|
return "mixed";
|
|
28
67
|
}, "identifyCase");
|
|
29
68
|
|
|
@@ -1,27 +1,66 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
const IS_PASCAL_CASE = /^([A-Z][a-z]*)+$/;
|
|
4
|
+
const CONTAINS_LETTER_CASE_INSENSITIVE = /[a-z]/i;
|
|
5
|
+
const IS_UPPER_SNAKE_CASE = /^[A-Z0-9_]+$/;
|
|
6
|
+
const IS_LOWER_SNAKE_CASE = /^[a-z0-9_]+$/;
|
|
7
|
+
const IS_KEBAB_CASE = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
|
|
8
|
+
const IS_LOWERCASE_WITH_SPACE = /^[a-z ]+$/;
|
|
9
|
+
const IS_UPPERCASE = /^[A-Z][A-Z0-9]*$/;
|
|
10
|
+
const WHITESPACE_REGEX = /\s+/;
|
|
11
|
+
const IS_NUMERIC = /^\d+$/;
|
|
12
|
+
const IS_CAMEL_CASE_LIKE = /^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)+$/;
|
|
13
|
+
const CONTAINS_PUNCTUATION_MID_WORD = /[.!?;:,](?!\s|$)/;
|
|
3
14
|
const identifyCase = /* @__PURE__ */ __name((value) => {
|
|
4
|
-
if (typeof value !== "string"
|
|
5
|
-
|
|
15
|
+
if (typeof value !== "string") {
|
|
16
|
+
throw new TypeError("Expected input to be a string");
|
|
17
|
+
}
|
|
18
|
+
if (!value) {
|
|
19
|
+
return "unknown";
|
|
20
|
+
}
|
|
21
|
+
if (!CONTAINS_LETTER_CASE_INSENSITIVE.test(value)) {
|
|
22
|
+
return "unknown";
|
|
6
23
|
}
|
|
7
|
-
if (value
|
|
8
|
-
if (
|
|
24
|
+
if (value.includes("_")) {
|
|
25
|
+
if (IS_UPPER_SNAKE_CASE.test(value)) {
|
|
26
|
+
return "upper_snake";
|
|
27
|
+
}
|
|
28
|
+
if (IS_LOWER_SNAKE_CASE.test(value)) {
|
|
9
29
|
return "snake";
|
|
10
30
|
}
|
|
11
|
-
|
|
31
|
+
return "mixed";
|
|
32
|
+
}
|
|
33
|
+
if (value.includes("-")) {
|
|
34
|
+
if (IS_KEBAB_CASE.test(value)) {
|
|
12
35
|
return "kebab";
|
|
13
36
|
}
|
|
37
|
+
return "mixed";
|
|
38
|
+
}
|
|
39
|
+
if (IS_LOWERCASE_WITH_SPACE.test(value)) {
|
|
14
40
|
return "lower";
|
|
15
41
|
}
|
|
16
|
-
if (
|
|
42
|
+
if (IS_UPPERCASE.test(value)) {
|
|
17
43
|
return "upper";
|
|
18
44
|
}
|
|
19
|
-
|
|
45
|
+
const words = value.split(WHITESPACE_REGEX);
|
|
46
|
+
if (words.length > 1 && words.every((word) => IS_PASCAL_CASE.test(word))) {
|
|
47
|
+
return "title";
|
|
48
|
+
}
|
|
49
|
+
if (words.length > 1 && IS_NUMERIC.test(words[0]) && IS_PASCAL_CASE.test(words[1])) {
|
|
50
|
+
return "title";
|
|
51
|
+
}
|
|
52
|
+
if (words.length > 1 && IS_PASCAL_CASE.test(words[0]) && /^[a-z]/.test(words[1])) {
|
|
53
|
+
return "sentence";
|
|
54
|
+
}
|
|
55
|
+
if (IS_PASCAL_CASE.test(value)) {
|
|
20
56
|
return "pascal";
|
|
21
57
|
}
|
|
22
|
-
if (
|
|
58
|
+
if (IS_CAMEL_CASE_LIKE.test(value)) {
|
|
23
59
|
return "camel";
|
|
24
60
|
}
|
|
61
|
+
if (CONTAINS_PUNCTUATION_MID_WORD.test(value)) {
|
|
62
|
+
return "unknown";
|
|
63
|
+
}
|
|
25
64
|
return "mixed";
|
|
26
65
|
}, "identifyCase");
|
|
27
66
|
|
|
@@ -82,6 +82,9 @@ const getCharType = /* @__PURE__ */ __name((codePoint) => {
|
|
|
82
82
|
codePoint >= 12352 && codePoint <= 12543) {
|
|
83
83
|
return "wide";
|
|
84
84
|
}
|
|
85
|
+
if (codePoint === 8230) {
|
|
86
|
+
return "latin";
|
|
87
|
+
}
|
|
85
88
|
return "other";
|
|
86
89
|
}, "getCharType");
|
|
87
90
|
const getCachedCharWidth = /* @__PURE__ */ __name((codePoint, config) => {
|
|
@@ -196,7 +199,6 @@ const getStringTruncatedWidth = /* @__PURE__ */ __name((input, options = {}) =>
|
|
|
196
199
|
limit: options.limit ?? Number.POSITIVE_INFINITY
|
|
197
200
|
},
|
|
198
201
|
width: {
|
|
199
|
-
ambiguous: options.ambiguousWidth ?? 1,
|
|
200
202
|
ambiguousIsNarrow: options.ambiguousIsNarrow ?? false,
|
|
201
203
|
ansi: options.ansiWidth ?? 0,
|
|
202
204
|
control: options.controlWidth ?? 0,
|
|
@@ -231,7 +233,6 @@ const getStringTruncatedWidth = /* @__PURE__ */ __name((input, options = {}) =>
|
|
|
231
233
|
const strippedLinkText = linkText.replace(constants.RE_ANSI, "");
|
|
232
234
|
const linkTextWidthResult = getStringTruncatedWidth(strippedLinkText, {
|
|
233
235
|
ambiguousIsNarrow: config.width.ambiguousIsNarrow,
|
|
234
|
-
ambiguousWidth: config.width.ambiguous,
|
|
235
236
|
ansiWidth: config.width.ansi,
|
|
236
237
|
controlWidth: config.width.control,
|
|
237
238
|
countAnsiEscapeCodes: false,
|
|
@@ -78,6 +78,9 @@ const getCharType = /* @__PURE__ */ __name((codePoint) => {
|
|
|
78
78
|
codePoint >= 12352 && codePoint <= 12543) {
|
|
79
79
|
return "wide";
|
|
80
80
|
}
|
|
81
|
+
if (codePoint === 8230) {
|
|
82
|
+
return "latin";
|
|
83
|
+
}
|
|
81
84
|
return "other";
|
|
82
85
|
}, "getCharType");
|
|
83
86
|
const getCachedCharWidth = /* @__PURE__ */ __name((codePoint, config) => {
|
|
@@ -192,7 +195,6 @@ const getStringTruncatedWidth = /* @__PURE__ */ __name((input, options = {}) =>
|
|
|
192
195
|
limit: options.limit ?? Number.POSITIVE_INFINITY
|
|
193
196
|
},
|
|
194
197
|
width: {
|
|
195
|
-
ambiguous: options.ambiguousWidth ?? 1,
|
|
196
198
|
ambiguousIsNarrow: options.ambiguousIsNarrow ?? false,
|
|
197
199
|
ansi: options.ansiWidth ?? 0,
|
|
198
200
|
control: options.controlWidth ?? 0,
|
|
@@ -227,7 +229,6 @@ const getStringTruncatedWidth = /* @__PURE__ */ __name((input, options = {}) =>
|
|
|
227
229
|
const strippedLinkText = linkText.replace(RE_ANSI, "");
|
|
228
230
|
const linkTextWidthResult = getStringTruncatedWidth(strippedLinkText, {
|
|
229
231
|
ambiguousIsNarrow: config.width.ambiguousIsNarrow,
|
|
230
|
-
ambiguousWidth: config.width.ambiguous,
|
|
231
232
|
ansiWidth: config.width.ansi,
|
|
232
233
|
controlWidth: config.width.control,
|
|
233
234
|
countAnsiEscapeCodes: false,
|