Skip to content

Commit ef674ce

Browse files
committed
⭐ new(api): reflect locale message meta from SFC file info
1 parent dd5e2db commit ef674ce

File tree

3 files changed

+131
-9
lines changed

3 files changed

+131
-9
lines changed

src/reflector.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,42 @@
1-
import { LocaleMessageMeta } from '../types'
1+
import { LocaleMessageMeta, SFCFileInfo } from '../types'
2+
import { VueTemplateCompiler } from '@vue/component-compiler-utils/dist/types'
23

3-
export default function getLocaleMessageMeta (components: string[]): LocaleMessageMeta[] {
4-
return []
4+
import { parse } from '@vue/component-compiler-utils'
5+
import * as compiler from 'vue-template-compiler'
6+
import path from 'path'
7+
8+
import { debug as Debug } from 'debug'
9+
const debug = Debug('vue-i18n-locale-message:reflector')
10+
11+
export default function reflectLocaleMessageMeta (basePath: string, components: SFCFileInfo[]): LocaleMessageMeta[] {
12+
return components.map(target => {
13+
const desc = parse({
14+
source: target.content,
15+
filename: target.path,
16+
compiler: compiler as VueTemplateCompiler
17+
})
18+
const { contentPath, component, messageHierarchy } = parsePath(basePath, target.path)
19+
const cm = ''
20+
return {
21+
contentPath,
22+
content: cm,
23+
blocks: desc.customBlocks,
24+
component,
25+
messageHierarchy
26+
}
27+
})
28+
}
29+
30+
function parsePath (basePath: string, targetPath: string) {
31+
const parsed = path.parse(targetPath)
32+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
33+
const [_, target] = parsed.dir.split(basePath)
34+
const parsedTargetPath = target.split(path.sep)
35+
parsedTargetPath.shift()
36+
debug(`parsePath: contentPath = ${targetPath}, component = ${parsed.name}, messageHierarchy = ${parsedTargetPath}`)
37+
return {
38+
contentPath: targetPath,
39+
component: parsed.name,
40+
messageHierarchy: parsedTargetPath
41+
}
542
}

test/reflector.test.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,43 @@
1-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2-
import getLocaleMessageMeta from '../src/reflector'
1+
import { SFCFileInfo } from '../types'
2+
import reflectLocaleMessageMeta from '../src/reflector'
33

4-
test('getLocaleMessageMeta', () => {
4+
test('reflectLocaleMessageMeta', () => {
5+
const componentInfo: SFCFileInfo = {
6+
path: '/path/to/project1/src/components/common/Modal.vue',
7+
content: `
8+
<template>
9+
<!-- template contents is here ... -->
10+
</template>
11+
12+
<script>
13+
// script codes is here ...
14+
export default {}
15+
</script>
16+
17+
<style scoped>
18+
// css style codes is here ...
19+
</style>
20+
21+
<i18n>
22+
{
23+
"en": {
24+
"ok": "OK",
25+
"cancel": "Cancel"
26+
},
27+
"ja": {
28+
"ok": "OK",
29+
"cancel": "キャンセル"
30+
}
31+
}
32+
</i18n>
33+
`
34+
}
35+
36+
const metaInfo = reflectLocaleMessageMeta('/path/to/project1/src', [componentInfo])
37+
expect(metaInfo.length).toBe(1)
38+
const [meta] = metaInfo
39+
expect(meta.contentPath).toBe(componentInfo.path)
40+
expect(meta.component).toBe('Modal')
41+
expect(meta.messageHierarchy).toEqual(['components', 'common'])
42+
expect(meta.blocks.length).toBe(1)
543
})

types/index.d.ts

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { SFCCustomBlock } from '@vue/component-compiler-utils'
2+
13
/**
24
* Locale Message Recursive Structure
35
* e.g.
@@ -29,11 +31,23 @@ export interface LocaleMessageObject { [key: string]: LocaleMessage }
2931
export type LocaleMessages = { [key: string]: LocaleMessageObject }
3032

3133
/**
32-
* Locale Message Meta to squeeze / infuse.
34+
* SFC (Single-file component) file info
3335
* e.g.
3436
* {
35-
* contentPath: '/path/to/project1/src/components/common/Modal.vue',
37+
* path: '/path/to/project1/src/components/common/Modal.vue',
3638
* content: `
39+
* <template>
40+
* <!-- template contents is here ... -->
41+
* </template>
42+
*
43+
* <script>
44+
* // script codes is here ...
45+
* </script>
46+
*
47+
* <style scoped>
48+
* // css style codes is here ...
49+
* </style>
50+
*
3751
* <i18n>
3852
* {
3953
* "en": {
@@ -47,14 +61,47 @@ export type LocaleMessages = { [key: string]: LocaleMessageObject }
4761
* }
4862
* </i18n>
4963
* `,
64+
* }
65+
*/
66+
67+
export interface SFCFileInfo {
68+
path: string
69+
content: string
70+
}
71+
72+
/**
73+
* Locale Message Meta to squeeze / infuse.
74+
* e.g.
75+
* {
76+
* contentPath: '/path/to/project1/src/components/common/Modal.vue',
77+
* blocks: [{
78+
* type: 'i18n',
79+
* content: `
80+
* {
81+
* "en": {
82+
* "ok": "OK",
83+
* "cancel": "Cancel"
84+
* },
85+
* "ja": {
86+
* "ok": "OK",
87+
* "cancel": "キャンセル"
88+
* }
89+
* }
90+
* `,
91+
* attrs: { ... },
92+
* start: 10,
93+
* end: 30,
94+
* map: { ... }
95+
* }, ...],
5096
* component: 'Modal',
5197
* messageHierarchy: ['components', 'common', 'Modal']
5298
* }
5399
*/
54100

55-
export type LocaleMessageMeta = {
101+
export interface LocaleMessageMeta {
56102
contentPath: string
57103
content: string
104+
blocks: SFCCustomBlock[]
58105
component: string
59106
messageHierarchy: string[]
60107
}

0 commit comments

Comments
 (0)