Socket
Socket
Sign inDemoInstall

@lion/localize

Package Overview
Dependencies
Maintainers
2
Versions
102
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lion/localize - npm Package Compare versions

Comparing version 0.25.0 to 0.26.0

src/number/getSeparatorsFromNumber.d.ts

8

docs/overview.md

@@ -12,3 +12,3 @@ # Systems >> Localize >> Overview ||10

Further examples and a more in depth description can be found at the [Use Cases Page](https://github.com/ing-bank/lion/blob/9ebc79431bfdcacfd0d9c9b6457c1a99686a6a47/docs/fundamentals/systems/localize/use-cases.md).
Further examples and a more in depth description can be found at the [Use Cases Page](https://github.com/ing-bank/lion/blob/650657231a4ec83592d45cd69836d28436635340/docs/fundamentals/systems/localize/use-cases.md).

@@ -19,5 +19,5 @@ ## Content

| ---------------------------------------- | --------------------------------------------- |
| [Translate Text](https://github.com/ing-bank/lion/blob/9ebc79431bfdcacfd0d9c9b6457c1a99686a6a47/docs/fundamentals/systems/localize/text.md) | Load and translate text in multiple languages |
| [Format Numbers](https://github.com/ing-bank/lion/blob/9ebc79431bfdcacfd0d9c9b6457c1a99686a6a47/docs/fundamentals/systems/localize/numbers.md) | Format numbers in multiple languages |
| [Format Dates](https://github.com/ing-bank/lion/blob/9ebc79431bfdcacfd0d9c9b6457c1a99686a6a47/docs/fundamentals/systems/localize/dates.md) | Format dates in multiple languages |
| [Translate Text](https://github.com/ing-bank/lion/blob/650657231a4ec83592d45cd69836d28436635340/docs/fundamentals/systems/localize/text.md) | Load and translate text in multiple languages |
| [Format Numbers](https://github.com/ing-bank/lion/blob/650657231a4ec83592d45cd69836d28436635340/docs/fundamentals/systems/localize/numbers.md) | Format numbers in multiple languages |
| [Format Dates](https://github.com/ing-bank/lion/blob/650657231a4ec83592d45cd69836d28436635340/docs/fundamentals/systems/localize/dates.md) | Format dates in multiple languages |

@@ -24,0 +24,0 @@ ## Installation

@@ -15,4 +15,5 @@ export { formatDate } from "./src/date/formatDate.js";

export { getGroupSeparator } from "./src/number/getGroupSeparator.js";
export { getSeparatorsFromNumber } from "./src/number/getSeparatorsFromNumber.js";
export { normalizeCurrencyLabel } from "./src/number/normalizeCurrencyLabel.js";
export { parseNumber } from "./src/number/parseNumber.js";
export { localize, setLocalize } from "./src/localize.js";

@@ -16,3 +16,4 @@ export { formatDate } from './src/date/formatDate.js';

export { getGroupSeparator } from './src/number/getGroupSeparator.js';
export { getSeparatorsFromNumber } from './src/number/getSeparatorsFromNumber.js';
export { normalizeCurrencyLabel } from './src/number/normalizeCurrencyLabel.js';
export { parseNumber } from './src/number/parseNumber.js';
{
"name": "@lion/localize",
"version": "0.25.0",
"version": "0.26.0",
"description": "The localization system helps to manage localization data split into locales and automate its loading",

@@ -38,3 +38,3 @@ "license": "MIT",

"@bundled-es-modules/message-format": "6.0.4",
"@lion/core": "^0.23.0",
"@lion/core": "^0.24.0",
"singleton-manager": "^1.5.0"

@@ -41,0 +41,0 @@ },

@@ -12,3 +12,3 @@ # Systems >> Localize >> Overview ||10

Further examples and a more in depth description can be found at the [Use Cases Page](https://github.com/ing-bank/lion/blob/9ebc79431bfdcacfd0d9c9b6457c1a99686a6a47/docs/fundamentals/systems/localize/use-cases.md).
Further examples and a more in depth description can be found at the [Use Cases Page](https://github.com/ing-bank/lion/blob/650657231a4ec83592d45cd69836d28436635340/docs/fundamentals/systems/localize/use-cases.md).

@@ -19,5 +19,5 @@ ## Content

| ---------------------------------------- | --------------------------------------------- |
| [Translate Text](https://github.com/ing-bank/lion/blob/9ebc79431bfdcacfd0d9c9b6457c1a99686a6a47/docs/fundamentals/systems/localize/text.md) | Load and translate text in multiple languages |
| [Format Numbers](https://github.com/ing-bank/lion/blob/9ebc79431bfdcacfd0d9c9b6457c1a99686a6a47/docs/fundamentals/systems/localize/numbers.md) | Format numbers in multiple languages |
| [Format Dates](https://github.com/ing-bank/lion/blob/9ebc79431bfdcacfd0d9c9b6457c1a99686a6a47/docs/fundamentals/systems/localize/dates.md) | Format dates in multiple languages |
| [Translate Text](https://github.com/ing-bank/lion/blob/650657231a4ec83592d45cd69836d28436635340/docs/fundamentals/systems/localize/text.md) | Load and translate text in multiple languages |
| [Format Numbers](https://github.com/ing-bank/lion/blob/650657231a4ec83592d45cd69836d28436635340/docs/fundamentals/systems/localize/numbers.md) | Format numbers in multiple languages |
| [Format Dates](https://github.com/ing-bank/lion/blob/650657231a4ec83592d45cd69836d28436635340/docs/fundamentals/systems/localize/dates.md) | Format dates in multiple languages |

@@ -24,0 +24,0 @@ ## Installation

import { emptyStringWhenNumberNan } from './utils/emptyStringWhenNumberNan.js';
import { getSeparatorsFromNumber } from './getSeparatorsFromNumber.js';
import { getDecimalSeparator } from './getDecimalSeparator.js';

@@ -51,6 +52,12 @@ import { getGroupSeparator } from './getGroupSeparator.js';

const formattedNumber = Intl.NumberFormat(computedLocale, options).format(parsedNumber);
const regexCurrency = /[.,\s0-9]/;
const { decimalSeparator, groupSeparator } = getSeparatorsFromNumber(
parsedNumber,
formattedNumber,
options,
);
// eslint-disable-next-line no-irregular-whitespace
const regexCurrency = /[.,\s0-9 _ ]/;
const regexMinusSign = /[-]/; // U+002D, Hyphen-Minus, -
const regexNum = /[0-9]/;
const regexSeparator = /[.,]/;
const regexSpace = /[\s]/;

@@ -60,2 +67,11 @@ let currency = '';

let fraction = false;
let isGroup = false;
const group = getGroupSeparator(computedLocale, options);
const decimal = getDecimalSeparator(computedLocale, options);
if (decimalSeparator && groupSeparator && group === decimal) {
throw new Error(`Decimal and group (thousand) separator are the same character: '${group}'.
This can happen due to both props being specified as the same, or one of the props being the same as the other one from default locale.
Please specify .groupSeparator / .decimalSeparator on the formatOptions object to be different.`);
}
for (let i = 0; i < formattedNumber.length; i += 1) {

@@ -81,4 +97,8 @@ // detect minusSign

// detect dot and comma separators
if (regexSeparator.test(formattedNumber[i])) {
// group sep must be lead by / followed by a number
if (
formattedNumber[i] === groupSeparator &&
formattedNumber[i - 1].match(regexNum) &&
formattedNumber[i + 1].match(regexNum)
) {
// Write number grouping

@@ -89,13 +109,20 @@ if (numberPart) {

}
const decimal = getDecimalSeparator(computedLocale);
if (formattedNumber[i] === decimal) {
formattedParts.push({ type: 'decimal', value: formattedNumber[i] });
fraction = true;
} else {
formattedParts.push({ type: 'group', value: formattedNumber[i] });
formattedParts.push({ type: 'group', value: group });
isGroup = true;
}
if (formattedNumber[i] === decimalSeparator) {
// Write number grouping
if (numberPart) {
formattedParts.push({ type: 'integer', value: numberPart });
numberPart = '';
}
formattedParts.push({ type: 'decimal', value: decimal });
fraction = true;
}
// detect literals (empty spaces) or space group separator
if (regexSpace.test(formattedNumber[i])) {
const group = getGroupSeparator(computedLocale);
const hasNumberPart = !!numberPart;

@@ -113,6 +140,8 @@ // Write number grouping

formattedParts.push({ type: 'group', value: formattedNumber[i] });
} else {
// if we already pushed it as a group separator, don't add it as a literal on top..
} else if (!isGroup) {
formattedParts.push({ type: 'literal', value: formattedNumber[i] });
}
}
isGroup = false;
// Numbers after the decimal sign are fractions, write the last

@@ -119,0 +148,0 @@ // fractions at the end of the number

@@ -5,4 +5,5 @@ /**

* @param {string} [locale] To override the browser locale
* @param {import('../../types/LocalizeMixinTypes').FormatNumberOptions} [options]
* @returns {string} The separator
*/
export function getDecimalSeparator(locale?: string | undefined): string;
export function getDecimalSeparator(locale?: string | undefined, options?: import("../../types/LocalizeMixinTypes").FormatNumberOptions | undefined): string;

@@ -7,5 +7,9 @@ import { getLocale } from '../utils/getLocale.js';

* @param {string} [locale] To override the browser locale
* @param {import('../../types/LocalizeMixinTypes').FormatNumberOptions} [options]
* @returns {string} The separator
*/
export function getDecimalSeparator(locale) {
export function getDecimalSeparator(locale, options) {
if (options && options.decimalSeparator) {
return options.decimalSeparator;
}
const computedLocale = getLocale(locale);

@@ -12,0 +16,0 @@ const formattedNumber = Intl.NumberFormat(computedLocale, {

@@ -5,4 +5,5 @@ /**

* @param {string} [locale] To override the browser locale
* @param {import('../../types/LocalizeMixinTypes').FormatNumberOptions} [options]
* @returns {string}
*/
export function getGroupSeparator(locale?: string | undefined): string;
export function getGroupSeparator(locale?: string | undefined, options?: import("../../types/LocalizeMixinTypes").FormatNumberOptions | undefined): string;

@@ -8,5 +8,9 @@ import { getLocale } from '../utils/getLocale.js';

* @param {string} [locale] To override the browser locale
* @param {import('../../types/LocalizeMixinTypes').FormatNumberOptions} [options]
* @returns {string}
*/
export function getGroupSeparator(locale) {
export function getGroupSeparator(locale, options) {
if (options && options.groupSeparator) {
return options.groupSeparator;
}
const computedLocale = getLocale(locale);

@@ -13,0 +17,0 @@ const formattedNumber = Intl.NumberFormat(computedLocale, {

@@ -18,4 +18,4 @@ /**

* @param {string} value Number to be parsed
* @param {object} [options] Locale Options
* @param {import('../../types/LocalizeMixinTypes').FormatNumberOptions} [options] Locale Options
*/
export function parseNumber(value: string, options?: object | undefined): number | undefined;
export function parseNumber(value: string, options?: import("../../types/LocalizeMixinTypes").FormatNumberOptions | undefined): number | undefined;

@@ -67,8 +67,7 @@ import { getDecimalSeparator } from './getDecimalSeparator.js';

* @param {string} value Number to be parsed
* @param {Object} options Locale Options
* @param {string} [options.locale]
* @param {import('../../types/LocalizeMixinTypes').FormatNumberOptions} options Locale Options
*/
function parseWithLocale(value, options) {
const locale = options && options.locale ? options.locale : undefined;
const separator = getDecimalSeparator(locale);
const separator = getDecimalSeparator(locale, options);
const regexNumberAndLocaleSeparator = new RegExp(`[0-9${separator}-]`, 'g');

@@ -99,3 +98,3 @@ let numberAndLocaleSeparator = value.match(regexNumberAndLocaleSeparator)?.join('');

.replace(/(,|\.)([^,|.]*)$/g, '_decSep_$2')
.replace(/(,|\.| )/g, '') // 2. remove all thousand separators
.replace(/(,|\.| )/g, '') // 2. remove all group separators
.replace(/_decSep_/, '.'); // 3. restore decimal separator

@@ -124,3 +123,3 @@ return parseFloat(numberString);

* @param {string} value Number to be parsed
* @param {object} [options] Locale Options
* @param {import('../../types/LocalizeMixinTypes').FormatNumberOptions} [options] Locale Options
*/

@@ -127,0 +126,0 @@ export function parseNumber(value, options) {

@@ -182,4 +182,62 @@ import { expect } from '@open-wc/testing';

).to.equal('112.345.678,00');
expect(
formatNumber(112345678, {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
groupSeparator: ' ',
decimalSeparator: '.',
}),
).to.equal('112 345 678.00');
});
it('throws when decimal and group separator are the same value, only when problematic', () => {
localize.locale = 'nl-NL';
const fn = () =>
formatNumber(112345678, {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
decimalSeparator: '.', // same as group separator for nl-NL
});
expect(fn).to.throw(`Decimal and group (thousand) separator are the same character: '.'.
This can happen due to both props being specified as the same, or one of the props being the same as the other one from default locale.
Please specify .groupSeparator / .decimalSeparator on the formatOptions object to be different.`);
const fn2 = () =>
formatNumber(112345678, {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
groupSeparator: ',',
decimalSeparator: ',',
});
expect(fn2).to.throw(`Decimal and group (thousand) separator are the same character: ','.
This can happen due to both props being specified as the same, or one of the props being the same as the other one from default locale.
Please specify .groupSeparator / .decimalSeparator on the formatOptions object to be different.`);
// this one doesn't end up with decimals, so not a problem
const fn3 = () =>
formatNumber(112345678, {
groupSeparator: ',',
decimalSeparator: ',',
});
expect(fn3).to.not.throw();
// this one doesn't end up with group separators (<1000), so not a problem
const fn4 = () =>
formatNumber(112.345678, {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
groupSeparator: ',',
decimalSeparator: ',',
});
expect(fn4).to.not.throw();
});
it('formats 2-digit decimals correctly', () => {

@@ -186,0 +244,0 @@ localize.locale = 'nl-NL';

@@ -11,2 +11,7 @@ import { expect } from '@open-wc/testing';

});
it('will return the decimalSeparator from options if passed', () => {
expect(getDecimalSeparator('nl-NL')).to.equal(',');
expect(getDecimalSeparator('nl-NL', { decimalSeparator: '.' })).to.equal('.');
});
});

@@ -22,3 +22,2 @@ import { Constructor } from '@open-wc/dedupe-mixin';

returnIfNaN?: string;
decimalSeparator?: string;
mode?: 'pasted' | 'auto';

@@ -39,3 +38,7 @@

returnIfNaN?: string;
decimalSeparator?: string;
// https://en.wikipedia.org/wiki/Decimal_separator#Current_standards
decimalSeparator?: ',' | '.';
// https://en.wikipedia.org/wiki/Decimal_separator#Digit_grouping
// note the half space in there as well
groupSeparator?: ',' | '.' | ' ' | '_' | ' ' | "'";
mode?: 'pasted' | 'auto';

@@ -42,0 +45,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc