Skip to content
Open
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Before :unamused: | After :tada:
`42500` | `'42.5 kg'`
`1250000` | `'1.25 MB'`
`2700000000` | `'2.7 bil'`
`1500000000000000000000000000000` | `'1.5 Q'`


## Install
Expand Down Expand Up @@ -67,4 +68,5 @@ Name | Type | Default | Description
`locales` | `string \| Array<string>` | browser language | Formats the number in different languages
`lowercase` | `boolean` | `false` | Use lowercase abbreviations
`space` | `boolean` | `false` | Add a space between number and abbreviation
`unsafeInteger` | `boolean` | `false` | Use unsafe numbers
`units` | `Array<string>` | `['', 'K', 'M', 'B', 'T', 'P', 'E']` | Unit abbreviations
6 changes: 6 additions & 0 deletions bin/millify
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ require("yargs").command(
type: "boolean",
default: false,
})
.option("unsafeInteger", {
describe: "Use unsafe integer",
alias: "U",
type: "boolean",
default: false,
})
.option("units", {
describe: "Unit abbreviatons",
alias: "u",
Expand Down
2 changes: 1 addition & 1 deletion lib/millify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function millify(value: number, options?: Partial<MillifyOptions>): string {
// Originally this threw an error, but was changed to return a graceful fallback.
let val: number;
try {
val = parseValue(value);
val = parseValue(value, opts);
} catch (e) {
if (e instanceof Error) {
console.warn(`WARN: ${e.message} (millify)`);
Expand Down
9 changes: 9 additions & 0 deletions lib/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export interface MillifyOptions {
* A list of units to use.
*/
units: string[];
/**
* Use unsafe integer
* */
unsafeInteger: boolean;
}

/**
Expand All @@ -32,6 +36,7 @@ export const defaultOptions: MillifyOptions = {
lowercase: false,
precision: 1,
space: false,
unsafeInteger: false,
units: [
"",
"K", // Thousand
Expand All @@ -40,5 +45,9 @@ export const defaultOptions: MillifyOptions = {
"T", // Trillion
"P", // Quadrillion
"E", // Quintillion
"Z", // Sextillion
"Y", // Septillion
"R", // Octillion
"Q", // Nonillion
],
};
18 changes: 16 additions & 2 deletions lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
import { MillifyOptions } from "./options";

/**
* parseValue ensures the value is a number and within accepted range.
*/
export function parseValue(value: number): number {
export function parseValue(
value: number,
options?: Partial<MillifyOptions>,
): number {
const val: number = parseFloat(value?.toString());

if (isNaN(val)) {
throw new Error(`Input value is not a number`);
}
if (val > Number.MAX_SAFE_INTEGER || val < Number.MIN_SAFE_INTEGER) {
if (
options?.unsafeInteger &&
(val > Number.MAX_VALUE || val < Number.MIN_VALUE)
) {
throw new RangeError("Input value is outside of unsafe integer range");
}
if (
!options?.unsafeInteger &&
(val > Number.MAX_SAFE_INTEGER || val < Number.MIN_SAFE_INTEGER)
) {
throw new RangeError("Input value is outside of safe integer range");
}
return val;
Expand Down
29 changes: 29 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,35 @@ test("uses correct suffixes with default options", (t) => {
[1000000, "1M"],
[1000000000, "1B"],
[1000000000000, "1T"],
[1000000000000000, "1P"],
]);

for (const [value, expected] of tests.entries()) {
t.is(millify(value), expected);
}
});

test("uses correct suffixes with 'unsafeInteger' option", (t) => {
const tests = new Map([
[1000000000000000000, "1E"],
[1000000000000000000000, "1Z"],
[1000000000000000000000000, "1Y"],
[1000000000000000000000000000, "1R"],
[1700000000000000000000000000000, "1.7Q"],
]);

for (const [value, expected] of tests.entries()) {
t.is(millify(value, { unsafeInteger: true }), expected);
}
});

test("uses correct suffixes without 'unsafeInteger' option", (t) => {
const tests = new Map([
["1000000000000000000", "1000000000000000000"],
["1000000000000000000000", "1000000000000000000000"],
["1000000000000000000000000", "1000000000000000000000000"],
["1000000000000000000000000000", "1000000000000000000000000000"],
["1000000000000000000000000000000", "1000000000000000000000000000000"],
]);

for (const [value, expected] of tests.entries()) {
Expand Down