diff --git a/packages/i18n/src/index.ts b/packages/i18n/src/index.ts index 1c0b5ff1..8d9881ba 100644 --- a/packages/i18n/src/index.ts +++ b/packages/i18n/src/index.ts @@ -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 { +export interface MtcuteI18nParameters { /** * Primary language which will also be used as a fallback */ @@ -28,15 +33,21 @@ export interface MtcuteI18nParameters { * Defaults to {@link primaryLanguage} */ defaultLanguage?: string + + /** + * Adapter that will be used to extract language from the update. + */ + adapter?: MtcuteI18nAdapter } -export function createMtcuteI18n( - params: MtcuteI18nParameters -): MtcuteI18nFunction { +export function createMtcuteI18n( + params: MtcuteI18nParameters +): MtcuteI18nFunction { const { primaryLanguage, otherLanguages, defaultLanguage = primaryLanguage.name, + adapter = extractLanguageFromUpdate as any as MtcuteI18nAdapter, } = params const indexes: Record> = {} @@ -54,11 +65,15 @@ export function createMtcuteI18n( ) } - 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( return val } - return tr as MtcuteI18nFunction + return tr as MtcuteI18nFunction } diff --git a/packages/i18n/src/types.ts b/packages/i18n/src/types.ts index dce7d90f..e287167a 100644 --- a/packages/i18n/src/types.ts +++ b/packages/i18n/src/types.ts @@ -25,10 +25,12 @@ type ExtractParameter = GetValueNested< ? R : never -export type MtcuteI18nFunction = < +export type MtcuteI18nAdapter = (obj: Input) => string | null | undefined + +export type MtcuteI18nFunction = < K extends NestedKeysDelimited >( - lang: ParsedUpdate['data'] | string | null, + lang: Input | string | null, key: K, ...params: ExtractParameter ) => string | FormattedString diff --git a/packages/i18n/tests/i18n.spec.ts b/packages/i18n/tests/i18n.spec.ts index c328f759..13dcf334 100644 --- a/packages/i18n/tests/i18n.spec.ts +++ b/packages/i18n/tests/i18n.spec.ts @@ -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('Привет') + }) })