Skip to content

Commit

Permalink
feat(@formatjs/cli): add lokalise, crowdin, lingohub, phrase formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
longlho committed Aug 2, 2020
1 parent cd36f27 commit ebada90
Show file tree
Hide file tree
Showing 12 changed files with 295 additions and 2 deletions.
31 changes: 31 additions & 0 deletions packages/cli/src/formatters/crowdin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {FormatFn, CompileFn} from '../..';

export type SmartlingJson = Record<
string,
{
message: string;
description?: string;
}
>;

export const format: FormatFn<SmartlingJson> = msgs => {
const results: SmartlingJson = {};
for (const [id, msg] of Object.entries(msgs)) {
results[id] = {
message: msg.defaultMessage!,
description: msg.description,
};
}
return results;
};

export const compile: CompileFn<SmartlingJson> = msgs => {
const results: Record<string, string> = {};
for (const [id, msg] of Object.entries(msgs)) {
if (id === 'smartling') {
continue;
}
results[id] = msg.message;
}
return results;
};
9 changes: 9 additions & 0 deletions packages/cli/src/formatters/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import * as defaultFormatter from './default';
import * as transifex from './transifex';
import * as smartling from './smartling';
import * as simple from './simple';
import * as lokalise from './lokalise';
import * as crowdin from './crowdin';

export function resolveBuiltinFormatter(format?: string) {
if (!format) {
Expand All @@ -11,6 +14,12 @@ export function resolveBuiltinFormatter(format?: string) {
return transifex;
case 'smartling':
return smartling;
case 'simple':
return simple;
case 'lokalise':
return lokalise;
case 'crowdin':
return crowdin;
}
try {
return require(format);
Expand Down
30 changes: 30 additions & 0 deletions packages/cli/src/formatters/lokalise.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {FormatFn, CompileFn} from '../..';

export type StructuredJson = Record<
string,
{
translation: string;
notes?: string;
context?: string;
limit?: string;
}
>;

export const format: FormatFn<StructuredJson> = msgs => {
const results: StructuredJson = {};
for (const [id, msg] of Object.entries(msgs)) {
results[id] = {
translation: msg.defaultMessage!,
notes: msg.description,
};
}
return results;
};

export const compile: CompileFn<StructuredJson> = msgs => {
const results: Record<string, string> = {};
for (const [id, msg] of Object.entries(msgs)) {
results[id] = msg.translation;
}
return results;
};
12 changes: 12 additions & 0 deletions packages/cli/src/formatters/simple.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {FormatFn, CompileFn} from '../..';

export type PhraseJson = Record<string, string>;

export const format: FormatFn<PhraseJson> = msgs => {
return Object.keys(msgs).reduce((all: PhraseJson, k) => {
all[k] = msgs[k].defaultMessage!;
return all;
}, {});
};

export const compile: CompileFn<PhraseJson> = msgs => msgs;
24 changes: 24 additions & 0 deletions packages/cli/tests/compile/__snapshots__/integration.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ Object {
}
`;
exports[`normal json with crowdin 1`] = `
Object {
"a1d12": "I have {count, plural, one{a dog} other{many dogs}}",
"a1dd2": "my name is {name}",
"ashd2": "a message",
}
`;
exports[`normal json with formatter 1`] = `
Object {
"a1d12": "I have {count, plural, one{a dog} other{many dogs}}",
Expand All @@ -94,6 +102,22 @@ Object {
}
`;
exports[`normal json with lokalise 1`] = `
Object {
"a1d12": "I have {count, plural, one{a dog} other{many dogs}}",
"a1dd2": "my name is {name}",
"ashd2": "a message",
}
`;
exports[`normal json with simple 1`] = `
Object {
"a1d12": "I have {count, plural, one{a dog} other{many dogs}}",
"a1dd2": "my name is {name}",
"ashd2": "a message",
}
`;
exports[`normal json with smartling 1`] = `
Object {
"a1d12": "I have {count, plural, one{a dog} other{many dogs}}",
Expand Down
33 changes: 33 additions & 0 deletions packages/cli/tests/compile/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,39 @@ test('normal json with smartling', async () => {
expect(stderr).toBe('');
}, 20000);

test('normal json with simple', async () => {
const {stdout, stderr} = await exec(
`${BIN_PATH} compile ${join(
__dirname,
'lang/en-simple.json'
)} --format simple`
);
expect(JSON.parse(stdout)).toMatchSnapshot();
expect(stderr).toBe('');
}, 20000);

test('normal json with lokalise', async () => {
const {stdout, stderr} = await exec(
`${BIN_PATH} compile ${join(
__dirname,
'lang/en-lokalise.json'
)} --format lokalise`
);
expect(JSON.parse(stdout)).toMatchSnapshot();
expect(stderr).toBe('');
}, 20000);

test('normal json with crowdin', async () => {
const {stdout, stderr} = await exec(
`${BIN_PATH} compile ${join(
__dirname,
'lang/en-crowdin.json'
)} --format crowdin`
);
expect(JSON.parse(stdout)).toMatchSnapshot();
expect(stderr).toBe('');
}, 20000);

test('malformed ICU message json', async () => {
expect(async () => {
await exec(
Expand Down
14 changes: 14 additions & 0 deletions packages/cli/tests/compile/lang/en-crowdin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"ashd2": {
"message": "a message",
"description": "foo"
},
"a1dd2": {
"message": "my name is {name}",
"description": "foo"
},
"a1d12": {
"message": "I have {count, plural, one{a dog} other{many dogs}}",
"description": "foo"
}
}
14 changes: 14 additions & 0 deletions packages/cli/tests/compile/lang/en-lokalise.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"ashd2": {
"translation": "a message",
"notes": "foo"
},
"a1dd2": {
"translation": "my name is {name}",
"notes": "foo"
},
"a1d12": {
"translation": "I have {count, plural, one{a dog} other{many dogs}}",
"notes": "foo"
}
}
5 changes: 5 additions & 0 deletions packages/cli/tests/compile/lang/en-simple.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"ashd2": "a message",
"a1dd2": "my name is {name}",
"a1d12": "I have {count, plural, one{a dog} other{many dogs}}"
}
85 changes: 85 additions & 0 deletions packages/cli/tests/extract/__snapshots__/integration.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,42 @@ Object {
}
`;
exports[`typescript -> stdout with crowdin 1`] = `
Object {
"ae494": Object {
"description": "no ID",
"message": "No ID",
},
"app.home.kittens": Object {
"description": "Counts kittens",
"message": "{count, plural, =0 {😭} one {# kitten} other {# kittens}}",
},
"c63ed": Object {
"message": "No Desc",
},
"escaped.apostrophe": Object {
"description": "Escaped apostrophe",
"message": "A quoted value ''{value}'",
},
"foo.bar.baz": Object {
"description": "The default message",
"message": "Hello World!",
},
"foo.bar.biff": Object {
"description": "Another message",
"message": "Hello Nurse!",
},
"inline": Object {
"description": "foo",
"message": "formatted message",
},
"trailing.ws": Object {
"description": "Whitespace",
"message": " Some whitespace ",
},
}
`;
exports[`typescript -> stdout with formatter 1`] = `
Object {
"ae494": Object {
Expand Down Expand Up @@ -363,6 +399,55 @@ Object {
}
`;
exports[`typescript -> stdout with lokalise 1`] = `
Object {
"ae494": Object {
"notes": "no ID",
"translation": "No ID",
},
"app.home.kittens": Object {
"notes": "Counts kittens",
"translation": "{count, plural, =0 {😭} one {# kitten} other {# kittens}}",
},
"c63ed": Object {
"translation": "No Desc",
},
"escaped.apostrophe": Object {
"notes": "Escaped apostrophe",
"translation": "A quoted value ''{value}'",
},
"foo.bar.baz": Object {
"notes": "The default message",
"translation": "Hello World!",
},
"foo.bar.biff": Object {
"notes": "Another message",
"translation": "Hello Nurse!",
},
"inline": Object {
"notes": "foo",
"translation": "formatted message",
},
"trailing.ws": Object {
"notes": "Whitespace",
"translation": " Some whitespace ",
},
}
`;
exports[`typescript -> stdout with simple 1`] = `
Object {
"ae494": "No ID",
"app.home.kittens": "{count, plural, =0 {😭} one {# kitten} other {# kittens}}",
"c63ed": "No Desc",
"escaped.apostrophe": "A quoted value ''{value}'",
"foo.bar.baz": "Hello World!",
"foo.bar.biff": "Hello Nurse!",
"inline": "formatted message",
"trailing.ws": " Some whitespace ",
}
`;
exports[`typescript -> stdout with smartling 1`] = `
"{
\\"smartling\\": {
Expand Down
33 changes: 33 additions & 0 deletions packages/cli/tests/extract/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,39 @@ test('typescript -> stdout with transifex', async () => {
expect(stderr).toBe('');
}, 20000);

test('typescript -> stdout with simple', async () => {
const {stdout, stderr} = await exec(
`${BIN_PATH} extract ${join(
__dirname,
'typescript/actual.tsx'
)} --format simple`
);
expect(JSON.parse(stdout)).toMatchSnapshot();
expect(stderr).toBe('');
}, 20000);

test('typescript -> stdout with lokalise', async () => {
const {stdout, stderr} = await exec(
`${BIN_PATH} extract ${join(
__dirname,
'typescript/actual.tsx'
)} --format lokalise`
);
expect(JSON.parse(stdout)).toMatchSnapshot();
expect(stderr).toBe('');
}, 20000);

test('typescript -> stdout with crowdin', async () => {
const {stdout, stderr} = await exec(
`${BIN_PATH} extract ${join(
__dirname,
'typescript/actual.tsx'
)} --format crowdin`
);
expect(JSON.parse(stdout)).toMatchSnapshot();
expect(stderr).toBe('');
}, 20000);

test('typescript -> stdout with smartling', async () => {
const {stdout, stderr} = await exec(
`${BIN_PATH} extract ${join(
Expand Down
7 changes: 5 additions & 2 deletions website/docs/tooling/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,11 @@ Whether to compile message into AST instead of just string. See [Advanced Usage]

We provide the following built-in formatters to integrate with 3rd party TMSes:

- `--format transifex`: https://docs.transifex.com/formats/json/structured-json
- `--format smartling`: https://help.smartling.com/hc/en-us/articles/360008000733-JSON
- `--format transifex`: [Transifex's Structured JSON](https://docs.transifex.com/formats/json/structured-json)
- `--format smartling`: [Smartling ICU JSON](https://help.smartling.com/hc/en-us/articles/360008000733-JSON)
- `--format simple`: Simple key-value JSON, used by [Lingohub](https://lingohub.com/developers/resource-files/json-localization/) and [Phrase](https://help.phrase.com/help/simple-json)
- `--format crowdin`: [Crowdin Chrome JSON](https://support.crowdin.com/file-formats/chrome-json/)
- `--format lokalise`: [Lokalise Structured JSON](https://docs.lokalise.com/en/articles/3229161-structured-json)

## Custom Formatters

Expand Down

0 comments on commit ebada90

Please sign in to comment.