diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 18531b3..d36e1a8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,11 +12,9 @@ jobs: node-version: - 14 - 12 - - 10 - - 8 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/example.js b/example.js index 9cb1ccf..c696ff1 100644 --- a/example.js +++ b/example.js @@ -1,6 +1,5 @@ -'use strict'; -const fs = require('fs'); -const ansiEscapes = require('.'); +import fs from 'fs'; +import ansiEscapes from './index.js'; console.log(ansiEscapes.image(fs.readFileSync('fixture.jpg'), {width: 15})); diff --git a/index.d.ts b/index.d.ts index 5201942..47f3c73 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,64 +1,62 @@ -/// +/* eslint-disable @typescript-eslint/member-ordering */ import {LiteralUnion} from 'type-fest'; -declare namespace ansiEscapes { - interface ImageOptions { - /** - The width is given as a number followed by a unit, or the word `'auto'`. +export interface ImageOptions { + /** + The width is given as a number followed by a unit, or the word `'auto'`. - - `N`: N character cells. - - `Npx`: N pixels. - - `N%`: N percent of the session's width or height. - - `auto`: The image's inherent size will be used to determine an appropriate dimension. - */ - readonly width?: LiteralUnion<'auto', number | string>; + - `N`: N character cells. + - `Npx`: N pixels. + - `N%`: N percent of the session's width or height. + - `auto`: The image's inherent size will be used to determine an appropriate dimension. + */ + readonly width?: LiteralUnion<'auto', number | string>; - /** - The height is given as a number followed by a unit, or the word `'auto'`. + /** + The height is given as a number followed by a unit, or the word `'auto'`. - - `N`: N character cells. - - `Npx`: N pixels. - - `N%`: N percent of the session's width or height. - - `auto`: The image's inherent size will be used to determine an appropriate dimension. - */ - readonly height?: LiteralUnion<'auto', number | string>; + - `N`: N character cells. + - `Npx`: N pixels. + - `N%`: N percent of the session's width or height. + - `auto`: The image's inherent size will be used to determine an appropriate dimension. + */ + readonly height?: LiteralUnion<'auto', number | string>; - readonly preserveAspectRatio?: boolean; - } + readonly preserveAspectRatio?: boolean; +} - interface AnnotationOptions { - /** - Nonzero number of columns to annotate. +export interface AnnotationOptions { + /** + Nonzero number of columns to annotate. - Default: The remainder of the line. - */ - readonly length?: number; + Default: The remainder of the line. + */ + readonly length?: number; - /** - Starting X coordinate. + /** + Starting X coordinate. - Must be used with `y` and `length`. + Must be used with `y` and `length`. - Default: The cursor position - */ - readonly x?: number; + Default: The cursor position + */ + readonly x?: number; - /** - Starting Y coordinate. + /** + Starting Y coordinate. - Must be used with `x` and `length`. + Must be used with `x` and `length`. - Default: Cursor position. - */ - readonly y?: number; + Default: Cursor position. + */ + readonly y?: number; - /** - Create a "hidden" annotation. + /** + Create a "hidden" annotation. - Annotations created this way can be shown using the "Show Annotations" iTerm command. - */ - readonly isHidden?: boolean; - } + Annotations created this way can be shown using the "Show Annotations" iTerm command. + */ + readonly isHidden?: boolean; } declare const ansiEscapes: { @@ -218,7 +216,7 @@ declare const ansiEscapes: { @param buffer - Buffer of an image. Usually read in with `fs.readFile()`. */ - image(buffer: Buffer, options?: ansiEscapes.ImageOptions): string; + image(buffer: Buffer, options?: ImageOptions): string; iTerm: { /** @@ -238,11 +236,8 @@ declare const ansiEscapes: { @param message - The message to display within the annotation. The `|` character is disallowed and will be stripped. @returns An escape code which will create an annotation when printed in iTerm2. */ - annotation(message: string, options?: ansiEscapes.AnnotationOptions): string; + annotation(message: string, options?: AnnotationOptions): string; }; - - // TODO: remove this in the next major version - default: typeof ansiEscapes; }; -export = ansiEscapes; +export default ansiEscapes; diff --git a/index.js b/index.js index 2833318..dc91957 100644 --- a/index.js +++ b/index.js @@ -1,14 +1,11 @@ -'use strict'; -const ansiEscapes = module.exports; -// TODO: remove this in the next major version -module.exports.default = ansiEscapes; - const ESC = '\u001B['; const OSC = '\u001B]'; const BEL = '\u0007'; const SEP = ';'; const isTerminalApp = process.env.TERM_PROGRAM === 'Apple_Terminal'; +const ansiEscapes = {}; + ansiEscapes.cursorTo = (x, y) => { if (typeof x !== 'number') { throw new TypeError('The `x` argument is required'); @@ -26,21 +23,21 @@ ansiEscapes.cursorMove = (x, y) => { throw new TypeError('The `x` argument is required'); } - let ret = ''; + let returnValue = ''; if (x < 0) { - ret += ESC + (-x) + 'D'; + returnValue += ESC + (-x) + 'D'; } else if (x > 0) { - ret += ESC + x + 'C'; + returnValue += ESC + x + 'C'; } if (y < 0) { - ret += ESC + (-y) + 'A'; + returnValue += ESC + (-y) + 'A'; } else if (y > 0) { - ret += ESC + y + 'B'; + returnValue += ESC + y + 'B'; } - return ret; + return returnValue; }; ansiEscapes.cursorUp = (count = 1) => ESC + count + 'A'; @@ -110,28 +107,28 @@ ansiEscapes.link = (text, url) => { }; ansiEscapes.image = (buffer, options = {}) => { - let ret = `${OSC}1337;File=inline=1`; + let returnValue = `${OSC}1337;File=inline=1`; if (options.width) { - ret += `;width=${options.width}`; + returnValue += `;width=${options.width}`; } if (options.height) { - ret += `;height=${options.height}`; + returnValue += `;height=${options.height}`; } if (options.preserveAspectRatio === false) { - ret += ';preserveAspectRatio=0'; + returnValue += ';preserveAspectRatio=0'; } - return ret + ':' + buffer.toString('base64') + BEL; + return returnValue + ':' + buffer.toString('base64') + BEL; }; ansiEscapes.iTerm = { setCwd: (cwd = process.cwd()) => `${OSC}50;CurrentDir=${cwd}${BEL}`, annotation: (message, options = {}) => { - let ret = `${OSC}1337;`; + let returnValue = `${OSC}1337;`; const hasX = typeof options.x !== 'undefined'; const hasY = typeof options.y !== 'undefined'; @@ -141,17 +138,19 @@ ansiEscapes.iTerm = { message = message.replace(/\|/g, ''); - ret += options.isHidden ? 'AddHiddenAnnotation=' : 'AddAnnotation='; + returnValue += options.isHidden ? 'AddHiddenAnnotation=' : 'AddAnnotation='; if (options.length > 0) { - ret += + returnValue += (hasX ? [message, options.length, options.x, options.y] : [options.length, message]).join('|'); } else { - ret += message; + returnValue += message; } - return ret + BEL; + return returnValue + BEL; } }; + +export default ansiEscapes; diff --git a/index.test-d.ts b/index.test-d.ts index b83abea..22caf24 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,5 +1,5 @@ import {expectType} from 'tsd'; -import ansiEscapes = require('.'); +import ansiEscapes from './index.js'; expectType(ansiEscapes.cursorTo(0)); expectType(ansiEscapes.cursorTo(0, 1)); diff --git a/package.json b/package.json index 88a9356..b313b9d 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,10 @@ "email": "sindresorhus@gmail.com", "url": "https://sindresorhus.com" }, + "type": "module", + "exports": "./index.js", "engines": { - "node": ">=8" + "node": ">=12" }, "scripts": { "test": "xo && ava && tsd" @@ -46,12 +48,12 @@ "iterm2" ], "dependencies": { - "type-fest": "^0.21.3" + "type-fest": "^1.0.2" }, "devDependencies": { - "@types/node": "^13.7.7", - "ava": "^2.1.0", + "@types/node": "^14.14.41", + "ava": "^3.15.0", "tsd": "^0.14.0", - "xo": "^0.25.3" + "xo": "^0.38.2" } } diff --git a/readme.md b/readme.md index 9fbfec9..ea314ae 100644 --- a/readme.md +++ b/readme.md @@ -11,7 +11,7 @@ $ npm install ansi-escapes ## Usage ```js -const ansiEscapes = require('ansi-escapes'); +import ansiEscapes from 'ansi-escapes'; // Moves the cursor two rows up and to the left process.stdout.write(ansiEscapes.cursorUp(2) + ansiEscapes.cursorLeft); diff --git a/test.js b/test.js index 42ff96e..84387a3 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,5 @@ import test from 'ava'; -import ansiEscapes from '.'; +import ansiEscapes from './index.js'; test('main', t => { t.true(Object.keys(ansiEscapes).length > 0);