@lingui/cli 6.2.0 → 6.4.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/dist/api/catalog/extractFromFiles.d.ts +3 -3
- package/dist/api/catalog/extractFromFiles.js +7 -15
- package/dist/api/catalog.d.ts +1 -0
- package/dist/api/catalog.js +58 -4
- package/dist/api/extractors/babel.js +1 -0
- package/dist/api/extractors/index.d.ts +4 -1
- package/dist/api/extractors/index.js +10 -3
- package/package.json +8 -8
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExtractedMessage, LinguiConfigNormalized } from "@lingui/conf";
|
|
2
2
|
import { ExtractedCatalogType } from "../types.js";
|
|
3
|
-
import { ExtractWorkerPool } from "../workerPools.js";
|
|
4
|
-
export declare function extractFromFiles(paths: string[], config: LinguiConfigNormalized): Promise<
|
|
3
|
+
import type { ExtractWorkerPool } from "../workerPools.js";
|
|
4
|
+
export declare function extractFromFiles(paths: string[], onMessageExtracted: (msg: ExtractedMessage) => void, config: LinguiConfigNormalized): Promise<boolean>;
|
|
5
5
|
export declare function mergeExtractedMessage(next: ExtractedMessage, messages: ExtractedCatalogType, config: LinguiConfigNormalized): void;
|
|
6
|
-
export declare function extractFromFilesWithWorkerPool(workerPool: ExtractWorkerPool, paths: string[], config: LinguiConfigNormalized): Promise<
|
|
6
|
+
export declare function extractFromFilesWithWorkerPool(workerPool: ExtractWorkerPool, paths: string[], onMessageExtracted: (msg: ExtractedMessage) => void, config: LinguiConfigNormalized): Promise<boolean>;
|
|
@@ -33,18 +33,13 @@ function mergePlaceholders(prev, next) {
|
|
|
33
33
|
});
|
|
34
34
|
return res;
|
|
35
35
|
}
|
|
36
|
-
export async function extractFromFiles(paths, config) {
|
|
37
|
-
const messages = {};
|
|
36
|
+
export async function extractFromFiles(paths, onMessageExtracted, config) {
|
|
38
37
|
let catalogSuccess = true;
|
|
39
38
|
for (const filename of paths) {
|
|
40
|
-
const fileSuccess = await extract(filename,
|
|
41
|
-
mergeExtractedMessage(next, messages, config);
|
|
42
|
-
}, config);
|
|
39
|
+
const fileSuccess = await extract(filename, onMessageExtracted, config);
|
|
43
40
|
catalogSuccess &&= fileSuccess;
|
|
44
41
|
}
|
|
45
|
-
|
|
46
|
-
return undefined;
|
|
47
|
-
return messages;
|
|
42
|
+
return catalogSuccess;
|
|
48
43
|
}
|
|
49
44
|
export function mergeExtractedMessage(next, messages, config) {
|
|
50
45
|
if (!messages[next.id]) {
|
|
@@ -79,13 +74,12 @@ export function mergeExtractedMessage(next, messages, config) {
|
|
|
79
74
|
placeholders: mergePlaceholders(prev.placeholders, next.placeholders),
|
|
80
75
|
};
|
|
81
76
|
}
|
|
82
|
-
export async function extractFromFilesWithWorkerPool(workerPool, paths, config) {
|
|
83
|
-
const messages = {};
|
|
84
|
-
let catalogSuccess = true;
|
|
77
|
+
export async function extractFromFilesWithWorkerPool(workerPool, paths, onMessageExtracted, config) {
|
|
85
78
|
const resolvedConfigPath = config.resolvedConfigPath;
|
|
86
79
|
if (!resolvedConfigPath) {
|
|
87
80
|
throw new Error("Multithreading is only supported when lingui config loaded from file system, not passed by API");
|
|
88
81
|
}
|
|
82
|
+
let catalogSuccess = true;
|
|
89
83
|
const results = await Promise.all(paths.map((filename) => workerPool.run(filename, resolvedConfigPath)));
|
|
90
84
|
results.forEach((result) => {
|
|
91
85
|
if (!result.success) {
|
|
@@ -93,11 +87,9 @@ export async function extractFromFilesWithWorkerPool(workerPool, paths, config)
|
|
|
93
87
|
}
|
|
94
88
|
else {
|
|
95
89
|
result.messages.forEach((message) => {
|
|
96
|
-
|
|
90
|
+
onMessageExtracted(message);
|
|
97
91
|
});
|
|
98
92
|
}
|
|
99
93
|
});
|
|
100
|
-
|
|
101
|
-
return undefined;
|
|
102
|
-
return messages;
|
|
94
|
+
return catalogSuccess;
|
|
103
95
|
}
|
package/dist/api/catalog.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ export declare class Catalog {
|
|
|
48
48
|
files?: string[];
|
|
49
49
|
workerPool?: ExtractWorkerPool;
|
|
50
50
|
}): Promise<ExtractedCatalogType | undefined>;
|
|
51
|
+
private collectWithExtractors;
|
|
51
52
|
merge(prevCatalogs: AllCatalogsType, nextCatalog: ExtractedCatalogType, options: MergeOptions): {
|
|
52
53
|
[k: string]: CatalogType;
|
|
53
54
|
};
|
package/dist/api/catalog.js
CHANGED
|
@@ -4,8 +4,9 @@ import { globSync } from "node:fs";
|
|
|
4
4
|
import normalize from "normalize-path";
|
|
5
5
|
import { getTranslationsForCatalog, } from "./catalog/getTranslationsForCatalog.js";
|
|
6
6
|
import { mergeCatalog } from "./catalog/mergeCatalog.js";
|
|
7
|
-
import { extractFromFiles, extractFromFilesWithWorkerPool, } from "./catalog/extractFromFiles.js";
|
|
7
|
+
import { extractFromFiles, extractFromFilesWithWorkerPool, mergeExtractedMessage, } from "./catalog/extractFromFiles.js";
|
|
8
8
|
import { isDirectory, makePathRegexSafe, normalizeRelativePath, replacePlaceholders, writeFile, } from "./utils.js";
|
|
9
|
+
import { getConfiguredExtractors, isBatchExtractor, } from "./extractors/index.js";
|
|
9
10
|
const LOCALE = "{locale}";
|
|
10
11
|
const LOCALE_SUFFIX_RE = /\{locale\}.*$/;
|
|
11
12
|
export class Catalog {
|
|
@@ -75,10 +76,63 @@ export class Catalog {
|
|
|
75
76
|
const regex = new RegExp(options.files.join("|"), "i");
|
|
76
77
|
paths = paths.filter((path) => regex.test(normalize(path)));
|
|
77
78
|
}
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
const messages = {};
|
|
80
|
+
const onMessageExtracted = (next) => {
|
|
81
|
+
mergeExtractedMessage(next, messages, this.config);
|
|
82
|
+
};
|
|
83
|
+
const extractors = getConfiguredExtractors(this.config);
|
|
84
|
+
// Optimized hot path: if there are no batch extractors defined, skip the more complex logic.
|
|
85
|
+
if (!extractors.some(isBatchExtractor)) {
|
|
86
|
+
const success = options.workerPool
|
|
87
|
+
? await extractFromFilesWithWorkerPool(options.workerPool, paths, onMessageExtracted, this.config)
|
|
88
|
+
: await extractFromFiles(paths, onMessageExtracted, this.config);
|
|
89
|
+
return success ? messages : undefined;
|
|
80
90
|
}
|
|
81
|
-
return await
|
|
91
|
+
return await this.collectWithExtractors(extractors, paths, onMessageExtracted, messages, options);
|
|
92
|
+
}
|
|
93
|
+
async collectWithExtractors(extractors, paths, onMessageExtracted, messages, options) {
|
|
94
|
+
let remaining = paths;
|
|
95
|
+
let catalogSuccess = true;
|
|
96
|
+
for (const extractor of extractors) {
|
|
97
|
+
if (remaining.length === 0)
|
|
98
|
+
break;
|
|
99
|
+
const matched = [];
|
|
100
|
+
const unmatched = [];
|
|
101
|
+
for (const f of remaining) {
|
|
102
|
+
if (extractor.match(f)) {
|
|
103
|
+
matched.push(f);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
unmatched.push(f);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (matched.length === 0)
|
|
110
|
+
continue;
|
|
111
|
+
remaining = unmatched;
|
|
112
|
+
if (isBatchExtractor(extractor)) {
|
|
113
|
+
try {
|
|
114
|
+
await extractor.extractFromFiles(matched, onMessageExtracted, {
|
|
115
|
+
linguiConfig: this.config,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
console.error(`Extractor failed: ${e.message}`);
|
|
120
|
+
console.error(e.stack);
|
|
121
|
+
catalogSuccess = false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
const success = options.workerPool
|
|
126
|
+
? await extractFromFilesWithWorkerPool(options.workerPool, matched, onMessageExtracted, this.config)
|
|
127
|
+
: await extractFromFiles(matched, onMessageExtracted, this.config);
|
|
128
|
+
if (!success) {
|
|
129
|
+
catalogSuccess = false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (!catalogSuccess)
|
|
134
|
+
return undefined;
|
|
135
|
+
return messages;
|
|
82
136
|
}
|
|
83
137
|
/*
|
|
84
138
|
*
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
import { ExtractedMessage, LinguiConfigNormalized } from "@lingui/conf";
|
|
1
|
+
import { Experimental__BatchExtractorType, ExtractedMessage, ExtractorType, LinguiConfigNormalized, PerFileExtractorType } from "@lingui/conf";
|
|
2
|
+
export declare function isBatchExtractor(ext: ExtractorType): ext is Experimental__BatchExtractorType;
|
|
3
|
+
export declare function isPerFileExtractor(ext: ExtractorType): ext is PerFileExtractorType;
|
|
4
|
+
export declare const getConfiguredExtractors: (linguiConfig: LinguiConfigNormalized) => ExtractorType[];
|
|
2
5
|
export default function extract(filename: string, onMessageExtracted: (msg: ExtractedMessage) => void, linguiConfig: LinguiConfigNormalized): Promise<boolean>;
|
|
@@ -9,10 +9,17 @@ function createDefaultExtractor(linguiConfig) {
|
|
|
9
9
|
}
|
|
10
10
|
return defaultExtractor;
|
|
11
11
|
}
|
|
12
|
+
export function isBatchExtractor(ext) {
|
|
13
|
+
return "extractFromFiles" in ext && typeof ext.extractFromFiles === "function";
|
|
14
|
+
}
|
|
15
|
+
export function isPerFileExtractor(ext) {
|
|
16
|
+
return "extract" in ext && typeof ext.extract === "function";
|
|
17
|
+
}
|
|
18
|
+
export const getConfiguredExtractors = (linguiConfig) => {
|
|
19
|
+
return linguiConfig.extractors ?? [createDefaultExtractor(linguiConfig)];
|
|
20
|
+
};
|
|
12
21
|
export default async function extract(filename, onMessageExtracted, linguiConfig) {
|
|
13
|
-
const extractorsToExtract = linguiConfig.
|
|
14
|
-
createDefaultExtractor(linguiConfig),
|
|
15
|
-
];
|
|
22
|
+
const extractorsToExtract = getConfiguredExtractors(linguiConfig).filter(isPerFileExtractor);
|
|
16
23
|
for (const ext of extractorsToExtract) {
|
|
17
24
|
if (!ext.match(filename))
|
|
18
25
|
continue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingui/cli",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.0",
|
|
4
4
|
"description": "Lingui CLI to extract messages, compile catalogs, and manage translation workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -52,12 +52,12 @@
|
|
|
52
52
|
"@babel/generator": "^7.28.5",
|
|
53
53
|
"@babel/parser": "^7.22.0",
|
|
54
54
|
"@babel/types": "^7.21.2",
|
|
55
|
-
"@lingui/babel-plugin-extract-messages": "6.
|
|
56
|
-
"@lingui/babel-plugin-lingui-macro": "6.
|
|
57
|
-
"@lingui/conf": "6.
|
|
58
|
-
"@lingui/core": "6.
|
|
59
|
-
"@lingui/format-po": "6.
|
|
60
|
-
"@lingui/message-utils": "6.
|
|
55
|
+
"@lingui/babel-plugin-extract-messages": "6.4.0",
|
|
56
|
+
"@lingui/babel-plugin-lingui-macro": "6.4.0",
|
|
57
|
+
"@lingui/conf": "6.4.0",
|
|
58
|
+
"@lingui/core": "6.4.0",
|
|
59
|
+
"@lingui/format-po": "6.4.0",
|
|
60
|
+
"@lingui/message-utils": "6.4.0",
|
|
61
61
|
"chokidar": "5.0.0",
|
|
62
62
|
"cli-table3": "^0.6.5",
|
|
63
63
|
"commander": "^14.0.2",
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"msw": "^2.12.7",
|
|
82
82
|
"vitest": "catalog:"
|
|
83
83
|
},
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "e8657bf8cbe6e8abc62a46a24e018ff9812918be"
|
|
85
85
|
}
|