Skip to content

Commit

Permalink
feat: ✨ Optimized generated translations.json
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeychikk committed Aug 21, 2019
1 parent 18d7f0a commit e2a3bb3
Show file tree
Hide file tree
Showing 9 changed files with 412 additions and 23 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
## Usage

- `export-strings [input-files-glob] [output] [--default-locale=locale]` parse through all the files provided in `input-files-glob` (`src/**/{*.js,*.jsx,*.ts,*.tsx}` by default) (uses [glob](https://www.npmjs.com/package/glob)) and generate .pot file in the output path (`./src/i18n/template.pot` by default). Then searches for all the `.po` files in the same directory and updates them with new strings to translate. If `default-locale` is provided (e.g. `en`) and this locale's `.po` file exists in the same folder (e.g. `en.po`), this file will be populated with the translations automatically.
- `import-strings [po-files-path] [output]` parse all the `.po` files inside the directory provided as `po-files-path` (`./src/i18n/` by default) and generate [react-targem](https://github.com/trucknet-io/react-targem) or [lioness](https://github.com/alexanderwallin/lioness) compatible `.json` file in the output path (`./src/i18n/translations.json`), which is an object with each locale as a key and [gettext-parser](https://www.npmjs.com/package/gettext-parser) object for this locale as a value.
- `import-strings [po-files-path] [output]` parse all the `.po` files inside the directory provided as `po-files-path` (`./src/i18n/` by default) and generate [react-targem](https://github.com/trucknet-io/react-targem) or [lioness](https://github.com/alexanderwallin/lioness) compatible `.json` file in the output path (`./src/i18n/translations.json`), which is an object with each locale as a key and [gettext-parser](https://www.npmjs.com/package/gettext-parser) object for this locale as a value. By default all `translations.json` are optimized, e.g. all unnecessary fields are removed. Pass `--no-optimize` or `--optimize=false` to disabled optimizations.
- `merge-translations [po-files-dir-path] [template-path]` merge updated .pot file with .po. Done automatically by `export-strings` command. If `default-locale` is provided (e.g. `en`) and this locale's `.po` file exists in the same folder (e.g. `en.po`), this file will be populated with the translations automatically.
- `validate-strings [po-files-dir-path] [template-path]` validate all `.po` files inside `po-files-dir-path` (`./src/i18n/` by default) to have all the translations in the `.pot` file provided in `template-path` (`./src/i18n/template.pot` by default).

Expand Down
190 changes: 190 additions & 0 deletions __tests__/__snapshots__/importStrings.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,195 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`can optimize translations if boolean flag is passed 1`] = `
Object {
"en": Object {
"headers": Object {
"plural-forms": "nplurals=2; plural=(n != 1);",
},
"translations": Object {
"": Object {
"": Object {
"msgstr": Array [
"Content-Type: text/plain; charset=UTF-8
POT-Creation-Date: Thu Jan 01 2018 00:00:00
Content-Transfer-Encoding: 8bit
Plural-Forms: nplurals=2; plural=(n != 1);
Project-Id-Version:
PO-Revision-Date:
Language-Team:
MIME-Version: 1.0
X-Generator: Poedit 2.2.1
Last-Translator:
Language: en
",
],
},
},
"lion.females": Object {
"one female lion": Object {
"msgctxt": "lion.females",
"msgid_plural": "{{ count }} female lions",
"msgstr": Array [
"one female lion",
"{{ count }} female lions",
],
},
},
"lion.sound": Object {
"Rrrrr": Object {
"msgctxt": "lion.sound",
"msgstr": Array [
"Rrrr",
],
},
},
},
},
"fr": Object {
"headers": Object {
"plural-forms": "nplurals=2; plural=(n > 1);",
},
"translations": Object {
"": Object {
"": Object {
"msgstr": Array [
"Content-Type: text/plain; charset=UTF-8
POT-Creation-Date: Thu Jan 01 2018 00:00:00
Content-Transfer-Encoding: 8bit
Plural-Forms: nplurals=2; plural=(n > 1);
Project-Id-Version:
PO-Revision-Date:
Language-Team:
MIME-Version: 1.0
X-Generator: Poedit 2.2.1
Last-Translator:
Language: fr
",
],
},
},
"fake": Object {
"should be deleted": Object {
"msgctxt": "fake",
"msgid_plural": "Delete me {{ count }} times",
"msgstr": Array [
"Delete me",
"Delete me {{ count }} times",
],
},
},
"lion.females": Object {
"one female lion": Object {
"msgctxt": "lion.females",
"msgid_plural": "{{ count }} female lions",
"msgstr": Array [
"lionne",
"{{ count }} lionnes",
],
},
},
"lion.sound": Object {
"Rrrrr": Object {
"msgctxt": "lion.sound",
"msgstr": Array [
"Oooo",
],
},
},
},
},
"he": Object {
"headers": Object {
"plural-forms": "nplurals=4; plural=(n==1 ? 0 : n==2 ? 1 : n>10 && n%10==0 ? 2 : 3);",
},
"translations": Object {
"": Object {
"": Object {
"msgstr": Array [
"Content-Type: text/plain; charset=UTF-8
POT-Creation-Date: Thu Jan 01 2018 00:00:00
Content-Transfer-Encoding: 8bit
Plural-Forms: nplurals=4; plural=(n==1 ? 0 : n==2 ? 1 : n>10 && n%10==0 ? 2 : 3);
Project-Id-Version:
PO-Revision-Date:
Language-Team:
MIME-Version: 1.0
X-Generator: Poedit 2.2.1
Last-Translator:
Language: he
",
],
},
},
"lion.females": Object {
"one female lion": Object {
"msgctxt": "lion.females",
"msgid_plural": "{{ count }} female lions",
"msgstr": Array [
"לביאה",
"שתי לביאה",
"‫{{count}} לביאות",
"‏‫{{count}} לביא",
],
},
},
"lion.sound": Object {
"Rrrrr": Object {
"msgctxt": "lion.sound",
"msgstr": Array [
"רררר",
],
},
},
},
},
"ru": Object {
"headers": Object {
"plural-forms": "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);",
},
"translations": Object {
"": Object {
"": Object {
"msgstr": Array [
"Content-Type: text/plain; charset=UTF-8
POT-Creation-Date: Thu Jan 01 2018 00:00:00
Content-Transfer-Encoding: 8bit
Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);
Project-Id-Version:
PO-Revision-Date:
Language-Team:
MIME-Version: 1.0
X-Generator: Poedit 2.2.1
Last-Translator:
Language: ru
",
],
},
},
"lion.females": Object {
"one female lion": Object {
"msgctxt": "lion.females",
"msgid_plural": "{{ count }} female lions",
"msgstr": Array [
"одна львица",
"{{ сount }} львицы",
"{{ count }} львиц",
],
},
},
"lion.sound": Object {
"Rrrrr": Object {
"msgctxt": "lion.sound",
"msgstr": Array [
"Ррррр",
],
},
},
},
},
}
`;

exports[`should generate node-gettext .json files from .po files 1`] = `
Object {
"en": Object {
Expand Down
20 changes: 20 additions & 0 deletions __tests__/importStrings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,23 @@ it("should generate node-gettext .json files from .po files", async () => {
expect(file).toHaveProperty(localeToCheck);
}
});

it("can optimize translations if boolean flag is passed", async () => {
const tmpPath = await getTmpPath();
const filePath = path.join(tmpPath, "translations.json");
await importStrings("__fixtures__/po", filePath, true);

const file = JSON.parse(
fse.readFileSync(filePath, "utf-8"),
) as TranslationsMap;
expect(file).toMatchSnapshot();

const translation = file.en;
expect(translation).not.toHaveProperty("charset");
expect(Object.keys(translation.headers)).toHaveLength(1);
expect(translation.headers).toHaveProperty("plural-forms");

const message = translation.translations["lion.females"]["one female lion"];
expect(message).not.toHaveProperty("msgid");
expect(message).not.toHaveProperty("comments");
});
51 changes: 35 additions & 16 deletions definitions/gettext-parser.d.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,43 @@
interface Translation {
charset: Object;
headers: {
"plural-forms": string;
[key: string]: string;
interface TranslationMessage {
msgid?: string;
msgid_plural?: string;
msgctxt?: string;
msgstr?: string[];
comments?: {
reference: string;
};
}

interface TranslationHeaders {
"project-id-version"?: string;
"content-type"?: string;
"pot-creation-date"?: string;
"content-transfer-encoding"?: string;
"plural-forms"?: string;
"po-revision-date"?: string;
"language-team"?: string;
"mime-version"?: string;
"x-generator"?: string;
"last-translator"?: string;
language?: string;
}

interface TranslationContext {
[msgid: string]: TranslationMessage;
}

interface Translation {
charset?: string;
headers: TranslationHeaders;
translations: {
[key: string]: {
[key: string]: {
msgid: string;
msgid_plural?: string;
msgctxt?: string;
msgstr?: string[];
comments?: {
reference: string;
};
};
};
[msgctxt: string]: TranslationContext;
};
}

interface TranslationsMap {
[locale: string]: Translation;
}

declare module "gettext-parser" {
const def: {
po: {
Expand Down
4 changes: 3 additions & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@ yargs
({
poFilesPath,
outputFilePath,
optimize = true,
}: {
poFilesPath: string;
outputFilePath: string;
optimize?: boolean;
}) => {
return importStrings(poFilesPath, outputFilePath);
return importStrings(poFilesPath, outputFilePath, optimize);
},
)
.command(
Expand Down
Loading

0 comments on commit e2a3bb3

Please sign in to comment.