2
0
mirror of https://github.com/frappe/books.git synced 2024-11-08 14:50:56 +00:00
books/fyo/utils/translation.ts
18alantom c78237a0d9 fix: translations in setup wiz
- maintain translations on reload
2023-07-16 23:13:12 -07:00

137 lines
2.9 KiB
TypeScript

import { LanguageMap, UnknownMap } from 'utils/types';
import {
getIndexFormat,
getIndexList,
getSnippets,
getWhitespaceSanitized,
} from '../../utils/translationHelpers';
import { ValueError } from './errors';
export type TranslationArgs = boolean | number | string;
export type TranslationLiteral = TemplateStringsArray | TranslationArgs;
export class TranslationString {
args: TranslationLiteral[];
argList?: TranslationArgs[];
strList?: string[];
context?: string;
languageMap?: LanguageMap;
constructor(...args: TranslationLiteral[]) {
this.args = args;
}
get s() {
return this.toString();
}
ctx(context?: string) {
this.context = context;
return this;
}
#formatArg(arg: string | number | boolean) {
return String(arg ?? '');
}
#translate() {
let indexFormat = getIndexFormat(this.args[0] as string);
indexFormat = getWhitespaceSanitized(indexFormat);
const translatedIndexFormat =
this.languageMap![indexFormat]?.translation ?? indexFormat;
this.argList = getIndexList(translatedIndexFormat).map(
(i) => this.argList![i]
);
this.strList = getSnippets(translatedIndexFormat);
}
#stitch() {
if (!((this.args[0] as unknown) instanceof Array)) {
throw new ValueError(
`invalid args passed to TranslationString ${String(
this.args
)} of type ${typeof this.args[0]}`
);
}
this.strList = this.args[0] as unknown as string[];
this.argList = this.args.slice(1) as TranslationArgs[];
if (this.languageMap) {
this.#translate();
}
return this.strList
.map((s, i) => s + this.#formatArg(this.argList![i]))
.join('')
.replace(/\s+/g, ' ')
.trim();
}
toString() {
return this.#stitch();
}
toJSON() {
return this.#stitch();
}
valueOf() {
return this.#stitch();
}
}
export function T(...args: string[]): TranslationString {
return new TranslationString(...args);
}
export function t(...args: TranslationLiteral[]): string {
return new TranslationString(...args).s;
}
export function setLanguageMapOnTranslationString(
languageMap: LanguageMap | undefined
) {
TranslationString.prototype.languageMap = languageMap;
}
export function translateSchema(
map: UnknownMap | UnknownMap[],
languageMap: LanguageMap,
translateables: string[]
) {
if (Array.isArray(map)) {
for (const item of map) {
translateSchema(item, languageMap, translateables);
}
return;
}
if (typeof map !== 'object') {
return;
}
for (const key of Object.keys(map)) {
const value = map[key];
if (
typeof value === 'string' &&
translateables.includes(key) &&
languageMap[value]?.translation
) {
map[key] = languageMap[value].translation;
}
if (typeof value !== 'object') {
continue;
}
translateSchema(
value as UnknownMap | UnknownMap[],
languageMap,
translateables
);
}
}