@formatjs/cli-lib 8.1.0 → 8.2.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/index.d.ts +7 -7
- package/index.js +2 -2
- package/main.d.ts +0 -1
- package/main.js +1 -1
- package/package.json +12 -12
- 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 +1 -1
- package/src/console_utils.js +44 -46
- package/src/extract.d.ts +68 -68
- package/src/extract.js +165 -178
- 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/extract.js
CHANGED
|
@@ -1,190 +1,177 @@
|
|
|
1
|
-
import { interpolateName
|
|
2
|
-
import { outputFile } from
|
|
3
|
-
import { debug, getStdinAsString, warn, writeStdout } from
|
|
4
|
-
import * as stringifyNs from
|
|
5
|
-
import { resolveBuiltinFormatter } from
|
|
6
|
-
import { parseScript } from
|
|
7
|
-
import { readFile } from
|
|
1
|
+
import { interpolateName } from "@formatjs/ts-transformer";
|
|
2
|
+
import { outputFile } from "fs-extra/esm";
|
|
3
|
+
import { debug, getStdinAsString, warn, writeStdout } from "./console_utils.js";
|
|
4
|
+
import * as stringifyNs from "json-stable-stringify";
|
|
5
|
+
import { resolveBuiltinFormatter } from "./formatters/index.js";
|
|
6
|
+
import { parseScript } from "./parse_script.js";
|
|
7
|
+
import { readFile } from "fs/promises";
|
|
8
8
|
const stringify = stringifyNs.default || stringifyNs;
|
|
9
9
|
function calculateLineColFromOffset(text, start) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
if (!start) {
|
|
11
|
+
return {
|
|
12
|
+
line: 1,
|
|
13
|
+
col: 1
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const chunk = text.slice(0, start);
|
|
17
|
+
const lines = chunk.split("\n");
|
|
18
|
+
const lastLine = lines[lines.length - 1];
|
|
19
|
+
return {
|
|
20
|
+
line: lines.length,
|
|
21
|
+
col: lastLine.length
|
|
22
|
+
};
|
|
17
23
|
}
|
|
18
24
|
async function processFile(source, fn, { idInterpolationPattern, ...opts }) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
parseFile(source, fn, opts);
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
debug('Processing %s using typescript extractor', fn);
|
|
82
|
-
scriptParseFn(source);
|
|
83
|
-
}
|
|
84
|
-
debug('Done extracting %s messages: %s', fn, messages);
|
|
85
|
-
if (meta) {
|
|
86
|
-
debug('Extracted meta:', meta);
|
|
87
|
-
messages.forEach(m => (m.meta = meta));
|
|
88
|
-
}
|
|
89
|
-
return { messages, meta };
|
|
25
|
+
let messages = [];
|
|
26
|
+
let meta;
|
|
27
|
+
const onMsgExtracted = opts.onMsgExtracted;
|
|
28
|
+
const onMetaExtracted = opts.onMetaExtracted;
|
|
29
|
+
opts = {
|
|
30
|
+
...opts,
|
|
31
|
+
additionalComponentNames: ["$formatMessage", ...opts.additionalComponentNames || []],
|
|
32
|
+
onMsgExtracted(filePath, msgs) {
|
|
33
|
+
if (opts.extractSourceLocation) {
|
|
34
|
+
msgs = msgs.map((msg) => ({
|
|
35
|
+
...msg,
|
|
36
|
+
...calculateLineColFromOffset(source, msg.start)
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
messages = messages.concat(msgs);
|
|
40
|
+
if (onMsgExtracted) {
|
|
41
|
+
onMsgExtracted(filePath, msgs);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
onMetaExtracted(filePath, m) {
|
|
45
|
+
meta = m;
|
|
46
|
+
if (onMetaExtracted) {
|
|
47
|
+
onMetaExtracted(filePath, m);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
if (!opts.overrideIdFn && idInterpolationPattern) {
|
|
52
|
+
opts = {
|
|
53
|
+
...opts,
|
|
54
|
+
overrideIdFn: (id, defaultMessage, description, fileName) => id || interpolateName({ resourcePath: fileName }, idInterpolationPattern, { content: description ? `${defaultMessage}#${typeof description === "string" ? description : stringify(description)}` : defaultMessage })
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
debug("Processing opts for %s: %s", fn, opts);
|
|
58
|
+
const scriptParseFn = parseScript(opts, fn);
|
|
59
|
+
if (fn.endsWith(".vue")) {
|
|
60
|
+
debug("Processing %s using vue extractor", fn);
|
|
61
|
+
const { parseFile } = await import("./vue_extractor.js");
|
|
62
|
+
parseFile(source, fn, scriptParseFn);
|
|
63
|
+
} else if (fn.endsWith(".hbs")) {
|
|
64
|
+
debug("Processing %s using hbs extractor", fn);
|
|
65
|
+
const { parseFile } = await import("./hbs_extractor.js");
|
|
66
|
+
parseFile(source, fn, opts);
|
|
67
|
+
} else if (fn.endsWith(".gts") || fn.endsWith(".gjs")) {
|
|
68
|
+
debug("Processing %s as gts/gjs file", fn);
|
|
69
|
+
const { parseFile } = await import("./gts_extractor.js");
|
|
70
|
+
parseFile(source, fn, opts);
|
|
71
|
+
} else {
|
|
72
|
+
debug("Processing %s using typescript extractor", fn);
|
|
73
|
+
scriptParseFn(source);
|
|
74
|
+
}
|
|
75
|
+
debug("Done extracting %s messages: %s", fn, messages);
|
|
76
|
+
if (meta) {
|
|
77
|
+
debug("Extracted meta:", meta);
|
|
78
|
+
messages.forEach((m) => m.meta = meta);
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
messages,
|
|
82
|
+
meta
|
|
83
|
+
};
|
|
90
84
|
}
|
|
91
85
|
/**
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
86
|
+
* Extract strings from source files
|
|
87
|
+
* @param files list of files
|
|
88
|
+
* @param extractOpts extract options
|
|
89
|
+
* @returns messages serialized as JSON string since key order
|
|
90
|
+
* matters for some `format`
|
|
91
|
+
*/
|
|
98
92
|
export async function extract(files, extractOpts) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const { id, description, defaultMessage } = message;
|
|
133
|
-
if (!id) {
|
|
134
|
-
const error = new Error(`[FormatJS CLI] Missing message id for message:
|
|
93
|
+
const { throws, readFromStdin, ...opts } = extractOpts;
|
|
94
|
+
let rawResults = [];
|
|
95
|
+
try {
|
|
96
|
+
if (readFromStdin) {
|
|
97
|
+
debug(`Reading input from stdin`);
|
|
98
|
+
// Read from stdin
|
|
99
|
+
if (process.stdin.isTTY) {
|
|
100
|
+
warn("Reading source file from TTY.");
|
|
101
|
+
}
|
|
102
|
+
const stdinSource = await getStdinAsString();
|
|
103
|
+
rawResults = [await processFile(stdinSource, "dummy", opts)];
|
|
104
|
+
} else {
|
|
105
|
+
rawResults = await Promise.all(files.map(async (fn) => {
|
|
106
|
+
debug("Extracting file:", fn);
|
|
107
|
+
const source = await readFile(fn, "utf8");
|
|
108
|
+
return processFile(source, fn, opts);
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
} catch (e) {
|
|
112
|
+
if (throws) {
|
|
113
|
+
throw e;
|
|
114
|
+
} else {
|
|
115
|
+
warn(String(e));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const formatter = await resolveBuiltinFormatter(opts.format);
|
|
119
|
+
const extractionResults = rawResults.filter((r) => !!r);
|
|
120
|
+
const extractedMessages = new Map();
|
|
121
|
+
for (const { messages } of extractionResults) {
|
|
122
|
+
for (const message of messages) {
|
|
123
|
+
const { id, description, defaultMessage } = message;
|
|
124
|
+
if (!id) {
|
|
125
|
+
const error = new Error(`[FormatJS CLI] Missing message id for message:
|
|
135
126
|
${JSON.stringify(message, undefined, 2)}`);
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
return (stringify(formatter.format(results), {
|
|
172
|
-
space: 2,
|
|
173
|
-
cmp: formatter.compareMessages || undefined,
|
|
174
|
-
}) ?? '');
|
|
127
|
+
if (throws) {
|
|
128
|
+
throw error;
|
|
129
|
+
} else {
|
|
130
|
+
warn(error.message);
|
|
131
|
+
}
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (extractedMessages.has(id)) {
|
|
135
|
+
const existing = extractedMessages.get(id);
|
|
136
|
+
if (stringify(description) !== stringify(existing.description) || defaultMessage !== existing.defaultMessage) {
|
|
137
|
+
const error = new Error(`[FormatJS CLI] Duplicate message id: "${id}", ` + "but the `description` and/or `defaultMessage` are different.");
|
|
138
|
+
if (throws) {
|
|
139
|
+
throw error;
|
|
140
|
+
} else {
|
|
141
|
+
warn(error.message);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
extractedMessages.set(id, message);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const results = {};
|
|
149
|
+
const messages = Array.from(extractedMessages.values());
|
|
150
|
+
for (const { id, ...msg } of messages) {
|
|
151
|
+
// GH #3537: flatten is now applied during extraction in the babel plugin,
|
|
152
|
+
// so we don't need to apply it again here. The messages are already flattened.
|
|
153
|
+
results[id] = msg;
|
|
154
|
+
}
|
|
155
|
+
if (typeof formatter.serialize === "function") {
|
|
156
|
+
return formatter.serialize(formatter.format(results));
|
|
157
|
+
}
|
|
158
|
+
return stringify(formatter.format(results), {
|
|
159
|
+
space: 2,
|
|
160
|
+
cmp: formatter.compareMessages || undefined
|
|
161
|
+
}) ?? "";
|
|
175
162
|
}
|
|
176
163
|
/**
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
164
|
+
* Extract strings from source files, also writes to a file.
|
|
165
|
+
* @param files list of files
|
|
166
|
+
* @param extractOpts extract options
|
|
167
|
+
* @returns A Promise that resolves if output file was written successfully
|
|
168
|
+
*/
|
|
182
169
|
export default async function extractAndWrite(files, extractOpts) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
170
|
+
const { outFile, ...opts } = extractOpts;
|
|
171
|
+
const serializedResult = await extract(files, opts) + "\n";
|
|
172
|
+
if (outFile) {
|
|
173
|
+
debug("Writing output file:", outFile);
|
|
174
|
+
return outputFile(outFile, serializedResult);
|
|
175
|
+
}
|
|
176
|
+
await writeStdout(serializedResult);
|
|
190
177
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { CompileFn, FormatFn } from
|
|
1
|
+
import { type CompileFn, type FormatFn } from "./default.js";
|
|
2
2
|
export type CrowdinJson = Record<string, {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
message: string;
|
|
4
|
+
description?: string;
|
|
5
5
|
}>;
|
|
6
6
|
export declare const format: FormatFn<CrowdinJson>;
|
|
7
7
|
export declare const compile: CompileFn<CrowdinJson>;
|
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return results;
|
|
1
|
+
import "./default.js";
|
|
2
|
+
export const format = (msgs) => {
|
|
3
|
+
const results = {};
|
|
4
|
+
for (const [id, msg] of Object.entries(msgs)) {
|
|
5
|
+
results[id] = {
|
|
6
|
+
message: msg.defaultMessage,
|
|
7
|
+
description: typeof msg.description === "string" ? msg.description : JSON.stringify(msg.description)
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
return results;
|
|
12
11
|
};
|
|
13
|
-
export const compile = msgs => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
export const compile = (msgs) => {
|
|
13
|
+
const results = {};
|
|
14
|
+
for (const [id, msg] of Object.entries(msgs)) {
|
|
15
|
+
if (id === "smartling") {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
results[id] = msg.message;
|
|
19
|
+
}
|
|
20
|
+
return results;
|
|
22
21
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MessageDescriptor } from
|
|
1
|
+
import { type MessageDescriptor } from "@formatjs/ts-transformer";
|
|
2
2
|
export type FormatFn<T = Record<string, MessageDescriptor>> = (msgs: Record<string, MessageDescriptor>) => T;
|
|
3
3
|
export type CompileFn<T = Record<string, MessageDescriptor>> = (msgs: T) => Record<string, string>;
|
|
4
4
|
export type SerializeFn<T = Record<string, MessageDescriptor>> = (msgs: T) => string;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
export const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import "@formatjs/ts-transformer";
|
|
2
|
+
export const format = (msgs) => msgs;
|
|
3
|
+
export const compile = (msgs) => {
|
|
4
|
+
const results = {};
|
|
5
|
+
for (const k in msgs) {
|
|
6
|
+
results[k] = msgs[k].defaultMessage;
|
|
7
|
+
}
|
|
8
|
+
return results;
|
|
8
9
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { Comparator } from
|
|
2
|
-
import { CompileFn, FormatFn, SerializeFn } from
|
|
1
|
+
import type { Comparator } from "json-stable-stringify";
|
|
2
|
+
import { type CompileFn, type FormatFn, type SerializeFn } from "./default.js";
|
|
3
3
|
export interface Formatter<T> {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
serialize?: SerializeFn<T>;
|
|
5
|
+
format: FormatFn<T>;
|
|
6
|
+
compile: CompileFn<T>;
|
|
7
|
+
compareMessages?: Comparator;
|
|
8
8
|
}
|
|
9
9
|
export declare function resolveBuiltinFormatter(format?: string | Formatter<unknown>): Promise<any>;
|
package/src/formatters/index.js
CHANGED
|
@@ -1,36 +1,31 @@
|
|
|
1
|
-
import { resolve } from
|
|
2
|
-
import { pathToFileURL } from
|
|
3
|
-
import * as crowdin from
|
|
4
|
-
import * as defaultFormatter from
|
|
5
|
-
import
|
|
6
|
-
import * as
|
|
7
|
-
import * as
|
|
8
|
-
import * as
|
|
1
|
+
import { resolve } from "path";
|
|
2
|
+
import { pathToFileURL } from "url";
|
|
3
|
+
import * as crowdin from "./crowdin.js";
|
|
4
|
+
import * as defaultFormatter from "./default.js";
|
|
5
|
+
import "./default.js";
|
|
6
|
+
import * as lokalise from "./lokalise.js";
|
|
7
|
+
import * as simple from "./simple.js";
|
|
8
|
+
import * as smartling from "./smartling.js";
|
|
9
|
+
import * as transifex from "./transifex.js";
|
|
9
10
|
export async function resolveBuiltinFormatter(format) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return import(pathToFileURL(resolve(process.cwd(), format)).href);
|
|
31
|
-
}
|
|
32
|
-
catch (e) {
|
|
33
|
-
console.error(`Cannot resolve formatter ${format}`);
|
|
34
|
-
throw e;
|
|
35
|
-
}
|
|
11
|
+
if (!format) {
|
|
12
|
+
return defaultFormatter;
|
|
13
|
+
}
|
|
14
|
+
if (typeof format !== "string") {
|
|
15
|
+
return format;
|
|
16
|
+
}
|
|
17
|
+
switch (format) {
|
|
18
|
+
case "transifex": return transifex;
|
|
19
|
+
case "smartling": return smartling;
|
|
20
|
+
case "simple": return simple;
|
|
21
|
+
case "lokalise": return lokalise;
|
|
22
|
+
case "crowdin": return crowdin;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
// eslint-disable-next-line import/dynamic-import-chunkname
|
|
26
|
+
return import(pathToFileURL(resolve(process.cwd(), format)).href);
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.error(`Cannot resolve formatter ${format}`);
|
|
29
|
+
throw e;
|
|
30
|
+
}
|
|
36
31
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { CompileFn, FormatFn } from
|
|
1
|
+
import { type CompileFn, type FormatFn } from "./default.js";
|
|
2
2
|
export type StructuredJson = Record<string, {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
translation: string;
|
|
4
|
+
notes?: string;
|
|
5
|
+
context?: string;
|
|
6
|
+
limit?: string;
|
|
7
7
|
}>;
|
|
8
8
|
export declare const format: FormatFn<StructuredJson>;
|
|
9
9
|
export declare const compile: CompileFn<StructuredJson>;
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return results;
|
|
1
|
+
import "./default.js";
|
|
2
|
+
export const format = (msgs) => {
|
|
3
|
+
const results = {};
|
|
4
|
+
for (const [id, msg] of Object.entries(msgs)) {
|
|
5
|
+
results[id] = {
|
|
6
|
+
translation: msg.defaultMessage,
|
|
7
|
+
notes: typeof msg.description === "string" ? msg.description : JSON.stringify(msg.description)
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
return results;
|
|
12
11
|
};
|
|
13
|
-
export const compile = msgs => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
export const compile = (msgs) => {
|
|
13
|
+
const results = {};
|
|
14
|
+
for (const [id, msg] of Object.entries(msgs)) {
|
|
15
|
+
results[id] = msg.translation;
|
|
16
|
+
}
|
|
17
|
+
return results;
|
|
19
18
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CompileFn, FormatFn } from
|
|
1
|
+
import { type CompileFn, type FormatFn } from "./default.js";
|
|
2
2
|
export type PhraseJson = Record<string, string>;
|
|
3
3
|
export declare const format: FormatFn<PhraseJson>;
|
|
4
4
|
export declare const compile: CompileFn<PhraseJson>;
|
package/src/formatters/simple.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import "./default.js";
|
|
2
|
+
export const format = (msgs) => {
|
|
3
|
+
return Object.keys(msgs).reduce((all, k) => {
|
|
4
|
+
all[k] = msgs[k].defaultMessage;
|
|
5
|
+
return all;
|
|
6
|
+
}, {});
|
|
6
7
|
};
|
|
7
|
-
export const compile = msgs => msgs;
|
|
8
|
+
export const compile = (msgs) => msgs;
|
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
import type { Comparator } from
|
|
2
|
-
import { CompileFn, FormatFn } from
|
|
1
|
+
import type { Comparator } from "json-stable-stringify";
|
|
2
|
+
import { type CompileFn, type FormatFn } from "./default.js";
|
|
3
3
|
export interface SmartlingDirectives {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
string_format: string;
|
|
13
|
-
[k: string]: any;
|
|
4
|
+
translate_paths: [{
|
|
5
|
+
path: string;
|
|
6
|
+
key: string;
|
|
7
|
+
instruction: string;
|
|
8
|
+
}];
|
|
9
|
+
variants_enabled: boolean;
|
|
10
|
+
string_format: string;
|
|
11
|
+
[k: string]: any;
|
|
14
12
|
}
|
|
15
13
|
export type SmartlingJson = {
|
|
16
|
-
|
|
14
|
+
smartling: SmartlingDirectives;
|
|
17
15
|
} & Record<string, {
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
message: string;
|
|
17
|
+
description?: string;
|
|
20
18
|
}>;
|
|
21
19
|
export declare const format: FormatFn<SmartlingJson>;
|
|
22
20
|
export declare const compareMessages: Comparator;
|