Skip to content

Commit

Permalink
fix: don't fail on invalid locale code
Browse files Browse the repository at this point in the history
  • Loading branch information
stepan662 committed Sep 7, 2022
1 parent aa71ab4 commit 5434d32
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
21 changes: 21 additions & 0 deletions packages/core/src/modules/IcuFormatter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
jest.autoMockOff();
import { IcuFormatter } from './IcuFormatter';

describe('icu formatter', () => {
it('formats simple string', () => {
const formatter = new IcuFormatter();
const result = formatter.format({
translation: 'result is {number, number}',
params: { number: 42000 },
language: 'en',
});
expect(result).toEqual('result is 42,000');
});

it('fixes invalid locale', () => {
const formatter = new IcuFormatter() as any;
expect(formatter.getLocale('en_GB')).toEqual('en-GB');
expect(formatter.getLocale('en_GB-nonsenceeeee')).toEqual('en-GB');
expect(formatter.getLocale('cs CZ')).toEqual('cs-CZ');
});
});
26 changes: 24 additions & 2 deletions packages/core/src/modules/IcuFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,36 @@ import { TolgeeModule } from '../types';
export const IcuFormatter: TolgeeModule = class {
static type = 'formatter' as const;

cache = new Map<string, IntlMessageFormat>();
private locales = new Map() as Map<string, string>;

isLocaleValid(locale: string) {
try {
return Boolean(Intl.NumberFormat.supportedLocalesOf(locale).length);
} catch {
return false;
}
}

getLocale(language: string) {
if (!this.locales.get(language)) {
let localeCandidate: string = String(language).replace(/[^a-zA-Z]/g, '-');
while (!this.isLocaleValid(localeCandidate)) {
localeCandidate =
localeCandidate.split('-').slice(0, -1).join('-') || 'en';
}
this.locales.set(language, localeCandidate);
}
return this.locales.get(language);
}

format({ translation, language, params }) {
const ignoreTag = !Object.values(params).find(
(p) => typeof p === 'function'
);

return new IntlMessageFormat(translation, language, undefined, {
const locale = this.getLocale(language);

return new IntlMessageFormat(translation, locale, undefined, {
ignoreTag,
}).format(params) as string;
}
Expand Down

0 comments on commit 5434d32

Please sign in to comment.