diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b85fc2a..3b8aa86 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,14 +10,12 @@ jobs: fail-fast: false matrix: node-version: + - 16 - 14 - 12 - - 10 - - 8 - - 6 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 c617e9f..fbf1ea4 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,98 +1,95 @@ -declare namespace prettyBytes { - interface Options { - /** - Include plus sign for positive numbers. If the difference is exactly zero a space character will be prepended instead for better alignment. +export interface Options { + /** + Include plus sign for positive numbers. If the difference is exactly zero a space character will be prepended instead for better alignment. - @default false - */ - readonly signed?: boolean; + @default false + */ + readonly signed?: boolean; - /** - - If `false`: Output won't be localized. - - If `true`: Localize the output using the system/browser locale. - - If `string`: Expects a [BCP 47 language tag](https://en.wikipedia.org/wiki/IETF_language_tag) (For example: `en`, `de`, …) - - If `string[]`: Expects a list of [BCP 47 language tags](https://en.wikipedia.org/wiki/IETF_language_tag) (For example: `en`, `de`, …) + /** + - If `false`: Output won't be localized. + - If `true`: Localize the output using the system/browser locale. + - If `string`: Expects a [BCP 47 language tag](https://en.wikipedia.org/wiki/IETF_language_tag) (For example: `en`, `de`, …) + - If `string[]`: Expects a list of [BCP 47 language tags](https://en.wikipedia.org/wiki/IETF_language_tag) (For example: `en`, `de`, …) - __Note:__ Localization should generally work in browsers. Node.js needs to be [built](https://github.com/nodejs/node/wiki/Intl) with `full-icu` or `system-icu`. Alternatively, the [`full-icu`](https://github.com/unicode-org/full-icu-npm) module can be used to provide support at runtime. + __Note:__ Localization should generally work in browsers. Node.js needs to be [built](https://github.com/nodejs/node/wiki/Intl) with `full-icu` or `system-icu`. Alternatively, the [`full-icu`](https://github.com/unicode-org/full-icu-npm) module can be used to provide support at runtime. - @default false - */ - readonly locale?: boolean | string | readonly string[]; + @default false + */ + readonly locale?: boolean | string | readonly string[]; - /** - Format the number as [bits](https://en.wikipedia.org/wiki/Bit) instead of [bytes](https://en.wikipedia.org/wiki/Byte). This can be useful when, for example, referring to [bit rate](https://en.wikipedia.org/wiki/Bit_rate). + /** + Format the number as [bits](https://en.wikipedia.org/wiki/Bit) instead of [bytes](https://en.wikipedia.org/wiki/Byte). This can be useful when, for example, referring to [bit rate](https://en.wikipedia.org/wiki/Bit_rate). - @default false + @default false - @example - ``` - import prettyBytes = require('pretty-bytes'); + @example + ``` + import { prettyBytes } from 'pretty-bytes'; - prettyBytes(1337, {bits: true}); - //=> '1.34 kbit' - ``` - */ - readonly bits?: boolean; + prettyBytes(1337, {bits: true}); + //=> '1.34 kbit' + ``` + */ + readonly bits?: boolean; - /** - Format the number using the [Binary Prefix](https://en.wikipedia.org/wiki/Binary_prefix) instead of the [SI Prefix](https://en.wikipedia.org/wiki/SI_prefix). This can be useful for presenting memory amounts. However, this should not be used for presenting file sizes. + /** + Format the number using the [Binary Prefix](https://en.wikipedia.org/wiki/Binary_prefix) instead of the [SI Prefix](https://en.wikipedia.org/wiki/SI_prefix). This can be useful for presenting memory amounts. However, this should not be used for presenting file sizes. - @default false + @default false - @example - ``` - import prettyBytes = require('pretty-bytes'); + @example + ``` + import { prettyBytes } from 'pretty-bytes'; - prettyBytes(1000, {binary: true}); - //=> '1000 bit' + prettyBytes(1000, {binary: true}); + //=> '1000 bit' - prettyBytes(1024, {binary: true}); - //=> '1 kiB' - ``` - */ - readonly binary?: boolean; + prettyBytes(1024, {binary: true}); + //=> '1 kiB' + ``` + */ + readonly binary?: boolean; - /** - The minimum number of fraction digits to display. + /** + The minimum number of fraction digits to display. - If neither `minimumFractionDigits` or `maximumFractionDigits` are set, the default behavior is to round to 3 significant digits. + If neither `minimumFractionDigits` or `maximumFractionDigits` are set, the default behavior is to round to 3 significant digits. - @default undefined + @default undefined - ``` - import prettyBytes = require('pretty-bytes'); + ``` + import { prettyBytes } from 'pretty-bytes'; - // Show the number with at least 3 fractional digits - prettyBytes(1900, {minimumFractionDigits: 3}); - //=> '1.900 kB' + // Show the number with at least 3 fractional digits + prettyBytes(1900, {minimumFractionDigits: 3}); + //=> '1.900 kB' - prettyBytes(1900); - //=> '1.9 kB' - ``` - */ - readonly minimumFractionDigits?: number; + prettyBytes(1900); + //=> '1.9 kB' + ``` + */ + readonly minimumFractionDigits?: number; + /** + The maximum number of fraction digits to display. - /** - The maximum number of fraction digits to display. + If neither `minimumFractionDigits` or `maximumFractionDigits` are set, the default behavior is to round to 3 significant digits. - If neither `minimumFractionDigits` or `maximumFractionDigits` are set, the default behavior is to round to 3 significant digits. + @default undefined - @default undefined + ``` + import { prettyBytes } from 'pretty-bytes'; - ``` - import prettyBytes = require('pretty-bytes'); + // Show the number with at most 1 fractional digit + prettyBytes(1920, {maximumFractionDigits: 1}); + //=> '1.9 kB' - // Show the number with at most 1 fractional digit - prettyBytes(1920, {maximumFractionDigits: 1}); - //=> '1.9 kB' - - prettyBytes(1920); - //=> '1.92 kB' - ``` - */ - readonly maximumFractionDigits?: number; - } + prettyBytes(1920); + //=> '1.92 kB' + ``` + */ + readonly maximumFractionDigits?: number; } /** @@ -102,7 +99,7 @@ Convert bytes to a human readable string: `1337` → `1.34 kB`. @example ``` -import prettyBytes = require('pretty-bytes'); +import { prettyBytes } from 'pretty-bytes'; prettyBytes(1337); //=> '1.34 kB' @@ -119,9 +116,7 @@ prettyBytes(1337, {locale: 'de'}); //=> '1,34 kB' ``` */ -declare function prettyBytes( +export function prettyBytes( number: number, - options?: prettyBytes.Options + options?: Options ): string; - -export = prettyBytes; diff --git a/index.js b/index.js index 661c465..ce26746 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,3 @@ -'use strict'; - const BYTE_UNITS = [ 'B', 'kB', @@ -9,7 +7,7 @@ const BYTE_UNITS = [ 'PB', 'EB', 'ZB', - 'YB' + 'YB', ]; const BIBYTE_UNITS = [ @@ -21,7 +19,7 @@ const BIBYTE_UNITS = [ 'PiB', 'EiB', 'ZiB', - 'YiB' + 'YiB', ]; const BIT_UNITS = [ @@ -33,7 +31,7 @@ const BIT_UNITS = [ 'Pbit', 'Ebit', 'Zbit', - 'Ybit' + 'Ybit', ]; const BIBIT_UNITS = [ @@ -45,7 +43,7 @@ const BIBIT_UNITS = [ 'Pibit', 'Eibit', 'Zibit', - 'Yibit' + 'Yibit', ]; /* @@ -65,16 +63,16 @@ const toLocaleString = (number, locale, options) => { return result; }; -module.exports = (number, options) => { +export const prettyBytes = (number, options) => { if (!Number.isFinite(number)) { throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`); } - options = Object.assign({bits: false, binary: false}, options); + options = {bits: false, binary: false, ...options}; - const UNITS = options.bits ? - (options.binary ? BIBIT_UNITS : BIT_UNITS) : - (options.binary ? BIBYTE_UNITS : BYTE_UNITS); + const UNITS = options.bits + ? (options.binary ? BIBIT_UNITS : BIT_UNITS) + : (options.binary ? BIBYTE_UNITS : BYTE_UNITS); if (options.signed && number === 0) { return ` 0 ${UNITS[0]}`; @@ -94,7 +92,7 @@ module.exports = (number, options) => { } if (options.maximumFractionDigits !== undefined) { - localeOptions = Object.assign({maximumFractionDigits: options.maximumFractionDigits}, localeOptions); + localeOptions = {maximumFractionDigits: options.maximumFractionDigits, ...localeOptions}; } if (number < 1) { @@ -103,7 +101,7 @@ module.exports = (number, options) => { } const exponent = Math.min(Math.floor(options.binary ? Math.log(number) / Math.log(1024) : Math.log10(number) / 3), UNITS.length - 1); - // eslint-disable-next-line unicorn/prefer-exponentiation-operator + // eslint-disable-next-line prefer-exponentiation-operator number /= Math.pow(options.binary ? 1024 : 1000, exponent); if (!localeOptions) { diff --git a/index.test-d.ts b/index.test-d.ts index f7c94a7..64c3b30 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,7 +1,5 @@ import {expectType} from 'tsd'; -import prettyBytes = require('.'); - -const options: prettyBytes.Options = {}; +import {prettyBytes} from '.'; expectType(prettyBytes(1337)); expectType(prettyBytes(42, {signed: true})); diff --git a/package.json b/package.json index fb090d4..d973ce4 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,11 @@ "email": "sindresorhus@gmail.com", "url": "https://sindresorhus.com" }, + "type": "module", + "exports": "./index.js", + "types": "./index.d.ts", "engines": { - "node": ">=6" + "node": ">=12" }, "scripts": { "test": "xo && ava && tsd" @@ -37,8 +40,8 @@ "localized" ], "devDependencies": { - "ava": "^1.4.1", - "tsd": "^0.7.2", - "xo": "^0.24.0" + "ava": "^4.0.1", + "tsd": "^0.19.1", + "xo": "^0.47.0" } } diff --git a/readme.md b/readme.md index e33610c..58522bc 100644 --- a/readme.md +++ b/readme.md @@ -16,7 +16,7 @@ $ npm install pretty-bytes ## Usage ```js -const prettyBytes = require('pretty-bytes'); +import { prettyBytes } from 'pretty-bytes'; prettyBytes(1337); //=> '1.34 kB' @@ -95,7 +95,7 @@ The minimum number of fraction digits to display. If neither `minimumFractionDigits` or `maximumFractionDigits` are set, the default behavior is to round to 3 significant digits. ```js -const prettyBytes = require('pretty-bytes'); +import { prettyBytes } from 'pretty-bytes'; // Show the number with at least 3 fractional digits prettyBytes(1900, {minimumFractionDigits: 3}); @@ -115,7 +115,7 @@ The maximum number of fraction digits to display. If neither `minimumFractionDigits` or `maximumFractionDigits` are set, the default behavior is to round to 3 significant digits. ```js -const prettyBytes = require('pretty-bytes'); +import { prettyBytes } from 'pretty-bytes'; // Show the number with at most 1 fractional digit prettyBytes(1920, {maximumFractionDigits: 1}); diff --git a/test.js b/test.js index 04a7c8f..5ff616b 100644 --- a/test.js +++ b/test.js @@ -1,13 +1,14 @@ +import process from 'node:process'; import test from 'ava'; -import prettyBytes from '.'; +import {prettyBytes} from './index.js'; test('throws on invalid input', t => { t.throws(() => prettyBytes('')); t.throws(() => prettyBytes('1')); - t.throws(() => prettyBytes(NaN)); + t.throws(() => prettyBytes(Number.NaN)); t.throws(() => prettyBytes(true)); - t.throws(() => prettyBytes(Infinity)); - t.throws(() => prettyBytes(-Infinity)); + t.throws(() => prettyBytes(Number.POSITIVE_INFINITY)); + t.throws(() => prettyBytes(Number.NEGATIVE_INFINITY)); t.throws(() => prettyBytes(null)); }); @@ -122,11 +123,11 @@ test('fractional digits options', t => { t.is(prettyBytes(1001, {maximumFractionDigits: 3}), '1.001 kB'); t.is(prettyBytes(1000, {minimumFractionDigits: 1, maximumFractionDigits: 3}), '1.0 kB'); t.is(prettyBytes(3942, {minimumFractionDigits: 1, maximumFractionDigits: 2}), '3.94 kB'); - t.is.skip(prettyBytes(59952784, {maximumFractionDigits: 1}), '59.9 MB'); // eslint-disable-line ava/no-skip-assert - t.is.skip(prettyBytes(59952784, {minimumFractionDigits: 1, maximumFractionDigits: 1}), '59.9 MB'); // eslint-disable-line ava/no-skip-assert + t.is.skip(prettyBytes(59_952_784, {maximumFractionDigits: 1}), '59.9 MB'); // eslint-disable-line ava/no-skip-assert + t.is.skip(prettyBytes(59_952_784, {minimumFractionDigits: 1, maximumFractionDigits: 1}), '59.9 MB'); // eslint-disable-line ava/no-skip-assert t.is(prettyBytes(4001, {maximumFractionDigits: 3, binary: true}), '3.907 kiB'); - t.is(prettyBytes(18717, {maximumFractionDigits: 2, binary: true}), '18.28 kiB'); - t.is(prettyBytes(18717, {maximumFractionDigits: 4, binary: true}), '18.2783 kiB'); - t.is(prettyBytes(32768, {minimumFractionDigits: 2, maximumFractionDigits: 3, binary: true}), '32.00 kiB'); - t.is(prettyBytes(65536, {minimumFractionDigits: 1, maximumFractionDigits: 3, binary: true}), '64.0 kiB'); + t.is(prettyBytes(18_717, {maximumFractionDigits: 2, binary: true}), '18.28 kiB'); + t.is(prettyBytes(18_717, {maximumFractionDigits: 4, binary: true}), '18.2783 kiB'); + t.is(prettyBytes(32_768, {minimumFractionDigits: 2, maximumFractionDigits: 3, binary: true}), '32.00 kiB'); + t.is(prettyBytes(65_536, {minimumFractionDigits: 1, maximumFractionDigits: 3, binary: true}), '64.0 kiB'); });