Skip to content

Commit 44dc073

Browse files
authored
feat: format and ast option for compile command (#67)
1 parent 036f578 commit 44dc073

File tree

7 files changed

+316
-5
lines changed

7 files changed

+316
-5
lines changed

locales/en.json

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"the i18n resource source path": "the i18n resource source path",
66
"the compiled i18n resource output path": "the compiled i18n resource output path",
77
"the compiled i18n resource mode, 'production' or 'development' (default: 'production')": "the compiled i18n resource mode, 'production' or 'development' (default: 'production')",
8+
"resource compilation format, 'function' or 'ast' (default: 'function')": "resource compilation format, 'function' or 'ast' (default: 'function')",
89
"Success compilation: {source} -> {output}": "Success compilation: {source} -> {output}",
910
"{source}: Ignore compilation due to not supported '{ext}'": "{source}: Ignore compilation due to not supported '{ext}'",
1011
"Warning compilation: {source} -> {output}, {msg}": "Warning compilation: {source} -> {output}, {msg}",

locales/ja.json

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"the i18n resource source path": "コンパイルされる i18n リソースのパス",
55
"the compiled i18n resource output path": "コンパイルされた i18n リソースの出力先パス",
66
"the compiled i18n resource mode, 'production' or 'development' (default: 'production')": "コンパイルされる i18n リソースのモード, 'production' または 'development' (デフォルト: 'production')",
7+
"resource compilation format, 'function' or 'ast' (default: 'function')": "コンパイルされるリソースフォーマット, 'function' または 'ast' (デフォルト: 'function')",
78
"Success compilation: {source} -> {output}": "コンパイル成功: {source} -> {output}",
89
"{source}: Ignore compilation due to not supported '{ext}'": "{source}: '{ext}' がサポートされていないためコンパイルされません",
910
"Warning compilation: {source} -> {output}, {msg}": "コンパイル警告: {source} -> {output}, {msg}",

src/api/compile.ts

+8
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ export interface CompileOptions {
5757
* The mode of code generation. Default `production` for optimization. If `development`, code generated with meta information from i18n resources.
5858
*/
5959
mode?: DevEnv
60+
/**
61+
* Whether to generate AST format
62+
*
63+
* @remarks
64+
* default `false`, it will output the function format.
65+
*/
66+
ast?: boolean
6067
}
6168

6269
const COMPILE_MODE = ['production', 'development'] as const
@@ -114,6 +121,7 @@ export async function compile(
114121
const { code } = generate(source, {
115122
type: 'plain',
116123
filename: target,
124+
jit: !!options.ast,
117125
env,
118126
onError: (msg: string): void => {
119127
occuredError = true

src/commands/compile.ts

+10
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type CompileOptions = {
1313
source: string
1414
output?: string
1515
mode?: string
16+
format?: string
1617
}
1718

1819
export default function defineCommand() {
@@ -41,6 +42,14 @@ export default function defineCommand() {
4142
"the compiled i18n resource mode, 'production' or 'development' (default: 'production')"
4243
)
4344
})
45+
.option('format', {
46+
type: 'string',
47+
alias: 'f',
48+
default: 'function',
49+
describe: t(
50+
"resource compilation format, 'function' or 'ast' (default: 'function')"
51+
)
52+
})
4453
}
4554

4655
const handler = async (args: Arguments<CompileOptions>): Promise<void> => {
@@ -50,6 +59,7 @@ export default function defineCommand() {
5059
: process.cwd()
5160
const ret = await compile(args.source, output, {
5261
mode: args.mode as DevEnv,
62+
ast: args.format === 'ast',
5363
onCompile: (source: string, output: string): void => {
5464
console.log(
5565
green(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`compile > ast format 1`] = `
4+
{
5+
"backslash-backslash": {
6+
"b": {
7+
"i": [
8+
{
9+
"t": 3,
10+
},
11+
],
12+
"s": "\\\\\\\\",
13+
"t": 2,
14+
},
15+
"t": 0,
16+
},
17+
"backslash-single-quote": {
18+
"b": {
19+
"i": [
20+
{
21+
"t": 3,
22+
},
23+
],
24+
"s": "\\\\'",
25+
"t": 2,
26+
},
27+
"t": 0,
28+
},
29+
"complex": {
30+
"warnings": [
31+
{
32+
"b": {
33+
"i": [
34+
{
35+
"t": 3,
36+
},
37+
],
38+
"s": "NOTE: This is warning",
39+
"t": 2,
40+
},
41+
"t": 0,
42+
},
43+
{
44+
"named-waring": {
45+
"b": {
46+
"i": [
47+
{
48+
"t": 3,
49+
"v": "this is ",
50+
},
51+
{
52+
"k": "type",
53+
"t": 4,
54+
},
55+
{
56+
"t": 3,
57+
"v": " warining",
58+
},
59+
],
60+
"t": 2,
61+
},
62+
"t": 0,
63+
},
64+
},
65+
],
66+
},
67+
"emoji": {
68+
"b": {
69+
"i": [
70+
{
71+
"t": 3,
72+
},
73+
],
74+
"s": "😺",
75+
"t": 2,
76+
},
77+
"t": 0,
78+
},
79+
"errors": [
80+
{
81+
"b": {
82+
"i": [
83+
{
84+
"t": 3,
85+
},
86+
],
87+
"s": "ERROR1001",
88+
"t": 2,
89+
},
90+
"t": 0,
91+
},
92+
{
93+
"b": {
94+
"i": [
95+
{
96+
"t": 3,
97+
},
98+
],
99+
"s": "ERROR1002",
100+
"t": 2,
101+
},
102+
"t": 0,
103+
},
104+
],
105+
"hi": {
106+
"b": {
107+
"i": [
108+
{
109+
"t": 3,
110+
},
111+
],
112+
"s": "hi there!",
113+
"t": 2,
114+
},
115+
"t": 0,
116+
},
117+
"nested": {
118+
"hello": {
119+
"b": {
120+
"i": [
121+
{
122+
"t": 3,
123+
},
124+
],
125+
"s": "hello world!",
126+
"t": 2,
127+
},
128+
"t": 0,
129+
},
130+
"list": {
131+
"b": {
132+
"i": [
133+
{
134+
"t": 3,
135+
"v": "hi, ",
136+
},
137+
{
138+
"i": 0,
139+
"t": 5,
140+
},
141+
{
142+
"t": 3,
143+
"v": " !",
144+
},
145+
],
146+
"t": 2,
147+
},
148+
"t": 0,
149+
},
150+
"more": {
151+
"plural": {
152+
"b": {
153+
"c": [
154+
{
155+
"i": [
156+
{
157+
"k": {
158+
"t": 9,
159+
"v": "no apples",
160+
},
161+
"m": {
162+
"t": 8,
163+
"v": "caml",
164+
},
165+
"t": 6,
166+
},
167+
],
168+
"t": 2,
169+
},
170+
{
171+
"i": [
172+
{
173+
"i": 0,
174+
"t": 5,
175+
},
176+
{
177+
"t": 3,
178+
"v": " apple",
179+
},
180+
],
181+
"t": 2,
182+
},
183+
{
184+
"i": [
185+
{
186+
"k": "n",
187+
"t": 4,
188+
},
189+
{
190+
"t": 3,
191+
"v": " apples",
192+
},
193+
],
194+
"t": 2,
195+
},
196+
],
197+
"t": 1,
198+
},
199+
"t": 0,
200+
},
201+
},
202+
},
203+
"single-quote": {
204+
"b": {
205+
"i": [
206+
{
207+
"t": 3,
208+
},
209+
],
210+
"s": "I don't know!",
211+
"t": 2,
212+
},
213+
"t": 0,
214+
},
215+
"unicode": {
216+
"b": {
217+
"i": [
218+
{
219+
"t": 3,
220+
},
221+
],
222+
"s": "A",
223+
"t": 2,
224+
},
225+
"t": 0,
226+
},
227+
"unicode-escape": {
228+
"b": {
229+
"i": [
230+
{
231+
"t": 3,
232+
},
233+
],
234+
"s": "\\\\u0041",
235+
"t": 2,
236+
},
237+
"t": 0,
238+
},
239+
"こんにちは": {
240+
"b": {
241+
"i": [
242+
{
243+
"t": 3,
244+
},
245+
],
246+
"s": "こんにちは!",
247+
"t": 2,
248+
},
249+
"t": 0,
250+
},
251+
}
252+
`;

test/commands/compile.test.ts

+18-5
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@ const __dirname = dirname(fileURLToPath(import.meta.url))
1111
const CWD = resolve(__dirname, '../../')
1212

1313
let orgCwd
14-
beforeEach(async function () {
14+
beforeEach(async () => {
1515
await initI18n()
1616
orgCwd = process.cwd
1717
process.cwd = vi.fn().mockImplementation(() => CWD)
1818
})
1919

20-
afterEach(function () {
20+
afterEach(() => {
2121
process.cwd = orgCwd
2222
})
2323

24-
describe('compile', function () {
25-
it('basic', async function () {
24+
describe('compile', () => {
25+
it('basic', async () => {
2626
const cmd = yargs()
2727
// @ts-expect-error
2828
cmd.command(compile())
@@ -40,7 +40,7 @@ describe('compile', function () {
4040
expect(await prettier(compiled)).toBe(await prettier(expected))
4141
})
4242

43-
it('--mode development', async function () {
43+
it('--mode development', async () => {
4444
const cmd = yargs()
4545
// @ts-expect-error
4646
cmd.command(compile())
@@ -57,4 +57,17 @@ describe('compile', function () {
5757
)
5858
expect(await prettier(compiled)).toBe(await prettier(expected))
5959
})
60+
61+
it('ast format', async () => {
62+
const cmd = yargs()
63+
// @ts-expect-error
64+
cmd.command(compile())
65+
await cmd.parse(
66+
`compile --source ./test/fixtures/commands/compile-ast.json --output ./temp --format ast`
67+
)
68+
const code = await import(
69+
resolve(__dirname, '../../temp/compile-ast.js')
70+
).then(m => m.default || m)
71+
expect(code).toMatchSnapshot()
72+
})
6073
})
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"hi": "hi there!",
3+
"nested": {
4+
"hello": "hello world!",
5+
"more": {
6+
"plural": "@.caml:{'no apples'} | {0} apple | {n} apples"
7+
},
8+
"list": "hi, {0} !"
9+
},
10+
"こんにちは": "こんにちは!",
11+
"single-quote": "I don't know!",
12+
"emoji": "😺",
13+
"unicode": "\u0041",
14+
"unicode-escape": "\\u0041",
15+
"backslash-single-quote": "\\'",
16+
"backslash-backslash": "\\\\",
17+
"errors": ["ERROR1001", "ERROR1002"],
18+
"complex": {
19+
"warnings": [
20+
"NOTE: This is warning",
21+
{
22+
"named-waring": "this is {type} warining"
23+
}
24+
]
25+
}
26+
}

0 commit comments

Comments
 (0)