mirror of
https://github.com/cupcakearmy/svelte-i18n.git
synced 2024-06-30 18:54:49 +02:00
chore: fixes for 1st review
This commit is contained in:
parent
bf4189a862
commit
8235f1e078
|
@ -38,7 +38,11 @@ export const defaultFormats: Formats = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultOptions: ConfigureOptions = {
|
export const defaultOptions: Omit<
|
||||||
|
ConfigureOptions,
|
||||||
|
'fallbackLocale' | 'initialLocale'
|
||||||
|
> &
|
||||||
|
Record<'fallbackLocale' | 'initialLocale', null> = {
|
||||||
fallbackLocale: null,
|
fallbackLocale: null,
|
||||||
initialLocale: null,
|
initialLocale: null,
|
||||||
loadingDelay: 200,
|
loadingDelay: 200,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Formats } from 'intl-messageformat';
|
||||||
import IntlMessageFormat from 'intl-messageformat';
|
import IntlMessageFormat from 'intl-messageformat';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
|
@ -34,8 +35,8 @@ const getIntlFormatterOptions = (
|
||||||
): any => {
|
): any => {
|
||||||
const { formats } = getOptions();
|
const { formats } = getOptions();
|
||||||
|
|
||||||
if (type in formats && name in formats[type]) {
|
if (type in formats && name in (formats as Formats)[type]) {
|
||||||
return formats[type][name];
|
return (formats as Formats)[type][name];
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(`[svelte-i18n] Unknown "${name}" ${type} format.`);
|
throw new Error(`[svelte-i18n] Unknown "${name}" ${type} format.`);
|
||||||
|
@ -105,7 +106,7 @@ export const getTimeFormatter: MemoizedDateTimeFormatterFactoryOptional = ({
|
||||||
} = {}) => createTimeFormatter({ locale, ...args });
|
} = {}) => createTimeFormatter({ locale, ...args });
|
||||||
|
|
||||||
export const getMessageFormatter = monadicMemoize(
|
export const getMessageFormatter = monadicMemoize(
|
||||||
(message: string, locale: string = getCurrentLocale()) =>
|
(message: string, locale: string = getCurrentLocale()!) =>
|
||||||
new IntlMessageFormat(message, locale, getOptions().formats, {
|
new IntlMessageFormat(message, locale, getOptions().formats, {
|
||||||
ignoreTag: getOptions().ignoreTag,
|
ignoreTag: getOptions().ignoreTag,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -62,13 +62,13 @@ function loadLocaleQueue(locale: string, localeQueue: MessagesLoader[]) {
|
||||||
|
|
||||||
const activeFlushes: { [key: string]: Promise<void> } = {};
|
const activeFlushes: { [key: string]: Promise<void> } = {};
|
||||||
|
|
||||||
export async function flush(locale: string): Promise<void> {
|
export function flush(locale: string): Promise<void> {
|
||||||
if (!hasLocaleQueue(locale)) {
|
if (!hasLocaleQueue(locale)) {
|
||||||
if (locale in activeFlushes) {
|
if (locale in activeFlushes) {
|
||||||
return activeFlushes[locale];
|
return activeFlushes[locale];
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
// get queue of XX-YY and XX locales
|
// get queue of XX-YY and XX locales
|
||||||
|
|
|
@ -35,8 +35,8 @@ export function getMessageFromDictionary(locale: string, id: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getClosestAvailableLocale(
|
export function getClosestAvailableLocale(
|
||||||
refLocale: string,
|
refLocale: string | null | undefined,
|
||||||
): string | null | undefined {
|
): string | undefined {
|
||||||
if (refLocale == null) return undefined;
|
if (refLocale == null) return undefined;
|
||||||
|
|
||||||
const relatedLocales = getPossibleLocales(refLocale);
|
const relatedLocales = getPossibleLocales(refLocale);
|
||||||
|
|
|
@ -47,7 +47,7 @@ const formatMessage: MessageFormatter = (id, options = {}) => {
|
||||||
`[svelte-i18n] The message "${id}" was not found in "${getPossibleLocales(
|
`[svelte-i18n] The message "${id}" was not found in "${getPossibleLocales(
|
||||||
locale,
|
locale,
|
||||||
).join('", "')}".${
|
).join('", "')}".${
|
||||||
hasLocaleQueue(getCurrentLocale())
|
hasLocaleQueue(getCurrentLocale()!)
|
||||||
? `\n\nNote: there are at least one loader still registered to this locale that wasn't executed.`
|
? `\n\nNote: there are at least one loader still registered to this locale that wasn't executed.`
|
||||||
: ''
|
: ''
|
||||||
}`,
|
}`,
|
||||||
|
|
|
@ -5,8 +5,8 @@ import { getOptions } from '../configs';
|
||||||
import { getClosestAvailableLocale } from './dictionary';
|
import { getClosestAvailableLocale } from './dictionary';
|
||||||
import { $isLoading } from './loading';
|
import { $isLoading } from './loading';
|
||||||
|
|
||||||
let current: string;
|
let current: string | null | undefined;
|
||||||
const $locale = writable<string | null | undefined>(null);
|
const internalLocale = writable<string | null | undefined>(null);
|
||||||
|
|
||||||
function getSubLocales(refLocale: string) {
|
function getSubLocales(refLocale: string) {
|
||||||
return refLocale
|
return refLocale
|
||||||
|
@ -32,18 +32,21 @@ export function getCurrentLocale() {
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
$locale.subscribe((newLocale: string) => {
|
internalLocale.subscribe((newLocale: string | null | undefined) => {
|
||||||
current = newLocale;
|
current = newLocale;
|
||||||
|
|
||||||
if (typeof window !== 'undefined' && newLocale !== null) {
|
if (typeof window !== 'undefined' && newLocale != null) {
|
||||||
document.documentElement.setAttribute('lang', newLocale);
|
document.documentElement.setAttribute('lang', newLocale);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const localeSet = $locale.set;
|
const set = (newLocale: string | null | undefined): void | Promise<void> => {
|
||||||
|
if (
|
||||||
$locale.set = (newLocale: string): void | Promise<void> => {
|
((getClosestAvailableLocale as unknown) as (
|
||||||
if (getClosestAvailableLocale(newLocale) && hasLocaleQueue(newLocale)) {
|
refLocale: string | null | undefined,
|
||||||
|
) => refLocale is string)(newLocale) &&
|
||||||
|
hasLocaleQueue(newLocale)
|
||||||
|
) {
|
||||||
const { loadingDelay } = getOptions();
|
const { loadingDelay } = getOptions();
|
||||||
|
|
||||||
let loadingTimer: number;
|
let loadingTimer: number;
|
||||||
|
@ -65,7 +68,7 @@ $locale.set = (newLocale: string): void | Promise<void> => {
|
||||||
|
|
||||||
return flush(newLocale)
|
return flush(newLocale)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
localeSet(newLocale);
|
internalLocale.set(newLocale);
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
clearTimeout(loadingTimer);
|
clearTimeout(loadingTimer);
|
||||||
|
@ -73,12 +76,12 @@ $locale.set = (newLocale: string): void | Promise<void> => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return localeSet(newLocale);
|
return internalLocale.set(newLocale);
|
||||||
};
|
};
|
||||||
|
|
||||||
// istanbul ignore next
|
const $locale = {
|
||||||
$locale.update = (
|
...internalLocale,
|
||||||
fn: (value: string | null | undefined) => string | null | undefined,
|
set,
|
||||||
) => localeSet(fn(current));
|
};
|
||||||
|
|
||||||
export { $locale };
|
export { $locale };
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { FormatXMLElementFn, Formats } from 'intl-messageformat';
|
import type { Formats, FormatXMLElementFn } from 'intl-messageformat';
|
||||||
|
|
||||||
export interface LocaleDictionary {
|
export interface LocaleDictionary {
|
||||||
[key: string]:
|
[key: string]:
|
||||||
|
@ -27,7 +27,7 @@ export type InterpolationValues =
|
||||||
|
|
||||||
export interface MessageObject {
|
export interface MessageObject {
|
||||||
id?: string;
|
id?: string;
|
||||||
locale?: string;
|
locale?: string | null;
|
||||||
format?: string;
|
format?: string;
|
||||||
default?: string;
|
default?: string;
|
||||||
values?: InterpolationValues;
|
values?: InterpolationValues;
|
||||||
|
@ -53,11 +53,11 @@ export type NumberFormatter = (
|
||||||
options?: IntlFormatterOptions<Intl.NumberFormatOptions>,
|
options?: IntlFormatterOptions<Intl.NumberFormatOptions>,
|
||||||
) => string;
|
) => string;
|
||||||
|
|
||||||
export type JSONGetter = (id: string, locale?: string) => any;
|
export type JSONGetter = (id: string, locale?: string | null) => any;
|
||||||
|
|
||||||
type IntlFormatterOptions<T> = T & {
|
type IntlFormatterOptions<T> = T & {
|
||||||
format?: string;
|
format?: string;
|
||||||
locale?: string;
|
locale?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface MemoizedIntlFormatter<T, U> {
|
export interface MemoizedIntlFormatter<T, U> {
|
||||||
|
@ -73,14 +73,13 @@ export interface MessagesLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConfigureOptions {
|
export interface ConfigureOptions {
|
||||||
fallbackLocale: string | null | undefined;
|
fallbackLocale: string;
|
||||||
formats: Formats;
|
formats: Partial<Formats>;
|
||||||
initialLocale: string | null;
|
initialLocale: string;
|
||||||
loadingDelay: number;
|
loadingDelay: number;
|
||||||
warnOnMissingMessages: boolean;
|
warnOnMissingMessages: boolean;
|
||||||
ignoreTag: boolean;
|
ignoreTag: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ConfigureOptionsInit = Pick<ConfigureOptions, 'fallbackLocale'> &
|
export type ConfigureOptionsInit = Pick<ConfigureOptions, 'fallbackLocale'> &
|
||||||
Partial<Record<'formats', Partial<ConfigureOptions['formats']>>> &
|
Partial<Omit<ConfigureOptions, 'fallbackLocale'>>;
|
||||||
Partial<Omit<ConfigureOptions, 'fallbackLocale' | 'formats'>>;
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
import { $locale } from '../../src/runtime/stores/locale';
|
import { $locale } from '../../src/runtime/stores/locale';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
init(defaultOptions);
|
init(defaultOptions as any);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('inits the fallback locale', () => {
|
test('inits the fallback locale', () => {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
const formatsJson = require('../../fixtures/formats.json');
|
const formatsJson = require('../../fixtures/formats.json');
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
init({ fallbackLocale: undefined });
|
init({ fallbackLocale: undefined as any });
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('number formatter', () => {
|
describe('number formatter', () => {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { register, isLoading } from '../../../src/runtime';
|
||||||
import { hasLocaleQueue } from '../../../src/runtime/includes/loaderQueue';
|
import { hasLocaleQueue } from '../../../src/runtime/includes/loaderQueue';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
init({ fallbackLocale: undefined });
|
init({ fallbackLocale: undefined as any });
|
||||||
$locale.set(undefined);
|
$locale.set(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ test('if no initial locale is set, set the locale to the fallback', () => {
|
||||||
test('if no initial locale was found, set to the fallback locale', () => {
|
test('if no initial locale was found, set to the fallback locale', () => {
|
||||||
init({
|
init({
|
||||||
fallbackLocale: 'en',
|
fallbackLocale: 'en',
|
||||||
initialLocale: null,
|
initialLocale: null as any,
|
||||||
});
|
});
|
||||||
expect(get($locale)).toBe('en');
|
expect(get($locale)).toBe('en');
|
||||||
expect(getOptions().fallbackLocale).toBe('en');
|
expect(getOptions().fallbackLocale).toBe('en');
|
||||||
|
|
Loading…
Reference in New Issue
Block a user