@formatjs/cli-lib 8.0.8 → 8.1.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/index.d.ts +7 -7
- package/index.js +2 -2
- package/main.d.ts +0 -1
- package/main.js +1 -1
- package/package.json +5 -5
- package/src/cli.js +99 -153
- package/src/compile.d.ts +45 -45
- package/src/compile.js +79 -80
- package/src/compile_folder.d.ts +1 -1
- package/src/compile_folder.js +6 -6
- package/src/console_utils.d.ts +3 -1
- package/src/console_utils.js +44 -46
- package/src/extract.d.ts +68 -68
- package/src/extract.js +165 -182
- package/src/formatters/crowdin.d.ts +3 -3
- package/src/formatters/crowdin.js +19 -20
- package/src/formatters/default.d.ts +1 -1
- package/src/formatters/default.js +8 -7
- package/src/formatters/index.d.ts +6 -6
- package/src/formatters/index.js +29 -34
- package/src/formatters/lokalise.d.ts +5 -5
- package/src/formatters/lokalise.js +16 -17
- package/src/formatters/simple.d.ts +1 -1
- package/src/formatters/simple.js +7 -6
- package/src/formatters/smartling.d.ts +13 -15
- package/src/formatters/smartling.js +35 -40
- package/src/formatters/transifex.d.ts +5 -5
- package/src/formatters/transifex.js +16 -17
- package/src/gts_extractor.js +11 -11
- package/src/hbs_extractor.js +34 -41
- package/src/parse_script.d.ts +5 -5
- package/src/parse_script.js +40 -43
- package/src/pseudo_locale.d.ts +15 -15
- package/src/pseudo_locale.js +210 -94
- package/src/verify/checkExtraKeys.js +28 -32
- package/src/verify/checkMissingKeys.js +29 -33
- package/src/verify/checkStructuralEquality.js +67 -71
- package/src/verify/index.d.ts +5 -5
- package/src/verify/index.js +24 -27
- package/src/vue_extractor.js +52 -62
package/src/compile.js
CHANGED
|
@@ -1,91 +1,90 @@
|
|
|
1
|
-
import { parse } from
|
|
2
|
-
import { outputFile, readJSON } from
|
|
3
|
-
import * as stringifyNs from
|
|
4
|
-
import { debug, warn, writeStdout } from
|
|
5
|
-
import { resolveBuiltinFormatter } from
|
|
6
|
-
import { generateENXA, generateENXB, generateXXAC, generateXXHA, generateXXLS
|
|
1
|
+
import { parse } from "@formatjs/icu-messageformat-parser";
|
|
2
|
+
import { outputFile, readJSON } from "fs-extra/esm";
|
|
3
|
+
import * as stringifyNs from "json-stable-stringify";
|
|
4
|
+
import { debug, warn, writeStdout } from "./console_utils.js";
|
|
5
|
+
import { resolveBuiltinFormatter } from "./formatters/index.js";
|
|
6
|
+
import { generateENXA, generateENXB, generateXXAC, generateXXHA, generateXXLS } from "./pseudo_locale.js";
|
|
7
7
|
const stringify = stringifyNs.default || stringifyNs;
|
|
8
8
|
/**
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
* Aggregate `inputFiles` into a single JSON blob and compile.
|
|
10
|
+
* Also checks for conflicting IDs.
|
|
11
|
+
* Then returns the serialized result as a `string` since key order
|
|
12
|
+
* makes a difference in some vendor.
|
|
13
|
+
* @param inputFiles Input files
|
|
14
|
+
* @param opts Options
|
|
15
|
+
* @returns serialized result in string format
|
|
16
|
+
*/
|
|
17
17
|
export async function compile(inputFiles, opts = {}) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
18
|
+
debug("Compiling files:", inputFiles);
|
|
19
|
+
const { ast, format, pseudoLocale, skipErrors, ignoreTag } = opts;
|
|
20
|
+
const formatter = await resolveBuiltinFormatter(format);
|
|
21
|
+
const messages = {};
|
|
22
|
+
const messageAsts = {};
|
|
23
|
+
const idsWithFileName = {};
|
|
24
|
+
const compiledFiles = await Promise.all(inputFiles.map((f) => readJSON(f).then(formatter.compile)));
|
|
25
|
+
debug("Compiled files:", compiledFiles);
|
|
26
|
+
for (let i = 0; i < inputFiles.length; i++) {
|
|
27
|
+
const inputFile = inputFiles[i];
|
|
28
|
+
debug("Processing file:", inputFile);
|
|
29
|
+
const compiled = compiledFiles[i];
|
|
30
|
+
for (const id in compiled) {
|
|
31
|
+
if (messages[id] && messages[id] !== compiled[id]) {
|
|
32
|
+
throw new Error(`Conflicting ID "${id}" with different translation found in these 2 files:
|
|
33
33
|
ID: ${id}
|
|
34
34
|
Message from ${idsWithFileName[id]}: ${messages[id]}
|
|
35
35
|
Message from ${inputFile}: ${compiled[id]}
|
|
36
36
|
`);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}) ?? '');
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const msgAst = parse(compiled[id], { ignoreTag });
|
|
40
|
+
messages[id] = compiled[id];
|
|
41
|
+
switch (pseudoLocale) {
|
|
42
|
+
case "xx-LS":
|
|
43
|
+
messageAsts[id] = generateXXLS(msgAst);
|
|
44
|
+
break;
|
|
45
|
+
case "xx-AC":
|
|
46
|
+
messageAsts[id] = generateXXAC(msgAst);
|
|
47
|
+
break;
|
|
48
|
+
case "xx-HA":
|
|
49
|
+
messageAsts[id] = generateXXHA(msgAst);
|
|
50
|
+
break;
|
|
51
|
+
case "en-XA":
|
|
52
|
+
messageAsts[id] = generateENXA(msgAst);
|
|
53
|
+
break;
|
|
54
|
+
case "en-XB":
|
|
55
|
+
messageAsts[id] = generateENXB(msgAst);
|
|
56
|
+
break;
|
|
57
|
+
default:
|
|
58
|
+
messageAsts[id] = msgAst;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
idsWithFileName[id] = inputFile;
|
|
62
|
+
} catch (e) {
|
|
63
|
+
warn("Error validating message \"%s\" with ID \"%s\" in file \"%s\"", compiled[id], id, inputFile);
|
|
64
|
+
if (!skipErrors) {
|
|
65
|
+
throw e;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return stringify(ast ? messageAsts : messages, {
|
|
71
|
+
space: 2,
|
|
72
|
+
cmp: formatter.compareMessages || undefined
|
|
73
|
+
}) ?? "";
|
|
75
74
|
}
|
|
76
75
|
/**
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
76
|
+
* Aggregate `inputFiles` into a single JSON blob and compile.
|
|
77
|
+
* Also checks for conflicting IDs and write output to `outFile`.
|
|
78
|
+
* @param inputFiles Input files
|
|
79
|
+
* @param compileOpts options
|
|
80
|
+
* @returns A `Promise` that resolves if file was written successfully
|
|
81
|
+
*/
|
|
83
82
|
export default async function compileAndWrite(inputFiles, compileOpts = {}) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
83
|
+
const { outFile, ...opts } = compileOpts;
|
|
84
|
+
const serializedResult = await compile(inputFiles, opts) + "\n";
|
|
85
|
+
if (outFile) {
|
|
86
|
+
debug("Writing output file:", outFile);
|
|
87
|
+
return outputFile(outFile, serializedResult);
|
|
88
|
+
}
|
|
89
|
+
await writeStdout(serializedResult);
|
|
91
90
|
}
|
package/src/compile_folder.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Opts } from
|
|
1
|
+
import { type Opts } from "./compile.js";
|
|
2
2
|
export default function compileFolder(files: string[], outFolder: string, opts?: Opts): Promise<void[]>;
|
package/src/compile_folder.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { outputFile } from
|
|
2
|
-
import { basename, join } from
|
|
3
|
-
import { compile } from
|
|
1
|
+
import { outputFile } from "fs-extra/esm";
|
|
2
|
+
import { basename, join } from "path";
|
|
3
|
+
import { compile } from "./compile.js";
|
|
4
4
|
export default async function compileFolder(files, outFolder, opts = {}) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
const results = await Promise.all(files.map((f) => compile([f], opts)));
|
|
6
|
+
const outFiles = files.map((f) => join(outFolder, basename(f)));
|
|
7
|
+
return Promise.all(outFiles.map((outFile, i) => outputFile(outFile, results[i])));
|
|
8
8
|
}
|
package/src/console_utils.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare const writeStderr: (arg1: string | Uint8Array) => Promise<void>;
|
|
2
2
|
export declare const writeStdout: (arg1: string | Uint8Array) => Promise<void>;
|
|
3
|
-
|
|
3
|
+
// From:
|
|
4
|
+
// https://github.com/yarnpkg/yarn/blob/53d8004229f543f342833310d5af63a4b6e59c8a/src/reporters/console/util.js
|
|
5
|
+
export declare function clearLine(terminal: (typeof process)["stderr"]): Promise<void>;
|
|
4
6
|
export declare function debug(message: string, ...args: any[]): Promise<void>;
|
|
5
7
|
export declare function warn(message: string, ...args: any[]): Promise<void>;
|
|
6
8
|
export declare function error(message: string, ...args: any[]): Promise<void>;
|
package/src/console_utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as chalkNs from
|
|
2
|
-
import { clearLine as nativeClearLine, cursorTo as nativeCursorTo
|
|
3
|
-
import { format, promisify } from
|
|
1
|
+
import * as chalkNs from "chalk";
|
|
2
|
+
import { clearLine as nativeClearLine, cursorTo as nativeCursorTo } from "readline";
|
|
3
|
+
import { format, promisify } from "util";
|
|
4
4
|
const chalk = chalkNs.default ?? chalkNs;
|
|
5
5
|
const CLEAR_WHOLE_LINE = 0;
|
|
6
6
|
export const writeStderr = promisify(process.stderr.write).bind(process.stderr);
|
|
@@ -8,59 +8,57 @@ export const writeStdout = promisify(process.stdout.write).bind(process.stdout);
|
|
|
8
8
|
// From:
|
|
9
9
|
// https://github.com/yarnpkg/yarn/blob/53d8004229f543f342833310d5af63a4b6e59c8a/src/reporters/console/util.js
|
|
10
10
|
export async function clearLine(terminal) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
nativeCursorTo(terminal, 0, undefined);
|
|
24
|
-
}
|
|
11
|
+
if (!chalk.supportsColor) {
|
|
12
|
+
if (terminal.isTTY) {
|
|
13
|
+
// terminal
|
|
14
|
+
if (terminal.columns > 0) {
|
|
15
|
+
await writeStderr(`\r${" ".repeat(terminal.columns - 1)}`);
|
|
16
|
+
}
|
|
17
|
+
await writeStderr(`\r`);
|
|
18
|
+
}
|
|
19
|
+
} else {
|
|
20
|
+
nativeClearLine(terminal, CLEAR_WHOLE_LINE);
|
|
21
|
+
nativeCursorTo(terminal, 0, undefined);
|
|
22
|
+
}
|
|
25
23
|
}
|
|
26
24
|
const LEVEL_COLORS = {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
debug: chalk.green,
|
|
26
|
+
warn: chalk.yellow,
|
|
27
|
+
error: chalk.red
|
|
30
28
|
};
|
|
31
29
|
function label(level, message) {
|
|
32
|
-
|
|
30
|
+
return `[@formatjs/cli] [${LEVEL_COLORS[level](level.toUpperCase())}] ${message}`;
|
|
33
31
|
}
|
|
34
32
|
export async function debug(message, ...args) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
if (process.env.LOG_LEVEL !== "debug") {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
await clearLine(process.stderr);
|
|
37
|
+
await writeStderr(format(label("debug", message), ...args));
|
|
38
|
+
await writeStderr("\n");
|
|
41
39
|
}
|
|
42
40
|
export async function warn(message, ...args) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
await clearLine(process.stderr);
|
|
42
|
+
await writeStderr(format(label("warn", message), ...args));
|
|
43
|
+
await writeStderr("\n");
|
|
46
44
|
}
|
|
47
45
|
export async function error(message, ...args) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
await clearLine(process.stderr);
|
|
47
|
+
await writeStderr(format(label("error", message), ...args));
|
|
48
|
+
await writeStderr("\n");
|
|
51
49
|
}
|
|
52
50
|
export function getStdinAsString() {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
51
|
+
let result = "";
|
|
52
|
+
return new Promise((resolve) => {
|
|
53
|
+
process.stdin.setEncoding("utf-8");
|
|
54
|
+
process.stdin.on("readable", () => {
|
|
55
|
+
let chunk;
|
|
56
|
+
while (chunk = process.stdin.read()) {
|
|
57
|
+
result += chunk;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
process.stdin.on("end", () => {
|
|
61
|
+
resolve(result);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
66
64
|
}
|
package/src/extract.d.ts
CHANGED
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
import { MessageDescriptor, Opts } from
|
|
2
|
-
import { Formatter } from
|
|
1
|
+
import { type MessageDescriptor, type Opts } from "@formatjs/ts-transformer";
|
|
2
|
+
import { type Formatter } from "./formatters/index.js";
|
|
3
3
|
export interface ExtractionResult<M = Record<string, string>> {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
/**
|
|
5
|
+
* List of extracted messages
|
|
6
|
+
*/
|
|
7
|
+
messages: MessageDescriptor[];
|
|
8
|
+
/**
|
|
9
|
+
* Metadata extracted w/ `pragma`
|
|
10
|
+
*/
|
|
11
|
+
meta?: M;
|
|
12
12
|
}
|
|
13
13
|
export interface ExtractedMessageDescriptor extends MessageDescriptor {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Line number
|
|
16
|
+
*/
|
|
17
|
+
line?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Column number
|
|
20
|
+
*/
|
|
21
|
+
col?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Metadata extracted from pragma
|
|
24
|
+
*/
|
|
25
|
+
meta?: Record<string, string>;
|
|
26
26
|
}
|
|
27
|
-
export type ExtractCLIOptions = Omit<ExtractOpts,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
27
|
+
export type ExtractCLIOptions = Omit<ExtractOpts, "overrideIdFn" | "onMsgExtracted" | "onMetaExtracted"> & {
|
|
28
|
+
/**
|
|
29
|
+
* Output File
|
|
30
|
+
*/
|
|
31
|
+
outFile?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Input File
|
|
34
|
+
*/
|
|
35
|
+
inFile?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Ignore file glob pattern
|
|
38
|
+
*/
|
|
39
|
+
ignore?: string[];
|
|
40
40
|
};
|
|
41
41
|
export type ExtractOpts = Opts & {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
} & Pick<Opts,
|
|
42
|
+
/**
|
|
43
|
+
* Whether to throw an error if we had any issues with
|
|
44
|
+
* 1 of the source files
|
|
45
|
+
*/
|
|
46
|
+
throws?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Message ID interpolation pattern
|
|
49
|
+
*/
|
|
50
|
+
idInterpolationPattern?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Whether we read from stdin instead of a file
|
|
53
|
+
*/
|
|
54
|
+
readFromStdin?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Either path to a formatter file that controls the shape of JSON file from `outFile` or {@link Formatter} object.
|
|
57
|
+
*/
|
|
58
|
+
format?: string | Formatter<any>;
|
|
59
|
+
/**
|
|
60
|
+
* Whether to hoist selectors & flatten sentences
|
|
61
|
+
*/
|
|
62
|
+
flatten?: boolean;
|
|
63
|
+
} & Pick<Opts, "onMsgExtracted" | "onMetaExtracted">;
|
|
64
64
|
/**
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
* Extract strings from source files
|
|
66
|
+
* @param files list of files
|
|
67
|
+
* @param extractOpts extract options
|
|
68
|
+
* @returns messages serialized as JSON string since key order
|
|
69
|
+
* matters for some `format`
|
|
70
|
+
*/
|
|
71
71
|
export declare function extract(files: readonly string[], extractOpts: ExtractOpts): Promise<string>;
|
|
72
72
|
/**
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
* Extract strings from source files, also writes to a file.
|
|
74
|
+
* @param files list of files
|
|
75
|
+
* @param extractOpts extract options
|
|
76
|
+
* @returns A Promise that resolves if output file was written successfully
|
|
77
|
+
*/
|
|
78
78
|
export default function extractAndWrite(files: readonly string[], extractOpts: ExtractCLIOptions): Promise<void>;
|