Skip to content

Commit

Permalink
fix: parametrized message merge not working
Browse files Browse the repository at this point in the history
  • Loading branch information
BobbieGoede authored and kazupon committed Nov 16, 2023
1 parent 3c75cf9 commit dd86b7b
Show file tree
Hide file tree
Showing 12 changed files with 39 additions and 50 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
}
},
"dependencies": {
"@intlify/shared": "9.5.0",
"@intlify/shared": "^9.7.0",
"@intlify/unplugin-vue-i18n": "^1.4.0",
"@mizchi/sucrase": "^4.1.0",
"@nuxt/kit": "^3.7.4",
Expand Down
18 changes: 9 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions specs/basic_usage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,10 @@ test('(#2523) localePath should not double encode paths', async () => {
expect(await page.locator('#link-page-with-spaces').getAttribute('href')).toEqual(`/nl/${encodedPath}`)
expect(await page.locator('#link-page-with-spaces-encoded').getAttribute('href')).toEqual(`/nl/${encodedPath}`)
})

test('(#2476) Parametrized messages can be overwritten', async () => {
const { page } = await renderPage('/')

expect(await getText(page, '#module-layer-base-key')).toEqual('Layer base key overwritten!')
expect(await getText(page, '#module-layer-base-key-named')).toEqual('Layer base key overwritten, greetings bar!')
})
2 changes: 1 addition & 1 deletion specs/fixtures/basic_usage/layer-module/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default defineNuxtModule({
{
code: 'en',
iso: 'en-US',
file: 'en.json',
files: ['en-base.json', 'en.json'],
name: 'English'
},
{
Expand Down
4 changes: 4 additions & 0 deletions specs/fixtures/basic_usage/layer-module/locales/en-base.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"moduleLayerBaseKey": "This is a layer base key",
"moduleLayerBaseKeyNamed": "This is a layer base key, hello {name}!"
}
4 changes: 3 additions & 1 deletion specs/fixtures/basic_usage/layer-module/locales/en.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"moduleLayerText": "This is a merged module layer locale key"
"moduleLayerText": "This is a merged module layer locale key",
"moduleLayerBaseKey": "Layer base key overwritten!",
"moduleLayerBaseKeyNamed": "Layer base key overwritten, greetings {name}!"
}
4 changes: 4 additions & 0 deletions specs/fixtures/basic_usage/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -175,5 +175,9 @@ useHead({
<section>
<div id="runtime-config">{{ $t('runtimeKey') }}</div>
</section>
<section>
<div id="module-layer-base-key">{{ $t('moduleLayerBaseKey') }}</div>
<div id="module-layer-base-key-named">{{ $t('moduleLayerBaseKeyNamed', { name: 'bar' }) }}</div>
</section>
</div>
</template>
1 change: 1 addition & 0 deletions src/gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export function generateLoaderOptions(nuxt: Nuxt, { nuxtI18nOptions, vueI18nConf
* Prepare Vue I18n config imports
*/
const vueI18nConfigImports = vueI18nConfigPaths
.reverse()
.filter(config => config.absolute !== '')
.map(config => generateVueI18nConfiguration(config))

Expand Down
32 changes: 1 addition & 31 deletions src/runtime/internal.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import { isArray, isString, isFunction, isObject } from '@intlify/shared'
import { isArray, isString, isFunction, deepCopy } from '@intlify/shared'
import {
findBrowserLocale,
getLocalesRegex,
Expand Down Expand Up @@ -85,36 +85,6 @@ export function parseAcceptLanguage(input: string): string[] {
return input.split(',').map(tag => tag.split(';')[0])
}

function deepCopy(src: Record<string, any>, des: Record<string, any>, predicate?: (src: any, des: any) => boolean) {
for (const key in src) {
if (isArray(src[key])) {
if (!isArray(des[key])) {
des[key] = []
}
;(src[key] as any[]).forEach((item, index) => {
if (!des[key][index]) {
const desItem = {}
deepCopy(item, desItem, predicate)
des[key].push(desItem)
}
})
} else if (isObject(src[key])) {
if (!isObject(des[key])) {
des[key] = {}
}
deepCopy(src[key], des[key], predicate)
} else {
if (predicate) {
if (predicate(src[key], des[key])) {
des[key] = src[key]
}
} else {
des[key] = src[key]
}
}
}
}

type LocaleLoader = { key: string; load: () => Promise<any>; cache: boolean }
const loadedMessages = new Map<string, LocaleMessages<DefineLocaleMessage>>()

Expand Down
6 changes: 3 additions & 3 deletions src/runtime/plugins/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { computed } from 'vue'
import { createI18n } from 'vue-i18n'
import { deepCopy } from '@intlify/shared'
import {
createLocaleFromRouteGetter,
extendI18n,
Expand Down Expand Up @@ -41,7 +42,6 @@ import {
detectBrowserLanguage,
DefaultDetectBrowserLanguageFromResult
} from '#build/i18n.internal.mjs'
import defu from 'defu'

import type { Composer, Locale, I18nOptions } from 'vue-i18n'
import type { LocaleObject, ExtendProperyDescripters, VueI18nRoutingPluginOptions } from 'vue-i18n-routing'
Expand All @@ -62,12 +62,12 @@ export default defineNuxtPlugin({
const { vueApp: app } = nuxt
const nuxtContext = nuxt as unknown as NuxtApp

let vueI18nOptions: I18nOptions = { messages: {} }
const vueI18nOptions: I18nOptions = { messages: {} }
for (const configFile of vueI18nConfigs) {
const { default: resolver } = await configFile()
const resolved = typeof resolver === 'function' ? await resolver() : resolver

vueI18nOptions = defu(vueI18nOptions, resolved)
deepCopy(resolved, vueI18nOptions)
}

const useCookie = nuxtI18nOptions.detectBrowserLanguage && nuxtI18nOptions.detectBrowserLanguage.useCookie
Expand Down
5 changes: 3 additions & 2 deletions src/runtime/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
useSwitchLocalePath
} from 'vue-i18n-routing'
import { navigateTo, useState } from '#imports'
import { isString, isFunction, isArray, isObject } from '@intlify/shared'
import { isString, isFunction, isArray, isObject, deepCopy } from '@intlify/shared'
import { nuxtI18nInternalOptions, nuxtI18nOptionsDefault, NUXT_I18N_MODULE_ID, isSSG } from '#build/i18n.options.mjs'
import {
detectBrowserLanguage,
Expand Down Expand Up @@ -110,7 +110,8 @@ export async function loadInitialMessages<Context extends NuxtApp = NuxtApp>(
const { defaultLocale, initialLocale, localeCodes, fallbackLocale, lazy } = options
const setter = (locale: Locale, message: Record<string, any>) => {
const base = messages[locale] || {}
messages[locale] = { ...base, ...message }
deepCopy(message, base)
messages[locale] = base
}

// load fallback messages
Expand Down
4 changes: 2 additions & 2 deletions test/__snapshots__/gen.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -421,9 +421,9 @@ exports[`vueI18n option 1`] = `
"vueI18n": "vue-i18n.config.ts",
},
"vueI18nConfigs": [
"() => import(\\"../to/i18n.config.ts?hash=fb1304e8&config=1\\" /* webpackChunkName: \\"i18n_config_ts_fb1304e8\\" */)",
"() => import(\\"../layer1/i18n.custom.ts?hash=0ca697e2&config=1\\" /* webpackChunkName: \\"i18n_custom_ts_0ca697e2\\" */)",
"() => import(\\"../foo/layer2/vue-i18n.options.js?hash=475488e5&config=1\\" /* webpackChunkName: \\"vue_i18n_options_js_475488e5\\" */)",
"() => import(\\"../layer1/i18n.custom.ts?hash=0ca697e2&config=1\\" /* webpackChunkName: \\"i18n_custom_ts_0ca697e2\\" */)",
"() => import(\\"../to/i18n.config.ts?hash=fb1304e8&config=1\\" /* webpackChunkName: \\"i18n_config_ts_fb1304e8\\" */)",
],
}
`;

0 comments on commit dd86b7b

Please sign in to comment.