Skip to content

Commit

Permalink
⭐ new(api): extract i18n locale messages from i18n custom block meta …
Browse files Browse the repository at this point in the history
…info
  • Loading branch information
kazupon committed Jul 29, 2019
1 parent da18426 commit 9f4c47c
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 3 deletions.
48 changes: 47 additions & 1 deletion src/squeezer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
import { LocaleMessageMeta, LocaleMessages } from '../types'
import { VueTemplateCompiler } from '@vue/component-compiler-utils/dist/types'

import { parse } from '@vue/component-compiler-utils'
import * as compiler from 'vue-template-compiler'

import { debug as Debug } from 'debug'
const debug = Debug('vue-i18n-locale-messages:squeezer')

export default function sqeeze (meta: LocaleMessageMeta[]): LocaleMessages {
return {}
const messages: LocaleMessages = {}

meta.forEach(target => {
const blockMessages = squeezeFromI18nBlock(target.content)
const locales = Object.keys(blockMessages)
const collects: LocaleMessages = locales.reduce((messages, locale) => {
const ret = target.messageHierarchy.reduce((messages, key) => {
return Object.assign({}, { [key]: messages })
}, blockMessages[locale])
return Object.assign(messages, { [locale]: ret })
}, {})
debug('collects', collects)

locales.forEach(locale => {
messages[locale] = messages[locale] || {}
messages[locale] = Object.assign(messages[locale], collects[locale])
})
})

return messages
}

function squeezeFromI18nBlock (content: string): LocaleMessages {
const desc = parse({
source: content,
compiler: compiler as VueTemplateCompiler
})

return desc.customBlocks.reduce((messages, block) => {
if (block.type === 'i18n') {
const obj = JSON.parse(block.content)
if (block.attrs.locale) {
return Object.assign(messages, { [block.attrs.locale as string]: obj })
} else {
return Object.assign(messages, obj)
}
} else {
return messages
}
}, {})
}
47 changes: 47 additions & 0 deletions test/__snapshots__/squeezer.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`squeeze 1`] = `
Object {
"en": Object {
"App": Object {
"title": "Application",
},
"Modal": Object {
"components": Object {
"cancel": "Cancel",
"ok": "OK",
},
},
"RankingTable": Object {
"nest": Object {
"components": Object {
"headers": Object {
"name": "Name",
"rank": "Rank",
"score": "Score",
},
},
},
},
},
"ja": Object {
"App": Object {
"title": "アプリケーション",
},
"Login": Object {
"pages": Object {
"button": "ログイン",
"confirm": "パスワードの確認入力",
"id": "ユーザーID",
"passowrd": "パスワード",
},
},
"Modal": Object {
"components": Object {
"cancel": "キャンセル",
"ok": "OK",
},
},
},
}
`;
62 changes: 62 additions & 0 deletions test/fixtures/meta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
export default [{
contentPath: '/path/to/project1/src/App.vue',
content: `
<i18n>
{
"en": { "title": "Application" },
"ja": { "title": "アプリケーション" }
}
</i18n>
`,
component: 'App',
messageHierarchy: ['App']
}, {
contentPath: '/path/to/project1/src/components/Modal.vue',
content: `
<i18n locale="en">
{
"ok": "OK",
"cancel": "Cancel"
}
</i18n>
<i18n locale="ja">
{
"ok": "OK",
"cancel": "キャンセル"
}
</i18n>
`,
component: 'Modal',
messageHierarchy: ['components', 'Modal']
}, {
contentPath: '/path/to/project1/src/components/nest/RankingTable.vue',
content: `
<i18n locale="en">
{
"headers": {
"rank": "Rank",
"name": "Name",
"score": "Score"
}
}
</i18n>
`,
component: 'RankingTable',
messageHierarchy: ['components', 'nest', 'RankingTable']
}, {
contentPath: '/path/to/project1/src/pages/Login.vue',
content: `
<i18n>
{
"ja": {
"id": "ユーザーID",
"passowrd": "パスワード",
"confirm": "パスワードの確認入力",
"button": "ログイン"
}
}
</i18n>
`,
compnent: 'Login',
messageHierarchy: ['pages', 'Login']
}]
1 change: 1 addition & 0 deletions test/infuser.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import infuse from '../src/infuser'

test('infuse', () => {
Expand Down
1 change: 1 addition & 0 deletions test/reflector.tst.ts → test/reflector.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import getLocaleMessageMeta from '../src/reflector'

test('getLocaleMessageMeta', () => {
Expand Down
4 changes: 4 additions & 0 deletions test/squeezer.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import squeeze from '../src/squeezer'
import metaInfo from './fixtures/meta'
import { LocaleMessages, LocaleMessageMeta } from '../types'

test('squeeze', () => {
const mesasges: LocaleMessages = squeeze(metaInfo as LocaleMessageMeta[])
expect(mesasges).toMatchSnapshot()
})
4 changes: 2 additions & 2 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ export type LocaleMessages = { [key: string]: LocaleMessageObject }
* </i18n>
* `,
* component: 'Modal',
* messagePath: '/components/common'
* messageHierarchy: ['components', 'common', 'Modal']
* }
*/

export type LocaleMessageMeta = {
contentPath: string
content: string
component: string
messagePath: string
messageHierarchy: string[]
}

0 comments on commit 9f4c47c

Please sign in to comment.