From cb2d165cb559c5adad395f4b44ae78df12d52bf2 Mon Sep 17 00:00:00 2001 From: Devlin Pajaron Date: Tue, 2 Jun 2026 19:19:05 +0800 Subject: [PATCH 1/2] 4.3.1 Update readableBytes --- docs-md/api/readableBytes.md | 13 +++++--- docs-md/changelog.md | 5 +++ src/readable-bytes/readable-bytes.test.ts | 39 +++++++++++++++++++++-- src/readable-bytes/readable-bytes.ts | 35 ++++++++++++++++---- 4 files changed, 79 insertions(+), 13 deletions(-) diff --git a/docs-md/api/readableBytes.md b/docs-md/api/readableBytes.md index 280af972..6f1f6a3f 100644 --- a/docs-md/api/readableBytes.md +++ b/docs-md/api/readableBytes.md @@ -7,7 +7,10 @@ Converts a number of bytes to a human readable file size. ### Parameters * `bytes` **[number][1]** of bytes to show -* `decimals` **[number][1]?** optional number of decimals to show +* `options` **[Object][2]?** user provided options object + + * `options.decimals` **[number][1]?** optional number of decimals to show + * `options.minUnit` **(`"byte(s)"` | `"kB"` | `"MB"` | `"GB"` | `"TB"` | `"PB"`)?** minimum unit to display; if undefined, the most appropriate unit is selected automatically ### Examples @@ -19,7 +22,7 @@ readableBytes(1234, 2); // => 1.21 kB ``` -Returns **[string][2]** of human readable file size. +Returns **[string][3]** of human readable file size. **Meta** @@ -27,7 +30,9 @@ Returns **[string][2]** of human readable file size. [1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String +[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object + +[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String -* Source: [readable-bytes.ts](https://github.com/iamdevlinph/common-utils-pkg/blob/main/src/readable-bytes/readable-bytes.ts#L20-L30) \ No newline at end of file +* Source: [readable-bytes.ts](https://github.com/iamdevlinph/common-utils-pkg/blob/main/src/readable-bytes/readable-bytes.ts#L23-L26) \ No newline at end of file diff --git a/docs-md/changelog.md b/docs-md/changelog.md index 1a445b55..ec48a22d 100644 --- a/docs-md/changelog.md +++ b/docs-md/changelog.md @@ -5,6 +5,11 @@ id: changelog # Changelog +##### 4.3.1 + +- Update `readableBytes` to support minimum unit +- Update `readableBytes(number, options?)` to accept optional `options` object as 2nd parameter for decimal and minimum unit + ##### 4.3.0 - **NEW:** `Colors -> readableColor` - get light/dark mode color for text readability diff --git a/src/readable-bytes/readable-bytes.test.ts b/src/readable-bytes/readable-bytes.test.ts index e4e1627f..a8304136 100644 --- a/src/readable-bytes/readable-bytes.test.ts +++ b/src/readable-bytes/readable-bytes.test.ts @@ -1,15 +1,48 @@ import { readableBytes } from './readable-bytes'; describe('readableBytes', () => { - it('should convert bytes to readable format', () => { + it('should convert bytes to readable format with default options', () => { expect(readableBytes(1)).toEqual('1 byte(s)'); expect(readableBytes(1024)).toEqual('1 kB'); expect(readableBytes(1234)).toEqual('1.205078125 kB'); - expect(readableBytes(1234, 2)).toEqual('1.21 kB'); - expect(readableBytes(1234, 3)).toEqual('1.205 kB'); expect(readableBytes(1048576)).toEqual('1 MB'); expect(readableBytes(1073741824)).toEqual('1 GB'); expect(readableBytes(1099511627776)).toEqual('1 TB'); expect(readableBytes(1125899906842624)).toEqual('1 PB'); }); + + it('should support an empty options object', () => { + expect(readableBytes(1234, {})).toEqual('1.205078125 kB'); + }); + + it('should apply decimals when provided', () => { + expect(readableBytes(1234, { decimals: 2 })).toEqual('1.21 kB'); + expect(readableBytes(1234, { decimals: 3 })).toEqual('1.205 kB'); + }); + + it('should apply minUnit when provided', () => { + expect(readableBytes(500, { minUnit: 'kB' })).toEqual('0.48828125 kB'); + + expect(readableBytes(1234, { minUnit: 'MB' })).toEqual( + '0.0011768341064453125 MB' + ); + + expect(readableBytes(1048576, { minUnit: 'MB' })).toEqual('1 MB'); + }); + + it('should apply decimals and minUnit together', () => { + expect( + readableBytes(1234, { + decimals: 3, + minUnit: 'MB', + }) + ).toEqual('0.001 MB'); + + expect( + readableBytes(500, { + decimals: 2, + minUnit: 'kB', + }) + ).toEqual('0.49 kB'); + }); }); diff --git a/src/readable-bytes/readable-bytes.ts b/src/readable-bytes/readable-bytes.ts index 54040f91..0e0e899c 100644 --- a/src/readable-bytes/readable-bytes.ts +++ b/src/readable-bytes/readable-bytes.ts @@ -1,5 +1,6 @@ const isWholeNum = (number: number) => number % 1 === 0; +const units = ['byte(s)', 'kB', 'MB', 'GB', 'TB', 'PB'] as const; /** * Converts a number of bytes to a human readable file size. * @@ -7,24 +8,46 @@ const isWholeNum = (number: number) => number % 1 === 0; * @module File * @name readableBytes * @param {number} bytes of bytes to show - * @param {number} [decimals] optional number of decimals to show + * @param {Object} [options] user provided options object + * @param {number} [options.decimals] optional number of decimals to show + * @param {'byte(s)'|'kB'|'MB'|'GB'|'TB'|'PB'} [options.minUnit] - minimum unit to display; if undefined, the most appropriate unit is selected automatically * @returns {string} of human readable file size. * @example * * readableBytes(1234); * // => 1.205078125 kB * - * readableBytes(1234, 2); + * readableBytes(1234, { decimals: 2 }); * // => 1.21 kB + * + * readableBytes(500, { minUnit: 'kB' }); + * // => 0.48828125 kB + * + * readableBytes(500, { decimals: 2, minUnit: 'kB' }); + * // => 0.49 kB kB */ -export const readableBytes = (bytes: number, decimals = 0) => { - const units = ['byte(s)', 'kB', 'MB', 'GB', 'TB', 'PB']; +type ReadableBytesOptions = { + decimals?: number; + minUnit?: (typeof units)[number]; +}; + +export const readableBytes = ( + bytes: number, + options?: ReadableBytesOptions +) => { + const { decimals = 0, minUnit } = options || {}; + const number = Math.floor(Math.log(bytes) / Math.log(1024)); - const converted = bytes / 1024 ** Math.floor(number); - const unit = units[number]; + const minUnitIndex = minUnit === undefined ? number : units.indexOf(minUnit); + + const unitIndex = Math.max(number, minUnitIndex); + const converted = bytes / 1024 ** unitIndex; + const unit = units[unitIndex]; + const formatted = isWholeNum(converted) || !decimals ? converted : converted.toFixed(decimals); + return `${formatted} ${unit}`; }; From 7c17f4c52e8f9ab96875170fde74f5b6bd1a16b2 Mon Sep 17 00:00:00 2001 From: Devlin Pajaron Date: Tue, 2 Jun 2026 19:19:11 +0800 Subject: [PATCH 2/2] 4.3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b58c98e6..1b5fd771 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "common-utils-pkg", - "version": "4.3.0", + "version": "4.3.1", "description": "A package of commonly used JavaScript utilities.", "keywords": [ "utilities",