Skip to content

Commit ee49f8a

Browse files
authored
feat(i18n): add command to publish localization templates (#5037)
1 parent 4f872ae commit ee49f8a

File tree

2 files changed

+162
-0
lines changed

2 files changed

+162
-0
lines changed

commands/lang/publish.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* @adonisjs/core
3+
*
4+
* (c) AdonisJS
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import { BaseCommand, flags } from '../../modules/ace/main.js'
11+
import { writeFile, readFile, mkdir } from 'node:fs/promises'
12+
import { existsSync } from 'node:fs'
13+
import { dirname } from 'node:path'
14+
15+
/**
16+
* Publish localization templates
17+
*/
18+
export default class MakeCommand extends BaseCommand {
19+
static commandName = 'lang:publish'
20+
static description = 'Eject localization templates to resources/lang/en directory'
21+
22+
@flags.boolean({ description: 'Merge with existing "validator.json" file' })
23+
declare merge?: boolean
24+
25+
async run() {
26+
let messages: any = {}
27+
try {
28+
const vine = await import('@vinejs/vine/defaults')
29+
messages = vine.messages
30+
} catch {
31+
this.exitCode = 1
32+
this.logger.error('Vine is not installed. No localization templates to publish.')
33+
return
34+
}
35+
36+
const destination = this.app.languageFilesPath('en', 'validator.json')
37+
38+
if (existsSync(destination) && !this.merge) {
39+
this.exitCode = 1
40+
this.logger.error(
41+
'File "resources/lang/en/validator.json" already exists. Use "--merge" flag to update the file'
42+
)
43+
return
44+
}
45+
46+
let validatorMessages = {
47+
shared: {
48+
messages: {},
49+
},
50+
}
51+
52+
if (existsSync(destination)) {
53+
try {
54+
validatorMessages = JSON.parse(await readFile(destination, 'utf-8'))
55+
} catch {
56+
this.exitCode = 1
57+
this.logger.error(
58+
'Failed to parse existing validator.json. Overwriting with default contents.'
59+
)
60+
return
61+
}
62+
}
63+
64+
validatorMessages = {
65+
...validatorMessages,
66+
shared: {
67+
...validatorMessages.shared,
68+
messages: {
69+
...messages,
70+
...validatorMessages.shared?.messages,
71+
},
72+
},
73+
}
74+
75+
await mkdir(dirname(destination), { recursive: true })
76+
await writeFile(destination, JSON.stringify(validatorMessages, null, 2))
77+
78+
this.logger.success('Localization template published to resources/lang/en/validator.json')
79+
}
80+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { test } from '@japa/runner'
2+
import { AceFactory } from '../../factories/core/ace.js'
3+
import LangPublishCommand from '../../commands/lang/publish.js'
4+
5+
test.group('Lang publish', () => {
6+
test('publish validator messages', async ({ assert, fs }) => {
7+
const ace = await new AceFactory().make(fs.baseUrl)
8+
await ace.app.init()
9+
ace.ui.switchMode('raw')
10+
11+
const command = await ace.create(LangPublishCommand, [])
12+
await command.exec()
13+
14+
await assert.fileExists('resources/lang/en/validator.json')
15+
const json = await fs.contentsJson('resources/lang/en/validator.json')
16+
assert.isObject(json.shared)
17+
assert.isObject(json.shared.messages)
18+
assert.isTrue(Object.keys(json.shared.messages).length > 0)
19+
20+
assert.deepEqual(ace.ui.logger.getLogs(), [
21+
{
22+
message:
23+
'[ green(success) ] Localization template published to resources/lang/en/validator.json',
24+
stream: 'stdout',
25+
},
26+
])
27+
})
28+
29+
test('skip when validator messages file already exists', async ({ assert, fs }) => {
30+
const ace = await new AceFactory().make(fs.baseUrl)
31+
await ace.app.init()
32+
ace.ui.switchMode('raw')
33+
34+
await fs.create('resources/lang/en/validator.json', JSON.stringify({ old: true }))
35+
36+
const command = await ace.create(LangPublishCommand, [])
37+
await command.exec()
38+
39+
const json = await fs.contentsJson('resources/lang/en/validator.json')
40+
assert.deepEqual(json, { old: true })
41+
42+
assert.deepEqual(ace.ui.logger.getLogs(), [
43+
{
44+
message:
45+
'[ red(error) ] File "resources/lang/en/validator.json" already exists. Use "--merge" flag to update the file',
46+
stream: 'stderr',
47+
},
48+
])
49+
})
50+
51+
test('merge when validator messages file already exists and --merge is used', async ({
52+
assert,
53+
fs,
54+
}) => {
55+
const ace = await new AceFactory().make(fs.baseUrl)
56+
await ace.app.init()
57+
ace.ui.switchMode('raw')
58+
59+
await fs.create(
60+
'resources/lang/en/validator.json',
61+
JSON.stringify({
62+
shared: { messages: { required: 'foo' } },
63+
other: true,
64+
})
65+
)
66+
67+
const command = await ace.create(LangPublishCommand, ['--merge'])
68+
await command.exec()
69+
70+
const json = await fs.contentsJson('resources/lang/en/validator.json')
71+
assert.property(json, 'other')
72+
assert.equal(json.shared.messages.required, 'foo')
73+
74+
assert.deepEqual(ace.ui.logger.getLogs(), [
75+
{
76+
message:
77+
'[ green(success) ] Localization template published to resources/lang/en/validator.json',
78+
stream: 'stdout',
79+
},
80+
])
81+
})
82+
})

0 commit comments

Comments
 (0)