From 4b0fcb47ed7a1e3dd9fb447d3c12d80621ca67f2 Mon Sep 17 00:00:00 2001 From: John Gee Date: Sun, 9 Mar 2025 11:22:49 +1300 Subject: [PATCH 1/5] feat!: yargs is now ESM only --- index.mjs | 10 ++++---- lib/cjs.ts | 12 --------- lib/index.ts | 4 +-- package.json | 45 +++++++++++++-------------------- test/{cliui.cjs => cliui.mjs} | 12 ++++----- test/esm/cliui-test.mjs | 47 ----------------------------------- 6 files changed, 29 insertions(+), 101 deletions(-) delete mode 100644 lib/cjs.ts rename test/{cliui.cjs => cliui.mjs} (98%) delete mode 100644 test/esm/cliui-test.mjs diff --git a/index.mjs b/index.mjs index bc7a022..435bdbc 100644 --- a/index.mjs +++ b/index.mjs @@ -1,13 +1,13 @@ // Bootstrap cliui with CommonJS dependencies: import { cliui } from './build/lib/index.js' -import { wrap, stripAnsi } from './build/lib/string-utils.js' +import stringWidth from 'string-width' +import stripAnsi from 'strip-ansi' +import wrapAnsi from 'wrap-ansi' export default function ui (opts) { return cliui(opts, { - stringWidth: (str) => { - return [...str].length - }, + stringWidth, stripAnsi, - wrap + wrap: wrapAnsi }) } diff --git a/lib/cjs.ts b/lib/cjs.ts deleted file mode 100644 index bda4241..0000000 --- a/lib/cjs.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Bootstrap cliui with CommonJS dependencies: -import { cliui, UIOptions } from './index.js' -const stringWidth = require('string-width') -const stripAnsi = require('strip-ansi') -const wrap = require('wrap-ansi') -export default function ui (opts: UIOptions) { - return cliui(opts, { - stringWidth, - stripAnsi, - wrap - }) -} diff --git a/lib/index.ts b/lib/index.ts index 0673c3a..81c5c48 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -349,7 +349,7 @@ function _minWidth (col: Column) { } function getWindowWidth (): number { - /* istanbul ignore next: depends on terminal */ + /* c8 ignore next 5: depends on terminal */ if (typeof process === 'object' && process.stdout && process.stdout.columns) { return process.stdout.columns } @@ -371,7 +371,7 @@ function alignCenter (str: string, width: number): string { str = str.trim() const strWidth = mixin.stringWidth(str) - /* istanbul ignore next */ + /* c8 ignore next 3 */ if (strWidth >= width) { return str } diff --git a/package.json b/package.json index eab6bf4..128dc60 100644 --- a/package.json +++ b/package.json @@ -4,28 +4,19 @@ "description": "easily create complex multi-column command-line-interfaces", "main": "build/index.cjs", "exports": { - ".": [ - { - "import": "./index.mjs", - "require": "./build/index.cjs" - }, - "./build/index.cjs" - ] + ".": "./index.mjs" }, "type": "module", "module": "./index.mjs", "scripts": { - "check": "standardx '**/*.ts' && standardx '**/*.js' && standardx '**/*.cjs'", - "fix": "standardx --fix '**/*.ts' && standardx --fix '**/*.js' && standardx --fix '**/*.cjs'", - "pretest": "rimraf build && tsc -p tsconfig.test.json && cross-env NODE_ENV=test npm run build:cjs", - "test": "c8 mocha ./test/*.cjs", - "test:esm": "c8 mocha ./test/esm/cliui-test.mjs", + "check": "standardx '**/*.ts' && standardx '**/*.js'", + "fix": "standardx --fix '**/*.ts' && standardx --fix '**/*.js'", + "pretest": "rimraf build && tsc -p tsconfig.test.json", + "test": "c8 mocha ./test/*.mjs", "postest": "check", "coverage": "c8 report --check-coverage", "precompile": "rimraf build", "compile": "tsc", - "postcompile": "npm run build:cjs", - "build:cjs": "rollup -c", "prepare": "npm run compile" }, "repository": "yargs/cliui", @@ -49,28 +40,26 @@ "author": "Ben Coe ", "license": "ISC", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "devDependencies": { - "@types/node": "^14.0.27", + "@types/node": "^22.13.10", "@typescript-eslint/eslint-plugin": "^4.0.0", "@typescript-eslint/parser": "^4.0.0", - "c8": "^7.3.0", - "chai": "^4.2.0", - "chalk": "^4.1.0", + "c8": "^10.1.3", + "chai": "^5.2.0", + "chalk": "^5.4.1", "cross-env": "^7.0.2", "eslint": "^7.6.0", "eslint-plugin-import": "^2.22.0", "eslint-plugin-node": "^11.1.0", - "gts": "^3.0.0", - "mocha": "^10.0.0", - "rimraf": "^3.0.2", - "rollup": "^2.23.1", - "rollup-plugin-ts": "^3.0.2", + "gts": "^6.0.2", + "mocha": "^11.1.0", + "rimraf": "^6.0.1", "standardx": "^7.0.0", - "typescript": "^4.0.0" + "typescript": "^5.8.2" }, "files": [ "build", @@ -78,6 +67,6 @@ "!*.d.ts" ], "engines": { - "node": ">=12" + "node": ">=20" } } diff --git a/test/cliui.cjs b/test/cliui.mjs similarity index 98% rename from test/cliui.cjs rename to test/cliui.mjs index 6dd86e7..b2d5aa0 100644 --- a/test/cliui.cjs +++ b/test/cliui.mjs @@ -1,16 +1,14 @@ -'use strict' +import chalk from 'chalk' +import cliui from '../index.mjs' +import stripAnsi from 'strip-ansi' +import { should } from 'chai' /* global describe, it */ - -require('chai').should() +should() // Force chalk to enable color, if it's disabled the test fails. process.env.FORCE_COLOR = 1 -const chalk = require('chalk') -const cliui = require('../build/index.cjs') -const stripAnsi = require('strip-ansi') - describe('cliui', () => { describe('resetOutput', () => { it('should set lines to empty', () => { diff --git a/test/esm/cliui-test.mjs b/test/esm/cliui-test.mjs deleted file mode 100644 index f57d77d..0000000 --- a/test/esm/cliui-test.mjs +++ /dev/null @@ -1,47 +0,0 @@ -import {ok as assert, strictEqual} from 'assert' -import cliui from '../../index.mjs' - -describe('ESM', () => { - it("wraps text at 'width' if a single column is given", () => { - const ui = cliui({ - width: 10 - }) - - ui.div('i am a string that should be wrapped') - - ui.toString().split('\n').forEach((row) => { - assert(row.length <= 10) - }) - }) - - it('evenly divides text across columns if multiple columns are given', () => { - const ui = cliui({ - width: 40 - }) - - ui.div( - { text: 'i am a string that should be wrapped', width: 15 }, - 'i am a second string that should be wrapped', - 'i am a third string that should be wrapped' - ) - - // total width of all columns is <= - // the width cliui is initialized with. - ui.toString().split('\n').forEach((row) => { - assert(row.length <= 40) - }) - - // it should wrap each column appropriately. - // TODO: we should flesh out the Deno and ESM implementation - // such that it spreads words out over multiple columns appropriately: - const expected = [ - 'i am a string ti am a seconi am a third', - 'hat should be wd string tha string that', - 'rapped t should be should be w', - ' wrapped rapped' - ] - ui.toString().split('\n').forEach((line, i) => { - strictEqual(line, expected[i]) - }) - }) -}) \ No newline at end of file From dd06d6a5cb8eb0ab4dca527dfcc8e574332e5654 Mon Sep 17 00:00:00 2001 From: John Gee Date: Sun, 9 Mar 2025 13:32:31 +1300 Subject: [PATCH 2/5] Update Node.js target versions for CI --- .github/workflows/ci.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0f34c9e..a5eeeff 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: [12, 16, 18] + node: [20, 22] steps: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 @@ -28,7 +28,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 12 + node-version: 22 - run: npm install env: PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: true @@ -39,7 +39,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 14 + node-version: 22 - run: npm install env: PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: true @@ -51,7 +51,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 14 + node-version: 22 - run: npm install - run: npm run test:esm deno: @@ -60,7 +60,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 14 + node-version: 22 - run: npm install - run: npm run compile - uses: denolib/setup-deno@v2 From 479f7afce0898c93e7e64bbfbcd1ba7454125cd0 Mon Sep 17 00:00:00 2001 From: John Gee Date: Sun, 9 Mar 2025 13:34:09 +1300 Subject: [PATCH 3/5] Remove stale esm test from CI --- .github/workflows/ci.yaml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a5eeeff..75334d2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -45,15 +45,6 @@ jobs: PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: true - run: npm test - run: npm run coverage - esm: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: 22 - - run: npm install - - run: npm run test:esm deno: runs-on: ubuntu-latest steps: From 86f4bf3eb32aabbc69b33a8d4aa3cbd78c5d1f2e Mon Sep 17 00:00:00 2001 From: John Gee Date: Sun, 9 Mar 2025 13:49:43 +1300 Subject: [PATCH 4/5] Update Deno with wrapping --- deno.ts | 10 +++++----- lib/string-utils.ts | 30 ------------------------------ test/deno/cliui-test.ts | 11 +++++++---- 3 files changed, 12 insertions(+), 39 deletions(-) delete mode 100644 lib/string-utils.ts diff --git a/deno.ts b/deno.ts index a94e49f..70b4e28 100644 --- a/deno.ts +++ b/deno.ts @@ -1,14 +1,14 @@ // Bootstrap cliui with CommonJS dependencies: import { cliui, UI } from './build/lib/index.js' import type { UIOptions } from './build/lib/index.d.ts' -import { wrap, stripAnsi } from './build/lib/string-utils.js' +import stringWidth from 'string-width' +import stripAnsi from 'strip-ansi' +import wrapAnsi from 'wrap-ansi' export default function ui (opts: UIOptions): UI { return cliui(opts, { - stringWidth: (str: string) => { - return [...str].length - }, + stringWidth, stripAnsi, - wrap + wrap: wrapAnsi }) } diff --git a/lib/string-utils.ts b/lib/string-utils.ts deleted file mode 100644 index 23d78fd..0000000 --- a/lib/string-utils.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Minimal replacement for ansi string helpers "wrap-ansi" and "strip-ansi". -// to facilitate ESM and Deno modules. -// TODO: look at porting https://www.npmjs.com/package/wrap-ansi to ESM. - -// The npm application -// Copyright (c) npm, Inc. and Contributors -// Licensed on the terms of The Artistic License 2.0 -// See: https://github.com/npm/cli/blob/4c65cd952bc8627811735bea76b9b110cc4fc80e/lib/utils/ansi-trim.js -const ansi = new RegExp('\x1b(?:\\[(?:\\d+[ABCDEFGJKSTm]|\\d+;\\d+[Hfm]|' + -'\\d+;\\d+;\\d+m|6n|s|u|\\?25[lh])|\\w)', 'g') - -export function stripAnsi (str: string) { - return str.replace(ansi, '') -} - -export function wrap (str: string, width: number) { - const [start, end] = str.match(ansi) || ['', ''] - str = stripAnsi(str) - let wrapped = '' - for (let i = 0; i < str.length; i++) { - if (i !== 0 && (i % width) === 0) { - wrapped += '\n' - } - wrapped += str.charAt(i) - } - if (start && end) { - wrapped = `${start}${wrapped}${end}` - } - return wrapped -} diff --git a/test/deno/cliui-test.ts b/test/deno/cliui-test.ts index ce24068..2f3bcaf 100644 --- a/test/deno/cliui-test.ts +++ b/test/deno/cliui-test.ts @@ -6,6 +6,8 @@ import { } from 'https://deno.land/std/testing/asserts.ts' import cliui from '../../deno.ts' +// Just run a couple of the tests as a light check working from the Deno runtime. + Deno.test("wraps text at 'width' if a single column is given", () => { const ui = cliui({ width: 10 @@ -39,10 +41,11 @@ Deno.test('evenly divides text across columns if multiple columns are given', () // TODO: we should flesh out the Deno and ESM implementation // such that it spreads words out over multiple columns appropriately: const expected = [ - 'i am a string ti am a seconi am a third', - 'hat should be wd string tha string that', - 'rapped t should be should be w', - ' wrapped rapped' + 'i am a string i am a i am a third', + 'that should be second string that', + 'wrapped string that should be', + ' should be wrapped', + ' wrapped' ] ui.toString().split('\n').forEach((line: string, i: number) => { From 96a961f877ce29cd8551fba1e63c16aa473d915d Mon Sep 17 00:00:00 2001 From: John Gee Date: Sun, 9 Mar 2025 14:07:02 +1300 Subject: [PATCH 5/5] Update main entry point --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 128dc60..75d16a0 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "cliui", "version": "8.0.1", "description": "easily create complex multi-column command-line-interfaces", - "main": "build/index.cjs", + "main": "build/index.mjs", "exports": { ".": "./index.mjs" },