Skip to content

Commit

Permalink
breaking: change sfc custom block interface (#246)
Browse files Browse the repository at this point in the history
* breaking: change sfc custom block interface

* fix lint errors
  • Loading branch information
kazupon authored Dec 21, 2020
1 parent 5f56f69 commit 5228b0a
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 158 deletions.
60 changes: 13 additions & 47 deletions packages/vue-i18n/src/composer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
isObject
} from '@intlify/shared'
import {
parse as parsePath,
resolveValue,
createCoreContext,
MISSING_RESOLVE_VALUE,
Expand Down Expand Up @@ -108,9 +107,12 @@ export type PreCompileHandler<Message = VueMessageType> = () => {
functions: MessageFunctions<Message>
}

export type CustomBlocks<Message = VueMessageType> =
| Array<string | LocaleMessages<Message>>
| PreCompileHandler<Message>
export interface CustomBlock<Message = VueMessageType> {
locale: Locale
resource: LocaleMessages<Message> | LocaleMessageDictionary<Message>
}

export type CustomBlocks<Message = VueMessageType> = Array<CustomBlock<Message>>

/**
* Composer Options
Expand Down Expand Up @@ -950,15 +952,14 @@ export function getLocaleMessages<Message = VueMessageType>(

// merge locale messages of i18n custom block
if (isArray(__i18n)) {
__i18n.forEach(raw => {
deepCopy(isString(raw) ? JSON.parse(raw) : raw, ret)
__i18n.forEach(({ locale, resource }) => {
if (locale) {
ret[locale] = ret[locale] || {}
deepCopy(resource, ret[locale])
} else {
deepCopy(resource, ret)
}
})
return ret
}

if (isFunction(__i18n)) {
const { functions } = __i18n()
addPreCompileMessages<Message>(ret, functions as MessageFunctions<Message>)
}

return ret
Expand All @@ -985,41 +986,6 @@ function deepCopy(source: any, destination: any): void {
}
}

export function addPreCompileMessages<Message = VueMessageType>(
messages: LocaleMessages<Message>,
functions: MessageFunctions<Message>
): void {
const keys = Object.keys(functions)
keys.forEach(key => {
const compiled = functions[key]
const { l, k } = JSON.parse(key)
if (!messages[l]) {
messages[l] = {}
}
const targetLocaleMessage = messages[l]
const paths = parsePath(k)
if (paths != null) {
const len = paths.length
let last = targetLocaleMessage as any // eslint-disable-line @typescript-eslint/no-explicit-any
let i = 0
while (i < len) {
const path = paths[i]
if (i === len - 1) {
last[path] = compiled
break
} else {
let val = last[path]
if (!val) {
last[path] = val = {}
}
last = val
i++
}
}
}
})
}

/**
* Create composer interface factory
*
Expand Down
1 change: 1 addition & 0 deletions packages/vue-i18n/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export {
MissingHandler,
ComposerOptions,
Composer,
CustomBlock,
CustomBlocks
} from './composer'
export {
Expand Down
163 changes: 57 additions & 106 deletions packages/vue-i18n/test/composer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ import { isString, warn } from '@intlify/shared'
import {
createComposer,
MissingHandler,
addPreCompileMessages,
ComposerOptions,
VueMessageType,
TransrateVNodeSymbol,
NumberPartsSymbol,
DatetimePartsSymbol
} from '../src/composer'
import { generateFormatCacheKey } from '@intlify/shared'
import { watch, watchEffect, nextTick, Text, createVNode } from 'vue'
import {
Locale,
Expand Down Expand Up @@ -960,122 +958,97 @@ describe('getNumberFormat / setNumberFormat / mergeNumberFormat', () => {
})

describe('__i18n', () => {
test('default value', () => {
const options = {
__i18n: [
JSON.stringify({ en: { hello: 'Hello,world!' } }),
JSON.stringify({
ja: {
hello: 'こんにちは、世界!',
nest: {
foo: {
bar: 'ばー'
}
test('locale included locale messages', () => {
const enResource = {
locale: '',
resource: {
en: { hello: () => 'Hello,world!' }
}
}
const jaResource = {
locale: '',
resource: {
ja: {
hello: () => 'こんにちは、世界!',
nest: {
foo: {
bar: () => 'ばー'
}
}
})
]
}
}
}
const options = {
__i18n: [enResource, jaResource]
}
const { messages } = createComposer(
options as ComposerOptions<VueMessageType>
)
expect(messages.value).toEqual({
en: { hello: 'Hello,world!' },
ja: {
hello: 'こんにちは、世界!',
nest: {
foo: {
bar: 'ばー'
}
}
}
en: enResource.resource.en,
ja: jaResource.resource.ja
})
})

test('locale messages object', () => {
const options = {
__i18n: [
{ en: { hello: 'Hello,world!' } },
{
ja: {
hello: 'こんにちは、世界!',
nest: {
foo: {
bar: 'ばー'
}
}
}
}
]
test('locale not included locale messages', () => {
const enResource = {
locale: 'en',
resource: { hello: () => 'Hello,world!' }
}
const { messages } = createComposer(
options as ComposerOptions<VueMessageType>
)
expect(messages.value).toEqual({
en: { hello: 'Hello,world!' },
ja: {
hello: 'こんにちは、世界!',
const jaResource = {
locale: 'ja',
resource: {
hello: () => 'こんにちは、世界!',
nest: {
foo: {
bar: 'ばー'
bar: () => 'ばー'
}
}
}
})
})

test('merge locale messages', () => {
const msgFn = () => 'ふー'
}
const options = {
__i18n: [
JSON.stringify({ en: { hello: 'Hello,world!' } }),
JSON.stringify({ ja: { hello: 'こんにちは、世界!' } })
],
messages: {
en: { foo: 'foo' },
ja: { foo: msgFn }
}
__i18n: [enResource, jaResource]
}
const { messages } = createComposer(
options as ComposerOptions<VueMessageType>
)
expect(messages.value!.en).toEqual({
hello: 'Hello,world!',
foo: 'foo'
})
expect(messages.value!.ja).toEqual({
hello: 'こんにちは、世界!',
foo: msgFn
expect(messages.value).toEqual({
en: enResource.resource,
ja: jaResource.resource
})
})

test('function + locale messages', () => {
const functions = Object.create(null)
const msg1 = () => {}
const msg2 = () => {}
functions[generateFormatCacheKey('en', 'hello', 'hello,world')] = msg1
functions[
generateFormatCacheKey('ja', 'hello.hello', 'こんにちは、世界')
] = msg2
test('merge locale messages', () => {
const msgFnEn = () => 'foo'
const msgFnJa = () => 'ふー'
const enI18nFn = () => 'Hello,world!'
const jaI18nFn = () => 'こんにちは、世界!'
const options = {
__i18n: () => ({ functions }),
__i18n: [
{
locale: 'en',
resource: { hello: enI18nFn }
},
{
locale: 'ja',
resource: { hello: jaI18nFn }
}
],
messages: {
en: { foo: 'foo' },
ja: { foo: 'ふー' }
en: { foo: msgFnEn },
ja: { foo: msgFnJa }
}
}
const { messages } = createComposer(
options as ComposerOptions<VueMessageType>
)
expect(messages.value!.en).toEqual({
hello: msg1,
foo: 'foo'
hello: enI18nFn,
foo: msgFnEn
})
expect(messages.value!.ja).toEqual({
hello: {
hello: msg2
},
foo: 'ふー'
hello: jaI18nFn,
foo: msgFnJa
})
})
})
Expand Down Expand Up @@ -1208,28 +1181,6 @@ describe('__datetimeParts', () => {
})
})

test('addPreCompileMessages', () => {
const messages: any = {}
const functions = Object.create(null)
const msg1 = () => {}
const msg2 = () => {}
functions[generateFormatCacheKey('en', 'hello', 'hello,world')] = msg1
functions[
generateFormatCacheKey('ja', 'foo.bar.hello', 'こんにちは、世界')
] = msg2
addPreCompileMessages(messages, functions)
expect(messages!['en']).toMatchObject({
hello: msg1
})
expect(messages!['ja']).toMatchObject({
foo: {
bar: {
hello: msg2
}
}
})
})

describe('root', () => {
test('global', () => {
const __root = createComposer({
Expand Down
20 changes: 16 additions & 4 deletions packages/vue-i18n/test/i18n.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,14 @@ describe('useI18n', () => {
}
const options = instance.type as ComponentOptions
options.__i18n = [
JSON.stringify({ en: { hello: 'Hello,world!' } }),
JSON.stringify({ ja: { hello: 'こんにちは、世界!' } })
{
locale: '',
resource: { en: { hello: 'Hello,world!' } }
},
{
locale: '',
resource: { ja: { hello: 'こんにちは、世界!' } }
}
]
composer = useI18n()
return { t: (composer as Composer).t }
Expand Down Expand Up @@ -627,8 +633,14 @@ test('merge i18n custom blocks to global scope', async () => {
}
const options = instance.type as ComponentOptions
options.__i18nGlobal = [
JSON.stringify({ en: { foo: 'foo!' } }),
JSON.stringify({ ja: { foo: 'ふー!' } })
{
locale: 'en',
resource: { foo: 'foo!' }
},
{
locale: 'ja',
resource: { foo: 'ふー!' }
}
]
useI18n({
useScope: 'global',
Expand Down
7 changes: 6 additions & 1 deletion packages/vue-i18n/test/mixin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,12 @@ describe('beforeCreate', () => {
}
const App = defineComponent({
template: `<p>{{ $t('bye') }}</p>`,
__i18n: [JSON.stringify(messages)]
__i18n: [
{
locale: '',
resource: messages
}
]
})
const { html } = await mount(App, i18n)

Expand Down

0 comments on commit 5228b0a

Please sign in to comment.