mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
refactor(api): tidy the api and shared packages (#2733)
This commit is contained in:
1 parent
580401d2dc
commit
5afbf67a70
333 files changed
+10180
-7910
No files matched your search
@@ -1,13 +0,0 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {TemplateCompiler} from '@fluxer/i18n/src/runtime/I18nTypes';
|
||||
import type MessageFormat from '@messageformat/core';
|
||||
|
||||
export function compileTemplate<TValue, TVariables>(
|
||||
compiler: TemplateCompiler<TValue, TVariables>,
|
||||
template: TValue,
|
||||
variables: TVariables,
|
||||
mf: MessageFormat,
|
||||
): TValue {
|
||||
return compiler(template, variables, mf);
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {I18nResult, TemplateCompiler} from '@fluxer/i18n/src/runtime/I18nTypes';
|
||||
import {getEffectiveStaticLocale} from '@fluxer/i18n/src/runtime/StaticLocale';
|
||||
import MessageFormat from '@messageformat/core';
|
||||
import {renderTemplate} from '@fluxer/i18n/src/runtime/RenderTemplate';
|
||||
import {getEffectiveStaticLocale, hasStaticLocale} from '@fluxer/i18n/src/runtime/StaticLocale';
|
||||
import type MessageFormat from '@messageformat/core';
|
||||
|
||||
export type StaticLocaleMessages<TKey extends string, TValue> = Partial<Record<TKey, TValue>>;
|
||||
|
||||
@@ -28,20 +29,11 @@ export function createStaticI18n<TKey extends string, TValue, TVariables>(
|
||||
): StaticI18nModule<TKey, TValue, TVariables> {
|
||||
const loadedLocales = new Set<string>([config.defaultLocale]);
|
||||
const messageFormatCache = new Map<string, MessageFormat>();
|
||||
function getMessageFormat(locale: string): MessageFormat {
|
||||
const cached = messageFormatCache.get(locale);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
const messageFormat = new MessageFormat(locale);
|
||||
messageFormatCache.set(locale, messageFormat);
|
||||
return messageFormat;
|
||||
}
|
||||
return {
|
||||
getTemplate(key: TKey, locale: string | null, variables: TVariables): I18nResult<TKey, TValue> {
|
||||
const effectiveLocale = getEffectiveStaticLocale(config, locale);
|
||||
loadedLocales.add(effectiveLocale);
|
||||
const sourceTemplate = config.defaultMessages[key];
|
||||
const sourceTemplate = Object.hasOwn(config.defaultMessages, key) ? config.defaultMessages[key] : undefined;
|
||||
if (sourceTemplate === undefined) {
|
||||
return {
|
||||
ok: false,
|
||||
@@ -53,7 +45,11 @@ export function createStaticI18n<TKey extends string, TValue, TVariables>(
|
||||
locale: effectiveLocale,
|
||||
};
|
||||
}
|
||||
const translatedTemplate = config.localeMessages[effectiveLocale]?.[key];
|
||||
const localeMessages = Object.hasOwn(config.localeMessages, effectiveLocale)
|
||||
? config.localeMessages[effectiveLocale]
|
||||
: undefined;
|
||||
const translatedTemplate =
|
||||
localeMessages != null && Object.hasOwn(localeMessages, key) ? localeMessages[key] : undefined;
|
||||
const template = translatedTemplate ?? sourceTemplate;
|
||||
const validationError = config.validateVariables?.(key, template, variables);
|
||||
if (validationError) {
|
||||
@@ -67,27 +63,18 @@ export function createStaticI18n<TKey extends string, TValue, TVariables>(
|
||||
locale: effectiveLocale,
|
||||
};
|
||||
}
|
||||
try {
|
||||
return {
|
||||
ok: true,
|
||||
value: compile(template, variables, getMessageFormat(effectiveLocale)),
|
||||
locale: effectiveLocale,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
ok: false,
|
||||
error: {
|
||||
kind: 'compile-failed',
|
||||
key,
|
||||
message: error instanceof Error ? error.message : 'Failed to compile template',
|
||||
},
|
||||
locale: effectiveLocale,
|
||||
};
|
||||
}
|
||||
return renderTemplate({
|
||||
key,
|
||||
locale: effectiveLocale,
|
||||
template,
|
||||
variables,
|
||||
compile,
|
||||
messageFormatCache,
|
||||
});
|
||||
},
|
||||
hasLocale(locale: string): boolean {
|
||||
const normalizedLocale = config.normalizeLocale?.(locale) ?? locale;
|
||||
return normalizedLocale === config.defaultLocale || config.localeMessages[normalizedLocale] !== undefined;
|
||||
return hasStaticLocale(config, normalizedLocale);
|
||||
},
|
||||
getLoadedLocales(): Set<string> {
|
||||
return new Set(loadedLocales);
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {compileTemplate} from '@fluxer/i18n/src/runtime/CompileTemplate';
|
||||
import {getEffectiveLocale} from '@fluxer/i18n/src/runtime/GetEffectiveLocale';
|
||||
import type {I18nResult, I18nState, TemplateCompiler} from '@fluxer/i18n/src/runtime/I18nTypes';
|
||||
import {loadLocaleIfNotLoaded} from '@fluxer/i18n/src/runtime/LoadLocale';
|
||||
import MessageFormat from '@messageformat/core';
|
||||
import {renderTemplate} from '@fluxer/i18n/src/runtime/RenderTemplate';
|
||||
|
||||
export function getTemplate<TKey extends string, TValue, TVariables>(
|
||||
state: I18nState<TKey, TValue, TVariables>,
|
||||
@@ -41,31 +40,12 @@ export function getTemplate<TKey extends string, TValue, TVariables>(
|
||||
locale: effectiveLocale,
|
||||
};
|
||||
}
|
||||
try {
|
||||
const compiled = compileTemplate(compile, template, variables, getMessageFormat(state, effectiveLocale));
|
||||
return {ok: true, value: compiled, locale: effectiveLocale};
|
||||
} catch (error) {
|
||||
return {
|
||||
ok: false,
|
||||
error: {
|
||||
kind: 'compile-failed',
|
||||
key,
|
||||
message: error instanceof Error ? error.message : 'Failed to compile template',
|
||||
},
|
||||
locale: effectiveLocale,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getMessageFormat<TKey extends string, TValue, TVariables>(
|
||||
state: I18nState<TKey, TValue, TVariables>,
|
||||
locale: string,
|
||||
): MessageFormat {
|
||||
const cached = state.messageFormatCache.get(locale);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
const mf = new MessageFormat(locale);
|
||||
state.messageFormatCache.set(locale, mf);
|
||||
return mf;
|
||||
return renderTemplate({
|
||||
key,
|
||||
locale: effectiveLocale,
|
||||
template,
|
||||
variables,
|
||||
compile,
|
||||
messageFormatCache: state.messageFormatCache,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {I18nResult, TemplateCompiler} from '@fluxer/i18n/src/runtime/I18nTypes';
|
||||
import MessageFormat from '@messageformat/core';
|
||||
|
||||
interface TemplateRenderOptions<TKey extends string, TValue, TVariables> {
|
||||
key: TKey;
|
||||
locale: string;
|
||||
template: TValue;
|
||||
variables: TVariables;
|
||||
compile: TemplateCompiler<TValue, TVariables>;
|
||||
messageFormatCache: Map<string, MessageFormat>;
|
||||
}
|
||||
|
||||
export function renderTemplate<TKey extends string, TValue, TVariables>({
|
||||
key,
|
||||
locale,
|
||||
template,
|
||||
variables,
|
||||
compile,
|
||||
messageFormatCache,
|
||||
}: TemplateRenderOptions<TKey, TValue, TVariables>): I18nResult<TKey, TValue> {
|
||||
try {
|
||||
let messageFormat = messageFormatCache.get(locale);
|
||||
if (!messageFormat) {
|
||||
messageFormat = new MessageFormat(locale);
|
||||
messageFormatCache.set(locale, messageFormat);
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
value: compile(template, variables, messageFormat),
|
||||
locale,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
ok: false,
|
||||
error: {
|
||||
kind: 'compile-failed',
|
||||
key,
|
||||
message: error instanceof Error ? error.message : 'Failed to compile template',
|
||||
},
|
||||
locale,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,16 @@
|
||||
|
||||
import type {StaticI18nConfig} from '@fluxer/i18n/src/runtime/CreateStaticI18n';
|
||||
|
||||
export function hasStaticLocale<TKey extends string, TValue, TVariables>(
|
||||
config: StaticI18nConfig<TKey, TValue, TVariables>,
|
||||
normalizedLocale: string,
|
||||
): boolean {
|
||||
return (
|
||||
normalizedLocale === config.defaultLocale ||
|
||||
(Object.hasOwn(config.localeMessages, normalizedLocale) && config.localeMessages[normalizedLocale] !== undefined)
|
||||
);
|
||||
}
|
||||
|
||||
export function getEffectiveStaticLocale<TKey extends string, TValue, TVariables>(
|
||||
config: StaticI18nConfig<TKey, TValue, TVariables>,
|
||||
locale: string | null | undefined,
|
||||
@@ -10,10 +20,7 @@ export function getEffectiveStaticLocale<TKey extends string, TValue, TVariables
|
||||
return config.defaultLocale;
|
||||
}
|
||||
const normalizedLocale = config.normalizeLocale?.(locale) ?? locale;
|
||||
if (normalizedLocale === config.defaultLocale) {
|
||||
return config.defaultLocale;
|
||||
}
|
||||
if (config.localeMessages[normalizedLocale] === undefined) {
|
||||
if (!hasStaticLocale(config, normalizedLocale)) {
|
||||
config.onWarning?.(`Unsupported locale, falling back to ${config.defaultLocale}: ${locale}`);
|
||||
return config.defaultLocale;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user