Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

string-width

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

string-width - npm Package Compare versions

Comparing version
8.1.1
to
8.2.0
+33
-3
index.js

@@ -10,3 +10,4 @@ import stripAnsi from 'strip-ansi';

2. RGI emoji clusters (\p{RGI_Emoji}) are double-width.
3. Otherwise use East Asian Width of the cluster’s first visible code point, and add widths for trailing Halfwidth/Fullwidth Forms within the same cluster (e.g., dakuten/handakuten/prolonged sound mark).
3. Minimally-qualified/unqualified emoji clusters (ZWJ sequences with 2+ Extended_Pictographic, or keycap sequences) are double-width.
4. Otherwise use East Asian Width of the cluster's first visible code point, and add widths for trailing Halfwidth/Fullwidth Forms within the same cluster (e.g., dakuten/handakuten/prolonged sound mark).
*/

@@ -25,2 +26,25 @@

// Detect minimally-qualified/unqualified emoji sequences (missing VS16 but still render as double-width)
const unqualifiedKeycapRegex = /^[\d#*]\u20E3$/;
const extendedPictographicRegex = /\p{Extended_Pictographic}/gu;
function isDoubleWidthNonRgiEmojiSequence(segment) {
// Real emoji clusters are < 30 chars; guard against pathological input
if (segment.length > 50) {
return false;
}
if (unqualifiedKeycapRegex.test(segment)) {
return true;
}
// ZWJ sequences with 2+ Extended_Pictographic
if (segment.includes('\u200D')) {
const pictographics = segment.match(extendedPictographicRegex);
return pictographics !== null && pictographics.length >= 2;
}
return false;
}
function baseVisible(segment) {

@@ -59,3 +83,4 @@ return segment.replace(leadingNonPrintingRegex, '');

if (!countAnsiEscapeCodes) {
// Avoid calling stripAnsi when there are no ANSI escape sequences (ESC = 0x1B, CSI = 0x9B)
if (!countAnsiEscapeCodes && (string.includes('\u001B') || string.includes('\u009B'))) {
string = stripAnsi(string);

@@ -68,2 +93,7 @@ }

// Fast path: printable ASCII (0x20–0x7E) needs no segmenter, regex, or EAW lookup — width equals length.
if (/^[\u0020-\u007E]*$/.test(string)) {
return string.length;
}
let width = 0;

@@ -79,3 +109,3 @@ const eastAsianWidthOptions = {ambiguousAsWide: !ambiguousIsNarrow};

// Emoji width logic
if (rgiEmojiRegex.test(segment)) {
if (rgiEmojiRegex.test(segment) || isDoubleWidthNonRgiEmojiSequence(segment)) {
width += 2;

@@ -82,0 +112,0 @@ continue;

+4
-4
{
"name": "string-width",
"version": "8.1.1",
"version": "8.2.0",
"description": "Get the visual width of a string - the number of columns required to display it",

@@ -57,4 +57,4 @@ "license": "MIT",

"dependencies": {
"get-east-asian-width": "^1.3.0",
"strip-ansi": "^7.1.0"
"get-east-asian-width": "^1.5.0",
"strip-ansi": "^7.1.2"
},

@@ -64,4 +64,4 @@ "devDependencies": {

"tsd": "^0.33.0",
"xo": "^1.2.2"
"xo": "^1.2.3"
}
}

@@ -5,3 +5,3 @@ # string-width

Some Unicode characters are [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) and use double the normal width. [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) are stripped and doesn't affect the width.
Some Unicode characters are [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) and use double the normal width. [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) are stripped and do not affect the width.

@@ -8,0 +8,0 @@ Useful to be able to measure the actual width of command-line output.