Skip to content

Commit

Permalink
fix: resolve extending messages correctly (nuxt-modules#1765)
Browse files Browse the repository at this point in the history
  • Loading branch information
kazupon authored Dec 23, 2022
1 parent fea2819 commit 89e4d18
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 7 deletions.
83 changes: 77 additions & 6 deletions src/messages.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,100 @@
import createDebug from 'debug'
import { isString, isArray, isObject, hasOwn } from '@intlify/shared'

import type { Nuxt } from '@nuxt/schema'
import type { DefineLocaleMessage, Locale, LocaleMessages } from 'vue-i18n'
import type { DefineLocaleMessage, FallbackLocale, Locale, LocaleMessages } from 'vue-i18n'
import type { NuxtI18nOptions } from './types'

const debug = createDebug('@nuxtjs/i18n:messages')

export type AdditionalMessages = Record<Locale, DefineLocaleMessage[]>

export async function extendMessages(nuxt: Nuxt, localeCodes: string[]): Promise<AdditionalMessages> {
export async function extendMessages(
nuxt: Nuxt,
localeCodes: string[],
nuxtOptions: Required<NuxtI18nOptions>
): Promise<AdditionalMessages> {
const additionalMessages: LocaleMessages<DefineLocaleMessage>[] = []
await nuxt.callHook('i18n:extend-messages', additionalMessages, localeCodes)
debug('i18n:extend-messages additional messages', additionalMessages)

return normalizeAdditionalMessages(additionalMessages, localeCodes)
return normalizeMessages(additionalMessages, localeCodes, nuxtOptions)
}

async function normalizeAdditionalMessages(additional: LocaleMessages<DefineLocaleMessage>[], localeCodes: string[]) {
const isNotObjectOrIsArray = (val: unknown) => !isObject(val) || isArray(val)

// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
function deepCopy(src: Record<string, any>, des: Record<string, any>): void {
for (const key in src) {
if (hasOwn(src, key)) {
if (isNotObjectOrIsArray(src[key]) || isNotObjectOrIsArray(des[key])) {
des[key] = src[key]
} else {
deepCopy(src[key], des[key])
}
}
}
}

function getLocaleCodes(fallback: FallbackLocale, locales: Locale[]): Locale[] {
let fallbackLocales: string[] = []
if (isArray(fallback)) {
fallbackLocales = fallback
} else if (isObject(fallback)) {
const targets = [...locales, 'default']
for (const locale of targets) {
if (fallback[locale]) {
fallbackLocales = [...fallbackLocales, ...fallback[locale].filter(Boolean)]
}
}
} else if (isString(fallback) && locales.every(locale => locale !== fallback)) {
fallbackLocales.push(fallback)
}
return fallbackLocales
}

async function normalizeMessages(
additional: LocaleMessages<DefineLocaleMessage>[],
localeCodes: string[],
nuxtOptions: Required<NuxtI18nOptions>
) {
/**
* merge additional messages into vueI18n messages
*/

let targetLocaleCodes = [...localeCodes]
if (isObject(nuxtOptions.vueI18n)) {
nuxtOptions.vueI18n.messages = nuxtOptions.vueI18n.messages || {}
const locale = nuxtOptions.defaultLocale || nuxtOptions.vueI18n.locale || 'en-US'
const locales = nuxtOptions.vueI18n.fallbackLocale
? getLocaleCodes(nuxtOptions.vueI18n.fallbackLocale, [locale])
: [locale]
for (const locale of locales) {
nuxtOptions.vueI18n.messages[locale] = nuxtOptions.vueI18n.messages[locale] || {}
}
for (const [, messages] of Object.entries(additional)) {
for (const locale of locales) {
deepCopy(messages[locale], nuxtOptions.vueI18n.messages[locale])
}
}
targetLocaleCodes = localeCodes.filter(code => !locales.includes(code))
debug('vueI18n messages', nuxtOptions.vueI18n.messages)
}

/**
* collect additional messages for each locale
*/

const additionalMessages: AdditionalMessages = {}
for (const localeCode of localeCodes) {
for (const localeCode of targetLocaleCodes) {
additionalMessages[localeCode] = []
}

for (const [, messages] of Object.entries(additional)) {
for (const [locale, message] of Object.entries(messages)) {
additionalMessages[locale].push(message)
if (targetLocaleCodes.includes(locale)) {
additionalMessages[locale].push(message)
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export default defineNuxtModule<NuxtI18nOptions>({
* extend messages via 3rd party nuxt modules
*/

const additionalMessages = await extendMessages(nuxt, localeCodes)
const additionalMessages = await extendMessages(nuxt, localeCodes, options)

/**
* setup nuxt/pages
Expand Down

0 comments on commit 89e4d18

Please sign in to comment.