diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c1870cf..3b8aa86 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,12 +10,12 @@ jobs: fail-fast: false matrix: node-version: + - 16 - 14 - 12 - - 10 steps: - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - run: npm install diff --git a/index.d.ts b/index.d.ts index 9d3cc78..a3af616 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,3 +1,12 @@ +export interface Options { + /** + Whether [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) should be counted. They are ignored by default. + + @default false + */ + readonly countAnsiEscapeCodes?: boolean; +} + /** Get the real length of a string - by correctly counting astral symbols and ignoring [ansi escape codes](https://github.com/sindresorhus/strip-ansi). @@ -5,7 +14,7 @@ Get the real length of a string - by correctly counting astral symbols and ignor @example ``` -import stringLength = require('string-length'); +import stringLength from 'string-length'; '๐Ÿด'.length; //=> 2 @@ -17,6 +26,4 @@ stringLength('\u001B[1municorn\u001B[22m'); //=> 7 ``` */ -declare function stringLength(string: string): number; - -export = stringLength; +export default function stringLength(string: string, options?: Options): number; diff --git a/index.js b/index.js index c2589a2..2ec6c62 100644 --- a/index.js +++ b/index.js @@ -1,19 +1,18 @@ -'use strict'; -const stripAnsi = require('strip-ansi'); -const charRegex = require('char-regex'); +import stripAnsi from 'strip-ansi'; +import charRegex from 'char-regex'; -const stringLength = string => { +export default function stringLength(string, {countAnsiEscapeCodes = false} = {}) { if (string === '') { return 0; } - const strippedString = stripAnsi(string); + if (!countAnsiEscapeCodes) { + string = stripAnsi(string); + } - if (strippedString === '') { + if (string === '') { return 0; } - return strippedString.match(charRegex()).length; -}; - -module.exports = stringLength; + return string.match(charRegex()).length; +} diff --git a/index.test-d.ts b/index.test-d.ts index 09d16b9..86cdce0 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,5 +1,6 @@ import {expectType} from 'tsd'; -import stringLength = require('.'); +import stringLength from './index.js'; expectType(stringLength('๐Ÿด')); expectType(stringLength('\u001B[1municorn\u001B[22m')); +expectType(stringLength('\u001B[1municorn\u001B[22m', {countAnsiEscapeCodes: true})); diff --git a/package.json b/package.json index 5acf08f..f34a87b 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,10 @@ "url": "https://sindresorhus.com" }, "engines": { - "node": ">=10" + "node": ">=12.20" }, + "type": "module", + "exports": "./index.js", "scripts": { "test": "xo && ava && tsd" }, @@ -34,12 +36,12 @@ "codes" ], "dependencies": { - "char-regex": "^1.0.2", + "char-regex": "^2.0.0", "strip-ansi": "^6.0.0" }, "devDependencies": { - "ava": "^3.1.0", - "tsd": "^0.11.0", - "xo": "^0.25.3" + "ava": "^3.15.0", + "tsd": "^0.17.0", + "xo": "^0.40.2" } } diff --git a/readme.md b/readme.md index 6156940..cf0e88b 100644 --- a/readme.md +++ b/readme.md @@ -13,7 +13,7 @@ $ npm install string-length ## Usage ```js -const stringLength = require('string-length'); +import stringLength from 'string-length'; '๐Ÿด'.length; //=> 2 @@ -25,6 +25,21 @@ stringLength('\u001B[1municorn\u001B[22m'); //=> 7 ``` +## API + +### stringLength(string, options?) + +#### options + +Type: `object` + +##### countAnsiEscapeCodes + +Type: `boolean`\ +Default: `false` + +Whether [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) should be counted. They are ignored by default. + ## Related - [string-length-cli](https://github.com/LitoMore/string-length-cli) - CLI for this module diff --git a/test.js b/test.js index dcbf97d..7bedaa1 100644 --- a/test.js +++ b/test.js @@ -1,9 +1,10 @@ -const test = require('ava'); -const stringLength = require('.'); +import test from 'ava'; +import stringLength from './index.js'; test('get the real length of a string', t => { t.is(stringLength(''), 0); t.is(stringLength('\u001B[1m\u001B[22m'), 0); + t.is(stringLength('\u001B[1m\u001B[22m', {countAnsiEscapeCodes: true}), 9); t.is(stringLength('๐ €”'), 1); t.is(stringLength('foo๐ bar๐ €ƒ'), 8); t.is(stringLength('ใ‚'), 1); @@ -11,8 +12,10 @@ test('get the real length of a string', t => { t.is(stringLength('๐Ÿด'), 1); t.is(stringLength('๐Œ†'), 1); t.is(stringLength('\u001B[1mfoo\u001B[22m'), 3); + t.is(stringLength('\u001B[1mfoo\u001B[22m', {countAnsiEscapeCodes: true}), 12); t.is(stringLength('โค๏ธ'), 1); t.is(stringLength('๐Ÿ‘Š๐Ÿฝ'), 1); t.is(stringLength('๐Ÿด๓ ง๓ ข๓ ฅ๓ ฎ๓ ง๓ ฟโค๏ธ่ฐข๐Ÿ‘ช'), 4); t.is(stringLength('\u001B[1m๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆยฐโœฟ\u001B[22m'), 3); + t.is(stringLength('\u001B[1m๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆยฐโœฟ\u001B[22m', {countAnsiEscapeCodes: true}), 12); });