Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 12 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
{
"name": "bytes-kit",
"version": "1.2.0",
"version": "1.3.0",
"description": "Utilities for formatting, parsing, and working with byte sizes.",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
}
}
},
"files": [
Expand Down Expand Up @@ -57,6 +62,9 @@
"sideEffects": false,
"author": "Cool Dev Master <cooldev.master@gmail.com>",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/cool-Dev-master"
Expand Down
11 changes: 10 additions & 1 deletion playground.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import bytes, {
analyzeBytes,
isValidByte,
detectUnit,
convertBytes,
} from './src/index.js';

console.log('=== Bytes Kit Playground ===\n');
Expand Down Expand Up @@ -70,7 +71,15 @@ console.log('sortBytes(arr): ', sortBytes(arr));
console.log('analyzeBytes(arr):', analyzeBytes(arr));
console.log();

// 7. Error Handling Fallback Check
// 7. Conversion Operations
console.log('--- 6.5. Conversion Operations ---');
console.log('convertBytes("10 MB", "KB"): ', convertBytes('10 MB', 'KB'));
console.log('convertBytes("1 GiB", "MiB"): ', convertBytes('1 GiB', 'MiB'));
console.log('convertBytes("1 GiB", "MB"): ', convertBytes('1 GiB', 'MB'));
console.log('convertBytes("1.5 MB", "KB", { format: true }):', convertBytes('1.5 MB', 'KB', { format: true }));
console.log();

// 8. Error Handling Fallback Check
console.log('--- 7. Error Handling Fallback Check ---');
console.log('isValidByte("invalid"): ', isValidByte('invalid')); // never calls onError
console.log('parseBytes("invalid"): ', parseBytes('invalid')); // calls onError, returns 0
Expand Down
42 changes: 42 additions & 0 deletions src/formatter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
sortBytes,
isValidByte,
detectUnit,
convertBytes,
} from './formatter.js';
import { defaultConfig, getConfig, resetConfig } from './config.js';

Expand Down Expand Up @@ -451,6 +452,47 @@ describe('bytes-kit New Utility APIs', () => {
expect(sortBytes(['1 MB', 'invalid'])).toEqual(['invalid', '1 MB']);
});
});

describe('convertBytes', () => {
it('converts byte value to target unit returning a number by default', () => {
expect(convertBytes('10 MB', 'KB')).toBe(10000);
expect(convertBytes('1 GB', 'MB')).toBe(1000);
expect(convertBytes(10000000, 'MB')).toBe(10);
expect(convertBytes('10.5 MB', 'B')).toBe(10500000);
});

it('handles binary conversions correctly', () => {
expect(convertBytes('1 GiB', 'MiB')).toBe(1024);
expect(convertBytes('1024 KiB', 'MiB')).toBe(1);
expect(convertBytes(1024 * 1024 * 1024, 'GiB')).toBe(1);
});

it('handles cross-base conversions (binary <-> decimal)', () => {
expect(convertBytes('1 GiB', 'MB')).toBe(1073.741824);
expect(convertBytes('1 MB', 'KiB')).toBe(1000000 / 1024);
});

it('returns formatted string when options.format is true', () => {
expect(convertBytes('10 MB', 'KB', { format: true })).toBe('10000 KB');
expect(convertBytes('1 GiB', 'MiB', { format: true })).toBe('1024 MiB');
expect(convertBytes('1.5 MB', 'KB', { format: true, space: false })).toBe('1500KB');
expect(convertBytes(1024, 'KiB', { format: true, decimalPlaces: 1, fixedDecimals: true })).toBe('1.0 KiB');
});

it('throws errors on invalid inputs or units by default', () => {
expect(() => convertBytes('invalid', 'MB')).toThrow();
expect(() => convertBytes('10 MB', 'invalid' as any)).toThrow();
});

it('respects global error handling (throwOnError: false)', () => {
defaultConfig({ throwOnError: false });
expect(convertBytes('invalid', 'MB')).toBe(0);
expect(convertBytes('10 MB', 'invalid' as any)).toBe(0);

expect(convertBytes('invalid', 'MB', { format: true })).toBe('0 MB');
expect(convertBytes('10 MB', 'invalid' as any, { format: true })).toBe('0 B');
});
});
});


41 changes: 41 additions & 0 deletions src/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -472,3 +472,44 @@ export function sortBytes(
}
}

/**
* Converts a byte value (number or string) to a target unit.
*
* @param input The input byte value (e.g. '10 MB', or raw number of bytes).
* @param targetFormat The unit to convert to (e.g. 'KB', 'MiB').
* @param options Additional options. If `format` is true, returns a formatted string (e.g. "10000 KB").
* You can also pass formatting options (like `decimalPlaces`, `fixedDecimals`, `space`, `locale`).
* @returns The converted value as a number, or as a formatted string if `options.format` is true.
*/
export function convertBytes(
input: number | string,
targetFormat: UnitType,
options?: FormatOptions & { format?: boolean },
): number | string {
const cfg = mergeConfig(options);
try {
const bytes = toBytes(input);
const unitLower = targetFormat.toLowerCase();
const unitConfig = UNIT_POWER_MAP[unitLower];
if (!unitConfig) {
throw new Error(`Invalid target unit: "${targetFormat}"`);
}

const convertedValue = bytes / Math.pow(unitConfig.base, unitConfig.exponent);

if (options?.format) {
return _formatBytesCore(bytes, { ...cfg, unit: targetFormat });
}

return convertedValue;
} catch (err) {
const fallback = options?.format ? '0 B' : 0;
return handleError(
err instanceof Error ? err : new Error(String(err)),
fallback,
cfg,
);
}
}


3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export {
analyzeBytes,
isValidByte,
detectUnit,
convertBytes,
} from './formatter.js';

export { defaultConfig, getConfig, resetConfig } from './config.js';
Expand All @@ -34,6 +35,7 @@ import {
analyzeBytes,
isValidByte,
detectUnit,
convertBytes,
} from './formatter.js';

const bytes = {
Expand All @@ -49,6 +51,7 @@ const bytes = {
analyzeBytes,
isValidByte,
detectUnit,
convertBytes,
defaultConfig,
getConfig,
resetConfig,
Expand Down
Loading