@lingui/cli 5.9.3 → 6.0.0-next.1
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/ProgramExit.js +1 -5
- package/dist/api/catalog/extractFromFiles.d.ts +4 -4
- package/dist/api/catalog/extractFromFiles.js +38 -32
- package/dist/api/catalog/getCatalogDependentFiles.d.ts +1 -1
- package/dist/api/catalog/getCatalogDependentFiles.js +8 -47
- package/dist/api/catalog/getCatalogs.d.ts +2 -2
- package/dist/api/catalog/getCatalogs.js +35 -44
- package/dist/api/catalog/getFallbackListForLocale.js +5 -8
- package/dist/api/catalog/getTranslationsForCatalog.d.ts +1 -1
- package/dist/api/catalog/getTranslationsForCatalog.js +9 -13
- package/dist/api/catalog/mergeCatalog.d.ts +3 -3
- package/dist/api/catalog/mergeCatalog.js +13 -21
- package/dist/api/catalog.d.ts +15 -15
- package/dist/api/catalog.js +48 -45
- package/dist/api/compile/compileLocale.d.ts +3 -3
- package/dist/api/compile/compileLocale.js +28 -33
- package/dist/api/compile.js +13 -49
- package/dist/api/extractors/babel.d.ts +20 -4
- package/dist/api/extractors/babel.js +66 -56
- package/dist/api/extractors/index.js +16 -13
- package/dist/api/formats/formatterWrapper.d.ts +2 -2
- package/dist/api/formats/formatterWrapper.js +10 -12
- package/dist/api/formats/index.d.ts +3 -4
- package/dist/api/formats/index.js +5 -44
- package/dist/api/getPathsForCompileWatcher.d.ts +7 -0
- package/dist/api/getPathsForCompileWatcher.js +15 -0
- package/dist/api/getPathsForExtractWatcher.d.ts +8 -0
- package/dist/api/getPathsForExtractWatcher.js +14 -0
- package/dist/api/help.js +5 -7
- package/dist/api/index.d.ts +7 -7
- package/dist/api/index.js +7 -36
- package/dist/api/logger.d.ts +1 -1
- package/dist/api/logger.js +1 -2
- package/dist/api/messages.d.ts +2 -2
- package/dist/api/messages.js +5 -12
- package/dist/api/pseudoLocalize.js +3 -9
- package/dist/api/resolveWorkersOptions.js +3 -9
- package/dist/api/rethrownError.js +2 -5
- package/dist/api/stats.d.ts +3 -2
- package/dist/api/stats.js +7 -16
- package/dist/api/typedPool.d.ts +6 -0
- package/dist/api/typedPool.js +16 -0
- package/dist/api/types.js +1 -2
- package/dist/api/utils.d.ts +2 -2
- package/dist/api/utils.js +24 -41
- package/dist/api/workerLogger.d.ts +2 -2
- package/dist/api/workerLogger.js +2 -8
- package/dist/api/workerPools.d.ts +3 -0
- package/dist/api/workerPools.js +7 -0
- package/dist/extract-experimental/buildIncludeDepsFilter.js +1 -4
- package/dist/extract-experimental/bundleSource.d.ts +3 -2
- package/dist/extract-experimental/bundleSource.js +10 -13
- package/dist/extract-experimental/constants.js +2 -5
- package/dist/extract-experimental/extractFromBundleAndWrite.d.ts +3 -4
- package/dist/extract-experimental/extractFromBundleAndWrite.js +9 -22
- package/dist/extract-experimental/getExperimentalCatalogs.d.ts +4 -3
- package/dist/extract-experimental/getExperimentalCatalogs.js +10 -15
- package/dist/extract-experimental/linguiEsbuildPlugin.js +12 -19
- package/dist/extract-experimental/resolveCatalogPath.d.ts +1 -1
- package/dist/extract-experimental/resolveCatalogPath.js +7 -14
- package/dist/extract-experimental/resolveTemplatePath.js +7 -10
- package/dist/extract-experimental/workers/extractWorker.d.ts +5 -3
- package/dist/extract-experimental/workers/extractWorker.js +7 -10
- package/dist/extract-experimental/workers/extractWorkerWrapper.prod.d.ts +8 -0
- package/dist/extract-experimental/workers/extractWorkerWrapper.prod.js +2 -0
- package/dist/extract-experimental/writeCatalogs.d.ts +2 -2
- package/dist/extract-experimental/writeCatalogs.js +15 -22
- package/dist/index.js +1 -5
- package/dist/lingui-compile.d.ts +1 -1
- package/dist/lingui-compile.js +45 -59
- package/dist/lingui-extract-experimental.d.ts +3 -2
- package/dist/lingui-extract-experimental.js +58 -62
- package/dist/lingui-extract-template.d.ts +5 -4
- package/dist/lingui-extract-template.js +25 -27
- package/dist/lingui-extract.d.ts +3 -4
- package/dist/lingui-extract.js +62 -69
- package/dist/lingui.js +5 -10
- package/dist/services/translationIO/segment-converters.d.ts +1 -1
- package/dist/services/translationIO/segment-converters.js +16 -20
- package/dist/services/translationIO/translationio-api.d.ts +11 -7
- package/dist/services/translationIO/translationio-api.js +2 -19
- package/dist/services/translationIO.d.ts +4 -4
- package/dist/services/translationIO.js +28 -35
- package/dist/workers/compileWorker.d.ts +8 -11
- package/dist/workers/compileWorker.js +30 -36
- package/dist/workers/compileWorkerWrapper.prod.d.ts +7 -0
- package/dist/workers/compileWorkerWrapper.prod.js +2 -0
- package/dist/workers/extractWorker.d.ts +2 -3
- package/dist/workers/extractWorker.js +5 -12
- package/dist/workers/extractWorkerWrapper.prod.d.ts +6 -0
- package/dist/workers/extractWorkerWrapper.prod.js +2 -0
- package/package.json +26 -43
- package/dist/api/extractWorkerPool.d.ts +0 -1
- package/dist/api/extractWorkerPool.js +0 -8
- package/dist/api/extractors/typescript.d.ts +0 -3
- package/dist/api/extractors/typescript.js +0 -11
- package/dist/extract-experimental/getEntryPoints.d.ts +0 -1
- package/dist/extract-experimental/getEntryPoints.js +0 -7
package/dist/lingui-extract.js
CHANGED
|
@@ -1,54 +1,55 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const extractWorkerPool_1 = require("./api/extractWorkerPool");
|
|
19
|
-
const ms_1 = __importDefault(require("ms"));
|
|
20
|
-
async function command(config, options) {
|
|
1
|
+
import { styleText } from "node:util";
|
|
2
|
+
import chokidar from "chokidar";
|
|
3
|
+
import { program } from "commander";
|
|
4
|
+
import nodepath from "path";
|
|
5
|
+
import { getConfig } from "@lingui/conf";
|
|
6
|
+
import { getCatalogs } from "./api/index.js";
|
|
7
|
+
import { printStats } from "./api/stats.js";
|
|
8
|
+
import { helpRun } from "./api/help.js";
|
|
9
|
+
import ora from "ora";
|
|
10
|
+
import normalizePath from "normalize-path";
|
|
11
|
+
import { resolveWorkersOptions, } from "./api/resolveWorkersOptions.js";
|
|
12
|
+
import { createExtractWorkerPool, } from "./api/workerPools.js";
|
|
13
|
+
import ms from "ms";
|
|
14
|
+
import { getPathsForExtractWatcher } from "./api/getPathsForExtractWatcher.js";
|
|
15
|
+
import { glob } from "node:fs/promises";
|
|
16
|
+
import micromatch from "micromatch";
|
|
17
|
+
export default async function command(config, options) {
|
|
21
18
|
const startTime = Date.now();
|
|
22
19
|
options.verbose && console.log("Extracting messages from source files…");
|
|
23
|
-
const catalogs = await
|
|
20
|
+
const catalogs = await getCatalogs(config);
|
|
24
21
|
const catalogStats = {};
|
|
25
22
|
let commandSuccess = true;
|
|
26
23
|
let workerPool;
|
|
27
24
|
// important to initialize ora before worker pool, otherwise it cause
|
|
28
25
|
// MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 unpipe listeners added to [WriteStream]. MaxListeners is 10. Use emitter.setMaxListeners() to increase limit
|
|
29
26
|
// when workers >= 10
|
|
30
|
-
const spinner = (
|
|
27
|
+
const spinner = ora();
|
|
31
28
|
if (options.workersOptions.poolSize) {
|
|
32
29
|
options.verbose &&
|
|
33
30
|
console.log(`Use worker pool of size ${options.workersOptions.poolSize}`);
|
|
34
|
-
workerPool =
|
|
31
|
+
workerPool = createExtractWorkerPool(options.workersOptions);
|
|
35
32
|
}
|
|
36
33
|
spinner.start();
|
|
37
34
|
let extractionResult;
|
|
38
35
|
try {
|
|
39
36
|
extractionResult = await Promise.all(catalogs.map(async (catalog) => {
|
|
40
|
-
const result = await catalog.make(
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
const result = await catalog.make({
|
|
38
|
+
...options,
|
|
39
|
+
orderBy: config.orderBy,
|
|
40
|
+
workerPool,
|
|
41
|
+
});
|
|
42
|
+
catalogStats[normalizePath(nodepath.relative(config.rootDir, catalog.path))] = result || {};
|
|
43
|
+
commandSuccess &&= Boolean(result);
|
|
43
44
|
return { catalog, messagesByLocale: result };
|
|
44
45
|
}));
|
|
45
46
|
}
|
|
46
47
|
finally {
|
|
47
48
|
if (workerPool) {
|
|
48
|
-
await workerPool.
|
|
49
|
+
await workerPool.destroy();
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
|
-
const doneMsg = `Done in ${(
|
|
52
|
+
const doneMsg = `Done in ${ms(Date.now() - startTime)}`;
|
|
52
53
|
if (commandSuccess) {
|
|
53
54
|
spinner.succeed(doneMsg);
|
|
54
55
|
}
|
|
@@ -57,20 +58,24 @@ async function command(config, options) {
|
|
|
57
58
|
}
|
|
58
59
|
Object.entries(catalogStats).forEach(([key, value]) => {
|
|
59
60
|
console.log(`Catalog statistics for ${key}: `);
|
|
60
|
-
console.log(
|
|
61
|
+
console.log(printStats(config, value).toString());
|
|
61
62
|
console.log();
|
|
62
63
|
});
|
|
63
64
|
if (!options.watch) {
|
|
64
|
-
console.log(`(Use "${
|
|
65
|
-
console.log(`(Use "${
|
|
65
|
+
console.log(`(Use "${styleText("yellow", helpRun("extract"))}" to update catalogs with new messages.)`);
|
|
66
|
+
console.log(`(Use "${styleText("yellow", helpRun("compile"))}" to compile catalogs for production. Alternatively, use bundler plugins: https://lingui.dev/ref/cli#compiling-catalogs-in-ci)`);
|
|
66
67
|
}
|
|
67
68
|
// If service key is present in configuration, synchronize with cloud translation platform
|
|
68
|
-
if (
|
|
69
|
-
config.service.name &&
|
|
70
|
-
config.service.name.length) {
|
|
69
|
+
if (config.service?.name?.length) {
|
|
71
70
|
const moduleName = config.service.name.charAt(0).toLowerCase() + config.service.name.slice(1);
|
|
71
|
+
const services = {
|
|
72
|
+
translationIO: () => import(`./services/translationIO.js`),
|
|
73
|
+
};
|
|
74
|
+
if (!services[moduleName]) {
|
|
75
|
+
console.error(`Can't load service module ${moduleName}`);
|
|
76
|
+
}
|
|
72
77
|
try {
|
|
73
|
-
const module =
|
|
78
|
+
const module = services[moduleName]();
|
|
74
79
|
await module
|
|
75
80
|
.default(config, options, extractionResult)
|
|
76
81
|
.then(console.log)
|
|
@@ -82,8 +87,8 @@ async function command(config, options) {
|
|
|
82
87
|
}
|
|
83
88
|
return commandSuccess;
|
|
84
89
|
}
|
|
85
|
-
if (
|
|
86
|
-
|
|
90
|
+
if (import.meta.main) {
|
|
91
|
+
program
|
|
87
92
|
.option("--config <path>", "Path to the config file")
|
|
88
93
|
.option("--locale <locale, [...]>", "Only extract the specified locales", (value) => {
|
|
89
94
|
return value
|
|
@@ -96,30 +101,18 @@ if (require.main === module) {
|
|
|
96
101
|
.option("--clean", "Remove obsolete translations")
|
|
97
102
|
.option("--debounce <delay>", "Debounces extraction for given amount of milliseconds")
|
|
98
103
|
.option("--verbose", "Verbose output")
|
|
99
|
-
.option("--convert-from <format>", "Convert from previous format of message catalogs")
|
|
100
104
|
.option("--watch", "Enables Watch Mode")
|
|
101
105
|
.parse(process.argv);
|
|
102
|
-
const options =
|
|
103
|
-
const config =
|
|
106
|
+
const options = program.opts();
|
|
107
|
+
const config = getConfig({
|
|
104
108
|
configPath: options.config,
|
|
105
109
|
});
|
|
106
110
|
let hasErrors = false;
|
|
107
|
-
const prevFormat = options.convertFrom;
|
|
108
|
-
if (prevFormat && config.format === prevFormat) {
|
|
109
|
-
hasErrors = true;
|
|
110
|
-
console.error("Trying to migrate message catalog to the same format");
|
|
111
|
-
console.error(`Set ${picocolors_1.default.bold("new")} format in LinguiJS configuration\n` +
|
|
112
|
-
` and ${picocolors_1.default.bold("previous")} format using --convert-from option.`);
|
|
113
|
-
console.log();
|
|
114
|
-
console.log(`Example: Convert from lingui format to minimal`);
|
|
115
|
-
console.log(picocolors_1.default.yellow((0, help_1.helpRun)(`extract --convert-from lingui`)));
|
|
116
|
-
process.exit(1);
|
|
117
|
-
}
|
|
118
111
|
if (options.locale) {
|
|
119
112
|
const missingLocale = options.locale.find((l) => !config.locales.includes(l));
|
|
120
113
|
if (missingLocale) {
|
|
121
114
|
hasErrors = true;
|
|
122
|
-
console.error(`Locale ${
|
|
115
|
+
console.error(`Locale ${styleText("bold", missingLocale)} does not exist.`);
|
|
123
116
|
console.error();
|
|
124
117
|
}
|
|
125
118
|
}
|
|
@@ -132,9 +125,8 @@ if (require.main === module) {
|
|
|
132
125
|
overwrite: options.watch || options.overwrite || false,
|
|
133
126
|
locale: options.locale,
|
|
134
127
|
watch: options.watch || false,
|
|
135
|
-
files:
|
|
136
|
-
|
|
137
|
-
workersOptions: (0, resolveWorkersOptions_1.resolveWorkersOptions)(options),
|
|
128
|
+
files: filePath?.length ? filePath : undefined,
|
|
129
|
+
workersOptions: resolveWorkersOptions(options),
|
|
138
130
|
});
|
|
139
131
|
};
|
|
140
132
|
const changedPaths = new Set();
|
|
@@ -147,7 +139,7 @@ if (require.main === module) {
|
|
|
147
139
|
previousExtract = previousExtract.then(() => extract(filePath));
|
|
148
140
|
return previousExtract;
|
|
149
141
|
}
|
|
150
|
-
filePath
|
|
142
|
+
filePath?.forEach((path) => changedPaths.add(path));
|
|
151
143
|
// CLear the previous timer if there is any, and schedule the next
|
|
152
144
|
debounceTimer && clearTimeout(debounceTimer);
|
|
153
145
|
debounceTimer = setTimeout(async () => {
|
|
@@ -158,21 +150,22 @@ if (require.main === module) {
|
|
|
158
150
|
};
|
|
159
151
|
// Check if Watch Mode is enabled
|
|
160
152
|
if (options.watch) {
|
|
161
|
-
console.info(
|
|
153
|
+
console.info(styleText("bold", "Initializing Watch Mode..."));
|
|
162
154
|
(async function initWatch() {
|
|
163
|
-
const
|
|
164
|
-
const
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
155
|
+
const { paths, ignored } = await getPathsForExtractWatcher(config);
|
|
156
|
+
const matchedPaths = [];
|
|
157
|
+
for await (const path of glob(paths)) {
|
|
158
|
+
matchedPaths.push(path);
|
|
159
|
+
}
|
|
160
|
+
const watcher = chokidar.watch(matchedPaths, {
|
|
161
|
+
ignored: [
|
|
162
|
+
"/(^|[/\\])../",
|
|
163
|
+
(path) => micromatch.any(path, ignored),
|
|
164
|
+
],
|
|
172
165
|
persistent: true,
|
|
173
166
|
});
|
|
174
167
|
const onReady = () => {
|
|
175
|
-
console.info(
|
|
168
|
+
console.info(styleText(["green", "bold"], "Watcher is ready!"));
|
|
176
169
|
watcher
|
|
177
170
|
.on("add", (path) => dispatchExtract([path]))
|
|
178
171
|
.on("change", (path) => dispatchExtract([path]));
|
|
@@ -180,10 +173,10 @@ if (require.main === module) {
|
|
|
180
173
|
watcher.on("ready", () => onReady());
|
|
181
174
|
})();
|
|
182
175
|
}
|
|
183
|
-
else if (
|
|
176
|
+
else if (program.args) {
|
|
184
177
|
// this behaviour occurs when we extract files by his name
|
|
185
178
|
// for ex: lingui extract src/app, this will extract only files included in src/app
|
|
186
|
-
extract(
|
|
179
|
+
extract(program.args).then((result) => {
|
|
187
180
|
if (!result)
|
|
188
181
|
process.exit(1);
|
|
189
182
|
});
|
package/dist/lingui.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const commander_1 = require("commander");
|
|
8
|
-
const node_fs_1 = require("node:fs");
|
|
9
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
-
const packageJson = JSON.parse((0, node_fs_1.readFileSync)(node_path_1.default.resolve(__dirname, "../package.json"), "utf8"));
|
|
11
|
-
commander_1.program
|
|
2
|
+
import { program } from "commander";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
const packageJson = JSON.parse(readFileSync(path.resolve(import.meta.dirname, "../package.json"), "utf8"));
|
|
6
|
+
program
|
|
12
7
|
.version(packageJson.version)
|
|
13
8
|
.command("extract [files...]", "Extracts messages from source files")
|
|
14
9
|
.command("extract-experimental", "Extracts messages from source files traversing dependency tree")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { MessageType } from "@lingui/conf";
|
|
2
|
-
import { TranslationIoSegment } from "./translationio-api";
|
|
2
|
+
import { TranslationIoSegment } from "./translationio-api.js";
|
|
3
3
|
export declare function createSegmentFromLinguiItem(key: string, item: MessageType): TranslationIoSegment;
|
|
4
4
|
export declare function createLinguiItemFromSegment(segment: TranslationIoSegment): readonly [string, MessageType];
|
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createSegmentFromLinguiItem = createSegmentFromLinguiItem;
|
|
4
|
-
exports.createLinguiItemFromSegment = createLinguiItemFromSegment;
|
|
5
|
-
const generateMessageId_1 = require("@lingui/message-utils/generateMessageId");
|
|
1
|
+
import { generateMessageId } from "@lingui/message-utils/generateMessageId";
|
|
6
2
|
const EXPLICIT_ID_FLAG = "js-lingui-explicit-id";
|
|
7
3
|
const EXPLICIT_ID_AND_CONTEXT_FLAG = "js-lingui-explicit-id-and-context";
|
|
8
4
|
function isGeneratedId(id, message) {
|
|
9
|
-
return id ===
|
|
5
|
+
return id === generateMessageId(message.message, message.context);
|
|
10
6
|
}
|
|
11
7
|
const joinOrigin = (origin) => origin.join(":");
|
|
12
8
|
const splitOrigin = (origin) => {
|
|
13
9
|
const [file, line] = origin.split(":");
|
|
14
10
|
return [file, line ? Number(line) : null];
|
|
15
11
|
};
|
|
16
|
-
function createSegmentFromLinguiItem(key, item) {
|
|
12
|
+
export function createSegmentFromLinguiItem(key, item) {
|
|
17
13
|
const itemHasExplicitId = !isGeneratedId(key, item);
|
|
18
|
-
const itemHasContext = !!item.context;
|
|
19
14
|
const segment = {
|
|
20
15
|
type: "source", // No way to edit text for source language (inside code), so not using "key" here
|
|
21
16
|
source: "",
|
|
@@ -25,12 +20,12 @@ function createSegmentFromLinguiItem(key, item) {
|
|
|
25
20
|
};
|
|
26
21
|
// For segment.source & segment.context, we must remain compatible with projects created/synced before Lingui V4
|
|
27
22
|
if (itemHasExplicitId) {
|
|
28
|
-
segment.source = item.message || item.translation;
|
|
23
|
+
segment.source = item.message || item.translation || "";
|
|
29
24
|
segment.context = key;
|
|
30
25
|
}
|
|
31
26
|
else {
|
|
32
|
-
segment.source = item.message || item.translation;
|
|
33
|
-
if (
|
|
27
|
+
segment.source = item.message || item.translation || "";
|
|
28
|
+
if (item.context) {
|
|
34
29
|
segment.context = item.context;
|
|
35
30
|
}
|
|
36
31
|
}
|
|
@@ -40,7 +35,7 @@ function createSegmentFromLinguiItem(key, item) {
|
|
|
40
35
|
// Since Lingui v4, when using explicit IDs, Lingui automatically adds 'js-lingui-explicit-id' to the extractedComments array
|
|
41
36
|
const comments = [];
|
|
42
37
|
if (itemHasExplicitId) {
|
|
43
|
-
if (
|
|
38
|
+
if (item.context) {
|
|
44
39
|
// segment.context is already used for the explicit ID, so we need to pass the context (for translators) in segment.comment
|
|
45
40
|
comments.push(item.context, EXPLICIT_ID_AND_CONTEXT_FLAG);
|
|
46
41
|
}
|
|
@@ -51,30 +46,31 @@ function createSegmentFromLinguiItem(key, item) {
|
|
|
51
46
|
segment.comment = [...comments, ...(item.comments || [])].join(" | ");
|
|
52
47
|
return segment;
|
|
53
48
|
}
|
|
54
|
-
function createLinguiItemFromSegment(segment) {
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
const segmentHasExplicitIdAndContext = (_b = segment.comment) === null || _b === void 0 ? void 0 : _b.includes(EXPLICIT_ID_AND_CONTEXT_FLAG);
|
|
49
|
+
export function createLinguiItemFromSegment(segment) {
|
|
50
|
+
const segmentHasExplicitId = segment.comment?.includes(EXPLICIT_ID_FLAG);
|
|
51
|
+
const segmentHasExplicitIdAndContext = segment.comment?.includes(EXPLICIT_ID_AND_CONTEXT_FLAG);
|
|
58
52
|
const item = {
|
|
59
53
|
translation: segment.target,
|
|
60
|
-
origin:
|
|
54
|
+
origin: segment.references?.length
|
|
61
55
|
? segment.references.map(splitOrigin)
|
|
62
56
|
: [],
|
|
63
57
|
message: segment.source,
|
|
64
58
|
comments: [],
|
|
59
|
+
placeholders: {},
|
|
65
60
|
};
|
|
66
|
-
let id
|
|
61
|
+
let id;
|
|
67
62
|
if (segmentHasExplicitId || segmentHasExplicitIdAndContext) {
|
|
68
63
|
id = segment.context;
|
|
69
64
|
}
|
|
70
65
|
else {
|
|
71
|
-
id =
|
|
66
|
+
id = generateMessageId(segment.source, segment.context);
|
|
72
67
|
item.context = segment.context;
|
|
73
68
|
}
|
|
74
69
|
if (segment.comment) {
|
|
75
70
|
item.comments = segment.comment.split(" | ").filter(
|
|
76
71
|
// drop flags from comments
|
|
77
|
-
(comment) => comment !== EXPLICIT_ID_AND_CONTEXT_FLAG &&
|
|
72
|
+
(comment) => comment !== EXPLICIT_ID_AND_CONTEXT_FLAG &&
|
|
73
|
+
comment !== EXPLICIT_ID_FLAG);
|
|
78
74
|
// We recompose a target PO Item that is consistent with the source PO Item
|
|
79
75
|
if (segmentHasExplicitIdAndContext) {
|
|
80
76
|
item.context = item.comments.shift();
|
|
@@ -27,13 +27,6 @@ export type TranslationIoProject = {
|
|
|
27
27
|
name: string;
|
|
28
28
|
url: string;
|
|
29
29
|
};
|
|
30
|
-
export type TranslationIoResponse = {
|
|
31
|
-
errors?: string[];
|
|
32
|
-
project?: TranslationIoProject;
|
|
33
|
-
segments?: {
|
|
34
|
-
[locale: string]: TranslationIoSegment[];
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
30
|
export type FetchResult<T> = {
|
|
38
31
|
data: T;
|
|
39
32
|
error: undefined;
|
|
@@ -44,5 +37,16 @@ export type FetchResult<T> = {
|
|
|
44
37
|
};
|
|
45
38
|
data: undefined;
|
|
46
39
|
};
|
|
40
|
+
export type TranslationIoResponse = TranslationIoErrorResponse | TranslationProjectResponse;
|
|
41
|
+
type TranslationIoErrorResponse = {
|
|
42
|
+
errors: string[];
|
|
43
|
+
};
|
|
44
|
+
type TranslationProjectResponse = {
|
|
45
|
+
project: TranslationIoProject;
|
|
46
|
+
segments: {
|
|
47
|
+
[locale: string]: TranslationIoSegment[];
|
|
48
|
+
};
|
|
49
|
+
};
|
|
47
50
|
export declare function tioSync(request: TranslationIoSyncRequest, apiKey: string): Promise<FetchResult<TranslationIoResponse>>;
|
|
48
51
|
export declare function tioInit(request: TranslationIoInitRequest, apiKey: string): Promise<FetchResult<TranslationIoResponse>>;
|
|
52
|
+
export {};
|
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.tioSync = tioSync;
|
|
4
|
-
exports.tioInit = tioInit;
|
|
5
|
-
// todo: need to enable strictNullChecks to support this kind of type narrowing
|
|
6
|
-
// export type TranslationIoResponse =
|
|
7
|
-
// | TranslationIoErrorResponse
|
|
8
|
-
// | TranslationProjectResponse
|
|
9
|
-
//
|
|
10
|
-
// type TranslationIoErrorResponse = {
|
|
11
|
-
// errors: string[]
|
|
12
|
-
// }
|
|
13
|
-
// type TranslationProjectResponse = {
|
|
14
|
-
// errors: null
|
|
15
|
-
// project: TranslationIoProject
|
|
16
|
-
// segments: { [locale: string]: TranslationIoSegment[] }
|
|
17
|
-
// }
|
|
18
1
|
async function post(url, request) {
|
|
19
2
|
const response = await fetch(url, {
|
|
20
3
|
method: "POST",
|
|
@@ -34,9 +17,9 @@ async function post(url, request) {
|
|
|
34
17
|
}
|
|
35
18
|
return { data: await response.json(), error: undefined };
|
|
36
19
|
}
|
|
37
|
-
async function tioSync(request, apiKey) {
|
|
20
|
+
export async function tioSync(request, apiKey) {
|
|
38
21
|
return post(`https://translation.io/api/v1/segments/sync.json?api_key=${apiKey}`, request);
|
|
39
22
|
}
|
|
40
|
-
async function tioInit(request, apiKey) {
|
|
23
|
+
export async function tioInit(request, apiKey) {
|
|
41
24
|
return post(`https://translation.io/api/v1/segments/init.json?api_key=${apiKey}`, request);
|
|
42
25
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { LinguiConfigNormalized } from "@lingui/conf";
|
|
2
|
-
import { CliExtractOptions } from "../lingui-extract";
|
|
3
|
-
import { TranslationIoProject, TranslationIoSegment } from "./translationIO/translationio-api";
|
|
4
|
-
import { Catalog } from "../api/catalog";
|
|
5
|
-
import { AllCatalogsType } from "../api/types";
|
|
2
|
+
import { CliExtractOptions } from "../lingui-extract.js";
|
|
3
|
+
import { TranslationIoProject, TranslationIoSegment } from "./translationIO/translationio-api.js";
|
|
4
|
+
import { Catalog } from "../api/catalog.js";
|
|
5
|
+
import { AllCatalogsType } from "../api/types.js";
|
|
6
6
|
type ExtractionResult = {
|
|
7
7
|
catalog: Catalog;
|
|
8
8
|
messagesByLocale: AllCatalogsType;
|
|
@@ -1,24 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
exports.default = syncProcess;
|
|
7
|
-
exports.init = init;
|
|
8
|
-
exports.sync = sync;
|
|
9
|
-
exports.writeSegmentsToCatalogs = writeSegmentsToCatalogs;
|
|
10
|
-
const fs_1 = __importDefault(require("fs"));
|
|
11
|
-
const path_1 = require("path");
|
|
12
|
-
const translationio_api_1 = require("./translationIO/translationio-api");
|
|
13
|
-
const catalog_1 = require("../api/catalog");
|
|
14
|
-
const segment_converters_1 = require("./translationIO/segment-converters");
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import { dirname } from "path";
|
|
3
|
+
import { tioInit, tioSync, } from "./translationIO/translationio-api.js";
|
|
4
|
+
import { order } from "../api/catalog.js";
|
|
5
|
+
import { createLinguiItemFromSegment, createSegmentFromLinguiItem, } from "./translationIO/segment-converters.js";
|
|
15
6
|
const getTargetLocales = (config) => {
|
|
16
7
|
const sourceLocale = config.sourceLocale || "en";
|
|
17
8
|
const pseudoLocale = config.pseudoLocale || "pseudo";
|
|
18
9
|
return config.locales.filter((value) => value != sourceLocale && value != pseudoLocale);
|
|
19
10
|
};
|
|
20
11
|
// Main sync method, call "Init" or "Sync" depending on the project context
|
|
21
|
-
async function syncProcess(config, options, extractionResult) {
|
|
12
|
+
export default async function syncProcess(config, options, extractionResult) {
|
|
22
13
|
const reportSuccess = (project) => {
|
|
23
14
|
return `\n----------\nProject successfully synchronized. Please use this URL to translate: ${project.url}\n----------`;
|
|
24
15
|
};
|
|
@@ -40,7 +31,7 @@ async function syncProcess(config, options, extractionResult) {
|
|
|
40
31
|
}
|
|
41
32
|
// Initialize project with source and existing translations (only first time!)
|
|
42
33
|
// Cf. https://translation.io/docs/create-library#initialization
|
|
43
|
-
async function init(config, extractionResult) {
|
|
34
|
+
export async function init(config, extractionResult) {
|
|
44
35
|
const sourceLocale = config.sourceLocale || "en";
|
|
45
36
|
const targetLocales = getTargetLocales(config);
|
|
46
37
|
const segments = {};
|
|
@@ -54,7 +45,7 @@ async function init(config, extractionResult) {
|
|
|
54
45
|
if (entry.obsolete)
|
|
55
46
|
return;
|
|
56
47
|
targetLocales.forEach((targetLocale) => {
|
|
57
|
-
segments[targetLocale].push(
|
|
48
|
+
segments[targetLocale].push(createSegmentFromLinguiItem(key, entry));
|
|
58
49
|
});
|
|
59
50
|
});
|
|
60
51
|
}
|
|
@@ -69,7 +60,7 @@ async function init(config, extractionResult) {
|
|
|
69
60
|
});
|
|
70
61
|
}
|
|
71
62
|
}
|
|
72
|
-
const { data, error } = await
|
|
63
|
+
const { data, error } = await tioInit({
|
|
73
64
|
client: "lingui",
|
|
74
65
|
version: require("@lingui/core/package.json").version,
|
|
75
66
|
source_language: sourceLocale,
|
|
@@ -79,7 +70,7 @@ async function init(config, extractionResult) {
|
|
|
79
70
|
if (error) {
|
|
80
71
|
return { success: false, errors: [error.message] };
|
|
81
72
|
}
|
|
82
|
-
if (data
|
|
73
|
+
if ("errors" in data) {
|
|
83
74
|
return { success: false, errors: data.errors };
|
|
84
75
|
}
|
|
85
76
|
await writeSegmentsToCatalogs(config, sourceLocale, extractionResult, data.segments);
|
|
@@ -87,7 +78,7 @@ async function init(config, extractionResult) {
|
|
|
87
78
|
}
|
|
88
79
|
// Send all source text from PO to Translation.io and create new PO based on received translations
|
|
89
80
|
// Cf. https://translation.io/docs/create-library#synchronization
|
|
90
|
-
async function sync(config, options, extractionResult) {
|
|
81
|
+
export async function sync(config, options, extractionResult) {
|
|
91
82
|
const sourceLocale = config.sourceLocale || "en";
|
|
92
83
|
const targetLocales = getTargetLocales(config);
|
|
93
84
|
const segments = [];
|
|
@@ -97,10 +88,10 @@ async function sync(config, options, extractionResult) {
|
|
|
97
88
|
Object.entries(messages).forEach(([key, entry]) => {
|
|
98
89
|
if (entry.obsolete)
|
|
99
90
|
return;
|
|
100
|
-
segments.push(
|
|
91
|
+
segments.push(createSegmentFromLinguiItem(key, entry));
|
|
101
92
|
});
|
|
102
93
|
}
|
|
103
|
-
const { data, error } = await
|
|
94
|
+
const { data, error } = await tioSync({
|
|
104
95
|
client: "lingui",
|
|
105
96
|
version: require("@lingui/core/package.json").version,
|
|
106
97
|
source_language: sourceLocale,
|
|
@@ -112,13 +103,13 @@ async function sync(config, options, extractionResult) {
|
|
|
112
103
|
if (error) {
|
|
113
104
|
return { success: false, errors: [error.message] };
|
|
114
105
|
}
|
|
115
|
-
if (data
|
|
106
|
+
if ("errors" in data) {
|
|
116
107
|
return { success: false, errors: data.errors };
|
|
117
108
|
}
|
|
118
109
|
await writeSegmentsToCatalogs(config, sourceLocale, extractionResult, data.segments);
|
|
119
110
|
return { success: true, project: data.project };
|
|
120
111
|
}
|
|
121
|
-
async function writeSegmentsToCatalogs(config, sourceLocale, extractionResult, segmentsPerLocale) {
|
|
112
|
+
export async function writeSegmentsToCatalogs(config, sourceLocale, extractionResult, segmentsPerLocale) {
|
|
122
113
|
// Create segments from source locale PO items
|
|
123
114
|
for (const { catalog, messagesByLocale } of extractionResult) {
|
|
124
115
|
const sourceMessages = messagesByLocale[sourceLocale];
|
|
@@ -127,28 +118,30 @@ async function writeSegmentsToCatalogs(config, sourceLocale, extractionResult, s
|
|
|
127
118
|
{
|
|
128
119
|
const path = catalog.getFilename(targetLocale);
|
|
129
120
|
const jsPath = path.replace(new RegExp(`${catalog.format.getCatalogExtension()}$`), "") + ".js";
|
|
130
|
-
const dirPath =
|
|
121
|
+
const dirPath = dirname(path);
|
|
131
122
|
// todo: check tests and all these logic, maybe it could be simplified to just drop the folder
|
|
132
123
|
// Remove PO, JS and empty dir
|
|
133
|
-
if (
|
|
134
|
-
await
|
|
124
|
+
if (fs.existsSync(path)) {
|
|
125
|
+
await fs.promises.unlink(path);
|
|
135
126
|
}
|
|
136
|
-
if (
|
|
137
|
-
await
|
|
127
|
+
if (fs.existsSync(jsPath)) {
|
|
128
|
+
await fs.promises.unlink(jsPath);
|
|
138
129
|
}
|
|
139
|
-
if (
|
|
140
|
-
await
|
|
130
|
+
if (fs.existsSync(dirPath) && fs.readdirSync(dirPath).length === 0) {
|
|
131
|
+
await fs.promises.rmdir(dirPath);
|
|
141
132
|
}
|
|
142
133
|
}
|
|
143
|
-
const translations = Object.fromEntries(segmentsPerLocale[targetLocale].map((segment) =>
|
|
134
|
+
const translations = Object.fromEntries(segmentsPerLocale[targetLocale].map((segment) => createLinguiItemFromSegment(segment)));
|
|
144
135
|
const messages = Object.fromEntries(Object.entries(sourceMessages).map(([key, entry]) => {
|
|
145
|
-
var _a;
|
|
146
136
|
return [
|
|
147
137
|
key,
|
|
148
|
-
|
|
138
|
+
{
|
|
139
|
+
...entry,
|
|
140
|
+
translation: translations[key]?.translation,
|
|
141
|
+
},
|
|
149
142
|
];
|
|
150
143
|
}));
|
|
151
|
-
await catalog.write(targetLocale,
|
|
144
|
+
await catalog.write(targetLocale, order(config.orderBy, messages));
|
|
152
145
|
}
|
|
153
146
|
}
|
|
154
147
|
}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import { CliCompileOptions } from "../lingui-compile";
|
|
2
|
-
import { SerializedLogs } from "../api/workerLogger";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
10
|
-
export type CompileWorker = typeof compileWorker;
|
|
11
|
-
export {};
|
|
1
|
+
import { CliCompileOptions } from "../lingui-compile.js";
|
|
2
|
+
import { SerializedLogs } from "../api/workerLogger.js";
|
|
3
|
+
export type CompileWorkerFunction = typeof compileWorker;
|
|
4
|
+
export declare const compileWorker: (locale: string, options: CliCompileOptions, doMerge: boolean, linguiConfigPath: string) => Promise<{
|
|
5
|
+
logs: SerializedLogs;
|
|
6
|
+
error?: unknown;
|
|
7
|
+
exitProgram?: boolean;
|
|
8
|
+
}>;
|