@ni/xliff-to-json-converter 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # XLIFF to JSON Converter for Angular
2
+
3
+ The `@ni/xliff-to-json-converter` library converts XLIFF translation files to Angular's JSON format so that they can be loaded at runtime in Angular apps.
4
+
5
+ # Usage
6
+
7
+ 1. Install in your Angular app's `devDependencies`:
8
+
9
+ ```
10
+ npm install -D @ni/xliff-to-json-converter
11
+ ```
12
+
13
+ 2. Add scripts to your app's `package.json` to convert translated XLIFF files to JSON.
14
+
15
+ ```json
16
+ "scripts": {
17
+ "i18n:convert": "npm run i18n:convert:de && npm run i18n:convert:ja && npm run i18n:convert:zh",
18
+ "i18n:convert:de": "xliff-to-json-converter --source src/locales/messages.de.xlf --destination src/locales/messages.de.json",
19
+ "i18n:convert:ja": "xliff-to-json-converter --source src/locales/messages.ja.xlf --destination src/locales/messages.ja.json",
20
+ "i18n:convert:zh": "xliff-to-json-converter --source src/locales/messages.zh.xlf --destination src/locales/messages.zh.json",
21
+ },
22
+ ```
23
+
24
+ 3. Ensure those converted files are generated at build time and not checked in to source.
25
+
26
+ # Context
27
+
28
+ NI employees can see more info about our [recommended Angular localization toolchain in the NI internal wiki](https://dev.azure.com/ni/DevCentral/_wiki/wikis/AppCentral.wiki/6636/Internationalization-(Angular)).
29
+
30
+ # Contributing
31
+
32
+ See [CONTRIBUTING.md](/packages/xliff-to-json-converter/CONTRIBUTING.md) for instructions to make changes to the library.
33
+
34
+ # Acknowledgements
35
+
36
+ This library is forked from [talque/xliff-to-angular-json](https://github.com/talque/xliff-to-angular-json) with additions including auto-testing, linting, and some small functionality changes. Thanks to its main contributor [vbraun](https://github.com/vbraun) for the starting point!
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const yargs_1 = __importDefault(require("yargs"));
8
+ const helpers_1 = require("yargs/helpers");
9
+ const convert_1 = require("./convert");
10
+ // This is how yargs expects to be run at the entry point of a cli application
11
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions, @typescript-eslint/no-floating-promises
12
+ yargs_1.default(helpers_1.hideBin(process.argv))
13
+ .strict()
14
+ .scriptName('xliff-to-json-converter')
15
+ .usage('$0 --source <src.xlf> --destination <dst.json>')
16
+ .command('$0', 'Convert source xliff file to angular simple json format', yargsObj => yargsObj
17
+ .option('source', {
18
+ alias: 's',
19
+ type: 'string',
20
+ describe: 'Source xliff file',
21
+ demandOption: true
22
+ })
23
+ .option('destination', {
24
+ alias: 'd',
25
+ type: 'string',
26
+ describe: 'Destination json file',
27
+ demandOption: true
28
+ }), async (argv) => {
29
+ const { source, destination } = argv;
30
+ console.log(`Converting ${source} -> ${destination}`);
31
+ await convert_1.convertXliff2Json(source, destination);
32
+ })
33
+ .help()
34
+ .argv;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeParsedTranslation = exports.xliff2Json = exports.convertXliff2Json = void 0;
4
+ const json_file_1 = require("./json-file");
5
+ const xliff_file_1 = require("./xliff-file");
6
+ async function convertXliff2Json(src, dst) {
7
+ const xliff = await xliff_file_1.loadXliff(src);
8
+ const json = xliff2Json(xliff);
9
+ json_file_1.saveJson(json, dst);
10
+ }
11
+ exports.convertXliff2Json = convertXliff2Json;
12
+ function xliff2Json(xliff) {
13
+ const translations = {};
14
+ const template = xliff.resources['ng2.template'];
15
+ Object.keys(template).forEach(key => {
16
+ const target = template[key].target;
17
+ const translation = xliffTranslation2jsonString(target);
18
+ if (translation !== '') {
19
+ translations[key] = translation;
20
+ }
21
+ });
22
+ const json = {
23
+ locale: xliff.targetLanguage,
24
+ translations
25
+ };
26
+ return json;
27
+ }
28
+ exports.xliff2Json = xliff2Json;
29
+ function xliffTranslation2jsonString(xliff) {
30
+ if (xliff === undefined) {
31
+ // translating the empty string (empty source is technically allowed, makes no sense)
32
+ return '';
33
+ }
34
+ if (typeof xliff === 'string') {
35
+ // translation is plain string without interpolation
36
+ return xliff;
37
+ }
38
+ if (!(xliff instanceof Array)) {
39
+ // translation just interpolation (makes no linguistical sense, but technically possible)
40
+ return makeParsedTranslation(['', ''], [xliff.Standalone.id]);
41
+ }
42
+ // makeParsedTranslation expects messagePart0, placeholderName0,
43
+ // messagePart1, placeholderName1, ..., messagePartN. May have to
44
+ // add empty messagePart at front or back.
45
+ const messageParts = [];
46
+ const placeholderNames = [];
47
+ for (const part of xliff) {
48
+ if (typeof part === 'string') {
49
+ messageParts.push(part);
50
+ }
51
+ else {
52
+ // part is placeholder object
53
+ if (messageParts.length === placeholderNames.length) {
54
+ messageParts.push('');
55
+ }
56
+ placeholderNames.push(part.Standalone.id);
57
+ }
58
+ }
59
+ if (messageParts.length === placeholderNames.length) {
60
+ messageParts.push('');
61
+ }
62
+ return makeParsedTranslation(messageParts, placeholderNames);
63
+ }
64
+ /**
65
+ * Create a `ParsedTranslation` from a set of `messageParts` and `placeholderNames`.
66
+ *
67
+ * Adapted from the function in @angular/localize of the same name
68
+ */
69
+ function makeParsedTranslation(messageParts, placeholderNames) {
70
+ if (messageParts.length !== placeholderNames.length + 1) {
71
+ throw new Error('translation part length mismatch');
72
+ }
73
+ let messageString = messageParts[0];
74
+ for (let i = 0; i < placeholderNames.length; i++) {
75
+ messageString += `{$${placeholderNames[i]}}${messageParts[i + 1]}`;
76
+ }
77
+ return messageString;
78
+ }
79
+ exports.makeParsedTranslation = makeParsedTranslation;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.saveJson = exports.stringify = void 0;
4
+ const fs_1 = require("fs");
5
+ function stringify(json) {
6
+ const content = JSON.stringify(json, undefined, 4);
7
+ return content;
8
+ }
9
+ exports.stringify = stringify;
10
+ function saveJson(json, dst) {
11
+ const content = stringify(json);
12
+ fs_1.writeFileSync(dst, content);
13
+ }
14
+ exports.saveJson = saveJson;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseXliff = exports.loadXliff = void 0;
4
+ const fs_1 = require("fs");
5
+ const xliff_1 = require("xliff");
6
+ async function loadXliff(path) {
7
+ const xliff = fs_1.readFileSync(path);
8
+ return parseXliff(xliff.toString());
9
+ }
10
+ exports.loadXliff = loadXliff;
11
+ async function parseXliff(contents) {
12
+ return xliff_1.xliff12ToJs(contents);
13
+ }
14
+ exports.parseXliff = parseXliff;
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@ni/xliff-to-json-converter",
3
+ "version": "1.0.0",
4
+ "description": "A utility to convert translation files from XLIFF to JSON for Angular localization",
5
+ "main": "dist/commonjs/cli.js",
6
+ "bin": {
7
+ "xliff-to-json-converter": "./dist/commonjs/cli.js"
8
+ },
9
+ "scripts": {
10
+ "build": "npm run compile",
11
+ "compile": "tsc -p tsconfig.json",
12
+ "compile-watch": "tsc -p tsconfig.json -w",
13
+ "lint": "eslint .",
14
+ "format": "eslint . --fix",
15
+ "pack": "npm pack",
16
+ "invoke-publish": "npm publish",
17
+ "tdd": "npm run build && npm run test",
18
+ "test": "jasmine"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/ni/nimble.git",
23
+ "directory": "packages/xliff-to-json-converter"
24
+ },
25
+ "author": "National Instruments",
26
+ "license": "UNLICENSED",
27
+ "devDependencies": {
28
+ "@ni/eslint-config-javascript": "^3.1.0",
29
+ "@ni/eslint-config-typescript": "^3.0.5",
30
+ "@types/jasmine": "^4.0.2",
31
+ "@types/yargs": "^17.0.10",
32
+ "jasmine": "^4.2.0",
33
+ "jasmine-core": "^4.1.0",
34
+ "typescript": "^4.3.2"
35
+ },
36
+ "dependencies": {
37
+ "xliff": "^6.0.3",
38
+ "yargs": "^17.5.1"
39
+ }
40
+ }