Skip to content

Commit f21cb32

Browse files
authored
Merge pull request #165 from wilsenhc/feat/noEmptyTranslation
Feature: option for no empty translation when adding missing strings
2 parents e743a59 + a9b5a02 commit f21cb32

File tree

8 files changed

+71
-5
lines changed

8 files changed

+71
-5
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ This will print out a table of missing keys in your language files, as well as u
8989
// Example1 (specific, value is a key): user.auth.username.label
9090
// Example2 (nested, value is a node): user.auth
9191
// Example3 (multiple): --exclude user.auth.username.label --exclude user.auth.password.label
92+
93+
--noEmptyTranslation
94+
// String
95+
// Use if you want to generate a default translated string by using the key itself
96+
// Example 1: '' => DO NOT generate default strings (default)
97+
// Example 2: '*' => generate default string for ALL locales
98+
// Example 3: 'en' => generate default strings ONLY for en locale
9299
```
93100

94101
## Config File

bin/vue-i18n-extract.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ cli
3939
'--exclude <key>',
4040
'Use if you want to exclude a key. It can be used multiple times to exclude any amount of keys on the output'
4141
)
42+
.option(
43+
'--noEmptyTranslation',
44+
'Use if you want to generate a default translated string by using the key itself'
45+
)
4246
.action((options) => {
4347
createI18NReport(resolveConfig(options));
4448
});

src/config-file/vue-i18n-extract.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ export default {
77
add: false,
88
remove: false,
99
ci: false,
10-
separator: '.'
10+
separator: '.',
11+
noEmptyTranslation: ''
1112
};

src/create-report/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ export async function createI18NReport (options: ReportOptions): Promise<I18NRep
1414
remove,
1515
exclude = [],
1616
ci,
17-
separator
17+
separator,
18+
noEmptyTranslation = '',
1819
} = options;
1920

2021
if (!vueFilesGlob) throw new Error('Required configuration vueFiles is missing.');
@@ -47,7 +48,7 @@ export async function createI18NReport (options: ReportOptions): Promise<I18NRep
4748
}
4849

4950
if (add && report.missingKeys.length) {
50-
writeMissingToLanguageFiles(languageFiles, report.missingKeys, dot);
51+
writeMissingToLanguageFiles(languageFiles, report.missingKeys, dot, noEmptyTranslation);
5152
console.info('\nThe missing keys have been added to your language files.');
5253
}
5354

src/create-report/language-files.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,14 @@ export function extractI18NLanguageFromLanguageFiles (languageFiles: SimpleFile[
6262
}, {});
6363
}
6464

65-
export function writeMissingToLanguageFiles (parsedLanguageFiles: SimpleFile[], missingKeys: I18NItem[], dot: DotObject.Dot = Dot): void {
65+
export function writeMissingToLanguageFiles (parsedLanguageFiles: SimpleFile[], missingKeys: I18NItem[], dot: DotObject.Dot = Dot, noEmptyTranslation = ''): void {
6666
parsedLanguageFiles.forEach(languageFile => {
6767
const languageFileContent = JSON.parse(languageFile.content);
6868

6969
missingKeys.forEach(item => {
7070
if (item.language && languageFile.fileName.includes(item.language) || !item.language) {
71-
dot.str(item.path, '', languageFileContent);
71+
const addDefaultTranslation = (noEmptyTranslation) && ((noEmptyTranslation === '*') || (noEmptyTranslation === item.language));
72+
dot.str(item.path, addDefaultTranslation ? item.path : '', languageFileContent);
7273
}
7374
});
7475

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export type ReportOptions = {
77
remove?: boolean;
88
ci?: boolean;
99
separator?: string;
10+
noEmptyTranslation?: string;
1011
}
1112

1213
export type SimpleFile = {

tests/unit/create-report/index.spec.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,37 @@ describe('file: create-report/index', () => {
7575
languageFileActions.readLanguageFiles(options.languageFiles),
7676
expectedI18NReport.missingKeys,
7777
Dot,
78+
'',
79+
);
80+
expect(consoleInfoSpy).toHaveBeenLastCalledWith('\nThe missing keys have been added to your language files.');
81+
});
82+
83+
it('Write missing keys to language files without empty translation', async () => {
84+
options.add = true;
85+
options.noEmptyTranslation = '*';
86+
const writeMissingSpy: jest.SpyInstance<unknown> = jest.spyOn(languageFileActions, 'writeMissingToLanguageFiles');
87+
writeMissingSpy.mockImplementation(() => jest.fn());
88+
await createI18NReport(options);
89+
expect(writeMissingSpy).toHaveBeenCalledWith(
90+
languageFileActions.readLanguageFiles(options.languageFiles),
91+
expectedI18NReport.missingKeys,
92+
Dot,
93+
'*',
94+
);
95+
expect(consoleInfoSpy).toHaveBeenLastCalledWith('\nThe missing keys have been added to your language files.');
96+
});
97+
98+
it('Write missing keys to language files without empty translation for a single locale', async () => {
99+
options.add = true;
100+
options.noEmptyTranslation = 'en';
101+
const writeMissingSpy: jest.SpyInstance<unknown> = jest.spyOn(languageFileActions, 'writeMissingToLanguageFiles');
102+
writeMissingSpy.mockImplementation(() => jest.fn());
103+
await createI18NReport(options);
104+
expect(writeMissingSpy).toHaveBeenCalledWith(
105+
languageFileActions.readLanguageFiles(options.languageFiles),
106+
expectedI18NReport.missingKeys,
107+
Dot,
108+
'en',
78109
);
79110
expect(consoleInfoSpy).toHaveBeenLastCalledWith('\nThe missing keys have been added to your language files.');
80111
});

tests/unit/create-report/language-files.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,26 @@ describe('file: create-report/language-files', () => {
3838
expect(writeFileSyncSpy).toHaveBeenCalledTimes(3);
3939
expect(writeFileSyncSpy.mock.calls[0][1]).toContain('missing');
4040
});
41+
42+
it('Writes missing keys with no empty translation to language files', () => {
43+
const writeFileSyncSpy = jest.spyOn(fs, 'writeFileSync');
44+
writeFileSyncSpy.mockImplementation(() => jest.fn());
45+
const dotStrSpy = jest.spyOn(dot, 'str');
46+
writeMissingToLanguageFiles(readLanguageFiles(languageFiles), expectedI18NReport.missingKeys, dot, '*');
47+
expect(dotStrSpy).toHaveBeenCalledTimes(78);
48+
expect(writeFileSyncSpy).toHaveBeenCalledTimes(6);
49+
expect(writeFileSyncSpy.mock.calls[0][1]).toContain('missing');
50+
});
51+
52+
it('Writes missing keys with no empty translation for single locale to language files', () => {
53+
const writeFileSyncSpy = jest.spyOn(fs, 'writeFileSync');
54+
writeFileSyncSpy.mockImplementation(() => jest.fn());
55+
const dotStrSpy = jest.spyOn(dot, 'str');
56+
writeMissingToLanguageFiles(readLanguageFiles(languageFiles), expectedI18NReport.missingKeys, dot, 'en');
57+
expect(dotStrSpy).toHaveBeenCalledTimes(117);
58+
expect(writeFileSyncSpy).toHaveBeenCalledTimes(9);
59+
expect(writeFileSyncSpy.mock.calls[0][1]).toContain('missing');
60+
});
4161
});
4262

4363
describe('function: removeUnusedFromLanguageFiles', () => {

0 commit comments

Comments
 (0)