@lingui/cli 6.0.0-next.0 → 6.0.0-next.2
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.js +13 -4
- package/dist/api/catalog/mergeCatalog.js +1 -1
- package/dist/api/catalog.js +3 -3
- package/dist/api/compile.js +1 -1
- package/dist/api/extractors/babel.d.ts +20 -4
- package/dist/api/extractors/babel.js +16 -13
- package/dist/api/extractors/index.js +13 -3
- package/dist/api/typedPool.js +1 -1
- package/dist/extract-experimental/extractFromBundleAndWrite.js +3 -10
- package/dist/extract-experimental/linguiEsbuildPlugin.js +1 -1
- package/dist/lingui-compile.js +2 -2
- package/dist/lingui-extract.js +5 -4
- package/dist/services/translationIO.js +8 -2
- package/package.json +8 -8
|
@@ -2,11 +2,20 @@ import { styleText } from "node:util";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import extract from "../extractors/index.js";
|
|
4
4
|
import { prettyOrigin } from "../utils.js";
|
|
5
|
+
function compareOrigins(a, b) {
|
|
6
|
+
const byPath = a[0].localeCompare(b[0]);
|
|
7
|
+
if (byPath !== 0) {
|
|
8
|
+
return byPath;
|
|
9
|
+
}
|
|
10
|
+
const lineA = a[1] ?? 0;
|
|
11
|
+
const lineB = b[1] ?? 0;
|
|
12
|
+
return lineA - lineB;
|
|
13
|
+
}
|
|
5
14
|
function mergeOrigins(prev, next) {
|
|
6
15
|
if (!next) {
|
|
7
16
|
return prev;
|
|
8
17
|
}
|
|
9
|
-
return [...prev, next].sort(
|
|
18
|
+
return [...prev, next].sort(compareOrigins);
|
|
10
19
|
}
|
|
11
20
|
function mergePlaceholders(prev, next) {
|
|
12
21
|
const res = { ...prev };
|
|
@@ -77,8 +86,8 @@ export async function extractFromFilesWithWorkerPool(workerPool, paths, config)
|
|
|
77
86
|
if (!resolvedConfigPath) {
|
|
78
87
|
throw new Error("Multithreading is only supported when lingui config loaded from file system, not passed by API");
|
|
79
88
|
}
|
|
80
|
-
await Promise.all(paths.map(
|
|
81
|
-
|
|
89
|
+
const results = await Promise.all(paths.map((filename) => workerPool.run(filename, resolvedConfigPath)));
|
|
90
|
+
results.forEach((result) => {
|
|
82
91
|
if (!result.success) {
|
|
83
92
|
catalogSuccess = false;
|
|
84
93
|
}
|
|
@@ -87,7 +96,7 @@ export async function extractFromFilesWithWorkerPool(workerPool, paths, config)
|
|
|
87
96
|
mergeExtractedMessage(message, messages, config);
|
|
88
97
|
});
|
|
89
98
|
}
|
|
90
|
-
})
|
|
99
|
+
});
|
|
91
100
|
if (!catalogSuccess)
|
|
92
101
|
return undefined;
|
|
93
102
|
return messages;
|
|
@@ -22,7 +22,7 @@ export function mergeCatalog(prevCatalog, nextCatalog, forSourceLocale, options)
|
|
|
22
22
|
? nextCatalog[key].message || key
|
|
23
23
|
: prevCatalog[key].translation;
|
|
24
24
|
const { extra } = prevCatalog[key];
|
|
25
|
-
return [key, { ...
|
|
25
|
+
return [key, { ...nextCatalog[key], extra, translation }];
|
|
26
26
|
}));
|
|
27
27
|
// Mark all remaining translations as obsolete
|
|
28
28
|
// Only if *options.files* is not provided
|
package/dist/api/catalog.js
CHANGED
|
@@ -238,10 +238,10 @@ export async function writeCompiled(path, locale, compiledCatalog, namespace) {
|
|
|
238
238
|
await writeFile(filename, compiledCatalog);
|
|
239
239
|
return filename;
|
|
240
240
|
}
|
|
241
|
+
// hardcoded en-US locale to have consistent sorting
|
|
242
|
+
// @see https://github.com/lingui/js-lingui/pull/1808
|
|
243
|
+
const collator = new Intl.Collator("en-US");
|
|
241
244
|
export const orderByMessage = (a, b) => {
|
|
242
|
-
// hardcoded en-US locale to have consistent sorting
|
|
243
|
-
// @see https://github.com/lingui/js-lingui/pull/1808
|
|
244
|
-
const collator = new Intl.Collator("en-US");
|
|
245
245
|
const aMsg = a.entry.message || "";
|
|
246
246
|
const bMsg = b.entry.message || "";
|
|
247
247
|
const aCtxt = a.entry.context || "";
|
package/dist/api/compile.js
CHANGED
|
@@ -58,7 +58,7 @@ function buildExportStatement(expression, namespace) {
|
|
|
58
58
|
]));
|
|
59
59
|
}
|
|
60
60
|
else {
|
|
61
|
-
let exportExpression
|
|
61
|
+
let exportExpression;
|
|
62
62
|
const matches = namespace.match(/^(window|global)\.([^.\s]+)$/);
|
|
63
63
|
if (namespace === "cjs") {
|
|
64
64
|
// module.exports.messages = { message: "Translation" }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ParserOptions } from "@babel/core";
|
|
2
|
-
import { ExtractorType,
|
|
2
|
+
import { ExtractorType, ExtractedMessage, ExtractorCtx } from "@lingui/conf";
|
|
3
3
|
export declare const babelRe: RegExp;
|
|
4
4
|
/**
|
|
5
5
|
* @public
|
|
@@ -27,6 +27,22 @@ export declare const babelRe: RegExp;
|
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
29
|
export declare function extractFromFileWithBabel(filename: string, code: string, onMessageExtracted: (msg: ExtractedMessage) => void, ctx: ExtractorCtx, parserOpts: ParserOptions, skipMacroPlugin?: boolean): Promise<void>;
|
|
30
|
-
export declare function getBabelParserOptions(filename: string, parserOptions:
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
export declare function getBabelParserOptions(filename: string, parserOptions: BabelExtractorOptions["parserOptions"]): (import("@babel/parser").ParserPluginWithOptions | ("decimal" | "asyncDoExpressions" | "asyncGenerators" | "bigInt" | "classPrivateMethods" | "classPrivateProperties" | "classProperties" | "classStaticBlock" | "decorators-legacy" | "deferredImportEvaluation" | "decoratorAutoAccessors" | "destructuringPrivate" | "doExpressions" | "dynamicImport" | "explicitResourceManagement" | "exportDefaultFrom" | "exportNamespaceFrom" | "flow" | "flowComments" | "functionBind" | "functionSent" | "importMeta" | "jsx" | "logicalAssignment" | "importAssertions" | "importReflection" | "moduleBlocks" | "moduleStringNames" | "nullishCoalescingOperator" | "numericSeparator" | "objectRestSpread" | "optionalCatchBinding" | "optionalChaining" | "partialApplication" | "placeholders" | "privateIn" | "regexpUnicodeSets" | "sourcePhaseImports" | "throwExpressions" | "topLevelAwait" | "v8intrinsic" | "decorators" | "estree" | "importAttributes" | "moduleAttributes" | "optionalChainingAssign" | "pipelineOperator" | "recordAndTuple" | "typescript"))[];
|
|
31
|
+
export type BabelExtractorOptions = {
|
|
32
|
+
parserOptions?: {
|
|
33
|
+
/**
|
|
34
|
+
* default false
|
|
35
|
+
*
|
|
36
|
+
* By default, standard decorators (Stage3) are applied for TS files
|
|
37
|
+
* Enable this if you want to use TypesScript's experimental decorators.
|
|
38
|
+
*/
|
|
39
|
+
tsExperimentalDecorators?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Enable if you use flow. This will apply Flow syntax to js files
|
|
42
|
+
*/
|
|
43
|
+
flow?: boolean;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
export declare function createBabelExtractor(options?: BabelExtractorOptions): ExtractorType;
|
|
47
|
+
export declare const babelExtractor: ExtractorType;
|
|
48
|
+
export default babelExtractor;
|
|
@@ -131,7 +131,7 @@ export function getBabelParserOptions(filename, parserOptions) {
|
|
|
131
131
|
];
|
|
132
132
|
if ([/\.ts$/, /\.mts$/, /\.cts$/, /\.tsx$/].some((r) => filename.match(r))) {
|
|
133
133
|
parserPlugins.push("typescript");
|
|
134
|
-
if (parserOptions
|
|
134
|
+
if (parserOptions?.tsExperimentalDecorators) {
|
|
135
135
|
parserPlugins.push("decorators-legacy");
|
|
136
136
|
}
|
|
137
137
|
else {
|
|
@@ -149,15 +149,18 @@ export function getBabelParserOptions(filename, parserOptions) {
|
|
|
149
149
|
}
|
|
150
150
|
return parserPlugins;
|
|
151
151
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
|
|
152
|
+
export function createBabelExtractor(options) {
|
|
153
|
+
return {
|
|
154
|
+
match(filename) {
|
|
155
|
+
return babelRe.test(filename);
|
|
156
|
+
},
|
|
157
|
+
async extract(filename, code, onMessageExtracted, ctx) {
|
|
158
|
+
const parserOptions = options?.parserOptions ?? ctx.linguiConfig.extractorParserOptions;
|
|
159
|
+
return extractFromFileWithBabel(filename, code, onMessageExtracted, ctx, {
|
|
160
|
+
plugins: getBabelParserOptions(filename, parserOptions),
|
|
161
|
+
});
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
export const babelExtractor = createBabelExtractor();
|
|
166
|
+
export default babelExtractor;
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import fs from "fs/promises";
|
|
2
|
-
import
|
|
3
|
-
|
|
2
|
+
import { createBabelExtractor } from "./babel.js";
|
|
3
|
+
let defaultExtractor;
|
|
4
|
+
function createDefaultExtractor(linguiConfig) {
|
|
5
|
+
if (!defaultExtractor) {
|
|
6
|
+
defaultExtractor = createBabelExtractor({
|
|
7
|
+
parserOptions: linguiConfig.extractorParserOptions,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
return defaultExtractor;
|
|
11
|
+
}
|
|
4
12
|
export default async function extract(filename, onMessageExtracted, linguiConfig) {
|
|
5
|
-
const extractorsToExtract = linguiConfig.extractors ??
|
|
13
|
+
const extractorsToExtract = linguiConfig.extractors ?? [
|
|
14
|
+
createDefaultExtractor(linguiConfig),
|
|
15
|
+
];
|
|
6
16
|
for (const ext of extractorsToExtract) {
|
|
7
17
|
if (!ext.match(filename))
|
|
8
18
|
continue;
|
package/dist/api/typedPool.js
CHANGED
|
@@ -1,20 +1,13 @@
|
|
|
1
1
|
import { mergeExtractedMessage } from "../api/catalog/extractFromFiles.js";
|
|
2
2
|
import { writeCatalogs, writeTemplate } from "./writeCatalogs.js";
|
|
3
|
-
import
|
|
4
|
-
import { extractFromFileWithBabel, getBabelParserOptions, } from "../api/extractors/babel.js";
|
|
3
|
+
import extract from "../api/extractors/index.js";
|
|
5
4
|
async function extractFromBundle(filename, linguiConfig) {
|
|
6
5
|
const messages = {};
|
|
7
6
|
let success;
|
|
8
7
|
try {
|
|
9
|
-
|
|
10
|
-
const parserOptions = linguiConfig.extractorParserOptions;
|
|
11
|
-
await extractFromFileWithBabel(filename, file.toString(), (msg) => {
|
|
8
|
+
await extract(filename, (msg) => {
|
|
12
9
|
mergeExtractedMessage(msg, messages, linguiConfig);
|
|
13
|
-
},
|
|
14
|
-
linguiConfig,
|
|
15
|
-
}, {
|
|
16
|
-
plugins: getBabelParserOptions(filename, parserOptions),
|
|
17
|
-
}, true);
|
|
10
|
+
}, linguiConfig);
|
|
18
11
|
success = true;
|
|
19
12
|
}
|
|
20
13
|
catch (e) {
|
|
@@ -20,7 +20,7 @@ export const pluginLinguiMacro = (options) => ({
|
|
|
20
20
|
filename: filename,
|
|
21
21
|
sourceMaps: "inline",
|
|
22
22
|
parserOpts: {
|
|
23
|
-
plugins: getBabelParserOptions(filename,
|
|
23
|
+
plugins: getBabelParserOptions(filename, {}),
|
|
24
24
|
},
|
|
25
25
|
plugins: [
|
|
26
26
|
[
|
package/dist/lingui-compile.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { styleText } from "node:util";
|
|
2
|
-
import
|
|
2
|
+
import { watch } from "chokidar";
|
|
3
3
|
import { program } from "commander";
|
|
4
4
|
import { getConfig } from "@lingui/conf";
|
|
5
5
|
import { helpRun } from "./api/help.js";
|
|
@@ -116,7 +116,7 @@ if (import.meta.main) {
|
|
|
116
116
|
console.info(styleText("bold", "Initializing Watch Mode..."));
|
|
117
117
|
(async function initWatch() {
|
|
118
118
|
const { paths } = await getPathsForCompileWatcher(config);
|
|
119
|
-
const watcher =
|
|
119
|
+
const watcher = watch(paths, {
|
|
120
120
|
persistent: true,
|
|
121
121
|
});
|
|
122
122
|
const onReady = () => {
|
package/dist/lingui-extract.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { styleText } from "node:util";
|
|
2
|
-
import
|
|
2
|
+
import { watch } from "chokidar";
|
|
3
3
|
import { program } from "commander";
|
|
4
4
|
import nodepath from "path";
|
|
5
5
|
import { getConfig } from "@lingui/conf";
|
|
@@ -69,13 +69,14 @@ export default async function command(config, options) {
|
|
|
69
69
|
if (config.service?.name?.length) {
|
|
70
70
|
const moduleName = config.service.name.charAt(0).toLowerCase() + config.service.name.slice(1);
|
|
71
71
|
const services = {
|
|
72
|
-
translationIO: () => import(
|
|
72
|
+
translationIO: () => import("./services/translationIO.js"),
|
|
73
73
|
};
|
|
74
74
|
if (!services[moduleName]) {
|
|
75
75
|
console.error(`Can't load service module ${moduleName}`);
|
|
76
|
+
return false;
|
|
76
77
|
}
|
|
77
78
|
try {
|
|
78
|
-
const module = services[moduleName]();
|
|
79
|
+
const module = await services[moduleName]();
|
|
79
80
|
await module
|
|
80
81
|
.default(config, options, extractionResult)
|
|
81
82
|
.then(console.log)
|
|
@@ -157,7 +158,7 @@ if (import.meta.main) {
|
|
|
157
158
|
for await (const path of glob(paths)) {
|
|
158
159
|
matchedPaths.push(path);
|
|
159
160
|
}
|
|
160
|
-
const watcher =
|
|
161
|
+
const watcher = watch(matchedPaths, {
|
|
161
162
|
ignored: [
|
|
162
163
|
"/(^|[/\\])../",
|
|
163
164
|
(path) => micromatch.any(path, ignored),
|
|
@@ -3,6 +3,8 @@ import { dirname } from "path";
|
|
|
3
3
|
import { tioInit, tioSync, } from "./translationIO/translationio-api.js";
|
|
4
4
|
import { order } from "../api/catalog.js";
|
|
5
5
|
import { createLinguiItemFromSegment, createSegmentFromLinguiItem, } from "./translationIO/segment-converters.js";
|
|
6
|
+
import { readFileSync } from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
6
8
|
const getTargetLocales = (config) => {
|
|
7
9
|
const sourceLocale = config.sourceLocale || "en";
|
|
8
10
|
const pseudoLocale = config.pseudoLocale || "pseudo";
|
|
@@ -29,6 +31,10 @@ export default async function syncProcess(config, options, extractionResult) {
|
|
|
29
31
|
}
|
|
30
32
|
return reportError(errors);
|
|
31
33
|
}
|
|
34
|
+
function getLinguiVersion() {
|
|
35
|
+
const packageJson = JSON.parse(readFileSync(path.resolve(import.meta.dirname, "../../package.json"), "utf8"));
|
|
36
|
+
return packageJson.version;
|
|
37
|
+
}
|
|
32
38
|
// Initialize project with source and existing translations (only first time!)
|
|
33
39
|
// Cf. https://translation.io/docs/create-library#initialization
|
|
34
40
|
export async function init(config, extractionResult) {
|
|
@@ -62,7 +68,7 @@ export async function init(config, extractionResult) {
|
|
|
62
68
|
}
|
|
63
69
|
const { data, error } = await tioInit({
|
|
64
70
|
client: "lingui",
|
|
65
|
-
version:
|
|
71
|
+
version: getLinguiVersion(),
|
|
66
72
|
source_language: sourceLocale,
|
|
67
73
|
target_languages: targetLocales,
|
|
68
74
|
segments: segments,
|
|
@@ -93,7 +99,7 @@ export async function sync(config, options, extractionResult) {
|
|
|
93
99
|
}
|
|
94
100
|
const { data, error } = await tioSync({
|
|
95
101
|
client: "lingui",
|
|
96
|
-
version:
|
|
102
|
+
version: getLinguiVersion(),
|
|
97
103
|
source_language: sourceLocale,
|
|
98
104
|
target_languages: targetLocales,
|
|
99
105
|
segments: segments,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingui/cli",
|
|
3
|
-
"version": "6.0.0-next.
|
|
3
|
+
"version": "6.0.0-next.2",
|
|
4
4
|
"description": "CLI for working wit message catalogs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"@babel/generator": "^7.28.5",
|
|
51
51
|
"@babel/parser": "^7.22.0",
|
|
52
52
|
"@babel/types": "^7.21.2",
|
|
53
|
-
"@lingui/babel-plugin-extract-messages": "6.0.0-next.
|
|
54
|
-
"@lingui/babel-plugin-lingui-macro": "6.0.0-next.
|
|
55
|
-
"@lingui/conf": "6.0.0-next.
|
|
56
|
-
"@lingui/core": "6.0.0-next.
|
|
57
|
-
"@lingui/format-po": "6.0.0-next.
|
|
58
|
-
"@lingui/message-utils": "6.0.0-next.
|
|
53
|
+
"@lingui/babel-plugin-extract-messages": "6.0.0-next.2",
|
|
54
|
+
"@lingui/babel-plugin-lingui-macro": "6.0.0-next.2",
|
|
55
|
+
"@lingui/conf": "6.0.0-next.2",
|
|
56
|
+
"@lingui/core": "6.0.0-next.2",
|
|
57
|
+
"@lingui/format-po": "6.0.0-next.2",
|
|
58
|
+
"@lingui/message-utils": "6.0.0-next.2",
|
|
59
59
|
"chokidar": "5.0.0",
|
|
60
60
|
"cli-table3": "^0.6.5",
|
|
61
61
|
"commander": "^14.0.2",
|
|
@@ -79,5 +79,5 @@
|
|
|
79
79
|
"msw": "^2.12.7",
|
|
80
80
|
"vitest": "4.0.18"
|
|
81
81
|
},
|
|
82
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "f4bcdd555ceef0bed58b2f3075096efd4daaeec2"
|
|
83
83
|
}
|