Skip to content

Commit b3cd804

Browse files
Merge pull request #145 from MentorMate/96-i18n-solution-for-prompts-messages
feat: add localization prompt
2 parents bf19fa2 + 826b3c3 commit b3cd804

File tree

8 files changed

+390
-44
lines changed

8 files changed

+390
-44
lines changed

index.ts

+51-44
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { postOrderDirectoryTraverse, preOrderDirectoryTraverse } from './utils/d
1616
import generateReadme from './utils/generateReadme'
1717
import generateIndex from './utils/generateIndex'
1818
import getCommand from './utils/getCommand'
19+
import getLanguage from './utils/getLanguage'
1920
import renderEslint from './utils/renderEslint'
2021
import { FILES_TO_FILTER } from './utils/filterList'
2122

@@ -118,7 +119,7 @@ async function init() {
118119
const defaultProjectName = !targetDir ? 'vue-project' : targetDir
119120

120121
const forceOverwrite = argv.force
121-
122+
const language = getLanguage()
122123
let result: {
123124
projectName?: string
124125
shouldOverwrite?: boolean
@@ -158,99 +159,105 @@ async function init() {
158159
{
159160
name: 'projectName',
160161
type: targetDir ? null : 'text',
161-
message: 'Project name:',
162+
message: language.projectName.message,
162163
initial: defaultProjectName,
163164
onState: (state) => (targetDir = String(state.value).trim() || defaultProjectName)
164165
},
165166
{
166167
name: 'shouldOverwrite',
167-
type: () => (canSkipEmptying(targetDir) || forceOverwrite ? null : 'confirm'),
168+
type: () => (canSkipEmptying(targetDir) || forceOverwrite ? null : 'toggle'),
168169
message: () => {
169170
const dirForPrompt =
170-
targetDir === '.' ? 'Current directory' : `Target directory "${targetDir}"`
171+
targetDir === '.'
172+
? language.shouldOverwrite.dirForPrompts.current
173+
: `${language.shouldOverwrite.dirForPrompts.target} "${targetDir}"`
171174

172-
return `${dirForPrompt} is not empty. Remove existing files and continue?`
173-
}
175+
return `${dirForPrompt} ${language.shouldOverwrite.message}`
176+
},
177+
initial: true,
178+
active: language.defaultToggleOptions.active,
179+
inactive: language.defaultToggleOptions.inactive
174180
},
175181
{
176182
name: 'overwriteChecker',
177183
type: (prev, values) => {
178184
if (values.shouldOverwrite === false) {
179-
throw new Error(red('✖') + ' Operation cancelled')
185+
throw new Error(red('✖') + ` ${language.errors.operationCancelled}`)
180186
}
181187
return null
182188
}
183189
},
184190
{
185191
name: 'packageName',
186192
type: () => (isValidPackageName(targetDir) ? null : 'text'),
187-
message: 'Package name:',
193+
message: language.packageName.message,
188194
initial: () => toValidPackageName(targetDir),
189-
validate: (dir) => isValidPackageName(dir) || 'Invalid package.json name'
195+
validate: (dir) => isValidPackageName(dir) || language.packageName.invalidMessage
190196
},
191197
{
192198
name: 'needsTypeScript',
193199
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
194-
message: 'Add TypeScript?',
200+
message: language.needsTypeScript.message,
195201
initial: false,
196-
active: 'Yes',
197-
inactive: 'No'
202+
active: language.defaultToggleOptions.active,
203+
inactive: language.defaultToggleOptions.inactive
198204
},
199205
{
200206
name: 'needsJsx',
201207
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
202-
message: 'Add JSX Support?',
208+
message: language.needsJsx.message,
203209
initial: false,
204-
active: 'Yes',
205-
inactive: 'No'
210+
active: language.defaultToggleOptions.active,
211+
inactive: language.defaultToggleOptions.inactive
206212
},
207213
{
208214
name: 'needsRouter',
209215
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
210-
message: 'Add Vue Router for Single Page Application development?',
216+
message: language.needsRouter.message,
211217
initial: false,
212-
active: 'Yes',
213-
inactive: 'No'
218+
active: language.defaultToggleOptions.active,
219+
inactive: language.defaultToggleOptions.inactive
214220
},
215221
{
216222
name: 'needsPinia',
217223
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
218-
message: 'Add Pinia for state management?',
224+
message: language.needsPinia.message,
219225
initial: false,
220-
active: 'Yes',
221-
inactive: 'No'
226+
active: language.defaultToggleOptions.active,
227+
inactive: language.defaultToggleOptions.inactive
222228
},
223229
{
224230
name: 'needsVitest',
225231
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
226-
message: 'Add Vitest for Unit Testing?',
232+
message: language.needsVitest.message,
227233
initial: false,
228-
active: 'Yes',
229-
inactive: 'No'
234+
active: language.defaultToggleOptions.active,
235+
inactive: language.defaultToggleOptions.inactive
230236
},
231237
{
232238
name: 'needsE2eTesting',
233239
type: () => (isFeatureFlagsUsed ? null : 'select'),
234-
message: 'Add an End-to-End Testing Solution?',
240+
hint: language.needsE2eTesting.hint,
241+
message: language.needsE2eTesting.message,
235242
initial: 0,
236243
choices: (prev, answers) => [
237-
{ title: 'No', value: false },
244+
{ title: language.needsE2eTesting.selectOptions.negative.title, value: false },
238245
{
239-
title: 'Playwright',
246+
title: language.needsE2eTesting.selectOptions.playwright.title,
240247
value: 'playwright'
241248
},
242249
{
243-
title: 'Nightwatch',
250+
title: language.needsE2eTesting.selectOptions.nightwatch.title,
244251
description: answers.needsVitest
245252
? undefined
246-
: 'also supports unit testing with Nightwatch Component Testing',
253+
: language.needsE2eTesting.selectOptions.nightwatch.desc,
247254
value: 'nightwatch'
248255
},
249256
{
250-
title: 'Cypress',
257+
title: language.needsE2eTesting.selectOptions.cypress.title,
251258
description: answers.needsVitest
252259
? undefined
253-
: 'also supports unit testing with Cypress Component Testing',
260+
: language.needsE2eTesting.selectOptions.cypress.desc,
254261
value: 'cypress'
255262
}
256263
]
@@ -260,24 +267,24 @@ async function init() {
260267
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
261268
message: 'Add VueUse - Collection of essential Composition Utilities?',
262269
initial: false,
263-
active: 'Yes',
264-
inactive: 'No'
270+
active: language.defaultToggleOptions.active,
271+
inactive: language.defaultToggleOptions.inactive
265272
},
266273
{
267274
name: 'needsI18n',
268275
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
269276
message: 'Add i18n - internationalization plugin?',
270277
initial: false,
271-
active: 'Yes',
272-
inactive: 'No'
278+
active: language.defaultToggleOptions.active,
279+
inactive: language.defaultToggleOptions.inactive
273280
},
274281
{
275282
name: 'needsStorybook',
276283
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
277284
message: 'Add Storybook?',
278285
initial: false,
279-
active: 'Yes',
280-
inactive: 'No'
286+
active: language.defaultToggleOptions.active,
287+
inactive: language.defaultToggleOptions.inactive
281288
},
282289
{
283290
name: 'needsSonarQube',
@@ -289,22 +296,22 @@ async function init() {
289296
},
290297
message: 'Add SonarQube for code coverage?',
291298
initial: false,
292-
active: 'Yes',
293-
inactive: 'No'
299+
active: language.defaultToggleOptions.active,
300+
inactive: language.defaultToggleOptions.inactive
294301
},
295302
{
296303
name: 'needsTanStackQuery',
297304
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
298305
message:
299306
'Add TanStack Query - Hooks for fetching, caching and updating asynchronous data?',
300307
initial: false,
301-
active: 'Yes',
302-
inactive: 'No'
308+
active: language.defaultToggleOptions.active,
309+
inactive: language.defaultToggleOptions.inactive
303310
}
304311
],
305312
{
306313
onCancel: () => {
307-
throw new Error(red('✖') + ' Operation cancelled')
314+
throw new Error(red('✖') + ` ${language.errors.operationCancelled}`)
308315
}
309316
}
310317
)
@@ -346,7 +353,7 @@ async function init() {
346353
fs.mkdirSync(root)
347354
}
348355

349-
console.log(`\nScaffolding project in ${root}...`)
356+
console.log(`\n${language.infos.scaffolding} ${root}...`)
350357

351358
const pkg = { name: packageName, version: '0.0.0' }
352359
fs.writeFileSync(path.resolve(root, 'package.json'), JSON.stringify(pkg, null, 2))
@@ -552,7 +559,7 @@ async function init() {
552559
})
553560
)
554561

555-
console.log(`\nDone. Now run:\n`)
562+
console.log(`\n${language.infos.done}\n`)
556563
if (root !== cwd) {
557564
const cdProjectName = path.relative(cwd, root)
558565
console.log(

locales/en-US.json

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
"projectName": {
3+
"message": "Project name:",
4+
"invalidMessage": "Invalid package.json name"
5+
},
6+
"shouldOverwrite": {
7+
"dirForPrompts": {
8+
"current": "Current directory",
9+
"target": "Target directory"
10+
},
11+
"message": "is not empty. Remove existing files and continue?"
12+
},
13+
"packageName": {
14+
"message": "Package name:"
15+
},
16+
"needsTypeScript": {
17+
"message": "Add TypeScript?"
18+
},
19+
"needsJsx": {
20+
"message": "Add JSX Support?"
21+
},
22+
"needsRouter": {
23+
"message": "Add Vue Router for Single Page Application development?"
24+
},
25+
"needsPinia": {
26+
"message": "Add Pinia for state management?"
27+
},
28+
"needsVitest": {
29+
"message": "Add Vitest for Unit Testing?"
30+
},
31+
"needsE2eTesting": {
32+
"message": "Add an End-to-End Testing Solution?",
33+
"hint": "- Use arrow-keys. Return to submit.",
34+
"selectOptions": {
35+
"negative": { "title": "No" },
36+
"cypress": {
37+
"title": "Cypress",
38+
"desc": "also supports unit testing with Cypress Component Testing"
39+
},
40+
"nightwatch": {
41+
"title": "Nightwatch",
42+
"desc": "also supports unit testing with Nightwatch Component Testing"
43+
},
44+
"playwright": { "title": "Playwright" }
45+
}
46+
},
47+
"needsEslint": {
48+
"message": "Add ESLint for code quality?"
49+
},
50+
"needsPrettier": {
51+
"message": "Add Prettier for code formatting?"
52+
},
53+
"errors": {
54+
"operationCancelled": "Operation cancelled"
55+
},
56+
"defaultToggleOptions": {
57+
"active": "Yes",
58+
"inactive": "No"
59+
},
60+
"infos": {
61+
"scaffolding": "Scaffolding project in",
62+
"done": "Done. Now run:"
63+
}
64+
}

locales/fr-FR.json

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
"projectName": {
3+
"message": "Nom du projet\u00a0:",
4+
"invalidMessage": "Le nom du package.json est invalide"
5+
},
6+
"shouldOverwrite": {
7+
"dirForPrompts": {
8+
"current": "Répertoire courant",
9+
"target": "Répertoire cible"
10+
},
11+
"message": "n'est pas vide. Supprimer les fichiers existants et continuer\u00a0?"
12+
},
13+
"packageName": {
14+
"message": "Nom du package\u00a0:"
15+
},
16+
"needsTypeScript": {
17+
"message": "Ajouter TypeScript\u00a0?"
18+
},
19+
"needsJsx": {
20+
"message": "Ajouter le support de JSX\u00a0?"
21+
},
22+
"needsRouter": {
23+
"message": "Ajouter Vue Router pour le développement d'applications _single page_\u00a0?"
24+
},
25+
"needsPinia": {
26+
"message": "Ajouter Pinia pour la gestion de l'état\u00a0?"
27+
},
28+
"needsVitest": {
29+
"message": "Ajouter Vitest pour les tests unitaires\u00a0?"
30+
},
31+
"needsE2eTesting": {
32+
"message": "Ajouter une solution de test de bout en bout (e2e)\u00a0?",
33+
"hint": "- Utilisez les flèches et appuyez sur la touche Entrée pour valider",
34+
"selectOptions": {
35+
"negative": { "title": "Non" },
36+
"cypress": {
37+
"title": "Cypress",
38+
"desc": "prend également en charge les tests unitaires avec Cypress Component Testing"
39+
},
40+
"nightwatch": {
41+
"title": "Nightwatch",
42+
"desc": "prend également en charge les tests unitaires avec Nightwatch Component Testing"
43+
},
44+
"playwright": { "title": "Playwright" }
45+
}
46+
},
47+
"needsEslint": {
48+
"message": "Ajouter ESLint pour la qualité du code\u00a0?"
49+
},
50+
"needsPrettier": {
51+
"message": "Ajouter Prettier pour le formatage du code\u00a0?"
52+
},
53+
"errors": {
54+
"operationCancelled": "Operation annulée"
55+
},
56+
"defaultToggleOptions": {
57+
"active": "Oui",
58+
"inactive": "Non"
59+
},
60+
"infos": {
61+
"scaffolding": "Génération du projet dans",
62+
"done": "Terminé. Exécutez maintenant\u00a0:"
63+
}
64+
}

0 commit comments

Comments
 (0)