@nuxtjs/i18n
Version:
Internationalization for Nuxt
92 lines (85 loc) • 3.27 kB
JavaScript
import { deepCopy, isArray, isFunction, isObject } from "@intlify/shared";
import { localeLoaders, normalizedLocales, vueI18nConfigs } from "#internal/i18n-options.mjs";
import { dtsFile } from "#internal/i18n-type-generation-options";
import { loadVueI18nOptions } from "../shared/messages.js";
import { getMergedMessages } from "./utils/messages.js";
import { useRuntimeI18n } from "../shared/utils.js";
import { writeFile } from "node:fs/promises";
export default async () => {
const { experimental, defaultLocale } = useRuntimeI18n();
const targetLocales = [];
if (experimental.typedOptionsAndMessages === "default" && defaultLocale != null) {
targetLocales.push(defaultLocale);
} else if (experimental.typedOptionsAndMessages === "all") {
targetLocales.push(...normalizedLocales.map((x) => x.code));
}
const merged = {
messages: {},
datetimeFormats: {},
numberFormats: {}
};
const vueI18nConfig = await loadVueI18nOptions(vueI18nConfigs);
for (const locale of targetLocales) {
deepCopy(vueI18nConfig.messages?.[locale] || {}, merged.messages);
deepCopy(vueI18nConfig.numberFormats?.[locale] || {}, merged.numberFormats);
deepCopy(vueI18nConfig.datetimeFormats?.[locale] || {}, merged.datetimeFormats);
}
const loaderPromises = [];
for (const locale in localeLoaders) {
if (!targetLocales.includes(locale)) {
continue;
}
const loader = async () => deepCopy((await getMergedMessages(locale, []))?.[locale], merged.messages);
loaderPromises.push(loader());
}
await Promise.all(loaderPromises);
await writeFile(dtsFile, generateTypeCode(merged), "utf-8");
};
function generateInterface(obj, indentLevel = 1) {
const indent = " ".repeat(indentLevel);
let str = "";
for (const key in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
continue;
}
if (isObject(obj[key]) && obj[key] !== null && !isArray(obj[key])) {
str += `${indent}"${key}": {
`;
str += generateInterface(obj[key], indentLevel + 1);
str += `${indent}};
`;
} else {
let propertyType = isArray(obj[key]) ? "unknown[]" : typeof obj[key];
if (isFunction(propertyType)) {
propertyType = "() => string";
}
str += `${indent}"${key}": ${propertyType};
`;
}
}
return str;
}
function generateTypeCode(res) {
return `// generated by @nuxtjs/i18n
import type { DateTimeFormatOptions, NumberFormatOptions, SpecificNumberFormatOptions, CurrencyNumberFormatOptions } from '@intlify/core'
interface GeneratedLocaleMessage {
${generateInterface(res.messages || {}).trim()}
}
interface GeneratedDateTimeFormat {
${Object.keys(res.datetimeFormats || {}).map((k) => `${k}: DateTimeFormatOptions;`).join(`
`)}
}
interface GeneratedNumberFormat {
${Object.entries(res.numberFormats || {}).map(([k]) => `${k}: NumberFormatOptions;`).join(`
`)}
}
declare module 'vue-i18n' {
export interface DefineLocaleMessage extends GeneratedLocaleMessage {}
export interface DefineDateTimeFormat extends GeneratedDateTimeFormat {}
export interface DefineNumberFormat extends GeneratedNumberFormat {}
}
declare module '@intlify/core' {
export interface DefineCoreLocaleMessage extends GeneratedLocaleMessage {}
}
export {}`;
}