@lingui/cli 4.0.0-next.5 → 4.0.0-next.6
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/dist/api/catalog/extractFromFiles.d.ts +5 -0
- package/dist/api/catalog/extractFromFiles.js +27 -44
- package/dist/api/catalog/getCatalogs.d.ts +14 -0
- package/dist/api/catalog/getCatalogs.js +70 -78
- package/dist/api/catalog/getTranslationsForCatalog.d.ts +14 -0
- package/dist/api/catalog/getTranslationsForCatalog.js +36 -32
- package/dist/api/catalog/mergeCatalog.d.ts +3 -0
- package/dist/api/catalog/mergeCatalog.js +43 -74
- package/dist/api/catalog.d.ts +66 -0
- package/dist/api/catalog.js +144 -169
- package/dist/api/compile.d.ts +19 -0
- package/dist/api/compile.js +60 -87
- package/dist/api/extractors/babel.d.ts +3 -0
- package/dist/api/extractors/babel.js +43 -100
- package/dist/api/extractors/index.d.ts +6 -0
- package/dist/api/extractors/index.js +17 -23
- package/dist/api/extractors/typescript.d.ts +3 -0
- package/dist/api/extractors/typescript.js +7 -11
- package/dist/api/formats/formatterWrapper.d.ts +10 -0
- package/dist/api/formats/formatterWrapper.js +14 -19
- package/dist/api/formats/index.d.ts +5 -0
- package/dist/api/formats/index.js +15 -63
- package/dist/api/help.d.ts +1 -0
- package/dist/api/help.js +12 -13
- package/dist/api/index.d.ts +4 -0
- package/dist/api/index.js +24 -30
- package/dist/api/pseudoLocalize.d.ts +1 -0
- package/dist/api/pseudoLocalize.js +23 -27
- package/dist/api/rethrownError.d.ts +4 -0
- package/dist/api/rethrownError.js +4 -9
- package/dist/api/stats.d.ts +6 -0
- package/dist/api/stats.js +23 -55
- package/dist/api/types.d.ts +5 -0
- package/dist/api/types.js +1 -3
- package/dist/api/utils.d.ts +22 -0
- package/dist/api/utils.js +61 -59
- package/dist/extract-experimental/buildExternalizeFilter.d.ts +13 -0
- package/dist/extract-experimental/buildExternalizeFilter.js +19 -64
- package/dist/extract-experimental/bundleSource.d.ts +2 -0
- package/dist/extract-experimental/bundleSource.js +25 -74
- package/dist/extract-experimental/constants.d.ts +2 -0
- package/dist/extract-experimental/constants.js +4 -15
- package/dist/extract-experimental/getEntryPoints.d.ts +1 -0
- package/dist/extract-experimental/getEntryPoints.js +8 -16
- package/dist/extract-experimental/getExperimentalCatalogs.d.ts +3 -0
- package/dist/extract-experimental/getExperimentalCatalogs.js +15 -19
- package/dist/extract-experimental/resolveCatalogPath.d.ts +2 -0
- package/dist/extract-experimental/resolveCatalogPath.js +13 -24
- package/dist/extract-experimental/resolveTemplatePath.d.ts +1 -0
- package/dist/extract-experimental/resolveTemplatePath.js +11 -14
- package/dist/extract-experimental/writeCatalogs.d.ts +21 -0
- package/dist/extract-experimental/writeCatalogs.js +23 -36
- package/dist/lingui-compile.d.ts +9 -0
- package/dist/lingui-compile.js +94 -82
- package/dist/lingui-extract-experimental.d.ts +10 -0
- package/dist/lingui-extract-experimental.js +58 -67
- package/dist/lingui-extract-template.d.ts +6 -0
- package/dist/lingui-extract-template.js +29 -35
- package/dist/lingui-extract.d.ts +11 -0
- package/dist/lingui-extract.js +81 -117
- package/dist/lingui.d.ts +2 -0
- package/dist/lingui.js +11 -6
- package/dist/services/translationIO.d.ts +3 -0
- package/dist/services/translationIO.js +92 -89
- package/package.json +23 -14
- package/dist/tests.js +0 -137
package/dist/lingui-extract.js
CHANGED
|
@@ -1,124 +1,91 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
Object.defineProperty(exports, "
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const _help = require("./api/help");
|
|
17
|
-
const _ora = /*#__PURE__*/ _interopRequireDefault(require("ora"));
|
|
18
|
-
const _utils = require("./api/utils");
|
|
19
|
-
function _interopRequireDefault(obj) {
|
|
20
|
-
return obj && obj.__esModule ? obj : {
|
|
21
|
-
default: obj
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
function _getRequireWildcardCache(nodeInterop) {
|
|
25
|
-
if (typeof WeakMap !== "function") return null;
|
|
26
|
-
var cacheBabelInterop = new WeakMap();
|
|
27
|
-
var cacheNodeInterop = new WeakMap();
|
|
28
|
-
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
29
|
-
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
30
|
-
})(nodeInterop);
|
|
31
|
-
}
|
|
32
|
-
function _interopRequireWildcard(obj, nodeInterop) {
|
|
33
|
-
if (!nodeInterop && obj && obj.__esModule) {
|
|
34
|
-
return obj;
|
|
35
|
-
}
|
|
36
|
-
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
37
|
-
return {
|
|
38
|
-
default: obj
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
var cache = _getRequireWildcardCache(nodeInterop);
|
|
42
|
-
if (cache && cache.has(obj)) {
|
|
43
|
-
return cache.get(obj);
|
|
44
|
-
}
|
|
45
|
-
var newObj = {};
|
|
46
|
-
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
47
|
-
for(var key in obj){
|
|
48
|
-
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
49
|
-
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
50
|
-
if (desc && (desc.get || desc.set)) {
|
|
51
|
-
Object.defineProperty(newObj, key, desc);
|
|
52
|
-
} else {
|
|
53
|
-
newObj[key] = obj[key];
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
newObj.default = obj;
|
|
58
|
-
if (cache) {
|
|
59
|
-
cache.set(obj, newObj);
|
|
60
|
-
}
|
|
61
|
-
return newObj;
|
|
62
|
-
}
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
7
|
+
const chokidar_1 = __importDefault(require("chokidar"));
|
|
8
|
+
const commander_1 = require("commander");
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const conf_1 = require("@lingui/conf");
|
|
11
|
+
const api_1 = require("./api");
|
|
12
|
+
const stats_1 = require("./api/stats");
|
|
13
|
+
const help_1 = require("./api/help");
|
|
14
|
+
const ora_1 = __importDefault(require("ora"));
|
|
15
|
+
const utils_1 = require("./api/utils");
|
|
63
16
|
async function command(config, options) {
|
|
64
17
|
options.verbose && console.log("Extracting messages from source files…");
|
|
65
|
-
const catalogs = await (0,
|
|
18
|
+
const catalogs = await (0, api_1.getCatalogs)(config);
|
|
66
19
|
const catalogStats = {};
|
|
67
20
|
let commandSuccess = true;
|
|
68
|
-
const spinner = (0,
|
|
69
|
-
for (let catalog of catalogs){
|
|
70
|
-
const result = await catalog.make({
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
});
|
|
74
|
-
catalogStats[(0, _utils.normalizeSlashes)(_path.default.relative(config.rootDir, catalog.path))] = result || {};
|
|
75
|
-
commandSuccess &&= Boolean(result);
|
|
21
|
+
const spinner = (0, ora_1.default)().start();
|
|
22
|
+
for (let catalog of catalogs) {
|
|
23
|
+
const result = await catalog.make(Object.assign(Object.assign({}, options), { orderBy: config.orderBy }));
|
|
24
|
+
catalogStats[(0, utils_1.normalizeSlashes)(path_1.default.relative(config.rootDir, catalog.path))] = result || {};
|
|
25
|
+
commandSuccess && (commandSuccess = Boolean(result));
|
|
76
26
|
}
|
|
77
27
|
if (commandSuccess) {
|
|
78
28
|
spinner.succeed();
|
|
79
|
-
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
80
31
|
spinner.fail();
|
|
81
32
|
}
|
|
82
|
-
Object.entries(catalogStats).forEach(([key, value])=>{
|
|
33
|
+
Object.entries(catalogStats).forEach(([key, value]) => {
|
|
83
34
|
console.log(`Catalog statistics for ${key}: `);
|
|
84
|
-
console.log((0,
|
|
35
|
+
console.log((0, stats_1.printStats)(config, value).toString());
|
|
85
36
|
console.log();
|
|
86
37
|
});
|
|
87
38
|
if (!options.watch) {
|
|
88
|
-
console.log(`(use "${
|
|
89
|
-
console.log(`(use "${
|
|
39
|
+
console.log(`(use "${chalk_1.default.yellow((0, help_1.helpRun)("extract"))}" to update catalogs with new messages)`);
|
|
40
|
+
console.log(`(use "${chalk_1.default.yellow((0, help_1.helpRun)("compile"))}" to compile catalogs for production)`);
|
|
90
41
|
}
|
|
91
42
|
// If service key is present in configuration, synchronize with cloud translation platform
|
|
92
|
-
if (typeof config.service === "object" &&
|
|
43
|
+
if (typeof config.service === "object" &&
|
|
44
|
+
config.service.name &&
|
|
45
|
+
config.service.name.length) {
|
|
93
46
|
const moduleName = config.service.name.charAt(0).toLowerCase() + config.service.name.slice(1);
|
|
94
|
-
await
|
|
47
|
+
await import(`./services/${moduleName}`)
|
|
48
|
+
.then((module) => module.default(config, options))
|
|
49
|
+
.catch((err) => console.error(`Can't load service module ${moduleName}`, err));
|
|
95
50
|
}
|
|
96
51
|
return commandSuccess;
|
|
97
52
|
}
|
|
53
|
+
exports.default = command;
|
|
98
54
|
if (require.main === module) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
55
|
+
commander_1.program
|
|
56
|
+
.option("--config <path>", "Path to the config file")
|
|
57
|
+
.option("--locale <locale>", "Only extract the specified locale")
|
|
58
|
+
.option("--overwrite", "Overwrite translations for source locale")
|
|
59
|
+
.option("--clean", "Remove obsolete translations")
|
|
60
|
+
.option("--debounce <delay>", "Debounces extraction for given amount of milliseconds")
|
|
61
|
+
.option("--verbose", "Verbose output")
|
|
62
|
+
.option("--convert-from <format>", "Convert from previous format of message catalogs")
|
|
63
|
+
.option("--watch", "Enables Watch Mode")
|
|
64
|
+
.parse(process.argv);
|
|
65
|
+
const options = commander_1.program.opts();
|
|
66
|
+
const config = (0, conf_1.getConfig)({
|
|
67
|
+
configPath: options.config,
|
|
103
68
|
});
|
|
104
69
|
let hasErrors = false;
|
|
105
70
|
const prevFormat = options.convertFrom;
|
|
106
71
|
if (prevFormat && config.format === prevFormat) {
|
|
107
72
|
hasErrors = true;
|
|
108
73
|
console.error("Trying to migrate message catalog to the same format");
|
|
109
|
-
console.error(`Set ${
|
|
74
|
+
console.error(`Set ${chalk_1.default.bold("new")} format in LinguiJS configuration\n` +
|
|
75
|
+
` and ${chalk_1.default.bold("previous")} format using --convert-from option.`);
|
|
110
76
|
console.log();
|
|
111
77
|
console.log(`Example: Convert from lingui format to minimal`);
|
|
112
|
-
console.log(
|
|
78
|
+
console.log(chalk_1.default.yellow((0, help_1.helpRun)(`extract --convert-from lingui`)));
|
|
113
79
|
process.exit(1);
|
|
114
80
|
}
|
|
115
81
|
if (options.locale && !config.locales.includes(options.locale)) {
|
|
116
82
|
hasErrors = true;
|
|
117
|
-
console.error(`Locale ${
|
|
83
|
+
console.error(`Locale ${chalk_1.default.bold(options.locale)} does not exist.`);
|
|
118
84
|
console.error();
|
|
119
85
|
}
|
|
120
|
-
if (hasErrors)
|
|
121
|
-
|
|
86
|
+
if (hasErrors)
|
|
87
|
+
process.exit(1);
|
|
88
|
+
const extract = (filePath) => {
|
|
122
89
|
return command(config, {
|
|
123
90
|
verbose: options.watch || options.verbose || false,
|
|
124
91
|
clean: options.watch ? false : options.clean || false,
|
|
@@ -126,67 +93,64 @@ if (require.main === module) {
|
|
|
126
93
|
locale: options.locale,
|
|
127
94
|
watch: options.watch || false,
|
|
128
95
|
files: (filePath === null || filePath === void 0 ? void 0 : filePath.length) ? filePath : undefined,
|
|
129
|
-
prevFormat
|
|
96
|
+
prevFormat,
|
|
130
97
|
});
|
|
131
98
|
};
|
|
132
99
|
const changedPaths = new Set();
|
|
133
100
|
let debounceTimer;
|
|
134
101
|
let previousExtract = Promise.resolve(true);
|
|
135
|
-
const dispatchExtract = (filePath)=>{
|
|
102
|
+
const dispatchExtract = (filePath) => {
|
|
136
103
|
// Skip debouncing if not enabled but still chain them so no racing issue
|
|
137
104
|
// on deleting the tmp folder.
|
|
138
105
|
if (!options.debounce) {
|
|
139
|
-
previousExtract = previousExtract.then(()=>extract(filePath));
|
|
106
|
+
previousExtract = previousExtract.then(() => extract(filePath));
|
|
140
107
|
return previousExtract;
|
|
141
108
|
}
|
|
142
|
-
filePath === null || filePath === void 0 ? void 0 : filePath.forEach((path)=>changedPaths.add(path));
|
|
109
|
+
filePath === null || filePath === void 0 ? void 0 : filePath.forEach((path) => changedPaths.add(path));
|
|
143
110
|
// CLear the previous timer if there is any, and schedule the next
|
|
144
111
|
debounceTimer && clearTimeout(debounceTimer);
|
|
145
|
-
debounceTimer = setTimeout(async ()=>{
|
|
146
|
-
const filePath = [
|
|
147
|
-
...changedPaths
|
|
148
|
-
];
|
|
112
|
+
debounceTimer = setTimeout(async () => {
|
|
113
|
+
const filePath = [...changedPaths];
|
|
149
114
|
changedPaths.clear();
|
|
150
115
|
await extract(filePath);
|
|
151
116
|
}, options.debounce);
|
|
152
117
|
};
|
|
153
118
|
// Check if Watch Mode is enabled
|
|
154
119
|
if (options.watch) {
|
|
155
|
-
console.info(
|
|
120
|
+
console.info(chalk_1.default.bold("Initializing Watch Mode..."));
|
|
156
121
|
(async function initWatch() {
|
|
157
|
-
const catalogs = await (0,
|
|
122
|
+
const catalogs = await (0, api_1.getCatalogs)(config);
|
|
158
123
|
let paths = [];
|
|
159
124
|
let ignored = [];
|
|
160
|
-
catalogs.forEach((catalog)=>{
|
|
125
|
+
catalogs.forEach((catalog) => {
|
|
161
126
|
paths.push(...catalog.include);
|
|
162
127
|
ignored.push(...catalog.exclude);
|
|
163
128
|
});
|
|
164
|
-
const watcher =
|
|
165
|
-
ignored: [
|
|
166
|
-
|
|
167
|
-
...ignored
|
|
168
|
-
],
|
|
169
|
-
persistent: true
|
|
129
|
+
const watcher = chokidar_1.default.watch(paths, {
|
|
130
|
+
ignored: ["/(^|[/\\])../", ...ignored],
|
|
131
|
+
persistent: true,
|
|
170
132
|
});
|
|
171
|
-
const onReady = ()=>{
|
|
172
|
-
console.info(
|
|
173
|
-
watcher
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
path
|
|
177
|
-
]));
|
|
133
|
+
const onReady = () => {
|
|
134
|
+
console.info(chalk_1.default.green.bold("Watcher is ready!"));
|
|
135
|
+
watcher
|
|
136
|
+
.on("add", (path) => dispatchExtract([path]))
|
|
137
|
+
.on("change", (path) => dispatchExtract([path]));
|
|
178
138
|
};
|
|
179
|
-
watcher.on("ready", ()=>onReady());
|
|
139
|
+
watcher.on("ready", () => onReady());
|
|
180
140
|
})();
|
|
181
|
-
}
|
|
141
|
+
}
|
|
142
|
+
else if (commander_1.program.args) {
|
|
182
143
|
// this behaviour occurs when we extract files by his name
|
|
183
144
|
// for ex: lingui extract src/app, this will extract only files included in src/app
|
|
184
|
-
extract(
|
|
185
|
-
if (!result)
|
|
145
|
+
extract(commander_1.program.args).then((result) => {
|
|
146
|
+
if (!result)
|
|
147
|
+
process.exit(1);
|
|
186
148
|
});
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
extract().then((result) => {
|
|
152
|
+
if (!result)
|
|
153
|
+
process.exit(1);
|
|
190
154
|
});
|
|
191
155
|
}
|
|
192
156
|
}
|
package/dist/lingui.d.ts
ADDED
package/dist/lingui.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const packageJson = JSON.parse((0, node_fs_1.readFileSync)("../package.json", "utf8"));
|
|
7
|
+
commander_1.program
|
|
8
|
+
.version(packageJson.version)
|
|
9
|
+
.command("extract [files...]", "Extracts messages from source files")
|
|
10
|
+
.command("extract-experimental", "Extracts messages from source files traversing dependency tree")
|
|
11
|
+
.command("extract-template", "Extracts messages from source files to a .pot template")
|
|
12
|
+
.command("compile", "Compile message catalogs")
|
|
13
|
+
.parse(process.argv);
|
|
@@ -1,55 +1,50 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
Object.defineProperty(exports,
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const pofile_1 = __importDefault(require("pofile"));
|
|
9
|
+
const https_1 = __importDefault(require("https"));
|
|
10
|
+
const glob_1 = __importDefault(require("glob"));
|
|
11
|
+
const date_fns_1 = require("date-fns");
|
|
12
|
+
const getCreateHeaders = (language) => ({
|
|
13
|
+
"POT-Creation-Date": (0, date_fns_1.format)(new Date(), "yyyy-MM-dd HH:mmxxxx"),
|
|
14
|
+
"MIME-Version": "1.0",
|
|
15
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
16
|
+
"Content-Transfer-Encoding": "8bit",
|
|
17
|
+
"X-Generator": "@lingui/cli",
|
|
18
|
+
Language: language,
|
|
9
19
|
});
|
|
10
|
-
const
|
|
11
|
-
const _path = require("path");
|
|
12
|
-
const _pofile = /*#__PURE__*/ _interopRequireDefault(require("pofile"));
|
|
13
|
-
const _https = /*#__PURE__*/ _interopRequireDefault(require("https"));
|
|
14
|
-
const _glob = /*#__PURE__*/ _interopRequireDefault(require("glob"));
|
|
15
|
-
const _dateFns = require("date-fns");
|
|
16
|
-
function _interopRequireDefault(obj) {
|
|
17
|
-
return obj && obj.__esModule ? obj : {
|
|
18
|
-
default: obj
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
const getCreateHeaders = (language)=>({
|
|
22
|
-
"POT-Creation-Date": (0, _dateFns.format)(new Date(), "yyyy-MM-dd HH:mmxxxx"),
|
|
23
|
-
"MIME-Version": "1.0",
|
|
24
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
25
|
-
"Content-Transfer-Encoding": "8bit",
|
|
26
|
-
"X-Generator": "@lingui/cli",
|
|
27
|
-
Language: language
|
|
28
|
-
});
|
|
29
|
-
const getTargetLocales = (config)=>{
|
|
20
|
+
const getTargetLocales = (config) => {
|
|
30
21
|
const sourceLocale = config.sourceLocale || "en";
|
|
31
22
|
const pseudoLocale = config.pseudoLocale || "pseudo";
|
|
32
|
-
return config.locales.filter((value)=>value != sourceLocale && value != pseudoLocale);
|
|
23
|
+
return config.locales.filter((value) => value != sourceLocale && value != pseudoLocale);
|
|
33
24
|
};
|
|
25
|
+
// Main sync method, call "Init" or "Sync" depending on the project context
|
|
34
26
|
function syncProcess(config, options) {
|
|
35
27
|
if (config.format != "po") {
|
|
36
28
|
console.error(`\n----------\nTranslation.io service is only compatible with the "po" format. Please update your Lingui configuration accordingly.\n----------`);
|
|
37
29
|
process.exit(1);
|
|
38
30
|
}
|
|
39
|
-
const successCallback = (project)=>{
|
|
31
|
+
const successCallback = (project) => {
|
|
40
32
|
console.log(`\n----------\nProject successfully synchronized. Please use this URL to translate: ${project.url}\n----------`);
|
|
41
33
|
};
|
|
42
|
-
const failCallback = (errors)=>{
|
|
34
|
+
const failCallback = (errors) => {
|
|
43
35
|
console.error(`\n----------\nSynchronization with Translation.io failed: ${errors.join(", ")}\n----------`);
|
|
44
36
|
};
|
|
45
|
-
init(config, options, successCallback, (errors)=>{
|
|
46
|
-
if (errors.length &&
|
|
37
|
+
init(config, options, successCallback, (errors) => {
|
|
38
|
+
if (errors.length &&
|
|
39
|
+
errors[0] === "This project has already been initialized.") {
|
|
47
40
|
sync(config, options, successCallback, failCallback);
|
|
48
|
-
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
49
43
|
failCallback(errors);
|
|
50
44
|
}
|
|
51
45
|
});
|
|
52
46
|
}
|
|
47
|
+
exports.default = syncProcess;
|
|
53
48
|
// Initialize project with source and existing translations (only first time!)
|
|
54
49
|
// Cf. https://translation.io/docs/create-library#initialization
|
|
55
50
|
function init(config, options, successCallback, failCallback) {
|
|
@@ -57,26 +52,30 @@ function init(config, options, successCallback, failCallback) {
|
|
|
57
52
|
const targetLocales = getTargetLocales(config);
|
|
58
53
|
const paths = poPathsPerLocale(config);
|
|
59
54
|
const segments = {};
|
|
60
|
-
targetLocales.forEach((targetLocale)=>{
|
|
55
|
+
targetLocales.forEach((targetLocale) => {
|
|
61
56
|
segments[targetLocale] = [];
|
|
62
57
|
});
|
|
63
58
|
// Create segments from source locale PO items
|
|
64
|
-
paths[sourceLocale].forEach((path)=>{
|
|
65
|
-
const raw =
|
|
66
|
-
const po =
|
|
67
|
-
po.items
|
|
68
|
-
|
|
59
|
+
paths[sourceLocale].forEach((path) => {
|
|
60
|
+
const raw = fs_1.default.readFileSync(path).toString();
|
|
61
|
+
const po = pofile_1.default.parse(raw);
|
|
62
|
+
po.items
|
|
63
|
+
.filter((item) => !item["obsolete"])
|
|
64
|
+
.forEach((item) => {
|
|
65
|
+
targetLocales.forEach((targetLocale) => {
|
|
69
66
|
const newSegment = createSegmentFromPoItem(item);
|
|
70
67
|
segments[targetLocale].push(newSegment);
|
|
71
68
|
});
|
|
72
69
|
});
|
|
73
70
|
});
|
|
74
71
|
// Add translations to segments from target locale PO items
|
|
75
|
-
targetLocales.forEach((targetLocale)=>{
|
|
76
|
-
paths[targetLocale].forEach((path)=>{
|
|
77
|
-
const raw =
|
|
78
|
-
const po =
|
|
79
|
-
po.items
|
|
72
|
+
targetLocales.forEach((targetLocale) => {
|
|
73
|
+
paths[targetLocale].forEach((path) => {
|
|
74
|
+
const raw = fs_1.default.readFileSync(path).toString();
|
|
75
|
+
const po = pofile_1.default.parse(raw);
|
|
76
|
+
po.items
|
|
77
|
+
.filter((item) => !item["obsolete"])
|
|
78
|
+
.forEach((item, index) => {
|
|
80
79
|
segments[targetLocale][index].target = item.msgstr[0];
|
|
81
80
|
});
|
|
82
81
|
});
|
|
@@ -86,16 +85,17 @@ function init(config, options, successCallback, failCallback) {
|
|
|
86
85
|
version: require("@lingui/core/package.json").version,
|
|
87
86
|
source_language: sourceLocale,
|
|
88
87
|
target_languages: targetLocales,
|
|
89
|
-
segments: segments
|
|
88
|
+
segments: segments,
|
|
90
89
|
};
|
|
91
|
-
postTio("init", request, config.service.apiKey, (response)=>{
|
|
90
|
+
postTio("init", request, config.service.apiKey, (response) => {
|
|
92
91
|
if (response.errors) {
|
|
93
92
|
failCallback(response.errors);
|
|
94
|
-
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
95
|
saveSegmentsToTargetPos(config, paths, response.segments);
|
|
96
96
|
successCallback(response.project);
|
|
97
97
|
}
|
|
98
|
-
}, (error)=>{
|
|
98
|
+
}, (error) => {
|
|
99
99
|
console.error(`\n----------\nSynchronization with Translation.io failed: ${error}\n----------`);
|
|
100
100
|
});
|
|
101
101
|
}
|
|
@@ -107,10 +107,12 @@ function sync(config, options, successCallback, failCallback) {
|
|
|
107
107
|
const paths = poPathsPerLocale(config);
|
|
108
108
|
const segments = [];
|
|
109
109
|
// Create segments with correct source
|
|
110
|
-
paths[sourceLocale].forEach((path)=>{
|
|
111
|
-
const raw =
|
|
112
|
-
const po =
|
|
113
|
-
po.items
|
|
110
|
+
paths[sourceLocale].forEach((path) => {
|
|
111
|
+
const raw = fs_1.default.readFileSync(path).toString();
|
|
112
|
+
const po = pofile_1.default.parse(raw);
|
|
113
|
+
po.items
|
|
114
|
+
.filter((item) => !item["obsolete"])
|
|
115
|
+
.forEach((item) => {
|
|
114
116
|
const newSegment = createSegmentFromPoItem(item);
|
|
115
117
|
segments.push(newSegment);
|
|
116
118
|
});
|
|
@@ -122,16 +124,17 @@ function sync(config, options, successCallback, failCallback) {
|
|
|
122
124
|
target_languages: targetLocales,
|
|
123
125
|
segments: segments,
|
|
124
126
|
// Sync and then remove unused segments (not present in the local application) from Translation.io
|
|
125
|
-
purge: Boolean(options.clean)
|
|
127
|
+
purge: Boolean(options.clean),
|
|
126
128
|
};
|
|
127
|
-
postTio("sync", request, config.service.apiKey, (response)=>{
|
|
129
|
+
postTio("sync", request, config.service.apiKey, (response) => {
|
|
128
130
|
if (response.errors) {
|
|
129
131
|
failCallback(response.errors);
|
|
130
|
-
}
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
131
134
|
saveSegmentsToTargetPos(config, paths, response.segments);
|
|
132
135
|
successCallback(response.project);
|
|
133
136
|
}
|
|
134
|
-
}, (error)=>{
|
|
137
|
+
}, (error) => {
|
|
135
138
|
console.error(`\n----------\nSynchronization with Translation.io failed: ${error}\n----------`);
|
|
136
139
|
});
|
|
137
140
|
}
|
|
@@ -142,7 +145,7 @@ function createSegmentFromPoItem(item) {
|
|
|
142
145
|
source: itemHasId ? item.msgstr[0] : item.msgid,
|
|
143
146
|
context: "",
|
|
144
147
|
references: [],
|
|
145
|
-
comment: ""
|
|
148
|
+
comment: "",
|
|
146
149
|
};
|
|
147
150
|
if (itemHasId) {
|
|
148
151
|
segment.context = item.msgid;
|
|
@@ -156,44 +159,45 @@ function createSegmentFromPoItem(item) {
|
|
|
156
159
|
return segment;
|
|
157
160
|
}
|
|
158
161
|
function createPoItemFromSegment(segment) {
|
|
159
|
-
const item = new
|
|
162
|
+
const item = new pofile_1.default.Item();
|
|
160
163
|
item.msgid = segment.context ? segment.context : segment.source;
|
|
161
|
-
item.msgstr = [
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
item.references = segment.references && segment.references.length ? segment.references : [];
|
|
164
|
+
item.msgstr = [segment.target];
|
|
165
|
+
item.references =
|
|
166
|
+
segment.references && segment.references.length ? segment.references : [];
|
|
165
167
|
item.extractedComments = segment.comment ? segment.comment.split(" | ") : [];
|
|
166
168
|
return item;
|
|
167
169
|
}
|
|
168
170
|
function saveSegmentsToTargetPos(config, paths, segmentsPerLocale) {
|
|
169
|
-
Object.keys(segmentsPerLocale).forEach((targetLocale)=>{
|
|
171
|
+
Object.keys(segmentsPerLocale).forEach((targetLocale) => {
|
|
170
172
|
// Remove existing target POs and JS for this target locale
|
|
171
|
-
paths[targetLocale].forEach((path)=>{
|
|
173
|
+
paths[targetLocale].forEach((path) => {
|
|
172
174
|
const jsPath = path.replace(/\.po?$/, "") + ".js";
|
|
173
|
-
const dirPath = (0,
|
|
175
|
+
const dirPath = (0, path_1.dirname)(path);
|
|
174
176
|
// Remove PO, JS and empty dir
|
|
175
|
-
if (
|
|
176
|
-
|
|
177
|
+
if (fs_1.default.existsSync(path)) {
|
|
178
|
+
fs_1.default.unlinkSync(path);
|
|
177
179
|
}
|
|
178
|
-
if (
|
|
179
|
-
|
|
180
|
+
if (fs_1.default.existsSync(jsPath)) {
|
|
181
|
+
fs_1.default.unlinkSync(jsPath);
|
|
180
182
|
}
|
|
181
|
-
if (
|
|
182
|
-
|
|
183
|
+
if (fs_1.default.existsSync(dirPath) && fs_1.default.readdirSync(dirPath).length === 0) {
|
|
184
|
+
fs_1.default.rmdirSync(dirPath);
|
|
183
185
|
}
|
|
184
186
|
});
|
|
185
187
|
// Find target path (ignoring {name})
|
|
186
|
-
const localePath = "".concat(config.catalogs[0].path
|
|
188
|
+
const localePath = "".concat(config.catalogs[0].path
|
|
189
|
+
.replace(/{locale}/g, targetLocale)
|
|
190
|
+
.replace(/{name}/g, ""), ".po");
|
|
187
191
|
const segments = segmentsPerLocale[targetLocale];
|
|
188
|
-
const po = new
|
|
192
|
+
const po = new pofile_1.default();
|
|
189
193
|
po.headers = getCreateHeaders(targetLocale);
|
|
190
194
|
const items = [];
|
|
191
|
-
segments.forEach((segment)=>{
|
|
195
|
+
segments.forEach((segment) => {
|
|
192
196
|
const item = createPoItemFromSegment(segment);
|
|
193
197
|
items.push(item);
|
|
194
198
|
});
|
|
195
199
|
// Sort items by messageId
|
|
196
|
-
po.items = items.sort((a, b)=>{
|
|
200
|
+
po.items = items.sort((a, b) => {
|
|
197
201
|
if (a.msgid < b.msgid) {
|
|
198
202
|
return -1;
|
|
199
203
|
}
|
|
@@ -203,10 +207,8 @@ function saveSegmentsToTargetPos(config, paths, segmentsPerLocale) {
|
|
|
203
207
|
return 0;
|
|
204
208
|
});
|
|
205
209
|
// Check that localePath directory exists and save PO file
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}).then(()=>{
|
|
209
|
-
po.save(localePath, (err)=>{
|
|
210
|
+
fs_1.default.promises.mkdir((0, path_1.dirname)(localePath), { recursive: true }).then(() => {
|
|
211
|
+
po.save(localePath, (err) => {
|
|
210
212
|
if (err) {
|
|
211
213
|
console.error("Error while saving target PO files:");
|
|
212
214
|
console.error(err);
|
|
@@ -218,14 +220,15 @@ function saveSegmentsToTargetPos(config, paths, segmentsPerLocale) {
|
|
|
218
220
|
}
|
|
219
221
|
function poPathsPerLocale(config) {
|
|
220
222
|
const paths = {};
|
|
221
|
-
config.locales.forEach((locale)=>{
|
|
223
|
+
config.locales.forEach((locale) => {
|
|
222
224
|
paths[locale] = [];
|
|
223
|
-
config.catalogs.forEach((catalog)=>{
|
|
225
|
+
config.catalogs.forEach((catalog) => {
|
|
224
226
|
const path = "".concat(catalog.path.replace(/{locale}/g, locale).replace(/{name}/g, "*"), ".po");
|
|
225
227
|
// If {name} is present (replaced by *), list all the existing POs
|
|
226
228
|
if (path.includes("*")) {
|
|
227
|
-
paths[locale] = paths[locale].concat(
|
|
228
|
-
}
|
|
229
|
+
paths[locale] = paths[locale].concat(glob_1.default.sync(path));
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
229
232
|
paths[locale].push(path);
|
|
230
233
|
}
|
|
231
234
|
});
|
|
@@ -239,21 +242,21 @@ function postTio(action, request, apiKey, successCallback, failCallback) {
|
|
|
239
242
|
path: `/api/v1/segments/${action}.json?api_key=${apiKey}`,
|
|
240
243
|
method: "POST",
|
|
241
244
|
headers: {
|
|
242
|
-
"Content-Type": "application/json"
|
|
243
|
-
}
|
|
245
|
+
"Content-Type": "application/json",
|
|
246
|
+
},
|
|
244
247
|
};
|
|
245
|
-
const req =
|
|
248
|
+
const req = https_1.default.request(options, (res) => {
|
|
246
249
|
res.setEncoding("utf8");
|
|
247
250
|
let body = "";
|
|
248
|
-
res.on("data", (chunk)=>{
|
|
251
|
+
res.on("data", (chunk) => {
|
|
249
252
|
body = body.concat(chunk);
|
|
250
253
|
});
|
|
251
|
-
res.on("end", ()=>{
|
|
254
|
+
res.on("end", () => {
|
|
252
255
|
const response = JSON.parse(body);
|
|
253
256
|
successCallback(response);
|
|
254
257
|
});
|
|
255
258
|
});
|
|
256
|
-
req.on("error", (e)=>{
|
|
259
|
+
req.on("error", (e) => {
|
|
257
260
|
failCallback(e);
|
|
258
261
|
});
|
|
259
262
|
req.write(jsonRequest);
|