import { debuglog, format } from 'node:util'; import { EggCore } from '@eggjs/core'; import { isObject } from '../../utils.js'; const debug = debuglog('@eggjs/i18n/app/extend/application'); export const I18N_RESOURCES = Symbol('Application i18n resources'); export default class I18nApplication extends EggCore { declare [I18N_RESOURCES]: Record>; isSupportLocale(locale: string) { return !!this[I18N_RESOURCES][locale]; } gettext(locale: string, key: string, value?: any, ...args: any[]) { if (!locale || !key) { // __() // __('en') return ''; } const resource = this[I18N_RESOURCES][locale] || {}; let text = resource[key]; if (text === undefined) { text = key; } debug('%s: %j => %j', locale, key, text); if (!text) { return ''; } if (value === undefined) { // __(locale, key) return text; } if (args.length === 0) { if (isObject(value)) { // __(locale, key, object) // __('zh', '{a} {b} {b} {a}', {a: 'foo', b: 'bar'}) // => // foo bar bar foo return formatWithObject(text, value); } if (Array.isArray(value)) { // __(locale, key, array) // __('zh', '{0} {1} {1} {0}', ['foo', 'bar']) // => // foo bar bar foo return formatWithArray(text, value); } // __(locale, key, value) return format(text, value); } // __(locale, key, value1, ...) return format(text, value, ...args); } __(locale: string, key: string, value?: any, ...args: any[]) { return this.gettext(locale, key, value, ...args); } } const ARRAY_INDEX_RE = /\{(\d+)\}/g; function formatWithArray(text: string, values: any[]) { return text.replace(ARRAY_INDEX_RE, (original, matched) => { const index = parseInt(matched); if (index < values.length) { return values[index]; } // not match index, return original text return original; }); } const Object_INDEX_RE = /\{(.+?)\}/g; function formatWithObject(text: string, values: Record) { return text.replace(Object_INDEX_RE, (original, matched) => { const value = values[matched]; if (value) { return value; } // not match index, return original text return original; }); }