gristlabs_grist-core/app/common/Locales.ts
Dmitry S dd2eadc86e (core) Speed up and upgrade build.
Summary:
- Upgrades to build-related packages:
  - Upgrade typescript, related libraries and typings.
  - Upgrade webpack, eslint; add tsc-watch, node-dev, eslint_d.

- Build organization changes:
  - Build webpack from original typescript, transpiling only; with errors still
    reported by a background tsc watching process.

- Typescript-related changes:
  - Reduce imports of AWS dependencies (very noticeable speedup)
  - Avoid auto-loading global @types
  - Client code is now built with isolatedModules flag (for safe transpilation)
  - Use allowJs to avoid copying JS files manually.

- Linting changes
  - Enhance Arcanist ESLintLinter to run before/after commands, and set up to use eslint_d
  - Update eslint config, and include .eslintignore to avoid linting generated files.
  - Include a bunch of eslint-prompted and eslint-generated fixes
  - Add no-unused-expression rule to eslint, and fix a few warnings about it

- Other items:
  - Refactor cssInput to avoid circular dependency
  - Remove a bit of unused code, libraries, dependencies

Test Plan: No behavior changes, all existing tests pass. There are 30 tests fewer reported because `test_gpath.py` was removed (it's been unused for years)

Reviewers: paulfitz

Reviewed By: paulfitz

Subscribers: paulfitz

Differential Revision: https://phab.getgrist.com/D3498
2022-06-27 16:10:10 -04:00

71 lines
2.4 KiB
TypeScript

import * as LocaleCurrencyMap from 'locale-currency/map';
import * as LocaleCurrency from 'locale-currency';
import {nativeCompare} from 'app/common/gutil';
import {localeCodes} from "app/common/LocaleCodes";
const DEFAULT_CURRENCY = "USD";
export interface Locale {
name: string;
code: string;
}
export let locales: Readonly<Locale[]>;
// Intl.DisplayNames is only supported on recent browsers, so proceed with caution.
try {
const regionDisplay = new Intl.DisplayNames('en', {type: 'region'});
const languageDisplay = new Intl.DisplayNames('en', {type: 'language'});
const display = (code: string) => {
try {
const locale = new Intl.Locale(code);
const regionName = regionDisplay.of(locale.region!);
const languageName = languageDisplay.of(locale.language);
return `${regionName} (${languageName})`;
} catch (ex) {
return code;
}
};
// Leave only those that are supported by current system (can be translated to human readable form).
// Though, this file is in common, it is safe to filter by current system
// as the list should be already filtered by codes that are supported by the backend.
locales = Intl.DisplayNames.supportedLocalesOf(localeCodes).map(code => {
return {name: display(code), code};
});
} catch {
// Fall back to using the locale code as the display name.
locales = localeCodes.map(code => ({name: code, code}));
}
export interface Currency {
name: string;
code: string;
}
export let currencies: Readonly<Currency[]>;
// locale-currency package doesn't have South Sudanese pound currency or a default value for Kosovo
LocaleCurrencyMap["SS"] = "SSP";
LocaleCurrencyMap["XK"] = "EUR";
const currenciesCodes = Object.values(LocaleCurrencyMap);
export function getCurrency(code: string) {
const currency = LocaleCurrency.getCurrency(code ?? 'en-US');
// Fallback to USD
return currency ?? DEFAULT_CURRENCY;
}
// Intl.DisplayNames is only supported on recent browsers, so proceed with caution.
try {
const currencyDisplay = new Intl.DisplayNames('en', {type: 'currency'});
currencies = [...new Set(currenciesCodes)].map(code => {
return {name: currencyDisplay.of(code)!, code};
});
} catch {
// Fall back to using the currency code as the display name.
currencies = [...new Set(currenciesCodes)].map(code => {
return {name: code, code};
});
}
currencies = [...currencies].sort((a, b) => nativeCompare(a.code, b.code));