@eternl/formats 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -0
- package/dist/cjs/constants.js +21 -0
- package/dist/cjs/csv.js +83 -0
- package/dist/cjs/date.js +61 -0
- package/dist/cjs/display.js +213 -0
- package/dist/cjs/errors.js +48 -0
- package/dist/cjs/index.js +22 -0
- package/dist/cjs/internal/intl-cache.js +92 -0
- package/dist/cjs/internal/numeric.js +164 -0
- package/dist/cjs/types.js +16 -0
- package/dist/esm/constants.js +19 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/csv.js +77 -0
- package/dist/esm/csv.js.map +1 -0
- package/dist/esm/date.js +57 -0
- package/dist/esm/date.js.map +1 -0
- package/dist/esm/display.js +204 -0
- package/dist/esm/display.js.map +1 -0
- package/dist/esm/errors.js +42 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/intl-cache.js +87 -0
- package/dist/esm/internal/intl-cache.js.map +1 -0
- package/dist/esm/internal/numeric.js +154 -0
- package/dist/esm/internal/numeric.js.map +1 -0
- package/dist/esm/types.js +14 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/types/constants.d.ts +19 -0
- package/dist/types/csv.d.ts +5 -0
- package/dist/types/date.d.ts +2 -0
- package/dist/types/display.d.ts +9 -0
- package/dist/types/errors.d.ts +21 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/internal/intl-cache.d.ts +17 -0
- package/dist/types/internal/numeric.d.ts +19 -0
- package/dist/types/types.d.ts +50 -0
- package/package.json +54 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const numberFormatCache = new Map();
|
|
2
|
+
const numberFormatMetaCache = new Map();
|
|
3
|
+
const dateFormatCache = new Map();
|
|
4
|
+
const serializeOptions = (options) => {
|
|
5
|
+
const entries = Object.entries(options)
|
|
6
|
+
.filter(([, value]) => value !== undefined)
|
|
7
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
8
|
+
.map(([key, value]) => {
|
|
9
|
+
if (value
|
|
10
|
+
&& typeof value === 'object'
|
|
11
|
+
&& !Array.isArray(value)) {
|
|
12
|
+
return `${key}:{${serializeOptions(value)}}`;
|
|
13
|
+
}
|
|
14
|
+
if (Array.isArray(value)) {
|
|
15
|
+
return `${key}:[${value.join('|')}]`;
|
|
16
|
+
}
|
|
17
|
+
return `${key}:${String(value)}`;
|
|
18
|
+
});
|
|
19
|
+
return entries.join(',');
|
|
20
|
+
};
|
|
21
|
+
const buildNumberFormatKey = (locale, options) => `${locale}|${serializeOptions(options)}`;
|
|
22
|
+
const buildDateFormatKey = (locale, options) => `${locale}|${options ? serializeOptions(options) : ''}`;
|
|
23
|
+
export const getNumberFormat = (locale, options) => {
|
|
24
|
+
const key = buildNumberFormatKey(locale, options);
|
|
25
|
+
const cached = numberFormatCache.get(key);
|
|
26
|
+
if (cached) {
|
|
27
|
+
return cached;
|
|
28
|
+
}
|
|
29
|
+
const nf = new Intl.NumberFormat(locale, options);
|
|
30
|
+
numberFormatCache.set(key, nf);
|
|
31
|
+
return nf;
|
|
32
|
+
};
|
|
33
|
+
const deriveGrouping = (parts) => {
|
|
34
|
+
const integerParts = parts.filter((part) => part.type === 'integer');
|
|
35
|
+
if (integerParts.length <= 1) {
|
|
36
|
+
return { primary: 0 };
|
|
37
|
+
}
|
|
38
|
+
const lengths = integerParts.map((part) => part.value.length);
|
|
39
|
+
const primary = lengths[lengths.length - 1];
|
|
40
|
+
const secondary = lengths.length > 1 ? lengths[lengths.length - 2] : undefined;
|
|
41
|
+
if (secondary === primary) {
|
|
42
|
+
return { primary };
|
|
43
|
+
}
|
|
44
|
+
return { primary, secondary };
|
|
45
|
+
};
|
|
46
|
+
const analyzePattern = (nf) => {
|
|
47
|
+
const sampleValue = 1234567.89;
|
|
48
|
+
const positiveParts = nf.formatToParts(sampleValue);
|
|
49
|
+
const negativeParts = nf.formatToParts(-sampleValue);
|
|
50
|
+
const plusProbe = nf.formatToParts(1);
|
|
51
|
+
const groupSeparator = positiveParts.find((part) => part.type === 'group')?.value ?? '';
|
|
52
|
+
const decimalSeparator = positiveParts.find((part) => part.type === 'decimal')?.value ?? '.';
|
|
53
|
+
const grouping = deriveGrouping(positiveParts);
|
|
54
|
+
const minusSign = negativeParts.find((part) => part.type === 'minusSign')?.value;
|
|
55
|
+
const plusSign = plusProbe.find((part) => part.type === 'plusSign')?.value;
|
|
56
|
+
return {
|
|
57
|
+
positive: positiveParts,
|
|
58
|
+
negative: negativeParts,
|
|
59
|
+
groupSeparator,
|
|
60
|
+
decimalSeparator,
|
|
61
|
+
grouping,
|
|
62
|
+
minusSign,
|
|
63
|
+
plusSign
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
export const getNumberFormatPattern = (locale, options) => {
|
|
67
|
+
const key = buildNumberFormatKey(locale, options);
|
|
68
|
+
const cached = numberFormatMetaCache.get(key);
|
|
69
|
+
if (cached) {
|
|
70
|
+
return cached;
|
|
71
|
+
}
|
|
72
|
+
const nf = getNumberFormat(locale, options);
|
|
73
|
+
const pattern = analyzePattern(nf);
|
|
74
|
+
numberFormatMetaCache.set(key, pattern);
|
|
75
|
+
return pattern;
|
|
76
|
+
};
|
|
77
|
+
export const getDateFormat = (locale, options) => {
|
|
78
|
+
const key = buildDateFormatKey(locale, options);
|
|
79
|
+
const cached = dateFormatCache.get(key);
|
|
80
|
+
if (cached) {
|
|
81
|
+
return cached;
|
|
82
|
+
}
|
|
83
|
+
const df = new Intl.DateTimeFormat(locale, options);
|
|
84
|
+
dateFormatCache.set(key, df);
|
|
85
|
+
return df;
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=intl-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intl-cache.js","sourceRoot":"","sources":["../../../src/internal/intl-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import Big from 'big.js';
|
|
2
|
+
import { DECIMAL_DOT, DECIMAL_EMPTY, DECIMAL_ZERO, DEFAULT_SIGN_MINUS } from '../constants';
|
|
3
|
+
import { FormatError, toRangeError, toTypeError } from '../errors';
|
|
4
|
+
const ROUNDING_MODE_MAP = {
|
|
5
|
+
roundDown: Big.roundDown,
|
|
6
|
+
roundHalfUp: Big.roundHalfUp,
|
|
7
|
+
roundHalfEven: Big.roundHalfEven,
|
|
8
|
+
roundUp: Big.roundUp
|
|
9
|
+
};
|
|
10
|
+
const assertNonNegativeInteger = (value, label) => {
|
|
11
|
+
if (value === undefined) {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
15
|
+
throw toRangeError(FormatError.NonNegativeIntegerRequired, { label });
|
|
16
|
+
}
|
|
17
|
+
return value;
|
|
18
|
+
};
|
|
19
|
+
const assertPositiveInteger = (value, label) => {
|
|
20
|
+
if (value === undefined) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
if (!Number.isInteger(value) || value <= 0) {
|
|
24
|
+
throw toRangeError(FormatError.PositiveIntegerRequired, { label });
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
};
|
|
28
|
+
export const normalizeNumeric = (value) => {
|
|
29
|
+
if (value instanceof Big) {
|
|
30
|
+
if (!value.c) {
|
|
31
|
+
return new Big(DECIMAL_ZERO);
|
|
32
|
+
}
|
|
33
|
+
return new Big(value.toString());
|
|
34
|
+
}
|
|
35
|
+
if (typeof value === 'number') {
|
|
36
|
+
if (!Number.isFinite(value)) {
|
|
37
|
+
throw toRangeError(FormatError.NumericValueNonFinite);
|
|
38
|
+
}
|
|
39
|
+
return new Big(value);
|
|
40
|
+
}
|
|
41
|
+
if (typeof value === 'string') {
|
|
42
|
+
const trimmed = value.trim();
|
|
43
|
+
if (!trimmed) {
|
|
44
|
+
throw toRangeError(FormatError.NumericStringEmpty);
|
|
45
|
+
}
|
|
46
|
+
return new Big(trimmed);
|
|
47
|
+
}
|
|
48
|
+
throw toTypeError(FormatError.UnsupportedNumericInput);
|
|
49
|
+
};
|
|
50
|
+
const mapRoundingMode = (mode) => {
|
|
51
|
+
if (!mode) {
|
|
52
|
+
return Big.roundHalfUp;
|
|
53
|
+
}
|
|
54
|
+
return ROUNDING_MODE_MAP[mode];
|
|
55
|
+
};
|
|
56
|
+
export const toFixedNoSci = (value, fractionDigits, roundingMode) => {
|
|
57
|
+
const rm = mapRoundingMode(roundingMode);
|
|
58
|
+
let working = value;
|
|
59
|
+
if (fractionDigits !== undefined) {
|
|
60
|
+
working = working.round(fractionDigits, rm);
|
|
61
|
+
}
|
|
62
|
+
return bigToDecimalString(working);
|
|
63
|
+
};
|
|
64
|
+
export const computeNumericParts = (value, options = {}) => {
|
|
65
|
+
const minDecimals = assertNonNegativeInteger(options.minDecimals, 'minDecimals') ?? 0;
|
|
66
|
+
const maxDecimals = assertNonNegativeInteger(options.maxDecimals, 'maxDecimals');
|
|
67
|
+
const precision = assertPositiveInteger(options.precision, 'precision');
|
|
68
|
+
const roundingMode = mapRoundingMode(options.roundingMode);
|
|
69
|
+
if (maxDecimals !== undefined && maxDecimals < minDecimals) {
|
|
70
|
+
throw toRangeError(FormatError.MaxDecimalsLessThanMinimum);
|
|
71
|
+
}
|
|
72
|
+
let bigValue = normalizeNumeric(value);
|
|
73
|
+
if (precision !== undefined) {
|
|
74
|
+
const precise = bigValue.toPrecision(precision, roundingMode);
|
|
75
|
+
bigValue = new Big(precise);
|
|
76
|
+
}
|
|
77
|
+
if (maxDecimals !== undefined) {
|
|
78
|
+
bigValue = bigValue.round(maxDecimals, roundingMode);
|
|
79
|
+
}
|
|
80
|
+
const isZero = bigValue.eq(0);
|
|
81
|
+
const isNegative = !isZero && bigValue.s < 0;
|
|
82
|
+
const canonical = bigToDecimalString(bigValue.abs());
|
|
83
|
+
let [integerPart, fractionPart = DECIMAL_EMPTY] = canonical.split(DECIMAL_DOT);
|
|
84
|
+
integerPart = integerPart.replace(/^(0+)(\d)/, '$2');
|
|
85
|
+
if (!integerPart) {
|
|
86
|
+
integerPart = DECIMAL_ZERO;
|
|
87
|
+
}
|
|
88
|
+
if (fractionPart.length < minDecimals) {
|
|
89
|
+
fractionPart = fractionPart.padEnd(minDecimals, DECIMAL_ZERO);
|
|
90
|
+
}
|
|
91
|
+
if (maxDecimals !== undefined && fractionPart.length > maxDecimals) {
|
|
92
|
+
fractionPart = fractionPart.slice(0, maxDecimals);
|
|
93
|
+
}
|
|
94
|
+
if (options.trimTrailingZeros) {
|
|
95
|
+
const minKeep = minDecimals;
|
|
96
|
+
while (fractionPart.length > minKeep && fractionPart.endsWith(DECIMAL_ZERO)) {
|
|
97
|
+
fractionPart = fractionPart.slice(0, -1);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
big: bigValue,
|
|
102
|
+
integer: integerPart,
|
|
103
|
+
fraction: fractionPart,
|
|
104
|
+
isNegative,
|
|
105
|
+
isZero
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
export const bigToDecimalString = (value) => {
|
|
109
|
+
const coefficient = (value.c ?? [0]);
|
|
110
|
+
const exponent = value.e ?? 0;
|
|
111
|
+
const sign = value.s < 0 ? DEFAULT_SIGN_MINUS : '';
|
|
112
|
+
if (coefficient.every((digit) => digit === 0)) {
|
|
113
|
+
return DECIMAL_ZERO;
|
|
114
|
+
}
|
|
115
|
+
const digits = coefficient.join('');
|
|
116
|
+
const decimalIndex = exponent + 1;
|
|
117
|
+
if (decimalIndex <= 0) {
|
|
118
|
+
const zeros = DECIMAL_ZERO.repeat(Math.abs(decimalIndex));
|
|
119
|
+
return `${sign}${DECIMAL_ZERO}${DECIMAL_DOT}${zeros}${digits}`.replace(/\.$/, '');
|
|
120
|
+
}
|
|
121
|
+
if (decimalIndex >= digits.length) {
|
|
122
|
+
const zeros = DECIMAL_ZERO.repeat(decimalIndex - digits.length);
|
|
123
|
+
return `${sign}${digits}${zeros}`;
|
|
124
|
+
}
|
|
125
|
+
const integerPart = digits.slice(0, decimalIndex);
|
|
126
|
+
const fractionPart = digits.slice(decimalIndex);
|
|
127
|
+
return `${sign}${integerPart}${DECIMAL_DOT}${fractionPart}`;
|
|
128
|
+
};
|
|
129
|
+
export const applyGrouping = (integer, grouping, enableGrouping) => {
|
|
130
|
+
if (!enableGrouping || grouping.primary === 0 || integer.length <= grouping.primary) {
|
|
131
|
+
return integer;
|
|
132
|
+
}
|
|
133
|
+
const groups = [];
|
|
134
|
+
const primary = grouping.primary;
|
|
135
|
+
const secondary = grouping.secondary ?? primary;
|
|
136
|
+
let index = integer.length;
|
|
137
|
+
let usePrimary = true;
|
|
138
|
+
while (index > 0) {
|
|
139
|
+
const size = usePrimary ? primary : secondary;
|
|
140
|
+
if (size <= 0) {
|
|
141
|
+
groups.unshift(integer.slice(0, index));
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
const start = Math.max(index - size, 0);
|
|
145
|
+
groups.unshift(integer.slice(start, index));
|
|
146
|
+
index = start;
|
|
147
|
+
if (index <= 0) {
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
usePrimary = false;
|
|
151
|
+
}
|
|
152
|
+
return groups.join(grouping.separator);
|
|
153
|
+
};
|
|
154
|
+
//# sourceMappingURL=numeric.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numeric.js","sourceRoot":"","sources":["../../../src/internal/numeric.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const NUMBER_STYLES = {
|
|
2
|
+
decimal: 'decimal',
|
|
3
|
+
currency: 'currency',
|
|
4
|
+
percent: 'percent'
|
|
5
|
+
};
|
|
6
|
+
export const SIGN_DISPLAYS = {
|
|
7
|
+
auto: 'auto',
|
|
8
|
+
always: 'always',
|
|
9
|
+
exceptZero: 'exceptZero',
|
|
10
|
+
never: 'never',
|
|
11
|
+
negative: 'negative'
|
|
12
|
+
};
|
|
13
|
+
export const COMPACT_UNITS = ['K', 'M', 'B', 'T'];
|
|
14
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,aAAa,GAAM;IAC9B,OAAO,EAAsB,SAAS;IACtC,QAAQ,EAAqB,UAAU;IACvC,OAAO,EAAsB,SAAS;CAC9B,CAAA;AAIV,MAAM,CAAC,MAAM,aAAa,GAAM;IAC9B,IAAI,EAAyB,MAAM;IACnC,MAAM,EAAuB,QAAQ;IACrC,UAAU,EAAmB,YAAY;IACzC,KAAK,EAAwB,OAAO;IACpC,QAAQ,EAAqB,UAAU;CAC/B,CAAA;AAIV,MAAM,CAAC,MAAM,aAAa,GAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CompactUnit, NumberStyle } from './types';
|
|
2
|
+
export declare const STYLE_DECIMAL: NumberStyle;
|
|
3
|
+
export declare const STYLE_CURRENCY: NumberStyle;
|
|
4
|
+
export declare const STYLE_PERCENT: NumberStyle;
|
|
5
|
+
export declare const DISPLAY_SIGNS: {
|
|
6
|
+
readonly minus: "minus";
|
|
7
|
+
readonly plus: "plus";
|
|
8
|
+
readonly none: "none";
|
|
9
|
+
};
|
|
10
|
+
export type DisplaySignValue = typeof DISPLAY_SIGNS[keyof typeof DISPLAY_SIGNS];
|
|
11
|
+
export declare const DISPLAY_SIGN_MINUS: "minus";
|
|
12
|
+
export declare const DISPLAY_SIGN_PLUS: "plus";
|
|
13
|
+
export declare const DISPLAY_SIGN_NONE: "none";
|
|
14
|
+
export declare const COMPACT_ORDER: CompactUnit[];
|
|
15
|
+
export declare const DEFAULT_SIGN_MINUS = "-";
|
|
16
|
+
export declare const DEFAULT_SIGN_PLUS = "+";
|
|
17
|
+
export declare const DECIMAL_ZERO = "0";
|
|
18
|
+
export declare const DECIMAL_EMPTY = "";
|
|
19
|
+
export declare const DECIMAL_DOT = ".";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CsvColumnSpec, CsvNumberOptions, NumericLike } from './types';
|
|
2
|
+
export declare const formatCsvNumber: (value: NumericLike, options?: CsvNumberOptions) => string;
|
|
3
|
+
export declare const formatCsvPercent: (value: NumericLike, options?: CsvNumberOptions) => string;
|
|
4
|
+
export declare const csvCurrencyCode: (code: string, customSymbols?: Record<string, string>, useSymbol?: boolean) => string;
|
|
5
|
+
export declare const buildCsv: <T>(rows: T[], columns: CsvColumnSpec<T>[], delimiter?: string, lineEnding?: string) => string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DisplayNumberOptions, NumericLike } from './types';
|
|
2
|
+
export declare const formatDisplayNumber: (value: NumericLike, options: DisplayNumberOptions) => string;
|
|
3
|
+
export declare const formatDisplayCurrency: (value: NumericLike, options: DisplayNumberOptions & {
|
|
4
|
+
currencyCode: string;
|
|
5
|
+
}) => string;
|
|
6
|
+
export declare const formatDisplayPercent: (value: NumericLike, options: DisplayNumberOptions) => string;
|
|
7
|
+
export declare const formatDisplayCompact: (value: NumericLike, options: DisplayNumberOptions & {
|
|
8
|
+
compact: true;
|
|
9
|
+
}) => string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare enum FormatError {
|
|
2
|
+
NonNegativeIntegerRequired = "nonNegativeIntegerRequired",
|
|
3
|
+
PositiveIntegerRequired = "positiveIntegerRequired",
|
|
4
|
+
NumericValueNonFinite = "numericValueNonFinite",
|
|
5
|
+
NumericStringEmpty = "numericStringEmpty",
|
|
6
|
+
UnsupportedNumericInput = "unsupportedNumericInput",
|
|
7
|
+
MaxDecimalsLessThanMinimum = "maxDecimalsLessThanMinimum",
|
|
8
|
+
MissingLocale = "missingLocale",
|
|
9
|
+
MissingCurrencyCode = "missingCurrencyCode",
|
|
10
|
+
DateValueInvalid = "dateValueInvalid",
|
|
11
|
+
DateStringEmpty = "dateStringEmpty",
|
|
12
|
+
DateNumberNonFinite = "dateNumberNonFinite",
|
|
13
|
+
InvalidDateString = "invalidDateString",
|
|
14
|
+
UnsupportedDateInput = "unsupportedDateInput"
|
|
15
|
+
}
|
|
16
|
+
type ErrorDetails = Record<string, string>;
|
|
17
|
+
export declare const getFormatErrorMessage: (code: FormatError, details?: ErrorDetails) => string;
|
|
18
|
+
export declare const toRangeError: (code: FormatError, details?: ErrorDetails) => RangeError;
|
|
19
|
+
export declare const toTypeError: (code: FormatError, details?: ErrorDetails) => TypeError;
|
|
20
|
+
export declare const toError: (code: FormatError, details?: ErrorDetails) => Error;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { formatDisplayNumber, formatDisplayCurrency, formatDisplayPercent, formatDisplayCompact } from './display';
|
|
2
|
+
export { formatCsvNumber, formatCsvPercent, csvCurrencyCode, buildCsv } from './csv';
|
|
3
|
+
export { formatDisplayDate, formatCsvDate } from './date';
|
|
4
|
+
export { FormatError, getFormatErrorMessage, toError, toRangeError, toTypeError } from './errors';
|
|
5
|
+
export type { NumericLike, RoundingMode, NumberStyle, SignDisplay, CommonNumberOptions, DisplayNumberOptions, CsvNumberOptions, CsvColumnSpec, CsvRow, CompactUnit } from './types';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface GroupingMetadata {
|
|
2
|
+
primary: number;
|
|
3
|
+
secondary?: number;
|
|
4
|
+
}
|
|
5
|
+
export interface FormatPattern {
|
|
6
|
+
positive: Intl.NumberFormatPart[];
|
|
7
|
+
negative: Intl.NumberFormatPart[];
|
|
8
|
+
groupSeparator: string;
|
|
9
|
+
decimalSeparator: string;
|
|
10
|
+
grouping: GroupingMetadata;
|
|
11
|
+
minusSign?: string;
|
|
12
|
+
plusSign?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare const getNumberFormat: (locale: string, options: Intl.NumberFormatOptions) => Intl.NumberFormat;
|
|
15
|
+
export declare const getNumberFormatPattern: (locale: string, options: Intl.NumberFormatOptions) => FormatPattern;
|
|
16
|
+
export declare const getDateFormat: (locale: string, options?: Intl.DateTimeFormatOptions) => Intl.DateTimeFormat;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Big from 'big.js';
|
|
2
|
+
import type { CommonNumberOptions, NumericLike, RoundingMode } from '../types';
|
|
3
|
+
export interface NumericParts {
|
|
4
|
+
big: Big;
|
|
5
|
+
integer: string;
|
|
6
|
+
fraction: string;
|
|
7
|
+
isNegative: boolean;
|
|
8
|
+
isZero: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface GroupingConfig {
|
|
11
|
+
separator: string;
|
|
12
|
+
primary: number;
|
|
13
|
+
secondary?: number;
|
|
14
|
+
}
|
|
15
|
+
export declare const normalizeNumeric: (value: NumericLike) => Big;
|
|
16
|
+
export declare const toFixedNoSci: (value: Big, fractionDigits?: number, roundingMode?: RoundingMode) => string;
|
|
17
|
+
export declare const computeNumericParts: (value: NumericLike, options?: CommonNumberOptions) => NumericParts;
|
|
18
|
+
export declare const bigToDecimalString: (value: Big) => string;
|
|
19
|
+
export declare const applyGrouping: (integer: string, grouping: GroupingConfig, enableGrouping: boolean) => string;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type Big from 'big.js';
|
|
2
|
+
export type NumericLike = number | string | Big;
|
|
3
|
+
export type RoundingMode = 'roundDown' | 'roundHalfUp' | 'roundHalfEven' | 'roundUp';
|
|
4
|
+
export declare const NUMBER_STYLES: {
|
|
5
|
+
readonly decimal: "decimal";
|
|
6
|
+
readonly currency: "currency";
|
|
7
|
+
readonly percent: "percent";
|
|
8
|
+
};
|
|
9
|
+
export type NumberStyle = typeof NUMBER_STYLES[keyof typeof NUMBER_STYLES];
|
|
10
|
+
export declare const SIGN_DISPLAYS: {
|
|
11
|
+
readonly auto: "auto";
|
|
12
|
+
readonly always: "always";
|
|
13
|
+
readonly exceptZero: "exceptZero";
|
|
14
|
+
readonly never: "never";
|
|
15
|
+
readonly negative: "negative";
|
|
16
|
+
};
|
|
17
|
+
export type SignDisplay = typeof SIGN_DISPLAYS[keyof typeof SIGN_DISPLAYS];
|
|
18
|
+
export declare const COMPACT_UNITS: readonly ["K", "M", "B", "T"];
|
|
19
|
+
export type CompactUnit = typeof COMPACT_UNITS[number];
|
|
20
|
+
export interface CommonNumberOptions {
|
|
21
|
+
minDecimals?: number;
|
|
22
|
+
maxDecimals?: number;
|
|
23
|
+
precision?: number;
|
|
24
|
+
roundingMode?: RoundingMode;
|
|
25
|
+
trimTrailingZeros?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface DisplayNumberOptions extends CommonNumberOptions {
|
|
28
|
+
locale: string;
|
|
29
|
+
style?: NumberStyle;
|
|
30
|
+
currencyCode?: string;
|
|
31
|
+
useSymbol?: boolean;
|
|
32
|
+
customSymbols?: Record<string, string>;
|
|
33
|
+
compact?: boolean;
|
|
34
|
+
compactThresholds?: Partial<Record<CompactUnit, NumericLike>>;
|
|
35
|
+
compactSuffixes?: Partial<Record<CompactUnit, string>>;
|
|
36
|
+
signDisplay?: SignDisplay;
|
|
37
|
+
useGrouping?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface CsvNumberOptions extends CommonNumberOptions {
|
|
40
|
+
}
|
|
41
|
+
export type CsvRow = Record<string, unknown> | unknown[];
|
|
42
|
+
export interface CsvColumnSpec<T = any> {
|
|
43
|
+
header: string;
|
|
44
|
+
accessor: (row: T) => unknown;
|
|
45
|
+
formatter?: (value: unknown) => string;
|
|
46
|
+
}
|
|
47
|
+
export interface FormatDisplayParams {
|
|
48
|
+
locale: string;
|
|
49
|
+
options: Intl.NumberFormatOptions;
|
|
50
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@eternl/formats",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Locale-aware display and CSV formatting helpers for numeric data.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/cjs/index.js",
|
|
7
|
+
"module": "dist/esm/index.js",
|
|
8
|
+
"types": "dist/types/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/types/index.d.ts",
|
|
12
|
+
"import": "./dist/esm/index.js",
|
|
13
|
+
"require": "./dist/cjs/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "npm run clean && tsc -p tsconfig.build.json && tsc -p tsconfig.cjs.json",
|
|
21
|
+
"clean": "rimraf dist",
|
|
22
|
+
"lint": "eslint . --fix",
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"build:eslint-plugin": "tsc -p tools/eslint-plugin-padding/tsconfig.json",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"test:watch": "vitest",
|
|
27
|
+
"test:lint-rules": "node --test tools/eslint-plugin-padding/tests/run-tests.js",
|
|
28
|
+
"publish:prepare": "npm run build && npm run build:eslint-plugin",
|
|
29
|
+
"publish:npm": "npm run publish:prepare && npm publish --access public"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"number-formatting",
|
|
33
|
+
"csv",
|
|
34
|
+
"intl",
|
|
35
|
+
"browser"
|
|
36
|
+
],
|
|
37
|
+
"author": "",
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/big.js": "6.2.2",
|
|
41
|
+
"@types/node": "22.18.8",
|
|
42
|
+
"@typescript-eslint/parser": "8.46.0",
|
|
43
|
+
"@typescript-eslint/utils": "8.46.0",
|
|
44
|
+
"eslint": "9.37.0",
|
|
45
|
+
"rimraf": "6.0.1",
|
|
46
|
+
"tslib": "2.8.1",
|
|
47
|
+
"tsup": "8.5.0",
|
|
48
|
+
"typescript": "5.9.3",
|
|
49
|
+
"vitest": "3.2.4"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"big.js": "7.0.1"
|
|
53
|
+
}
|
|
54
|
+
}
|