Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: improve function type safety #3024

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor: restructure and improve types
  • Loading branch information
BobbieGoede committed Jul 11, 2024
commit af9f6e58d2dbcc51103a1ac97ed2ff93401c384b
8 changes: 4 additions & 4 deletions src/runtime/composables/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ref, computed, watch, onUnmounted } from 'vue'
import { parseAcceptLanguage, wrapComposable, runtimeDetectBrowserLanguage } from '../internal'
import { localeCodes, normalizedLocales } from '#build/i18n.options.mjs'
import { getActiveHead } from 'unhead'
import { getNormalizedLocales, initCommonComposableOptions } from '../utils'
import { getNormalizedLocales, initCommonComposableOptions, getLocale, getLocales } from '../utils'
import {
getAlternateOgLocales,
getCanonicalLink,
Expand All @@ -17,7 +17,7 @@ import {
localeRoute,
switchLocalePath
} from '../routing/compatibles'
import { findBrowserLocale, getComposer, getLocale, getLocales } from '../routing/utils'
import { findBrowserLocale, getComposer } from '../routing/utils'

import type { Ref } from 'vue'
import type { Locale } from 'vue-i18n'
Expand All @@ -44,8 +44,8 @@ export function useSetI18nParams(seoAttributes?: SeoAttributesOptions): SetI18nP
const i18n = getComposer(common.i18n)
const router = common.router

const locale = getLocale(i18n)
const locales = getNormalizedLocales(getLocales(i18n))
const locale = getLocale(common.i18n)
const locales = getNormalizedLocales(getLocales(common.i18n))
const _i18nParams = ref({})
const experimentalSSR = common.runtimeConfig.public.i18n.experimental.switchLocalePathLinkSSR

Expand Down
37 changes: 24 additions & 13 deletions src/runtime/plugins/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,28 @@ import {
normalizedLocales
} from '#build/i18n.options.mjs'
import { loadVueI18nOptions, loadInitialMessages, loadLocale } from '../messages'
import { loadAndSetLocale, detectLocale, detectRedirect, navigate, injectNuxtHelpers, extendBaseUrl } from '../utils'
import {
getBrowserLocale as _getBrowserLocale,
getLocaleCookie as _getLocaleCookie,
setLocaleCookie as _setLocaleCookie,
loadAndSetLocale,
detectLocale,
detectRedirect,
navigate,
injectNuxtHelpers,
extendBaseUrl,
_setLocale,
mergeLocaleMessage,
getLocale,
setLocale
} from '../utils'
import {
getBrowserLocale,
getLocaleCookie,
setLocaleCookie,
detectBrowserLanguage,
DefaultDetectBrowserLanguageFromResult,
getI18nCookie,
runtimeDetectBrowserLanguage
} from '../internal'
import { getI18nTarget, getLocale, inBrowser, resolveBaseUrl, setLocale } from '../routing/utils'
import { inBrowser, resolveBaseUrl } from '../routing/utils'
import { extendI18n, createLocaleFromRouteGetter } from '../routing/extends'

import type { LocaleObject } from '#build/i18n.options.mjs'
Expand Down Expand Up @@ -72,7 +83,7 @@ export default defineNuxtPlugin({
ssg: isSSG && runtimeI18n.strategy === 'no_prefix' ? 'ssg_ignore' : 'normal',
callType: 'setup',
firstAccess: true,
localeCookie: _getLocaleCookie(localeCookie, _detectBrowserLanguage, runtimeI18n.defaultLocale)
localeCookie: getLocaleCookie(localeCookie, _detectBrowserLanguage, runtimeI18n.defaultLocale)
},
runtimeI18n
)
Expand Down Expand Up @@ -124,7 +135,7 @@ export default defineNuxtPlugin({
ssg: 'ssg_setup',
callType: 'setup',
firstAccess: true,
localeCookie: _getLocaleCookie(localeCookie, _detectBrowserLanguage, runtimeI18n.defaultLocale)
localeCookie: getLocaleCookie(localeCookie, _detectBrowserLanguage, runtimeI18n.defaultLocale)
},
initialLocale
)
Expand All @@ -137,7 +148,7 @@ export default defineNuxtPlugin({
reason,
from
)
await getI18nTarget(i18n).setLocale(browserLocale)
await _setLocale(i18n, browserLocale)
ssgModeInitialSetup = false
})
}
Expand Down Expand Up @@ -202,15 +213,15 @@ export default defineNuxtPlugin({
)
}
composer.loadLocaleMessages = async (locale: string) => {
const setter = getI18nTarget(i18n).mergeLocaleMessage
const setter = mergeLocaleMessage.bind(null, i18n)
await loadLocale(locale, localeLoaders, setter)
}
composer.differentDomains = runtimeI18n.differentDomains
composer.defaultLocale = runtimeI18n.defaultLocale
composer.getBrowserLocale = () => _getBrowserLocale()
composer.getBrowserLocale = () => getBrowserLocale()
composer.getLocaleCookie = () =>
_getLocaleCookie(localeCookie, _detectBrowserLanguage, runtimeI18n.defaultLocale)
composer.setLocaleCookie = (locale: string) => _setLocaleCookie(localeCookie, locale, _detectBrowserLanguage)
getLocaleCookie(localeCookie, _detectBrowserLanguage, runtimeI18n.defaultLocale)
composer.setLocaleCookie = (locale: string) => setLocaleCookie(localeCookie, locale, _detectBrowserLanguage)

composer.onBeforeLanguageSwitch = (oldLocale, newLocale, initialSetup, context) =>
nuxt.callHook('i18n:beforeLocaleSwitch', { oldLocale, newLocale, initialSetup, context }) as Promise<void>
Expand Down Expand Up @@ -320,7 +331,7 @@ export default defineNuxtPlugin({
ssg: isSSGModeInitialSetup() && runtimeI18n.strategy === 'no_prefix' ? 'ssg_ignore' : 'normal',
callType: 'routing',
firstAccess: routeChangeCount === 0,
localeCookie: _getLocaleCookie(localeCookie, _detectBrowserLanguage, runtimeI18n.defaultLocale)
localeCookie: getLocaleCookie(localeCookie, _detectBrowserLanguage, runtimeI18n.defaultLocale)
},
runtimeI18n
)
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/routing/compatibles/head.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { unref, useNuxtApp, useRuntimeConfig } from '#imports'

import { getComposer, getLocale, getLocales, getNormalizedLocales } from '../utils'
import { getComposer, getNormalizedLocales } from '../utils'
import { getRouteBaseName, localeRoute, switchLocalePath } from './routing'
import { isArray, isObject } from '@intlify/shared'
import { joinURL } from 'ufo'

import type { I18n } from 'vue-i18n'
import type { I18nHeadMetaInfo, MetaAttrs, LocaleObject, I18nHeadOptions } from '#build/i18n.options.mjs'
import type { CommonComposableOptions } from '../../utils'
import { getLocale, getLocales, type CommonComposableOptions } from '../../utils'

/**
* Returns localized head properties for locale-related aspects.
Expand Down
9 changes: 7 additions & 2 deletions src/runtime/routing/compatibles/routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ import { DEFAULT_DYNAMIC_PARAMS_KEY } from '#build/i18n.options.mjs'
import { unref } from '#imports'

import { resolve, routeToObject } from './utils'
import { getLocale, getLocaleRouteName, getRouteName } from '../utils'
import { extendPrefixable, extendSwitchLocalePathIntercepter, type CommonComposableOptions } from '../../utils'
import { getLocaleRouteName, getRouteName } from '../utils'
import {
extendPrefixable,
extendSwitchLocalePathIntercepter,
getLocale,
type CommonComposableOptions
} from '../../utils'

import type { Strategies, PrefixableOptions, SwitchLocalePathIntercepter } from '#build/i18n.options.mjs'
import type { Locale } from 'vue-i18n'
Expand Down
36 changes: 1 addition & 35 deletions src/runtime/routing/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import { isString, isSymbol, isFunction } from '@intlify/shared'
import { isRef, unref } from '#imports'
import { isRef } from '#imports'

import type { LocaleObject, Strategies, BaseUrlResolveHandler } from '#build/i18n.options.mjs'
import type { Composer, I18n, Locale, VueI18n } from 'vue-i18n'
Expand Down Expand Up @@ -47,40 +47,6 @@ export function getComposer(i18n: I18n | VueI18n | Composer): Composer {
return target
}

/**
* Get a locale
*
* @param i18n - An [I18n](https://vue-i18n.intlify.dev/api/general.html#i18n) instance or a [Composer](https://vue-i18n.intlify.dev/api/composition.html#composer) instance
*
* @returns A locale
*/
export function getLocale(i18n: I18n | Composer | VueI18n): Locale {
return unref(getI18nTarget(i18n).locale)
}

export function getLocales(i18n: I18n | VueI18n | Composer): string[] | LocaleObject[] {
return unref(getI18nTarget(i18n).locales)
}

export function getLocaleCodes(i18n: I18n | VueI18n | Composer): string[] {
return unref(getI18nTarget(i18n).localeCodes)
}

/**
* Set a locale
*
* @param i18n - An [I18n](https://vue-i18n.intlify.dev/api/general.html#i18n) instance or a [Composer](https://vue-i18n.intlify.dev/api/composition.html#composer) instance
* @param locale - A target locale
*/
export function setLocale(i18n: I18n | Composer, locale: Locale): void {
const target = getI18nTarget(i18n)
if (isRef(target.locale)) {
target.locale.value = locale
} else {
target.locale = locale
}
}

export function adjustRoutePathForTrailingSlash(
pagePath: string,
trailingSlash: boolean,
Expand Down
82 changes: 73 additions & 9 deletions src/runtime/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { joinURL, isEqual } from 'ufo'
import { isString, isFunction, isObject } from '@intlify/shared'
import { navigateTo, unref, useNuxtApp, useRouter, useRuntimeConfig, useState } from '#imports'
import { isRef, navigateTo, unref, useNuxtApp, useRouter, useRuntimeConfig, useState } from '#imports'
import {
NUXT_I18N_MODULE_ID,
isSSG,
Expand Down Expand Up @@ -32,9 +32,9 @@ import {
DefaultPrefixable,
DefaultSwitchLocalePathIntercepter
} from './routing/compatibles'
import { getLocale, setLocale, getLocaleCodes, getI18nTarget } from './routing/utils'
import { getI18nTarget } from './routing/utils'

import type { I18n, Locale, Composer, VueI18n } from 'vue-i18n'
import type { I18n, Locale } from 'vue-i18n'
import type { NuxtApp } from '#app'
import type { Ref } from '#imports'
import type { Router } from '#vue-router'
Expand All @@ -44,6 +44,70 @@ import type { GetLocaleFromRouteFunction } from './routing/extends/router'
import type { RouteLocationNormalized, RouteLocationNormalizedLoaded } from 'vue-router'
import type { RuntimeConfig } from '@nuxt/schema'
import type { ModulePublicRuntimeConfig } from '../module'
import type { UnwrapRef } from 'vue'

function extractI18nProperty<T extends ReturnType<typeof getI18nTarget>, K extends keyof T>(
i18n: T,
key: K
): UnwrapRef<T[K]> {
return unref(i18n[key]) as UnwrapRef<T[K]>
}

export function getI18nProperty<K extends keyof ReturnType<typeof getI18nTarget>>(i18n: I18n, property: K) {
return extractI18nProperty(getI18nTarget(i18n), property)
}

export function getLocale(i18n: I18n): Locale {
return getI18nProperty(i18n, 'locale')
}
/**
* Set a locale
*
* @param i18n - An [I18n](https://vue-i18n.intlify.dev/api/general.html#i18n) instance or a [Composer](https://vue-i18n.intlify.dev/api/composition.html#composer) instance
* @param locale - A target locale
*/
export function setLocale(i18n: I18n, locale: Locale): void {
const target = getI18nTarget(i18n)
if (isRef(target.locale)) {
target.locale.value = locale
} else {
target.locale = locale
}
}

export function getLocales(i18n: I18n): string[] | LocaleObject[] {
return getI18nProperty(i18n, 'locales')
}

export function getLocaleCodes(i18n: I18n): string[] {
return getI18nProperty(i18n, 'localeCodes')
}

export function _setLocale(i18n: I18n, locale: Locale) {
return getI18nTarget(i18n).setLocale(locale)
}

export function setLocaleCookie(i18n: I18n, locale: Locale) {
return getI18nTarget(i18n).setLocaleCookie(locale)
}

export function mergeLocaleMessage(i18n: I18n, locale: Locale, messages: Record<string, any>) {
return getI18nTarget(i18n).mergeLocaleMessage(locale, messages)
}

async function onBeforeLanguageSwitch(
i18n: I18n,
oldLocale: string,
newLocale: string,
initial: boolean,
context: NuxtApp
) {
return getI18nTarget(i18n).onBeforeLanguageSwitch(oldLocale, newLocale, initial, context)
}

function onLanguageSwitched(i18n: I18n, oldLocale: string, newLocale: string) {
return getI18nTarget(i18n).onLanguageSwitched(oldLocale, newLocale)
}

/**
* Common options used internally by composable functions, these
Expand Down Expand Up @@ -84,7 +148,7 @@ export async function loadAndSetLocale(
if (opts === false || !opts.useCookie) return
if (skipSettingLocaleOnNavigate) return

getI18nTarget(i18n).setLocaleCookie(locale)
setLocaleCookie(i18n, locale)
}

__DEBUG__ && console.log('setLocale: new -> ', newLocale, ' old -> ', oldLocale, ' initial -> ', initial)
Expand All @@ -107,7 +171,7 @@ export async function loadAndSetLocale(
}

// call `onBeforeLanguageSwitch` which may return an override for `newLocale`
const localeOverride = await getI18nTarget(i18n).onBeforeLanguageSwitch(oldLocale, newLocale, initial, nuxtApp)
const localeOverride = await onBeforeLanguageSwitch(i18n, oldLocale, newLocale, initial, nuxtApp)
if (localeOverride && localeCodes.includes(localeOverride)) {
// resolved `localeOverride` is already in use
if (oldLocale === localeOverride) {
Expand All @@ -120,9 +184,9 @@ export async function loadAndSetLocale(

// load locale messages required by `newLocale`
if (lazy) {
const i18nFallbackLocales = unref(getI18nTarget(i18n).fallbackLocale)
const i18nFallbackLocales = getI18nProperty(i18n, 'fallbackLocale')

const setter = getI18nTarget(i18n).mergeLocaleMessage
const setter = mergeLocaleMessage.bind(null, i18n)
if (i18nFallbackLocales) {
const fallbackLocales = makeFallbackLocaleCodes(i18nFallbackLocales, [newLocale])
await Promise.all(fallbackLocales.map(locale => loadLocale(locale, localeLoaders, setter)))
Expand All @@ -138,7 +202,7 @@ export async function loadAndSetLocale(
syncCookie(newLocale)
setLocale(i18n, newLocale)

await getI18nTarget(i18n).onLanguageSwitched(oldLocale, newLocale)
await onLanguageSwitched(i18n, oldLocale, newLocale)

return true
}
Expand Down Expand Up @@ -373,7 +437,7 @@ export async function navigate(
}
}

export function injectNuxtHelpers(nuxt: NuxtApp, i18n: I18n | VueI18n | Composer) {
export function injectNuxtHelpers(nuxt: NuxtApp, i18n: I18n) {
/**
* NOTE:
* we will inject `i18n.global` to **nuxt app instance only**
Expand Down