feat(i18n): allow custom adapters

This commit is contained in:
teidesu 2022-08-29 18:53:27 +03:00
parent ea299cacca
commit 689533c549
3 changed files with 42 additions and 11 deletions

View file

@ -1,10 +1,15 @@
import { MtArgumentError, ParsedUpdate } from '@mtcute/client'
import { I18nValue, MtcuteI18nFunction, OtherLanguageWrap } from './types'
import {
I18nValue,
MtcuteI18nAdapter,
MtcuteI18nFunction,
OtherLanguageWrap,
} from './types'
import { createI18nStringsIndex, extractLanguageFromUpdate } from './utils'
export * from './types'
export interface MtcuteI18nParameters<Strings> {
export interface MtcuteI18nParameters<Strings, Input> {
/**
* Primary language which will also be used as a fallback
*/
@ -28,15 +33,21 @@ export interface MtcuteI18nParameters<Strings> {
* Defaults to {@link primaryLanguage}
*/
defaultLanguage?: string
/**
* Adapter that will be used to extract language from the update.
*/
adapter?: MtcuteI18nAdapter<Input>
}
export function createMtcuteI18n<Strings>(
params: MtcuteI18nParameters<Strings>
): MtcuteI18nFunction<Strings> {
export function createMtcuteI18n<Strings, Input>(
params: MtcuteI18nParameters<Strings, Input>
): MtcuteI18nFunction<Strings, Input> {
const {
primaryLanguage,
otherLanguages,
defaultLanguage = primaryLanguage.name,
adapter = extractLanguageFromUpdate as any as MtcuteI18nAdapter<Input>,
} = params
const indexes: Record<string, Record<string, I18nValue>> = {}
@ -54,11 +65,15 @@ export function createMtcuteI18n<Strings>(
)
}
const tr = (lang: ParsedUpdate['data'] | string | null, key: string, ...params: any[]) => {
const tr = (
lang: Input | string | null,
key: string,
...params: any[]
) => {
if (lang === null) lang = defaultLanguage
if (typeof lang === 'object') {
lang = extractLanguageFromUpdate(lang) ?? defaultLanguage
if (typeof lang !== 'string') {
lang = adapter(lang) ?? defaultLanguage
}
const strings = indexes[lang] ?? fallbackIndex
@ -72,5 +87,5 @@ export function createMtcuteI18n<Strings>(
return val
}
return tr as MtcuteI18nFunction<Strings>
return tr as MtcuteI18nFunction<Strings, Input>
}

View file

@ -25,10 +25,12 @@ type ExtractParameter<Strings, K extends string> = GetValueNested<
? R
: never
export type MtcuteI18nFunction<Strings> = <
export type MtcuteI18nAdapter<Input> = (obj: Input) => string | null | undefined
export type MtcuteI18nFunction<Strings, Input = ParsedUpdate['data']> = <
K extends NestedKeysDelimited<Strings>
>(
lang: ParsedUpdate['data'] | string | null,
lang: Input | string | null,
key: K,
...params: ExtractParameter<Strings, K>
) => string | FormattedString<any>

View file

@ -91,4 +91,18 @@ describe('i18n', () => {
expect(tr(message, 'direct')).to.equal('Привет')
})
it('should accept custom adapters', () => {
const tr = createMtcuteI18n({
primaryLanguage: {
name: 'en',
strings: en,
},
otherLanguages: { ru },
adapter: (num: number) => num === 1 ? 'en' : 'ru',
})
expect(tr(1, 'direct')).to.equal('Hello')
expect(tr(2, 'direct')).to.equal('Привет')
})
})