Skip to content

Commit

Permalink
refactor: resolve vue i18n options
Browse files Browse the repository at this point in the history
  • Loading branch information
BobbieGoede committed Nov 13, 2023
1 parent 11cdb00 commit 178aff0
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 42 deletions.
16 changes: 6 additions & 10 deletions src/options.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import type { NuxtI18nOptions, NuxtI18nInternalOptions, RootRedirectOptions } from './types'
import type { NuxtI18nOptionsDefault } from './constants'
import type { DeepRequired } from 'ts-essentials'
import type { NuxtApp } from '@nuxt/schema'
import type { I18nOptions } from 'vue-i18n'

/**
* stub type definition for @nuxtjs/i18n internally
Expand All @@ -19,16 +19,12 @@ type LocaleLoader = {
export const loadMessages: () => Promise<any> = () => Promise.resolve({})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const localeMessages: Record<string, LocaleLoader[]> = {}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const resolveNuxtI18nOptions: <Context = NuxtApp>(
context: Context
) => Promise<DeepRequired<NuxtI18nOptions<Context>>> = () => Promise.resolve({})
export type LoaderResult = Record<string, unknown> | (() => Record<string, unknown>)
type LoadedConfig = Record<string, unknown>
export type VLoaderType = () => Promise<{ default: LoadedConfig | (() => LoadedConfig) }>
export const vueI18nConfigLoaders: VLoaderType[]

export type VueI18nConfig = () => Promise<{ default: I18nOptions | (() => I18nOptions | Promise<I18nOptions>) }>
export const vueI18nConfigs: VueI18nConfig[]

export const localeCodes: string[] = []
export const nuxtI18nOptions: DeepRequired<NuxtI18nOptions> = {}
export const nuxtI18nOptions: DeepRequired<NuxtI18nOptions<Context>> = {}
export const nuxtI18nOptionsDefault: NuxtI18nOptionsDefault = {}
export const nuxtI18nInternalOptions: DeepRequired<NuxtI18nInternalOptions> = {}
export const NUXT_I18N_MODULE_ID = ''
Expand Down
3 changes: 2 additions & 1 deletion src/runtime/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ export function detectBrowserLanguage<Context extends NuxtApp = NuxtApp>(
context: any,
nuxtI18nOptions: DeepRequired<NuxtI18nOptions<Context>>,
nuxtI18nInternalOptions: DeepRequired<NuxtI18nInternalOptions>,
vueI18nOptions: I18nOptions,
detectLocaleContext: DetectLocaleContext,
localeCodes: string[] = [],
locale: Locale = ''
Expand Down Expand Up @@ -370,7 +371,7 @@ export function detectBrowserLanguage<Context extends NuxtApp = NuxtApp>(
localeFrom
)

const vueI18nLocale = locale || (nuxtI18nOptions.vueI18n as I18nOptions).locale
const vueI18nLocale = locale || vueI18nOptions.locale
__DEBUG__ && console.log('detectBrowserLanguage: vueI18nLocale', vueI18nLocale)

// handle cookie option to prevent multiple redirects
Expand Down
27 changes: 9 additions & 18 deletions src/runtime/plugins/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import {
import { defineNuxtPlugin, useRouter, useRoute, addRouteMiddleware, defineNuxtRouteMiddleware } from '#imports'
import {
localeCodes,
resolveNuxtI18nOptions,
vueI18nConfigLoaders,
vueI18nConfigs,
nuxtI18nOptions,
nuxtI18nInternalOptions,
isSSG,
parallelPlugin
Expand All @@ -32,7 +32,8 @@ import {
extendBaseUrl,
extendPrefixable,
extendSwitchLocalePathIntercepter,
_setLocale
_setLocale,
resolveVueI18nOptions
} from '#build/i18n.utils.mjs'
import {
getBrowserLocale as _getBrowserLocale,
Expand All @@ -42,10 +43,9 @@ import {
DefaultDetectBrowserLanguageFromResult
} from '#build/i18n.internal.mjs'

import type { Composer, I18nOptions, Locale } from 'vue-i18n'
import type { Composer, Locale } from 'vue-i18n'
import type { LocaleObject, ExtendProperyDescripters, VueI18nRoutingPluginOptions } from 'vue-i18n-routing'
import type { NuxtApp } from '#app'
import defu from 'defu'

type GetRouteBaseName = typeof getRouteBaseName
type LocalePath = typeof localePath
Expand All @@ -62,18 +62,7 @@ export default defineNuxtPlugin({
const { vueApp: app } = nuxt
const nuxtContext = nuxt as unknown as NuxtApp

const nuxtI18nOptions = await resolveNuxtI18nOptions<NuxtApp>(nuxtContext)

// @ts-ignore
nuxtI18nOptions.vueI18n = { messages: {} }

for (const vLoader of vueI18nConfigLoaders) {
const { default: resolver } = await vLoader()
const resolved = typeof resolver === 'function' ? resolver() : resolver

// @ts-ignore
nuxtI18nOptions.vueI18n = defu(nuxtI18nOptions.vueI18n, resolved)
}
const vueI18nOptions = await resolveVueI18nOptions(vueI18nConfigs)

const useCookie = nuxtI18nOptions.detectBrowserLanguage && nuxtI18nOptions.detectBrowserLanguage.useCookie
const { __normalizedLocales: normalizedLocales } = nuxtI18nInternalOptions
Expand Down Expand Up @@ -103,7 +92,6 @@ export default defineNuxtPlugin({
defaultLocaleRouteNameSuffix
)

const vueI18nOptions = nuxtI18nOptions.vueI18n as I18nOptions
vueI18nOptions.messages = vueI18nOptions.messages || {}
vueI18nOptions.fallbackLocale = vueI18nOptions.fallbackLocale ?? false

Expand All @@ -124,6 +112,7 @@ export default defineNuxtPlugin({
nuxt.ssrContext,
getLocaleFromRoute,
nuxtI18nOptions,
vueI18nOptions,
getDefaultLocale(defaultLocale),
{ ssg: isSSG && strategy === 'no_prefix' ? 'ssg_ignore' : 'normal', callType: 'setup', firstAccess: true },
normalizedLocales,
Expand Down Expand Up @@ -177,6 +166,7 @@ export default defineNuxtPlugin({
nuxtContext,
nuxtI18nOptions,
nuxtI18nInternalOptions,
vueI18nOptions,
{ ssg: 'ssg_setup', callType: 'setup', firstAccess: true },
localeCodes,
initialLocale
Expand Down Expand Up @@ -456,6 +446,7 @@ export default defineNuxtPlugin({
nuxt.ssrContext,
getLocaleFromRoute,
nuxtI18nOptions,
vueI18nOptions,
() => {
return getLocale(i18n) || getDefaultLocale(defaultLocale)
},
Expand Down
13 changes: 4 additions & 9 deletions src/runtime/templates/options.template.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,19 @@
<% options.importStrings.forEach(function (importer) { %>
<%= importer %><% }); %>

export const localeCodes = <%= JSON.stringify(options.localeCodes, null, 2) %>
export const localeCodes = <%= JSON.stringify(options.localeCodes, null, 2) %>;

export const localeMessages = { <% options.localeMessages.forEach(function ([key, val]) { %>
"<%= key %>": [<% val.forEach(function (entry) { %>
{ key: <%= entry.key %>, load: <%= entry.load %>, cache: <%= entry.cache %> },<% }); %>
],<% }); %>
}

export const vueI18nConfigLoaders = [
<% options.vueI18nConfigs.forEach(function (importer) { %><%= importer %>,
<% }); %>
export const vueI18nConfigs = [<% options.vueI18nConfigs.forEach(function (importer) { %>
<%= importer %>,<% }); %>
]

export const resolveNuxtI18nOptions = async (context) => {
const nuxtI18nOptions = <%= JSON.stringify(options.nuxtI18nOptions, null, 2) %>

return nuxtI18nOptions
}
export const nuxtI18nOptions = <%= JSON.stringify(options.nuxtI18nOptions, null, 2) %>

export const nuxtI18nOptionsDefault = <%= JSON.stringify(options.nuxtI18nOptionsDefault, null, 2) %>

Expand Down
42 changes: 38 additions & 4 deletions src/runtime/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
DefaultDetectBrowserLanguageFromResult
} from '#build/i18n.internal.mjs'
import { joinURL, isEqual } from 'ufo'
import defu from 'defu'

import type {
Route,
Expand All @@ -42,8 +43,13 @@ import type {
SwitchLocalePathIntercepter
} from 'vue-i18n-routing'
import type { NuxtApp } from '#app'
import type { I18n, Locale, FallbackLocale, LocaleMessages, DefineLocaleMessage } from 'vue-i18n'
import type { NuxtI18nOptions, DetectBrowserLanguageOptions, RootRedirectOptions } from '#build/i18n.options.mjs'
import type { I18n, I18nOptions, Locale, FallbackLocale, LocaleMessages, DefineLocaleMessage } from 'vue-i18n'
import type {
NuxtI18nOptions,
DetectBrowserLanguageOptions,
RootRedirectOptions,
VueI18nConfig
} from '#build/i18n.options.mjs'
import type { DetectLocaleContext } from '#build/i18n.internal.mjs'
import type { DeepRequired } from 'ts-essentials'

Expand Down Expand Up @@ -200,6 +206,7 @@ export function detectLocale<Context extends NuxtApp = NuxtApp>(
context: any,
routeLocaleGetter: ReturnType<typeof createLocaleFromRouteGetter>,
nuxtI18nOptions: DeepRequired<NuxtI18nOptions<Context>>,
vueI18nOptions: I18nOptions,
initialLocaleLoader: Locale | LocaleLoader,
detectLocaleContext: DetectLocaleContext,
normalizedLocales: LocaleObject[],
Expand All @@ -214,8 +221,22 @@ export function detectLocale<Context extends NuxtApp = NuxtApp>(
__DEBUG__ && console.log('detectLocale: (ssg, callType, firstAccess) - ', ssg, callType, firstAccess)

// prettier-ignore
const { locale: browserLocale, stat, reason, from } = nuxtI18nOptions.detectBrowserLanguage
? detectBrowserLanguage(route, context, nuxtI18nOptions, nuxtI18nInternalOptions, detectLocaleContext, localeCodes, initialLocale)
const {
locale: browserLocale,
stat,
reason,
from
} = nuxtI18nOptions.detectBrowserLanguage
? detectBrowserLanguage(
route,
context,
nuxtI18nOptions,
nuxtI18nInternalOptions,
vueI18nOptions,
detectLocaleContext,
localeCodes,
initialLocale
)
: DefaultDetectBrowserLanguageFromResult
__DEBUG__ &&
console.log(
Expand Down Expand Up @@ -516,4 +537,17 @@ export function extendBaseUrl<Context extends NuxtApp = NuxtApp>(
}
}

export const resolveVueI18nOptions = async (configFiles: VueI18nConfig[]) => {
let resolvedOptions: I18nOptions = { messages: {} }

for (const configFile of configFiles) {
const { default: resolver } = await configFile()
const resolved = typeof resolver === 'function' ? await resolver() : resolver

resolvedOptions = defu(resolvedOptions, resolved)
}

return resolvedOptions
}

/* eslint-enable @typescript-eslint/no-explicit-any */

0 comments on commit 178aff0

Please sign in to comment.